OmniAICreator/Qiita-1.07M huggingface dataset:
Swiftでアナグラムをグルーピングする

# 概要
[49. Group Anagrams](https://leetcode.com/problems/group-anagrams/description/)をすっきり解けたので忘れないうちにメモを残しておく。

文字列の一次元配列が与えられた時、各文字列をアナグラムとなる文字列ごとにグループ化し、二次元配列の中に詰めて返却する関数を書く、という要件です。

アナグラムとは、ある言葉や単語の文字を並び替えることによって、別の意味を持つ言葉や単語を作る言葉遊びのことです。 

以下が[49. Group Anagrams](https://leetcode.com/problems/group-anagrams/description/)で与えられる入力例と出力例です。

```Swift:Group Anagrams
Example 1:

Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]

Example 2:

Input: strs = [""]
Output: [[""]]

Example 3:

Input: strs = ["a"]
Output: [["a"]]
```

なお、ここでは以下のような制約が存在します。

```
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] consists of lowercase English letters.
```


# 詳細

こういった問題が出てくるとアナグラム内の文字列をカタログ(例えば文字列中にaが2回出現しているならa:"2")みたいにカウントしてそれぞれを照会したくなるが、それだと結構長めのコードを書かないといけなくなる。

直前に[242. Valid Anagram](https://leetcode.com/problems/group-anagrams/editorial/)(与えられた二つの文字列がアナグラムであるかを判定する問題)を解いていたので、これを応用すればいけるじゃん！って気付いてからは早かった。

```Swift:Valid Anagram
class Solution {
    func isAnagram(_ s: String, _ t: String) -> Bool {
        guard s.count == t.count else {
            return false
        }

        let sortedS = s.sorted()
        let sortedT = t.sorted()
        
        return sortedS == sortedT
    }
}
```

コードは以下の通りです。

```swift:Group Anagrams
class Solution {
    func groupAnagrams(_ strs: [String]) -> [[String]] {
        var anagramGroups:[String:[String]] = [:]

        for s in strs{
            let sortedString = String(s.sorted())
            if var group = anagramGroups[sortedString]{
                group.append(s)
                anagramGroups[sortedString] = group
            }else{
                anagramGroups[sortedString] = [s]
            }
        }
        return Array(anagramGroups.values)
    }
}
```

1. for文で引数の配列をループします
2. ループで各文字列をソートし、そのソートの結果が既に文字列の中にKeyとして存在する場合にはKeyに結びついている既存の配列に追加し、そうでない場合には新しく配列を追加します
2. 返すべき値にKeyは必要ないので、作成した`anagramGroups`のValueのみを抽出し、配列に詰めて返します

例えば、`"eat","tea","tan"`が順番に与えられる場合、

```
[aet:["eat"]]
[aet:["eat","tea"]]
[aet:["eat","tea"],ant:["tan"]]
```

といった結果になります。
おうちパソコン強化

こんにちは
おうちで家族が使うパソコンなんてOfficeが入っていてそれが普通に動けば十分と思っている。実際それで事足りる。
なので企業のおさがりであろう低スペックPCを中古で買うと２万円いかないぐらいで買えたりする。
なんだけど、ちょっとマイクラサーバー動かしてみようとか思うと途端にがくがくしだして、なんだかなーと思っていた。
別に今更自作しようとか思わないし、そんなつもりで買ったPCをいじろうとかこれっぽっちも思わなかったけど、これだけ古いなら強化してもたいしてお金かからないのでは？と思って少しだけ調べた。

## スペック
OptiPlex7010
Intel Core i5 (3世代)
Memory 8GB
SSD 256GB

## 分解
蓋開けてほこりを飛ばすくらいはしてたけど本格的に分解するとは思わなかった。
この機種、ディスクなんかのマウンターが邪魔してメモリに直でアクセスできない。なんてこった、メモリ確認したいだけなのにけっこう分解しないといけない。
めんどくせーーーーと思ったけど、こういう量産型は組み立てしやすくしてること多いから分解もけっこう簡単だった。なんなら矢印マークやら親切に書いてくれてるので調べなくてもいける。

![a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491285/9133bb0b-61cd-6415-0ea8-e8b2c72c88ce.jpeg)

これが４枚差さっていた。
この規格はエルピーダメモリ DDR3 1333MHz 2GB

「ふ～ん」って感じ。

## 購入
その前にうちで大昔サーバー用途なんかで余ってたメモリを譲り受けた気がして屋根裏をあさってみたら出てきた。
DDR3 - 1600MHz - 4GB が2枚（おうちの）
「おっ、規格あってるしいけそうじゃん。」
でも一応中古でも売ってるかもしれんしと思って分解したままその足でドライブがてらパソコン工房によってみると「あった。」
DDR3 - 1600MHz - 8GB 950円 (ノーブランド)
DDR3 - 1600MHz - 4GB 350円 (ノーブランド)
DDR3 - 1333MHz - 4GB 300円 (ノーブランド Made in China)
うん、全部怪しい。特に最後のやつ。全部買った。

## 組付け
どれかダメだろうし組み合わせていけそうなやつ採用しようと思って帰宅後
4枚全部抜いて組み合わせて指していこうと思った。
うちに余ってたメモリ、さすがにサーバー用途にしようとしてただけあっていっちょまえにヒートシンクついてるしごついのでこいつを優先的につけて、余ったスロットを全部埋めていこう作戦にした。
メモリスロットには順番があったりする。そこはちゃんとマザーボード（機種）の規格を見て。
１，２，３，４から同じ規格のメモリはデュアルに対応しているので、１と２，３と４で組み合わせてくれってことなんで
１，２ → DDR3 - 1600MHz - 4GB が2枚（おうちの）
３ → DDR3 - 1600MHz - 8GB 950円 (ノーブランド)
４ → DDR3 - 1600MHz - 4GB 350円 (ノーブランド)

これで最初の2枚がデュアルで認識されれば4GB + 8GB + 4GBで16GBにならんかなーと期待して指しなおして起動。
「起動しない！BIOSも起動しない！」
やばい、壊した・・・・と思って念のため適当に差したメモリをもう一度念押しして注意深く差しなおしてもっかい起動。
「普通に起動した」
差しが甘かったのか。でもBIOS起動しないとかあるんかい、とか思ったけど割とどうでもいいPCなので3秒で忘れた。
ちゃんと16GBで認識されてるし動作がめちゃ軽い！
前もってスペックを認識するアプリを使ってメモリの状態を見ておいたものと比較してもちゃんと認識されてるしスペックだけ上がっている状態。
（画像がなくてすいません）

## まとめ
重い腰をあげてやってよかった。
こんな低スペックを使う人がここを見るとも思えないけど、私みたいな人他にいませんか？
ぜひチャレンジしてみてください！
memosのupdate(Docker)

## はじめに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443650/2d121ff4-b142-110d-e1cb-3f97f5edddad.png)

こういった通知が来ることがあるので、たまにアップデートしているが、毎回調べているのでメモする。

## 前提

初期のデプロイにはこれを使用しているとする。

> Deploy with Docker in seconds
> `docker run -d --name memos -p 5230:5230 -v ~/.memos/:/var/opt/memos neosmemo/memos:stable`

## 方法

```bash
docker stop memos
docker rm memos
docker pull ghcr.io/usememos/memos:latest
docker run -d --restart=always --name memos -p 5230:5230 -v ~/.memos/:/var/opt/memos ghcr.io/usememos/memos:latest
```

## 参考
- https://github.com/usememos/memos
- https://github.com/usememos/memos/pkgs/container/memos
- https://wineroses.hatenablog.com/entry/2023/10/13/150839
やっぱり、エンジニアならハッカソンは一度は経験しよう！🤣

## はじめに

社内でAIハッカソンが行われました！
最近、AIブームすぎて何が何だかっていう感じですが、ここは流れに乗ってやったろうじゃないかとハッカソンに参加してみました！

あくまで、個人の参加録、振り返りです。
もし、これから、ハッカソンに挑戦したい人の参考になればと幸いです！

どのチーム・どのアイディアが優勝するのでしょうか？

## 伝えたいこと

### ハッカソンはいいぞ〜！

## なんのテーマでやるのか？

ずばり、**生成AI**です！

**生成AI**を利用して、何某かの施策立案を生成するツールの開発です！

業務時間を使用して行うハッカソンなので、新規性・創造性・実現可能性をしっかり考慮する必要がありました。

## チーム構成

今回のハッカソンは、日本とベトナムの混合チームで日本語と英語でコミュニケーションしながら、進めていきました。

以下の5名で行いました。

- コンサルタント
- Webエンジニア
- AIエンジニア
- AIエンジニア
- Webエンジニア　← 自分

## つくるもの

### 成果物

ユーザーのバイアスに気づかせ、新たな観点と情報を提供するWebアプリ

### 機能

以下の機能を持っているアプリです。

- 何某かのレポート投入
- 提案を生成
- 自律的になDBを構築

### 使用技術

- 生成AIツール
- Python
- LangChain

### 期間

**4日間**

2024/2/19(月) 〜 2024/2/22(木)

## 振り返り

ここからは、振り返りを行っていきたいと思います！

振り返りの手法として、KPTで行っていきます。

### Keep

- コンセプトは一貫して変えずに作り切ることができた
- プロジェクトワークで一つのコンセプトで徹底的にディスカッションできた
- 英語多めでもでもなんとかなった
- プログラミングは手段を徹底できた
- まず、動くものをという中で、いかに新規性を入れられるかを工夫できた

### Problem

- 英語のボキャブラリーの少なさ、咄嗟の"I see"とかがでてこない
- バイアスを取り除きたいといっているのに、自分たちがバイアスに掛かりまくっている
- LangChain、RAGとかキャッチアップできていないツケが回ってきた
- 生成AIは遊びでクソアプリしか作っていなかったので業務利用のイメージがない
- プレゼン資料作りとかコンサルの方にほぼ任せてしまった

### Try

- それな、それはそう、そうなんだけれども・・・、みたいな慣用句的な英単語は勉強してもいい
- LangChain、RAGは、ミニマムにアプリを作ってみる
- Gemini とか最新の動向をもっと追う、他社事例の勉強会の参加や発信をする
- LTとかさまざまなドキュメント関連で理解しやすい資料を心がける
- Qiitaの発信をもっと行う
- 勉強会の企画をもっと行う

### Action

- LangChain、RAGは、ミニマムにアプリを作る
- Gemini とか最新の動向をもっと追う、他社事例の勉強会の参加や発信
- それな、それはそう、そうなんだけれども・・・、みたいな慣用句的な英単語は勉強してもいい

:::note
Actionは、今後、実施して記事化する
※こうしないと忘れる。。。
:::

### 気づき

- ハッカソンはコンセプトがしっかりしていないとうまくいかない
    - コンセプトの共通認識を固める
- 普段、SESとかクライアントワークやっていると、チーム内もしくはお客様までしか関わらないけど、他の職種の人と関わるのって楽しいのだなと感じた
- ベトナム人めっちゃ乾杯したがる
- バインミー食べたい
- たーのしー（ハイキューゴミ捨て場の決戦　孤爪研磨のとあるセリフ）


## 結果

我々のチームは、２位/4チーム中でした！
優勝チームは、前回チャンピオンの2連覇で幕を閉じました。

楽しかったし、LLMもキャッチアップできたし、たくさん刺激を受けました！

## まとめ

今回のハッカソンでは、さまざまの方の尽力のおかげで開催できました。いち参加者として、めちゃくちゃ刺激を受けたし楽しかったハッカソンでした！

ここから業務に繋がればもっといいし、LLMやってみたいなとも思えた4日間でした！
（そのためには、もっと力をつけねば・・・！）

最後に、ちらっとこれから技術的なイベントにも力を入れたいと聞けたし、もっとラフにハッカソンをしたいとも聞くことができたのでリベンジもしたいです！

<font color="red">**ハッカソンを楽しもう！**</font>

## さいごに

弊社では、エンジニア積極採用中です！
SES、請負、受託、Saleforce やりたい方はご興味を持っていただけたら幸いです。

ワクトでは、以下の Mission・Vision・Value を掲げております。

Mission : 「IT× ワクワク」で、社会の発展に貢献する
Vision : 大切な人に心から薦めたい会社であり続ける
Value :
One team for customers
熱意 × 人格 × 能力
まずやってみる
ワクトでは、もう一つ重要なものとして「 マインドマップ 」というものがあります。
個人的にですが、こちらに共感していただけた方はワクトに合うかなと思っております。

![MindMap](https://camo.qiitausercontent.com/d4bc1bad02e4881409ad684cdf3e1fa4b25b2a6c/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333531323631362f37636461653334372d626230632d393532372d656430382d3164393463376630333337652e706e67)


https://wakuto.net/

https://www.wantedly.com/companies/wakuto0910

https://twitter.com/wakuwaku_toyou

また、本記事の内容は個人の考えであり、会社を代表するものではございません。
【Windows】忘れがちな朝の勤怠をPC立ち上げと共に表示してみた

ごきげんいかがですか。新卒一年目エンジニアのyuchamです

最近、特に休み明け等に勤怠を忘れることがあります😂
その度に、翌日勤怠実績修正をして上長に承認してもらわなければいけません

なるべくそのような手間をかけさせないようにしようと思い、
PC起動と共に勤怠のWebサイトを表示させることにしました

簡単ですが、メモ程度に以下で手順を説明していきます。

今回はPC起動時にQiitaサイトを表示させます

#### 1.事前準備

① まずはPC起動時に表示したい勤怠のサイトURLをコピーします。
（今回はQiitaのURLで、、😄）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/81a873ac-8e2b-cdea-1711-dc800806841b.png)

② デスクトップにいきます。

③ 右クリックをして、【新規作成】を押下し【ショートカット】を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/30fe9eea-dee8-704c-7a04-1d275bd21190.png)

④ ①でコピーしたURLを貼り付け、【次へ】を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/ab6f27cb-457d-b9b1-c446-2659af7e7eba.png)

⑤ ショートカットの名前を入力し、【完了】を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/f81f0196-fbab-69f7-edd8-5504230b88d9.png)

#### 2.PC起動時に特定のWebページを表示させる

①【スタート】を右クリックして、【ファイル名を指定して実行】を押下する。

②【名前】にshell:startupを入力し、【OK】を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/39ee2633-21e9-17cb-5f15-b0d5cfb2e907.png)

③ 開かれた【スタートアップ】フォルダに先ほど事前準備の⑤で作成したショートカットをドラッグアンドドロップする。

以上で完了になります！

#### 3.さいごに
簡単な内容でしたが、常に工夫しながら業務に向き合っていきたいと思います！
Flaskをdockerで立ち上げようとしたら色々エラーが出て苦しんだ記録

エラーログをちゃんと見て一瞬で解決したので、自慢がてら久々に記事を書いてみようと思った次第です。

# やりたいこと

以下のDockerfileを準備して、MacOS上でFlaskを起動したい
Dockerfileは docker-compose から読み込む形にする

# 遭遇したこと

Flaskが5000ポートで上手く立ち上がらなかったので困った。。。

## 環境
MacOS Sonoma 14.2.1
Docker version 24.0.7

## Dockerfile
```docker
FROM python:3

RUN apt-get update
RUN pip install --upgrade pip
RUN mkdir /usr/src/app
ADD . /usr/src/app
WORKDIR /usr/src/app
COPY ./requirements.txt /usr/src/app

RUN pip install -r requirements.txt
```

## docker-compose
```yaml
version: '3' # composeファイルのバージョン
services:
  backend:
    container_name: backend
    build:
      context: .
      dockerfile: ./build/Dockerfile
    volumes:
      - ./backend:/usr/src/app
    tty: true
    environment:
      FLASK_APP: apps.app
      DEBUG: True
      TZ: Asia/Tokyo
    ports:
      - 5000:5000
    working_dir: /usr/src/app
    command: bash -c "flask run --host=0.0.0.0"
```

こんなん準備して、とりあえずFlask環境構築するかー。
といういつものサクサク作るノリでやってみました。

# 作業内容とログ

実施コマンド
```sh
$ docker compose up -d --build

[+] Running 1/1
 ✔ Container backend Created                                                                          0.0s
Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:5000 -> 0.0.0.0:0: listen tcp 0.0.0.0:5000: bind: address already in use
```

おー。まさかのエラーログ。
5000ポートを誰かが使ってるので犯人探し開始

```sh
sudo lsof -P -i:5000
COMMAND   PID      USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ControlCe 675 gessy0129    8u  IPv4 0xee030b0cd4ce567b      0t0  TCP *:5000 (LISTEN)
ControlCe 675 gessy0129    9u  IPv6 0xee030b08260f71eb      0t0  TCP *:5000 (LISTEN)
```

ControlCeって誰・・。

まぁ、見覚えがないCOMMANDかつUSERがPCのユーザー、そして、IPv4とIPｖ６があるという事は、
・MacのOSが提供してる機能である
・ネットワーク系の機能である
という絞り込みが出来るので、後はググれば問題なし

参考までにググったキーワードは
**mac controlcenter port 5000**

ググった結果、
このAirPlayレシーバーというヤツが５０００番、７０００番を使うやつらしい。
そんなん使わないで欲しい。。。

![スクリーンショット 2024-02-26 9.56.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11006/4b85d9ec-eb69-16f3-f349-17ea2309e52e.png)

# 対処方法
このチェックボックスをOFFにすればオッケー
ついでにそれ以外の共有系の設定も見直してます

チェックボックスを外してさえあげれば問題なく起動出来ます。
```sh
$ docker compose up -d

[+] Running 1/1
 ✔ Container backend   Started                                                                          0.2s
```

これでとりあえず問題なし。

# 蛇足

・どうしてもAirPlayレシーバーを使いたい
・Flaskに5000を使って欲しい
という場合は、

**Flask起動後にAirPlayレシーバーをONにする**

という事をすれば7000番のPortを使ってくれるみたいです。
ビジネスの視点からアプリケーションを監視する

# 概要
モバイルアプリケーションのログ設計を考えるにあたり、何か良い本がないかを探したところ、[入門　監視](https://www.oreilly.co.jp/books/9784873118642/)が良さそうだったので長期休みを使って一読しました。

どの章も面白かったのですが、その中でもビジネスの視点からアプリケーションを監視するということにフォーカスした章があり、エンジニアとして考えたことのなかった視点から解説していたため、興味深かった箇所をメモとして残しておきます。

# 詳細

## KPI

KPIはビジネスが良い状態であるために会社が重要だと認識している計画の状態を測るための指標です。

一般的に、経営者の視点の関心は以下のようなものです。

- 顧客はアプリケーションあるいはサービスを使えているか
- 儲かっているか
- 成長しているか、縮小しているか、停滞しているか
- どのくらい利益が出ているか。収益性は改善しているか、悪化しているか、停滞しているか
- 顧客は喜んでいるか

つまり、現在会社は**儲かっている**か、**将来に向けて儲かるような状態を作れている**か、または**その両方**を満たしているかを測りたいということになります。

上記のような関心を持った経営者の質問に事業責任者が答える時、以下のような指標を出して説明を行うことが多いとしています。

- 月次計上収益
- 顧客からの月毎の経常収益
- 顧客あたりの収益
- 課金顧客の数
- ネットプロモータスコア(ユーザーあるいは顧客満足度の指標のこと。よくある「このアプリを友人に薦めますか？」という10段階のアンケートはこれを測るためのもの)
- 顧客生涯価値(Life Time Valueとも。1人もしくは1社が生涯にわたって企業にもたらす利益。顧客当たりの収益との違いは顧客当たりの収益は年単位、こちらの単位は生涯に渡って計算されること)
- 顧客あたりのコスト
- 顧客獲得単価
- 顧客の解約数
- アクティブユーザー数
- バーンレート(会社全体でどれくらいのお金を使っているか)
- ランレート(現在の支出を続けた場合に資金がなくなるまでの期間)
- TAM(ある特定のマーケットがどのくらいの大きさなのかの指標)
- 粗利(販売したもののコストを除いた利益を表す指標)
など。

補足となりますが、この記事で列挙している項目に対してより深く解説をしている[こちらの記事](https://a16z.com/16-startup-metrics/)を読むと、より理解が深まります。

##  YelpとRedditの事例

### Yelp

[Yelp](https://www.yelp.co.jp/%E6%96%B0%E5%AE%BF%E5%8C%BA)はローカルビジネスと人々を繋げるオンラインプラットフォームで、以下のような特徴があります。

- ローカルビジネスを探している人(レビューを書くユーザー)とビジネスページを管理するビジネスオーナー(レビューに返事をするかもしれないユーザー)が存在している
- ビジネスオーナーはビジネスページを「無料」で取得でき、Yelpはビジネスオーナから広告費用を徴収することでサービスをマネタイズしている

これらの記述だけでもビジネスKPIを作ることができます。

- 検索実行
- レビュー投稿
- ユーザーのサインアップ
- ビジネスページの取得
- アクティブユーザー
- アクティブビジネス
- 広告購入
- レビューに対する返事


これらを計測することで直感的にビジネスの状況を把握することができます。
つまり、**儲かっている**か、**将来に向けて儲かるような状態を作れている**か、または**その両方**を満たしているかを把握することができる、ということです。


### Reddit

[Reddit](https://www.reddit.com/)はSNSで、Redditには以下のような特徴があります。
- ユーザーはアカウントを作らなくてもRedditを閲覧可能である
- スレッドを投稿したり、コメントを付けたり、投票したり、プライベートメッセージを送信するにはアカウントが必要
- 広告、有料アカウントにグレードを設けるなどの手段でマネタイズを行っている

こちらもYelpと同様に、主要機能に対してのビジネスKPIを作ることができます。

- 現在サイトに滞在しているユーザー
- ユーザーのログイン
- コメント投稿
- スレッド作成
- 投票
- プライベートメッセージの送信
- 有料アカウントの課金者数
- 広告購入

主要機能に関連するビジネスKPIを計測することで直感的にビジネスの状況を把握することができます。

これらのビジネスKPIは、実は技術指標に結びつけることが可能です。
例えば、**ユーザーのログイン**というビジネスKPIを、**ユーザーのログインの失敗、ログインのレイテンシ**というような技術指標と結びつけます。
技術的な指標に結びつけることで、ビジネスKPIのみを設定するときよりも細かいレベルで「アプリケーションが動作しているかどうか」という質問に答えられるようになることがメリットです。


## 会社のビジネスKPIを見つける

全てのビジネスは異なるので一般化するのには無理があります。
ただ、何を計測するかを判断するときに間違いない方法があります。

それは「**人と話す**」ことです。

どういった人と話せばよいかというと、まず第一に**プロダクトマネージャー**です。プロダクトマネージャーの仕事は顧客が何を必要としているかを理解し、それを実現するためにエンジニアリングチームと協力することです。
多くのプロジェクトマネージャーは何が問題なのかを高いレベルで把握していることが大きな理由です。

その次に**ソフトウェアエンジニアリングチームのマネージャー**、**シニアソフトウェアエンジニア**と話せば何が問題で、どのように問題点を理解できているはずです。

そういった「人と話す」状況で著者がよく使う質問は、

- 私が会社に入りたてだとして、アプリケーションが動いていることをどうやって知ったら良いでしょうか？何をチェックしていますか？どう動いていたらよいのでしょうか？
- アプリケーションのKPIは何ですか？　なぜそのKPIを使っているのですか？　そのKPIはどんなことを教えてくれますか？

というものとされています。

## 感想

冒頭でも述べている通り、普段あまりビジネスの視点からアプリケーションを深く考察することがないため、勉強になりました。
アプリケーションログを設計する時にこれを取っておくとビジネス的な視点から分析するときに役に立つよね、という考えを事前に持つことができたのはこの章のおかげだと思います。

ただ、関わっているアプリケーションが社内向けのアプリであり、直接的な儲けを出さない場合、計測はどのように修正すれば良いのか？という疑問が少し残る部分もありました。
それも、既存の業務の置き換えの場合ならまだしも、完全新規の社内向けアプリとなると経営陣の欲しい情報は十分に取れるのでしょうか。
どこかにそんな事例を紹介した記事があれば読みたいです。情報お待ちしています。
【Laravel】ルーティング設定で同じディレクトリはまとめる！


# ルーティング設定で同じディレクトリはまとめる
例えば「hoge」というディレクトリにページが複数ある場合はグループを使ってまとめるようにする。
```
Route::get('/hoge/page1', function () {
    return view('page1');
});
Route::get('/hoge/page2', function () {
    return view('page2');
});
Route::get('/hoge/page3', function () {
    return view('page3');
});
```

↓

```
Route::group(['prefix'=>'hoge'], function () {
    Route::get('/page1', function () {
        return view('page1');
    });
    Route::get('/page2', function () {
        return view('page2');
    });
    Route::get('/page3', function () {
        return view('page3');
    });
}
```
BCM5301Xのまとめ

なんとか使えるようになったので、いったんまとめをします。

やったこと

* ビルドが通る様に既存コードを修正
* Ethernetドライバが動かなかったのでif_amac.cとして作り変え
* XHCI(USB3)のドライバを追加
* USBを有効にするためGPIO制御を追加
* Device Management Unit(dmu)のドライバを追加してCPUの温度をsysctlに追加

問題点

* ~~メモリが128Mしか使えない~~ (2024/3/7 修正済み)
* cpufuncの問題でセカンドのCPUが起動するが落ちて使えない(c2kでは使えているのでブートの初期化に依存しているのかもしれません)
* NANDの確認が出来てない(カーネルはネットワークで読み込んでrootfsはUSBにおいているので必要性がありません)
* amacは一つしか確認してない
* Robo Switchの任意の設定ができない
* armv7(non-hf)のユーザーランド(base)の動きがおかしい
* CFEなのにu-bootの処理が入ってしまっている
* VFPが無いが抜いてカーネルがビルドできない

使われていないので、いろいろ問題はありましたが、致命的に壊れているところはなくNetBSDの信頼性の高さがうかがえます。

完璧ではありませんが、十分実用になると思います。
【備忘】SendGridとは？

## Sendgridとは
Sendgrid＝メール配信サービス。
⇒クラウド型のシステムでアカウントを作成するだけで即日メールを送信できる、メールサーバーの構築が不要なメール配信システム

## 特徴
**1.信頼性の高い配信**：SendGridは、信頼性の高いインフラストラクチャーを活用して、メールの配信率を最適化可能。これにより、メールがスパムフィルターに引っかかることなく、受信者のインボックスに届く確率が高まる。

**2.柔軟なAPI**： SendGridは、開発者が独自のアプリケーションやシステムにメール送信機能を統合するための柔軟なAPIを提供。これにより、カスタムメールの送信や自動化が容易になる。

**3.詳細な分析と追跡**： SendGridは、送信されたメールのパフォーマンスを追跡し、開封率やクリック率などの詳細な分析を提供。これにより、マーケティングキャンペーンの効果を評価し、改善することが可能。

**4.スケーラビリティ**： SendGridは、さまざまな規模のビジネスに対応するスケーラブルなソリューションを提供している。小規模なスタートアップから大規模なエンタープライズまで、幅広いニーズに対応可能。

**5.セキュリティ**： SendGridは、セキュリティ対策に力を入れており、メール送信プロセス全体でデータの保護とセキュリティを確保可能。これにより、ユーザーのプライバシーが守られ、機密情報が保護される。

## メリット・デメリット
### メリット

**1.高い信頼性と配信率**: SendGridは、高い信頼性と配信率を提供。これにより、メールがスパムフィルターに引っかかるリスクが低くなり、受信者のインボックスに届きやすくなる。

**2.スケーラビリティ**: SendGridはクラウドベースのプラットフォームであり、ビジネスの成長に柔軟に対応で可能。急速にメールの送信量が増えても、SendGridはそれに対応し、高いパフォーマンスを維持している。

**3.豊富な機能**: SendGridには、A/Bテスト、スケジュール送信、カスタムテンプレート、リアルタイムの配信解析など、多くの機能が備わっている。これにより、メールマーケティングキャンペーンの最適化や効果の測定が容易になる。

### デメリット:

**1.コスト**: SendGridは他のメール配信プラットフォームと比較して、一部のユーザーにとっては高価になる可能性あり。特に送信量が多い場合や高度な機能を利用する場合は、追加のコストがかかること可能性もあり。

**2.学習曲線**: SendGridの高度な機能を最大限に活用するには、一定の学習曲線が必要。初めて利用するユーザーにとっては、操作方法や設定の理解に時間がかかる可能性あり。

## 他社製品との違い

**独自の機能セット**: SendGridは独自の機能セットを提供しており、他社製品とは異なる利点がある。
たとえば、リアルタイムの解析や高度なセグメンテーション機能など。

**開発者向けのフレンドリーさ**: SendGridは開発者向けに設計されており、APIやSDKを活用して簡単に統合することが可能。
そのため、開発者が既存のシステムやアプリケーションにSendGridを追加する際に、他社製品よりも利便性が高い。

**スケーラビリティと信頼性**: SendGridは大規模なメール配信において高いスケーラビリティと信頼性を提供可能。これは、大規模な顧客基盤や急速な成長を実現しているビジネスにとって重要な要素となる。

参考：https://notepm.jp/blog/2933

## まとめ
Sendgrid＝メール配信サービスのSaas製品となり、メールサーバの構築不要で対応できカスタマイズ可能なメール配信サービスである。
【Laravel】自分のiPhoneでローカル環境を確認する方法


# 自分のiPhoneでローカル環境を確認する方法

## viteの設定を変更する
serverのhostをtrueにする
```
export default defineConfig({
    ~~~
    server: {
        host: true,
        ~~~
    },
});

```

## --hostをつけて開発環境立ち上げ
```
npm run dev --host
```

```
Port 5173 is in use, trying another one...

  VITE v5.0.12  ready in 118 ms

  ➜  Local:   http://localhost:5174/
  ➜  Network: http://192.168.11.3:5174/
  ➜  press h + enter to show help

  LARAVEL v10.43.0  plugin v1.0.1

  ➜  APP_URL: http://localhost

```

これだけ！

接続できない場合は
- iPhoneとPCが別のネットワーク(wifi)に繋がってる可能性
- iPhoneのネットワーク設定を変更すれば解決するかも！
【Laravel】DBから取得数を指定してデータを取得する＠モデル


# DBから取得数を指定してデータを取得する
DBから取得したい数を指定してgetする方法はこれ！
```
Model::take($count)->get();
```

categoryが1のものを10兼取得する
```
Model::where("category", "like", "1")->take(10)->get();
```
Pandas、統計量のメソッド一覧



## はじめに
Pandas、統計量のメソッド一覧に関しての備忘録です。
コードを書き始めて1年以内の若輩者です😅
もし間違いがあれば、ご指摘いただけると助かります🙇
<br>
## 🦁<INS>**結論**</INS>🦁
様々な計算、方法がある。
正しい選択の仕方から、統計の公式を理解してする必要がある。

:::note info
押さえておくべき点
* 基本は列などをして指定して行う。
* Excelよりも早く処理ができる。（膨大なデータから計算するのに向いている。）
:::  
***

:::note alert
注意点
*  なにも選択してない場合（列など）は数値部分、全てを計算してしまう。
* numeric_only=Trueを入れないと「warning」が出ることがある。
:::  

***

## <INS>**一覧**</INS>
全ての数値の列の統計
※列を指定する→ df['列名']

## <INS>**df.mean()**</INS>
選択してる部分の平均を出す。
```py
df['年齢'].mean()
# 平均年齢
```
***  

## <INS>**df.max**</INS>

```py
df['年齢'].max()  
# 年齢の最大値
```
***  

## <INS>**df.min**</INS>

```py
df['年齢'].min()  
# 年齢の最小値
```
***  

## <INS>**df.sum**</INS>

```py
df['年齢'].sum()  
# 年齢の合計
```
***  

## <INS>**df.std**</INS>
選択したデータの標準偏差を計算。
データの比較をする際にバラツキ度合いを見るために使われる。
```py
df['年齢'].std()  
# 年齢の標準偏差
```
***  

## <INS>**df.var**</INS>
選択したデータの分散を計算。
標準偏差に近い意味合い。
```py
df['年齢'].var()  
# 年齢の分散
```
***  

## <INS>**df.median**</INS>
選択したデータの中央値を出す。
中央値は全体の数値のある中でのちょうど真ん中にあたるのが中央値。
```py
df['年齢'].median()  
# 年齢の中央値
```
***  


## まとめ✍️
大事なのは覚えることではなく、触れておくことだなと感じる。そして実際にコードで書いてみて覚えていこうと思う。

***  
## 参考にした記事📕
[Pandasの基本～表形式データ・データ分析～初心者向けのDataFrameの操作入門！]（https://youtu.be/HYWQbAdsG6s?si=WRW_Ld81eWhSVSSP）
[PHP]メモ化再帰アルゴリズム

今回は、計算コストの高い再帰関数の最適化手法の一つである「メモ化再帰アルゴリズム」に焦点を当て、PHPを用いた実装方法を解説します。

# メモ化再帰アルゴリズムとは
メモ化再帰アルゴリズムは、計算結果を一時的に保存（メモ化）して再利用することで、同じ計算の繰り返しを避け、アルゴリズムの効率を向上させるテクニックです。この方法は、特に再帰的な計算処理において、計算時間の削減に大きな効果を発揮します。

# メモ化再帰の動作原理
メモ化再帰では、関数が返す結果をキーと結果のペアで保存します。関数が呼び出されると、まず保存された結果の中に答えがないかを探します。もし以前に計算した結果があれば、その結果を直接返します。なければ、計算を行い、結果を保存してから返します。このプロセスにより、同じ計算を何度も行う無駄を省き、効率的なプログラムを実現します。

# PHPによるメモ化再帰アルゴリズムの例
```php
function fib($n, &$memo = array()) {
    if ($n <= 1) {
        return $n;
    }
    if (!isset($memo[$n])) {
        $memo[$n] = fib($n - 1, $memo) + fib($n - 2, $memo);
    }
    return $memo[$n];
}

echo fib(10); // 55
```
このコードでは、$memo配列を使用して、計算済みのフィボナッチ数の値を保存しています。これにより、計算時間が劇的に短縮されます。


# メモ化再帰のメリットと注意点
メモ化再帰の最大のメリットは、計算効率の大幅な改善です。特に再帰呼び出しによる計算量が指数関数的に増加する場合、メモ化による最適化は効果が顕著です。しかし、メモ化によってメモリ使用量が増加するため、使用するメモリの量には注意が必要です。大規模なデータや深い再帰を扱う場合、メモリの限界を超えてしまう可能性があるため、状況に応じた適切な最適化戦略が求められます。

# まとめ
メモ化再帰アルゴリズムは、PHPをはじめとする多くのプログラミング言語で有効な最適化手法です。この記事では、基本的な使い方を理解するためにフィボナッチ数列を例に取り上げました。
RestClientのDELETEリクエストでリクエストボディを使用する方法

# 概要
Spring FrameworkでREST APIの呼び出しでDELETEメソッドにリクエストボディを使用する方法です。

# Rest Clientのサンプル
[Rest Clientの公式ページ](https://spring.pleiades.io/spring-framework/reference/integration/rest-clients.html#_migrating_from_resttemplate_to_restclient)には以下のような3種類のサンプルがあります。
(RestTemplate から RestClient への移行)


```java
restClient
    .delete()
    .uri(String, Object…​)
    .retrieve()
    .toBodilessEntity()
```

```java
restClient
    .delete()
    .uri(String, Map)
    .retrieve()
    .toBodilessEntity()
```

```java
restClient.
    .delete()
    .uri(URI)
    .retrieve()
    .toBodilessEntity()
```

このいずれの方法でもDELETEにリクエストボディを付与することができませんでした。
（パスパラメータに変数を設定するメソッドのようです）

# 解決した方法
以下のような方法で解消しました。
```java
restClient
    .method(HttpMethod.DELETE)
    .uri(URI)
    .body(requestBodyMap)
    .retrieve()
    .toBodilessEntity()
```
個人開発でFlutterとFirebaseを使って60日でアプリをリリースした方法

## この記事について
FlutterとFirebaseを初めていじりながら、個人開発でアプリを作ってみたんです。開始から60日でリリースまで持っていけたのは、めちゃくちゃ嬉しい！この記事では、短期間でアプリをリリースするためのTipsをシェアしたいと思います。

## リリースしたアプリについて
作ったのは「ちょいトレ」というトレーニングアプリです。

コンセプトは「毎日たった3分から始められるトレーニングの友」。ちょっとした時間に健康への一歩を踏み出せるようなアプリを目指しました。

アプリの詳細・ダウンロードは[こちら](https://bit.ly/49x7VMP)です。
良かったら使ってみてください。m_ _m

https://bit.ly/49x7VMP

(現在はiOSのみで、Android版ももうすぐ出したいと思います。)
![Frame 12 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/80e97137-1ec8-3ede-8e28-b2ede2da7685.png)


### 使用技術
このアプリ開発には主に以下を使いました。
- Flutter
- Firebase
- Cloud Functions

## 開発期間
新年に「今年こそは何かアプリをリリースしてみたい」と思ってスタート。週末を使ってコツコツと開発して、約60日後にはリリースでき、この期間で完成できたのはかなり嬉しかったです。

## リリースに成功した4つのポイント
### Point1: シンプルに、無駄を省く
筋トレにハマっていて、それをアプリにしようと思い立ちました。一番大事にしたのは、やるべきことをシンプルに保つこと。いつだってやりたい機能はガンガンもりもりになっていきます。
今回は、「毎日短いトレーニング動画が届いて、トレーニング結果を記録できる」ここだけに絞りました。
また、画面遷移なども、紙に全体遷移を書くぐらいのざっくり計画に留めて進めています。(適当でも進められるのは、一人開発の利点ですね。)

![Screenshot 2024-02-26 at 8.05.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/38b0a4f2-2832-5951-ee59-6a136363078b.png)

常に持ってるのはこちらの精神です。大事ですね。w
![Screenshot 2024-02-26 at 8.08.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/f9d07dd9-f015-97b1-0e60-b6bdaaf54edd.png)
[参照](https://x.com/tokkun_9/status/1131177680785858561?s=20)


### Point2: FlutterとFirebaseの組み合わせは最高
FlutterでスムーズでキレイなUIを作れました。設定画面とかも、[settings_ui](https://pub.dev/packages/settings_ui)パッケージなどを使って一瞬でできました。
Firebaseは認証からデータベース、プッシュ通知まで、色々簡単にできて、マジで便利でした。
サーバレスの力を感じました。
個人開発で、アプリを作るなら、現状この2つの技術はオススメです。

### Point3: AIの力を借りる
Chat-GPTとGitHub Copilotは開発の大きな助っ人。特にChat-GPTは、コーディングのサポートからライブラリのオススメ、プライバシーポリシーの作成まで幅広く手伝ってくれました。Copilotもコーディングを予測してくれるので、作業がグンと早くなります。

### Point4: 焼肉駆動開発
「リリースできなかったら焼肉をご馳走する」と同僚に宣言。これがなかなか良い緊張感を生んで、モチベーションアップにつながりました。

## 役立ったツール集
開発で役立ったツールやリソースを紹介します。
- Figma : アプリ審査のスクショを作るとき「のみ」に使いました。
- [Flutterで始めるアプリ開発](https://www.flutter-study.dev/):無料で、始めてのflutter入門に最適です。
- [実践Firestore 技術の泉シリーズ](https://amzn.to/3uNJJ9P): kindle unlimited入っていれば無料です。
- Trello: タスク管理に使いました。
- ペライチ: サービスHP制作に使いました => [HP](https://choitore.hp.peraichi.com)
- GitHub Pages: 静的ページのプライバシーポリシー作るの使いました。ちなみにプライバシーポリシー文面はChat-GPTに作ってもらってます。 => [プライバシーポリシー](https://yuto-ktok.github.io/choitore/privacy-policy.html) 
- Notion: 作業ログまとめに

これらのポイントやツールを活用することで、もっとスムーズに、そして楽しく開発を進めることができます。個人開発の際にはぜひ参考にしてみてください。


## さいごに
まだ、荒削りなアプリですが、今後進化させていければと思います。
良かったら、いいねくださると励みになります！m_ _m

(この記事は書きたいこと、ばっと箇条書きにして、chat-GPTに校正してもらいました。ほんと便利な奴だぜ。)
ナレッジ記事未解決

[ナレッジ記事関連の覚えに戻る](https://qiita.com/Keiji_otsubo/items/3e5dcc478cb65b0d432c)



+ [Cahbge Knowledge page layout on Knowledge Article in the FSL Mobile app.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007FzQjH)
+ [Using Server Side Includes (SSI) or Similar?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007I4nfw)

残念ながらできない

+ [On "Enable Digital Experiences and Set Permissions" can't verify admin](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007LpL9D)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8f70ae59-a6be-ab8c-0dfc-38bc8f8f8de4.png)

We can't verofy that the admin is selected as a Lighning Knowledge Author

+ [ナレッジ記事をバージョン履歴とともにエクスポート](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Yvbe1SAB)

+ [【未解決】Export Articles for Translation Failure](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Pyd8R)

+ [【未解決】別の組織の知識を既存の組織に統合する](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000NERFZ)
【Next.js】レンダリングとは

# レンダリングとは
Next.jsのレンダリングは、Next.jsフレームワークにおいて、クライアントサイドとサーバーサイドのレンダリングの両方を含むプロセスを指します。

1\. **サーバーサイドレンダリング（SSR）** : Next.jsでは、ページがサーバー上で最初にレンダリングされ、HTMLコンテンツがクライアントに送信されます。これにより、初期のページの読み込みが高速化され、検索エンジンのクローラーがページの内容を確実にインデックスすることができます。サーバーサイドレンダリングは、getServerSidePropsメソッドを使用してページごとに定義されます。

2\. **クライアントサイドレンダリング（CSR）** : ページが初めて読み込まれた後、Next.jsはクライアント側でルーティングを処理し、必要なデータをフェッチしてコンポーネントを再度レンダリングします。これにより、ページ間の移動が高速化され、ユーザーエクスペリエンスが向上します。クライアントサイドレンダリングは、通常のReactコンポーネントのマウントと更新によって行われます。

# まとめ
Next.jsは、SSRとCSRの両方をサポートし、適切なレンダリング方法を選択することができます。これにより、ページの読み込み速度とパフォーマンスを最適化しながら、検索エンジンのクローラーと検索エンジン最適化（SEO）の観点からも優れたエクスペリエンスを提供することができます。
レンダリングとは

# レンダリングとは
レンダリングとは、コンピュータのデータや情報を、人間が理解できる形式に変換するプロセスを指します。特に、ウェブ開発の文脈では、レンダリングはウェブページやウェブアプリケーションの画面表示を生成するプロセスを指します。

# 手順
ウェブページやウェブアプリケーションのレンダリングは、通常次のような手順で行われます：

1\. **HTML生成** : ウェブページのコンテンツや構造が定義されたHTMLコードを生成します。これには、テンプレートエンジンやフレームワークなどが使用されることがあります。

2\. **CSSスタイリング** : HTML要素に適用されるスタイルやデザインを定義します。これにより、ページの見栄えやレイアウトが設定されます。

3\. **JavaScriptの実行** : ウェブページがインタラクティブになるために、JavaScriptコードが実行されます。これには、イベント処理や動的なコンテンツの変更などが含まれます。

4\. **画面への表示** : 最終的に、生成されたHTMLコードとCSSスタイルがブラウザによって解釈され、画面に表示されます。これにより、ユーザーがウェブページを閲覧し、操作することができます。

# まとめ
レンダリングのプロセスは、サーバーサイドで行われる場合もあれば、クライアントサイドで行われる場合もあります。サーバーサイドレンダリングでは、サーバーがHTMLコードを生成してクライアントに送信します。一方、クライアントサイドレンダリングでは、ブラウザがJavaScriptを使用してページの内容を動的に生成します。
[Google Sheets API] テキストを検索＆置換する

Google Sheets API v4（Java）を使用して、
スプレットシート内のテキストを検索し、そのテキストを置換する方法
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する](https://qiita.com/doran/items/3d43f776188b2281044c)
を参照ください。
```java
//例：
requests.add(moveDimension(sheetId)); //実行したいリクエストのMethodを指定
```
:::

:::note info
その他のGoogle Sheets APIは、下記の記事を参照ください。
[⧉[Google Sheets API] JavaでスプレットシートのメニューとAPIを関連づけてみた](https://qiita.com/doran/items/2f6f8932b994fbd1a170)
:::

|No|目次|
|---|---|
|1|[検索＆置換対象が全てのシート、またはシート指定](#1-検索置換対象が全てのシートまたはシート指定)|
|2|[検索＆置換対象が指定したシートの指定した範囲のみ](#2-検索置換対象が指定したシートの指定した範囲のみ)|

## 1. 検索＆置換対象が全てのシート、またはシート指定
検索＆置換の対象を全てのシートか、指定したシートのみにします。

検索オプションとして以下の指定が使えます。
　　・大文字、小文字を区別するか？
　　・検索値がセル全体と一致しているか？
　　・検索値が正規表現か？
　　・検索に数式を含めるか？

**サンプル コード**
シートを指定しない場合、findReplace(null)で呼び出してください。
```java
public Request findReplace(String sheetId) {
    Request request = new Request();

    FindReplaceRequest r = new FindReplaceRequest();
    r.setFind("2024年");          //検索する文字列
    r.setReplacement("XXXX年");   //置換する文字列
    
　　　　　　　　if (sheetId != null) {
        r.setSheetId(sheetId);    //シートを指定する場合
	} else {
         r.setAllSheets(true);    //全てのシートの場合
	}
    
    //r.setMatchCase(true);	       //大文字と小文字を区別する場合
    //r.setMatchEntireCell(true);  //検索値がセル全体と一致する必要がある場合
    //r.setSearchByRegex(true);	   //検索値が正規表現の場合
    //r.setIncludeFormulas(true);  //検索に数式を含むセルを含める場合

    request.setFindReplace(r);
    return request;
}
```
**実行結果**
これが、
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/490a2033-5788-da8a-181f-866631b5aa06.png">
全部置換されました。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/5fd53317-4b3c-ca98-6533-d60038029b5e.png">

## 2. 検索＆置換対象が指定したシートの指定した範囲のみ
検索＆置換の対象を指定したシート、範囲のみにします。
指定できる検索オプションは全てのシートを指定した場合と同じです。

**サンプル コード**
```java
public static Request findReplace(Integer sheetId) {
    Request request = new Request();

    FindReplaceRequest r = new FindReplaceRequest();
    r.setFind("2024年");            //検索する文字列
    r.setReplacement("XXXX年");     //置換する文字列
    //r.setMatchCase(true);	        //大文字と小文字を区別する場合
    //r.setMatchEntireCell(true);	//検索値がセル全体と一致する必要がある場合
    //r.setSearchByRegex(true);	    //検索値が正規表現の場合
    //r.setIncludeFormulas(true);	//検索に数式を含むセルを含める場合
    
    GridRange range = new GridRange();	//検索＆置換の範囲
    range.setSheetId(sheetId);		    //設定するシートID
    range.setStartRowIndex(0);		    //開始行(0スタート)
    range.setEndRowIndex(2);		    //終了行(0スタート)
    range.setStartColumnIndex(0);	    //開始列(0スタート)
    range.setEndColumnIndex(1);	        //終了列(0スタート)
    r.setRange(range);				    //範囲を設定

    request.setFindReplace(r);
    return request;
}
```
**実行結果**
これが、
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/490a2033-5788-da8a-181f-866631b5aa06.png">
指定の範囲のみ置換されました。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/b786b775-8cc9-47f7-58c9-bea9b6a7015f.png">

おしまい。。
【数学溢れ話】【Token】Lp空間(pノルム)

# Lp空間の概説
詳しくは以下を。
[Wikipedia「Lp空環」](https://ja.wikipedia.org/wiki/Lp%E7%A9%BA%E9%96%93)

# 実装例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597772/5ac32527-a4a1-c86d-be71-8f4c4d0d08dc.png)

```R
cx<-seq(0,1,length=61)
f0<-function(x,p){(1-(x^p))^(1/p)}
cy10<-f0(cx,1/10)
cy15<-f0(cx,1/1.782273)
cy20<-f0(cx,1)
cy30<-f0(cx,2)
cy40<-f0(cx,99)
plot(cx,cy10,type="l",asp=1,xlim=c(0,1),ylim=c(0,1),main="p-Norm",xlab="",ylab="",col=rgb(1,0,1))
par(new=T)
plot(cx,cy15,type="l",asp=1,xlim=c(0,1),ylim=c(0,1),main="p-Norm",xlab="",ylab="",col=rgb(1,1,0))
par(new=T)
plot(cx,cy20,type="l",asp=1,xlim=c(0,1),ylim=c(0,1),main="",xlab="",ylab="",col=rgb(0,1,0))
par(new=T)
plot(cx,cy30,type="l",asp=1,xlim=c(0,1),ylim=c(0,1),main="",xlab="",ylab="",col=rgb(1,0,0))
par(new=T)
plot(cx,cy40,type="l",asp=1,xlim=c(0,1),ylim=c(0,1),main="",xlab="",ylab="",col=rgb(0,0,1))
# 凡例を書き添える 。
legend("bottomleft", legend=c("p=0.1","p=1/1.78…","p=1","p=2","p=99"), lty =c(1,1,1,1,1),col=c(rgb(1,0,1),rgb(1,1,0),rgb(0,1,0),rgb(1,0,0),rgb(0,0,1)),cex=0.8) 
```
ここに突如登場する数1/1.782273(=0.561081276)は何かというとpノウムで「L2空間の真逆の円弧が軌跡として現れるp値」の近似値です。力任せで発見した後で数値検索をかけたら、Python製凸最適化モデリングツールCVXPYなどが採用している模様…
[CVXPY matrix style modeling limits](http://yetanothermathprogrammingconsultant.blogspot.com/2019/11/cvxpy-matrix-style-modeling-limits.html)
[Python による数理最適化モデリングツール CVXPY の初歩](https://mirucacule.hatenablog.com/entry/2019/10/22/163106)

# 実用例

詳しくは以下を。
[【機械学習】LPノルムってなんだっけ？](https://qiita.com/kenmatsu4/items/cecb466437da33df2870)
[線形回帰の過学習を抑えよう ～Ridge回帰とLasso回帰](https://www.n-insight.co.jp/niblog/20190917-1351/)

そんな感じで以下続報…
almalinuxにnode.jsとexpressをインストールする　

# almalinuxでnode.jsを開発したい -まずはコンソール-

※ここでの環境は2024年　almalinux9.3 node.js20.9 express4.18.2で検証しています。
バージョン違いでコマンド入力や記法が変わることも有るのであしからずご了承ください

※ここではエディタにvimを使っていますが、jsファイルの編集なら他のIDEとかを使ってもいいかもです。
visual studio codeなら公式サイトのRPMでインストールできるし日本語化もできるからいいかも？
https://code.visualstudio.com/download

## 手順
node.jsのパッケージをインストール
expressをインストール
maria dbをインストール
hallo world

## node.jsのパッケージをインストール
ターミナルで以下の操作をする
> dnf module list nodejs

これでバージョン確認2024年現在では20と18が使えるようです。

> sudo dnf module -y install nodejs:20/common

20をインストールしましょう

### npmが入っているか確認
> npm -v

10.1.0と表示されました

## expressをインストール
npmを使います

>npm install express

これで入りました。

## Maria DBをインストール
>sudo dnf -y install mariadb-server

インストール完了

## 設定ファイルを書く
> sudp vi /etc/my.cnf.d/charset.cnf

以下の記述を行う
>[mysqld]
character-set-server = utf8mb4
[client]
default-character-set = utf8mb4

これでOK
## mariadをサービス登録
> sudo systemctl enable --now mariadb

サービス登録できました

## hallo woaldしてみる

>cd "npm install express"を実行したディレクトリ

例
>cd /home/usui
ls -la

node_modulesと出てくるので

>cd ./node_modules
ls -la

express と表示されるので
>cd express
ls -la

package.json
が生成されているのでvimで覗いてみる

>vim ./package.json

いろいろ書いてあるのが分かったらvimは終了させる
expressの中にindex.jsがあるのでいろいろ書いてみる

>vim index.js

```
/*!
 * express
 * Copyright(c) 2009-2013 TJ Holowaychuk
 * Copyright(c) 2013 Roman Shtylman
 * Copyright(c) 2014-2015 Douglas Christopher Wilson
 * MIT Licensed
 */

'use strict';

module.exports = require('./lib/express');
console.log("hallo world!");

```

>node index.js

hallo worldと出力される

# almalinuxでnode.jsを開発したい -まずはブラウザで動くようにしたい-

expressディレクトリで
>sudo npm install -g express-generator
>express server

引き続き
>vim index.js

※他のIDEでも良い(画面はvisual source code)

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43283/f2664003-896c-cee8-7f5c-504b6b199d12.png)

index.jsを次のように書き換える
```
/*!
 * express
 * Copyright(c) 2009-2013 TJ Holowaychuk
 * Copyright(c) 2013 Roman Shtylman
 * Copyright(c) 2014-2015 Douglas Christopher Wilson
 * MIT Licensed
 */

'use strict';

const express = require('./lib/express')
const app = express()

app.get("/", function (req, res) {
    res.send("こんにちは");
})

app.listen(5000, function() {
    console.log("Listening on localhost port 5000");
})
```
## ブラウザでアクセス
まず、プログラムを起動
>node index.js

次にブラウザで
http://localhost:5000/
にアクセス
こんにちはと表示されればOK
PlunkerでPhaser.Physics その15

# 概要
Plunkerで、Phaser.Physicsやってみた。
CartPoleを、立たせます。
エージェントを、導入します。
環境が、エージェントにポールの傾きを与え、エージェントがPID制御を計算して、方向量ベクトルを返します。
環境が、重力シミュレートして、カートを動かします。
Kp,Ki,Kdは、自分が決めました。それぞれ、1.0，0.2、0.2です。
←キー、→キーで、外乱を与えることができます。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/fcfcb9b5-f6fb-9c4c-8b1b-4bb7a2b55a76.png)

# 

```

var Agent3 = function() {
	this.err2 = 0;
    this.err = 0;
    this.P = 0;
    this.I = 0;
    this.D = 0;
};
Agent3.prototype.get_action = function(setPoint, input) {
    var Kp = 1.0;
    var Ki = 0.2;
    var Kd = 0.2;
    var dt = 0.01;
	this.P = setPoint - input;
    this.I += this.P * dt;
    this.D = (this.P - this.err2) / dt;
	var u = Kp * this.P + Ki * this.I + Kd * this.D;
	this.err2 = this.err;
	this.err = this.P;
	return u;
}
function create() {
    game.physics.startSystem(Phaser.Physics.BOX2D);
    game.physics.box2d.debugDraw.joints = true;
    game.physics.box2d.setBoundsToWorld();
    game.physics.box2d.gravity.y = 100;

    ground = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 275, 0);
    ground.setRectangle(400, 50, 0, 0, 0);

    cart = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 243);
    cart.setRectangle(60, 10, 0, 0, 0);
    cart.mass = 10;

    pole = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 295);
    pole.setRectangle(4, 100, 0, 0, 0);
    pole.mass = 0.1;
    pole.linearDamping = 4; 
    game.physics.box2d.revoluteJoint(cart, pole, 0, -5, 0, 50);
    pole.angle = 5; 

    cursors = game.input.keyboard.createCursorKeys();
    
    agent = new Agent3();

    caption1 = game.add.text(5, 30, 'Angle: ' + pole.angle, { 
      fill: '#dddddd', 
      font: '10pt Arial' 
    });
}
function update() {
    caption1.text = 'Angle: ' + pole.angle;
    var u = agent.get_action(0, pole.angle);
    cart.applyForce(-u, 0);
    
    if (cursors.left.isDown) 
    {
        cart.applyForce(-5, 0);
    }
    if (cursors.right.isDown) 
    {
        cart.applyForce(5, 0);
    }
}
function render() {
    game.debug.box2dWorld();
}
var game = new Phaser.Game(400, 300, Phaser.CANVAS, 'phaser-example', { 
    create: create, 
    update: update, 
    render: render 
});
  
         


```

# 成果物

https://embed.plnkr.co/plunk/15lAINQI4EZGaam1


以上。
PlunkerでPhaser.Physics その14

# 概要
Plunkerで、Phaser.Physicsやってみた。
いよいよ、シュミレーションやってみます。
強化学習で使われる、CartPoleです。
←キー、→キーでCartが、移動します。
pole.angleで、ポールの傾きが取れます。
cart.applyForceで、カートを動かせます。
次回は、立たせます。

# 写真


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/932e3ea7-b121-dbbc-36d7-4a3a514ecda5.png)

# サンプルコード

```

function preload() {
}
function create() {
    game.physics.startSystem(Phaser.Physics.BOX2D);
    game.physics.box2d.debugDraw.joints = true;
    game.physics.box2d.setBoundsToWorld();
    game.physics.box2d.gravity.y = 10;

    ground = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 275, 0);
    ground.setRectangle(400, 50, 0, 0, 0);

    cart = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 243);
    cart.setRectangle(60, 10, 0, 0, 0);
    cart.mass = 1;

    pole = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 295);
    pole.setRectangle(4, 100, 0, 0, 0);
    pole.mass = 0.1;
    pole.linearDamping = 4; 
    game.physics.box2d.revoluteJoint(cart, pole, 0, -5, 0, 50);
    pole.angle = 5; 

    cursors = game.input.keyboard.createCursorKeys();
    
    game.add.text(5, 5, 'Pole balancing.', { 
      fill: '#ffffff', 
      font: '14pt Arial' 
    });
    caption1 = game.add.text(5, 30, 'Angle: ' + pole.angle, { 
      fill: '#dddddd', 
      font: '10pt Arial' 
    });
}
function update() {
    caption1.text = 'Angle: ' + pole.angle;
    if (cursors.left.isDown) 
    {
        cart.applyForce(-5, 0);
    }
    if (cursors.right.isDown) 
    {
        cart.applyForce(5, 0);
    }
}
function render() {
    game.debug.box2dWorld();
}
var game = new Phaser.Game(400, 300, Phaser.CANVAS, 'phaser-example', { 
    preload: preload, 
    create: create, 
    update: update, 
    render: render 
});
  
         


```

# 成果物

https://embed.plnkr.co/plunk/C7BZEdiFSVSbAsHJ


以上。
TA-LibをLinux環境にインストールした際の備忘録

# TA-Libをインストールする方法

この記事では、TA-Lib（テクニカル分析ライブラリ）をLinux環境にインストールする方法を紹介します。私自身のための備忘録です。

参考記事: https://pypi.org/project/TA-Lib/

## ステップ1: TA-Lib Cライブラリのインストール

TA-LibをPythonで使用するには、まずC言語で書かれたライブラリをシステムにインストールする必要があります。ルートアクセス権限がない場合は、ホームディレクトリ内でソースコードからコンパイルする必要があります。

Bashコンソールを開きTA-Libのソースコードをダウンロード。

```
wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz
```

ソースコードを展開します。

```
tar -xzf ta-lib-0.4.0-src.tar.gz
```

コンパイルとインストールを実行します。
```
cd ta-lib/
./configure --prefix=$HOME/.local
make
make install
```

## ステップ2: TA-Lib Pythonラッパーのインストール
Cライブラリがインストールできたら、PythonからTA-Libを使用するためのラッパーをインストールします。

必要な環境変数を設定がもしあれば設定します。

```
export LD_LIBRARY_PATH=$HOME/.local/lib:$LD_LIBRARY_PATH
```

TA-Lib Pythonラッパーをインストールします。
```
pip install TA-Lib
```
2024/2/26主にITとかセキュリティの記事

充電式バイブレータからマルウェア検出、USB充電デバイスに注意(2/24)
https://news.mynavi.jp/techplus/article/20240224-2889949/

サイバー犯罪5年で最多　沖縄県内23年　摘発96人、相談数も倍増(2/24)
https://ryukyushimpo.jp/news/entry-2837257.html

Z世代の若者の方が高齢者よりもオンライン詐欺の被害に遭いやすいのはなぜなのか？(2/24)
https://gigazine.net/news/20240224-gen-z-vs-boomers-scams/

セッションとは(2/23)
https://qiita.com/utyuuuu/items/8a678bd8cb6b736a25de

Cookieって何？(2/23)
https://qiita.com/utyuuuu/items/826b77cdd588f677e148

なぜ大規模言語モデル(LLM)はだまされやすいのか？(2/24)
https://gigazine.net/news/20240224-llm-gullible/

中共が民間企業を動員してサイバースパイ活動を強化(2/24)
https://www.epochtimes.jp/2024/02/207286.html

“中国製クレーンから情報漏洩リスク”米メディア　中国政府「完全にでたらめな話だ」と反発(2/23)
https://nordot.app/1133739702671785992
Ubuntu用GPU使用状態表示

linuxだとGPUの温度とか分かりにくくて怖い &「nvidia-smi」が見づらいので。
![Screenshot from 2024-02-26 01-58-60.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723193/960832c2-d797-7072-850f-6538c13789bc.png)
with chatgpt4くんと一緒作成。
多分誰でも作れます。
nc(netcat)コマンドの説明と使い方について

## 序章

「nc(netcat)」は、ネットワーク接続の読み書きを行うための強力なコマンドラインツールであり、ネットワークデバッグやデータ転送に広く使用されます。このブログ投稿では、ncコマンドの基本的な説明と、その使い方について3つの観点から説明します。

## ncコマンドの基本的な説明

「nc(netcat)」は、TCPやUDPプロトコルを使って、ネットワーク接続の読み書きを行うシンプルなユーティリティです。ポートスキャニング、ネットワーク接続の診断、データ転送、ポートリッスニングなどの機能を提供します。また、スクリプトと組み合わせることで、複雑なネットワークタスクを自動化することも可能です。

## ncコマンドの基本的な使い方

ncコマンドの基本的な使い方は非常に簡単です。例えば、指定したホストとポートにTCP接続を開くには、次のようにコマンドを入力します: `nc [hostname] [port]`。また、指定したポートでリッスンするには、`nc -l [port]`と入力します。これにより、接続要求を待ち受けることができます。

## ncコマンドの応用的な使い方

「nc」コマンドはその単純さと汎用性から、さまざまな応用的な使い方があります。たとえば、データ転送に使うことができます。送信側では、`nc -l [port] < [file]`と入力することで、指定したファイルを指定したポートで待ち受けます。受信側では、`nc [hostname] [port] > [file]`と入力することで、送信側からのデータをファイルに保存します。これにより、ネットワーク経由でのファイル転送が可能となります。

## ハンズオン：簡易チャットシステムの作成

ncコマンドを使用して、クライアント・サーバーシステムを作成し、簡易的なチャットシステムを構築してみましょう。

### サーバー側の設定

まず、サーバー側で待ち受けるために、`nc`コマンドを利用してリッスンモードで待ち受けます。ここでは、ポート12345で待ち受ける例を示します。

```bash
nc -l 12345
```
### クライアント側の設定
次に、クライアント側からサーバーに接続します。ここでは、サーバーのホスト名がserver_hostnameであると仮定しています。

```bash
nc server_hostname 12345
```

これで、サーバーとクライアント間での接続が確立され、メッセージの送受信が可能になります。クライアント側でテキストを入力し、エンターキーを押すと、そのテキストはサーバー側に送信され、サーバー側の画面に表示されます。同様に、サーバー側でテキストを入力すれば、それがクライアント側に送信されます。

このように、ncコマンドを使って簡易的なチャットシステムを作成することができます。ただし、この方法は非常に基本的なものであり、エラーハンドリングや複数のクライアントへの対応など、実際の通信アプリケーションを作成する際には考慮すべき多くの要素が省略されています。しかし、基本的なネットワーク通信の概念を理解するためのスタートポイントとしては、これ以上ないくらいシンプルな例です。


#### 自分のホスト名の調査方法
サーバーへの接続を確立するためには、サーバーのホスト名を知る必要があります。自分のサーバーのホスト名を調査する方法として、以下のウェブサイトが参考になります。

[自分のIPアドレスやホスト名を調べる方法](https://livra.geolocation.co.jp/iplearning/1700/)


## 結論
以上が、nc(netcat)コマンドについての説明でした。シンプルでありながらも強力なこのツールは、ネットワーク関連の作業を行う際には欠かせない存在となっています。この機会にぜひncコマンドをマスターして、あなたのネットワーク作業をより効率的に行いましょう。
Godot(4.x)で色をRGBの0~255で表現したいのに，なぜか真っ白になっちゃう！！！


:::note warn
警告
便宜上表記拡張子は.pyとしています．
脳内で.gdに変換してください．
:::

### TL;DR;
`Color`ではなく，`Color8`を使う．
```.py
var colorBackground = Color8(r, g, b)
```

### はじめに
最近 ~~(UnityとUEに挫折して)~~ Godot(Godot Engine v4.2.1)を触り始めた人です．
さて，背景色をスクリプトから灰色`(128, 128, 128)`に指定したいと思い`Color`というものを使って見たのですが，なぜか背景色は真っ白になってしまいました．．．ちゃんと`(128, 128, 128)`を渡しているのになぜだろう．．．

### 結論
はい．[ドキュメント](https://docs.godotengine.org/ja/4.x/classes/class_%40gdscript.html#class-gdscript-method-color8)を読みましょう．0~255のRGBで指定するには`Color8`というものを使う必要がありますね．`Color`は0~1のRGBで指定するものみたいです．おそらく1以上のものは自動的に1に変換されていたから，`(128, 128, 128)`を渡したら自動的に`(1, 1, 1)`に変換されて，白色になっていたのでしょう．
```.py
# r, g, bは0~1である必要がある．
var colorBackground0to1 = Color(r, g, b)

# r, g, bは0~255である必要がある．
var colorBackground0to255 = Color8(r, g, b)
```
【仕事の進め方評価アンケート】自立駆動してチームに貢献するための取り組み

# はじめに
こんにちは、ジュニアエンジニアの清水です。
この記事では、私が下半期の目標の一つとして設定した「**仕事の進め方評価アンケート**」の取り組みについて、共有します。

この取り組みは、どのような仕事にも適用可能で、成長のために大事な知見を得られたので、ぜひ読んでいただきたいです！👍

# 仕事の進め方評価アンケートの説明
では、仕事の進め方評価アンケートとは何なのかを紹介していきます。

## 背景と目的
私の目標は、自立駆動してチームに貢献することでした。以前は、指示に従って業務をこなすことが多かったため、自分で考えて行動し、チームへの貢献を目指したいと考えました。

この目標を達成するため、仕事の進め方の評価を可視化し、フィードバックを基に早期の成長を図るために、仕事の進め方評価アンケートを導入しました！

## アンケート内容
仕事の進め方評価アンケートは私のタスクが完了する度に、仕事の関係者に私の仕事の進め方はどうだったかフィードバックをもらうためのアンケートです。タスクごとにフィードバックをいただくことにより、私の仕事の進め方について良い点や改善点が即座に得られて、次のタスクに活かすことができます！

実際に、下半期に取っていたアンケートの項目は下記になります。

1. 評価対象の仕事内容
1. 自立駆動してチームに貢献できていたか、5段階で評価
1. フィードバックコメント

![スクリーンショット 2024-02-25 21.31.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588214/55efc1d2-b975-1455-bb9d-2ba7a61ee5f5.png)

シンプルですが、私の仕事の進め方に対する評価を可視化でき、フィードバックをもとに改善点が見つかり、早く成長できる内容になっています。

## 振り返り方法
フィードバックは、KPT (Keep, Problem, Try)に分類し、Notionに記録しました。
また、上司とは2週間ごとに振り返りを行い、改善策を決定しました。

これにより今後のタスクにおいてより自立駆動できるように成長できます!

# 仕事の進め方評価アンケートの実施結果
実際にアンケートを実施して得られたことを共有していきます！

## フィードバック内容
アンケートからは、肯定的なフィードバックとともに、コミュニケーションやタスク管理に関する貴重な改善提案を受け取りました。これらのフィードバックは、私の成長にとって非常に有益でした。
実際にフィードバックコメントをいただいたタスクについて、以下のようにKPTに分類しました。

![スクリーンショット 2024-02-25 21.21.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588214/38a2d15f-1053-7cc7-b5b4-e7762cfbd566.png)

アンケートにご回答していただいた上司、同僚、後輩に大変感謝しています！🙏

## 改善と成長
フィードバックを受けて、私は特にコミュニケーションスキル、タスク管理能力、および技術力の向上に焦点を当てました。定期的なフィードバックの振り返りが、自己反省と目標設定を効果的に進めるための貴重な機会となりました。
ここでは、具体的なタスクにおける振り返りの例をいくつか紹介します。

**脆弱性対応タスク**：初めて扱うサービスの修正と実装に自立して取り組んだことが評価されました。また、日々の進捗報告を通じてコミュニケーションの質を向上させることに成功しましたが、コードの可読性について改善の余地があるとの指摘を受け、技術的な理解を深めました。

**WOVN翻訳対応**：仮説を立てる力やコーチングを受ける機会が多いとのフィードバックを受けて、具体的な改善策に取り組み、自立してタスクを遂行できるようになりました。

**負荷試験**：責任を持って取り組んだものの、実行背景の理解や相手目線でのアウトプットに改善の余地があると感じました。これを受けて、タスクの意図を深く理解し、常に相手の立場に立ったコミュニケーションを心がけるようにしました。

**各種問い合わせ対応**：プロダクト改善において既存の処理にとらわれず、より良い解決策を考えることや、知識と情報を充実させる必要性を指摘されました。これを機に、知識を広げ、プロダクトを改善するための自発的な思考を強化しました。これらのフィードバックを活用して、その後の問い合わせ対応で積極的な姿勢と迅速な対応、コードの早期調査・修正を実現し、肯定的な評価を増やすことができました。

これらの改善を通じて、技術的スキルだけでなく、コミュニケーション能力やタスク管理能力も向上し、自立駆動してチームに貢献できるようになったと感じています。

## 学んだ教訓
この取り組みを通じて学んだ最も大切な教訓は、**フィードバックの価値**と**継続的な改善の重要性**です。フィードバックを真摯に受け止め、具体的なアクションに落とし込むことで、目に見える形での成長を実感できました。また、自分一人では気付かなかった視点や改善点が明らかになり、それらを改善することで、より効率的に、かつ質の高い仕事をすることができるようになりました。

# まとめ
この取り組みを通じて、自立駆動してチームに貢献する能力を大きく向上させることができました。今後は、この経験を活かし、さらに高いレベルでの自立駆動を目指していきます。また、今回学んだフィードバックの重要性を忘れずに、常に自己反省と自己改善を続けていきたいです！

# おわりに
仕事の進め方評価アンケートを実施し、フィードバックを基に成長するこの取り組みは、私にとって非常に価値のある経験でした。この記事を通じて、同じように成長したいと考えている人に少しでもインスピレーションを与えられれば幸いです。

最後まで読んでいただき、ありがとうございました！
Android studioのUnit testやってみる

## はじめに
Android studioで簡単なUnit Testを行ってみました。
使用言語はJavaです。
Javaのテストといえば「JUnit」ですが、Android studioでもJUnitを用いてテストを行います。


## テスト用のクラスを作る

テストで使用するクラスを作成します。

```Hoge.java

package com.example.sampleapplication;

public class Hoge {

    private String name;
    private int age;

    public Hoge(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public String selfIntroduction() {
        String text = "私の名前は"+name+"です。年齢は"+age+"歳です。";
        return text;
    }
}

```

適当なメソッドにカーソルを合わせ、Ctrl＋shift+Tを押し、「Create Test」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520337/9c717148-c38f-d2e8-6efd-7eb474e69d92.png)

SetUpとtearDownは、テスト内容に応じてチェックを入れてください。
また全メソッドをテストしたい場合、Memberのチェックを全てONにしてください。
OKを押すと、テスト用のクラスが`module-name/src/test/`配下に作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520337/0012816d-a478-f31a-f4b1-35f9c0a521f1.png)


## テストを記述する

↓が作成されたテストファイルに、テスト内容を記述したものになります。

```HogeTest.java
package com.example.sampleapplication;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class HogeTest {

    Hoge hoge;

    @Before
    public void setUp() throws Exception {
        hoge = new Hoge("太郎", 20);
    }

    @Test
    public void getAge() {
        assertEquals(10, hoge.getAge());
    }

    @Test
    public void getName() {
        assertEquals("太郎", hoge.getName());
    }

    @Test
    public void selfIntroduction() {
        String name = hoge.getName();
        int age = hoge.getAge();
        assertEquals("私の名前は"+name+"です。年齢は"+age+"歳です。", hoge.selfIntroduction());
    }
}
```

SetUpにチェックを付けると、`@Before`から始まるメソッドを用意してくれます。
こちらは、各テストメソッドを実行する前に都度実行してくれるSetUpメソッドになります。
今回はHoge.javaをインスタンス化してくれてます。

`@Test`から始まっている部分が、テストメソッドになります。

## テストの実施

Ctrl＋shift+F10か、テストファイルを右クリックして「Run ファイル名」を選択することで、テストを走らせることができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520337/5907f508-a5cc-a385-c1a5-4f51d7372089.png)


結果は以下のように出力されます。
こちらは全テストが無事通ったケースです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520337/bde5dea9-5890-c4b2-8e97-1483490017de.png)


テストに失敗した場合、このような表示です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520337/9f2fbc0a-b050-a036-7f50-9e9b07e71332.png)


## 終わりに
Android studioでのUnit testの実施は比較的簡単でした。
今回はassertEqualsを使った簡単なテストしか行っていませんが、
Androidのアプリ開発を行うなら、しっかりJunitの使い方も勉強しなければなりませんね。

こちらの記事では、Junitしか使用していませんが、
テスト用のライブラリを使用する場合、依存関係を**build.gradle**に記述する必要があります。
詳しくは、[デベロッパーガイド](https://developer.android.com/training/testing/local-tests?hl=ja&_gl=1*l367k3*_up*MQ..*_ga*MzIzMTE4MjQxLjE3MDg4NzA0Njg.*_ga_6HH9YJMN9M*MTcwODg3MDQ2Ny4xLjAuMTcwODg3MDQ2Ny4wLjAuMA..#java)をご確認ください。
strings command

# Linuxコマンド「strings」の解説と使い方

## はじめに

Linuxユーザーにとって、コマンドラインツールは日々の作業を効率化するための重要な要素です。今日は、その中でも特に有用なコマンドの一つ、「strings」について詳しく説明し、その使い方を示します。

## 「strings」コマンドとは？

「strings」コマンドは、バイナリファイルを読み込み、その中に含まれる印刷可能な文字列を抽出して表示するLinuxコマンドです。これは、バイナリファイルの中身を調査する際や、デバッグ時に非常に便利なツールとなります。

## 「strings」の基本的な使い方

「strings」コマンドの基本的な使い方は非常に簡単です。コマンドラインに「strings [ファイル名]」と入力します。例えば、「strings example.bin」と入力すると、ファイル「example.bin」内の印刷可能な文字列が全て表示されます。

## 「strings」の高度な使い方

「strings」コマンドは、その基本的な使い方だけでなく、オプションを用いることでさらに強力なツールとなります。例えば、「-n」オプションを使用すると、指定した長さ以上の文字列のみを表示することができます。「strings -n 10 example.bin」と入力すると、10文字以上の文字列だけが表示されます。

## まとめ

Linuxコマンドの一つである「strings」は、バイナリファイルから文字列を抽出するための強力なツールです。基本的な使い方から高度な使い方まで、色々な方法で使用することができます。日々の作業を効率化するために、「strings」コマンドの使い方を覚えておくと良いでしょう。
Vim cheat sheet

# Vimの基本的なコマンド
- `i` : カーソルの前に挿入モードに入ります。
- `a` : カーソルの後に挿入モードに入ります。
- `v` : 文字単位のビジュアルモードに入ります。
- `V` : 行単位のビジュアルモードに入ります。
- `:w` : ファイルを保存します。
- `:q` : Vimを終了します。
- `:wq` : ファイルを保存してVimを終了します。

# 削除に関するコマンド
- `x` : カーソルがある位置の文字を削除します。
- `dd` : カーソルがある行を削除します。
- `2dd` : カーソルから始まる2行を削除します。(数字は任意の行数を指定できます)
- `:%d` : 全部の行を削除します。
- `:[n],[n]d` : n行目からn行目を削除します。

- `set number` : 行番号を表示させます。 


# Vimを使い倒す
- https://vim-adventures.com/
- https://dev.classmethod.jp/articles/vim-quickstart-with-vimtutor/