OmniAICreator/Qiita-1.07M huggingface dataset:
CloudStorageで静的サイトホスティングをする方法を比べる

# はじめに
GoogleCloudで、静的ウェブサイトをホスティングする方法が大きく分けて2つあります。
それぞれについてメリット・デメリットは何か、どういう状況でどちらを採択すべきか、について検討してみました。


# 前提整理
1. ロードバランサのバックエンドとして、ウェブサイトコンテンツを配置したGCSバケットを指定する
2. ウェブサイトコンテンツを配置したGCSバケットを作成し、CloudDNSのCNAMEにてCloudStorageにリクエストを向ける。

それぞれの方法については公式ドキュメントに公開されている通りです

- 1の方法  
https://cloud.google.com/storage/docs/hosting-static-website?hl=ja

- 2の方法
https://cloud.google.com/storage/docs/hosting-static-website-http?hl=ja

※ 1の方法に関して、コンテンツ配信のためにCloudCDNを使う/使わないで若干の構成差分はありますが、大きな差分ではないため同一とみなして取り扱います。


細かい手順は公式ドキュメントに譲りますが、以下を実施しています

##### 共通
- コンテンツを配置したGCSを公開し、パブリックからアクセス可能にする
- バケットの設定で、Webサイトとしての構成を可能にする

##### 1.の方法
 - 外部ロードバランサを作成し、バックエンドとしてバケットを指定する。

##### 2.の方法
 - コンテンツを格納するGCSバケット名は、ドメイン名と一致させる(サブドメインも可)
 - CloudDNSで、GCSバケット名のレコードとして、CNAMEレコード `c.storage.googleapis.com.`を設定する

# メリット・デメリット

## 1の場合

### メリット
 - CloudLoadBalancingを使っており、SSL証明書によるHTTPS通信のサポートが容易です。
 - CoudCDNを用いた構成にすると、キャッシュの制御もすることができます。
   
### デメリット
 - 外部IPの予約、グローバルロードバランサの作成などでコストが2の場合よりも高くなります。
 - 外部グローバルロードバランサを必要とするため、構築したい環境・GCP組織上の制約に引っかかる可能性があります。

## 2の場合

### メリット
 - GCSとDNSだけで完結するため、コストがかからずシンプルな構成にできます。
### デメリット
 - ロードバランサが無いため、負荷分散は出来ません。
 - HTTPSでの接続がサポートされていません。

# 採択基準
前の章でのデメリットの通り、コストや動きの優劣ではなく機能としての可否で明確な差異があります。

これらを踏まえていくつかのケースでどちらを採択するか考えてみます。

## ケースa HTTPS通信が必須の場合
必然的に1を採択することになります。

## ケースb リソースをグローバルに配置してはならない(国内のみに限定する)場合
必然的に2を採択することになります。

## ケースc 大量のトラフィックが予想される場合
ロードバランサによる負荷分散ができる1を採択するのが望ましいです。

## ケースd GCPの内部ネットワーク内向けにホスティングが必要な場合
1の場合には外部ロードバランサを必要としますので、内部ネットワークで配信したいとしたら合致しません。
2の方法で、かつ限定公開DNSゾーンにてCNAMEレコードの設定をすれば、外部から名前解決されることもなく安全に使えます。


# 参考
 - [静的ウェブサイトをホストする | Google Cloud ](https://cloud.google.com/storage/docs/hosting-static-website?hl=ja)
 - [HTTP を使用した静的ウェブサイトのホスティング | Google Cloud ](https://cloud.google.com/storage/docs/hosting-static-website-http?hl=ja)
 - [Cloud Storage トラブルシューティング | Google Cloud ](https://cloud.google.com/storage/docs/troubleshooting?hl=ja#cnames)
【機械学習】WindowsでcuMLとかcuDFを使えるようにしていく【RAPIDS】

## cuMLってなんぞ
NVIDIAが提供するRAPIDSというオープンソースライブラリに含まれるSk-learnのGPU版です。
せっかくGPUがあるのでこっちを使ってみたいと思ったのですが、なんかwindowsはサポートしてないらしい・・・というわけでローカルでUbuntuを使ってcumlが使える環境を作っていきます。


詳しくは↓
・[RAPIDSってなに？](https://www.slideshare.net/NVIDIAJapan/rapids-120510206)
・[Sk-learnってなに？](https://aiacademy.jp/media/?p=664)

## 実行環境
OS:Windows11
CPU:Intel core i-7 12700H
GPU:GEFORCE RTX3060 Laptop(NVIDIA Pascal™ 以上があればOK)

## 環境構築
[RAPIDSの公式ドキュメント](https://docs.rapids.ai/install)を参照しながら準備していきます。
#### ①WSL2とUbuntuをインストール
これはめっちゃ簡単です。
Windows PowerShellを管理者権限で開き下記のコマンドを入力すればOK
```PowerShell.
wsl --install
```
これだけでWSL2とUbuntuが入ります。(スタートメニューにUbuntuがあると思います。なければ検索)

#### ②NVIDIAのドライバーを最新のやつにする
↓ここでご自身のグラボに合うドライバーをダウンロードしてセットアップしてください。
[NVIDIA Driver Downloads](https://www.nvidia.com/download/index.aspx)

#### ③Ubuntuにログインする
Ubuntuを起動するとユーザーネームとパスワードの入力を求められるので、適当にユーザー名とパスワードを決めて入力します。
ちなみに一度Ubuntuを削除して再インストールした場合は[こちらの手順](https://www.techgaku.com/fix-ubuntu-boot-error-on-wsl-after-reinstall/)に従って初期化してください(多分初期化しないとエラーが出ます)

#### ④Minicondaをインストールする
以下をUbuntuのプロンプトに入力してください。(MinicondaではなくAnacondaでも可。好みで)
```Ubuntu.
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
```

時々yes,noの回答を求められますが、全部yesで大丈夫です。
インストールが完了したらcondaのpathを通していきます。
まず、編集用のテキストエディタをインストールします(なんでもよい。ここではgeditを使う)
あとアップデートもしておく(これやらないと404エラーが出た)。
```Ubuntu.
sudo apt-get update
sudo apt install gedit
```
終わったら.bashrcを編集していく。Ubuntuで下記を実行
```Ubuntu.
gedit ~/.bashrc
```
そしたらテキストエディタが開くので、一番下までスクロールして下記を入力。

export PATH=~/miniconda3/bin:$PATH

入力したらSAVEをクリック
![qiita用_text.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1601909/2af9a63f-473e-8515-b7a0-1a5dd7a7d0bc.png)
Ubuntuで下記を入力して設定を有効にする。
```Ubuntu.
source ~/.bashrc
```

#### ⑤RAPIDSをインストールする
[RAPIDS Release Selector](https://docs.rapids.ai/install#selector)を使用してRAPIDSを入れていく。自分はデフォルトのままやりました。
```Ubuntu.
conda create -n rapids-23.02 -c rapidsai -c conda-forge -c nvidia  \
    rapids=23.02 python=3.10 cudatoolkit=11.8
```
※conda create -n の後に続く「rapids-23.02」は仮想環境の名前なので、すきな名前に変えて大丈夫です。

#### ⑥RAPIDSの動作確認
仮想環境がアクティベートの状態で
```Ubuntu.
python
```
でPythonを起動し
```Python
import cudf
import cuml
print(cudf.Series([1, 2, 3]))
```
と実行して正常に動いていれば無事インストール完了です！

WSLまわりで躓いたこととかほかにも記事にするかも。
ではまた。
[有料級]　Rails7(Turbo), Docker, Bootstrap5を使ったtodoリストの作り方第1章-2(Todoリスト一覧表示編)

## 前回のあらすじ
ここまでみていただきありがとうございます！
前回はTodoリスト準備編でTodoリストの開発の準備を行いました。
[[有料級]　Rails7(Turbo), Docker, Bootstrap5を使ったtodoリストの作り方第1章-1(Todoリスト準備編)](https://qiita.com/streasure0426/items/45446e2b2c5d3fa3104a)
早速始めてみましょう。

## 事前準備
Dockerを一度止めている方はこちらのコマンドでDockerを起動し、コンテナに入りましょう。
``` bash
docker-compose up -d
docker-compose exec app bash
```

## コントローラーの編集
まずは全体テストとして書いたコードを全て消しましょう。
``` diff_erb: app/views/todos/index.html.erb
- <h1>Indexのページです</h1>
- <h1 class="text-danger">Textの色が赤くなります</h1>
```
こちらで
http://127.0.0.1:3050
のページは白紙になりました。

### indexメソッドの編集
indexメソッドを編集していきます。
コントローラーのファイルに次のようなコードを書いてみてみます。
``` diff_ruby: app/controllers/todos_controller.rb
class TodosController < ApplicationController
  def index
+   @todos = Todo.all
  end
end
```
コードの説明をします
- `@todos` : 変数
- `Todo.all` : 前回作成したTodoデータを全て取得する

こちらでコントローラーの編集は終了です。

## ビューの編集
次にviewファイルを編集します。
### slimファイルへの変換
viewファイルを編集する前にコードを書きやすくするためにviewファイルをerb形式からslim形式に変更しましょう。

まずGemfileの一番下に以下のgemを追加します。
``` diff:Gemfile
+ gem 'slim-rails'
+ gem 'html2slim'
```
gemを追加したらターミナルで以下のコマンドを入力します
```bash
bundle
```
こちらでslim形式のファイルが使えるようになりました。
ターミナルで以下のコマンドをうち、viewファイルの全てをslim形式にしましょう
``` bash
erb2slim app/views app/views -d
```
こちらで全てのviewファイルがslim形式に切り替わりました。
実際にファイルがslim形式になっているか確かめてみてください。

### viewファイルの編集
slim形式に変更できたのでviewファイルを編集していきます。
今回はテーブル形式で一覧表示させたいと思います。
```slim: app/views/todos/index.html.slim
h1 Todo一覧

table.table
  thead
    tr
      th scope="col" 題名
      th scope="col" 詳細
  tbody
    - @todos.each do |todo|
      tr
        td = todo.title
        td = todo.description
```
コードの説明をします
- `@todos.each do |todo|` : eachメソッドを使って@todosに格納されているデータを一つ一つ取り出しています。

こちらで一覧表示できるようになりました。
画面はこのようになれば成功です。
![スクリーンショット 2023-04-06 18.40.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982962/54acaaf7-97fd-dc47-f16b-4f1a9eaaa756.png)

実際にtodoが一覧表示されているかは新規登録編で検証します。

今回はここまで！

続けて読んでもらうとありがたいです！

[[有料級]　Rails7(Turbo), Docker, Bootstrap5を使ったtodoリストの作り方第1章-3(Todoリスト新規作成編)
](https://qiita.com/streasure0426/items/b0f2efcdd303449a5f54)
Chromeの印刷選択時にクラッシュする問題の解決方法

## 症状
Chromeの印刷機能を実行すると、必ずクラッシュする

## 修正方法
Windowsの「設定 → デバイス → プリンターとスキャナー」から接続できないプリンターを削除する
以上

##### あとがき
存在しない接続先があるだけでなんでクラッシュするんでしょうね...
詳しい方いらっしゃれば、コメントでご教授のほどよろしくお願いいたします。
Power Automate for desktop の基本操作を覚える

こちらの記事の内容は、以下の書籍の勉強の記録です。
書籍の内容を合わせてご確認いただくと、分かりやすいものと思われます。

https://www.amazon.co.jp/%E3%81%A7%E3%81%8D%E3%82%8BPower-Automate-desktop-%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E3%81%82%E3%83%BC%E3%81%A1%E3%82%83%E3%82%93/dp/4295015938/ref=sr_1_6?keywords=power+automate+%E6%9C%AC&qid=1680744459&sprefix=Power+Automate%2Caps%2C163&sr=8-6

基本的には、私の勉強記録ですので気楽にご覧いただければと思います。
最初からご覧になりたい方はこちら。▼

https://qiita.com/inaho3517/items/c1e702f763631d3fd081

# 勉強内容の確認

書籍について公開されている目次は以下の通りです。

　＜基本編＞
　　　第１章　[Power Automate for desktopの基本を学ぼう](https://qiita.com/inaho3517/items/c1e702f763631d3fd081 "Power Automate for desktop を勉強する話")
　　　**第２章　業務の自動化に必要な基本操作を覚えよう**　　◀ 本日はこちら！
　＜活用編＞
　　　第３章　[Excelの作業を自動化しよう](https://qiita.com/inaho3517/items/490fe4e36b981ea2b135 "Power Automate for desktopでExcelの作業を自動化してみる")
　　　第４章　[Webフォームへの入力を自動化しよう](https://qiita.com/inaho3517/private/3eb2edd276b9c8222f97 "Power Automate for desktopでWebの操作を自動化してみる")
　　　第５章　業務シーン別のテクニックを覚えよう

今日は、基本操作を覚えます！💪

# ツールの基本操作を覚える
どんなRPAツールでも、まず覚えなければならないのが「基本操作」！
ということで、書籍の通りに学習していこうと思います。

こちらの書籍のコンセプトは「**作りながら覚える**」が基本のようです。

最初に業務手順の整理の解説があり、そのあとツールを実際に触っていきます。
基本操作の説明概要は以下の通りでした。

* ２種類の作成方法
* 実行のしかた
* ロボットの編集方法
    1. 変数について
    1. 繰返し処理について
    1. 条件分岐について
* エラーの確認

RPAのロボット作成に必要な内容は網羅されているようです。
これは分かりやすい構成！

# 本日の勉強メモ
ではさっそく、書籍通りに勉強していきます！
## 業務手順の整理
紙とペンでのアウトプット方法について、例を交えて解説されています。
やはり基本は「書く」ことですよね♪
そして整理した後のことも説明されています。勉強になる～。
また、書くのが面倒……という人のためのスキルアップの解説まで。（もちろん動画付き）
至れり尽くせりですね！😁
## ２種類の作成方法
RPAツールはだいたい２種類の作成方法がありますが、それぞれの手順が解説されています。
どこに何を配置するかはもちろん、各操作について解説が細かく付いています。
また、スキルアップのコラムも便利機能やロボットの動きが確実に動く工夫について紹介されていて、かなり勉強になります！独学では得られない情報ばかりでありがたい🎶
## 実行のしかた
完成したロボットの実行・編集の手順についての説明でした。
ロボットの動作確認をするときの一時停止の方法も記載されていて、この方法が頭に入っていれば初心者でも一つずつ動きを確認できそうだなと改めて構成に感心しました😁
また、クラウド上に保存されてしまうロボットを別アカウントに移す方法も記載されていて、ユーザーのいろいろなニーズに対応した内容が記載されています。
## ロボットの編集方法
いよいよロボットの作成編！ワクワクです😆
### １．変数について
この辺りはね、まあプログラミングには必須の知識ですよね～。
しかし変数に２種類あって、それぞれの使い分けは改めて勉強になりました！

また、変数の編集方法のお作法が知れてよかったです。
な～んとなくでも、もちろん使えるんですが、手順通りにやるとスッキリしますね。

それにしても変数の値が……関係者に関連する特産物になってる🤣
### ２．繰返し処理について
繰返し処理には２種類の方法の説明があることが分かりました。
それぞれの使い分けも丁寧に説明されていて、用意された教材で動きが確認できました！
また変数の扱いに慣れませんが、何回かやっていくうちに慣れていけそうな予感。
ここでは初心者の苦戦しそうな特殊な文字列の入力方法まで解説されていて、丁寧な作りに感心しました！
### ３．条件分岐について
条件分岐は繰返し処理よりも複雑な作りですが、なんとかクリア！
英語での表現が多いので、最初は混乱しそうですね💦
ただ、ここも丁寧に解説されているのでちゃんと作成できましたよ💪
## エラーの確認
こちらも問題なくクリア！
エラー内容が日本語で出てきているので、エラーの修正とかも大丈夫そうかも、と一安心しました。
別のツールのお話になりますが、エラーの時に英語ばかりで頭がパンクした思い出があります💦
訳しても一向に何のことか分からず、そのツールの勉強を断念しましたが、これなら続けられそう！
# 本日のまとめ
独学で勉強していて、ふわっとした知識しかありませんでしたが、基礎固めが無事できました。
ただ、数日明けたら忘れそうなので、続けて第３章に入ろうと思います。

次回もお楽しみに！😄
MySQL接続のエラー（SQLSTATE[HY000] [1045]） の対処法

＜発生した問題＞
xamppを使用してPHPとMySQLの勉強をしている時、
SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES)
が発生した。

＜環境＞
OS：Windows11 Home（Ver.22H2）
MySQL：Ver. 10.4.24
XAMPP、phpMyAdminを使用

＜対処法＞
①XAMPPでApacheとMySQLを起動する。
②XAMPPでShellを起動する。
③Shellに以下を入力してEnterを押す。
```
mysql -u root
```
※今回はこの時点でMySQLにログインできた。
以下のようなログが表示された。(一部紹介)
```
Welcome to the MariaDB monitor.  Commands end with ; or \g.
 ```


④Shellに以下を入力して、Enterを押す。
```
use mysql
```


⑤Shellに以下を入力して、Enterを押す。
（MySQLというデータベースを使用する。という指定を行う。）
```
flush privileges;
```


⑥Shellに以下を入力して、Enterを押す。
```
ALTER USER 'root'@'localhost' IDENTIFIED BY '任意のパスワード';
```
※'任意のパスワード'は設定したいパスワードを入力してください。


⑦XAMPPでMySQLを再起動する。Shellに以下を入力してEnterを押す。
```
mysql -u root -p
```
※パスワードを聞かれたら、⑥で設定したパスワードを入力し、Enterを押す。


⑧以下のようなログが出たらログイン成功。
```
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.4.24-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```


最後に以下の変更もお忘れなく...。
・PDOに設定したパスワード
・phpMyAdminのconfig.inc.php内のパスワード
　ファイル場所…C:\xampp\phpMyAdmin\config.inc.php
```
$cfg['Servers'][$i]['password'] = 'xxxxxxxx';
$cfg['Servers'][$i]['controlpass'] = 'xxxxxxxx';
```


＜参考サイト＞
https://blog.senseshare.jp/forget-rootpassword.html


＜エラーが発生した原因＞
ibdata1ファイルを削除したことが原因だと思う。
エラーが発生する前にXAMPPのMySQLが起動しなかった。
MySQLのdataフォルダ内をbackupフォルダを使用して復元したが、
誤ってdataフォルダ内のibdata1ファイルを削除してしまった。


※この記事に関して、個人的にメモを残しているだけなので、
違っている点があれば申し訳ないです。
AWSのSAA試験に合格するまで

# はじめに
インフラ未経験でAWS Certified Solutions Architect(SAA)試験に一発合格することができました。
合格するためにどのように勉強したか、何に気を付けたらいいのかをご紹介いたします。
受験を検討している方の参考になれば嬉しいです。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124412/87d7b775-053b-7d80-7607-f2358f0db5d5.png">

ギリギリでした、、(汗)

# 受験の経緯
今までにサーバを立てた経験すらなくインフラ関係に疎かったのですが、FY23の組織変更で基盤運用チームに配属されることになりました。
社内基盤がAWSで構築されていることもあり設計・構築できることは必須のスキルでしたので、最低限の知見を習得しなければいけないと思い資格の取得を目指すことに決めました。
また、インフラに関しての基礎知識も習得できると感じた点も受験のきっかけになりました。

# 前提知識
* 基本情報技術者試験
* AWSの実務経験１年弱

配属からテスト環境の構築(EC2)や不要な環境の棚卸などの業務を行っていましたが、気づけば1年ほど経っていました、、
ぼちぼち勉強は続けていたのですが、さすがに受験しないとやばいと思い申し込みをしてから2か月弱ほどは集中して取り組みました。

# 学習教材
### 概要理解
#### [【SAA-C03版】これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座](https://www.udemy.com/course/aws-associate/)
SAA試験の範囲でAWSサービスをハンズオンで学べる講座です。
長尺の講座になりますが、資格取得のためだけではなく実務でも活きる知識を学ぶことができます。
この講座を一通り受講すればAWSサービスの全貌は理解できるようになります。
AWSサービスの変更があっても内容の更新がされるので、最新の情報に即した非常に優良な講座だと思います。
まずは受講することをおすすめします。

https://www.udemy.com/course/aws-associate/

### 問題演習
#### [【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)
標準レベル4回分+高難度レベル2回分の計6回分が収録されています。
設問数や回答時間などが本試験と同じ構成になっているので、合格ラインになるまで何度もテストすることをおすすめします。
私が受けた試験と比べるとこちらの模擬試験問題の方が難しかった印象です。
すべての模擬試験が合格ラインを越えるようになっていれば合格しやすいかもしれません。

https://www.udemy.com/course/aws-knan/

#### [AWS認定資格 無料WEB問題集＆徹底解説](https://aws-exam.net/saa/)
基本的には模擬試験で学習していましたが、試験当日の追い込みとして利用していました。
ランダム順や難しい順など問題の出題順序を変えられるので、試験日の朝や移動中に使うにはおすすめです。

https://aws-exam.net/saa/


# 試験を終えて
試験を終えて大事だったなと思った観点を整理します。
### 問題文の意図を読み取る
問題文の最後には必ず問いが入っています。
SAA試験は問題文が長文であることが多いので、まずはそこから読むと内容が頭に入ってきやすいです。
また、引っ掛け問題を間違えることも少ないです。
私は「**最も**」や「**最小限の**」などの問いはよく間違えていました。

**例題**
設計しているアプリケーションは、ファイルを受信して​​処理します。通常、ファイルのサイズは約4GBで、アプリケーションはファイルからメタデータを抽出します。これには通常、各ファイルに数秒かかります。更新のパターンは非常に動的で、アクティビティがほとんどない時間で、その後短時間で複数のアップロードが行われます。

次のソリューションの中で最もコスト効率が高いのはですか？

ア、Kinesisデータストリームを使用してファイルを保存し、Lambdaを使用して処理します
イ、ファイルをS3バケットにアップロードし、Amazon S3イベント通知を使用してLambda関数を呼び出してメタデータを抽出します
ウ、ファイルをSQSキューに配置し、一連のEC2インスタンスを使用してメタデータを抽出します
エ、処理のために別のEC2インスタンスからアクセスできるEBSボリュームにファイルを保存します

引用記事

https://aws-exam.net/saa/saa_q.php?q_id=70

### 環境構成図を思い描く
SAA試験はAWS Well-Architected フレームワークの知識を求められるので、問題文を読んで構成図を思い描けるようになるといいです。
思い描いた構成図とWell-Architected フレームワークを比べてみた時の差異が回答になることが多いです。
学習教材を繰り返し勉強して構成図が想像できると理想です。
さらに、AWSで環境構築してみるとなおよいと思います。

[イメージ図]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124412/59699f36-6710-f4bf-2c5b-cea113c9dd54.png)

引用記事

https://www.ketancho.net/entry/2018/05/07/080000


# 今後の目標
今後AWSを利用して社内でやってみたいことをまとめてみました。

* AWSを用いたBizRobo!環境構築のナレッジ・Tipsを公開する
* スケーラブルで高可用な基盤の構築・運用をする
* 不要なコストのカットと最小力の管理体制を築く

まだまだ力不足なので知見を深めていきたいと思います。
社内外によい影響を与えられるように邁進します。
# 終わりに
SAAを取得するために勉強してよかったと感じています。
当初はインフラのイの字も知らない状態でしたが、受験勉強をしたことによって今では上長やベンダーさんと環境構築についての議論ができるようになりました。
AWS Well-ArchitectedフレームワークはAWSの基礎でもあり、インフラの基礎でもあるのでこれからインフラ関連のお仕事を始められる方は受験してみても良いかもしれません。
個人のスキル評価に箔が付くのも良いポイントですよね。

SAA試験を受講しようと検討している方の一助になれば幸いです。
Monaca + NCMB + ChatGPTでAIチャットアプリを作る（その1：画面仕様とNCMBの初期化）

NCMBでは公式SDKとしてSwift/Objective-C/Kotlin/Java/Unity/JavaScript SDKを用意しています。また、それ以外にもコミュニティSDKとして、非公式ながらFlutter/React Native/Google Apps Script/C#/Ruby/Python/PHPなど幅広い言語向けにSDKが開発されています。

今回は公式SDKの一つ、JavaScript SDKとFramework7を使ってChatGPTを用いたチャットアプリを作ってみます。まず画面の仕様とSDKの初期化について解説します。

## コード

今回のコードは [NCMBMania/monaca-chatgpt](https://github.com/NCMBMania/monaca-chatgpt) にアップロードしてあります。実装時の参考にしてください。


## 利用技術について

今回は次のような組み合わせになっています。

- Monaca
- Framework7
- NCMB
- OpenAI API

## 仕様について

今回のアプリは以下のような機能があります。

- チャット画面
- メッセージをNCMBに保存
- OpenAI APIを使って返答を取得
- 返答をNCMBに保存

ChatGPTでは過去のメッセージもAPIで送信することで、以前の内容を踏まえた回答をしてくれます。過去のメッセージをNCMBに保存しているので、復元が容易です。

## 利用する機能について

このチャットアプリで利用しているNCMBの機能は以下の通りです。

- データストア
    - データ登録
    - データ検索
- スクリプト
    - OpenAI APIの実行

## 画面について

現時点で、画面は以下の1つのみです。

### チャット画面

チャット画面はFramework7の[メッセージコンポーネント](https://framework7.io/docs/messages)を使っています。

![0985 localhost - 0406170656.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/958814b4-a59a-7182-93f1-afa7000ecf87.jpeg)


### SDKのインストール

今回はMonacaのJS/CSSコンポーネントの追加と削除より、NCMBを追加します。アプリのテンプレートはFramework7のJavaScript版（VueやReactではなく）を選択しています。

## NCMBのAPIキーを取得

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)にてアプリを作成し、アプリケーションキーとクライアントキーを作成します。

## js/config.jsonの作成

js/config.jsonを作成し、その中に先ほど取得したNCMBのAPIキーを設定します。内容は次のようになります。

```
{
	"applicationKey": "YOUR_APPLICATION_KEY",
	"clientKey": "YOUR_CLIENT_KEY"
}

```

## 初期化

初期化は `js/app.js` にて行います。config.jsonを読み込む関係上、非同期処理内にて行います。cordovaの有無（アプリまたはプレビューの違いを検知）によって初期化時のイベント処理を変えています。

```jsx
// NCMBの初期化用
const event = window.cordova ? 'deviceready' : 'DOMContentLoaded';
document.addEventListener(event, async (e) => {
	// この中に処理を書きます
});

```

config.jsonの内容を読み込んで、NCMBとFramework7の初期化を行います。

```jsx
window.config = await (await fetch('./js/config.json')).json();
window.ncmb = new NCMB(config.applicationKey, config.clientKey);
window.app = new Framework7({
	name: 'My App', // App name
	theme: 'auto', // Automatic theme detection
	el: '#app', // App root element
	// App store
	store: store,
	// App routes
	routes: routes,
});

```

これでNCMBの初期化が完了します。

## ルーティング設定

チャット画面のルーティングを `/home/` として `js/routes.js` に定義します。 

```jsx
const routes = [
  {
    path: '/',
    url: './index.html',
  },
  // チャット画面
  {
    path: '/home/',
    componentUrl: './pages/chat.html',
  },
  // Default route (404 page). MUST BE THE LAST
  {
    path: '(.*)',
    url: './pages/404.html',
  },
];
```

## まとめ

今回はチャットアプリの仕様と画面、NCMBの初期化までを解説しました。[次回はOpenAI APIの呼び出し（スクリプト）](https://qiita.com/goofmint/items/f1d7449dcecfb4075002)について解説します。
[UVM] Nested classの中でuvm_info()を使う

# 問題
下記サンプルコードのようにuvm_componentの派生クラスの中でNested classを定義したところ、uvm_infoの部分でコンパイルエラーとなってしまったのでその原因と対策を調べてみました。
```Verilog
import uvm_pkg::*;
`include "uvm_macros.svh"

class Outer extends uvm_component;
  `uvm_component_utils(Outer)

  class Inner;
    function void print_message(uvm_component caller);
      `uvm_info(caller.get_type_name(), "Test", UVM_MEDIUM)
      // `uvm_info_context(caller.get_type_name(), "Test", UVM_MEDIUM, caller)
    endfunction
  endclass

  function new(string name, uvm_component parent);
    Inner inner;
    super.new(name, parent);

    inner = new();
    inner.print_message(this);
  endfunction
endclass

program top;
  initial begin
    Outer outer;

    outer = Outer::type_id::create("top", null);
  end
endprogram
```

```text
Error-[IRPCM] Illegal reference to parent class method 
testbench.sv, 9 
"uvm_report_enabled" 
  The method call resolves to a non-static task/function  
  'uvm_report_object::uvm_report_enabled' of an ancestor class. Such  
  references to non-static method are not allowed. 
  Please declare the method as static.
```


# 解決方法
uvm_info()ではなくuvm_info_context()を使いましょう。
上記コードでuvm_info()をコメントアウトし、下の行のuvm_info_context()のコメントアウトを戻すと動作するようになります。

同様にuvm_warning()はuvm_warning_context(),
uvm_error()はuvm_errro_context(), uvm_fatal()にはuvm_fatal_context()でそれぞれ置き換えることができます。

# 説明
エラーメッセージからも推測できますがuvm_info()のマクロは内部でuvm_report_enabled()を呼んでいます。uvm_componentの派生クラスであれば、親クラスのuvm_report_objectの中で定義されたuvm_report_enabled()が継承されて、結局自分が持っているuvm_report_enabled()が呼ばれることになります。
一方上記のNested classの場合はInnerの中にはuvm_report_enabled()が定義されていないので、この定義を探しに行き、uvm_report_object::uvm_report_enabled()を見つけてしまいます。エラーメッセージの通りこの関数はstaticではありませんのそのまま呼び出すことはできずコンパイルエラーとなります。

uvm_info_context()はuvm_report_object内の関数ではなく、uvm_package内の関数を使用します。こちらはnew()しないでも使用できるのでコンパイルエラーにはなりません。追加の引数としてcontextを渡さなければならないので、本例ではOuterのインスタンスを渡しています。外側のインスタンスを渡すのが難しい場合はuvm_root::get()でルートのインスタンスを渡してしまっても構いません。この場合uvm_componentの階層によるMessage制御が効かなくなるなどの機能の制限があります。

余談ですがuvm_objectやmoduleからuvm_info()を使う場合は(uvm_report_object内で定義されているものではなく)uvm_packageの中で定義されている関数が呼ばれます。このため上記のような問題は起きません。
mavenにプロキシを設定したが反応されない事

## 環境

- macos 13
- maven 3.9.1

## 症状

設定ファイルにプロキシを記述しましたが、ビルドする時、mavenはプロキシを経由しませんでした。

`/opt/homebrew/Cellar/maven/3.9.1/libexec/conf/settings.xml`に下記の内容を記述した上で、

```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <proxies>
    <proxy>
      <id>http</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>127.0.0.1</host>
      <port>3341</port>
      <nonProxyHosts>localhost|127.0.0.1</nonProxyHosts>
    </proxy>
  </proxies>
</settings>
```

`mvn clean package`をすると、`Downloading: https://github.com/xxx.exe`は行き詰まった。

## 原因

`<protocol>http</protocol>`に注目してください。このプロトコルは、あなたのプロキシ自身の種類じゃなくて、プロキシさんに代理してもらいたいプロトカルの種類です。

プロキシ自身のプロトカルは、一般的に`socks`、`http`、`https`三種類を指します。一方で、代理してもらいたいプロトカルは、あなたがネット通信をするプロトカルです。`mvn`でほとんどの場合、`https`を利用します。二つのプロトカルは、一致しなくても構いません。

ですから、先の記法を変えて、

```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <proxies>
    <proxy>
      <id>http</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>127.0.0.1</host>
      <port>3341</port>
      <nonProxyHosts>localhost|127.0.0.1</nonProxyHosts>
    </proxy>
    <proxy>
      <id>https</id>
      <active>true</active>
      <protocol>https</protocol>
      <host>127.0.0.1</host>
      <port>3341</port>
      <nonProxyHosts>localhost|127.0.0.1</nonProxyHosts>
    </proxy>
  </proxies>
</settings>

```

`https`プロキシの項目も追加して、無事解決いたしました。
挿入ソート（Insertion Sort）を使ってみた。

# はじめに
Insertion sortは、リスト内の値をインデックス順に見ていき、現在の値よりも数の小さいものがあったら、その値を適切な位置まで移動させるようなソート方法である。

# 実装【Python】
```python:insertion_sort.py
# 一回のリストのループ中に数の逆転があったら、その値を適切な位置まで移動させる
from typing import List


def insertion_sort(numbers: List[int]) -> List[int]:
    len_numbers = len(numbers)
    for i in range(1, len_numbers):
        # 現在の最小の値を保持しておく
        temp = numbers[i]
        j = i - 1
        # 適切な位置まで移動させる
        while j >= 0 and numbers[j] > temp:
            numbers[j+1] = numbers[j]
            j -= 1
        numbers[j+1] = temp
    return numbers


if __name__ == "__main__":
    import random
    nums = [random.randint(0, 1000) for _ in range(10)]
    print(insertion_sort(nums))

```

# 参考
https://www.udemy.com/course/python-algo/
Javaの環境構築と、基礎構文解説

## はじめに

Javaの環境構築、簡単な構文を書いてそちらの解説までしたいと思います！
Javaについてもっと詳しく知りたい方は
過去にJavaについて解説している記事を投稿していますので、
こちらをご覧くださいm(__)m
https://qiita.com/ooyama-tetu/items/ad7ecfb62bc4c0b5b21f

## Javaの環境構築
Javaの環境構築ですが、JDKをインストールする必要があります。
JDKとは、**Java Development Kitの略で、Javaのプログラムを実行するときに必要な機能がパッケージされたものです**

お使いのパソコンによってダウンロード方法が違うのですが、私はWindowsですのでこちらからダウンロードしました。
https://www.techfun.co.jp/services/magazine/java/windows-jdk-install.html

お次は、Javaの簡単なコードを解説していきます。

## Javaの構文の解説
まずはこちらのコードをご覧ください。

```
class Greeting {
    public static void main(String[] args) {
        System.out.println("Good morning");
        System.out.println("Good afternoon");
        System.out.println("Good evening");
    }
}
```

こちらを実行すると
```
Good morning
Good afternoon
Good evening
```
と、出力されます。
一つ一つ解説していきます。

```
class Greeting {　//1.クラスを定義する
    public static void main(String[] args) { //2.メソッドを定義する
        System.out.println("Good morning"); //3.処理を記述
        System.out.println("Good afternoon"); //3
        System.out.println("Good evening"); //3
    }
}
```
1. Javaではクラスの組み合わせでプログラムを作っていく。Javaの土台となります。また、こちらの名前はファイル名と同じになります。クラス名の最初は大文字になります。
最初にclassと記述するのは「ルール」です。クラスの名前の事をクラス名といいます。{}でくくられた部分をブロックといいます。{}の中にプログラムに命令する処理を記述します。

2. メソッド（プログラミングでの意味は処理）を記述します。メソッドを定義します。この記述はそのまま覚えてください。

3. 処理を記述。パソコンに挨拶を表示させる処理です
System.out.println();　読み方→システム　アウト　プリントライン();
処理の終わりに``;``を付けるのはJavaの決まりです。

ファイルを実行させて文字を表示させます。
その前にコンパイルをします

## コンパイルの解説と方法

まず、コンパイルとは``Javaのプログラムをパソコンが読み取れる機械語に変換すること``です。

以下のコマンドをターミナルに打ち込みます。
```
javac ファイル名（今回はGreeting.java）
```

すると、フォルダにGreeting.classというファイルが生成されます。

次にこのファイルを実行します。

## 実行方法

以下のコマンドをターミナルに打ち込みます。
```
java ファイル名（今回はGreeting）
```
エンターを押すと、、
```
Good morning
Good afternoon
Good evening
```

このように表示されます！
このようにJavaはコンパイル→実行という方法で行います。

## おわりに

今回はJavaの環境構築、簡単に表示方法を解説しました。
自身の備忘録を兼ねて、随時投稿していきますのでよろしくお願いいたします。
[GAS] ライブラリの中からスプレッドシートを取得できるのか？→できる

# こんな事がありました

複数のスプレッドシートに、全く同じGASを適用させたい。
スプレッドシートごとにスクリプトエディタ入れて、コードをコピーして、、、ってやりたくない。
コードを「ライブラリ」にして、各スクリプトエディタから読み込むだけにしたい。

疑問点として「スタンドアロンであるライブラリから、`Spreadsheet.getActive()`ってできるんだっけ？」
の調査。

結果としては「できる」



# スタンドアロンスクリプトからは当然無理

```js
/**
 * ライブラリ(スタンドアロンスクリプト)の中のコード
 */
function getSsName(){
  const ss = SpreadsheetApp.getActive()
  console.log(ss.getName()) 
} 
```


```:実行結果
TypeError: Cannot read properties of null (reading 'getName')
```

そりゃそうですよね。スタンドアロンスクリプトなんだから `SpreadsheetApp.getActive()` できないですよね。


# ライブラリにして読み込むとスプレッドシートを取得できる

上記のスクリプトを「ライブラリ」として公開する。(公開の仕方は調べてみてください)

下記は「そんなことできるのか？」という名前のスプレッドシートにバインドされているスクリプト。上のライブラリを `LIB` としている

```js:スプレッドシートにバインドされてるスクリプト
/**
 * 「そんなことできるのか？」という名前のスプレッドシートにバインドしているスクリプト
 */
function myFunction() {
  LIB.getSsName()
}
```


```: 実行結果
そんなことできるのか？
```


よかった。コード管理が楽になりそう。
XCodeの操作について

【前提】
・アプリ経験が薄いエンジニア

【記載内容】
・操作に関して

【内容】
・GoogleService-infoはFirebaseから直接いじるとのことで、基本的にFirebaseのjsonファイルをダウンロードしてファイル毎直接修正するのが通例らしい。

・info.plistは直接いじることが多いが、基本はxmlような表示ではなく、UIから直接いじる方が多いとのこと。
PATを使ってGitLabとVsCodeを連携しよう

初投稿です。
書き方がまだ分からないので、読みづらい記事になると思いますが、ご容赦ください。

今回は自分の備忘録のためにも載せておきます。
その前に今回の記事を記載するに至った経緯を述べます。

# 経緯
私自身４月に新しい会社に入社し、最初の研修は簡単なアプリを作成することから始まりました。
そこで、コードを共有するためにGitLabを使用するとのことでした。
でもそこで思ったんですよね。

VsCodeと連携して使いたくね？とね！
そのために、最初はSSH接続を試しましたが全然つながらず、会社の同僚に質問するとhttps経由でPATを使う方法を試してみるといいよ！
回答がありました。

そこで、調べてみたのですが。。。

記事が見つからん！

そうして、何とか調べて接続できたので、今日はそのやり方を記載しようと思います。

# 手順
STEP1 VsCodeをインストールしよう
STEP2 GITをインストールしよう
STEP3 GitLabに登録しよう
STEP4 GitLabでプロジェクトを作成しよう
STEP5 VsCodeとGitを連携しよう
こんな手順です。それでは解説していきます。
# STEP1 VsCodeをインストールしよう
これは漁れば記事がたくさん出てきますので割愛します。
適当な記事を参考にしてください。
リンクを載せておきます。
[VscCodeのインストール手順](https://qiita.com/psychoroid/items/7d85ae6bade4a67aedb1)

# STEP2 GITをインストールしよう
こちらも同様なので割愛します。
リンクはこちらをどうぞ。
[GITのインストール手順](https://qiita.com/nakazawaken1/items/bbcb4640cf9aceee5745)

# STEP3 GitLabに登録しよう
まずはこちらにアクセス[GitLabのサイト](https://gitlab.com/users/sign_in)
![gitlab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/9902f28a-9e14-4cd6-c7e4-cacc9b593a10.jpeg)

画像の赤枠をクリックすると
![gitlab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/e044081d-06d5-c58d-6552-e7cd618ce8ca.jpeg)
こんな感じの画面が表示されるので、入力して登録しちゃいます。

# STEP4 GitLabでプロジェクトを作成しよう
GitLabに入り、Create a projectをクリック。
こんな画面が表示されるので、プロジェクト名に任意の名前を入力、Visibility Levelはとりあえずプライベートでよきかと。
必要に応じて内部やパブリックにしてください。
入力したら緑のCreate projectをクリックして完了。
![gitlab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/f9c36a51-c7d8-f8b1-bf6e-839c244d8110.jpeg)

# STEP5 VsCodeとGitを連携しよう
ということで最後に連携しちゃいます。
まずはGitLabの画面の右上から設定を開き。設定画面からアクセストークンをクリックします。
![gitlab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/712eb10d-f7a8-08d8-2467-b11213b1d3e9.jpeg)
すると、こんな感じの画面が出るので任意の名前と有効期限(Expires at)を入力してください。
(有効期限は未入力でもOKです)
スコープはとりあえず、apiとread userにチェック。
そうすると　Create personal access tokenのボタンが活性化するので、クリック。
![gitlab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/4c9097d3-af3e-9dcd-8054-45f91924e311.jpeg)
これでアクセストークンの作成が完了しました。
黒塗りしてあるところに文字列が表示され、後で使うのでこれはメモしておいてください。(忘れると再作成する必要があります。)

次はGitLabのユーザ情報を覚えさせます。
コマンドプロンプトを開いて下のように入力します。
GitLabに登録した際のユーザーネームをnameに、メールアドレスをmail:addressに入力してください。
```
> git config --global user.name "name"
> git config --global user.email "mail:address"
> git config --global core.quotepath false
> git config --global core.editor "code --wait"
```
最後に、複製をローカルに作成します。
コマンドプロンプトで作成したい場所のディレクトリに移動します。
移動したら下記の通りにコマンドを入力して実行してください。
```
> git clone https://oauth2:"アクセストークン"@"URL".git
```
アクセストークンは先ほど、作成したときに発行された文字列ですね。(後で使うといったのはここで使います。)
URLはGitLabから複製したいプロジェクトの画面を開いてそのURLをコピペしちゃってください。
恐らく、こんな感じのURLかなと。。。
https://gitlab.com/ユーザ名/プロジェクト名
ユーザ名はGitLabに登録した名前で、プロジェクト名はSTEP4で作成した名前です。
で、このURLの後ろに.gitをつける必要があります。

これでローカルに複製が出来ました。
あとはVsCodeで複製したフォルダを開けば編集できます。
お疲れ様でした。

こんな感じでVsCodeとGitLabの連携がすることが出来ました。
ただ、手探りでやったので、無駄な手順があったり、上手くいかなかったらごめんなさい。

今回はここまで！ではでは
rails構築時の対処(自分用メモです( ´Д`))


`gem install bundler`と`gem install rails`を行いました。

`rbenv versions`で確認しました。

`rbenv --version `で確認しました。


`bundle install`のコマンド入力により下記エラーが発生

`An error occurred while installing nio4r (2.5.9), and Bundler cannot continue.`


ググって下記コマンド入力
`sudo gem install nio4r`


`An error occurred while installing puma (5.6.5), and Bundler cannot continue.`
のエラーに対しては下記コマンドを入力
`sudo gem install puma -v '5.6.5'`

その後Gemfileにて
```
# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "~> 5.0"
```
という記述から
```
# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "~> 5.6.5"
```
に変更しました

再度
`bundle install`
と打つと成功

`An error occurred while installing nio4r (2.5.9), and Bundler cannot continue.`
上記エラー分は何度も表示されたので、表示されたモジュール名？をひたすらインストールしました。
pi picoでmicropython その34

# 概要
picoでmicropythonやってみた。
練習問題やってみた。

# 練習問題
オセロを実行せよ。

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c15ba5d4-2540-127e-66c0-be57617e6a4c.png)

以上。
[2023/04/27予定] UiPath ホストフィード変更ってなんのこと？

# ホストフィード変更とは？
以下のリリースノートで2023/02/22にアナウンスされた、Automation Cloud の仕様変更です。

https://docs.uipath.com/ja/automation-cloud/automation-cloud/latest/release-notes/release-notes-february-2023

公式パッケージフィードとして従来使われていたMygetフィードの利用が非推奨となり、以下のフィードに変更となります。
新フィード：https://pkgs.dev.azure.com/uipath/Public.Feeds/_packaging/UiPath-Official/nuget/v3/index.json

:::note warn
**注意点**
新フィードへアクセスする際に、ネットワーク環境によってはファイアウォールやProxy等の設定によって通信が出来ない場合があります。その様な場合には、通信許可の為の設定（ファイアウォールの許可リストへの追加、等）が必要になります。
:::

# FAQ
良くありそうな質問について、Q&A形式でまとめます。

## Q: ホストフィードとは何ですか？​
Orchestrator サーバー上において、そのすべてのテナントで共有される唯一の Nuget フィードです。この Orchestrator に接続された Studio/Robot は、このフィードから UiPath の公式アクティビティパッケージをダウンロードします。

## Q: Automation Cloud のホストフィードが変更される、とはどういうことですか？
Automation Cloud に接続された Studio/Robot は、これまではアクティビティパッケージを https://www.myget.org/ からダウンロードしていました。今後は、https://pkgs.dev.azure.com/ からダウンロードするようになります。この変更は自動で行われます。​

## Q: この変更に影響を受けるのはどの範囲ですか？
Automation Cloud に接続している Studio/Robot 環境において、ファイアウォールやProxy等のネットワークの制約により https://pkgs.dev.azure.com/ との通信が遮断されている場合に影響があります。

:::note info
必要なアクティビティパッケージをすべてテナントフィードに配置しているなど、ホストフィードを使っていないケースでは影響範囲外です。
:::

## Q: どのような対応が必要ですか？​
お使いの環境から、https://pkgs.dev.azure.com/uipath/Public.Feeds/_packaging/UiPath-Official/nuget/v3/index.json にアクセスできることを確認してください。アクセスできない場合は、ファイアウォールやProxy等でこの通信をブロックしていないか確認し、許可設定をしてください。​

:::note warn
**動作確認時の注意点**
- ブラウザからの確認では Studio/Robot と異なる通信経路での確認になってしまう可能性があります。Studioのフィード設定を変更して、公式パッケージをダウンロードできるか確認してください。Studioの「パッケージを管理 > 設定」メニューから、フィードの設定が可能です。
- Studio/Robot には、複数のフィードを登録できます。パッケージによっては、ほかのフィードからもダウンロードできるため、影響がないように見える場合があります。
- インストールしたアクティビティパッケージはローカルにキャッシュされるため、直ちに影響が出ないようにみえる場合があります。しかしながら、他の端末、他のパッケージでは影響を受ける場合があるため対応が必要です。
:::

## Q: 対応をしないとどうなりますか？​
Automation Cloud に接続した Studio/Robot は、公式アクティビティパッケージをダウンロードできなくなります。そのため、Robot は自動化プロセスを実行できません。また、Studio では開発に使いたいパッケージをインストールできません。
pi picoでmicropython その33

# 概要
picoでmicropythonやってみた。
練習問題やってみた。

# 練習問題
俺言語インタープリタを実行せよ。
hello worldを表示せよ。

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4829493b-fe8f-2fe8-10a5-d79ea74a71a9.png)


以上。
AppArmor その2: シェルスクリプトを保護する

普通の実行ファイルとシェルスクリプトで AppArmor profile の記述に違いがあるかどうか調べました。

事前準備

```shell
$ echo Hello white > /tmp/white.txt
$ echo Hello black > /tmp/black.txt
$ cat <<'EOT' > /tmp/cat.sh
#!/bin/sh

cat $@
EOT
$ chmod 755 /tmp/cat.sh
$ sudo aa-genprof /tmp/cat.sh 
```

指示に沿って操作すると次のようなプロファイルが出来ました。

```
#include <tunables/global>

/tmp/cat.sh {
  #include <abstractions/base>  # 共有ライブラリへのアクセスなど基本的な権限
  #include <abstractions/bash>  # .profile などシェルスクリプトが読む基本的な権限

  /bin/cat mrix,                # m: 実行出来るメモリを作れる r: 読み込める ix: 親 profile を引き継いで実行
  /bin/dash ix,
  /lib/x86_64-linux-gnu/ld-*.so mr,  # 共有ライブラリ
  /tmp/cat.sh r,                     # シェルスクリプト本体の読み込み
  owner /tmp/white.txt r,            # ファイルの読み込み

}
```

これで、/tmp/white.txt にしかアクセス出来ないシェルスクリプトが出来ました。

```shell
$ /tmp/cat.sh /tmp/white.txt 
Hello white
$ /tmp/cat.sh /tmp/black.txt 
cat: /tmp/black.txt: Permission denied
```

ついでに、不要なルールを削除してシンプルにした profile も載せます。

```
include <tunables/global>

/tmp/cat.sh {
  include <abstractions/base>

  /bin/cat ix,
  /tmp/cat.sh r,
  /tmp/white.txt r,
}
```

ということで、シェルスクリプトではスクリプト本体とスクリプトから呼び出すコマンドに実行権限が必要な以外は普通の profile だという事が分かりました。なぜか上の例だと /bin/sh の権限も不要だったのですが、もしかして必要になるかも。また `include <abstractions/consoles>` が必要になるかも知れません。
FormRecognizerを使った請求書解析


# 概要
本稿ではFormRecognizerの事前構築済みモデルの一つであるInvoiceモデルを使って英語と日本語の請求書それぞれについて検出精度の確認を行いました。

# FormRecognizerStudioを使った解析
まず手始めにFormRecognizerStudioを使って解析を行ってみました。
なお解析にはInvoicesモデルを使用しています。

とりあえずStudio上にあらかじめ用意されているサンプル画像で解析を行った結果が次の画像です。
もとの画像上に検出結果を枠線で囲って表示してくれています。
![スクリーンショット 2023-03-22 131246.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/f198cf9b-b4a5-bdc9-2fdb-cd19aa7f329b.png)
上記の画像からもわかる通り、請求金額や商品名はもちろん支払い期日や住所等も検出できていることが分かります。

さらに検出箇所にマウスを合わせると詳細情報を確認することができます。
ためしに請求金額の詳細情報を表示させてみます。
![スクリーンショット 2023-03-22 132424.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/7d133d77-3b19-7645-9d0b-e72a3c03c104.png)
少し見にくいかもしれませんが、PRICE列の1行目にカーソルを合わせたときの画像を表示しています。単価が30ドルであることが正しく検出できている様子が分かります。

ここでは割愛しますが、他の属性(商品名や個数、合計金額など)についても正確に検出できていることが確認できました。

# 日本語の請求書で試してみる
英語の請求書では上手に解析ができているようなので、日本語の請求書でも解析をしてみましょう。
適当な請求書が見つからなかったので、適当に自作した請求書で解析を行ってみました。
![スクリーンショット 2023-03-22 133846.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/e1a6c3c5-fc90-c54b-da11-fc99105e7e7a.png)

一見したところ請求金額が検出できていない?と思いましたが、表の一番下の欄から合計金額を拾ってきてくれていますね。　すこし不安になる挙動ではありますが一応正しく検出できているようです。
また宛名の一部で誤検知や検出漏れが発生しており、英語版ほどの精度で検出はできていないようです。

なお後日ドキュメントを確認してみたところ、請求書モデルの対応言語は下記の通りとのことでした。英語版ほどの精度が出なかったのはこれが原因かもしれません。

- 英語
- スペイン語
- ドイツ語
- フランス語
- イタリア語
- ポルトガル語
- オランダ語
https://learn.microsoft.com/ja-jp/azure/applied-ai-services/form-recognizer/language-support?view=form-recog-3.0.0より抜粋

レシートモデルなどのモデルでは日本語対応がなされているようなので、
請求書モデルについても日本語対応が行われることを期待したいと思います。
DaVinci Resolve: Text+用 TimeCode の代替え Expression

Text+ にある __TimeCode__ 表示を Expression で作りました。
Fusion ページは使わず、Edit ページのみで完結させられます。
![dr003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/027294db-9d25-0592-cd06-25c0b2f0282e.png)

:::note info
#### 標準 TimeCode との違い
- 開始時間指定が可能
- 標準TimeCodeがフレーム数に対し、1/100秒を表示
- 秒毎に区切り文字を点滅（フォントによっては位置ずれする）
:::
```lua
: -- 複数行宣言
start = "00:00:00:00"; -- 開始タイムコード
-- time値と開始タイムコードから「秒」を算出
seconds = time / comp:GetPrefs().Comp.FrameFormat.Rate; -- time値とフレームレートから秒に
seconds = seconds + string.sub(start, 10, 11) / 100; -- ミリ秒
seconds = seconds + string.sub(start, 7, 8); -- 秒
seconds = seconds + string.sub(start, 4, 5) * 60; -- 分
seconds = seconds + string.sub(start, 1, 2) * 60 * 60; -- 時
-- 「秒」から時分秒ミリ秒を算出
function string:padding(num) return string.sub(floor(num) + 100, -2) end -- 桁揃え関数
ms = string:padding(floor((seconds - floor(seconds) + 0.005) * 100)); -- ミリ秒
ss = string:padding(seconds % 60); -- 秒
mm = string:padding(seconds / 60 % 60); -- 分
hh = string:padding(seconds / 60 / 60 % 24); -- 時
data = {hh, mm, ss, ms}; -- 表示用に配列化
-- 区切り文字を秒毎に切り替えて表示
return table.concat(data, iif(floor(seconds) % 2 == 0, ":", " "));
```

#### Text エリアを右クリックし、プルダウンリストからExpressionを選択
標準 TimeCode と言ってるのは、このリストにある TimeCode です。
![dr001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/596b599e-02fd-0e33-beb0-669ca81fc4cb.png)
#### コードを入力
初期値「Text("Custom Title")」は消してください。
![dr002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/b62b3477-4221-5132-c245-b26ebf33e03e.png)
このエリアで編集は無理だと思います。別途エディタを使ってコピペしましょう。
![dr003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/027294db-9d25-0592-cd06-25c0b2f0282e.png)
テキスト内容を Expression で動的に変更しているだけなので、フォントや位置、サイズは自由に変更可能です。

:::note warn
開始タイムコードの分割をsplit的な関数作って区切り文字を探して分割させようとしたら、おかしな表示になるのでsubで固定位置で抜いています。
「00:00:00:00」型以外の指定は考慮していないので、時やミリ秒が必要なければ、Write On スライダーを使って前後を削ってください。
:::
:::note warn
Text+ クリップをタイムラインに __配置した時の左端__ が time 値「ゼロ」です。
標準の TimeCode 同様、クリップを左に伸ばすとマイナス方向（23時）に伸びます。
:::
### 区切り文字
区切り文字は「:」と「 」（スペース）を交互に使ってるだけなので、フォントによっては位置ずれします。
区切り文字の字間は空きますが、Advanced Controls の __Force Monospaced__ を 1.0 にすれば位置ずれはしなくなります。
![dr004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/29310308-ecbb-2e32-0280-30a58b67925d.png)
![dr005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/b272a8a6-e486-97ff-eeee-da8c2ac05863.png)
「:」の固定でよければ、最終行を以下に変更してください。
```lua
return table.concat(data, ":");
```
CI/CDとは？

# はじめに
本記事は CI/CD についてとなります。
CI/CD 初心者向けに記述したものになります。
筆者が初心者のため備忘録替わりに使ってます^^;

# CI/CD とは
「CI/CD」とは、ソフトウェア開発におけるビルドやテスト・デリバリー・デプロイメントを自動化し、継続的に行うアプローチを指す名称です。
「CI」は「Continuous Integration」の略称で「継続的インテグレーション」と呼ばれます。
「CD」は「Continuous Delivery」の略称で「継続的デリバリー」と呼ばれます。

# CI (継続的インテグレーション)とは
ソースコードを変更してGitHubにアップする度にビルドやテストを自動実行し、コードの品質を一定に保つ手法

# CD (継続的デリバリー)とは
CI(継続的インテグレーション)で検証済みのコードのリリースを自動化することで、リリースを効率化する手法

# CI/CDのサービス例
|サービス|説明|
|---|---|
|AWS CodeBuild|AWSのコードのビルドおよびテスト環境をフルマネージドで提供するCIサービス|
|CircleCI|テスト・ビルド・デプロイなどが管理できるCIツール|
|GitHub Actions|GitHub の CI/CDツール。<br>GitHubから直接コードをビルド、テスト、デプロイが可能。|

# 参考記事
・[CI/CDとは](https://pfs.nifcloud.com/navi/words/ci_cd.htm)
pi picoでmicropython その32

# 概要
picoでmicropythonやってみた。
練習問題やってみた。

# 練習問題
じゃんけんを実装せよ。

# サンプルコード

```
from random import randint

def main():
    hands = {
        0: "gu",
        1: "choki",
        2: "pa"
    }
    rules = {
        (0, 0): "aiko",
        (0, 1): "kati",
        (0, 2): "make",
        (1, 0): "make",
        (1, 1): "aiko",
        (1, 2): "kati",
        (2, 0): "kati",
        (2, 1): "make",
        (2, 2): "aiko",
    }
    while True:
        pc_hand = randint(0, 2)
        user_hand_str = input("0:gu 1:choki 2:pa 3:end\n")
        if user_hand_str == "3":
            print("matane")
            break
        if user_hand_str not in ("0", "1", "2"):
            continue
        user_hand = int(user_hand_str)
        print("you: " + hands[user_hand] + " mi: " + hands[pc_hand] + " -> " + rules[user_hand, pc_hand])
        print("")

```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/27f71ece-1904-f964-e15b-f4d1094abec5.png)



以上。
DynamoDBでResourceNotFoundExceptionが発生する原因と対処

## 事象
DynamoDBのテーブルに対して、アプリケーションから更新した際に、ごく稀にResourceNotFoundExceptionが発生

## 原因
DynamoDBのテーブルを削除し、同一テーブル名で再作成した場合、新たに作成したテーブルへのリクエストで稀に発生するとのこと


## 対応
アプリケーションによるリトライで回避できることが期待されるためリトライで対応する

## 後がき
DynamoDBのとてもニッチなエラーに当たったのでメモ書き程度に残しておきます。
誰かの参考になれば幸いです。
【備忘録】CISCO892J 2台でスタティックルート→OSPFのルート再配信を行う

# はじめに
こんにちは、インフラ系初心者です。
今回、CISCO892Jを用いてスタティックルート→OSPFのルート再配信の練習をします。
ただ、2台しかルーターを持ち合わせておらず、2台だけ再配信の設定を行った事を備忘録として残しておきます。

# 名称
CISCO 1
CISCO 2

# 設定について

ルート再配信は、OSPF(配信先)の設定で行います。
今回、スタティックルート(配信元)は特に設定の必要はありません。

というか、本当は相互で再配信の設定（"CISCO 1" OFPS→スタティックルート "CISCO2"スタティックルート→OFPS ）をしたいのですが、やり方がわからない。
なんなら実務で存在するのかもわからないので一旦割愛します。

※追記　OFPS→スタティックルートについて、そもそもスタティックルートは明示的に設定（管理者が手動で設定）するものなのでありえません。技術的にも存在してない様です。



本当はルーターが3台あるとわかりやすいのですが、無いので、擬似的にCISCO3ルーター≠インターフェースを作成してルート情報としてCISCO2から1に流します。


基本的にインターフェースがアップしていればルートととして設定≠認識させる事ができます。つまり再配信は可能です。（Pingが通るとは言っていない）（そもそも存在しないからね）


物理インターフェースでも可能ですが、ルーター内で完結させる為にLoopbackインターフェースを使います。
普段LoopbackなんてPing用にしか使っていなかったので、そんな使い方あるとはびっくり！（まあ、インターフェースなので当たり前なのですが）


まず、ループバックインターフェースを作ります。

今回は10.0.30.2にCISCO3を想定するので、ループバックインターフェースは/32ではなく、/24で作り10.0.30.2~254の範囲のどこでも設定が可能にします

CISCO_2(config)#int loopback 1
CISCO_2(config-if)#ip add 10.0.30.1 255.255.255.0 
CISCO_2(config-if)#no shutdown
CISCO_2(config-if)#exit

CISCO_2(config)ip route 10.250.1.1 255.255.255.255 10.0.30.2

10.250.1.1 ←ここは存在していなくても、10.0.30.2←ここがアップ(Loopbackにアップできるポートと認識)されていればsh ip route に乗るので10.250.1.1は適当でOK。
10.0.30.2の部分は/24でインタフェースを作ったので、10.0.30.2~254の間ならどれ指定しても動きます。
10.0.30.1はループバックが使ってる（CISCOルーター内に存在する）ので指定できないしそもそも指定できたとしてもsh ip route には乗ってこないと思います。

次にスタティックルートをOSPFで再配信します。

CISCO_2(config)#router ospf 1
CISCO_2(config-router)#redistribute static subnets

これで終了です。
CISCO_1でsh ip routeするとO E2で出てきます。

ここには書いていませんが前提としてCISCO_1,CISCO_2の間でOSPFネイバー関係を気付く必要があります。
gitするとstale fileエラーが出る



# 症状

linuxのqueueシステムで長大計算をしているときに，

```ruby
cat job_file.e13023
FILE :in `p': Stale file handle @ rb_io_flush_raw - <STDOUT> (Errno::ESTALE)
```

なるエラーを吐いて，ジョブが中断されます．


# 原因

gitでpull.rebaseでやっているときにおかしくなります．


# 対策

1.  長大計算のdirectoryはgitしない!
2.  mergeだとOK? -> !


# 詳細

linux上でqueueに長大計算させている時に，jobが中断されることが発生しました．Errorが記録されるのが，

```
bob@asura0 ~/n/frenkel (main)> ls -lat */*.e* 
-rw-r--r-- 1 bob users 408  4月  4 16:40 v096_l050_r0_t700/fp3_4k_096.e13027
-rw-r--r-- 1 bob users 408  4月  4 16:40 v096_l000_r0_t700/fp3_4k_096.e13025
-rw-r--r-- 1 bob users 408  4月  4 16:40 v096_l000_r0_t500/fp3_4k_096.e13024
-rw-r--r-- 1 bob users 408  4月  4 16:40 v096_l000_r0_t900/fp3_4k_096.e13023
-rw-r--r-- 1 bob users 408  4月  4 16:39 v096_l050_r0_t900/fp3_4k_096.e13026
-rw-r--r-- 1 bob users 408  4月  4 16:39 v096_l050_r0_t500/fp3_4k_096.e13028
-rw-r--r-- 1 bob users   0  4月  4 16:39 i8k_v096_l100_r0_t900/fp3_8k_v096.e13029
```

と，一斉に止まりますが，jobによって中断時期が不確定でapplicationのバグと思えなかったのです．

で，gitの同期をかけているので怪しいと思って実験をしてみると，

```bash
> git pull origin main                           (base) 
> qstat -f
all.q@asura1                   BIP   0/64/64        64.03    linux-x64
  13032 0.60500 fp3_4k_096 bob          r     04/06/2023 14:52:50    64
> ls -lat */*.e*
-rw-r--r-- 1 bob users   0  4月  6 14:57 v096_l1000_r1_t500/fp3_4k_096.e13037
> ls -lat */*.e*
-rw-r--r-- 1 bob users 408  4月  6 16:12 v096_l1000_r1_t500/fp3_4k_096.e13037
```

となります．

```
> git config -l
pull.rebase=true
```

となっているのが原因かな．Fileを書き換えるので，i-nodeが変わるようです．

```
> git config --global pull.merge true
> git config --global pull.rebase false
> git config -l
pull.rebase=false
pull.merge=true
```

として計算をqsubしたのちにgit pullをかけたところ

```
> git pull origin main
> date
2023年  4月  6日 木曜日 16:40:30 JST
> ls -lat
-rw-r--r--  1 bob users  29500  4月  6 16:41 fp3_l100_r1_t900.o13038
-rw-r--r--  1 bob users      0  4月  6 16:36 fp3_l100_r1_t900.e13038
```

と無事計算が進みました．やれやれ．



------
 - **source** ~/current_research/higher_moment/new_moment_al/docs/Qiita_git_file_stale.org
laravel formRequest バリデーションチェック前に実行されるメソッド

# 概要

- laravelのformRequestにて、バリデーションチェック前に実行される`prepareForValidation()`メソッドをまとめる。

# prepareForValidationメソッド

- 使用用途はサニタイズ
- つまり、「送られてきたリクエストの中身に悪意のあるHTML要素が含まれている場合カットする」などの処理をこちらに記載する。
- 例えば下記のようにstrip_tags()関数を使って記載する。

    ```formRequest.php
    public function prepareForValidation()
    {
        $input = $this->all();

        // リクエストデータから悪意あるHTMLタグとPHPタグを取り除く
        $input['name'] = strip_tags($input['name']);

        // リクエストボディーがname要素だけの場合、HTMLタグを取り除いたキーと情報で置き換える
        $this->replace($input);
    }
    ```

- あとは下記のようにstringで受け取った整数をintに変換するなどの処理も実施する事ができる。

    ```formRequest.php
    public function prepareForValidation()
    {
        $input = $this->all();

        // キーがidの値をint型に変換
        $input['id'] = (int) $input['id'];

        // リクエストボディーがid要素だけの場合、置き換えを行う
        $this->replace($input);
    }
    ```
OpenAIが「GPTs are GPTs」論文で挙げた、大規模言語モデルの応用例 9つ

# GPTs are GPTs 論文について

2023年3月17日にChatGPTを開発するOpenAIから 
**「GPTは汎用技術（General Purpose Technology）である」** として、
その[労働市場への影響を調査した論文が発表](https://www.itmedia.co.jp/news/articles/2303/21/news068.html)され大きな反響を呼びました。

[元の論文はこちら](https://arxiv.org/abs/2303.10130)
[翻訳Qiita記事](https://qiita.com/taka_yayoi/items/1bdbb59946ebff78a689)

汎用技術の例としては蒸気機関や活版印刷が挙げられ、
技術自体とその幅広い応用によって社会に重大な影響を与えるものとされます。

この論文では、大規模言語モデル（LLM）の最新版であるGPT-4を使い、
50%以上効率化できる仕事の割合を調べています。

その方法は
- LLM（大規模言語モデル）の出力に詳しい人間が
- 政府統計で使われる職業とタスク定義を元に
- LLMを使った場合に、LLM未使用時と同じクオリティで50%以上時間を短縮できると思うかを判定

という多分に主観的な基準ではあるものの、GPTに詳しい人が確認しているなら、
今後の可能性を見る上では有用です。

さらにLLMを使った場合については、

1. LLMをChatGPTからのみを利用した場合
2. 1に加えて、**LLMを応用したアプリケーション** を利用した場合

の2段階が想定されています。

# 知りたかったことは見つからず

個人的には、今の仕事への直接的な影響度合いが知りたく、
ソフトウェアエンジニアの具体的なタスクに対して、
どれが50%以上効率化すると判定されたかが気になって読んでいました。

ですが、論文では給与別、参入障壁別といった全体傾向と、
いくつかの職業での影響度合い程度しか書かれておらず、
知りたかった詳細な調査結果は載っていませんでした。

# 9つのLLM応用例

予想外におもしろかったのは、50%効率化の2段階目として、
ChatGPT単体ではなく、LLMを応用したアプリケーションによって時間を半減できるかが判定され、
その **LLM応用例が9つ書かれていた**ことでした。
※原文では `additional software that could be developed on top of the LLM that
would reduce the time it takes to complete the task by half`

LLM応用例として挙げられていたのは以下の9つです
* 2000文字以上のドキュメントを要約する。それをベースに質問に回答する
* インターネットから最新の情報を取得して組み合わせる
* 組織に蓄積された知識、データ、ドキュメント等を取得する
* 高度に専門的な分野の知識を取得する
* LLMに何を与えたらよいアウトプットが出るかレコメンドする
* 情報を分析して意思決定を助ける
* 高度に専門的な分野のトレーニングのための素材を生成する
* 問題に対して助言する
* 複雑なデータベースを取り扱う

LLMや機械学習の専門家ではない自分としては、
開発元のOpenAIが挙げている応用例は今後の展開をイメージするために役立ちます。
これらは技術の本質的な制約ではなく、
早期に実現できるものとして想定しておく必要があると思います。

以下はそれぞれの簡単な考察です。

## 1. 2000文字以上のドキュメントを要約する。それをベースに質問に回答する

※引用部分は原文。その下は自分の考察
> Summarizing documents longer than 2000 words and answering questions about those documents

GPT-4でも文字数制限は緩和されたが、今後も性能は継続的に上がっていくということ。

## 2. インターネットから最新の情報を取得して組み合わせる

> Retrieving up-to-date facts from the Internet and using those facts in combination with the LLM capabilities

Bing AIでは既に実現されているもの。

## 3. 組織に蓄積された知識、データ、ドキュメント等を取得する

> Searching over an organization’s existing knowledge, data, or documents and retreiving information

Embeddings APIを利用して、ドキュメントをベースに回答するチャットボットの例が増えてきている。
ChatGPTプラグインもこれに近いか。

## 4. 高度に専門的な分野の知識を取得する

> Retrieving highly specialized domain knowledge

現時点でも各種試験の成績を見るに知識レベルは高いが、それを専門分野にも応用できるということ。
市場価値が高いと今までは言われたような知識が、LLMに大部分が代替されていくのか。

## 5. LLMに何を与えたらよいアウトプットが出るかレコメンドする

> Make recommendations given data or written input

プロンプトエンジニアリングが流行っているが、それ自体もレコメンドしてくれると確かに助かる。
使う人によるアウトプットの差を埋められると、さらに社会への影響は大きくなりそう。

## 6. 情報を分析して意思決定を助ける

> Analyze written information to inform decisions

要約してくれるだけでも意思決定を助けることにはなるが、
メリット・デメリットや各種フレームワークに基づいた分析をしてくれるということか。
ChatGPT単体との差異があまりわからず。

## 7. 高度に専門的な分野のトレーニング素材を生成する

> Prepare training materials based on highly specialized knowledge,

生成の応用例。ChatGPT単体でも試験問題を作ったりするのは簡単にできるが、これは4の専門知識習得と組み合わせるイメージか。

## 8. 問題に対して助言する

> Provide counsel on issues

今だとアドバイスのようで、一般的なことを並べているだけに見えることはある。
それが応用だと実際の問題を踏まえた具体的なアドバイスになるのか。

## 9. 複雑なデータベースを取り扱う

> Maintain complex databases

ちょっとイメージがつかず。
ChatGPT pluginsのようにAPIでDB操作をするということなのか。
cscの作法 その301

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
ラズベリーパイpico用のプログラムランチャーを実装せよ。
input文に対応せよ。

# サンプルコード

```

using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO.Ports;
using System.Text;
using System.Threading;

class form1: Form {
	private Button button1;
	private Button button2;
	private TextBox textBox0;
	private TextBox textBox1;
	private static TextBox textBox2;
	private SerialPort port1;
	form1() {
		Text = "program launcher";
		ClientSize = new Size(800, 400);

		button1 = new Button();
		button1.Location = new Point(300, 340);
		button1.TabIndex = 0;
		button1.Text = "set";
		button1.Click += new EventHandler(button1_Click);

		button2 = new Button();
		button2.Location = new Point(700, 50);
		button2.TabIndex = 0;
		button2.Text = "send";
		button2.Click += new EventHandler(button2_Click);

		textBox0 = new TextBox();
		textBox0.Location = new Point(30, 20);
		textBox0.Multiline = true;
		textBox0.Size = new Size(300, 300);
		textBox0.TabIndex = 2;
		textBox0.Text = @"led = machine.Pin(25, machine.Pin.OUT)";

		textBox1 = new TextBox();
		textBox1.Location = new Point(400, 20);
		textBox1.Multiline = false;
		textBox1.Size = new Size(300, 20);
		textBox1.TabIndex = 2;
		textBox1.Text = @"led.toggle()";

		textBox2 = new TextBox();
		textBox2.Location = new Point(400, 80);
		textBox2.Multiline = true;
		textBox2.Size = new Size(380, 300);
		textBox2.TabIndex = 2;
		textBox2.Text = @"";

		port1 = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
		port1.BaudRate = 115200;
		port1.Parity = Parity.None;
		port1.DataBits = 8;
		port1.StopBits = StopBits.One;
		port1.Handshake = Handshake.None;
		port1.PortName = "COM3";
		port1.Encoding = System.Text.Encoding.ASCII;
		port1.NewLine = "\r\n";
		port1.DtrEnable = true;
		port1.RtsEnable = true;
		port1.DataReceived += new SerialDataReceivedEventHandler(DataReceived_Handler);
		port1.Open();
		Controls.AddRange(new Control[] {
			button1,
			button2,
			textBox0,
			textBox1,
			textBox2
		});
	}
	private void button1_Click(object sender, EventArgs e) {
		string s = "e";
		byte[] array = Encoding.UTF8.GetBytes(s);
		array[0] = 5;
		string ctrl_e = Encoding.UTF8.GetString(array);
		array[0] = 4;
		string ctrl_d = Encoding.UTF8.GetString(array);
		string msg;
		msg = ctrl_e + textBox0.Text + "\r\n\r\n" + ctrl_d + textBox1.Text;
		port1.WriteLine(msg);
		Console.WriteLine(msg);
	}
	private void button2_Click(object sender, EventArgs e) {
		string msg;
		msg = textBox1.Text;
		port1.WriteLine(msg);
		//textBox1.Text = "";
		Console.WriteLine(msg);
	}
	private delegate void SetTextDelegate(string msg);
	private static void SetText(string msg) {
		textBox2.AppendText(msg);
	}
	private void DataReceived_Handler(object sender, SerialDataReceivedEventArgs e) {
		SerialPort sp = (SerialPort) sender;
		string msg = sp.ReadExisting();
		Console.Write(msg);
		this.Invoke(new SetTextDelegate(SetText), new object[] { msg });
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f6a29877-ac17-93b3-82e7-e92dbab367d8.png)


以上。
ActiveSupport::MessageVerifier::InvalidSignatureエラー

# 動画投稿機能を作った後にrspecを実行するとこのようなエラーが出た。

```
ActiveSupport::MessageVerifier::InvalidSignature:
       ActiveSupport::MessageVerifier::InvalidSignature
```

# 原因
開発の最初の方でとりあえず入れておいたFactorybotの動画ファイルを保存する欄が良くなかったようです。
```ruby:qiita.rb
FactoryBot.define do
    factory :post do
        title        { "example post" }
        video_url    { "hoge_url" }
    end
end
```

# 解決法
とりあえず上の`video_url`の欄を消すとエラーは治りました。
しかしこのままでは動画のテストができないので他の方法も探していこうと思います。