OmniAICreator/Qiita-1.07M huggingface dataset:
AtCoder初心者振り返りメモ ABC345

# ABC345の回
https://atcoder.jp/contests/abc345
# A-問題
https://atcoder.jp/contests/abc345/tasks/abc345_a

[問題文]
<, =, > のみからなる文字列 S が与えられます。
S が 双方向矢印型 の文字列 <=> であるか判定してください。

[考察や感想]
入力例３で <>>はNo判定なので、
最終形が　<> であれば「双方向矢印型」ではないかと推測し
= をreplaceで除去して、<> であれば Yes でなければ No と記述しました。

````Python:A.py
# 入力の受け取り
T = input()

S = T.replace("=","")

if S == "<>":
    print("Yes")
else:
    print("No")
````
# B-問題
https://atcoder.jp/contests/abc345/tasks/abc345_b

![345b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547298/c24f48f9-2b91-b22f-b640-eef033a69326.png)

[考察や感想]
入力例と出力例をいくつか見て、10で割って切り上げていると思いつき割と早く正答できました。
10で割り切れない場合は、商 + 1 
10で割り切れる場合は、そのまま商を返します。

````Python:B.py
# 入力の受け取り
N = int(input())

if N % 10 != 0:
    ans = N // 10 + 1
else:
    ans = N // 10

print(ans)
````
チートポインタラクションモード

# 背景
チートポの7章である、インタラクションモードに関する章のワークショップを開催してきた。

https://team-topologies-object-modeling.connpass.com/event/311595/

# 概要
環境変化に強い迅速なデリバリーを実現するための組織設計には、
大きく分けて７つのポイントがある。

## 各チームのロール
大きく分けて４つ。
主に各ドメインごとの開発を行うストリームアラインドチームと
それらを支援する
プラットフォームチーム、イネイブリングチーム、
再利用コンポーネントなどを担当するプラットフォームチーム。

## 他チームとの連携の仕方
コンテキスト境界があいまいな場合に他チームと部分的に交わるコラボレーション。
完全に疎な独立した関係性のX-as-a-Servise連携。
イネイブリングチームがストリームアラインドと交わる部分の連携であるファシリテーション。


# 感想
ある時はストリームアイランドチームのロールとして、
ある時はイネイブリングチームとしてというように
ロールの固定なく循環し、

さらに連携の仕方もコラボという密な協力であったり、
XaaSのように疎結合なかかわり方であったり、
だれかをサポートするようなファシリテーションかかわり方であったり。

アンチパターンは、
ずっと同じロールのままで、かつ他コンテキストとのかかわり方も固定的であること。
これは動的な変化、循環を生まずに、水の流れと一緒で組織が腐ることを助長する。

たまには違う道を歩いてみるとか、普段会わないような人と会ってみるとかがいいと言われる理由はコレ。
【java】インターフェースの特徴について

javaSilver勉強にあたって、javaのインターフェースについてまとめてみた。

インターフェースには次のような特徴がある。
・公開するためのものなので、publicなメンバを定義する。
・インスタンス化できない。
・抽象メソッドを定義できる
・デフォルトメソッドとstaticメソッドとして実装を定義できる
・デフォルトメソッドとstaticメソッドから利用されることを想定し、privateな具象メソッドを定義できる。
・定数は定義できるが、フィールドは定義できない。

　
　
またインターフェースでは実装を持たない抽象メソッドの宣言で、abstractで修飾されていなくても、暗黙的にabstractであると解釈される。

例：
```
public String methodA();
```

finalで抽象メソッドを宣言できない。
finalは変更できないことを宣言するもので、この抽象メソッドはインターフェースを実現したクラスによってオーバーライドされるために存在する。つまり、変更されるのが前提であり、インターフェースに定義する抽象メソッドはfinalで修飾することができない

例：
```
final void methodB();
```

【デフォルトメソッドについて】
インターフェース内で「default」キーワードを使用して宣言され、具象メソッドとして機能します。
これにより、インターフェースを実装するクラスはデフォルトメソッドをオーバーライドすることなく使用することができます。

【staicメソッドについて】
staticメソッドもインターフェース内で宣言でき、インターフェース名を通じて、呼び出すことが可能です。
staticメソッドはインスタンスに依存しないため、インターフェースのインスタンス化なしに使用できます。

以下にデフォルトメソッドとstaticメソッドの例を示します。

 　

```
public interface MyInterface {
    // デフォルトメソッドの宣言
    default void printGreeting() {
        System.out.println("こんにちは、デフォルトメソッドです！");
    }

    // staticメソッドの宣言
    static void printStaticGreeting() {
        System.out.println("こんにちは、staticメソッドです！");
    }
}

public class MyClass implements MyInterface {
    // デフォルトメソッドをオーバーライドすることもできます
    @Override
    public void printGreeting() {
        System.out.println("こんにちは、MyClassのデフォルトメソッドです！");
    }
}

public class Test {
    public static void main(String[] args) {
        MyInterface myInterface = new MyClass();
        myInterface.printGreeting(); // "こんにちは、MyClassのデフォルトメソッドです！" を出力

        MyInterface.printStaticGreeting(); // "こんにちは、staticメソッドです！" を出力
    }
}

```


※これらメソッドを使用する際は、名前の衝突や継承の問題に注意する必要があります。
Laravel（PHP）でOpenAI APIを使用する

ハッカソンで、Laravel（PHP）からOpenAIのAPIをたたく機会がありました。
OpenAI APIのドキュメントにはPython、node.js、curlの呼び出し形式がありますが、PHPからの呼び出し形式はなかったので、備忘録として書き残します。
# 目次
- [テキストからテキスト](#テキストからテキスト)
- [テキストから画像](#テキストから画像)
- [画像からテキスト](#画像からテキスト)
- [APIリクエストの実装方法](#APIリクエストの実装方法)

## テキストからテキスト
https://platform.openai.com/docs/guides/text-generation
エンドポイント：`https://api.openai.com/v1/chat/completions`
~~~php
[
    'model' => 'gpt-4',
        'messages' => [
            [
                "role" => "user",
                "content" => [
                    [
                        "type" => "text",
                        "text" => {プロンプト}
                    ],
                ],
            ]
        ],
    "max_tokens" => 1000,
]
~~~
## テキストから画像
https://platform.openai.com/docs/guides/images
エンドポイント：`https://api.openai.com/v1/images/generations`
~~~php
[
    'model' => 'dall-e-3',
    'prompt' => {プロンプト},
    'size' => "1024x1024",
    'quality' => "standard",
    'n' => 1,
]
~~~
## 画像からテキスト
https://platform.openai.com/docs/guides/vision
エンドポイント：`https://api.openai.com/v1/chat/completions`
~~~php
[
    [
        'model' => 'gpt-4-vision-preview',
        'messages' => [
            [
                "role" => "user",
                "content" => [
                    [
                        "type" => "text",
                        "text" => {プロンプト}
                    ],
                    [
                        "type" => "image_url",
                        "image_url" => [
                            "url" => {画像へのURL}
                        ]
                    ],
                ],
            ]
        ],
        "max_tokens" => 1000,
    ]
]
~~~
## APIリクエストの実装方法
リクエストにはHttpファサードを使用しました。
また、リクエストのヘッダにOpenAIのサイトで生成したトークンを含める必要があるので、AuthorizationヘッダのBearer認証でトークンを送りました。

`$response`の中身はモデルによって違うので注意が必要です。
都度返ってきたJSONをデコードして中身を確認し、欲しいデータを取ってきてください。
~~~php
$apiKey = {OpenAIのAPIキー};
$headers = [
    "Content-Type" => "application/json",
    "Authorization" => "Bearer $apiKey"
]
$response = Http::withHeaders($headers)
    ->timeout(60)
    ->post({エンドポイント}, {呼び出し形式通りのデータ});
~~~
【Android】Jetpack ComposeのButtonあれこれ【Kotlin】

# 目次
* Button
* FilledTonalButton
* TextButton
* OutlinedButton
* ElevatedButton
* IconButton
* FloatingActionButton
* RadioButton


# Button
```
        Button(onClick = {}) {
            Text("Button")
        }
```
デフォルトで背景色がついているボタン

# FilledTonalButton
```
   FilledTonalButton(onClick = {}) {
            Text("FilledTonalButton")
        }
```
デフォルトの背景色がSecondaryColorによって設定されている

# TextButton

```
        TextButton(onClick = {}) {
            Text("TextButton")
        }
```
特に装飾のないTextにClick処理をつけられる

# OutlinedButton
```
        OutlinedButton(onClick = {}) {
            Text("Outlined Button")
        }
```
Textの周りにボーダーラインがついている
他のButtonでもborder（外枠線）をつけられるので、あんまり使わないかも

# ElevatedButton
```
        ElevatedButton(onClick = {}) {
            Text("Elevated Button")
        }
```
デフォルトでelevation(高さ)が設定されてる
他のButtonでもelevationが設定できるので、あんまり使わないかも

# IconButton

```
        IconToggleButton(
            checked = true,
            onCheckedChange = {}
        ) {
            Icon(
                Icons.Filled.Favorite,
                contentDescription = "ハート",
            )
        }
```
画像にClick処理をつけられる


# FloatingActionButton
```
        FloatingActionButton(onClick = {}) {
            Icon(
                Icons.Filled.Favorite,
                contentDescription = "ハート",
            )
        }
```
よく使うアクションなどを設定して、画面上に常に出ているボタンなどに使う

# RadioButton
```
        RadioButton(
            selected = true,
            onClick = {}
        )
```
選択式の入力フォームなどで使う


# プレビュー
![スクリーンショット 2024-03-17 21.54.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/74580bd8-a807-0230-d313-2fb13ea14f86.png)



# 参考

https://developer.android.com/jetpack/compose/components/button?hl=ja

https://developer.android.com/jetpack/compose/components/fab?hl=ja

https://techbooster.org/android/ui/18533/

https://techbooster.org/android/ui/18597/

https://zenn.dev/joo_hashi/books/f646fb076f58dc/viewer/4228c9
(自分用)GPU+Python開発用Dockerfile

```dockerfile
FROM nvidia/cuda:12.1.0-base-ubuntu22.04

# aptの更新など
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y htop vim wget curl
RUN apt-get install -y nodejs npm
RUN apt-get install -y python3.10 python3-pip
RUN apt-get install -y openssh-server
RUN apt-get clean

# .bashrcの編集
RUN sed -i 1iforce_color_prompt=yes /root/.bashrc
RUN echo alias la="'ls -lah'" >> /root/.bashrc

# SSH接続のための設定
RUN mkdir /var/run/sshd
RUN echo '\n'PermitRootLogin yes >> /etc/ssh/sshd_config
RUN mkdir /root/.ssh
COPY $HOME/.ssh/id_rsa.pub /root/.ssh/authorized_keys
RUN chmod 600 /root/.ssh/authorized_keys
# runしたときにSSH接続を開始
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

## コマンド
# docker build -f .\work\dockerfiles\ssh_ubuntu_cuda -t ssh:ubuntu22.04-cuda12.1 .
# docker run --gpus all --name ssh_ubuntu_cuda -d -p 10000:22 -p 8888:8888 ssh:ubuntu22.04-cuda12.1
# ssh root@127.0.0.1 -p 10000
```
【Linux・Rails6・Cloud9】ngrokのインストール(無料版)

LINEのAPIを導入する際に、windowsのCloud9でのngrok導入方法が分からず詰んでいたところ、メンターさんに教えていただき解決できたので備忘録として載せます。

ngrok(エングロック)とは、開発時に外部接続をしたい場合に使用すると有効なツールです。本番環境で外部接続をすることもできますが本番環境で色々試すのは危険なので、ngrokを使用するという感じです。
公式通りにngrokをインストールしていたところ、まったくうまくいきませんでした。なので、成功したパターンを載せていきたいと思います。(一番は公式通りできることですが、、)

# 方法
### ngrokでサインアップする(無料)

https://ngrok.com/

サインアップ後、以下の画面が出てくると思うので今回はagentの**Linux**を選択してください。(コマンドは今回公式と別で用意しているのでauthtokenぐらいしか使わないかもしれませんが、、)
![スクリーンショット 2024-03-17 210611.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677302/d7054b4f-abbe-6fea-ac4a-99c05548da63.png)

### アプリケーションに移動
まずは**開発しているアプリ**に移動してください。
```terminal:ターミナル1
cd アプリ名
```
ここからngrokのインストール部分です。
```terminal:ターミナル1
wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz
```
```terminal:ターミナル1
sudo tar -xvzf ngrok-v3-stable-linux-amd64.tgz -C /usr/local/bin
```
上のコマンドでうまくいかなかった場合は、binフォルダが無い可能性があるので、`mkdir bin`でbinフォルダを作成してください。

### authtoken取得
この後**authtoken**というものを使用するのですが、確認方法は2つあります。
どちらも公式サイトから確認するので、サイトに移動してください。authtokenはコピーしておくと:ok_woman:
①ngrok公式の画面左上のYour Authtokenから確認

![スクリーンショット 2024-03-17 211611.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677302/9c01c57c-5c87-57bc-0165-1044b0d24c3e.png)
➁downloadタブを開いてコマンド部分から確認(青く隠してある部分です)
![スクリーンショット 2024-03-17 211721.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677302/6974fd2b-6bb2-0705-baa0-69ce9ea2306a.png)

authtoken確認後、再びターミナルへ戻りこのコマンドを実行してください。
```terminal:ターミナル1
ngrok config add-authtoken 自分のauthtokenをここにコピペ
```

これで導入が完了！
railsサーバーを起動しましょう。
```terminal:ターミナル1
rails s
```
ここで注意点！
サーバーを動かしているターミナルとは別に、**もう１つターミナルを開いてください。**
別に開いたターミナルを説明の際はターミナル2とします。
ターミナル2でngrokのコマンドを打ち込みます。
```terminal:ターミナル2
ngrok http 8080
```
打ち込むとngrokの黒い画面が出てくるので、**Forwarding**の**https:から始まる文字列**を少し面倒ですがご自分のブラウザの検索窓に手打ちしてください。(コピペできなかった気がします。)
一度確認の画面を挟むと思うので、青いボタンを押してページに遷移してください。
ターミナル2でエラーが出ていなければ成功です！

## 使用上の注意
:::note warn
2回目以降も必ず2つターミナルを使用し、片方はサーバーを立ち上げた状態でもう片方のターミナルでngrok http 8080のコマンドを使用してください。
:::
:::note warn
ngrokコマンドを使うたび無料版なので毎回URLが変わります。ページ検索の際は注意してください。大抵最初の数字が変わっているだけです。
:::

## 最後に
初めてngrokを使用したので、説明が至らない部分や間違っている部分があればご気軽に教えていただけると幸いです。
GLSLライブコーディングVJに使えそうなツールを色々触った雑な感想

# GLSLライブコーディングVJに使えそうなツールを色々触った雑な感想

- 個人の意見です
- GLSLを書けるとこはいっぱいありますが、その中でもライブコーディングVJに使えそうなものを選びました
- 随時追記していきます

### Sh4derJockey
https://github.com/slerpyyy/sh4der-jockey
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950881/35a7f0b1-99af-88b2-2d2b-abea6c6bffb9.png)

- glslを書く事だけに集中できるツール
- コードエディタはないが、ホットリロードしてくれるのでライブコーディングできる
- fft,image,ndi,midiを扱える
- パイプラインを.yamlとして記述できる
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950881/8cedee58-ab1e-e32b-a4c5-555281400b62.png)
- MIDIのバインディングがGUIで簡単にできる
- vertex,fragment,compute shaderを使える
- いつもVJの時に使ってます

### kodelife
https://hexler.net/kodelife
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950881/eca00117-1d2b-96bf-1740-7a6b526e01f4.png)

- LiveCoding環境
- MIDI,fft,3dモデル,video,OSCとかを扱える
- 3Dモデルを入力として使える
- fftも取れる
- spout出力も可能
- シェーダーステージやuniformのカスタマイズが容易
- エディタの触り心地があまり好きじゃない
- スマホバージョンもあるが、使いにくい

### Bonzomatic
https://github.com/Gargaj/Bonzomatic
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950881/96864d61-560b-0352-30af-1814370069a5.png)

- RevisionというでかいDemopartyで使われたりする、レギュがしっかりしたLiveCoding環境
- DX9,DX11,GLFWバージョンがある
- fft、noise textureが使えたりする
- 変なことをするとフォントも使えるという噂
- フォークバージョン
    - https://github.com/TheNuSan/Bonzomatic
        - リモートでもライブコーディングできる
    - https://github.com/wrightwriter/Bonzomatic-Compute
        - compute shader使える
- 好き

### VEDA
https://veda.gl
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950881/40dbc18b-8dd8-8655-fd0c-1febc55bab3a.png)

- 今は無きAtomで動くライブコーディングツール
    - やりたいならPulsar(https://pulsar-edit.dev )で動かせる
- webgl
- 画像の通りいろんな入力を使える
- Atomのシンプルなコードが映えてかっこいいと思う

### POSH BROLLY
https://www.poshbrolly.net/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950881/28230a0e-6b11-fc51-201e-b441308ed283.png)

- ブラウザで動くライブコーディング環境
- timeline制御,sliderのui,fft(youtubeから),cameraのマウス操作,midiなどがある
- ライブコーディング用のタイマー表示
- shader minify機能
- 打ち込み可能シンセ機能
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950881/cad1d4dd-6274-5f21-1364-5e4eeb9fda45.png)
- デモとして出力可能
- UIの動きとか色がかわいくて良い

### Twigl
https://twigl.app/

![Screenshot_20240317-212727~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950881/96e36865-5438-d0b2-6bdc-931ba5047bae.png)

- ブラウザで動く
- uniformが一文字になったレギュレーションがある
- つぶやきGLSLの公式(?)レギュレーション
- 動画、画像、共有リンクのエクスポート、ブロードキャスト機能もあり
- サウンドシェーダーもあります
javacコマンドとjavaコマンドについて

javaSilvarの問題の一部抜粋。
javacコマンドとjavaコマンドに関して2点気をつける。

・コンパイルするときのjavacコマンドの引数には、拡張子の.javaまで含むソースファイル名を記述する。
・実行するときのjavaコマンドの引数にはクラスファイルのファイル名ではなく完全修飾クラス名を記述する。

例：
```Sample.java
> javac Sample.java
> java Sample
```
/

簡単ではありますが以上となります。
javaSilverの資格勉強の一環としてQiitaに投稿させていただきます。
[Mac] イメージをクリップボードにコピーする impbcopy コマンド


標準の `pbcopy`コマンドは、`テキスト`をクリップボードにコピーしますが、`イメージ`はコピーできません。
そこで、`イメージ`をクリップボードにコピーする `impbcopy`コマンドを作ります。
とは言っても、自分のオリジナルではなく、GitHubに上がっていた Objective-C で書かれたコードを Swift に書き換えただけです。<br><br>

Objective-Cで書かれた元のソースコードは、↓こちら。
（これをこのまま利用しても、もちろん 問題なく動作します）

[https://gist.github.com/mwender/49609a18be41b45b2ae4](https://gist.github.com/mwender/49609a18be41b45b2ae4)
[<img width="300" alt="pbcopy.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/f6c9d12e-33bc-51a2-fdf5-706b25917a1d.png" />](https://gist.github.com/mwender/49609a18be41b45b2ae4)


# impbcopy コマンド

↓Swiftに書き換えたコードです。


```swift:impbcopy.swift
import Cocoa

func copy_to_clipboard(_ path: String) -> Bool {
    let image: NSImage?
    if path == "-" {
        let input = FileHandle.standardInput
        image = NSImage(data: try! input.readToEnd()!)
    } else {
        image = NSImage(contentsOfFile: path)
    }
    var copied = false
    if let image {
        let pasteboard = NSPasteboard.general
        pasteboard.clearContents()
        let copiedObjects = [image]
        copied = pasteboard.writeObjects(copiedObjects)
    }
    return copied
}

let main: () -> Bool = {
    guard CommandLine.arguments.count > 1 else {
        print("""
            Usage:\n
            Copy file to clipboard:\n    ./impbcopy path/to/file\n
            Copy stdin to clipboard:\n    cat /path/to/file | ./impbcopy -
            """)
        return false
    }
    
    let path = CommandLine.arguments[1]
    return copy_to_clipboard(path)
}

exit(main() ? EXIT_SUCCESS : EXIT_FAILURE)
```

## ビルド

次のコマンドでビルド（コンパイル&リンカ）します。

```terminal:コンパイル&リンカ
$ swiftc impbcopy.swift -o impbcopy
```

## 使い方

```terminal
$ impbcopy
Usage:

Copy file to clipboard:
    ./impbcopy path/to/file

Copy stdin to clipboard:
    cat /path/to/file | ./impbcopy -

$ impbcopy sample.png

$ cat sample.png | impbcopy -
```

## 環境

執筆時の環境は以下の通り

```terminal
$ uname -a
Darwin Mac-mini.local 23.4.0 Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:06 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T8103 arm64

$ swiftc --version
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
```

### 以上です

<br><br><br><hr>

### 追伸

:::note
[`ユニバーサルクリップボード`](https://support.apple.com/ja-jp/102430)の機能で、Mac ⬄ iPhone 間で自由にコピペできるのは、ホント便利ですね。
:::
HTML: select要素のvalueがすり替わる話

常識から非常識までselect要素を使った情報取得について紹介します。
## value==単調増加の数値
```html
<select id=s><option value=1>paq<option value=2>cmix<option value=3>nncp</select>
<input id=i>
<script>s.onchange=()=>i.value=s.value</script>
```
このような場合`value`属性を設定するまでもありません。`value=数値`の部分を全て排除して`selectedIndex+1`を参照すれば事足ります。
```html
<select id=s><option>paq<option>cmix<option>nncp</select>
<script>s.onchange=()=>i.value=s.selectedIndex+1</script>
```
## value==optionの文字列
```html
<select id=s><option value=huffman>huffman<option value=jones>jones<option value=polar>polar</select>
<input id=i>
<script>s.onchange=()=>i.value=s.value</script>
```
`value=文字列`の部分を全て排除して`options[...].text`を参照すれば事足ります。
```html
<select id=s><option>huffman<option>jones<option>polar</select>
<input id=i>
<script>s.onchange=()=>i.value=s.options[s.selectedIndex].text</script>
```
## text or value?
option要素に`value`が設定されていない場合、`value`を参照すると`text`の値が返される模様。
`value=""`だと`text`の値を無視して空文字列が返されます。
逆に`value`が設定されていて`text`がスッカラカンの場合は、`value`は設定値通り取得され、`text`を参照すると空文字が返されます。
```html
<select id=s><option>lzw<option value=bwt><option value="">ppm</select><br>
<script>
for(let t of s.options)document.write(t.text," (",t.value,")<br>")
</script>
```
## sizeがoption数がより大きい
```html
<select id=s size=4><option>la+<option>demon</select><br>
<script>
for(let t of s.options)document.write(t.text," (",t.value,")<br>")
</script>
```
option数を超えて参照される訳がありません。本当です。何でもしないので信じて下さい。
## optionがcssで非表示
```html
<style>option{display:none}</style>
<select id=s><option>null<option>obfuscate<option>minify</select><br>
<script>
for(let t of s.options)document.write(t.text," (",t.value,")<br>")
</script>
```
先頭のoptionだけ表示されます。こんな事する意味あるんでしょうか…。JavaScriptでは全option参照できるのは言うまでもありません。
## 実験環境
窓s10 偶狂苦労夢122.0.6261.129
SwitchBot API を使い iPhoneショートカットでスイッチ操作

SwotchBotのアプリでやればいいんですが、たくさん登録してると単純操作が面倒なので、ショートカット化してみました。
アプリを入れてるなら、アプリをショートカットで動かせばいいんですが、アプリを入れてない家族のiPhoneにも入れたかったので、せっかくなのでAPIを使ってみました。

## ショートカットの設計
今回登録する機器は、照明なんですが、スイッチを1回押すと電気が付き、もう１回押すと、茶色になり、もう1回押すと消える、みたいな順番で状態が変わる照明です。

メニューを出して、下記の3つから選ぶようにしました。「何もしない」があるのは間違えたときの逃げ道（キャンセル）です。
* 何もしない
* ON/OFF（2回押し）
* ON/OFF（1回押し）

## SwitchBot API
下記が公式サイトです。
最新はV1.1なんですが、簡単なV1.0にしました。
https://github.com/OpenWonderLabs/SwitchBotAPI/blob/main/README-v1.0.md

## トークンの取得
いろんなサイトで記事になっていますが、トークンは、下記な感じで取得します。
1. アプリを開く
2. プロフィールタップする
3. 設定をタップする
4. アプリバージョンを10回タップする
5. 「開発者向けオプション」は表示されるので、タップする
6. 「トークンを取得」をタップする
7. トークンが2行表示されるので上段のトークンをコピーする　→自分はメモに貼っておきました
 
## デバイスの確認
```
GET https://api.switch-bot.com/v1.0/devices
```
で登録されているデバイスが取得できるようです。
自分は、Macなので、ターミナルから、下記コマンドで取得しました。

```
curl -X GET -H "Authorization:トークン文字列" https://api.switch-bot.com/v1.0/devices
```

いっぱいでてきます。（改行したり、マスクしたり、削除したり、とか加工してます・・）
```
{
"statusCode":100,
"body":{
"deviceList":[
{"deviceId":"hogehoge","deviceName":"Hub Mini Main","deviceType":"Hub Mini","hubDeviceId":"000000000000"},
{"deviceId":"hogehoge","deviceName":"Hub Mini Sub","deviceType":"Hub Mini","hubDeviceId":"000000000000"}
],
"infraredRemoteList":[
{"deviceId":"テレビのデバイスID","deviceName":"テレビ","remoteType":"TV","hubDeviceId":"hogehoge"},
{"deviceId":"部屋のデバイスID","deviceName":"部屋","remoteType":"DIY Light","hubDeviceId":"hogehoge"},
・・・
・・・
・・・
{"deviceId":"ライトのデバイスID","deviceName":"ライト","remoteType":"DIY Light","hubDeviceId":"hogehoge"}]},
"message":"success"
}
```

今回は、「ライト」を使うので、「ライトのデバイスID」を、メモります。

## ターミナルで実験
一度試します。
デバイスの制御は下記です。
```
POST /v1.0/devices/{deviceId}/commands
```

```
curl --request POST 'https://api.switch-bot.com/v1.0/devices/ライトのデバイスID/commands'  --header 'Authorization:トークン文字列' --header 'Content-Type: application/json; charset=utf8' --data-raw '{ "command": "turnOn", "parameter": "default", "commandType": "command" }'
```

動きました！
やったー！

## ショートカットの作成

では、いよいとショートカットを作ります。
ショートカットの使い方は、ここでは書きませんので、わかってる前提で…
（簡単ですが…）

こんな感じにしています　↓↓↓
![IMG_9309.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186659/abfd1758-33b0-079c-2699-2451431f9c06.png)

写真とるときに、ヘッダー部分の展開を忘れましたが、そこには、下記が入っています。
```
Authorization　　　トークン文字列
```

## 完成
めでたしめでたし
Pillow で画像の外にはみ出た切り取り (crop)

タイトルにある通りのことをしたかった。
単純に はみ出し `crop` すると背景は黒くなるので、これを白くする。
簡単にまとめると、`Image.new` に `paste` した後 `crop` した。

# Pillow で単純な crop をすると黒背景になる

[Pillow](https://pypi.org/project/pillow/) では次のように `crop` できる。

[PIL.Image.Image.crop - documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.crop)
```python
from PIL import Image

img = Image.open("lena.jpg") # 512 x 512

width = 512
height = 512

left = 256
top = 256
right = left + width
bottom =  top + height

rect = (left, top, right, bottom)

img = img.crop(rect)
img.save("lena_crop.jpg")
```
<img width="300" alt="lena.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704971/0109778c-616b-ec82-a6bd-b7dfd58b707d.jpeg">
<img width="300" alt="lena_crop.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704971/b5b0231c-cdb1-e612-347a-a3cc5ba875db.jpeg">

はみ出した背景は黒で埋められる。

# crop の背景を白で埋める

次のように `Image.new` で白背景の画像を作り `paste` してから `crop` する。
```python
from PIL import Image

img = Image.open("lena.jpg") # 512 x 512, RGB

width = 512
height = 512

left = 256
top = 256
right = left + width
bottom =  top + height

rect = (left, top, right, bottom)

img_old = img

# 背景色は白(0xFF)
bgcolor = 255

# ( 幅 , 高さ ) = ( left + width ,  left + width ) の大きい画像を作る
img = Image.new(img_old.mode,(left+width,left+width),(bgcolor,bgcolor,bgcolor))

# 大きい画像の 左上 (0,0) に貼り付け
img.paste(img_old,(0,0))

img = img.crop(rect)
img.save("lena_crop.jpg")
```

<img width="300" alt="lena.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704971/0109778c-616b-ec82-a6bd-b7dfd58b707d.jpeg">
<img width="300" alt="lena_crop.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704971/cfadff64-0735-3080-b207-8f3a660293cf.jpeg">

このように、はみ出した背景を白くできた。

# 注意点

今回使った画像は `mode` が `"RGB"` なので、
```python
img = Image.new(img_old.mode,(left+width,top+height),bgcolor)
```
のように単純に `int` を渡すと赤 ( RGB の R ) とみなされ、背景が赤くなる。

<img width="300" alt="lena_crop.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704971/d7fd4f62-088b-4a1e-9354-1d5514881c78.jpeg">

逆に、グレースケール (`mode`が`"L"`) の画像に `(255,255,255)` と色指定すると次のようなエラーが出る。
```
TypeError: color must be int or single-element tuple
```
途中で `img_old = img_old.convert("L")` のような変換をしていた場合は `int` を渡す。 

場合分けを書く場合は、以下のページなどを見ながら書くと良いと思う。

[Concepts - Pillow documentation](https://pillow.readthedocs.io/en/stable/handbook/concepts.html)

より良い方法が見つかれば追記する。

# 参考サイト

- [pillow 公式ページ](https://pypi.org/project/pillow/)
- [PIL.Image.Image.crop - documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.crop)
- [Concepts - Pillow documentation](https://pillow.readthedocs.io/en/stable/handbook/concepts.html)
TeX Live 2024 にアプデした (Windows)

TeX Live 2024 をインストールしました。
念の為、備忘録として残しておきます。環境は Windows と WSL Ubuntu です。

# 要約

[TeX Live のページ](https://www.tug.org/texlive/) に諸々書いています。手順に沿ってインストールしてください。
[[初心者]LaTeXのインストールから使い方までこれ一本！](https://qiita.com/alpaca-honke/items/f30a2d04eedaa3c36a21)も参考になります。

# Windows の場合

[TeX Live on Windows](https://www.tug.org/texlive/windows.html) にある `install-tl-windows.exe` をダウンロードして実行するだけです。

[Windows によってPCが保護されました] と表示されますが、まあ信頼できるソフトなので、詳細設定から実行します。

設定などは変更せず全部そのままで進めました。4700くらいパッケージがあるので気長に待ちます。私の環境では2時間ほどで終わりました。

Pathの設定も勝手にされていました。これで完了です。

**TeX Live 2023 のアンインストール** はスタートメニューの中の `Uninstall TeX Live` というショートカット、もしくは、そのリンク先 `C:\texlive\2023\tlpkg\installer\uninst.bat` を実行すると良さそうです。Pathも勝手に消えます。

あと、よくわかりませんが、Powershell で `tlmgr update --self --all` すると、
```
Locale 'Japanese_Japan.932' is unsupported, and may crash the interpreter.
```
と表示されるようになりました。update はできるみたいですし、GUI の方をよく使うのであまり気にしてません。

# Ubuntu (WSL) の場合

[TeX Live - Quick install for Unix](https://www.tug.org/texlive/quickinstall.html) にある作業をしていきます。
```
cd /tmp
wget https://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
zcat < install-tl-unx.tar.gz | tar xf -
cd install-tl-何かの日付
sudo perl ./install-tl -no-gui
```
長い質問をされますが `I` で大丈夫です。重いのが嫌なら `S` で scheme を full から他のものに変更してください。

公式ページだと `perl ./install-tl --no-interaction` でしたが、`tlmgr`がうまく入らなかったのでオプション消しました。`-no-gui` つけてます。なくても良いと思います。

あとは、Pathを通しておきます。`.bashrc` に次を追加します。
すでに2023のPathの設定がある場合は `3` を `4` にするだけです。
```
PATH=/usr/local/texlive/2024/bin/x86_64-linux:$PATH
```
ついでに、`sudo tlmgr`が動かなくて困ったので、次のように、`tlmgr` で root の Path にも追加しました。
```
sudo /usr/local/texlive/2024/bin/x86_64-linux/tlmgr path add
```

要らなくなった TeX Live 2023 については、`rm`で消して良いそうなので、次を実行して消します。残す場合は実行しないでください。
```
sudo rm -rf /usr/local/texlive/2023
rm -rf ~/.texlive2023
```

インストール用のファイルも要らなければ
```
rm -rf /tmp/install-tl-*
```
で消します。以上です。

# 参考サイト

- [TeX Live](https://www.tug.org/texlive/)
- [[初心者]LaTeXのインストールから使い方までこれ一本！](https://qiita.com/alpaca-honke/items/f30a2d04eedaa3c36a21)
WSL2上でTauri環境を構築したけれどたまにしかウィンドウを開いてくれない問題

# はじめに

Tauriの開発コマンドを実行すると新たにウィンドウが表示されるはずですが、ごくまれにしかウィンドウを開いてくれないという問題が発生しました。
今回はこの問題の解消方法を紹介します。

# 問題が発生した状況

以下のページを参考に、CargoとpnpmでTauri環境を構築しました。

https://tauri.app/v1/guides/getting-started/setup/next-js

`cargo tauri dev`コマンドを実行した所、無事にウィンドウが表示されました。

しかし2度目以降の実行ではウィンドウが表示されませんでした。
この際、環境構築直後からコードは何も変更していません。

# 問題の原因

ごくまれにウィンドウが開いた際には、以下のような警告が表示されていました。

```bash
$ cargo tauri dev
libEGL warning: failed to open /dev/dri/renderD128: Permission denied
```

# 問題の解消方法

（参考にしたissueはTauriのものではありませんが、）ドライバーのパーミッションを変更してあげれば良さそうです。

> If you have full control (i.e. root privileges) on this machine, it might simply be a matter of correcting the permissions on /dev/dri/renderD129 (usually by adding your user to the group that owns the device).
>
> [*libEGL warning: failed to open /dev/dri/renderD128: Permission denied #214*](https://github.com/google-deepmind/dm_control/issues/214)

```bash
$ ls -l /dev/dri
crw-rw-rw-  1 root render 226, 128  3月 17 12:28 renderD128
$ sudo usermod -aG render <username>
```

WSL2を再起動します。

```posh
wsl.exe --shutdown
```

再起動後、`cargo tauri dev`コマンドを実行することで（現時点では）何度コマンドを実行してもウィンドウが開くようになりました。

# libEGL warning: MESA-LOADER: failed to open vgem

ウィンドウが開くようになりましたが、以下のような警告も表示されるようになりました。

```bash
$ cargo tauri dev
libEGL warning: MESA-LOADER: failed to open vgem: /usr/lib/dri/vgem_dri.so: cannot open shared object file: No such file or directory (search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)
```

こちらのDiscussionを見てみると、WSL2固有の問題の可能性がありそうです。

https://github.com/tauri-apps/tauri/discussions/8648

現時点ではこれによる問題は発生していませんが、対処法が分かり次第、追記します。
android studio PNG画像インポート時のtips

# はじめに
今回はすごい基本的なことである`AndroidStudio`のプロジェクト内に`png`の画像を入れる方法を紹介します
最近はsvgを使用することが多いので中々使わないので最近自分が触って意外と細かい部分で忘れてるのがあったので紹介していきます
### 本文
まず、基本的に使う画像はデザイナさんか`Figma`から受け取ると思うのですが`svg`と違い`png`は各サイズを用意しないといけません。
その時に各サイズをまとめてフォルダでインポートすると思うのですが、`Figma`とかだと画像のファイル名に対して`hogehoge@1x.png`のような設定になってると思いますがそのフォルダをそのままインポートしようとすると[公式](https://developer.android.com/studio/write/resource-manager#automatic-parsing)にもあるように下記の三種類しか対応しません。
* @2
* @3
* @4

そのため、すべての名前を変更して`ldpi`などの指定をしてあげないといけません。
### 最後に
今回は転ばぬ先の杖じゃないですが、今後の備忘録TipsとしてPNG画像インポート時の基本を書いてみました
どなたかのお役に立てれば幸いです
Windowsの環境構築

## はじめに
備忘録
MacユーザーがWindowsを利用する際の環境構築手順

## 手順
1 PowerToysの導入 
2 [入力切り替えをMac風にする](https://ringo-hack.com/mac/windows-mac-keyboard-style/#google_vignette)
3 [Caps LockをControlとして使用する](https://atmarkit.itmedia.co.jp/ait/articles/2007/10/news016.html)
3 [wsl2の導入, Gitの導入, Dockerの導入](https://learn.microsoft.com/ja-jp/windows/wsl/setup/environment#set-up-your-linux-username-and-password)
4 [ビープ音の無効化](https://azukipochette.hatenablog.com/entry/2018/06/20/012641) ※[ファイル変更時はsudoをつけてroot権限で開く](https://gohsan53.hatenablog.com/entry/2020/04/27/234609)
5 [gitHubのSSHの設定](https://i-doctor.sakura.ne.jp/font/?p=48511)


PowerToysは Microsoft製の便利パックでalt + spaceでランチャーアプリが利用可能になる
Macのalfredみたいなもの

## その他参考
把握しておきたいリンク
[ubuntuのリセット](https://qiita.com/PoodleMaster/items/b54db3608c4d343d27c4)
[Windowsのショートカット](https://pc.watch.impress.co.jp/docs/column/tukaikonashijuku/1009039.html)
【UiPath】特定処理日のチェックする方法

# はじめに
ロボ処理要件の中で、特定日で追加処理を行うケースがあります。ロボ内部で直接、ハードコーディングすれば簡単に解決しますが、業務フロー見直し時に特定日が変更になる場合、ロボ内部の修正が必要になります。
今回はConfigファイルに特定日情報を持たせて、ロボ内部で処理有無の分岐を行わせる方法をメモとして残します。

## この記事の対象者
- UiPath初学者
- UiPath Studioを特定日判定する方法を身につけたい方

# 目次
1. 開発環境紹介
1. 処理要件確認
1. 実装
1. 解説

# 開発環境紹介
- OS：Windows11
- 開発ツール：UiPath Studio
- バージョン：2023.10.0
- ライセンス：Community License
- モダン デザイン エクスペリエンス：いいえ
- Microsoft Excel：2310

:::note warn
- 開発環境に関しては、バージョン等が異なっていても問題ございません
- バージョンによっては画面が一部異なる可能性はございます
:::

### UiPath 依存関係
| パッケージ名 | バージョン |
|:--|:--|
| UiPath.Excel.Activities | 2.22.2 |
| UiPath.Mail.Activities | 1.21.1 |
| UiPath.System.Activities | 23.10.2 |
| UiPath.Testing.Activities | 23.10.0 |
| UiPath.UIAutomation.Activities | 23.10.3 |

# 処理要件確認
・特定処理日(01,02,03,04,05,25,26,27,28,29,30,31)の時に追加処理を行えるようにする。
・業務担当者の要望として、月初・月末時に追加の処理を行う。
・業務内容の見直しで特定処理日を変更する可能性がある。

### Config情報
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/6be67549-9cc5-2f14-afa2-c1bc3f895b67.png)

# 実装
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/4c6f1e20-3c1a-3356-426d-291b677e2142.png)

### 実装補足
~~~vb:代入：ロボ実行日(dd)
DateTime.Now.ToString("dd")
~~~

~~~vb:代入：特定処理日
Config("特定処理日").Split(","c)
~~~

### 変数情報
| 名前 | 変数の型 | スコープ | 規定 | 注釈 |
|:--|:--|:--|:--|:--|
| arrSpecificDay | System.String[] | Main Sequence | | 特定処理日 |
| processFlg | Boolean | Main Sequence | | 処理フラグ(True:処理対象日,False:処理対象外) |
| strProcessDay | String | Main Sequence | | ロボ実行日(dd) |

# 解説
処理内容として、Configから日付(dd)情報を取得する。
まとめてチェックを行いたいため、特定の値で区切れるような形式をとる。
※今回のケースの場合、カンマ(",")区切りで設定を行っています。
ロボで処理日(dd)とConfigから取得した特定日付情報をもとにループチェックを行い、条件一致した場合に特定処理できるようにフラグ管理した構築になっております。

【メリット】
* Configファイルを修正することにより簡単に処理条件を変更することが可能となる

【デメリット】
* 業務担当者がConfigファイルを修正する場合、修正方法を誤るケースがある
※業務担当者に理解していただくように説明資料作成または修正フォローを行うことによりデメリット解消を行える

# おわりに
特定処理日で処理方法の分岐は業務要件として発生するケースはあります。実装自体は簡単ですが、保守性も考慮して変更可能性があるデータは極力Configファイルにまとめると良いでしょう。ロボ実行中に特定処理日の条件変更は発生しないため、Configで管理することで、修正が容易になります。今回のメモが誰かの参考になれば幸いです。

# 参考サイト
[【UiPath】配列の操作(List,Dictionary,Array)](https://penrako.com/uipatharraymanipulation/)
1カ月半でCCNP ENARSIを取得した話

CCNP ENARSIを取得したので、学習時間・方法を紹介したいと思います。これからCCNP ENARSIを受験する方に向けて、参考になれば幸いです。

### プロフィール
通信キャリア内SI業務に1年従事、主に省庁・金融・医療系のNW・サーバの設計を担当しております。

### なぜCCNPを受けようと思ったか
CCNAが11月で失効だったので、社内での評価基準にもなるし、インフラエンジニアという職業に箔がつくかなと思い、どうせならプロフェッショナルグレードのCCNP Enterpriseを取得しようと思いました。

### 試験結果
まず、私の試験結果については以下の通りとなります。
| Section | Percent |
|:-----------|------------:|
| VPN Technology       | 100%        |
| infrastructure Security     | 100%      |
| infrastructure Service     | 87%      |
| Layer 3 Technology       | 71%       |

### 勉強方法
#### 1.学習期間
学習期間は約1カ月半。年度末という忙しい時期でしたが、通勤時間や休憩時間や帰宅後の時間で毎日合計３時間ほど学習しました。土日は1日中引きこもって学習していました。

#### 2.学習方法
##### 開始～2週間目
VPN周りは業務でよく扱っており、動的ルーティングプロトコルに関しても基礎的な部分は抑えていたので、教本等のインプットはせずに、Ping-tを1週しました。わからないことはCCNPイージス・Cisco公式ドキュメントを調べ、なぜ他の選択肢が間違っているのか理解できるまで調べました。

https://www.infraexpert.com/info/ccnpz00.html

##### 3週間~4週間目
シミュレーション問題で何が出題されるかを調べ、実機にて設定し、動作を確認できるまでトラブルシューティング

##### 4週間目~5週目
模擬問題を2,3週

##### 試験前まで
シミュレーション問題の模擬構築

### 試験時のポイント
シミュレーション問題が出題されます。ただ、バグなのか確認コマンドを打つと「ネイバーが表示されない、けど、対向機器でコマンドを打つとネイバーが確認できる」という、バグっぽい現象が多々起こっていたので、必ずPingやtracerouteを打って然るべきところに疎通できるか、疎通すべきでないところ、到達不能か確認しましょう。あと、設定はちゃんと保存しましょう(私はシミュレーションで1問保存し忘れました笑)

### 最後に
ENARSIは基礎を理解して、各機能の関係性が理解できていれば受かる資格です！
ある程度勉強して、受かる兆しが見えてきたら試験をスケジュールして、追い込みかけましょう！これから受験する皆様のご健闘を祈っております！！！
【Windows】最近使うショートカットキー　メモ

はじめまして。

最近、よく使うショートカットキーについて備忘録的に書きます。

## 共通
#### Winキー
これを押すと検索バーが表示されるので、アプリ名などを入力するとダイレクトにアプリを起動することが可能。

フォルダーも開けます。
「フォルダー：フォルダ名」で検索できるので、「フォルダー：」を単語登録。

#### Ctrl + W
現在アクティブのタブを閉じることが可能です。
ブラウザや一部エディタで使用可能。

#### Ctrl + Tab
タブを右に移動
ブラウザや一部エディタで使用可能。

#### Ctrl + Shift + Tab
タブを左に移動
ブラウザや一部エディタで使用可能。

#### Shift + F10
右クリックと同様の機能

#### アプリケーションキー
右クリックと同様の機能

#### Winキー + E
エクスプローラー起動

#### Winキー + D
ブラウザやアプリを最小化しデスクトップを表示

#### Winキー + L
画面をロック

#### Winキー + T
画面下のタスクバーにフォーカス

#### Winキー +　Shift + S
スクリーンショット

#### Alt + Tab
開いているアプリやブラウザなどのウィンドウを切り替える。
右方向に切り替え。

#### Alt + Shift + Tab
Alt + Tab同様の機能。
左方向に切り替え。

## エクスプローラー操作

#### Ctrl + Shift + Tab
エクスプローラー上での操作。
左側のナビゲーションウィンドウにフォーカス

#### F6
フォーカスを外す

#### フォルダやファイル名の頭文字(アルファベットのみ)
フォルダ名などがアルファベットの場合、頭文字のキーを入力すると、そのフォルダにフォーカスします。
例：フォルダ名「work」なら「w」を入力。

## ブラウザ上操作
#### Alt + Shift + B
ブラウザ上。
お気に入りバーにフォーカス

#### F6
フォーカスを外す

#### Ctrl + W
現在アクティブのタブを閉じることが可能です。
ブラウザや一部エディタで使用可能。

#### Ctrl + Tab
タブを右に移動
ブラウザや一部エディタで使用可能。

#### Ctrl + Shift + Tab
タブを左に移動
ブラウザや一部エディタで使用可能。
Python loggingモジュール使用方法

# コンソール出力
```python:コード
import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

logging.debug('これはデバッグメッセージです')
logging.info('これは情報メッセージです')
logging.warning('これは警告メッセージです')
logging.error('これはエラーメッセージです')
logging.critical('これは致命的なエラーメッセージです')
```
```:出力
2024-03-17 18:09:55,797 - DEBUG - これはデバッグメッセージです
2024-03-17 18:09:55,797 - INFO - これは情報メッセージです
2024-03-17 18:09:55,797 - WARNING - これは警告メッセージです
2024-03-17 18:09:55,797 - ERROR - これはエラーメッセージです
2024-03-17 18:09:55,797 - CRITICAL - これは致命的なエラーメッセージです
```
Pythonスクリプトを書いた際に変数の確認にprintで確認するとコードが長い場合、どの部分のprintか分からなくなるので、loggingモジュールでlinenoオプションを使用して行数を表示するとコードのデバッグ時に便利
```python:コード（linenoオプションを追加）
import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(lineno)d - %(message)s')

logging.debug('これはデバッグメッセージです')
logging.info('これは情報メッセージです')
logging.warning('これは警告メッセージです')
logging.error('これはエラーメッセージです')
logging.critical('これは致命的なエラーメッセージです')
```
```:出力
2024-03-17 18:10:16,004 - DEBUG - 5 - これはデバッグメッセージです
2024-03-17 18:10:16,004 - INFO - 6 - これは情報メッセージです
2024-03-17 18:10:16,004 - WARNING - 7 - これは警告メッセージです
2024-03-17 18:10:16,004 - ERROR - 8 - これはエラーメッセージです
2024-03-17 18:10:16,004 - CRITICAL - 9 - これは致命的なエラーメッセージです
```

メッセージの出力が不要になった場合、**basicConfig**の**level**を変更すればそのレベル以下のメッセージは表示されなくなる。
```python:コード（level=logging.CRITICALnに変更）
import logging

logging.basicConfig(level=logging.CRITICAL, format='%(asctime)s - %(levelname)s - %(lineno)d - %(message)s')

logging.debug('これはデバッグメッセージです')
logging.info('これは情報メッセージです')
logging.warning('これは警告メッセージです')
logging.error('これはエラーメッセージです')
logging.critical('これは致命的なエラーメッセージです')
```
```:出力
2024-03-17 18:10:39,807 - CRITICAL - 9 - これは致命的なエラーメッセージです
```
# ログファイル出力
メッセージをログファイルに出力したい場合は、**filename**を指定する
※コンソールには出力されない
```python:コード（ファイル出力）
import logging

logging.basicConfig(level=logging.CRITICAL, format='%(asctime)s - %(levelname)s - %(lineno)d - %(message)s', filename='debug.log')

logging.debug('これはデバッグメッセージです')
logging.info('これは情報メッセージです')
logging.warning('これは警告メッセージです')
logging.error('これはエラーメッセージです')
logging.critical('これは致命的なエラーメッセージです')
```
```:出力
なし
```
# コンソールとログファイルの両方に出力
ロガーにハンドラーを追加する
```python:コード（コンソールとログファイルの両方に出力）
import logging

logging.basicConfig(level=logging.CRITICAL, format='%(asctime)s - %(levelname)s - %(lineno)d - %(message)s', filename='debug.log')

# コンソールハンドラーの作成
console_handler = logging.StreamHandler()

# フォーマッターの設定
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(lineno)d - %(message)s')
console_handler.setFormatter(formatter)

# ロガーにハンドラーを追加
logging.getLogger().addHandler(console_handler)

logging.debug('これはデバッグメッセージです')
logging.info('これは情報メッセージです')
logging.warning('これは警告メッセージです')
logging.error('これはエラーメッセージです')
logging.critical('これは致命的なエラーメッセージです')
```
```:出力
2024-03-17 18:44:01,973 - CRITICAL - 19 - これは致命的なエラーメッセージです
```
NVIDIA H100 (80GB VRAM)を使ってBeautiful Soup + Google's gemma-2b LLMで実験してみた。

<iframe width="560" height="315" src="https://www.youtube.com/embed/tay89wjZv_Y?si=vuJAOqKakQ8i6dUe" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
先日、NVIDIAのH100を使うことができたので、BeautifulSoupとGoogleのgemma-2b LLM (Gemma)を使って実験をしてみました。

スペックはと言うと、80GBのVRAM（H100)と200GBのRAM。BeautifulSoupでサイトを取ってきて、Gemma 2bで推論させました。

これからのプランはと言うと、このような割と軽量なLLMで推論をさせて、ウェブクローラー(BeautifulSoup)を制御させようと思うのです。

このサンプルでは、面白いキーワードを出力するうようにとプロンプトに入れています。

株式会社インスパイアサーチではLLM＋ウェブクローラーや各種検索サービスのコンサルティングや開発支援をしていますので、何かありましたら、お気軽にご相談ください。

https://www.inspiresearch.io
【HTB Cyber Apocalypse 2024】:Misc -Character-Writeup

# 問題概要

>Security through Induced Boredom is a personal favourite approach of mine. Not as exciting as something like The Fray, but I love making it as tedious as possible to see my secrets, so you can only get one character at a time!

>退屈を誘うことによるセキュリティは、私の個人的なお気に入りのアプローチです。 The Fray のようなものほどエキサイティングではありませんが、自分の秘密を見るのをできるだけ退屈にするのが好きなので、一度に 1 つのキャラクターしか入手できません。

`netcat`でリクエストを送るとindex番号の文字列が表示される。

```
┌──(kali㉿kali)-[~]
└─$ nc 83.136.253.251 32407
Which character (index) of the flag do you want? Enter an index: 0
Character at Index 0: H
Which character (index) of the flag do you want? Enter an index: 1 
Character at Index 1: T
Which character (index) of the flag do you want? Enter an index: 2
Character at Index 2: B
Which character (index) of the flag do you want? Enter an index: 3
Character at Index 3: {
Which character (index) of the flag do you want? Enter an index: 4
Character at Index 4: t
Which character (index) of the flag do you want? Enter an index: 5
Character at Index 5: H
Which character (index) of the flag do you want? Enter an index: 
```

# 解法

まずは最大の番号を調べると、`103`まであることが分かった。

```
Which character (index) of the flag do you want? Enter an index: 100
Character at Index 100: g
Which character (index) of the flag do you want? Enter an index: 120
Index out of range!
Which character (index) of the flag do you want? Enter an index: 110
Index out of range!
Which character (index) of the flag do you want? Enter an index: 105
Index out of range!
Which character (index) of the flag do you want? Enter an index: 104
Index out of range!
Which character (index) of the flag do you want? Enter an index: 103
Character at Index 103: }
Which character (index) of the flag do you want? Enter an index: 
```

すべて手作業で行うのは面倒なのでスクリプトを書いた。

```bash
#!/bin/bash

HOST=""
PORT=
response=""

for ((i=0; i<=103; i++)); do
    response="$response$(echo $i | nc -q 1 $HOST $PORT | awk '{print $17}')"
    echo "Sent index: $i"
    sleep 1
done

echo "Finish"
echo "$response"
```

これを実行してフラグゲット。

```
Sent index: 99
Sent index: 100
Sent index: 101
Sent index: 102
Sent index: 103
Finish
HTB{tH15_1s_4_r3aLly_l0nG_fL4g_i_h0p3_f0r_y0Ur_s4k3_tH4t_y0U_sCr1pTEd_tH1s_oR_els3_iT_t0oK_qU1t3_l0ng!!}
```
【HTB Cyber Apocalypse 2024】:Web -TimeKORP-Writeup

# 問題概要

>Are you ready to unravel the mysteries and expose the truth hidden within KROP's digital domain? Join the challenge and prove your prowess in the world of cybersecurity. Remember, time is money, but in this case, the rewards may be far greater than you imagine.

>KROPのデジタル領域に隠された謎を解き明かし、真実を明らかにする準備はできていますか? チャレンジに参加して、サイバーセキュリティの世界で自分の実力を証明してください。 時は金なりであることを覚えておいてください。しかし、この場合、あなたが想像しているよりもはるかに大きな報酬が得られる可能性があります。

サイトを閲覧すると、時間や日付が表示されるサイトになっていることが確認できる。

![first_screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/639fbff8-5da8-381b-c169-1bd92071b2c1.png)

# 解法

ダウンロードされたファイルを確認すると、PHPの`exec`を使用して、引数に渡されたフォーマットで日付を表示していることが分かる。

```TimeController.php
<?php
class TimeController
{
    public function index($router)
    {
        $format = isset($_GET['format']) ? $_GET['format'] : '%H:%M:%S';
        $time = new TimeModel($format);
        return $router->view('index', ['time' => $time->getTime()]);
    }
}
```

```TimeModel.php
<?php
class TimeModel
{
    public function __construct($format)
    {
        $this->command = "date '+" . $format . "' 2>&1";
    }

    public function getTime()
    {
        $time = exec($this->command);
        $res  = isset($time) ? $time : '?';
        return $res;
    }
}
```

`exec`で任意のコマンドが実行できるので、`%Y';cat /flag'`この値をURL Decodeして`format`に渡す。

`?format=%Y%27;cat%20/flag%27`

そうするとPHP側で`date '+Y';cat /flag '' 2>&1`となり、フラグ取得が可能。

![flag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/3510b8a4-0ac2-f844-1417-527cc40b990f.png)
【HTB Cyber Apocalypse 2024】:Web -Flag Command-Writeup

# 問題概要

>Embark on the "Dimensional Escape Quest" where you wake up in a mysterious forest maze that's not quite of this world. Navigate singing squirrels, mischievous nymphs, and grumpy wizards in a whimsical labyrinth that may lead to otherworldly surprises. Will you conquer the enchanted maze or find yourself lost in a different dimension of magical challenges? The journey unfolds in this mystical escape!

>「次元脱出クエスト」に乗り出し、目覚めるとそこはこの世のものではない神秘的な森の迷路です。 歌うリス、いたずら好きなニンフ、不機嫌そうな魔法使いたちとともに、別世界のような驚きにつながるかもしれない風変わりな迷宮を進んでください。 魔法の迷路を征服しますか、それとも別の次元の魔法の挑戦に迷い込んでしまいますか? 旅はこの神秘的な逃避行の中で展開します！

サイトにアクセスすると4択のミニゲームが用意されています。

![FlAG_COMMAND_START.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/c76e1726-152a-0dfb-5084-4ccc4f1e0ffd.png)

# 解法

Burpで確認すると`/api/options`というエンドポイントが確認できます。

![flag_command_endpoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/06d1b00a-6a7d-5894-f83e-ce164826f168.png)

`secret`キーの文字列を送信するとフラグが表示されます。

![FLAG COMMAND GET FLAG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/eafaa233-df4c-45ee-b5f2-eadbc958f92f.png)
Pleasanterのスクリプトをアップロードするコマンドを作った

## 概要

- Pleasanterの画面スクリプトをアップロードするコマンドを作りました
- [PleasanterのスクリプトをTypeScriptで書きたい](https://qiita.com/yamada28go/items/1dde681e915edacebea1)の続きです
 - TypeScriptとWebPackを駆使した事により、様々なライブラリを組み込んだスクリプトが書けるようになりました
- 生成したスクリプトサイズが大きくなりすぎるとビルドした結果をWeb画面にコピーして貼り付ける事が大変です。(デバッグシンボルを含むと数Mとなるので...。)
- コマンド一発で更新できるようにしました

## 使い方
### 環境

- .Net6環境で動きます。事前に環境を用意してください

### 取得

以下サイトにバイナリがあります。
(使用は自己責任でお願いします。)

[put-pleasanter-script](https://github.com/yamada28go/put-pleasanter-script/tags)

### 実行コマンド

スクリプトの送信は以下コマンドで実行できます。
(windowsの場合、dotnetコマンドを使わずに、put-pleasanter-script.exeでも動きます。)

```
dotnet put-pleasanter-script.dll PutScript <ConfigurationFileName>
```

実行するためには設定ファイルが必用となります。
設定ファイルのひな形は以下コマンドで作成してください。
パラメータの詳細は[Readme.md](https://github.com/yamada28go/put-pleasanter-script/blob/main/Readme.md)を参照してください。

```
dotnet put-pleasanter-script.dll DefaultConfiguration <OutFileName>
```

### 便利な使い方

フロント開発ではnpmを使用すると思います。
`package.json`にコマンドとして登録しておくと便利です。

設定例

```:package.json
{
・・・
  "scripts": {
    "put": "dotnet /*** 展開したパス ***/put-pleasanter-script.dll PutScript put-config.xml"
  },
  ・・・
}
```

送信実行

```
npm run put
```
Terraform覚書き2

## main.tf
- 実行するTerraformのバージョンとプロバイダの指定
- モジュールの設定
```hcl
# ---------------------------------------------
# Terraform configuration
# ---------------------------------------------
terraform {
  required_version = ">=1.7.4"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.61.0"
    }
  }
}

# ---------------------------------------------
# Provider
# ---------------------------------------------
provider "aws" {
  region = var.region
}
# ---------------------------------------------
# modules
# ---------------------------------------------

# network
module "network" {
  source = "./modules/network"

  name      = var.name
  region    = var.region
  vpc_cidr  = var.vpc_cidr
  pub_cidrs = var.public_subnet_cidrs
  pri_cidrs = var.private_subnet_cidrs
}

# ec2
module "ec2" {
  source = "./modules/ec2"

  app_name   = var.name
  vpc_id     = module.network.vpc_id
  subnet_ids = module.network.pub_subnet_ids
}

# rds
module "rds" {
  source = "./modules/rds"

  app_name                  = var.name
  db_name                   = var.db_name
  db_username               = var.db_username
  vpc_id                    = module.network.vpc_id
  subnet_ids                = module.network.pri_subnet_ids
  subnet_cidr_blocks        = module.network.pri_subnet_cidr_blocks
  source_security_group_ids = [module.ec2.ec2_security_group_id]
}

# s3
module "s3" {
  source = "./modules/s3"

  name        = var.name
  identifiers = [module.iam.policy_arn]
}

# IAMrole
module "iam" {
  source = "./modules/iam"
}
```

## terraform.tfvars
- Terraformの実行時に読み込ませたい変数の値を定義するためのファイル
- ファイル名を「terraform.tfvars」としていた場合は、Terraformの実行時に自動的にtfvarsファイルに設定されている変数の値を読み込ませることが出来る
- 認証情報もproviders.tfに直接記述可能が、セキュリティリスクを考慮し環境変数で定義

```hcl
#--------------------------------------------------------------
# General
#--------------------------------------------------------------

name   = "lecture13"
region = "ap-northeast-1"

#--------------------------------------------------------------
# keys
#--------------------------------------------------------------

access_key = "***************"
secret_key = "*******************"

#--------------------------------------------------------------
# Network
#--------------------------------------------------------------

vpc_cidr = "10.0.0.0/16"
public_subnet_cidrs = {
  "a" = "10.0.0.0/24",
  "c" = "10.0.1.0/24"
}
private_subnet_cidrs = {
  "a" = "10.0.2.0/24",
  "c" = "10.0.3.0/24"
}

#--------------------------------------------------------------
# RDS
#--------------------------------------------------------------

db_name     = "lecture13db"
db_username = "admin"
```
## valiable.tf
- 変数情報をmain.tf等から分離するためのテンプレートファイル
- main.tfに記述しても良いが内容が増えるため分割
```hcl
# ---------------------------------------------
# Variables
# ---------------------------------------------
variable "region" {}
variable "name" {}
variable "vpc_cidr" {}
variable "public_subnet_cidrs" { type = map(string) }
variable "private_subnet_cidrs" { type = map(string) }
variable "db_name" {}
variable "db_username" {}
variable "access_key" {}
variable "secret_key" {}
```
ローカル開発用のデータベースをDockerで構成する際のおすすめボイラープレート



こんにちは！学びと成長しくみデザイン研究所の斉藤です。
私は開発環境でDBを使用する際、よくDockerを使用しています。
Dockerを使用するとプロジェクト毎に異なる種類のDBやバージョンを簡単に切り替えることができて便利です。
今回はDocker-Composeの設定ファイルである `compose.yaml` のおすすめボイラープレートをご紹介します。

# おすすめのGitHubリポジトリ

https://github.com/luisaveiro/localhost-databases

- 特徴
    - RDB(MySQL, PostgreSQL, etc..)やNoSQL(redis, DynamoDB, etc..)など、様々な `compose.yaml` がある
    - `compose.yaml` のパスワードやポート番号などが `.env` で変数管理されている


## 試してみる

例としてmysqlのリポジトリを使ってみます。
※ Docker環境の構築に関しては触れません

1. mysqlのディレクトリを開く
    - https://github.com/luisaveiro/localhost-databases/tree/main/databases/mysql
1. `compose.yaml` と `.env.example` をローカルへコピー&ペーストする
1. `.env.example` を `.env` へリネームし、`DB_ROOT_PASSWORD` を `pass` にする
1. 利便性向上のため `compose.yaml` 一部編集
    1. `services` に `adminer` を追加し、DBをブラウザから操作できるようにする
        ```yml
        adminer:
          image: adminer:latest
          container_name: adminer
          ports:
            - 8080:8080
          depends_on:
            - mysql
          networks:
            - local
        ```

    1. デフォルトの認証方式である `caching_sha2_password` だとTLSによる保護がされていない通信はエラーになり、他のホストのSQLクライアントから接続できないため、`mysql_native_password` に変更する
        ```yml
        # Use mysql_native_password instead of caching_sha2_password
        command: "--default-authentication-plugin=mysql_native_password"
        # ↑ コメントアウトされている箇所を有効にすればOK
        ```

1. `docker compose up`
1. ブラウザで `http://localhost:8080` にアクセスして以下のように入力するとDBへアクセスできる

    ※ `サーバ` の箇所は `compose.yaml` の `services` 名を入力します
    ![image001](https://raw.githubusercontent.com/SaitoJP/engineer_nootebook/main/images/202403/20240317_001.png)


# さいごに

今回ご紹介したボイラープレートを使うことで、開発環境のセットアップ時間を削減し、様々なDB環境を容易に構築することができます。
ぜひこの機会に活用し、より快適な開発環境を実現してみてください。
Chaliceってなに？ ー＞　Lambda関数をお手軽に作れるライブラリ

## イントロダクション

このブログでは、AWSのChaliceを使用してPythonサーバレスAPIを作成する方法について詳しく説明します。Chaliceは、AWS Lambda関数の作成やAPI Gatewayの設定など、サーバレスアプリケーションの構築を容易にするPythonフレームワークです。

## Chaliceとは何か？

Chaliceは、AWSが提供するPython用のマイクロフレームワークで、サーバーレスアプリケーションを簡単に作成できます。Chaliceを使用すると、AWS Lambda関数の作成やAPI Gatewayの設定などが簡単に行えます。また、Chaliceは、Pythonのデコレータを使用してルーティングを設定するなど、Pythonらしい書き方が可能なため、Python開発者にとってはとても使いやすいツールです。

[Documentation — AWS Chalice](https://aws.github.io/chalice/)

## ChaliceでのPythonサーバレスAPIの作成

ChaliceはCLI（Command Line Interface）を提供しており、このCLIを使用して新しいプロジェクトを作成したり、既存のプロジェクトをデプロイしたりすることができます。新しいプロジェクトを作成するには、`chalice new-project`コマンドを使用し、プロジェクトをデプロイするには`chalice deploy`コマンドを使用します。これらのコマンドは、AWSの他のサービスと同様にAWS CLIを通じて実行され、開発者はAPIのエンドポイントやLambda関数の設定を容易に行うことができます。

## Chaliceのメリットとデメリット

ChaliceはPython開発者がサーバーレスアプリケーションを素早く作成するための便利なツールですが、一方でいくつかの制限もあります。例えば、ChaliceはPython 3.6以上でしか動作しないという制限があります。また、ChaliceはAWS環境でしか動作しないため、他のクラウドプロバイダでの使用はできません。しかし、その一方で、AWSの豊富なサービスとの統合や、サーバーレスアプリケーションのデプロイを容易にするといった強力な機能を備えているため、これらの制限は大きな欠点とは言えません。

## 結論

Chaliceは、Python開発者がAWS上でサーバーレスAPIを簡単に作成できる強力なツールです。いくつかの制限がありますが、それらはその便利さとパワフルさに比べれば小さなものです。PythonとAWSを活用してサーバーレスアプリケーションを開発するなら、Chaliceは絶対に試してみるべきツールです。
技術雑誌が減ってしまった

# はじめに
近年、技術雑誌が次々廃刊になっているのを憂いている私が、昔はよく購入していた技術雑誌を挙げて行こうと思います。

## Linux、Unix編
・日経Linux
・Linux World
・UNIX Magazine
・BSD magazine

等あり、インフラエンジニアには重宝されていました。全て廃刊になって寂しいですね。

## 開発系
・JAVA WORLD
・Web DB Press
・C Magazine
・マイコンBASICマガジン
・Visual Basic Magazine

今では日経ソフトウエアとSoftware Magazineだけになりました。

## DB系
DB Magazine

一番読んでいた雑誌。休刊になった時は悲しかったですね。

## 現在も継続して出版されている雑誌
・日経ソフトウエア
・Software Design
・Interface


# 最後に
電子書籍の時代になってしまったということなんですね。