OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでDjangoを使ってみる

# はじめに
Djangoに触れる機会があったので、プロジェクトの作成から画面の表示までまとめてみました。

# Djangoとは
PythonでWebアプリケーションを開発するためのフレームワーク。

# プロジェクトの作成から画面の表示まで

## Djangoのインストール

```bash
# インストール
python3 -m pip install Django

# インストールされたか確認
python -m django --version
```

## プロジェクトの作成

```
django-admin startproject ${プロジェクト名}
or
python3 -m django startproject ${プロジェクト名}
```

## 開発サーバを立ち上げてみる
以下のコマンドを実行するとサーバが立ち上がる。
「http://127.0.0.1:8000/」にアクセスするとサーバの画面が表示される。
```
# デフォルトのポートで起動する
python3 manage.py runserver

# ポートを指定して起動する
python manage.py runserver ${ポート番号}
```

## アプリケーションを作成

```
# プロジェクトのディレクトリへ移動
cd ${プロジェクト名}

# アプリケーションを作成
python3 manage.py startapp ${アプリケーション名}
```

## プロジェクトからアプリケーションを認識できるようにする
「${プロジェクト名}/settings.py」を以下のように書き換える。
```
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    '${アプリケーション名}.apps.${apps内に記載されているクラス名}' ←追記
]
```

## Viewを作成
「${アプリケーション名}/views.py」を以下のように書き換える。
```bash:
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello World")
```

## ルーティングの追加
「${プロジェクト名}/urls.py」を以下のように書き換える。
```
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path("${パス}/", include("アプリケーション名.urls")),
    path('admin/', admin.site.urls),
]
```

## アプリケーションにアクセスする
「http:\//127.0.0.1:8000/${パス}/」にアクセスすることでアプリケーションにアクセスできる。

# その他

## タイムゾーンの変更
「${プロジェクト名}/settings.py」を以下のように書き換える。
```
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
↓
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
```

## MySQLの設定を行う
以下のコマンドで接続に必要なドライバーをインストールする。
```
python3 -m pip install pymysql
```
「${プロジェクト名}/__init__.py」を以下のように書き換える。
```
import pymysql

pymysql.install_as_MySQLdb()
```
「${プロジェクト名}/settings.py」を以下のように書き換える。
```
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
↓
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '${DBのホスト名}'',
        'PORT': '${DBのポート}',
        'NAME': '${DB名}',
        'USER': 'DBのユーザ名',
        'PASSWORD': 'DBのユーザのパスワード',
    }
}
```

# 参考
https://docs.djangoproject.com/ja/4.2/topics/install/#installing-official-release
https://docs.djangoproject.com/ja/4.2/intro/tutorial01/
NSLで回路を作ろう#00: はじめに

# はじめに

NSLについて勉強する機会があり、
そこで得た知見について今後まとめていく。
ハードウェアに関しては初学者なので、
多少至らぬ点があるだろうが、ご理解いただきたい。

# NSLとは

正式名称: Next Synthesis Language
- つまり、次世代を担うHDL

特徴
- C言語みたいに書ける
  - 関数を組合わせた構造化プログラミングが簡単に回路になる！
- 可読性が高い
  - 信号ベースじゃなくて機能ベースに書ける
- 記述量が少ない
  - `always`と`RST`に追われる日々から脱却
- 単相クロック同期回路に強い
  - クロック・リセットはインフラという考えで、言語側で用意してくれる

# 今後の流れ

今後の流れとして以下の点を説明していく
- 参考テキスト
- 作成環境
- 作る予定の回路
- 作成する記事の内容


## 参考テキスト
[text]: https://gihyo.jp/book/2018/978-4-7741-9388-5

[【改訂2版】FPGAボードで学ぶ 組込みシステム開発入門［Intel FPGA編］][text]を参考に回路等を色々と作っていく。
- この本の中では、Verilog HDLを使った回路の設計から、Platform Designer(旧 QSyS)を使ったCPU組込み回路の作り方まで紹介されている。

## 作成環境

以下で示す環境で回路を作っていく
- FPGAボード: Terasic社 DE1-SoC
  - [テキスト][text]で対象になっているボードの一つ
- コーディング: Visual Studio Code
- NSLのコンパイル: NSL CORE
  - Verilogに変換してFPGAに実装する
    - [NSL LiveCygwin 環境のダウンロード](https://www.overtone.co.jp/download)
- CPUの組込み、FPGAに実装等: Quartus Prime 18.1
- 回路のシミュレーション: ModelSim - INTEL FPGA STARTER EDITION 10.5b

## 作る予定の回路
作る予定の回路としては以下のようになっている。
- 24時間時計
  - 1秒を計ってカウントアップしていき、時分秒を7セグメントLEDで表示、ボタン入力で時刻調整も実装する
- CPUを組合わせた回路
  - 上記と同様に24時間時計を作っていくのだがPlatform Designerを使ってCPUを組込み、ハードウェア側では7セグメントLEDの表示、ソフトウェア側では表示する回路の制御等と、ソフトとハードを両方を組み合わせていく。
- マウスやキーボード入力を受取る回路
  - マウスやキーボードを接続して、入力を7セグメントLED等に表示する。
- ディスプレイに文字を表示してみる
  - ディスプレイを接続して画面上に文字を表示する
- 外部メモリを使ったグラフィック表示
  - FPGAボード上にあるにあるRAMを使って画像データをディスプレイに表示する
- CMOSカメラを使った画像キャプチャ
  - カメラでキャプチャした映像をRAMに保存する回路を作ってディスプレイに表示する


記事の中では以下の順で実装を進めていく
- どんな回路を作るのか機能分割
- 分割していった各機能をNSLで作ってみる
- 作った回路でシミュレーションをしてみる


# まとめ

初回ということでこれからやることについて説明した。

[次回](https://qiita.com/mk_masa/items/2c4eb17dde97695cee4c)は24時間時計を作っていく。
(リンクだけです)「角度80°」を過去問より集めた。

# 過去問
・勉強中 ＜　問題掲載大学一覧MathJax 様

①　[2022　北海道教育大学　前期【３】](https://mathexamtest.web.fc2.com/2022/202210002/2022100020100mj.html#top-0103)
　　tan(90°-α)=１/tan(α)
　
 ②　[2022　弘前大学　前期【１】(1)(2)](https://mathexamtest.web.fc2.com/2022/202210041/2022100410100mj.html)
　 　sin(40°)-　sin(80°)+ sin(160°)
　 　tan(40°)-4tan(80°)+4sin(160°)

③　[ 2021　福島大学　前期【１】(4)](https://mathexamtest.web.fc2.com/2021/202110141/2021101410100.html#top-0104)
　 　cos(40°)+cos(80°)+cos(160°)

④　[ 2018　兵庫県立大学　前期【１】(3)](https://mathexamtest.web.fc2.com/2018/201811613/2018116130100mj.html#top-0107)
　 　tan30°tan40°tan80°の値を求めよ．

⑤　[ 2013　千葉大学　前期【10】](https://mathexamtest.web.fc2.com/2013/201310241/2013102410100mj.html#top-0110
)
　 　tan10°=tan20°tan30°tan40° を示せ.

# 過去問解答例
数学日和 様
＞tan10°=tan20°tan30°tan40° を示せ.

https://matsubushi.com/2020/09/28/%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%82%86%E3%81%88%E3%81%AE%E9%9B%A3%E3%81%97%E3%81%95-2013%E5%B9%B4-%E5%8D%83%E8%91%89%E5%A4%A7%E5%AD%A6/

https://www.google.com/search?q=%E6%95%B0%E5%AD%A6%E5%85%A5%E8%A9%A6%E5%95%8F%E9%A1%8C+%E5%8D%83%E8%91%89%E5%A4%A7+2013+tan&oq=%E6%95%B0%E5%AD%A6%E5%85%A5%E8%A9%A6%E5%95%8F%E9%A1%8C%E3%80%80%E5%8D%83%E8%91%89%E5%A4%A7%E3%80%802013+tan&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQABiiBDIHCAIQABiiBDIHCAMQABiiBDIKCAQQABiiBBiJBdIBCTQ5NzA0ajBqN6gCALACAA&client=ms-android-huawei&sourceid=chrome-mobile&ie=UTF-8

# 過去問内部検索　80 °　(不要な検索結果も含まれます。)
約 110 件（0.15 秒） 2023/11/01

https://cse.google.com/cse?cx=a8908fbc24340ebc5&q=80%20%C2%B0&oq=80%20%C2%B0&gs_l=partner-web.12..0i512j0i30i625j0i30l3j0i5i30l3.2718.19598.0.24139.16.16.0.0.0.0.128.1677.6j10.16.0.csems%2Cnrl%3D10...0....1j4.34.partner-web..0.16.1676.wU4dlgVlZ2I

# 過去問内部検索　10 °　(不要な検索結果も含まれます。)
約 1,290 件（0.19 秒） 2023/11/01

https://cse.google.com/cse?cx=a8908fbc24340ebc5&q=10%20%C2%B0&oq=10%20%C2%B0&gs_l=partner-web.12..0i512j0i30j0i30i625l2j0i30j0i30i625j0i30l2j0i30i625l2.2348.7820.0.10642.3.3.0.0.0.0.133.335.0j3.3.0.csems%2Cnrl%3D10...0....1.34.partner-web..0.3.335.qGK20XoIfs0

# wikipedia 正接(英:tan)
・下の方です。
・証明の情報を、お待ちしております。

＞ **Identities_without_variables**
＞...
＞Similarly,
＞tan50°・tan60°・tan70°=tan80°
＞tan40°・tan30°・tan20°=tan10°

https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Identities_without_variables

＞**特定の角度に関する式**
＞上の式を利用して以下の式が得られる。
＞tan50°+tan60°+tan70°=tan50°・tan 60°・tan70°=tan 80°

https://ja.wikipedia.org/wiki/三角関数の公式の一覧#特定の角度に関する式   

＞**応用例**
＞x=10°を入力すると、tan30°=tan10°・tan70°・tan0°から
＞tan50°・tan 60°・tan70°=tan 80°　が成り立つのが分かる。

https://ja.wikipedia.org/wiki/三角関数の公式の一覧#応用例
Kaggleの最新LLMコンペ「LLM - Detect AI Generated Text」

昨日、Kaggleで「LLM - Detect AI Generated Text」というコンペが開始されました。
![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/e5293d1b-53d1-cf43-92e4-0124b37ecf0b.png)


タイトルの通りに、提供された文章が学生によって書かれたものなのか、それともAIによって生成されたものなのかを判別するコンペです。（outputとしては、文章が生成された可能性は何パーセントなのかという感じです。）
 
テーマは全部で7つありますが、学習データには2つのテーマからのデータ（約1300件）しか入ってないので、
残りの5つのテーマに関するデータセットは自分で作る必要があります。
 
私が考えたやり方としてはまずlangchainのoutputparserとGPT4を繋がってデータセット作って、
それで文章をAIか学生か分類するモデルをfinetuningしたいと思います。
（最近langchainでLLMを段階的に思考させる手法を学びましたので、このコンペでは活用できると考えています。）
 
ちなみに、このコンペでは多分RAGはあまり重要ではないと思います。精度の差はfinetuningとpromptによって生じると考えられますね。まだ始まったばかりなので、もう少し様子見て、締め切りの1ヶ月前から参加してみたいと思います。
Unity Netcode: クライアント側でだけ位置がガガガと震える問題

あるキャラクターの位置を同期する際に、サーバでは正常に位置が更新され、クライアント側では位置がガガガガっとシェイクするような見た目が起こるバグがあった。

割と複雑な構造なプロジェクトだったので気が付かなかったが、**IsServerを入れれていなかったことが原因だった。** 

実際に起こったことをシンプルに書くと以下のような感じだった。


修正前

```
protected override void HandleCharacterEnter(BaseNetworkCreature character)
{
    obj.GetComponent<NetworkObject>().Spawn();
}
```

修正後

```
protected override void HandleCharacterEnter(BaseNetworkCreature character)
{
    if (IsServer) {
        obj.GetComponent<NetworkObject>().Spawn();
    }
}
```
バリデーションエラー時のrenderメソッドとredirectメソッドの違い

## バリデーションエラー時のrenderメソッドとredirectメソッドの違い

Ruby on Railsのコントローラーで、バリデーションエラーが発生した場合、`render`メソッドと`redirect`メソッドの違いは重要です。この記事では、これらのメソッドの違いと、それぞれの利用ケースについて説明します。

### `render`メソッドの利点

#### 1. バリデーションエラーの詳細を表示

`render`メソッドを使用すると、バリデーションエラーが発生したときに、詳細なエラーメッセージをビューに表示できます。これはユーザーにエラーの具体的な内容を伝え、修正の手助けをします。

#### 2. フォームの再表示

`render`メソッドを使用すると、フォームの入力内容を保持したまま、エラーメッセージとともに再度同じページを表示できます。ユーザーはエラーを修正しやすく、データの再入力が不要です。

#### 3. コントローラーアクションが再実行されない

`render`メソッドを使用すると、コントローラーアクションが再実行されず、バリデーションエラーが発生したページが表示されます。これにより、不必要なデータベースクエリの再実行を防ぐことができます。

### `redirect`メソッドの利点

#### 1. リダイレクトによるパターン

`redirect`メソッドは、バリデーションエラーが発生した場合に、新しいURLにリダイレクトすることができます。このパターンは、フォームの再送信を防ぎ、ユーザーがページをリロードした際にブラウザからの再送信の確認ダイアログを回避できます。

#### 2. フラッシュメッセージ

`redirect`メソッドを使用する場合、通常は`flash`ハッシュを使ってフラッシュメッセージを設定します。これにより、バリデーションエラーが発生した際にエラーメッセージを表示し、ユーザーに通知できます。例えば、登録フォームの送信後に「登録に成功しました」と表示できます。

### どちらを選ぶべきか

選択肢は具体的なユースケースに依存します。一般的なガイドラインは以下です：

- バリデーションエラーの詳細情報やフォームの再表示が必要な場合、`render`メソッドを使用します。
- バリデーションエラーを通知するためにフラッシュメッセージが必要な場合、`redirect`メソッドを使用します。

例えば、ユーザーの登録フォームでバリデーションエラーが発生した場合、フォームの再表示とエラーメッセージの表示に`render`メソッドを使用し、成功時には`redirect`メソッドとフラッシュメッセージを使うことがあります。適切な方法を選択することで、ユーザーエクスペリエンスを向上させ、アプリケーションの品質を維持できます。
JavaScritで関数型プログラミング

# 初めに

最近の学習はfreeCodeCampで基礎を見直しています。そこで普段何気なく使用している関数（function, アロー関数）について1つの関数に複数の役割を持たせていることに気付いたので、関数の役割を1つの定めるようにしました。

今回のプログラムを説明すると、

「昨日お酒を何杯呑みましたか？」の質問に対して入力したお酒の杯数分「🍺」が描画されるプログラムです。

# ソースコード

### 修正前

```javascript

// ビールの個数を受け取って、ビールの配列を返す
function getBeers(numOfCups) {
    const beers = [];

    for (let cups = 1; cups <= numOfCups; cups +=1) {
        beers.push(prepareBeer());
    }
    //HTMLに描画
    beers.map((beer) => {
        let div = document.createElement('div');
        div.textContent = beer;
        beerBox.appendChild(div);
    })
};

```

ビールを取得するgetBeers関数でHTMLの描画まで行っています。このように1つの関数に複数の役割を持たせると結局は1つの大きな関数となって、関数型の優位性が失われてしまいます。

### リファクタリング

```javascript

// ビールの個数を受け取って、ビールの配列を返す
function getBeers(numOfCups) {
    const beers = [];

    for (let cups = 1; cups <= numOfCups; cups +=1) {
        beers.push(prepareBeer());
    }
    return beers;
};

// ビールの配列をHTMLに描画する
function renderBeers(beers) {
    beerBox.textContent = beers.join("");
}
```

ソースコードの一部を切り取っての説明で申し訳ございません。

getBeers()関数は純粋にビールの配列を返すだけ。関数の役割が1つに定まる。renderBeers()関数でHTMLに描画する。このようにHTML関連部分を切り分けています。


# 終わりに

関数型で1つの関数に役割を持たせることで誰が見ても読みやすいプログラムを書けることを学べました。
AWS Configを使用した「require-tag」ポリシーの組織全体適用手順

# AWS Configを使用した「require-tag」ポリシーの組織全体適用手順

## 前提
- AWS Control Towerを使用し、組織全体を管理していること。
- 自動的に生成されるAWS Configリソースに関する情報は、[このリンク](https://qiita.com/tonkatsu_oishi/items/82811c94ebdc6fe509f2) を参照してください。
- 初期設定されていないルールを追加する場合は、[このガイド](https://fu3ak1.hatenablog.com/entry/2021/01/05/110810) を参照してください。

## AWS Configサービスの委任について
AWS Configを組織全体で一括管理するために、以下の手順を実行します。詳細は[こちら](https://fu3ak1.hatenablog.com/entry/2021/01/05/110810) を参照してください。
1. Organizationsの「信頼されたアクセス」を有効化します。
2. メンバーアカウントにAWS Configを委任します。

## Slack通知について
- Control Towerが有効な場合、自動的に生成されたSNSトピックにChatbotを設定することで、Slack通知が送信されるようになります。
- デフォルトの通知設定ではリソースが作成されるたびに通知が送信されています。`require-tag`ポリシーのみ通知させるために、自動的に生成されたEventBridgeのルールを編集します。Control Towerで作成されたルールはSCPで変更できないため、作業前後で一時的にSCPをデタッチする必要があります。

EventBridgeの変更内容は以下のとおり。
```json
変更前
{
  "source": ["aws.config"],
  "detail-type": ["Config Rules Compliance Change"]
}
変更後
{
  "source": ["aws.config"],
  "detail-type": ["Config Rules Compliance Change"],
  "detail": {
    "messageType": ["ComplianceChangeNotification"],
    "configRuleName": ["require-tag"],
    "newEvaluationResult": {
      "complianceType": ["NON_COMPLIANT"]
    }
  }
}
```

## `require-tag`ポリシーの作成について

`require-tag`ポリシーを作成する手順に関して、[このブログの手順](https://fu3ak1.hatenablog.com/entry/2021/01/05/110810) を参考に、CLIコマンドを使用して以下のコマンドを実行します。

### 適用コマンド:

```bash
$ aws configservice put-organization-config-rule \
--organization-config-rule-name org-required-tags \
--organization-managed-rule-metadata '{
  "Description": "指定したタグがリソースに存在するかチェックします。",
  "RuleIdentifier": "REQUIRED_TAGS",
  "InputParameters": "{\"tag1Key\":\"CostCenter\"}",
  "ResourceTypesScope": ["AWS::ACM::Certificate", "AWS::AutoScaling::AutoScalingGroup", "AWS::CloudFormation::Stack", "AWS::CodeBuild::Project", "AWS::DynamoDB::Table", "AWS::EC2::CustomerGateway", "AWS::EC2::Instance", "AWS::EC2::InternetGateway", "AWS::EC2::NetworkAcl", "AWS::EC2::RouteTable", "AWS::EC2::SecurityGroup", "AWS::EC2::Subnet", "AWS::EC2::Volume", "AWS::EC2::VPC", "AWS::EC2::VPNConnection", "AWS::EC2::VPNGateway", "AWS::ElasticLoadBalancing::LoadBalancer", "AWS::ElasticLoadBalancingV2::LoadBalancer", "AWS::RDS::DBInstance", "AWS::RDS::DBSecurityGroup", "AWS::RDS::DBSnapshot", "AWS::RDS::DBSubnetGroup", "AWS::RDS::EventSubscription", "AWS::Redshift::Cluster", "AWS::Redshift::ClusterParameterGroup", "AWS::Redshift::ClusterSecurityGroup", "AWS::Redshift::ClusterSnapshot", "AWS::Redshift::ClusterSubnetGroup", "AWS::S3::Bucket"]
}'
```
上記のコマンドは、require-tagポリシーを作成する手順を示しています。このポリシーは指定したタグがAWSリソースに存在するかをチェックします。ポリシーの詳細や適用対象のリソースタイプに関する情報が提供されています。上記のコマンドを実行することで、require-tagポリシーがAWS Configで組織全体に適用されます。

### 確認コマンド:

```
$ aws configservice describe-organization-config-rules
```
上記の確認コマンドを使用すると、require-tagポリシーが正常に設定され、組織内で適用されていることを確認できます。このコマンドを実行することで、ポリシーの適用状況を確認できます。
【Pyinstaller】誤検知を回避する

本当に自分用のメモでゴメンナサイ…

https://qiita.com/tru-y/items/cb3cebe9612d367dccb2

の手順で実施すると次のコマンドでエラーが起きた。

`python ./waf distclean all`

```bash
Checking for 'msvc' (C compiler)         : not found
Checking for 'gcc' (C compiler)          : not found
Checking for 'clang' (C compiler)        : not found
could not configure a C compiler!
```

なので、下のサイトに従いchocoをインストールする。

https://gamingpc.one/dev/python-pyinstaller/

ただこれも次のコマンドで詰まる。

`choco install -y python vcbuildtools`

エラーが出てインストールにfailする。

なので、オフィシャルに従い次のコマンドを実行する。

`choco install -y python3 visualstudio2019-workload-vctools`

https://pyinstaller.org/en/latest/bootloader-building.html#build-using-visual-studio-c

これで`python ./waf distclean all`が通った。

後は↓に戻って従えばOK

https://qiita.com/tru-y/items/cb3cebe9612d367dccb2
Pythonで「数値を文字列に変換して文字列と連結する」の動作を確認してみた

# 概要

Pythonで「数値を文字列に変換して文字列と連結する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/string/index9.html

# 実装

以下のファイルを作成しました。
```sample.py
num = 18
print("My age is " + str(num))
num1 = 8
num2 = 6
print(str(num1) + "+" + str(num2) + "=" + str(num1 + num2))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
My age is 18
8+6=14
```

# まとめ

何かの役に立てばと。
RENDERからAWS S3への移行に伴うエラーについて２

## Mysql(MariaDB)で設定したdatabase接続用のパスワードと、EC2ターミナル上で設定したパスワードが異なっているとエラーが出る

mariaDBで設定したパスワードと一致していないといけないので、もし片方が違うかったら修正する。

では確認するためには、どうすればいいのか。
それは、
EC2ターミナル上で設定したパスワードの設定を確認するには以下のコマンドを実行する。

```bash
[ec2-user@ip-172-31-23-189 ~]$ sudo vim /etc/environment

```

そうすると設定が確認できるので、確認し修正する。
Databricksのワークスペースファイルを有効化・無効化する

こちらで触れたワークスペースファイル、便利な機能ですが、セキュリティ要件によってはオフにしたいというニーズもあるかと思います。

https://qiita.com/taka_yayoi/items/d61a77747ec7325d6526

こちらのドキュメントには`管理者が REST API を使用して無効にすることができます。`との記載があります。

https://docs.databricks.com/ja/files/workspace.html

しかし、具体的な方法が記載されておらず右往左往しました。

ヒントはこちらにありました。

https://docs.databricks.com/ja/repos/enable-disable-repos-with-api.html

こちらのノートブックを修正して実行することで、ワークスペースファイルを有効・無効にすることができます。ドキュメントチームにはフィードバックしておきます。

デフォルトではワークスペースファイルは有効化されているので、以下のように`py`ファイルなどを作成することができます。
![Screenshot 2023-11-01 at 16.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/006563ae-f91a-b336-1889-158f1e9e30e6.png)
![Screenshot 2023-11-01 at 16.07.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/db5ce3a0-d347-a858-323c-32092a9ef32a.png)

# ワークスペースファイルの無効化

databricks-sdkを使いますが、REST API呼び出しでもいけるはずです。

```py
%pip install databricks-sdk --upgrade
dbutils.library.restartPython()
```

APIクライアントを初期化します。

```py
from databricks.sdk.core import ApiClient

client = ApiClient()
```

キー`enableWorkspaceFilesystem`を指定して、現在の設定を確認します。

```py
client.do("GET", "/api/2.0/workspace-conf", {"keys": "enableWorkspaceFilesystem"})
```

有効化されています。
```json
{'enableWorkspaceFilesystem': 'true'}
```

無効化します。

```py
client.do("PATCH", "/api/2.0/workspace-conf", body={"enableWorkspaceFilesystem": "false"}, headers={"Content-Type": "application/json"})
```

```json
{}
```

設定を反映させるために、ブラウザをリロードします。

メニューから**ファイル**が表示されなくなります。
![Screenshot 2023-11-01 at 16.11.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f4109742-8dbb-c0b9-391b-a7d0ec6b9c6c.png)

# ワークスペースファイルの有効化

再度有効化する際には、キー`enableWorkspaceFilesystem`を`true`に設定します。

```py
client.do("PATCH", "/api/2.0/workspace-conf", body={"enableWorkspaceFilesystem": "true"}, headers={"Content-Type": "application/json"})
```

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
FireBaseの認証機能を利用してサーバーサイドでユーザー操作をする

# FireBaseの認証機能を利用してサーバーサイドでユーザー操作をする

FireBaseでの認証を行い、登録されているユーザーに対して操作を行う時のFireBaseのモジュールの使用方法です。今回は使用した言語がPythonのため、Pythonでの書き方を中心に行います。

firebaseの認証機能を導入済みの方が対象です。

### FireBaseの認証機能とは


Firebaseはクラウドベースのプラットフォームであり、ユーザーの認証やデータベースの管理など、さまざまな機能を提供しています。サーバーサイドでユーザー操作を行うためには、まずFirebaseの認証機能を設定する必要があります。

Firebaseの認証機能を使用することで、ユーザーを登録し、ログイン、ログアウトなどの操作を簡単に行うことができます。また、Firebaseのデータベースを使用することで、ユーザーの情報を保存し、必要なデータを取得することもできます。

Firebaseの認証機能を利用してサーバーサイドでユーザー操作を行うことで、安全かつ効率的なユーザー管理が可能となります。

### FireBaseに用意されているモジュール

`firebase_admin`

https://firebase.google.com/docs/reference/admin/python/firebase_admin.auth

### 主な使用方法

認証機能を使用してGoogleアカウントでの認証を行なったり、登録されたユーザーの確認、操作を行うことができます。

Firebaseの認証機能を利用すると、サーバーサイドでユーザー操作を行うことができます。

ユーザーの操作を行うにはUIDを使用した操作が求められます。

UIDを取得し、そのUIDを使用して該当ユーザーに対して操作を行います。

まず`firebase_admin` モジュールをimportして、`firebase_admin.initialize_app()` でSDKを初期化してから使用します。

この時に複数回SDKの初期化を行おうとすると、エラーを吐くので注意してください

**[Firebase Admin の二重初期化エラーの対策（modular版）](https://zenn.dev/mktu/articles/55b3bfee839cfc)Zenn**

### firebaseに登録されているユーザー情報に対して操作を行う

firebaseのユーザーを特定するためにDBに対して一意のデータを取得する。

firebaseのユーザー検索で使用できるのは、電話番号(phoneNumber)、メールアドレス(email)、uidになります。firebaseのuidをDBに保存していない限り、phoneNumberかemailの二択になるかと思いますので、ここではemailを取得する方法で行います。

ちなみに、ユーザーに対しての操作でemailを使用することはできません。

例としてここではユーザーのemailを取得します

**通常通りuserテーブルからemailを取得します**

```python
def get_user_email(user_id : int):
	user_email = db.query(User.email).filter(User.id == user_id).one()
```

**取得したemailを使用して、firebaseに対してユーザー検索を行います。**

```python
from firebase_admin import auth

def get_user_by_email(user_email: string)
user = firebase_admin.auth.get_user_by_email(user_email)
```

この時、受け取る値としては

```python
{
	uid: 該当ユーザーのuid,
	display_name: 該当ユーザーの氏名,
	email: 該当ユーザーのemail
}
```

が取得することができます

`firebase_admin.auth.get_user_by_email()` を使用して得た`uid`を使用してfirebaseのユーザー情報に対して操作を行います

**使用例として削除処理を行います。**

`firebase_admin.auth.delete_user(uid)`　`uid`の部分に引数として上記で取得した`uid`

を渡してメソッドを実行します

そうするとfirebaseコンソールでユーザーの削除が行えているかと思います。

削除したくない方は`firebase_admin.auth.update_user(uid)` で更新処理を試してみてください。

以上、firebaseでのユーザー操作でした。
アジャイルとは

こんにちは。株式会社ネオシステムの高橋です。
今回はアジャイルについてまとめたいと思います。

以下の記事も作成しているので併せて読んでみてください。
- [キャンバスアプリvsモデル駆動アプリ -こんな時どっちを使う?-](https://qiita.com/szn-t/items/534c22bd70e63ae18efd)
- [業務フロー図を作成する](https://qiita.com/szn-t/items/22e5e223fe56bf7e0c48)
- [業務の最適化](https://qiita.com/szn-t/items/6e1db534c0a848605ede)
- [ユースケース図を作る](https://qiita.com/szn-t/items/66308396377aa7ae5245)
- [ER図の作り方まとめ](https://qiita.com/szn-t/items/e05e9e59af3471a724a4)
- [WBSを作る前に知っておきたいこと](https://qiita.com/szn-t/items/3b6e46560c482b62d620)
- [システム開発チームのメンバー役割](https://qiita.com/szn-t/items/888a51da7f097a40d9d4)
- [ウォーターフォール開発における要件定義の進め方(PMの場合)](https://qiita.com/szn-t/items/c51e64adde93c546b35c)
- [ビジネス要求定義における問題と解決-ビジネス要求の獲得-](https://qiita.com/szn-t/items/77b1cdafc46e3b658671)
- [ビジネス要求定義における問題と解決-ビジネス要求の分析-](https://qiita.com/szn-t/items/1d42127c60e1780528f8)

# 目次
- アジャイルとは
- ウォーターフォールとの比較
- アジャイルを実現するために
- アジャイルの活用例

# アジャイルとは
- アジャイルソフトウェア開発の略称
- アイディアや現場の課題解決を実現化するアプリケーションを、**スピーディー**に開発する軽量な開発手法群の総称
- PDCAサイクル(Plan-Do-Check-Act)のように、「要求分析」、「設計」、「開発」、「テスト」の**サイクルを短い期間で繰り返し**、トライアンドエラーで改良していく手法


# ウォーターフォールとの比較
## ウォーターフォールの欠点

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599668/b69649d9-b3e9-b4ad-9827-77d836cf847f.png)

- アプリユーザが実際にアプリを見るまで時間がかかる
- 当初の要件と成果物にギャップが生じやすい
- 手戻りが発生した場合、さらに期間が延びる


## アジャイルの利点

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599668/07acc2ef-dc74-32c1-0778-e3bdc24da38d.png)
      
- アプリユーザーが実際にアプリを見るまでの期間を短縮できる
- ユーザの要望とアプリとの間にギャップが生じるリスクを軽減できる
- 新たな要件が発生した場合には、新しい機能を次のバージョンに追加できる

# アジャイルを実現するために
アジャイルで開発を進めるには、やらなければならないことがいくつかあります。

## バックログでTODOを管理する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599668/e693b91c-dbc2-21ba-8251-5a98dbeb2444.png)

- スプリント(１回のサイクル)でどのような作業をするかを管理する必要がある
- TODOチケットを管理するツールや資料はバックログと呼ばれている
- バックログに記載されているTODOチケットの単位で進捗を計る

【参考】[作業項目を表示および追加する](https://learn.microsoft.com/ja-jp/azure/devops/boards/work-items/view-add-work-items?view=azure-devops&tabs=browser)

## ふりかえりを実施してスプリントの質を高める

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599668/7c3e4581-6196-e610-6642-ed41e7b6d7a5.png)

- 1回のスプリントが完了した時点で、チーム内で振り返りを実施する
- KPT(Keep, Problem, Try)などのふりかえりテンプレートを用いる
- メンバー同士で結果を共有することで、次のスプリントを改善していく

# アジャイルの活用例
アジャイルで開発を進めたいがウォーターフォールから脱却できない事例を紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599668/508c70bd-4250-919d-2e4f-3f0965b23fe0.png)

この事例ではフェーズをプロトタイプ開発と本開発に分け、プロトタイプフェーズでアジャイルを導入しました。
その結果、従来よりも要求分析をスピーディに進めることができ、本番運用の納品物とのギャップも軽減できました。

# まとめ
今回はアジャイルの概念とポイントについてまとめました。
冒頭では「アジャイルはスピーディに開発する」と記載しましたが、ローコード・ノーコード開発ツールを導入することでアジャイルの効果をさらに引き出せます。
Microsoftが提供している[PowerApps](https://learn.microsoft.com/ja-jp/power-apps/powerapps-overview)がその例です。
[こちらの記事](https://qiita.com/szn-t/items/534c22bd70e63ae18efd)ではPowerAppsについてまとめているので、併せて参考にしてみてください。
slim で `-` と `=` を間違えて書いていた

自分が悪いんですが，記録に残してもいいかなと思ったので一応

## slim を書いていた

何故か slim を書くことになっていた．
それは，もうしょうがない．

```slim
= if xxx
  javascript:
    console.log('hello');
```

```slim
= render 'something.html.slim'
```

まあ，なんかpartial に if 文書いて，何かする．みたいな．

## なんか，おかしい

なんか2回実行されてない？

はいそうです．`=` だからですね．
あまり書かないから，間違えてました．

```slim
- if xxx
  javascript:
    console.log('hello');
```

久し振りに書くものこそ，丁寧に書かないとですね．
Gitにsshで接続する

## 背景
GithubにSSH接続しようとする度にやり方を忘れて調べているので備忘として記載しています

## 手順
### 前提
1. Githubアカウントが作成されている（作成されていな場合は https://github.com/ から作成する）
2. githubでリモートリポジトリが作成されている（既存のプロジェクトを追加する方法はそのうち書く...多分...）

### 秘密鍵・公開鍵を作成する
以下のコマンドで秘密鍵と公開鍵を作成する
``` bash
ssh-keygen -t rsa
```
以下の2つのファイルが~/.ssh/に作成される
id_rsa: 秘密鍵
id_rsa.pub: 公開鍵
※ファイル名を指定したい場合は`-f <秘密鍵のPATH>`をオプションで追加する

### 公開鍵の確認
以下のコマンドで公開鍵の中身を確認し、表示された文字列をコピーしておく（Githubの登録で利用する）
```bash
cat ~/.ｓｓｈ/id_rsa.pub
```

### 作成した公開鍵をGithubに登録する
1. Githubの画面で右上の自分のアイコンをクリック
2. 下の方にあるSettingsを選択
3. 左メニューの真ん中らへんにある「SSH and GPG Keys」を選択する
4. SSH Keysという項目で「New SSH Key」というボタンがあるので押下
5. TitleとKeyを入力する
    * Title: 表示名（どんなSSH Keyかわかるように任意の値を入れる）
    * Key: 公開鍵を記載する（先ほどコピーしておいた公開鍵を貼り付ける）
![スクリーンショット 2023-11-01 15.19.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580771/22fabf58-8bed-0163-6877-ddd1ace19b21.png)
6. 「Add SSH Key」を押下する
PowerAutomateの編集画面が新しくなったので使ってみる

2023/11/10 追記
使用できない場合があることについて追記しました。

## この記事で伝えたいこと
:::note info
今までのに比べてめっちゃ軽いし新しい編集画面最高！！
:::
:::note warn
なんかでも、偶にバグってうまく動かない？
:::

## 概要
PowerAutomateの編集画面が新しくなったので、早速ちょっといじってみました。
正確には新しくなったというより、新しい編集画面が使えるようになりました。
自分で選ぶような形ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/3834abaf-6bc5-dab3-78f4-cf5cac903877.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/776838f1-483b-8af6-7163-c681dd9d0c90.png)

全体を通してスッキリと、見やすくなったイメージでしょうか。
また動作もかなり軽くなりました。

## 使用感とか
意味もなくネストさせてもサクサクです。
ひと目見ただけでどこにどう分岐しているのかわかりやすいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/7d18b3c5-2bdd-9933-e7eb-bbb6c3d4a40d.png)

条件などの入力画面は今までのに慣れていた人は少し違和感がありますが
そもそも別窓で出てきてくれるのでだいぶ見やすい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/c68f93a4-e044-9b34-3ab7-ec8a32d228e2.png)

変数などを入力する場合は今までと同じ感じで使えますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/adee1e97-1ffa-bcc7-3661-5a07b67afeb9.png)

スイッチアクションを使った時に異様に横に長くなって何も見えなくて、
スクロールバーをいちいち触って・・・なんてことも有りません。

環境によるとは思いますが、筆者環境では13個まで横に伸ばせました。
また、はみ出した分に関しては、スクロールバー触るのではなくドラッグで動かせるようになりスムーズに・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/e53951bf-c78a-99a7-b2e5-278235547797.png)

もちろん拡大縮小もお手の物。
画面左下の＋－ボタンで調整するのもいいですが・・・
Ctrl+マウスホイールで自由自在に(上限はあるけど。)ズームイン、ズームアウトできちゃいます。
Fit viewというボタンが＋－ボタンの1個下にありこれを押すと一撃で全体像が見えるようなサイズに調節してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/38d27f8d-f093-6fb4-d3ec-a8a1b9a80b58.png)

また、更にそのひとつ下のボタンに虫眼鏡のボタンがあります。
これがまた便利で操作に移動、とある通り今までいちいち探してそこに自分で移動していたものを
ボタン一つでそこまで自動で移動してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/b5a187dd-1cc6-c2dc-4ac7-f235f6c7ee81.png)

## デメリット
致命的なのがたまに**バグる**
まだプレビュー版的な立ち位置なんでしょうかね？
条件がわからないけど、アクションの検索がまともに**機能しなくなる**ことがある
例えば・・・検索窓にメチャクチャなワードを入れてもガン無視されることがあったり、アクションが何も出てこなかったり・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/942170c9-88a7-5a56-dc21-327913cd5bd9.png)

2023/11/10 追記
どうやらアクション数が多いと利用できないようです。
これから先も使えないんですかね？
ちょっと前は使えてたので、今だけ、とかだといいんですが・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/bc352a76-c7a2-ee2f-8852-9fa21828bb3e.png)


## 終わりに
これから基本的にはこの編集画面になるんでしょうかね？
動作も軽くなりましたし、画面の見やすさも段違いです。
不具合が治れば、間違いなくおすすめですね。

ちなみに筆者環境では執筆時点で初めてこの前述した不具合に遭遇しました。
前回2,3日使ったときは問題なかった(別の人は同じ不具合に遭遇していた・・・がいつの間にか治っていた)のであまり遭遇率は高くないと思います。
Railsのcreateアクションにおけるsubmitボタンのデフォルト名

# Railsの`create`アクションにおける`submit`ボタンのデフォルト名

Railsにおいて、フォームを使ってデータの新規作成を行う際、通常は`create`アクションが利用されます。このアクションでは、新しいデータベースレコードを作成するため、ユーザーにデータの入力を促すフォームが表示されます。その際、`submit`ボタンは非常に重要な要素で、ユーザーがデータを送信するためのトリガーとなります。

Railsにおいて、`submit`ボタンのデフォルトの名称は「Create + モデル名」の形式で決定されます。これはRailsのコーディング慣習に基づいた自動的な命名ルールです。例えば、`Post`モデルを新規作成するフォームにおいて、`submit`ボタンのデフォルト名は「Create Post」になります。同様に、他のモデルに対しても「Create モデル名」といった形式でボタン名が生成されます。

このデフォルトのボタン名の決定にはいくつかの利点があります：

1. **一貫性**: Railsの慣習に従った命名を使用することで、開発者間のコードの一貫性が保たれます。これはメンテナンスや協力が行いやすく、コードベースが読みやすくなります。

2. **簡潔さ**: デフォルトのボタン名は通常の使用において十分で、追加のカスタマイズを必要としないことが多いです。そのため、簡潔なコーディングが実現されます。

3. **適切な意味**: ユーザーがボタンを見たときに、何が行われるのかが明示的に表現されます。例えば、「Create Post」は新しい投稿が作成されることを示唆します。

もしデフォルトのボタン名が望ましいものであれば、そのまま使用することができます。ただし、必要に応じてボタン名をカスタマイズすることもできます。Railsでは、`f.submit`メソッドを使い、`value`パラメータを指定することで、ボタン名をカスタマイズできます。以下は例です：

```ruby
<%= f.submit '新しい投稿を作成' %>  # ボタン名をカスタマイズ
```

このように、デフォルトの挙動と一貫性を保ちつつ、必要に応じてボタン名を個別に調整できます。 Railsのデフォルトの`submit`ボタン名の自動生成は、コーディングの簡便さと一貫性を提供する一方で、カスタマイズも容易に行える柔軟性を持っています。
MagicPodで自動化率を爆上げしたハナシ

こんにちは、QAエンジニアの田井です。
こちらの記事は2022年8月26日に公開したものです。

10年ぐらい前に購入したテレビが壊れてしまったので買い替えたのですが、機能が多すぎてまだ慣れません。。
映像もとても綺麗で、技術の進化を日々感じています。

## はじめに
### 回帰テストの現状
ノハナにはAndroid、iOS、決済(サーバー)の3つの回帰テストがあり、リリースのたびにAndroid、iOSの回帰テストを実施しています。
決済(サーバー)は修正が入ったときに、影響範囲を考慮し必要に応じて回帰テストを実施しています。
元々は全て手動でテストをしていたのですが、数年前からMagicPodを使い自動化を進めています。

### 自動化率(2022年5月時点)
Androidは2021年ごろから約1年半をかけて自動化率を約69%まで伸ばしました。Androidのケースでは、自動化前は8時間以上かかっていた回帰テストの工数が3時間弱となり、**5時間以上の工数を削減**することができました。また、自動テストを早朝にステージング環境で定期実行して問題がないことを確認しており、エラーがあれば都度対応しています。
ただ、決済に関しては半年ぐらい前までは未着手の状態でした。理由としては、回帰テスト自体の実施頻度が低く優先度が低かったからです。
iOSの自動化率も昨年末では20%ぐらいでしたが、シナリオの見直しをしたため、自動化率が低い状態が続いていました。

### 目標の自動化率
そこで、全体の自動化率を上げることを目標に、決済とiOSの自動化に着手することにしました。
決済の回帰テストのシナリオは30ぐらいあるので、3ヶ月(四半期)で50%を自動化することを目標としました。
iOSについても、70%の自動化を目標に進めました。

自動化についての過去の記事は**[こちら](https://blog.nohana.co.jp/article/test-automation2019)**をご覧ください。

## テスト自動化作業
決済の場合、注文内容や支払い方法などは異なるけど、操作自体は同じケースが多いので、**共有ステップ** を多用しました。以下の表は組み合わせのサンプルです(実際の組み合わせではありません)。このケースだと5シナリオあるので、それぞれで個別にテストコードを作成するとそれだけでも大変ですが、仕様変更時などのたびに5つのシナリオを修正する必要が出てきます。
このような時も、共有ステップだと1つのテストコードを修正するだけで対応できるので、大きなメリットだと思います。

<img src="https://blog.nohana.co.jp/wp-content/uploads/2022/08/スクリーンショット-2022-08-25-18.31.17.png" alt="" width="443" height="147" class="alignnone size-full wp-image-2008" />

画面ごとに共有ステップとして登録し、データパターンを各シナリオごとに設定し、共有ステップを組み合わせてテストコードを作成しています。
以下は実際のシナリオではないですが、このように注文フローを共有ステップとして管理しています。

<img src="https://blog.nohana.co.jp/wp-content/uploads/2022/08/スクリーンショット-2022-08-25-18.18.26.png" alt="" width="786" height="276" class="alignnone size-full wp-image-2000" />

共有ステップ内ではデータパターンの値をもとに条件分岐を入れています。
最初に共有ステップを作る時間はかかりましたが、結果として異なる条件でもデータパターンを変えるだけで良くなり、新規シナリオを作成するときも、テストコード自体の変更はほぼ必要なくなりました。

## 現段階での状況
このブログを書いている時点での状況は以下のようになっています(Sprint#18)。
Androidは変わりありませんが、決済とiOSの自動化が進んでいることがわかると思います。

<img src="https://blog.nohana.co.jp/wp-content/uploads/2022/08/自動化率.png" alt="" width="1092" height="642" class="alignnone size-full wp-image-1997" />

全体では41%弱ぐらいまで自動化できましたが、まだまだ先があります。
一部自動化が難しいところもあるので、目標としては全体の80%ぐらいを自動化できればと考えています。

## 今後の予定
グラフの点線以降が次の四半期の自動化率の見込みです。
全体では75%を自動化し、決済については90%を自動化することを目標にしています。
決済については共有ステップを使いシナリオを作成できるため、自動化率の見込みがかなり高くなっています。

## 改善してほしいところ
MagicPodはほぼプログラミングの知識がなくても自動化が可能な強力なツールなのですが、いくつか改善してほしいところもあります。
まず、iOSは要素が見つからないケースや、エラーになるケースが多いです。
修正対象外の箇所で前回は問題なかったのに失敗するケースなどが多く、テストコード作成後のシナリオの確認作業に想定以上の工数がかかっているのが現状です(グラフでもiOSの伸びが若干鈍いことがわかると思います)。
また、Androidのケースでは実機だと成功するけど、エミュレータだと失敗するなどのケースもあり、このような課題が解決すると、さらにスピードアップできるのかなと感じています。

## 最後に
最終的なゴールは、ステージングにデプロイされたタイミングで回帰テストのシナリオを回すことです。
これによりバグを早いタイミングで検知でき、手戻りも少なくなり、常に安定した品質をキープしていきたいと思います。
スクラム開発でアジャイルテスティングを実施し、リリースサイクルを早めたハナシ

こんにちは、QAエンジニアの田井です。
こちらの記事は2021年12月17日に公開済みの記事です！

QAチームでキャンプ場で日帰り合宿をしてから、キャンプに行きたくてウズウズしてます。
関東近郊でオススメのキャンプ場があれば教えてください！
後日、合宿の内容についてもブログに掲載しますので、お楽しみに！！

さて、ノハナではQAのプロセス改善を常に意識しており、様々な取り組みを行なっています。
今回は、今年の初めから取り組んでいるスクラム開発とQAチームが取り組むアジャイルテスティングについてお話したいと思います。

## スクラム開発導入前(オフショアでテストをしていたとき)
コストを削減する手段としてどうするかと考えたときに、よくあるケースだと思うのですが、ノハナでもオフショアでテストをしていました。ただ、オフショアでよくある課題で、英語だけしか話せないと翻訳作業が発生したりするため、日本語が話せるテストベンダーに作業を依頼することにしました。オフショアでのテストに関する記事は[こちら](https://blog.nohana.co.jp/article/visit-danang)にありますので、お時間があればご一読ください。
オフショアでのテストの大まかな流れとしては、テスト観点はノハナ側で作成し、テストケースはオフショアで作成していました。テストケースの確認内容は細かい観点まで確認しており、テストケース数も膨大な数になったため、コストは下がったものの、レビュー時間やテスト実行時間が増えることになりました。テスト実行はオフショアに任せて、ノハナ側では結果のレビューやバグの対応などを行なっていました。
日本語が話せるとはいえ言語の障壁もあり、細かいニュアンスが伝わりにくかったり、日本のメンバーよりも若干ではありますが生産性が低いなど課題がありました。
その上、事前にテスト実行の見積もり工数を出してもらい、その工数を元にリリーススケジュールを決めていたため、リリース日も不定期になっていました。その結果、テストの完了待ちが発生し、マーケチームやCSチームへの共有が漏れてしまったことや、その他の問題も多く発生していました。
また、社内でも細かい施策をできるだけ早く、定期的にリリースしたいという方針もあり、大幅な方針転換をしました。

<img src="https://blog.nohana.co.jp/wp-content/uploads/2021/12/今までのフローSprint導入前-1024x136.png" alt="" width="720" height="96" class="alignnone size-large wp-image-1914" />

## スクラム開発導入後(開発期間とテスト期間でスプリントをわけていたとき)
そこで、スピーディーにテストまで終わらせ、定期的にリリースするために導入したのがスクラム開発です。とはいえ、スクラム開発未経験のチームがいきなり1スプリントで開発とテストを終わらせるのは難しいということで、まずは開発スプリントとリリーススプリントと2つに分けることにしました。
開発スプリントは2週間で開発とプレテストを行い、リリーススプリントは1週間で本テストと回帰テスト、リリース作業までを行うことにしました。これによりリリースの曜日が一定の期間で固定され、以前のような問題も大幅に減りました。
プロダクトバックログ(以降PBI)で管理することで、開発が完了したPBIからプレテストを行うため、早い段階でブロッキングとなり得るバグを見つけられるようになり、開発の手戻りも減り、本テストも比較的スムーズに実施できるようになりました。
この体制を数ヶ月続けたのち、満を持して1スプリントで開発とテストを実施するフェーズへ移行しました。

<img src="https://blog.nohana.co.jp/wp-content/uploads/2021/12/今までのフローSprint導入後-1024x159.png" alt="" width="720" height="112" class="alignnone size-large wp-image-1913" />

## スクラム開発の現状
現在、ノハナではアプリを2週間に1回リリースをしています。2週間のスプリントでテストを完了させるために、探索的テストとテスト自動化を活用したアジャイルテスティングを実施していて、スクリプトテストは実施していません。
QAチームのスプリント内での流れとして、1週目は主にテスト観点の作成やテスト準備を行い、開発が終わったPBIごとに探索的テストを順次行なっていきます。PBI単位でテストするので、QAチームからのフィードバックも以前よりも早くなり、開発の手戻りも減りました。
開発の方も、開発凍結のデッドラインを設けているので、間に合わなければ次のスプリントへ持ち越すルールとし、ズルズルと開発が続いてしまうということもありません。
通常の探索的テストと少し異なる点としては、担当者により確認内容にブレ幅が出ることがあるので、大まかなテスト観点を書いています。この段階で仕様についての細かい確認も行うので、仕様の考慮漏れなども事前に見つけることができています。テスト観点のレビューも行うので、担当者により認識が大幅に異なっているというような問題は起きていません。
スプリントレビューをパスした後は、リリース用のアプリで回帰テストを行い、問題なければリリースとなります。回帰テスト自体も一部を自動化し、工数削減に寄与しています。
このフローを導入して数ヶ月経ちますが、機能の実装漏れがあったとか、インシデントが増えたとかネガティブなことはなく、リリースサイクルが早まったことにより、多くの施策をよりスピーディーにリリースできるようになりました。

<img src="https://blog.nohana.co.jp/wp-content/uploads/2021/12/最新のフローSprint導入後-1024x194.png" alt="" width="720" height="136" class="alignnone size-large wp-image-1911" />

## おわりに
個人的にはQAでどのやり方が正解というのはないと思っています。ただ、リリースサイクルが固定されることによるメリット、早く施策をリリースしてスピーディーにお客様に届けることができるという意味では、2週間のスプリントで開発からリリースまで完了させる進め方は大きなメリットがあると感じています。
JavascriptのIntersectionObserverについて

### はじめに
この投稿は解説などではなく、忘れないためのメモ的な感覚で投稿いたします。
見て頂く方々に関しましては、私の解釈が間違っていたりベストな情報ではない可能性が高いので、そのつもりで閲覧していただければと思います。
加えて、そのようなことがあればコメントしていただけると大変助かります。

# IntersectionObserverとは
HTMLの要素とウィンドウの交差を監視している。
使い方は、newで作成したIntersectionObserverのインスタンスにコールバック関数を渡してておく。それの.observeメソッドの引数に監視対象を入れることで、交差したときにコールバック関数が発火する。
後々のためにインスタンスはconstで定義する。

```js
//監視したいDOMを定義
const dom = docment.querySelector('監視したいDOM');

//newでインスタンスを作ってio(変数名は何でもいいが略語のioにしておく)として定義する
const io = new IntersectionObserver(cb);

//コールバックで実行したい関数を定義する
const cb = function (){
例)alert("内");
};

//定義したDOMを.observeメソッドの引数いれる
io.observe(dom);
```
### 監視対象が複数の場合
コールバック関数には**entries**と**observe**の2つオブジェクトを引数にとることができる。
下のように監視対象が増えた場合、**forEach**でそれぞれを監視することができる。
一度監視に入ったあとは監視をしないようにしたい場合はovserveのunobsereveにentry.targrtを入れる。ここでとってくるentry.targrtはdomだったりdom1だったりの各監視対象のこと。

```js
const cb = function(entries,observe){
    entries.forEach(e =>{
        if(entries.isIntersectiong){
            console.log("内");
            //observe.unobserve(e.target);
        } else{
            console.log("外");
        }
});

io.observe(dom);
io.observe(dom1);
io.observe(dom2);
```
### オプション


```js
const options = {
//交差対象にしたい要素を設定できる（親要素だったり先祖要素）
//実際はあまり変更しないとか、、、
    root:null;

//交差点を調整できる-の値で交差点を画面の内側に広げることができる。値必ずpxで
    rootMargin: -300px 0px 0px -300px;
//デフォルト値は0、0～1の値をとり、入る側を0、出る側を1として、監視対象の交差点を調節できる。
//[0, .5, 1]とすることで、三か所で発火させることができる
    threshold: .5;
}
```
Android Studio: ViewBinding の使い方

## プロジェクトの作成
プロジェクト名: binding01

## 環境

```app/build.gradle.kts
（省略）
android {
（省略）
buildFeatures{
    viewBinding = true
    }
    （省略）
```

## 画面

```xml:layer/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="409dp"
        android:layout_height="729dp"
        android:orientation="vertical"
        tools:layout_editor_absoluteX="1dp"
        tools:layout_editor_absoluteY="1dp">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView"
        android:textSize="50sp" />

        <EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="text"
            android:text=""
        android:textSize="50sp" />

        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button"
android:textSize="50sp" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
```

## プログラム

```MainActivity.kt
package com.example.binding01

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.example.binding01.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.textView.text = "こんにちは"

        binding.button.setOnClickListener(this)

    }

    override fun onClick(v: View) {
        val text_in = binding.editText.text
    binding.textView.text = "Hello " + text_in
    }
}
```

## 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/07bf0acb-c242-0e6f-5890-5c5ff329d8c5.png)

Tom と入力して、ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6e280c2e-d7ef-8764-7ca4-329ef408013f.png)
AIが書籍をピックアップしてくれるセレクション機能を作りました

初めまして。ガマリと申します。

https://yommy-books.com/

Yommyと呼ばれる書籍アプリを作っています。

https://qiita.com/Gamari0009/items/a132cd75c9dc1f647986

――今回はYommyの新機能である「AIセレクション」という機能を作ったので、その機能に関しての紹介と、簡単に仕組みを説明させていただきます。

気になる方は是非！

## AIセレクション機能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/4a7a3ad9-3640-531e-77b7-c5921bbb370f.png)

YommyではAIセレクション機能を実装いたしました。
上記の画像は、AIが選定した3つの書籍が格納されたセレクションページになります。
実際のページはこちらになります。

https://yommy-books.com/selection/32be8163-b905-4712-9c84-984e461a36c1/

AIセレクション機能は「AI属性を持ったユーザー」が、自動的に本をセレクトしてくれるという機能になります。
AIと言っても、実際に動いているのはChatGPTAPIです。
ChatGPTを上手く活用することで、書籍を選択しています。

### AI属性

AIユーザーには属性を持たせています。
属性はユーザー詳細画面を見ると分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/dc0b2737-80db-afdd-63fa-aed05e850dc9.png)

「異世界転生大好き」というAIユーザーの例では、「異世界転生物が好き」というのが属性に当たる説明です。
この属性が、各AIの選択する書籍の領域を決めています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/c1ed63dc-d916-0545-3868-dc76d8b3a8e6.png)

こちらのライフハックAIは、メンタルや断捨離といった、生活にかかわる書籍をまとめる性質を持っています。

このように、YommyではAIに属性を持たせることで、色々なセレクションを作成してもらおうと考えています。
現状、ChatGPT3.5を利用していますが、GPT-4を使えばより精度の高いセレクションができると思うので、後々そういった機能を実装したいと思っています。

## 仕組み

仕組みを至って簡単です。
AIと言っても、利用しているのはOpenAIのみになります。

具体的にはOpenAIを活用して、「検索」「選択」というった処理を任せているだけです。

Function callingを上手く活用することで、上記の「単発の動作」を、OpenAIにやらせることが可能になります。

https://qiita.com/Gamari0009/items/a7de53514504ea99db7d

上記のTODOアプリも、Function callingを使って上手いことやってます。
それを上手く利用して、良い感じに書籍をピックアップする。
それが、AIセレクション機能になります。


## 今後の展開

まず、AIセレクションの精度を上げるのが先決です。
現状、ピッタリと当てはまればいいのですが、体感5割ぐらいでまったく関係の無いものを選択することがあります。
半分近くとなると、やはり精度は悪いです。

対策としては、Yommyのデータを上手く活用することを考えています。
AIセレクション機能では、書籍を選択する際、オブジェクトとして選択肢を渡すのですが、その中で「レビュー点数」などを提示することで、少なからず精度が上がるように感じられます。

つまり、ユーザーが利用すればするほど、様々データが蓄積されて、AIセレクション機能の精度も上がる、って感じです。

また、AI属性の横展開も頑張ります。
様々な属性を持ったAIを増やすことで、その人に会ったセレクションを提供できるAIを用意したいと思っています。

## まとめ

AIセレクション機能に関しては以上になります。
ご一読くださり、ありがとうございましす。

https://yommy-books.com/

ほぼ利用者がいない状況ですので、この機会に少しでも触っていただけると励みになります。
また、チーム開発等も考えているので、「開発してみたい方」がございましたら是非お声がけください。

それでは、以上になります！

## そのほかの記事

https://qiita.com/Gamari0009/items/a132cd75c9dc1f647986

https://qiita.com/Gamari0009/items/a6379efe12439f25cd05

https://qiita.com/Gamari0009/items/39e84a9d08e20a1635e4
機械学習の主な3つのタイプ

# はじめに
Scikit-learnというPythonの機械学習のライブラリを使うことになり、機械学習の基礎となる概念について調べていました。

# 機械学習とは
械学習は、明示的にプログラムされずにコンピューターが経験から学習し、向上する人工知能の1つです。
![img_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/10560999-96d8-0b7f-60b6-16f3452ef200.jpeg)
(https://www.fujielectric.co.jp/products/foodfactory/basic/ai/ より引用)

# 機械学習の主要な3タイプ
+ 教師あり学習
+ 教師なし学習
+ 強化学習

### 教師あり学習
学習データに正解のデータが含まれているものを学習させる方法です。
モデルはデータセットを基に正解を判定します。
例えば、犬と猫の画像を学習させたモデルがあり、それに猫の画像を見せると猫と判定し、犬の画像を見せると犬と判定するものです。

用途として、画像処理で使われることが多いです(Qiita内に記事が多くあると思います）
他には不動産価格と予測、手書き文字の認識、クレジットカードの信用スコアなどがあります。
![29-1-E69599E5B8ABE38182E3828AE5ADA6E7BF92E381A8E381AF_E4BFAEE6ADA3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/afe8d072-3f39-9c33-ddef-3fc6a8c7dece.png)
(https://ai-kenkyujo.com/artificial-intelligence/kyoushiarigakusyu-kyoushinasigakusyu/ より引用)


### 教師なし学習
学習データに正解データを与えずに学習させる方法です。
モデルは、入力データからパターンを見つけ出します。
例えば、食べ物のデータを学習させると、スイーツ類やラーメン類などモデルが分類するものです。

用途として、クラスタリング、クレジットカードの不正利用などがあります。
![29-2-教師なし学習とは_修正.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/c6a95219-4581-e059-9727-54d9ad3c0127.png)
(https://ai-kenkyujo.com/artificial-intelligence/kyoushiarigakusyu-kyoushinasigakusyu/ より引用)

### 強化学習
学習データに正解データは無いが、報酬（スコア）を最大化するように行動を学習する方法です。
例えば、藤井聡太さんで有名な将棋のゲームで使われます。

用途として、自動運転技術やWeb広告の表示などに使われています。
![強化学習とは_修正.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/4ce6ffbf-fae9-8fe4-a97f-37fa469581f0.png)
(https://ai-kenkyujo.com/kyoukagakusyu/kyoukagakusyu-2/ より引用)

# おわりに
教師あり学習と教師なし学習は大学の講義で情報系の教授が今季よく説明していたので少しは理解していましたが、強化学習は未知の世界です。
セキュリティーが高い三井住友カードの不正検知が教師なし学習が使われているのかなと思ったりと、それぞれのタイプが実社会にどのように使われているのか想像すると理解しやすいのかなと思いました。
今回はPythonでアプリを作る中でScikit-learnを使用するために調べた機械学習についてまとめました。
PDF形式ですが、以下のサイトが分かりやすかったです。

https://www.stat.go.jp/teacher/dl/pdf/c4learn/materials/fourth/dai3.pdf

https://www.stat.go.jp/teacher/dl/pdf/c4learn/materials/fourth/dai4.pdf

この資料のあるサイトは総務省の統計局で、小中高校の授業用の資料のサイトのようです。
どうりで分かりやすい訳だ。

https://www.stat.go.jp/teacher/
社会人しながら1ヶ月で基本情報を取ってみた

# 目次
|章|タイトル|
|:-|:--|
||はじめに|
|1|基本情報技術者試験について|
|2|科目A 勉強方法|
|3|科目Aの戦略|
|4|科目B 勉強方法|
|5|科目Bの戦略|
|6|試験当日について|
||おわり|

## はじめに
基本情報技術者試験を先日受験し、合格点に達していたので合格体験記としてこの記事を作成しました。
勉強期間は1ヶ月で、月に2回ほど休日出勤しているので休日の追い込み等も満足にはできていません。私みたいに完全週休2日でない方や短期間で合格したい方向けの記事を書いていきます。

また、本記事のURLはアフィリエイトリンクではないです。
## 1. 基本情報技術者試験について
簡単に基本情報技術者試験について説明します。
|科目|問題数|試験時間|合格点|
|:--|:--|:--|:--|
|科目A|60問|90分|600点以上/1000点|
|科目B|20問|100分|600点以上/1000点|

## 2. 科目A 勉強方法
科目Aは一問一答形式ということで質よりも量という記事をよく見かけたので[過去問道場](https://www.fe-siken.com/fekakomon.php)で量を意識した勉強を試験日までの最初の2週間行っていましたが、過去問道場の掲示板で過去問で見たような問題が少ない、見たことがない問題が多かったという不合格者の意見が多く見られました。しかし、合格者は、過去問道場かイラストの参考書で勉強をしている...。
「でも、オカンが言うには...」というミルクボーイ状態になってしまいました。

出題範囲が変わるわけではないので、問題文や選択肢がちょいちょい違うのでは？と予想し、勉強法を量と質にシフトしました。
勉強期間前半(試験日までの最初の2週間)は科目Bも並行で勉強していたので毎日過去問道場40問していました。
勉強期間後半(試験日までの最後の2週間)は、平日は過去問道場を毎日1年分(春秋)やっていました。なんとなくで当たった問題をなくすようにチェック機能などを活用して勉強し、選択肢がなぜ違うのかを1つ1つ答えられるように質も意識して勉強をしていました。
過去問の範囲は過去8年分を1ヶ月で1782問解いて、正答率は70%ぐらいです。

## 3. 科目Aの戦略
記事の投稿主は、算数にめっぽう弱いので計算問題では勝負しないことにしました。(皆さんは計算問題はサービス問題として解けると強いと思います。)
なので、とにかく暗記系を勉強しました。
アルファベットの単語でどうしても分からない問題が出たら、選択肢から何の略かを考えて選択するといいかなと思います。

## 4. 科目B 勉強方法
科目Bについては、個人用に社内業務の自動化システムを作ったりしているのでなんとなく自信がありました。なので、試験日までの最初の2週間を科目Bの勉強にあて、勉強期間後半は暗記系の科目Aに集中しました。

そんな科目Bの勉強法ですが、科目Bのセキュリティとアルゴリズムの解き方を勉強するために、こちらの書籍を使用しました。
セキュリティの模擬試験もあるところが嬉しいポイントで、文法やリスト、オブジェクト思考の問題があるほか、模擬問題もあるので科目Bに特化した書籍が欲しいならこれ。解き方が丁寧に解説されています。
※全問この書籍通りに解くと時間がなくなるので注意。

[情報処理教科書 出るとこだけ！基本情報技術者［科目B］](https://amzn.asia/d/gFVp62r)
![スクリーンショット 2023-10-31 0.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788322/e365b0a1-2596-732d-f256-eefaed3fa1b2.png)

模擬試験を休日に行うためにこちらの問題集も使用しました。
分かりやすいし、ポイントを押さえてるのでとてもおすすめです。
科目Aの小さい解説コラムを見て復習できたので、科目A対策にもおすすめ。

[(全文電子版付)かんたん合格 基本情報技術者予想問題集 令和5年度](https://amzn.asia/d/apDssb0)![スクリーンショット 2023-10-31 0.55.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788322/4b8547df-6fb7-a3a7-873e-39875d6e384d.png)



勉強期間後半は、解き方覚えたしやっても意味がないだろうということでアルゴリズムの勉強はしませんでした。(それよりも科目Aを1回でも多くこなしたかった。)

あとはサンプル問題も解説を読んだりして解き方を理解しました。科目Bは過去問が少ないのでとてもありがたかったです。

## 5. 科目Bの戦略
科目Aと科目Bの隙間時間は10分なので、その10分間に水分補給とトイレを済ませ、チョコレートとウィダーを頬張りましょう！とにかく糖分補給と目と頭の休憩が大事でした！
これは、休日に模擬試験を自分でやってみて自分に適した休憩の仕方を調べるしかなかったです。

科目Bが始まったらセキュリティから手をつけることをおすすめします。必ず取れる点を確実に取りに行きましょう。

アルゴリズムはとにかくトレースしましょう。全てトレースすると時間がかかるので注意。
時間がなくてどうしようもない時は、アルゴリズムを見てどんなアルゴリズムかを理解し、これなら期待する値や結果が取れるだろうな〜で選択しました。(回答しないのは勿体無い...。)


## 6. 試験当日について
- 本人確認できるものを準備する。
- 試験前に頭を使いすぎないようにする。
- 休憩は糖分補給も忘れずに

## おわりに
戦略と勉強法がバッチリはまってよかったです。
諦めずに最後まで確認をしましょう！
<next.js>storybookでuseParamsを使いたい

前提
next.js v13.4 (app router)
storybook v7.4

```.storybook/main.ts
import type { StorybookConfig } from '@storybook/nextjs'
import { join, dirname } from 'path'

function getAbsolutePath(value: string): any {
  return dirname(require.resolve(join(value, 'package.json')))
}
const config: StorybookConfig = {
  stories: [
    '<components path>/**/*.stories.@(js|jsx|mjs|ts|tsx)',
  ],
  addons: [
    getAbsolutePath('@storybook/addon-links'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@storybook/addon-onboarding'),
    getAbsolutePath('@storybook/addon-interactions'),
  ],
  framework: {
    name: getAbsolutePath('@storybook/nextjs'),
    options: {},
  },
  docs: {
    autodocs: 'tag',
  },
}
export default config

```

デフォルトではuseParamsを使うコンポーネントをStorybookでレンダリングしたところ取得できない。

# やり方
parametersにnextjs用の設定を追加すれば良い。
自分の例では`https://example.com/[locale]/hoge` のように `[locale]`部分が動的に切り替わりここを取得したかったのでsegmentsで書いてあげればよかった。

```tsx:.storybook/previewtsx
const preview: Preview = {
  parameters: {
    actions: { argTypesRegex: '^on[A-Z].*' },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
    // 追加
    nextjs: {
      appDirectory: true,
      navigation: {
        segments: [['locale', 'ja']],
      },
    },
  },
}
```

他にもpathの指定やqueryの指定もできる。詳しくは公式を参照してください。

https://github.com/storybookjs/storybook/tree/next/code/frameworks/nextjs#nextjs-routing
DP-203合格記(2023/11/1投稿)

# はじめに
この度MicrosoftのDP-203試験(Azure Data Engineer Associate)を受験してきましたので、勉強した内容と受験した感想を書いておきます。
これから受験される方の参考になれば幸いです。


# 前提
* AZ-900/AZ-104/AZ-700/AZ-305/AZ-204/DP-900/AZ-500は取得済み
* AzureはAPIM、DevOps、AppService等の一部サービスを検証で触った程度。データ分析系のサービスは未使用
* AWSの実務経験あり
* AWS認定は全て取っています(詳細は[こちら](https://qiita.com/handy-dd18/items/d21d914bf1c475d777f2))　※PASは[こちら](https://qiita.com/handy-dd18/items/18e8a856906f97bbb964)
* Google Cloud認定は5つ取ってます


# 学習内容
## ①MS Learn
DP-203は試験本などは出ていないのでMS Learnで基礎知識を学習しました。
内容としては、データを溜めるAzure Data Lake Storage、データを変換するAzure Data Factory、データをリアルタイム連携するAzure Stream Analytics・Azure Event Hubs、データ系の機能が統合されているAzure Synapse Analytics・Azure Databricksが主なものとなります。

以下の資格ページの下の方にラーニングパスがあるので、全部読みました。
ラボは環境がなかったので、省略しています。
https://learn.microsoft.com/ja-jp/credentials/certifications/exams/dp-203/


## ②Udemy
MS Learnを使って学んだあとはUdemyで以下の問題を解きました。
思ったよりも難しいというか、この講座の問題の出し方があまり良くなく、問題文を読み解くだけでかなり時間がかかるのであまりお勧めはしません。
恐らく本番よりも難易度は高めに設定されていると思います。

- [Practice Exams | Microsoft Azure DP-203 Data Engineering
](https://www.udemy.com/share/104r8k3@XZ48cel5_v0s7RhwFm2Zy3zY0oNG05KZz2Cj6Y1EuN4NQdK-YfPVO8CgM8WB835h/)

## ③公式模擬問題
Azureは公式が無料の模擬問題を準備してくれているので、こちらも解きました。
こちらは本番よりも難易度は低めに設定されていましたが、知識の確認には良かったので、ここでわからない内容をMS Learnなどで振り返るのが良いと思います。

- [Microsoft 認定資格のプラクティス評価](https://learn.microsoft.com/ja-jp/credentials/certifications/practice-assessments-for-microsoft-certifications)


# 受験した感想
思ったよりは難しかったですが、試験中に確認できるMS Learnを駆使して何とか解ききることができました。
ただ、当たり前かもしれませんが、答えがそのまま載ってることはほとんどないので、答えに関連する記述を読み解く必要があります。
MS Learn頼りの合格は難しいと思うので、せめて各サービスの機能の概要や使い方はイメージできるようになってから受験されると、最後の一押しぐらいはしてくれると思います。

# 受験結果
かなりギリギリでしたが合格でした。
MS Learnで調べた問題が最後の一押しをしてくれたと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/34e746bb-eab5-04bc-89b3-f41172ce7366.png)


# おわりに
AWSのデータ系サービスに比べるとかなり機能が統合されて使いやすい印象を受けました。
実際に業務で使うと違うのかもしれませんが、サービスの考え方は他のデータ基盤にも流用できそうな内容でもあったので、サービスの知識以上に得るものは多かったと思いました。

この記事がどなたかの参考になれば幸いです。
PHP8/xampp で zip を有効にする

ちょっと迷ったので載せておきます。

/xampp/php/php.ini に 次の項目があればコメントを外します。
項目がなければ、追加します。
```/xampp/php/php.ini
extension=zip
```

xampp コントロールパネル等から apache を再起動すれば zip が有効化します。