OmniAICreator/Qiita-1.07M huggingface dataset:
Failed to create schema directory 'test_table' (errno: 2 - No such file or directory)の解決法

# 目的
``` mysql> create database database_name;```でデータベースを作成しようとしたところ、

```
Failed to create schema directory 'test_table' (errno: 2 - No such file or directory)
```
と表示されてしまったため、その解決法をまとめようと思う。

# 結論
PCを再起動し、
mysqlログインの際に、作成したユーザーでログインするのではなく、

```
mysql -uroot
```
でログインするとすんなりdatabaseの作成が行えた。
# 実施環境
### ハードウェア環境
| 項目 | 情報 |
|:-:|:-:|
| OS  |macOS Catalina(10.15.7)   |
|ハードウェア   |  MacBook Air (11-inch, Early 2015) |
|プロセッサ   | 1.6 GHz デュアルコアIntel Core i5|
|メモリ   |  4 GB 1600 MHz DDR3 |
|グラフィックス   |  intel HD Graphics 6000 1536 MB |
### ソフトウェア環境
| 項目 | 情報 |
|:-:|:-:|
| homebrew  | 3.3.8 |
| mysql | Ver 8.0.27 for macos10.15 on x86_64 |
| python  | 3.8.12 |
| django  | 3.1.2 |

# 経緯
ローカル開発環境でmysqlにログイン後、``` mysql> create database database_name;```でテーブルを作成しようとしたところ、

```
Failed to create schema directory 'test_table' (errno: 2 - No such file or directory)
```
と表示された。
# 原因究明
ログインしているユーザーにtableのcreate権限がないということが判明した。
権限の付与を行う必要がある。
[こちら](https://qiita.com/shuntaro_tamura/items/2fb114b8c5d1384648aa)と[こちら](https://www.dbonline.jp/mysql/user/index6.html)の記事を参考にユーザーに権限を付与していく。
testというユーザーを作成し

```
create user test@localhost identified by 'test_password';
```
createだけでなく、全ての権限を与えたが、

```
grant all on *.* to test@localhost;
```
変わらず、、。
# 解決
PCを再起動し、ログインの際に

```
mysql -uroot
```
でログインするとすんなりデータベースの作成が行えた。
なぜこれでいけるのかかなり引っかかるため、この権限周りについては後ほど詳細に調べていく。
Mattermostからメール送信できない

# 症状

『接続をテストする』ボタンを押すと成功するがメールが届かない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/347d9f1c-65ff-1497-3829-14cd8cb76329.png)

# 原因

* 送信者メールアドレスが無い
* 送信者名が無い

# 設定

左上の「9点リーダ」から「システムコンソール」を選択

![スクリーンショット 2021-12-28 4.40.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/fe5d294c-3064-b40a-1552-906d00038cf8.png)

左側の「サイト設定」内の「通知」を選択
「電子メール設定を有効にする: 」を有効を選択

![スクリーンショット 2021-12-28 4.44.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/51622852-e6dc-8369-d759-dcdec86f5652.png)

「通知の表示名」と「通知の送信元電子メールアドレス」を入力

![スクリーンショット 2021-12-28 4.46.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/050c8846-060f-7789-e7a3-dd79ec0dab59.png)

忘れずに保存する

![スクリーンショット 2021-12-28 4.49.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/2cc2c504-26d5-d3db-2450-f9eb9cfdb9df.png)

# 動作確認

『接続をテストする』ボタンを押すとメールが届きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/4e403189-2168-d30f-f85a-180cb29ce8a3.png)
Matermostでユーザ削除エラー 

# バージョン

Mattermost Team Edition
Mattermostのバージョン: 6.3.0-rc1

# エラー内容

```bash
$ mmctl user delete hoge@gmail.com
Unable to delete user 'hoge' error: : Permanent user deletion feature is not enabled. Please contact your System Administrato
r.,
```

# 原因

ユーザ削除機能が有効化されていない。

# 解決

ユーザ削除機能を有効化

```bash
$ mmctl config set ServiceSettings.EnableAPIUserDeletion true --local

#もしくは

$ mmctl config set ServiceSettings.EnableAPIUserDeletion true
```

# 参考

https://forum.mattermost.org/t/error-when-deleting-user-using-mmctl/10847/3

https://docs.mattermost.com/configure/configuration-settings.html#user-management

https://docs.mattermost.com/manage/mmctl-command-line-tool.html#mmctl-user-delete

# コメント

mattermost Ver.6 からmattermostコマンドからmmctlコマンドに変わってた。
ku○ectlみたいで可愛いい( ←関係ないので伏せ字)
Windows Terminal を DOS IDE ランチャーとして使う

# はじめに
**Windows Terminal** のプロファイルって何でも登録できる事に気付きました。

# DOS IDE
MS-DOS で動作する IDE をここに登録しておけば便利なのでわ？

 - [Embarcadero が公開しているアンティークソフト一覧 (Qiita)](https://qiita.com/ht_deko/items/ae7605c6b1f426ae234a)

ならば登録だ！

## 設定
 1. `〔Ctrl〕+〔,〕` で設定タブを開きます。

 2. [スタートアップ] で起動サイズを `80x25` に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/125c0ea5-2f1c-fe0a-95c0-e5e8cfb973e9.png)
サイズ固定になっている IDE は 80x25 でないと画面が崩れる事があります。

 3. 左側のハンバーガーメニューの [プロファイル] から `新しいプロファイルを追加します` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/0c304eb1-6b65-5b9c-453e-d11832dbc9bd.png)

 4. `新しい空のプロファイル` ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/675ba5bc-331c-6500-1ef1-3cb1f81d780c.png)

 5. 設定を適当に埋めます。普通のショートカットの設定と同じです。[外観] [詳細設定] タブにある設定は特にいじる必要はないと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b2f686fb-572b-4de3-c9ea-7d1ecc90b3a7.png)
できあがりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/20bedd93-b6fd-86a6-9a68-c63df046c855.png)
IDE を閉じると Windows Terminal のタブも閉じていい感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/e2134cc2-203f-750c-836a-b89498f9bd00.png)
今の所、プロファイルの順序を変更するには直接 JSON ファイルをいじるしかなさそうですね。

### 画面分割

画面分割して使いたい合には、起動サイズを次のように設定してみてください。

| 分割 | サイズ |
|:---|:---:|
| なし | 80x25 |
| 横 2 分割 | 164x25  |
| 縦 2 分割 | 80x50  |
| 四分割 | 164x50 |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b90f95e3-ab58-bc83-af62-95eeeb29d2fd.png)
**See also:**

 - [Windows ターミナルのペイン (docs.microsoft.com)](https://docs.microsoft.com/ja-jp/windows/terminal/panes)

## DOS-IDE 用の汎用アイコン
DOS-IDE 用の汎用アイコンを作ってみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/f0bc1442-e9e5-17ce-6966-45b56a2ee5b4.png)
「DOS の IDE は青い」というイメージがあります。

# おわりに
他にも、FTP クライアントとか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/ed591af9-8ea6-2893-5df9-eb2407f6a8e7.png)
データベースクライアントとか、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b0a9ef21-a420-2e4f-e6db-5c7c9cb6f08f.png)
対話型のアプリケーションを登録しておくと便利そうです。登録できそうな対話型のアプリケーションがない？そういう場合は自分で作ればいいのですよ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/04b09361-f660-8d8c-9daa-d9402de54823.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/cdf8a7ad-5573-4dce-6188-a30d68c2ff73.png)
**See also:**

 - [P_IDE (GitHub)](https://github.com/ht-deko/P_IDE)
macでrtspサーバを立てる

# gstreamerをインストール

```
$ brew install gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad
$ brew install gst-plugins-ugly
$ brew install gst-rtsp-server
$ gst-launch-1.0 --version
gst-launch-1.0 version 1.18.5
GStreamer 1.18.5
Unknown package origin
```

参考: https://dev.classmethod.jp/articles/gstreamer-on-macos-video/

# [rtsp-simple-server](https://github.com/aler9/rtsp-simple-server)をインストールして起動

1. [リリースページ](https://github.com/aler9/rtsp-simple-server/releases)から最新の rtsp-simple-server_v0.XX.XX_darwin_amd64.tar.gz をダウンロードして解凍する。
2. サーバを起動する

```
./rtsp-simple-server
```

# ストリームをpublishする


テストビデオ(時間付き)

```
$ gst-launch-1.0 videotestsrc ! timeoverlay font-desc="Sans 36" ! capsfilter caps="video/x-raw" ! queue ! x264enc ! rtspclientsink location=rtsp://localhost:8554/mystream
```

カメラ画像(時間付き)

```
$ gst-launch-1.0 avfvideosrc ! timeoverlay font-desc="Sans 36" ! capsfilter caps="video/x-raw" ! queue ! x264enc ! rtspclientsink location=rtsp://localhost:8554/mystream
```

参考: https://stackoverflow.com/a/47088647/4791194

# ストリームを開く

1. [VLC](https://www.videolan.org/vlc/download-macosx.ja.html)をインストールして起動する
1. VLCメニュー > ファイル > ネットワークを開く
1. URLに「rtsp://localhost:8554/mystream」を入力して開く
![vlc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9875/5980a311-ec8f-e287-c25c-aa84988d6cce.png)
1. 以下のような動画が表示される
![スクリーンショット 2022-01-06 9.46.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9875/7dd3ab59-1bd5-a995-3262-063e4c198903.png)

(VLCインストール後はChromeにrtspのURLを指定してストリームを開くこともできます)
jqコマンドでキーが数字の要素にアクセスする

以下のようなjson形式のデータがあるとする

```json:
$ jq .debug_info.line_score result.json 
{
  "1": 100,
  "2": 300,
  "3": 700,
  "4": 1300,
  "gameover": -500
}
```

`gameover`は`jq`コマンドを用いて以下のように取得できる

```shell:
$ jq .debug_info.line_score."gameover" result.json 
-500
```

`"1"`を取得したい場合、以下のように`jq`コマンドを用いても取得できない

```shell:
$ jq .debug_info.line_score."1" result.json 
jq: error: syntax error, unexpected LITERAL, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
.debug_info.line_score.1                      
jq: 1 compile error
```

これは以下のようにすると取得できる

```shell:
$ jq .debug_info.line_score.\"1\" result.json 
100
```
[VBA] 名前をつけて保存＆ファイル存在チェックをするマクロを作る

#　目次
[1.はじめに](#1-はじめに)
[2.本マクロの仕様](#2-本マクロの仕様)
[3.最終的なコード](#3-最終的なコード)
[4.おわりに](#4-おわりに)
[5.参考サイト](#5-参考サイト)

#1. はじめに
Excel VBAマクロで名前をつけて保存をするマクロを作る。
通常のExcel操作で、エクセルファイルを開いている状態で別名で名前をつけて保存するようなマクロを作る。

#2. 本マクロの仕様
- 実行時のディレクトリに保存
- 保存ファイル名はエクセルの特定のセルの値を取得
- ファイル存在チェックをする
- YES／NOダイアログを表示しユーザーに促す

#3. 最終的なコード
```vb
' /**
'  * 現在実行しているディレクトリに
'  * 指定されたファイル名で新規ブック保存します。
'  */
Private Sub createFileButton_Click()
    
    ' 変数定義
    Dim nowWorkbookPath As String      ' 作業中のブックパス
    Dim saveFileName As String         ' 保存ファイル名
    Dim saveFileDir As String          ' 保存先ディレクトリ
    Dim saveFileFullPath As String     ' 保存先フルパス

    ' 作業中のブックパスを取得
    nowWorkbookPath = ThisWorkbook.Path
    ' 指定されたセルのファイル名を取得
    saveFileName = Range("A1") & ".xlsx"
    ' 保存先フルパスを設定
    saveFileFullPath = nowWorkbookPath & "\" & saveFileName
    'カレントディレクトリを変更
    ChDir nowWorkbookPath

    ' ファイル存在チェック
    If fileExists(saveFileFullPath) = True Then
        ' 既にファイルが存在する場合
        Dim rc As VbMsgBoxResult
        rc = MsgBox("既に" & saveFileFullPath & "が存在しますが上書きしますか？", vbYesNo + vbDefaultButton2)
    
        If rc = vbYes Then
            ' 以下で表示されるメッセージを非表示に
            Application.DisplayAlerts = False
        Else
            ' ユーザーアクションNoのため処理終了
            End
        End If
    Else
        ' 重複するファイル名はないため処理続行
    End If
    
    ' 新規ブックとワークシートを作成
    Dim newWb As Workbook
    Set newWb = Workbooks.Add
    Set newWs = newWb.Worksheets(1)

    ' ----------------------------------------------
    ' 既存ブックから新規ブックへ値をコピーする
    ' ----------------------------------------------
    newWs.Range("A1") = Range("A1")
        
    ' 保存ファイルパスと保存形式を指定する。
    newWb.SaveAs Filename:=saveFileFullPath, _
                 FileFormat:=xlOpenXMLWorkbook
    newWb.Close

End Sub

' /**
'  * 指定されたファイル名が存在するか返します。
'  * @param saveFileFullPath {String} フルパス
'  * @return fileExists {boolean} 存在する／しない
'  */
Function fileExists(ByVal saveFileFullPath As String) As Boolean
    If Dir(saveFileFullPath) <> "" Then
        fileExists = True
    Else
        fileExists = False
    End If
End Function
```

#4. おわりに
ワークブックを新規作成した後に現在のワークブックをコピーしていく方法しかないのかなと思っているので、より良い方法をご存知の方いらっしゃいましたらご教授ください。

#5. 参考サイト
- [excel.xlfileformat](https://docs.microsoft.com/ja-jp/office/vba/api/excel.xlfileformat)
- [【ExcelVBA入門】SaveAsメソッドを使ったファイル保存方法を徹底解説！](https://www.sejuku.net/blog/67491)
- [ファイルの存在を調べる](http://officetanaka.net/excel/vba/file/file06.htm)
ジョハリの窓から学ぶドラッガー風エクササイズ・ペパボエディションの良さ


## ジョハリの窓とは
自分の理解、他人からの理解を４つの枠に捉えることで
自己理解のズレを減らしていくフレームワークになります。

![スクリーンショット 2021-12-27 12.08.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138619/157664f8-cbdf-9d30-c1ec-2fc75831c2b4.png)

￼

- 開放の窓
- 盲点の窓
- 秘密の窓
- 未知の窓

の４つに分類されます

開放の窓：自分も知っていて他人も知っている自己
盲点の窓：自分は気づいていないが、他人は知っている自己
秘密の窓：自分は知っているが他人は気がついていない自己
未知の窓：自分も、他人も気がついていない自己

という風に分けられます。

### 個人的に思うジョハリの窓目的

![スクリーンショット 2021-12-27 12.08.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138619/989c8e5b-7cc8-8b51-5a58-88074eb51492.png)

- 盲点の窓
- 秘密の窓

を減らしていくこと=>つまり開放の窓の領域を広げていくことが目的になっていると思っています。
つまり開放の窓の領域を広げることでお互いの認識のずれがなくなり
コミュニケーションが円滑になることが目的だと思っています。
また他人だけが知っている自分を知ることで新しい自分の発見ができるというメリットがあります。
￼
## ドラッガー風エクササイズ・ペパボエディションとは
アジャイルサムライに記載があるチームビルディングの手法を[GMOペパボ風にカスタマイズした手法](https://tech.pepabo.com/2017/07/07/the-drucker-exercise/)です。

- 自分は何が得意なのか？
- チームメンバーは自分にどんな成果を期待していると思うか？
- 他のチームメンバーに期待することは何か？

こちらの３つの質問を答えることでお互いの期待をすり合わせることを目的とします。

通常のドラッガー風エクササイズでは
- 自分は何が得意なのか？
- どういうふうに仕事するか？
- 自分が大切に思う価値は何か？
- チームメンバーは自分にどんな成果を期待できるか？

という質問を答えることになっています



## ドラッガー風エクササイズ・ペパボエディションで効果がある部分
通常のドラッガー風エクササイズは
自分の価値観、他人から自分はどう思われているのかの予測
を大切にしている質問であるのに対して

ドラッガー風エクササイズ・ペパボエディションは
- 自分が期待されていること
- 他人から期待されていること

を把握できるため


- 他人は知っていて自分は気づいていない長所
- 自分は知っているが他人は気づいていない長所

が把握できます。

このことをドラッガー風エクササイズでは期待値のすり合わせと言っていて
ジョハリの窓では開放の窓が広がると表現しています。


# 未知の窓をどんどん減らしていくには
盲点の窓、秘密の窓がなくなったからと言って終わりではなく、チームビルディング、コーチング等の流れの中で
開放の窓を広げる必要がある（そもそもなくなることはないと思っていますが、、）

# 最後に
ドラッガー風エクササイズ・ペパボエディションはよくできたフレームワークだと思っています。
自分が思うメリットをジョハリの窓の観点から記載してみました。
ご指摘等あればコメントにてお願いいたします。

# 引用
https://tech.pepabo.com/2017/07/07/the-drucker-exercise/
AtomCam2のRTSP通信で映像を取得しStreamlitで公開すーる（Python3.6、Windows10）

# はじめに
AtomCam2がRTSP対応したので、Streamlitで公開しちゃおう

# 開発環境
- Windows 10 PC
- Python 3.6
- streamlit
- opencv-python
- pillow
- AtomCam2 (ファームウェア：4.58.0.73)

# 実装
1．AtomCam2のRTSP通信設定をします
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おおお！ついにATOMCamが公式にRTSP対応だぞ！！(現在はベータ版なのでtestflightが必要)<br>とりあえず動くね。パスワードとユーザー名が内部で生成されるのWyzeと同じ。メモリ転送もwyzeと同じshmなのでそっちから持って来れたのね。おめでとう。 <a href="https://t.co/2n0LMfeFue">pic.twitter.com/2n0LMfeFue</a></p>&mdash; ひろみつ (@bakueikozo) <a href="https://twitter.com/bakueikozo/status/1446355640415227905?ref_src=twsrc%5Etfw">October 8, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

2．streamlitをインストールします

~~~cmd
pip install streamlit
streamlit hello
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/9fb446d1-ff62-faf1-e519-ad7d56ac5bb4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/d9d02bcd-915e-1b8f-9a66-41d6d894f6b3.png)

Ctrl+Cで中断します

3．下記コードを作成し実行します。

~~~streaming.py
import cv2
import streamlit as st
import time
from PIL import Image

st.markdown("# Gachimoto AtomCam2 Live")

cap = cv2.VideoCapture('rtsp://xxxx:yyyy@zzz.zzz.zzz.zzz/live')
_, frame = cap.read()
height, width = frame.shape[:2]
print(height, width) # SD : 1080, 1920

image_loc = st.empty()
while(True):
    _, frame = cap.read()
    frame = cv2.resize(frame, ((int)(width/4), (int)(height/4)))
    frame = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    image_loc.image(frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
~~~

~~~streaming.py
streamlit run streaming.py
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/9ce54f48-361c-6d39-1ed1-4237edffea0b.png)

# ngrokで外部公開

ngrokによってローカルサーバーを外部に公開することができます

https://ngrok.com/


~~~cmd
ngrok.exe authtoken XXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXX
ngrok.exe http 8501
~~~

ドメインお持ちの方

~~~cmd
ngrok.exe http -subdomain=name 8501
~~~

<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/2711d14a-6d1e-377e-40c7-2ae3d68faaf2.png">

遠隔で見えるわーい

# 参考
https://qiita.com/SatoshiTerasaki/items/f1724d68deecdc14103f
【Rails】scaffoldについて【簡単なアプリケーションがすぐに作れる】

## はじめに
　本記事は、プログラミングの学習を始めて1ヶ月の初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## 今回の疑問点
　今回の疑問点は、

　　_scaffoldについて_
　
　です。　

## 疑問点についての解説

###結論
ターミナルで`rails g scaffold モデル名 カラム名①:データの型① ...`を実行することでアプリケーションの雛形を作成することができる。

###使い方の流れ

まず、ターミナルで以下のコマンドを実行し、sample_appを作成する。

````
 rails new sample_app
```

アプリケーションが作成できたら以下のコマンドでsample_appディレクトリへ移動する。

```
 cd sample_app
```
移動ができたら以下の通り入力。

```
rails g scaffold Comment title:string content:text
```

すると指定したモデル名やカラム名等で以下のファイルが作成される。

- マイグレーションファイル
- モデル
- コントローラーファイル（「index」「show」「new」「edit」「create」「update」「destroy」アクション）
- ルーティング
- ビュー（index、edit、show、new、form）

マイグレーションファイルを使用してテーブルを作成するために以下のコマンドをターミナルに入力。

```
 rails db:migrate
```

上記が完了したら、サーバーを起動するために以下のコマンドを実行

```
 rails s
```

上記の作業をするだけで、簡単なアプリケーションを作成することができます。
画面を表示させるには、URLを入力する必要があります。
各ページのURLについては以下のコマンドで確認できます。

```
 rails routes
```

## まとめ
scaffoldは手軽に簡単なアプリケーションを作成できる非常に便利なコマンドです。
Railsをこれから学習しようという方が、どこにどのようなファイルがあり、どういった形でアプリケーションが動いているのか体感するためにはイメージがつきやすくとても良いと思います。
また、gem等の動作確認をする際に使用するのにも便利だと思っています。
しかし、簡単に動くアプリケーションが作れてしまうため、初学者が乱用するとRubyやRailsの知識が身につきづらくなると言われていますので使いすぎには気をつけましょう。
PHPのgRPC Serverがオフィシャルでサポートされてた件

## はじめに
これまでgRPCをPHPで扱うにはクライアントの用途しか存在せず、公式ドキュメントもサーバ側の実装はNode.jsで実装されるという悲しい現実をペチパー達は噛みしめていました。

- [なぜPHPはgRPCサーバーがサポートされていないのか？](https://youngforever.hatenablog.com/entry/2018/02/18/172852)
- [PHPでもgRPCサーバを立てたいだけの人生だった](https://speakerdeck.com/n1215/phpdemogrpcsabawoli-tetaidakefalseren-sheng-datuta)

しかし、githubのPRを暇つぶしにボケーっと見ていたところどうやら実装されているらしいというのがわかったので動作確認までやってみました。

## gRPCリポジトリの該当PR
https://github.com/grpc/grpc/pull/26841

> last step to complete php server.
( gRPCサーバーを完成させる為の最後のステップ )


## 実際に動かせるサンプルコード
https://github.com/grpc/grpc/blob/master/examples/php/greeter_server.php

## ローカルPCで動作するか確認してみた

![スクリーンショット 2021-12-27 23.33.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/5c78aa88-7d1c-1862-ac52-e9b0dcf43495.png)

Σ(ﾟДﾟ)ｽｹﾞｪ!! ちゃんと動くぞ...

## Serverのコード生成どうしてるの？
phpのprotoc pluginだと確かクライアント側のコードしか生成してくれないはず。

### Server側のコード生成方法

https://github.com/grpc/grpc/blob/master/examples/php/greeter_proto_gen.sh

``` generate_server: ``` のオプション渡してますね。
古いgrpc_php_pluginだと認識されないのでbazelで最新のpluginをビルドして使うと生成できそうです。

## 公式のクイックスタートとチュートリアルを確認してみた
https://grpc.io/docs/languages/php/quickstart/
https://grpc.io/docs/languages/php/basics/

まだサーバ側はNode.jsで実装されてますね。
公表するには早いのか、ドキュメント調整中なのか。。。

## あとがき

[RoadRunner × PHP-gRPCプラグイン](https://roadrunner.dev/docs/beep-beep-grpc)を使ってPHPのgRPCサーバー建てる記事書こうと思ってたんですが書かなくてよかった？w

Interceptor周りもコード追って使いたいすね ><

それでは皆様...

![yoiotoshiwo_omukaekudasai_y.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/8758b807-a2ea-d608-35d6-c0100317e2fb.png)
ヴェイパーヴェイヴ工場

前に書いた記事を組み合わせたら無限にヴェイパーヴェイヴできるんじゃないかなと思ったので



# 工場を作る
youtubeライブ配信で垂れ流してみる

## サーバの用意

サーバはOCIのalways freeで作れるやつでubuntu入れた

https://www.oracle.com/jp/cloud/free/

具体的にはこんなスペック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175961/453e0609-d089-8b40-9c8b-e3efa08f562a.png)

## 配信環境
OBSStudioってやつを入れた

ここを参考にした

http://pineplanter.moo.jp/non-it-salaryman/2021/05/04/obs-studio-ubuntu/

# 工場を稼働した

稼働した

<iframe width="560" height="315" src="https://www.youtube.com/embed/GoBwm9PnwWk" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

録画だからまだ流れているようにみえるけど
実際ライブ配信した時はCPU張り付いて動画配信がめっちゃ遅延した

# 今後の展開

- もうちょっとスペックいいサーバ用意すれば回る気がする
- サムネが寂しいのでGANとかでなんか仮想画像作れないかなとか思いがある

# 実は
~~もうちょっといいサーバということで前に話題になったOCIの4CPUで24GメモリのVPSを取得した。~~
~~だけどOBSStudioが入らない。~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175961/c00ddb51-73c5-5d5e-8d61-c5a1b5439950.png)

~~これCPUの命令セットがArmだからじゃね？（違ったら教えて欲しい）~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175961/0a657239-4608-db59-a73b-6efc5c84d67e.png)

~~なのでこちらの記事を参考に自前でコンパイルしたりしてみてるけどうまく行ってない~~

~~https://qiita.com/kitazaki/items/fe037d195f497eb54427~~

~~この問題誰か何か知ってたら教えて欲しいです。~~
~~OBS Studioじゃなくて他のアプリでもubuntuで配信できるよ、とかでも嬉しい。~~


# あれこれsimplescreenrecorder使うとできる？
simplescreenrecorder使うとライブ配信できるくさい

<iframe width="560" height="315" src="https://www.youtube.com/embed/zb_CPBAizkA" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

しかしこれ流しっぱなしにするとネットワーク帯域とか課金されそうで怖いな

# 朝起きたら下のエラー吐いてライブ配信落ちてた
こんなエラー出てsimplescreenrecorder落ちてた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175961/e20b8027-5310-dd9d-cc98-ee38a744314b.png)

これ定期的に出るのかな

# その後

GUIが壊れて二度とログインできなくなった。
前に借りたサーバがArmベースで似たようなことあったんだよなあ。
工場潰れた。

仕方ないので元々使っていたロースペックサーバで再稼働

<iframe width="560" height="315" src="https://www.youtube.com/embed/0B-VPTGwVj8" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

OBS StudioやめてSimpleScreenRecorderにしたら負荷下がってちょっと安定稼働してる気する。
SwiftUI List .listStyle(PlainListStyle()) の1番上と下の線を消したい

# 困ったこと

```.swift
    let items = ["hoge", "higa", "piyo"]
    
    var body: some View {
        VStack () {
            List {
                ForEach(0 ..< items.count) { index in
                    Text(items[index])
                }
            }
            .listStyle(PlainListStyle())
        }
    }
```

このコードを表示すると、こんな風に表示される

![スクリーンショット 2021-12-27 23.27.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/27c09913-4e84-7999-f67b-eb2bfc8da1b6.png)

1番上と下のライン消したいんだがどうしたらいいのやら

# 対応方法

SectionでList内を囲って、 .listSectionSeparator(.hidden) を指定すればOK

``` .swift
    let items = ["hoge", "higa", "piyo"]
    
    var body: some View {
        VStack () {
            List {
                Section() {
                    ForEach(0 ..< items.count) { index in
                        Text(items[index])
                    }
                }.listSectionSeparator(.hidden)
            }
            .listStyle(PlainListStyle())
        }
    }

```

![スクリーンショット 2021-12-27 23.35.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/06d616f1-d921-ce13-e52c-0a49c087df60.png)

無事消えました🙏


# 参考
https://devtechie.medium.com/new-for-list-in-swiftui-3-and-ios-15-64367e937029
UnityでImgurで画像アップロードしようとしたらWebGLビルドだけ429エラーになった話


# 前置き/出会った事象
- Unityでスクショを撮ってImagurにアップロードしてtweetするアセットをメンテしていたら、WebGLビルドだけ何故か429エラーになってしまった話
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/2a3e9b93-5a8a-5b88-4345-12bc4bed42c3.png)
- 429エラー＝`Too Many Requests`エラー
- 一般的には、一定時間内に送信したリクエストが多すぎる際に発生するエラーみたい
- でもリクエストは1回しかしてない……謎
- iOS/Android/UnityEditorでは問題なかった


# 原因
- Imgurがどうにもlocalhostからのリクエストを拒否するようになったみたい
- なので、WebGLで`Build And Run`するとどうしても発生してしまう
- 参考資料
    - [Imgur api responding with code 403 with server error 429](https://stackoverflow.com/questions/66195106/imgur-api-responding-with-code-403-with-server-error-429)
    - [Imgur image not showing on localhost](https://stackoverflow.com/questions/43912795/imgur-image-not-showing-on-localhost)


# 解決策
- 自サーバや、WebGLを実行できるサービスにuploadしてテストする
    - 自分の場合は[unityroom](https://unityroom.com/)で、未公開状態でテストさせていただいてます🙏 


# 感想
- 解決策は分かればなんてことない話だった。
- エラーコード間違ってません……？
Domino Designer 12.0.1 でアプリケーションアイコンを 64 ピクセルに更新

#ワークスペースアイコンをちょっとリッチに
HCL Notes/Domino 12.0.1 がリリースされました。
**Lotus -> IBM -> HCL** とメーカーが変わって**吹っ切れた感**のある機能追加とバージョンアップを繰り返しており、最新の V12 では**モバイルアプリ(iPhone/iPad/Android)版のクライアント**だけでなく **PWA 版のクライアント**に加えて、**ローコード開発**機能が入ったりとアプリケーションの開発実行基盤の領域への積極投資が続いています。
従来の Notes クライアント向けにも**モダナイズ**の波が来ており、象徴的な一つがアプリケーションアイコンが 64×64px に拡張されて見た目も今風にできる様になっています。
この**新機能**を紹介する Blog 記事が出ていたので、試してみました。

[HCL Domino 12.0.1 でアプリケーションアイコンを作成する方法](https://www.hcljapan.co.jp/software/blog/how-to-create-application-icons-in-domino-12-0-1)

#Domino Designer 12.0.1 で既存アプリケーションを更新
IDE ツールである Domino Designer は、**Windows 版のみ**提供されており Windows 10 にて試しました。

1. **ファイル-アプリケーション-開く** もしくは **Ctrl+O** にてダイアログから既存のアプリケーションを開きます。
2. 左ペインのデータベースナビゲータに**設計要素**が並ぶので、対象のアプリケーションの **リソース-アイコン** を選択します。
![DesignerIcon1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437712/9cd36d33-66eb-f690-9918-0df26872924b.jpeg)

3. アイコンのプロパティに**アプリケーションアイコン**欄があり、状況に応じて**参照・置換・削除・エクスポート**とメニューが選択できます。
参照や置換ボタンからPC上のファイルを選択できます。ファイルは **GIF, JPEG, ビットマップ, PNG** の4種のイメージファイルから選べます。![DesignerIcon4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437712/2a327041-20b1-1353-f843-e6916df60db7.jpeg)
**提供されているアイコン集※**から選ぶと下の32pxの時よりちゃんと4倍大きくてグラデーションの効いたキレイなアイコンだと確認できます。
![DesignerIcon5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437712/fca96f65-b573-ca45-3440-450ac66f9e3f.jpeg)
ちなみに64pxより大きなファイルも選択できます。ここでは横長のファイルを選んでみました。縦横比が1:1に直されます。（横潰れしてしまうので、縦横比が等しいファイルを選ぶことをおすすめします）![DesignerIcon3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437712/5f389c5b-0fb6-13ff-379a-7934b47a7ff0.jpeg)

好きなイメージファイルを用いて、見た目のキレイなワークスペースアイコンに更新してみてください！

#アイコン集のダウンロード方法
※提供されているアイコン集は、ウェビナーのリプレイリンク
[HCL Domino Designer Webinar: How to Update Application Icons](https://support.hcltechsw.com/community?id=community_Event&sys_id=f607c1cb1bbf7cd0a2f48661cd4bcbc3&fbclid=IwAR34nKWUMJwYnkmcf8LXP6X-AQz0kq_ogRknIYznDuc4avgRJEyHsB5y8Y8)
ここにある _Applications.zip_ に上で紹介したブログの元記事とアイコン集がダウンロードできます。機能を表す絵だけではなく、テーマ毎(Commerce, Data, People, Travelなど)に利用できるアイコンも提供されています。
【Rails】一定期間でログファイルを削除【手動は卒業】

開発中ってログの容量食いますよね...。
みなさんは、どうしてますでしょうか？

適当なタイミングで削除はしてるのでしょうか？

実のところ私は、開発の際は、pryの方を使うことが多く、正直
ログに関してあまり理解していなかったんですよね...。

ただ、これを機に色々調査してみたので共有いたします！

# rails：ログを削除するコマンド
```
$ rake log:clear
```

コンソールで、上記コマンドを実行すればログファイルが消えるかと思います。

ただ、毎回毎回手動で削除するのってかなり面倒ですよね？
そこで、何かいい方法がないか調べてみました。

# ログローテーションとは？
>ログローテーションとは、システムが残す時系列の記録データ（ログ）が際限なく増えることを防ぐために、一定の容量や期間ごとに古いログを削除したり新しいログで上書きすること。また、そのような機能。
[IT用語辞典 e-Words](https://e-words.jp/w/%E3%83%AD%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.html)

Railsにもログローテーションの便利な機能がデフォルトで備わっているらしい。

詳細はこちら、[デフォルトのログファイルはどこに？](https://takeda-no-nao.net/programming/ruby/delete-log-files-after-certain-period-of-time/)にもあるのですが、開発環境の場合はログの設定用のファイルに追記することでログを定期退避＆削除できるようです。


### ログ設定用のファイル：config/environments/production.rb

```config/environments/development.rb
# 5M をこえたらログが日付付きで退避され、合計が10ファイルをこえたら古いファイルは削除
config.logger = Logger.new('log/sample.log', 10, 5 * 1024 * 1024)
```

```config/environments/development.rb
# 日付でログローテート
config.logger = Logger.new('log/sample.log', 'daily')
```
これだと、「sample.log.日付」というファイル名で、各日付ごとにログが退避されました。

***

今日が12/27日だとすると、明日には、
- sample.log.20211226


明後日には、
- sample.log.20211226
- sample.log.20211227

明明後日には、
- sample.log.20211226
- sample.log.20211227
- sample.log.20211228
・
・
・

***

ってファイルが退避されてるイメージですね。


１日でも容量が結構いくようなアプリを作ってる方だと、１日退避は結構便利ですよね。

# 「日付」「週間」「月ごと」などの期間で設定できる
```config/environments/development.rb
# 日付でログローテート
config.logger = Logger.new('log/sample.log', 'daily')

# 週間単位でログローテート
config.logger = Logger.new('log/sample.log', 'weekly')
```

あと、「日付」「週間」「月ごと」などの期間で設定できるみたいなので、色々お試しあれ。

ちなみに、１つ落とし穴というか気をつけるべきポイントがあって、
自動で定期削除されるのは「日付」の方はどうやら無理らしい...。

下記の、容量で設定する場合のみしか、自動で削除までは行われないようです。うーん。自動で削除できないのなら、あまり使う意味はない気もしてくる...

```config/environments/development.rb
# こちらは削除してくれる
config.logger = Logger.new('log/sample.log', 10, 5 * 1024 * 1024)

# daily（日付）の場合は、退避されるだけで削除はされないらしい
config.logger = Logger.new('log/sample.log', 'daily')
```


まあ、でも日付つけてリネームしてくれるだけでも十分便利ではあるか。


# 参考

[【Rails】一定期間でログファイルを削除【手動は卒業】](https://takeda-no-nao.net/programming/ruby/delete-log-files-after-certain-period-of-time/)
ubuntu環境でpython3のバージョンを3.6-->3.9に更新する際のメモ

ubuntu環境でpython3のバージョンを3.6-->3.9に更新する際のメモ

以下の通り`3.6.x`を使用している状態

```
$ python3 --version
Python 3.6.9
```

[こちら](https://codechacha.com/ja/ubuntu-install-python39/)を参考に以下の通り更新する

```
sudo apt update -y
sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.9 -y
```

上記で解決、、と思いきやまだ更新できていなかった。

```
$ python3 --version
Python 3.6.9
```

代わりに以下を実施

```
sudo apt update -y
sudo apt install -y build-essential libbz2-dev libdb-dev libreadline-dev libffi-dev libgdbm-dev liblzma-dev libncursesw5-dev libsqlite3-dev libssl-dev zlib1g-dev uuid-dev tk-dev
wget https://www.python.org/ftp/python/3.9.9/Python-3.9.9.tar.xz
tar xJf Python-3.9.9.tar.xz
cd Python-3.9.9
./configure
make
sudo make install
```

上記で解決、、と思いきやまだ更新できていなかった。

```
$ python3 --version
Python 3.6.9
```

ログアウト、ログインすると解決した。
が、（なぜか）ライブラリが追従できなかったので、pip3 upgradeした。

```
/usr/bin/python3 -m pip install --upgrade pip
```

このあとpip3でエラーが出る場合は以下を参照して解決するとOK
[pip3をupgradeしたあと、pip3を使用時にModuleNotFoundError: No module named 'pip._internal'となる際の解決策](https://qiita.com/seigot/items/add5668643576a61fd96)


## 以下は失敗

実体を検索すると、`python3.6`のシンボリックリンクとなっていたので、

```
$ which python3
/usr/bin/python3
$ ls -l /usr/bin/python3
/usr/bin/python3 -> python3.6
```

シンボリックリンクを張り替える

```
/usr/bin/
sudo ln -nfs python3.9 python3
```

これで`python3`を使う際は`python3.9`が使えるようになった

```
$ python3 --version
Python 3.9.9
```

と、思いきや他のライブラリが使えなくなったのでもとに戻した（シンボリックリンク張り替え前に戻した）


# 参考
[Ubuntu - Python 3.9のインストール方法](https://codechacha.com/ja/ubuntu-install-python39/)
[Python 3.9、このバージョンをUbuntu20.04にインストールする方法](https://ubunlog.com/ja/python-3-9ubuntu%E3%81%AB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%9520/#Instalacion_de_Python_39)
constexpr関数は必ずしもコンパイル時にのみ呼び出されるわけではない

constexpr関数はコンパイル時に実行される完全に定数のようなものという理解だったのですが、
正確には「constexpr関数の結果を受け取る左辺によって決定される」らしい。


>constexpr関数がコンパイル時に呼び出されるか、実行時に呼び出されるかは、その関数の結果を受け取る、左辺によって決定される。引数が定数でかつ、左辺がconstexpr修飾された変数であれば、右辺の関数はコンパイル時に呼び出される。そうでなければ、関数は実行時に呼び出される。

https://cpprefjp.github.io/lang/cpp11/constexpr.html

実務で使ったことないので、イマイチ使い所がわからない。
>関数を静的に評価する仕組みが必要とされた。

アプリケーションレベルではあまり使わないのかな。
Minitestで「forkしたRubyのサブプロセスのIO」をテストする

## はじめに

この記事を書いている人も完全には理解していないが、一応解決したので、似たような状況で困っている人のヒントになるように記事を残す。

バインディングを作っている時に、「有る操作を行うと、バインディングのC側のグローバル変数みたいなものが変更されてしまうため、後続のテストに影響を与えないようにフォークしてテストを行いたい」というような面倒なケースがある。

Minitestには、`assert_output`という便利なメソッドがあり、stdoutやstderrのテストができる。しかし、これらはサブプロセスのIOまでは掌握してくれなかったりする。

かといって、spawn使って `bundle exec ruby -r minimap2 -e "hogefuga"` みたいなのを書くというのも嫌な感じがする。なにしろこの場合、bundlerを使わないとテストが成功しない。それはどうなのか。

## capture_subprocess_io を使う

うまい解決策はないだろうか？　実は Minitestの `assert_output` のドキュメントを見ると

> NOTE: this uses capture_io, not capture_subprocess_io.


という注釈がある。どうやら、サブプロセスのIOを把握する方法もあるけれども、それは遅いから `assert_output` では使ってないよということらしい。そこで`capture_subprocess_io` を利用する。これとForkを組み合わせることで、サブプロセスの実行するプロセスのIOのテストが可能になる。こんな感じである。

```ruby
  def test_execute_with_string_arg
    out, err = capture_subprocess_io do
      pid = fork do
        MM2.execute('--version') # ここの操作をフォークして行いたい
      end
      Process.waitpid(pid)
    end
    assert_equal "2.24-r1122\n", out
    assert_equal "", err
  end
```

この記事は、やや適当な記事で、技術的には間違っている部分もあるかもしれないが、ネットでググってもあまりめぼしい情報がヒットしないので記事にした。間違っている場合は、コメント欄で教えてください。

この記事は以上です。
Goroutineとselectとchannelを使って共同作業

田中君：1作業あたり1秒
鈴木君：1作業あたり1秒

ルール
- 作業6個分になったら仕事終了
- 仕事が終了するまでにかかった時間を計測する

田中君だけで作業をした場合 (鈴木君のgoroutineをコメントアウト）

```go

package main

import (
	"fmt"
	"time"
)

var total_work = []string{}

func tanaka(ch chan string) {
	for {
		time.Sleep(1 * time.Second)
		ch <- "作業"
	}
}

func suzuki(ch chan string) {
	for {
		time.Sleep(1 * time.Second)
		ch <- "作業"
	}
}

func main() {
	start_time := time.Now()
	c1 := make(chan string)
	c2 := make(chan string)
	go tanaka(c1)
	// go suzuki(c2)

	for {
		fmt.Println(total_work)
		if len(total_work) >= 6 {
			elapsed_time := time.Since(start_time)
			fmt.Printf("経過時間 : %v\n", elapsed_time)
			break
		}
		select {
		case unit_work1 := <-c1:
			total_work = append(total_work, unit_work1)
			fmt.Println(unit_work1)
		case unit_work2 := <-c2:
			fmt.Println(unit_work2)
			total_work = append(total_work, unit_work2)
		}
	}
}


```

実行結果

```

[]
作業
[作業]
作業
[作業 作業]
作業
[作業 作業 作業]
作業
[作業 作業 作業 作業]
作業
[作業 作業 作業 作業 作業]
作業
[作業 作業 作業 作業 作業 作業]
経過時間 : 6.0380414s

```

田中君と鈴木君が共同作業した場合

```go

package main

import (
	"fmt"
	"time"
)

var total_work = []string{}

func tanaka(ch chan string) {
	for {
		time.Sleep(1 * time.Second)
		ch <- "作業"
	}
}

func suzuki(ch chan string) {
	for {
		time.Sleep(1 * time.Second)
		ch <- "作業"
	}
}

func main() {
	start_time := time.Now()
	c1 := make(chan string)
	c2 := make(chan string)
	go tanaka(c1)
	go suzuki(c2)

	for {
		fmt.Println(total_work)
		if len(total_work) >= 6 {
			elapsed_time := time.Since(start_time)
			fmt.Printf("経過時間 : %v\n", elapsed_time)
			break
		}
		select {
		case unit_work1 := <-c1:
			total_work = append(total_work, unit_work1)
			fmt.Println(unit_work1)
		case unit_work2 := <-c2:
			fmt.Println(unit_work2)
			total_work = append(total_work, unit_work2)
		}
	}
}

```

実行結果

```

[]
作業
[作業]     
作業       
[作業 作業]
作業
[作業 作業 作業]     
作業
[作業 作業 作業 作業]
作業
[作業 作業 作業 作業 作業]
作業
[作業 作業 作業 作業 作業 作業]
経過時間 : 3.0256638s

```
Next.js12にstorybookを追加する際に詰まった点

こんにちは。
Reactを学習中のkeito654です。
現在Next.jsを使って開発をしており、storybookを導入してみたのですが、いろいろつまずいた点があったので、メモ書き程度に自分なりにまとめてみます。
#参考文献
###公式

https://storybook.js.org/blog/get-started-with-storybook-and-next-js/

#環境
macOS(m1チップ)
Node.js 14.18.2
Next.js 12.0.7
@storybook/reat 6.4.9

#インストール
```
npx sb init --builder webpack5
```
このコマンドを実行するだけで、インストールからいろいろな環境設定まで全部してくれるみたいです。
Next.js v12はwebpack v5が導入されているので、``--builder``でwebpackのバージョンを教えてあげます。

##"Cannot find module 'webpack/lib/util/makeSerializable.js"
え！？webpackのなんかのモジュールがない！？いろいろ全部してくれるんじゃ・・・

https://github.com/storybookjs/storybook/issues/15336

ここではその問題が取り扱われており、いろいろな解決方法が挙げられています。
``.storybook/main.js``に``typescript: { reactDocgen: false }``を追加する方法が多く実践されているみたいですが、このスレッドの最後の方でこれを非推奨とするコメントもあります。
そのため私は

```
yarn add -D webpack@5
```
を実行しました。今のところ、これで問題なく動いています。

随時追加していきます。

#読んでくれた方へ
最近Twitterをはじめました。あなたのような人と繋がりたいです。
ぜひフォローを！

https://twitter.com/YrGcj
Docusaurusにおけるdocsのページに最終更新日時を表示する

# 概要

[Docusaurus](https://docusaurus.io/) で作成しているドキュメントサイトにおいて、各 docs の最終更新日時を表示する便利設定を見つけました。

こちらです。
https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs#showLastUpdateTime
これを true にすると、各 docs ページの末尾に最終更新日時が表示されます。

showLastUpdateAuthor という設定もあり、trueにすると最終更新者が表示されます。

# 表示例

Docusaurus 自身のドキュメントでは、両方とも true にしているようです。以下のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188748/bb009156-67c6-55e0-ec0f-f9f817a6d940.png)

表示する値は、Git の履歴から取得しているようです。
値を決定するのはビルド時であり、ローカルでサーバーを起動している時にはダミーの値が表示されます。

# 設定方法

showLastUpdateTime や showLastUpdateAuthor は、@docusaurus/plugin-content-docs の設定値の一つです。

@docusaurus/plugin-content-doc は、[@docusaurus/preset-classic](https://docusaurus.io/docs/presets#docusauruspreset-classic) というプリセットに同梱されているプラグインです。
そして @docusaurus/preset-classic は `npx create-docusaurus` で作られるテンプレの中で設定されているので、ほとんどの場合、意識せずとも設定されているでしょう。

というわけで、あとは docusaurus.config.js に設定の行を追加するだけです。

docusaurus.config.js の presets のところに、@docusaurus/preset-classic を設定している箇所があるはずです。
なおプリセットの設定方法には shorthand があって、`@docusaurus/preset-classic` ではなく `classic` と書かれている場合もあります。

```js:docusaurus.config.js
const config = {
  // ...
  presets: [
    [
      '@docusaurus/preset-classic', // または 'classic'
      {
        docs: {
          // sidebarPath などの設定 ...
          showLastUpdateTime: true, // この行を追加
          showLastUpdateAuthor: true, // お好みでこちらも
        },
        // ...
      },
    ],
  ],
  // ...
};
```
databricks notebook での !pipと%pip の違い


Databricks notebookを使っててpipを使ったインストールなどで`%pip install ...` など出てくる。

あれ？`!pip install`じゃダメなの？と思って`!pip install`すると問題なく成功します。

念の為、何が違うのか調べてみました。

### 結論
- **`!pip install`**: ドライバーノードにのみインストールされる。
- **`%pip install`**: クラスター全体にインストールされる。

どういうことかというと、Databricksの場合Spark Cluster上でノートブックが実行されるため複数のサーバーが起動しております。

クラスターは全体を指揮する**ドライバーノード**と実際の処理を実行する**ワーカーノード**に分けられ、複数のワーカーノードが起動しております。なので`!pip`だとドライバーノードの１台しかインストールされないのです。

これからはデータブリックスでは**`%pip`**をこれからは利用しましょう！
Webアプリケーションについて②

# キャッシュサーバー
リクエスト数が多くなるとWebサーバーが重くなってしまう。
そこで、使用頻度の高いデータを要求するリクエストに対し、レスポンスを記憶しておけば、Webサーバーへの負担が軽くなる。このレスポンスを記憶しておく役割を持つのが`キャッシュサーバー`というプログラム。

####1. キャッシュ
使用頻度の高いデータを記憶すること
####2. コンテンツキャッシュ
文書や動画などのコンテンツのキャッシュ
####3. クエリキャッシュ
DBMSへのクエリ（データ検索要求）の結果のキャッシュ


###CDN（Contents Delivery Network）
キャッシュサーバーの集合体。
世界各地に分散して配置しており、アクセスしてきたリクエストに対して、ネットワーク的に一番近いキャッシュサーバーが対応することで、より素早いレスポンスを可能にしている。


# Webサーバー
Webクライアントとやり取りを行うプログラム。
Webサーバーに不具合が発生するとサービスが提供できなくなるので、こういった事態を避けるためにもWebサーバーの台数を複数設置し、他のWebサーバーが機能しなくてもサービスには影響の無いようにすることが一般的。このような構成を`冗長化`という。

# アプリケーションサーバー
RubyやJavaなどのサーバーサイド・プログラムを動作させるためのプログラム。
Webサーバーの要求通りにデータの加工・データベースのデータを検索し、その結果をWebサーバーへ返す役割を持つ。
ステートフルな通信が必要な場合はアプリケーションサーバーから`セッションID`をWebサーバーへ渡し、それを用いてWebブラウザを認識する。

# 　データベースサーバー
データベース管理システムを搭載したプログラム。
データベースの保存もWebサーバーと同じく非常に重要であるため、Webサーバーと同じく`冗長化`の構成を取ることが一般的。

# 参考
[イラスト図解式 この一冊で全部わかるWeb技術の基本](https://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E5%9B%B3%E8%A7%A3%E5%BC%8F-%E3%81%93%E3%81%AE%E4%B8%80%E5%86%8A%E3%81%A7%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8BWeb%E6%8A%80%E8%A1%93%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%B0%8F%E6%9E%97-%E6%81%AD%E5%B9%B3/dp/4797388811)
paizaラーニングの論理演算メニューのrubyの解答例

Paizaラーニングの論理演算メニューのrubyでの模範解答です。
答えだけですみません。
 
STEP: 1 論理積( AND )の基本
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step1

```ruby:step1.rb
a,b =gets.split(' ').map(&:to_i)

if a == 0 || b == 0
    puts 0
else
    puts 1
end
```

STEP: 2 論理和( OR )の基本
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step2

```ruby:step2.rb
a,b = gets.split(' ').map(&:to_i)

if a == 1 || b == 1
    puts 1
else
    puts 0
end
```

STEP: 3 否定( NOT )の基本
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step3

```ruby:step3.rb
a = gets.to_i

if a == 0
    puts 1
else
    puts 0
end
```

STEP: 4 排他的論理和( XOR )の基本
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step4

```ruby:step4.rb
a,b = gets.split(' ').map(&:to_i)

if a == 1 && b == 1
    puts 0
elsif a ==1 || b == 1
    puts 1
else
    puts 0
end
```


STEP: 5 NAND 演算の基本
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step5

```ruby:step5.rb
a,b = gets.split(' ').map(&:to_i)

if a == 1 && b == 1
    puts 0
else
    puts 1
end
```

STEP: 6 NOR 演算の基本
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step6

```ruby:step6.rb
a,b = gets.split(' ').map(&:to_i)

if a == 0 && b == 0
    puts 1
else
    puts 0
end
```

STEP: 7 XNOR 演算の基本
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step7

```ruby:step7.rb
a,b = gets.split(' ').map(&:to_i)

if a == 0 && b == 0
    puts 1
elsif a == 0 || b == 0
    puts 0
else
    puts 1
end
```

STEP: 8 半加算器
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step8

```ruby:step8.rb
a,b = gets.split(' ').map(&:to_i)

if a == 1 && b == 1
    c = 1
    s = 0
elsif a == 1 || b == 1
    c = 0
    s = 1
else
    c = 0
    s = 0
end
puts "#{c} #{s}"
```

STEP: 9 全加算器
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step9

```ruby:step9.rb
a,b,c = gets.split(' ').map(&:to_i)


if c == 1
    if a == 1 && b == 1
        d = 1
        s = 1
    elsif a == 1 || b == 1
        d = 1
        s = 0
    else
        d = 0
        s = 1
    end
else
    if a == 1 && b ==  1
        d = 1
        s = 0
    elsif a == 1 || b == 1
        d = 0
        s = 1
    else
        d = 0
        s = 0
    end
end

puts "#{d} #{s}"
```

STEP:10論理演算を用いた計算のまとめ
https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_boss

```ruby:step10.rb
a,b,c,d = gets.split(' ').map(&:to_i)

if a == 0 && b == 0
    e = 1
else
    e = 0
end
    
if c == 0 || e == 1
    f = 0
else
    f = 1
end

if f == 1 && d == 1
    puts 0
elsif f == 1 || d == 1
    puts 1
else
    puts 0
end
```
composerのupdateコマンドが中途半端な綴りでもOKな理由を探る


# 要するに

* `composer upda` とかの中途半端なコマンドでも `update` と解釈してくれる
* symfony が前方一致で探索してくれているおかげ

# ことの始まり

```bash
[higa@local]$ composer upda
```
あらー。 `update` としたいところ、間違えて `upda` って打っちゃったー。
これはコマンド失敗でしょうねー。

```bash
[higa@local]$ composer upda
Loading composer repositories with package information
```

へ？

```bash
[higa@local]$ composer upda
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 1 update, 0 removals
# 以下略
```

ほ？
普段の `update` と同じ出力が流れ始めたんですがー。

```bash
# もちろん成功
composer update
# もちろん成功 (公式でエイリアスを用意している)
composer u

# updateコマンドとして処理してくれる
composer updat
# 同上
composer upda
# 同上
composer upd
# 同上
composer up
```

どういうことー？

# composer のマニュアル

マニュアルやコードによると、アップデートできるコマンドは `update`。
エイリアスとして `u`, `upgrade` を用意しています。
他の、途切れた文字列は未定義です。

```bash
[higa@local]$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 2.2.1

Usage:
  command [options] [arguments]

Available commands:
  u                    Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
  update               Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
  upgrade              Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
```

[https://github.com/composer/composer/blob/2.2.1/src/Composer/Command/UpdateCommand.php#L48](https://github.com/composer/composer/blob/2.2.1/src/Composer/Command/UpdateCommand.php#L48)

```php
class UpdateCommand extends BaseCommand
{
    /**
     * @return void
     */
    protected function configure()
    {
        $this
            ->setName('update')
            ->setAliases(array('u', 'upgrade'))
```

# symfony のコード

composer は symfony/console などのライブラリを使っています。
下記は `Application::find()` の一部です。この下で、引数が ambiguous かどうかを判断しますが、composer では `u` から始まるコマンド・エイリアスが、たまたま `update` 1種類しかありません。
そのため、右文字がいかに削れようとも、無事に `update` コマンドと解釈して処理するようです。

[https://github.com/symfony/console/blob/v2.8.52/Application.php#L493](https://github.com/symfony/console/blob/v2.8.52/Application.php#L493)

```php
    public function find(string $name)
    {
// 中略
        $allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands);
        $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
// 引数 (composerのコマンド) が、途中で切れた `upda` であったとき、
// $expr = 'upda[^:]*[^:]*';
// になる。
        $commands = preg_grep('{^'.$expr.'}', $allCommands);
// 正規表現で前方一致探索してくれるので、
// $commands = ['update'];
// を選定する。
```

# おわりに

この記事では `composer update` コマンドが途中で切れていても動作する理由を探りました。
原因の箇所が `vendor` ディレクトリ配下にあるので、「composer の案内と違うけどなー？」と、しばらく混乱したのでした。

それではごきげんよう。
メモ：windowsでjenkins

CodePipelineは使っていたが、jenkinsは使った事がないので一応触ってみておいたメモ。
とりあえず手元で使えるWindowsServer2012で初歩だけ試す。
Jenkins 2.319.1

# インストール
[公式](https://ics.media/entry/2410/)からLTS版Windows用をダウンロード
.msiをダブルクリックでインストール。
今回はポートを4040にしたので
`http://localhost:4040/`
でアクセスできる事を確認。
指定されたファイルのパスワードを入力

プロキシを設定しないとプラグインが入らないので、OffLine画面が出たらプロキシ設定をする。
Install suggested pluginsを選択してプラグインインストール
adminユーザを設定して完了


# ジョブ作成

ジョブ作成からフリースタイルを選択。
とりあえず確認のためにWindowsコマンド`echo 'HelloWorld'`のジョブを作成して、ビルド実行。
成功すればOK

# パイプライン
フリースタイルでジョブの作成をすると一連の管理が難しくなりそうなので、自分で書けるパイプラインを使った方が良さそう。
[ここ](https://qiita.com/miyasakura_/items/9d9a8873c333cb9e9f43)とか[ここ](https://cloudbees.techmatrix.jp/blog/struggle-story-about-ci-10/)とかで基本がある。

.batを叩くのは単純に書くだけなので

```
node{
  stage('gitpull'){
    echo "dir"
    bat 'dir'
  }
  stage('build') {
    bat  'C:/Jenkins/test.bat'
  }
}
```

のようにコマンドを実行出来る。
windowsでもバックスラッシュではなく普通のスラッシュでパスを書く。
パイプラインそのものはジョブ作成から。
パイプラインを変更したい場合は「設定」を開く。


jenkinsと直接関係はないが、codecommitに接続する場合は[公式](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-https-unixes.html)に載っている。
httpsならAWSのCLIのクレデンシャルにxxxの名前でセットしておいて

```
git config --global credential.helper '!aws xxx codecommit credential-helper $@'
git config --global credential.UseHttpPath true
```

上はLinuxやMacで、Windowsだと実行されないので、その場合は[こっち](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-https-windows.html)を見る。
引用符が違うだけ。

```
git config --global credential.helper "!aws xxx codecommit credential-helper $@"
git config --global credential.UseHttpPath true
```



プラグイン等を組み合わせる事で色々な処理も可能。

マネージドのcodepipelineが使える環境ならそっちにするかも。
SVGのコードレビューをするときに見ていること

## この記事の概要

SVGは画像でありつつもコードで描画できます。
そのため、JPGやPNGと違いしっかりと内訳が表示されます。

とは言えほとんど暗号みたいな内容ですから、みなさん「これは流石に見なくてOK」と判断していませんか？
コードになっているからこそ気付きやすい点もあるので、その観点を記事にしてみました。

:::note warn
真面目な文章で書きますし、全く効果がない訳ではありませんが、ほとんどネタみたいな記事として捉えてください。
:::

## 見るポイント

### Generatorのコメント

SVGファイルであれば大抵はデザイナーが用意するはずです。
デザイナーが用意するのであればAdobe IllustratorやSketchで書き出している可能性は高いですよね。

するとコードの中にこんなコメントが入っている場合があります。

```xml
<!-- Generator: Adobe Illustrator x.x.x, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
```

```xml
<!-- Generator: Sketch x.x - http://www.bohemiancoding.com/sketch -->
```

これらは`SVGを表示する`という役割においては何も影響を及ぼしません。
コメントですからそりゃそうですよね。

なお、[SVGO](https://github.com/svg/svgo)などの最適化ツールを使えば削除できます。

:::note warn
ライセンス的にこのコメントを消してはいけない可能性もある……？と思って調べてみましたが、各種ヘルプページを見ても見つけられませんでした。
私の知る限りIllustratorではアートボード書き出しでSVGを生成するとこのコメントは入りません。
若干怪しいので、普段はそちらの書き出し方を選んでいます。
:::

### やたらたくさんの`<g>`

https://developer.mozilla.org/ja/docs/Web/SVG/Element/g

これも、グラフィックソフトから書き出すと起こる可能性があります。

操作しやすいようにグループ化するとそれがそのままコードに反映されてしまうんですね。

minifyするようなイメージで、不要な`g`は消しておいた方が（ほんの少しですが）軽くなります。

なお、[SVGO](https://github.com/svg/svgo)などの最適化ツールを使えば削除できます。

### viewBoxの小数点

SVGのコードはこんな感じで始まります。

```xml
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
```

viewBoxの詳しい解説をしようと思うとかなり長くなってしまうので、ここでは省略します。

本当にざっくりですが、widthとheightが指定されているイメージで読み進めてください。
上記のコードであれば100x100pxの正方形のエリアの中にパスで図形が描かれます。

さてこのviexBoxですが、これもグラフィックソフトで作ると小数点が入ってしまう場合があります。
すると微妙に表示が切れたり、端が汚くなったり……良いことがありません。

整数で作り直すようにレビューをしましょう。

### rectやcircleなど、プリミティブな要素の小数点

さすがに自由曲線のパスの場合はコードを見ていても無理がありますが、プリミティブな図形であれば変な小数点が無いかを一応見ています。
`0.5`とかならわかりますが`0.02`とかになっていたら「多分ずれてるはず」と判断して元データをチェック。

### evenodd

fill-ruleやclip-ruleあたりでしょうか。

これも結構ややこしい話なのですが、パスは本来決まった向きで書かれていないとくり抜きができません。
それを無視するのがevenoddです。

ルールを簡単にしてくれるなら良いじゃ無いかと思われるかもしれませんが、例えば以下のようなことがおきます。

https://stackoverflow.com/questions/46017839/how-does-fill-rule-evenodd-work-on-a-star-svg

リンク先の例でいうと、そもそもこんなパスの作り方をするのが間違いな気はしますが……

- evenoddを発見する
- 外してみる
    - ちゃんと表示されたら
        - 表示されるのだから、要らない記述は無い方が良い
    - 表示がおかしくなったら
        - パスの作りとして何かがおかしい可能性がある

こうやっていつもたしかめています。

### font-family

https://www.w3.org/TR/SVG2/text.html#FontsGlyphs

あくまで仕様としてフォントをSVG内部で使うこと自体はOKなのです。
しかしSVGで文字要素を作っているということは、装飾的なフォントとか、普通のPCには無いフォントを使っている可能性が高いです。

アウトライン化をし忘れていてfont-familyが指定されてしまっているのかな？と思って作成者に聞いて見るが吉です。

### 日本語の属性

レイヤー名などが日本語で入ってしまっているデータを見ることがあります。
表示は問題なくできますが、コードとしてはあまりよろしくないですよね。

「変数名は日本語でつけても良いから日本語でつけました」っていうのと同じ印象というか……。

というわけで英語に変えてもらうようにしています。
Googleの検索ページの<meta content="???">　???にあるもの

#Google検索ページのmeta content
ちょっとした発見かもしれないので、共有します。
タイトル通りなんですが、スクレイピングの練習でGoogleのソースを開いたら、「meta content」にちょっとした言葉が隠れていたみたいです。
[Google](https://www.google.co.jp)

##???とは
？？？とは、
_「世界中のあらゆる情報を検索するためのツールを提供しています。さまざまな検索機能を活用して、お探しの情報を見つけて下さい。」_
でした。

##検証のためのソースコード
下記に置きました。
実行するとUIが起動しますので、そこに「google.co.jp」を打ち込んで、ボタンを押すと該当するソースが確認できます。

```
#coding: utf-8

import tkinter
import requests
from bs4 import BeautifulSoup
from tkinter import messagebox

URL_HEAD = "https://www."

#UI
root = tkinter.Tk()
root.geometry('300x200')
root.title('Input URL for monitoring')

lbl = tkinter.Label(text='https://www.')
lbl.place(x=15, y=70)

txt = tkinter.Entry(width=20)
txt.place(x=90, y=70)

def btn_click():
    URL_BODY = txt.get()
    response = requests.get(URL_HEAD+URL_BODY)
    messagebox.showinfo('Status', f'{response.text}')

btn = tkinter.Button(root, text='INPUT', command=btn_click)
btn.place(x=140, y=170)

root.mainloop()

```
開発ツール(Checkstyle, Spotbugs, Formatter)について

開発ツール(Checkstyle, Spotbugs, Formatter)について

Checkstyleについて
→コーディング規約に則ったJavaコードを書くのを補助する開発ツール
https://checkstyle.sourceforge.io/

Spotbugsについて
→Javaプログラムの中のバグを見つけるプログラム(ツール)
https://spotbugs.readthedocs.io/ja/latest/introduction.html

Formatterについて
→コーディング規約に沿ってソースを修正してくれるツール
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Formatter.html