OmniAICreator/Qiita-1.07M huggingface dataset:
[レビューの役割] JSTQB FL 勉強記録③

# 目次
[1.はじめに](#1-はじめに)
[2.形式的レビューでの役割](#2-形式的レビューでの役割)
[3.作成者](#3-作成者)
[4.マネージャー](#4-マネージャー)
[5.ファシリテーター](#5-ファシリテーター)
[6.レビューリーダー](#6-レビューリーダー)
[7.レビューア](#7-レビューア)
[8.書記](#8-書記)
[9.おわりに](#9-おわりに)
# 1 はじめに
早くも第3回ということで自分の意外な継続力に驚いています。
今回は***レビューの役割***についてJSTQB Foundation 第4版 2018シラバス対応を参考に、自身の勉強も兼ねてまとめていこうと思います。

レビューと聞くと一般的には「商品レビュー」など、何かを評価することだと思いますよね。ソフトウェアテストの観点においても、おおよそそちらの考え方で合っているかと思います。

すごく簡単に記してくれているサイトがあるので載せておきます。
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://www.bing.com/ck/a?!&&p=3d0c05a2907e817dJmltdHM9MTY1ODgxOTc5MiZpZ3VpZD1iMTZiZGJlNy03YTg1LTQxMmQtODcyMS04ODA0Y2M0MTJlN2YmaW5zaWQ9NTE3Mw&ptn=3&hsh=3&fclid=e016d94c-0cb2-11ed-a2b6-c540277c2b37&u=a1aHR0cHM6Ly93YTMuaS0zLWkuaW5mby93b3JkMTUxNi5odG1s&ntb=1)

では早速まとめていきます。
# 2 形式的レビューでの役割
以下JSTQB Foundation 第4版 2018シラバス対応より引用（以下の引用はすべてJSTQB Foundation 第4版 2018シラバス対応からの引用とし、省略する）
>レビューは複数の人がチームを組み実施する場合があります。レビューチームへの参加者が多いほど、形式に沿ったレビューが効果的になります。
形式に沿ったレビューでは、参加者に役割を持たせてレビューを運営していきます。

レビューの役割にはいくつかの役割があります。JSTQBの問題にも多く出てきている印象なので紹介します。

# 3 作成者
レビュー対象の作業成果物に責任を持つ人です。
その作業成果物によって微妙に役割の範囲が違いますが基本的には***その作業成果物を作った開発担当者***という認識で良いと思います。
具体的な作業については以下の通りです。

>***・レビュー対象の作業成果物を作成する***
***・レビュー対象の作業成果物の欠陥を修正する（必要な場合）***
# 4 マネージャー
レビューを運営する責任者です。
>レビューチーム参加者がレビューに貢献できるよう計画を行い、コストと期間を守りながら、目的を達成できるようにレビューを運営していくことが役割となります。

また、マネージャーは業績の評価も実施しているため、その場での発言・行動が評価されるというバイアスがかかるため、***マネージャーは実際のレビューミーティングには参加しない方が良い***とされています。
具体的な作業については以下の通りです。
>***・責任を持ってレビューの改革を行う。***
***・レビューの実行を決定する***
***・担当者、予算、時間を割り当てる***
***・費用対効果を継続的にモニタリングする***
***・不適切な結果が発生した状況に対してコントロールをする***

# 5 ファシリテーター
ファシリテーターはモデレーターとも言い、レビューミーティングの取りまとめ役です。
>役割は、レビューミーティングの計画・見積もり、レビューミーティングの運営、ミーティング後のフォローアップと多岐にわたります。

このように様々な役割を柔軟にこなさなければならないため、レビューが成功するかどうかはファシリテーターの手腕にかかっていると言えます。
ではどのような人がファシリテーターを務めればよいのでしょうか？
ファシリテーターには開発チームやテストプロジェクトのリーダーを経験したことがあるような実力や経験がある人が望ましいと言えます。
具体的な作業については以下の通りです。

>***・効果的なレビューミーティングを運営する***
***・さまざまな意見の調整を行う（必要な場合）***
***・レビューの成功を左右する重要な役割を果たす***

# 6 レビューリーダー
レビューリーダーは、レビューアを選ぶ権利を有しており、レビューにおける実質的な責任者です。
具体的な作業については以下の通りです。
>***・レビューに関して全体的な責任を持つ***
***・参加者を人選し、レビューを実施する機関と場所を決定する***

# 7 レビューア
レビューアは各領域の専門家です。作業成果物に対する懸念事項を識別できる人が選ばれ、同じ目的を持つすべてのレビューに参加します。

レビューアは各専門領域のチェックリストを事前に用意するとレビューの効率も上がり、効果も大きくなります。
具体的な作業については以下の通りです。
>***・特定分野の専門家、プロジェクトの従事者、作業成果物に関心のあるステークホルダー、そして/または特定の技術や業務のバックグラウンドを持つ個人などが行う***
***・レビュー対象の作業成果物の欠陥を識別する***
***・それぞれに異なる観点（例えば、テスト担当者、プログラマー、ユーザー、オペレーター、ビジネスアナリスト、使用性専門家など）でレビューを行う***

# 8 書記
形式的なレビューではレビューミーティングの議事記録を目的として書記（記録係）が存在します。中立な立場でミーティングに参加し、議事録作成をします。
具体的な作業については以下の通りです。

>***・個々のレビュー活動の期間に見つかった潜在的な欠陥を照合する***
***・（開催時に）レビューミーティングで見つかった新しい潜在的な欠陥、未決事項、決定事項を記録する***

# 9 おわりに
以上がレビューの役割になります。ほかにもレビュータイプなどあり、同じように書いていくと多分大変な量になります。可読性も低いため、どうにかテーブルにまとめられないかな・・・なんて考えています。気が向いたらレビュータイプについてもまとめてみたいと思います。

話を戻しますが、JSTQBの勉強をしている中で[テス友](https://www.qbook.jp/info-testomo/)というアプリを使って理解度確認を図っているのですが、***マネージャー、ファシリテーター、レビューア***の問題は特に多いと感じています。
自分でも今回の記事を何度も見直して勉強に役立てたいと思います。
しかし、今回の記事はJSTQB Foundation 第4版 2018シラバス対応を要約しているだけなのでより詳しく知りたい！という方がいらっしゃいましたら是非JSTQB Foundation 第4版 2018シラバス対応を読んでみてください。

最後まで読んでくださりありがとうございました。
Python3エンジニア認定基礎試験合格レポート

はじめまして！今年から社会人になりました新卒エンジニアです。
入社後配属された部署の課題でPython3エンジニア基礎試験を受験し合格したので、勉強方法や受験してみての感想について書こうと思います。

私は就職のため地方から引っ越してきて数か月ということもあり金銭的余裕がなかったので、参考書などを購入せずにネット上の模擬試験を駆使して勉強しました。
内容に対して少々お高めの受験料だと思うため、同じ状況の人の参考になれば幸いです。
# Python3エンジニア認定基礎試験とは
Python3エンジニア認定基礎試験とは簡単に言うとPythonの基礎知識を問う資格試験です。
### 試験概要（資格概要）
受験日：通年
試験センター：全国のオデッセイコミュニケーションズCBTテストセンター
受験料金：1万円（税別）　学割5千円（税別）
問題数：40問
試験時間：60分
合格ライン：正答率70%
出題範囲：オライリー・ジャパン「Pythonチュートリアル」＋一般的な知識
参考：Pyhon3エンジニア認定基礎試験公式サイト

https://www.pythonic-exam.com/exam/basic
### 私のPython歴
大学の機械学習に関する研究で必要な部分を触ったことがある程度です。
講義などで丁寧に教わったことはなく独学で必要な部分だけ学習したので、今回資格として勉強してみて新たに得た知識もありました。
# 勉強に使ったサイト
出題範囲のテキストですが、ネットで見ることができます。

https://docs.python.org/ja/3/tutorial/

特別紙媒体で欲しいなどこだわりがなければワード検索もしやすいですしこちらで十分かなと思いました。

Python3エンジニア認定公式サイトには無料模擬試験が受験できる4つのサイトが紹介されています。
リーディング・エッジ社は残念ながら登録がうまくいかず（登録メールが迷惑メールに振り分けられていました...）利用できなかったのですがそれ以外のサイトは試したので、それぞれの特徴を書いていきたいと思います。なお、すべて無料会員分での感想になります。
### プライム・ストラテジー

https://study.prime-strategy.co.jp/

問題の難易度は少し高めですが、出題内容や順番がかなりテキストに沿った内容になっていると感じました。試験後メールですべての問題文とその正解、自分の解答が送られてくるため苦手な範囲を把握しやすいです。ただし解説は自分で調べる必要があります（ほとんどテキストに載っています）。
試験は第3回まであるので、はじめに出題形式を知りたいときや受験直前の腕試しとして取り組むのが良いと思いました。
### DIVE INTO CODE

https://diver.diveintocode.jp/python_basic/lp

DIVE INTO CODEの良いところは問題がランダム順で出題されるところです。ただ、全く同じ問題が2回連続で出題されることもあります。過去2回分のみですが結果がサイトに保存されるため、周回用として利用していました。
問題の難易度は低めで総数も多くないため、いつのまにか解答自体を覚えてしまうのが難点です。
### トレノケート

https://camp.trainocate.co.jp/map/python/

模擬試験は1パターンですが、全問題に解説があります。難易度は中間ぐらいに感じました。私は時間の都合上見ませんでしたが無料で視聴できる講義動画もあるようです。気分を変えたい時などに試してみると良いと思います。
# 結果
850/1000点で合格でした！
勉強期間は3週間、総勉強時間は15時間程度でした。
### 感想
###### Pythonの基礎知識を見直す良い機会になった
ネット上にサンプルコードが多く存在することもありなんとなくで触っていたPythonを資格取得のために勉強することでより理解できたように感じました。試験の難易度としては正直高くないため、これからPythonを扱いたい・勉強したいと考えている人にとっては良い一歩となるのではないでしょうか。
###### 「Pythonを扱える」ことを証明するエビデンスができた
前述の通り学生時代Pythonを触ったことがありましたがそれを証明するものがなかったので、資格を持っているということは社会人になったばかりの自分にとって一つの自信に繋がりました。
###### 複数パターンの問題を解いてみることが合格の近道！
他の言語でもそうだと思うのですが、同じ処理でも複数の書き方があったりちょっと書き方を変えるだけで全く違う結果になったりと一方のやり方を暗記しているだけでは解けない問題が数多く存在します。まず合格したいならテキストをくまなく頭に入れるよりもより多くの模擬試験を受けることをオススメします。
もちろん模擬試験を解くだけでは本番でカバーしきれない問題が必ず出てきます（私がそうでした）。ですので高得点を目指したい方は間違えた問題の別の記述法や関連する内容などを幅広く復習するのが良いと思います。
その中でも標準ライブラリは数が多いため、当日全く勉強していなかったものが出てきて焦りました...

### 最後に
いろいろ書きましたが、上記の感想に加え社会人生活の中で勉強を習慣付ける意味でも今回取得して良かったなと思いました。
ここまでお読みくださりありがとうございました！
Salesforceで商談レコード作成時にデフォルトの項目値を取引先の値で作成する方法

Salesforceで商談作成をする際に取引先の値を商談項目にデフォルトで記載されている状態でレコード作成できる方法をお伝えします


## ステップ１ 取引先オブジェクトで「アクション」作成
![取引先アクション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/0d2edeca-6507-df38-f361-8a3b78dab93f.png)

取引先のオブジェクトマネージャー「ボタン、リンク、アクション」から新規アクションを作成します。
このとき
・アクション種別　レコードを作成
・対象オブジェクト　商談

と設定してください

## ステップ２ 作成した取引先オブジェクトの「アクション」を編集しデフォルト値を設定

作成したアクションの「対義済み項目値」の新規ボタンをクリックします
![定義済み.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/8a3372c7-8f89-c4e8-1aa4-8b1e21166d0f.png)

こちらでデフォルト値を設定し「保存」をクリックします

今回は例として
「商談名のデフォルト値に取引先名が入る」とします
![アクション２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/874d8eb7-e6eb-30a4-46e6-b43e32091b85.png)

## ステップ３ 取引先オブジェクトの「ページレイアウト」を編集し保存

最後に取引先のページレイアウトを編集します
「Salesforce モバイルおよび Lightning Experience のアクション」に先ほど作成したアクションを追加し「保存」をクリックします
![作成商談.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6acd8a2f-ae84-93cb-f077-1eb0481800b0.png)


こちらで設定完了です。

実際に取引先ページを見れば右上にアクションが設置されているのが分かります
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/9f0c6a8f-4a70-5093-3f5f-09d82f90d5c8.png)


こちらのアクションをクリックすると商談名にデフォルトで取引先名が記載されていますね
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c439679b-3387-fe95-0599-25cc1d439f58.png)
Windows Insider 利用者が SSMS を開けない時の回避策

Windows Insider Programに参加していると、SQLServer Management Studio（SSMS）が正常に起動しないことがあり、解決策を見つけたので備忘録として書いておきます。

# エラー発生時の状況
業務でSQLServerを使用する必要があったので、SQLServerをインストールし、そのままSSMS（18）のインストールもしました。
インストールが終わろうとする頃、こんなエラーメッセージが出ました。
`Microsoft Visual Studio 2017 Shell (Isolated)`
`Cannot find one or more components. Please reinstall the application.`
![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234496/55206111-667c-deea-e2e8-21d9ac6e1255.png)
「？」と思いつつ、SSMSはメニューに追加されていたので、ポップアップを閉じてSSMSを開いたところ、再度同じエラー表示が出ました。
エラーメッセージで検索し、以下のことを試しましたが、全てダメでした。
- SQLServer、SSMSに関連するプログラムを全てアンインストールしSSMSの再インストール
- SSMS 19のインストール
- SSMS 17のインストール
- レジストリエディタのSSMSに関するConfigを削除

# エラーが起こる人の特徴
[マイクロソフト公式のQAでも22年6月くらいから話題になっていました。](https://docs.microsoft.com/en-us/answers/questions/896918/management-studio-18-amp-19-don39t-start-microsoft.html)
どうやら**Windows11のInsider Programに参加している人**に起きている事象のようです。

# 解決策
Azureのフォーラムにありました。回答しているErinさんはSSMSの中の人っぽいですね
https://feedback.azure.com/d365community/idea/6b7d06dc-9bec-ec11-a81b-6045bd7ac9f9
https://feedback.azure.com/d365community/idea/82a9ea93-08ee-ec11-a81b-6045bd7ac9f9

### 具体的な回避手順
1. [ViVeTool](https://github.com/thebookisclosed/ViVe/releases) をGitHubからインストール
2. 管理者権限でコマンドプロンプトを開き、以下のコマンドを実行
```console
> vivetool /disable /name:SV2Navpane
> shutdown -r -t 0 
```
二つ目のコマンドで再起動されますので、再起動後、SSMSを開くと無事に起動できました。

ViVeToolというのは、Windowsの隠し機能を有効化・無効化できるツールです。
一つ目のコマンドで、ナビゲーションパネルの機能を無効化しています。
どうやらInsider Previewで使用できるタブ機能付きエクスプローラーを無効化するとSSMSのエラーが治るようです。
訳わかりませんね。
FlutterでiOS開発を久々に実機で検証する時につまづく

開発も山場を迎え実機での検証を余儀なくされた時に
```
Error: iPhone is busy: Fetching debug symbols for iPhone. 
Xcode will continue when iPhone is finished. (code -10)
```
こんなエラーに出くわす。。。

- `Mac`上の`iTunes`を閉じる。
- 端末(`iphone`)の再起動。
- `Xcode`の再起動。
- `Mac`・エディタ(`VSCode`)の再起動。

で上手くいかない場合は、
![スクリーンショット 2022-07-26 17.32.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/aae7078c-1523-50a0-9071-16f8add19ef1.png)
`Xcode`で端末を接続し直して、
![スクリーンショット 2022-07-26 17.33.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/821ee916-3037-05c5-daa4-dd1ca6780c8f.png)
一度実行させます。
![スクリーンショット 2022-07-26 16.29.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/25b4067e-7983-1cfa-f3d7-02a03857115e.png)
すると、右上の方で頑張ってくれて実行しようとしてくれますが`Mac`の`upgrade`などの影響で、ファイヤーウォールのエラーだったり、`codesignがキーチェーン に含まれるキー"private key"を使用して署名しようとしています`や下記VMのエラーなどが起こります。
```
Exception attempting to connect to the VM Service: SocketException: Connection refused (OS Error: Connection refused, errno = 61)
```
- `ファイヤーウォール`の場合は`システム環境設定`から`オフ`にする。
- `キーチェーン`は本機パスワードを入力し、常に許可を指定。それでも消えない場合は再起動。
- `VMエラー`の場合は、`iproxy`が未確認の開発者と断定されている可能性が高いので、`システム環境設定`から`セキュリティとプライバシー`に移動し許可させます。
![スクリーンショット 2022-07-26 17.28.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/5f0a57a3-8e02-b962-a8a7-83e7356c1af4.png)
if文で、「AまたはBまたはCまたは....の場合」の条件式をスッキリ書きたい（PHP, JavaScript）

## 初めに
if文で、
`「AまたはBまたはCまたは...の場合」`というように、
特定のOR条件のパターンでのみ実行したい処理がある場合
愚直に書くとif文の条件式が長くなりがちです

イメージ（PHP）：
```hoge_before.php
<?php

function hoge(string $s)
{
    if (
        $s === 'A' ||
        $s === 'B' ||
        $s === 'C' ||
        $s === 'D'
    ) {
        echo 'OK!';
    } else {
        echo 'NG!';
    }
}

hoge('A'); // 出力結果： OK!
hoge('B'); // 出力結果： OK!
hoge('C'); // 出力結果： OK!
hoge('D'); // 出力結果： OK!
hoge('Z'); // 出力結果： NG!

```

こんな時は、配列等を利用するとif文の条件式をスッキリ書くことができます。


## 配列を使う
### PHPの場合

```hoge_after.php
<?php

function hoge(string $s)
{
    $arr = [
        'A', 'B', 'C', 'D'
    ];

    // $arrの配列に、$sが含まれるかをチェック
    if (in_array($s, $arr, true)) {
        echo 'OK!';
    } else {
        echo 'NG!';
    }
}

hoge('A'); // 出力結果： OK!
hoge('B'); // 出力結果： OK!
hoge('C'); // 出力結果： OK!
hoge('D'); // 出力結果： OK!
hoge('Z'); // 出力結果： NG!

```

**参考：**
- [in_array()](https://www.php.net/manual/ja/function.in-array.php)


### JavaScriptの場合

```hoge_after.js
function hoge(s) {
    const arr = [
        'A', 'B', 'C', 'D'
    ];

    // 変数arrの配列に、変数sが含まれるかをチェック
    if (arr.includes(s)) {
        console.log('OK!　');
    } else {
        console.log('NG!　');
    }
}

hoge('A'); // 出力結果： OK!
hoge('B'); // 出力結果： OK!
hoge('C'); // 出力結果： OK!
hoge('D'); // 出力結果： OK!
hoge('Z'); // 出力結果： NG!

```

**参考：**
- [Array.prototype.includes()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)


## match式を使う

### PHP 8.0.0 以降の場合
追記：
コメントにて補足いただいたのですが、PHP 8.0.0以降の場合はmatch式が利用できます。
その場合、上記の配列を使った書き方よりも簡潔に記述することができます。
（コメントありがとうございました！🙇‍♂️）

```hoge_after2.php
function hoge(string $s)
{
    echo match($s){
        'A', 'B', 'C', 'D' => 'OK!',
        default => 'NG!'
    };
}

hoge('A'); // 出力結果： OK!
hoge('B'); // 出力結果： OK!
hoge('C'); // 出力結果： OK!
hoge('D'); // 出力結果： OK!
hoge('Z'); // 出力結果： NG!
```

**参考：**
- [match](https://www.php.net/manual/ja/control-structures.match.php)
フロントエンドフレームワークに挑むために必要な助走

# はじめに

フロントエンドをやりたいと思った初心者は、まずはVue.jsやReactといった単語に目を引かれてそちらから手を出してしまうケースがあると思いますが、実際のところはそれらフロントエンドのフレームワークに手を付ける前には助走が必要となります
助走というのは、Vue.jsなどのフロントエンドフレームワークに手を出す前にまずHTMLやCSSやJavaScriptやTypeScriptを習得するということです
助走せずにVue.jsなどのフレームワークから手を出してしまうと手も足も出ませんが、世の中のフロントエンドフレームワークの入門教材は助走抜きで語り始めている教材が多く、さらに助走の仕方も教えていないところの方が多いと思うので、この記事はそんなフロントエンドフレームワークを勉強するための助走にもってこいな教材を紹介して、フロントエンドの初心者が迷わずに助走できるようにしたいと思います

ちなみにすべて無料で公開されている教材を使うことで助走することができます


# HTML CSS 

HTMLやCSSが全く分からないという人は[Progate](https://prog-8.com/)がおすすめです
アカウントを作るかTwitterアカウントでもできるので登録して利用しましょう
簡単なレッスンは基本無料で使えます

なお、HTMLやCSSは使っているうちに学習する手合いのものなので最初はじっくり時間をかけて学ぶ必要はありません
ProgateのHTML&CSSのレッスンが終わったらすぐにJavaScriptを学べばよいでしょう

また、HTMLやCSSはすでに知っているという人は次に行ってください

# JavaSript

JavaScriptを全く触ったことがない人は「ProgateのJavaScript講座」か「[ドットインストール](https://dotinstall.com/lessons/basic_javascript_v5)」もオススメです
映像教材は動きを追えるので何をやっているのかのイメージがつくので初心者には映像教材を探すのもオススメです


上記の教材は基本的な内容だけでとどまりすぎているので、上記の内容が理解出来たら次はこちらのUdemyの[JavaScript中級講座](https://www.udemy.com/course/road-to-javascript-master/)を見ましょう
Vue.jsなどのフロントエンドフレームワークで開発する際に必ず必要となるJavaScriptの知識を習得することができます


# TypeSript

フロントエンジニアにはTypeScriptの習得がほぼ必須のためTypeScriptも学んでおきましょう
typescriptの勉強にオススメなのはこちらの[Udemy無料教材](https://www.udemy.com/course/typescript-react-frontend/)です


# おわりに

上記の教材をやっておけばひとまずVue.jsなどのフレームワークに手を出しても大丈夫だと思います
ただ、フロントエンドを習得するには、次の関門としてVuexなどのフロントエンドの関連技術周りで苦しむことになると思いますが、そちらは頑張って習得していきましょう
Golang + Ginのテスト内でセッションを保存する方法

## TL; DR
Golang + Ginを使ったリクエストのテスト中でセッションを保存する方法に多少苦戦したので紹介

## 結論

```go
import (
	"net/http/httptest"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/sessions"
)

func SaveSession(recorder *httptest.ResponseRecorder, context *gin.Context, key string, value interface{}) {
	var store = sessions.NewCookieStore([]byte("secret"))
	session, _ := store.Get(context.Request, "session")
	session.Values[key] = value
	session.Save(context.Request, recorder)
}
```

使い方

```go
import (
	"net/http"
	"net/http/httptest"

	"github.com/gin-gonic/gin"
)

func Router() *gin.Engine {
	r := gin.New()
	r.GET("/url", func(ctx *gin.Context) {
		ctx.Status(http.StatusOK)
	})
	return r
}

func (suite *Controller) TestIndexSuccess() {
	recorder := httptest.NewRecorder()
	context, _ := gin.CreateTestContext(recorder)
	userID := uint(1)
	router := s.Router()
	context.Request, _ = http.NewRequest("GET", "/url", nil)
	SaveSession(recorder, context, "session key", userID)
	router.ServeHTTP(recorder, context.Request)
	suite.Equal(http.StatusOK, recorder.Code)
}
```
[Python3] 2重loopをitertools.productで置き換えて、速度が遅くならないか確かめた


# 経緯

1. 2重ループを廃止して可読性を上げたい
※ループがネストしていると単体テストを書きにくい、という問題もある
2. しかし、`itertools.product()`は遅いという情報を入手した

「2.」の情報元は以下の記事

https://stackoverflow.com/questions/24555457/itertools-product-slower-than-nested-for-loops

リファクタリングしたせいで処理が遅くなったら困るので、どのくらい遅くなるのか、自分で確かめることにした。

# 環境

測定は、お手軽に試せる Google Colaboratory 上で行いました。

```python:colaboratory
!python --version
Python 3.7.13
```


# 調査 part.1 (2重ループ)

## 比較対象

1. 2重forループ
2. `itertools.product`に対するループ

## ソースコード

### 1. ループ対象

まず、ループ対象になる配列を生成しておく。
これをループさせる。（今回はrangeとした）

```python:colaboratory
ran1 = range(1, 10000)
ran2 = range(1, 500)
```

実際の運用で想定されるのよりも、ちょっと多めのloop数にしておいた。


### 2. 2重ループ

```python:colaboratory
%%timeit -r 5 -n 20

cnt = 0
for i in ran1:
    for j in ran2:
        cnt += i * j
```

### 3. `itertools.product()`のループ

```python:colaboratory
%%timeit -r 5 -n 20

import itertools

cnt = 0
iterator = itertools.product(ran1, ran2)
for i, j in iterator:
    cnt += i * j
```

## 結果

|ループ種別|測定結果|測定結果詳細|
|:-|-:|:-|
|2重ループ|**505 ms**|20 loops, best of 5: 505 ms per loop|
|itertools.product()ループ|**556 ms**|20 loops, best of 5: 556 ms per loop|

んーーーー10%の遅延？？
大差ないじゃんかーーーもー(´^ω^｀)

stackoverflowにビビらされただけでした。

# 調査 part.2 (5重ループ)

...で、終わったら記事として物足りないので、**多重ループさせた場合の比較**もしてみることにした。
stackoverflowは2重じゃなくて多重ループを取り上げてましたしね。

別に目の前の仕事では必要なかったんですけど、、、いつか使うかもしれないし。。。いや、使いたくないけど(｡ŏ﹏ŏ)


## 比較対象

1. 5重forループ
2. `itertools.product`に対するループ

## ソースコード

### 1. ループ対象

```python:colaboratory
ran1 = range(1, 10)
ran2 = range(1, 5)
ran3 = range(1, 21)
ran4 = range(1, 18)
ran5 = range(1, 6)
```

ループ数は適当


### 2. 5重ループ

```python:colaboratory
%%timeit -r 5 -n 20
cnt = 0
for i in ran1:
    for j in ran2:
        for k in ran3:
            for l in ran4:
                for m in ran5:
                    cnt += i + j + k + l + m
```

### 3. `itertools.product()`のループ

```python:colaboratory
%%timeit -r 5 -n 20
import itertools

cnt = 0
iterator = itertools.product(ran1, ran2, ran3, ran4, ran5)
for i, j, k, l, m in iterator:
    cnt += i + j + k + l + m
```

## 結果

|ループ種別|測定結果|測定結果詳細|
|:-|-:|:-|
|2重ループ|**52.5 ms**|20 loops, best of 5: 52.5 ms per loop|
|itertools.product()ループ|**63.7 ms**|20 loops, best of 5: 63.7 ms per loop|

ループのネスト数が増えたら、確かに遅延割合も大きくなった。
2重のネスト程度なら10%遅延で済むけど、**5重ネストだと20%程度遅延することもある**みたい。

# 考察

itertools.productの導入に当たっては、ループ数とループのネスト数に注意する必要があるのではないかと思う。

たとえばループ内の処理がそもそも重い処理（ファイル出力とか画像読み込みとか？）で、**ループ数もネスト数も少ない場合は、この遅延はそんなに気にならないはず**。

理由としては、重い処理自体が更に遅くなるわけではないからである。
あくまでも、1ループごとに余計なオフセットがうっすら上乗せされるだけなので、loopのネストをitertools.productに置き換えたところで、ループ数もネスト数も少なければ、誤差程度の遅延が発生するだけだろう。
たとえば、2時間かかってた処理が2時間3分になるとかその程度だと思われる。

逆に、ループ内の処理ではなくて、**ループ数やネスト数が膨大なために処理時間がかかっているような場合は、今回の調査結果のように10%や20%の遅延が発生する**ので、itertools.productに置き換えるべきかどうかは落ち着いて考えた方が良いかもしれない。

また、**5重以上のループの場合は当然20%以上の遅延が発生する**と思われるので、注意が必要だろう。
stackoverflowに掲載されていた8重ループの例では、60%ほどの遅延が発生していた。


# 補足

前記stackoverflowの回答のうち、この人の回答

https://stackoverflow.com/a/24556612/8674852

に従えば遅延を防げるのかもしれないけど、今回の当初の目的は可読性を上げることだったので、なかなか理解しにくいこの実装は候補から除外した。
表の各行の高さをそろえる【PowerPointVBA】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/e2c6c515-613e-5022-e754-00fdf5ac6201.png)

ppt上の表の各行の高さをそろえるメソッドがわからなかったので

1. ループで総和求めて
1. 平均出して
1. ループで各行に高さ付与し直し

という手をとった
ググってズバリのメソッドを探すよりも作成コストが安くて動けば良いのでとりあえずこれで

高さをそろえるメソッドご存じの方いらっしゃったら教えてください・・・

``` vb
Sub ppTable上の全行の高さをそろえる(TableObj As PowerPoint.Table, r_Top As Long)
'TableObj :pptスライド上のTableオブジェクト
'r_Top      :高さ修正対象の1行目 ヘッダ行が1行なら2
    
  Dim Rcnt
  Rcnt = TableObj.Rows.Count - r_Top + 1
  
  Dim i, H_sum
  H_sum = 0
  
  For i = r_Top To TableObj.Rows.Count
    H_sum = H_sum + TableObj.Rows(i).Height
  Next
  
  Dim H_ave
  H_ave = H_sum / Rcnt
  For i = r_Top To TableObj.Rows.Count
    TableObj.Rows(i).Height = H_ave
  Next

End Sub

```
VisibleSimセットアップ備忘録


### インストール
* ~~LinuxかMacでしか動かなそうなのでとりあえず仮想環境を作成した。Windowsの人は下記参照に作成するとよいかも(Ubuntu 20.04で動作確認済み)。~~
Windowsでも動くみたい。https://benoitpiranda.fr/#/education/programmable-matter/visible-sim-1:~:text=Windows%20installation
仮想環境作りたいなら以下を参照にするとよいかも
    * Hyper-V：https://qiita.com/Shinya_IDENO/items/aecccaa0cc1e58190aff
    * Virtual Box：https://qiita.com/HirMtsd/items/225c20b77a7cd5194834


* まずリポジトリから本体をCloneする。
```
git clone https://github.com/ProgrammableMatterProject/VisibleSim.git
```

* GitHubにssh keyを設定する
https://qiita.com/shizuma/items/2b2f873a0034839e47ce

* Submoduleを更新する
```
cd VisibleSim
git submodule init
git submodule update
```



* 次に必要なパッケージをインストール
Linuxのひと
```
sudo apt-get install build-essential
sudo apt-get install freeglut3-dev
sudo apt-get install libglew-dev
sudo apt-get install sbcl
sudo apt-get install libmuparser-dev

# [Optional]
sudo apt-get install doxygen # for html documentation 
sudo apt-get install ffmpeg # for video export
sudo apt-get install libsfml-dev # for BlinkyBlocks sound simulation
```
Macのひと
```
brew install freeglut
brew install glew
brew install sbcl
brew install muparser

[Optional]
brew install ffmpeg # for video export
brew install sfml # for BlinkyBlocks sound simulation
```

* サンプルがcppで書かれているのでビルドしたいのだが、その前にビルド対象となるソースコードを指定する
```diff: VisibleSim/applicationsSrc/Makefile
- SUBDIRS = myApp
+ SUBDIRS = C3DRotate hexanodes_demo meld reconfCatoms3DMultilayer scaffolding_pyramid_async simpleColorC2D csgCatoms3D lightWalkCatoms3D musicPlayer robot02 scaffolding_pyramid_sync c2d_demo datomsRotate maxFlowSC nodes2D_demo sbReconf simpleColorSC sinkSource c2srCatoms2D distanceSC reconfCatoms3D scaffolding_cube simpleColorBB simpleColorSB molding datomsTestbed gameOfLife rainbow tetris

subdirs: $(SUBDIRS)

# autoinstall not needed anymore
$(SUBDIRS):
	@mkdir -p ../applicationsBin/$@
	@echo "Checking $@ block code"
	@$(MAKE) -C $@ APPDIR=../../applicationsBin/$@ GLOBAL_INCLUDES="$(GLOBAL_INCLUDES)" GLOBAL_LIBS="$(GLOBAL_LIBS)" GLOBAL_CCFLAGS="$(GLOBAL_CCFLAGS)"
...
```

* 最後にリポジトリのルートからmakeしてあげる
```diff: VisibleSim/
make
```

* VisibleSim/applicationsBin配下に実行可能ファイルが生成されているので好きな奴を起動してみる(結構動かないやつも多い)
```diff:VisibleSim/applicationsBin/lightWalkCatoms3D/lightWalk/
./lightWalk 
```
こんな感じで表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2584877/96923715-e5c8-13c8-285f-a5e9c64558a9.png)

この状態でrを押すと動く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2584877/0cffbd46-8355-f4ef-ac37-b5748a9efc94.png)

* 参考リンク
https://www.programmable-matter.com/
https://github.com/ProgrammableMatterProject/VisibleSim
https://www.youtube.com/watch?v=6U3Wsroy-f8&ab_channel=ProgrammableMatterProject
GCPでイベント駆動な構成を検討したときに考えたことメモ

# 背景
GCSにファイルがuploadされたら、そのイベントをトリガーにそのファイルを処理してBigQueryにLoadする処理を作りたい

# 先に結論
- Cloud Run + Eventarcの組み合わせが良さそうでした
    - コンテナベースでの開発が可能
    - CloudFunction(1st gen)に比べるとtimeoutやmemoryなど採用できるリソースが大きい
        - 第二世代はCloudRunにかなり寄ってきているらしいがpreviewなのでここでは取り扱わない
- GCSのファイルuploadをトリガーとする場合はEventarcのdirect eventによるトリガーが良さそうでした

# Cloud Function? Cloud Run?

イベントドリブンと聞いてまず思い浮かんだのはCloud Functionでした。イベントをトリガーとして処理を動かす場合、以前はCloud Functionが一番手っ取り早く作れた記憶がありました。

現在はEventarcというものが登場していて、お手軽にCloud Runをイベントトリガーで起動可能ということがわかりました。

https://cloud.google.com/blog/ja/products/serverless/build-event-driven-applications-in-cloud-run


Cloud Function か Cloud Run か? という選択になると個人的には俄然Cloud Runを使いたい派です。

まずコンテナベースで開発ができる。これが大きいです。

また、Cloud Function(1st gen)比較すると、使用可能なリソースがCloudRunの方が大きいです
  - timeoutの最大:  Cloud Function 9min vs Cloud Run 1hour
  - 最大メモリ搭載: Cloud Function 約8GB vs Cloud Run 32GiB
  - cloud run は同時リクエスト 1000 まで可能などなど

Cloud Runを使う前提で考えていくことにしました。

# Eventarc

Eventarcとは何なんでしょうか。

イベントドリブンアーキテクチャを実現するための、イベントトリガーの仕組みのようなものですかね。各サービスのイベントのトリガーの仕掛け先として、現在はCloud Run, Cloud Workflows, GKEなどがあります。

Eventarcには3種類あります。

### 1. Direct Event
Cloud Storage バケットの更新や Firebase Remote Config テンプレートの更新など、Google Cloud プロバイダからの直接イベントによって Eventarc をトリガーできます([サポートされているイベント](https://cloud.google.com/eventarc/docs/reference/supported-events?hl=ja#directly-from-a-google-cloud-source))

### 2. Cloud Audit Log経由
Eventarc トリガーのフィルタ条件に一致する監査ログが作成されると、イベントがルーティングされます。 1でサポートされていないイベントは大体ここでサポートされます。

### 3. Pub/Sub経由
Eventarc トリガーのフィルタ条件で指定された Pub/Sub トピックにメッセージが公開されると、イベントがルーティングされます。これは、サービスによるイベントトリガーではなく、独自のイベントを発生させたい場合などに使うのではないでしょうか。

どれも、Eventarcでのイベントトリガーであれば、[CloudEvent形式](https://cloud.google.com/eventarc/docs/cloudevents?hl=ja)というHTTPの形式でデータがやり取りされ、統一されたHTTPのヘッダープロトコル上での開発が可能になっています。

https://cloud.google.com/eventarc/docs/overview?hl=ja

# で、どれを使えばいいの？

Eventarcの3種類に加え、[既存のPubSubを使ったトリガー方法(非Eventarc)](https://cloud.google.com/run/docs/triggering/pubsub-push?hl=ja)も存在します。この4種類のうちどれを使うべきかというのが、公式ドキュメントでフローチャートで解説されています。

![スクリーンショット 2022-07-21 14.19.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/2e205f8c-d424-bc0b-f4ca-648aa0fc5acd.png)

https://cloud.google.com/eventarc/docs/run/event-routing-options?hl=ja

優先度としては

- Eventarc(direct event)
- Eventarc(Audit Log経由)
- Eventarc(Pub/Sub経由)
- 既存のPubSub方式

という順序になりそうです。まずは、Eventarc(direct event)で実装できるかを検討しましょう。今回のGCSのファイルuploadはこのEventarc(direct event)で実装可能でした。


# 参考
https://cloud.google.com/functions/docs/configuring/memory?hl=ja

https://cloud.google.com/functions/docs/configuring/timeout?hl=ja

https://cloud.google.com/run/docs/configuring/memory-limits?hl=ja

https://cloud.google.com/run/docs/configuring/request-timeout?hl=ja
【Flutter】iOS実機にてReleaseビルドが通らない場合の対処法

# 開発環境
OS: MacOS
Flutter: 3.0.4
Flutter Channel: Stable
Dart: 2.17.5
Android Studio: Artic Fox | 2020.3.1 Patch4

# エラーメッセージ
~~~
Automatically signing iOS for device deployment using specified development team in Xcode project: XXXXXXX
Running pod install...
Running Xcode build...
Xcode build done.                                            8.3s
Failed to build iOS app
Error output from Xcode build:
↳
    ** BUILD FAILED **


Xcode's output:
↳
    Writing result bundle at path:
    	/var/folders/xz/8ytcyfm94hj21ggqskb0fgsc0000gn/T/flutter_tools.XxfdYA/flutter_ios_build_temp_dirhG8RAE/temporary_xcresult_bundle

    note: Using new build system
    note: Planning
    note: Build preparation complete
    note: Building targets in parallel
    /Users/ユーザ名/AndroidStudioProjects/アプリ名/ios/Flutter/Release.xcconfig:3:1: error: could not find included file 'Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig' in search paths
    /Users/ユーザ名/AndroidStudioProjects/アプリ名/ios/Flutter/Release.xcconfig:3:1: error: could not find included file 'Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig' in search paths
    /Users/ユーザ名/AndroidStudioProjects/アプリ名/ios/Flutter/Release.xcconfig:3:1: error: could not find included file 'Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig' in search paths

    Result bundle written to path:
    	/var/folders/xz/8ytcyfm94hj21ggqskb0fgsc0000gn/T/flutter_tools.XxfdYA/flutter_ios_build_temp_dirhG8RAE/temporary_xcresult_bundle


Could not build the precompiled application for the device.
Error (Xcode): could not find included file 'Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig' in search paths
/Users/ユーザ名/AndroidStudioProjects/アプリ名/ios/Flutter/Release.xcconfig:2:0


Error running application on 実機名.
~~~

# 原因
includeに指定したファイルのパスが誤っていることが原因です。
下記エラーメッセージではRelease.xcconfigにてincludeに指定しているPods-Runner.profile.xcconfigが見つからないよ、と言っています。
~~~
Error (Xcode): could not find included file 'Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig' in search paths
/Users/ユーザ名/AndroidStudioProjects/アプリ名/ios/Flutter/Release.xcconfig:2:0
~~~
実際にファイルの階層を確認してみると頭のPods/が抜けていることがわかります。
※ Release.xcconfigから見た相対パス
![スクリーンショット 2022-07-26 17.00.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980010/b1e81e8b-2c44-4f8b-5c15-ef6a081fdea0.png)

# 対処法
ios/Flutter/Release.xcconfigにてincludeに指定しているファイルのパスを修正します。
Pods-Runner.profile.xcconfigの先頭にPods/を追加します。
~~~ c++:修正前
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
// ↓修正対象
#include "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"
~~~
~~~ c++:修正後
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
// ↓先頭にPods/を追加
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"
~~~
ローカルに構築したブロックチェーンでdappsを走らせる老技術者あり

# はじめに
個人企業を営む老技術者のところにも昨今はNFTの話が次々と舞い込んでくる。私のつたない作品のNFTを発行したいのだがというような方には他をあたってくださいと言うが，他の技術を絡めて何かをやりたい系の面白いやつが舞い込むと嬉々として引き受けてしまう。そして土日祭日はそれに~~朝~~ 昼から~~晩~~ 明け方まで取り組むことになる老技術者なのだった。

# まずはローカルにブロックチェーン構築
Windows10の人はまずはWSL2を導入しUbuntuを使えるようにする。
Macの人はターミナルを立ち上げるだけでいい。
そして以下を導入
Docker and Docker Compose
Node.js version 12 or higher
Truffle
cURL command line
MetaMask
詳しくは
https://qiita.com/oldEng/items/557ceb29a7849e92b5f2
をご覧ください。
Ubuntuから
```
$ npx quorum-dev-quickstart
```
を実行すると、どんどんやってくれる。
はじめに質問が出るので、
Hyperledger Besuを選ぶ
Codefi Orchestrate、Quorum Key Managerとprivate transactionsはnと答える。
logging with ELKを選ぶ
BlockscoutはNと答える
Where should we create the config files for this network?
という問いにはEnterでdefault設定にする｡
Installation complete.が出ればOK！

# Pet Shop開店
ここまでは実にスムーズに来るのだが，このまま突き進むと大変なことになる。
私もこれで半日持っていかれた。
読者にはその労苦から解放される恩恵が与えられる，と神のようなことを言ってみる。

フォルダ名をdefault設定にしてあれば，
```
$ cd quorum-test-network/dapps/pet-shop
$ ./run_dapp.sh

```

```
$ cd quorum-test-network/dapps/pet-shop
$ ./run_dapp.sh

```
なんかすごくいろいろやってくれて，終わった感じになったらブラウザの拡張機能のMetamaskを開き，Localhost 8545に接続。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/cf7267ee-c0e2-a49d-9da7-f5380286218c.png)

そして，そのブラウザで
http://localhost:3001/
を開くと，こんなかわいいのが現れる！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/00fc602a-aae5-3d48-cb9c-77fe14a210ef.png)

同時にMetamaskがポップアップしてきてアカウントの接続を求めるのでアカウントを接続。
気に入った犬のAdoptを押してみるとMetaMaskがポップアップして確認を求めてくる。
なんかしっかり犬の値段とガス代の見積もりが入っている。
金持ちなので確認ボタン押下。

![スクリーンショット 2022-07-27 1.16.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/72ac64dc-6712-1556-dd52-f4df5006448f.png)

買った犬が「Success」となっている。
![スクリーンショット 2022-07-27 1.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/9a70fa9d-a6bf-20f7-7617-e5b71d894fa1.png)
サーバやPC上のプログラムでModbus機器からデータを取得 (1)

サーバやPC上のプログラムでModbus機器からデータを取得、なんて場面があります。例えば、接点やセンサーがつながったリモートIOからデータを取得したい場合などです。

この記事では、Modbus/TCPでリモートIOなどからデータを取得するサンプル・プログラムを紹介します。

この記事で紹介するサンプルはModbus/TCPを前提としていますが、Modbus/RTUでも原理は同じです
。Socketがシリアル・インタフェースに変わり、やりとりするデータのフォーマットがTCPからRTUに変わるだけです。
※RTUの場合、送受するデータにCRCを組み込む必要があり、少々やっかいですけどね。

>リモートIOのメーカーのサイトでは、PLCがリモートIOからデータを取得するように書かれていたりします。リモートIOからのデータを使って機械を制御する場合はそんな構成なのかもしれませんが、そのデータをサーバやPCで処理したい場合には、リモートIOのデータをサーバやPCが直接取得するのが合理的です。リモートIOとPLCは必ずしもセットではないのです。
>「そんなことは、ここであらためて書かなくてもあたりまえだろ」と思われる方も多いでしょうが、固定観念と先入観が、迷わず（本来は不要であるはずの）PLCを登場させてしまいます。
## Modbus/TCP
Modbusについては、エム・システム技研さまのこのドキュメントがおすすめです。
[Modbus プロトコル概説書](http://www.m-system.co.jp/mssjapanese/kaisetsu/nmmodbus.pdf)
## サンプル・プログラム
今回はPerlを使いました。Perlである必要性はありませんが、Perlではだめだという理由もありません。なぜPerlを選択したか？僕のセルフォンでPerlが使えたからです。

サンプルでは、ファンクション0x03: Read Holding Register を使っています。

データをコンソールに16進表記で表示するために、公開されていたコレを遠慮なく拝借いたしました。
[(Perl) バイナリ変数の１６進ダンプ表示](https://netlog.jpn.org/r271-635/2018/11/perl-bynary-dumper.html)
```perl
#!/usr/bin/perl

use IO::Socket;

{
	my $Server = 'localhost';
	my $Port = 5502;

	my $socket = new IO::Socket::INET( 
		PeerAddr=>$Server,
		PeerPort=>$Port,
		Proto=>'tcp');
	die "IO::Socket : $!" unless $socket;
	print "connected to the server\n";

	my $TransactionID = 0x0200;
	my $ProtocolID = 0x0000;
	my $Length = 0x0006;

	my $UnitID = 0x01;
	my $FunctionCode = 0x03;
	my $StartAddress = 0x0000;
	my $CountRegister = 0x0001;

	my $req = pack("n3C2n2", 
		$TransactionID, $ProtocolID, $Length, 
		$UnitID, $FunctionCode, 
		$StartAddress, $CountRegister);
	my $size = $socket->send($req);
	print "sent data:\n";
	BinaryDump($req);

	shutdown($socket, 1);

	my $response = "";
	$socket->recv($response, 1024);
	print "received response:\n";

	BinaryDump($response);

	$socket->close();
}

# 利用させていただきました
# https://netlog.jpn.org/r271-635/2018/11/perl-bynary-dumper.html
sub BinaryDump {
    my ($buf) = @_;
    my $len;
    my $i;
 
    $len = length($buf);
    printf ("length = %d\n", $len);
    for ($i = 0; $i < $len; $i++) {
        printf("%02X ", ord(substr($buf, $i, 1)));
        # 16文字目で画面上の改行
        if (($i % 16) == 15) {
            print "\n";
        }
    }
    if (($i % 16) != 15) {
        print "\n";
    }
}
```
## テスト
テストにも僕のセルフォンを使いました。
Modbusスレーブとして、Androidアプリケーション"ModTCPSimX"に活躍いただきました。
![672850389bd205ccd2287edea4b6eea462df857ac0e06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737842/fd2d2a18-3be3-1bec-1227-a480a1bdee98.png)
ModTCPSimX のポート番号のデフォルトは5502です。僕のプログラム側も5502にしてあります。
※一般的なModbus/TCPは502です。
Holding Register 40001 に任意の数値を設定しておきます。
※ModTCPSimX では値の背景が黄色の場合は更新がコミットされていません。鉛筆アイコンでコミットするのを忘れずに
![e0e934f699c14d7e14657cced9848d5c62df8d8718344.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737842/d7e99363-13ca-37ee-9cf0-eec63cf0f72b.png)
Termuxでプログラムを動かすと、最後のバイトに値が置かれたTXが返ります。
![a486c6b8599b14f88005f174460cdbd662df8dad794c7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737842/b79658d6-5d82-9561-4ec7-28e120f64298.png)
## 次回
せっかくなので、次回は取得したデータをデータベースに保存します。次回は今回以上にどうってことない記事です。
google-images-download使い方メモ

# 準備
## google-images-downloadをインストール
この時`pip`でやらずに公開されているGithubから`clone`します。

```:コマンドプロンプト
git clone https://github.com/Joeclinton1/google-images-download.git gid-joeclinton

```
この時最新版の`selenium`がダウンロードされるが、`find_element_by`から始まるメソッドが使えなくなっているので、バージョンを落とす必要があるため一度`selenium`を削除して、古いバージョンを入れる。

```:コマンドプロンプト
pip uninstall selenium
```

```:コマンドプロンプト
pip install selenium==4.0.0
```

`selenium`のバージョンが`4.3.0`より古ければ大丈夫だと思う。

## Chrome Driverのインストール
[Downloads – ChromeDriver](https://chromedriver.chromium.org/downloads)からChromeDriverをダウンロード。
zipファイルを展開して実行するPythonファイルと同じディレクトリに入れておく。

# Pythonファイル
Pythonの実行ファイルはこんな感じ。

```Python
#モジュールのインポート
from google_images_download import google_images_download  
#responseオブジェクトの生成
response = google_images_download.googleimagesdownload()  

#検索キーワード/ダウンロード画像の数

arguments = {"keywords":検索したいワード,
              "limit":1000,
              "chromedriver":"chromedriver.exe",
              "format":"jpg"
             } 

#ダウンロードの実行
response.download(arguments)
```

`keywords`に検索するワードを入れる。スペースを使うのはあり。
`limit`は何枚の画像を保存するのかを指定する。今回の場合は1000枚ダウンロードしてる。
`chromedriver`はさっきダウンロードしたchromedriverのpath
`format`は保存形式を指定する。

実行すると実行したディレクトリに`downloads`という名前のフォルダが作成されてその中にダウンロードした画像が保存される。

# 参考
https://usimaru.net/python-google_images_download-install/
お手軽にデザインセンスがない人がロゴを作った（生成した）話

## この記事は？

個人サイトにロゴが欲しいと思い、ロゴを作成したときに使用したサイトの話です。
**有料のwebサービス使っています。**

 - 作ったロゴ
![clapton.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/f68692fd-b565-4b63-e466-a458a20ef4fd.png)
![logo - コピー (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/357dd0c3-e1a9-7c5b-e6fd-524ac0cf96b2.png)

## この記事で解説しないこと

 - ロゴをいい見た目にする方法（自分も知りたい）
 - 生成したロゴの使い方
 - ロゴの加工のコツ

## 結論
[Logo Maker & Logo Generator](https://logotypemaker.com/) を使いました。
それっぽいロゴを自動生成してくれる＋編集や各素材用にダウンロードのカスタマイズもできます。

## 筆者のスキル
 - デザインセンス×
   - フレームワークやツールなど、安定した見た目のものをどうにか弄ってそれっぽくするタイプ
 - 画像編集×
   - ほぼやったことなし。

こんな感じでも、いい感じにロゴを生成できました。

## 詳細
### 利用料金

まずは気になるお値段から。
1ロゴ当たりの料金です。（編集した際にはログが残り、ログを含めて、1ロゴとみなされるみたいです）
※ 2022/07/26当時の料金
海外のサイトのため、為替レートで微妙に値段変わります。

 - Basicプラン（ダウンロードや、リサイズ、背景色の変更などできる）
   - $19.99
   - 筆者が使用したのはこちら
 - Premiumプラン（Vector形式のファイル生成、署名や名刺用の画像の生成、Faviconの生成やSNSのヘッダー用素材などの生成ができる）
   - $49.99
   - Basicプランからのアップグレードも可能。差額支払いらしい。

プロモーションコードの入力があり、検索すると出てくるものを入力すると3割引きになりました（購入当時）。探すと少しお得になるかも。

支払方法はクレカorPayPalです。 [Vプリカ](https://vpc.lifecard.co.jp/) が使用可能だったため、決済手段未所持だった場合でも、コンビニ行けば支払できます。

### ロゴのベースの生成方法
1. [Logo Maker & Logo Generator](https://logotypemaker.com/) にアクセス

2. 上部に表示されるテキストボックスにロゴに表示したい名前（アプリ名、会社名、サークル名など）を入力し、 `Get Started をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/1f89f37c-f271-d7d9-f4e8-521884279a30.png)

3. ロゴが色々自動生成されるので、よさげなのが出るまで再生成をする
この際に、Searchからそれっぽい単語を入れることで、関連性のあるものに絞り込まれて生成されます。
アイコンにホバーすると♡アイコンがでて、WishListに追加できるので、気になったものはとりあえず入れておくといくつかの中から比較でき ます。（ページ離れると結構WishListの中身が飛んだので、出来るだけ一気に決めるまでやったほうがいいかもしれません。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/07277c8e-e80a-cef8-a1b4-f537b72099ef.png)

4.ロゴが決まったら `Edit` をクリック、エディタが開くので、必要なら微調整をします。
右上の `Video Tutorial` に使い方の説明があるので、詳細はそちらから。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/1ab1e6cc-dbef-9e82-f6af-7965c94f7024.png)
5. 調整が終わったら `Save and Download` で保存します。（会員登録のページが出てくるので、Gooleアカウント等で登録します）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/ad767bb7-5a75-bc7e-b4e2-e144809164ee.png)
6. ロゴのページからダウンロードができます。ダウンロードをしようとした際に料金支払いの促しがあるので、支払いを行います。
7. ダウンロードダイアログで大きさの調整、背景色の調整（や、透過）などができるので、使いたいように変更してダウンロードすれば完了です！（SVG、PDF、EPS形式はプレミアムプラン用のものらしいです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/cd824a3f-3df4-8e0b-a83d-99acd4172b00.png)

## まとめ
実際にロゴを使った様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/56b06894-7b50-631c-dad0-41f3a556a67c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/796120/97ab8bb6-fc85-c8f6-2034-107c19c62f39.png)

やっぱりロゴがあると華やかになっていいですね！

ちなみに個人開発しているのはコミケでほしいものをグループ単位で管理するアプリです。
個人アプリ: [clapton](https://clapton.newstep-info.com/mypage)
github: https://github.com/moriyadetteiu/clapton
【Golang】C compiler "gcc" not foundエラーからの脱出

# 問題発生
VSCodeでGo言語勉強中に下記のように初めてSQLiteをインポートしようとしました。
```
go get github.com/jinzhu/gorm
go get github.com/mattn/go-sqlite3
```
```Go:main.go
import (
   //他のインポート
    "github.com/jinzhu/gorm"
    _ "github.com/mattn/go-sqlite3"
)
```
そしていざ実行！
```
go run main.go
```
すると下記のエラーにぶち当たりました。
```
exec: "gcc": executable file not found in %PATH%
```
ああ、SQLiteを使うにはgccというC言語コンパイラーが必要なんだな。
そこで[こちら](https://jmeubank.github.io/tdm-gcc/)の「MinGW-w64 based」からgccをインストール！
一応確認。
```
gcc -v
```
するとちゃんと反応あってインストールに成功している！
よし！これでGoが動くぞ！と思って ` Go run main.go ` しようとしたらまた ` exec: "gcc": executable file not found in %PATH% ` エラー...
なんでやねんと思い再インストールなどしてもこのエラーから脱出できませんでしたが...

<strong>VSCodeを再起動するとエラーが治りました</strong>

今思うとVSCodeのターミナル開きっぱなしにしてたからpathが更新されてなかったのかな？と推測

というしょうもないお話でした！
JUnit4＋Kotlinでのパラメータテストの書き方

パラメータを生成するメソッドがStaticメソッドである必要があるのでJvmStaticにする必要があった

``` kotlin
@RunWith(Parameterized::class)
internal class ParameterTest(
    val case: TestCase
) {
    data class TestCase(
        val param: Param,
        val expect: Expect
    ) {
        // テストケースのパラメータを定義する
        data class Param(
            val parameter: Parameter
        )

        // テストケースの期待値
        data class Expect(
            val value: String
        )
    }

    companion object {
        @JvmStatic
        @Parameters
        fun params() = listOf(
            TestCase(
                param = TestCase.Param(),
                expect = TestCase.Expect("dummy")
            )
        )
    }

    @Test
    fun test_param() {
        val act = TestTarget(
            param = case.param.parameter,
        )

       assertThat(act).isEqualTo(case.expect.value)
    }
}
```
アナログ技術セミナー2022 ～最先端RFテクノロジーとソリューション～ 

__アナログ技術セミナー2022 ～最先端RFテクノロジーとソリューション～__ に参加したよ
https://www.analog.com/jp/landing-pages/003/event/rf-seminar-2022.html
![IMG_4093.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/037e3ecf-ff48-da88-338d-6a5cea1ced3f.jpeg)
# アナログ技術セミナー
アナログ・デバイセズは年に一度アナログ技術セミナーを開催していましたが、コロナ禍ということもあり2022年は電源を対象とした半日のセミナーを6月にオンラインで開催しました。
そしてRFを対象としたセミナーを7月にオンライン・オフラインハイブリッド開催しました。
# アナログ・デバイセズの5G無線プラットフォーム
アナログ・デバイセズは買収に買収を重ねた結果、電源から通信（セルラー系をのぞく）までを網羅することができた。
これをもとにO-RUというプラットフォームを開発した。
https://www.analog.com/jp/applications/technology/sdr-radioverse-pavilion-home/o-ru-radio-platform.html
# 沖縄の通信速度は遅い
__「オープンソースを活用した5Gネットワークの構築」__
沖縄は通信速度が遅くeスポーツでは対戦相手として敬遠されてしまうそう
これは、東京を経由するためだそうで
5Gのネットワークを東京と沖縄の二つの経路を使って検証した結果、遅延が遅延が1／20になったそう
#### 遅延
- 東京周り：60.53ms
- 沖縄周り：2.53ms
# シミュレーションソフト　MATLAB
MATLABで信号生成や線形予測、電波伝搬シミュレーション等126種類以上のツールにより設計・解析シミュレーションが行える。
__Interface 2022年9月号にMATLABの6カ月ライセンスが付属していて試せる模様__

https://interface.cqpub.co.jp/magazine/202209/

# 基板設計者必見
- 「広帯域トランシーバRadioVerseの実装テクニック」
- 「ADRV9002評価ボード基板の設計と評価」
# ADRV9002の独自基板製作方法
独自基板の製作にはアナログ・デバイセズのGithubを参考に行うとのこと。

https://github.com/analogdevicesinc/linux/blob/master/drivers/iio/adc/navassa/adrv9002.h

ちなみに、__マリモ電子__ さんのこのボードCycloneVにLinuxとNon-OSが動作可能であり、STマイクロのUSB-PDコントローラーが乗っていたりちょっと面白い基板です。
![IMG_4092.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ba3cbce8-9e3d-cd2b-5ca1-121138f79bac.jpeg)
# 評価ボードの設計の際の勘所
Shunt-Cをマッチング回路として入れておくと良い、ただし使わないところに入れる0Ωの抵抗は0.3n（0603）程度のインダクタになることは留意した方がいい。
*1005の場合　0.5n程度のこと
# 総評
ADRV9002のセミナーという印象でしたが、今回も来場者の方のクオリティが高く、すごく刺激が多いセミナーでした。
アナログ・デバイセズさんのセミナーは会場参加することをお勧めします。
pythonのChromeDriverManager記述について

```
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

options = Options()
#最初からheadlessでは書かないので、コメントアウト
#options.add_argument('--headless')

#好きなフォルダーを記載
driverfolder = r"C:\python\drivers"
driverpath = ChromeDriverManager(path=driverfolder).install()
driver = webdriver.Chrome(service=Service(driverpath),options=options)

driver.get('https://www.google.com/')

#以下必要な処理を記載
```
話はそれるのですが、データの取り出しはBeautifulSoupが便利です。
紹介は[［Python入門］Beautiful Soup 4によるスクレイピングの基礎](https://atmarkit.itmedia.co.jp/ait/articles/1910/18/news015.html)こちらに譲ります。
Next&Django Rest FrameworkでS3上のデフォルト画像を表示する

# IAMの作成
- プログラムによるアクセスにチェック
- `AmazonS3FullAccess`のポリシーを割り当てる
- svg形式で発行される、アクセスキーとシークレットアクセスきーが後のDjangoの設定で必要になる

# S3の作成
## バケットの作成
- デフォルトでは、パブリックアクセスすべてブロックになっているので、チェックを外す。

## バケットポリシーの設定をする(バケットを選択し、アクセス許可項目にある）
![スクリーンショット 2022-07-26 11.57.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596659/c97d32c5-4ca7-5dc3-91d3-19da4b9d0d69.png)

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "任意",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::バケット名/*"
        }
    ]
}
```

# Djangoでの設定

```
pip install boto3 django-storages
```

```
import environ

env = environ.Env()
env.read_env(os.path.join(BASE_DIR, '.env'))

# Django-Storage
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

# AWS-Settings
AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME')
AWS_LOCATION = 'static'  # s3バケット上のベースとなるファイルパス

# STATIC-Files
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
```

```
python manage.py collectstatic
```
散らばった画像や、jsを集約


# 参考文献
- [Nuxt&Django REST FrameworkでS3を使ってメディアを保存する](https://qiita.com/KueharX/items/0a97fdf7efb6dcd7f775)
- [Amazon S3 のポリシーとアクセス許可](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/access-policy-language-overview.html)
- [S3のバケットポリシー書き方まとめ](https://qiita.com/irico/items/a3ab1f8ebf1ece9cc783)
プリザンターでAPIを利用してデータを更新するpowershell

公式マニュアル
https://pleasanter.org/manual/api

```
#今回は新規作成と更新をサポートすることにする
function Get-ULI(){
    Param($id)
    #idが渡されてくれば、更新URLを返す。URLは自分の環境に合わせて変更してください。
    if($id -eq ''){
        return 'https://example.qiita.com/api/items/1/create'
    } else {
        return "https://example.qiita.com/api/items/$id/update"
    }
}

#前回登録した情報があるかどうかチェック
$idfile = 'c:\users\public\documents\checkerid.txt'
$recordid = ''
if(test-path $idfile){
    #ファイルがある場合は中身を読み込む
    Get-Content -Path $idfile -Encoding Default
    $recordid = Get-Content -Path $idfile -Encoding Default
}

#この辺は決まり事
$header = 'application/json'
$apikey = '利用したいユーザーでプリザンターにログインしてapiキーを発行してください'
$uri = Get-ULI($recordid)
$body = ''

#今回はPC名とログイン名を取ってくることにしました。
$pc = $env:COMPUTERNAME
$user = $env:USERNAME

$body =@{
    apiversion = '1.1'
    apikey = $apikey
    title = $pc    #タイトル
    ClassHash = @{
        ClassA = $pc   #分類A項目
        ClassB = $user #分類B項目
    }
}

$json = $body | ConvertTo-Json

$ret = Invoke-RestMethod -Uri $uri -ContentType $header -Method Post -Body $json
$ret | Select -ExpandProperty Id | Out-File -FilePath $idfile -Force -Encoding default

```

必要なコードはコピペしたつもりですが、いかんせん、動かしているわけではないので、
全部コピーしても動きません。必要なところだけ参考にしてください。
【css】複数行テキストの末尾を３点リーダーで省略する

![スクリーンショット 2022-07-26 15.45.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/035bbe44-5e96-c929-8bca-d9f62acd0d22.png)
![スクリーンショット 2022-07-26 15.45.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/9421cd4d-736e-7077-cb81-6c7d6316f22f.png)
図のように最終行の末尾をCSSのみで３点リーダーで省略する方法についてアウトプットします。さまざまなサイトで書かれていたコードを、コピペしてもうまくいかなかったので誰かのためになれば幸いです。

# 結論
```html:html
<div class="room-title">
  <a href="#">
    タイトル
  </a>
</div>
```
```css:親要素
.room-title{
word-break: break-all;
display: block;　 /*今回の例では不要*/
}
```
```css:子要素
.room-title a{
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
```
### 解説
まず、全体像を説明します。
親要素に「文字がblockの横幅をオーバーした場合、折り返しする」と「block要素であること」を設定します。
子要素（つまり、文字列が入る所）に「親要素をオーバーした分に関してはテキストが消える」と「何行目に消えるのか」を設定します。

#### 親要素について
word-break: break-all;
これは文字が折り返し表示されるように設定するための記述。「word-break: break-word;」といった設定もある。
親要素はどうやらブロック要素を持っている必要があるらしく、aタグなどを親要素にする場合は要注意。

https://developer.mozilla.org/ja/docs/Web/CSS/word-break

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Text/Wrapping_Text


#### 子要素について
display: -webkit-box;
この記述で要素の性質を変化させます。

overflow: hidden;
これではみ出したテキストを隠すように設定できます。

-webkit-box-orient: vertical;
あまり推奨された記述ではないようですが、この記述がないとうまくいきません。要素の方向性を決めるための記述だそうですが、よくわかりません。

-webkit-line-clamp: 2;
何行目で要素を非表示にするか決めます。一番上の図のように３行目で非表示にする場合は「-webkit-line-clamp: 3;」とします。

https://developer.mozilla.org/ja/docs/Web/CSS/WebKit_Extensions

https://qiita.com/watanabejunya/items/40b6c915639be5fa943f

https://developer.mozilla.org/ja/docs/Web/CSS/-webkit-line-clamp

# その他補足情報
・詳しくは調べていませんが、「-webkit-box-orient: vertical;」は一時期サポートされない時期があったらしく、推奨された記述ではないようです（現在はどうかは不明）。webkitはflexboxの記述が普及する黎明期に利用されていたものらしく、今では全てflexboxで代用できるとのこと。
・同様の機能はjsやJquaryでも実装できます。
・私が調べたサイトでは親要素、子要素の関係について記述されているものが少なかったので、うまくいかなかった人はそういう要素関係に注意して実装してみて下さい。

https://developer.mozilla.org/ja/docs/Web/CSS/box-orient
Pardot FormでJava Scriptを使った検証ルールを書く

[Pordotの質問と回答をまとめ](https://qiita.com/Keiji_otsubo/items/a3ccd1370697dd914723)


無料のPardotの環境がないので確かめることはできませんが、仮想でコードを組み立てることはできそうです。
--> 単純にWEBサーバーを使ってHTMLを作れば検証はできるように思います。うまくすれば私でも回答できる範囲を広げることができるかもしれません。ただのJava ScriptでPardotの技術でない。

[Javascript Form Validation to be written in thank you code](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000HEThW)

フィールドのAPI名はわかんないので想像で答えています。

```
<script>
    window.addEventListener("load", function () {
        var firstname = document.querySelector(".First name input");
        var lastname = document.querySelector(".Last name input");
        var element = document.querySelector(".First name div");
        firstname.onkeyup = function (e) {
            if (firstname.value == lastname.value ) {
                element.innerHTML = "<p class='error'>error </p>";
                element.style.display = "block";
            }

        var Email = document.querySelector(".Email input");
        var element2 = document.querySelector(".First name div");
        var Emailstr = Email.value;
        var check1 = Emailstr.includes(firstname.value);
        var check2 = Emailstr.includes(lastname.value);

        Email.onkeyup = function (e) {
            if (check1 && check2 ) {
                element2.innerHTML = "<p class='error'>error </p>";
                element2.style.display = "block";
            }
   

        };
        
    });        
</script>
```

# 関連資料

+ [HTTPS Issues with Javascript in Pardot Forms](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000A8Lw8SAF)
+ [Pardotフォームでバリデーションを設定する](https://fact-marketing.jp/pardot/pardot-validation/)
+ [Tips and tricks to improve Pardot form select fields with JavaScript](https://webocreation.com/blog/tips-and-tricks-to-improve-pardot-form-select-fields-with-javascript/)
+ [Implement JS Validation Against A Required Field In A Pardot Form](https://www.minddigital.com/implement-js-validation-against-a-required-field-in-a-pardot-form/)
+ [JavaScriptを使用してPardotフォーム選択フィールドを改善するためのヒントとコツ](https://webocreation.com/blog/tips-and-tricks-to-improve-pardot-form-select-fields-with-javascript/)
pythonで機械学習するときの自分用テンプレート

## 基本テンプレート
```python
import numpy as np
import pandas as pd

dataset = pd.read_csv("CSVファイル名")
def ping(data):
    df = data.dropna()
    df = pd.get_dummies(df, drop_first=True)
    return df

train = ping(dataset)

from sklearn.model_selection import train_test_split
x = train.drop("答えの名", axis=1).values
t = train["答えの名"]

x_train_val, x_test, t_train_val, t_test = train_test_split(x, t, test_size=0.2, random_state=1)
x_train, x_val, t_train, t_val = train_test_split(x_train_val, t_train_val, test_size=0.3, random_state=1)

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import RandomizedSearchCV

estimator = DecisionTreeClassifier(random_state=0)

param_distributions = {
    'max_depth': list(range(5, 100, 2)),#開始値,終了値,ステップ（刻み値）
    'min_samples_split': list(range(2, 50, 1))
}

#試行回数
n_iter = 100

cv = 5

tuned_model = RandomizedSearchCV(
    estimator=estimator, 
    param_distributions=param_distributions, 
    n_iter=n_iter, cv=cv, 
    random_state=0, return_train_score=False
)

tuned_model.fit(x_train_val, t_train_val)

dd = pd.DataFrame(tuned_model.cv_results_).sort_values('rank_test_score').T
dd.to_csv("me.csv")

best_model = tuned_model.best_estimator_

print(best_model.score(x_train_val, t_train_val))
print(best_model.score(x_test, t_test))

```
## 予測
```python
#テストデータ
test_data = [[0,0],[1,1]]
test_label = best_model.predict(test_data)
print("予測結果→")
print(test_label)
```