OmniAICreator/Qiita-1.07M huggingface dataset:
Watson Speech to Text for Embedを使用してみた

## 初めに
オンプレ環境を含め、コンテナが動く環境であれば、Watson Speech to Text / Text to Speech が使える
IBM Watson Speech Libraries for Embedが発表されています。
そこで、今回はWindows 10環境に導入し、音声認識(speech to text)を実施してみました。

※IBM Cloud版のWatson Speech to Textの実行については、下記をご参照ください。
[PowerShellからIBM Watson Speech to Text / Text to Speech を使ってみた](https://qiita.com/ac_qiita/items/a06acbbffc594e30852c)

## 前提
コンテナイメージをダウンロードするためのEntitlementキーが入手できていること。
https://www.ibm.com/products/watson-speech-embed-libraries から評価版を申請できます。

## 実施手順

### 1. 「Container Desktp」の導入
Windows 10でコンテナを実行するために、「Container Desktop」を導入します。
導入手順については、以下を参照してください。
[Container Desktopを試してみた](https://qiita.com/ac_qiita/items/4e9820410abde12b740b)

### 2. イメージの作成
以下のようなDockerfileを作成します。
今回は、日本語が使えるようにしています。ほかの言語も提供されています。
詳細は[ドキュメント](https://www.ibm.com/docs/ja/watson-libraries)を参照してください。

```
# Model images
FROM cp.icr.io/cp/ai/watson-stt-generic-models:1.1.0 as catalog
FROM cp.icr.io/cp/ai/watson-stt-ja-jp-multimedia:1.1.0 as ja-jp-multimedia

# Base image for the runtime
FROM cp.icr.io/cp/ai/watson-stt-runtime:1.1.0 AS runtime

# Configure the runtime
# MODELS is a comma separated list of Model IDs
ENV MODELS=ja-JP_Multimedia
ENV DEFAULT_MODEL=ja-JP_Multimedia

# Copy in the catalog
# $CHUCK is already set in the base image
COPY --chown=watson:0 --from=catalog catalog.json ${CHUCK}/var/catalog.json

# Intermediate image to populate the model cache
FROM runtime as model_cache

# Copy model archives from model images
RUN sudo mkdir -p /models/pool2
COPY --chown=watson:0 --from=ja-jp-multimedia model/* /models/pool2/

# Run script to initialize the model cache from the model archives
RUN prepare_models.sh

# Final runtime image with models baked in
FROM runtime as release

COPY --from=model_cache ${CHUCK}/var/cache/ ${CHUCK}/var/cache/
```

Dockerfileを作成したら、そこからイメージファイルを作成します。

```
docker build . -t stt-standalone
```


### 3. コンテナの起動
以下のコマンドを実行し、作成したイメージからコンテナを起動します。


```
docker run -d --rm --name stt-standalone --env ACCEPT_LICENSE=true --publish 1080:1080 stt-standalone
```


### 4. APIをコールし、音声認識を実行。
PowerShell上で以下のコマンドを実行し、音声認識できることを確認します。

```
$result = Invoke-RestMethod -Method POST -Headers @{"Content-Type"="audio/mp3"} -InFile common_voice_ja_20088745.mp3 -Uri "http://localhost:1080/speech-to-text/api/v1/recognize?model=ja-JP_Multimedia"
$result.recoResult | ForEach-Object {$_.results | ForEach-Object {Write-Host $_.alternatives[0].transcript}}
```
※音声ファイル「common_voice_ja_20088745.mp3」は、お手持ちのmp3ファイルに置き換えてください。
【メモ】WordPressでPHPのカスタマイズ

# 【メモ】WordPressでPHPのカスタマイズ

## ■自分の状況

Laravel、Fuelなどでの開発経験があるが、WordPressにはふれたことがない。

自分の開発メモ、情報共有として。



## ■function.phpとショートコードを用いたサンプル

### ●現時点の理解

- function.php

  →関数の定義ファイル。ここにコードを追加してカスタムする

  →配置場所：/wp-content/themes/テーマの名前/function.php

  ​	→存在するテーマごとにfunction.phpが存在している。

  ​		→ファイルを間違えないように注意

  ​		→テーマの適用のし忘れ注意

- ショートコード

  →テーマからfunction.phpを呼びだすための仕組み

### ●サンプル

#### function.php

パス：配置場所：/wp-content/themes/テーマの名前/function.php

```php
function testFunc() {
    // returnとバッファの利用でechoでコード出力際のずれを補正
    // ショートコードの処理をob_start();とreturn ob_get_clean();で囲む
    ob_start();
    echo the_title();
    
    // ちなみに、exitをつかって処理をとめることもできる...デバッグ用に
		// $test = '現時点までで処理がとまる';
		// echo $test;
		// exit;
		
    return ob_get_clean();
}
// ショートコードを定義して、使用できるようにする
// add_shortcode('ショートコード名', 'メソッド名');
add_shortcode('test', 'testFunc');
```

##### 適用したいページでショートコード埋め込み

構文：[ショートコード名]

```
 ショートコードでタイトル表示：[test]
```
ラズパイにvscodeを入れる方法(raspbianとubuntu)

# **raspbianの場合**
```
$ sudo apt install code
```

# **ubuntuの場合**
(1)下記サイトにアクセス。
https://code.visualstudio.com/Download

(2)**.deb**の**Arm64**をダウンロード(ラズパイは**Arm64**のプロセッサが使用されているため)
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333131333732342f33363761373432622d343564362d653665662d343938372d373132313.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113724/adf713f2-f640-173b-cc2a-aed616465dc4.png)

(3)先ほどダウンロードしたディレクトリに移動
```
$ cd Download
```

(4)dpkgコマンド実行
＊**code_1.74.3-1673284080_arm64.deb**の所はダウンロードパッケージ名
＊**-i**オプションはインストールの略(詳しくは
https://qiita.com/sei_yu/items/d3267c91b47198279a7e
を参照)
```
$ dpkg -i code_1.74.3-1673284080_arm64.deb
$ (sudo apt install code_1.74.3-1673284080_arm64.deb)←こっちでも可能
```
chatgpt を使ってライティング

chatgptを使って、クオリティの高い記事を作りたい

https://twikon.club
を作っているが、記事の外注も面倒なので自動で生成できないか検討中。

この「twitter 婚活 方法」というのを好きなワードに変更するだけで、他の文章も生成することができる。


# 以下のプロンプトでどんどん新しいもじを書いていける

```
以下のプログラムをシミュレートし、再帰的に品質をアップしつつ文章を作成してください
最終的に完成した文章のみを表示してください

def create_text(theme):
	quality = 0
	text = generate(theme)
	review = review_text(text)
	
	i = 0
	while i < 10:
		text = update_text(theme,review)
		review_how_to_fix = review_text(text)
		i++
		print(text)
		print(review_how_to_fix)
	
theme = "恋愛小説の書き出し"
create_text(theme)

```



# 追記
クレジットカードで検索した時表示されるキーワードで、他のユーザーが検索したものをそのままchatgptに入力して記事を作る

# 見出しを生成する

```
Googleで「Twitter婚活 方法」と検索した際に上位表示される記事の見出しを生成して下さい
```


# 生成された見出しから、更に小見出しを出力する

```
上記の見出し候補をさらに深く掘り下げて小見出しを追加して下さい
```

# 小見出しに対する記事を生成

```
上記の、「さらに深く掘り下げて小見出し」に対する記事を、それぞれ書いて下さい
```


chatgptが途中で止まった場合は

```
続けて出力せよ
```

# キーワードアイデアを出す

```
「twitter婚活」とGoogle検索したユーザーが、次に検索する可能性がある検索ワードを抽出せよ
```

# メモ



整形された文章の作り方

先に命令文、順番に実行

```
[C1] 「クレジットカード　社会人　おすすめ」ブログ記事の構成案

[C2] 各見出しごとに文章を500文字で作成してください]

> Run[C1]->[C2]
```


商品説明をしてくれる



婚活失敗事例をネタにする

ネガティブキーワードおすすめ
・後悔
・いらない
・やめとけ
・できない
・効果ない

みたいなキーワード

掛け合わせるツールを作るか



[C1] 「婚活　20代　おすすめ」ブログ記事の構成案

[C2] 各見出しごとに文章を500文字で作成してください]

> Run[C1]->[C2]
slickの実装でつまづいたところ

<h2>目次</h2>
　<ul>
　　<li>各画像のサイズがバラバラだったこと</li>
　　<li>複数枚表示の設定にしたときに、画像の数がそれ以下だったこと</li>
　　<li>課題</li>
　</ul>
<div>
　<h2 id=1>各画像のサイズがバラバラだったこと</h2>
　<p>スマホで撮影した３つの画像を用意して基本のスライダーを作ってみたのですが、画像のサイズが大きすぎて、画面いっぱいに表示されてしまいました。<br>
そのため、CSSでwidthを600pxなどに変更してみたのですが、今度は画像が左端の方に表示されてしまいました。<br>
imgはdiv要素に入っているので、divの左端に寄っているのだということが分かり、CSSで<strong>"margin : auto"</strong>に設定。<br>
これで左端だったものを中央に寄せることができました。<br>
ところが、各画像の元々のサイズがバラバラだったため、スライドするたびに画像の高さが変わってしまい、イマイチな感じでした。<br>
そのため、サイズを揃えたいと思いCSSでwidthやheightをいじってみたのですが、なぜか上手くいかず。<br>
サイズの変更について記述されたサイトを参照し、<strong>heightをvwで設定</strong>、<strong>"object-fit : cover"</strong>を記載してみたところ、改善しました。</p>
　<p>参照したサイト</p>
　<a>https://design-levelup.com/webdesign/js/jquery_making_3/</a><br>
　<a>https://and-ha.com/coding/slick/</a>
</div>
<div>
　<h2 id=2>複数枚表示の設定にしたときに、画像の数がそれ以下だったこと</h2>
　<p>色々なパターンのslickの実装を試していた時に、もう一つ躓いた点があります。<br>
それは、３枚のスライドを表示させるタイプの実装を行っている時に、そもそも用意している画像がぴったり３枚だったために、<strong>それ以上スライドして表示させる画像がなく、スライダーとして機能しなかった</strong>ことです。<br>
なぜスライドしないのか理解するまで少し時間がかかりました。<br>
最終的にこのタイプのスライダーは採用しませんでしたが、覚えておく必要があるなと思ったので記載させていただきます。</p>
</div>
<div>
　<h2>課題</h2>
　<p>とりあえず簡単なslickの実装は完了しましたが、ググると様々なslickのカスタマイズができることが分かりました。<br>
cssの記載がたくさんあったりして理解が難しかったので、余裕ができたら理解できるように勉強したいと思います。<br>
それと、slickを実装したタイミングだと思うのですが、サイトがとても重くなって、<strong>リロードにすごく時間がかかる</strong>ようになってしまいました。<br>
画像のサイズが大きいせいかと思い、画像のリサイズをして容量を小さくしてみたのですが変わりはなく、これをなんとか改善せねばと思っています。<br>
読み込んでいるファイルが多いからでしょうか。css、Bootstrap、slick、Javascript、Jquery...。<br>
その問題を調査しつつ、次はProfileのパートに取り掛かりたいと思っています。
</p>
</div>
Testing LibraryのgetByRoleで指定できる属性一覧

`getByRole("指定するキーワード")`で取得可能。
属性が複数存在する場合は`getAllByRole("指定するキーワード")`で取得する。

|  属性  |  指定するキーワード  |
| ---- | ---- |
|  article  |  article  |
|  button  |  button  |
|  td  |  cell, gridcell  |
|  input(type=checkbox)  |  checkbox  |
|  input(type=radio)  |  radio  |
|  input(type=search)  | searchbox   |
|  input(type=text)  |  textbox  |
|  th  |  columnheader  |
|  select  |  combobox, listbox  |
|  menuitem  |  command, menuitem  |
|  dd  |  definition  |
|  figure  |  figure  |
|  form  |   form |
|  table  |  grid, table  |
|  fieldset  |  group  |
|  h1 ~ h6  |  heading  |
|  img  |  img  |
|  a  |  link  |
|link|link|
|ol, ul |list|
|li|listitem|
|nav|navigation|
|option|option|
|frame|region|
|rel|roletype|
|tr|row|
|tbody, tfoot, thead|rowgroup|
|hr|separator|
|dt, dfn|term|
|textarea|textbox|


aタグはhref属性が無いと反応しない？要検証、、、
AndroidのエミュレーターでFirebaseがタイムアウトになる事象の対応

# 背景
- Flutterアプリを開発中に複数デバイスで動作確認を行っていた際、Androidのエミュレーター使用時のみFirebaseへの接続がうまくいっておらず、データが更新されないことが起こった。
- ちなみに前日までは同じエミュレーター上で正常に動いていた。

# エラー内容
```
Could not reach Cloud Firestore backend. 
Backend didn't respond within 10 seconds
``` 

# 解決方法
- どうやらエミュレーター側の問題のようで、新しいエミュレーターを作成してインストールすることで、Firebaseに接続することができた。

# 参考
- [Firebase doesn't work on Android Studio Emulator](https://stackoverflow.com/questions/73370728/firebase-doesnt-work-on-android-studio-emulator/73584389#73584389)
- [Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds - Flutter Android Studio](https://stackoverflow.com/questions/73345658/could-not-reach-cloud-firestore-backend-backend-didnt-respond-within-10-second)
【WSL2】Windowsのファイル・フォルダをchmodする

#### 今回の内容  
WSL2(Windows Sussystem for Linux 2)にて、(Linux側ではなく)Windows側のファイル・フォルダをchmodで権限を変える方法についてです。  
  
#### 詳細について  
WSL2は、WindowsでLinuxを扱えるということで、(昨今は稼働サーバーがLinuxということが多いのもあって)開発環境として利用したり、Windowsのファイル・フォルダなどをLinuxベースで扱えたりと、大変便利です。  
  
しかし、実は「(WSLではなく)Windowsのファイル・フォルダは、chmodで権限を変えられない」という制約があり、これが結構不便だったりします。  
  
特に、リモート接続時などに使用する秘密鍵ファイルは、変に公開範囲が広いと接続時にエラーになるので(public key)、権限を変更したいのですが、  
  
- Windowsのファイル・フォルダは、chmodで権限を変えられない  
- WSL側で権限変更してからWindows側にコピーしても、なぜかWindows側で権限が変わってる(=公開範囲が広くなってる)  
  
ということがあるので、Windowsのファイル・フォルダも、chmodで権限を変えたい、というケースがあります。  
  
#### やり方  
で、いきなり結論ですが、下記の手順を踏むことで、Windowsのファイル・フォルダも、chmodで権限を実行できるようになります。(全てWSL2側での作業です)  
参考：[WSL2はファイル権限を変更できません](https://www.fixes.pub/program/695629.html)
  
1. ```/etc/wsl.conf``` ファイルを開く。(なければ作成する)
1. ```/etc/wsl.conf```に下記の内容を記載し、保存する
1. PCを再起動する。(これは無くてもできるかも...ただ再起動すれば確実)
  
```sh
# Enable extra metadata options by default
[automount]
enabled= true
root= /mnt/
options= "metadata,umask=22,fmask=11"
mountFsTab= false
# Enable DNS – even though these are turned on by default, we'll specify here just to be explicit.
[network]
generateHosts= true
generateResolvConf= true
```
  
上記手順を踏んだ後、WSL側でWindows側のファイル・フォルダをchmodしてみると、ちゃんと権限が変えられると思います。  
  
#### wsl.confと.wslconfigの違いについて  
とりあえず問題は解決しましたが、今回設定を記載した```etc/wsl.conf```ファイルについて、  
  
> Windowsのユーザーフォルダ(デフォルトではC:\Users\<ユーザー名>)に```.wslconfig```ってあったよな。あれとの違いは何だ？  
  
と思ったので、調べてみました。  
  
といっても、これはマイクロソフト公式サイトで、これ以上ないほど分かりやすい説明がありました。   
[wsl.conf と .wslconfig の違いは何ですか?](https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config#what-is-the-difference-between-wslconf-and-wslconfig)
  
簡単に言えば  
  
- ```etc/wsl.conf```はディストリビューション個別の設定  
- ```.wslconfig```は全ディストリビューションで共通の設定
  
ということみたいです。(ちなみに、先述の設定を```.wslconfig```に書いても、chmodで権限変更はできませんでした)  
  
#### 告知  
今週の土曜日(2023/1/21)に[VS Code Conference Japan 2022 - 2023](https://vscode.connpass.com/event/263206/)という、VS Code Meetup主催のVS Codeの一大イベントが開催されます。  
  
このイベントで「Remote SSHで行うVS Codeリモートホスト開発とトラブルシューティング」という内容で登壇させて頂くことになりましたので、よろしければぜひご参加ください。
  
ちなみに内容は、以前投稿した [【VS Code】Remote SSHでSSH接続する](https://makky12.hatenablog.com/entry/2022/09/20/120500) の記事をベースに、デモや発生頻度が高い「接続できない」事例も含めて紹介する予定です。  


それでは、今回はこの辺で。
バリデーション（withValidator）

### withValidatorを用いたバリデーション

メモです。

検索窓にて、
金額の上限と下限を設定するときに
#### 上限値が下限値未満の際にエラーになるバリデーションを作成したかった。

以下の記事を参考にさせていただきました。
https://www.kamome-susume.com/laravel-withvalidator/

$validator -> after(
function($validator){
	$使用する値１を入れる変数１　=　使用する値１を持ってくる
	$使用する値２を入れる変数２　=　使用する値２を持ってくる
 	if(isset( 変数１) && isset( 変数２)){
if(ここで上限下限のif文の条件を作成){
　　$validator->errors()->add(‘errorを表示する場所’, ‘エラー文’)
}
}
} ) ;

after の（）を最後閉じ忘れないように

上限値を下限値未満にするとエラーが表示されました。
WARP client で外から家のローカルネットワークをアクセスしたい

## 症状

WARP client でログインしても、お外から家のローカルネットワークをアクセスできない

## 前提条件
- Cloudflare アカウント作成済み、ZeroTrust アカウント作成済み（Freeアカウント）
- tunnel を Cloudflare ZeroTrust Web画面から作成済み
   - ⚠ ローカルで `cloudflared tunnel` コマンドを使わない
- WARP ClientはノートPCやスマホにインストール済み、ログイン済み

## 手順

1. tunnel を作り、cloudflared を自宅ネットワーク内の PC やラズパイにインストールしておく。すでに作成済みの場合は(2)に進む。

   cloudflared をインストール際は、architecture を間違えないよう気をつけまる。最近のラズパイはarm64のほうが多い。インストールコマンドが tunnel 設定画面の overview に表示されるので、そのままコピペする。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/4f8a7663-b0fd-ddb9-e9d0-a7dc095a20d2.png)

1. tunnel 状態が `active` であることを確認し、適当な tunnel を選び、【Configure】を押す
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/3c1f8625-aa7e-c762-565c-7da0be81d2b0.png)

1. Private Network の下の "Add a private network" を押して、ご自宅のローカルネットワークのCIDRを入力する。例えば `192.168.1.{0~255}` の場合は `192.168.1.0/24`
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/82418ab0-c590-3915-ec6c-999d1741f1b1.png)

1. settings > network を開き、Firewall > Proxy を有効にする
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/883c5838-9b7d-bde3-ab6a-ba7ee6bfa2fe.png)
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/80df256a-407f-f6a7-795a-b9c50a29e3f9.png)

1. settings > WARP client を開き、Device settings の下の Default の横の Configure を押して、除外ルール一覧を開く
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/4fb6d1b2-6674-6dbd-c4e9-db934dd7aa38.png)
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/9e1ba047-810f-6962-e419-dead4582f6fb.png)

1. Split tunnels の Exclude の Manage ボタンを押す
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/d1b0f0c1-07cf-f013-1405-5f0f81882066.png)

1. exclude ルールを消す、特に `192.●●●●` の項目は全部消す
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/97fcd625-0273-18b4-c654-0662c8445e67.png)

## 確認

1.1.1.1 のVPN接続を有効にする
![IMG_3318.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/ccdf5718-a60e-2d1a-c133-2541ce1d44ce.png)

ルーターのアドレス 192.168.xxx.xxx をアクセスしてみる
![IMG_3319.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/b51f09f9-9a72-4b5f-d2c1-1d23d9b7a896.png)

注：mDns名 (`hogehoge.local`) は使えないので、ネットワーク内のリソースはIPアドレスでアクセスしましょう（例：Jellyfin iOSクライアント↓）
![IMG_3320.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207164/5b5338d8-fda8-8855-a0e4-63a96da2a725.png)
[正規表現]英文として成り立っているかを調べる

# はじめに
正規表現を学び始めたので、習作に書いてみました。
ここでの「英文」の定義は以下とします。

* アルファベット（A~Z, a-z）と半角数字（0~9）、アポストロフィ（'）で構成される
* 単語の区切りに1文字の空白文字を挟む
* 文の終わりにピリオド（.）、エクスクラメーション（!）、クエスチョン（?）をつける

文法として成り立ってる！というものではないので注意。（それはそれで面白そうだけど）

# 結果
```py
import re

s = input()
p = r"^([A-Z|a-z|0-9|']+\s)*[A-Z|a-z|0-9|']+[.|!|?]$"

if re.search(p, s):
    print("Yes")
else:
    print("No")
```

うーん、ゴツい。

# 説明
```py
p = r"^([A-Z|a-z|0-9|']+\s)*[A-Z|a-z|0-9|']+[.|!|?]$"
```

まずはわかりやすいところから。

## ^, $（文頭・末尾の一文字を指定する）
それぞれ`^<文字>`, `<文字>$`を文頭、末尾につけることで指定できます。

## +, *（n文字以上の連続した文）
`<文字>+`, `<文字>*`で**n文字以上の、指定した文字で構成された文**となります。
`*`は0文字以上（なくてもOK）`+`は1文字以上（ないとNG）という意味。

## []（文字の指定）
`[<文字>]`とすることで、使用できる文字を限定できます。文字列でも可。
パイプ（`|`）で区切ることで複数指定も可能。

文中で使っている`[A-Z|a-z|0-9|']`は「アルファベット（A~Z, a-z）と半角数字（0~9）、アポストロフィ（'）だけしか使えないよ」って感じ。

## \s（空白文字）
空白はコードでは表しづらいので、かわりに`\s`を使います。いわゆるエスケープシーケンス。
かわりに半角文字を使っても大丈夫ですが、個人的にはう～んって感じです。

## 要約
ようやく全部終えたところで、あらためて見てみます。

```py
p = r"^([A-Z|a-z|0-9|']+\s)*[A-Z|a-z|0-9|']+[.|!|?]$"
```

分解して考えていきましょう。

+ 英文を「`[単語+空白] *n + 単語 (+ 記号)`」として考える
`This is a null.`という例文を考えます。
このとき、`This `、`is `、`a `の3つは「単語+空白」というパターンを持ってることがわかります。

    これを正規表現で表すとこんな感じ。
    ```
    ^([A-Z|a-z|0-9|']+\s)*
    ```

    1単語が`[A-Z|a-z|0-9|']+`に相当します。

+ 最後の単語と記号を認識
とくに言うことなしです。以下の通り。

```
[A-Z|a-z|0-9|']+[.|!|?]$
```

# 実行してみる
テストケースと結果を見ていきます。

```console
This is a pen.
> Yes
```

ルールに従っている文なので、しっかり認識します。

```console
This is a pen
No
```

末尾に記号が入っていないので弾かれてしまいました。

```console
これはペンです.
No
```

当然日本語は弾きます。

```console
ThIs Is A pEn.
Yes
```

大文字小文字がバラバラでも認識します。まあいいや。

```console
Kore Ha Pen Desu.
Yes
```

エセ英語も通してしまいます。要改善。



# おわりに
複雑そうで避けていた正規表現ですが、意外と面白そうでした。
使用頻度も高そうなので習得しておきたい。
Auraコンポーネントのボタンからクイックアクションを起動する

コンポーネントをクイックアクションで呼び出すことは何度かやったことがありますが、その逆はなかった。しかしクイックアクションのURLを眺めてみたらIdを指定しているようですので、これなら大丈夫と思い、以下のコードを設定。

無事起動しました。


```
var recordId = component.get("v.recordId");
		var myURL = "/lightning/action/quick/Account.Approval107?objectApiName=fkd_Approval__c&context=RECORD_DETAIL&recordId="+ recordId + "&backgroundContext=%2Flightning%2Fr%2FAccount%2F" + recordId + "%2Fview";        
        $A.get("e.force:navigateToURL").setParams({
            "url": myURL
        }).fire(); 
```
thread class, runnable interface

Runnableはrun methodをもつfunctional interface
constructor of Threadにrunnableを引き渡す
```java
public class Outer {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            public void run() {
                System.out.println(" i am run method");
            }
        });
        t.start();       
    }
}
```
```
 i am run method
```
単体テスト流れ メモ

## Test流れ
test->コンパイルエラー->修正->test->成功->一通りtestを終了後にtestリファクタリング

詳細
0.Main コードを作成する際、どんな引数があればテストしやすいか考える
1. 追加したい次の機能のテストを作成し、失敗させる(Red)
1.5 エラー内容を把握
2.テストに合格するまでコードを記述し、テストを通す(Green)
3.コードをリファクタリングする（Refactor)

ゴールは「きちんと動作するきれいなコード」　

## アサーション
@ParameterizedTest
Junitでテストでは入力値が異なるだけで、結果が変わらないことがある。
そのような場合、１テストに対して１テストメソッドをつくることは面倒くさを感じられる。そこで、@ParameterizedTestを利用すること、複数のテストメソッドをまとめることができる。

@MethodSource
任意のクラスを引数に渡せる
staticメソッドを定義する

@CsvSource
複数のパラメータをメソッドに渡したい時に使用する

## 参考資料
https://www.youtube.com/watch?v=UhHdnLTxOjE
https://junit.org/junit5/docs/5.3.0/user-guide/#writing-tests-parameterized-tests
[android] https://twitter.com/shareのendpointが利用できなくなった模様

# 結論
twiterのシェアには
`https://twitter.com/intent/tweet`
を使う


# 起きていること

twitterのシェアには
- https://twitter.com/share
- https://twitter.com/intent/tweet
 
などのendpointがありますが、`https://twitter.com/share`を用いている場合、androidでtwitterア
プリがインストールされている環境だとツイートができなくなった模様です。
（2023/1/16時点。確認したバージョンは9.71.0-release.0）
![IMG_20230116_131501.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324924/efe454b3-fa07-ba5d-d901-893292f09a92.jpeg)
何故か検索扱いになる

不具合として修正される可能性もありますが、ドキュメント的には`https://twitter.com/intent/tweet`が指定されているようなので、`https://twitter.com/intent/tweet`に統一したほうが良さそうです。
- https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/overview
【Unity】 Camera.mainが使用できなかった時の対処法

また同じミスをしないようにする為の脳内記録のため、ささっと本題に入ります。

# Camera.mainがなぜ使えなかったのか
エラー内容
```
Assets/Scriptes/Obstacle.cs(50,29): エラー CS0117: 'Camera' には 'main' の定義が含まれていません
```

答えは、__Camaraというクラス(スクリプト)名を使用していたから__ です。

# 最後に
私は、よくクラスや関数、変数など全てにおいてざっくりとした名前をつける癖があるので、もっと具体的な分かりやすい名前をつけるように心がければ、今回のようなエラーは出なくなると言うことです。
SvelteKit 環境で GraphQLを使う

# SvelteKit 環境で GraphQLを使う

SvelteKit使い始めたばっかりですが、簡潔に記述できるし、SSRがかんたんに出来たりで、とても気に入っています。
Dunning-Kruger効果的には「完全に理解した」状態ですが、学んだこと書いておきます。

## やりたいこと。

バックエンドはGraphQLを開発しているので、GraphQLで定義された型、Query、Mutationをフロントで再度定義することなく利用したい。
以下のリンクを参照しながら進めます。the guildのドキュメントは再現性低くて昔から結構読みにくいです。。。

https://the-guild.dev/graphql/codegen/docs/guides/svelte 
https://zenn.dev/takurinton/articles/76582f25d942f0


## 環境について
Ubuntu 22.04
svelte 3.54.0
@graphql-codegen/cli 2.16.4
@graphql-codegen/typescript 2.8.7
@graphql-codegen/typescript-operations 2.5.12

## 進め方
結果論になりますが、 svelte-apollo は解決不能なエラーが解消が出来ず、初期導入がどうしても出来ずに、諦めました。なんかバグある？
なので、@apollo/clientのインスタンスを自分で作って、CodeGenで作成されるコードから参照させる形を取りました。

## Setup

```bash
# 素のアプリケーション作成
npm create svelte@latest myapp
cd myapp 
npm install

# code generatorを入れる
npm install --save-dev @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations graphql-codegen-svelte-apollo

# apollo clientをいれる
npm install --save @apollo/client
```

以下のようにCode Generatorの設定を入れます。
```yaml:codegen.yml
schema:
  - http://localhost:8080/graphql:
documents:
  - ./src/**/*.gql
generates:
  './src/graphql/generated.ts':
    plugins:
      - typescript
      - typescript-operations
      - graphql-codegen-svelte-apollo
    config:
      clientPath: ../lib/graphql/apollo
```

そしてApollo ClientをdefaultでExportするファイルを作る。場所は `codegen.yml` の `generates.config.clientPath`と一致させます。
ついでにidTokenを更新するための関数も用意してexportしておきます。 (トークンを更新するたびにこれを呼べばOKです)
```typescript:/src/lib/graphql/apollo.ts
import { ApolloClient, InMemoryCache } from '@apollo/client/core/core.cjs'
import { HttpLink } from '@apollo/client/link/http/http.cjs'

const cache = new InMemoryCache()
const client = new ApolloClient({
  cache,
})

const newLink = (idToken: string) => {
  return new HttpLink({
    uri: 'https://MY_GRAPHQL_HOST/graphql',
    headers: {
      Authorization: `Bearer ${idToken}`,
    },
  })
}

export default client
export const updateClientWithIdToken = (idToken: string) => {
  const newHttpLink = newLink(idToken)
  client.setLink(newHttpLink)
}
```

Firebase Authenticationの場合こんな感じで更新する。。。
```typescript
getAuth().onAuthStateChanged(async (user) => {
  if (!!user) {
    const idToken = await user.getIdToken()
    updateClientWithIdToken(idToken)
  }
}
```


## 使ってみる
とりあえずQueryなりMutationなり書いてみる。`codegen.yml` で指定した `documents` で拾われる場所であればどこで置いてもいいです。

```graphql:src/graphql/my-mutations.gql
mutation SomeMutation {
   someMutation {
    id
    uid 
    validUntil
    createdAt
  }
}

```

`npx graphql-codegen` でコードが自動生成されますので、早速使ってみましょう。


```html
<script lang="ts">
  import { onMount } from 'svelte'
  import { SomeMutation } from '../../../../graphql/generated'
  import store from './store'

  onMount(async () => {
    const result = await SomeMutation({})
    store.set(result.data?.someMutation)
  })
</script>

{$store?.id} <-- こんな感じで参照する。型も自動生成されるので、IntelliSenseが効いてとても便利です。

```

## まとめ
ドキュメントが少なすぎて環境作る際にとても苦労しましたが、それ以外はすんなり行きました。誰かの役に立てば幸いです。
フロントエンドではやっぱり型定義などはやらず、ビジネスロジックをなるべく省いてPresentation Layerの関心事だけに集中するのが好きですが、結構それに近くて気に入っています。

♥ Svelte/Kit, GraphQL
JavaScript行きついた結論

個人的に二転三転して、やはりJavascriptに戻ってきた話

一時期はStreamlitでフロントエンドは作れると考えていた。

https://qiita.com/EasyCording/items/7bff63db95f8d9f39378

もちろん、この選択は間違っていない。
サクッと周りに動くものを見せたいのであれば、現時点でも100%お勧めする。

しかしながら、StreamlitをWEB-APPとして、リリース可能なホスティングサービスが無い
（Streamlit Cloud という、ホスティングサービスはあるが、アクセスしないと直ぐにログアウトされる）

# React

何度かReactのプロジェクトを作っては消し、作っては消し・・・
Next.Jsのプロジェクトを作っては消し、作っては消し・・・
Gatsby.Jsのプロジェクトを作っては消し、作っては消し・・・

もう半年近く、同じことを繰り返している。。。

# Vercel

ホスティングサービスのVercelを知ってからは、GITHUBとCI&CDを回せることを学ぶ
もちろん、ここにもテンプレートがぎっしり用意されている。

https://vercel.com/new/templates

見たこともない用語がびっしり並ぶ・・・

何々?　Preact?　少し軽いReactらしい・・・
何々?　Vite?　ちょっと軽いビルドツールらしい・・・

片っ端からテンプレートを使って、プロジェクト作っては消し、作っては消し・・・
今度は自分のGITHUBに、ゴミプロジェクトが溜まりだした。

# JSの世界感

自分が知っている常識をはるかに上回るペースで、JavaScriptの世界は日々移り変わっている。
少しばかりサーバー側のレンタリングのために、NODE.JSのフレームワークも調べ始めたが、
この言語に共通する世界観として、プログラム言語としての統一感以上に、その周辺を取り巻く開発環境が余りにも複雑になりすぎている。
どうもJsエンジニアというのは、何というか盛りだくさんの内容を、いかに自分たちが優位性を保つために競い合っているだけで、何か共通の課題に向けて方向を合わせて進めようという感覚が無いように思える。

# 最終的な結論

フロントエンドだけの話であれば、最終的にはビルド済みの静的ファイルを得ることが目的である。
特定の用途では、HTMLにscriptを埋め込むだけで十分という選択もある
これ以上、自分がJSフレームワークに溺れて、余計な時間を費やしたくない。
そもそも、少しだけのアプリケーションの用途で、巨大なnodeライブラリのインストールはしたくないし、ライブラリ自体のバージョン不整合で開発が一向に進まないという状況に陥りたくない。

# 英語学習

JSスキル獲得の傍らで、実は英語勉強もかなり進めてきており、最近は英語のYoutube動画もすんなり理解できるレベルに達している。やはり語学勉強はプログラミング以上に、時間をかければ身につくものだと実感する。

そして今回は、たまたま見た下記のYOUTUBEが自分の方向付けの決定打となった。

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

# Percel

どうやら、自分のようにJSでウンザリしてきた方は、他にもいるようだ。
そんな中、このビルドツールはとてもシンプルであり、初めてJSの世界で、腑に落ちるという感覚を味わった。もちろん、その感覚は、さんざん苦労してきた自分だからわかる話しであって、全くの初心者には理解できないであろう。

https://parceljs.org/

# もう一度React
　このツールを使う前提で、もう一度Reactのポイントだけを詰め込んで、もう一度JavaScriptを始めてみたいと思った。Reactについては、散々苦しめられたが、以下のページにポイントがまとめられている

https://mae.chab.in/archives/2956

　あとは常識的には、ReactでもTypeScriptは使った方が良い　

https://qiita.com/taqm/items/ffcc363cb56f872967a4

　ビルドツールが軽いから、物凄くモチベーションが上がった。
　つまり、ビルドツールの複雑さが、ＪＳ習得の最大の課題だったということを、個人的には学んだ。
サイトスピード測定について

## 概要
サイトスピード測定方法は従来様々な方法があったと思うが、測定方法が確立しつつあり、LighthouseとWebpagetestを使ってみた内容を整理する


## 指標について
Googleが提供しているWeb Vitals(https://web.dev/vitals/) では以下３つの観点だけを挙げている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/bcde1257-e253-a821-2292-c6eb1be0a7b0.png)

##### LCP(Largest Contentful Paint) - 最大視覚コンテンツの表示時間
読み込みのパフォーマンスを測定するための指標。つまりは、読み込み速度といったらこれを指標にすればよい。

##### FID(First Input Delay) - 初回入力までの遅延時間
ユーザーがページを操作してから、ブラウザが実際に処理を開始するまでの時間。

##### CLS(Cumulative Layout Shift) - 累積レイアウト シフト数
ページの表示中に発生した予期しないレイアウトシフトの最大時間。
https://web.dev/cls/ の動画が分かりやすいです。



## 使ってみた結果
以下認証付きのサイトにログインして、同じ画面を測定した結果です

### Lighthouse
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/db34d2ae-ddb2-8352-0348-0b90b16f160c.png)

・実行に１分くらいかかる
・各指標の小数点以下１桁まで表示してくれる
・何度か測定すると若干ばらつきがあるため、５回ほど測定して平均とった方がよさそう
・ログインした状態で、Chrome開発者ツールで測定したが、Lighthouse計測開始するとたまにログアウト状態になってしまい計測失敗する

### Webpagetest

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/ede01515-7056-df9e-1018-f9fa29194174.png)

・実行に５分くらいかかる
・各指標の小数点以下３桁まで表示してくれる
・速度の設定（Connection）により結果が大きく異なる（実際のインターネット速度に合わせるのがよい）
・テスト試行回数（Number of Tests to Run）が少ないと、失敗して計測できないことがある（５回にするのが良さそう）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/f9cc8d04-88a2-0440-5ecd-fcd22e57780f.png)

:::note warn
同じLCPでも若干結果が異なる
:::



## 指標整理
LighthouseやWebpagetestでは、Web Vitals以外の指標が表示されるので整理する

### Lighthouse
参考：https://developer.chrome.com/docs/lighthouse/

##### FCP(First Contentful Paint)
ユーザーがページに移動してからブラウザがDOMコンテンツの最初の部分をレンダリングするのにかかる時間

##### Speed Index
ページがユーザーに表示されるコンテンツをレンダリングした速度を表す計算指標

##### TTI(Time to Interactive)
ページが完全にインタラクティブになるまでにかかる時間

##### TBT(Total Blocking Time)
マウスのクリック、画面のタップ、キーボードの押下などのユーザー入力への応答がブロックされている合計時間


### WebPageTest
参考：https://docs.webpagetest.org/

WebPageTestにしか表示されていない指標はこちら
##### First Byte
最初のバイト時間(TTFBと略されることが多い)は、最初のナビゲーションの開始からベースページの最初のバイトがブラウザによって受信されるまでの時間

##### Start Render
最初のナビゲーションの開始から最初の白以外のコンテンツがブラウザのディスプレイにペイントされるまでの時間


#### 整理すると…



|  | LCP | FID | CLS | FCP | Speed Index | TBT | TTI | First Byte | Start Render |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|Web Vitals|○|○|○|   |   |   |   |   |
|Lighthouse|○|   |○|○|○|○|○|   |   |
|WebPageTest|○|   |○|○|○|○|   |○|○|


Web Vitalsの重要指標のLCP(Largest Contentful Paint)とCLS(Cumulative Layout Shift)は、LighthouseでもWebPageTestでも扱っているので、どちらで計測しても使えますね


First Byteを速度改善の指標として報告している現場を見たことあるが、意味があるのか…
PCLのインストール

# はじめに
実行環境：Windows10　VS2019
PCLバージョン：1.13.0
事前にGitBashはインストール済み
PCLのインストールは外部ライブラリが多く面倒のようで，本家HPを参照するとWindowsではvcpkgを利用してインストールすることがおススメされている

# 1. vcpkgのインストール
GitBashにて，適当な空のフォルダ内でvcpkgをクローン
```
git clone https://github.com/Microsoft/vcpkg.git
```
PowerShellにて，インストールしたフォルダ内にあるスクリプトbootstrap-vcpkg.batを実行
```
PS> .\bootstrap-vcpkg.bat
```

# 2. PCLのインストール
PowerShellにてvcpkg installを実行
```
.\vcpkg install pcl
```
とても時間かかる．．．既に10分くらい経過している気がする
PointClodLibraryのBuilding x86-windows-relでずっと止まっている．．．
45分くらい経ってインストール完了

vcpkg\installedにインストールされていることがわかる
このままではvisualizationがインストールされていないが，今回はRegistration（スキャンマッチング）を使いたいためここで終了


# 参考資料
https://qiita.com/Azuryl/items/b3708b17ebb86810bd70
https://pointclouds.org/downloads/#cross-platform
Ruby on Railsを基本からまとめてみた【エラーに対するトラブルシューティング①】

railsで『API』を作成しようとしたら、下記のエラーが表示。

```
Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.
```
#### 解決方法

下記のコマンドをシェルに打ち込んだら、解決したので記載。

```
export PATH="$HOME/.rbenv/bin:$PATH" 
```
または

```
export PATH="$HOME/.rbenv/shims:$PATH" 
```

#### 原因

シェルを変えたことで、パスを設定し直さなければならないのを忘れていたことが原因とのこと。
rbenvのpathが無くなったことで、macに標準でインストールされているrubyのgemを確認してrailsのgemが無いとエラーを出していたらしい。



## 参考サイト
[Shellをzshにしたらrailsコマンドが動かなくなった話](https://viblo.asia/p/shell%E3%82%92zsh%E3%81%AB%E3%81%97%E3%81%9F%E3%82%89rails%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8C%E5%8B%95%E3%81%8B%E3%81%AA%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F%E8%A9%B1-E375zBYP5GW)
Androidで実機をPCにミラーリングするのはAndroid Studioだけで簡単にできるよ

# 概要

Android Studio Electric Eelがリリースされました。
意外と気づいてないかもですが、このバージョンから、なんと実機をPC上でミラーリングできる機能が追加されました!!

特にリモートで開発している場合、周りに自分の実機画面を表示しながら説明したいことがあると思います。これが簡単にできるのです。

今までは、以下のようなサービスを使ってましたが、もう不要かもです。（個人的にはApowerMirrorにお布施してたのが残念ですが、最近安定してなかったのでよかった）

* ApowerMirror
* LetsView
* Vysor

# やり方

Preferencesを開いて、以下の画像のように 「Experimental」 の 「Device Mirroring」 を ONにします。

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10494/cdeb55ae-f3ed-a958-7bd4-a9816a46d6f4.png">

実機に接続して、以下の画像のように「Running Devices」 を表示します。これだけです。実機で表示している画面がAndroid Studioでミラーリングされています。(この画像の上部分が実機を動かすと同じように動きます)

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10494/765b3f30-09f5-d7cf-2676-2f3a4701baae.png">

動作させている動画も取れるし、スクショも取れるし、とても便利です。これで、PRとかにも気楽に上げられますね。
【Unity】3dプロジェクトで2d素材を正面に向かせる方法

3Dプロジェクトで２D素材を扱う時に発生しがちな問題として、
２D素材を用いたオブジェクトがカメラの方向を向いてくれない！！

というものがあると思います。

今回の記事ではそれを改善できるテクニックを紹介していきます。




# Unity3Dと２D混在させる方法

まず肝心の３Dプロジェクトで２D素材を使う方法ですが
下記のように空のオブジェクトを作成して、SpriteRendererを追加してください。

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541829/f5989207-9257-fda9-ce7f-361539ccde9b.jpeg)



その後表示したい２D素材をSpriteに入れてあげましょう。

そうすると下記のように、
３D空間でも２D素材を表示することが可能になります！
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541829/c91ed4a5-ded1-4b81-0168-58632e42b91b.jpeg)


ですがこのままでは、
カメラを動かしても正面に向いてはくれません。

![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541829/b76749f3-42e2-7f96-1ebb-04c107908bec.jpeg)



次からはこのオブジェクトを
カメラ正面に向かせるコードを記述していきます。

# Unityの3D空間でと２D素材に正面を向かせる方法

CameraFrontスクリプトを作成して、
先ほど作ったオブジェクトにアタッチしてください。
![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541829/c6ca75ea-3b6b-2182-9223-4ebb9f4fcf95.jpeg)


スクリプトには下記コードを記述してください。

```C#:CameraFront.cs

using UnityEngine;

public class CameraFront : MonoBehaviour
{

	Camera maincam;

    private void Start()
    {
        //メインカメラ取得
		maincam = Camera.main;
    }

    private void Update()
    {
        TurningImage();
    }

    //オブジェクトをメインカメラの方向に向ける
    private void TurningImage()
	{
		transform.LookAt(maincam.transform.position);
	}
}

```

これでカメラを動かしても
常に正面を向いてくれるようになりました！
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541829/345b990d-227a-76a7-44fd-096c785f2a51.gif)




## YouTubeチャンネル

ゲーム雑学や、具体的なゲーム開発方法まで紹介しているチャンネルを運営しています！

https://www.youtube.com/channel/UCVMfSecoP77yIh1a1O-7Wjg



## 参照記事
https://docs.unity3d.com/ja/2019.4/ScriptReference/Transform.LookAt.html
geopandasでshpファイルを扱う

## はじめに
国土数値情報をpythonで扱うときには、geopandasを用いると便利です。
京都府の上水道関連施設データをもとに可視化を行ってみます。
リンクはこちらです。

https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-P21.html#prefecture26

## 実装
あらかじめ、京都府のデータをダウンロード、解凍しておきます。
実装ではshpファイルを指定しますが、内部的には読み込み時に他のファイルも必要となります。

```python
# !pip install geopandas
import geopandas as gpd
import matplotlib.pyplot as plt

path_shp = "P21-12_26_GML/P21-12a_26.shp"
gdf = gpd.read_file(path_shp, encoding='shift-JIS')
gdf.head()
```
**データフレーム**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/3a388590-baae-acdf-4c7f-38a6145856b8.png)

matplotlibで小畑の領域を可視化してみます。

```python
# https://minus9d.hatenablog.com/entry/2016/04/21/215532
plt.gca().get_xaxis().get_major_formatter().set_useOffset(False)
plt.plot(*gdf.iloc[0].geometry.exterior.xy)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/ff507003-2203-440f-6c6b-8a3e03393d18.png)

京都府すべての事業所を地図上に重ねてみます。
`leafmap` というライブラリを用いると便利です。
```python
# !pip install geocoder
# !pip install leafmap
# !pip install PyCRS # for m_add_shp
import geocoder
import leafmap

# マップの初期表示範囲を指定
location = '京都府'
ret = geocoder.osm(location, timeout=5.0)
m = leafmap.Map(center=ret.latlng, zoom=9)

# 京都府の水道事業の所在地を追加
m.add_shp(path_shp, layer_name="kyoto", encoding='shift-JIS')

# 表示
m
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/11353d88-752a-1a96-fd1a-675d9a239615.png)

## 今後
水道事業で問題になるのは老朽化した水道管の交換のタイミングです。
傾斜や地盤の硬さ、天候、交通状況、水道管の使用状況等の周辺環境によって水道管老朽の速度は大きく変わってしまいます。
日本は水道管の事故は諸外国と比べると少ないですが、その分メンテナンスに大きな労力がかかっています。
また、これから高度経済成長期に大量に敷設された水道管の寿命が来ることが予想されています。
様々なデータを用いて老朽化した水道管を予測することで、維持コストを下げ、持続可能な安全なインフラが実現します。
データ活用して今後取り組めたらと思います。
Python 3.10 の導入 on Windows

# 最新版のダウンロード
Python3.10のBinary版の最新版を以下から探します。Stable版では3.10.9が最新でした(2023-01-16時点)。

https://www.python.org/downloads/windows/


Windows installer (64-bit)をダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/305060f1-9e61-0a9f-c240-f3aba31c01f0.png)



# インストール
python-3.10.9-amd64.exeを実行します。

ここではデフォルトのまま導入します。

* 「Add Python 3. to PATH」はしていません。複数バージョンを同居させたときに、PATHの切り替えをしたくないためです。pyランチャーでバージョンの切り替えは行います。VS Codeを使うときにもPATHは通っていなくても利用できました。
* Install for all usersではなく、ユーザーディレクトリに導入します。パスが長くなるのが厄介ですが、pipを管理者ユーザーで行わなくてよいのが便利です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/8191aa3b-9bee-6fea-ef6a-f4c06729dac5.png)


導入が終わったら、「Close」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e4ded3f8-99ed-4de7-421f-c8bbfb3c92a9.png)


# 導入確認

コマンドプロンプトを開いて以下を入力し、3.8.10が導入されたことを確認します。

```batch
py -V
```

```txt:結果
C:\temp>py -V
Python 3.10.9
```

とりあえず、pipはアップデートしておきます。
```batch
py -m pip install --upgrade pip
```

```txt:結果
C:\temp>py -m pip install --upgrade pip
Requirement already satisfied: pip in c:\users\XXXXXX\appdata\local\programs\python\python38\lib\site-packages (21.1.1)
Collecting pip
  Downloading pip-22.3.1-py3-none-any.whl (2.1 MB)
     |████████████████████████████████| 2.1 MB 6.4 MB/s
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 21.1.1
    Uninstalling pip-21.1.1:
      Successfully uninstalled pip-21.1.1
  WARNING: The scripts pip.exe, pip3.10.exe, pip3.8.exe and pip3.exe are installed in 'C:\Users\XXXXXX\AppData\Local\Programs\Python\Python38\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-22.3.1
````


# 環境
* windows 11 64bit
* Python 3.10.9


# 参考

#### 【windows】Pythonのインストールと実行 - Qiita 

https://qiita.com/d0raem0n/items/2367a5542a78682c3bb6


#### Windows で複数バージョンの Python を使う - Qiita 

https://qiita.com/landwarrior/items/1b5e0f9af5316a025fe0


#### Windows で Python を使う — Python 3.10 ドキュメント 

https://docs.python.org/ja/3.10/using/windows.html
Xserverで不要ファイルを定期的に移動する

Xserverで検索に一致するディレクトリを定期的に別のディレクトリに移動する


```bash:mv.sh
#!/bin/bash

# 32日より前のファイルを移動
find /home/サーバーID/ドメイン/public_html/hoge/* -type d -mtime +32 | xargs --no-run-if-empty mv -t /home/サーバーID/backup/hoge/
```
-type f：対象をファイルにする
-type d：対象をディレクトリにする
-mtime +x・・・過去からx+1日前までを対象とする



アップロードして、パーミッションは「704」に変更する

cronを設定する

```
/home/サーバーID/backup/file_mv.sh
```
paiza.ioでelixir その172

# 概要
paiza.ioでelixirやってみた。
task使ってみた。

# 参考にしたページ

https://qiita.com/koheiyamaguchi0203/items/0a052e1d12bc36c03096

# サンプルコード

```

defmodule Main do		
	def sleep_rand(n) do
    	sleep_time = :rand.uniform(n)
    	:timer.sleep(sleep_time)
    end
    def exec_seq(n) do
	    IO.puts "開始: #{n}回rand_sleepを繰り返す"
	    result = Enum.map(1..n, fn _ -> 
	        sleep_rand(10) 
	    end) 
	    IO.puts "終了: "
	    result
    end
    def exec_pal(n) do
    	IO.puts "開始: #{n}回rand_sleepを繰り返す(並列)"
    	list = Enum.map(1..n, fn _ -> 
    	    Task.async(Main, :sleep_rand, [10]) 
    	end)
    	result = Enum.map(list, fn x  -> 
    	    Task.await(x) 
    	end)
    	IO.puts "終了:"
    	result
    end
    def main() do
        prev = System.os_time()
        exec_seq(10)
        next = System.os_time()
        diff = next - prev
        prev = next
        IO.puts diff
        exec_seq(100)
        next = System.os_time()
        diff = next - prev
        prev = next
        IO.puts diff
        exec_pal(10)
        next = System.os_time()
        diff = next - prev
        prev = next
        IO.puts diff
        exec_pal(100)
        next = System.os_time()
        diff = next - prev
        prev = next
        IO.puts diff
        exec_pal(1000)
        next = System.os_time()
        diff = next - prev
        prev = next
        IO.puts diff
    end
end

Main.main


```

# 実行結果

```
開始: 10回rand_sleepを繰り返す
終了: 
74823283
開始: 100回rand_sleepを繰り返す
終了: 
696018660
開始: 10回rand_sleepを繰り返す(並列)
終了:
10977485
開始: 100回rand_sleepを繰り返す(並列)
終了:
11200330
開始: 1000回rand_sleepを繰り返す(並列)
終了:
22040490

```

# 成果物

https://paiza.io/projects/yDhnLPhnis0k6fq7mxFETA?language=elixir

以上。
C9環境で1年越しにaws-cdkを使用したらスタック作成時にruntimeエラーで詰まった

# 概要
システムの改修要望があったため、コードを修正して1年ぶりにCDKを使用してスタックを作成した際に下記のruntimeエラーがでて詰まったので備忘録。

```bash
Resource handler returned message: 
"The runtime parameter of python3.6 is no longer supported for creating or updating AWS Lambda functions. 
We recommend you use the new runtime (python3.9) while creating or updating functions.
```

## 解決方法
先に結論を書くと使用していたツールやmodule群のバージョンが古いことが原因でした。今回の肝はCDKのバージョンはあげたもののpackage.json内のmodule群のバージョンを上げ忘れたことです。なんてことないミスなのですが、エンジニア歴が浅い自分には盲点でした。

CDKのissueでも同様のことが取り上げられてますので詳しく知りたい方はこちらをご覧ください.
[(aws-s3-deployment): BucketDeployment creates Lambda function with unsupported runtime #21467](https://github.com/aws/aws-cdk/issues/21467)

### バージョンを上げたツール/module群
- CDK　⇦主にこいつが原因
- package.json内のmodule群　
- nodejs
- nvm

## エラー前開発環境
AWS C9上で開発

|name|バージョン|
|:-:|:-:|
|aws-cdk|v1.171.0|
|nvm|v0.31.1|
|nodejs|v12.20.8|

ちなみに、CDKのVersion 1はメンテナンスモードに入っているためVersion 2が推奨です。(2023年1月現在)
[Migrating to AWS CDK v2](https://docs.aws.amazon.com/ja_jp/cdk/v1/guide/work-with-cdk-v2.html)

## 詰まった点①　nvmのバージョン管理方法

runtimeエラーだったので、とりあえずnvmにてnodeのv16をいれて、aws-cli/cdkをインストールします。
ここも軽く詰まったのですが、nvmでバージョン管理する場合、npm i -g XXXでインストールされるモジュールたちは各バージョンごとに管理されます。`cdk deploy`を行った際のnodeのバージョンで動くcdkのバージョンも違います。

|nvm のバージョン||cdkのバージョン|
|:-|:-:|:-|
|v12.20.8|→|\@v1.171.0|
|v16.8.0|→|\@v2.59.0|

```bash
$ nvm alias default v16
$ node -v
v16.8.0
$ cdk --version
2.59.0 (build b24095d)
```
アップデートも確認できたので`cdk deploy`でデプロイをすると無事エラーを吐いたままです。


## 詰まった点② bash -l -cでバージョンが違う
Makefile内のコマンドを確認すると`bash -l -c`と見慣れない記述がありました。
```makefile
deploy:
    bash -l -c 'npm install && cdk deploy`
```
> `bash -l`コマンドはログイン状態のshellでコマンドを実行する

ここはいまだに理解ができていないのですが、なにやら`cdk --version`と`bash -l -c 'cdk --version'`では別バージョンになっていたため、cdkのバージョンがアップデートできていなかったようです。
```bash
$ cdk --version
2.59.0 (build b24095d)
$ bash -l -c 'cdk --version'
1.171.0
```

対策方法はいろいろあると思うのですが、今回はログイン状態のShell上でnvmで使用するdefaultを変更することで解決しました。元々のMakefileをいじらないでCDKのバージョンアップは完了です。
```bash
$ bash -l -c 'node -v'
v12.20.8
$ bash -l -c 'nvm alias default v16'
$ bash -l -c 'node -v && cdk --version'
v16.8.0
2.59.0 (build b24095d)
```

## 詰まった点③ package.json内のmodule群のバージョンを上げ忘れた

ツール類のバージョンアップは完了したのにまだ、runtimeエラーが出ている状況が続いている時に上記の[issue](#解決方法)を見つけました。issueを参考にpackage.jsonに記載されているmodule群のバージョンを上げて`npm i`したらエラー解消しました。

|module| before | after |
|:-:   | :-:    | :-:   |
|@aws-cdk/assert| 1.101.0 | 2.59.0 |
|@types/node |10.17.27| 18.11.18 |
|aws-cdk|1.101.0| 2.60.0 |
|ts-node| ^9.0.0| ^10.9.1 |
|typescript| ~3.9.7| ~4.9.4 |

バージョンアップには`npm-check-updates`を使用しました。

https://qiita.com/sugurutakahashi12345/items/df736ddaf65c244e1b4f

無事deploy完了です!!

## 感想
バージョン上げる時に限らず、変更を加えた時nい影響を受ける範囲は考えないといけないなーと思いました。今回のエラーで技術以外にもググり方などかなり学びがあったので、エラーはやはりエンジニアを強くするなと思いました。(issueに感謝!!)
タブの連携動作で、複数のグルーピングについて検討しています。

# 概要
拡張機能を作成していて、タブの連携動作を行っていますが、中々、処理がややこしくなっています。それは、ひとつの親タブから二つのタブを開いて処理を実行されるものです。しかし、そこで、この3つのタブを一つのグループとして考えたとき、使い方によっては、複数のグループが並行的に実行することも可能です。そうすると、その場合のプラグインの作り方は極端に難しくなります。このケースが発生するのは、小生が作成している「yyプラグインプラス」という拡張機能です。
今回は、この問題について検討してみたいと思います。
# 一つの事例で
「yyプラグインプラス」については、他の投稿記事で説明していますので、ご参照ください。ここでは、具体的な例でご説明いたします。
### 手順
まず、chromeブラウザーを開きます。この時、「yyプラグインプラス」はインストールしておきます。ブラウザーを開いたときにプラグインはブラウザーの管理メモリーにロードされます。この時、ロードされる主なファイルはcontent.jsとbackground.jsです。
次に、たとえば、「yahoo!Japan」サイトのページを開くとします。そして、このページのある選択可能なテキストを選択します。例えば「トラベル」というテキストを選択し、Ctrlキーを押してclickします。すると、yyプラグインプラスのポップアップが表示されます。
そこで、youtubeサーチボタンをclickすると、先にプレーヤー画面が開き、次にyoutubeサーチ画面が開きます。その時のアクティブタブはyoutubeサーチタブです。このアクティブタブは後の説明に関係します。
ここで、一通りのタブが開きました。タブの数は3つです。これを一つのグループとして考えます。
# 複数グループについて
先に3つのタブが開かれた状態です。その時点で、youtubeサーチが実行しています。スクロールをしながらサーチをしています。
その状態で、タブの右端にある＋ボタンを押し、新規タブを開きます。
そのタブで更にもう一つのyahoo!Japanページを開き、前回と同様の操作
を行うとむ、もう一つのグループができ、そこでもyoutubeサーチが実行しています。但し、サーチが行われてるのは、アクティブタブのyoutubeサーチのみです。スクロールが実行されるのはアクティブタブなので、もう一方のyoutubeサーチはペンディング状態になっています。カーソルを移動してそのタブをアクティブにすれば、今度はそちらのyoutubeサーチが続行して、前のyoutubeサーチタブはペンディング状態になります。
いずれにしても、そのような操作を続けるとグループがいくつも出来上がります。メモリやCPUスピードが許せば、グループを増やせます。
ここで、問題になるのは、タブの管理で、各グループ毎のyoutubeサーチ結果を処理するには、それらのタブidの管理が正しく行われなければ、正しい結果が表示されません。正しい表示とは、各グループのプレーヤタブに意図したサーチ結果の再生リストが表示されるかです。
# 各グループのタブid管理とアクティブタブidの管理について
タブのアクティブやメッセージ送受信にはタブidが必要です。それらの管理をbackground.jsが一手に引き受けています。content.jsは各タブのDOMにアクセスできます。今回問題の複数グループのタブid管理は「yyプラグインプラス」拡張機能の要になります。
現在、まだこの要の機能は実装されていません。早急にこの機能を実装して行きたいと思います。
# あとがき
このプラグインを作成していて、タブのグルーピング処理をうまく行わないといけないと痛感しています。
複数のタブを扱うとメッセージ送受信が大変複雑になってきます。content.jsとbackground.js間でかなり多くのメッセージが飛び交うことになります。
タブの数だけcontent.jsの中でメッセージを振り分けて処理を行わなければなりません。現在どのタブがアクティブなのかを把握して処理しなければなりません。
もう少し、時間はかかりますが、近々、公開したいと思います。
インターン生がコードレビューしてみた感想

### はじめに
先日インターン先で社内の技術ハンズオンのコードレビューをした。

インターン生がコードレビューをするということもあり、貴重な経験であると感じたので新鮮なうちにここに書き留めておく。

# 目次
**1. コードレビューをするにあたっての経緯**


**2. コードレビューをする際に意識したこと**


**3. コードレビューをしてみて**




## コードレビューをするにあたっての経緯

私が現在インターンしている部署では、インターン生、正社員関わらずエンジニアが実際に仕事を受ける前にハンズオンを取り組むことによって必要最低限の技術を身につける。

去年の8月にインターン生としてアサインした私ももちろんそのハンズオンを取り組み、現在実務に取り組んでいる。

このハンズオンの内容としてはシンプルで、「指定した条件に沿うデータを擬似データベースから検索、参照するAPIを実装する」といったもので、この部署でエンジニアとして立ち回るための最初の課題になっている。

そして11月に私が務める部署にアサインされた新卒社員の方がこのハンズオンに取り組むことになった。

基本的にこのハンズオンは実装の後にレビューしていただいて合格をもらえれば「ハンズオン修了」となる。

そのため、本来ならば先輩社員の方が新卒社員が取り組んだハンズオンのコードレビューをする。

しかし、最近ハンズオンを経験した私は良い復習になるかもと感じ、先輩にお願いしてコードレビューをさせていただくことになった。

*****

## コードレビューをする際に意識したこと

ここで、実際にコードレビューをした際に意識したことを以下にまとめたい。

私が意識したことは以下三つである。
* ロジックの整合性（APIとして正しく動作するか、無駄がないか）
* 変数名などの可読性（変数名は読みやすいものになっているか）
* コード全体の可読性（適切にコメントを使っているか、変に冗長なものになっていないか）

主にチームで開発することを踏まえて、チームメンバーが読みやすいコードになっているかどうかを念頭に入れてコードレビューした。

これは私がハンズオンに取り組んだ際、先輩レビュアーの方からおすすめされた書籍で培った考えである。

その書籍が以下にある『リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック』である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959493/9cb80055-1de2-8161-f89d-d08a71efc6be.png)

かなり有名な書籍なので、おそらく既に読んだことがある方も多いと思うが、この書籍はチームで開発する際には必須といっても過言ではないものなので是非お勧めしたい。


*****

## コードレビューをしてみて

以上のことを意識して実際にコードレビューを行った。

全体を通して、コードレビューは個人的に興味深かった。

まず同じハンズオンに取り組んでいても、人によって全くコードの書き方やロジックの組み立て方が異なる点が面白かった。

この点に関しては、コードレビューをすることによって感じることができたと思う。

また、可読性を意識したレビューをすることによって次に自分がコードを書く時に注意することができるのでそれも恩恵に感じられた。

もちろん可読性以外にもコードレビューはさまざまな観点が存在すると思うので、次回からはさまざまな視点を持ってレビューしたいと感じた。

*****
Python 3.8 の導入 on Windows

# 最新版のダウンロード
Python3.8のBinary版の最新版を以下から探します。3.8.10: Monday, 2021-05-03 (final regular bugfix release with binary installers)がBinary版としては最新でした。

PEP 569 – Python 3.8 Release Schedule | peps.python.org 

https://peps.python.org/pep-0569/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/ed474bce-ea8a-26c8-0731-2fe1db878019.png)


Windows installer (64-bit)をダウンロードします。

https://www.python.org/downloads/release/python-3810/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2e9e7f4f-3f25-fcc5-b3ee-3af8edf3dab3.png)


# インストール
python-3.8.10-amd64.exeを実行します。

ここではデフォルトのまま導入します。

* 「Add Python 3. to PATH」はしていません。複数バージョンを同居させたときに、PATHの切り替えをしたくないためです。pyランチャーでバージョンの切り替えは行います。VS Codeを使うときにもPATHは通っていなくても利用できました。
* Install for all usersではなく、ユーザーディレクトリに導入します。パスが長くなるのが厄介ですが、pipを管理者ユーザーで行わなくてよいのが便利です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/633606f8-25b6-6a59-a285-c28f0949aae8.png)

導入が終わったら、「Close」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/edf99735-c1bc-b55e-d3ab-88f25cc3a84d.png)

# 導入確認

コマンドプロンプトを開いて以下を入力し、3.8.10が導入されたことを確認します。

```batch
py -V
```

```txt:結果
C:\temp>py -V
Python 3.8.10
```

とりあえず、pipはアップデートしておきます。
```batch
py -m pip install --upgrade pip
```

```txt:結果
C:\temp>py -m pip install --upgrade pip
Requirement already satisfied: pip in c:\users\XXXXXX\appdata\local\programs\python\python38\lib\site-packages (21.1.1)
Collecting pip
  Downloading pip-22.3.1-py3-none-any.whl (2.1 MB)
     |████████████████████████████████| 2.1 MB 6.4 MB/s
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 21.1.1
    Uninstalling pip-21.1.1:
      Successfully uninstalled pip-21.1.1
  WARNING: The scripts pip.exe, pip3.10.exe, pip3.8.exe and pip3.exe are installed in 'C:\Users\XXXXXX\AppData\Local\Programs\Python\Python38\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-22.3.1
````


# 環境
* windows 11 64bit
* Python 3.8.10


# 参考

#### 【windows】Pythonのインストールと実行 - Qiita 

https://qiita.com/d0raem0n/items/2367a5542a78682c3bb6


#### Windows で複数バージョンの Python を使う - Qiita 

https://qiita.com/landwarrior/items/1b5e0f9af5316a025fe0


#### Windows で Python を使う — Python 3.8.10 ドキュメント 

https://docs.python.org/ja/3.8/using/windows.html
【PHP】in_arrayではなくissetとarray_key_existsを使おう

# in_arrayではなくissetとarray_key_existsを使おう
## 理由
* in_arrayよりもissetやarray_key_existsの方が断然処理が早いから。

## 使用方法
### issetの場合
```php
$array = array(
                "orange" => true,
                "banana" => true,
                "lemon" =>true
                );
if(isset($array['orange'])){
    echo "これはオレンジです";
}
```

### array_key_existsの場合
```php
$array = array(
                "orange" => true,
                "banana" => true,
                "lemon" =>true
                );
if(array_key_exists("orange",$array)){
    echo "これはオレンジです";
}
```

* 連想配列の作成は以下
```php
// 対象となる配列
$array = array("orange","banana","melon");
$count = count($array);
$i = 0;
// trueの配列を作成
while($i < $count){
    $true[] = true;
    $i++;
}

// 連想配列
$associativeArray = array_combine($array,$true);

// isset
if(isset($associativeArray['orange'])){
    echo "isset_orange";
}

// array_key_exists
if(array_key_exists("orange",$associativeArray)){
    echo "array_key_exists";
}
```

___
## スニペット
```json
	"isset": {
		"prefix": "i",
		"body": [
			"\\$array = $1;",
			"\\$count = count(\\$array);",
			"\\$i = 0;",
			"while(\\$i < \\$count){",
				"\t\\$true[] = true;",
				"\t\\$i++;",
			"}",
			"\\$associativeArray = array_combine(\\$array,\\$true);",
			"if(isset(\\$associativeArray['$2'])){",
			"\t$3",
			"}",
		],
		"description": "issetを使用するための連想配列の作成"
	},
	"array_key_exists": {
		"prefix": "a",
		"body": [
			"\\$array = $1;",
			"\\$count = count(\\$array);",
			"\\$i = 0;",
			"while(\\$i < \\$count){",
				"\t\\$true[] = true;",
				"\t\\$i++;",
			"}",
			"\\$associativeArray = array_combine(\\$array,\\$true);",
			"if(array_key_exists(\"$2\",$associativeArray)){",
			"\t$3",
			"}",
		],
		"description": "array_key_existsを使用するための連想配列の作成"
	}
```
みんな大好きgnuplot備忘録

みんな大好きgnuplotの備忘録

基本的にlinuxを前提

# gnuplot
[gnuplot homepage](http://www.gnuplot.info/)

ASCIIデータの列からいろいろできるグラフ描画アプリ。
Matplotlib on pythonの様に図を整える容易さはないけれど、コンソールから呼んで短いコマンドで一次元データをプロットするのにはとても適している。

# `.gnuplot`
これをホームに置いておくと、中のファイルが

```gnuplot
set colorsequence classic #色が古き良きred-green-blueから始まるカラーパレットになる
```

# 環境変数

基本的には`.gnuplot`に書いておいたコマンドが起動時に読み込まれるはず。なぜだかわからないが、私の環境だと`set term x11`がどうしても読み込まれなかったので、x11をデフォルトターミナルにするために、以下の環境変数で対応した。(例えば`qt`系を入れると、インタラクティブな描画ができたりエイリアスが効いたりして良い一方、リモートから操作すると余計なデーモンが生き残ったりして綺麗なログアウトが阻害されたりする。なので、基本はx11での描画をよく用いている。)
```bash
export GNUTERM=hogehoge # hogehogeがset termの引数に渡される
```