OmniAICreator/Qiita-1.07M huggingface dataset:
QEPCAD を M1 Mac で実行する

## 概要
QEPCAD は、量化子消去を実行してくれるソフトウェアです。([大学の数学の入試問題を量化子消去でサッと解く](https://qiita.com/kobae964/items/30dcb77837068b2638be)に詳しい解説があります。)
ただし、QEPCAD のインストール方法として https://ashiato45.hatenablog.jp/entry/2018/04/25/070040 の方法は M1 Mac では実行できません。(コンパイルに失敗します。)
この記事では、これを回避し、M1 Mac でも QEPCAD を実行できるようにします。

## 対象読者
- M1 Mac などを使っていて、自分のマシーンで QEPCAD をコンパイルできないが QEPCAD を動かしたい人
- x86 マシーンを使用していて QEPCAD のインストールは可能ではあるものの、手順が面倒なので楽をしたい人

## 事前準備
Docker for Mac をインストールします。

筆者の環境は以下です:
```
$ docker version
Client:
 Cloud integration: v1.0.35
 Version:           24.0.2
 API version:       1.43
 Go version:        go1.20.4
 Git commit:        cb74dfc
 Built:             Thu May 25 21:51:16 2023
 OS/Arch:           darwin/arm64
 Context:           desktop-linux

Server: Docker Desktop 4.21.0 (113844)
 Engine:
  Version:          24.0.2
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.4
  Git commit:       659604f
  Built:            Thu May 25 21:50:59 2023
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
```
## 実行方法

ターミナルからデータを入力する場合
```bash
docker run --rm --platform linux/amd64 -it kobae964/qepcad +N10000000
```

ファイルからデータを入力する場合
```bash
docker run --rm --platform linux/amd64 -i kobae964/qepcad +N10000000 <filename.txt
```

(これをそのまま実行すると、初回実行時に Docker イメージを取得する時間がかかります。それを実行時間に含めたくない場合は、あらかじめ
```bash
docker pull kobae964/qepcad
```
を実行しておけば、docker run ではすぐに実行が始まります。)

## 何をやっているのか
https://github.com/koba-e964/qepcad-image で、実際に QEPCAD をインストールする手順を Dockerfile に書き、Docker イメージを作りました。
イメージは https://hub.docker.com/repository/docker/kobae964/qepcad/general で公開されており、上の手順ではそれを取得していたのです。

## 関連記事
https://qiita.com/kobae964/items/30dcb77837068b2638be
Hướng dẫn nạp tiền Suncity cực nhanh 2023

Nạp tiền SunCity là một từ khóa được tìm kiếm rất nhiều của anh em bet thủ trong thời gian qua.. Bởi khi nạp tiền vào tài khoản sân chơi tại nhà cái Suncity bạn mới có thể tham gia cá cược đổi thưởng tiền mặt. Trong bài viết dưới đây chúng tôi sẽ hướng dẫn bạn cách nạp tiền theo quy trình chuẩn năm 2023.

Một vài lưu ý cần ghi nhớ trước khi nạp tiền SunCity
Sau đây là một vài điều các bạn cần ghi nhớ để có thể nạp tiền SunCity vào tài khoản nhà cái chính xác và nhanh chóng. Cụ thể là:

Bạn cần đảm bảo rằng tài khoản thành viên bạn sắp nạp tiền vào là tài khoản của chính bản thân mình. Bằng cách kiểm tra lại tên đăng nhập cũng như mật khẩu đăng nhập xem đã trùng khớp hay chưa.
Bạn cần đảm bảo rằng thông tin tài khoản nhà cái Suncity phải là thông tin chính xác, vẫn đang được nhà cái sử dụng. Nếu bạn chuyển nhầm địa chỉ do sơ sót nào đó, nhà cái sẽ không chịu trách nhiệm.
Bạn nên áp dụng hình thức chuyển tiền nhanh 24/7 để tiền được cập nhật vào tài khoản lập tức.
Khi chuyển tiền vào tài khoản nhà cái bạn bắt buộc phải ghi nội dung chuyển tiền thật chính xác để nhà cái đối chiếu. Nội dung chuyển tiền bao gồm tên đăng nhập tài khoản và một số thông tin quan trọng khác tuỳ theo yêu cầu của từng phương thức. 
Sau khi bạn đã nạp tiền xong hãy chụp lại hoá đơn giao dịch để tiện xử lý nếu sau này có xảy ra vấn đề nào đó.
【CMSを初めて知る】

この動画を見て纏めただけです。
https://www.youtube.com/watch?v=exeBOPA8bq8&t=88
# CMSって？
- ContentsManagementSystemの略
- WEBサイトを構築/管理するものを纏めたもの
- CMSを使えばプログラミング言語を使わなくてもWEB作成が可能
- WordPressもCMSのひとつ
- 無料版と有料版がある

# CMSには2種類
- ①オープンソース型
代表例はWordPress / 無料 / カスタマイズ可能
- ②独自開発型
IT企業や個人が開発したCMS / 様々なサイトタイプに合うCMSが色々な企業から提供されている

# CMSの主機能
- コンテンツ作成、編集
- ユーザー管理
- サイトマップ機能
- SEO機能

# CMSのメリット
- 開発スキルがなくてもWeb開発ができる
（プログラミング未経験者でもできる/ログインIDとパスワードがあれば複数人で利用できる）
- マルチデバイスに対応できる
- 発注コストを削減できる

# CMSのデメリット
- 基礎的な操作方法の習得が必要（簡単なHTML/CSSの知識が必要）
- セキュリティ対策が必要
- 大幅なカスタマイズには不向き

# 無料で使える代表的なCMS
- WordPress
直観的に操作できる　/　利用者が多い
- Wix
直観的に操作ができる　/　人気が出始めている
- Jindo
直観的に操作ができる　/　シェアは少ないがなるべく早く作成したい人におすすめ

# 有料で使える代表的なCMS
- NOREN
- a-blog cMS
- HartCore
システム開発プロセス/開発モデル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/ea24ecbd-d226-a8d8-35d8-2eb11f55cd62.png)
１：共通フレーム
　共通フレームとは、ソフトウェアの開発者と発注者の間で、ソフトウェア開発の段取りに対する共通の概念を作ることを目的としています。
　共通フレームに定められている代表的なプロセスは
①企画プロセス：経営・事業の目的、目標を達成するというか難点から、経営上のニーズシステム化の方針、システムを実現するための実施計画をまとめる。

②要件定義プロセス：必要とする機能、処理性能（レスポンスタイムやスループット）、使いやすさ、セキュリティレベル、信頼性（稼働率や故障率）などを明確にし、文書としてまとめる。企画プロセスで定められた内容に沿って、要件を定義する。

③開発プロセス：要件を詳細下して設計を進め、ソフトウェアを作成しテストする。

④運用プロセス：システムを導入し、ユーザ教育などを行いながら、継続的に運用する。

⑤保守プロセス：不具合や経営・事業環境の変化に対応する。

⑥管理プロセス：開発、運用、保守などの各プロセスの管理、支援を行う。

２：共通フレームの開発プロセスにおける活動
　共通フレームでは、開発プロセスを上記の代表的プロセスのような一連の活動（アクティビィ）に細分化しています。大きく分けると、システム全体を対象とした作業と、ソフトウェアを対象とした作業に分かれます。

　設計段階では、システム全体から個々のプログラムコードへと、大きな単位から小さな単位へと作業を進めます。そして、最終的にプログラムコード位を作成し完成させます。その後、検証（テスト）段階に進むと、小さな単位から大きな単位へと作業を進めます。この流れはV字型にまとめられます。

「開発プロセスの活動内容」
①ソフトウェア要件定義：システムの機能要件（必要な機能）と非機能要件（性能、信頼性、セキュリティなど）を具体的に定義する。

②システム方式設計：定義したシステム要件を実現できるようにシステムの構成を大枠で設計する。ハードウェア構成、ソフトウェア構成、ネットワーク構成、サブシステム間のつながりなどシステムの全体像を具体的に設計する。

③ソフトウェア要件定義：DFDやER図などを用いてモデル化し、ソフトウェアに求められる機能要件、非機能要件を定義する。

④ソフトウェア方式設計：定義したソフトウェア要件を実現できるように、ソフトウェアの外部設計、内部設計を行う。

⑤ソフトウェア詳細設計：モジュール（部品単位でのソフトウェア）の設計を行う。

⑥ソフトウェア結合：ソフトウェア詳細設計、ソフトウェア方式設計で定義した内容が正しく動作するかを検証する。

⑦ソフトウェア適格性確認テスト：ソフトウェア要件定義で定めた要件を満たしているのかを検証する。

⑧システム結合：システム方式設計で定めた内容が正しく動作するのかを検証する。

⑨システム適格性確認テスト：システム要件定義で定めた要件を満たしているかを検証する。

３：ウォータフォールモデル
　ウォータフォールモデルは、工程の流れ：基本計画→外部設計→内部設計→プログラム設計（上流工程）→プログラミング→テスト→運用・保守（下流工程）逃れでシステムを開発します。前工程で決めた内容を踏まえて、次工程を進めます。ウォータフォールモデルでは、工程の後戻りを考慮していません。したがって、前工程に溥儀があり、工程を後戻りする（前工程をやり直す）と、非常に大きなコストがかかることになります。一方、後戻りをしないということは、先の見通しが効くということ言うことでもあります。ウォータフォールモデルでは、いつ開発が終わるのかが見通しやすく、コストや開発期間の見積もりが容易になります。

①基本計画：基本計画では、システムに対するユーザ要求の分析（要求分析）を行い、機能や性能に関しての仕様を定義します。定義された仕様は、「要求仕様書」にまとめて文書化します。

②外部設計：　システムやソフトウェアをユーザ側の視点で捉えて設計を行います。どのような機能が必要かといったことを洗い出し、おおまかな機能単位にシステムを分けます。これをサブシステム化すると言います。また、システムで扱うデータを定義したり、画面やコードを設計します。プログラムで具体的にどう実現するのかと言う細部については、この段階では考慮しません。設計結果は、「外部設計仕様書」にまとめて、文書化します。

「外部設計の内容」
１：論理データ設計：システムに記録するデータ要素を洗い出し、データ型（数値化文字化など）や桁数を決める。ファイルに記録する内容を決めて、ファイル仕様書を作成する。

２：入出力設計：画面や帳票のレイアウトを作成する。また、各画面の遷移について画面フローを作成する。

３：コード設計：商品コード、顧客コードなどのコードの桁数、フォーマットを設計する。

③内部設計
　外部設計で定義した機能（サブシステム）を、プログラムで具体的にどう実現するのかといった観点から設計します。機能分割をして、プログラム単位に詳細化します。設計結果は、「内部設計仕様書」にまとめ、文書化します。
ETロボコン2023 C# Windowsアプリでロボコンスナップをアップロードする

ETロボコン2023でロボコンスナップをダウンロードする側を作ったついでに
アップロード側も作ったので公開します。

```
private async void button1_Click(object sender, EventArgs e)
{
    HttpClient client = new HttpClient();
    string uri = "http://192.168.100.1/snap?id=1";     // 画像のアップロード チームID:1の例
    string path = @"LA.png";        // アップロードするファイル名

    try
    {
        using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
        {
            byte[] buf = new byte[fs.Length];
            fs.Read(buf, 0, (int)fs.Length);
            var content = new ByteArrayContent(buf);
            content.Headers.ContentType = new MediaTypeHeaderValue("image/png");

            var response = await client.PostAsync(uri, content);

            if (response.StatusCode != HttpStatusCode.Created)
            {
                MessageBox.Show("競技システムへの画像アップロードに失敗しました. StatusCode=" + response.StatusCode.ToString());
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("競技システムと通信できません.\n" + ex.Message);
    }
}
```
急な投稿で雑ですが参考になれば幸いです。
mozcの変換にRinna GPTモデルを使ってみる

# はじめに
Rinna から提供されている gpt モデルを使って遊んでみています。

- [Rinna GPT モデルを onnx 形式に変換して C++ から使う](https://qiita.com/shinjimorimitsu/items/b61aa693f8e2988c8590)
- [GPTが与えられた文字列に対して確率を計算するか確認した](https://qiita.com/shinjimorimitsu/items/f4b5ecccf88a41263fe9)
- [mozcのかな漢字変換コードを調査する](https://qiita.com/shinjimorimitsu/items/e18e54d07e9e13d66ac9)

という流れからの、実装です。

# 何を実装したのか

mozc が変換時は Viterbi の結果をそのまま使っているようなので
1. A*アルゴリズムを実装して Viterbi の結果を利用しつつ NBest パスを見つける。(今回 10 固定)
1. 前確定文字列も含んでいる NBest パスを、Rinna GPT モデルで評価してみる。Batch として N 個のパスを渡しているのでモデルの起動は一度だけです。
1. NBest パスで、異なっている文字列の部分だけ logits を取得して softmax を計算し、確率とする。ちなみに、普通にかけるとすぐアンダーフロー起こすので sum(log(softmax)) を計算結果とします。
1. もっとも高い確率のパスで、Viterbi の結果をリプレースする。

という感じで、変換結果を入れ替えています。

# デモスクリーンショット

![RinnaGPT.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3540211/4998efc8-617f-1783-2c12-291ac817aae3.gif)

# うまく変換するサンプル

| 確定済み文字列 | 入力 | 変換結果 |
|---|---|---|
| 部屋で犬を | かう | 飼う |
| 店で犬を | かう | 買う |
| 彼の足はとても | はやい | 速い |
| 彼は朝がとても | はやい | 早い |
| 山をゆっくり | のぼる | 登る |
| 朝日がゆっくり | のぼる | 昇る |

わかりやすいサンプルは、文末の動詞ですが、文中の入力でも

| 確定済み文字列 | 入力 | 変換結果 |
|---|---|---|
| 東京支社に彼は | いどう | 異動 |
| 東京に会場は | いどう | 移動 |

と変換はします。

# とはいえ

いろいろ入力すると、うまく同音異義語を選ばない場合や、明らかな副作用があったりで、調整は必要ですね。(というか、mozc の CRF&Word Cost の値と、GPT の確率値とでは、線形補間できるか不明ですが)

また、mozc の性能評価は、何かツールがあるんでしょうかね。知っている方、ご教示願います。
【Python】Conda環境のトラブルを回避！快適な開発環境の構築

# はじめに
Conda環境，すぐ壊れるし嫌いって人多いのではないでしょうか．

しかし，誰しも一回はConda環境を使わなければならない時が訪れると思います．
私はインターン先でそのようなことがありました．苦労しながらうまく付き合う方法を見つけたため，共有できればと思います．

:::note info
この記事でわかること
**快適なConda環境を使うことができる**
:::

## 開発環境
MacOS 13.2.1

# Conda環境のインストール
快適なConda環境を使うにあたり，Condaのインストールについて解説します．すでにインストールされている方は飛ばしてください．

公式ページ (https://www.anaconda.com/download) から環境にあったものをダウンロードし，インストールしてください．
![anaconda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305858/8a22d451-c51c-5895-e4cb-dcfac34e309e.png)
今回はMacOS M1チップですので，**64-Bit (M1) Graphical Installer**をダウンロードします．
![スクリーンショット 2023-10-03 21.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305858/331cb618-dcf3-e9e5-6d02-b91af1ee5d55.png)
インストーラを開き，インストールします．
ソフトウェアに**Anaconda-Navigator**があればOKです．

ターミナルを開くと
```
(base) ~ %
```
のように`(base)`が先頭についていると，Condaが有効となっている状態となります．

常に有効にしたい場合は
```zsh
% env | grep conda
...
CONDA_PYTHON_EXE=/Users/seast/anaconda3/bin/python
...
% ~/anaconda3/bin/conda init シェル名
```
無効にしたい場合は
```zsh
% conda config --set auto_activate_base false
```
とします．詳しくは[macOSでCondaコマンドを使う](https://www.tankobucreate.com/post-211/)をご参照ください．
これでConda環境のインストールは完了です．

# Conda環境と付き合うために
本題のConda環境が壊れにくい方法について解説します．
結論をお伝えしますと，
- base環境に色々インストールしない
- `conda install`を絶対に使わない

この二つが大事です．二つについて詳しく解説します．
## base環境に色々インストールしない
**Anaconda-Navigator**を見るとわかるのですが，base環境にはいろいろな基本のライブラリがインストールされており，ここにライブラリを増やしていくのは壊れる元でありあまりお勧めしません．
![スクリーンショット 2023-10-03 21.46.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305858/acd1b97b-ec8c-2397-340e-8bd419df2b3d.png)
おすすめは**仮想環境**を作り、そこにインストールしていくことです．
仮想環境とはbase上に作ることができる，文字通り仮想的な環境であり，プロジェクトごとに仮想環境を作ることをお勧めします．
作り方は簡単で
```zsh:仮想環境の作成
(base) ~ % conda create -n 好きな環境名
```
または，pythonのバージョンを指定して
```zsh:仮想環境の作成（python）
(base) ~ % conda create -n 好きな環境名 python=好きなバージョン
```
で仮想環境を作ります．
`好きな環境名`：py39，`好きなバージョン`：3.9として進めます．
```zsh:仮想環境の確認
(base) ~ % conda env list
# conda environments:
#
base                  *  /Users/seast/anaconda3
py39                     /Users/seast/anaconda3/envs/py39
```
```zsh:仮想環境の有効
(base) ~ % conda activate py39
(py39) ~ % 
```
```zsh:仮想環境を抜ける
(py39) ~ % conda deactivate
(base) ~ %
```
以上のようにして，仮想環境の有効化，無効化を行います．

## conda installを絶対に使わない
仮想環境を作成すれば，そこに必要なライブラリをインストールしてコードを動かしていくと思うのですが，その際に大切なことは<font color=red>`conda install`を絶対に使わない</font color>ことです．

**ライブラリをインストールする際は`pip install`を使いましょう．**

conda環境には標準で`pip`が入っているので，それを利用しましょう．

環境破壊の原因はconda installでよく起きるConflictであり、pipでは起きることはほとんどありません。

ライブラリのインストールの際は，仮想環境上で
```zsh: scipyのインストール
(py39) ~ % pip install scipy
```
全て`pip`でインストールすれば環境は壊れません．
また，`pip`のいいところはrequirementsを一気にインストールしたり，書き出してくれるところも便利です．
```zsh:requirements.txtのインストール，書き出し
# インストール
(py39) ~ % pip install -r requirements.txt

# 書き出し
(py39) ~ % pip freeze > requirements.txt
```

# まとめ
Conda環境とうまく付き合うためには

- 仮想環境を使う
- `pip install`を使う

ことを守りましょう．

もし疑問やコメントがあれば、下のコメント欄でお知らせください！

# 参考
https://www.tankobucreate.com/post-211/

https://ovaldesign.jp/2022/03/24/anaconda/

https://qiita.com/ozaki_physics/items/985188feb92570e5b82d

https://zenn.dev/unemployed/articles/cc111706c3167c
クラスメソッド書類選考の不合格について

9月29日にクラスメソッド ソリューションアーキテクト（AWS）部門に応募しましたが、書類選考から落ちてしまいました。

一応、選考を入れる前からフィードバックを求めたのですが、クラスメソッド側で選考を保留にした理由は以下の通りでした。


:::note alert
劉様の自ら積極的に学ぶ姿勢は大変魅力的に感じた一方で、ご自身の取り組みによって顧客やチームにどんな好影響があったかが十分に見え切らず、スキルやご経験とのバランスも踏まえ、入社後早期からご活躍いただけるイメージが湧き切らなかったためです。
:::
 

私がアピールできる部分は最大限にアピールしたのですが、 

最終的には、熱意と意欲はあるものの、クラスメソッド側で私が入社しても仕事ができるのかという疑問を解決できなかったことが、保留の最大の理由だと思います。

実際に私が仕事をしながらどのような部分を顧客やチームに貢献したかをアピールできる要素は少なく、スキルや経験を判断できる客観的な指標がCKA資格一つしかありませんでした。

たとえAWS関連の業務を1年間進めたものの、書類上、私が業務的な能力を証明したとは言えないのが現実でした。

:::note info
*そこで、クラスメソッドでいただいた意見を参考に、長所と短所を少しずつ補完していこうと思います。*
:::



自分で積極的に学ぼうとする姿勢をもっと高めるためには、とりあえず私がクラスメソッドで目指したアウトプットを別にするのが正しいと思いました。 

後述しますが、資格の勉強にもある程度比重を置かなければならない部分があるので、週に2～3つずつテーマを決めて関連するポストを作成しようと思います。

個人的な勉強に関する領域を一つ選んで書くのが一つ、

残りの1つから2つは、私が仕事でやってきたこと、これからやっていくこと、いろいろと感じたこと、達成したことを書いてみようと思っています。

:::note warn
これが私の第一の目標であり、優先されるのはアウトプットの実現です。

**それに関連したブログサイトを一つ作ってアップしておかないといけないと思い、こうしてqiitaに初投稿することになりました。**
:::


:::note warn
二つ目は、クラスメソッドで指摘した「顧客やチームへの好影響が十分に見えていない」という点において、**仕事をしながら改善していく必要があると考えています。**
:::


現在も、業務に関してはec2ベースからコンテナベースに移行しようとしていますが、このような部分でなくても、自社開発をしながらどのような好影響を生み出すか、私と一緒に働くチームメンバーにポジティブな影響を与えるにはどうしたらいいのか、考えていきたいと思います。

だから、ブログを書くことにも大きな比重を置こうと思っています。

:::note warn
三つ目は、**スキルや経験のバランスが低く、入社後早期に活躍できるイメージが湧かないという点で、それを補っていきたいと思います。**
:::

先ほどの選考の影響に加え、私の実力に対する部分がきちんと証明できていないからこそ、選考の保留が決まったと思うので、これがきちんと補われなければ、再度選考に応募しても大きな変化はないと感じています。

そのために、実際にクラスメソッドではどのようなステータスを求めているのかを詳しく調べる必要があり、それに合わせて私がどのようなステータスを上げればいいのかをまず調べてみて、その結果に合わせて方向性を決めようと思いました。

とりあえず調査をする前に確定しておいた予定としては、今月10.28にSAA試験を受けることにしていたので、この後のスケジュールをどうするかというのがポイントでした。

一番参考にした部分はやっぱり既存のクラスメソッドがDeveloperIOでどんな形のアウトプットをしているかという部分でした。

https://dev.classmethod.jp/articles/hatagaki-aws-certified-clf-and-3-associates/

https://dev.classmethod.jp/articles/shun230615/

その中で確かに印象的な部分は資格証の取得です。

一度私がAWSソリューションアーキテクトに応募した以上、自分自身を証明するためにはAWSに関する知識と能力が証明されなければならないと感じました。

:::note info

純粋に私の勝手な判断の結果ですが、*今年が終わる前に少なくともアソシエイトの資格を全て取得しようと思います*

**SAA (AWS 認定ソリューションアーキテクト - アソシエイト)**

**SOA (AWS 認定 SysOps アドミニストレーター - アソシエイト)**

**DVA (AWS 認定デベロッパー - アソシエイト)**
:::

この3つを今年中に取得するようにチャレンジして、ブログ作成とアソシエイト資格認定を終えてから、もう一度クラスメソッド選考に挑戦しようと思います。

これも私の基準なので、実際に選考に再チャレンジしても、また挫折する可能性がありますが、その時はまたもっと高い目標を立てればいいと思います。

今年が終わる前の目標はアソシエイト認定達成と決めて、

https://dev.classmethod.jp/articles/o2mami-1-year-hurikaeri/

このブログのように、来年は12冠達成してJapan AWS All Certifications Engineersを目指したいと思います。

クラスメソッドで書類選考から保留になりましたが、むしろ得るものが多く、成長できるチャンスだと思い、これからもっと頑張ろうと思います。
[超初心者] Github入門

# 概要
超初心者がGitHub関して纏めます。
また、シナリオに沿ってどのような操作が必要になるかも纏めます

まずは、Gitが生まれた背景を見てみましょう

## ソースコード管理の歴史
ソースコード管理（Source Code Management, SCM）は、ソフトウェア開発における欠かせない要素であり、その進化はソフトウェア開発プロセスの革命をもたらしました。

### 中央集中型バージョン管理（CVCS）の課題
ソフトウェア開発の初期には、中央集中型バージョン管理システム（CVCS）が主流でした。CVCSでは、プロジェクトのソースコードは中央リポジトリに集約され、開発者は中央リポジトリからコードをチェックアウトして編集しました。しかし、CVCSには以下の課題がありました

- 競合とコンフリクトの管理: 複数の開発者が同時にコードを変更すると、競合やコンフリクトが頻繁に発生しました。これを解決する手段が必要でした。

- 履歴の管理: プロジェクトの変更履歴を効果的に追跡し、特定のバージョンを特定する方法が不足していました。

### BitKeeperとDVCSの出現
Linus Torvalds(リーナス・トーバルズ)氏は、BitKeeperを使用してLinuxカーネルのソースコード管理を行っていました。BitKeeperは商用バージョン管理ツールで、Linuxカーネルの開発者は無料で使用する特権を得ていました。しかし、BitKeeperのライセンスに関する問題が発生し、Linuxカーネルの開発者コミュニティ内で不満が高まりました。この問題は、BitKeeperの使用を継続することが難しくなり、Linus Torvalds氏がGitを開発するきっかけとなりました。

### Gitの誕生 (2005年~
SCM問題への解決策として、Linus Torvalds氏はGitを開発しました。Gitは分散バージョン管理システム（DVCS）であり、以下の特徴を備えています

- 分散性: 各開発者は中央リポジトリとローカルリポジトリの両方を持ち、オフラインでも作業できます。競合やコンフリクトを最小限に抑え、柔軟な作業を可能にしました。

- 履歴の管理: Gitは優れた履歴管理を提供し、変更履歴を透明かつ効果的に追跡します。これにより、特定のバージョンを特定しやすくなりました。

- 分散協力: 開発者は地理的に離れていても協力し、コードを共有しやすくなりました。これはオープンソースプロジェクトにとって特に重要です。

- 柔軟性: 開発者は異なるワークフローに合わせてGitをカスタマイズできます。

Gitは成功し、Linuxカーネルの開発においても使用されました。その後、Gitの影響力は拡大し、GitHubやGitLabなどのプラットフォームが登場し、ソフトウェア開発プロセスを大きく変革しました。

### GitHub (2008年~
Gitベースのソースコードホスティングプラットフォームで、多くの開発者によってソースコードがホストされ、共有されています。主要な機能には次のものがあります

- プルリクエスト: 開発者は変更を提案し、コードレビューと協力を行うためのプルリクエストを作成できます。

- イシュートラッキング: 問題やタスクを追跡し、プロジェクトの進捗を管理できます。

- コラボレーション: チーム内外の開発者がプロジェクトに参加し、コードを共同で開発できます。

- ウィキとドキュメンテーション: プロジェクトに関する情報を整理し、ドキュメンテーションを提供できます。

### GitLab (2011年~
Gitベースのソースコード管理プラットフォームのもう1つの重要な選択肢です。以下はGitLabの特徴です

- 自己ホスティング: GitLabはオンプレミスで自己ホスティングすることができ、セキュリティとデプロイメントのコントロールを提供します。

- CI/CDパイプライン: 統合とデリバリーのための自動化ツールを統合し、DevOpsの原則を支援します。

- アクション: イベントに応じた自動化を可能にするアクションという概念を提供します。

- 柔軟なライセンス: GitLabはオープンソース版とエンタープライズ版を提供し、異なるニーズに合わせて選択できます。


- - -
ここからはGitHubの話題に戻り、基本的な概念を紹介します

## Githubの基本的な操作フロー
### リポジトリのクローン (Clone)

ソフトウェアプロジェクトのリポジトリ（コードベース）をGitHubからローカルに複製します。これにより、自分のコンピュータで作業できるようになります。

次のコマンドでリポジトリをクローンします。

```bash
git clone <リポジトリのURL>
```
### ソースコードの改修 (Edit)

ローカルでコピーされたリポジトリ内で、必要なコードの変更や改修を行います。この段階ではまだ変更はリモートリポジトリに影響を与えません。

### コミット (Commit)
ソースコードの改修が完了したら、変更をコミットします。コミットは変更のスナップショットを作成し、変更の説明（コミットメッセージ）を付け加えます。

```bash
git commit -m "変更内容の説明"
```
### プッシュ (Push)

ローカルでのコミットが完了したら、変更をリモートリポジトリにアップロード（プッシュ）します。これにより、他の開発者と変更を共有できます。

```bash
git push
```
### プルリクエストの作成 (Create a Pull Request)


プッシュした変更を元のリポジトリに統合するために、プルリクエスト（Pull Request, PR）を作成します。PRは変更内容とその説明を含むリクエストで、他の開発者に対して変更の確認とレビューを依頼します。

### マージ (Merge)

プルリクエストをレビューし、変更が承認された場合、リポジトリの管理者が変更をマージします。これにより、変更が元のリポジトリに統合され、プロジェクト全体に適用されます。







加筆中…
PHPでLINEのクローンアプリを作成

メッセージを送受信ができるアプリを作ってみました。

![ezgif.com-video-to-gif (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353802/d2ba3585-5a12-cf79-04f1-3352280f652e.gif)


# リポジトリをclone

```bash
git clone https://github.com/gong-cha/line-clone
```

ソースコード

https://github.com/gong-cha/line-clone

# 実装した機能

- 新規登録
- ログイン
- ログアウト
- アカウント削除
- リアルタイムメッセージ受信
- 画像投稿
- アイコン表示
- 既読機能
- ユーザー一覧に最新のメッセージ表示

# 意識したこと

- プリペアードステートメント
- 飲んす機能
- デザイン

# リアルタイムメッセージの手法の検討

**ブラウザに通知する方法の検討**
- WebSockets
    - レンタルサーバーでは、pushできない
- Server Sent Events (SSE)
    - よさそう
- Long Polling
    - Server Sent Events (SSE)の方がコネクション節約できそう
- Short Polling
    - Server Sent Events (SSE)の方がリアルタイム性ありそう

**新しいメッセージの検知**
- inotify
    - レンタルサーバーにphpizeでインストールできないため却下 (php-develがインストールできない)
- pcntl_signal
    - php cliでしか使用できないため却下
- MySQL Binlog stream https://github.com/bullsoft/php-binlog
    - レンタルサーバーにphpizeでインストールできないため却下 (php-develがインストールできない)
- TCP/UDP Socket
    - Unix Domain Socketの方がプロセス間通信の効率よさそう
- Unix Domain Socket (抽象名前空間)
    - よさそう

# 参考にしたサイト

LINEのクローンアプリを作成してみた

https://qiita.com/ayukin/items/7cfb3089fd155467d30e

Reactでアプリを作成しました【9】【LINE clone】

https://qiita.com/kanfutrooper/items/d43ac5bc7f0d94a084e2

ReactでLINEクローンの作り方 - React×Firebaseチュートリアル

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

1ヶ月でLINEクローンを開発！LINEの新卒エンジニア技術研修をご紹介

https://engineering.linecorp.com/ja/blog/introducing-line-new-graduate-engineering-technical-training

# まとめ

まだまだ分からない部分がありますが、職業プログラマーとして働けるように就職活動していきます。
Proxmox VE上のコンテナにSSH接続する

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

前回、PVE上にubuntu22.04のtemplateを使ったコンテナをデプロイしました。

https://qiita.com/ohtsuka-shota/items/a46b79af31a44a236704

今回はこのコンテナに対してssh接続していきます。
※やっていることはかなり簡単ですが、接続出来ずに焦ったので備忘録です。

# 手順
まず、PVE上のコンソールを使ってコンテナに接続します。
systemctl status sshを実行するとinactiveとなっております。
![image (43).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/490c15bc-022d-c69c-3741-fe279b50e6e7.png)
systemctl start sshを実行してactiveにします。
![image (44).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/3bbb1e3d-8584-7c2a-a954-0cf6370bed3b.png)
ubuntuはrootでssh接続するのを拒否する設定になっているので、これを無効化してrootユーザでssh出来るようにします。
以下のコマンドを入力し、sshをrestartします。
※PVEのコンソールでコピペできます。
```
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart ssh
```
![image (45).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/5bd65f37-1de0-f3c4-35a8-eb51f07b3cd7.png)

これでssh接続出来るようになります。
コンテナのIPアドレス、rootユーザ、設定したパスワードでログイン可能です。
外部との接続もできます。
![image (46).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/4b1b98a2-25de-1a70-1c66-9cec7854115e.png)

# 余談的なもの
今回はPVEのコンソールから操作しましたが、lxcコマンドを使って操作することも可能です。
PVEにssh接続した後以下の様なlxcコマンドを使うことで接続可能です。
lxc-lsでLXCコンテナ一覧を取得。今回のコンテナは101という名前で認識されていることが分かります。
lxc-console -nでコンテナを指定して、後はユーザ名・パスワードでログイン出来ます。
```
root@pve03:~# lxc-ls
101
root@pve03:~# lxc-info -n 101
Name:           101
State:          RUNNING
PID:            2206
IP:             192.168.2.101
Link:           veth101i0
 TX bytes:      10.89 KiB
 RX bytes:      4.57 MiB
 Total bytes:   4.58 MiB
root@pve03:~# lxc-console -n 101

Connected to tty 2
Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself

Ubuntu 22.04 LTS firstLXC tty2

firstLXC login: root
Password:
Welcome to Ubuntu 22.04 LTS (GNU/Linux 5.15.102-1-pve x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Tue Oct  3 12:55:21 UTC 2023 from 192.168.2.65 on pts/3
root@firstLXC:~#
```
起動時に画面が真っ暗になる

PC起動時になったときの対処方法

①再起動
電源を長押しして、強制的に電源OFFにして再起動をさせる

②ショートカットキー
「shift + Ctrl + B + Windowsキー」を同時に押すとグラフィックドライバーが初期化される

※起動してから画面が真っ暗なままになるまでの間に、メーカーのロゴが表示されるかもポイントになる。
GitHub CopilotとGitHub Copilot Chatのはじめ方

## これは何

GitHub Copilot、GitHub Copilot Chatについて、自分の使い方や意識していることをまとめたもの

## GitHub Copilot

https://github.com/features/copilot

- GitHubとOpenAIが共同で開発したAI駆動のコーディングアシスタント

### 主な使い方

- 補完
  - 書いてるところから、どんどんサジェストしてくれる
    - 特にimportなどの定型的な部分、簡単な正規表現などはサジェスト強い
  - `Tab`でサジェスト内容を適用する
  - `Esc`でサジェスト内容を棄却出来る
  - `Command + →`でワードごとの適用
  - `Option + [`、`Option + ]`で代替サジェストを見ることができる
- Quick QA
  - コード上のコメントでQAが出来る

```ruby
# me: 現在の時刻を取得するにはどうすると良い？
# copilot: Time.now

# 下記のようにも書き換えできる

# q: 現在の時刻を取得するにはどうすると良い？
# a: Time.now
```

roleをつけることも出来ますが、あまりプログラミングに関係ない内容は省かれているかもしれません

```ruby
  # Roles: copilot
  #   Rubyのexpertなお嬢様です、語尾にですわをつけるのが特徴です
  # Role: me
  #   初心者エンジニア
  #
  # me: このscopeの意味がわかりません
  # copilot: このscopeは、指定した月の範囲内に作成されたrecordを取得するためのscopeです
  scope :hogehoge, ->(month) {
    where("created_at >= ? AND created_at <= ?", month.beginning_of_month.to_i, month.end_of_month.to_i)
  }
```

GitHubのアーキテクトの方が個人でGitHub Copilotの使い方をまとめてくれているので、見てみると面白いです。

https://patterns.hattori.dev/ja/

### 上手な使い方

公式のブログなどから、情報を得ている

https://github.blog/2023-06-20-how-to-write-better-prompts-for-github-copilot/

- コメントファーストで考える
  - 自然言語でコメントして、対話をする
    - 最初は面倒、コード書いたほうが早いかもだが、自身の整理にも繋がるので、全てが悪いわけではないと思う
- Copilotに必要なファイルはタブで開いておく
  - GitHub CopilotがContextとして、読み込んでくれるファイルは下記
    - ワークスペース内のファイル
    - 編集中のファイル(ワークスペース外でも)
- Rails開発におけるCopilotの活用をまとめてくれてる方もいらっしゃる

https://qiita.com/Teach/items/93220cc1be44f43e4895

## GitHub Copilot Chat

https://docs.github.com/ja/copilot/github-copilot-chat/about-github-copilot-chat

- 対話型のインターフェース

- GitHub Copilotとの違いって何?
  - 内部で使用されているLLMが異なる
    - GitHub Copilot: Codex(GPT-3がベース)
    - GitHub Copilot Chat: GPT-4
- ChatGPTとの違いって何?
  - VSCode上で対話ができるので、スムーズ
  - 開いているファイル、選択しているコードをcontextとして読み取って、やり取りをしてくれる
    - ChatGPTにcontextを説明するよりは楽に感じる
  - コードに対して特化した`/コマンド`の存在

### 主な使い方

- `/コマンド`を使う
  - `/explain`
    - コードに対する説明をしてくれる
    - `/explain 日本語で` とか、`/explain-ja`で日本語出力される
  - `/tests`
    - テストコードをサジェスト
  - `/fix`
    - リファクタ案を出してくれる
- 開発に関わる質問

![実際に聞いてみた](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/906eeb60-94b1-8732-3998-35b2d85e3877.png)

### 上手な使い方

- 基本的にChatGPTのプロンプトをイメージすると良さそう
  - [プロンプト エンジニアリングの能力を高めるためのヒント](https://cloud.google.com/blog/ja/products/application-development/five-best-practices-for-prompt-engineering)

- 開発に関わるやり取りはできるので、勉強会などでメモ取る時にわからない単語聞いたりなどは、結構やります。
  - 発表者とVSCodeに集中できるので個人的にとても助かっています。

https://qiita.com/fussy113/items/d46bbb87199b92dfddf1
CH32V003F4P6をch32v003funを使ってLチカするまで (macOS)

# はじめに

<img width="540" alt="CH32V003F4P6" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569302/f5f78427-e83f-0783-8324-6deaed802861.jpeg">

Intel MacのmacOS 13.6を使用します。

こちらの説明通りに作業を進めました。
https://74th.hateblo.jp/entry/ch32v003fun

# コンパイラが見つからない

`./ch32v003fun/ch32v003fun/ch32v003fun.mk`を開発環境に合わせてあげます。

```diff_make:ch32v003fun.mk
- PREFIX?=riscv64-unknown-elf
+ PREFIX?=riscv32-unknown-elf
```

# Build

```shell
% make all
riscv32-unknown-elf-gcc -o test.elf ch32v003fun/ch32v003fun/ch32v003fun.c test.c -g -Os -flto -ffunction-sections -static-libgcc -march=rv32ec -mabi=ilp32e -I/usr/include/newlib -I./ch32v003fun/ch32v003fun/../extralibs -I./ch32v003fun/ch32v003fun -nostdlib -I. -Wall  -L/usr/local/opt/bison/lib -T ./ch32v003fun/ch32v003fun/ch32v003fun.ld -Wl,--gc-sections -L./ch32v003fun/ch32v003fun/../misc -lgcc
dyld[34374]: Library not loaded: /usr/local/opt/isl/lib/libisl.22.dylib
  Referenced from: <97D19A7B-A41C-3329-A4F2-A3DDEE64C664> /opt/riscv/libexec/gcc/riscv32-unknown-elf/8.3.0/cc1
  Reason: tried: '/usr/local/opt/isl/lib/libisl.22.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/opt/isl/lib/libisl.22.dylib' (no such file), '/usr/local/opt/isl/lib/libisl.22.dylib' (no such file), '/usr/local/lib/libisl.22.dylib' (no such file), '/usr/lib/libisl.22.dylib' (no such file, not in dyld cache), '/usr/local/Cellar/isl/0.26/lib/libisl.22.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/Cellar/isl/0.26/lib/libisl.22.dylib' (no such file), '/usr/local/Cellar/isl/0.26/lib/libisl.22.dylib' (no such file), '/usr/local/lib/libisl.22.dylib' (no such file), '/usr/lib/libisl.22.dylib' (no such file, not in dyld cache)
riscv32-unknown-elf-gcc: internal compiler error: Abort trap: 6 signal terminated program cc1
```

エラーで止まりました。
`libisl.22.dylib`がないとでています。

# libを誤魔化す

私の環境にインストールされているlibが`libisl.23.dylib`だったので、`libisl.22.dylib`としてシンボリックリンクを作成します。バージョンが一つしか違わないので多分動くでしょう😜

```shell
% cd /usr/local/Cellar/isl/0.26/lib/
% ln -s libisl.23.dylib libisl.22.dylib
% cd -
```

# 再Build ＆ Flush

```shell
% make all
... 中略 ...

Found WCH Link
WCH Programmer is LinkE version 2.10
Chip Type: 003
Setup success
Flash Storage: 16 kB
Part UUID    : 5c-96-ab-cd-c4-b6-bc-53
PFlags       : ff-ff-ff-ff
Part Type (B): 07-13-bb-91
Read protection: disabled
Interface Setup
Image written.
```

# 書き込み成功🎉

おつかれさま🍺

![Lチカ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569302/be20ccd4-4d66-365b-0c0c-3a93e6fc2b7c.jpeg "Blink")
じゃんけんアプリ　Vue.jsを勉強したし取り敢えずアプリを作ってみた。　Part３


目標は相手の手を画像として表示させていく事。

じゃんけんの条件式を検索している中で見かけた記事がありましたのでそこから試すことにしました。

取り敢えず参考にしたコードに似せて,

```vue
<script>
if (computer.value === "グー") {
        imgs.value =require("./src/assets/images/~~.png");
      } else if (computer.value === "チョキ") {
        imgs.value = require("./src/assets/images/~~.png");
      } else {
        imgs.value = require("./src/assets/images/~~.png");
      }
</script>

<template>
 <img :src="imgs" alt="logo" class=""/>
</template>
```

早速エラーが、、、
require（）を入れるとノードの型定義がないと、、、
ノード　型　定義　わからん笑

沼から抜けれなくなる前に方向性を変えます。

次は、連想配列を試したのですがさらに沼リマス( ͡° ͜ʖ ͡°)( ͡° ͜ʖ ͡°)

さらに検索をしていく中で閃いたのがrequire（）いらなくねっ(｀・∀・´)
早速試してみることに。
```vue
<script>
 if (computer.value === "グー") {
        imgs.value = "Gu";
      } else if (computer.value === "チョキ") {
        imgs.value = "choki";
      } else {
        imgs.value = "Pa";
      }
</script>
<template>
<img
      :src="`../assets/images/${imgs}.png`"
      alt="logo"
      class=""
    />
</template>
```
これもダメ、、、、

ただコンソールを確認すると、データは格納されてる！
エラーを見たら４０４番
もしやと思いルートを変更してみると、、、

```vue
<template>
<img
      :src="`./src/assets/images/${imgs}.png`"
      alt="logo"
      class=""
    />
</template>
```
![スクリーンショット 2023-10-03 21.59.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512450/ec9c2729-82ab-521d-ef75-3b1d33c75145.png)

![スクリーンショット 2023-10-03 21.59.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512450/d7a07703-e877-9580-1bf8-89e03bfb4049.png)



できました笑
なんてとこで躓いてるんだ、、、

ただこの知恵の輪を解いた感じがたまらなく好きな自分がいます( ・∇・)



色々な記事を見過ぎて混乱したのか基礎が出来てないから沼にハマったのか、、、
出来たからいっかで解決していいものか、、、、、、


取り敢えずいい感じに動作してるので目的達成です笑

あとは見た目を整えて完成させていこうと思います！！！
PHPのコードレビューこんなんやってる（その２）

# 概要
意外とそんなにパターン無いのではと思い、整理と今後の備忘がてら記載してみました。実際にメンバーにしたレビュー内容をもとにしています。今回はこれ。

https://twitter.com/HouseToma/status/1709122974018830482

※写真は全く関係ない

## ちなみに前回はこちら

https://qiita.com/WdknWdkn/items/fa653a1f153a64d92b10

# 前提
以下の内容を踏まえてもらえるとひょっとしたら何かの参考になる度合いが
* PHPです
* 1年目にしたレビューが元になっています

# レビュー内容

* ifの条件文が複雑なので分解して早期return
* ifの条件文とtrue/falseの意味を入れ替えて条件を分解

## ifの条件文が複雑なので早期return

### before
```PHP
function sample()
{
    if ($hogeFlg !== true || !($hugaInfo === 'xxx' || $piyoInfo === 'yyy' || $pikoInfo === 'zzz')) {
        return false;
    }
    return true;
}
```

### 新米修正後
```PHP
function sample()
{
    // hoge条件※何故か一つだけ早期return
    if ($hogeFlg !== true) {
        return false;
    }

    // 他条件
    if (!($hugaInfo === 'xxx' || $piyoInfo === 'yyy' || $pikoInfo === 'zzz')) {
        return false;
    }
    return true;
}
```

## ifの条件文とtrue/falseの意味を入れ替えて条件を分解
```PHP
function sample()
{
    // hoge条件
    if ($hogeFlg === true) {
        return true;
    }

    if ($hugaInfo === 'xxx') {
        return true;
    }

    if ($piyoInfo === 'yyy') {
        return true;
    }

    if ($pikoInfo === 'zzz') {
        return true;
    }

    return false;
}
```

# 終わり

1回の指摘で必ずしもすべての工夫を理解するのは、それはそれなりに経験が必要ということです。
GPT PYNVIM

このプラグインは、OpenAIのGPTモデルを使用してコードレビューやコードに関する質問の回答を生成するNeovimプラグインです。Neovimを使用して簡単にコードレビューを行い、Vimを介してOpenAI APIを通じて会話をすることができます。

たとえば、Vimで開いたファイル内のコードを選択し、Enterキーを押すと、選択したコードが表示されるチャットバッファウィンドウが開き、それに関する質問を簡単にすることができます。

さらに、コードを選択してドットを押すと、OpenAIに選択したコードのコードレビューをリクエストすることもできます。

別の機能として、GptNvimSummarizeUrlsを実行し、URLを入力することで、URLの内容を要約することができます。

OpenAI GPTからの返答がMAX_TOKENSに収まらない場合は、自動で返答を再取得します。会話のコンテキストは、GNVM_PRIOR_CONVERSAION_SIZEで指定した数だけ記憶します。やり取りが各モデルの最大トークンを超える場合は、自動でより処理性能の高いモデル（gpt-3.5-turbo-16k）を選択します。

矩形選択した状態で、CTR+tを押すと、選択したテキストを簡単に翻訳できます。CTR+eを押すと英語に翻訳します。CTR+Tは、LANGUAGEに指定した言語に翻訳します。

https://github.com/JFK/gpt_pynvim
tqdmでzip,enumerate,map関数のプログレスバーを簡単に書く方法

# はじめに

[tqdm](https://tqdm.github.io/)は、Pythonで進捗バーを表示するためのツールで、リスト、タプル、イテレータなどを簡単にラップし、その進行状況を表示できます。しかし、これまで``zip``、``enumerate``、``map``関数などを使う場合はプログレスバーを表示するのに工夫が必要でした。

2020年1月25日にリリースされた[tqdmのバージョン4.42.0](https://pypi.org/project/tqdm/4.42.0/)以降では、そういった問題を解決するため、``tzip``、``tenumerate``、``tmap``が導入され、簡単に進捗バーを書けるようになりました。この記事では、これらの関数を使った方法について、従来の方法と合わせて紹介します。

# 新しい方法
``tzip``、``tenumerate``、``tmap``はtqdmのバージョン4.42.0以降で登場し、通常の``zip``、``enumerate``、``map``の書き方でプログレスバーを簡単に表示することができます。これらの関数の引数の詳細等は[公式ページ](https://tqdm.github.io/docs/contrib/)で紹介されています。

以下ではその書き方の一例を紹介します。

## tzipでの表示方法
```python:tzipでの表示方法
from tqdm.contrib import tzip
import time

mylist_a = list(range(10))
mylist_b = list(range(10))
for _, _ in tzip(mylist_a, mylist_b):
    time.sleep(0.1)
```

## tenumerateでの表示方法
```python:tenumerateでの表示方法
from tqdm.contrib import tenumerate
import time

mylist = list(range(10))
for _, _ in tenumerate(mylist):
    time.sleep(0.1)
```

## tmapでの表示方法
```python:tmapでの表示方法
from tqdm.contrib import tmap
import time

def myfunc(x):
    time.sleep(0.1)
    return x*2

mylist = list(range(10))
result = list(tmap(myfunc, mylist))
```

# 従来の方法
``tzip``、``tenumerate``、``tmap``を使わずに進捗バーを表示するには、比較的簡単なものに``tqdm``の引数``total``にリスト長を指定する方法や``tqdm``にイテラブルを指定した上で表示する方法などがあります。ここでは、その2つの方法について紹介します。

## tqdmでのzipの表示方法
```python:tqdmでのzipの表示方法
from tqdm import tqdm
import time

mylist_a = list(range(10))
mylist_b = list(range(10))

# 方法1: tqdmのtotal引数にリスト長を指定して表示
for _, _ in tqdm(zip(mylist_a, mylist_b), total=len(mylist_a)):
    time.sleep(0.1)

# 方法2: tqdm(iterable)を使って表示
for _, _ in zip(tqdm(mylist_a), mylist_b):
    time.sleep(0.1)
```

## tqdmでのenumerateの表示方法
```python:tqdmでのenumerateの表示方法
from tqdm import tqdm
import time

mylist = list(range(10))

# 方法1: tqdmのtotal引数にリスト長を指定して表示
for _, _ in tqdm(enumerate(mylist), total=len(mylist)):
    time.sleep(0.1)

# 方法2: tqdm(iterable)を使って表示
for _, _ in enumerate(tqdm(mylist)):
    time.sleep(0.1)
```

## tqdmでのmapの表示方法
```python:tqdmでのmapの表示方法
from tqdm import tqdm
import time

def myfunc(x):
    time.sleep(0.1)
    return x*2

mylist = list(range(10))

# 方法1: tqdmのtotal引数にリスト長を指定して表示
result = list(tqdm(map(myfunc, mylist), total=len(mylist)))

# 方法2: tqdm(iterable)を使って表示
result = list(map(myfunc, tqdm(mylist)))
```

# まとめ

この記事では、Pythonの進捗バー表示ツールであるtqdmを活用して、``zip``、``enumerate``、``map``関数といった一般的なイテレーション操作に対してプログレスバーを表示する方法を紹介しました。

従来の方法では、tqdmを使って``total``引数にリスト長を指定したり、``tqdm(iterable)``を使って進捗バーを表示する方法がありましたが、tqdmのバージョン4.42.0以降では、``tzip``、``tenumerate``、``tmap``といった新しい関数が登場し、よりシンプルで直感的な方法でプログレスバーを導入できるようになりました。

本記事が、どなたかの役に立てば幸いです。
Android App store‐自分への戒め

# アカウント作成や基本的に手続きの解説

:::note info
インフォメーション
まずは準備段階で必要な事がまとめられているこちらのページをご覧ください。
:::

## nyanさんのアプリ開発
https://akira-watson.com/android/developer-console.html

作ったは良いけど、どうしたら公開できるのといった細かい点が網羅されています。


# アップ時の決まり事
- Release 版をアップしましょう。
- 私はうっかりDebug版あげてました（メニュー上、選択していない方）
- アップロード時点でエラーが出たらとにかくつぶします。
- 知らずにアップした時点でだれか？がめいいっぱいテストして、問題点指摘してくれます


![屏幕截图 2023-10-03 21.38.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/014e4d0f-b311-7374-f4f7-2bc6fab2cc25.png)

## 注意2 難読解ファイル問題はかたづけておく

https://codeforfun.jp/android-studio-path-to-mapping-txt-and-upload/

私がかくより、Saraさんの解説見たい方がいいです。


# 必要な手続きは全て網羅しておくこと
- 免許証登録したり、米国の税金関連の書類（これはGitもおなじですね）等々
- 審査があり、数日待つことがあります。
- アカウント自体は1日程度で取れますが、リリースまではどうも1週間はかかりそう。

## 不完全だとアラート出ます

![屏幕截图 2023-10-03 20.38.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/5ba72721-9857-ec92-2140-1dba37117be8.png)

# 審査中の身ですが、人事を尽くして天命を待つ　の心境

:::note warn
注意
会社サポートないので、持ち出しです
:::
JTReg実行備忘録[Ubuntu 22.04]

# おねがい
この記事を参考にして実行に失敗した方は後学のためにコメントをいただけますと幸いです。
質問にもお答えできる限りお答えしますので是非コメントを残してください。

# 環境
OS : Ubuntu 22.04.3 LTS

前回の[JTRegビルド](https://qiita.com/tabatad/items/a05f3a6fb1bab327e9c9)の続きになります。

# 手順

## 1. Gtest資材ダウンロード
```
$ cd ~/work
$ git clone -b release-1.8.1 https://github.com/google/googletest
```

## 2. JDKのリビルド
```
$ cd ~/work/jdk17
$ bash configure --with-jtreg=$JT_HOME --with-gtest=/home/tabatad/work/googletest
$ make clean
$ make images
```

## 3. テスト実行
テストの起動に失敗した。
```
$ make run-test-tier1
~~~~~~~~~~略~~~~~~~~~~
/home/tabatad/work/jdk17/test/hotspot/jtreg/runtime/StackGuardPages/exeinvoke.c: In function 'set_signal_handler':
/home/tabatad/work/jdk17/test/hotspot/jtreg/runtime/StackGuardPages/exeinvoke.c:72:15: error: storage size of 'altstack' isn't constant
   72 |   static char altstack[SIGSTKSZ];
      |               ^~~~~~~~
gmake[3]: *** [test/JtregNativeHotspot.gmk:1525: /home/tabatad/work/jdk17/build/linux-x86_64-server-release/support/test/hotspot/jtreg/native/support/exeinvoke/exeinvoke.o] Error 1
gmake[3]: *** Waiting for unfinished jobs....
gmake[2]: *** [make/Main.gmk:612: build-test-hotspot-jtreg-native] Error 2

ERROR: Build failed for target 'run-test-tier1' in configuration 'linux-x86_64-server-release' (exit code 2)
~~~~~~~~~~略~~~~~~~~~~
```
## 4. バグ対応
https://bugs.openjdk.org/browse/JDK-8272472

今回の環境では上記のバグが発生しているようなので[File changed](https://github.com/openjdk/crac/pull/37/files)を参考にソースを編集する。
編集対象のファイルは`test/hotspot/jtreg/runtime/StackGuardPages/exeinvoke.c`。

## 5. JDKのリビルド（再）
```
$ cd ~/work/jdk17
$ bash configure --with-jtreg=$JT_HOME --with-gtest=/home/tabatad/work/googletest
$ make clean
$ make images
```

## 6. テスト実行（再）
```
$ make run-test-tier1
~~~~~~~~~~略~~~~~~~~~~
==============================
Test summary
==============================
   TEST                                              TOTAL  PASS  FAIL ERROR
   jtreg:test/hotspot/jtreg:tier1                     1757  1757     0     0
>> jtreg:test/jdk:tier1                               2063  2062     1     0 <<
>> jtreg:test/langtools:tier1                         4215  4204     6     5 <<
   jtreg:test/jaxp:tier1                                 0     0     0     0
   jtreg:test/lib-test:tier1                            28    28     0     0
==============================
TEST FAILURE
```

# 参考
- OpenJDK jdk17 building.md

https://github.com/openjdk/jdk17/blob/master/doc/building.md
JSXの基礎文法〜最低限知っておきたいルール〜

# はじめに
初めてJSXファイル(TSX含む)を見て、何がなんやらわからない人に向けて、JSXの基礎中の基礎を書かせていただきます。

# JSXの基礎文法
#### reactライブラリをimportする
JSXは必ずreactライブラリをimportする必要があります。実際のソースコードから下記の記述があることを確認してみてください。
```React
import React from 'react';
```

#### return文の中がJSXの記法
基本的にはHTMLと同じ書き方となります。その認識をもった上でソースコードを読んでみてください。
ただし一部違うこともありますので注意してください。(例:HTMLのclassはJSXだとclassNameとなります。)


#### キャメルケースで記述する
JavaScriptは-(ハイフン)を読み取ることができないため、キャメルケースで記述する必要があります。
もしソースコードに手を加えるとなった際は間違えないよう注意してください。

#### ｛｝内はJavaScriptの世界となる
｛｝内はJavaScriptの記述を使うことができます。
const ◯◯で定義した変数などを｛｝内で使うことができます。

#### JSXは必ず階層構造になっていなければならない
JSXはreturn文の直下に複数のタグを置くことはできません。(最上位コンポーネントは並列にできない。)
※ターミナルにエラー文が出力されます。
そのためreturn文直下が複数のタグになる場合は、< React.Fragment >< / React.Fragment >で囲むか、もしくはReact.Fragmentの省略形である<> < />(空タグ)で囲ってください。

```React
return (
 <React.Fragment>
　　<p>サンプル文章</p>
　　<p>サンプル文章</p>
</React.Fragment>
)
```
これでもいけるし、、、、
```React
return (
 <>
　　<p>サンプル文章</p>
　　<p>サンプル文章</p>
</>
)
```
こっちでもOK。(これよく見る。)




# 最後に
まだまだ分からないことが多いので、引き続き勉強していき、わかったことがあればまた追加で記事投稿していきます！
【メモ】PythonでPDF結合_PyPDF2 v3.0.0以上の場合

# 概要
PDF結合しようとしてPythonでさくっとスクリプト書こうとした。
Pythonならすぐ出るだろうとChatGPTに書かせてみたら地味につまづいてしまったのでメモ。

# 環境
Windows 11
Python 3.11.5
PyPDF2 3.0.1
VSCode 1.68.0

# やりたかった処理
指定したフォルダ（folder_path）の中にあるPDFファイルをすべて結合。
出力先PDF（output_pdf）はカレントディレクトリに作成される。

# 詰まったところ
`PdfFileMerger`クラスが間違ってるって言われる。

# 対策
`PdfFile◯◯◯`クラスは`Pdf◯◯◯`というクラスに置き換える。
[【Python】PDFをいじる](https://zenn.dev/ijiwarunahello/articles/c82dfdc402cf65) によれば、PyPDF2ライブラリはVer3.0.0から仕様が変わったようだ。
PyPDF2の公式Documentでもそうなっていて、`PdfFile◯◯◯`クラスを呼ぶと「`Pdf◯◯◯`の間違いだろ？」というエラーメッセージを出すようになってる。
[The PdfMerger Class — PyPDF2 documentation](https://pypdf2.readthedocs.io/en/3.0.0/modules/PdfMerger.html)

# ソースコード

```python
# 標準だとUTF-8指定で書けって言われたけど面倒なのでShift-JIS指定した
# -*- coding: Shift-jis -*-

import os
from PyPDF2 import PdfMerger

# 結合するPDFファイルが格納されているフォルダを指定
# '/path/to/your/folder'にフォルダパスを指定する。
folder_path = '/path/to/your/folder'

# 結合後のPDFファイル名を指定
output_pdf = 'combined.pdf'

# PdfMergerオブジェクトを作成
pdf_merger = PdfMerger()

# フォルダ内のPDFファイルを取得
pdf_files = [f for f in os.listdir(folder_path) if f.endswith('.pdf')]

# ファイルが見つからない場合、エラーメッセージを表示
if not pdf_files:
    print("フォルダ内にPDFファイルが見つかりませんでした。")
else:
    # PDFファイルを順番に結合
    for pdf_file in pdf_files:
        pdf_path = os.path.join(folder_path, pdf_file)
        pdf_merger.append(pdf_path)

    # 結合したPDFファイルを保存
    with open(output_pdf, 'wb') as output:
        pdf_merger.write(output)

    pdf_merger.close()

    print(f"{len(pdf_files)} 個のPDFファイルを {output_pdf} に結合しました。")

```
SDKMANを使って Javaをインストール

普段Javaを使ったりしないが、なんだかんだ３ヶ月ぐらいごとに　必要としていつもいつも思った以上に時間がかかっているため、今回メモを残すことにしました。

まず、Javaを直接システムに使うと後で管理色々と面倒なので Package Managerにお任せしたい。

そのためSDKMANを利用!

## 1. SDKMANをインストール

https://sdkman.io/usage

最初SDKMANがインストールもしていないので [公式ガイドの通りインストール](https://sdkman.io/install)する。

```zsh
# インストール
curl -s "https://get.sdkman.io" | bash
# PATHなどを設定する
source "/Users/ignacio/.sdkman/bin/sdkman-init.sh"
# 確認
sdk version
```

注意: もし curl 56 recv failure とか出たら　別のネットワークに切り替えた方がいい。これはSDKMANのせいではなく、おそらくそのネットワークの設定が何か関わっていると思われる。

ちなみに、上記の無事に実行していると　`~/.zshrc` に以下の内容が追加される。

![Screenshot 2023-10-03 at 21.06.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/f122c23e-7ba7-3fc9-de86-93959bed7ef6.png)



## 2. SDK manを使って適切なJava versionを特定

まずJavaを検索し

```zsh
sdk list java
```

結果:
![Screenshot 2023-10-03 at 20.46.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/3b826785-386f-3158-1922-5b101c6b630d.png)

良さそうなもののIdentierを覚えておきます。

リストが長すぎて filterしたいは

```zsh
sdk list java | grep sem
```
結果:
```zsh
# Semeru        |     | 20.0.2       | sem     |            | 20.0.2-sem          
#               |     | 20.0.1       | sem     |            | 20.0.1-sem          
#               | >>> | 17.0.8       | sem     | installed  | 17.0.8-sem          
#               |     | 17.0.8.1     | sem     |            | 17.0.8.1-sem        
#               |     | 17.0.7       | sem     |            | 17.0.7-sem          
#               |     | 11.0.20      | sem     |            | 11.0.20-sem         
#               |     | 11.0.20.1    | sem     |            | 11.0.20.1-sem       
#               |     | 11.0.19      | sem     |            | 11.0.19-sem   
```


例: 「攻めるJava」をインストールしたい！

```zsh
sdk install java 17.0.8-sem
```

### 2.1 SDKMANの簡単な使い方

複数のバージョンがあればデフォルトのバージョンを指定したい（変えたい）時は 以下のコマンドで

```zsh
sdk default java 17.0.8-sem
```

また、現在のバージョンはどれかを調べたい時に　以下のコマンドで

```zsh
sdk current java
```


## 3. インストールの確認

```zsh
java --version
# openjdk 17.0.8 2023-07-18
# IBM Semeru Runtime Open Edition 17.0.8.0 (build 17.0.8+7)
# Eclipse OpenJ9 VM 17.0.8.0 (build openj9-0.40.0, JRE 17 Mac OS X aarch64-64-Bit 20230718_382 (JIT enabled, AOT enabled)
# OpenJ9   - d12d10c9e
# OMR      - e80bff83b
# JCL      - 77b0f754805 based on jdk-17.0.8+7)
```
期待通り！

```zsh
echo $JAVA_HOME
# /Users/ignacio/.sdkman/candidates/java/current
```

上記のファイルが実はsoft linkなので readlinkで解決すると 期待通りの17.0.8が表示される。

```zsh
readlink $JAVA_HOME
# 17.0.8-sem
```

![Screenshot 2023-10-03 at 21.28.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/cdd06cd8-d61d-a15d-06c9-747df3e5390c.png)

全て期待通り！

## 4. オマケ: XcodeのBuild ScriptにもSDKMANのJAVA_HOMEを認識させる

前ここに方法を書いていたが、書きたい内容が増えたり本記事と内容が異なったりして専用のPostにしました。よかったらこちらをお読みください [XcodeにJAVA_HOMEを認識させる](https://qiita.com/nacho4d/items/6d04c9287c55c26fca95) 

これでスッキリ！


See you later! 🐊
PHP+MySQLでユーザーログインシステムを作成（覚書）

PHPでユーザーログインシステムを作成するための備忘録

データベースにユーザー情報を保存します。
ユーザー名とパスワードを使用し、ログイン認証を行いセッションを使用してログイン状態を管理します。
### データベースのセットアップ

ユーザー情報を保存するテーブルを作成します。
```sql
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL
);
```
### login.php｜PHPファイルの作成
ログインページ、ログインフォームの作成をします。
```php
<?php
session_start();

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $username = $_POST["username"];
    $password = $_POST["password"];

    // データベースからユーザー情報を取得
    // この部分はデータベースへの接続とクエリの実行が必要です

    if ($user_exists && password_verify($password, $hashed_password)) {
        // 認証成功
        $_SESSION["username"] = $username;
        header("Location: dashboard.php"); // ダッシュボードページにリダイレクト
        exit;
    } else {
        // 認証失敗
        $error_message = "ユーザー名またはパスワードが正しくありません。";
    }
}
?>
```
表示部分のHTMLは以下、別ファイルにしてincludeしても良いし、login.phpに処理と一緒に書いてもOK。
```html
<!DOCTYPE html>
<html>
<head>
    <title>ログイン</title>
</head>
<body>
    <h1>ログイン</h1>
    <?php if (isset($error_message)) { ?>
        <p><?php echo $error_message; ?></p>
    <?php } ?>
    <form method="POST" action="">
        <label for="username">ユーザー名:</label>
        <input type="text" name="username" required><br>
        <label for="password">パスワード:</label>
        <input type="password" name="password" required><br>
        <button type="submit">ログイン</button>
    </form>
</body>
</html>
```
簡易的に書いた覚書です。
動作確認してないのでエラー出るかも。
Promise.all()を使って反復処理を速く実行

## はじめに
JavaScriptにおいて、for文中で同期処理を利用したい場合にasync/awaitでなくPromise.all()というメソッドを用いると良い、という話です。
自分自身がasync/awaitで反復処理を行い非常に実行に時間を要して困っていたため、記事にしてみました。


## そもそもJavaScriptの同期/非同期処理とは
そもそも、JavaScriptは同期処理であり、非同期処理でもあるプログラミング言語です。
基本的にはコードを上から実行しますが、時間がかかる処理は終了を待たずに進んでいきます。
有名な事例ですが......

```js
console.log("A");
setTimeout(() => {
    console.log("B");
}, 1000);
console.log("C");
```

上記の場合、"A"が出力され、次にsetTimeout関数が実行され、1秒後にBが出力されることになります。
待ってる間もプログラムの実行が進むので、先に"C"の出力が行われ、最後に1秒後の"B"が出力されます。


## Promiseとasync/await
例えば外部APIのやり取りなど時間のかかる処理を行い、その後その結果を元にプログラムの実行を進行したい場合、外部APIとのやりとりの完了を待ってその後プログラムを実行したい。という状況になるかと思います。
そのような場合に同期処理としてPromiseもしくはasync/awaitというメソッドを用います。
ES2015の時点ではPromiseというメソッドのみでしたが、ES2017でasync/awaitが登場し、こちらの方が簡単で、読み手としても書き手としても理解しやすいため、特に初心者エンジニアはこちらを頻繁に使っているのではないでしょうか。


単純に「この処理が終わるまで待ちたい」というシチュエーションであればasync/awaitの方がマッチしています。

## async/awaitでうまくいかなかった
私自身も使いやすいasync/awaitを主に使用していました。
しかし、反復処理で時間のかかる処理を連続で行いたい場合に、非常に時間を要することに困っていました。

```js
// 外部APIを処理する関数
async function externalAPIProcess (user) {
    // 時間のかかる処理
    return userResult;
}
```

```js
// 非常に時間がかかってしまう......
const users = [user1, user2, user3, user4, user5];
const results =[];

for (const user of users) {
    const userResult = await externalAPIProcess(user);
    results.push(userResult);
}
console.log(results);
```



## Promise.all()の利用
Promise.all()というメソッドを用いることでこれを解決することができました。
async/awaitのみでの記述では、要素数に比例して実行時間が伸びていきます。
しかし、反復処理中では同期処理を行わず、```await Promise.all()```を反復処理終了後に行うことで、処理時間を大幅に短縮できます。
メモリと処理量にもよりますが、理論上要素数が増えても実行時間は変わりません。


```js
const users = [user1, user2, user3, user4, user5];
const resultPromises =[];

for (const user of users) {
    const userResult = externalAPIProcess(user);
    resultPromises.push(userResult);
}
const results = await Promise.all(resultPromises);
console.log(results);
```

私の場合でも、大幅な短縮を図ることができました。
単純なメソッドかもしれないですが、長期間悩んでいたことがあっさり解決できたので記事に上げてみました。


## 結論
JavaScriptの同期処理はasync/awaitがわかりやすく使いやすいですが、
Promise.all()などasync/awaitだけでは実現できない機能も多いです。

## 参考文献
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
SDK: Unity com.unity3d.ads:unity-ads（バージョン 4.0.1 へのアップグレードをご検討ください）

2年以上前に作成したアプリのバージョン上げてgoogleに申請したらリジェクトされた。

![Screenshot 2023-10-02 at 18.20.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2436967/ccdacc62-e637-e194-7488-da35ca87fffd.png)

# Unity com.unity3d.ads:unity-ads
これは、アプリに広告を載せる際に必要となるSDKらしいのだが
そもそも私のアプリは広告を載せないので、削除したい。

# adsを削除する
Packages/manifest.json と
Packages/package-lock.jsonから
com.unity.adsを削除
![Screenshot 2023-10-03 at 20.59.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2436967/7bc9d4ed-9ef8-7896-ba21-f7907490ffed.png)
![Screenshot 2023-10-03 at 21.00.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2436967/7587030e-87c0-625f-0a66-f4bb596e422f.png)

これで再度ビルドし、申請したら通りました！
![Screenshot 2023-10-03 at 21.00.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2436967/1d3cf979-b7a5-7ea3-bf57-e40464b94057.png)
AWS Certified DevOps Engineer - Professional に合格したので振り返り

AWS Certified DevOps Engineer - Professional(以下DOP) に合格できたので振り返り。

### 基本情報
- 業務経験: AWSの実務経験は4ヶ月程
- 保有資格: CLF, SAA, DVA, SOA, SAP, DBS

学習期間は1ヶ月程度です。

### 教材

[AWS Certified DevOps Engineer - Professional サンプル問題](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-devops-pro/AWS-Certified-DevOps-Engineer-Professional_Sample-Questions.pdf)

[AWS Certified DevOps Engineer - Professional 公式練習問題集](https://explore.skillbuilder.aws/learn/course/external/view/elearning/14541/aws-certified-devops-engineer-professional-official-practice-question-set-dop-c02-japanese)

[AWS WEB問題集で学習しよう](https://cloud-license.com/exam/) のDOP#61~79


### 学習の進め方
サンプル問題を解く
↓
公式練習問題集を解く
↓
AWS WEB問題集で学習しようのDOP#61~79

DOPの場合は書籍やドキュメントでのインプットに集中する期間はなく、**すべて問題演習を通して学習**しました。他資格の貯金が残ってたこともあり、サンプル問題を解いた段階ですら、全く知らないサービスや機能が解答の障壁になることはあまりありませんでした。文章中の要件とシステム構成の理解不足や、曖昧にしか理解していない知識によって誤答する場合が多かったです。
そのため、網羅的に学習するよりも、演習で見つかった穴を埋めていく方針で学習を進めていきました。また、**本番試験でも、上記教材とほぼ同じ問題が結構な頻度で出てきたので、SAPよりもだいぶ問題が使い回されている印象**です。そういう意味でも多くの問題をこなす価値は高いと思います。

インプットについて強いて言うならControl Towerが本番試験で思いの外出題されたので、別途学習しておけばよかったと反省しています。上記教材の演習問題で埋めきれなかった穴でした。

他の試験でもそうですが、演習問題については解答の根拠が言えるまで公式ドキュメントなどを読んで調べます。誤答が知識ではなく、情報整理ができてなかった故に起きる時もあるので、その場合はどこを見落としたせいで正解できなかったのかを整理しました。
覚える必要のある知識は[Anki](https://apps.ankiweb.net/)というアプリで暗記カードを作成しました。

#### 問題演習を始める基準について

自分はSAPを数ヶ月前に取得していたので、学習開始時点から問題演習に取りかかれましたが、人によって知識レベルは違いますから、いきなり演習を始めていいものか迷う方もいるかと思います。
これについては、実際に問題を数問解いてどこか体系的な知識不足が解答のボトルネックになっているかを確認するのが一番確実だと思います。問題文に出てくるサービスが知らないものばかりで、文章の意味がよくわからない場合などは、一度書籍などで体系的なインプットをしたほうがよいと思います。また、何が原因で間違えているかが重要なので、得点率はあまり基準するべきではないです。

ただ、DOPを受ける人はアソシエイトの資格は揃えている人が多いと思うので、その場合あまり知識不足で問題演習自体が始められないというケースは少ないのではないかと感じています。


#### 問題の傾向について

問題自体はプロフェッショナル試験だけあって範囲も広く、あんまり極端な傾向はない印象ですが、強いて言えば下記の3つが多かった印象です。

**Codeシリーズのメインどころ**
AWS CodeBuild、AWS CodeCommit、AWS CodeDeploy、AWS CodePipelineはよく出てきます。逆にCodeStarのようなややマイナーなサービスはほぼ出題されません。また、マニアックな機能の知識が必要な問題はそこまで出されず、各サービスの概要を知っていれば対応できる問題が多かった印象です。
例えば、CodeBuildでデプロイしようとしている選択肢とかが出てきます。問題文と選択肢も長いとつい見逃してしまうので、反応できるのが大事です。

**自動化の問題**
DebOpsエンジニアの試験だけあって、自動化に関する問題は多かったです。そのため、EventBridge, CloudWatchAlarm, SSMなどのサービスはよく顔を出します。問題文の要件を満たす上で、適切な使い方がされているかがよく問われた印象です。
例えば、直接Lambdaを呼び出せないサービスからLambdaを起動させている（EventBridgeが不足している）選択肢や、OSのパッチ更新をする時に、Patch ManagerではなくLambdaとEventBridge組み合せて頑張っている選択肢を切る際に必要な知識です。

**各デプロイ方法と使うべき場面**
例えば、Blue/Green Deploymentはどういうデプロイ方法で、どのような場面で使うべきなのか、といった知識を各デプロイ手法ごとに整理しておくといいと思います。
コストを抑えるためデプロイ先のインタンスを増やしてはいけない、ロールバックは迅速に行いたい、デプロイ失敗時の影響をできるだけ抑えたいなど、文章中に様々な条件がでてきて、それらを考慮したデプロイ方法を選択する問題が比較的よく出てきた印象です。

それ以外には前述の通り、サンプル問題や公式問題集から使い回されている問題が見受けられるので、少なくともこの2つに出題された問題は確実に解けるようにするとよいと思います。

### 問題を解く時に注意したこと

とにかく要件を漏らさないことです。知識不足というよりも問題文と選択肢の把握が解答のボトルネックになる場合が多いと感じました。SAPの時もそうでしたが、テストセンターから渡されるボードにしっかりメモを取りながら読み進めました。



一個人の感想でしかないですが、誰かの役に立てば幸いです。