OmniAICreator/Qiita-1.07M huggingface dataset:
Remote ContainerのlocalhostへのアクセスがERR_EMPTY_RESPONSEを返す

VSCodeのRemote Containerで[php-apacheイメージ](https://hub.docker.com/_/php)を利用したところ、localhostへのアクセスが`ERR_EMPTY_RESPONSE`を返しました。ポートなどの設定も見直しました（[docker上のアプリにlocalhostでアクセスしたらERR_EMPTY_RESPONSEが出る](https://qiita.com/amuyikam/items/01a8c16e3ddbcc734a46#comments)）が問題がなく悩みました。

## 環境
- Windows10 WSL(Ubuntu 20.04)
- Docker Desktop for Windows
- VSCode 1.52.1(Nov 2020)

## 原因
Apacheのサービスが起動していませんでした。
コンテナ内で下記コマンドによりサービスの起動を確認したところ、apache2が起動していないことが分かります。

```console
$ service --status-all
 [ - ]  apache-htcacheclean
 [ - ]  apache2
 [ ? ]  hwclock.sh
 [ - ]  procps
```

WSLから`docker run`した場合は自動的に起動していたので、Remote Containerでも起動しているものだと思っていました。

## 解決法
`devcontainer.json`でコンテナ起動後にデフォルトのコマンド（Apacheの起動コマンド）が実行されるように指定する必要があります。

```diff:devcontainer.json
{
	"build": {
		"dockerfile": "Dockerfile"
	},
	"mounts": [
		"source=${localWorkspaceFolder}/public,target=/var/www/html,type=bind,consistency=cached"
	],
	"forwardPorts": [80],
+	"overrideCommand": false
}

```

`overrideCommand`はデフォルトでは`true`であり、コンテナ既定のコマンドの代わりに`/bin/sh -c "while sleep 1000; do :; done"`を実行するとされています（[devcontainer.json reference](https://code.visualstudio.com/docs/remote/devcontainerjson-reference)）。これを`false`にすることでコンテナ既定のコマンドが起動時に実行されるようになります。

上記はDockerfileを利用した構成ですが、Docker Composeの場合は必須のserviceプロパティがあるのでそれが利用できます。
ちなみに、Dockerfileは下記のようになります。

```dockerfile
FROM php:7.4.7-apache

EXPOSE 80

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
      git \
      vim \
      unzip \
      libonig-dev \
      libzip-dev \
      libfreetype6-dev \
      libjpeg62-turbo-dev \
      libpng-dev \
      libwebp-dev && \
    docker-php-ext-configure gd --with-jpeg --with-webp --with-freetype && \
    docker-php-ext-install -j$(nproc) \
      mbstring \
      zip \
      gd \
      exif && \
    # reduce image size
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

COPY --from=composer /usr/bin/composer /usr/bin/composer

COPY --from=node /usr/local/bin/ /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules

RUN a2enmod rewrite headers
```

## 補足
`overrideCommand`を変更する以外の方法として、明示的にApacheを起動するコマンドを指定することもできます。この場合は`devcontainer.json`に

```
"postStartCommand": "service apache2 start"
```

を追加します。

## 参考
- [devcontainer.json reference](https://code.visualstudio.com/docs/remote/devcontainerjson-reference)
条件分岐 (if, case),  Array.each 



# 条件分岐 (if)


## if-elsif-else文の記述方法

```ruby
if 式 [then]
  式 ...
[elsif 式 [then]
  式 ... ]
...
[else
  式 ... ]
end
```

C 言語とは違って else if ではなく elsif であることに注意

then は省略可


## お題 (うるう年の判定)

うるう年を判定する check\_leap\_year.rb を作成する.

うるう年とは

    1. 4で割り切れる年
    2. 100で割り切れる年はうるう年ではなく, 400で割り切れる年はうるう年


## 解説:if-elsif-else-if

まずは簡単に2004年はうるう年か

```ruby
p year = ARGV[0].to_i
if year % 4 == 0
  p true
end
```

のように書ける

    > ruby check_leap_year.rb 2004
    2004
    true

次に1999年はうるう年でないのでfalseを返すようにする

```ruby
p year = ARGV[0].to_i
if year % 4 == 0
  p true
else
  p false
end
```

これでfalseが出力されるようになったが, 1900年はどうだろうか

    > ruby check_leap_year.rb 2004
    1900
    true

1900年は100で割り切れるのでうるう年でないから条件式を追加する

```ruby
p year = ARGV[0].to_i
if year % 100 == 0
  p false
elsif year % 4 == 0
  p true
else
  p false
end
```

    > ruby check_leap_year.rb 2004
    1900
    false

このままだと400で割り切れる年もfalseとなってしまうのでもう一つ条件式を追加する

```ruby
p year = ARGV[0].to_i
if year % 400 == 0
  p true
end
elsif year % 100 == 0
  p false
elsif year % 4 == 0
  p true
else
  p false
end
```

    > ruby check_leap_year.rb 2004
    2000
    true

これでOK

しかし引数でいちいち打ち込むのはめんどくさい

そこで次のArray.eachを使う


# Array.each


## お題:テストの自動化

配列にしてループで回すだけ

```ruby
[2000, 1900, 2004, 1999].each do |year|
p year
if year % 400 == 0
  p true
end
elsif year % 100 == 0
  p false
elsif year % 4 == 0
  p true
else
  p false
end
```

このように書くと

    > ruby check_leap_year.rb 2004
    2000
    true
    1900
    false
    2004
    true
    1999
    false

と出力される


## メソッドにしよう

関数名を leap? とする

```ruby
def leap?(year)
  if year % 400 == 0
    p true
  end
  elsif year % 100 == 0
    p false
  elsif year % 4 == 0
    p true
  else
    p false
  end
end

[2000, 1900, 2004, 1999].each do |year|
  p year
  leap?(year)
end

```

このように書くと

    > ruby check_leap_year.rb 2004
    2000
    true
    1900
    false
    2004
    true
    1999
    false

同じ出力になることを確認


# 条件分岐 (case)

case を使うともっと綺麗になる


## case 文の記述方法

```ruby
case [式]
[when 式 [, 式] ...[, `*' 式] [then]
  式..]..
[when `*' 式 [then]
  式..]..
[else
  式..]
end
```


## お題:case

先程のifのプログラムをcaseのプログラムに変更すると

```ruby
def leap?(year)
  return case
  when year % 400 ==0 ; true
  when year % 100 ==0 ; false
  when year % 4 ==0 ;   true
  else ;                false
  end
end

[2000, 1900, 2004, 1999].each do |year|
  p year
  p leap?(year)
end
```

となり, 出力を確認すると

    > ruby check_leap_year.rb
    2000
    true
    1900
    false
    2004
    true
    1999
    false


# おまけ (三項演算子)

三項演算子は if をもう少しスマートに書ける.

    条件式 ? (真の場合) : (偽の場合)

という風に書く

```ruby
def leap?(year)
  return (year % 400 == 0) ? true :
	   (year % 100 == 0) ? false :
	     (year % 4 == 0) ? true : false
end

[2000, 1900, 2004, 1999].each do |year|
  p year
  p leap?(year)
end
```


# 参考ページ

[チャート式ruby-III(if, case, Array.each by leap year)](https://qiita.com/daddygongon/items/a550bde1ed6bff5217d8)



------
 - **source** ~/grad_members_20f/members/djj31370/c3_if_case_leap_year.org
PHPのページ遷移で<form>タグを1つにまとめる方法

お疲れ様です！TaYです:open_hands:

今PHPでECサイトを製作中で、商品の一覧ページから編集、削除、追加などをできるボタンを設置しています。

![スクリーンショット 2020-12-29 15.24.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/957298/932bfa9d-1b1e-9f08-7896-7b7a4c7d7585.png)
↑こんな感じ

通常ボタンを使う場合はボタン1つにつきformタグ1個が定番ですが、このように何個もボタンを追加するとその都度formタグをかかなければなりません:sweat:

```php:sample_1.html

<input type="radio" name="code" >
<form method="post" action="sample_2.php">
<input type = "submit" value="参照">
</form>
<form method="post" action="sample_3.php">
<input type = "submit" value="追加">
</form>
<form method="post" action="sample_4.php">
<input type = "submit" value="編集">
</form>
<form method="post" action="sample_5.php">
<input type = "submit" value="削除">
</form>

```
面倒だしコードもごちゃごちゃして見づらいですよね。

そこで、これらのページの分岐ページを作ってあげます！

```php:sample_1.html

<form method="post" action="sample_branch.php">
<input type = "submit" name="display" value="参照">
<input type = "submit" name="add" value="追加">
<input type = "submit" name="edit" value="編集">
<input type = "submit" name="delete" value="削除">
</form>

```
```php:sample_branch.php
<?php
if(isset($_POST['display']) == ture){
  header('Location: sample_2.php');
  exit();
}

if(isset($_POST['add']) == ture){
  header('Location: sample_3.php');
  exit();
}

if(isset($_POST['edit']) == ture){
  header('Location: sample_4.php');
  exit();
}

if(isset($_POST['delete']) == ture){
  header('Location: sample_5.php');
  exit();
}
?>

```
処理の流れとしては
①：sample_branch.phpがsample_1.phpからname情報を受け取る。
②：①で受け取った情報をif文で判定し、任意のページにとばしてくれる。
という仕組みです。

こうするとコードがスッキリしますね！

ちょっとしたことですが、覚えておくとどこかで役に立つかも知れませんね！


それでは今回はこのへんで:wave:
PythonとRDKitでアミノ酸配列から環状ペプチドを生成してみる

#はじめに
掲題の件を実現するにあたって、CycloPsというライブラリを見つけたので今回試してみた。

#環境
- Python3.x
- RDKit 2020.X
- CycloPs

#CycloPsとは
アミノ酸配列から環状ペプチドのバーチャルライブラリを生成してくれるツールである。
1次元のアミノ酸配列から、残基同士を結合することで、環状のペプチドを生成してくれる。
GUIとコマンドラインの両方で使える。
詳しくは参考文献の論文を参照のこと。


残基同士を結合するパターンは次の5種類である。それぞれ細かい条件があるようなので詳しくは論文を見てほしい。

- head-to-tail bond 
  アミノ酸配列のC端とN端を結合する。
- disulfide bond
　システイン残基同士を結合する。
- side-chain to side-chain bond
　側鎖同士を結合する。
- side-chain to N-terminal bond
　側鎖とN端を結合する
- side-chain to C-terminal bond
　側鎖とC端を結合する

#CycloPsのインストール

元々はPython2系で開発されているが、自分の環境だとRDkitがうまく動作しなかったため、3系でイントールする。


```sh
　$ conda create -n cyclops python==3.6
　$ conda activate cyclops
　$ conda install -c rdkit rdkit
  $ git clone https://github.com/fergaljd/cyclops.git
```

#インストール後の作業
Python3系ではCycloPsが動作しないためソースを修正する必要がある。今回は、コマンドラインのみ使えればよい。
そこで ``` PepLibGen/StructGen/StructGen.py ``` を以下の通り修正することで、Python3でも動作するようにする。

###修正内容
- print a, b のような記載を print(a,b) のように修正する。
- Except a, b のような記載を Except a as b のように修正する。
- 940行目あたりでエラーが出るため、以下のように修正する

```
            # print(out,mollstr)
            # print(out, '$$$$')
            out.write(molstr)
            out.write('$$$$')
            out.write('\n')
```
- その他実行時エラーとなるところを、Python3で動作するよう修正する(手抜き)。

#実行例
[CPPsite 2.0](https://webs.iiitd.edu.in/raghava/cppsite/index.html) に登録されている環状ペプチドのアミノ酸配列と出力SDFを指定して実行する。
するとSDFに、5種類のパターンにより生成された環状ペプチドのリストが出力される。
以下実行例である。

```sh
python PepLibGen/StructGen/StructGen.py CSKSSDYQC hoge.sdf
```

#実行結果例
アミノ酸配列 "CSKSSDYQC" を指定して得られた6つの構造を以下に列挙する。

###1番目
これは線形タイプである。環状ではないものも出力される仕様のようである。
![CSKSSDYQC.mol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/52152122-b380-3ab5-1aab-3cd6e6c43ab4.png)

###2番目
これはN端とC端をつなげたものか。
![CSKSSDYQCHT.mol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/ce808466-d392-69ea-e4fe-198f068fd36e.png)

###3番目
これは末端と側鎖か。
![CSKSSDYQCSCXEXXXXXXX.mol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/12b0a8a7-0056-5381-b620-973b6847838e.png)

###4番目
これは側鎖同士か。
![CSKSSDYQCSCXEXXXZXXX.mol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/a73c33dd-ba72-2dee-80ea-626faa162e5a.png)

###5番目
これは側鎖同士か
![CSKSSDYQCSCXXXXXZXXX.mol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/8249aefa-15e2-e983-bb19-da67c89fe1b1.png)

###6番目
これはシステイン残基同士の結合だろう。
![CSKSSDYQCSSCXXXXXXXC.mol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/272c4224-25ce-f1f7-52fc-6637c8a5c5ed.png)

#参考
- [CycloPs: generating virtual libraries of cyclized and constrained peptides including nonnatural amino acids](https://pubmed.ncbi.nlm.nih.gov/21434641/)
- [CycloPs: A Cyclic Peptide Library Generator](https://github.com/fergaljd/cyclops)
- [CPPsite 2.0](https://webs.iiitd.edu.in/raghava/cppsite/index.html)
Apache httpdでsatisfy anyを使うと一部ファイルへのアクセス制限が外れる仕様がある

# 確認方法
Apache 2.4の環境において、``AllowOverride FileInfo``などで.htaccessを有効にした状態で、以下のような設定をする。この設定では、特定のネットワーク内からだと認証無し、それ以外からはShibboleth認証をした場合にウェブページが閲覧できるようになる。

```apache:.htaccess
Satisfy any

Order deny,allow
Deny from all
Allow from 192.168.0.0/24

AuthType shibboleth
Require shib-session
```

ただし、この場合許可されたIPアドレスの範囲（192.168.0.1など）から当該ディレクトリにアクセスした際、URIを指定することで.htaccessの内容が閲覧できるようになっている。
上記設定だと特に見られても問題なさそうではあるが、設定によっては致命的となりうる。

たとえば以下の場合、不用意にも.htpasswdをドキュメントルート配下に設置しているため、.htaccessを見た後に.htpasswdをウェブブラウザで見ることができ、ユーザ名とパスワードハッシュが漏洩する。

```apache:/var/www/html/.htaccess
Satisfy any

Order deny,allow
Deny from all
Allow from 192.168.0.0/24

AuthType basic
AuthUserFile /var/www/html/.htpasswd
AuthGroupFile /dev/null
AuthName "Authentication required"
Require valid-user
```

もしBASIC認証にLDAPを利用していた場合は、バインドユーザの情報が漏洩することになる。

# 対応方法
httpd 2.2互換の記述方法ではなく、httpd 2.4標準の``RequireAny``を使う。

```apache:.htaccess
<RequireAny>
   Require all denied
   Require ip 192.168.0.0/24

   AuthType shibboleth
   Require shib-session 
</RequireAny>
```

# 補足メモ
* ググってみると本現象について簡単に触れているものはあったが、半ば常識なのか詳細な解説は見られなかった。バグでは無く仕様っぽい。
* 恐らく``/etc/httpd/conf/httpd.conf``で、.ht*に対してアクセスできないよう設定されているディレクティブが上書きされてしまうため、このような現象となると思われる。
* CentOS 7で確認したが、httpd 2.4.46をソースからビルドしても同様となった。
* 許可されたIPアドレスからアクセスした場合のみ.ht*にアクセス可能、認証した場合は.ht*にはアクセスできない（許可されたIPアドレスであっても）。
MYSQLで分析関数(ROW_NUMBER, DENSE_RANK, RANK)を使わずに連番を振る 

# はじめに
このようなテーブルに対して点数の昇順に連番を振る

|氏名|点数|
|----|----|
|佐藤|80|
|鈴木|70|
|高橋|90|
|田中|80|
|山田|80|

# スキーマ

```sql
CREATE TABLE 成績表(氏名 varchar(4), 点数 int);
INSERT INTO 成績表(氏名, 点数)
VALUES ('佐藤', 80),
       ('鈴木', 70),
       ('高橋', 90),
       ('田中', 80),
       ('山田', 80);
```

# 分析関数の場合

## ROW_NUMBER

```SQL
SELECT ROW_NUMBER() OVER(ORDER BY 点数) AS 番号
     , Z.*
  FROM 成績表 AS Z;
```

実行結果

| 番号 | 氏名 | 点数 |
| ---- | ---- | ---- |
| 1    | 鈴木 | 70   |
| 2    | 佐藤 | 80   |
| 3    | 山田 | 80   |
| 4    | 田中 | 80   |
| 5    | 高橋 | 90   |

## DENSE_RANK 

```SQL
SELECT DENSE_RANK() OVER(ORDER BY 点数) AS 番号
     , Z.*
  FROM 成績表 AS Z;
```

実行結果

| 番号 | 氏名 | 点数 |
| ---- | ---- | ---- |
| 1    | 鈴木 | 70   |
| 2    | 佐藤 | 80   |
| 2    | 田中 | 80   |
| 2    | 山田 | 80   |
| 3    | 高橋 | 90   |

## RANK

```SQL
SELECT RANK() OVER(ORDER BY 点数) AS 番号
     , Z.*
  FROM 成績表 AS Z;
```

実行結果

| 番号 | 氏名 | 点数 |
| ---- | ---- | ---- |
| 1    | 鈴木 | 70   |
| 2    | 佐藤 | 80   |
| 2    | 田中 | 80   |
| 2    | 山田 | 80   |
| 5    | 高橋 | 90   |



# 分析関数を使わない方法

## ROW_NUMBERと同じ結果を得る方法

```SQL
SELECT @rank := @rank + 1 AS 番号
     , Z.*
FROM (SELECT * FROM 成績表 ORDER BY 点数) AS Z
   , (SELECT @rank:=0) AS X;
```

実行結果

| 番号 | 氏名 | 点数 |
| ---- | ---- | ---- |
| 1    | 鈴木 | 70   |
| 2    | 佐藤 | 80   |
| 3    | 田中 | 80   |
| 4    | 山田 | 80   |
| 5    | 高橋 | 90   |

## DENSE_RANK と同じ結果を得る方法

```SQL
SELECT @rank :=
         CASE
         WHEN @rankval = 点数 THEN @rank
         ELSE @rank + 1
         END AS 番号
     , @rankval := 点数 AS rankval
     , Z.*
FROM (SELECT * FROM 成績表 ORDER BY 点数) AS Z
   , (SELECT @rank:=0, @rankval:=NULL) AS X;
```

実行結果

| 番号 | rankval | 氏名 | 点数 |
| ---- | ------- | ---- | ---- |
| 1    | 70      | 鈴木 | 70   |
| 2    | 80      | 佐藤 | 80   |
| 2    | 80      | 田中 | 80   |
| 2    | 80      | 山田 | 80   |
| 3    | 90      | 高橋 | 90   |

## RANKと同じ結果を得る方法

```SQL
SELECT @rank :=
         CASE
         WHEN @rankval = 点数 THEN @rank
         ELSE @rank + @gap + 1
         END AS 番号
     , @gap := 
         CASE
         WHEN @rankval = 点数 THEN @gap + 1
         ELSE 0
         END AS gap
     , @rankval := 点数 AS rankval
     , Z.*
FROM (SELECT * FROM 成績表 ORDER BY 点数) AS Z
   , (SELECT @rank:=0, @rankval:=NULL, @gap:=0) AS X;
```

実行結果

| 番号 | gap  | rankval | 氏名 | 点数 |
| :--- | :--- | :------ | :--- | :--- |
| 1    | 0    | 70      | 鈴木 | 70   |
| 2    | 0    | 80      | 佐藤 | 80   |
| 2    | 1    | 80      | 田中 | 80   |
| 2    | 2    | 80      | 山田 | 80   |
| 5    | 0    | 90      | 高橋 | 90   |



# お試し

http://sqlfiddle.com/#!9/441f6e/7/0



# 参考記事

https://qiita.com/a__i__r/items/510ca4a86b693627055a
ドミノ倒し やってみた



<p class="codepen" data-height="414" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="yLapKYK" style="height: 414px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="domino toppling by using cannon.js">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/yLapKYK">
  domino toppling by using cannon.js</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

ソースはほぼ参考サイト1を
コピー
参考にさせて頂きました。

イメージ通りにドミノが倒れず、色々調べていたところ参考サイト2 を見つけ、解決しました。摩擦係数大事！

# 参考サイト

1. [三次元物理演算エンジン、Cannon.jsを使ってみた。 | KnockKnock](http://www.knockknock.jp/archives/540)
- [Javascript で動く軽量物理エンジン Cannon.js と3Dレンダラ Three.js で書いた短いサンプルコード - Qiita](https://qiita.com/yamazaki3104/items/fafb7879591caf137b52)
Amazon EC2にSSHで接続する（Ubuntu）

#記事の内容
AWSの練習でUbuntuからSSH接続するときに以下のエラー回避するのに色々調べたりして時間かかったので、コマンドを備忘として記載。Linuxのコマンドあまり分かってないのもあって苦戦した。

```
Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
```


#作業
UbuntuにSSHクライアントが入っていなければインストールする。

```
 $ sudo apt-get install openssh-client 
```
鍵をユーザ名配下のフォルダに移動。

```
 $ mv 鍵名.pem /home/ユーザ名/.ssh 
```

権限設定

```
 $ chmod 400 鍵名.pem 
```

SSH接続

```
$ ssh -i 鍵名.pem ec2-user@[IPアドレス or DNS名]
```

#コメント
自分の場合はユーザー名ec2-userを書き間違えたり、鍵ファイルを適当な場所に配置していてエラーが解消できずなかなか前に進まなかった。これから始める人は参考にしてください。
Dynmapの画像軽量化設定

ちょっとしたメモですが、spigotの超有名プラグインであるdynmapの設定についてです。
/plugins/dynmap/configuration.txtにimage-formatという設定があります。
デフォルトだとjpg-q90になっているのですが、それだとかなり重いので好きな品質にしてDynmapを軽量化しましょう

```config
# Default image format for HDMaps (png, jpg, jpg-q75, jpg-q80, jpg-q85, jpg-q90, jpg-q95, jpg-q100, webp, webp-q75, webp-q80, webp-q85, webp-q90, webp-q95, webp-q100),
image-format: jpg-q90 #ここをいい感じにしよう
```
## 補足
Dynamap3.1-betaからフォーマットにwebpを選べるようになっていますが、
いろいろやらないと有効化できません。
詳しくは[ここ](https://www.reddit.com/r/Dynmap/comments/ji7h87/support_for_webp_map_image_format_in_31snapshot/)からどうぞ


## 補足2
画像の圧縮設定については[この記事](https://qiita.com/miyanaga/items/a616261de490cc342d08)が非常に参考になります。
FreeBSDでsnoop

IoTモジュールのようなもので通信内容を確認したときがあります。ルーターなどのスイッチに接続すると、他の機器にはパケットは飛んでこないので、通信内容を知る事はできません。スイッチには特定ポートの内容をすべて送るミラーなどの機能があることが多いですが、使える環境は限られます。

このためFreeBSDをブリッジにして通信内容を覗いてみます。

[FreeBSD/i386](https://qiita.com/yamori813/items/2cdc2f8164e3973eb240)を使い構成はこのようになります。

![snoop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/fd93147a-deaf-a308-e901-1eed9dacd9b3.png)

通常はfxp0を使っています。ブリッジを設定します。

```
% sudo ifconfig bridge create
% sudo ifconfig bridge0 up
% sudo ifconfig bridge0 addm fxp0
% sudo ifconfig bridge0 addm vr0
% sudo ifconfig vr0 up
```

これで

```
% sudo tcpdump -i vr0
```

通信内容の確認ができます。このケースではbridge0やvr0にIPアドレスは必要ありません。

インターフェースはなんでもよくてUSB-Etherモジュールが手軽でよいかもしれません。

tcpdumpのhostでモジュールのIPアドレスを指定したり、etherでMACアドレスを指定すると、モジュールに関係するパケットだけ見れます。

HTTPであればtcpdump -xXで中身も見れますが、HTTPSの場合中身を見てもなんだか分かりません。

FreeBSDでは上記のkernel moduleを使う方法とは別にnetgraphを使ってもbridgeを実現できます。この場合/usr/share/examples/netgraph/ether.bridgeを修正して試すのが良いでしょう。

この構成でdummynetを使って帯域制御やパケットロスをシュミレーションすることもできます。
アイコンの作り方

この記事はPARONYM Advent Calendar 2020の記事です。

＊私は日本でデザイナーとして仕事している中国人です。
今年は４年目になります。まだまだ日本語下手なので、ご了承ください。:bow:

**なぜきれいなアイコンが必要？**
プロダクトのデザインの中には、多少のアイコンが使われるでしょう。
これらのアイコンは、プロダクトにとって非常に小さな役割かもしれませんが、細かいところまでこだわってデザインをしたほうが、ユーザーにとってより良い体験を作り出せるかと考えています。
***
**どんなアイコンが良いアイコン？**

**１、アイコンが使われるシナリオ**
そのプロダクトがどんなサービスなのか（例えばツール系、またはエンタメ系）、ユーザーの性別、年齢など、アイコンをデザインする際に考慮しなければならない要素があります。
例としては、ツール系のアイコンは比較的に四角目なアイコン（男性向き）、エンタメ系のアイコンはやわらかい印象のある丸みをおびたアイコン（女性向き）の方が良いと思います。
![img_5@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914144/9f830f5f-cfc4-98d6-c66d-5a518549cbc0.png)


**２、アイコンの（PC/SP）サイズ**
同じアイコンでも、SPで使われるとき少しPCより大きめのほうが良いでしょう。
なぜなら、SPの時、指で操作できる範囲を考慮しないといけないからです。
PCの場合、マウスで操作するので、見える範囲で少し小さめの方がよりきれいに見えるでしょう。
![img_6@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914144/044cb0ea-1130-28ae-0b7a-9dd6639b6b06.png)


**３、アイコンの統一性**
アイコンの大きさ、丸角のサイズ、ストローク（塗りつぶし）など、これらのようなアイコンの視覚的な特徴が統一されているかどうかが決め手になります。
***
**どうすれば統一性のあるアイコンを作れますか？**

**１、アイコンのグリッドを作りましょう**
まずはアイコンの大きさ、基本の形を描きましょう。（正方形、横長長方形、縦長長方形、丸）
例として、アイコンのボックスを24pxに設定、そして、余白4pxを空けましょう。
（なぜ4px余白をつけるかというと、最終調整するとき余裕がある方が良いためです。）
こうして、アイコンの最大のサイズは20×20pxになります。
丸は視覚的に大きさが一番小さいので、丸のサイズを20×20pxにしましょう。
正方形は16×16px、横長長方形は18×14px、縦長長方形は14×18pxに設定しましょう。
![img_1@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914144/379e26d5-b905-5612-74cd-4aa08057f94f.png)



**２、ストローク（塗りつぶし）系のアイコンを統一して、角丸を決めましょう**
アイコンのデザインの種類をストローク系か塗りつぶし系か決めましょう。
例えば、ストローク系にする場合は、枠線の太さと、角丸のサイズも決めておきましょう。
![img_3@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914144/60c07496-06a1-e0b6-2fad-8a078e19c963.png)


**３、アイコンを描きましょう**
![img_4@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914144/c3166c53-293a-1819-7ada-8d75aba964d5.png)


**４、統一性を調整しましょう**
グリッドはサンプルとして使うため、実際の大きさや統一性など、最後は自分の目で確かめましょう。
例えば、プレイアイコンの三角、左右の間隔は同じ7pxですが、実際に目で見ると左に寄せています。こうよう場合は、目で見ながら、右側のほうに調整しないとアイコンのバランスが悪くになります。
![img_2@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914144/10fe0d32-e79e-e63b-d09b-4ecd9d9168d2.png)

****
以下は中国語です。

为什么要考虑图标的美观性？
在产品设计中，会或多或少会运用到一些图标。
这些图标在一个产品中的作用可能非常小，只是起到一定的辅助引导作用。对这个产品是否好用并不能起到关键作用。
但是正是这些细节部分的设计，会使用户感受到产品的用心程度。带来使用愉悦感。

什么样的图标才是优秀的图标？

1．考虑图标的使用场景
工具型的产品或是娱乐型的app，用户的性别，年龄等等，这些都是在设计图标时需要考虑的因素。
工具型产品的图标可以相对方正（用户倾向 男性），娱乐型产品的图标可以圆润活泼（用户倾向 女性）。
用户的年龄相对较大时，制作的图标大小可以相对大一些。使用面型图标。反之，同理。

2，图标的大小（PC/SP）
用在PC时的图标，大小可以相对用在手机上的小一些。
因为手机需要考虑手指的点击范围，太过小的图标会容易造成误操作。
而pc则使用鼠标进行操作，点击准确度相对较高，在可视性没有问题的情况下可以相对小一些。

3，图标的统一性
图标大小，圆角角度，线性图标（面性图标），这些都是决定一组图标在视觉上是否统一关键要素。

如何绘制一组具有统一性的图标？

1，首先制作图标参考线
首先绘制图标的基本形状（正方形，横矩形，竖矩形，圆形），规定图标在产品中的使用大小，绘制好参考线。
这里规定图标容器大小24X24px，预留4px的安全间距，图标最大大小20x20px。
由于视差关系，圆形在图标里的尺寸是最大的，所以圆形大小为20x20px
正方形大小16x16px，横矩形18x14px，竖矩形14x18px

2，线性图标的线的粗细，圆角角度统一
在这里规定线的粗细1px，圆角角度1px	

3，绘制图标

4，统一性调整
参考线的作用只是参考，最后的图标大小，准确性要靠自己的眼睛去测量。
比如这里的播放图标，三角形的左右间距数值相等，但在视觉上却偏左，在这种情况下就要靠自己的眼睛去调整，使右侧的间距相对小一些，达到视觉平衡感。
GitHooksをElixir開発環境へ導入して、コミットやプッシュの際にコード検査やテストが走るようにする

# 概要

Elixir開発環境にGitフックを導入し、コミットやプッシュのタイミングで自動的にコード検査やテスト等が実行されるようにします。

- Hexの[GitHooks](https://github.com/qgadrian/elixir_git_hooks)を使います。
  - JavaScript（Node.js）で言うところのHusky的なライブラリです。
- これにより、Gitフックを簡単に生成してElixir開発ディレクトリへ導入することができます。

### 実行環境

- MacOS
- Elixir 1.15.7 (compiled with Erlang/OTP 26)
- mix

# コード

```elixir:mix.exs
defp deps do
  [
    {...},
    {:git_hooks, "~> 0.7.3", only: [:dev], runtime: false}
  ]
end
```

```elixir:config/config.exs
...

# 例
config :git_hooks,
  auto_install: true,
  verbose: true,
  hooks: [
    pre_commit: [
      tasks: [
        {:cmd, "mix format --check-formatted"}
      ]
    ],
    pre_push: [
      verbose: false,
      tasks: [
        {:cmd, "mix test"},
        {:cmd, "mix dialyzer"}
      ]
    ]
  ]
```

- 各人やプロジェクトのGit運用スタイルに合わせて、pre_commitやpre_pushを設定します。

# 設定手順

1. 上記各ファイルへ設定追記。
1. `mix deps.get && mix deps.compile`を実行。
1. 念のため`mix git_hooks.run pre_commit`して、手動で走るか確認する。
1. `mix git_hooks.install`を実行。（開発ディレクトリにhooksファイルを書き出す）

これ以降は、git commitやgit pushのたびに自動でhooksが走るようになります。

```terminal:Git
$ git commit -m "commit NOT-formatted code"

↗ Running hooks for :pre_commit
** (Mix) mix format failed due to --check-formatted.
The following files are not formatted:

  * config/config.exs

× pre_commit failed on `mix format --check-formatted`
** (exit) 1
    ...
```

# 補足

### pre_commit / pre_push を再設定する

`config/config.exs`で設定を書き直してから、`mix git_hooks.install`を実行します。

### hooksをスキップしたい

通常のgit hooksと同様に`--no-verify`オプションを付加することで、hooksをスキップできます。

```terminal:Git
$ git commit -m "commit without hooks" --no-verify
```

# おわりに

GitHooksをサクッとElixir開発ディレクトリに導入して、CIを回す前のローカルリポジトリ段階でもコード検査やテスト実行を自動化して開発効率や開発体験を向上させていきましょう。
【VBA】配列を使うと早いと思っていたら失敗した話

#はじめに
ExcelVBAを使ってとある処理をしようとしたところ、配列の使い方が良くなかったために少し失敗したので、情報を共有したいと思います。
先に結論を述べてしまうと、`ReDim Preserve`を大量に使用すると、処理が遅くなるようでした。
#処理の概要と原因
1. テキストファイルを読み込み、配列その1にデータを格納
2. 配列その1のデータのうち、一定条件に合うもののみ配列その2に移行
3. 配列その2のデータを配列その3に移行
4. 配列その3のデータをワークシートに書き出し

このような処理を行うコードを書いたところ、配列1から2に移すデータの件数が多い場合に、なぜか時間がかかってしまいました。
そこで各処理の時間を測ってみると、以下のようなことがわかりました。

* 1は結構早い。そもそも、常にテキストを全て読み込んでいるので、「移行件数が多いときに時間がかかる」という事象の原因にはならない。
* 3は同じサイズの配列を2つも作ってデータをやりとりしており、無駄な処理をしているようにみえる。しかし、時間は全然かかっていない。
* 4はそれなりに時間がかかる。ExcelVBAを使う上で必ず課題になる「画面描画」を行うため、ある程度時間がかかるのは仕方ない。しかし、今回は、時間がかかる主な原因にはなっていないようである。

つまり、2のプロセスに問題があるようです。
#詳しく
2のプロセスで、配列その2に移行するデータの件数が不確定であることから、配列その2は「初めは最小サイズにしておき、格納するデータがあれば少しずつサイズを大きくしていく」というプログラムにしていました。
どうもこのために動作が遅くなってしまったようでした。
以下、簡単な検証をしてみます。

```vb
Sub test()
    Dim arr() As Variant
    Dim i As Long
    For i = 1 To 100000
        ReDim Preserve arr(i)
        arr(i) = i
    Next i
End Sub
```

10万回ループを行い、10万個の要素を配列に格納しています。
要素を格納する前に、毎回配列のサイズを1個分ずつ広げています。
ループ回数を増やして時間を計測したところ、以下のような結果になりました。

* ループ100,000回：1秒未満
* ループ500,000回：約4秒
* ループ1,000,000回：約16秒

どんどん遅くなっていきます。
実際のプログラムでは2次元配列を使用していたので、2次元配列でテストしてみます。

```vb
Sub test()
    Dim arr() As Variant
    Dim i As Long
    For i = 1 To 100000
        ReDim Preserve arr(1, i)
        arr(0, i) = i
        arr(1, i) = i
    Next i
End Sub
```

結果は以下のとおりです。

* ループ100,000回：1秒未満
* ループ500,000回：約16秒
* ループ1,000,000回：約69秒

とても実用レベルには至らない実行時間になってしまいました。
#改善
初めから大きな配列を作って値を格納し、最後にサイズを調整する方法に変えてみました。

```vb
Sub test()
    Dim arr() As Variant
    ReDim arr(10000000)
    Dim i As Long
    For i = 1 To 100000
        arr(i) = i
    Next i
    ReDim Preserve arr(i - 1)
End Sub
```

最初に1千万個分の大きさの配列を作り、最後に、実際に格納された要素数分のサイズに縮めています。
(最初の配列のサイズをこんなに大きくする必要はないのですが・・・テスト用に適当なサイズにしているだけです。また、配列のインデックスは0から始まるので、厳密には、サイズは要素数+1個分になります。)

結果は以下のとおりです。

* ループ100,000回：1秒未満
* ループ500,000回：1秒未満
* ループ1,000,000回：1秒未満
* ループ10,000,000回：1秒未満

2次元配列も試してみます。

```vb
Sub test()
    Dim arr() As Variant
    ReDim arr(10000000)
    Dim i As Long
    For i = 1 To 100000
        arr(0, i) = i
        arr(1, i) = i
    Next i
    ReDim Preserve arr(1, i - 1)
End Sub
```

結果は以下のとおりです。

* ループ100,000回：1秒未満
* ループ500,000回：1秒未満
* ループ1,000,000回：1秒未満
* ループ10,000,000回：約1秒

おお、早くなりました。
#おわりに
`ReDim Preserve`を多用すると処理が遅くなることがわかりました。
配列の要素数が予め特定できない場合は上記のような工夫をしたり、そもそも配列ではなく、`Collection`や`Dictionary`を使用した方が良いですね。
TextFormFieldでsaveやvalidateを呼ぶとクラッシュする : NoSuchMethodError: The method 'validate' was called on null

FlutterのTextFormFieldを初めて使ったら、クラッシュに遭遇しました。

#何がいけなかったのか

TextFormFieldをFormでラップしないといけないみたいでした！

参考URL
https://stackoverflow.com/questions/52384943/nosuchmethoderror-the-method-validate-was-called-on-null
ブログにツイートシェアボタンを設置する

#経緯
当初サイト[https://publish.twitter.com/#](https://publish.twitter.com/#)からツイートボタンを設置したが、何をしているか把握できるようにaタグのみで下記のようにリンクを作成した

```html
<a href="http://twitter.com/share?url=https://avnoblog.com/review_15%0a&text=作品の紹介文%0a&hashtags=タグ1,タグ2" target="_blank">ツイート</a>
```
※以下の当初案は実装を中止

#当初案
##ツイートシェアボタンを設置する
- 下記サイトでTwitter Buttonを選択するしコピーする
https://publish.twitter.com/#
- Share Buttonを選択する
- コードをコピーしブログに設置する

```html 
<a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-show-count="false">Tweet</a>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
```

##ツイート内容、ハッシュタグの設定
[twitterのツイートボタンを作るためのリンクshareとintent/tweet](https://qiita.com/coconeko/items/dcd3a004578e02f63da5)
を参考にテキストを設定<a>タグを下記のように変更

```html
        <a class="twitter-share-button" href="https://twitter.com/share?text=#たぐ１ #たぐ２%0a">Tweet</a>
```

#参考
1. [Twitterのツイートボタンをホームページやブログに設置する設置方法](http://www.kingsite.jp/blog/sns/2015-10.php)
1. [twitterのツイートボタンを作るためのリンクshareとintent/tweet](https://qiita.com/coconeko/items/dcd3a004578e02f63da5)
1. [Twitterシェアボタン シェアされる文字を変更する](https://masizime.com/blog/2020-02-26)
【備忘録】既に公開しているCocoapodsライブラリを手動でアップデートする手順

#.podspecのバージョンを編集
例）
`spec.version      = "0.0.3"`
#gitにタグをpushする
例）
`git tag 0.0.3`
`git push origin 0.0.3`


#ライブラリの更新を反映
`pod trunk push LibraryName.podspec --allow-warnings`

#後で自動化したい！
きっと、もっと楽な方法があるはず！
リモートサーバーのmysqlからローカルに落とし込む ~メモ~

RDSのDBインスタンスからmysqlの特定のテーブルデータをエクスポートしようとしたのですが、
SequelProでssh設定が適切でなかったのか、awsで構築したRDSのDBインスタンス内のmysqlにアクセス出来なかったので、

・ec2インスタンスにssh接続
・mysqlデータをdump
・scp接続でlocalのmysqlに落とす。

という手順を踏みました。
初めて扱うコマンドが大半であったので、メモ。。。

まずRDSのDBインスタンスに接続できる
リーモートサーバー(ec2インスタンス)にsshアクセスします。

そこで下記コマンドを実行

```
remote-sever $ mysqldump -h host_name -u user_name -p database_name table_name > file_name.sql
```


|オプション|名所|説明|
|:---|:---|:--|
|-u|	ユーザー名|	サーバに接続するユーザー名|
|-p	|パスワード|	パスワードを指定してログイン|
|-h|	ホスト名|	接続するサーバのホスト名(default: localhost)|
|-B|	データベース|	複数のデータベースを名前を指定してダンプ|
|-A|	すべてのデータベース|	複数のデータベースをまとめてダンプ|
|-d|	定義のみ	|定義のみダンプを取りたいときに指定|
|-n|	データベースは無視|	データベースを作成せずにダンプ|
|-t|	テーブルは無視|	テーブルの作成を行わずにダンプ|

optionを追加した後、">" で作成ファイル名を指定。

```
remote-sever $ ls
file_name.sql
```
一旦リモートサーバーを抜け後、scpアクセスします。

#### SCP(Secure Copy Protocol)
「SFTP」同様、Secure Shell（ssh）に含まれるsshの機能を使ってセキュリティ性の高いファイル転送を行うプロトコルといえます。
「SFTP」に比べて通信速度は速いといわれているのですが、この「SCP」を利用する場合はサーバにUNIX系のシェルが備えられている必要があります。Webサーバを作ろうとするとほとんどのサーバにはシェルは入っているので意識することは少ないです。

```
$ scp user_name@host_name:~/file_name.sql ~/Desktop/
$ scp [ユーザー名]@[ホスト名]:[コピー元PATH] [localのコピー先]
```

|オプション|名所|説明|
|:---|:---|:--|
|-u|	ユーザー名|	サーバに接続するユーザー名|
|-i| 鍵ファイル	|ssh接続に使用する鍵ファイルを指定する|
|-P| ポート番号	|(sshのポートを変更している場合などに)接続に使用するポートを指定する|
|-p|	|コピー元のタイムスタンプやパーミッションを保持する|
|-r|	|ディレクトリごと再帰的にコピーする|

うまくDesktopにsqlファイルをエクスポート出来ました。
あとはSequelProでlocalのmysqlにインポートすれば反映されます。
Athenaを利用してCloudTrailのログを検索する

## 概要

過去のCloudTrailログに対してAthenaを使用して解析する機会があったのでこちらの記事にまとめたいと思います。
コンソールからテーブルを作成し、クエリを実行するだけで過去のイベントが簡単に検索できます。

## テーブル作成
CloudTrailにコンソール上からアクセスし「イベント履歴」ページを開きます。



「Athenaテーブル作成」ボタンをクリック。
![スクリーンショット 2020-12-23 0.51.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432486/f16366a6-262f-e2d4-ddde-931d2b1b2ec5.png)



Athenaテーブル作成ページが表示されるので
ログ保存バケットを選択し、右下の「テーブル作成」をクリック。

```
CREATE EXTERNAL TABLE table_name (
    eventVersion STRING,
    userIdentity STRUCT<
        type: STRING,
        principalId: STRING,
        arn: STRING,
        accountId: STRING,
        invokedBy: STRING,
        accessKeyId: STRING,
        userName: STRING,
        sessionContext: STRUCT<
            attributes: STRUCT<
                mfaAuthenticated: STRING,
                creationDate: STRING>,
            sessionIssuer: STRUCT<
                type: STRING,
                principalId: STRING,
                arn: STRING,
                accountId: STRING,
                userName: STRING>>>,
    eventTime STRING,
    eventSource STRING,
    eventName STRING,
    awsRegion STRING,
    sourceIpAddress STRING,
    userAgent STRING,
    errorCode STRING,
    errorMessage STRING,
    requestParameters STRING,
    responseElements STRING,
    additionalEventData STRING,
    requestId STRING,
    eventId STRING,
    resources ARRAY<STRUCT<
        arn: STRING,
        accountId: STRING,
        type: STRING>>,
    eventType STRING,
    apiVersion STRING,
    readOnly STRING,
    recipientAccountId STRING,
    serviceEventDetails STRING,
    sharedEventID STRING,
    vpcEndpointId STRING
)
COMMENT 'CloudTrail table for cloudtrail-bucket bucket'
ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://cloudtrail-bucket/AWSLogs/XXXXXXXXXXXX/CloudTrail/'
TBLPROPERTIES ('classification'='cloudtrail')
```

※こちらのクエリを直接Athenaに貼り付けても、テーブルの作成はできます。
CREATE EXTERNAL TABLE にテーブルネーム
LOCATION　S3に保管しているCloudTrailログのパスを指定

## クエリ実行
Athenaを開き、テーブルが作成されているのを確認。
クエリを実行しカラム解析を行う。

### よく使うカラム

```
useridentity
eventtime　
eventsource 
eventname
awsregion　
useragent
requestparameters
```

カラムの詳細については公式ページの「CloudTrailレコードの詳細」を参考にしてください
https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html

## クエリ実行例

```
SELECT "useridentity","eventtime","eventsource","eventname","awsregion","useragent"
,"requestparameters"
FROM "テーブル名"
WHERE eventName　='CreateStuck(検索したいAPI名)'AND 
awsregion　='ap-northeast-1'(検索したいリージョン)AND 
eventTime > '2020-12-01T00:00:00Z(検索したい期間)';
```
上記の例でクエリを実行すると、12月00日以降、東京リージョンで作成されたCloudFromationのスタック作成イベントを検索します。

### まとめ
過去のCloudTrailログを検索するのにAthenaはとても便利です。
まずは中身の内容について知ることでより検索の精度が上がると思うのでまずはSELECTで"*"をかけてみて全カラムの内容を確認してみると良いと思います。

### 参照ページ
AWS CloudTrail ログのクエリ
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/cloudtrail-logs.html
About package.json

```package.json
{
  "name": "foo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "request": "^2.81.0"
  },
  "devDependencies": {
    "mocha": "^3.4.2"
  }
}
```

## dependenciesとdevDependenciesの違い

### dependencies
本番環境で使用するもの


```
$ npm i -S <package-name>
```

### devDependencies
開発環境で使用するもの

```
$ npm i -D <package-name>
```
Node.js: Redis のデータを読む

## プログラム

```js:redis_read.js
#! /usr/local/bin/node
// ---------------------------------------------------------------
//
//	redis_read.js
//
//						Mar/25/2023
// ---------------------------------------------------------------
'use strict'

const redis = require('redis')

// ---------------------------------------------------------------
async function read_proc()
{
//	const redisUrl = 'redis://127.0.0.1:6379'
//	const client = redis.createClient(redisUrl)
	const client = redis.createClient()

	await client.connect()

	const keys = await client.keys('*')

	for(var it in keys)
		{
		const key = keys[it]
		try
			{
			const value = await client.get(key)
			const data = JSON.parse(value)
			var out_str = key + "\t"
			out_str  += data.name + "\t"
			out_str += data.population + "\t"
			out_str += data.date_mod
			console.log (out_str)
			}
		catch (error)
			{
			console.error ("*** error *** from JSON.parse ***")
			console.error (error)
			console.error (key)
			}
		}
 
	await client.disconnect()
	console.error ("*** 終了 ***")
}

// ---------------------------------------------------------------
console.error ("*** 開始 ***")
read_proc()
// ---------------------------------------------------------------
```

## 実行結果

```text
$ export NODE_PATH=/usr/local/lib/node_modules
$ ./redis_read.js
*** 開始 ***
t1859	坂井	25397	1950-11-9
t1858	越前	52486	1950-7-26
t1857	あわら	38251	1950-3-21
t1855	勝山	41358	1950-8-14
t1851	福井	92714	1950-9-12
t1853	小浜	67241	1950-10-2
t1852	敦賀	28158	1950-3-15
t1854	大野	32164	1950-6-22
t1856	鯖江	64792	1950-9-12
*** 終了 ***

```

## 確認したバージョン

```text
$ node --version
v22.3.0
```

## 関連情報
[Node.js: Redis のデータを作成 (Create)](https://qiita.com/ekzemplaro/items/cfc60e49cd716d408bf5)
[Node.js: Redis のデータを更新 (Update)](https://qiita.com/ekzemplaro/items/c1765e4c17fb32793b7f)
[Node.js: Redis のデータを削除 (Delete)](https://qiita.com/ekzemplaro/items/a034f033f41392ec30c0)
SharePoint や OneDrive に保存したファイルを PDF でダウンロードする

Officeファイルを開いて、PDF化するひと手間を省きたいときに使えるかも？

# 公式ドキュメント
> 別の形式でファイルをダウンロードする
> https://docs.microsoft.com/ja-JP/graph/api/driveitem-get-content-format?view=graph-rest-1.0&tabs=http

# 実行例( SharePoint Online 向け)
以下を実行すると、数分だけ有効なダウンロードURLにリダイレクトされる。

``` url:GET
https://{hostname}/_api/v2.0/sites/{hostname}:/sites/{sitename}:/drives/{library-id※}/root:{filepath & filename}:/content?format=pdf
``` 

※{library-id} の調べ方
Driveも名前で指定したかったけど、みつからなかったのでidでやる。
以下を実行すると、指定のサイトにあるライブラリの一覧が取得できるので、その中から指定のライブラリのidを抜き出す。

``` url:GET
https://{hostname}/_api/v2.0/sites/{hostname}:/sites/{sitename}:/drives
```
Promise.all()の応用

業務の中で触れたので、知識の定着&備忘のために記録します。

## Promise.allを使って並列処理する
まずは、前提になる並列処理についてです。
itemA, itemBに代入したいデータを返すfuncA, funcBという2つの非同期関数があるとして、並列処理をしようと思うと、こうなります。


```js
  // funcAが終わってからfuncBを処理するので処理に時間がかかる
  var itemA = await funcA();
  var itemB = await funcB();


  // 並列処理をするパターン
  var promises = [
    funcA(),
    funcB()
  ];
  var [itemA, itemB] = await Promise.all(promises);

```

## ネストさせる
ここから、自分が直近勉強した並列処理の応用です。
以下のオブジェクトについて、firestoreからデータをフェッチして、新しい配列をつくる処理を考えます。関数の中身は適当です。
下のitemsという配列に入ってる動画とそのサムネイルのファイルを、
それぞれfirebase storageにアップロードして、帰ってきたurlをオブジェクトに紐付ける処理を考えます。

```js
  // 対象のオブジェクト
  var items = [
    {thumbnail: file, video: file},
    {thumbnail: file, video: file},
    {thumbnail: file, video: file},
  ];

  // idからデータを取得する関数
  var uploadFile = async(file) => {
    var ref = firebase.storage().ref();
    var snapshot = await ref.child('test').put(file);
    // urlを返す
    return await snapshot.ref.getDownloadURL();
  };
```

やりかたはこうなります。

```js
  //配列
  var promises = items.map(async(item) => {
    var upload_promises = [
      uploadFile(item.thumbnail),
      uploadFile(item.video)
    ];
    var [thumbnail_url, video_url] = await Promise.all(upload_promises);
    // オブジェクトとして返す
    return {thumbnail_url, video_url};
  });
  //[{thumbnail_url: 'https://~~', video_url: 'https://~~'},{...},...]が返ってくる
  var urls = await Promise.all(promises); 

```

[この記事](https://qiita.com/jkr_2255/items/62b3ee3361315d55078a)にあるように、forEachでasync/awaitを使うと順番が担保できなくなる、というのは知っていたので、なんとなくmapでasync/awaitを使っていいのかな、という疑問というか不安みたいなものがあったのですが、この書き方だと順番も担保されたまま並列処理ができます。
【mongoDB】mongoDBチートシート「ユーザー管理」

※当方駆け出しエンジニアのため、間違っていることも多々あると思いますので、ご了承ください。また、間違いに気付いた方はご一報いただけると幸いです。

##作成するデータベースに移動

```
use <database>
```

##ユーザー作成

```js
db.createUser({
  user: "<username>", //ユーザー名 
  pwd: "<password>",  //パスワード
  roles: [{
    role: "<role>", //権限種類
    db: "<database>" //データーベース
  }]
})
```

##パスワードの変更

```js

db.changeUserPassword(
  "<username>",
  "<password>"
)
```
##ロール（権限）の追加
```js
db.grantRolesToUser(
  "<username>",
 ["<roles>"]
)
```

##ロール（権限）の削除
```js
db.revokeRolesFromUser(
  "<username>",
 ["<roles>"]
)
```

##ユーザー削除

```js
db.dropUser(<"username">)
```

##主なロールの一覧
| 分類 | ロール名 | 説明 |
|:--|:--|:--|
|ユーザーDB操作用ロール|read|コレクションに対する読み|
|ユーザーDB操作用ロール|readWrite|コレクションに対する読み書き|
|  ユーザーDB操作用ロール |  dbAdmin |db管理用ロール   |
| ユーザーDB操作用ロール  |  userAdmin |ユーザー管理用ロール   |
|  ユーザーDB操作用ロール | dbOwner  |  システム管理用ロール<br>以下のロールを含む<br>dbadmin<br>userAdmin<br>readWrite |

| 分類 | ロール名 | 説明 |
|:--|:--|:--
| クラスタ管理・操作用ロール  |clusterManager   |クラスタ管理用ロール    |
|  クラスタ管理・操作用ロール |  clusterMonitor | クラスタ読み取り専用ロール |
|クラスタ管理・操作用ロール   |  hostManager |   クラスタ操作用ロール|
|クラスタ管理・操作用ロール   |  clusterAdmin | クラスタ管理用ロー<br>clusterManager<br>clusterMonitor<br>hostManager<br>dropDatabaseアクション  |

| 分類 | ロール名 | 説明 |
|:--|:--|:--|
| バックアップ・リストア用ロール |backup   | バックアップ用ロール   |
| バックアップ・リストア用ロール  | restore  |リストア用ロール   |

| 分類 | ロール名 | 説明 |
|:--|:--|:--|
|全DB管理操作用ロール  |  readAnyDatabase | 全DBの読み取り専用ロール |
| 全DB管理操作用ロール  |  readWriteAnyDatabase | 全DBの読み書き用ロール  |
| 全DB管理操作用ロール  | userAdminAnyDatabase  |  全DB のユーザー管理用ロール |
| 全DB管理操作用ロール  | dbAdminAnyDatabase  |  全DB 管理用ロール |

| 分類 | ロール名 | 説明 |
|:--|:--|:--|
| システム管理用ロール  |root   | システム管理用ロール  |
|  mongodb内部使用ロール | _system  | mongodbが内部で使用するロール  |
よく使用する gcloud コマンドまとめ

## はじめに
GCPによるインフラ環境の運用を始めると gcloud コマンドで各種操作が必要となることが分かりました。ついつい忘れてしまうので、よく使用するコマンドをまとめておきます。

## 認証

以下コマンドを実行すると認証を行う 

```shell
# Google アカウントの選択とアクセスの許可を行う認証画面がブラウザ上で開かれるので許可をする
$ gcloud auth login

# プロジェクト一覧を確認する
$ gcloud projects list

# gclould コマンドで操作したいプロジェクトのプロジェクトIDを指定する
$ gcloud config set project [PROJECT ID]

# 事故防止のため操作が完了したら認証解除をする
$ gcloud auth revoke
```

## GAE

```
# デプロイ(暗黙的に app.yaml が参照される)
$ gcloud app deploy

# yamlファイルを指定してデプロイ
$ gcloud app deploy app.yaml

# ログの参照
$ gcloud app logs tail -s default
```

## 参考
- [gcloud コマンドライン ツールの概要  \|  Cloud SDK のドキュメント  \|  Google Cloud](https://cloud.google.com/sdk/gcloud)
ERC20メモ

pragma solidity ^0.6.0;

import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";

contract MyCompanyToken is ERC20 {

    string private _name = "xxxxxx";
    string private _symbol = "ABC";

    constructor() ERC20( _name, _symbol) public {
        _setupDecimals(8);                      //小数点以下の以下の桁数を明示的に指定(8桁)する
        _mint(msg.sender, 2100000000000000); //2100万枚発行
    }
}
NFTメモ

pragma solidity >0.5.0 <0.7.0;

/**
import "@openzeppelin/contracts/token/ERC721/ERC721Full.sol";
import "@openzeppelin/contracts/drafts/Counters.sol";
**/
// black "https://ipfs.io/ipfs/xxxxx"
// white "https://ipfs.io/ipfs/xxxxx"

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
//import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/90ed1af972299070f51bf4665a85da56ac4d355e/contracts/utils/Counters.sol";
//import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/90ed1af972299070f51bf4665a85da56ac4d355e/contracts/math/SafeMath.sol";
//import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/90ed1af972299070f51bf4665a85da56ac4d355e/contracts/math/Math.sol";

contract GameItem is ERC721 {
    //using Counters for Counters.Counter;
    //Counters.Counter private _tokenIds;
    uint256 internal nextTokenId = 0;
    
    
    constructor() ERC721("xxxxxx", "ABC") public {
    }

    function awardItem(address player, string memory tokenURI) public returns (uint256) {
   // function awardItem(address player) public returns (uint256) {
        // _tokenIds.increment();

        // uint256 newItemId = _tokenIds.current();
        // uint256 newItemId = uint8(now);
        uint256 newItemId = nextTokenId;
        nextTokenId = nextTokenId.add(1);
        //_mint(player, newItemId);
        _mint(player, newItemId);
        //_setTokenURI(newItemId, "https://ipfs.io/ipfs/xxxxxxxxxxxx");
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}
Perlを使って乱数の出方を調べてみた。

とある本を読んでいて、乱数のアルゴリズムは果たしてどのような偏りがあるのかが気になったので、Perlでスクリプトを書いてみた。

```Perl
#(C)Tsubasa Kato 2020/11/7
#Last Updated on 2020/12/29
#Random Number Generator 
$counter = 1;
@number = 0;
$limit = 10000;
#decide upper limit of how many random numbers generated:
while ($counter <= $limit){
	$random_number = int(rand(10));
	@number[$counter] = $random_number;
	print "$counter: $random_number\n";
	$counter = $counter+1;

	$both = $both.@number[$counter - 1];
	
	
}

#prints all numbers made randomly.
print $both;
print @number[$counter];
#code used from: https://stackoverflow.com/questions/12948136/digit-occurence-of-a-number-in-perl
my (%counts, $sum);

while ($both =~ m/(\d)/g) {

    $counts{$1}++;
    $sum++;
}

print "The count each digit appears are: \n";
print "'$_' - $counts{$_}\n" for sort keys %counts;
print "The sum of all the totals is $sum\n";
```
出力（途中略）（例）

```
... 
9996: 6
9997: 6
9998: 6
9999: 5
10000: 7
667970441779473693333652299825501575481805785072233480307589190253118939996004889972812135817276495384858466221061134885961147664807314795423520407167266255738789149849690　
...
```

頻度分析の出力（例）：
このように、10000回ゼロから九まで頻度分析してみると偏りが出ている。

```
The count each digit appears are: 
'0' - 955
'1' - 1021
'2' - 1033
'3' - 995
'4' - 1031
'5' - 958
'6' - 963
'7' - 1098
'8' - 982
'9' - 964
The sum of all the totals is 10000
```

発展版としてC言語などで書き直してみるのも良いかもしれない。
引用コードのURL：https://stackoverflow.com/questions/12948136/digit-occurence-of-a-number-in-perl
【Android】Context って何？？

# はじめに
Contextについて自分なりに調べて学んだので記事に残します。

きっかけとしては、
Android開発をしていて、何も考えずにContextをメソッドの引数に渡しまくっていたところ、リードエンジニアにこのようなレビューを受けたことがある。
>Contextの過剰摂取には気をつけましょう。
いつの間にか抜け出せなくなっていずれ手のつけようがなくなってしまいます。
引数にContextを追加したら負けぐらいの気持ちでContextを引数に追加しないことを意識したほうが良いです。

そこで「Contextって何？？」っと思って色々調べた。

# そもそも Context とは？？
#### 日本語の意味的なContext
>（文章の）前後関係、文脈、脈絡、背景、状況、環境

などと出てくる

#### プログラミングにおけるContext
こちらのサイトから抜粋
http://e-words.jp/w/%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88.html

>プログラミングの分野でも、同じコード記述やプログラム上の要素が、その置かれているプログラム内での位置や、実行される際の内部状態などによって異なる振る舞いをしたり、異なる制約を受けたりすることを指してコンテキストということがある。

#### Android開発におけるContext
##### クラス定義と継承関係
- Contextは抽象クラスで定義されている
- Activityのスーパークラス（ActivityがContextクラスを継承している）
  - 継承関係: ``Context``←``ContextWrapper``←``ContextThemeWrapper``←``Activity``
- Applicationのスーパークラス(ApplicationがContextクラスを継承している）
    - 継承関係: ``Context``←``ContextWrapper``←``Application``
     

ちなみに``ContextWrapperクラス``に``getApplicationContext()``が定義されてる

##### どんなときに登場、利用するか
- Dialog生成時
- Intent利用時
- アプリケーションのリソースにアクセスする際(例: ``getString()``など)

などなど... とにかく神出鬼没


# どうやら大きく２種類のContextがあるらしい（他にもあるようだが今回は割愛）
### ActivityのContext
- Activityのライフサイクルに依存する。そのためActivityが破棄されるとき（画面回転時など）はContextも同様に破棄される。
- インスタンスはシングルトンではないようである。

#### 取得方法

- Java
  - ``Activity: this``
  - ``View, Fragment: getContext(), requireContext()``

- Kotlin
  - ``Activity: this``
  - ``View, Fragment: context, requireContext()``

##### getContext()とrequireContext()の違い
- ``getContext()``: null値許容 （Kotlinでは Context? として扱う）のContextを値として返す
- ``requireContext()``: 非nullのContextを値として返す

参考資料

- https://stackoverflow.com/questions/60402490/difference-between-getcontext-and-requirecontext-when-using-fragments
- https://developer.android.com/kotlin/common-patterns?hl=ja

### ApplicationのContext
- アプリケーションに関連していて、Activityのライフサイクルに依存しない。
- シングルトンとしてアプリケーションが生きている間は破棄されたり変更されたりしない。

#### 取得方法
Java: ``getApplicationContext()``
Kotlin: ``applicationContext``

# どうやって使い分けるのが望ましいのか？
結論としては、「**ライフサイクルとメモリリークの危険性を考慮した上で実装する**」という抽象的なものになってしまった。

だが、基本的にはメモリリークの危険性を考慮して極力``ActivityContext``を使う方が良さそう。
複数の記事を参考にしましたが、いろいろな意見がありました。


#### メモリリークについてContextの取り扱いにおいての注意事項
- Contextの寿命が受け取る側のオブジェクトの寿命より長くなる場合: 好ましい実装
- Contextの寿命より受け取る側のオブジェクトの寿命が長くなる場合: メモリリークの危険がある

# じゃあ今後Contextに出くわしたらどうする？
今までは何も考えずに適当に``Context``を利用していたが、今後はこの場面では「``ActivityContext``と``ApplicationContext``どちらを使うのがベターなのだろう？」と考えながら実装していこうと思います。
その中で理解を深めいく。

※ 自分自身の実力不足で色々と抜け漏れがあるかもです。精進します。

# スペシャルサンクス（参考にさせていただいた資料）
- https://qiita.com/iduchikun/items/34b3ae26cfc438e7e5dc
- https://tech.ga-tech.co.jp/entry/2020/06/android-contexts
- https://www.lanches.co.jp/blog/9776
- https://developer.android.com/reference/android/content/Context?hl=ja
- http://mitoroid.com/category/android/android_context.php
- https://qiita.com/k-yamada-github/items/bd99f45ed0d7176d2612
- https://qiita.com/roba4coding/items/0585b8240873ec5e9c20
- https://blog.meilcli.net/2018/12/26/185752
- https://blog.meilcli.net/2018/12/26/185752

# 最後に
間違い、ご指摘などありましたらぜひともコメントいただきたいです！

最後に結論として、Context難しい...
ありがとうございました。
Python3の文字コードについて

情報系の備忘録的なのを書こうかと思い、投稿してみた。

…が、書き途中で他の仕事やり始めてしまったので、とりあえず未完成品を投稿。
余裕がある時にコードとか追加しようかな…。

# はじめに
今回は、Python3の文字コードについてまとめておこうと思う。

最近、他のサイトのデータを持ってきて、整形する作業をやってみたが、
requestで持ってくるときや、ファイル書き込みするときにErrorや文字化けが…。

色々サイトを漁ってもよくわからなかったので、詳しい人に聞いてみました。
以外とスッキリした気がするので、ここに書いておこうと思う。

# 文字コードとは
まず文字コードとは何ぞやという人もいると思い、簡単に書いてみる。

端的に言うと、
###文字1つに対して、1つの2進数が割り振られているもの
だと思います…。

ある文字に対して、1つの通し番号が割り振られており、
その通し番号で、どの文字に変換するかを決めたもの。

# Python3の文字コードは??
では、Python3の文字コードは何が使われているのか。

全体を図にするとこんな感じ。
![picture_for_qittq_strcode.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988190/ae980276-0c5b-eb51-6e53-d50b2f779843.jpeg)


これを1つずつ説明していく。

##Python3の文字について
Python3内の変数などに格納される文字は、**Unicode**。

```python:PythonConsole
>>>'あ' == u'\u3042'
True
```

Python2だとstring型とか色々あったらしいが、
少なくともPython3の文字はこれで統一されているみたい。

##.pyファイルの文字コード
Pythonのコードが書かれたファイルは**UTF-8**で書かれている。

試しに以下のようなファイルを作成して

```python:test_python_file.py
test = "こんにちは世界"
```
WindowsのConsole(Shift-jis)で出力してみると

```config:console(Windows)
>type test_python_file.py
test = "縺薙ｓ縺ｫ縺｡縺ｯ荳也阜"
```

.pyのファイルは**UTF-8**で書かれているため、もちろん文字化けする


##Pythonのプログラムで作成された.txtファイルなど
これについては、ちょっと複雑。

使っている環境(OS)で異なるみたい。

Windows -> Shift-jis
Mac, Linux -> UTF-8 


# まとめ
全体的に言いたいことは、以下の通り。

|環境|文字コード|
|:---:|:---:|
|Python3の文字|**Unicode**|
|.pyファイルのコード|**UTF-8**|
|出力ファイルなど|Windows : **Shift-jis**, Mac&Linux : **UTF-8** (環境に依存)|

この内部構造が分かっていると、文字コードのErrorとかも対処しやすそう…。

間違ってたら教えてくださるとありがたい!
[Unity]TransformのPositionのYを０にしたのにキャラクターが浮いてしまう事象の解決例

## どんな状態だったか

１枚目の画像のように、inspector内の`transformのpositionのyを0に指定`したのに、２枚目の画像のようにキャラクターが浮いてしまいました。

↓0に指定したのに再生ボタンを押すとYが1.43になってしまう。
![スクリーンショット 2020-12-29 13.32.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/94991d4b-160a-c98f-8210-238496911fc9.png)

↓実際に浮いてしまっている様子。
![スクリーンショット 2020-12-29 13.32.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/5119ba30-6407-b4e4-e8c4-6d4afd5239e7.png)



## 原因
CharacterControllerの衝突判定をしているHeightをキャラクターより大きくして、はみ出た部分を地面埋め込むように設定していたのが原因でした。

↓衝突判定の楕円が地面にめり込んでしまっている様子。実際はめり込まずにキャラクターを押し上げてしまう。
![スクリーンショット 2020-12-29 13.42.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/46511cf1-09ef-6c73-6269-dc316f3eb13e.png)




## 解決方法
CharacterControllerのCenterとHeightの数値を調整して、下記の図のように衝突判定のエリアが地面にめり込まないようにすることで解消できます。

![スクリーンショット 2020-12-29 13.44.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/7fde865f-e96a-6e0e-bbd1-7ced019158e5.png)


ちなみに筆者の場合はキャラクターの全長が0.8だったので、下記の図のようにCenter = 0.4,Height = 0.8 としたら浮かばず接地した状態にすることができました。

↓Center = 0.4,Height = 0.8とした。
![スクリーンショット 2020-12-29 13.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/386fd0b2-f9a4-518b-471a-c43018db6567.png)


↓修正後に接地できていることが確認できる。
![スクリーンショット 2020-12-29 13.49.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/60feaeb3-c7e6-8197-8c61-646324536a04.png)

## 参考
CharacterControllerの細かい説明は下記のサイトに記載があるので興味があればみてみてください。
公式リファレンス：
https://docs.unity3d.com/ja/2019.4/Manual/class-CharacterController.html
ナビのborderを両端以外につける方法。（隣接セレクタ）

ホームページには欠かせないナビメニュー。
そのナビメニューで項目ごとにボーダーをつけると「左端、もしくは右端のボーダーはいらないんだよな。」みたいな時ありませんか？
そんな時は『隣接セレクタ』を使います。
例えばナビメニューで
ul
 li /li
 li /li
 li /li
/ul
このようなリストがある場合
cssで、li + li {}とします。
そうすることで「リストの次に来るリスト」のにスタイルがつく為、最初と最後にはボーダーがつきません。

以上
@Autowired, @Resource, @Injectのメモ

# `@Autowired`
[Spring Framework 5.3.2 API Javadoc](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html)
Spring Framework発祥。元祖Injection。
Spring依存。

---
# JSRで仕様策定

## `@javax.annotation.Resource`
[Jakarta EE 8 仕様 API Javadoc](https://spring.pleiades.io/specifications/platform/8/apidocs/javax/annotation/resource)
JSR-250。

### Springサポート
あり。

### Beanの探索順
1. Bean名
2. 型
3. @Qualifier

## `@javax.inject.Inject`
[Jakarta EE 8 仕様 API Javadoc](https://spring.pleiades.io/specifications/platform/8/apidocs/javax/inject/inject)
`@Autowired`を一般化
JSR-330。

### Springサポート
あり。ただし、インタフェースの依存関係が必要。

#### gradle
```gradle
implementation 'javax.inject:javax.inject:1'
```

#### maven
```xml
<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>
```


### Beanの探索順
1. Bean名
2. 型
3. @Qualifier