OmniAICreator/Qiita-1.07M huggingface dataset:
【React × firebase hosting × supabse】学習記録アプリを作ってgithub actionsでCI/CDを構築

# はじめに
私は現在、プログラミングコミュニティ「JISOU」に参加させていただいており、Reactの勉強を基礎から行っています。
supabaseの利用、Reactの自動テストやgithub actionsを使ったCI/CDの構築などを初めて行いました。そこでの気づきの共有となります。

# 行ったこと
前回のJISOUの課題は、学習記録アプリの作成(データが永続的ではないもの)でした。

https://qiita.com/yuuki4135/items/d5d147ca84a007d44088

今回は前回の学習記録アプリへの追加改修で
・supabaseのデータベースを利用して、記録を永続化する
・firebase hostingを利用して、ページをネット上に公開する
・github actionsを利用し、CI/CDを構築する
・jestとreact-testing-libraryを利用し、自動テストを行う
というものでした。


https://github.com/yuuki4135/study-time-record-app-v2

# 気づき
* supabaseについて
supabseは初めて利用しました。<b>数行のコードで簡単にDBに接続できとても便利</b>だと感じました。
私はfirestoreやawsのdynamoDBを利用したことがありましたが、supabseはNoSQLではなく、リレーショナルDBとなっており普段MySQLなどを使う人にとっては、データベースの構成が作りやすいと思いました。AuthenticationやStorageなどのサービスもあるようなので、使ってみたいです。
* github actionsについて
初めてgithub actionsを利用してCI/CDを組むことになったんですが、ベースイメージを選択して(今回はubuntu)、stepごとにコマンドを実行し、reactのビルド・テスト・デプロイなどを行うものでした。普段Dockerを使っていたからかもしれないですが、<b>とてもイメージしやすく使いやすかった</b>です。
ベースイメージにはMacOSなども入っているようだったので、iOSアプリの開発など行った際にはgithub actionsでビルドしたいなと思いました。
* reactの自動テストについて
こちらの気づきは別の記事として公開しました。

https://qiita.com/yuuki4135/items/cf39ac202009ca5e12f9

自動テスト時のデータベース関連処理やAPI処理がうまくイメージできず、苦戦しました。
JISOUの他のメンバーの方も苦戦されているようでした。



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

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

https://projisou.jp
【React / Jest / react-testing-library】自動テスト時のデータベース通信処理やAPI通信処理について / モック化

# はじめに
ReactのJestとreact-testing-libraryを使用して自動テストを組んでいる際にテスト中のデータベースとの通信処理やAPIの通信処理のテストをどう書けばいいのかわからず、調べるのに時間がかかってしまったためまとめます。

# 問題
reactで自動テストを組んでいるときに、コンポーネントのテストを行っていたのですが、その中に記載していたsupabaseとの通信処理が終わらず、テスト時はローディングが出たままになっており、データ表示のテストができませんでした。

# 解決方法
#### その１
* 通信処理終了とstateの変更処理まで処理を待ってあげる
await actを使用することでstateの変更が終わって再レンダリングがすべて終わるのを待つことができるみたいです。
  ```javascript
    it('should render title', async() => {
    await act(async () => {
      render(<App />);
    });
    const titleTag = screen.getByTestId('title');
    expect(titleTag).toHaveTextContent('学習記録一覧');
  });
  ```
  
#### その2
* 既存の関数をモック化する
モック化の方法は参考記事を見ていただきたいです

Jestやreact-testing-libraryの自動テスト中の通信処理の返り値というのは実際にDBに入ってる値を使ってしまうとバラバラの値が返却されてしまうため、モック関数を用意しその中で予測される値を返してあげることでテスト中の値のばらつきがなくなるみたいでした。

# おわりに
DBやAPIなどの通信処理のテスト方法はモックを使えばいいということまで自分の検索ワードではすぐにたどり着くことができませんでした。同じようにモックに行きつくまでに時間のかかる人が少なくなるようまとめてみました。どなたかの時間削減になれば幸いです。

# 参考
https://qiita.com/bisketoriba/items/8e2295895d74d646b1e6

https://qiita.com/shunii/items/64ff8b8c7957d8f8b61a
VSCode+PythonでAtCoderを自動提出（の補足）

基本的には[この記事](https://qiita.com/prln/items/974f1280baa70bd1fd0d)を参考にすると良い。補足として…

- 例えば「[アルゴリズムと数学](https://atcoder.jp/contests/math-and-algorithm)」について、VSCodeにディレクトリが自動作成するためには、`acc new math-and-algorithm`を実行すれば良い。
- ローカル環境に複数のPython環境が複数ある場合は、`tasks.jaon`を以下のように変更すると良い。

```json:tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "CheckTestCase",
      "type": "shell",
      "command": "cd ${fileDirname} && oj t -c 'python3 main.py' -d ./tests/",
      "presentation": {
        "reveal": "always",
        "focus": true,
        "panel": "shared"
      }
    },
    {
      "label": "SubmitCode",
      "type": "shell",
      "command": "cd ${fileDirname} && acc s ${fileBasename} -- --langage:xxx",  // 変更点。xは使用するPythonインタープリタ
      "presentation": {
        "reveal": "always",
        "focus": true,
        "panel": "shared"
      }
    }
  ]
}
```
最近よく出るQiita/Browser Error(131) 

直近のQiitaの仕様変更、エラー類は、作業効率が落ちる。

【殿堂入りキャンペーン】N倍の文字列 (paizaランク D 相当) C++(55)
https://qiita.com/kaizen_nagoya/items/5b9d56fd2bca32bd7dbf

の実行結果をはりつけると。頻繁に

>メモリの使用路湯が多すぎたため、このページを再読み込みしています。

が出るようになった。

上記エラーがでずに、再読み込みのような動作をすることもある。

ブラウザ側の問題か、Qiita側の問題かを切り分けるためのパケット記録の確認はまだ。
LeetCode挑戦日記：Day42

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 841. Keys and Rooms

`0`から`n-1`までラベル付けされた`n`部屋があり、部屋`0`を除いてすべての部屋はロックされています。
あなたの目標はすべての部屋を訪れることです。
しかし、鍵がないとロックされた部屋に入ることはできません。

部屋を訪れると、一連の異なる鍵を見つけることがあります。
各鍵には数字が付いており、それがどの部屋を開けるかを示しています。
これらの鍵をすべて持って他の部屋を開けることができます。

配列`rooms`が与えられたとき、`rooms[i]`は部屋`i`を訪れたときに見つける鍵のセットを表します。
すべての部屋を訪れることができる場合は`true`を、そうでない場合は`false`を返します。

## 素直に解いてみる

### 考え方

1. 訪れた部屋を保存する配列を作成し、再帰関数を使って見つけた鍵の部屋を順番に訪れていく
1. 全ての部屋を訪れていたら`true`を返す

### コーディング

```typescript
function canVisitAllRooms(rooms: number[][]): boolean {
    const visitedRoom = new Array(rooms.length).fill(false);

    const func = (roomNumber: number): void => {
        if (visitedRoom[roomNumber]) { return; }
        visitedRoom[roomNumber] = true;

        rooms[roomNumber].forEach((key: number) => {
            func(key);
        });
    }
    func(0);

    return visitedRoom.indexOf(false) === -1;
};
```

### 結果

Runtime：49ms
Beats 96.94%

Memory：52.08MB
Beats 65.14%
GitHubでリポジトリを作成後、pushするまでの手順

## 概要
GitHubでリポジトリを作成してから、`git push`するまでの流れを備忘録として残す。
## 手順
1. GitHubで作成したpushしたいリポジトリを開いてください
2. 「Code」ボタンをクリックしてください
3. cloneするためのURLおよびSSHがあるので、コピーしてください
4. ターミナルに移動し、`git clone [URL]`をしてください
5. その後、コードを変更した場合は`git add 'ファイルのパス'`を実行後、`git commit -m 'コミットメッセージ'`をしてください
6. 最後に`git push`をすれば、完了です

## 最後に
ここまで読んでくださりありがとうございます。
今更ですが、リポジトリを作成してから`git push`するまでの流れについて度々調べることがあったので、記事にまとめました笑
この記事が誰かの役に立ってくれれば嬉しいです。
## 参考資料
- [【メモ】GitHubでgit clone〜git pushまで](https://qiita.com/nt-7/items/c5ea999a2638e03ee418)
「LINE Bot」で、社内の困り事を解決！

# 超初心者の試み
みなさま、はじめまして。プログラミング超初心者が１週間で挑戦してみました。
小売業スタッフとして勤務しており、身近な課題についてアクションできないか
奮闘した記事になります。

# 使用ツール
・LINE
・Make
・Google スプレッドシート

# 作成したのはLINE Botの「ろぼっとくん:robot:」
自分の直近月度の勤務計画を確認する時、わざわざPCを立ち上げたり、全て手帳に記入しておいたり、印刷して冷蔵庫に貼ったり（うちの妻がよくやる）…
#### <font color="red">**「なんだかアナログな確認方法だなぁ」**</font>と思っていました。

そこで「簡易秘書＝ろぼっとくん」に日付入力に対して、勤務計画を返信してもらおうと考えました。
様々な記録媒体を確認するのが手間で、自分の記憶に頼る⇒勤務計画を勘違いして
勤怠エラーなんて事が過去にも何度もありました…(笑)

加えて、部署内の皆さんにどんな機能が欲しいかヒアリングしたところ
「【店舗名】入力で【店舗コード】と【店舗Mgr電話番号】がすぐに確認できるようにして欲しい」と意見を頂きました。長年勤めていて、60店舗以上の店舗コードを
全て暗記している人もいますが、私含め経験の浅い方々は、出先で確認したい時に
意外と困るもの…。
電話番号もアドレス帳に全て登録しておけば…？と思われるかもしれませんが、
こちらも出先や社用スマホ外からの連絡時には確認が難しいです。

#### 今回の「ろぼっとくん」は、サクッと確認できるのが一番の利点です！
<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="zxx" dir="ltr"><a href="https://t.co/oJe3yZuWID">pic.twitter.com/oJe3yZuWID</a></p>&mdash; minaharu (@mina_haru_32527) <a href="https://twitter.com/mina_haru_32527/status/1824269834684883453?ref_src=twsrc%5Etfw">August 16, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# Makeシナリオ作成
【手順①】Makeシナリオを以下のように配置する。
![シナリオ①.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844566/9f6bbfaf-3d0b-33a2-1e88-d3df7e2317b2.png)

## 各モジュール作成
【手順②】Googleスプレッドシートを設定する。
「キーワード」＝LINE入力テキストと
「返却」＝返信内容を事前に作成しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844566/15e54950-e2cc-6074-5a61-53da5c73cbc0.png)

店舗情報についても同じシートに列挙しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844566/78d4f911-6a62-efd2-ef1a-fdcdd8942e91.png)

【手順③】返信内容の分岐を設定する。
★Router分岐①　返信内容が「ある」場合（Set up a filter）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844566/1da651bd-c06e-fadc-d17c-14fd1cabb144.png)
こんな感じでフィルター内を設定します。
ポイントは
・「<font color="red">**Exists**</font>」を選択すること
・「Add <font color="red">**AND**</font> rule」を選択して「返却」を設定すること
「OK」を押して完了。

「ある」場合の返信設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844566/8933846b-5bbd-4c88-65b0-1feeb9b9c89e.png)
こんな感じでTextに「返却」を選択します。
「OK」を押して完了。

★★Router分岐②　返信内容が「ない」場合（Set up a filter）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844566/0b7becb3-1921-9c71-854e-a18f401e2c43.png)
こんな感じでフィルター内を設定します。
ポイントは
・「<font color="red">**Does not exist**</font>」を選択すること
・「Add <font color="red">**OR**</font> rule」を選択して「返却」を設定すること
「OK」を押して完了。

## 実際の動作状況


こんな感じで自身の勤務計画と、店舗情報を返信してくれる「簡易秘書」完成！
実際にこの画面を部署内の皆さんに見せたところ感動していました(笑)
今後は皆さんの勤務計画を追加で登録して、「ろぼっとくん」アカウントを
部署内の皆さんに共有して使えるようにしたら、完了です！

## 最後に
超初心者でも簡単に設定できました！
まだまだ追加したい機能はありますが、ひとまず満足のいく出来栄えです(笑)
拙い文章と、ちっぽけな制作ですが、記事に残させて頂きます。
JPEG画像とRAW画像を整理するツールを作成したお話

## はじめに

花火を撮るため久しぶりに一眼カメラ(SONY a6400)を触りました。

折角なのでRAW現像もしたいなと思い、データの保存モードをJPEG+ARWで保存して打ち上げ花火を撮りまくってたのですが、データ数がめちゃくちゃ多い&よく撮れてない物も多く写真を選別することにしました。

SONYのカメラではRAW形式のファイル(ARWファイル) と JPEGファイルが同じディレクトリ以下に格納されるため、JPEG画像で取れ高を確認⇒JPEGとRAW画像を削除みたいな感じにすると途中で画像セットがよくわかんなくなってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3864340/d5a58eb0-ff39-25aa-16ea-d4196d173865.png)

なのでJPEGファイルをプレビューしつつ不要な画像はRAWファイルもろとも削除する(別ディレクトリへ整理する)みたいなツールを書いてみました。

## 環境情報

* Windows10
* Python 3.10.6
    * opencv-python
    * shutil

## ツール実物

[GitHub](https://github.com/hlowin/delete_jpg_arw_set)にコミットしてみました。

肝となる部分としては下記になります。

1. [DELETE]ディレクトリの作成

    間違って削除してしまった場合でもすぐ戻せるように[DELETE]ファイルへ削除したファイルを移動しておきます。

    ```python
    ...
      # make directry for delete files
      delete_dirpath = dirpath + "/[DELETE]"
      os.makedirs(delete_dirpath, exist_ok=True)
    ...
    ```

2. キー操作で画像送り、削除、終了操作
    * "<"キーで前の画像へ
    * ">"キーで次の画像へ
    * "d"キーで画像削除
    * "esc"キーで終了

    ```python
    ...
      while True:
      ...
        # operation process
        if key == 46:       # next image by ">" key
          index = index + 1
        if key == 44:       # prev image by "<" key
          index = index - 1
        if key == 100:      # delete file by "d" key
          # move jpeg and arw files
          arw_filepath = jpeg_filepath.upper().replace(".JPG", ".ARW")
          shutil.move(jpeg_filepath, delete_dirpath)
          shutil.move(arw_filepath, delete_dirpath)
          print("[INFO] delete " + jpg_file_list.pop(index))
    
          # update file list size
          jpg_file_list_size = len(jpg_file_list)
        elif key == 27:     # quit by "esc" key
          break
    ...
    ```

## 動作確認

意図通りファイル操作は出来ていそうです。

![exec00.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3864340/faa5277d-9d20-0653-dacb-d4d5e843d11a.gif)

ファイル削除することでリストサイズが変わったりするので一応ガード処理諸々入れていますが、あまり意地悪操作による確認はできていません。

今後使ってる最中になんか見つけたら修正するかもしれません。

## おわりに

ということで、カメラで撮った画像たちを整理するツールを作ってみました。

果たしてRAW現像はやるのか。
【2024】情報セキュリティマネジメント試験の振り返り

# この記事の対象
・情報セキュリティマネジメント試験を受験予定の方
・情報セキュリティを本格的に学びたい方
・ゼロトラストに興味がある方

# 情報セキュリティマネジメント試験を振り返る

2024年6月末にセキュリティマネジメント試験を受験し、結果として合格しました。
合格から2ヶ月が経とうとしているため、このタイミングで振り返りたいと思います。

## 資格取得の目的
セキュリティに関する知識のインプットとアウトプットを繰り返すこと。

## 勉強開始時期
試験の約1ヶ月前

## 勉強時間
平日：業後1時間
土日：10時間（試験直前の週のみ勉強）
合計：30時間

## 勉強方法
[だれでもわかる＆受かる！　情報セキュリティマネジメントやさしいテキスト+頻出問題集[科目A・科目B]](https://amzn.asia/d/b0JWpkJ)


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768548/4ecfb385-9835-f574-6088-79d9957c8428.png" width=50%>

一読し、知らない用語に関しては注意深く読んだ。
知っている内容については、軽く目を通した。

[情報セキュリティマネジメント過去問道場](https://www.sg-siken.com/sgkakomon.php)
過去問８回分を全て解き、間違えた箇所について上記の本で知識をインプットする。
過去問Aを全て解き終えてから過去問B（長文問題）を解いた。
予想問題は解かずに過去問のみを演習した。

## 試験内容
実際に受験した試験の内容については公開が禁止されているルールがありますが、
過去問演習のみで十分に対策ができると感じました。

## 試験結果
680点/1000点
合格基準は600点

## 試験勉強中の反省
過去問を全て演習したので、試験勉強自体の反省はなし。

## 試験後の反省
資格試験は受かれば嬉しい。資格不要論があるものの、一定の基準がクリアしているのと、努力の姿勢を含めた客観的評価なのは間違いない。

しかしながら、資格試験の勉強が試験前のインプットに限られてしまい、試験後にはセキュリティに対して興味を持ちながら継続的にインプット&アウトプットしないことが、反省すべき点だと感じた。

セキュリティマネジメント試験に限らず、すべての資格勉強に共通して言えることですが、私は資格取得後に継続してインプットやアウトプットが出来ていないことが多いこと。

## 次に向けて
現在進行中ですが、日経ネットワークを年間購読し、定期的にインプットを行う。
インプットしたものをQiitaを利用してアウトプットする。
セキュリティに関してのコラムがあるので記事を読んで好奇心を持つこと。
好奇心と疑問を持つことが今後の課題。

セキュリティー対策の事例を以下のムック本でインプットすること。
[ランサムウエアに負けない、ゼロトラスト大全](https://amzn.asia/d/0FiEpCk)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768548/f24d83a7-52d0-2cd6-b56e-f0a35d6dd4cd.png" width=50%>

## まとめ
資格試験前だけではなく、日経NETWORKでネットワーク・セキュリティの部分をインプットし、疑問や好奇心を持った点については自ら調べて、その内容をQiitaで言語化することを習慣化する。
AndroidでBitmap生成時の落とし穴

# はじめに
今回はAndroidで印刷用のBitmap生成時にはまったポイントを紹介していきます
### 本文
AndroidではBitmap生成時に引数として各色に対しての使用するbit数設定することができます。
その時RGB_565を設定するとbitmap作成後、グレースケールに変換する際、なぜか緑が表現できず緑や、黄色系の色を変換できず白抜けしてしまうという不具合が発生してしまいます
### 最後に
原因の特定までは至っていませんが、判明次第追記していこうと思います
【資格】200-301 CCNA 取得への冒険譚

## はじめに

ますだです。
普段は AWS 案件の保守や運用辺りを担当してます。  
今回、200-301 CCNA に合格したので、アウトプットも兼ねて学習方法や期間についてゆるっと書いてみます。

※ 2024-08-20 に出題範囲がマイナーチェンジするみたいなので、近々受験予定の方はご注意を [【出題範囲】](https://learningnetwork.cisco.com/s/ccna-v1-1-exam-topics) (AI 絡みだったり、より今風に)

---

## ざっくり纏め

- **Cisco Certified Network Associate (200-301 CCNA)**：[公式](https://www.cisco.com/c/ja_jp/training-events/training-certifications/certifications/associate/ccna.html)
- **合格ライン**：70 ～ 75% (らしい)
- **結果**：70% (以下を基に)
Network Fundamentals 70% (20)
Network Access 55% (20)
IP Connectivity 68% (25)
IP Services 100% (10)
Security Fundamentals 60% (15)
Automation and Programmability 90% (10)
- **学習期間**：2024-07-25 ～ 2024-08-18 (25 日間)
- **教材**：[Ping-t](https://mondai.ping-t.com/g) (これだけ), [完全初学者向けなら Youtube (まさるの勉強部屋)](https://www.youtube.com/playlist?list=PLfrpqyRFsglLIZ38E6ih11nEQZjNGgbVN)

---

## スペック

- 業界未経験からキャリーバック片手に上京して 5 年
- AWS サービスに触れる機会多め
- ネットワーク (Cisco 系) はほとんど触らない
- DX, TGW, SG, ACL 等 AWS が絡むとがっつり経験あり
- 公共ネットワークを整備する案件で、Wifi やスイッチ・AP の基本中の基本コマンド投入していたレベル
- 頭は良くないので勉強は時間と量でごり押しタイプ

---

## 受験のきっかけ

1. **過去のリベンジ**  
   ぶっとい黒本を 1 章読んで Cisco 製品使わないからポイッとした過去あり
   
2. **セキュリティ知識の深化に向けて**  
   セキュリティのお勉強を進めていると、どうしてもジャンルを問わず幅広い一般知識を持っていることが前提な部分があり、一度ネットワークの基礎固めをしたかったため
3. **Ping-t のプレミアム期間**  
   まだ有料会員期間が残っていたので、ついでの部分も大きい
---

## 学習方法

問題演習のみ (Ping-t)。
試験日から逆算して 1 日に解く問題数を決めて、以下のように進めました。
- **1 週目**：100 問 / 日
- **2 週目**：100 問 / 日 (半分くらい)
- 1 週目が終わった段階で、コマ問を 3 日に 1 回ペースで挟む
- ラスト 3 日でシミュレーション問題対策

ザ・王道。
経験則的に指で覚えやすいので、コマ問は休憩感覚でカチャカチャ。
(なんやかんや頭にも残る気がします)

問題集は 3 周するとほぼ定着するんじゃね派閥の人間ですが、流石に試験日までの勉強時間を確保しきれませんでした。
結果、結構ギリギリの合格ラインだったのではないかなーと。
(受かれば良かろうなのです)

## 少しだけ感想
- 時間が足りない
これまで試験で時間が足りなくなった経験はないのですが、
ラストで 5 分程しか残りませんでした。
合格体験記で時間に追われることを知りつつも、ちょっとなめてました。

- やっぱりシミュレーション問題ムズイ
時間がない & 何をすればいいのか解釈するのに手間取り。
比較的 3 問全捨てで受かってる話も聞くので、飛ばすのもありかと。
自分もラスト 1 問は飛ばしました (IP 設定系ぽく一番簡単そうではありましたが断念)
あまり中身までは言及できませんが、ざっくりスイッチの設定 (完答)・ポートチャネル (7 割) くらいの感触。
正直、受けた今でも対策という対策は浮かばないので、簡易シミュレーションで出題形式に慣れておき、あまり深入りしないのが吉な気がしますね。

---

## まとめ + 次にやろうかなーてきなこと

- **ネットワーク馴染めない**  
  今回で再度痛感しました。
  失効するまでには CCNP も目指します。
  
- **今後の学習予定**  
  前回から変わらず、秋には情報処理安全確保支援士を受験予定。
  期間が空きそうなので箸休めに LinuCレベル3 303 (Security)

`(リングフィットアドベンチャー 3 週目クリアしたので、ひたすら毎日トレーニングモードを続けている日々)`

---

以上、200-301 CCNA に合格するまででした。
少しでも参考になれば嬉しいです！
foobar2000でColumns UI導入後にレーティングまわりの設定

# 前提条件

下記記事の内容は終わってる前提です。

https://qiita.com/waokitsune/items/9cf9351d60eeff419927

https://qiita.com/waokitsune/items/df0a4158fe418b6e39c7

# 概要

この記事は

* レーティングカラムの追加。
* レートを付けるキーボードショートカットの設定。

の2つのやり方となります。

# レーティングカラムの追加

『Library』の『Configure』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f0aed27a-ed17-60f7-d279-19c54af09eae.png)

今回は『Rate』という名前のカラムを追加しました。
『Display script』は下記。

```:コピペ用
$if(%rating%,$repeat(★,%rating%),)
```

設定画面はこんなかんじで…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/80e44748-ec42-b0e3-81d6-46ed79748bb4.png)

設定後の表示はこんなかんじ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c8e55171-809f-344a-4f06-6dfd058c96a5.png)

個人的には★は4か5しか付けません。
なので、『Display script』を下記のようにして…

```:コピペ用
$ifequal(%rating%,4,☆4,)
$ifequal(%rating%,5,★5,)
```

**ぱっと見で分かりやすく** かつ **カラム幅の節約** といったこともできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b4cf0f67-5217-e7a4-f0f8-dc438710a720.png)

# レートを付けるキーボードショートカットの設定

例えば下記のような設定なら、『5』というキーを押したら選択中の曲に5のレートが付けられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/4b8b599c-29e7-04ef-6a4f-a263d7788922.png)

# 蛇足

マウスでポチポチしながらレートを付ける方法が見つからなかったです。
最初は妥協案でキーボードショートカット割り当てたのですが、ショトカの方が断然操作ラクでした。

# 参考サイトさん

https://hydrogenaud.io/index.php/topic,120943.0.html

https://aresei-note.com/17878

# バージョン

Microsoft Windows [Version 10.0.22631.4037]
foobar2000 v2.1.5 [×64]
【docker】データバックアップの定期実行CRONで環境変数を展開するのに苦労した話

## はじめに
dockerのMySQLコンテナでデータバックアップをとっておこうと思ってshellscriptを組んで定期CRON実行しようとした矢先に・・・
なんとコンテナに環境変数でDB情報群を渡しているのにCRON実行するときに環境変数の展開ができてなくてダンプできないという話になった。
色々、調べていたらCRONでshellscriptを組むときに環境変数は簡単に取れないという結論になったので
今後忘れないように備忘録として残しておく。

## 実行したいこと
ただ単にとりあえずSQLファイルでダンプしたいだけなのに・・・って感じ。

## 原因
Dockerコンテナ内では、ホスト側の .env ファイルや compose.yml で設定された環境変数は、コンテナが起動する際に環境変数としてメモリにロードされるだけであり、コンテナ内のファイルシステムに保存されることはないらしい。そのため、コンテナ内に環境変数が記録されている特定のファイルや場所は存在しないっぽい。環境変数はコンテナの実行プロセスに結びつけられていて、コンテナのライフサイクルと共に管理されるんだって。

んー知らんかった。

## はまったところ
### 直接シェルで叩くと実行できるのにCRONでは実行できない。
　定期CRONで実行できなかったので、shellを組み違えているのかなと思い、直接実行してみた結果、うまく実行できていた。この時点でshellは合ってそうだなと思った。

 ### バックアップファイルに何か書き込まれた！と思ったら
 ```backup.sql
Usage: mysqldump [OPTIONS] database [tables]
OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR     mysqldump [OPTIONS] --all-databases [OPTIONS]
For more options, use mysqldump --help
 ```
 何やらSQLの実行文で何が足りなかったり、間違えていたりすると出るっぽい。

 なかなか道のり長い・・・


 ## そして思いついた
 ### もうshellファイルで環境変数ファイルを直接読み込むしか！
 セキュリティ的にはどうなのか、というかよくないだろうけど、直接読み込めば多分いけるでしょ。変数展開できるでしょと浅はかな考えの結果・・・
 うまくいっちゃった!
 

 ### やったこと
 #### 1.まずcomposeファイルでenvファイルの設定は行なっているが、これを任意の場所にマウントする。
 #### 2.そのディレクトリ位置をshellscriptで読み込む。
 ```backup.sh
set -a
source /path/to/.env
set +a

# ---後続処理---
 ```
 #### 3. build up!!!!
 うまく行った。


 ## まとめ
 いやぁどうなんでしょう・・・
 まあいっか！！！
android端末でテスト（アサーション）する



今回使う**assertステートメント**はデフォルトでは無効になっているので、それを有効にする方法を記事にしていきます。

# 
まずは、android端末が接続されていることを確認してください。

次にandroidStudio内のコマンドで以下を実行します。
```
adb shell setprop debug.assert 1 
```
これでアサーションを有効にできます。

また、無効にするには以下を実行します。
```
adb shell setprop debug.assert 0
```

- - -


この方法でテストを行った時、端末が接続されていないか、２つ以上の端末が接続されている場合
コマンドが失敗します。

# 参考

https://www.hiramine.com/programming/android/assertion.html
【React入門】簡単なTodoアプリでチュートリアル⓪


## はじめに
この投稿では、フロントエンド初学者のわたしが、
ShinさんのReactチュートリアル動画を参考にして学んだ内容をまとめて
アウトプットする目的で作成しています。

## 参考動画

[【React入門】完全初心者OK！１から簡単なTodoアプリを作ってReactの１歩を踏み出してみよう ~Reactチュートリアル~](https://youtu.be/nRCNL9T3J98?si=sjsEnGQCBDnM1O0q)

https://youtu.be/nRCNL9T3J98?si=sjsEnGQCBDnM1O0q

## 前回の記事

Reactプロジェクトのスタートアップについては、前回の記事をご参照ください。

https://qiita.com/n1sp/items/0a57c4869664c1e6edc6

## プロジェクトの構成について

動画の内容に基づいて不要な部分を省略していますので、生成されたプロジェクトのコードとは一部異なる場合があります。

### package.json

```json
{
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
}
```

`package.json` の `scripts` セクションには、Node.jsプロジェクトでよく使われるコマンドが定義されています。これらのスクリプトは、以下のようにカスタマイズすることも可能です。

```json
{
  "scripts": {
    "lint": "eslint src/**/*.{js,jsx}",
    "deploy": "npm run build && firebase deploy"
  }
}
```

- **`lint`**: `npm run lint` コマンドを使用して、ESLintでコードをリント（静的解析）します。
- **`deploy`**: `npm run deploy` コマンドでビルドした後、Firebaseにデプロイします。

### index.js

```js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
```

`const root = ReactDOM.createRoot(document.getElementById('root'));` 
では、`<div id="root"></div>`の要素を `root` として定義し、
`root.render` を使って、この `div` 要素に `App` コンポーネントをレンダリングします。

`<React.StrictMode>` は、Reactの「厳格モード」を適用するもので、
潜在的な問題や脆弱性を検出し、警告やエラーを即時に表示する役割があります。
基本的には、このモードを有効にした状態で開発を進めることが推奨されます。

`<App />` は、`App.js` で定義された `App` コンポーネントを指し、
`import App from './App';` でインポートされた `App` コンポーネントが 
`render` メソッドで呼び出されています。

### App.js

```js
function App() {
  return (
    <div className="App">Hello React</div>
  );
}

export default App;
```

このコードでは、`App` コンポーネントを定義しています。このコンポーネントは、`Hello React` というテキストを含む `div` タグをレンダリングします。また、この `Hello React` というテキストを `Hello React Tutorial` に変更すると、保存しなくてもリアルタイムで画面に反映されます。
これは **ホットリロード** という機能で、Reactでも対応しています。

### まとめ
今回はReactプロジェクト生成時の構成やレンダリングの基本知識についてまとめました。
次回は実際Todoリストの土台を作成していきます。
【Reactアプリ開発】デジタル名刺アプリを作成してみた！開発プロセスと学びの振り返り

# はじめに
前回の記事（↓を参照）では学習管理アプリのご紹介をしましたが、今回はJISOUの課題として新たなアプリを作成しましたので、そのご紹介と開発してみての感想を記事にしたいと思います。

https://qiita.com/Kei-dev-1213/items/cbdbbbd5a7a4ac942d4b

# 完成したアプリ
- **デジタル名刺アプリ**
  - オンライン上でユーザーの名刺を登録・検索できるアプリ

・**操作イメージ（左：検索　右：登録+検索）**
<div style="display: flex; justify-content: space-around;">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832049/37aa31bf-ca64-32b5-b93a-6c37aec11490.gif" width="47%">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832049/5d4c4d69-a1ef-d2b4-fea9-462452a1197b.gif" width="47%">
</div>

- **使用している技術スタック**
  - TypeScript: ^8.0.0
  - @chakra-ui/icons: ^2.1.1
  - @chakra-ui/react: ^2.8.2
  - @emotion/react: ^11.13.0
  - @emotion/styled: ^11.13.0
  - @supabase/supabase-js: ^2.45.1
  - @types/canvas-confetti: ^1.6.4
  - canvas-confetti: ^1.9.3
  - dotenv: ^16.4.5
  - framer-motion: ^11.3.24
  - punycode: ^2.3.1
  - react: ^18.3.1
  - react-dom: ^18.3.1
  - react-hook-form: ^7.52.2
  - react-icons: ^5.2.1
  - react-rewards: ^2.0.4
  - react-router-dom: ^6.26.0

- **機能詳細**
  - **デジタル名刺の検索機能**
ユーザーIDを入力すると、それに対応するデジタル名刺を表示します。もし一致する名刺が見つからない場合は、その旨を画面に表示します。表示する情報は、名前、自己紹介文、好きな技術、GithubID、QiitaID、XIDです。また、GithubID、QiitaID、XIDのアイコンをクリックすると、それぞれのIDに関連するページが開きます。
  - **デジタル名刺の登録機能**
デジタル名刺を登録するための機能です。ユーザーID、名前、自己紹介文、好きな技術、GithubID、QiitaID、XIDを入力します。ユーザーID、名前、自己紹介文、好きな技術は必須入力で、残りの項目は任意です。さらに、ユーザーID、GithubID、QiitaID、XIDは半角英数字のみ入力可能です。
  - **前回の学習管理アプリとの違い**
前回のアプリにもCRUD機能がありましたが、今回はページ遷移があるため、より本格的なアプリになっています。また、前回はsupabaseのテーブルが1つだけでしたが、今回は3つのテーブルを使用しており、データの整合性を保つための配慮が必要でした。

# 作成を終えた所感
今回のアプリは、スマホでの利用を想定してiPhone SEの画面サイズを基準に開発しました。レスポンシブ対応は初めてだったので少し戸惑いましたが、ChakraUIはコンポーネントのサイズ指定が簡単にできるので、やり方さえ分かればスムーズに開発を進めることができました。

前回の学習管理アプリでは、新しい技術が多くて苦労しましたが、今回のアプリは前回とほぼ同じ技術スタックを使用したため、あまり苦労せずに完成までたどり着けました。<font color="red">`一度苦労して学んだことは、再現しやすく、応用も効く`</font>ということを改めて実感しました。

また、今回はユーザーエクスペリエンス（UX）を意識し、細部にまで工夫を凝らしました。例えば、↑の操作イメージの通り、登録完了時に紙吹雪が舞う演出を取り入れました。「紙吹雪を降らせられないかな」と思い、「react 紙吹雪」で検索したところ、実装方法が見つかったので、すぐに取り入れてみました。他にも、登録ボタンを押したときのローディングアニメーションやトースト表示など、細かな演出を追加しました。これも、Reactでの開発に慣れてきたからこそスムーズに実装できたものと思います。

今回の開発を通じて、技術的なスキルだけでなく、UI/UXの視点から考えることの重要性も学びました。ユーザーが使いやすいアプリを作るには、ただ動作するだけでなく、見た目や操作感にも気を配ることが大切だと実感しました。今後も技術の習得だけでなく、デザインやユーザー体験の向上にも力を入れていきたいと思います！

## JISOUのメンバー募集中🔥
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします！👇

https://projisou.jp/
cliからvpnに接続したい

# cliからvpn接続したい

最近vpn接続することが何度かあったのですが、いちいち設定のネットワークから選択して、、、というのが面倒でした。
そこでcliから vpn 接続ができないかと探していたところ、openvpnに辿り着いたので忘備録です。

## 環境
```
macOS Sonoma 14.1
Homebrew 4.3.16
```

## 手順
homebrewを利用します。
vpn接続設定ファイル（.ovpn）は取得している状態です。

### 1. openvpnをインストール
```zsh
brew install openvpn
```

### 2. vpn接続用ファイル保存ディレクトリ作成 & ファイル格納

.ovpnファイルを格納するディレクトリを作成し、ファイルを格納します。
コマンドは参考ですので、好きな場所にファイルを置いておけば大丈夫です。

```zsh
mkdir -p ~/openvpn
cp Path/to/your/<file名>.ovpn ~/openvpn
```

### 3. openvpnを開始する
以下コマンドで、openvpnを開始します。
```zsh
sudo brew services start openvpn
```
成功するとログが出ます
```zsh
==> Successfully started `openvpn` (label: homebrew.mxcl.openvpn)
```

（止めたい場合はstopします）
```zsh
sudo brew services stop openvpn
```

### 4. vpn接続する
```zsh
sudo openvpn --config ~/openvpn/<file名>.ovpn
```

成功すると、（サーバーごとに違うかもですが）ログが出てvpn接続した状態になります。

```zsh
~~ 中略 ~~
2024-08-18 18:06:02 Initialization Sequence Completed
```

以上で完了です。
configファイル等を設置すればssh接続のようにできるかも、、、？と思いましたが、今回はひとまずここまでにします。
Reactで画像の切り取り(クロップ) react-image-crop

Reactで画像の一部をクロップする機能を実装しました。自分のメモ程度にまとめました。

## ライブラリ
実装の都合上[react-image-crop](https://www.npmjs.com/package/react-image-crop) の方が合っていたのでこちらを使用しました。他にcrop用のライブラリはあります。
[react-easy-crop](https://www.npmjs.com/package/react-easy-crop)

## 実装
ライブラリをインストールします。
`npm i react-image-crop --save`

インストールすると`ReactCrop`タグが使用できます。このタグでcropするためのイメージを囲みます。
ReactCropタグの中に別の要素も配置できるので画像の上にテキストや図形なども配置したい場合は、`react-image-crop` が合っているかもしれません。
```js
function CropDemo({ src }) {
  const [crop, setCrop] = useState<Crop>()
  return (
    <ReactCrop crop={crop} onChange={c => setCrop(c)}>
      <Image src={src} />
    </ReactCrop>
  )
}

```
cropの四角の座標、width,heightがcropの値として更新されるようになります。
このようにすることでcropする四角の初期値を設定できます。unitはpxか%で指定できます。
```js
const [crop, setCrop] = useState<Crop>({
  unit: '%',
  x: 25,
  y: 25,
  width: 50,
  height: 50
})
```

実際はこのようなカスタムフックを作成しました。
スタイルはReactCropタグでstyle属性より指定することもできます。
初期値は`%`ですが、一度でも操作するとunitの値は`px`になります。一度でも操作した場合に保存することができるように`isEnableSave`の条件式を指定しました。
```js
import { useState } from 'react';
import { Crop } from 'react-image-crop';

export const useImageCrop = () => {
  const [crop, setCrop] = useState<Crop>({
    unit: '%',
    x: 50,
    y: 50,
    width: 15,
    height: 15,
  });

  const isEnableSave =
    crop.width > 0 && crop.height > 0 && crop.unit === 'px';
  const cropSelectionElement = document.querySelector(
    '.ReactCrop__crop-selection'
  ) as HTMLElement;
  if (cropSelectionElement) {
    cropSelectionElement.style.border = '2px solid #fff';
    cropSelectionElement.style.opacity = '1';
    cropSelectionElement.style.backgroundImage = 'none';
    cropSelectionElement.style.animation = 'none';
  }
  return {
    crop,
    setCrop,
    isEnableSave
  };
};
```
keepSelection属性を追加しcropする四角の枠が常に表示され続けるようにしました。これがないと別のところをクリックした場合四角が消えてしまいます。
```js
<ReactCrop 
 crop={crop}
 onChange={(c) => setCrop(c)}
 keepSelection
 minHeight={1}
 minWidth={1}
 style={{
  cursor: 'initial',
 }}
>
```
画像の拡大縮小や回転してcropすることも可能ですが、座標を取得して何か別の操作をしたい場合などは補正する必要が出てきます。
保存の処理があるなら保存時に補正するか、onChangeで補正した値を`setCrop(c)`としてcropを更新していくなどの処理が必要になってくるかもしれません。


## まとめ
他にもいろいろな属性が追加できるようです。
割と簡単に実装できました。
こちらでライブラリの[demo](https://codesandbox.io/p/sandbox/react-image-crop-demo-with-react-hooks-y831o)が参照できます。
【名ポエム】尻拭い


仕事でクソコードをいじってイライラするときに、いつも読んでいた「尻拭い」というポエムがあった。

しかし残念なことに今ではサイトが消滅して読めなくなってしまった。

この秀逸なポエムが消えてしまうのは非常にもったいないのでアーカイブを貼っておく。

https://web.archive.org/web/20220315162510/http://www.pro.or.jp/~fuji/mybooks/okite/okite.7.4.html

>どの世界でも、尻拭いという作業は存在する。下手な奴、失敗する奴がいるから、尻拭いは絶対にある。問題は、尻拭いは優秀な人間にしかできないことである。下手なプログラマには、どうやっても責任は取れない。せいぜい、仕事を退くことによってしか責任を取れない。直そうと思って修正を加えると、どんどん症状を悪化させるだけだから、退くことが唯一の道である。作業から離れて、学習にでも精出してくれれば言うことなしだ。
優秀なプログラマに尻拭いをさせるのは、非常にもったいない。尻拭いをするくらいだったら、初めからその人が作っていれば良い物ができる。しかし、優秀なプログラマの多くは、尻拭いに忙しいのである。低レベルのプログラマを早く締め出すのが急務である。
【DI】依存性の注入についてまとめてみた

実務の中でDIについて考えるきっかけがあったので、学んだことをまとめてみました

# DI -依存性の注入-とは？

:::note
**DIの基本的な考え方**
あるコンポーネントが他のコンポーネントを使用する際に、そのインスタンスを自ら生成するのではなく、外部から提供してもらう
:::


# DI学んだきっかけになったレビュー
先輩から以下のようなレビューをいただき、DIについて学ぶきっかけになりました

**レビュー前のコード**
* あるクラス(以下の`XxxCommand`)の引数として、オブジェクトResourceA、ResourceBのidを受け取るように実装
* 受け取ったidを元に、クラス内でResourceAおよびResourceBのインスタンスを生成

```ruby
class XxxCommand
  def initialize(resource_a_id:, resource_b_id:)
    @resource_a = ResourceA.find_by(id: resource_a_id)
    @resource_b = ResourceB.find_by(id: resource_b_id)
  end

  def run
    # 処理ロジック
  end
end
```

**困ったこと**

* テストが書きづらい
    * `XxxCommand`クラスの中で直接インスタンス化しているので、`ResourceA`クラスや`ResourceB`クラスの実装に依存したテストとなってしまう
    * その結果、コード内で依存関係が固定されてしまい、モックに差し替えることができない


**レビュー後のコード**
* クラス内で生成するのではなく、引数としてResourceAおよびResourceBのオブジェクトを直接受け取るように
* これにより、`ResourceA`クラスや`ResourceB`クラスの実装に依存せず、テスト時にモックやスタブを渡すことができるように
```ruby
class XxxCommand
  def initialize(resource_a:, resource_b)
    @resource_a = resource_a
    @resource_b = resource_b
  end

  def run
    # 処理ロジック
  end
end
```

:::note
上記のレビューをきっかけに、なんとなく聞いたことがあったDIについて学ぶことになりました。以下学んだことをまとめていきます。
:::


*以下の参考文献をもとに学習しました*

https://gihyo.jp/magazine/SD/archive/2024/202406


# そもそも依存とは？
:::note
プログラムにおける依存(Dependency)とは、あるクラスやモジュールが、他のクラスやモジュールを使用することで生じる関係性のことを指す。

例えば、ユーザー情報を扱うクラスがデータベースアクセスを行うクラスを使用する場合、ユーザー情報管理クラスはデータベースアクセスクラスに依存していると言える。
:::

依存はプログラミングをしている限り、日常的に発生するものだが、以下のようなリスクを内包する。
#### 依存に潜む問題点
* クラスAの変更が、クラスAに依存しているクラスに影響を与える可能性がある
* ユニットテストを行う際に、モック化が困難になる

# DIが解決すること
#### バリエーションの拡張
* DIをインターフェースなどの抽象化と組み合わせることで、依存オブジェクトを柔軟に変更ができる
* これにより、さまざまなバリエーションに対応することが可能になる

#### 共通処理の呼び出し
*　複数のオブジェクトで共通して使用される処理を依存オブジェクトとして注入できる
*　これにより、コードの重複を減らし、保守性を高めることができる

#### オブジェクトの生成と使用の分離
* オブジェクトの生成と使用を分離できる
* これによりオブジェクトの生成方法を変更しても、オブジェクトの使用する側のコードに影響を与えないようになる

# 適切な責務分割が可能に
https://zenn.dev/tokium_dev/articles/dependency-injection-watanabe

こちらの記事の`Car`クラスと`Engine`クラスの考え方がとても分かりやすかったので、引用させていただきます。

簡単にまとめると、
#### DIを行う前
* `Car`クラス自身が内部で`Engine`インスタンスを生成する
* 「車の作成」の中で、「エンジンの作成」まで責務を持っている状態

#### DIを行った後
* `Car`クラスは、外部から`Engine`インスタンスを受けとるように
* 「車の作成」時に、部品としてエンジンを受け取るだけに
* エンジンの作成方法などは、知る必要がない状態になる（責務外になる）

---

もっと上手く言語化できるように、さらに理解が深まったら資料を更新しようと思います。
ここまで記事を読んでくださりありがとうございます。コメントなど大歓迎ですので、気になったことなどございましたらコメントお願いします。
ORACLE MASTER Silver SQL 1Z0-071試験の勉強方法

## はじめに
2024年の1月にORACLE MASTER Silver SQL 1Z0-071試験を受験し、合格したので勉強方法を公開したいと思います。

今後受験される方の力になれば幸いです。

## 学習時間と正答率
+ 学習時間：44時間
+ 正答率：74%（合格ライン63%）

## 受験したときの感想
実際に受験して感じたことは、「**思ったより難しい**」でした。

実はORACLE MASTER Silver SQL 1Z0-071試験、一度受験して不合格になっています。
最初に受験したときは正答率55%で、合格ラインに8%ほど足りませんでした。
（最初に受験したときは勉強時間30時間ほどで受験しました。）

受験料が高額なため不合格になると、精神的かつ金銭的に高ダメージを受けることになります。（経験済み）

入念に準備して受験することをお薦めします。

## 使用教材
使用した教材は以下の通りです。
+ [黒本（オラクルマスター教科書 Silver SQL Oracle Datebase SQL）](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E6%95%99%E7%A7%91%E6%9B%B8-Silver-SQL-Oracle-Database/dp/4798172367/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3T8SJ0IV0MBU9&dib=eyJ2IjoiMSJ9.ppERzau89lxXIJNzzZP_nlbWnckCw6UCtNi-Jq233ehf0YhhxAU5kdGtVR9mhts_diY7D6acqVR2SAfRCykg6YJ36ovbBsHY8gs4UTdKjyzY0Gsj_ibmLg1UPxwMaN44b-1yB234vDFmCqLIjSeo50ujr1BKeq1S-NpTgEE7HNTFYduosMfjgmGzGsHMCA3p69uDv20wiaLXXUFYF6mYsLH0_U2Kk0HRKcc5nj-OJfvw91pemE56aMb6YVUidsTEfd_m2KQCoRewiuHMRq1_2RiThvnvjwgr1LwoTdeyqqM.NhJeyKGdcfDMVq4_cu7L36VTzbd86rQMlLYX7HCldaQ&dib_tag=se&keywords=oracle+silver+sql&qid=1723967493&sprefix=oracle+silver+sql%2Caps%2C226&sr=8-1)
数少ないORACLE MASTER Silver SQLの参考書です。
実際の試験では、この参考書に書かれていることが多く出題されました。
受験される方は購入を検討された方が良いかと思います。

+ [Ping-t](https://mondai.ping-t.com/g/question_subjects)
問題集はPing-tを使用しました。
ORACLE MASTER Silver SQLの問題集は無料で利用することができます。
スマホで問題を解くこともできるので、隙間時間も有効活用することができます。

+ [Oracle Universityの動画](https://learn.oracle.com/ols/course/oracle-master-silver-sql-2019-certification-exam-prep-seminar-oracle-master-silver-sql-jp/84763/88453)
こちらはSQLについて動画で学ぶことができます。
「オラクルマスター教科書 Silver SQL Oracle Datebase SQL」の参考書で理解しづらかった点をこちらの動画で学習しました。
動きを実際に目で見て確認できるので、理解しやすかったです。
※一部有料となってしまいます。筆者の場合は無料部分のみ視聴しました。

## 勉強方法
+ **黒本（オラクルマスター教科書 Silver SQL Oracle Datebase SQL）**
メインの参考書は黒本を使用します。
まずは黒本を1周、あまり時間をかけずに取り組みます。（全体像を掴むイメージ）
2周目、3周目で徐々に理解度を高めていきます。
筆者は合計で**3周**しました。
ちなみに、本試験では**黒本に記載されている細かい箇所まで出題されます。**
「そこまで出るか！」みたいな感じだったので、隅々まで理解するようにしてください。

+ **Ping-t**
黒本を2周したあたりから、Ping-tで問題を解いていきます。
黒本は掲載されている問題数が少ないので、基本的に問題を解く（アウトプット）はPing-tで行います。
Ping-tでは、問題の正答と併せて解説も記載されています。
間違った問題は解説を必ずチェックして理解度を深めましょう。
Ping-tのランダムで出題される問題に対して、7～8割程度正解できるようになったら、本試験も合格可能だと思います。


+ **Oracle Universityの動画**
Oracle Universityの動画は補助教材として使用します。
黒本で理解しづらかったセクション、Ping-tでよく間違うセクションを視聴します。
実際に動画で確認することで、気が付くこと、理解が深まることも多くありました。


## おわりに
ORACLE MASTER Silver SQL 1Z0-071試験の勉強方法について紹介しました。
SQLは開発の現場ではほぼ必須のスキルであり、エンジニアでなくても活用の場面は多々あるかと思います。
この試験の勉強を通して、SQLの基礎知識を身に付けることができました。
（実務で活用するにはやはり手を動かすしかないですが・・）

Oracleでなくても活かせる知識なので、勉強して損はないかと思います。
最後まで読んでいただきありがとうございました！

### おまけ
Oracleの試験は、楽天で購入するとポイントも溜まって、少し安く買えるのでおすすめです！
+ [受験チケット](https://item.rakuten.co.jp/it-test/137327/)
はじめてのWebアプリを作ろう（1）-環境構築

HTML・CSS・JavaScriptの基本を学び終えた初心者です。

学んだことを体系的に復習するため、いくつかWebアプリを作っていきます。
定番のToDoアプリを作成したのち、TypeScript・Reactを用いてアップグレードしていく予定です。

私と同じように基本を学び終え、「次なにしよう…」と迷っている方の一助となれば幸いです。

今回は環境構築について一部まとめます。

※プログラミング初学者がまとめている記事です。
温かい目で見守ってくださると嬉しいです:hugging:

# 前提条件

以下の環境で使用している前提でまとめていきます。
- OS：Windows10 22H2 or Windows11
- エディタ：Visual Studio Code
- 仮想環境：Docker Desktop

# 1.Docker導入

仮想環境の構築については、すでに多くの先輩方が解説されているので、そちらの記事を参考にします。

まずはじめに、WSL2とDockerを導入します。
- [Windows上でDocker環境を作成する方法とその構成](https://qiita.com/hoshimado/items/51c99ccaee3d4222d99d)

次に、VSCodeとDockerを連携するDevContainerを導入します。
- [VSCodeを使ってDockerコンテナ内で開発を行う方法](https://qiita.com/75ks/items/b2961e8562c353f42d21)

これで、VSCodeとDockerの連携ができました。
仮想環境を使用して作業するときは、Docker Desktopを起動しておきます。

# 2.VSCodeからコンテナーで仮想環境を構築する

コードを保存するフォルダを開いたら、
1. 左下の><（くの字のアイコン）をクリック
2. 『新しい開発コンテナー』を選択
3. 『Node.js & JavaScript』を選択

するとコンテナーの構築が始まります。
しばらく待つと左下に「開発コンテナー：…」と表示されるはずです。
この仮想環境には、Node.jsとJavaScriptがあらかじめインストールされています。

VSCodeのターミナルで、以下のコマンドを実行してみてください。
```terminal:ターミナル
npm -v
node -v
```
それぞれバージョンが返ってくるか確認してください。

これで仮想環境の構築は完了です。

### なぜ仮想環境を使うのか？
主にこれらのメリットがあります。
- ローカルを汚さない。直接インストールしてしまうと、後々面倒なことになる
- 複数台のPC・あるいは複数人で作業するとき、イメージを共有すれば同じ環境を簡単に整えられる
- バージョンの差異によるエラーを予防できる

# 3.Node.js

今回はNode.jsのフレームワーク・Expressを使って開発するので、コマンドを実行してこれをインストールしていきます。

以下、Progateのこちらのページを参考にしています。
- [Node.jsの新規アプリケーションを作ろう！](https://prog-8.com/docs/nodejs-new-application)

まず、npmの設定ファイルを生成します。
```console:ターミナル
npm init --yes
```
するとフォルダ内にpackage.jsonが生成されます。

次に、Expressとejs、nodemonをインストールします。
nodemonを導入することで、ホットリロード（ファイルを書き換える度に、サーバーを再起動せずとも変更内容を反映すること）が可能になります。
```console:ターミナル
npm install express ejs
npm install -g nodemon
```
これで開発環境を整えることができました。

# 4.サーバーを起動する
最後にサーバーを立ててみて、動作を確認します。

- 作業フォルダ内に、ルーティング処理を記述する routes.js を作成する
- 作業フォルダ内に、ビューファイルを置く views フォルダを作成する
- viewsフォルダ内に、表示するページとなる index.ejs を作成する

それぞれに以下のコードを記述します。
```html:index.ejs
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Hello</title>
    </head>

    <body>
        <h1>Hello, world!<h1>
    </body>
</html>
```
```javascript:routes.js
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.render('index.ejs');
});

app.listen(port);
```

保存し、ターミナルで以下のコマンドを実行します。
```console:ターミナル
node routes.js
```
実行すると、仮想環境上でサーバーが起動します。
デフォルトのブラウザから localhost:3000 にアクセスすればページが表示されます。

ターミナルにCtrl+Cを入力するとサーバーを終了できます。

環境構築は、ひとまずこれで完了です。
ubuntu 24.04 LTSで自宅サーバー構築（SysStatの設定）

<a href="https://px.a8.net/svt/ejp?a8mat=3ZDGSF+2SMFEY+CO4+60OXE" rel="nofollow">初期費用無料、月額990円から、高速・多機能・高安定レンタルサーバー『エックスサーバー』</a>
<amp-pixel src="https://www19.a8.net/0.gif?a8mat=3ZDGSF+2SMFEY+CO4+60OXE" layout="nodisplay"></amp-pixel>
taisuke@ubuntuserver:~$ sudo apt -y install sysstat
taisuke@ubuntuserver:~$ sudo systemctl enable --now sysstat
Synchronizing state of sysstat.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable sysstat
Created symlink /etc/systemd/system/multi-user.target.wants/sysstat.service → /usr/lib/systemd/system/sysstat.service.
Created symlink /etc/systemd/system/sysstat.service.wants/sysstat-collect.timer → /usr/lib/systemd/system/sysstat-collect.timer.
Created symlink /etc/systemd/system/sysstat.service.wants/sysstat-summary.timer → /usr/lib/systemd/system/sysstat-summary.timer.
#デフォルトの取得間隔は以下の設定による
taisuke@ubuntuserver:~$ sudo grep -A 1 'Timer' /usr/lib/systemd/system/sysstat-collect.timer
[Timer]
OnCalendar=*:00/10
#取得間隔を変更する場合は以下
taisuke@ubuntuserver:~$ sudo systemctl edit sysstat-collect.timer
#例として 5分間隔に変更する
[Timer]
OnCalendar=
OnCalendar=*:00/5
taisuke@ubuntuserver:~$ sudo vi /etc/sysstat/sysstat
#sysstat configuration file. See sysstat(5) manual page.
#How long to keep log files (in days).
#Used by sa2(8) script
#If value is greater than 28, then log files are kept in
#multiple directories, one for each month.
#ログの保管期間 (日数)
HISTORY=7
#Compress (using gzip or bzip2) sa and sar files older than (in days):
#指定日数より古いログは圧縮する
COMPRESSAFTER=10
#Parameters for the system activity data collector (see sadc(8) manual page)
#which are used for the generation of log files.
#By default contains the `-S DISK' option responsible for generating disk
#statisitcs. Use `-S XALL' to collect all available statistics.
#デフォルトでは取得されない設定となっている情報を追加取得するオプション *1
SADC_OPTIONS="-S DISK"
#*1 指定可能なオプション
INT     ⇒  System Interrupts
DISK    ⇒  Block Devices
SNMP    ⇒  SNMP statistics
IPV6    ⇒  IPv6 statistics
POWER   ⇒  Power Management statistics
ALL     ⇒  All of the above
XDISK   ⇒  DISK + Partition statistics
XALL    ⇒  All of the above (ALL + XDISK)
<a href="https://px.a8.net/svt/ejp?a8mat=3ZDGSF+2SMFEY+CO4+60OXE" rel="nofollow">初期費用無料、月額990円から、高速・多機能・高安定レンタルサーバー『エックスサーバー』</a>
<amp-pixel src="https://www19.a8.net/0.gif?a8mat=3ZDGSF+2SMFEY+CO4+60OXE" layout="nodisplay"></amp-pixel>
Ubuntuへインストールしたnarou.rbをアップデート

今回は一例として以下の手順で構築したnarou.rb環境を更新する。

https://qiita.com/kokotaro@github/items/a105245fada60db654e0

# 目的
1. 改造版AozoraEpub3の最新版を使用する (2024.08.18時点で 1.1.1b24Q)
1. 読書端末はKindle PaperWhiteとする
1. Javaも含めて最新版(あればLTS)を使用する
1. 無職転生　- 異世界行ったら本気だす - の変換がEPUBで完了すること
1. できる限りnarou.rbで設定しているCSSスタイルに準拠すること

## 手順参照時のインストールバージョン
* Ruby：rbenv環境を使用し3.3.0
* Java：openjdk-21-jdk (21.0.2+13-1)
* [改造版AozoraEpub3](https://github.com/kyukyunyorituryo/AozoraEpub3)：AozoraEpub3-1.1.1b22Q.zip 
* narou.rb：3.8.2＋パッチ諸々版

## 2024/08/18時点で採用したバージョン
* Ruby：rbenv環境を使用し3.3.4
* Java：openjdk-21-jdk (21.0.4+7)
* [改造版AozoraEpub3](https://github.com/kyukyunyorituryo/AozoraEpub3)：AozoraEpub3-1.1.1b24Q.zip 
* narou.rb：3.9.0


## 変更手順
### Java
``` shell
$ sudo apt update
$ sudo apt upgrade
$ java --version
openjdk 21.0.4 2024-07-16
OpenJDK Runtime Environment (build 21.0.4+7-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 21.0.4+7-Ubuntu-1ubuntu222.04, mixed mode, sharing)
```

### Ruby
rbenv環境でインストールしたので、rbenv側のアップデートも必要。
``` shell
$ rbenv install --list
3.0.6
3.1.4
3.2.3
3.3.0
略)
```
アップデートしない状態でインストール可能なバージョンをリストアップしてもインストール時から更新されてない。なのでまずはruby-buildコマンドをアップデートする
``` shell
$ git -C "$(rbenv root)"/plugins/ruby-build pull
中略
 create mode 100644 share/ruby-build/3.3.2
 create mode 100644 share/ruby-build/3.3.3
 create mode 100644 share/ruby-build/3.3.4
 ……
```
アップデート後にrbenvコマンドからインストール可能なバージョンを再確認する
``` shell
$ rbenv install --list
3.1.6
3.2.5
3.3.4
略)
```
あとは参照した手順と同様に希望する3.3.4をインストールする
``` shell
$ rbenv install 3.3.4
中略
==> Installed ruby-3.3.4 to /home/catapult/.rbenv/versions/3.3.4
$ rbenv global 3.3.4
$ ruby -v
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
```

### 改造版AozoraEpub3の更新
``` shell
$ wget https://github.com/kyukyunyorituryo/AozoraEpub3/releases/download/v1.1.1b24Q/AozoraEpub3-1.1.1b24Q.zip
2024-08-18 17:04:13 (3.53 MB/s) - ‘AozoraEpub3-1.1.1b24Q.zip’ へ保存完了 [5499180/5499180]
$ unzip AozoraEpub3-1.1.1b24Q.zip -d AozoraEpub3
$ cd AozoraEpub3
$ java -cp AozoraEpub3.jar AozoraEpub3 --help
usage: AozoraEpub3 [-options] input_files(txt,zip,cbz)
version : 1.1.1b24Q
```

### narou.rbの更新
``` shell
$ gem install narou
※rubyのバージョンが変更されたので、新規にインストールしている状態
中略
3.9.0: 2024-04-02
-----------------
#### 修正内容
- 小説家になろうの目次修正に対応
- カクヨムの目次修正に対応

thanks for contributors: @topstone, @rogenobl, @happynow, @etg-lt

************************************************************
Successfully installed narou-3.9.0
$ narou version
3.9.0
```

### 無職転生のダウンロードと変換
以下のようにePUBの変換にエラーがなければ完了
一応すでにダウンロード済みなので -fオプションをつけて実行
``` shell
$ narou download n9669bk -f
...
ID:0　無職転生　- 異世界行ったら本気だす - の変換を開始
小説状態の調査結果を 調査ログ.txt に出力しました（エラー：0件、警告：43件、INFO：4件）
縦書用の変換が終了しました
AozoraEpub3でEPUBに変換しています...........変換しました
[理不尽な孫の手] 無職転生　- 異世界行ったら本気だす -.epub を出力しました
EPUBファイルを出力しました
小説の保存フォルダを開きますか (y/n)?: n
```

# 結果
narou.rbと改造版AozoraEpub3が要求するソフトウェアバージョンに変化がないので、アップデートは特に問題がない感じ。
【SQL】JOIN句の省略形

# はじめに
SQLのJOIN句にはいくつか省略形がありますが、気を抜くと分からなくなることがあるので備忘録として残します。
同じような方のお役に立てば幸いです。

# JOIN
JOINとだけ記述した場合は、INNER JOIN（内部結合）になります。
つまり、以下の2つのクエリは全く同じ意味になります。

```
SELECT * FROM table1 INNER JOIN table2 ON table1.common_column = table2.common_column;
```

```
SELECT * FROM table1 JOIN table2 ON table1.common_column = table2.common_column;
```

また、今回の趣旨とは異なりますが、結合条件が同じカラム名の場合はUSINGを使って以下のような記述が可能です。

```
SELECT * FROM table1 JOIN table2 USING (common_column);
```

INNER JOIN（内部結合）についてはこちらを参照してください。

https://qiita.com/george_desuyo/items/aa4abc2f210a4f9688bb

# LEFT JOIN, RIGHT JOIN, FULL JOIN
LEFT JOINという書き方も可能です。
この場合は、LEFT OUTER JOIN（左外部結合）になります。
つまり、以下の2つのクエリは全く同じ意味になります。

```
SELECT * FROM table1 LEFT OUTER JOIN table2 ON table1.common_column = table2.common_column;
```

```
SELECT * FROM table1 LEFT JOIN table2 ON table1.common_column = table2.common_column;
```

RIGHT JOIN, FULL JOINについても同様です。

# まとめ
まとめると、以下のようになります。
INNER JOIN = JOIN
LEFT OUTER JOIN = LEFT JOIN
RIGHT OUTER JOIN = RIGHT JOIN
FULL OUTER JOIN = FULL JOIN

INNERとOUTERは省略可能ということですね。
他にもあれば教えていただければ幸いです。

---
以上です。
Rubyで多重配列に名前を付けてループを回す方法について

# はじめに
Rubyで多重配列を扱う際に、各要素に名前を付けてeachやmapで回す事ができます。

# 環境

```
❯ ruby -v                                    
ruby 3.2.0 (2022-12-25 revision a528908271) [x86_64-darwin20]
```

# 多重配列の例
まず、以下のような多重配列を用意します。

```rb
data = [
  [1, "Alice", 30],
  [2, "Bob", 25],
  [3, "Charlie", 35]
]
```

この配列は、ID、名前、年齢の情報を持つ3つの要素から構成されています。

# 名前を付けてループを回す方法
多重配列の各要素に名前を付けてループを回すには、eachメソッドやmapメソッドでブロック引数に名前を付けて以下のように書きます。

## eachの例
```rb
data.each do |id, name, age|
  puts "ID: #{id}, Name: #{name}, Age: #{age}"
end
```
このコードを実行すると、以下のように出力されます。

```
ID: 1, Name: Alice, Age: 30
ID: 2, Name: Bob, Age: 25
ID: 3, Name: Charlie, Age: 35
```

## map

```rb
formatted_data = data.map do |id, name, age|
  "ID: #{id}, Name: #{name}, Age: #{age}"
end

puts formatted_data
```

```
ID: 1, Name: Alice, Age: 30
ID: 2, Name: Bob, Age: 25
ID: 3, Name: Charlie, Age: 35
```

# 最後に

弊社CBcloudではエンジニアの募集を行なっております！
https://recruit.cb-cloud.com/

一緒に会社を盛り上げてくれる人を絶賛募集中です！
Javaで「DOTALLフラグ(ドット(.)が行末記号とマッチする)」の動作を確認してみた

# 概要

Javaで「DOTALLフラグ(ドット(.)が行末記号とマッチする)」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/regex/index19.html

# 実装

以下のファイルを作成しました。
```JSample19_1.java
import java.util.regex.*;

class JSample19_1{
  public static void main(String[] args){
    String target1 = "<p>Lemon is yellow.Strawberry is red</p>";
    String target2 = "<p>Lemon is yellow.\nStrawberry is red</p>";

    String regex = "<p>.*</p>";
    Pattern p1 = Pattern.compile(regex);

    Matcher m1_1 = p1.matcher(target1);
    System.out.println(target1 + ":" + m1_1.find());
    Matcher m1_2 = p1.matcher(target2);
    System.out.println(target2 + ":" + m1_2.find());

    System.out.println("---- ----");

    Pattern p2 = Pattern.compile(regex, Pattern.DOTALL);

    Matcher m2_1 = p2.matcher(target1);
    System.out.println(target1 + ":" + m2_1.find());
    Matcher m2_2 = p2.matcher(target2);
    System.out.println(target2 + ":" + m2_2.find());
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample19_1.java 
$ java JSample19_1 
<p>Lemon is yellow.Strawberry is red</p>:true
<p>Lemon is yellow.
Strawberry is red</p>:false
---- ----
<p>Lemon is yellow.Strawberry is red</p>:true
<p>Lemon is yellow.
Strawberry is red</p>:true
```

# まとめ

何かの役に立てばと。
CopilotさんにQiita用のアイコン画像を作ってもらう

# はじめに
Qiitaへの記事投稿を始めて少し経ちましたが、Qiita用のアイコンをどうするか悩んでいました。また、最近久しぶりに自宅のWin10 PCを開いたら、タスクバーにCopilotアイコンが出現していました。

![Win10 PCに出現したCopilotアイコン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781638/ac40eb98-9b0b-7495-9c1c-2fc2ceff5bba.png)

Edgeブラウザ上で使えることでもおなじみのCopilotさんでは、DALL-Eを使った画像生成もできるようになっています。

じゃあアイコン画像をCopilotさんに作ってもらおうじゃないか、と思いついたのがこの記事作成のきっかけです。

# 作ってもらう
私のアカウント名「ogabk」から連想されるものを画像にしてもらうことにしました。その結果がこちら。

![ogabkときいて連想される画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781638/45cbb2d3-6ca3-69dc-b6f2-f7e65a34b9c3.png)

# どうしてこうなった
予想の斜め上を行く画像が生成されました…。どうしてこうなった。
Copilotさんに説明してもらいます。

![連想の経緯.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781638/ecfb78a6-f92d-d68b-9c65-efc94f41a520.png)

お、おう…　なる…ほど…？

右上のキャラクターが一番なんだか斬新で不気味かわいいのでこちらを採用することにしました。

# おわりに
というわけで、今後はこの画像を使用していきます。

ではまた。
スクラムフェス金沢に初参加、初登壇してみての感想

7/19~7/20 [スクラムフェス金沢](https://www.scrumfestkanazawa.org/)に初登壇、初参加してきました！

記事にするのが遅くなりましたが、私の経験談からこれから初登壇する方の背中を押せたらと思ったため、まとめていきます！

## プロポーザルを出そうと思ったきっかけ
昔から発表の場の空気感が好きだったので、「いつかどこかで発表してみたいなー。」という思いだけぼんやりとありました。しかし、社会人になってから発表できるような良いテーマが無いことから登壇は厳しいなとなっていまして、ずっと何か話せるテーマはないかと探していました。

そんな時に平鍋さんから新卒採用でスクラム導入したテーマって他の人やってないんじゃない？このテーマ需要あると思うよ！と声をかけていただき、ここで発表してみよう！となりました。


## なぜスクラムフェス金沢だったか
スクラムフェス金沢の運営もしていた岡本さんからの社内アナウンスがきっかけで、ここならプロポーザル出せそう！となったからです。

### どんなアナウンス？
社内会議で初めてプロポーザル出してみませんか？という内容です。

> （アナウンス内容の一部）
> こんな人を探しています
>  - イベント発表に興味がある
>  - イベントで発表したことがない
>  - 背中を押されるのを待っていた

これは全部自分に当てはまっている！ということで、スクラムフェス金沢に参加しよう！という決意が固まりました。

## プロポーザル作成まで
主に二つの会に参加して、プロポーザルの内容を詰めていきました。
私自身、文章を書くことが苦手なので、どうやって書こうとずっと悩んでいましたが、以下の2つのイベントのお陰で何とか書き切ることができました。

#### プロポーザル書いてみよう、プロポーザルの提出方法を出してみようの会
社内でスクラムフェス金沢に登壇しようと考えている人達で集まってアドバイスをし合う会を行いました。
最初はConfengineの使い方（Abstractにはこんなこと書くんだよのレベルから）講座をした後、自分たちが書いたプロポーザルを出し合ってアドバイスをし合いました。

プロポーザルのアドバイスを出し合う会が終わっても社内slackで沢山アドバイスを貰いながらプロポーザルの内容をブラッシュアップしていきました。


#### プロポーザルわいわい会
他の方がどのような思いで参加されているかを知るため、プロポーザルわいわい会に参加しました。
わいわい会当日は体調不良で声が枯れてしまっていてプロポーザル出した思いなどは話せる状態ではなかったため、聞き専で参加をしていました。
しかし、他の人の登壇の思いを聞いている中で他の人が考えている思いが沢山聞けて、自分も参考になるアドバイス（プロポーザルを書くコツなど）も知れたのでとても有意義な時間になりました。
聞くだけでも他のスクラムフェスにも参加してみたいと思えますし、推しプロポーザルも見つけられるチャンスなので、スクラムフェス参加しようと思っている方は聞いてみると良いかもしれません。

https://beyond-hardware-agile.connpass.com/event/317387/

## 発表してみて
![DSC00661.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821736/b306b100-248e-ae48-9798-a8436336cbd7.jpeg)
このような会場で発表をしてきました。自分が想定していたよりも参加者の距離が近かったこともあり、人生で1,2を争うレベルで緊張しました。

しかし皆さん温かい目で発表を聞いてくださっていたこともあり、良い緊張感で発表をすることができました。発表を終えてみて、自分が伝えたかったことは全て伝え切れたという達成感があり、準備はとても大変でしたがとても楽しかったです！（発表の反省も沢山ありますが・・・）


また、発表後のOSTの時間や懇親会の時間に
「うちの会社もスクラム取り入れようとしているんだけど、会社の人事むけに話をしてみて欲しい！」
というような提案をしていただいたり、

エンジニアではない方からも
「こんな活用事例があるんだ。と知れてよかった！私の会社でもスクラムやってみようと思えた！」
と言っていただけて、自分の発表の目的であった「発表を聞いた後に開発外でスクラムを取り入れたい！と思ってもらえる」というところが達成できたので良かったです。


## 全体を通して
今回登壇できたのは周りのサポートや後押しがあったからだなと改めて実感しました。そのため今後は自分が登壇するだけでなく、周りの登壇してみたいと思っている方の背中も押せるようになっていきたいです。
最後になりますが、登壇の準備を手伝ってくださった方、応援してくださった方、私の発表を聞いてくださった方、本当にありがとうございました！

当日発表したスライドはこちら

https://speakerdeck.com/reinasaito/xin-zu-cai-yong-huo-dong-nisukuramuwodao-ru-sitahua
技術ブログ内に貼るURLは、公式DocsよりGitHubが嬉しい

# はじめに

「自分で書く技術記事には、積極的にGitHubのリンクを載せていこう」と考えるに至った理由を書いた。
（便宜上GitHubと書いているが、BitbucketやGitLabなどでも :ok_hand: ）

# 理由その1: 公式Docsのリンクは、GitHubリポジトリに比べて変更される可能性が高い

例えば、Goのwebフレームワーク https://github.com/beego/beego は、過去に公式DocsのURLが `beego.me` から `beego.vip` に変更されていた。
→変更が反映されたPR: https://github.com/beego/beego/pull/4959

また、2024年8月時点では `.vip` へのリンクも切れている模様。
→ `unavailable` と追記されたPR https://github.com/beego/beego/pull/5628

さらに、（筆者の記憶上かつ2024年8月時点では確認できないため、話半分として読み流してほしいが、）2022年8月時点では `.me` ドメイン上には全く関係ないサイトが展開されていた……

# 理由その2: GitHubリポジトリを探す読者の手間を削減してあげる親切心

技術ブログに登場したライブラリの実装が気になってGitHubリポジトリを探しにいく、といった読者は一定数いるだろう。

分かりやすい箇所にGitHubリポジトリへのリンクが貼られている公式Docsであれば、
「技術ブログ内のリンク→公式Docs内のリンク→GitHubリポジトリ」
の移動がスムーズなので、読者はそこまで負担を感じないだろう。

しかし、webサイトのレイアウトはどうしても各々で異なるため、また人によって見やすさが異なるため、公式Docsによってはリンクを見つけることに苦戦してしまう。
そういった負担を和らげるためにも、GitHubリポジトリへのリンクが貼られていると嬉しい。

とはいえ、

- 実装よりも概要が気になるので、公式Docsに初手で辿り着きたい読者もいる
- GitHubリポジトリ上から公式Docsのリンクが見つけられないパターンもある
- 読者が自分自身でググれ

といった考え方もあるので、この理由はそこまで本記事の主張を支持するようなものではないか……

# おわりに

筆者自身、最近意識し始めたばかりなので過去記事は対応できておらず心苦しい……

ちなみに、読み手として、

> 実装よりも概要が気になるので、公式Docsに初手で辿り着きたい

この感情を抱くことも多いので、公式DocsとGitHubリポジトリ両方のリンクを載せるという案もありか。
（把握してないだけで、GitHubリポジトリが変更になる事例も実はたくさんあるかもしれないし）