OmniAICreator/Qiita-1.07M huggingface dataset:
【Docker】基礎③ ~conainerの操作~

## コンテナの作成と起動
### イメージからコンテナを作成し、起動する
```bash
docker container run { image名 }
```
| オプション | 効果 |
|:-:|:-:|
| -i | コンテナへの標準入力を受け付ける |
| -t | 標準入力の結果をターミナル形式で出力するようにする |
| --name { 任意のコンテナ名 } | コンテナに任意の名称をつける |
| --rm | コンテナを起動後直ちに破棄する |
| -d | デタッチドモードで起動 |

:::note info
runコマンドの末尾にコマンドを入力することで起動時に実行するコマンドを変更することができる
何もコマンドを指定しない場合は基本的に**bash** が実行される
> docker image inspect { イメージ名 }
で表示される詳細の中の
**Config** -> **Cmd** のなかに設定されているものが初期値に当たる
```bash:example
docker container run -it ubuntu:20.04 ls
```
:::

### docker container run hello-world の動作
> **hello-world**というイメージは **/hello**というコマンドを実行するだけのもの
#### 処理の流れ
コンテナが作成される (status: **created**)
↓
コンテナが起動 (status: **up**)
↓
**/hello**を実行
↓
コンテナが停止 (status: **exited**)

上記のように必要な処理が終わり次第、コンテナは停止される

## 基本的なコマンド
### ローカルの起動中のコンテナを一覧表示
```bash
docker container ls
```
| オプション | 効果 |
|:-:|:-:|
| -a | 起動中でないコンテナも表示に含める |

### コンテナを停止
```bash
docker container stop { コンテナ名 or コンテナID }
```

### コンテナを再起動
```bash
docker container restart { コンテナ名 or コンテナID }
```

### 停止中のコンテナを一件削除
```bash
docker container rm { コンテナ名 or コンテナID }
```
| オプション | 効果 |
|:-:|:-:|
| -f | 起動中のコンテナでも強制的に削除する |

### 停止中のコンテナを一括削除
```bash
docker container prune
```

### 既存のコンテナにコマンドを実行させる
```bash
docker container exec { コンテナ名 or コンテナID } { コマンド }
```
| オプション | 効果 |
|:-:|:-:|
| -i | コンテナへの標準入力を受け付ける |
| -t | 標準入力の結果をターミナル形式で出力するようにする |


## デタッチドモードとフォアグラウンドモード
> デタッチドモードとは、
バックグラウンドでコンテナを起動させるモードのこと

dockerでは起動時に **-d** をつけない場合は自動的にフォアグラウンドモードになり、
-dをつけた場合にのみデタッチドモードになる

### デタッチドモードになっているコンテナに接続する
```bash
docker container attach { コンテナ名 or コンテナID }
```

------------
:::note info
**dockerではオプションを複数つける場合省略して書くことができる**
```bash
# 省略前
docker container run -i -t -d ubuntu

# 省略後
docker container run -itd ubuntu
```
:::
【ポエム】スペースキーが壊れると。。

# はじめに
昨日、家のノートPCのスペースキーが壊れました。

## プログラミングにおける影響
**影響がデカい。デカすぎる**

## どうしたか
今日の朝、ヨドバシカメラに行き、外付けキーボードを買いました

## 結果
開発用のノートPCに外付けし、無事プログラミング、Qiitaの記事投稿ができるようになりました。

# 最後に
**スペースキーは大事だよ**
EC2でスクレイピング備忘録

:::note alert
Amazon Linux 2023のみ下記手順でインストール可能です。
Amazon Linux 2 AMIでは
```/opt/google/chrome/google-chrome: symbol lookup error: /opt/google/chrome/google-chrome: undefined symbol: cupsUserAgent```
と言われて、インストールできません。
:::


1. google-chrome.repoを作成して、下記を記載する
    ```terminal
    sudo emacs /etc/yum.repos.d/google-chrome.repo 
    
    ------------------------------------------------------------------
    [google-chrome]
    name=google-chrome
    baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64
    enabled=1
    gpgcheck=1
    gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub

    [google-chrome]
    name=google-chrome
    baseurl=https://dl.google.com/linux/chrome/rpm/stable/x86_64
    enabled=1
    gpgcheck=1
    gpgkey=https://dl.google.com/linux/linux_signing_key.pub 
    ------------------------------------------------------------------
    ```
2. Chromeをインストールする
    t2インスタンスでは下記
    ```terminal
    sudo yum install --enablerepo=google-chrome google-chrome-stable
    google-chrome --version
    >> Google Chrome 126.0.6478.126
    
    or
    
    wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
    sudo yum install ./google-chrome-stable_current_x86_64.rpm
    ```
    t3インスタンスでは下記
    ```terminal
    sudo yum install google-chrome-stable.x86_64 --nogpgcheck
    google-chrome --version
    >> Google Chrome 126.0.6478.126
    ```
    :::note warn
    Google Chromeは公式にはx86_64アーキテクチャ（Intel/AMDプロセッサ）向けに提供されています。したがって、t4gインスタンス（ARM64アーキテクチャ）に直接インストールするのは難しいらしい
   :::    
3. chromedriverをダウンロードして、固定のフォルダに置く
   URLは対応するドライバーのURLへ変更する。下記リンクから確認できる。
   https://developer.chrome.com/docs/chromedriver/downloads?hl=ja
    ```terminal
    wget https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.126/linux64/chromedriver-linux64.zip
    sudo unzip chromedriver-linux64.zip
    cd chromedriver-linux64/
    sudo mv chromedriver /usr/local/bin
    ```
4. 日本語フォントをインストール
    ```terminal
    sudo yum install ipa-pgothic-fonts.noarch
    ```
5. Pythonライブラリをインストール
    ```terminal
    pip3 install selenium
    pip3 install PyInstaller webdriver_manager
    pip3 install chromedriver-binary==117.0.5938.149.0
    ```
6. Pythonコードを実行
    ```Python:sample.py
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.by import By
    
    options = webdriver.ChromeOptions()
    options.add_argument("--headless")
    
    service = webdriver.chrome.service.Service(executable_path='/usr/local/bin/chromedriver')
    driver = webdriver.Chrome(service=service, options=options)
    
    driver.get('https://www.google.co.jp')
    element_text=driver.find_element(By.CLASS_NAME,"MV3Tnb").text
    
    print(element_text)
    
    driver.quit()
    ```


出力は ```Googleについて```


### 補足
インストールに失敗した場合、古いキャッシュを一度削除する必要があります。

```
sudo yum remove -y google-chrome-stable
sudo yum clean all
```
円滑なプルリクエスト進行にレビュイーができること5選

チーム開発において効率的にレビューしてもらうことはタスクを円滑に進めるために重要です。

コードの構築や設計をする時間が支配的になると考えがちですが、レビューを依頼して承認をしてもらうことで初めてタスクが完了します。

そんなレビューの時間を効率的にできることをレビュイーができることたちを紹介します。

最後にちょっとした仕組み的な解決方法も紹介します。

## レビュイーができること

### どのような目的タスクなのかを明記する

レビュイーは構築を担当しているので基本的に要件や実装内容、テスト内容を最もしているはずです。

一方でレビュワーはそのタスクがどのような目的で実装されたのかを事細かに知らないことがあります。

レビュイー目線で当たり前になっていることもレビュワーは知らないことがあるので、プルリクを作成するときにはそのタスクの変更の背景/目的、実装方針と内容を一目で読んでわかるように明記することが重要です。

### 動作確認、テストの結果を明記する

実装内容を事細かに説明しても、その動作が正常に行われているかどうかはコードを読むだけではわからないことも多い。

もし動作確認の内容を伝えなかったらレビュワーは実装内容をローカルに落としてデータを準備して、実行して動作チェックをすることで何重にも確認のための作業が必要になります。

プルリクを作成するときに動作確認内容を明記することでレビュワーはその内容を参考にして動作確認を行うことができ、レビュワーの負担を減らすことができます。

### 特に構築しているときに迷ったことなどアドバイスしてもらいたい箇所を明記する

自分をジュニアと思っていても、ある程度経験をしたエンジニアだと思っていても実装や設計に迷うことはもちろんあると思います。

実際にコーディングしていてもしっくりこなくてより良い方法がありそうなものの思いつかないなど人に相談したいことは少なくないと思います。

そんな時には`XXXについてもっと良い書き方があればコメントがほしい`という感じでレビュワーにアドバイスを求めちゃいましょう。

（レビュワーもきっとアドバイスをしてくれるはずだ）

### タイポや誤字脱字をレビュー依頼前にレビューに出す前に修正する

レビューの価値はコードや設計を第三者の目を通して確認してもらい品質を向上させることだと思っています。

この営みの中でスペルミス、タイポ、誤字脱字などはレビュワーにとっては上記の目的を達成するためのノイズになってしまいます。

レビュイーもレビュワーに求めるコメントはコードや設計に関するものであって、スペルミスや誤字脱字に関するものは求めていないと思います。

このようなノイズを減らすためにはレビュイーがプルリクを出す前にセルフレビューをして極力減らすことが重要。

### Linter, Formatter, 自動テストなどのツールを使って反している部分はレビューに出す前に修正する

プロジェクト内のコードの品質を自動で高めるためにCIでLinterやFormatter、自動テストを実行していることが多いと思います。

その中で規定されているルールに反してCIが通らない状況でプルリクを出すとレビュワーはその部分に対してコメントをすることになります。

この連絡のラリーはレビュワーの時間を奪ってまでやることではないと思うのでCIが通っているかを確認してからプルリクを出しましょう。

## 仕組み的な解決方法

### .github/PULL_REQUEST_TEMPLATE.mdの作成

GitHubではプルリクを作成するときにテンプレートを作成しておくことができます。

プルリクエストを作成するときに自動でtextboxにテンプレートが表示されるので、そのテンプレートに沿って情報を入力することでレビュイーに必要な情報をぬけもれが少なくなります。

## まとめ

レビュイーができることをまとめました。

意識的にセルフレビューをしてテンプレートを使って効率にレビューをしていきましょう！
How will the Right Engineering College Impact the Growth of Future Engineers

Beginning a suitable career in engineering can be challenging and exciting, and is important to select the right engineering college to pursue the engineering courses. Your college selection can impact your future growth since the knowledge and training you obtain will affect which companies are interested in hiring you. Choosing a well-known and reputed engineering college boosts your chances of getting a job at a top company, preparing you for a successful future.  Let’s explore How do you choose right engineering colleges?

Here are some essential tips for choosing the ideal engineering college for your future!

●      Choosing the engineering branch that best suits your interests and skills is essential. This choice impacts selecting the best engineering college in Villupuram, as certain colleges specialize in specific engineering areas more than others. For example, one college may specialize in electrical engineering, and another might specialize in computer engineering. Choosing a college with a strong reputation in your chosen specialization improves the experience and opens doors to more career opportunities in the field of interest.

●      The Next one is Accreditation; It means an independent group evaluates a college or university to ensure that it satisfies particular academic criteria. This evaluation is necessary to verify that your degree is recognized and valued by companies, national organizations and other colleges.

●      The expertise of teaching staff is essential. Faculty members should have relevant experience, competence and enthusiasm for their disciplines. Choose colleges that are actively engaged in research and demonstrate a proven track record of academic achievement.

●      Next, college infrastructure is paramount. Choose cutting edge facilities such as well-equipped labs, classrooms, and libraries. A library with diverse resource is essential. Modern labs provide hands on learning and research.

●      When selecting a Tamilnadu engineering college or one across India, the most crucial factor is the placement prospects. Look for universities with a track record of placing students in top companies. Research online for placement records to learn more about current possibilities.

 

The choice of engineering college significantly impacts the development of future engineers. ES College of Engineering is a top choice, ranked among the best engineering colleges in Villupuram, Tamilnadu.
語学学習のお供に

# はじめに

NHKの語学学習を楽しむために、ダウンロードプログラムを探していたところ、python実装の[radio-gogaku-downloader](https://github.com/ikakunsan/radio-gogaku-downloader)を見つけました。

自己研鑽も兼ねて、`radio-gogaku-downloader`を参考にして、NHKの語学の番組情報を他のプログラムでも使用しやすいようにAPI化してみました。API化したものは、pypiに[gogaku-dl](https://pypi.org/project/gogaku-dl/)パッケージで登録しました。

いまのところ、エラーケースは未考慮です。:P

# 実装例

以下は、`gogaku-dl`を使用したダウンロード実装例です。

## ソースコード

``` python
#!/usr/bin/env python
#-*- coding: utf-8 -*-

from gogaku_dl import english
from ffmpeg import (
    FFmpeg,
    Progress)
from tqdm import tqdm
import re


def main(title: str) -> None:
    program = english.get_hls(title)
    for episode in program['episodes']:
        for title, info in episode.items():

            subtitle = re.sub(r'.*「', '', title)
            subtitle = re.sub(r'」.*', '', subtitle)
            progress_bar = tqdm(
                desc=subtitle,
                total=int(info['len_in_sec']),
                bar_format='{l_bar}{bar}{n_fmt}/{total_fmt} sec'
            )
            cur_sec = 0

            ffmpeg = (
                FFmpeg()
                .option('y')
                .option('f', 'hls')
                .input(info['hls'],
                       {"seg_max_retry": "100",
                        "http_seekable": "0"})
                .output(
                    f'{title}.mp3',
                    {'codec:a': 'libmp3lame',
                     'b:a': '128k'}))

            @ffmpeg.on("progress")
            def on_progress(progress: Progress):
                nonlocal progress_bar
                nonlocal cur_sec

                old_sec = cur_sec
                cur_sec = int(progress.time.total_seconds())
                progress_bar.update(cur_sec - old_sec)

            @ffmpeg.on("completed")
            def on_completed():
                nonlocal progress_bar
                nonlocal cur_sec

                cur_sec = int(info['len_in_sec']) - cur_sec
                progress_bar.update(cur_sec)
                progress_bar.close()

            ffmpeg.execute()


if __name__ == '__main__':
    main('エンジョイ・シンプル・イングリッシュ')

```

## 実装例の実行の様子

実行には、外部プログラムとしてffmpegがPATHの通った箇所にある必要があります。

![example.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59920/f022f8e2-07f0-1b75-a3c8-93810fb8c239.gif)

# 謝辞

最後になりますが、実装する上で、以下のサイトを参考にさせていただきました。情報のご提供ありがとうございます。

- [radio-gogaku-downloader](https://github.com/ikakunsan/radio-gogaku-downloader)
- [『らじる★らじる』の聴き逃がしサービス（4）](https://gihyo.jp/article/2023/04/zoku-gansiki-0048?summary)
- [語学講座CS2 (2024年度)](https://csreviser.github.io/CaptureStream2/)

以上
Record-Triggered Flows トレイルヘッド


https://trailhead.salesforce.com/content/learn/modules/record-triggered-flows?trail_id=build-flows-with-flow-builder

# Add a Scheduled Task to Your Flow

+ 何もしないで検証ボタンをクリックしてみる。

:::note alert
ラベルとして「Review Opportunity with Account Owner」、API 名として「Review_Opportunity_with_Account_Owner」を持つフローが見つかりません。

We can’t find a flow with 'Review Opportunity with Account Owner' as the label and 'Review_Opportunity_with_Account_Owner' as the API Name.
:::

このフローがいるみたい

https://www.youtube.com/watch?v=GsNLU7Fzfbw

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a8332d65-d717-a5a7-e171-bad279a9e233.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/619dad3a-0c03-d84d-1245-63d3e08efb69.png)

+  作ったあと

:::note alert

「アカウント所有者による商談の確認」フローでは、API 名「X3_Days_After_Last_Modified_Date」のパスが見つかりません。フロー内の変更を必ず保存してください。

In the 'Review Opportunity with Account Owner' flow, we can’t find a Path with the API name 'X3_Days_After_Last_Modified_Date'. Make sure you saved the changes in your flow.
:::

改めて作ったフローを認識しているようだ。ここスタート

:::note alert
In the 'Create Phone Call Task' action, we can’t find the 'Activity Date' field set to a valid date.
:::

以下が設定されてなかった

Activity Date = enter today’s date (we won't check the actual date, just that it's a valid date)


有効化してないけど、合格した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c4ab8417-8ab4-0b35-022f-0ec867395a29.png)

# Meet Flow Trigger Explorer

クイズだな。
[Python] 例外処理について

## はじめに

こんにちは！今回も、備忘録を兼ねて。

プログラムを書いていると、予期せぬエラーが発生することがあります。
エラーが発生するとプログラムは処理を停止してしまいますが、エラー発生時の処理を適切に行うことで、プログラムを途中で止めずに処理を継続したり、ユーザーに分かりやすいメッセージを表示したりすることができます。

このようなエラー発生時の処理を、「**例外処理**」と呼びます。
今回は、例外処理の基礎から振り返ってみます。

## 例外処理の基本

Pythonの例外処理は、`try`、`except`、`else`、`finally`というキーワードを使って行います。基本的な構文は以下の通りです。

```python
try:
    # 例外が発生する可能性のある処理
except 例外型:
    # 例外が発生した場合の処理
else:
    # 例外が発生しなかった場合の処理
finally:
    # 例外発生の有無に関わらず実行する処理
```

* **tryブロック:** 例外が発生する可能性のある処理を記述します。
* **exceptブロック:** `try`ブロック内で指定した例外が発生した場合に実行する処理を記述します。
* **elseブロック:** `try`ブロック内で例外が発生しなかった場合に実行する処理を記述します。
* **finallyブロック:** 例外発生の有無に関わらず必ず実行する処理を記述します。

### 例外処理の基本的な例

```python
def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("エラー: 0で割ることはできません。")
    else:
        print(f"計算結果: {result}")
    finally:
        print("処理を終了します。")

divide(10, 2)  # 出力: 計算結果: 5.0
                 #     処理を終了します。
divide(10, 0)  # 出力: エラー: 0で割ることはできません。
                 #     処理を終了します。
```

## 複数の例外への対応

`except`文は複数記述することができます。
これにより、発生する可能性のある複数の例外に対して、それぞれ異なる処理を行うことができます。

```python
try:
    # 例外が発生する可能性のある処理
except ZeroDivisionError:
    # ZeroDivisionErrorが発生した場合の処理
except TypeError:
    # TypeErrorが発生した場合の処理
except Exception as e:
    # その他の例外が発生した場合の処理 (例外は変数eに代入)
```

## 例外の伝播

例外が発生した際に、その場で処理されなかった場合、例外は呼び出し元の関数に伝播していきます。

```python
def func_a():
    print("func_a開始")
    func_b()
    print("func_a終了")

def func_b():
    print("func_b開始")
    raise ValueError("func_bでエラー発生！")
    print("func_b終了")

try:
    func_a()
except ValueError as e:
    print(f"エラーをキャッチ: {e}")

# 出力結果: 
# func_a開始
# func_b開始
# エラーをキャッチ: func_bでエラー発生！
```

## 独自の例外クラスの定義

`Exception`クラスを継承して、独自の例外クラスを定義することができます。

```python
class MyCustomError(Exception):
    def __init__(self, message):
        super().__init__(message)
        self.message = message

try:
    raise MyCustomError("独自の例外が発生しました！")
except MyCustomError as e:
    print(f"MyCustomErrorをキャッチ: {e}")

# 出力結果: MyCustomErrorをキャッチ: 独自の例外が発生しました！
```

## 実践的なエラー処理の例

### ファイル操作

ファイルを開く際に、ファイルが存在しない場合などの例外処理。
外部要因に関連するものは、実装しといた方がいいです。

```python
try:
    with open("myfile.txt", "r") as f:
        content = f.read()
except FileNotFoundError:
    print("エラー: ファイルが見つかりません。")
```

### ネットワーク処理

ネットワーク処理では、接続エラーやタイムアウトなど、様々なエラーが発生します。
これも問題の早期解決のため、実装しましょう。

```python
import requests

try:
    response = requests.get("https://www.example.com")
    response.raise_for_status()  # ステータスコードがエラーの場合に例外を発生させる
except requests.exceptions.RequestException as e:
    print(f"エラー: {e}")
```

## まとめ

今回は、Pythonの例外処理について、基礎から振り返ってみました。

例外処理は、予期せぬエラーからプログラムを守り、より安全なアプリケーションを開発するために非常に重要です。

みなさんも、今回紹介した内容を参考に、例外処理を意識したコーディングを行いましょう！
【Docker】基礎① ~imageとcontainer~

## Dokcer imageとは
**container**に必要な
- ソフトウェア
- 環境変数
- 設定

などが入っているもの。

**image**は、**静的テンプレート(ただのファイル)** で、
起動すると**container**になる。
**image**を共有することで、どこでも同じ環境を作ることができる

## imageとcontainerのライフサイクル
下記のような流れで**image**から**container**が生成され、
**container**のstatusが変化する

imageを起動
↓
containerが作成される (status: **created**)
↓
containerが起動 (status: **up**)
↓↑
containerが停止 (status: **exited**)

:::note info
exited状態のcontainerを再度起動(up状態)にすることはできる
:::
PHP, Python の正規表現で、何故 \\ でバックスラッシュ \ がエスケープ出来るケースがあるのか


バックスラッシュ自身 `\` に対する正規表現で、バックスラッシュ 2個(`\\`) - *結果として埋め込まれるのは `\\\`* - で OK なケースがある。この説明を実際の仕様ではなく、日曜プログラマが理解可能なレベルで記載したい。[^1]

[^1]: 過去にあった同様の記事は見当らない、埋もれてる or 失われているので、、、

当然 `'//'` (PHP)、`r""` (Python) は使わない前提での文章となる。

<br>

## 前知識

- PHP, Python では、正規表現エンジンレベルでのエスケープ(PHP では PCRE)の他に、言語側の文字列としての展開を抑制するエスケープの2段階が必要
- 16進表記の文字列(`\x5c`) は(正規表現エンジンレベルでは)、エスケープの必要が無い(当たり前)

一部 `pcregrep` [^2] を用いて説明しているが、これは言語仕様によるノイズを排除するためのもの。

[^2]: PCRE の純正 grep。インストールの仕方などは省略 (PHP が入ってる環境なら入っているでしょ、知らんけど)

```
# STRING => 検索文字列
# REGEXP => 正規表現
% echo STRING | pcregrep 'REGEXP'
```
<br>

## 解

### 正規表現エンジンレベル側


正規表現エンジンレベルで文字列 `\` にマッチさせるためには、エスケープ `\` が必要。[^3]

[^3]: 多くの言語は、このレベルでのみのエスケープで済む

```
# PHP の正規表現エンジンである PCRE による実行
# ※ カスタム文字クラス内外
% echo '\\' | pcregrep '\\'
\
% echo '\\' | pcregrep '[\\]'
\
```

ところで `\\` はエスケープ無しの `\x5c` (Ascii 16進数)と記載可能である。

```
% echo '\\' | pcregrep '\x5c'
\
% echo '\\' | pcregrep '[\x5c]'
\
```

<br>

### 言語側

*便宜上、言語側レベルでのエスケープシーケンスを `~` で表記する*

言語側からは、正規表現エンジンに正しく `\\`、もしくは、`\x5c` が渡る様にしたい訳で。
その場合、以下のパターンが考えられる。

1. `\\` のそれぞれの展開を抑制させるために、それぞれエスケープする(`~\~\`)
2. `\x5c` の展開を抑制するために先頭の `\` をエスケープする(`~\x5c`)
3. 文字列 `\x5c` の展開を抑制するために先頭の `\` を 16進数表記のバックスラッシュでエスケープする(`\x5c\x5c`)

まあ、こんな感じ。

で、`\x5c` を `\\` に変換し、`~` を本来の `\` で記載すると、`\\\` か `\\\\` となる。

<br>
簡単だが、証明終り。

後は、言語仕様が、これを許容するかどうか。(後述)
<br>
<br>

# Appendix

## 実際の所の `\\` + `\`

PHP の場合は、文字クラス内外双方で通る。

```
% cat test.php
<?php
print(preg_match("/\\\\/", '\\'))   . "\n";
print(preg_match("/\\\/",  '\\'))   . "\n";
print(preg_match("/[\\\\]/", '\\')) . "\n";
print(preg_match("/[\\\]/",  '\\')) . "\n";
% php test.php
1
1
1
1
```

Python の場合、文字クラス外では通さない。

```
% cat test.py
import re;

print(bool(re.match('\\\\', "\\")))
#print(bool(re.match('\\\', "\\")))           # <= エラーで実行出来ず
print(bool(re.match('[\\\\]', "\\")))
print(bool(re.match('[\\\]', "\\")))

% python test.py
True
True
True
```

## `\x5c` で `\` をエスケープ



PHP の場合は、文字クラス内外双方で通る。

```
% cat test.php
<?php

print(preg_match("/\x5c\/",  '\\'))   . "\n";
print(preg_match("/[\x5c\]/",  '\\')) . "\n";
% php test.php
1
1
```

Python の場合、文字クラス外での `\x5c\` は通さない。

```
% cat test.py
import re;

#print(bool(re.match('\x5c\', "\\")))           # <= エラーで実行出来ず
print(bool(re.match('[\x5c\]', "\\")))
% python test.py
True
```

うん、沼りそうなので、ここで止め。
pnpm iできない

## 問題
`pnpm i`をすると、以下のようにエラーが出ました。
```shell
ERROR: This version of pnpm requires at least Node.js v18.12
The current version of Node.js is v16.14.2
Visit https://r.pnpm.io/comp to see the list of past pnpm versions with respective Node.js version support.
```

そこで、nodeのバージョンを確かめると、nodeとNodeのバージョンが違うという謎現象が起きていました。
```zsh
(base) hirune (*･∀-)b functions % node --version
v20.11.0
(base) hirune (*･∀-)b functions % Node --version
v16.14.2
```

## 解決
~/.zshrcの中に以下を書き足すと、成功しました🎉
```zsh
export VOLTA_FEATURE_PNPM=1
```
`pip install "numpy==1.26"`はnumpy 1.26の最も大きいバージョンでなく最も小さいバージョンがインストールされる

# 環境
* Python 3.12.1
* pip 24.1.1

### numpy 1.26のバージョン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37903/f0742b14-bcb3-b3cc-447f-297498087c8d.png)

# 内容
numpy 1.26の最新バージョンをインストールしたくて、以下のコマンドを実行しました。

```
$ pip install numpy==1.26

$ python -c "import numpy; print(numpy.__version__)"
1.26.0
```

しかし、numpyのバージョンは1.26.4ではなく1.26.0でした。
バージョン1.26の最新をインストールする場合は、以下のように上限を指定する必要があります。

```
$ pip install "numpy<1.27"

$ python -c "import numpy; print(numpy.__version__)"
1.26.4
```

poetryで利用できるCaret requirementsという記法（例：`numpy = "^1.26"`）に慣れてしまい、`numpy==1.26`は1.26の最新バージョンがインストールされることを期待してしまいました。
Flutterでポケモンバトルを実装する(Step5: Entitiyのテストを実施する)

## はじめに
前回までの記事の続きです。Entitiyのコードを作成したので、テストコードを書いていきます。
Unitテスト等の細かい単位でテストを実施していくことで、品質だけでなく生産性も向上していきます。

https://qiita.com/koji0705/items/4a0ef05a67678b5746f2

## ソースコード
```shell:ディレクトリ
├── test
│   └── domain
│       └── entities
│           ├── move_test.dart
│           ├── pokemon_test.dart
│           └── stats_test.dart
```

```dart:test/domain/entities/move_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:pokemon_battle_app/domain/entities/move.dart';

void main() {
  group('Move', () {
    test('should create a Move with correct properties', () {
      final move = Move(name: 'Thunderbolt', power: 90);

      expect(move.name, 'Thunderbolt');
      expect(move.power, 90);
    });
  });
}
```


```dart:test/domain/entities/pokemon_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:pokemon_battle_app/domain/entities/move.dart';
import 'package:pokemon_battle_app/domain/entities/pokemon.dart';
import 'package:pokemon_battle_app/domain/entities/stats.dart';
import 'package:pokemon_battle_app/domain/enums/pokemon_type.dart';

void main() {
  group('Pokemon', () {
    test('should create a Pokemon with correct properties', () {
      final move1 = Move(name: 'Thunderbolt', power: 90);
      final move2 = Move(name: 'Quick Attack', power: 40);
      final moves = [move1, move2];
      final stats = Stats(hp: 35, attack: 55, defense: 40, speed: 90);
      final pokemon = Pokemon(
        name: 'Pikachu',
        imageUrl:
            'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png',
        moves: moves,
        stats: stats,
        type: PokemonType.electric,
      );

      expect(pokemon.name, 'Pikachu');
      expect(pokemon.imageUrl,
          'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png');
      expect(pokemon.moves, moves);
      expect(pokemon.stats.hp, 35);
      expect(pokemon.stats.attack, 55);
      expect(pokemon.stats.defense, 40);
      expect(pokemon.stats.speed, 90);
      expect(pokemon.type, PokemonType.electric);
    });
  });
}
```

```dart:test/domain/entities/stats_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:pokemon_battle_app/domain/entities/stats.dart';

void main() {
  group('Stats', () {
    test('should create Stats with correct properties', () {
      final stats = Stats(hp: 35, attack: 55, defense: 40, speed: 90);

      expect(stats.hp, 35);
      expect(stats.attack, 55);
      expect(stats.defense, 40);
      expect(stats.speed, 90);
    });
  });
}
```

:::note info
インスタンスを作成し、期待値と比較するだけです。
:::

```shell:実行結果
~/develop/pokemon_battle_app (main)$ flutter test
00:02 +3: All tests passed!  
```
【テスト設計】権限テストの要件整理

# はじめに
権限テストのテスト設計をしていた中で得た気付きと進め方について共有できればなと思います。

## 背景
実務ではスプシでテスト設計しています。
今回は700項目程度ある機能テストのテスト設計をしている中で、並行して権限テストのテスト設計も行なっています。
テストに必要な権限を持ったアカウントを発行しておく必要があるため、そこを明瞭にしておく必要がありました。（必要が3回入っている…）

## 内容
※詳細をマスクするために記号やアルファベットを使用しています。

![権限テスト_要件整理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3144030/9799f3e0-6c95-4d45-8f3b-cc382bddeb67.png)

資料左側にある要件はコンフルからスプシに転記したものです。
右側の内容が整理後ですね。（テスト内容についてはかなり暈している）
今回については権限による表示の有無を確認することが目的なので、それをどの権限で行うかを整理できれば特段難しいテスト設計ではないのかなと思いました。
Flutterでポケモンバトルを実装する(Step4: Entitiyを実装する)

## はじめに
ポケモンバトルを実装していきます。実装しやすいようにDDDで作っていくため、Entitiyの定義から始めていきます！では、Start!!!!

https://qiita.com/koji0705/items/8763a5a259d30bbeaec3

## ソースコード
```shell:ディレクトリ構成
~/develop/pokemon_battle_app (main)$ tree lib 
lib
├── data
│   └── sample_data.dart
├── domain
│   ├── entities
│   │   ├── move.dart
│   │   ├── pokemon.dart
│   │   └── stats.dart
│   └── enums
│       └── pokemon_type.dart
├── main.dart
├── models
│   └── pokemon.dart
├── page
│   ├── battle.dart
│   ├── home.dart
│   └── info.dart
└── router.dart

7 directories, 11 files
```
:::note info
今回はdomain配下のディレクトリを中心に実装していきます。
:::

```dart:lib/models/pokemon.dart
class Pokemon {
  final String name;
  final String imageUrl;
  final List<Move> moves;

  Pokemon({required this.name, required this.imageUrl, required this.moves});
}

class Move {
  final String name;
  final int power;

  Move({required this.name, required this.power});
}
```

```dart:lib/domain/entities/move.dart
class Move {
  final String name;
  final int power;

  Move({required this.name, required this.power});
}
```

```dart:lib/domain/entities/stats.dart
class Stats {
  final int hp;
  final int attack;
  final int defense;
  final int speed;

  Stats({
    required this.hp,
    required this.attack,
    required this.defense,
    required this.speed,
  });
}
```

```dart:lib/domain/enums/pokemon_type.dart
enum PokemonType {
  fire,
  water,
  grass,
  electric,
}
```
READMEにはこれ書こう !

# 目次
1. [きっかけ](https://qiita.com/drafts/a83c51c5586a3d4e51c1/edit#%E3%81%8D%E3%81%A3%E3%81%8B%E3%81%91)
2. [READMEとは](https://qiita.com/drafts/a83c51c5586a3d4e51c1/edit#readme%E3%81%A8%E3%81%AF)
3. [READMEに何書く?](https://qiita.com/drafts/a83c51c5586a3d4e51c1/edit#readme%E3%81%AB%E4%BD%95%E6%9B%B8%E3%81%8F)
4. [追記作成したREADME](https://qiita.com/drafts/a83c51c5586a3d4e51c1/edit#%E8%BF%BD%E8%A8%98%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9Freadme)
5. [誰が見てもわかるように](https://qiita.com/drafts/a83c51c5586a3d4e51c1/edit#%E8%AA%B0%E3%81%8C%E8%A6%8B%E3%81%A6%E3%82%82%E3%82%8F%E3%81%8B%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB)
6. [最後に](https://qiita.com/drafts/a83c51c5586a3d4e51c1/edit#%E6%9C%80%E5%BE%8C%E3%81%AB)



# きっかけ
環境構築に関しての記載がREADMEにほぼない状態でPC移行作業を行い、
環境構築の大変さを改めて実感したこと

# READMEとは
>コードを閲覧するエンジニア、特に初めてのユーザーに方向性を示すことを目的


https://google.github.io/styleguide/docguide/READMEs.html#:~:text=styleguide-,README.md%20files,-About%20README.md


>プロジェクトの目的を説明し、インストール手順を提供し、使用方法に関するガイダンスを提供し、プロジェクトに貢献する方法に関する情報を含むガイドとして機能します。

https://wengerk.medium.com/why-having-a-readme-on-your-internal-project-is-essential-c85cb9dd8e65

# READMEに何書く?
>オープンソース プロジェクトと内部プロジェクトでは対象ユーザーが異なるため、README ではその違いを反映する必要があります

__1. コードの目的に関する情報__
このパッケージ/ライブラリには何が含まれており、何に使用されるのか。

__2. コードの使用方法およびビルド方法の説明__
環境構築や実行方法など

__3. 連絡先__
恐らく、オープンソースの場合はEmailアドレスなど
内部プロジェクトの場合は担当課や担当チームなど

__4. ステータス__
このパッケージ/ライブラリが非推奨かどうか、一般リリース用かどうかなど

__5. 詳細情報: 詳細なドキュメントを参照できる場所__
より詳細な概念情報については、overview.md ファイルを参照してください

# 追記作成したREADME
追記部分 : 環境構築、環境変数
```README.md
Project Name
これこれこうこう、こういうプロジェクトです。

ファイル構成
Project
 ├── main.py
 ├── lib
     ├── submain.py
     └── manage.py
 ├── log
     └── app.log
 ├── .env
 ├── .gitignore
 ├── config.ini
 ├── README.md
 └── requirements.txt


環境構築
サイトからダウンロードが必要な場合
Python
https://www.python.org/

システム環境変数設定が必要な場合
C:\User\user_name\AppData\...
C:\Program file\...

システム環境変数確認コマンド
python --version

実行方法
pip install -r requirements.txt

./venv/Scripts/activate
python main.py

※ batファイルでの実行の場合
batの置き場所、実行方法記載する

資料
Project Name Flowchart
Path/to/the/flowchart(フローチャートなどある場合保存先のパス)
APIなど使用した場合のドキュメント先
https://developers.google.com/gmail/postmaster?hl=ja

```

# 誰が見てもわかるように

- 『先にこのライブラリのインストールを行う』等、
ソースコード内には書かない !
<br></br>
- これくらいわかるやろ。と思うものも記載してください
  - わかりやすく、丁寧なREADMEになる:sparkles:
  - 自分のように未経験者がみる可能性もある
  (めちゃくちゃありがたい:tulip:)
<br></br>
<br></br>

他気づいたことあれば追記していきます。

# 最後に
最後まで読んでいただきありがとうございます !

この項目足りない！これもあったほうが良いよ！などありましたら、
コメントお願い致します:bow_tone1:
【新入社員必見】エクセルの独自ショートカットで作業効率アップ！

# 概要
皆さんはエクセルのショートカットってどのくらい覚えておりますか？
コピー＆ペーストなどの共通なものから、シート移動やセルの末尾移動などエクセル独自のものもあり、それこそショートカットの数は無限とあるのではないでしょうか？

しかも、なかなか使わない機能のショートカットもあるせいで、ショートカット自体が複雑になってしまっていて、不便に思うこともあります。

でも、エクセルやワードに代表されるOfficeアプリって、機能に対してショートカットを割り振ることが出来るって知ってました？
それが、『クイックアクセスツールバー』という機能になります。
（下記の図の赤枠部分になります。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/3802addd-2c88-29a0-1f63-0c08a6fa225f.png)

# 機能について
例えば、下記は私のエクセルのクイックアクセスツールバーの設定になりますが、
『書式のコピー／貼り付け』と頻繁に使うものから、『値の貼付け』というよく使うけどリボンからたどっていかないといけない機能、『カメラ』というそもそもデフォルトのリボンのどこにも配置されていない機能を設定することも出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/084bbf17-2a8d-34b8-74ca-d5782a758ca4.png)


それが私の場合で行くと
・『書式のコピー／貼り付け』：ALT＋1
・『値の貼付け』：ALT＋2
・『カメラ』：ALT＋3
で実行できます。
そうなんです！『クイックアクセスツールバー』は左から『ALT＋N』でアクセスできるんです！
（「ALT」キーを押すと、ALTキーと何を押せばよいか出てきます！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/9c306ce3-9374-9c3b-2d2e-50147345dc0f.png)


# クイックアクセスツールバーの設定
ではクイックアクセスツールバーの設定の仕方を見ていきましょう。

**➀、リボンの「ファイル」をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/0ba914ce-fc6d-dec2-4c7d-bbb492816409.png)

**➁、「その他のオプション」をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/ce8eb611-ed19-a9b1-7af1-9813338b2a81.png)

**➂、「Excelのオプション」の「クイックアクセスツールバー」を選択**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/ddcacb61-0172-243f-b542-4020859e238e.png)

**➃、クイックアクセスツールバーの設定が表示される**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/690a1603-5fc9-b8d5-6090-1eef28b51883.png)


**➄、コマンドの選択をクリックし、「すべてのコマンド」を選択**
※こちらを行わないと『カメラ』などのマイナーな機能は表示されないので、お気をつけを!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/42aed164-1991-a358-71b6-174e99e25577.png)

もちろん、選択後、順番を入れ替えることでショートカットの「ALT＋N」の「N」の部分を変更可能ですので、使いやすい設定を見つけてみてくださいな！

はい、本日は以上です。
是非、試してみてくださいね！！

# 最後に
最後になりますが、この記事が皆さんの成長の少しでも手助けになることを祈って、この記事を閉めたいと思います。
最後までお読みいただきありがとうございました。
Qiitaで見たReactロードマップを実践する ~TODOアプリ編~

# はじめに
前回に続きQiitaで見たReactロードマップのSTEP3をやってみました。ロードマップの参考記事と前回の記事は以下になります。

https://qiita.com/Sicut_study/items/78910cd8d103b8d45a73

https://qiita.com/bisketoriba/items/dde798808498d0c26c42
# 作ったもの
勉強記録アプリとなっていますが中身はTODOアプリです。元のロードマップのものと少しだけデザインを変えて実装しました。コードは[こちら](https://github.com/hirohiro-sys/react-roadmap/tree/main/STEP3/todo-app)になります。

![スクリーンショット 2024-07-06 14.34.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/3f82f8bc-dc36-6ca5-4f2c-4ba3c5aa66a9.png)

今回は新しくTypescript、react icons、styled componentsを取り入れました。日付を扱えるようにする箇所やTypescriptのエラーで少し悩みましたが、そこはGPTさんで解決しました。

# おわりに
まだSTEP1のインプットが全部終わっていないので、早く終わらせて最終ステップの個人開発に入りたいと思います。最終ステップではReactの復習も兼ねてReactに関する簡単なクイズアプリを作成する予定です。

# 次回の記事

https://qiita.com/bisketoriba/items/1a56b91648e77b1f4864
Goでベンチマークを測ってみた

## はじめに
Goで関数のパフォーマンスを測ってみたいと思い、調べて使ってみました。

## コード
文字列をループで回して結合する関数
stringsのJoinで結合する関数
どちらのほうがパフォーマンスがいいか計測してみます。
```main.go
package main

import "strings"

func ConcatenateStrings(strs []string) string {
	var result string
	for _, str := range strs {
		result += str
	}
	return result
}

func JoinStrings(strs []string) string {
	return strings.Join(strs, "")
}

func main() {
	// main関数には実行コードがなくても大丈夫です
}
```

ここでは、1000個の配列テストデータを作成して、それを対象関数に渡しています。
testing.Bがベンチマーク用のパッケージになります。
```main_test.go
package main

import (
	"testing"
)

func generateTestData(n int) []string {
	strs := make([]string, n)
	for i := 0; i < n; i++ {
		strs[i] = "test"
	}
	return strs
}

func BenchmarkConcatenateStrings(b *testing.B) {
	strs := generateTestData(1000)
	for i := 0; i < b.N; i++ {
		ConcatenateStrings(strs)
	}
}

func BenchmarkJoinStrings(b *testing.B) {
	strs := generateTestData(1000)
	for i := 0; i < b.N; i++ {
		JoinStrings(strs)
	}
}

```

## 動かしてみる
3105や141476は、実行した回数
ns/opは、１回あたりの実行に掛かったナノ秒
B/opは、１回あたりのアロケーションで確保したメモリ容量
allocs/opは、1回あたりのアロケーション回数
```zsh
go test -bench=. -benchmem
```
実行速度的にもメモリ的にも、strings.Join()の方が優秀ということが分かった。
```zsh
goos: darwin
goarch: amd64
pkg: github.com/xxxxx/xxxxx
cpu: Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
BenchmarkConcatenateStrings-4               3105            402025 ns/op         2137578 B/op        999 allocs/op
BenchmarkJoinStrings-4                    141476              7990 ns/op            4096 B/op          1 allocs/op
PASS
ok      github.com/xxxxx/xxxxx   3.652s
```
[備忘録]　IT用語について分かったことをまとめてみた ~ver.3

# はじめに
こんにちは，Umamusume22です．今回の記事ではよく使うIT用語についてまとめてみました．分かっているようで分かっていなかったりします．(私の場合)

# 備忘録
#### スケーラビリティ[1]
- 負荷が増えたときに容易に性能を上げられるかという意味
    - 規模が変化したときにどれくらい柔軟に対応できるか
    - どれくらい拡張性があるか
        - 高い，低いまたはある，ないで表現する
        - pcのスペックを落とす場合，維持費を安くしたい

#### ライブラリ[2]
- 便利なプログラムの部品を沢山集めて，ひとまとめにしたファイルのこと
- ありがちな処理をプログラムの部品の形で沢山詰め込んだファイルのこと
    - 単体ではプログラムとして動作しない

#### モジュール[3]
- 部品のこと
- 何かの部品のこと
- ライブラリと似ているから厄介

#### サイクルタイム[4]
- 1回行うのにかかる時間のこと
- 2回以上繰り返して何かをやる時の1回にかかる時間のこと
    - サイクルは周期という意味

# 最後に
今回も記事の内容が短くて申し訳ありません．知っていて当然なIT用語シリーズでしたが意外に説明を求められたら答えられない用語です．(あくまで私の話ですが)
引き続きIT用語について分かったことをアウトプットしていきます
開発中，単語の意味が分からなくてこっそり調べたりします
読んでいただきありがとございました!

※ウマ娘の声をフーリエ変換した記事や水栓の開閉判定をLineに通知する記事も書いています．suzuが私です．興味がある方はぜひご覧ください！
https://vigne-cla.com/31-1/#toc5

※noteも始めました．
https://note.com/madoka235/n/nbba2153326e1

ぜひフォローよろしくお願いします!


# 参考文献
[1] "「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典"
https://wa3.i-3-i.info/word110379.html

[2] "「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典"
https://wa3.i-3-i.info/word1473.html

[3]　"「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典"
https://wa3.i-3-i.info/word12243.html

[4] 　"「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典"
https://wa3.i-3-i.info/word15659.html
私のGitコマンドチートシート（初心者目線）

# 自分の開発用にGitコマンドのチートシート（随時更新）

### 背景
開発時に別プラットフォームでチートシートまとめているより、
Qiitaに投稿してチートシートを参照する方がモチベーション上がると思い投稿しました。

また、初心者ならではの視点で、それぞれのコマンドがどういう場面で使いたくなったのか、という視点でまとました。

そのため、敢えて初心者がこういう風に捉えているという文言で書いているのでご了承ください。


### Gitコマンドチートシート
| どういう場面で使う？ |コマンド  |動作 |
| ---- | ---- |-----|
| githubやcodecommit上にあるデータをPCに持ってきたい | git clone ＜URL＞ |サーバー上から変更履歴を複製|
| 今どのブランチを指定しているか知りたい | git branch –a |ローカル・リモートブランチを表示|
|ブランチを切り替えたい|git switch <ブランチ名>|指定しているブランチを変更|
|新しいブランチを作成したい|git checkout –b <ブランチ名> origin/＜リモートブランチ名＞|指定した名前のブランチを作成（origin ～の内容を踏襲したものとなる）|
|変更されたファイルの差分が見たい|git diff|ワークツリーとインデックスの差分を表示|
|ファイルをステージングしたい|git add .|変更したすべてのファイルをステージング|
|コミット前のステージング状況が知りたい|git status|コミット前のステージングにあるものと、変更されているがaddされていないものを表示|
|ファイルをコミットしたい|git commit -m “コメント”|addした全てのファイルにコメントをつけてコミット|
|変更履歴を確認したい（コミット後）|git log　　⇒qで元に戻る　|レポジトリの変更履歴を確認|
|マージしたい（相手のブランチを今いるブランチに）|git merge <相手ブランチ名>|自分の今いるブランチに<br>相手ブランチがマージされる|
|コミットした内容をリモートに反映させたい|git push origin <ブランチ名>|リモートレポジトリに<br>ローカルでの変更内容をアップロード|
|リモートレポジトリの情報をローカルに反映したい|git fetch|リモートレポジトリと通信し、<br>そのリポジトリにあって<br>現在のリポジトリにない情報を全て取得|
|リモートレポジトリのブランチ内容をコピーしたい|git pull origin <ブランチ名>|リモートレポジトリ上での変更を取得してローカルのファイルを書き換える|
|add前のローカル変更を戻したい、<br>編集してステージングしていないファイルをもとに戻したい|git checkout -- <ファイル名>|手元で変更したが、インデックスに登録されていないファイルを元に戻す|
|add直後の変更を取り消したい|git reset HEAD -- <ファイル名>|インデックスに登録したファイルを取り消し|
|Github上で閉じたブランチをローカルレポジトリからも消したい|git fetch --prune|リモートリポジトリで削除されたブランチをローカルからも削除|
|マージ後のローカルブランチを削除したい|git branch –d　＜ブランチ名＞|ローカルブランチを削除(-dを-Dにすると強制削除）|
|直前のコミットを取り消したい|git reset --soft HEAD^|1つ前のコミットの実行を取り消す|
|一時的に過去のcommitに戻って操作したい|git checkout <コミット名>|ブランチを過去のコミットに戻す|
|最新のcommit状態に戻したい|git checkout <ブランチ名>|現在のcommit状態に戻す過去のcommitに戻ると、操作しているブランチとは異なるブランチを一時的に作成している|
TextGrid.API

プレーンテキスト上で 小さなテーブルが
欲しい時があります。
とにかく コレ作るのは 邪魔くさいんで
自動作表APIを 用意しました。
ご自由に ご利用ください。

[TextGrid.API](https://twilight-bluesy.net/_etc/dsAdoc-v10/index.html?srcD=https%3A%2F%2Ftwilight-bluesy.net%2F__YORI%2Fcont%2F&srcF=x126.adoc&docT=%E3%82%88%E3%82%8A%E3%81%BF%E3%81%A1.x126&code=x126) ( TwilightBluesy )

```shell:boot.sh
#!/bin/bash
# ----------------------
clear
cd `dirname $0`
# ----------------------
r_gH=./__gH.txt
r_gZ=./__gZ.txt
r_pH=./__pH.txt
r_pZ=./__pZ.txt
# ----------------------
if [ -e ${r_gH} ]; then rm ${r_gH}; fi
if [ -e ${r_gZ} ]; then rm ${r_gZ}; fi
if [ -e ${r_pH} ]; then rm ${r_pH}; fi
if [ -e ${r_pZ} ]; then rm ${r_pZ}; fi
# ----------------------
_URL="https://twilight-bluesy.net/_api/211/"
hURL="${_URL}hLin.php"
zURL="${_URL}zLin.php"
# ----------------------
padH=2
dSrc="110,ポリス;119,消防;117,Time_Signal;177,天気予報;171,災害伝言ダイヤル"
# ----------------------
data="padH=${padH}&dSrc=${dSrc}"
# ----------------------
curl -X GET  ${hURL}?${data}    > ${r_gH}
curl -X GET  ${zURL}?${data}    > ${r_gZ}
curl -X POST ${hURL} -d ${data} > ${r_pH}
curl -X POST ${zURL} -d ${data} > ${r_pZ}
# ----------------------
```
【注意】OpenAI APIの無料クレジットが廃止されてしまいました。利用には最低$5のクレジットの購入が必須です。

# 事の起こり
ChatGPTで知られるOpenAIは気軽にChatGPTをはじめとする最新のLLMを利用出来る様にAPIを公開しています。このAPIを無料で試せる様に3ヶ月間有効な$5分の無料クレジットが付与されていました。この無料クレジット取得には以下の条件が求められます。
* OpenAIのアカウント登録に<font color=RED>初めて利用する</font>メールアドレス
* OpenAIアカウントに初めて紐付ける<font color=RED>初めて利用する</font>電話番号

筆者は社内の技術コミュニティではOpenAI APIを利用してきましたが、プライベート用にアカウントを取得したいと考え、上記条件を満たす様に、OpenAIアカウントに紐付いていないプライベートのメールアドレスと電話番号で登録を実施しました。ところが。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/c0ff414b-f36f-fe5a-3f7a-0a3a953ecd60.png)

無料クレジットが付与されません！？メールアドレス、電話番号は初めてOpenAIアカウントに紐付けるものであるため、無料クレジットは即座に付与される筈です。原因が分からないため、ネットを調べていると、以下の記事を見つけました。

https://qiita.com/kurata04/items/a10bdc44cc0d1e62dad3

この記事に気になる記載が有りました。

> 以前は無料クレジットが貰えていましたが廃止されたようです

無料クレジットが廃止された！？日本語で検索してもそれらしい記事がヒットしません。無料クレジットの貰い方という記事は大量にヒットしますが、廃止について言及された記事は上記記事を除いて見つけられませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/57e5223f-1aa4-be5c-1b80-9da98c2a33a6.png)

そこで、英語で検索してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/a0b0853b-f62b-a2fd-9c58-179acdc7e5d0.png)

公式のDeveloper Forumへの以下の投稿が見つかりました。

https://community.openai.com/t/is-openai-free-trial-credits-have-been-discontinued/809503

今年の初め(つまり2024年の初め)に廃止されている！？

![openai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/282735eb-d36b-968b-2cf9-150c1b8ec643.png)

> In order to use the API you need to fund your account with a minimum balance of USD 5.
> API を使用するには、最低 5 米ドルの残高をアカウントに入金する必要があります。

ということで、利用にはクレジットカードを登録して、最低\\$5の利用クレジットを購入する必要が有ります。\\$5のクレジットでも最新のGPT-4oで100万トークン使って初めて使い切るといったレベルです。

https://openai.com/api/pricing/

# まとめ
無料クレジットが廃止されたのは残念ですが、恐らくそれだけ利用者が増えて無料クレジットで釣る必要が無くなったということでしょう。無料特典は<font color=RED>いつまでも続くものではなく、いつかは終わってしまうものと考えて、早めに試すことが肝要です。</font>但し、無料クレジットでは最新のモデルが実行出来ません。筆者は、この後早速\\$5のクレジットを購入することにします。
macにPowerShellをインストール

macにPowerShellをインストールする。

macOS への PowerShell のインストール
https://learn.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-on-macos?view=powershell-7.4
<br>

記事にそって進めると、xcodeが古いというエラー。
```
$ brew install powershell/tap/powershell
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Preferences.
```
<br>

xcodeを最新化する。
```
$ sudo rm -rf /Library/Developer/CommandLineTools
$ sudo xcode-select --install
```
<br>

powershellをインストール。
```
$ brew install powershell/tap/powershell
$ pwsh
PowerShell 7.4.2
```
スクラム開発中で問題に気づくためには？成功体験から学ぶ実践的アプローチ


## はじめに
スクラム開発は、アジャイル開発手法の一つとして広く採用されています。しかし、スクラム開発を進める中で問題に気づくことができなければ、プロジェクトの成功は難しいでしょう。この記事では、スクラム開発中で問題に気づくための具体的な方法と、私の成功体験から得た実践的なアプローチを紹介します。

## デイリースクラムの重要性
デイリースクラムは、チームメンバーが毎日集まり、進捗状況や問題点を共有する場です。この短いミーティングを効果的に活用することで、問題に早期に気づくことができます。

### ポイント
- **時間厳守**: デイリースクラムは15分以内に終わらせることが理想です。
- **フォーカス**: 各メンバーが「昨日何をしたか」「今日何をするか」「障害は何か」を簡潔に報告します。
- **障害の共有**: 問題が発生した場合、その場で解決策を議論するのではなく、後で詳しく話し合うための時間を設けます。

## バックログリファインメントの活用
バックログリファインメントは、プロダクトバックログのアイテムを詳細に検討し、優先順位をつけるプロセスです。このプロセスを定期的に行うことで、潜在的な問題を事前に発見することができます。

### ポイント
- **定期的な見直し**: スプリントごとにバックログを見直し、最新の情報を反映させます。
- **チーム全体の参加**: 全員が意見を出し合い、問題点を洗い出します。
- **透明性の確保**: バックログの内容を全員が理解し、共有することが重要です。

## レトロスペクティブの実施
レトロスペクティブは、スプリントの終了後に行う振り返りのミーティングです。この場で、チームは何がうまくいったか、何が問題だったかを話し合い、次のスプリントに向けた改善策を考えます。

### ポイント
- **オープンなコミュニケーション**: 全員が自由に意見を言える雰囲気を作ります。
- **具体的なアクションプラン**: 問題点に対する具体的な改善策を決定し、次のスプリントで実行します。
- **継続的な改善**: レトロスペクティブで出た改善策を継続的に実行し、効果を確認します。

## モニタリングとアラートの設定
クラウドベンダーのサービスを活用することで、システムのモニタリングとアラートを設定し、問題が発生した際に即座に対応することができます。

### ポイント
- **リアルタイムモニタリング**: クラウドサービスのダッシュボードを活用し、リアルタイムでシステムの状態を監視します。
- **アラート設定**: 異常が発生した際に通知を受け取るためのアラートを設定します。
- **ログの分析**: ログを定期的に分析し、潜在的な問題を早期に発見します。

## 結論
スクラム開発中で問題に気づくためには、デイリースクラム、バックログリファインメント、レトロスペクティブ、そしてクラウドサービスのモニタリングとアラート設定を効果的に活用することが重要です。これらの方法を実践することで、問題を早期に発見し、迅速に対応することができます。皆さんもぜひ、これらのアプローチを試してみてください。

## 参考文献
- [Scrum Guide](https://www.scrumguides.org/)
- [AWS CloudWatch](https://aws.amazon.com/cloudwatch/)
- [Azure Monitor](https://azure.microsoft.com/en-us/services/monitor/)
スクラム開発におけるファイブフィンガーの活用法


## はじめに

スクラム開発において、チームの合意形成や意思決定は非常に重要です。その中でも「ファイブフィンガー」という手法は、シンプルでありながら効果的な方法として知られています。この記事では、ファイブフィンガーの基本的な使い方から、実際のプロジェクトでの応用例までを詳しく解説します。

## ファイブフィンガーとは？

ファイブフィンガーは、チームメンバーがある提案や決定に対してどれだけ賛成しているかを示すための手法です。各メンバーは手を挙げ、指の本数で自分の意見を表現します。

- **5本指**: 完全に賛成
- **4本指**: ほぼ賛成だが、少しの懸念がある
- **3本指**: 中立
- **2本指**: 反対だが、受け入れられる
- **1本指**: 完全に反対
- **0本指**: 強く反対

## ファイブフィンガーのメリット

### 1. 簡単で迅速

ファイブフィンガーは非常にシンプルで、特別なツールや準備が不要です。会議中に即座に実施でき、迅速にチームの意見を集約できます。

### 2. 全員の意見を反映

全員が自分の意見を表明するため、特定のメンバーだけが意見を述べることがなくなります。これにより、チーム全体の合意形成が促進されます。

### 3. 意見の違いを可視化

指の本数で意見の違いが一目でわかるため、どの部分に懸念があるのか、どの部分が合意されているのかが明確になります。

## 実際のプロジェクトでの応用例

### 1. スプリントプランニング

スプリントプランニングでは、各タスクの優先順位やスコープについてチーム全員の意見を集めることが重要です。ファイブフィンガーを使うことで、各タスクに対する賛成度を迅速に確認できます。

### 2. レトロスペクティブ

レトロスペクティブでは、過去のスプリントの振り返りを行います。ここでもファイブフィンガーを使って、各メンバーがどれだけ満足しているか、どれだけ改善が必要だと感じているかを確認できます。

### 3. デイリースクラム

デイリースクラムでは、各メンバーの進捗状況や問題点を共有します。ファイブフィンガーを使って、各メンバーがどれだけ進捗に満足しているか、どれだけ問題があるかを迅速に確認できます。

## まとめ

ファイブフィンガーは、スクラム開発における合意形成や意思決定を迅速かつ効果的に行うための強力なツールです。シンプルでありながら、全員の意見を反映し、意見の違いを可視化することで、チーム全体のパフォーマンスを向上させることができます。ぜひ、次のプロジェクトで試してみてください。
react-router-dom v6でSwitchが使えない。(export 'Switch' (imported as 'Switch') was not found in 'react-router-dom' )

## react-router-domをv5からv6.24.1へアップデートするとSwitchが使えない

エラーが発生しているコード。
```
import './App.css';

import { BrowserRouter, Link, Switch, Route, Routes } from 'react-router-dom';

import { Home } from './Home';
import { Page1 } from './Page1';
import { Page2 } from './Page2';

export default function App() {

  return (
    <BrowserRouter>
      <div className="App">
          <Link to='/'>Home</Link>
          <br />
          <Link to='/page1'>Page1</Link>
          <br />
          <Link to='/page2'>Page2</Link>
      </div>
      <Switch>
        <Route path='/page1'>
          <Page1 />
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

```

エラー内容
```
ERROR in ./src/App.js 48:35-41
export 'Switch' (imported as 'Switch') was not found in 'react-router-dom' (possible exports: AbortedDeferredError, Await, BrowserRouter, Form, HashRouter, Link, MemoryRouter, NavLink, Navigate, NavigationType, Outlet, Route, Router, RouterProvider, Routes, ScrollRestoration, UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, UNSAFE_ErrorResponseImpl, UNSAFE_FetchersContext, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, UNSAFE_ViewTransitionContext, UNSAFE_useRouteId, UNSAFE_useScrollRestoration, createBrowserRouter, createHashRouter, createMemoryRouter, createPath, createRoutesFromChildren, createRoutesFromElements, createSearchParams, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, resolvePath, unstable_HistoryRouter, unstable_usePrompt, unstable_useViewTransitionState, useActionData, useAsyncError, useAsyncValue, useBeforeUnload, useBlocker, useFetcher, useFetchers, useFormAction, useHref, useInRouterContext, useLinkClickHandler, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, useSearchParams, useSubmit)
```

## Routesを使うと解消する
v6からSwitchではなくRoutesを使って欲しいみたいです。
```diff
import './App.css';

import { BrowserRouter, Link, Switch, Route, Routes } from 'react-router-dom';

import { Home } from './Home';
import { Page1 } from './Page1';
import { Page2 } from './Page2';

export default function App() {

  return (
    <BrowserRouter>
      <div className="App">
          <Link to='/'>Home</Link>
          <br />
          <Link to='/page1'>Page1</Link>
          <br />
          <Link to='/page2'>Page2</Link>
      </div>
-     <Switch>
-       <Route path='/page1'>
-         <Page1 />
-       </Route>
-     </Switch>
+     <Routes>
+       <Route path='/page1' element={<Page1 />} />
+     </Routes>
    </BrowserRouter>
  );
}
```

switchだとlinkとの兼ね合いで到達できないパスができるバグがあったようです。
▼公式ドキュメント
https://reactrouter.com/en/main/upgrading/v5#upgrade-all-switch-elements-to-routes:~:text=React%20Router%20v6%20introduces%20a%20Routes%20component%20that%20is%20kind%20of%20like%20Switch%2C%20but%20a%20lot%20more%20powerful.%20The%20main%20advantages%20of%20Routes%20over%20Switch%20are%3A
ICPC2024 国内予選 参加記

ICPC2024国内予選にチーム「MiSuNa」として参加してきました。
# メンバー
メンバーは[miie](https://atcoder.jp/users/miie)、[superZ](https://atcoder.jp/users/superZ)、[nashisandesu](https://atcoder.jp/users/nashisandesu)(私)でした。予選一週間前は緑だった私とsuperZは、なんとかABC360で入水し、同系色チームになりました。チーム名はそれぞれの名前の最初の二文字をとって「MiSuNa」と名付けられました。
# 当日
私たちのチームは全員の使用言語が揃っていないので、実装をmiie（タイピングに魂を売っている）、考察をsuperZと私がやることにしました。ABCはmiieに実装考察を任せ、D以降を残りの二人で考察を進める作戦にしました。結果的にこの作戦は正しかったと思います。
#### ABC 実装・考察：miie
miieが爆速実装してくれました(感謝)
#### D 実装：miie, 考察：nashisandesu
ここでミラクル発生。
私が一週間前に実装したものとほぼ同じ問題が出ました。一週間前にバグり散らかした私はバグポイントを全て知っているので、miieに爆速実装を頼み、横から適時口を挟むことに。
結果的にsampleケースでも一回もバグらせることなくAC。**全体19位学内1位に躍り出ました。**
#### E 実装：miie, 考察：superZ,(nashisandesu)
Dが解けた時点でEに全員で取り組むべきという話になり、先に考察を進めていたsuperZに概要を聞き考察開始。
私は図形問題が大の苦手なので、考察が詰まってきた段階で私は早々に撤退しました。
しかし、考えていた考察が十分条件だったようでACならず。チームとして悔しい結果になりました。
#### F 考察：superZ
鏡のように空間を広げられる考察までできていましたが、及ばず。
#### G 考察：nashisandesu
問題要約をし、偶奇に注目する部分まではあっていましたが、水色が倒せる壁ではありませんでした泣

# 結果
結果としてABCD4完で全国63位学内6位でした。弊学が強すぎます笑
終了後の懇親会でコーチから「序盤ノーマークのMiSuNaが上位にいてビビった」と言っていただけたのは嬉しかったです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739888/ea1861a2-da2b-b843-5b4b-b80771ee7657.png" width=1200>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739888/e8e6236e-9ca8-e2a0-661e-fc69d40ba889.png" width=1200>
# 反省と今後
後から振り返って、D問題は私が実装すべきだったと思います。後半の問題で図形が多いことは目に入っていたので、役に立たない私が考察するよりは、miieの考察時間を増やすべきだったなと。~~それより早く私の図形アレルギー治してください。~~
私は早生まれではないので、今年のICPCが最初で最後となりましたが、もっと早く出会いたかったです。私のICPCは終わってしまいましたが、弊学からは3チーム本選に行くので応援側に回ろうと思います！
誘ってくれた御二方と運営の方々、本当にありがとうございました！
GitHub Actionsで実行しているテストが通らないとマージできないようにするには、ブランチ保護の設定でステータスに`job_id`を入力する

# 環境
* Python 3.11

# はじめに
TravisCIでPythonコードのテストとリントを実行していましたが、諸々の理由でGitHub Actionsへ移行することになりました。


### TravisCIの設定ファイル

```xml:.travis.yml
dist: xenial
language: python
python:
  - "3.11"
  - "3.12"
install:
  - pip install poetry
  - travis_retry poetry install
script:
   - make lint
   - make test
branches:
  only:
  - main
```

### GitHub Actionsの設定ファイル
設定ファイルは"Python application"というテンプレートを利用しました。
https://github.com/actions/starter-workflows/blob/main/ci/python-app.yml

https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python を参考にしました。


```yaml:.github/workflows/lint-test.yml
name: Python application

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

permissions:
  contents: read

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        python-version: ["3.11", "3.12"]

    steps:
      - uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip "poetry<1.9"
          poetry install
      - name: Lint
        run: |
          make lint
      - name: Test
        run: |
          make test
```

### Makefile

```plain:Makefile
ifndef SOURCE_FILES
	export SOURCE_FILES:=src
endif
ifndef TEST_FILES
	export TEST_FILES:=tests
endif

.PHONY: lint format test

format:
	poetry run ruff format ${SOURCE_FILES} ${TEST_FILES}
	poetry run ruff check ${SOURCE_FILES} ${TEST_FILES} --fix-only --exit-zero
	
lint:
	poetry run ruff check ${SOURCE_FILES} ${TEST_FILES}
	poetry run mypy ${SOURCE_FILES} ${TEST_FILES}

test:
	poetry run pytest tests
```

# Pull Requestのマージをブロック
GitHub Actionsでのリントとテストが成功しないと、マージできないようにしたいです。
以下の手順で対応しました。

1. "Sttings"タブから"Branch protection rule"を設定する画面に移動する
2. "Require status checks to pass before merging"チェックボックスをONにする
3. ステータスに"build"を入力する。検索候補である"build (3.11)"と"build (3.12)"を選択する
    * "build"は、GitHub Actionsの設定ファイルに記載されている`jobs`配下の`build`というjob_idに対応する


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37903/c9d2c3d2-94c3-d824-b61e-80158323be3e.png)

ちなみに、TravisCIの場合は、ステータスに"travis"と入力して"Travis CI - Branch"と"Travis CI - Pull Request"を選択していました。
Github Actionsに移行した際、どのようなスタータスが候補になるのか分からなくて、少しハマりました。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37903/fb975147-1ec7-eaa0-ba82-0be9051f0ec1.png)

# 所感
* ステータスは、最初から選択できる候補をすべて表示して欲しかった。そうすれば、今回ハマることはなかったと思う。
* GitHub Actionsの場合、`matrix`に指定したPythonのバージョンごとにステータスを選択できる。便利。




# 参考にしたサイト
https://qiita.com/ghaaaaana/items/80c1124a605efc9b5f73

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_id