OmniAICreator/Qiita-1.07M huggingface dataset:
ラズパイでビデオシンセサイザーを試してみる

# ビデオシンセサイザーで遊ぶ
まあ、音声によって画像が変わります、的な。
Critter&Guitari という会社が、Raspberry pi Compute Moduleを使って、「EYESY」というビデオシンセサイザーを出しています。
こんなのね。

![maxresdefault.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216885/ccd9dbe2-3c62-44e8-7352-bc4848f734bc.jpeg)

https://www.critterandguitari.com/eyesy
こいつのラズパイフォーク版を、お手持ちのRaspberry piに突っ込んで、遊んでみます、というお話。

# ソースはこちら
https://github.com/okyeron/EYESY_OS_for_RasPi

# セットアップ
## オーディオデバイス
ラズパイは音声入力持ってないので、適当なUSBオーディオデバイスと使ってみます。
って、適当じゃダメでした・・・。

- TASCAM US-122mk2 : 動かず
- Creative SoundBlaster USB : 動作はするが頻繁に入力見失ってOut of range
- Roland VT-3 : 動かず
- Roland Quad Capture : 動かず
- Roland ( EDIROL ) UA-25 : 無事動作

今時の色気のあるオーディオインターフェースは、厳しいみたいです。
古い枯れたのを用意しろってことかな？。

## 音声入力順序
Eyesyは、デフォルトの音声入力を使用します。
ラズパイの音声は、標準だとSoCのものが優先されます。
が、もちろんそいつは音声入力が無いので。
USBオーディオを優先に変更！
ま、modeprobeで優先順位変更し、リブートすればOKです。

```/etc/modprobe.d/alsa-base.conf
options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1
```

## X Window
Raspberry pi OSのLITE版を愛用のオイラは、Xなんて普段は入れてません。
なので、以下コマンドでセットアップ！。

```
apt install libxm4 mwm xserver-xorg xinit x11-xserver-utils xterm x11-apps
```
ユーザーサイドでXを動かすわけではないので、.xinitrcとかの記載は不要です。

## Eyesyセットアップ
ま、以下な感じで。
なお、ディレクトリは決め打ちで、かつユーザも決め打ちなので、変更すると正常に動きません。

```
pi ユーザでログイン ( not root )
apt -y install git
cd
git clone https://github.com/okyeron/EYESY_OS_for_RasPi.git Eyesy
cd Eyesy
./deploy.sh
```
何度かy押しますが、まあスムーズに終わります。

## Web I/F スタート
```
~/Eyesy/start_web.sh
```
したあとは、「http://[IPアドレス]:8080/」で、Web I/Fにアクセスできます。
こんなの。
![eye_ui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216885/742015ff-e943-cf36-18e3-c7180a6d39d1.png)

# おたのしみ
Web I/F上の「Start Python」でXが起動し、ビデオシンセサイザー画面になります。
![DSC03926.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216885/f93e5a6c-57ce-8d93-bd3c-9ac01e3053be.jpeg)

「default」がどうのとエラーが出る場合は、オーディオI/Fを見直してみて下さいな。

# コントロール
標準では、何も操作が出来ません。
本来であればGPIOにつないだスイッチでゴニョゴニョ、らしいのですが、ね。
MIDIフィジコンを繋ぐか、「TouchOSC」というソフトで制御が出来ます。
こんな感じで。
![DSC03923.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216885/66749979-b5df-65aa-d281-beee934bb9e4.jpeg)

# おしまい
なんか色々マニアックなこと出来そうな感じだけ漂ってますが。
まあ画面が色々切り替わるのだけでも、楽しい感じ！。
まんぞく！。

![DSC03924.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216885/3c20605e-aa1e-6d4d-3c89-92d1a2c1625a.jpeg)
[000] Ruby の elasticsearch client パッケージを使って Elasticsearch 7.14 を操作してみる ... 検証環境構築編

|シリーズトップページ|
|:--|
|https://qiita.com/robozushi10/items/2c8b6951ee342b013974|

# 概要

Ruby の Elasticsearch Client を使って Elasticsearch 7.14 で REST API の操作する.


# 検証環境の構築手順

## 1. docker-compose を使ってローカルマシン上に Elasticsearch を立ち上げる

Elasticsearch と Kibana のポート番号がやや特殊である.

```bash
$ git clone -b Qiita-02 git@github.com:robozushi10/qiita-efk.git
$ cd qiita-efk
$ docker-compose build --no-cache
$ docker-compose up -d
```

引用元:
[[02] EFK (Elasticsearch + Fluentd + Kibana) の構築 ... Dockerコンテナの立ち上げ(説明なし)](https://qiita.com/robozushi10/items/9cf4cbdbad613cff4f72)

## 2. サンプルデータ「Shakespeare」を 1 の環境に登録する

「Shakespeare」とは Elasticsearch のチュートリアルで公開されている 11万件超のデータである.

```bash
$ curl -O https://download.elastic.co/demos/kibana/gettingstarted/7.x/shakespeare.json
$ curl -X POST -H "Content-Type: application/x-ndjson" \
    localhost:29200/_bulk --data-binary @shakespeare.json 
```

引用元:
[Elasticsearch 7.14で『📘 データ分析基盤構築入門』を写経してみた (16章)](https://qiita.com/robozushi10/items/4238600dcb0231d227d4#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%85%A5%E5%8A%9B-p264)


## 3. Elasticsearch Client を導入した Ruby on Docker 環境を用意する

下記リポジトリには、Elasticsearch パッケージを定義した Gemfile を準備済みである.

```bash
$ git clone git@github.com:robozushi10/qiita-ruby3.0-docker
$ cd qiita-ruby3.0-docker
$ docker-compose build --no-cache
$ docker-compose up -d
```

　

以上で次の環境が構築できたので、Ruby で操作をしてみる.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/957f2884-bcf2-a8d1-379b-7a425c69c492.png)
AnacondaでDjangoを簡単起動.batの作成方法

AnacondaでDjango実行までのワンクリック .batの作り方をご共有します。

```StartDjango.bat
echo on

cd C:\ProgramData\Anaconda3\Scripts
call C:\ProgramData\Anaconda3\Scripts\\activate.bat
call activate Python36
cd C:\Users\Administrator\Documents\Django
python manage.py runserver

pause
```

以下がコードの内容となります。
1. cd C:\ProgramData\Anaconda3\ScriptsでAnaconda環境へ移動
2. call C:\ProgramData\Anaconda3\Scripts\\activate.batでAnaconda Promptを起動
3. call activate Python36でAnacondaの該当環境をActivate
4. cd C:\Users\Administrator\Documents\DjangoでDjangoディレクトリへ移動
5. python manage.py runserverでDjango実行

出来た！
これだけでだいぶ工数が減らせます！
SQL文基本

#■SELECT文　取得
テーブルから指定したカラムを取得
*全て

``` sql
SELECT 取得したいカラム名　FROM 取得したいテーブル名
```

###▼検索条件を指定 WHERE
WHEREの後に検索条件を指定できる。
=の部分は比較演算子を使う

``` sql
SELECT 取得したいカラム名 FROM 取得したいテーブル名 WHERE カラム名=値
```
####■AND OR

AND(かつ) 
OR(または)

``` sql
//例 nameがステッカーで1000以下のprice
SELECT * FROM  テーブル名 WHERE name='ステッカー' AND price > 1000
```

###▼LIMIT 検索条件の数を指定 

``` sql
//これで検索条件の数を3に指定した。
SELECT * FROM テーブル名 LIMIT3
```

####■OFFSET

OFFSETで指定した数,先頭から無視する。

``` sql
//これで10個分飛ばして11番目から3つ取得
SELECT * FROM テーブル名 LIMIT3 OFFSET 10
```

#■INSERT INTO データの追加

``` sql
INSERT INTO テーブル名(登録したいカラム名) VALUES(登録するデータ)

//例 2つのカラムを指定する場合
INSERT INTO product(name,price) VALUES('マフラー',1000)

//複数のデータを追加
INSERT INTO product(name,price) VALUES('マフラー',1000)('ペンライト',500)

//カラム名の省略 全てのカラム名を指定する時に使える。
INSERT INTO product VALUES('マフラー',1000)('ペンライト',500)
```

#■UPDATE 指定したデータをアップデートする。

``` sql
UPDATE テーブル名 SET　カラム名　= カラムに登録する値 WHERE　検索条件

UPDATE product SET product_name = 'ロゴTシャツ' WHERE id=1 
```

#■DELET 指定したデータを消去する。

``` sql
DELET FROM テーブル名　WHERE 条件

DELET FROM product WHERE id=1
```
STM32L010で周波数を作てみた。(約1khzぐらい)(PWM利用)


x mbed2のリビジョン143

目的
基板作成が落ち着いたから
だいたい1khzを作った


![pwm_hz_out1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7302a152-1874-66d9-864c-30aec6cdb5e3.jpeg)


忙しい人よう


https://os.mbed.com/users/caa45040/code/pwm_hz_out_010_1/



```c++


#include "mbed.h"

//1khzの時は、1000と設定
#define XHZ (1000)
#define XHZ_A  (1000000/XHZ)
#define XHZ_B ((1000000/XHZ)/2)

//PWMのピンの設定
PwmOut servo(A4); //PA_5   //010
//PwmOut servo(PA_4); //PA_5   //010

//debug
DigitalOut myled(PA_4);

int main() {

    //周期の設定        
    servo.period_us(XHZ_A);

    //間隔の設定
    servo.pulsewidth_us(XHZ_B);

    while(1) {
        
        myled = 1;  
        //250ミリ秒まつ
        wait_ms(250);   
        
        myled = 0;  
        //200ミリ秒まつ
        wait_ms(250);

    }//while


}//main

//容量削減
void error(const char* format, ...){}




```
PyenvをCentOS7にインストールする

pipenvを使いたかったので[ここ](https://blog.cles.jp/item/11113)を参考した。
参考記事は少し古いからかうまくできない部分があったので、忘備録として残す

結局は1次情報である[github](https://github.com/pyenv/pyenv)を見るのが早かった。

# anacondaのPATHからの削除
anacondaをすでに入れていた人向け

~/.bashrcからanacondaのPATH追加部分を削除


# pyenvのインストール

```bash
# 必要なライブラリを導入
sudo yum install -y git gcc zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel libuuid-devel xz-devel libffi-devel 

# pyenv を github から clone
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

# bashrc, bash_profileの編集

```bash:bash_profile
# デフォルトのbash_profileでは.bashrcを読み込む部分があるが、それより前に以下を挿入
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
~中略~
# 一番下に追記
eval "$(pyenv init --path)"
```

```bash:bashrc
# 一番下に追記（bashでコマンド補完するのに必要）
eval "$(pyenv init -)"
```


# ログインし直せば完了
GitHubでhttpsのパスワード認証が廃止された。Please use a personal access token instead.



昨夜作業中にgit pushしたところ見慣れ無いエラーが発生しました。

```
$ git push origin branch名
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: unable to access 'https://github.com/名前/リポジトリ.git/': The requested URL returned error: 403
```
   Please use a personal access token instead.
訳:　代わりにパーソナルアクセストークンを使用してください。

調べてみたところGitHubで2021年8月13日にパスワード認証が廃止されたそうです。
日を跨いで作業していたのでかなりタイムリーなエラーでした。
#####参考記事
https://qiita.com/shiro01/items/e886aa1e4beb404f9038

##1.キーチェーンアクセスの削除　とosxkeychainの関係

####osxkeychainとは?
ここにパスワードを格納しておけばhttps接続の場合毎回パスワードを入力する手間を省けます。
更にキーチェーンにも格納されるので便利。


osxkeychainはこちらで確認できます。

```
$ git config --list
```

mac本体の検索からキーチェーンアクセスを開き、github.comを見つけ出します。
github.comのアクセス権限を削除し保存します。

#####キーチェーンアクセスは、パスワードやアカウント情報を保管するmacOSアプリケーションです。このアプリケーションを使用することで、記憶および管理する必要のあるパスワードの数を減らすことができます。


##2.個人アクセストークンを作成、使用する

こちらは公式のものを参照してください
https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token
トークンのコピーはページを離れると参照不可になリますのでご注意ください。

##3.git pushする
この際にパスワードとして先ほどコピーしたトークンを使います。
２回目以降は求められませんでしたが、設定の先にトークンの期限を選択できますので期限が過ぎるをまた作り直すことになりそうです。


##パスワード認証が廃止された経緯について
https://gigazine.net/news/20201219-github-token-git-operations/

##SSH接続の手順
#####ssh接続なら今回の変更の影響を受けないので備忘録として残します。

鍵を入れるフォルダに移動

```
$cd ~/.ssh
```
こちらは隠しファイルになるので確認の際は**$ls -la**する


```
$ ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/satoshun/.ssh/id_rsa): 
/Users/satoshun/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 

```
ここで名前を設定することができます。


###公開鍵のgithubへの登録

https://github.com/settings/ssh

鍵の中身のクリップボードへのコピーは
**$ pbcopy < ~/.ssh/id_rsa.pub**


鍵を作るときに名前を設定しない場合、id＿rsaとなるがこちらがデフォルトで
id＿rsaを見に行くようになっている。

```
$ vim ~/.ssh/config
```

```config
Host github
  HostName github.com
  IdentityFile ~/.ssh/id_rsa 鍵名
  User git
```


###接続のチェック
```
$ ssh -T git@github.com
```
Hi (名前)! You've successfully authenticated, but GitHub　does not provide shell access.
StyleGAN環境構築

まずはとにかく動かしたい！そんな方に成功した互換性をご共有します。

#※デモデータ
現在アクセス制限でダウンロードできず１日待ち？中ですので次回他にも試してます！
URL : https://drive.google.com/uc?id=1MEGjdvVpUsu1jB4zrXZN7Y4kBBOzizDQ

# Tensorflow Ver.
今回はVer2.2.0を利用しますのでエラーの都度styleGAN側のメソッド名を更新します。

例えば"variable_scope"がない際、

```
err.msg. AttributeError: module 'tensorflow' has no attribute 'variable_scope'
```
と表示されますので該当ラインにて、このように書き換えます。

```
前) tf.variable_scope
後) tf.compat.v1.variable_scope
```

最後に下記に今回が成功した互換性のリストです。
皆様もぜひお試しください！

#互換性リスト
```
OS : windows 10 (GPUなし)
Python 3.6.13 : Anaconda, Inc. (anaconda環境)

pip list (以下参照)
absl-py                0.13.0
astor                  0.8.1
astunparse             1.6.3
cached-property        1.5.2
cachetools             4.2.2
certifi                2021.5.30
charset-normalizer     2.0.4
colorama               0.4.4
dataclasses            0.8
gast                   0.3.3
google-auth            1.34.0
google-auth-oauthlib   0.4.5
google-pasta           0.2.0
grpcio                 1.39.0
h5py                   2.10.0
idna                   3.2
importlib-metadata     4.6.4
Keras                  2.4.3
Keras-Applications     1.0.8
Keras-Preprocessing    1.1.2
Markdown               3.3.4
numpy                  1.19.5
oauthlib               3.1.1
opt-einsum             3.3.0
Pillow                 8.3.1
pip                    21.2.2
protobuf               3.17.3
pyasn1                 0.4.8
pyasn1-modules         0.2.8
PyYAML                 5.4.1
requests               2.26.0
requests-oauthlib      1.3.0
rsa                    4.7.2
scipy                  1.4.1
setuptools             52.0.0.post20210125
six                    1.16.0
tensorboard            2.2.2
tensorboard-plugin-wit 1.8.0
tensorflow             2.2.0
tensorflow-estimator   2.2.0
termcolor              1.1.0
tqdm                   4.62.0
typing-extensions      3.10.0.0
urllib3                1.26.6
Werkzeug               2.0.1
wheel                  0.37.0
wincertstore           0.2
wrapt                  1.12.1
zipp                   3.5.0
```
外部ファイル（ifstream）の内容を内部メモリ（vector）へ読み込む方法

## 実装例

```cpp
#include <fstream>
#include <iostream>
#include <vector>

void main(){
std::ifstream inputFile("ファイルパス");
std::vector<char> data{std::istreambuf_iterator<char>(inputFile), std::istreambuf_iterator<char>()};
std::cout << data[0] << std::endl;
}
```

## 解説  

`ifstream`はファイル読み込みに使用するクラスです。
`fstream`がファイル入出力で、読み込み専用なのでinputのiがついて`ifstream`となります。
出力用だとoutputのoがついて`ofstream`です。

vectorの波カッコは一様初期化というコンストラクタの呼び出し方です。
vectorコンストラクタに
`vector(InputIter first, InputIter last, const Allocator& a = Allocator());`
というものがあります。
第一引数のイテレータから第二引数のイテレータまでの範囲をvectorのメモリに格納してくれるというものです。
`ifstream`のイテレータを作成するため`istreambuf_iterator`を使用します。
`istreambuf_iterator`は引数を指定しなければendイテレータと等しくなるため、第二引数に使用できます。

## 注意点

vectorのコンストラクタを丸カッコで呼び出すこともできます。
`std::vector<char> data((std::istreambuf_iterator<char>(inputFile)), (std::istreambuf_iterator<char>()));`
この時、vectorコンストラクタの第一引数、第二引数共にカッコでくくられていることに注意してください。
例えばカッコを削除してしまい、
`std::vector<char> data((std::istreambuf_iterator<char>(inputFile)), (std::istreambuf_iterator<char>()));`
とするところを
`std::vector<char> data(std::istreambuf_iterator<char>(inputFile), std::istreambuf_iterator<char>());`
としてしまうと思った通りの挙動にならないので注意してください。
`data[0]`などとアクセスするタイミングでビルドエラーになります。

理由は、カッコを無くした場合関数宣言になってしまうからです。
`std::vector<char>`が戻り値で`std::istreambuf_iterator<char>(inputFile)`と`std::istreambuf_iterator<char>()`が引数の`data`という関数が宣言されてしまいます。
そのため、data[0]などと記述すると怒られます。
[シリーズ 全2回] docker-composeを活用して即座に Ruby 3.0 slim-buster を立てる

次の記録である.

限られた物理PC の中で、複数の Ruby バージョンをインストールして
プログラムを作成することになった.
　
ただし、物理PC を汚染させるわけにもいかないので Docker を活用した.
(操作しやすいように docker-compose を導入した)

|コンテンツ|掲載時期|
|:--|:--|
|[[01] docker-composeを活用して即座に Ruby 3.0 slim-buster を立てる (簡易手順のみ)](https://qiita.com/robozushi10/items/6bcbc01ecb792f2ddb06)|2021/08|
|[[02] docker-composeを活用して即座に Ruby 3.0 slim-buster を立てる (説明あり)](https://qiita.com/robozushi10/items/2cb56482f9c8ff604746)|2021/08|
ゲストログイン機能

##環境
Rails 6.1.3
MySQL
##ゲストログイン機能の設定
```routes.rb
 get '/guest_session' => 'guest_sessions#new_guest'
```
```guests_essions_controller.rb
class GuestSessionsController < ApplicationController
  def new_guest
    user = User.find_or_create_by(email: 'guest@exapmle.com') do |user|
      user.password = SecureRandom.urlsafe_base64
      user.name = 'ゲストユーザー'
    end
    session[:user_id] = user.id
    flash[:notice] = 'ゲストユーザーとしてログインしました'
    redirect_to('/posts/index')
  end
end
```
##解説
####・find_or_create_byでゲストユーザーをあらかじめ作成する手間を省きます。またメールアドレスを'guest@exapmle.com'で固定します。
####・　user.password = SecureRandom.urlsafe_base64はuserのパスワードをA-Z, a-z, 0-9, “-” and “_” **の中からランダムで作成します。ランダムで生成するのはパスワードを特定されると，ユーザー編集ページからメールアドレス・パスワードを変更される可能性があるためです。
####・nameを'ゲストユーザー'で固定します。
##参考記事
[[Ruby 2.x] SecureRandom を利用した乱数の生成方法](https://qiita.com/colorrabbit/items/f65454105bb0e1cfbf74)
[ゲストログイン機能の追加](https://qiita.com/Nishi-Shin/items/0118fc02bd4a2aada840)
[簡単ログイン・ゲストログイン機能の実装方法（ポートフォリオ用）](https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104)
[02] docker-composeを活用して即座に Ruby 3.0 slim-buster  を立てる (説明あり)


# はじめに

限られた物理PC の中で各バージョンの Ruby プログラムを作成することになった.

ただし、これ以上 物理PC を汚染させるわけにもいかないので Docker を活用した.
(操作しやすいように docker-compose を導入した)

また、物理ホスト側からバッチを使って、極力コンテナに「手動で」ログインせずに
Ruby コードを実行するようにした.

今後もこの環境構築は頻発すると思うので書き残しておく.

今回は「**ビルドコンテナ**」を作成する場合についてである.
　

# 構築後のファイル構成

```bash
.
|-- PV ......................... 永続ボリューム
|   `-- rb
|       `-- app ................ この直下に *.rb を配置していく
|           `-- Gemfile
|-- assets
|   `-- rb
|       `-- Dockerfile
`-- docker-compose.yml
```


# 手順

## 1. 永続ボリュームを作成する

コードやデータを配置するために使用する.

```bash
$ mkdir -p PV/rb/app
```

## 2. Dockerfile を作成する

独自拡張するために使用する.

```bash
$ mkdir -p assets/rb/
$ vim assets/rb/Dockerfile
```

### assets/rb/Dockerfile

```dockerfile
FROM ruby:3.0-slim-buster

## プロキシサーバを使う場合
# ENV http_proxy="http://proxy.co.jp:8080"  
# ENV https_proxy="http://proxy.co.jp:8080"
  
# コンテナ内での作業場所を /usr/src/app とする
WORKDIR /usr/src/app
  
# Ruby に関する環境変数
  
# 日本環境に合わせる
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
ENV LANGUAGE ja_JP.UTF-8
ENV LANG ja_JP.UTF-8

```

## 3. Gemfile を作成する

ここでは `PV/rb/app/Gemfile` に定義する

### PV/rb/app/Gemfile

以下は例である.

```ruby
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

# gem "rails"
gem 'faker', '1.7.2'
gem 'elasticsearch', '7.14.0'
gem 'elasticsearch-api', '7.14.0'
gem 'multi_json'
gem 'faraday'
gem 'activesupport'
gem 'minitest'
gem 'jbuilder'
gem 'hashie'
```

## 4. docker-compose.yml を作成する

### docker-compose.yml

```yaml
version: '3.7'
services:
  rb:
    build: ./assets/rb
    image: myruby3.0
    container_name: myruby3.0
    tty: true
    volumes:
      - ./PV/rb/app/:/usr/src/app/
    command: >
      bash -c '
        bundle install
        while true; do sleep 3600; done
      '
```

## 5. イメージビルドをする

次のコマンドによって、Dockerイメージ「`myruby3.0`」が作られる

```bash
$ docker-compose build --no-cache
```

## 6. 常駐型コンテナを起動させる

次のコマンドによって、Dockerコンテナ「`myruby3.0`」が作られる

```bash
$ docker-compose up -d
```

```bash
$ docker-compose ps
  Name     Command   State   Ports
----------------------------------
piyoruby3.0   bash -c            Up           
                bundle install 
```

## 7. 所望のバージョンであることを確認する

デフォルトで使用される Ruby が 3.0 であることを確認する.

```bash
$ docker-compose exec rb bash -c 'which ruby' 
/usr/local/bin/ruby
$ docker-compose exec rb bash -c 'ruby --version' 
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
```

## 8. サンプルコード a.rb を作成する

```bash
$ cat <<'EOL' | tee PV/rb/app/a.rb
#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-

p 'Hello Ruby'

EOL

$ chmod +x PV/rb/app/a.rb
```

## 9. 実行する

コンテナログイン時のパスは `/usr/src/app` である. (∵ Dockerfile の WORKDIR のため)

```bash
$ docker-compose exec rb bash -c './a.rb' 
"Hello Ruby"
```

　

# 補足

## コンテナ内にログインするには

次を実行する

```bash
$ docker-compose exec rb bash
```


## 実行環境 (イメージとコンテナ) を一掃する

永続ボリューム (ここでは `./PV`) は残るので問題ない

```bash
$ docker-compose down --rmi all  --volumes --remove-orphans
```
[01] docker-composeを活用して即座に Ruby 3.0 slim-buster を立てる (簡易手順のみ)


# はじめに

「**Ruby 3.0-slim-buster を使ったビルドコンテナ**」を作成する
　

# 手順

```bash
$ git clone git@github.com:robozushi10/qiita-ruby3.0-docker
$ cd qiita-ruby3.0-docker
$ vim PV/rb/app/Gemfile
導入したいパッケージを書く

$ docker-compose build --no-cache
$ docker-compose up -d
```

PV/rb/app/. にコードを配置していく.

なお、コンテナ内にはエディタが存在しないのでホスト側から編集する想定である.

　

以上.
戻りを待つか、待たないか。そして、タイムアウト。

# はじめに
Automation360の「Excelの高度な操作」アクションの「マクロを実行」でマクロエラーが起きるとBotの実行が止まってしまいます。どうやら「マクロを実行」はマクロの終了を待っているようです。
では、その他の実行系のアクションはどうなっているのか、試してみました。

★A360.22でタイムアウトがサポートされました。
　なので以下で書いた『タイムアウト無理やり実装』はもう意味ありません。 (2021/9/18)

# 結果

| アクション                                  | 終了を待つ | 待たない　 |
|---------------------------------------------|----|------|
|アプリケーション: プログラム/ファイルを開く      |    |　　○|
|VBScript: 関数を実行                          |　　○|        |
|Python スクリプト: スクリプトを実行            |　　○|        |
|Excel の高度な操作: マクロを実行               |　　○|        |

# Excelマクロエラーで止まらないようにできないか
エラーが起きないようにマクロを作るのが大前提なのですが、それでも不測の事態に備えマクロが一定時間戻ってこなかった場合にタイムアウトができるか否かを考えてみます。
まず、Automation Anywhere V11にはタスクのプロパティとして「timeout設定」がありましたが、これはExcelマクロエラーのようにBotから呼んだアクションが長時間戻ってこない場合には使えません(詳しい理由は割愛)。
それ以前に、Automation 360には現在のところタイムアウト設定がないようです。
そのため、自力で無理やりな実装を考えてみます。

# ひとつの案
（１）マクロを「Excel の高度な操作: マクロを実行」ではなく、「アプリケーション: プログラム/ファイルを開く」で起動する。
（２）マクロを実行したあとBotの次のステップに進むのでループと遅延を使って一定時間たったら強制的にExcelを終了させる。

※(1)については以下を参考にしました。
https://qiita.com/tomotagwork/items/4a5927142ee4b939c4cd

#タイムアウト付きのマクロ実行

![timeout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/b50ee058-9397-b559-4ffe-2becb2064516.png)

＃１：VBscriptを実行後すぐに戻るよう、「アプリケーション: プログラム/ファイルを開く」で起動。
＃２：１００回は適当。変数\$Counter\$に回数を入れる。
＃４：Excelが終わっていたらループを抜ける（正常終了）
＃６：変数\$Counter\$ ＞ １５ならタイムアウトとみなして、強制終了させる。１５は適切な値にする。
＃７：タイムアウトのため、強制終了させるbatファイルを呼ぶ

# 使ったVBSやBAT
最小限の動作確認のため、非常に雑な作りである点、ご注意ください。

＃１のVBscript

```
Dim obj
Set obj=WScript.CreateObject("Excel.Application")

obj.Visible=true
obj.Workbooks.Open  "D:\temp\MacroTest.xlsm"
obj.Application.Run "Macro1"

obj.Application.DisplayAlerts = False
obj.Workbooks.Close
obj.Application.Quit
    
set obj = nothing
```


＃７のBAT

```
@echo off
taskkill /F  /IM  wscript.exe
taskkill /F  /IM  EXCEL.EXE
```
・無理やり終わらせているので、Excelの回復が裏で走る。あとで綺麗にしないといけない。
・GUIのエラーダイアログが出てたら消すために、wscript.exeも殺しています。
・Excelやwscript.exeが他には動いていない事が前提。


#さいごに
試してみたものの、やっぱり煩雑。
Automation360自身に綺麗なタイムアウトが実装される事を期待。
でも、一番考えるべきは、呼び出すマクロやプログラムを、止まらないようにきちんと作る事かな。

★A360.22でタイムアウトがサポートされました。 (2021/9/18)
【React / Next.js】環境変数を呼び出せなくてハマった

# はじめに
普通の``React``と``Next.js``で環境変数の設定方法が異なることを知らず、``APIキー``を呼び出せずハマってしまった。

かなり初歩的です。

# .env ファイルで定義
まず、プロジェクトのルートディレクトリに``.env``ファイルを作成する。
（``.gitignore``に記述して``git``管理外にしておく）

``APIKEY``を設定する例としてます。

### React の場合
環境変数定義の際、変数名の最初に``REACT_APP_``をつける

```..env
REACT_APP_APIKEY="xxxxxxxxxxxxxxxxxxxxxxx"
```

### Next.js の場合
環境変数定義の際、変数名の最初に``NEXT_PUBLIC_``をつける

```..env
NEXT_PUBLIC_APIKEY="xxxxxxxxxxxxxxxxxxxxxxx"
```

# js（もしくはts）ファイルで呼び出す

``React``の場合でも``Next.js``の場合でも``process.env.環境変数名``で呼び出す。

### React の場合

```..js
const apiKey = process.env.REACT_APP_APIKEY;
```

### Next.js の場合
```..js
const apiKey = process.env.NEXT_PUBLIC_APIKEY;
```

# 最後に
``Next.js``のプロジェクトで``REACT_APP_``を使ってしまい、APIに接続できずに悩みました...

参考になる詳しい記事がたくさんありました。
ありがとうございました。

- https://qiita.com/KZ-taran/items/64cad61096cf45f18c24
- https://zenn.dev/kazumax4395/articles/643ffc25d3f803
- https://qiita.com/hirogw/items/aa6e589bc90f1495033c
- https://qiita.com/wakeupsloth/items/ec19b9fbfddfb1cd58bb
GitHubによるGit操作時のパスワードのみ認証禁止に対する解決策

##はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

昨日(2021/08/13)、突然何の警告もなくGitHubからパスワード認証を拒否されて困ったので、解決策(MacOS)を残しておきます。(後でメールを確認したら、しっかり通知メールが届いてました...GitHubさんごめんなさい)

間違いなどがございましたら、ご指摘のほどよろしくお願い致します。

##git push 実行時に出た警告文
```
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: unable to access 'https://github.com/username/repository.git/': The requested URL returned error: 403
```
パスワード認証が廃止され、上記のような警告文が表示されました。
パスワードの代用として、個人アクセストークンを使うらしいです。
分からないなりに色々と調べて解決できたので、下記にて手順を記録しておきます。

##パスワード認証から個人アクセストークン認証に変更する手順
###1.GitHubで、個人アクセストークンを作成する
リンク先([個人アクセストークンを使用する](https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token))で、作成方法が載っているので参考にしてください。

###2.個人アクセストークンを作成後、MacOSのキーチェーンの内容を修正する
リンク先([macOS キーチェーンからの認証情報を更新する](https://docs.github.com/ja/github/getting-started-with-github/getting-started-with-git/updating-credentials-from-the-macos-keychain))を参考にして、認証情報を修正します。

まず初めに、キーチェーンを選択してgithub.comを検索します。
![スクリーンショット 2021-08-14 17.52.33（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891113/e195d820-c118-73f5-627f-7036a876426c.png)

次に、右クリック後、``情報を見る``を選択します。
![スクリーンショット 2021-08-14 17.53.55（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891113/27baccb0-f5d4-96cb-907d-8fa7491437ca.png)

最後に、パスワードを表示項目に、作成した個人アクセストークンを貼り付けて変更内容を保存します。

![スクリーンショット 2021-08-14 17.54.06（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891113/c72c20c7-e3cf-55f8-9973-a82d6eb9fe21.png)

以上で、再びgit pushができるようになりました。

もし、上記の手順でも解決できない場合は、コマンドラインかGUIでキーチェーンエントリを消去してください。キーチェーンのアクセス制御画面で消去できます。

##参考文献
[個人アクセストークンを使用する](https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)
[macOS キーチェーンからの認証情報を更新する](https://docs.github.com/ja/github/getting-started-with-github/getting-started-with-git/updating-credentials-from-the-macos-keychain)
【React Hook Form】useFieldArrayを試してみた

## React Hook Form

React Hook Form をちゃんと使いこなしたいなぁと思っているので、これから少しずつ試して行こうと思っています（ React Hook Formシリーズ化決意🤓 ）。

- React Hook Form の基本
    - React Hook Form の基本機能
- React Hook Form の応用
    - useForm
    - useController
    - useFormContext
    - useWatch
    - useFormState
    - [useFieldArray](https://qiita.com/seira/items/1f6b1f71ca411b21372f)　 <=いまココ
        - useFieldArrayがネストされた場合編

### React Hook Form で料金計算フォームを作ってみた

請求書とか見積書、納品書などでよく見かける、行を追加削除出来る超単純なフォームを作ってみました。

お気に入りのコンポーネントライブラリ「Chakra UI」との組み合わせですが一部 React Hook Form と相性の悪い Form 系のコンポーネントもあるみたいです。ちなみに [Number Input](https://chakra-ui.com/docs/form/number-input)をうまく組み込むことが出来なかったので解決したい。。。


![useFieldArrayで請求書テーブル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218656/48f45c72-3cc7-67d8-e2df-f59a319c279d.png)

コードは次の通りです。

```App.tsx
import {
  Box,
  Flex,
  Button,
  Table,
  Thead,
  Tbody,
  Tr,
  Th,
  Td,
  IconButton,
  Text,
  Input
} from "@chakra-ui/react";
// Chakra icons を import
import { DeleteIcon, AddIcon } from "@chakra-ui/icons";
// React Hook Form を import
import { useForm, useFieldArray, useWatch, Control } from "react-hook-form";

// FormValues の型
type FormValues = {
  itemRows: {
    itemName: string;
    unitPrice: number;
    quantity: number;
    amount: number;
    taxAmount: number;
  }[];
};

// すべてのアイテムの金額を合計する TotalAmount コンポーネント
const TotalAmount = ({ control }: { control: Control<FormValues> }) => {
  const formValues = useWatch({
    name: "itemRows",
    control
  });
  const total = formValues.reduce(
    (acc, { unitPrice, quantity }) => acc + (unitPrice || 0) * (quantity || 0),
    0
  );
  return (
    <Text fontSize="sm">
      {total}
      <small>円</small>
    </Text>
  );
};

// 続きはCodeSandbox上で。。。

```

CodeSandBox上に[useFieldArrayで請求書テーブル](https://codesandbox.io/s/react-hook-form-usefieldarray-ryli5)のコードを置いていますので、興味のある方はのぞいてみてください。

参考サイト：

- [React Hook Form (useFieldArray)](https://react-hook-form.com/api/usefieldarray)
- [Chakra UI](https://chakra-ui.com/)
Chapter 1 - §03 文字列・数値

#　文字列
[§01](https://qiita.com/confrict/items/e1e5c53dd89b79485799#%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%84%E3%81%A6%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)でも紹介したように、 `print()`の中には変数以外に直接文字を入れることができます。
`print()`文でできることを上げていきます。

## ・変数に代入した文字列を連結させて表示する
文字列を変数に代入して、それをつなげ合わせるとき、 `,` を使います。

例えば、`a = 明日は`, `b = 晴れます`　
この二つの単語を`明日は晴れます`にするために a と b の文字列を繋げるとします。
この時、

```python
print(a, b)
```
とすれば、

```python
明日は晴れます
```
と出ます。

## ・print()文でできること　(＋α)
##　空白行を作る
文字通り、空白の行を入れることができます。

```python
print("100")
print("200")
print("300")

# これを実行すると

100
200
300
```
となります。

これを、それぞれの文の間に `print()` をもう一つ入れることで、

```python
print("100")
print()
print("200")
print()
print("300")

# これを実行すると

100

200

300
```
となり、少し見やすくすることができます。

これは、`100` と `200`、`200` と `300` の間に `print()` の中身 (何もない) が挟まっているので空白の行を作ることができます。

##　区切り文字・文末文字を指定
本来、`print()` は`(値a, 値b, …, sep = "", end = "")` という形で使いますが、普段は `sep="", end=""` は使わないので省略されています。(オプションとして付けることができる、という考え方でOKです)
使い方は、

`sep = "" ：値a と 値b の間に入れる区切り文字  ('sep'はseparator の略)`
`end = "" ：最後の値の後につける文末としての文字`

です
使用例：

```python
a = 100
b = 200
c = 300
d = 400
print(a, b, c, d, sep = ",", end = ".")

#実行結果
100,200,300,400.
```
このように、値の間を`,`、文末を`.` で終わらせることができます。

#　数値
pythonでは、整数、n進数、小数、複素数を扱うことができます。
整数の扱い方は前回説明したので省略します。
なので、n進数・小数・複素数について説明します。

**ちなみに、これらはすべて計算に用いることができます。**

##　n進数
普段の生活の中ではあまりよく使われませんが、pcなどでの電子機器では2,8,16進数で動いています。
なのでこの3つについて説明します。

###　2進数
2進数表記は、数字の前に `'0b'(b は binary)` を付けます

`print(0b1010)` を実行すると、`10` という値が出てきます。これは、`1010` という2進数を10進数に直すと `10`
という値になるからです。
他にも、
`0b1111` は `15`
`0b11001100` は `204`
という結果が出ます。

###　8進数
8進数は、数字の前に `'0o'(o は octal)` を付けます。

`0o1257` は `687`
`0o15214` は `6796`
という結果が出ます。

###　16進数
16進数は、数字の前に `'0x'(x は hexadecimal)` を付けます。
`0xfff` は `4095`
`0x195af` は `103855`
です。

##　小数
小数同士・小数と整数の計算ができます。
例：

```python
10.5 + 0.2 = 10.7
15 - 1.55 = 13.45
1.1 * 1000 = 1100.0
100 * 0.2 = 20
```
しかし、`//`という演算子を使うと、小数点以下を切り捨てた数値を返します。
また、`/` を使うと、割り切れる場合は、基本的に小数点第1位まで表示されます。

小数点以下を丸めるには、`round()` を使います。
これは四捨五入とは少し違い、小数点以下が.5の時はいちばん近い偶数に丸めます。

例えば2.5に近い整数は2または3ですが、どちらも0.5の違いなので、`round(2.5)` のときは偶数の2に丸めます。また、`round(3.5)` の時は偶数に近づけるので、4になります。

丸める桁数を指定したいときは、`round(数値, 桁数)` の順に並べます。

使用例： 

```python
print(round(1.4))
1

print(round(9.584, 2))
9.58
```

##　複素数
(複素数とは、虚数単位を2乗すると `-1` になる数のこと)
複素数は `実部 + 虚部` を使って表します。
数学では、虚数単位は `i` を使いますが、pythonでは `j` を使います。

計算例：

```python
print(1j * 1j)
(-1 + 0j)

a = 2.6 + 0.5j
b = 0.5 + 0.8j
print(a + b)
(3.1 + 1.3j)

print(a * b)
(0.9+2.33j)
```
また、複素数から実部、虚部をそれぞれ取り出すこともできます。

`v = 3.1 + 1.3j` とします
実部：(変数).real
虚部：(変数).imag

```python
v = 3.1 + 1.3j
print(v.real)
3.1

print(v.imag)
1.3
```
また、`complex()` を使うことで、逆に数を2つ与えて複素数を作ることもできます。
`complex(実部, 虚部)` のように使います。

```python
complex(2, 5)
(2 + 5j)
```
複素数はあまり使いませんが、覚えておきましょう。


今回は以上です。

前回：[計算・コメント](https://qiita.com/confrict/items/823bb4b20946cdeba023)


間違いなどのご指摘がございましたら、修正依頼を出していただけたら幸いです。


<head>
    <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4386565414956285"
     crossorigin="anonymous"></script>
</head>
Forkのカスタムコマンド

# はじめに
GitクライアントであるForkというアプリのカスタムコマンドの作成について示します。
カスタムコマンドを設定するとよく使用するコマンドをGUIから簡単に起動できるようになります。

# 開発環境
```
Fork v2.10
macOS Big Sur(v11.3)
```

# カスタムコマンドの作成方法
メニューから設定ダイアログを開きます。
![2021-08-14_16-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263901/854d51ed-2a42-0283-c775-b1a81f940e8a.png)

設定ダイアログの中のカスタムコマンドタブを選択します。
まだ空っぽです。
![2021-08-14_16-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263901/7b7543fd-760e-5a9b-e400-5420f4b613b8.png)

左下のプラスボタンから項目を追加できます。
まずは `Add Commit Custom Command` を試してみます。
このメニューの場合、コミットを右クリックしたときに現れるコンテキストメニューから起動できるコマンドが作成されます。
![2021-08-14_16-32_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263901/b4a55ec9-63ea-08bb-8c8f-77d6fa2cdc72.png)


追加した直後は以下のような設定となっています。
![2021-08-14_16-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263901/0be3cca0-2f08-bbae-80be-d631b1273a3d.png)

Actionのところをクリックすると実行される処理を変更できます。
まずはサンプルということで、Forkのホームページを開くアクションを設定します。
![2021-08-14_16-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263901/fdfde5f6-437d-a1bc-1a7a-220fd3603ef9.png)

ここまで設定すると、コミットを右クリックしたときにコマンドも表示されるようになります。
実際にこれをクリックするとブラウザから[Forkのホームページ](https://fork.dev/)が開かれます。
※Nameに最初から入力されていた `Revision Custom Command` が表示名として使用されている。
![2021-08-14_16-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263901/73c0bbcc-6196-1b07-4be8-b4f9642e90e7.png)

# 実用的なカスタムコマンドの例
上記では任意のURLを開くカスタムコマンドを定義しましたが、
Actionではgitやその他任意のシェルスクリプトの起動も可能です。

## コミットの取り消し
例えば以下のように設定すると右クリックからコミットを取り消せるようになります。
※どのコミットを右クリックしても実際に取り消されるのは最後のコミットであることに注意してください。
![2021-08-14_16-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263901/ed465135-f9cd-497a-5c82-c822e03ad2a8.png)

参考: [[Git]コミットの取り消し、打ち消し、上書き](https://qiita.com/shuntaro_tamura/items/06281261d893acf049ed)

変更内容を破棄せずに残しておきたい場合もあるので、`--hard` の部分を `--soft` に置き換えたバージョンも定義しておくと便利です。
Kubernetesがわかるようになるためのステップ

# モチベーション
* Kubernetesの記事は数年前と比べてあふれている
* だけど、なんか難しいし、ECSやDocker Composeの方が好きという声が多い
* でもやっぱりKubernetesが好きなので知ってもらいたい

# まずはこの3つを読めばOK（自著）

Kubernetesの代表的なリソースを知り、裏の動作原理を知って、動かしてみるのが良いだろうということで、以下の3つを紹介。

* [Kubernetesの構成要素をWeb3層モデルに無理矢理当てはめる](https://news.mynavi.jp/itsearch/article/devsoft/4097)
 * LB：Service
 * サーバの単位：Docker
 * Webサーバの冗長構成：ReplicaSet
 * 監視：Pod（Side Car）
* [Kubernetesが動く仕組みを知る](https://news.mynavi.jp/itsearch/article/devsoft/4729)
 * Reconciliation Loop
* [Kubernetesを動かす](https://news.mynavi.jp/itsearch/article/devsoft/4252)
 * インストール不要で動かしてみる
   * [Play with Kubernetes classroom](https://training.play-with-kubernetes.com/kubernetes-workshop/)

# その先は？

## 方向性1：CKAD, CKAを取る

言わずもがなKubernetesの代表的な資格Top2。最近はCKNAやCKSも出てきたのでそちらをやってみるのも良い。

### なぜこの資格を取ると良いのか

勉強方法が明確でハズレがない。

以下のUdemyの動画を見て、付属されている無償Kubernetes環境を使ったハンズオントレーニングをすることで、マニュアルの見方、コマンドの打ち方など一通りのことが学べる。

https://www.udemy.com/course/certified-kubernetes-application-developer/

https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/

## 方向性2：Kubernetes Meetup Tokyoの資料を見てみる

2022/8/14時点で291件の資料が載っている。さまざまな方面の資料が載っている。
ガチ勢の方は深く読み込むのが良いし、初学者の方は資料の概要部分を中心に読み漁ってみるのが良いと思う。

https://k8sjp.connpass.com/presentation/

# まとめ・所感

Kubernetesは非常に流行してきている一方で、ハードルが高いのも事実。だからこそ、身につけておくと、市場での価値も高まると考えて、勉強してみるのも一つ。

技術の移り変わりは早いので、表面的なオペレーションを覚えるだけでなく、ネットワークやデータベースなどの比較的足の長い技術を着実に身につけておく必要もあると思う。
mysqli_fetch_assocの使い方について

#独学エンジニア学習(レッスン5)

##疑問に思ったこと
sqlを使用せずにphpのみで読書ログの登録、表示を行っていた時はforeachを使って読書ログの表示を行っていた。そこでsqlをからデータを抽出してログを表示させるときもforeachを使ってもできるのではないかと思った。しかし、foreachでやろうとするとデータが1つしか表示できなかった。
下記のようなイメージ↓

```php
    $sql_log = 'SELECT * FROM logs';

    $results = mysqli_query($link, $sql_log);

    $logs = mysqli_fetch_assoc($results);

    foreach ($logs as $log) {
        echo '書籍名：' . $log['title'] . PHP_EOL;
        echo '著者名：' . $log['author'] . PHP_EOL;
        echo '読書状況：' . $log['status'] . PHP_EOL;
        echo '評価：' . $log['score'] . PHP_EOL;
        echo '感想：' . $log['imp'] . PHP_EOL;
        echo '-------------' . PHP_EOL;
    }
```

この記述をすると初めの一つのデータしか抽出されなかった。
![Qiita](https://dotup.org/uploda/dotup.org2561582.png)

```php
    var_export(mysqli_fetch_assoc($results));
```
してみると、
![Qiita](https://dotup.org/uploda/dotup.org2561590.png)
1個目のデータしか取得できていなかった。foreach使う場合はこの$logsの中に全部の配列が入っていないと繰り返しはできないから1個目の表示しかされなかったという風に解釈した。

結局動画で取り扱っていた通りのwhile文で実装
mysqli_fetch_assoc自体を繰り返さないといけなかった。

```php
    $sql_log = 'SELECT * FROM logs';

    $results = mysqli_query($link, $sql_log);
    
    while ($log = mysqli_fetch_assoc($results)) {
        echo '書籍名：' . $log['title'] . PHP_EOL;
        echo '著者名：' . $log['author'] . PHP_EOL;
        echo '読書状況：' . $log['status'] . PHP_EOL;
        echo '評価：' . $log['score'] . PHP_EOL;
        echo '感想：' . $log['imp'] . PHP_EOL;
        echo '-------------' . PHP_EOL;
    }

```


##phpでの関数

__mysqli_query__：データベース上でクエリーを実行(関数)、実行したらmysqli_resultオブジェクトを返す。
__mysqli_fetch_assoc($result)__：結果の行を連想配列で取得。$resultはmysqli_resultオブジェクト
__mysqli_free_result__：結果で使用したメモリを開放する。これを実行しないと負荷が重くなるので基本やる。

```php
    $result = mysqli_query($link, $sql);

    //tureとfalseで返ってくるのでその結果に合わせてif文を使用
    if ($result) {
        echo 'データを追加しました' . PHP_EOL;
    } else {
        echo 'Error：データの追加に失敗しました' . PHP_EOL;
        echo 'Debugging error； ' . mysqli_error($link) . PHP_EOL;
    }

    //上記の$resultの結果を使用して実行(while文などで配列の中身を取り出したりできる)
    mysqli_fetch_assoc($result);

    while ($company = mysqli_fetch_assoc($results)) {
        echo '会社名；' . $company['name'] .PHP_EOL;
        echo '代表者名；' . $company['founder'] .PHP_EOL;
    }

    //メモリの解放
    mysqli_free_result($result);
```

__mysqli_connect__：sqlとの接続を行う

```php
    mysqli_connect(string $host, string $username, string $passwd, string $dbname);
```

__mysqli_close__：sqlとの接続を切断

```php
    mysqli_close($hoge);
```

###バリデーションで使用した関数
__strlen__：文字数をカウント
__in_array__：特定の文字列を含んでいるか判定

```php
    strlen($hoge)

    $status = [
        '未読',
        '読んでる',
        '読了'
    ];

    if (!in_array($log['status'], $status, true)) {
        $errors['status'] = '読書状況は未読、読んでる、読了のいずれかを入力してください';
    }
```

##SQLでの関数

##知識

・コードエディタ上で複数行での記述の行い方(EOTの部分がキー)

```php
    $sql = <<<EOT
    INSERT INTO logs (
        ...
    ) VALUES (
        ...
    )
    EOT;
```

・sql上で日本語が文字化けしないための記述(ググって出てきたやつだからこれが最適な書き方かどうかは不明)

```php
    $link = mysqli_connect('db', 'book_log', 'pass', 'book_log');
    $link->set_charset('utf8');
```
VBA のヒアドキュメント風 JSON チックコンフィグ 

# これは何
いろいろ設定をいじって動かしながら VBA を書いてるんだけど、VBA じゃ連想配列のリテラルを書くのもつらい。ってことで、JSON チックにコンフィグを書けるといいな、と思ったり、ヒアドキュメント風に書けたら VBE だけで開発できていいな、と思ったり。ということで、今現在、開発に使っている、コンフィグの使いかたをメモしておこう的なものがこの記事。

# 要求と解決策と実際の記述例

<dl>
<dt>JSON っぽく、配列や連想配列も書きたい </dt>
<dd>[VBA-JSON](https://github.com/VBA-tools/VBA-JSON) で。長年の VBA における JSON 難民には嬉しいですね。VBA-JSON。</dd>
<dt>VBE で完結させたい (コンフィグを別ファイルにしない)</dt>
<dd>VSCode の拡張機能で XVBA というのがあって、VBE 外で開発できるかも、期待したけど、今書いてるの、Excel VBA じゃなくて Publisher VBA なんですよね。なんで、コンフィグ書くのも VBE で完結できると嬉しい。本当は VSCode で書きたいのよ。</dd>
<dt>設定以外の文字列があまりないようにしたい</dt>
<dd>ヒアドキュメントがサポートされていない、複数行にわたる文字列が書けない、`&=` って表記もない VBA の制限の中で、設定を記述しているところに他の文字列があまり出現しないようにしたい。
結局、中で VBA-JSON を使う `Config` クラスを作ってみました (後述)。</dd>
<dl>

次に、コンフィグの実例を示します。

```vb:Module1.bas
Public Function getConf() As Object
    Dim c As New Config
    
    c.a "{"
    c.a " deck: {"
    c.a "   top: 7, left: 7 "
    c.a " },"
    c.a " card: {"
    c.a "   size: 90, gap: 5 "
    c.a " },"
    c.a " chars: [[_莨_, _たばこ_ ], [_藜_, _あかざ_ ],   [_菱_, _ひし_ ], [_莠_, _えのころぐさ_ ] ,"
    c.a "         [_蕨_, _わらび_ ], [_艾_, _もぐさ_ ],   [_蓼_, _たで_ ], [_苓_, _みみなぐさ_ ],"
    c.a "         [_葎_, _むぐら_ ], [_菘_, _すずな_ ],   [_蒜_, _ひる_ ], [_茆_, _じゅんさい_ ],"
    c.a "         [_菫_, _すみれ_ ], [_苧_, _からむし_ ], [_蕪_, _かぶ_ ], [_蕣_, _あさがお_ ],"
    c.a "         [_薊_, _あざみ_ ], [_萍_, _うきくさ_ ], [_芹_, _せり_ ], [_茅_, _かや_ ]],"
    c.a " dish: {"
    c.a "   holeSize: 0.19, traySize: 0.22, mealSize: 0.20 "
    c.a "   pairs: ["
    c.a "     { x: 0.2,  y:-0.01, z:0 }, { x: 0.38, y:-0.12, z:1 }, { x:-0.35, y: 0.36, z:1 },"
    c.a "     { x: 0.36, y: 0.34, z:0 }, { x:-0.2,  y: 0.23, z:0 }, { x:-0.06, y: 0.38, z:1 },"
    c.a "     { x: 0.03, y: 0.19, z:1 }, { x: 0.37, y: 0.13, z:0 }, { x: 0.16, y: 0.38, z:1 }"
    c.a "          ]"
    c.a " }"
    c.a "}"
    
    Set getConf = c.Value
End Function
```

# `Config` クラス

```vb:Config.cls
Private mBuffer As String

Private Sub Class_Initialize()
    mBuffer = ""
End Sub

Public Function a(str As String) As Config
    mBuffer = mBuffer & str
    Set a = Me
End Function

Public Property Get Value() As Object
    Dim reg As Object: Set reg = CreateObject("VBScript.RegExp")
    With reg
        .Pattern = "([a-zA-Z0-9]+)([ ]*)(?=:)"
        .IgnoreCase = False
        .Global = True
    End With
    Dim str As String: str = reg.Replace(Replace(mBuffer, "_", """"), """$1""")
'    Debug.Print str
    Set Value = JsonConverter.ParseJson(str)
End Property
```

工夫している点は、次のとおり。
* JSON の組立てを、`c.a "[1, 2, 3]"` とか書けるようにしている。文字列変数 `s` を用いて ` s = s & "[1, 2, 3]"` とか書かなくてよい。
* VBA の文字列としてダブルクォーテーションはダブルクォーテーションでエスケープしなくてはならくて辛いので、ダブルクォーテーションの代わりにアンダースコアを使ってもいいようにした。つまり、JSON として `{ "name": "Candy" }` と表現しなければならない場合、VBA の文字列リテラルとしては `{ ""name"": ""Candy"" }` と書かなければならないわけだけど、タルいので `{ _name_: _Candy_ }` と書いてもいいようにした。(`Replace()` 関数を使うだけ)
    * 連想配列のキーはダブルクォーテーションで括らなくてもいいようにした。`{ name: _Candy_ }` と書ける。(`RegExp.Replace()` を使用)

# 追記 (2021-08-14 21:36)
VBA-JSON 自体に `AllowUnquotedKeys` オプションがある模様。
【データベース】DBMS・正規化・3層スキーマ

SQLを使う前に、データベースについての根本的な知識も重要だと感じたので、備忘録として残しておこうと思う。

##DBMS（データベース管理システム）と関係データベース
DBMSは、データベースの定義・操作・制御などの機能をアプリケーションから簡単に扱えるようにした**ミドルウェア**。

データベースにはいくつか種類があり、代表的なものに「関係型」「階層型」「ネットワーク型」があり、現在は「**関係型**」と呼ばれるものが主流に使われている。


##表を分ける「正規化」
関係データベースでは、データに矛盾や重複が発生しないように表を最適化する。このときに表を分割することを**正規化**と呼ぶ。
以下のような段階を経て正規化を行い、表が最適化される。

####非正規形の表
表の中に繰り返し部分があり、各レコードの長さがバラバラな状態。

####第1正規形の表
非正規形の表から、繰り返しの部分を取り除いた状態。（切り離したデータを、それぞれ独立したレコードとして挿入する。）

#####<font color="MediumBlue">（第2正規形の前に・・・）　関数従属と部分関数従属について</font>
**関数従属**
主キーが決まれば、列の値が一意に定まる関係のこと。
｟例｠
・社員番号（主キー）が決まれば、名前が決まる
・学年・クラス・出席番号（主キー/複合キー）が決まれば、名前が決まる

**部分関数従属**
複合キーの一部の項目だけで、列の値が一意に定まる関係のこと。
｟例｠
主キーは受注NOと商品コードの複合キーとする
・受注NOが決まれば、受注日付・顧客名が決まる
・商品コードが決まれば、商品名・単価・数量が決まる


####第2正規形の表
部分関数従属している列を切り出した状態。

####第3正規形の表
第2正規形の表から、主キー以外の列に関数従属している列を切り出した状態。

##関係演算とビュー
データに矛盾や重複が生じないように正規化することが重要な一方、分割されすぎるとデータを活用しにくくなってしまう。
そこで効率的にデータを活用するため、表の中から特定の行や列を取り出したり、表と表を結合して新しい表を作り出したりする演算を行う。
このような表操作を**関係演算**といい、**「選択」「射影」「結合」**などがある。

・**選択**
表の中から特定の条件に合致する行だけを取り出す演算。

・**射影**
表の中から特定の条件に合致する列だけを取り出す演算。

・**結合**
2つの表の中にある共通の列を介して、表と表をつなぎ合わせる演算。

このように、関係演算を用いて仮想的に作る一時的な表のことを**ビュー
表**と呼ぶ。

##3層スキーマ構造
スキーマとは、概要・要旨という意味を持つ言葉で、データベースの構造や使用を定義するもの。
標準的に使用されている規格では、**3層スキーマ構造**をとっている。

・**外部スキーマ**
3層のうち、一番外向き（プログラム寄り）の層。
利用者の必要とするデータの見方を表現する。
｟例｠ビュー表

・**概念スキーマ**
3層のうち、中間層。
データの論理的関係を表現する、データベース本体。プログラムからもハードウェアからも切り離されており、データの独立性を保っている。
｟例｠表の定義

・**内部スキーマ**
3層のうち、一番内向き（ハードウェア寄り）の層。
データを物理的にどう記憶させるかを定義している。
｟例｠データを記憶させるハードウェアの変更

このように3層に定義を分けることで、データの独立性を保っている。



<br><br>
####引用・参考文献
https://gihyo.jp/book/2019/978-4-297-11021-5

https://www.udemy.com/course/lerning-fe/?utm_source=adwords&utm_medium=udemyads&utm_campaign=LongTail_la.JA_cc.JP&utm_content=deal4584&utm_term=_._ag_107996380920_._ad_537567317193_._kw__._de_c_._dm__._pl__._ti_dsa-1219013026218_._li_1009507_._pd__._&matchtype=b&gclid=CjwKCAjw092IBhAwEiwAxR1lRjLg6hdV4PmHzAK_DKR1ijHrKd1nrGngvFoeguLIP5uv2cYDy1k4-BoCILkQAvD_BwE
抑えておきたいリーダブルコード


この記事はプログラミングの実務経験と『リーダブルコード』を照らし合わせ、
これだけは抑えておきたいと思った項目をピックアップしています。

<img width="200px" alt="readablecode" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620908/48f646f8-43b3-5878-3668-666998973f43.png">

# 抑えておきたいこと

## 他人が理解しやすいコードを書く

常に「他人が理解しやすいコード」を意識する。

これは１章に書いており、本書の核となっています。
他章はこの核をもとに、具体的な事例に落とし込んでいます。
「他人が理解しやすいコード」は、プログラミングをする上で最も重要であり、意識し続ける必要があります。

##名前に情報を詰め込む
見ただけで処理の内容が伝わるよう意識します。

１度決めた名前は後から中々変えづらいため、慎重に命名する必要があります。
また、プロジェクトが進むにつれて、追加機能や機能変更が発生することがあります。

Ex.)ボールを蹴るメソッド
→shoot?pass?kick?
Ex.)サッカーボールだけでなくラグビーボールも蹴れるようにしたい（追加開発）
→kickBallに決めてたのに、、、

このような場合は、以下のような対策をしてください
・開発チームに命名規則を伝える
・configに書く
・クラスやメソッドにコメントを書く
など。
余裕があればリファクタリングしてください。

##インシデントを整えることで可読性が増す

インシデントルールがメンバによって異なる場合、可読性が落ちます。
エディタを活用し、インシデントを整理してからgitに上げるようにしましょう。

##スネークケースとキャメルケース

本書には載っていない項目です。
どちらを利用するかはプロジェクトによると思います。（あるいは言語ごとの慣習がある）
私がやっているLaravelでの開発では、キャメルケースを基本としています。


##複雑な処理についてはコメントを入れる
読み手が質問しそうなことを考えます。
・処理の内容
・経緯
・欠陥
・自分の考え

全てを書く必要はありません。（コードですぐにわかることは書かない）

##ループと条件式の単純化
ネストが深くなるにつれ可読性が落ちます。
私のプロジェクトでは2階層までとしています。

複雑な条件式を無理やり１行まとめると、可読性が落ちます。
（正直、三項演算子は読みにくい）

ケースバイケースですが、初心者にもわかるように意識してほしいです。

##感想
###リーダブルコードは全てのビジネス文書に通づる。
最初に書いた「他人が理解しやすいコードを書く」は、ビジネスにおけるメールやドキュメントにも言えることです。
リモートワークが増えた今、文章は「能力や性格」を表現するものとなっています。
読みにくい、誤字が多い、というだけで評価が下がることもあります。
逆にいうと、伝わる文章を書くだけで、評価が上がり、ビジネスが円滑に進んで行きます。
それだけ重要あり、ビジネスの基本なのです。

###動くのは当たり前
疲れていたり、納期が迫っていたりすると、
動けばいいや〜と思いがちです。
ですが、プロとして、
「動くのは当たり前」という心構えを常に持つことが重要だと思います。
AWSデプロイ後、we are sorry...のエラー画面が出てしまった

![エラー画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727249/4343cc80-d1f6-a629-79c3-bdca38710ba5.png)

### AWSでデプロイ後、エラー画面が出てしまった。


### 解決した方法
色々試してみたが
githubの内容をEC2へ反映させ、プロセスを確認、プロセスのkill、再起動で解決出来た。

```terminal
①  git pull origin master
②　　　　ps aux | grep unicorn
③  kill プロセス番号 (unicorn_rails masterと書かれている一番上の行の左から二番目の5桁の数字)
④　　　RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
```
Song Maker を MIDI に接続する

(夏休み企画 7/20)

「Song Maker - Chrome Music LabSong Maker - Chrome Music Lab」
https://musiclab.chromeexperiments.com/Song-Maker

マウスでなぞるだけで音が鳴る音楽エデュケーションアプリ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2bdb25dd-e103-4b74-066d-ab9d1c7bcb8d.png)

Midiボタンを押すと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ee6dab8f-920d-f322-7f86-9a9ecb7c98a0.png)

MIDI キーボードにつながるようだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c11c44a0-2741-c470-535e-633a82d9b237.png)



「MIDI 仮想キーボードと物理キーボードを Ubuntu で試す」
https://qiita.com/nanbuwks/items/055cffd9beb2caf4acb0

で取り上げた vkeybd を起動してキーボードを押してみました。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3ebf82d6-70fa-db9d-8675-0dfb017ca654.png)

特に設定無くてもキー入力がインプットとして Song Maker に入力できました。

MIDIインプットデバイスが使えるようです。

先の記事の「MIDI 物理キーボードを接続する」でためした物理キーボード、CASHIO LK-80も同様に調子よく接続できました。
Kaspersky のうざい通知を消す

# これはなに

Firefox とか Chrome を立ち上げた時に Kaspersky Internet Security がしょーもない通知を出すのを黙らせます。

# TL;DR

設定 → インターフェイス → 通知の設定 でどの通知を出すか個別に選べる

# 操作方法

設定から「インターフェイス」を選び、「通知の設定」を選ぶ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992/87f39d2c-c3ef-116b-f22c-73cf7dc1ce28.png)

「システム監査」項目の下の方に「Google Chrome を利用されていますか？」などの項目があるので、この部分のチェックを外す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992/5d0bc4ed-dd48-7646-8c1b-19725f16d565.png)

まぁ今時 Windows のビルトインで十分な性能が出ており、 Kaspersky 入れてる人も少ないとは思いますが、ご参考まで。
TableView Cellにチェックマークなどを表示する(.accessoryType)　

#今回の内容

* `.accessoryType`を用いてTableViewのCellにチェックマークなどを表示する。

# コードと簡単解説

## .accessoryType = .checkmark 

<img width="150" alt="66E4123C-F50A-4094-9B3C-81AA0814D914_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/6426718c-fe3d-49b3-27e5-394b52b54ed8.jpeg">

* `func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}`内でindexPathからタップされたCellを取得します。
  
*  `cell?.accessoryType = .checkmark `でタップされたCellにチェックマークを表示します。

```Swift:
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let cell = tableView.cellForRow(at: indexPath)
        
        cell?.accessoryType = .checkmark  //チェックマーク
     
    }
```

## .accessoryType = .detailButton

<img width="150" alt="E6B9FC7F-EB38-4242-9B4F-72648226CECE_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/f0f664b1-3b80-d2e8-7abb-fb43dda697ee.jpeg">

```Swift:
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let cell = tableView.cellForRow(at: indexPath)
        
        cell?.accessoryType = .detailButton
     
    }
```

## .accessoryType = .disclosureIndicator

<img width="150" alt="A3897341-6011-4620-BB74-7B2F89519024_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/f9c1a301-ceb2-1d8f-ce4f-c4009b93c82c.jpeg">

```Swift:
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let cell = tableView.cellForRow(at: indexPath)
        
        cell?.accessoryType = .disclosureIndicator
     
    }
```

## .accessoryType = .detailDisclosureButton

<img width="150" alt="300CFDAD-0DC6-4D1C-A3FF-83FE3C46EE1D_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/014177fe-b9db-e077-dc27-9200e0449762.jpeg">

```Swift:
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let cell = tableView.cellForRow(at: indexPath)
        
        cell?.accessoryType = .detailDisclosureButton
     
    }
```

#終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
Spring BootのjarをDocker上で動かすまで

# はじめに
Docker上でSpring Bootのjarを動かすための備忘録。[公式](https://spring.pleiades.io/guides/gs/spring-boot-docker/)にも書いてあるけど自分用に念のため検証した。

# 環境
- Docker 20.10.8, build 3967b7d
- Spring Boot 2.5.3
- Openjdk 11

# 内容
## アプリケーション側
検証用なので文字列返すだけ。 コマンドでもIDEでもいいからビルドしてjarを作っておく。

``` java
@Controller
@RequestMapping("/demo")
public class ContainerdemoController {

    @GetMapping
    @ResponseBody
    public String demo() {
        return "sample";
    }
}
```

## Dockerfile
Openjdk11指定で `JAR_FILE` 相対パスのjarを `app.jar` としてコピー。
最後にENTRYPOINTで `java -jar /app.jar` を指定して実行。

``` Dockerfile
FROM openjdk:11
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
```

## コンテナビルド&立ち上げ

下記コマンドで `containerdemo` のタグをつけてイメージビルド完了。

``` bash
docker build -t containerdemo .
```

``` bash
docker build -t containerdemo .
[+] Building 2.0s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 144B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/openjdk:11                                                      1.9s
 => [internal] load build context                                                                                  0.0s
 => => transferring context: 89B                                                                                   0.0s
 => [1/2] FROM docker.io/library/openjdk:11@sha256:369854afc795005451787f24e455daa8f409ecf3b1f67c3c1395359adf1234  0.0s
 => CACHED [2/2] COPY target/*.jar app.jar                                                                         0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:97ebdd9191f5a9aa77b8f6396986e4023b6119d59692f613691314d2aa0a1234                       0.0s
 => => naming to docker.io/library/containerdemo                                                                   0.0s
```

下記コマンドでホスト側のポート9999とコンテナのポート8080をポートフォワーディングして実行することで立ち上げまで完了。

``` bash
docker run -p 9999:8080 containerdemo
```
コンテナ側で8080ポートで立ち上がるアプリケーションに `localhost:9999` でアクセスできていることを確認できる。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212284/f7e2cb08-2feb-0d78-5cf9-9dfb80308b8d.png)

おわり。