OmniAICreator/Qiita-1.07M huggingface dataset:
Vue.js v-on ボタンのクリックで処理を実行する

## やること

v-onディレクティブを用いてボタンがクリックされたらダイアログウインドウを表示するようにする。

## 準備

下記の内容を任意のhtmlファイルに記載して保存します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">

        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {

                }
            },
        })
    </script>
</body>
</html>
```

## 方法

まずはscript要素内で「buttonClicked」メソッド（オプションAPI）を定義します。

```html
<script>
    let app = new Vue({
        el: '#app',
        data(){
            return {
            }
        },
        methods: {
            buttonClicked(){
                window.alert('クリックしましたね')
            }
        }
    })
</script>
```

div要素内を下記のように記載してv-onディレクティブで先程定義した「buttonClicked」メソッドを呼び出します。

```html
<div id="app">
    <button v-on:click="buttonClicked">クリック</button>
</div>
```

ファイル全体は下記の様になっています。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">
            <button v-on:click="buttonClicked">クリック</button>
        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {
                }
            },
            methods: {
                buttonClicked(){
                    window.alert('クリックしましたね')
                }
            }
        })
    </script>
</body>
</html>
```

コレで準備は完了です！当該のhtmlファイルをブラウザで開くと下記のように「クリック」と書かれたボタンが表示されます。

![Document-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f404e4e2-9eaa-80f3-eb2a-c11194a442ba.png)

このボタンをクリックすると下記の様なダイアログウインドウが開きます。![127_0_0_1_5500_の内容_と_Document.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/16d7afff-deba-0cbc-dfdf-3931875453a9.png)

v-onディレクティブは省略記載に対応しています。div要素内のv-onディレクティブ呼び出し部分を下記のように修正しても同じ動作をします。

```html
<div id="app">
    <button @click="buttonClicked">クリック</button>
</div>
```
[過去記事]Vue.js v-on ページが更新されないようにする

## やること

v-onディレクティブに「prevent修飾子」をつけて処理の後にページが更新されないようにする。

## 準備

下記の内容を任意のhtmlファイルに記載して保存します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">
            <form>
                <button type="submit" @click="buttonClicked">送信（ページ更新あり）</button>
                <br>
                <button type="submit" @click.prevent="buttonClicked">送信（ページ更新なし）</button>
            </form>
        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {
                }
            },
            methods: {
                buttonClicked(){
                    window.alert('test');
                }
            }
        })
    </script>
</body>
</html>
```

コレで準備は環境です！当該のhtmlファイルをブラウザで開いてみると下記の様に２つの送信ボタンが表示されます。

![Document-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/06322c59-3e4d-e77f-6063-ce614c5e48f7.png)

まずは、「送信（ページ更新あり）」をクリックしてみましょう。その後表示されるダイアログの「OK」をクリックした直後、ブラウザのタブが一瞬非表示になって当該のhtmlが再び読み込まれている事がわかります。

![Document-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/73184304-c057-4cfc-f1ff-51b0696b1657.png)

今度は「送信（ページ更新なし）」をクリックしてみましょう。ダイアログの「OK」をクリックした後もページが更新されていないことが分かります。

![Document-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b300544a-dc6f-6d69-3fbf-571a234e8938.png)

## 簡単な解説

２つのボタンの差はv-onディレクティブの呼び出し部分にあります。

動作の後ページ更新を行いたくない場合、v-onディレクティブに「.provent修飾子」を付与すればOKです！
[過去記事]Vue.js v-on メソッドの引数をダイアログで表示する

## やること

メソッドに引数を渡して、その引数をダイアログで表示する。

## 準備

下記の内容を任意のhtmlファイルに記載して保存します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">

        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {

                }
            },
        })
    </script>
</body>
</html>
```

## 方法

まずscript要素内で「buttonClicked」メソッドを定義します。

```html
<script>
    let app = new Vue({
        el: '#app',
        data(){
            return {
            }
        },
        methods: {
            buttonClicked(argument){
                window.alert(argument);
            }
        }
    })
</script>
```

div要素内を下記の様に記載してv-onディレクティブの省略記法でボタンを実装します。

```html
<div id="app">
    <button @click="buttonClicked(1)">クリック</button>
</div>
```

ファイル全体は下記の様になっています。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">
            <button @click="buttonClicked(1)">クリック</button>
        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {
                }
            },
            methods: {
                buttonClicked(argument){
                    window.alert(argument);
                }
            }
        })
    </script>
</body>
</html>
```

コレで準備は完了です！当該のhtmlファイルをブラウザで開き「クリック」ボタンをクリックします。

v-onディレクティブでメソッド呼び出し時に設定している「1」がダイアログに表示されました！

![127_0_0_1_5500_の内容_と_Document-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/eb521a9b-2ada-7a1e-ff02-6c209f27d948.png)
[過去記事]Vue.js v-html 指定された文字列中にhtml要素があったときhtml要素としてふるまう

## やること

v-htmlディレクティブを用いて文字列中のhtml要素をhtml要素としてふるまわせる。

## 準備

下記の内容を任意のhtmlファイルに記載して保存します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">

        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {

                }
            },
        })
    </script>
</body>
</html>
```

## 方法

まずはscript要素内で「str」キーに紐づく「あああ <br> いいい」を定義します。

```html
<script>
    let app = new Vue({
        el: '#app',
        data(){
            return {
                str: 'あああ <br> いいい'
            }
        },
    })
</script>
```

div要素内を下記のように記載してv-htmlディレクティブにてキー「str」を指定して呼び出します。

```html
<div id="app">
    <div v-html="str"></div>
</div>
```

ファイル全体は下記の様になっています。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">
            <div v-html="str"></div>
        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {
                    str: 'あああ <br> いいい'
                }
            },
        })
    </script>
</body>
</html>
```

コレで準備は完了です！当該のhtmlファイルをブラウザで開くと下記のように<br>タグが表示されず改行が行われて表示されています。

![Document-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/2c924640-1f40-c78e-6921-b0b0630b4de2.png)
Jetpack Composeでテキスト入力欄にPrefix, Suffixを入れる

# 本文
主にAndroid開発でKotlinのJetpack Composeで入力欄にprefix, suffixを付ける方法。
たとえば、金額入力欄に
「料金1000円」
と入力させたいときに、ユーザーには数値のみを入力させ、最初の「料金」(prefix)と最後の「円」(suffix)を自動で付加できる。

```FormText.kt
OutlinedTextField(
    visualTransformation = PreSuffixTransformer("料金", "円"),
    label = {
        Text("お会計")
    },
)

class PreSuffixTransformer(val prefix: String = "", val suffix: String = "") : VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {
        val result = AnnotatedString(prefix, spanStyle = SpanStyle(Color.Gray)) + text + AnnotatedString(suffix, spanStyle = SpanStyle(Color.Gray))

        val offsetMapping = object : OffsetMapping {
            override fun originalToTransformed(offset: Int) =
                offset + prefix.length
            override fun transformedToOriginal(offset: Int) =
                if(text.length < offset){ text.length } else { offset }
        }
        return TransformedText(result, offsetMapping)
    }
}
```

# 参考
【Jetpack Compose】TextFieldの表示形式変換機能の活用例5選
https://mixi-developers.mixi.co.jp/compose-textfield-visualtransformation-d17cfd0980ed
Convert any images into full-color Bitmap

#### (1) Open any image with Paint.
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567519/4536a80e-785e-cf23-97a0-e843f43d8fd6.png">

#### (2) Click `File` on menu.
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567519/0f76cb73-afca-4cd8-8545-0de69db96a83.png">

#### (3) Hover on `Save as`, select `BMP pictures`
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567519/09618fda-4bc9-f44d-cf00-2fc3c64c355f.png">


#### (4) In order to save it as full color bitmap, select `24-bit Bitmap` and save it.
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567519/c000c86a-36b5-d4f8-625f-7af8265c763e.png">

#### (5) Now 24-bit Bitmap file is created from png file.
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567519/17a77f5e-7b99-d393-031b-8ff33d3940c2.png">
LLMのマージを試した：中国語モデルに日本語能力を持たせる

先日LLMのマージ（複数のLLMを一つに結合して精度を向上するテクニック）を試してみました。mergekitというフレームワークを使って行いました。

https://github.com/arcee-ai/mergekit

mergekitの使い方はとてもシンプルで、マージしたいモデルと評価指標を設定し、必要なパラメータを調整するだけで、マージがスタートできます。

# 1. 評価指標について
私が使用した評価指標は、現在日本語モデルの評価でよく使われている”elyza-100”と”JGLUE”
です。イメージとしては以下の感じです。（複雑な指示・タスクを含む日本語データです)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/6ea559e7-0b91-882f-c01f-a65f987fe813.png)

# 2. 利用モデル
今回、私は中国語と日本語のモデルのマージを試しました。使用したモデルはqwen-1.5-7bとrinna-7bで、それぞれ選んだ理由もあります。
qwenは現在中国語で最も性能の高いモデルであり、rinnaはqwenをベースに継続学習で開発されたモデルなので、モデルの構成やレイヤーのベクトルサイズなども似ってますので、マージしやすいです。（もし他の日本語モデルを使いたいなら、レイヤー変換のコードを別途作成する必要があります。）

マージ処理はA100上で10時間くらいでできました。（⇩マージ際のスクリーンショット）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/714dac12-43a4-2b29-7c64-b6af6ffd54cc.png)

マージ後のモデルを実際に試してみた感想としては、初級レベルの日本語能力を得る代わりに、その分中国語能力も高から中に低下したように感じました。（モデルサイズが小さいのが原因かもしれません。）

⇩はマージ後のモデルが日本語の質問に対して日本語で回答している例です。デフォルトのqwenなら同じ質問に対して中国語で回答してしまいます）
![屏幕截图 2024-05-08 232001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/06b44f5e-515e-3d9e-7662-136923aa6f99.png)

今度マージ後モデルのベンチマークテストも試してみたいと思います。

参考：

https://blog.ori.co/mergekit-model-merge-for-code-generating-llms

https://note.com/npaka/n/nb9abed7b1ecf

https://blog.arcee.ai/tutorial-tutorial-how-to-get-started-with-evolutionary-model-merging/
10^9以下の値をランダムに生成して、値が素数になるまで操作を繰り返すときTLEしない理由

# はじめに
https://atcoder.jp/contests/abc339/tasks/abc339_f
この問題を解いていて、解説放送のコードで「10^9以下の数字をランダムに求めて、その値が素数となるまで繰り返す」という操作を10回行っていてなぜTLEしないのか疑問に思い、質問して解決したので記事にしたいと思います。

# 内容
まず、10^9以下の素数の個数を求めます。これは「50847534」で、だいたい「5×10^7」なので、5×10^7個とします。
https://2357.aimary.com/total_prime.html

次に、一回の操作で素数が現れる確率を求めます。これは「素数の個数/全体の個数」なので、「(5×10^7)/(10^9)」となります。これを通分すると、「1/20」となります。

「一回の操作で素数が現れる確率」を元に、「一回の操作で素数が現れない確率」を求めます。これは「1-(一回の操作で素数が現れる確率)」なので、1-(1/20)となり=(19/20)です。

ここから100回ランダムに出力する操作を行うとします。そうすると「100回の操作で一度も素数が現れない確率」は
「(19/20)^100」となります。これを計算してみます(wolfram alphaくんにお願いしました)

https://ja.wolframalpha.com/input?i2d=true&i=Power%5BDivide%5B19%2C20%5D%2C100%5D

結果はだいたい「0.005」という値になりました。つまり
「100回の操作で一度も素数が現れない確率」は「0.5%」です。

ここで元々何を求めたかったかというと、「TLEしない理由」だったので、TLEする回数について考えます。TLEするこの操作回数をだいたい10^9回とします(素数判定を毎回するのでもう少し小さくなるはずです)。
となると、「10^9回の操作で一度も素数が現れない確率」となり、上で求めた話を持ってくると、100回の時点で、0.005だったので、10^9回になったらとんでもなく確率が小さくなりそうなのがなんとなくわかると思います。
以上です。

# まとめ
というわけで「10^9以下の値をランダムに生成して、値が素数になるまで操作を繰り返すときTLEしない理由」がわかりました。
ちなみに(0.005)^(10^9)をwolfram alphaくんにお願いするとよくわからない答えになるので(0.005)^(10^5)でお願いすると
1.0009989037986941668162647131933062484993475083057800492... × 10^-230103
という答えが返ってきます。ものすごく小さい確率なのはわかるけどそれ以外のことはよくわからないですね！()

https://ja.wolframalpha.com/input?i2d=true&i=Power%5B%5C%2840%290.005%5C%2841%29%2C100000%5D

質問に答えていただいたsnukeさんに感謝です。土下座しますorz
https://www.youtube.com/live/Cw29uys1JV0?si=0KDavcDEjGA0TvpV&t=11242
光回線なしで自宅ネットワークを構築した話

# 光回線なしで自宅ネットワークを構築した話
自宅にネットワーク環境を構築したいなと思いつつ、我が家は複雑な問題を抱えているので、試行錯誤した結果を残しておきます。もしよければ参考程度にどうぞ。
※もっと良い構成が思いつけば、記事を更新します。




# 我が家の現状
+ 光回線を契約していない（そもそも工事をしていないので引き込み線すらない）
+ 家族全員スマホの無制限プランを契約しているので、光回線が不要
　私は楽天モバイルと契約（4Gと5G Sub6の圏内）
+ でも、プリンターを使うのにネットワーク環境は構築したい
+ ファームウェアアップデートをしたいから、月１でインターネットに接続したい
+ スマホのテザリング機能だと電池を激しく消費するので嫌
+ プリンターのWi-Fi接続先を変更するのも面倒（プリンターに登録できるSSIDは１つ）




# 要件定義
とりあえず、以下ができることを目標としましょう。
+ PCとプリンターをつなげるネットワーク構築（インターネットに常時接続はしない）
+ 光回線を使わない（工事も契約もしない）
+ スマホの電池を食わない
+ プリンターの設定を変えずに済む（つまり、SSID１つで済ませる）
+ てぎるだけお安く（追加購入する機器は必要最小限に）


### 構築イメージ
![スライド1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618162/8ba4e17c-cd19-205f-857d-d86466cd1f77.jpeg)


# とりあえず案を出す
### ①スマホのWi-Fiテザリング／Windowsホットスポット
メリット
+ 手軽でカンタン
+ 追加購入不要

デメリット
+ スマホもPCも電池食う
+ ネットワーク分離機能をOFFにできない（スマホテザリングのみ）
　PCからプリンターへ、印刷やスキャンリクエストが送れない時あり
+ 家族がプリンターを使うためには、私がテザリングを毎回つけないといけない


### ②プリンター内蔵ルーター機能を使う
メリット
+ 説明書通りにやれば簡単に設定できる
+ 追加購入不要

デメリット
+ PCは同時に１つのネットワークにしか繋げないので、「インターネットに接続」と「印刷」を同時にできない。


### ③ルーターを買う＜現状ベスト＞
メリット
+ SSID１つで済む
+ テザリングより細かい設定ができる

デメリット
+ ルーター購入代の出費
+ 光回線ないのにインターネットにどうつなぐか
⇒Android11から「イーサネットテザリング」という新機能
　⇒充電もできるし、これでいいのでは！？







# 最終的なネットワーク構成図
### デフォルト構成
![スライド3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618162/dc11a2c6-91b3-0c37-0fa3-b1648cd4e23a.jpeg)

### アプデ構成（インターネットにつなぎたい時）
![スライド2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618162/af0f5c09-30c3-b05b-ef35-a19923798efb.jpeg)


<details><summary>詳細NW構成図</summary>

![スライド4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618162/18178e84-51f5-2fc5-9bb8-b11ea44271a4.jpeg)

![スライド5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618162/c602b7ac-9145-e910-eded-c2390c42db7e.jpeg)

</details>



# 速度評価
3回測定して、平均値（小数点以下第二位を四捨五入）を取りました。
測定ツール：[Speedtest by Ookla](https://www.speedtest.net/ja)のアプリ版
| 測定環境 | ↓ download(Mbps) | ↑ upload(Mbps) | ping(ms) |
|:-:|:-:|:-:|:-:|
| PC（デフォ構成） | 46.1 | 32.3 | 26.0 |
| PC（アプデ構成） | 88.2 | 31.9 | 26.3 |
| 【参考】スマホ本体 | 219.3 | 38.6 | 32.3 |

~~色々ツッコみたい気がしますが、実測値ですし3回しか計測してないですし...~~


# さいごに・展望
要件を全て満たせているのでニッコニコです。
金額的な面で言うと、ほとんど中古で揃えたので１万円強に収まっています。（ルーター、変換アダプター、LANケーブル１本買いました）
Android11以上であればイーサネットテザリングは使えるようなので、Androidを１台購入して常にインターネット接続できるようにしてもいいですね。ついに我が家にIoTの恩恵が!?とか何とか...夢が膨らみます


# 別添資料

## 接続機器
| 種類 | 製品名・URL |
|:-:|:-:|
| ルーター | [WX3600HP](https://www.aterm.jp/product/atermstation/product/warpstar/wx3600hp/) |
| スマホ | [OPPO A79 5G](https://www.oppo.com/jp/smartphones/series-a/a79-5g/) |
| プリンター | [MFC-J7300CDW](https://www.brother.co.jp/product/printer/inkjet/mfcj7300cdw/index.aspx) |
| プリンター | [DCP-J968N](https://www.brother.co.jp/product/printer/inkjet/dcpj968n/index.aspx) |
| テレビ | [LG OLED65B2PJA](https://www.lg.com/jp/tvs-soundbars/oled/oled65b2pja/) |
| 変換アダプター | [GOPPA GP-CR45H](https://www.iodata.jp/product/goppa/web-meeting/gp-cr45h/) |
| 変換アダプター | [BUFFALO LUA3-U2-ATX](https://www.buffalo.jp/product/detail/lua3-u2-atx.html) |
| LANケーブル | [ナカバヤシ BTKL10FWH](https://www.biccamera.com/bc/item/4049325/) |

## 更新履歴
2024/5/12 初版

## 参考文献

https://qiita.com/satorus_1106/items/788d3388fcade42f875f
Aeonモバイルの格安SIM + Aterm HT100LNで自宅回線の冗長化

あんまり得意分野ではないけれど、作業メモとして記録しておきます。

# Wi-Fi側
現在のPC（Windows11）のネットワークインターフェースはWi-Fi。Wi-Fiルーター経由で光回線に接続されている。
インターフェース名は"vEthernet (External Switch)"、セグメントは192.168.0.0/24。
WSLインストール時にブリッジ接続になっている模様。

```
netsh interface ipv4 set interface "vEthernet (External Switch)" metric=1
netsh interface ipv6 set interface "vEthernet (External Switch)" metric=1
```
Wi-Fi側のメトリック（優先度）を1に。通常はこちらのネットワークを利用する。

```
route add 0.0.0.0 mask 0.0.0.0 192.168.0.1 metric 1
netsh interface ipv6 add route ::/0 "vEthernet (External Switch)" ****::****:****:****:**** metric=1
```
Wi-Fi側の ゲートウェイのメトリック（優先度）を1に。多分、自動で設定済みのはず。

# 有線側

新たに [Aterm HT100LN](https://www.aterm.jp/product/atermstation/product/mobile/ht100ln/) とPCを有線で接続する。
AEONモバイルの格安SIM、データ通信のみで月1078円/5GB。
インターフェース名は"イーサネット"、セグメントは192.168.179.0/24。

```
netsh interface ipv4 set interface "イーサネット" metric=100
netsh interface ipv6 set interface "イーサネット" metric=100
```

有線側のメトリック（優先度）を100に。Wi-Fi側に問題が発生した時のバックアップ。

```
route add 0.0.0.0 mask 0.0.0.0 192.168.179.1 metric 100
netsh interface ipv6 add route ::/0 "イーサネット" ****::****:****:****:**** metric=100
```
有線側のゲートウェイのメトリック（優先度）を100に。この設定が無いと、有線側からインターネットに出て行けない。


これで、回線障害やWi-Fiルーターのハングアップ時にもインターネット接続が維持・・・できるといいな。
Compose改行したテキストとサイズの違うテキストの下部を揃える方法

Compose改行したテキストとサイズの違うテキストの下部を揃える方法です。

実装サンプル画像
![スクリーンショット 2024-05-12 19.24.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/094f0100-da3f-c300-3ed5-f1fadce5d961.png)


```TextSample.kt

@Composable
fun TextSample() {
    Row {
        Text(
            text = "取得",
            modifier = Modifier.alignByBaseline(),
            maxLines = 1,
            fontSize = 20.sp
        )
        Text(
            text = "1000",
            modifier = Modifier.alignByBaseline(),
            maxLines = 1,
            fontSize = 25.sp
        )
        Text(
            text = "テスト\nポイント",
            modifier = Modifier.alignBy(LastBaseline),
            maxLines = 2,
            fontSize = 10.sp
        )
    }
}

```

`alignByBaseline()`を設定するといい感じに揃えてくれます。
改行したテキストには`alignBy(LastBaseline)`を設定するといい感じに揃えてくれます。
javaのクラスを使ってプログラムを書いてみた。

# はじめに
今回はクラスについて自分で勉強したことを活かして作成したプログラムを解説してみようと思います。
解釈が違っている点やアドバイスがあればご教授頂けると幸いです。

# プログラム概要
乗り物を表す親クラス`Vehicle`、バスを表す`Bus`クラス、電車を表す`Train`クラス、タクシーを表す`Taxi`クラスを定義する。`Bus`クラス、`Train`クラス、`Taxi`クラスは`Vehicle`クラスを継承している。また、停車を表す`Stoppable`インターフェースを定義し、`Bus`と`Taxi`にのみ実装する。そして`test.java`ファイルで全クラスの挙動を確かめる。
全クラス、のコードは以下に示す。

# 全プログラムのコード

## Vehicle
```java
public class Vehicle {
    protected int passenger_num;

    public void setPassenger_num(int passenger_num){
        this.passenger_num = passenger_num;
    }

    public int getPassenger_num(){
        return this.passenger_num;
    }

    public void display(){
        System.out.println("乗客数 : " + this.passenger_num);
    }

}
```
`Vehicle`は乗客数を表す`passenger_num`フィールドを持っている。
また、`passenger_num`のgetter、setterである、`getPassenger_num`と`setPassenger_num`メソッドを持っている、そして乗客数を画面に表示する`display`メソッドを持っている。

## Bus
```java
public class Bus extends Vehicle implements Stoppable {
    public Bus(int passenger_num){
        this.passenger_num = passenger_num;
    }
    
    public void stop(){
        System.out.println("停車しました。");
    }
}
```

## Train
```java
public class Train extends Vehicle {
    public Train(int passenger_num){
        this.passenger_num = passenger_num;
    }
}

```

## Taxi
```java
public class Taxi extends Vehicle implements Stoppable {
    public Taxi(int passenger_num){
        this.passenger_num = passenger_num;
    }

    public void stop(){
        System.out.println("停車しました。");
    }

    @Override
    public void display(){
        System.out.println("タクシーの乗客数 : " + this.passenger_num);
    }
}

```
`Bus`、`Train`、`Taxi`は`Vehicle`を継承しており、`Vehicle`が持つフィールド、メソッドを持っている。また、これら3つのクラスはインスタンス化をする際に呼び出されるコンストラクタが定義されており、`int`型の引数`passenger_num`に値を設定して呼び出すことで、インスタンス化と同時に乗客数`passenger_num`が設定できるようになっている。また、`Taxi`のみ`Vehicle`の`display`メソッドをオーバーライドしている。これにより`Taxi`の`display`メソッドを呼び出したときは`Bus`や`Train`のときとは違う挙動をするはずである。

## Stoppable
```java
public interface Stoppable {
    public void stop();
}
```
停車機能を表す`Stoppable`は`Bus`と`Taxi`のみ実装しているインターフェースである。`Stoppable`の中には、停車したことを画面に表示する、`stop`メソッドが定義されている。

## test.java
```java
public class test {
    public static void main(String[] args) {
        Vehicle[] vehicle = new Vehicle[3];
        
        vehicle[0] = new Bus(10);
        vehicle[1] = new Train(11);
        vehicle[2] = new Taxi(2);

        for(int i = 0; i < vehicle.length; i++){
            vehicle[i].display();
        }
        
    }
}
```

`test.java`で上記のクラスを使っている。まず、`Vehicle`クラスの配列`vehicle`を定義し、それぞれの要素に`Bus`、`Train`、`Taxi`クラスのインスタンスを格納している。(親クラスのインスタンスに子クラスのインスタンスを代入することをアップキャストというらしい。)またインスタンス化する際に、コンストラクタに`int`型の引数を設定することにより、乗客数を設定している。
そして`for`文による繰り返し処理で`Bus`、`Train`、`Taxi`の`display`メソッドを呼び出している。
実行結果を以下に示す。

```
乗客数 : 10
乗客数 : 11
タクシーの乗客数 : 2
```

上記の実行結果により、コンストラクタで値が設定できていることがわかる。
また、オーバーライドした`Taxi`の`display`メソッドのみ他の2つとは挙動が違う。

# 終わりに
最後まで見て頂き、ありがとうございます。
この春からエンジニアとして仕事をすることになったのでその勉強のアウトプットとして定期的にQiitaに投稿しようと思います。
アドバイス等ありましたら、ご教授して頂けると幸いです。
Azure AI Servicesの翻訳機能を使ってみました

## はじめに
近年、クラウドと同じくらい、AIに関する利用が加速し始めているかと思います。ニュースでも何かとAIの話題が持ちきりですよね。
私がこれまで最新技術の習得に興味をもって取り組んできたエリアはAWS、Azure、Google Cloudに代表されるパブリック・クラウドがメインでしたが、昨今のAIの流れに取り残されることのないよう、先月あたりから個人的にAIのスタディーを始めました。
今回は、最初の取り組みとして、AzureのAI Servicesの1つである、翻訳機能(Translator)を使ってみましたので、これに関する使用体験をご紹介します。

## Azure AI Services
### 概要
Azure AI Servicesは、機械学習の専門的なスキルを必要とすること無く、Azure側で事前に構築されているAPI等のサービスを利用して、開発者がAIアプリケーションを迅速に開発できるように役立つサービスとなっています。

https://learn.microsoft.com/ja-jp/azure/ai-services/what-are-ai-services

Azureポータルにおける、Azure AI Servicesの画面イメージは下記の通りです。
![q1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/c7ddceb6-384c-77ae-33b4-5c543d220389.jpeg)

使用できるサービスは上記画面で表示されているものだけではないですが、今回はその中から翻訳サービス(赤枠箇所)を使用してみました。

### 翻訳サービスのセットアップ
先ほどの画面の赤枠箇所にて、「＋作成」ボタンを押下します。詳細な手順は割愛しますが、基本的に以下のリソース作成を行います。
* リソース・グループ
* Azure AIサービスを使用するためのインスタンス
  * インスタンスを配置するリージョン、インスタンス名、価格レベルを指定
  ※お試しですので、価格レベルは無料タイプの物を指定しました。
  
セットアップ完了後の画面イメージです。 
![q2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/d124fd7d-8bdf-a5b4-d053-aaa84b6cddfb.jpeg)

![q3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/ecbc0495-df86-2677-ea31-cb1f42cb23ff.jpeg)

翻訳したい言語を「始点」と「宛先」それぞれにおいて、プルダウンメニューから選択します。今回は日本語を英訳してみることにしましたので、「始点」に日本語、「宛先」に英語をそれぞれ選択します。

## 翻訳サービスの使用
後は、「始点」の下にある空白欄に日本語の文章を書くだけです。試しに下記のような文章を書いてみました。

～～翻訳元の文章～～
私は先月あたりからAzure AI Servicesのスタディーを始めました。今回はお試しに翻訳機能を使用してみましたが、今後も音声サービスなど様々な機能を試してみたいと思います。

～～英訳結果～～
I started studying Azure AI Services in the last month or so. This time, I tried using the translation function as a trial, but I would like to try various functions such as voice services in the future.

![q4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/0a4fd085-37d3-1cc5-a771-79b364feceb3.jpeg)

なかなか、いい感じで英訳できており、英作文にも苦労しなくなるかと思います。勿論、英語だけでなくドイツ語やフランス語、スペイン語など様々な翻訳が可能です。日本人にはありがたい限りです。

なお、サンプルコードもC#、Java、Node.js、Pythonの4つの言語において提供されています。
![q5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/56957b30-ae13-fb5d-fdac-d3c14c288db0.jpeg)


## Azure AI 翻訳機能の使用が見込めるユースケース
個人的には下記のようなケースで当該機能が大活躍するのではと思います。

* PMP受験申請
PMI(Project Management Institute)が実施しているプロジェクト・マネジメント関連の認定試験の事前申請です。

https://www.pmi.org/certifications/project-management-pmp

PMP試験を受験する前には、PMIに受験しても良いか否かの申請を行う必要がありますが、その際の申請文書を英語で記載する必要があります。私は2013年にPMPを取得しましたが、当時は、色々と単語を調べて英作文を書いていましたので、結構申請準備をするだけで疲れました。

今の時代にPMPを受験される方は、こういったAIによる翻訳サービスが充実しており、申請準備も以前ほど時間をかけなくても実施できるようになったのではないかなと思います。

また、PMP申請準備以外にも、英語での応募申請が必要な場面で大活躍するのではと思います。

* 英文メール
英語で質問メールを記載する場面もあるかと思います。短文であれば、わざわざ翻訳機能を使うまでもないかなとは思いますが、長文メールの際には重宝出来るのではと思います。

## さいごに
今回は、AIのスタディーの第1歩として、Azure AI Servicesの翻訳機能のセットアップ、実際に使用してみた使用感を元に、当該機能が活躍しそうなユースケースをご紹介しました。
まだまだAIに関しては超初心者レベルですが、これを機会に様々なAIサービスに触れて、AIスキルを向上させていきたいと思います。
Vue3 Vutify v-selectタグで作成したセレクトボックスのタイトルと値をカスタマイズする


::: note warn
記事を作成した際のバージョンは以下の通りです。
- Vue：3.4.27
- Vuetify：3.6.0
:::

## カスタマイズ方法

`items`に加え、`item-title` と `item-value` に、対象オブジェクトのプロパティを関連付ければOKです。

```vuejs
<template>
  <v-container>
    <h3>選択された値: {{ selectedOption }}</h3>
    <v-select
      v-model="selectedOption"
      :items="options"
      :item-title="options.title"
      :item-value="options.value"
      label="選択してください"
    ></v-select>
  </v-container>
</template>

<script setup>
import { ref } from 'vue'

const selectedOption = ref('')
const options = [
  { title: 'オプション 1', value: 'option1' },
  { title: 'オプション 2', value: 'option2' },
  { title: 'オプション 3', value: 'option3' }
]
</script>

```

上記コンポーネントを`<v-app>`タグ内に記述すれば、↓のようにタイトルと値が個別に設定されていることが確認できます。

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764512/5acfe78d-56a3-bace-8caa-1fb9c7704b67.gif)


## 公式リファレンス

↓のページに注意書きが書いてありました。。。

https://vuetifyjs.com/en/components/selects/

↓原文
>When using objects for the items prop, you must associate item-title and item-value with existing properties on your objects. These values are defaulted to title and value and can be changed.

↓機械翻訳
>items propにオブジェクトを使用する場合、item-titleとitem-valueをオブジェクトの既存のプロパティに関連付けなければなりません。これらの値はデフォルトで title と value に設定されており、変更することができます。

`v-select`タグに設定できる他の項目が気になる人は、↓をご覧ください。

https://vuetifyjs.com/en/api/v-select/

## 参考文献

https://vuetifyjs.com/en/components/selects/

https://vuetifyjs.com/en/api/v-select/
プロジェクト管理における効果的なリーダーシップスタイルの選択

## プロジェクト管理におけるリーダーシップスタイルの違い

プロジェクトの成功にはリーダーシップスタイルが重要です。しかし、リーダーシップにはいくつかの異なるスタイルがあり、それぞれがプロジェクトの性質やチームのニーズによって最適な場面が異なります。以下に、最も一般的な三つのスタイルを紹介し、それぞれの特徴と適用シナリオを具体的な例で説明します。

### トランスフォーメーショナルリーダーシップ（変革的リーダーシップ）

このスタイルのリーダーは、まるで良きコーチのように、チームメンバーを励まし、モチベーションを高め、自己超越を促します。彼らはチームに大きなビジョンを示し、そのビジョン達成のために一致団結するよう導きます。

**例**: マラソンのコーチがランナーの可能性を引き出し、最高記録を目指すように励ますようなものです。

### サーバントリーダーシップ（奉仕的リーダーシップ）

サーバントリーダーは、チームメンバーのニーズを自分のニーズよりも優先します。このリーダーシップは、チームメンバーが自身の職務で最高の成果を出せるように、支援やリソースの提供に注力します。

**例**: レストランのシェフが料理人たちが最高の料理を提供できるように、必要な道具や材料を提供するようなものです。

### トランザクショナルリーダーシップ（取引的リーダーシップ）

トランザクショナルリーダーシップは、明確な目標とそれに対する報酬を設定することで、チームを動機づけます。このスタイルは、具体的な成果が求められる状況に最適です。

**例**: 営業マネージャーが売上目標を達成した営業員にボーナスを与えるようなものです。

## 結論

これらのリーダーシップスタイルを理解し、状況に応じて適切に適用することが、プロジェクトリーダーとして成功するための鍵となります。スタイルによってチームの反応や成果が大きく変わるため、プロジェクトの目的とチームのニーズに合わせて選択することが重要です。
DBを作ってみる　♯初心者

## 初心者がDBを作ってみた
###### プロセス
1\. pokeAPIから必要なデータをGet
2\. GetしたデータをDataFrame（元df)に格納
3\. Getしたデータのうち、単純なデータではなく「ネストされた値」を単純データにして、別のDataFrameに格納
4\. 元dfに別のDataFrameのデータをMerge
5\.単純データで構成されたdfをSqliteファイルに変換
###### 参考になったサイト
（作者の方、ありがとうございました。）
https://smart-hint.com/poke-data/pokeapi/#PokeAPI
###### 完成したmokemon_db
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761000/b2d1dba5-45bc-5fbe-d213-9398415b882c.png)
【React×TypeScript】学習歴3カ月でデジタル名刺アプリつくってみた

# はじめに
Reactの学習を始めて3カ月が経過しました。
**アウトプット中心の学習**を行っているのですが、今回はその一環で**デジタル名刺アプリ**を作成しました！

なお、**先月は学習記録アプリを作りました！**

https://qiita.com/AK_React/items/528237d75074712db5b8
# 作成したアプリ
**使用言語**
React、TypeScript

**UI**
Chakura UI

**DB**
Supabase

**テスト**
Jest
React Testing Library

**その他使用した技術**
React Hook Form
Github
Supabase

**実装機能**

・ユーザー検索機能

存在しないIDで検索をかけた場合、エラーメッセージが出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/3095f1b1-2098-0cec-afb2-a6d71f383dac.png)

ユーザー表示画面はこんな感じです。
SNSアイコンを押すと、該当アカウントのページにちゃんと遷移します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/f5812c8a-239c-c4fe-c868-bb98d37629b4.png)

・ユーザー登録機能
　Qiita・Github・X(Twitter)の登録は任意で、それ以外は必須項目です。
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/8468b4e8-7834-5a92-a34d-6465bbd2ff0d.png)

**アプリ作成の背景**
**ひたすらなにかを作って手を動かすことで、知識を定着させていく**という狙いです。
実は、**前回作成した学習記録アプリと、使用している技術と作成の流れはほぼ変わりません。**
なので、環境構築なんかは前回と同じことをすればいいのですが、**何度も同じ工程を繰り返すと、知識が深まりやすく自分の成長にも気づきやすいと思います。**

**デモ**　（デザインは最低限です。。）

![名刺アプリデモ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/155ab8ba-b7d9-5594-5a4c-e74136f30634.gif)

# 作成の流れ
アプリ作成の大まかな流れはこちらです！
前回作成したアプリと流れは変わらないので、**前回との相違点を太字にしました。**

１．環境構築（Vite）
２．CI/CD構築（Github Actions）
**毎朝6:00に昨日分の登録データが消去されるバッチ処理を追加**
３．DBの作成・設定（Supabase）
**これまで1つのテーブルで行っていたが今回は複数テーブルを作成。**
（ユーザー情報・ユーザーのスキル情報・ユーザーIDで前述した2つの情報の紐づけを行う中間テーブル）
４．アプリの機能実装
５．テスト作成（Jest）

# おわりに
ここ最近は気温の変化が激しかったり現場の稼働が高くなった影響で、気持ちが落ち込んだりコンディションが下がったりと、不安定な日々を送っていました。
そんな中でも、**10分だけでもいいから勉強しよう**という思いで着実に積み上げることを意識しています。これからも粘り強く学習をしていきたいです。

# JISOUのメンバー募集中

プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp
Elixirで言語処理100本ノックやってみた！vol.8

こんにちは！
3ヶ月で、Elixir言語で開発できるようになるため、奮闘中のこーへーです！

期間が空きましたが、8つ目の問題をどうにかこうにかクリアできたので、アップしていきたいと思います。

[100本ノックの記事はこちら](https://nlp100.github.io/ja/ch01.html)

### 08. 暗号文Permalink
与えられた文字列の各文字を，以下の仕様で変換する関数cipherを実装せよ

- 英小文字ならば(219 - 文字コード)の文字に置換
- その他の文字はそのまま出力
この関数を用い，英語のメッセージを暗号化・復号化せよ

#### Cipherモジュールとconversion関数の作成
```
defmodule Cipher do
  def conversion(input_text) do
    input_text
    |> String.graphemes()
    |> Enum.map(fn x -> conversion_char(x) end)
    |> Enum.join()
  end
  ```
上記関数で、`String.grahemes()`を使っていますが、ここは`codepoints`でも実現したいことは変わりません。ただ、grahemesは、Unicodeを解釈してくれる機能があります。
例えば、`\u0065\u0301`を変換すると次のようになります。
```
iex(30)> String.graphemes("\u0065\u0301")
["é"]
```
基本的には、各要素に分割した文字列リストを返してくれます。

#### conversion_char関数の作成
```
def conversion_char(x) do
    <<c :: utf8>> = x
    if c >= ?a and c <= ?z do
      <<219 - c :: utf8>>
    else
      x
    end
  end
```

これは、なかなかギョッとしますよね。
まず、`<<c :: utf8>> = x`の部分ですが、xに入ってきた文字を1文字づつ取り出して、cにバインドしています。
もし、utf8でなければエラーが発生します。

その次のif文は英子文字であるかをチェックしています。
正直ここは書き方がわからなかったので、少しチョンボしましたがこういう書き方があるんだと勉強になりました。

というわけで、全体を繋げると以下のようになります。

```
defmodule Cipher do
  def conversion(input_text) do
    input_text
    |> String.graphemes()
    |> Enum.map(fn x -> conversion_char(x) end)
    |> Enum.join()
  end

  @spec conversion_char(binary()) :: binary()
  def conversion_char(x) do
    <<c :: utf8>> = x
    if c >= ?a and c <= ?z do
      <<219 - c :: utf8>>
    else
      x
    end
  end
end
```

実行すると以下のようになります。
```
iex(32)> Cipher.conversion("すずき")
"すずき"
iex(33)> Cipher.conversion("abc")   
"zyx"
iex(34)> Cipher.conversion("0123")
"0123"
iex(35)> Cipher.conversion("ABC") 
"ABC"
iex(36)> Cipher.conversion("/////")
"/////"
iex(37)> Cipher.conversion(".......") 
"......."
```

2つ目に実行した`"abc"`という文字列は暗号化されて、それ以外はそのまま（復号化）されていることがわかるかと思います。

### まとめ
今回の問題では、conversion関数の中で、conversion_char関数の呼び出しを行っています。
今までは、関数ひとつひとつを作ってそれぞれ実行していましたが、初の試みだったのでより柔軟な発想が必要だと感じました。
Androidでキーボードの表示非表示を検知する【Kotlin】

# 準備

https://github.com/yshrsmz/KeyboardVisibilityEvent

こちらのライブラリを使ってソフトキーボードの表示中を検知します。
↑を元に準備していきます。
```php:build.gradle(:app)
dependencies {
    api 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:2.1.0'
}
```

# 実践
```php:MainActivity.kt
     KeyboardVisibilityEvent.setEventListener(this) {
            KeyboardVisibilityEventListener {
                   if (it) {
                    // 表示
                } else {
                    // 非表示
                }
            }
        }
```
KeyboardVisibilityEvent.setEventListener()の引数にActivityを追加

>  KeyboardVisibilityEventListener {
>           
>  }

内で表示非表示の判定ができる。
文章の中でどの文字が一番登場したのかを判定するやつ

```python:main.py

# 与えられたテキスト
text = "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, `and what is the use of a book,' thought Alice `without pictures or conversation?'"
alphabet = [["air",1]]

for i in text:
    judge_num = 0
    for num in alphabet:
        if str(i) == str(num[0]):
            num_1 = num[1]
            num[1] = int(num_1) + 1
            judge_num = 1
            break
    if judge_num == 0:
        alphabet.append([str(i),1])

alphabet_num_base_num = 0
alphabet_num_base_name = ""
for alphabet_name , alphabet_num in alphabet:
    if alphabet_name == "," or alphabet_name == " " or alphabet_name == "." :
        pass
    else:
        if alphabet_num_base_num <= alphabet_num :
            alphabet_num_base_num = alphabet_num
            alphabet_num_base_name = alphabet_name
        
print(alphabet)
print("_________________")
print(alphabet_num_base_name)
print(alphabet_num_base_num)



```
discord bot開発で使っていたvenv環境をdockerに移行しよう

# はじめに
少し前にdiscord botの記事をvenv環境で作っていたのですが、友人にdockerを教えていただき、かなり魅力的だったのでvenvで作成した仮想環境から　Dockerに移行しようと思いました。
今回はdiscord botの環境構築をdockerでやる＋venv環境で開発していたのを、Dockerに移行できるようにしてみようと思います。

# Dockerとは
[Docker](https://www.docker.com/ja-jp/)とは、コンテナ型の仮想環境を作成、実行、配布ができるプラットフォームです。特徴としては、開発環境を迅速に構築できる、Vscodeなどの既存ツールとの連携、あらゆる環境で一貫した動作が可能であることです。

また、今回はdocker-composeというツールも使います。docker-composeは複数のコンテナを一度に起動操作ができるツールです。

::: note warn
dockerは理解できている自信がないので簡単にしか説明できないです、すいません
:::

# botのコードについて
少し前に作成した[こちらの記事](https://qiita.com/maooz4426/items/2c39929756af5541648f)で作ったbotを使っています。そのbotを使った.envファイルの作成の[記事](https://qiita.com/maooz4426/items/a7bbc07d867d9191efc4)もあるので、そちらも参考にしてください。

# Dockerfileの作成
imageにあたるDockerfileを作成します。
Dockerfileは以下のように作成します。
```
FROM python:3.12.2

WORKDIR /bot

COPY requirements.txt /bot/

RUN pip install requirements.txt

COPY . /bot/
```

- `FROM python:3.12.2`でpythonのバージョンを指定します。
- `WORKDIR`で作業ディレクトリを指定、もし存在しなければ作成します。コマンドを打つ際に基準となるディレクトリになります。今回はbotディレクトリを作成しました。
- `COPY requirements.txt /bot/`で、botディレクトリの中に ライブラリを記述しているrequirements.txtをコピーします。requirements.txtはこの後作成しますので、とりあえず気にしないでください。
- `RUN pip install requirements.txt`は、requirements.txtに書いてあるライブラリを再起的にインストールします。
- `COPY . /bot/`でアプリケーションの中身を全てbotディレクトリの中に入れます。

# docker-compose.ymlの作成
今回はdocker-composeも使用するので、docker-compose.ymlも作成します。
docker-compose.ymlは以下のように作成します。

```
version: '3'

services:
  bot:
    build: .
    command: python main.py
    volumes:
      - .:/bot
    environment:
      - TOKEN = ${TOKEN}
```

- `version: '3'`でdocker-composeの使用バージョンを指定しています。
- `services:`で作成するサービス(コンテナ）をこの下に書いています。今回はbotというコンテナの設定について記述しています。
- `build:`でアプリケーションをビルドする場所を指定しています。
- `command`でコンテナ起動時に実行するコマンドを指定しています。（今回はbot起動に使うコマンドを指定しています。）
- `volumes`でボリュームを設定しています。
- `enviroment`で環境変数を設定しています。今回は.envファイルから読み込みたいため、.envファイルに書かれている`TOKEN`を`${TOKEN}で取得します。

# requirements.txtの作成
ライブラリを指定するため、`requirements.txt`を作成します。

- venv環境を作っていた場合
まずアクティベートして、仮想環境に入ります。
```
source venv/bin/activate
```

その後、以下のコマンドでインストールしているライブラリを書き出してください。
```
pip freeze > requirements.txt
```

今回は以下のようなものが生成されました。
```
aiohttp==3.9.5
aiosignal==1.3.1
attrs==23.2.0
frozenlist==1.4.1
idna==3.7
multidict==6.0.5
py-cord==2.5.0
python-dotenv==1.0.1
yarl==1.9.4

```

- venv環境じゃなく、１から作る場合
上のように必要なライブラリを書いてください。おそらくpycordとdotenvで十分だと思います。


# コンテナの作成、起動
コンテナの作成と起動は以下のコマンドで実行します。

```
docker-compose up
```

こうすることでコンテナが起動し、botも起動します。

![スクリーンショット 2024-05-11 23.23.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/4dadb9b3-6711-f8ec-2178-d49d4317346b.png)


# 最後に
今回、初めてDockerを使いましたが、仮想環境がファイルを記述することで起動できることに魅力を感じましたし、これを共有できることにも魅力を感じました。まだ理解できていない自覚があるので今回の記事をきっかけにちゃんと理解を深めようと思います。

リポジトリはこちら↓

https://github.com/maooz4426/pycord-hello
ABC352解説(A-C問題)

# ABC352解説（A～C問題）
## このコンテストの反省

https://atcoder.jp/contests/abc352

今回、A・B・C問題は瞬殺、D問題に関して、見通しは立ったものの、実装ができずACならず。A・B・C問題は安定して解けるようになったので、アルゴリズムをもっと習得して、D問題も解けるようになりたい。
## A問題解説・解答

https://atcoder.jp/contests/abc352/tasks/abc352_a

↑問題はこちら
### 解説
これは、うーんX<YかY<Xで場合分けするかな。
あんまりNは関係ないことに注意しよう（え、N使わないじゃん、自分のコード間違ってる？なんてかんじになりそうだし…）。
### 解答

```cpp:solve.cpp
#include <bits/stdc++.h>
using namespace std;

int N, X, Y, Z;

int main() {
  cin >> N >> X >> Y >> Z;
  if (X <= Z && Z <= Y) cout << "Yes" << endl;
  else if (Y <= Z  && Z <= X) cout << "Yes" << endl;
  else cout << "No" << endl;
  return 0;
}
```
要するに、ZがX~Yの中にあるか判定すればいいんですね。

## B問題解説・解答

https://atcoder.jp/contests/abc352/tasks/abc352_b

↑問題はこちら
### 解説
まず、打ち込む予定だった文字列SをキューQに入れてみる
そんで、文字列Tを一文字目から見ていって、Qの一番前の文字とその文字列T内の文字が一致したら、その文字のインデックスを答えを格納するvectorに追加して、Qを一回popする。これを最後までで繰り返す。（キューを使ったのは、普通に、S内のどの文字を入力する予定かっていう文字のインデックスを数値で管理するのがめんどくさかったからです）
### 解答
``` cpp:solve.cpp
#include <bits/stdc++.h>
using namespace std;

string S, T;
queue <int> Q;
vector <int> ans; //答えを格納するvector

int main() {
    cin >> S >> T;
    for (int i = 0; i < S.size(); i++) Q.push(S[i]); //文字列SをQに格納
    //Tを一文字目から調べる
    for (int i = 0; i < T.size(); i++) {
        if (Q.empty()) break;
        char C = Q.front();//Qの一番前の文字を取得
        if (C == T.at(i)) {ans.push_back(i + 1); Q.pop();}//一致したらQから一番前の文字列を取り出す
    }
    for (int i = 0; i < ans.size(); i++) {
        cout << ans[i];
        if (i == ans.size() - 1) cout << endl;
        else cout << " ";
    }
    return 0;
}
```
## C問題解説・解答

https://atcoder.jp/contests/abc352/tasks/abc352_c

↑問題はこちら
### 解説
C問題にしては簡単だったかな？
巨人が肩に乗る。一番上に乗る巨人以外の頭の高さは除外されるから、一番上に乗る巨人が一番頭が大きいように巨人を積めばいいね。
まず、全ての巨人の肩までの高さの総和を出して、それに一番大きい頭の高さを足せばいい。
### 解答
``` cpp:solve.cpp
#include <bits/stdc++.h>
using namespace std;

int N, A[200009], B[200009];

int main() {
    //入力
    cin >> N;
    for (int i = 1; i <= N; i++) cin >> A[i] >> B[i];
    //すべての巨人の肩の高さの総和を出す
    long long sum = 0;
    for (int i = 1; i <= N; i++) sum += A[i];
    //一番大きい頭の高さを出す
    int M = 0;
    for (int i = 1; i <= N; i++) {
        int head = B[i] - A[i];
        if (M < head) M = head;
    }
    cout << sum + M << endl;
    return 0;
}
```
コードが書けない高専卒がReactで学習記録アプリを作ってみた

# はじめに
僕は #JISOU というコミュニティでReactを学習しているコードが書けない高専卒のart93です！
初投稿記事はこちら👇
[コードが書けない高専卒エンジニア2年生がReactを勉強して真のエンジニアを目指す話
](https://qiita.com/art93dev/items/a0ddf7481129e996fd2f)

今回はJISOUでの最初の課題である、学習記録アプリケーションを作成した記事になります。

# 課題内容
React(JavaScript)にて、画像のように学習した内容とその時間を記録するアプリケーションを作成しました。
実装した機能は以下のとおりです。
+ 入力された学習内容と学習時間をリスト形式で表示する
+ 入力されていない項目がある場合、赤字でエラーを表示する
+ 学習時間の合計を計算して表示する
+ CSSはすべてChatGPTに書いてもらいました笑

![スクリーンショット 2024-05-12 17.41.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781911/393a8db9-db6d-28ec-dad3-e4b25075cec9.png)

# 苦労した点
一番苦労した点は、最初のコードを書き始めたところです💦
筆が乗り始めてからはスラスラと迷うことなくかけたのですが、最初の骨子を組み立てるところで迷い、Udemyの講座を見返しました。
一番最初に[ジンさん](https://twitter.com/Sicut_study)が言っていた「Udemyはアウトプットではなくインプット」という言葉が身にしみました。

# お気持ち
自分でモノを作れないことがずっとコンプレックスだったのですが、小さなモノでも自分で作れることができて少し自信が湧きました！
コードを書いている時間や、コードを書くためのアルゴリズムを考える時間もとても楽しいため、これから続けていきたいと思います！！

# 最後に
「プログラミングができるようになりたいけど何からしたらいいかわからない...」「スキルが身につかない部署で将来が不安...」といった悩みを持っていませんか？
僕もその悩みを抱えているため、そういった不安を乗り越えて自分でモノを作れるようになれる過程をお届けできたらと思います！

ぜひ[Twitter](https://twitter.com/art93dev)もフォローお願いします！　

# JISOUのメンバー募集中

プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp

### 参考文献
+ [【最新ver対応済】モダンJavaScriptの基礎から始める挫折しないためのReact入門
](https://www.udemy.com/course/modern_javascipt_react_beginner/learn/lecture/40838780#content)
+ [Reduce関数を使ってみよう](https://zenn.dev/nu_______ll/articles/d12a649c56217a)
PHPカンファレンス香川2024に参加してきました #phpconkagawa

# はじめに
[PHPカンファレンス香川2024](https://phpcon.kagawa.jp/2024/)に参加してきました。
[びきニキさんが「みんな、ブログ書こうぜ！！！！」と呼びかけていた](https://x.com/BkNkbot/status/1789273368690376871)ので、久々にQiita記事を書いてみました。

# 聞いた講演とその感想
## PHP コードの実行モデルを理解する
https://fortee.jp/phpconkagawa-2024/proposal/8251b4a5-bb67-4d84-b538-0a018d5cb292

なんとなくPHP-FPMやPHPのCLIを使ってきたので、体系立てて理解する契機になりました。オペコードの中身を初めて見ました。何度も資料を読み込んで深い理解に至りたいです。

## 新米SRE、4つのプロダクトを同時にPHP7.0から8.1へ！！
https://fortee.jp/phpconkagawa-2024/proposal/3746d04f-d0cd-4f02-b603-4132f82c080d

一気にバージョン引き上げではなく、PHPとLaravelで交互にバージョンを刻みながらアップデートする手法はなかなか聞かない手法でした。
「静的解析と自動テストを日頃から整備しておくと、バージョンアップの難易度が下がる」と聞きました。この講演を聞いたからには、静的解析と自動テスト運用の旗振り役として動いていきたいです。
「4つのプロダクトを同時」は私には敵わない要素です。

## 泥まみれの技術革新: あなたの[ PHPバージョンアップ | 新フレームワーク採用 | アーキテクチャ刷新 | … ]を後押しするために
https://fortee.jp/phpconkagawa-2024/proposal/7f4622af-03b6-4b83-a0ef-e1cfc7b7c930

一言で言うと「力こそパワー」でした。実力のあるエンジニアならではの動きが聞けました。

## 令和版ソフトウェアエンジニアの情報収集術
https://fortee.jp/phpconkagawa-2024/proposal/d9f74b93-9991-4932-afaf-ada75c330094

[冴えカノポストを拾ってもらった](https://note.com/samurai_se/n/nc0b406a83363#6cd4f1b6-930e-4b10-b1f7-d0459fafb999)、Kanonさんの講演です。[SlackにRSSを読み取って更新を通知してくれる機能](https://slack.com/intl/ja-jp/help/articles/218688467)がついているので、活用してみたいです。

## PHP 9 に備えよ - 動的プロパティ、どうすればいぃ？
https://fortee.jp/phpconkagawa-2024/proposal/039ebb21-d104-4df2-86bb-be2680979b7b

PHP 8.3のDeprecatedに対処しておけばPHP 9も迎え撃てそうな気がしてきました。あと、未定義変数へのアクセスでエラーになる点はPHP 9の変更点の中でも険しい部類に入りますね…。

## 実践、プロダクト品質向上に重要なテスト分析とテスト設計
https://fortee.jp/phpconkagawa-2024/proposal/2204046f-e0bc-4818-94fc-4992bd2c5946

試験項目の観点の比較表がスライドの中にあったのですが、経験の浅いほうの観点はあるあるネタでした。

## mb_trim関数を作りました - PHPに新しい関数を追加しました
https://fortee.jp/phpconkagawa-2024/proposal/0ec36f50-c4b7-4aa4-abef-006f8bab3931

php-src（PHP自体のソースコード）のコミッターとして大活躍されている、てきめんさんの話です。
紆余曲折を経ながら英語を駆使してmergeまで到達できるところにタフさを感じました。
「動けば良い」ではなく計算量を下げる実装を模索しているところに使いやすさの追求を感じました。

## PHPer のための Cloudflare 活用術
https://fortee.jp/phpconkagawa-2024/proposal/4cc166b7-3759-438f-a5af-6926720324bd

「光が遅い」ことを体感してもらうために、ブラジルにインスタンスを立ててライブデモを見せてもらって、エッジコンピューティングの有益性を身をもって感じられました。

## レガシーコードにもオブザーバビリティを 〜少しずつ始めるサービス監視〜
https://fortee.jp/phpconkagawa-2024/proposal/adf74428-3316-444c-9680-fea1b2e42d0c

`監視`と`オブザーバビリティ`の違いから始まり、サイトクロール処理の障害に対して「恒久対応で目視確認追加」以外で根本的解決を図る流れは真似したいと思いました。

## 哲学史とモデリング 〜クラスはイデアだと思った? ざーんねんっ⭐︎エポケーでした〜
https://fortee.jp/phpconkagawa-2024/proposal/4ed7eece-47f7-4978-a8fd-452b29e0a234

[ちょうぜつ本](https://www.amazon.co.jp/dp/4297132346)の著者の人の話です。以前から哲学の面からプログラミングを語っていて、私が持っていない観点で毎回興味深く聴いています。
`ITの本場西洋と日本で概念の違いがあるのでその違いを意識する`が一番響いた言葉でした。

# 雑感
- 和室での技術カンファレンスは、天候が良かったおかげもあって、田舎のおばあちゃんちに居るようなチルい感覚でした。
- 四国のエンジニアさんと交流できました！
- 「MySQLを8.0.36から8.4.0にバージョンアップしたときにつまづいたこと」で即興LTしました。ご清聴ありがとうございました。
- [株式会社STYLY](https://styly.inc/ja/)さんの[無料配布の新刊](https://twitter.com/STYLY_XR/status/1788098902656471466)を手に入れて小躍りしていました（`新刊`という響きに胸躍る性格でして）。
- 無限うどんは素うどんとぶっかけうどんの2種類を楽しみました。
- この記事は[南海フェリー](https://nankai-ferry.co.jp/)乗船中に執筆しました。机、椅子、電源コンセント、無料Wi-Fiが揃っていて、「130分1本勝負」の気分で書き上げました。
Notion数式で分数を時刻文字列に変換


# 常に"H:MM:SS"の場合
```javascript
lets(
	h, floor(prop("分") / 3600),
	m, floor(mod(prop("分"), 3600) / 60),
	s, mod(prop("分"), 60),
	h + ":" + (m < 10 ? "0" : "") + m + ":"  + (s < 10 ? "0" : "") + s
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578163/59a6a97d-9b8c-cbf8-0fac-fd10ac084931.png)



# １時間未満なら"M:SS"の場合
```javascript
lets(
	h, floor(prop("分") / 3600),
	m, floor(mod(prop("分"), 3600) / 60),
	s, mod(prop("分"), 60),
	(h ? h + ":": "") + (h && m < 10 ? "0" : "") + m + ":"  + (s < 10 ? "0" : "") + s
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578163/c7302bd8-b1c0-364e-38a5-888c9fd99936.png)

# １分未満なら"S"の場合
```javascript
lets(
	h, floor(prop("分") / 3600),
	m, floor(mod(prop("分"), 3600) / 60),
	s, mod(prop("分"), 60),
	(h ? h + ":": "") + (h || m ? (h && m < 10 ? "0" : "") + m + ":" : "") + ((h || m) && s < 10 ? "0" : "") + s
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578163/27b4d5ef-41f9-8a05-f9d3-bd1317556c26.png)

# 参考
https://www.notion.so/ja-jp/help/formula-syntax
【SwiftUI】超簡単なカレンダーを自作

# 概要
今回は以下のようなカレンダーを自作します。
<img width = 400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3456384/3c6b4e76-7220-a253-412c-40cbdf91713f.png">

# やり方
1. 「その月の日数」と「その月の最初の曜日」を取得
2. LazyVGridで7日おきに改行
3. その月の最初の曜日まではSpacer()で空白を挿入
4. 「年と月」と「曜日」を表示
5. 完成

まず、DateExtentionで「その月の日数」と「その月の最初の曜日」を取得します。

```Swift: Date+
import Foundation

enum Weekday: Int, CaseIterable {
    case sunday = 0
    case monday = 1
    case tuesday = 2
    case wednesday = 3
    case thursday = 4
    case friday = 5
    case saturday = 6
    
    var name: String {
        switch self {
        case .sunday: return "日"
        case .monday: return "月"
        case .tuesday: return "火"
        case .wednesday: return "水"
        case .thursday: return "木"
        case .friday: return "金"
        case .saturday: return "土"
        }
    }
}

extension Date {
    /// 月の日数を取得
    var numberOfDaysInMonth: Int? {
        let calendar = Calendar.current
        guard let range = calendar.range(of: .day, in: .month, for: self) else {
            return nil
        }
        return range.count
    }
    
    /// 月の最初の曜日を取得
    var weekdayOfFirstDay: Weekday? {
        let calendar = Calendar.current
        let weekdayNumber = calendar.component(.weekday, from: self)
        return Weekday(rawValue: weekdayNumber)
    }
    
    /// 年と月を取得
    func yearAndMonth() -> String {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.year, .month], from: self)
        let year = components.year ?? 2000 // デフォルト値は2000年
        let month = components.month ?? 1 // デフォルト値は1月
        
        return String(format: "%04d年%02d月", year, month)
    }
}
```

次にLazyVGridとForEachでカレンダーを作成します。

```Swift: CalendarView
import SwiftUI

struct CalendarView: View {
    let daysInMonth: Int = Date().numberOfDaysInMonth ?? 30
    let firstDayOfMonth: Weekday = .saturday
    
    var body: some View {
        VStack {
            Text(Date().yearAndMonth())
                .padding()
            
            HStack {
                ForEach(0..<Weekday.allCases.count, id: \.self) { week in
                    Text(Weekday(rawValue: week)?.name ?? "a")
                        .frame(maxWidth: .infinity)
                }
            }
            .padding(.horizontal, 5)
            
            LazyVGrid(columns: Array(repeating: GridItem(), count: 7), spacing: 0) {
                ForEach(0..<daysInMonth + firstDayOfMonth.rawValue, id: \.self) { day in
                    if day >= firstDayOfMonth.rawValue {
                        Text("\(day - firstDayOfMonth.rawValue + 1)")
                            .frame(maxWidth: .infinity)
                            .border(Color.gray)
                    } else {
                        Spacer()
                    }
                }
            }
            .frame(maxWidth: .infinity)
            .padding(.horizontal, 5)
        }
    }
}

#Preview {
    CalendarView()
}
```

# 終わりに
今回はできる限りシンプルにカレンダーを自作してみました。もっとシンプルな方法があればコメントで教えてください。