OmniAICreator/Qiita-1.07M huggingface dataset:
Docker,docker-composeコマンド

# Docker コマンド一覧

## イメージ関連
- `docker build -t <イメージ名> .`
  - 現在のディレクトリから Docker イメージをビルドします。
- `docker images`
  - ローカルに存在する Docker イメージの一覧を表示します。
- `docker rmi <イメージID>`
  - 指定したイメージを削除します。

## コンテナ関連
- `docker run -d --name <コンテナ名> <イメージ名>`
  - 指定したイメージから新しいコンテナをバックグラウンドで起動します。
- `docker ps`
  - 実行中のコンテナの一覧を表示します。
- `docker ps -a`
  - 全てのコンテナ（停止中も含む）の一覧を表示します。
- `docker stop <コンテナID>`
  - 指定したコンテナを停止します。
- `docker rm <コンテナID>`
  - 指定したコンテナを削除します。

## ネットワーク関連
- `docker network ls`
  - Docker ネットワークの一覧を表示します。
- `docker network create <ネットワーク名>`
  - 新しい Docker ネットワークを作成します。
- `docker network rm <ネットワーク名>`
  - 指定した Docker ネットワークを削除します。

## ボリューム関連
- `docker volume ls`
  - Docker ボリュームの一覧を表示します。
- `docker volume create <ボリューム名>`
  - 新しい Docker ボリュームを作成します。
- `docker volume rm <ボリューム名>`
  - 指定した Docker ボリュームを削除します。
  - 
# Docker Compose コマンド一覧

## 基本操作
- `docker compose up`
  - `docker-compose.yml` ファイルに基づいてサービスを起動します。
- `docker compose down`
  - `docker-compose.yml` ファイルに基づいて起動したサービスを停止し、コンテナを削除します。
- `docker compose start`
  - 停止中のサービスを再起動します。
- `docker compose stop`
  - 実行中のサービスを停止します。
- `docker compose restart`
  - 実行中のサービスを再起動します。

## サービス管理
- `docker compose ps`
  - 現在のプロジェクトのサービスの状態を表示します。
- `docker compose logs`
  - サービスのログを表示します。
- `docker compose exec <サービス名> <コマンド>`
  - 実行中のサービス内でコマンドを実行します。
  - 例: `docker compose exec web /bin/bash`

## ビルド関連
- `docker compose build`
  - `docker-compose.yml` ファイルに基づいてサービスをビルドします。
- `docker compose build --no-cache`
  - キャッシュを使用せずにサービスをビルドします。

## その他
- `docker compose config`
  - `docker-compose.yml` ファイルの内容を検証し、表示します。
- `docker compose pull`
  - サービスのイメージをリポジトリからプルします。
- `docker compose push`
  - サービスのイメージをリポジトリにプッシュします。
- `docker compose rm`
  - 停止中のサービスのコンテナを削除します。
Sidekiq、Redis って何が嬉しんだっけ？ 〜ECサイトを具体例にまとめてみた〜 [Rails]

# はじめに
 本記事は、私自身が開発を行う中で、「結局、Sidekiq、Redis って何が嬉しんだっけ？」 という疑問に対して、それぞれの特徴や、どのような通信の順序でシステムに恩恵を与えてくれているのかについて備忘録も兼ねて整理したものとなります。
 また、具体例があると分かりやすいので、ECサイトを元に記述しています。

 # 具体例として利用するECサイトのインフラ構成図
 Railsアプリケーションでよく見る構成図だと思います。
 また、Renderを利用していますが、AWSでもheroku でもOKです。（もちろん、DBもpostgres以外でもOKです）
 
 ![Frame 6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552488/b2256aba-b6fa-fa1b-d6b1-4b933fa48b15.jpeg)

# 基本説明のおさらい

### Sidekiq とは？
 Sidekiqは、バックグラウンドジョブを非同期に処理するためのツールです。これにより、時間がかかるタスク（例、商品注文確定メールの送信）をWebリクエストの外で実行でき、アプリケーションのレスポンスを高速化できます。

 **主な特徴**
 - 非同期処理
     - ジョブを即座に実行せず、バックグラウンドで処理
 - 並行処理
     - 複数のジョブを同時に処理できるため効率的
 - 信頼性
     - Redisを使ってジョブキューを管理し、ジョブが失われないようにする
 - 管理画面でのモニタリング可能
     - ジョブの状況を簡単に監視できることで、問題発生時にトラブル対応が容易になる

### Redisとは？
　Redis（Remote Dictionary Server）は、インメモリのデータ構造ストアであり、データベース、キャッシュ、およびメッセージブローカーとして利用されるオープンソースのソフトウェアです。高いパフォーマンスと多機能性を持ち、多くのアプリケーションで広く使用されています。

 **主な特徴**
 - 高速性
     - データは全てメモリ上に格納されるため（インメモリデータベース）、高速な読み書きが可能
 - 多様なデータ構造
     - String, List, Set, Hash などなど様々なデータ構造に対応
 - 永続性
     - データをメモリ上に保持するだけでなく、ディスクに永続化することもできる

# 本題 ~ECサイトを元に考えてみた~
Sidekiq, Redis の概要がわかったところで、「ECサイトでのユーザーからの購入」などのシナリオに沿って整理していきたいと思いますー！

### ①ユーザーが商品を購入する
1. **ユーザーが商品をカートに追加**
    - フロントエンド: ユーザーが商品詳細ページで「カートに追加」ボタンをクリック。
    - バックエンド: このリクエストはRailsコントローラーに送信され、カート（通常はセッションまたはデータベース）に商品が追加される。

2. **ユーザーが決済ページに移動**
    - フロントエンド: ユーザーがカート画面から「決済」ボタンをクリック。
    - バックエンド: Railsコントローラーがカートの内容を確認し、決済ページを表示します。

3. **ユーザーが注文を確定**
    - フロントエンド: ユーザーが支払い情報を入力し、「注文を確定」ボタンをクリック。
    - バックエンド:
    - 注文データの保存: RailsコントローラーがPostgreSQLに注文データを保存。
    - バックグラウンドジョブのキューイング: 注文確定後、**Sidekiq**を使って以下のジョブを非同期で処理。
        - 注文確認メールの送信
        - 在庫の更新（更新後在庫数 = 更新前在庫数 - 購入数）
4. **注文確認メールの送信（バックグラウンド）**
    - **Sidekiqジョブ**: OrderConfirmationJobがRedisのキューから取り出され、Sidekiqワーカーによって実行される。
    - **メール送信処理**: UserMailer.order_confirmation(order).deliver_nowを実行。
    - 状態更新: 処理結果をPostgreSQLに記録
5. **在庫の更新（バックグラウンド）**
    - **Sidekiqジョブ**: InventoryUpdateJobが**Redis**のキューから取り出され、Sidekiqワーカーによって実行される
    - 在庫減少処理
    - 状態更新: 処理結果をPostgreSQLに記録
6. **管理者への通知**
    - **Sidekiqジョブ**: 新しい注文があることを管理者に通知するジョブ（例：Slackなどに通知）も非同期で実行

### ②ユーザーがアカウント情報を更新する
1. **ユーザーがアカウント情報を入力**

- フロントエンド: アカウント設定ページで情報を入力し、「保存」ボタンをクリック。
- バックエンド: 入力されたデータがRailsコントローラーに送信され、データベースに保存される。

2. **バックグラウンドでの追加処理**

**Sidekiqジョブ**: ユーザー情報更新後、確認メールを送信するジョブがキューに追加される。
確認メールが送信され、ユーザーにアカウント情報の更新が通知される。

# まとめ
SidekiqとRedisを活用することで、時間のかかる処理をバックグラウンドで実行し、ユーザー体験を向上させることができます。

最後までお読みいただきまして、ありがとうございました！
この記事が、どなたかのご参考になれば嬉しいです！
iOSで位置情報を取得する

iOSアプリで位置情報を取得するための基本的な方法をSwiftUIを使用して解説します。位置情報を取得するには、`CoreLocation`フレームワークを利用します。以下はその基本的な手順です。
<br>

1. **必要な権限の設定**: まず、位置情報を取得するために必要な権限を`Info.plist`ファイルに追加します。以下の2つのキーを追加します。
    - `NSLocationWhenInUseUsageDescription`: アプリがフォアグラウンドで動作しているときに位置情報を使用する理由を説明する文字列。
    - `NSLocationAlwaysUsageDescription`: アプリがバックグラウンドで動作しているときにも位置情報を使用する場合。

    
    ```xml
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>アプリの使用中に位置情報を使用します。</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>バックグラウンドでも位置情報を使用します。</string>
    ```

<br>

2. **CoreLocationフレームワークのインポート**: Swiftファイルで`CoreLocation`フレームワークをインポートします。
    

    
    `import CoreLocation`

    <br>
    
3. **位置情報管理クラスの作成**: 位置情報を管理するクラスを作成します。このクラスは`CLLocationManagerDelegate`プロトコルに準拠します。
    
    ```swift
    import CoreLocation
    import SwiftUI
    
    class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
        private let locationManager = CLLocationManager()
        @Published var location: CLLocation? = nil
    
        override init() {
            super.init()
            self.locationManager.delegate = self
            self.locationManager.requestWhenInUseAuthorization()
            self.locationManager.startUpdatingLocation()
        }
    
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            if let location = locations.last {
                self.location = location
            }
        }
    }
    ```
    <br>
    
4. **SwiftUIビューでの使用**: 作成した`LocationManager`をSwiftUIビューで使用します。
    
    ```swift
    struct ContentView: View {
        @StateObject var locationManager = LocationManager()
    
        var body: some View {
            VStack {
                if let location = locationManager.location {
                    Text("Latitude: \(location.coordinate.latitude)")
                    Text("Longitude: \(location.coordinate.longitude)")
                } else {
                    Text("Getting location...")
                }
            }
            .onAppear {
                locationManager.locationManager.requestWhenInUseAuthorization()
            }
        }
    }
    ```
    
<br>
これで、位置情報が取得できるようになります。`LocationManager`クラスは位置情報の更新を監視し、`ContentView`に位置情報を表示します。この基本的な構成を基に、さらなる機能を追加してアプリを発展させていくことができます。
python の練習。 オーディプレイヤーの作成

pythonの練習です。
pythonでオーディオ再生するのってどうやるのか気になって調べました。

１つの解として、pygameパッケージする方法がありました。

```py
import pygame
# 初期化
pygame.mixer.init()
# オーディオの設定
pygame.mixer.music.load("オーディオファイルパス")
# 再生
pygame.mixer.music.play()
# 停止
pygame.mixer.music.stop()
```

オーディオコントロールが簡単におこなえそうです！

---

GUIはtkinterで作ってみます。

```
import tkinter as tk

# ボタンを作成＋ファイルロードイベントを設定
load_button = tk.Button(self.tk_root, text="Load", command=self.load_audio)
# 同じくオーディオ再生イベントを設定
play_button = tk.Button(self.tk_root, text="Play", command=self.play_audio)
# 停止イベントを設定
stop_button = tk.Button(self.tk_root, text="Stop", command=self.stop_audio)
```

ファイル読み込みもtkinterでできました。
pythonって楽ちん。

```py
from tkinter import filedialog
audio_file = filedialog.askopenfilename(filetypes=[("Audio Files", "*.mp3")])
```

---

全体プログラムはこんなになりました。

```py
import pygame
import tkinter as tk
from tkinter import filedialog

class AudioPlayer:
    def __init__(self, tk_root):
        self.tk_root = tk_root
        self.tk_root.title("Audio Player")

        self.tk_root.geometry("480x320")
        self.tk_root.resizable(False, False)
        
        self.init_pygame()
        self.create_widgets()

    def init_pygame(self):
        pygame.mixer.init()

    def load_audio(self):
        self.audio_file = filedialog.askopenfilename(filetypes=[("Audio Files", "*.mp3")])
        if self.audio_file:
            pygame.mixer.music.load(self.audio_file)
            self.status_label.config(text=f"Loaded: {self.audio_file}")

    def play_audio(self):
        pygame.mixer.music.play()
        self.status_label.config(text="Playing")

    def stop_audio(self):
        pygame.mixer.music.stop()
        self.status_label.config(text="Stopped")

    def create_widgets(self):
        load_button = tk.Button(self.tk_root, text="Load", command=self.load_audio)
        play_button = tk.Button(self.tk_root, text="Play", command=self.play_audio)
        stop_button = tk.Button(self.tk_root, text="Stop", command=self.stop_audio)
        
        load_button.pack(pady=5)
        play_button.pack(pady=5)
        stop_button.pack(pady=5)
        
        self.status_label = tk.Label(self.tk_root, text="No file loaded")
        self.status_label.pack(pady=5)

if __name__ == '__main__':
    tk_tk_root = tk.Tk()
    app = AudioPlayer(tk_tk_root)
    tk_tk_root.mainloop()
```

結果。

![Screenshot from 2024-07-07 11-06-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812996/8de472a7-7e3e-f890-4b5a-0a5480e8aaf3.png)


見栄えのする画面ではないですが、とりあえずできました！
スクショじゃわかりませんが、ちゃんと再生できました！
bash組み込みのtimeコマンドでrealの時間のみを取得したい

bashでtimeコマンドを実行する場合。

shellに組み込みされているtimeコマンドがありますが。
それ以外にも外部コマンドとしてgnuが提供しているtimeコマンドもインストールされており。

gnu版timeコマンドもインストールされている場合などで、単純にtimeとしてコマンドを実行すると、bash組み込みのtimeが優先して実行されます。
なおbash組み込みのtimeコマンドとgnu版timeコマンドではパラメータや出力結果が異なります。

今回は実行ログなどへの処理時間のみの書き込みを想定して、shell組み込みのbashコマンドの実行結果から実行時間のみ取得する方法について説明します。

## 組み込み版timeの出力について

組み込み版timeを利用してsleep 2を実行し場合の出力は下記画像のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/1013b564-3bb0-2a51-2334-6a92d570cccf.png)

bash組み込みのtimeコマンドは実行結果を標準エラーに出力するのでリダイレクトしてgrepに渡して、ログに書き込みしている。

## 余談 helpとman

timeコマンドの使い方を調べる際に、man help とするとgnu版の説明がでてくるので。
built-in版の説明を調べたい場合はhelpコマンドを利用しましょう。

timeコマンドが2種類ある事をしらないと、ここらへん混乱するので注意。

#### man time

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/26596f6e-711f-f51e-571f-e55aef57545a.png)

#### help time

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/bac74ff5-1c4b-5da6-daac-1ac5c58f3eb5.png)

### timeコマンド実行結果から実行時間のみを取得

helpで説明を確認すると、組み込み版timeコマンドではフォーマットを指定して出力すうようなオプションはないので、出力結果から実行時間を抽出します。

```bash

# 組み込み版timeコマンドはエラー出力に結果出力するのでエラー出力を標準出力にも出力するようにリダイレクト
# grepとawkを利用して出力結果をフィルタ
{ time -p sleep 2 ; } 2>&1 | grep 'real' | awk '{ print $2 }'

# 組み込み版timeコマンドはエラー出力に結果出力するのでエラー出力を標準出力にも出力するようにリダイレクト
# awkを利用して出力結果をフィルタ
{ time -p sleep 2 ; } 2>&1 | awk '/real/ {print $2}'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/467de7ed-7348-f474-8970-80c4cfcb9edb.png)

# 総評

bashを利用する際に、built-inコマンドのtimeを実行しているのか、外部コマンドのtimeを実行しているのか。
その存在を理解していないと、意外と混乱する気がします。
【Python】tkinterでcolorchooserを使って文字の色を変える方法

## はじめに

tkinterにてcolorchooserを使用して、Text領域の文字に色を付ける方法を紹介します。
colorchooserを使用することで、カラーパレットを表示しその中から色を選択することが出来るので、柔軟に文字色を変更することが可能です。tkinterを使ってGUIアプリを作成される方の参考になれば幸いです。

#### 開発環境
・WSL2/Ubuntu環境
・Python: 3.10.12

## colorchooserを使って文字の色を変える方法

```SampleColorText.py:

import tkinter as tk
from tkinter import Text, colorchooser


# Applying color to selected text
def Sample_Apply_Color():
    color = colorchooser.askcolor(title="Color-Palet")
    if color:
        selectcolor = color[1]
        area_text.tag_configure(selectcolor, foreground=selectcolor)
        area_text.tag_add(selectcolor, "sel.first", "sel.last")


# configure root
root = tk.Tk()
root.title("ColorText")
root.geometry("800x600")

# configure menu
bar_menu = tk.Menu(root)
list_decoration = tk.Menu(bar_menu, tearoff=0)
bar_menu.add_cascade(label="Decoration", menu=list_decoration)
list_decoration.add_command(label="Color", command=Sample_Apply_Color)
root.config(menu=bar_menu)

# make text
area_text = Text(root, wrap="word", undo=True)
area_text.pack(fill="both", expand=True)

# display window
root.mainloop()

```

#### Text領域で文字の色を変更する流れ
①Text領域に文字列を入力します
②Text領域の文字列をマウスなどで選択します
(選択した文字列の色が変わって強調表示されます)
③DecorationタブのColorをクリックし、カラーパレットから色を選択します
④Text領域で選択した文字列がカラーパレットで選択した色に変更されます

## 参考文献
本記事は以下情報を参考にして執筆しました。

https://www.python-beginners.com/entry/20190523/1558595892
PythonでLLMとGoogle検索APIを使用した記事生成ツールの作成を試してみた：

# PythonでLLMとGoogle検索APIを使用した記事生成ツールの作成

この記事では、Pythonを使用して大規模言語モデル（LLM）とGoogle検索APIを活用した記事生成ツールの作成方法を紹介します。このツールは、ユーザーが入力したテーマに基づいて記事を生成し、結果をファイルに保存します。以下にコードの詳細とその動作を説明します。

```python
import os
from langchain.agents import initialize_agent, Tool
from langchain.utilities import GoogleSearchAPIWrapper
from langchain.prompts import PromptTemplate
from langchain.agents import AgentType
from langchain.chat_models import ChatOpenAI

# ユーザー入力に基づいてプロンプトを作成する関数
def create_prompt(user_input):
    # PromptTemplateを使用してプロンプトのテンプレートを作成
    prompt = PromptTemplate(
        input_variables=["theme"],
        template="""
        貴方はブロガー
        1000文字以上で日本語出力
        ###
        テーマ:{theme}
        """
    )
    # テンプレートにユーザー入力のテーマをフォーマットしてプロンプトを作成
    return prompt.format(theme=user_input)

# 使用するツールを定義する関数
def define_tools():
    # Google検索APIのラッパーを使用
    search = GoogleSearchAPIWrapper()
    # 検索ツールをToolオブジェクトとしてリストで返す
    return [
        Tool(
            name = "Search",
            func=search.run,
            description="useful for when you need" 
        ),
    ]

# レスポンスをファイルに書き込む関数
def write_response_to_file(response, filename):
    # 指定されたファイル名でファイルを開き、UTF-8エンコーディングで書き込む
    with open(filename, 'w', encoding='utf-8') as file:
        file.write(response)
    # 書き込み完了を通知するメッセージを表示
    print('出力しました')

# メイン関数
def main():
    # OpenAIのチャットモデルを初期化（温度設定とモデル、トークンの最大数を指定）
    llm = ChatOpenAI(temperature=0, model="gpt-4-turbo", max_tokens=500)
    # ツールを定義
    tools = define_tools()
    # エージェントを初期化
    agent = initialize_agent(tools, llm, agent=AgentType.OPENAI_FUNCTIONS)
    # ユーザーから記事のテーマを入力させる
    prompt = create_prompt(input("記事のテーマを入力: "))
    # エージェントを使ってプロンプトに基づくレスポンスを生成
    response = agent.run(prompt)
    # レスポンスをファイルに書き込む
    write_response_to_file(response, 'output.txt')

# スクリプトが直接実行された場合にmain関数を実行
if __name__ == "__main__":
    main()

```

必要なモジュールのインストール
```
import os
from langchain.agents import initialize_agent, Tool
from langchain.utilities import GoogleSearchAPIWrapper
from langchain.prompts import PromptTemplate
from langchain.agents import AgentType
from langchain.chat_models import ChatOpenAI
```

# 各関数の説明

create_prompt(user_input):
ユーザーの入力を受け取り、指定されたテンプレートにフォーマットしてプロンプトを生成します。

define_tools(): 
GoogleSearchAPIWrapperを使用して検索ツールを定義し、それをツールリストとして返します。

write_response_to_file(response, filename): 
レスポンスを指定されたファイルに書き込み、書き込み完了のメッセージを表示します。

main():
        OpenAIのチャットモデルを初期化します。
        ツールを定義し、エージェントを初期化します。
        ユーザーから記事のテーマを入力させ、それに基づくプロンプトを生成します。
        エージェントを使ってプロンプトに基づくレスポンスを生成し、それをファイルに書き込みます。


## 実行例
```
> python app.py
> 記事のテーマを入力: chatPGTのLLMについて教えてほしい。
```

下記のoutputファイルがカレントディレクトリに出力される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381629/f345e751-8704-9deb-5e26-6684d8796f6d.png)


# まとめ

このコードを使用すると、ユーザーが入力したテーマに基づいて自動的に記事を生成し、その結果をファイルに保存するツールを簡単に作成できます。PythonとLLMを活用することで、効率的にコンテンツを生成することが可能です。ぜひお試しください。

# 最後に

この記事が皆さんの開発の参考になれば幸いです。質問やコメントがあれば、ぜひお知らせください。Happy coding!
github action で "exit code 16"の場合の解決手順

## 備忘録
github pages を公開したく、jekyllでビルドするgithub action で下記エラーが発生した場合に解消できた手順を記す。

``` 
The process '/opt/hostedtoolcache/Ruby/3.2.2/x64/bin/bundle' failed with exit code 16
```

他の解決策で2番目と3番目が入れ替わって説明しているものがあったがそれでは解決しなかった。下記手順でビルドとデプロイが成功した。依存関係を削除[rm]して、作り直して[install]、それからプラットフォームを追加する。
```
$ rm Gemfile.lock
$ bundle install
$ bundle lock --add-platform x86_86-linux
```

更新したGemfileをコミットする。
```
git add Gemfile.lock
git commit -m "Gemfile.lock再作成" 
git push origin main
```

Github Actionが実行されて成功のチェックマークが表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/489e636a-7f5a-499c-13d2-0d7567bc6d7c.png)


6時間くらい悩んだ。Copilotありがとう。
【Python】Excelシートのセルから情報を取得する


for i in range(2, maxRow):
#1行目は項目欄なので2行目から開始、max_rowでデータが存在する分繰り返しiで行の変数を挿入している。
Cell_01 = ws1.cell(i,1)
Cell_02 = ws1.cell(i,2)
Cell_03 = ws1.cell(i,3)
Cell_04 = ws1.cell(i,4)
Cell_05 = ws1.cell(i,5)

Cell_01_fill = str(Cell_01.value).zfill(4) #桁を揃える

ws2[“b1”] = Cell_01_fill
ws2[“c5”] = Cell_02.value
ws2[“c6”] = Cell_03.value
ws2[“f3”] = Cell_04.value
ws2[“f4”] = Cell_04.value
【ABC361】コンテストメモ【AtCoder】

## はじめに

毎週取り組んでいる「AtCoder Beginner Contest」の感想・まとめをこちらの記事に散文的にまとめていきます。

:::note info
使用言語はC++です。
:::

:::note info
「未着手」は手を付けていない問題。
「未提出」は手を付けたけれど提出はしていない問題。
:::

## 結果

- 順位: 4642nd / 12626
- 点数: 600点
- time: 62:04
- pef: 777相当
- rating: 263 → 313 (+50) Highest更新！
- 完問数:3完 ABC

## 問題別評価

### A問題

- AC 4:09
- [実行結果](https://atcoder.jp/contests/abc361/submissions/55257196)

「正数列の途中にある値を入れましょう」という問題。方法としては

- 配列に差し込んで出力する
- 配列の出力の途中である値を出力する

がある。後者の方法が簡単だと思うのでそちらで実行した。ただ細かい処理の違いでミスってしまった。

### B問題

- AC 62:04
- [実行結果](https://atcoder.jp/contests/abc361/submissions/55299919)

三次元空間にある２つの箱が重なっているかどうかを判定する問題です。この「重なっている」をどのように解釈するかが鍵です。

数直線を考えます。数直線上に異なる線分を２つ用意して。その２つが重なっているかどうかを確認することを考えます。それをxy平面、yz平面、zx平面で確認します。気づくのにすごく時間がかかりました。

### C問題

- AC 34:39
- [実行結果](https://atcoder.jp/contests/abc361/submissions/55284220)

配列の中から「最大-最小」が最小にする問題です。配列を昇順にして下からn-k個を順番に判断していけば正解できます。

### D問題

- 未提出

さっぱりわかりませんでした。なにか簡単な方法があると思っていたのですが解説をみるとBFSで解くようです。意外と処理の量が多くないのでできるみたいです。誰か詳細をおしえてください...（泣）

### E問題

- 未着手

### F問題

- 未着手

### G問題

- 未着手

## 総評・まとめ

久しぶりのRateで緊張しましたがかなり調子が悪くてA問題しか解けないかと思いました。最近の精進がA問題しか解いていなかったのでBCも厳しかったです。基本的にE問題以降はグラフ理論になるのでD問題くらいまでは一般的な（？）アルゴリズムで解けるはずなのでこの難易度の問題を日々精進しようと思いました。

### 今日の学び
- 一日一精進(AB+茶色)を解く
- Qiitaの記事にして理解を深める
Pandasを利用するときの前処理

データサイエンスのためによく利用されるPandas。
私は主に営業データのエクセルを加工するときに利用します。
必要な機能のみを抜粋した記事にしました。
参考になれば幸いです。

# 抽出
```python:extract.py
指定のカラムのみ抽出
df = df[['得意先コード', "得意先名", "電話番号"]]

指定のカラムから指定の値のデータを抽出
df = df[df["営業担当"] == "佐藤"]

指定のカラムから営業担当が佐藤と鈴木のデータを抽出
df = df['営業担当'].isin(["佐藤", "鈴木"])
```

# 除外
```python:exclusion.py
指定のカラムのデータが欠損値の場合データを除外
df = df.dropna(subset=['得意先コード', '電話番号'])

商品分類がアンチウィルスソフトでファイアウォール機能がついていない商品を除外
df = df[~((df["商品分類"] == "アンチウィルスソフト") & (df["ファイアウォール"] == False))]
```

# 変換
```python:dtype.py
カラムをdatetime型に変換
df["日付"] = pd.to_datetime(df["日付"])
```

# 並び替え
```python:sort_values.py
byで並び替えたいカラムを指定、ascendingで昇順・降順を指定
df = df.sort_values(by=['sales_month', 'customer_id'], ascending=[True, True])

```

# リスト・辞書変換
```python:tolist_dict.py
カラム名をリストで取得
df.columns.values.tolist()

指定カラムの値をリストで取得
df['取引先名'].tolist()

すべての値をリストで取得
df.values.tolist()

すべての値を辞書で取得
df.to_dict()
```

# 結合
```python:marge_concat.py
データフレームを横方向に連結
# 2つのデータフレームの'customer_code'と'得意先コード'を元にdf_add_customersのデータを追加
df_marge = pd.merge(df_source_customes, df_add_customers, left_on='customer_code', right_on='得意先コード', how='left')

データフレームを縦方向に連結
df = pd.concat([df, df_add])
```

# sqlite
```python:sqlite.py
import sqlite3

file_sqlite3 = "main.db"
table_name = "report"

書き込み
with sqlite3.connect(file_sqlite3) as conn:
    df.to_sql(table_name, conn, if_exists='append')

読み込み
with sqlite3.connect(file_sqlite3) as conn:
    df = pd.read_sql_query('SELECT * FROM report', conn)
```


# 表示のオプション
jupyterlabで表示結果が省略されなくなる
```python:option.py
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
```
robloxでassistant その121

# 概要
robloxでassistantやってみた。
練習問題やってみた。

# 練習問題
スクリプトだけで、箱に画像を張り付けよ。

# サンプルコード

```
local part = Instance.new("Part")
part.Size = Vector3.new(5, 5, 5)
part.Position = Vector3.new(0, 2.5, -10)
part.Anchored = true
part.TopSurface = Enum.SurfaceType.Smooth
part.BrickColor = BrickColor.new("Toothpaste")
local decal = Instance.new("Decal")
decal.Face = Enum.NormalId.Back
decal.Parent = part
local happyFace = "http://www.roblox.com/asset/?id=26424652"
local sadFace = "http://www.roblox.com/asset/?id=147144198"
decal.Texture = happyFace
part.Parent = workspace

```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ece5e32f-025f-7f81-3fe4-36aba27ed3c5.png)


以上。
【Python】任意のExcelのシート情報を取得する

●openpyxlのインストール(PythonでExcelを操作するのに必要)

from openpyxl import load_workbook
from openpyxl.cell.cell import Cell

filepath1 = 'Book1.xlsx'
filepath2 = 'Book2.xlsx'

#エクセルを読み込む
wb1 = load_workbook(filename=filepath1)
ws1 = wb1['Sheet1']

print(ws1.max_row)

wb2 = load_workbook(filename=filepath2)
ws2 = wb2['Sheet1']

print(ws2.max_row)

●max_row
値の入っている行の中で、最終行のcell情報を取得する。

●max_column
値の入っている列の中で、最終列のcell情報を取得する。
EFSのマウント状態をモニタリングする

# はじめに
EFSをEC2等でマウントして利用している際、EFS側のシステムトラブルや、何らかの原因でEFSが利用できないことがあったら検知したいなぁと思い、方式を検討しました。

# そもそもEFSのモニタリングは？

https://docs.aws.amazon.com/ja_jp/efs/latest/ug/efs-metrics.html

EFS標準で提供されているメトリクスは上記のとおりです。
この中でEFSが利用できているのだろうか？というところを確認する方法として１つ考えられるのがClientConnectionsの数をモニタリングすることです。
しかしこの方法には１つ問題があります。

通常このような形で、EC2などからAZ毎にマウントポイントに接続する構成です。
![スクリーンショット 2023-10-21 17.12.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/f8729805-e073-217a-a6b8-5cd4c001d0d4.png)

仮にClientConnectionをモニタリングする場合、正常にマウントできている状態のクライアント数をCloudWatch Alarmの閾値にするわけですが、AutoScalingなどにより、台数が上限する場合、特定のインスタンスで問題が発生しているかは特定することができません。仮に閾値を２にしていた場合、３台目がデプロイされ、３台目がマウントされていなくてもアラームは発砲されません。

![スクリーンショット 2023-10-21 17.16.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/c6476104-4157-abcb-79f5-e47b14b16c82.png)

# 解決策
解決策として考えうるものは以下２つです。
案１：マウント状態のモニタリングではなく、アプリケーション側からエラー検知を行う
これは、アプリケーション側で、EFSへの書き込み、読み込みができない場合、エラーログを生成してもらう方法です。そもそも、ファイルの読み書きができない場合、アプリケーション側で通常何らかのエラーが出力される気がしますが、EFSの読み書きということでエラーが出ていることはログ上特定できるようにしたほうがよいでしょう。
![スクリーンショット 2023-10-21 17.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/0dbc9241-03ce-9e99-5357-0eb20d428d6b.png)
案２：EFSのファイルパスをWEBアプリで公開している場合、該当のURLをELBからヘルスチェック対象のパスとする
これは、Apache等でWEB公開している場合、EFSのマウントが前提となっているURLをELBのヘルスチェック対象としてしまう方法です。こちらの方法では、何らかの異常があった場合、インスタンスの切り離しも可能ですし、大きな実装もありません。とはいえ、そもそもEFSの利用用途がウェブ公開でない場合には向きません。
![スクリーンショット 2023-10-21 17.25.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/8f331789-8f32-34ec-dbcf-3765a6169c44.png)
案３：独自のスクリプトでカスタムメトリクスを作成する
これは実装が手間ですが、Cron等でスクリプトを実行、読み書きができるかをチェックし、結果をカスタムメトリクスとして、記録する方法です。カスタマイズ性や、柔軟な作り込みに対応可能です。
![スクリーンショット 2023-10-21 17.25.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/28e59294-b05a-690d-887d-fffe8d3c64fa.png)

# メリデメ
| 案 |メリット |デメリット |
|---|---|---|
|アプリケーション側でエラーログ生成  |アプリケーション側のエラーログとまとめることが可能  |アプリケーション側のカスタマイズ、実装が必要  |
|EFSのファイルパスの一部をWEB公開しALBからヘルスチェック  |比較的簡単に実装できる、ウェブ公開するアプリケーションであった場合インスタンスの切り替えも自動化できる  |ウェブアプリでない場合や、EFSのファイルパスを公開したくない場合利用できない  |
|独自のスクリプトでカスタムメトリクスを生成  |　指定した感覚で確実に読み書き可能かチェックできる、アプリケーションのカスタマイズは不要 |スクリプトの実装が必要  |

# スクリプト概要
スクリプトの概要です。
※メトリクスに書き込めなかった際などのエラー処理を除く
1.EFSのマウントパスにファイルを書き込む
2.書き込みができなかった場合、CloudWatchメトリクスに１を書き込む、書き込みができた場合、CloudWatchメトリクスに０を書き込む
3.事前に設置してあるファイルを読み込む
4.読み込みができなかった場合、CloudWatchメトリクスに１を書き込む、読み込みができた場合、CloudWatchメトリクスに０を書き込む

このようなスクリプトを定期実行し、メトリクスに出力、アラーム側では、複数台のインスタンスからメトリクスが出力されるため、１台でも１を超えた場合アラーム発砲できるようにルール設定します。

# まとめ
できうる限り作り込みはしたくないのですが、EFSに関しては慎重に見極めが必要です。
スクリプト以外の手段もあるので、最適なものを選択しましょう。
paiza.ioでelixir その293

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
リストの各要素に対し、spawnシリーズで処理を行い、それをreceiveで受け取るようにせよ。

# サンプルコード

```
defmodule Parallel do
    def pmap(collection, fun) do
        me = self()
        collection
        |> Enum.map(fn elem ->  
                spawn_link(fn -> 
                    (send me, { self(), fun.(elem) }) 
                end) 
            end) 
        |> Enum.map(fn pid ->
            receive do 
                { ^pid, result } -> 
                    result 
            end
        end)
    end
end

Parallel.pmap(1..10000, fn x -> 
    x + 1 
end)
|> IO.puts()


```

# 成果物

https://paiza.io/projects/vdYjyWox_7uwwhsx4h4WYg


以上。
【Go】ライブラリの関数をテストする時はgomonkeyでモックしちゃえ！

# はじめに
こんにちは、H×Hのセンリツ大好きエンジニアです。（同担OKです😉）

Goでテストする時、ライブラリの関数どうテストするか迷いますよね🥹
そんな時は関数をモックして特定の動作を行うようにしちゃいましょう！
`gomonkey`というライブラリを使用していきます。

# gomonkeyとは
> gomonkey is a library to make monkey patching in unit tests easy, and the core idea of monkey patching comes from Bouke, you can read this blogpost for an explanation on how it works.

gomonkeyは、単体テストでのモンキーパッチングを簡単に行うためのライブラリです。

モンキーパッチとは、既存のコードを実行範囲内で拡張または修正するというテクニックであり、これにより関数をモック化できるわけですね！

https://github.com/agiledragon/gomonkey

gomonkeyを使うことで依存関係を制御しやすくし、より効率良く単体テストを書くことができるようになるとのことです！

# 使用例
### テスト元のコード
``` random.go
package random

import (
    "math/rand"
)

func Rand() int {
    randomNum := rand.Intn(10)
    return randomNum
}
```
簡単な乱数生成の関数です。
0~9までのランダムな整数を生成し、返します。

しかし、テストを行う場合はランダム性を排除したいですよね🤔
毎回違う結果になると確かめようがないので。。。

### テストコード
``` test_rand.go
package random

import (
    "math/rand"
    "testing"

    "github.com/agiledragon/gomonkey"
    "github.com/stretchr/testify/assert"
)

func TestRand(t *testing.T) {
    // rand.Intnをモックして常に0を返すように設定
    patches := gomonkey.ApplyFunc(rand.Intn, func(n int) int {
        return 0
    })
    // テスト終了時に、パッチをリセット
    defer patches.Reset()

    // モックされたrand.Intnを用いたRand()は常に0を返す
    result := Rand()
    // 期待される値と結果を比較
    assert.Equal(t, 0, result)
}
```

上記のようにすれば、`rand.Intn`の挙動を変更できるので不確実性を排除したテストコードを作成できます！
具体的には、

``` test_rand.go
patches := gomonkey.ApplyFunc(rand.Intn, func(n int) int {
        return 0
    })
```
`gomonkey.ApplyFunc`で`rand.Intn`の返り値を強制的に0にしています。
このように記述することでライブラリの関数をモック化できます！

他にも、メソッドの挙動を変更する`ApplyMethodFunc`などさまざまな機能を用意しているので、是非見てみてください！

https://pkg.go.dev/github.com/agiledragon/gomonkey/v2

# おわりに
単体テストでライブラリの挙動を制御したいときや、不確定要素を無くしたいときに`gomonkey`を利用することができるかなと思います！🤗

最後までご覧いただきありがとうございました！
以上、センリツでした。🤓
ディレクトリ構造を自動で作るアプリの作成

## はじめに
最近の生成AIの進化は目覚ましく、ChatGPTやClaudeを使ってアプリやプロジェクトの雛形を生成してもらう機会が増えてきました。しかし、生成されたコードを自分の環境で実行する際に、いちいちディレクトリやファイルを手動で作成するのは面倒だと感じることはありませんか？

そこで、今回はディレクトリ構造を自動で生成してくれるGUIアプリをPythonとTkinterを使って開発してみました。

## リンク
作成したプロジェクトのGitHubのURLを載せておきます．
[Directory Structure Generator](https://github.com/Rikuto-Yamamoto/Directory-Structure-Generator)
README.mdは日本語と英語を両方書いていますが，生成AIに作ってもらったものなので適当です．

## 使い方
![スクリーンショット 2024-07-06 21.34.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470659/86de7d05-1dc7-dad7-46f8-345acdae2881.png)
実行するとこんな画面が出てくるはずです．
右上の大きい四角のところにディレクトリ構造を入れると自動で作ってくれます．
入れるときの形式はこんな感じ
````
project/
    src/
        main.py
        utils.py
    tests/
        test_main.py
    README.md
````
ディレクトリはインデントを使って階層構造を表現します。インデントは半角スペース4つにしてください．
入力が完了したら、「Generate」ボタンをクリックすると、指定したディレクトリ構造が自動的に生成されます。
本当はツリー構造でやりたかったんですけど上手くいきませんでした．

## 注意点
このアプリはTkinterを使用しているため、Python環境にTkinterがインストールされている必要があります。
僕はPyCharmで仮想環境を作って実行しました．

## まとめ
今回は、PythonとTkinterを使ってディレクトリ構造を自動生成するGUIアプリを作成しました。このアプリを活用することで、面倒なディレクトリ作成作業から解放されて、開発効率を向上させることができるかもしれません．
計量文献学入門_00：計量文献学とは

### リンク
次の記事：[計量文献学入門_01：著者推定の概要とデータの前処理](https://qiita.com/_Ji_N0/items/00a1e0bda47b1a31c8ee)

## はじめに
しばらく前、趣味（あるいは学業）で計量文献学について触れる機会がありました。そこで得た知識やらなんやらの備忘録として記事を残します。狭い学問分野ですが、どなたかの助力になれば幸いです。
なお、この記事は『計量文献学入門_xx：*』に関連して執筆する予定です。計量文献学についてふんわり解説しながら、実際に著者推定を行ってくので、他の記事も参照ください。

## この記事の目標
私自身まだまだ初学者です。計量文献学の概要を、能書きをたれながらなんとなく理解することがこの記事の目標です。

## 計量文献学とは
文学や哲学、宗教学といった様々な分野における重要な文献は、「本物なのか」「成立年代はいつなのか」「執筆者は誰なのか」といった諸問題を抱えていることが少なからずあります。さらに、その文章の特徴（文体）は、読み手の感覚的な評価によって決定されるため、解決に導くことが簡単ではありません。
そのため、文献に現れる特徴を定量化し、客観的な観点からこれらの問題を解明しようとする手法が考えられました。その研究を行うのが計量文献学です。この研究分野では、例えば
 - ある単語の出現率
 - 品詞の出現率
 - 読点の打ち方
 - 出現する語彙の量
 
 といった観点から文献の特徴を抽出し、その文献の考証を行います。
 以前は小規模な解析が行われていたようですが、現在はマシンパワーによって、大量な文献データを用いた解析が行われるようになっています。

## 諸研究
この学問分野の、有名なトピックを取り上げます。

### 源氏物語
平安時代に成立した有名な古典『源氏物語』は、全54帖からなる長編物語であり、その作者は紫式部であると言われています。しかしながら、末尾の宇治十帖（うじじゅうじょう）と呼ばれる十帖は、別の著者が執筆したという説が古くから存在します。

安本美典（1958年）は各巻ごとに(1)頁数、(2)和歌の使用度、(3)直喩の使用度、(4)声喩の使用度、(5)色彩語の使用度、(6)心理描写文の数、(7)文の長短、(8)名詞の使用度、(9)用言の使用度、(10)助詞の使用度、(11)助動詞の使用度、(12)品詞数を調べました。その結果、宇治十帖と他の四十四帖とは有意な差がみられたと結論づけ、作者は異なる可能性があると報告しています。

村上征勝、今西祐一郎（1999年）は、『源氏物語』54巻の本文すべてを単語に分割し、約37万6千語のデータベースを作成しました。そして、主に助動詞の出現頻度に着目し分析を行い、他の研究と同様に宇治十帖の異質性を指摘しています。

他にも様々な研究がありますが、特に安本のそれは、国語文献の計量分析において先駆的な研究です。以降、宇野浩二や井原西鶴などの文学作品も計量的な手法で分析がなされました。

### シェイクスピア
外国文献の計量的な分析は日本のそれよりも早く、「ド・モルガンの法則」でおなじみのDe Morganが、文章の統計的な分析により著者推定ができる可能性を唱えたことにあります。

Mebdenhall（1901年）はシェイクスピアが執筆したとされる戯曲を対象に分析を行いました。もとよりシェイクスピアの著作は別人（フランシスコ・ベーコン）であるという説があります。彼はシェイクスピアとベーコンそれぞれの作品に出現する単語の長さを調べ、その長さの最頻値を根拠としてベーコンが書いたという説を否定しました。

この研究が嚆矢となって、様々な文献の計量的な分析が行われるようになったそうです。なお、その他のシェイクスピア別人説は[wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF%E3%82%B9%E3%83%94%E3%82%A2%E5%88%A5%E4%BA%BA%E8%AA%AC "シェイクスピア別人説")が詳しいのでそちらに譲ります。

## 頻出する特徴量
特徴量は分析目的によって使い分けられ、今日までに提案されている著者の特徴を定量化する観点は多くあります。この節では、近年の研究でよく用いられている特徴量を（独断と偏見で）まとめています。細かな解説は、次回以降触れる機会があればその都度行っていきます。

<table>
  <caption>
    よく用いられる特徴量
  </caption>
  <thead>
    <tr>
      <th scope="col"></th>
      <th scope="col">説明</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">品詞の出現頻度</th>
      <td>名詞や動詞、形容詞といった品詞が、文章中にどれくらい出現するかを観点とする特徴量。</td>
    </tr>
    <tr>
      <th scope="row">n-gram</th>
      <td>n個の要素の連なりをn-gramと言う。      
      文字や品詞、音素などの連なりを抽出する。</td>
    </tr>
    <tr>
      <th scope="row">読点の打ち方</th>
      <td>日本語特有の観点。読点の間隔やどのような品詞の後に出現するかなどを調べ、定量化する。</td>
    </tr>
    <tr>
      <th scope="row">語彙の豊富さ</th>
      <td>文章中に出現するすべての語の数と、それに対する異なる語の数の比率。K特性値やHerden'Cなどの、工夫された計算式も提案されている。</td>
    </tr>
    <tr>
      <th scope="row">各機能語の使用度</th>
      <td>andやofといった文法機能に係る語を機能語といい、日本語では助詞や助動詞に相当する。機能語のうち、どの語がどれくらい出現するかを観点とする特徴量。</td>
    </tr>
  </tbody>
</table>

## おわりに
本記事では計量文献学の概要を解説しました。次回以降は、実際に頻出する手法を用いて著者推定タスクに取り組んでいきます。どうぞよしなに。

## 参考文献
1. 安本美典（1958年）「文体統計による筆者推定-源氏物語・宇治十帖の作者について」『心理学評論』Vol.2 No.1 147-156
1. 村上征勝 今西祐一郎（1999年）「源氏物語の助動詞の計量分析」『情報処理学会論文誌』Vol.40 No.3 774-782
1. Mendenhall T.C.（1901年）「A mechanical Solution of a Literary problem」『Popular Science Monthly』Vol.60 97-105
1. 村上征勝 金明哲 土山玄 上阪彩香(2016年)「計量文献学の射程」 勉誠出版
Jestの実行結果をいい感じに出したい！

# はじめに
皆さんは[Jest](https://jestjs.io/ja/)**の実行結果の表示をいい感じに出したい**！と思ったことはありませんか？
デフォルトだと下記のような感じで結果を見せてくれますが、これだと自分が見る分には十分なんだけどちょっと無骨な印象もあります。
```shell
# ここら辺にテストファイルのパスと結果

Test Suites: 9 passed, 9 total
Tests:       119 passed, 119 total
Snapshots:   0 total
Time:        2.466 s, estimated 12 s
Ran all test suites matching /date/i.
```

後はテストを通っているならともかく、エラーが多いとかなり見にくくなってしまいます。~~そもそもエラー出すな~~

後から結果を見返す時とか、プログラマじゃない人にもこんな感じでテストしてますよ～って見せる時を考えるとやっぱり何とかしたいです。
何より綺麗にテスト結果が見えたら良い気分になりますよね！

ここまでで「いや別に？」って思った方も居ると思いますが、まあこんなのもあるんだ程度で見てくれればと思います。

# 結論
自力で作ることも一手なのですが、既にあるのならばそれを利用するのが手っ取り早いです。
ということで探してみたのですが、ちょうど求めているものがありました。
それが[jest-html-reporters](https://www.npmjs.com/package/jest-html-reporters)です。
これを使うとJestの実行結果がHTMLで出力され、ブラウザ上で綺麗に表示される優れものです。

使い方は簡単で、上記ライブラリをnpmでも何でもインストールし、後はjestの実行時にオプションを設定する形です。CLIでもconfigファイルでもどちらでもOK。

##### configファイル(cjsでもtsでもjsonでもお好きなもの)
```js
const config = {
  // --その他諸々の設定--

  // オプション無し
  reporters: [
    'jest-html-reporters'
  ],

  // オプション付き
  reporters: [
    'jest-html-reporters', {
      publicPath: './html-report',
      filename: 'report.html',
      openReport: true
    }
  ]
};

module.exports = config;
```
##### CLI
```
jest --reporters=jest-html-reporters
```

:::note warn
CLIだと細かなオプション設定は出来ないので、必要な場合はconfigファイルを設定しておいてください。
[Jest CLI オプション・Jest --reporters](https://jestjs.io/ja/docs/cli#--reporters)

細かいオプションについては今回は割愛しますが、必要であれば下記を参考にしてみてください。
[Available Options](https://github.com/Hazyzh/jest-html-reporters?tab=readme-ov-file#available-options)
※基本的にはデフォルトのままで事足ります
:::

上記の設定をして実行すると、テスト完了と同時にHTMLファイル(デフォルトではjest_html_reporters.html)およびソースフォルダを吐き出してくれます。

それを開くとどんな感じなのかというとこんな感じ。
※以下画像の黒塗りの部分はテストファイルのパスが表示されているので隠しています

![header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690817/d7d27a05-5c8f-556a-1214-ffc1cd85b049.png)
![details.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690817/871a2b61-ce78-b49f-655d-2e1b38d78280.png)

いい感じですね！
各セクションの表示は見た通りですが、下記のような感じです。

### Dashboard
全体のテスト結果のサマリーが表示され、いくつのテストに成功・失敗したのかが分かります。

### Information
テストファイルそれぞれの実行時間がグラフで表示されており、どれに時間がかかっているのかが一目でわかります。
自動実行する場合の分析に役立てていけそうですね。

### Details
各テストファイルごとに、実行結果が詳細に表示されます。
クリックするとさらにファイル内のテストケースごとに結果が見えるようになります。

![details-expand.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690817/67c6fe27-67b6-3835-19dc-27b19f867cbc.png)

エラーがあると赤く表示され、「Info」をクリックするとその詳細も見せてくれます。

![error-info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690817/3053ce87-c256-388f-f5be-34513de2a896.png)

地味にフィルタしたりソートしたり出来ますし、まさに**良い感じ**に表示してくれます。
HTMLで吐き出してくれるので、ある時点の結果として残しておくこともやりやすくなるというメリットもありますね。
綺麗にPASSされているテスト結果を見て、テンションを上げていきましょう！

# 終わりに
ということで、今回は[jest-html-reporters](https://www.npmjs.com/package/jest-html-reporters)の紹介となりました。
Jestにはjsonファイルで結果を吐き出すオプションがあるので、それを使って色々と自分でカスタマイズして結果表示することも出来るのですが、既にあるものを使って手っ取り早くやるなら良い選択肢だと思います。
Jestを導入しても面倒くさがって書かないとかだと意味がないのですが、こうやって良い感じにテスト結果を表示させることで、自発的にもっとテストを書きたくなるようにしていきたいですね！
東大のAWSによるクラウド入門やってみた日記

# 今日の勉強内容

一時期バズっていた東大のAWS授業の資料を読み進めながら、資料内のハウンドアウトを進めてみました。

AWSによるクラウド入門
https://tomomano.gitlab.io/intro-aws/

## 環境の準備
### WSLをインストール
```
wsl --install -d Ubuntu
```
※資料中のMicrosoft公式だと`wsl --install`しか書いていないが、実際は-dオプションでディストリビューションを指定する必要がある。また、後述しますがWSL2でないとdockerがうまく動かないので、このときに指定すればよかった。その場合`wsl --set-default-version 2`を先に入力するのだろうか？

WSLはインストールごユーザー登録することになるのでユーザー名とパスワードを用意しておくと楽。

WSLはインストール後すぐに動いたが、2つほど後付手作業が発生したので記載。

1. インストールご自動でユーザー権限モードで実行されるが、dockerがうまく動かないので管理者権限モードで起動し直した
1. sudoでパスワードを何度も聞かれるのでコンソールのタイトルバーを右クリックして［プロパティ］→［オプション］タブのCtrl+Shift+C/Vをコピー/貼り付けとして使用するをONにすると楽
![f18960ee0aa625d5646c08916341ea93.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831926/88469b93-1c1e-d197-7a06-e27b9d2f4a63.png)

### dockerをインストール
これが一番ハマったかも

下記サイトを参考に進行したところ最後の`sudo docker run hello-world`でエラーになりました。
https://zenn.dev/thyt_lab/articles/fee07c278fcaa8

エラー内容は/var/log/docker.logに出力されていました。

エラーのときに参考にしたのはこちら
https://blog.jp.square-enix.com/iteng-blog/posts/00024-wsl2-docker-ce/

下の方のトラブルシューティングに全部書いてありました。感謝しかない。。。
トラブル2と3は前述の通りWSLの起動権限とバージョンの問題。

```
Error starting daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables/1.8.2 Failed to initialize nft: Protocol not supported
```
* トラブル1
  - よくわかりませんがnfttablesは使えないのでiptables-legacyに切り替える必要があるみたいです
```
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables v1.8.7 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
```
* トラブル2
  - スクエニさんのブログでも書いてあるとおり、WSLを管理者権限で動かす必要があります
* トラブル3
  - スクエニさんのブログでも書いてあるとおり、WSLのバージョンをWSL2にする必要があります
  - バージョン切り替えのコマンドは`wsl --set-version Ubuntu 2`
```
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: waiting for init preliminary setup: EOF: unknown.
```

### Pythonのインストール
WSLにデフォルトで入っているのでインストール不要とのこと
`Python3 --version`コマンドでインストール済みであることとバージョンのみ確認で終わり。

### node.jsのインストール
下記ブログを参考に実行バージョンだけ資料に合わせて10に変えました。
https://qiita.com/c8h9no2/items/9a2e1278976db1b390a5

## おわり

後は資料を3.5.3まで読み進めたところで時間切れ
次回はAWSアカウントを作るところから進めます。
【Next.js】ReactUseを使用する

# はじめに

こんにちは、エンジニアのkeitaMaxです。

今回はNext.jsにReactUseをインストールして使えるようにします。

# ReactUseとは
>Reactuse is a comprehensive collection of custom React Hooks designed to supercharge your functional components! you can easily unlock the full potential of React Hooks and leverage their power to create reusable and efficient code.
(引用：https://www.reactuse.com/)

便利な React Hookのライブラリです。

# インストール

以下のでコマンドでインストールします。

```
npm i react-use
```

# 使用方法

使用したい箇所で`useEffectOnece`などと書いて、クイックフィックスをすると勝手にimportしてくれます。

`useEffect`などと同じように使用することができます。

色々あるので、公式サイトをみてみてください。

https://www.reactuse.com/


# 自動でimportされない時は

もしクイックフィックスをした時にimportが候補に出ない時は`ts.config.json`を確認してください。

```
"moduleResolution": "node",
```

`moduleResolution`が`bundler`になっているとimportされないので、`node`に修正してみてください。

# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！

# 参考

https://www.npmjs.com/package/react-use

https://www.reactuse.com/
Ubuntuデスクトップの作業効率を超絶改善するトラックボールとその設定

## 1. 真ん中ボタン(ホイールボタン)をアクティビティに変える

Linux系では真ん中ボタンは貼り付けが自動でマッピングされてしまいますが、むしろ邪魔です。

そこで、Macをマウスで操作する場合のデフォルト設定と同じく、真ん中ボタンクリックでアクティビティ(MacのMissionControl相当)が起動するように設定します。

### 設定方法

導入していない人はxdotoolとxbindkeysをインストール
```
sudo apt-get install -y xdotool xbindkeys
```

個人環境に設定ファイルをコピー&編集していきます
```
xbindkeys --defaults > ~/.xbindkeysrc
vim .xbindkeysrc
```
エディタはvimを使ってますが、そこは好きなの使っちゃってください。

```
"xdotool key super+s"
  b:2
```
を最後に記述しておきます。`super+s`はアクティビティが開くショートカットなので、設定を変えている人はそちらに変更してください。Macになれている方は是非設定しておくことをおすすめします。

## 2.真ん中ボタン押し込み+ボール回転で上下左右スクロール

トラックホイールをゴリゴリ回してスクロール、ちょっと不便です。安物だと左右スクロールも出来ず、イラッとしますね、わかります。

せっかくの大きなボールがあるので、これでスクロール出来るように設定しましょう。どんな長い文章でも、巨大なスプレッドシートでも難なく上下左右移動できるのは圧倒的快感です。

### 設定方法

他の方が設定方法を書かれていたので、コチラを参考にしてみてください。
https://memo.yammer.jp/posts/ubuntu-m570-scroll

## 3.マウスジェスチャーでデスクトップ移動+α

Macのトラックパッドだと、指3本すワイプでデスクトップ移動できたりしますね、アレ結構便利なんですよね。トラックボールでも是非再現したい。デスクトップをコロコロ切り替えながら出来ると、作業が断然楽になります。

### 設定方法

easy strokeをインストールしましょう。aptでもいけますし、Ubuntuストアでもインストールできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/cf805ff4-bb3f-ec4e-c160-2ed5642bebb2.png)

あとは、アプリケーションをアプリケーション一覧(ランチャー)から普通に起動しましょう。

自分の設定はこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/6dedaebb-870f-cfa6-9ec0-8579b32791c9.png)

アプリケーションごとの設定もできるので、よく使うアプリ専用のジェスチャーも仕込んでおくとより便利です。VSCodeで関数の定義元にジャンプする機能や、ターミナルを開いたり閉じたりするなどは多様するので、ショートカット用のジェスチャーを仕込んでいくと、開発効率が上がります。是非工夫してみてください。
Excel時短テクニックまとめ（クイックアクセスツールバー編）

# はじめに

業務効率化のため、Excelの作業効率化に繋がるTipsをまとめます。
今回は「クイックアクセスツールバー編」です。

## クイックアクセスツールバーとは

初期状態だとエクセルのウインドウの左上に表示されている、「上書き保存」「元に戻す」「やり直し」などのアイコン群です。（バージョンによって異なります）

＜Excel 365の場合の初期状態＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818933/5ab62b8f-3e6f-4ace-3a45-fb88ae421a35.png)


Altキーを押すとこれらのアイコンに覆いかぶさるように数字が表示され、続けて数字キーを押すことで対象のアクションが実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818933/9389b678-63a4-a5e1-7b9b-3f6138b8188f.png)


これを活用することで、以下のメリット（時短効果）が期待できます。

- マウスを使用せず各種アクションが実行できる（キーボードで完結する）
- ショートカットキーが割り当てられていない（もしくは割り当てられているとしてもキー押下数が多い）操作に対し、少ないキー押下で各種操作が実行できる

## どのアクションを割り当てるべきか

前述のメリットを最大限享受できるものを選択するのがおすすめです。
以下を満たすものを自分なりに選択しましょう。

- マウスを使用するとクリック数が多くなってしまうもの
- ショートカットキーが割り当てられていないもの（もしくは割り当てられているとしてもキー押下数が多いもの）
- 使用頻度が非常に多いもの

## どの順番で並べるべきか

1番目～9番目までは Alt → 数字1桁 で発動可能ですが、10番目以降は Alt → 数字2桁 となるためキー押下数が増え若干面倒になります。
よって使用頻度が高いものを1番目～9番目までに優先的に並べるとよいでしょう。

## おすすめの割り当てアクション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818933/85d1fde8-43bc-fa2b-48ea-4362c8c332ab.png)

:::note info
私が個人的にどの環境でも割り当てているものです。
人によって当然異なると思いますので、あくまで参考までに。
:::

### ❶フォントの色

Alt → H → F → C でも開くことが可能ですが、面倒。
パレットが開くと「自動」（黒文字）がデフォルト選択状態なので、赤文字を黒文字にしたい場合などはAlt → 数字 → Enter で実現可能なのでかなり時短になります。

### ❷塗りつぶしの色

Alt → H → H でも開くことが可能。フォントの色よりマシですが、それでも面倒。
パレットが開くと「塗りつぶしなし」に「N」が、「その他の色」に「M」が割り当てられた状態となります。なのでセルの背景色を無しにしたい場合はAlt → 数字 → N で実現可能なのでかなり時短になります。

### ❸中央揃え

Alt → H → A → C でも開くことが可能ですが。面倒。
セルの書式設定 → 配置タブ選択 → 横位置ドロップダウンを開く→ 中央揃えを選択 はもっと面倒。
中央揃えの解除にも使える。
左右揃えと比べて、表のタイトル部分など利用シーンが多いので活用してます。

### ❹読み取り専用の設定/解除

編集モードで開いているブックを読み取り専用にしたい場合や、読み取り専用で開いていたブックを途中から編集したくなった場合などに使用。利用頻度はかなり高い。
ショートカットの割り当てがないので、クイックアクセスツールバーの本領発揮。

### ❺横方向に結合

Alt → H → M → A でも実行可能ですが。面倒。
セルの結合自体あまり推奨しませんが、加工が必要ない「見せるための」表などでは使わざるを得ない場面も多く、対象行が多い場合は有効な機能。

### ❻セルの結合

Alt → H → M → M でも実行可能ですが。面倒。
セルの書式設定 → 配置タブ選択 → Alt + M は同じくらい面倒。
結合に関しては上述の通り。

### ❼セル結合の解除

Alt → H → M → U でも実行可能ですが。面倒。
セルの書式設定 → 配置タブ選択 → Alt + M は同じくらい面倒。
結合に関しては上述の通り。

### ❽❾フォント、フォントサイズ

リボンを非表示にしていると、アクティブセルのフォントやフォントサイズが確認できないので、クイックアクセスツールバーで常時表示・確認可能にしておくと意外と便利。

## 設定が終わったら

以下の場合に備えて、設定をエクスポートしておきましょう。その他のユーザ設定と一緒に作業環境を保存できます。

- アプリケーションの不具合などで、何かの拍子に設定が初期化されてしまった場合
- 他のPCで同じ環境を再現したい場合

「ファイル」 → 「オプション」 → 「クイックアクセスツールバー」 → 「インポート/エクスポート」 → 「すべてのユーザー設定をエクスポート」で「.exportedUI」という拡張子の設定ファイルがエクスポートされます。

## おわりに

クイックアクセスツールバーは初期状態のまま活用されていないケースが多いと思います。
それぞれに合う設定とすることで劇的に作業効率が上がるので、是非活用してください。
kotlin-react-routerを6.7->6.23にする時にまたしてもRouteで躓いた

## 要約
kotlin-react-routerを6.16.0-pre634から6.17.0-pre635にする段階で`import react.router.Route`しようとしても、見つかりませんと言われるようになる。そもそもkotlin-react-routerからはlegacyとして削除されているので`react.router.RouterProvider`などを用いて書き直すしかない。

## 環境
+ Ubuntu 20.04LTS
+ IntelliJ IDEA 2024.1.2 (Community Edition)
+ Kotlin/JS 1.9.24(IRコンパイラ)
+ Kotlin Wrappers 1.0.0-pre.755
+ kotlin-react-router-dom 6.23.1-pre.755
+ gradle 8.4

## 動機
[前回のライブラリ更新](https://qiita.com/sskki/items/61a1c0e747b66a88b943)からほぼ1年。Kotlin 2.0も出てきたし、いい加減 Kotlin 1.8 -> 1.9 に移行しておこうと思って各種ライブラリを更新し、[`kotlin-wrappers`](https://github.com/JetBrains/kotlin-wrappers)も更新の対象になった。

## 現象
`kotlin-wrappers`の更新をすると、`react.router.Route`, `react.router.dom.BrowserRouter` その他諸々がないと言われてコンパイル不可になった。

## 調査
今回はすぐに[原因となるライブラリ更新](https://github.com/JetBrains/kotlin-wrappers/commit/6d4288b0164880eb8901f4d42384d0a39ffcb75c)が見つかった。その[元となったissue](https://github.com/JetBrains/kotlin-wrappers/issues/2024)を無理矢理3行で要約すると、

+ ユーザー: `Route`で`path`と`element`プロパティが使えないこと(前回の自分が記事にしたやつ)の指摘(2023/6/9)。
+ 開発者: 新しいAPIを使ってください(2023/6/25)
+ 開発者: Legacyは削除しました(2023/10/22)

ということで、前回のワークアラウンドは無駄になりましたとさ。

[この記述](https://tokuhirom.github.io/kotlin-js-samples/02-frameworks/04-react/03-react-router/)を元に`react.router.RouterProvider`や`react.router.dom.createBrowserRouter`辺りを使って書き直したら動いた。

## 考察
GitHubの履歴によると、6.16.0-pre634から6.17.0-pre635になった2023年10月21日のことだったらしい。

## 改訂履歴(表現の修正などは除く)
+ 2024/6/9: 作成
+ 2024/7/7: 時間が取れずサンプルコードを断念し公開
git commitがinsufficient permission for ～で失敗する

# git commitがinsufficient permission for ～で失敗する

SSHを使用している環境で`sudo git clone`を無意識に使用してしまい、リポジトリのアクセス権限が適切に設定されていない場合、git操作でエラー発生することがあります。

### エラー例
[1] git commitでエラー。
     .gitフォルダに書き込み権限なし。
```
git commit実行
masami@masami-L ~/ecommerce (main)> git commit -m "Initial data was created using the seed file"
error: insufficient permission for adding an object to repository database .git/objects
error: Error building trees
```
[2] 何も考えずに`sudo`を付加して実行。
     root ユーザーには Git の user.email と user.name が設定されていない。
```
masami@masami-L ~/ecommerce (main)> sudo git commit -m "Initial data was created using the 
seed file"
[sudo] masami のパスワード: 
Author identity unknown

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'root@masami-L.(none)')
```

[3] もう1回、`sudo`を付けずに実行。前回のコマンドで一般ユーザーにroot権限が付き、    .gitフォルダへの書き込みが可能になる。
```
masami@masami-L ~/ecommerce (main)> git push
Enumerating objects: 19, done.
Counting objects: 100% (19/19), done.
Delta compression using up to 4 threads
Compressing objects: 100% (13/13), done.
Writing objects: 100% (13/13), 7.22 MiB | 646.00 KiB/s, done.
Total 13 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/pea-sys/ecommerce.git
   5ff5c13..8595f38  main -> main
```

### 解決方法
sudo を使用して Git 操作を行うのは一般的に推奨されません。
下記操作により、エラーが解決します。

* git ディレクトリの所有権を正しいユーザーに戻す
```
sudo chown -R yourusername:yourusername .git
```
* 適切な権限を設定する
```
chmod -R u+rwX,go-w .git
```
GCPのタイムアウト問題について

## はじめに

GCP（Google Cloud Platform）を使ってSlackボットを開発していた際、クラウドスケジューラーを使用して毎週アンケートメッセージを自動送信する機能を実装しました。しかし、しばらくするとSlack内のボットが動作しなくなる問題が発生しました。この問題の原因と解決方法について、具体的なGCPの構造を交えながら解説します。

## 問題の発生

クラウドスケジューラーを使って定期的にアンケートメッセージを送信する設定を行いました。しかし、メッセージが送信されて数分後にSlackボットが動作しなくなることが発生しました。具体的には、Slackからのリクエストに対する応答が途絶えるという現象が起こりました。

## 原因の究明

原因を調査したところ、GCPのCloud Runでデプロイしたコンテナのインスタンスが最小0に設定されていたため、アイドル状態のときにインスタンスがシャットダウンされていたことが判明しました。

### Cloud Runの構造

Cloud Runは、コンテナ化されたアプリケーションをデプロイし、リクエストに応じて自動的にスケールするマネージドサービスです。Cloud Runは、インスタンスを動的にスケールアップおよびスケールダウンすることで、リソースの効率的な利用を実現します。デフォルト設定では、アイドル状態が続くとインスタンス数が0にスケールダウンされます。

この設定はコスト効率を高めるために有用ですが、リクエストが発生した際にインスタンスを起動するまでの遅延が発生することがあります。特に、定期的なリクエストや長時間アイドル状態が続いた後のリクエストでは、この遅延が顕著になります。

### Slackボット特有の問題

通常のWebアプリケーションと異なり、Slackボットの使用パターンは断続的であり、ユーザーの操作が長期間発生しないことがよくあります。これにより、Cloud Runのインスタンスがシャットダウンされる可能性が高くなります。インスタンスが0になると、Slackからのリクエストが発生した際にインスタンスの起動遅延が生じ、ボタン操作などのリアルタイムのインタラクションがうまく機能しなくなります。

### 最小インスタンス数の設定

この問題を解決するためには、Cloud Runの最小インスタンス数を1に設定することで、常に少なくとも1つのインスタンスが稼働している状態を維持します。これにより、アイドル状態からのインスタンス起動による遅延を防ぎ、Slackからのリクエストに迅速に応答できるようになります。

以下は、Cloud Runの最小インスタンス数を1に設定するコマンドです。

```sh
gcloud run services update [SERVICE_NAME] --min-instances 1
```

## ボットの反応速度の改善

さらに、Slackボットの反応が遅いという問題も発生していました。原因を調査した結果、Cloud RunのCPU割り当て設定が「リクエストがないときにCPUリソースが解放される」設定になっていたことが判明しました。

### CPUリソースの常時割り当て

Cloud Runでは、デフォルト設定ではアイドル状態のインスタンスのCPUリソースが解放され、リクエストが発生した際に再度割り当てられます。この設定はリソース効率を高めますが、リクエストに対する応答速度に影響を及ぼすことがあります。

この問題を解決するために、Cloud RunのCPU割り当て設定を「常に割り当て」に変更しました。これにより、インスタンスがアイドル状態であってもCPUリソースが確保され続け、リクエストに対する応答速度が向上します。

以下は、Cloud RunのCPU割り当て設定を「常に割り当て」に変更するコマンドです。

```sh
gcloud run services update [SERVICE_NAME] --cpu-idle always
```

## まとめ

GCPのCloud Runを使用したSlackボットの開発において、インスタンスの最小数とCPU割り当て設定の重要性を理解することができました。以下に、問題の解決手順をまとめます。

### インスタンスの最小数を1に設定

Cloud Runの最小インスタンス数を1に設定することで、アイドル状態からの遅延を防ぎます。

```sh
gcloud run services update [SERVICE_NAME] --min-instances 1
```

### CPU割り当て設定を常時割り当てに変更

Cloud RunのCPU割り当て設定を「常に割り当て」に変更することで、リクエストに対する応答速度を向上させます。

```sh
gcloud run services update [SERVICE_NAME] --cpu-idle always
```

このようにして、GCPのCloud Runを効果的に設定することで、Slackボットの安定性とパフォーマンスを向上させることができました。これからも最適な設定を見つけて、より良いサービスを提供できるように努めていきたいと思います。
Xserver VPS のキー配列に初見殺しされた件

## 何があった？
クラウド環境（本番環境）でdockerを安く楽に使いたかったのでXserverVPSというものを契約した。

そこではAWSのEC2のような形で自分で環境構築する必要があった。

そのため作業手順の一つとして環境変数を設定すべくxsever側で用意してくれたコンソール画面（黒い画面）で.bashrcをviで開いたが、何をどうやっても`=`が打てず苦しんだので記事にした。

## 原因
（おそらく）日本語配列に準拠していたため。

us配列で`を打つと@が出てくるような感じだった。

## 解決方法

ローカルPCからssh接続で操作したところ、手元のPCのusキー配列で操作できた。

※キー配列の設定も試したけど現時点ではうまくいかなかった。