OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】ジェネリクスを使ってみた

#はじめに
コードでよく見る&lt;T&gt;の意味を理解するために、ジェネリクス(ジェネリック関数とジェネリック型)を使ってみました。


#ジェネリックの必要性
以下のサンプルプログラムの関数はInt型の値を受け取り値が同じか判定するものです。

```swift
//受け取った引数の値が同じかどうかを判定する
func equalJudge(x:Int,y:Int) -> Bool {
    return x == y
}
let x :Int = 10
let y :Int = 11

equalJudge(x: x, y: y) //false

```
これはInt型のみを受け取ることができる関数で、その他のDouble型などは受け取れません。
Double型を受け取る場合は別途、別の関数を用意する必要があります。

そんなときに便利なのがジェネリクスです。
ジェネリクスを使用することで、Int型でもDouble型でも両方の値を使用できる
汎用的な関数を作成することができます。

#ジェネリック関数
```swift
//受け取った引数の値が同じかどうかを判定する
func equalJudge<T:Equatable>(x:T,y:T) -> Bool {
    return x == y
}

equalJudge(x: 10, y: 11) //false
equalJudge(x: 10.5, y: 10.5)//true
equalJudge(x: "10.5", y: "10.5")//true
```

先程のサンプルプログラムと比較してみましょう。
Intとなっていた箇所がTに変わっています。
また、関数名の後ろに&lt;T:Equatable&gt;が追加されています。


このTは汎用的な型を表しており、関数を呼び出し時にIntやDoubleなどの型として使用されます。
例えば、引数のx,yの値がInt型の場合、T型はInt型として決定されます。
よく使われるのはTですが、T以外でも問題ありません。

また、&lt;T:Equatable&gt;はTがEquatableプロトコルに準拠していることを示しており、
xとyを比較することが可能になっています。


#ジェネリック型
```swift
struct ValueStruct<T>{
    var valueA:T
    var valueB:T
    
}

let val = ValueStruct<String>(valueA:"Value" , valueB: "Value") //ValueStruct<String>
let val2 = ValueStruct(valueA: "Value", valueB: "Nothing")//ValueStruct<String>
```
ジェネリック型についても、ジェネリック関数と同様にTは汎用的な型として扱われます。
上記の例ではTをValueStructのプロパティの型として使用しています。

初期化時に&lt;String&gt;と型を明示することでTはString型と決定されます。
また、型を明示していない場合でも、型推論により自動的にTをString型と決定することが可能です。



#参考
[[Swift]ジェネリクスについて](https://kentaro.app/posts/swift-generics)

[Swift実践入門](https://www.amazon.co.jp/dp/B086VVQ3DJ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
Linuxにて、csvから指定した列の値のみ取得する方法

csvから指定した列の値のみ取得するのに手こずったため、その方法を共有します。

#環境
Windows10
WSL2
Ubuntu 20.04.2 LTS (Focal Fossa)

#前提
以下のファイルの中身を取得します。

```test.csv
apple,banana,orange
Tokyo,Osaka,Kyoto
Baseball,Basketball,Soccer
```

#実行

```sample.sh
#!/bin/bash

while read row; do
        num=(${row//,/ })
        num1=${num[0]}
        echo $num1
done < test.csv
```
test.csvから一行ずつループ処理します。

>num=(${row//,/ })

Linuxではデフォルトの区切り文字は「スペース」「タブ」「改行」（$'\t\n')となっているので、カンマを「スペース」に置換し、num配列に格納します。


```
$ bash sample.sh
apple
Tokyo
Baseball
```
test.csvの最初の列の値が全て取得できてますね。

#注意
```sample_false.sh
#!/bin/bash

while read row; do
        num=($row)
        echo ${num[0]}
done < test.csv
```

```
$ bash sample_false.sh
apple,banana,orange
Tokyo,Osaka,Kyoto
Baseball,Basketball,Soccer
```
カンマを「スペース」に置換しなかった場合、
csvファイルから取得した一行がひとまとまりのデータと認識され、配列の0番目の要素に全て格納されてしまいます。

###終わりです。

#関連リンク

https://www.koikikukan.com/archives/2019/05/09-235555.php
WioLTE: http post クライアント

Wio LTE for Arduino の http post クライアントのサンプルです。

仕様
[HttpPost](https://seeedjp.github.io/Wiki/Wio_cell_lib_for_Arduino/reference-ja.html#httppost)

## フォルダー構造

```text
$ tree http_post/
http_post/
├── http_post.ino
└── setupLTE.ino
```

## プログラム

```text:http_post/http_post.ino
// ---------------------------------------------------------------
/*
	http_post.ino

						Aug/23/2021
*/
// ---------------------------------------------------------------
#include <WioLTEforArduino.h>
#include <stdio.h>

#define URL	"https://httpbin.org/post"

#define INTERVAL          (10000)

WioLTE Wio;
	
// ---------------------------------------------------------------
void setup() {
	setupLTE();

	SerialUSB.println("### Setup completed.");
}

// ---------------------------------------------------------------
void loop() {
	char data[100];
	int status;

	SerialUSB.println("### Post.");
	sprintf(data, "{\"user\":\"jiro\",\"password\":\"123456\",\"uptime\":\"%lu\"}", millis() / 1000);
	SerialUSB.print("Post:");
	SerialUSB.print(data);
	SerialUSB.println("");
	if (!Wio.HttpPost(URL, data, &status)) {
		SerialUSB.println("### ERROR! HttpPost ###");
	}
else
	{
	SerialUSB.print("Status: ");
	SerialUSB.println(status);
	}	

	SerialUSB.println("### Wait.");
	delay(INTERVAL);
}

// ---------------------------------------------------------------
```

setupLTE.ino はこちら
[UDP で温度と湿度を Harvest に送る](https://qiita.com/ekzemplaro/items/690faa6f56003272299f)


## 実行結果
![http_post.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/526fd2d6-9260-91af-181e-d875377f295a.png)

次のスケッチ例を改造しました。
Arduino/libraries/Wio_LTE_for_Arduino/examples/http/ifttt-webhook/ifttt-webhook.ino

## Arduino IDE
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/1e3638bf-b87d-40b3-2723-a26bb372b163.png)
学習の方向性について　

学習を進めるにあたり、目標設定とそのプロセスを決めることは非常に重要である。
まず、何から手を付ければいいか、全く想像がつかなかった私はYouTubeやネットで情報収集から始めた。
そこで、マナブさんというブロガーの「プログラミング独立の完全ロードマップ」という記事にたどり着き、その記事を信じて学習を進めることとした。
その理由の一つに、マナブさんの動画の中で心に残った言葉があった。
「スキル　＝　学習　×　経験」という言葉だ。
いくら学習をしても、それをアウトプットして、経験を積まなければスキルにならない。
そして、転職活動の際、評価の対象になるのは、「学習」ではなく「スキル」だ！
だから、私もこのブログを通して、「スキル」の向上を目指したい！
Automation360のメニュー、アクション名の翻訳について

#はじめに
だいぶ改善されたものの所々おかしな日本語訳が見られるAutomation360。
じゃぁ、中国版や韓国版はどんな感じなんだろう？
言語リソースの切り替えだけだから、各国のリソースを書いた人の力量で決まるのかな？

というわけで、日本語版で気になった箇所を中国版・韓国版で確認してみました。
なお、この記事は単なるお遊びです。
技術的に何も見るべき話はありませんので、あしからず。



#エラーハンドラーアクション

| 英語版 | 日本版 | 韓国版 | 簡体字版 |
|-------|--------|-------|----------|
|Try    |試行    |Try    |Try      |
|Catch  |キャッチ |Catch  |Catch   |
|Finally|最終    |최종    |Finally |
|Throw  |スロー  |Throw   |Throw   |

※全部英語でいいじゃないか、と思う。これ使うのはプログラマだろう。
※なぜに韓国語版は「最終(최종)」だけハングル？

#ディクショナリアクション

| 英語版 | 日本版 | 韓国版 | 簡体字版 |
|-------|--------|-------|----------|
|Assign |代入    |지정    |赋值      |
|Get    |Get     |가져오기  |Get    |
|Put    |挿入    |놓기    |放置     |
|Remove |削除    |제거    |移除     |
|Size   |サイズ  |크기    |大小     |

※辞書に新しいキーと値を入れるのが「代入」か「挿入」かで、よく間違う（笑）。

# 文字列アクションの「テキストファイル」

| 英語版 | 日本版 | 韓国版 | 簡体字版 |
|-------|--------|-------|----------|
|Import string from text file|テキストファイル|문자열을 |从文本文件中导入字符串 |
※日本版と韓国版は、何するアクションかわからない

#日時アクション

| 英語版 | 日本版 | 韓国版 | 簡体字版 |
|-------|--------|-------|----------|
|Add    |追加    | 추가    |添加|
|Assign  |代入 |지정  |赋值|
|Is after|指定より後の日付 |이후임   |晚于|
|Is before  |指定日より前の日付  |이전임  |早于  |
|Is equal  |指定日と同じ日付  |동등함  |等于   |
|Substract  |減算  |빼기  | 减去 |
|To string  |文字列に変換  |To 문자열  |转换为字符串   |

※どれもIs～ という疑問形が表現できてないように見えるけど。
※「追加」と「代入」を間違えるので、「追加」は「減算」の対で「加算」にしてほしい。

#DLLアクション

| 英語版 | 日本版 | 韓国版 | 簡体字版 |
|-------|--------|-------|----------|
| Run function (Legacy) |関数を実行（レガシー）|기능(레거시) 실행 |运行功能（旧式）|
|Run function  |関数を実行 |  함수 실행 |运行函数|

※韓国語版と簡体字版ではfuntionに対し、「機能」「関数」と両方使うのはなぜ？
★「レガシー」は無くなりました（2022/9/17）。 

#待機アクション

| 英語版 | 日本版 | 韓国版 | 簡体字版 |
|-------|--------|-------|----------|
|Wait for condition|条件を満たすまで待機します    | 조건 대기    |等待条件满足|
|Wait for screen change|スクリーンの変化を待つ |화면 바뀜 대기 |等待屏幕变化|
|Wait for window|ウィンドウを待つ |창 대기   |等待窗口|

※これは似たりよったり。
ただ、日本語版の「条件を満たすまで待機します」が妙に丁寧なのが、、、

#画像認識アクション

| 英語版 | 日本版 | 韓国版 | 簡体字版 |
|-------|--------|-------|----------|
|Find image in window |ウィンドウで画像を検索 |이미지를 창에서 찾기 |在窗口内查找图像|
|Find window in window|ウィンドウでウィンドウを検索 |창을 창에서 찾기|在窗口内查找窗口|

※特に後者、最初全く意味わからなかったのだけど、実は英語版から意味不明。訳はどれも英語版同等。

※でも、しばらく使っていると慣れる。
（マニュアル曰く「干し草の中から針を探す」。  干し草が何で、針が何になるかを指定）



# サイドメニュー

| 英語版 | 日本版 | 韓国版 | 簡体字版 |
|-------|--------|-------|----------|
|Manage          |管理    |관리     |管理   |
|Administration  |管理   |관리     |管理    |

※これはアジア圏、みんな困った？（笑）。
★A360.22で「マネージ」と「管理」に変わりました（2022/9/17）。 

#最後に
これは2021/7/23にCommunity Editionのbuild9637で書いたものです。
きっとこの先、いろいろ変わるでしょう。
（賞味期限が短い一発芸記事）

#おまけ
アクション名についてはバルーンヘルプが出るから、少し訳が変でもなんとかなります。
C++ 処理時間測定 std::chrono::duration_cast

以下の`stopwatch()`を処理したい前後でコールする。

```c++
#include <iostream>
#include <chrono>

float stopwatch(std::chrono::system_clock::time_point t = std::chrono::system_clock::now())
{
    static std::chrono::system_clock::time_point ref_time;
    if (ref_time == std::chrono::system_clock::time_point())
    {
        ref_time = t;
        return 0.0;
    }
    float elapsed = static_cast<float>(std::chrono::duration_cast<std::chrono::milliseconds>(t - ref_time).count());
    ref_time = t;
    return elapsed;
}

int main(int argc, char *argv[])
{
    stopwatch();
    // 時間測定したい処理
    std::cout << "process time: " << stopwatch() << "[ms]" << std::endl;
    return 0;
}
```
Unity - Editor Console Pro を使うと StackTraceのLogTypeが強制的にScriptOnlyに上書きされる

https://assetstore.unity.com/packages/tools/utilities/editor-console-pro-11889


Unityの既定のConsoleを拡張してくれて非常に便利なアセットですが、罠のような挙動が見つかったため共有します。

それは、Editor Console Pro　のタブを開いているとStackTraceのLogTypeが全て強制的にScriptOnlyに上書きされることです。

PlayerSettingsで設定を変更できる以下の箇所の話です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237014/779c514a-6718-91b5-34ef-269d7ef3768e.png)


Editor Console Proのタブを閉じると上書きされなくなります。

タブを開いたままこの挙動をOFFにできないか問い合わせましたが、「仕様やねん」みたいな回答を受けました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237014/6a0cbf58-df6d-d0cf-04d1-3b87c10807bf.png)


非常に便利なアセットの一つとして色々な場所で推薦されてますが、この挙動については知られてないと思ったので、注意頂ければと思います。
Serverless FrameworkでCognito認証

CognitoのSignin情報を利用して、指定エンドポイントに認証を追加する方法です。

# 設定後の利用方法
1. CognitoにSigninしてIdTokenを取得する
1. 取得したIdTokenをheaderに設定してAPIのリクエストをする
    - headerのKeyは、オーソライザー作成時のトークンのソース

これだけで、認証されていない場合のアクセスを防ぐことが可能

# やったこと

## Api Gatewayでオーソライザー(cognito)の作成
設定画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247263/6430fc37-7de3-c88c-85dc-37790b734974.png)

- Cognitoユーザープール（ユーザー情報の場所）は、作成していると選択可能
- トークンのソースは、APIに設定するヘッダー名を入れる
- 作成すると、下記のようにIDができるのでそれをメモ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247263/b2517ebd-c6bc-a5d0-2ae2-a50817c6b99b.png)

※おまけで、試しに認証した後にトークンのソースを変更してみたのですが、即適用されなかったです。再デプロイで適用されたので、ウォームスタート状態だと即適用はされなそうです。

## serverless.yamlにauthoraizerの設定を追加
- 要認証のエンドポイントに下記の感じで設定を入れる

```
      - http:
          cors: true
          path: "{proxy+}"
          method: any
          authorizer: 
            type: COGNITO_USER_POOLS
            authorizerId: "pk2q0p"
```
- authorizerIdはオーソライザー作成で作られたIDを設定する

### 追記
公式見てて、下記の定義することで、オーソライザーを手動作成せず自動でいけました。

https://www.serverless.com/framework/docs/providers/aws/events/apigateway/#http-endpoints-with-aws_iam-authorizers

※env.USER_POOL_ID　は、cognitoユーザープールを手動作成してできたものを設定

````
authorizer: 
  name: Myauthorizer
  type: COGNITO_USER_POOLS
  arn:
   !Join [ ":", [ "arn:aws:cognito-idp", Ref: AWS::Region, Ref: AWS::AccountId, "userpool/${env:USER_POOL_ID}" ] ]
```

# まとめ

やったことなかったので試しにやってみたら、あっさりでした。
軽く作る時とかこれで十分ですね。
【Win10】複数ユーザーでconda仮想環境を共有する方法

# 背景
Windows10マシン内で、複数ユーザーが同じPython環境を使えるようにしたのでそのメモ。
以下ではAnacondaを利用していることを前提に話を進めますが、Minicondaでも同様の手続きで環境構築が可能です。
また、ターミナルにはGit Bash(Git for Windows)を使用しているので、パス表記がUnix風です。
必要に応じてWinスタイルに直してください。

# 状況設定
- OS: Windows10
- Terminal: Git Bash(Git for Windows)
- Anaconda3を```/c/ProgramData/```下に[インストール済み](https://docs.anaconda.com/anaconda/install/multi-user/)
- 管理者ユーザーで環境構築を行い、一般ユーザー(管理者権限なし)がその環境を利用

# 方法
まずは結論から。
管理者ユーザーで以下を実行。
※環境名```{ENV-NAME}```やPythonのバージョンはそれぞれ決めてください。

```
conda create --prefix /c/ProgramData/Anaconda3/envs/{ENV-NAME}
```

これで```{ENV-NAME}```という環境が作成され、一般ユーザーもこの環境を使用できます。
```conda info -e```で環境を参照できているか確認できます。

あとは```{ENV-NAME}```内で必要なパッケージなどをインストールしましょう。

# 解説

全ユーザーが参照できる場所に環境を構築しました。
オプション```--prefix```で```/c/ProgramData/Anaconda3/envs/```下に環境を構築しています。prefixしなければ```/c/Users/{ユーザー名}/Anaconda3/envs``` 下に作られてしまいますが、この場所は他ユーザーから参照できません。
今回は手動で保存場所を指定することで全ユーザーが利用できる環境を整えました。

---
間違いなどありましたらご指摘お願いします。
付け焼き刃でFargateにgoでマイグレーション＆シード

## 目的

go-ginで開発しているときにFargateに無理やりマイグレーション＆シードを行いたかった感じです。

ただlayerが多すぎて肥大化しているので、あまりおすすめしません。
本当はfargateで新しいタスク立てたり、code pipeline使うべきなんでしょうけど、急いでいるのでこれで。

## ファイル

以下fargateにデプロイするようのDockerfileです。
migrationとseedディレクトリにmain.goが入っているのでそれをbuildしてalpineのほうのイメージに移動させます。

```Dockerfile
FROM golang:latest as builder

ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
COPY . /go/src/backend

WORKDIR /go/src/backend

RUN go get github.com/line/line-bot-sdk-go/linebot && \
  go get github.com/joho/godotenv && \
  go get -u gorm.io/gorm && \
  go get gorm.io/driver/mysql && \
  go get github.com/golang-migrate/migrate && \
  go get github.com/golang-migrate/migrate/database/mysql && \
  go get github.com/golang-migrate/migrate/source/file && \
  go get github.com/pkg/errors && \
  GOOS=linux GOARCH=amd64 go build -o /main

WORKDIR /go/src/backend/migration
RUN go get github.com/go-sql-driver/mysql@v1.6.0 && \
  GOOS=linux GOARCH=amd64 go build -o /go/src/backend/migration/main

WORKDIR /go/src/backend/seed
RUN GOOS=linux GOARCH=amd64 go build -o /go/src/backend/seed/main

# runtime image
FROM alpine
RUN apk update \
  && apk add --no-cache git curl make gcc g++
COPY --from=builder /main .
COPY --from=builder /go/src/backend/migration ./migration
COPY --from=builder /go/src/backend/seed ./seed
COPY ./entrypoint.sh .
RUN ["chmod", "u+x", "./entrypoint.sh"]

ENV PORT=${PORT}
ENTRYPOINT ["./entrypoint.sh"]
```

`entrypoint.sh`は以下です。
ステージングなので、まずデータベースのマイグレーションをすべてドロップします。そのあとマイグレーションをおこなって、シーディングして最後にサーバーのコードを走らせる感じです。

```entrypoint.sh
#!/bin/sh
/migration/main drop
/migration/main up
/seed/main seed
/main
```
base64エンコードされた文字列からjpgファイルを作成する

```html
<img id='base64image' src='data:image/jpeg;base64, LzlqLzRBQ...' />
```

```bash
> ls
source.csv
> cat source.csv
"1","STR_BASE64"
"2","STR_BASE64"
...
> cat source.csv | xargs -I{} sh -c 'echo {} | cut -d , -f 2 | base64 -di > $(echo {} | cut -d , -f 1).jpg'
> ls
source.csv 1.jpg 2.jpg ...
```
WioLTE: 電話番号を取得

Wio LTE for Arduino で SIM の電話番号を取得する方法です。020 で始まる番号が取得できます。

## プログラム

```text:get_phone_number/get_phone_number.ino
// ---------------------------------------------------------------
/*
	get_phone_number.io

					Aug/26/2021
*/
// ---------------------------------------------------------------
#include <WioLTEforArduino.h>
#define INTERVAL    (2000)

WioLTE Wio;

// ---------------------------------------------------------------
void setup() {
	char num[20];

	delay(1000);
	SerialUSB.println("*** get_phone_number.io ***");
	SerialUSB.println("*** Setup aaa ***");
	delay(1000);
	SerialUSB.println("*** Setup bbb ***");
	setupLTE();

	SerialUSB.println("*** Setup ddd ***");
	delay(1000);
	SerialUSB.println("*** Setup eee ***");

	int numberSize = sizeof(num);

	int vv =  Wio.GetPhoneNumber(num,numberSize);

	if(0 < vv)
		{
		SerialUSB.println(num);
		}
	else
		{
		SerialUSB.println("*** error *** GetPhoneNumber ***");
		SerialUSB.println("vv = " + String(vv));
		}

	SerialUSB.println("*** setup completed *** Aug/08/2021 ***");
}

// ---------------------------------------------------------------
void loop() {
	SerialUSB.println("*** loop *** aaa ***");
	Wio.LedSetRGB(0, 0, 1); 
	delay(INTERVAL / 2);
	SerialUSB.println("*** loop *** bbb ***");
	Wio.LedSetRGB(0, 0, 0); 
	delay(INTERVAL / 2);
}

// ---------------------------------------------------------------
```

```text:get_phone_number/setupLTE.ino
// ---------------------------------------------------------------
/*
	setupLTE.ino

					Aug/09/2021
*/
// ---------------------------------------------------------------


#define APN		"soracom.io"
#define USERNAME	"sora"
#define PASSWORD	"sora"

// ---------------------------------------------------------------
void setupLTE() {
	delay(200);

	SerialUSB.println("");
	SerialUSB.println("*** start *** seupLTE ***");

	SerialUSB.println("### I/O Initialize.");
	Wio.Init();

	SerialUSB.println("### Power supply ON.");
	Wio.PowerSupplyLTE(true);
	delay(500);

	SerialUSB.println("### Turn on or reset.");
	if (!Wio.TurnOnOrReset()) {
		SerialUSB.println("### ERROR! TurnOnOrReset ###");
//	return;
	}
	delay(500);

	SerialUSB.println("*** Connecting to \"soracom.io\" ***");
	if (!Wio.Activate(APN, USERNAME, PASSWORD))
		{
		SerialUSB.println("### ERROR! Activate ###");
		}
	else
		{
		SerialUSB.println("*** SetupLTE completed ***");
		}

	SerialUSB.println("*** end *** seupLTE ***");
}

// ---------------------------------------------------------------
```

## ノート

うまく番号が取得できない時は、sim の刺し方が間違っています。
表裏を変えても、前後を変えても sim は刺さります。
４パターン試せば、どれか当たります。私はそうしました。
ボックスカルバートの形状予測AI ～学習用設計データの作成編～

## シリーズ目次

- [ボックスカルバートの形状予測AI ～データ整理編～](https://qiita.com/sasaco/items/81881e2797de51f0dc5b)
- ボックスカルバートの形状予測AI ～学習用設計データの作成編～
- [ボックスカルバートの形状予測AI ～ニュートラルネットワークの構築編～](https://qiita.com/sasaco/private/b2aedcd5f91a07199ef1)
- [ボックスカルバートの形状予測AI ～いざ予測 編～](https://qiita.com/sasaco/private/9ea9b67683650deb619c)
- [Tensorflow.Keras で学習したモデルをtensorflow.jsで使う](https://qiita.com/sasaco/items/9c7a4e247710ed747dbd)

## ボックスカルバートの設計データについて

ボックスカルバートと一言にいっても色々な種類があります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142847/1804a554-a887-57a0-c236-4e100f955aa2.png)

これらすべての形状に対して予測する **万能な AI** は実現が難しいので、今回は簡単な形状をターゲットにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142847/74561a0f-07ae-2afe-dbb6-bf094139a4da.png)

# 学習用設計データの作成

設計は、以下の条件としました。

## 設計条件

ボックスカルバートは、**左右対称の形状**とする


### ハンチ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142847/28b48763-9d13-5cde-bfe6-b09e9c493e59.png)

ハンチ１は、**側壁**と**上床版** の **薄い方** の **1/2** の大きさとする

**下床版**にハンチは**設けない**

### 地表面に載る荷重

常時の上載荷重は **10**kN/m2 とする

地表面の活荷重は **下表**の荷重とする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142847/db1d682b-680e-0ec1-52e9-4bba73259b15.png)

### 設計水位

高水位は **地表面** とする

低水位、平水位は **考慮しない**


### ボックス内部の活荷重
 考慮しない

### 温度荷重
 **10**℃ とする

### 鉄筋について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142847/6589a806-e696-c150-ffe9-53ad41208256.png)

ボックスカルバートの部材の鉄筋量は、一般に 0.15% ～ 1.0% の鉄筋が入っている
今回は、部材厚を予測するので、鉄筋量の増減は 学習データに含めたくなかった

そこで、今回は、 全設計データで 一律 **断面の0.6%** の鉄筋が入っているものとして
設計データを作成した


### 地盤定数について

一般的には ボックスカルバートは多層地盤中に構築されるため 関係する地盤数は任意の数になる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142847/6327f757-84f0-0018-26ed-7a094462c7ca.png)

数が固定されていない状況は ニューラルネットワーク の入力が 難しくなるため
今回は、

- ボックス直上の**埋め戻し土**
- ボックスより上の部分の**地層1**
- ボックスの上半分の**地層2**
- ボックスの下半分の**地層3**

というように 地層の数を固定した

### 地盤の湿潤重量

最大 **20** kN/m3 の値を取ることとした 

### 地盤定数

今回は、杭なし構造物を弾性体として解く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142847/ce919bd0-03f9-602a-d900-b8ec759cacad.png)

したがって地盤反力係数を計算するための変形係数を設定する

### 静止土圧係数

土圧の算定に用いる係数で一般的には、下表の関係があるが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142847/2dbf3e62-855b-593f-1bb3-ff8df6f9483f.png)

今回は 0.8 以下の 任意の数値とする


以上の条件により **15万件** のボックスカルバートのデータを生成し設計をおこなった


設計した結果を格納した csvファイル を下記の URL から 入手できます。

**[boxculvert_data.csv](http://gofile.me/4fNCe/y3K32QQbY)**


## 次回

次回、は 生成した**15万件**のデータを学習させ、部材厚を予測するAI を実際に作成してみます。

[ボックスカルバートの形状予測AI ～ニュートラルネットワークの構築編～](https://qiita.com/sasaco/private/b2aedcd5f91a07199ef1)
SATA とは

## 勉強前イメージ

ストレージ系でケーブルとかそこらへん？

## 調査

### SATA とは

Serial Advanced Technology Attachment の略で、
PCとストレージ間でのインタフェースの規格であるATAの拡張仕様で、
シリアル転送方式の規格になります。

### SATAの種類

- SATAⅠ

最初のSATAの規格で、理論上最大の転送速度は1.5Gbpsとなっています。

- SATAⅡ

2代目のSATAの規格で、理論上最大の転送速度は3Gbpsになります。
SATAⅡからAHCI(通信プロトコル)を採用した。

- SATAⅢ

3代目のSATAの規格で、理論上最大の転送速度は6Gbpsになります。

- mSATA

Mini SATA SSD の略で、ノートパソコンや薄型のデバイスに
搭載できるようなコンパクトな形状になります。

- eSATA

External SATA SSD の略で、
外付けとして使用するために利便性を向上したものになります。
抜け落ちずらかったり、ケーブルの挿抜可能回数を増やしたものになります。

## 勉強後イメージ

SATA → インタフェースの規格
AHCI → 通信プロトコル(HDDに最適化)
NVMe → 通信プロトコル(SSDに最適化)

こんなイメージかな？
あとはざっくりとしか知らなかったけど、ちょっとずつ理解できたかも。
昔PCのHDD指してたやつはどれやったんやろ？

## 参考

- [eSATAを使いこなす！](https://www.ratocsystems.com/products/esata_pop.html)
- [SATA規格の種類とは？IDEやNVMeとの違いも含め詳しく解説](https://www.pro.logitec.co.jp/houjin/usernavigation/hddssd/20200417/index.html)
Redmine をリストアしよう！

# やったこと

 落としてきたファイルから本当に Redmine を再現できるか確かめる（リストア）。
Redmine のバックアップに関しては、[この記事](https://qiita.com/tama2ka/items/54d0a92d8c2aa86691fa) を参考にしてね。

## 環境

- Ubuntu 20.04.2 LTS
- Docker version 20.10.7
- docker-compose version 1.21.2

## 実際の手順

　手順は以下の３つだ。全てローカル（外部サーバを使わず、自分のバソコン内だけ）で実行した。

###手順１
以下ディレクトリを用意して、バックアップしてあるfilesとconfigを入れておく。

```
/var/redmine/files
/var/redmine/config
``` 

###手順２
適当なディレクトリにdocker-compose.ymlファイルを置く。

<details><summary>docker-compose.yml</summary><div>

```yml
version: '3.5'
services:
  redmine:
    image: redmine:3-passenger
    container_name: redmine
    restart: always
    ports:
      - 13000:3000 # 「ホストでアクセスしたいポート:3000」で設定
    environment:
      TZ: Asia/Tokyo
      REDMINE_DB_MYSQL: mysql
      REDMINE_DB_DATABASE: redmine
      REDMINE_DB_USERNAME: redmine
      REDMINE_DB_PASSWORD: redmine
      REDMINE_DB_ENCODING: utf8mb4
    depends_on:
      - mysql
    volumes:
      # 「マウントしたいホストの絶対パス:コンテナ内の絶対パス」
      - /var/redmine/files:/usr/src/redmine/files
      - /var/redmine/config:/usr/src/redmine/config
      # - /var/redmine/plugins:/usr/src/redmine/plugins
      # -/var/redmine/log:/usr/src/redmine/log
      # -/var/redmine/public/themes:/usr/src/redmine/public/themes
  mysql:
    image: mysql:5.7
    container_name: mysql
    restart: always
    environment:
      TZ: Asia/Tokyo
      MYSQL_ROOT_PASSWORD: P@ssw0rd # 適当に変更する？
      MYSQL_DATABASE: redmine 
      MYSQL_USER: redmine
      MYSQL_PASSWORD: redmine
    volumes:
      - mysql-data:/var/lib/mysql
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_bin
volumes:
  mysql-data:
    name: mysql-redmine

```

</div></details>


そのディレクトリで以下コマンドを順に実行する
$DMP_FILE_PATHの箇所はバックアップした.dmpファイルのパスを入れる。

```
docker-compose up -d
docker exec -i mysql mysql -u redmine -predmine  redmine < $DMP_FILE_PATH
```

ローカルホスト13000番にアクセスしてRedmineが正しくリストアできていることを確認する。

###手順３
確認が終わったら以下コマンドを実行してコンテナを落とす。

```
docker-compose down
```

以上でリストア終わり。おつかれさんっ！！

### 参考文献

- https://qiita.com/bezeklik/items/b5c39136a8db23e2e81c
ATtiny1616でエンコーダーモーターを動かす2

ATtiny1616でエンコーダーモーターを動かすの続きです。
https://qiita.com/usashirou/items/4dc1c7c28c142e90bd5b
今回は、ADCを追加します。
#ADCを追加
ADCを追加します。
ADCにより電圧を測ることが可能です。
今回は1番ピンの電圧を測ります。

    sensorValue = analogRead(ADC);
#プログラム
analogReadでピンを指定して、毎回読み込んでいます。

```
#define ENCA 2 // YELLOW
#define ENCB 3 // WHITE
#define IN2 8
#define IN1 9
int pos = 0;
int sensorValue = 0;        // value read from the pot

void setup() {
  Serial.begin(9600);
  pinMode(ENCA, INPUT);
  pinMode(ENCB, INPUT);
  attachInterrupt(digitalPinToInterrupt(ENCA), readEncoder, RISING);
}

void loop() {
  setMotor(1, 150, IN1, IN2);
  delay(2000);
  Serial.println(pos);
  setMotor(0, 0, IN1, IN2);
  Serial.println(pos);
  sensorValue = analogRead(1);
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  Serial.print("\n");
  delay(500);
  setMotor(-1, 350, IN1, IN2);
  delay(2000);
  Serial.println(pos);
  setMotor(0, 0, IN1, IN2);
  sensorValue = analogRead(1);
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  delay(1500);
  Serial.println(pos);
  sensorValue = analogRead(1);
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  Serial.print("\n");
}

void setMotor(int dir, int pwmVal,  int in1, int in2) {
  if (dir == 1) {
    analogWrite(in1, pwmVal);
    digitalWrite(in2, LOW);
  }
  else if (dir == -1) {
    digitalWrite(in1, LOW);
    analogWrite(in2, pwmVal);
  }
  else {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
  }
}

void readEncoder() {
  int b = digitalRead(ENCB);
  if (b > 0) {
    pos++;
  }
  else {
    pos--;
  }
}
```
[Rails]コードの品質を上げるために僕らが出来ること。

# はじめに
いきなりですが、コードの品質ってかなり重要ですよね？
汚いコードを書くと、自分だけでなく一緒に開発しているメンバーにも迷惑をかけてしまいます。この記事では品質を上げるために必要なものを紹介します！

# CI(継続的インテグレーション)について
CIとは、`コードの更新に対して自動でテストを実行させる仕組み`のことです。
これを実行する有名なツールやサービスとして、、

- CircleCI
- Travis CI
- Github Actions

などがあります。

その中でも自分が使っていたGithub Actionsについて記事を執筆したので、良ければこちらをご覧ください。

https://qiita.com/ren0826jam/items/bd2767a3ba7bc8c1b92b

# Gemの定期アップデートについて
Gemは日々更新されているので、アプリケーションの方で定期的なアップデートが必要です。怠ってしまうと、更新時の作業コストが大きくなってしまうので定期的に行いましょう。

## 手動で更新する
手動で、`bundle update`を行なって、最新をメインブランチにpushすれば更新完了です。

# Dependabot
まずは手動で`bundle update`して、現時点の最新バージョンにしておきます。

## ブラウザから設定する場合
以下の記事を参考にセットアップしてください。

https://qiita.com/takasp/items/c2907f2da855c207b8ef

## 設定ファイルをリポジトリに追加する場合
以下のファイルを作成する。

```.dependabot/config.yml
version: 1
update_configs:
  - package_manager: 'ruby:bundler'
    directory: '/'
    update_schedule: 'weekly'
    allowed_updates:
      - match:
          update_type: 'all'
```

# 静的解析について

## Rubocop
問題のあるコードがある場合に指摘してくれるツールです。これを利用すると、バグの可能性を潰したり、コーディング規約に則ってチームメンバーと書き方を統一したりできます。導入方法や設定方法は以下の記事を参考ください。

https://qiita.com/piggydev/items/074e020e07af7ebc872d

### copの種別

| ルール名 | 概要 |
|:-:|:-:|
| Layout cops  | インデントやスペースの有無を検査する  |
| Lint cops  | バグの可能性があるコードを検査する  |
| Metrics cops  | クラスやメソッドの長さ、コードの複雑さを検査する  |
| Naming cops  | メソッド名や変数名など、命名に関する検査をする  |
| Security cops  | セキュリティ観点での検査をする  |
| Style cops  | コーディング規約に沿っているか検査する  |

## Breakman
コードを解析して脆弱性に関係ありそうな箇所をレポート出力します。

https://brakemanscanner.org/

# カバレッジ測定について
カバレッジとは、アプリケーションコード全体でテストコードにより実行されたコード割合がどれくらいなのかを表す指標のことです。カバレッジを測定することで、テストで網羅しきれていない部分を見つけて効率よくテストを実行することができます。ここでは、SimpleCovを紹介します。

## SimpleCov
カバレッジを測定できるgemです。テストコード実行時にカバレッジ測定結果レポートをHTMLレポート出力します。

### 使い方
1.gemを追加し、`bundle install`を実行する。

```
group :test do
  ...
  gem 'simplecov'
end
```

2.テストを実行すると、`coverge/index.html`へ結果が出力される。

# 終わりに
ここまで、コードの品質を上げるための方法を見てきましたが、どれも現場では導入されていることが多いので抑えておきましょう！
【UiPath】実行マシンの情報を取得する（ブラウザ情報）

# はじめに

この投稿は、RPAツール「UiPath」での 実装例 について記事です。

UiPathのコミュニティ「UiPath Friends」が企画する「UiPathブログ発信チャレンジ2021サマー」の 23日目の投稿でもあります。

企画の内容は [**こちら**](https://note.com/shumpei_w/n/n651cbdbec4e8) 。カレンダーのURLは [**こちら**](http://u0u1.net/sUwZ) です。

https://twitter.com/ShumpeiWatanabe/status/1405168150736359427

# 実行マシンの情報を取得するシリーズ

同様の内容で以下の投稿もあります。参考まで

https://qiita.com/miya_gis/items/a32fe3a64acc8b6b8ef5

https://qiita.com/miya_gis/items/3393940487f49ed7fe16


# ブラウザの情報が知りたいとき

UiPathでWeb操作を自動化する際に「どのブラウザで操作するか」を決めますが、

- 対象システムの推奨ブラウザに指定されているもの
- 自分との相性（好み、習熟度）

などで判断すると思います。

ただ、実行するマシンに「どのブラウザがインストールされているのか」をパッと知る方法がありません。
また、インストールされているバージョンが古くて「想定しないエラー」につながることもあります。

なので「インストールされているブラウザは何か？そのバージョンは何か」が分かると役に立つことがあります。

# .NETで取得する

標準アクティビティで「インストールされたブラウザのバージョン情報を取得」アクティビティ みたいなのがあれば良いのですが、現時点ではありません。

なので、以下に VB.NET で取得するコードを用意しました。（持ち出しやすいように、匿名変数型にしています）

``` VB
func =
	Function() As Dictionary(Of String, Object)
		Dim dic As New Dictionary(Of String, Object)
		Dim browserKeys As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\WOW6432Node\Clients\StartMenuInternet")
		If browserKeys Is Nothing Then
			browserKeys = Registry.LocalMachine.OpenSubKey("SOFTWARE\Clients\StartMenuInternet")
		End If
		Dim browserNames As String() = browserKeys.GetSubKeyNames
		For Each bName As String In browserNames
			Dim browserKey As RegistryKey = browserKeys.OpenSubKey(bName)
			Dim browserKeyPath As RegistryKey = browserKey.OpenSubKey("shell\open\command")
			Dim browserName As String = browserKey.GetValue(Nothing).ToString
			Dim browserPath As String = browserKeyPath.GetValue(Nothing).ToString.Trim.Replace("""","")
			Dim browserVersion As String = System.Diagnostics.FileVersionInfo.GetVersionInfo(browserPath).FileVersion
			dic(browserName) = browserVersion
		Next
		Return dic
	End Function
```

これを、こんな感じのフローで実行すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/30664d35-9169-0d62-a115-b515a4f34ff7.png)

以下のように出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/8dcab899-6171-9070-ac78-757c3c78b83b.png)

確認しやすいように、以下でxamlを公開しています。

https://github.com/miyag/UiPath.ReusableCode/blob/master/GetMachineSpec/GetInstalledBrowserVersion.xaml

# 終わりに

いかがでしたでしょうか？実装の参考になれば幸いです。

この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。
デバック環境を構築するスクリーンショット編

ソフトウェアやハードウェアのデバックを行う際に開発環境とともに必要となるのがデバック環境です。
今回はスクリーンショットの取り方を取り上げます
#Windows10編
##画面を収録する
Windows10ではWindowsキー＋Siftキー＋Sで画面のスクリーンショットを取る事が出来ます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/eb56df1e-7891-3494-e255-b11154bd9cf5.png)
##画面を録画する
Windows10ではWindowsキー＋Gで画面の動画を収録する事が出来ます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6445447b-cc72-823f-ab17-ad0910336200.png)
ただし、これ一筋縄ではいかないのです。
あるソフトは全く使えないのです。
こんな時に使うのがOBS Studioです。
#OBS Studio
https://obsproject.com/ja/download
OBS Studioを使う事で画面動画を収録することが出来ます。
使用方法はこちら___デバック環境を構築する OBS Studioを使おう___
https://qiita.com/usashirou/items/cec06e3491776ce9f19f
#Mac編（Mojave以降）
MacOSX10.14以降については標準で画面キャプチャ、録画できるようになりました。
___command＋Shift+5___を押すことで録画アプリが起動します。
![mac-screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/df9eb92b-8cba-ec99-820b-83f943edca77.png)
#JetsonNano・RaspberryPi
___デバック環境を構築する OBS Studioを使おう___をご覧ください。
https://qiita.com/usashirou/items/cec06e3491776ce9f19f#%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E3%81%99%E3%82%8B
HaskellのHSpecで複数ファイルのテストを同時に走らせる

# 概要
Haskellのstackのプロジェクトで、HSpecでテストを書く時、複数テストファイルを同時に走らせたかったら、Automatic spec discoveryを使う。senseiを使うとなお便利。

# 背景

stackを使ってwebアプリっぽいものを作る過程で、複数のHSpecテストファイルができたのだが、それらをまとめて走らせる良い方法がわからず詰まったのでメモする。

# 環境

- MacOS Big Sur 11.4
- MacBook Air M1
- stack 2.7.1

# やり方
### I. HSpecのAutomatic spec discoveryを使って、複数ファイルのテストコードを`stack test`で実行できるようにする

- `stack new (プロジェクト名)`で適当なstackプロジェクトを作る。

- `package.yaml`の、testsという項目の、(プロジェクト名)-testという項目のdependenciesに、`- hspec`という一行を追加

- [このページ](https://hspec.github.io/hspec-discover.html)を参考に、`src`ディレクトリにプロダクションコード、`test`ディレクトリにテストコードを書いていく。
このとき、以下の点に注意

    - 各テストコードのファイル名は、`xxxSpec.hs`とする
	- 各テストコードのファイルは、`Spec`型の、`spec`という名前の関数をエクスポートするモジュールにする必要がある。
    - 以下の一行だけを持つ、`test/Spec.hs`というファイルを作っておく。
   
    ```haskell:test/Spec.hs
   {-# OPTIONS_GHC -F -pgmF hspec-discover #-}
    ```

- `stack build`としてプロダクションコードをビルド、その後`stack test`とすると、全てのテストコードが実行される。
このとき、裏ではHSpecのAutomatic spec discoveryが走っており、自動的にテストコードを収集、実行してくれている。

### II. senseiを使って、テストコードorプロダクションコードが変更されたら即座にテストを自動実行できるようにする

さらに便利にするために、[sensei](https://github.com/hspec/sensei)というツールで、コードの変更を自動で検知し、即座にテスト実行できるようにする。

上記手順Iが終わっているという想定で、下記手順を実行。

- `stack install sensei`として、senseiをインストール。

- senseiは、デフォルトでは`$HOME/.local/bin`にインストールされるが、ここにパスが通っている必要がある。そこで、`.zshrc`や`.bashrc`などに以下の行を追加してパスを通す。その後シェル再起動もしくは`source ~/.zshrc`などでリロード。

```sh
PATH="$HOME/.local/bin:$PATH"
```
- 手順Iで作ったstackで作ったプロジェクトのルートディレクトリに、下記内容の`.ghci`という名前のファイルを作成。(これを行わないと、senseiが`test`ディレクトリの中のモジュールを読み込んでくれず、エラーになってしまう)

```
:set -isrc -itest
```
- プロジェクトのルートディレクトリで、`stack exec sensei test/Spec.hs`とすると、senseiが立ち上がり、テストが自動実行される。この状態で、プロダクションorテストコードを変更すると、即座にテストが再実行されるようになる。
個人で小規模サービスをリリースしたときのメモ

# 開発のきっかけ／この記事の目的
コロナ渦前の出来事で、SNSで知り合った知人とオフ会を通じて親しくなり、

「こんなんやってるんだけど、世の中のサービスが使いづらくって。
  あんなことやこんなことに配慮できるサービスが作れたらいんだけどな。
  できる？ オナシャス:bow_tone1:」

という、飲み会でアルコールもほどよく入った状態から、

「できますとも:ok_hand:　ちょうど興味があったので。やりましょう:beers:」

という、エンジニアが頼られるありがちな話からスタートして、
隔週程度のskype会議、chatworkでのコミュニケーションを経て、
半年後にβ版としてリリースしました。

採用したサービス・技術スタック、ポイントを整理する目的で筆を執ることにしました。

# 採用したサービス／技術スタック

* 方向性
  * 企画する人が使い、開発する人が使う
  * 利用者で運用費を負担（割り勘）するコンセプトで企画費、開発費などは個別に徴収しない
  * 小規模のため運用費は固定がいい（という全体の意見）
  * 細く長く使いたい
  * 開発者１名、初めて全工程に取り組むのでPaaSに頼らずスクラッチで組み上げる

* サービス／技術スタック
 * システム構成図は以下の通り。
  ![スクリーンショット 2021-07-23 16.11.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121442/bd3c2739-aa40-c503-3e2c-ccc7eed1027f.png)

 * 詳細を以下の表に示します。  
 
        | 観点 | 内容 |
        |:----------:|:-----------:|
        | 実行環境       | [さくらVPS 2G](https://vps.sakura.ad.jp/)  |
    | ドメイン管理 | [さくらのドメイン](https://domain.sakura.ad.jp/)|
    | SSL証明書 | Let's Encrypt |
    |OS|Ubuntu 18.04 |
    |Webサーバ| Nginx 1.14|
    |Webアプリフレームワーク | Django 1.11 |
    |データベース| MongoDB 3.4 |
    |ユーザ認証 | Keycloak 3.4.4 |

# ポイント
* Ubuntu
    * iptables, ufwによるフィルタ
* Nginx
    * letsencryptの設定
    * 内部Webアプリケーション、keycloackへのlocationの設定
    * 404,403等のerror_pageの設定
* Keycloak
    * ログイン画面のテンプレートを修正
    * ユーザの新規追加/退会時の削除、ロールの定義によってユーザごとに許可する機能をカスタマイズ
    * （ユーザからのパスワード変更などはこのサービスに任せられる）
* Django&Webアプリ
    * Keycloak連携のためのパッケージ
        * https://github.com/jhuapl-boss/django-oidc.git
        * https://github.com/jhuapl-boss/drf-oidc-auth.git
        * https://github.com/jhuapl-boss/boss-oidc.git
    * bossoidc.backendからget_roles(token)してロール別のviewを制御
    * デザインはthemeforest.netなどで小規模ライセンスを数十ドルで購入して簡素に対応

# まとめ
プライベートの開発捻出時間は40h/月がいいところで（家庭の事情など各位の状況に依存しますねー）、
OSレイヤーから1人で運用するのは、結構やりがいがありました。
でも、アタックのログが気になる・・・。
次は、Ubuntu/Nginx/Keycloak/mongodbあたりをクラウドのPaaSに任せて、
アプリケーション部分に集中するような開発を実践していきたいと思います。
費用徴収もキャッシュレスで集金したりリモートで完結することを意識しているのですが、
最初っから割り勘で契約できるといいのですけれどね。
Ubuntu + Blenderで辺ループ選択できない問題対応メモ

Ubunt18.04 上でBlender2.93を使っていて、Macだとできる辺ループ選択`Alt+左クリック`(古いバージョンは右クリック)が動かなかったので対応メモ

`compizconfig setting manager`で「ウインドウメニュー」のキー割当を`Alt+Button3`から他のキーに割当てみたが変わらず。

最終的に`gnome-tweaks` の「ウインドウ操作キー」で`Alt`を`無効`に変更することで動いた。

![Screenshot from 2021-07-23 15-08-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118567/b1494528-997a-2f23-33a8-2fef93a25d23.png)
Google翻訳、DeepL翻訳ともに、エラーメッセージの日本語訳が上手な気がする。

# Google翻訳、DeepL翻訳ともに、エラーメッセージの日本語訳が上手な気がする。（トレーニングデータとして直接学習しているのでは。）

タイトルの通り。
対訳の入手が可能で、トレーニングデータとして、それらを利用しているのでは？という推測。この推測が正しい可能性２０％ぐらい。

# 例1

## 原文
TypeError: Expected cv::UMat for argument 'array'

## Google翻訳
TypeError：引数 'array'にcv :: UMatが必要です

## DeepL翻訳
TypeError: 引数 'array' には cv::UMat が必要です。

## 補足
Expected　⇔　必要　は、通常の領域（ドメイン）では、出てこない翻訳では？

# まとめ
特になし
Databricksにて外部Hive Metastore（ver:2.3.7）を構築する際にデータベースを初期化する方法について

## 概要
2021年7月23時点にて、Databricksにて外部Hive Metastore（version:2.3.7）を構築する際にデータベースの初期化をDatabricks（Spark）から実施できなかったため、Hiveのコードに含まれるDDLを事前に実行する方法を共有します。下記のいずれのDBでも初期化がされず、同様にHiveのDDLを事前に実行することで適切に動しました。

- Azure SQL Database 
- Azure Database for MySQL


Databricksのドキュメントにて下記のように記載がある通り、外部Hive Metastoreを構築する際のデータベースの初期化（≒テーブル作成）を実施してくれるとの記載があったので実行したのですが、私の環境では動作しませんでした。

```SparkConfig
datanucleus.autoCreateSchema true
datanucleus.fixedDatastore false
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/0b0fded7-9957-8245-90ea-aa32205849a9.png)
引用元：[外部Apache Hiveメタストア - Azure Databricks - Workspace | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/databricks/data/metastores/external-hive-metastore#troubleshooting)

私の環境では、下記のようなエラーメッセージが表示されておりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/692c89d1-5a1a-e5e8-1bbf-b0ded4b34866.png)


## 検証環境
Databricks Runtime 7.3とDatabricks Runtime 8.3のいずれでも同様の動作でした。

### 検証環境１
databricks runtime: 7.3.x-cpu-ml-scala2.12
Python  version:    3.7.10
pyspark version:    3.0.0.dev0

### 検証環境２
databricks runtime: 8.3.x-scala2.12
Python  version:    3.8.8
pyspark version:    3.1.2.dev0


## 手順
### 1. GithubにおけるHiveのレポジトリから想定のデータベースとHiveのバージョン（今回は2.3.0）のDDL文をダウンロードします。

- Azure SQL Databaseの場合
    - https://github.com/apache/hive/blob/master/metastore/scripts/upgrade/mssql/hive-schema-2.3.0.mssql.sql
- Azure Database for MySQLの場合
    - https://github.com/apache/hive/blob/master/metastore/scripts/upgrade/mysql/hive-schema-2.3.0.mysql.sql

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/48387977-25c7-8a96-855d-b6b1985c99b5.png)
引用元：[hive/hive-schema-2.3.0.mssql.sql at master · apache/hive (github.com)](https://github.com/apache/hive/blob/master/metastore/scripts/upgrade/mssql/hive-schema-2.3.0.mssql.sql)

### 2. ダウンロードしたファイルを実行します。
MySQLにてすべてのクエリを実行する場合には`SOURCE hive-txn-schema-2.3.0.mysql.sql;`のところでエラーとなるため、その後の`INSERT INTO VERSION...`のところも実行してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/fdaa4865-01dd-d873-0b7f-1980b16200f0.png)


### 3. エラー表示が消え、データベース・テーブルが作成できることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/729f50a3-2f29-46bc-c78f-9cf0011d5715.png)
Railsで架空のCafeのHPを作ってみよう!【10日目】『deviseのform_forにクラス名をつける』編

#概要
基本Railsの記法に則り書いていきます！
１から全ての説明ではなく
その中であれ？どうやるの？と
疑問に思った点や実装に困った箇所を
ピックアップして紹介していきます♩

#設定と準備
・Rails
・HTML
・CSS
・Javascript(jQuery)

↑上記の言語とフレームワークを使い
架空(自分で考えたテキトーなもの)のCafeの
HPを作っていこうと思います！

#10日目の作業内容:round_pushpin:
・ビューの作成

#10日目の気になった箇所:zap:
deviseを導入しdeviseで用意されたviewを使いつつ
自分でレイアウトしたいがclass名の付与がうまくいかない。

#仮説:pushpin:
<%= %>←railsの記法であるこの形は<div>タグと同じ扱いになるため
クラス名を付与すればcssファイルを使い編集することことが可能なため

```views/registrations/new.html.erb

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>

  <%= f.email_field :email, autofocus: true, autocomplete: "email" %>

  <%= f.password_field :password, autocomplete: "new-password" %>

  <%= f.password_field :password_confirmation, autocomplete: "new-password" %>

  <%= f.submit "Sign up" %>

<% end %>

```
これらにクラス名を付与していけば編集が可能だと思われる。
しかし、上手くclass名が付与できない。
(上記のマークダウンはsign inするのに最小限必要なものだけを抜き出して記述しております)

#結論:star:
今回の場合、
class名の書き方が<%= form_for %>と<%= f. %>で異なることがわかった。

```views/registrations/new.html.erb
form_forの場合

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {class:"sample"}) do |f| %>

<% end %>

```

このように html: {class:""} という記述が必要になる。
(今回の場合sampleというclass名を付与)

```views/registrations/new.html.erb
f. の場合
  <%= f.submit "Sign up", class:"sample" %>

```

こちらはclass:""とすることでclass名の付与ができる。

今回formのブロック変数であるfを使った場所に対してのclass名付与でしたが
railsの記法である<%= %>も同じようにclass名を付与できます。

```
例)
<%= @sample.name, class:"sample" %>
```

form_forの場合や私が確認した中ですとactive hashを使ったものの場合などは
class名の付与が違う場合があるので気をつけましょう！
Python。OpenCVのバージョンをエラー発生都合で上げたり下げたりする。

# OpenCVのバージョンをエラー発生都合で上げたり下げたりする。
タイトルの通り。

# 事例1
# エラーメッセージ
```
TypeError: Expected cv::UMat for argument 'array'
```

全体としては、以下。

```
Traceback (most recent call last):
  File "C:\Users\XYZZ0\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 121, in worker
    result = (True, func(*args, **kwds))
  File "C:\Users\XYZZ0\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 47, in starmapstar
    return list(itertools.starmap(args[0], args[1]))
  File "C:\_panorama\_panorama_test01\panoramas-image-stitching-master\src\utils.py", line 75, in cylindrical_projection
    x, y, w, h = cv2.boundingRect(contours[0])
TypeError: Expected cv::UMat for argument 'array'
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "./main.py", line 29, in <module>
    cylinder_img_list = pool.starmap(utils.cylindrical_projection, [(img_list[i], focal_length[i]) for i in range(len(img_list))])
  File "C:\Users\XYZZ0\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 276, in starmap
    return self._map_async(func, iterable, starmapstar, chunksize).get()
  File "C:\Users\XYZZ0\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 657, in get
    raise self._value
TypeError: Expected cv::UMat for argument 'array'
```

# エラーが発生した作業内容
https://github.com/SSARCandy/panoramas-image-stitching

# エラー発生時のバージョン
opencv-python-4.1.0.25

# エラー解決時のバージョン
opencv-python-3.4.15.55
  
```
python -m pip install "opencv < 4.0.0"
```

# まとめ
特にありません。エラーを分析してくれるツールを作りたいとは思っているのですが。。。
OpenAI の GPT-3 でノーコードでシナリオ生成

# この記事の内容

最強の言語処理AIとの呼び声も高い GPT-3 を OpenAI がベータとして提供しています。
その性能を試すために、日本語でのシナリオ自動生成を試します。

既存の会話シナリオの少数（70セリフ程度）の例を与えて、それっぽい出力ができているかを試します。

OpenAI の Playground で試しているので、コーディングはなにもしていません。そう、ノーコード。
・・・すみません、流行り言葉をちょっと使ってみたかっただけです。

# 論より Run

10回くらい出力させてみて、気になったものをピックアップ。

![出力サンプル1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151254/2f7c1067-4440-cdb1-3f08-35a31b9e0ed5.png)

値上がりしたようです。

![出力サンプル2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151254/bd2012f0-54f5-51ee-5453-8c9609b34730.png)

Fly Me To The Moon.
例示には一人称が「僕」の文があるのですが、強く誘導されなかったようですね。

![出力サンプル3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151254/6f1d8836-c4b3-299b-e6f7-b492111bb9f3.png)

入れている会話サンプルに「ビーム」も「セカンドアタック」もないので、GPT-3が内包している何かの ~~性癖~~ 学習データのトリガーを引いてしまった模様。

![出力サンプル4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151254/8abdeb96-b2bb-e1e4-3d7f-9c931e8587d2.png)

頼んでもいないのに次回予告が生成されました。
入力に「次回予告」も「〜の中の声」もないので、GPT-3の中に眠れる何かを引き出してしまったようです。

# 解説という名の蛇足

OpenAI の GPT-3 は現在ベータで、[公式サイト](https://beta.openai.com/)から WAITLIST に登録することができます。私の場合はかなり前に「日本語でどのくらい使えるのか、遊んでみたいから（意訳）」というような理由で申し込んだところ、忘れた頃に案内が来ました。

[GPT-3 の解説はネット上にたくさんある](https://www.intellilink.co.jp/column/ai/2021/031700.aspx)ので、そちらを参照いただくとして、何をしたかだけ簡単に。

OpenAI の GPT-3 は Fine-tuning にも対応しているのですが、まずは Few-Shot での例示から、どれだけそれっぽいシナリオ生成ができるのかを確認しました。

text prompt として与えたのは以下のようなテキストです。既存のシナリオから抜き出した5シーンの計70セリフ程度。
prompt（入力）と completion（出力） の合計が最大2048トークンという制限があるため、制限にかからない範囲に調整しました。

```
人物名1: セリフ
人物名2: セリフ
（続きの会話）...

###

（次の文脈での会話）...

###

しゃべりだしの人物名:
```

これで Submit することで、続きを補完しようとして、シナリオの自動生成が動き出すというわけです。

パラメータはほぼデフォルトで。Response Length を長めにして、長文の出力をするようにしたり、Temperature を 0.7 から大きくすることでよりカオスな展開にさせてみたりもしていますが、Temperature を大きくしすぎると例示で与えた会話フォーマットすら崩れていくので、ほどほどで。

## お値段など

一番強力な Davinci モデルを使っているので、1000トークンあたり6セント。1例生成するたびに2000トークン使っているので、12セントくらい費用がかかっていることになります。

アカウント作成時に最初の3ヶ月間使える18ドルのクレジットが付与されていますので、ちょっと遊ぶだけなら無料ですが、きちんと使おうと思うと、安いモデルでも同等の性能が出るかの評価など、やり方を色々考える必要がありますね。

## その他

改正された著作権法の30条の4で、AIのモデル作成のために既存の著作物を利用することは広い範囲で適法になりましたし、キャラクターの名前だけであれば著作権は及ばないとされるのが通常ですが、既存の著作物から学習したAIでそれっぽいセリフを生成することを業として行うことは、さまざまなリスクがありますよ、という当たり前のことを最後に書き記しておきます。

## （追記）fine-tuning

fine-tuning も試しているのですが、fine-tuning に対応している curie エンジンだと、そもそもキャラクターを保った会話生成ができないという悩みを抱えていまして、プロンプトの改善でどうにかなるレベルなのかと懐疑的です。

そして、セリフを単体で fine-tuning に流し込んでも、男性キャラが女性のセリフで話し始めたりと、変なフィッティングが行われてつらい・・・。

few-shot でそれなりに動く davinci エンジンの汎用性がすごいですね。（けど、高い）
paizaで個人的にお世話になった記法【Python編】

#Progateを一通り終えたら次はpaizaだ！
そんな声を聞いたのでやり始めた去年の夏。
Dランクですら回答がままならないのに凹んでた学習中の私。
色々躓きまくったが、ロジック力やデバック力やググり力が付いたので結果的にとても良く、今でもちょっとややこしい処理を書く時にはあの時の経験を活かして解決できていると自負してる。

Aランク目指してたまーにやろうかなと思ったから復習まとめ&これから勉強して行く初学者の方達に少しでも力になれればと、paizaの問題でよく使った入力と出力とかの記法を纏めます。(Bランク相当)
思いついたりしたら新しく足して行くかも


##標準入力編

#####スペース区切りの数値をリストに

```Python
30 30 10
```

```Python
num_list = [int(i) for i input().split()]
print(num_list)
```
>[30, 30, 10]

#####スペース区切りの数値をそれぞれの変数に

```Python
30 30 10
```

```Python
num1, num2, num3 = list(map(int, input().split()))
print(num1, num2, num3)
```
>30, 30, 10

#####連続した数値の入力処理

```Python
3
6 
7 
8 
```

```Python
num_list =[ int(input()) for i in range(4)]
print(num_list)
```
>[3, 6, 7, 8]

#####連続した入力を辞書型に

```Python
"A" 3
"B" 5
"C" 5
```

```Python
num_dic = {}
for i in range(3):
    word, num = input().split()
    num_dic[word] = int(num)

print(num_dic)
    
```
>{"A": 1, "B": 2, "C": 3}

#####多次元配列

```Python
66737
56173
59414
25469
63955
```

```Python
num_list = []

for i in range(5):
    nums = list(map(int, input()))
    num_list.append(nums)
    
print(num_list)
```

>[[6, 6, 7, 3, 7], [5, 6, 1, 7, 3], [5, 9, 4, 1, 4], [2, 5, 4, 6, 9], [6, 3, 9, 5, 5]]

##出力編

#####辞書型

```Python
num_dic = {"A": 1, "B": 2, "C": 3}

for word, num in num_dic.items():
  print(word, num)

```

>"A", 3
"B", 5
"C", 5

#####多次元配列
その１

```Python
num_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

for i in range(3):
  for j in range(3):
    print(num_list[i][j])

```

>1
2
3
4
5
6
7
8
9

その２

```Python
num_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

for nums in num_list:
  print(nums)
  for num in nums:
    print(num)

```

>[1, 2, 3]
1
2
3
[4, 5, 6]
4
5
6
[7, 8, 9]
7
8
9

#####末尾のスペース消せなくて困ってる場合

```Python
word_list = [["A", "B", "C"], ["D", "E", "F"], ["G", "I", "H"]]

for i in word_list:
    print(' '.join(map(str, i)))
```

>A B C
D E F
G I H


##番外編

#####アルファベットのリスト

```Python
alpha_list1 = []
alpha_list2 = []
for i,c in enumerate(range(ord('A'),ord('Z')+1)):
    alpha_list1.append(chr(c))
print(alpha_list1)
for i,c in enumerate(range(ord('a'),ord('z')+1)):
    alpha_list2.append(chr(c))
print(alpha_list2)
```
(iには０からの数字が入っている。なくても動く)

>[['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

#####リストのソート
昇順

```Python
num_list = [3, 4, 2, 1]
num_list.sort()
print(num_list)

```
>[1, 2, 3, 4]

降順

```Python
num_list = [3, 4, 2, 1]
num_list.sort(reverse=True)
print(num_list)

```
>[4, 3, 2, 1]
Railsコマンドが動作しなくなって困った話

# 状況整理
 - Railsアプリを作り勉強中
 - `rails g ~~~` を実行するとターミナルがフリーズ
 - `control + c`で止めるとエラーが出力される
 - ターミナルを閉じても状況変わらず上記をループ

# 現状
エラーコードの内容はこんな感じです。

```
Traceback (most recent call last):
        17: from bin/rails:2:in `<main>'
        16: from bin/rails:2:in `load'
        15: from /Users/ryo/git/sample/bin/spring:7:in `<top (required)>'
        14: from /Users/ryo/git/sample/bin/spring:7:in `tap'
        13: from /Users/ryo/git/sample/bin/spring:10:in `block in <top (required)>'
        12: from /Users/ryo/git/sample/bin/spring:10:in `require'
        11: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/binstub.rb:11:in `<top (required)>'
        10: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/binstub.rb:11:in `load'
         9: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/bin/spring:49:in `<top (required)>'
         8: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client.rb:30:in `run'
         7: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client/command.rb:7:in `call'
         6: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client/rails.rb:24:in `call'
         5: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client/command.rb:7:in `call'
         4: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client/run.rb:35:in `call'
         3: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client/run.rb:42:in `warm_run'
         2: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client/run.rb:62:in `run'
         1: from /Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client/run.rb:117:in `verify_server_version'
/Users/ryo/git/sample/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib/spring/client/run.rb:117:in `gets': Interrupt
```
springが関係してる感じ？
# 対応
とりあえずプロセスを確認

```
ps aux | grep spring
ryo    34384   0.7  0.1  4404564  10456   ??  Ss   11 721   13:57.60 ruby -I /Users/ryo/git/53/vendor/bundle/ruby/2.7.0/gems/spring-2.1.1/lib -e require 'spring/application/boot'
ryo    67650   0.0  0.1  4389184  11980   ??  S    11:34AM   0:00.34 spring server | sample | started 1 hour ago   
ryo    19556   0.0  0.0  4384084   4388   ??  S     8 721    0:00.42 spring server | project_53 | started 362 hours ago   
ryo    70187   0.0  0.0  4268424    696 s003  S+    1:30PM   0:00.00 grep spring
```

一旦再起動させてみた

```
$ kill -9 67650
```
再度`rails g `を実行

```
$ rails g model User name:string email:string
invoke  active_record
      create    db/migrate/20210723043237_create_users.rb
      create    app/models/user.rb
```
なおりました！

# 参考資料
- [railsのコマンドが動かない時はspringを(stop|kill)してみよう](https://qiita.com/yokozawa/items/7b92c260f8c3dfec8e28)
- [【ps・kill】実行中のプロセス表示と強制終了](https://qiita.com/shuntaro_tamura/items/4016868bda604baeac3c)
SymPyの定積分を使ってみたくて、自動車タイヤのゴムの減りkgを考えてみた


　Pythonに、便利な代数計算能力を与えるSymPyモジュール。これの自分の腕試しに定積分をしてみようと思い、題材を自動車タイヤのゴムの減りの重さ(kg)を考えてみました。
　式さえ立てられれば、あとの計算は、SymPyにお任せです。

#式に至る考え
　自動車タイヤを路面に接する部分の表面積は、$2πrh$。これを使って、タイヤがすり減った際の、減ったゴムの体積を考える。
　半径 $r$ のタイヤが、半径 $r-x$ にまで減ったとする。
　すると、$2πrh$ と $2π(r-x)h$ で定積分すると、溝の分の考慮無しですが、減ったゴム体積が求まる（と思う）。これにゴムの重さ（水との比重）を使うと、減ったゴムの重さが求まる。
![sym.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173967/9f99dcc8-e1ff-2d73-a535-1ae549aa537b.png)


 定積分の$\int_{r-x}^{r}$は、SymPyではintegrate(式, limの下, limの上)
 これに、数字を当てはめる。

*半径310ミリメートルのタイヤが、半径305ミリメートルにまで減（ _x_=5 ミリメートル）
*タイヤの幅は200ミリ
*1立方ミリメートルは、1ミリグラム
*タイヤのゴムをイソプレンゴムとすると比重は0.92
*タイヤの溝の体積を20%とする

# SymPYを使う

　このタイヤ1本の、すり減った重さ（kg）は、

```py
from sympy import  *
r = symbols("r")
r1 = 305
r2 = 310
h = 200
m = 2 * 3.14 * r * h 
integrate(m, (r, r1, r2)) *0.92 / 1000 /1000 * 0.8
```
　結果、1.4212896キログラム。
　<font color="red">∴4本で、約5.7キログラム。</font>
　日本では、数100万台の自動車が走っているので、結構な量はすり減っている。

※式は、あっているのかな？

※ところで、以下の答えは、$\sqrt{2}$と $-\sqrt{2}$。SymPyは、検算に結構便利（宿題にも）。

```py
from sympy import  *
x = symbols("x")
y = x ** 2 - 2
solve(y)
```
以上