OmniAICreator/Qiita-1.07M huggingface dataset:
UserLAnd/Termuxとキーボードまとめ

# 概要

- LinuxやUnix系OSを使っていると様々なキーバインドが思った通りに設定されていないと使いづらいことがよくある
- 典型的には、ハードウェアキーボードでCapsLockがCtrlになっていてほしいとか、EmacsではCtrl-spaceでマークできないと困るとかがある
- この記事では、UserLAnd/Termuxを使う上でのキーボード・キー入力がらみの設定をまとめる

# 環境

- Pixel 4a 5G(android 11)
- ハードウェアキーボード： MOBO keyboard
    - https://mobo-jp.com/products/mobo-keyboard/

# ソフトウェアキーボード

- Gboard
    - 日本語キーボードだけだと単語を確定させるのが面倒なので、英語キーボードも入れておく
    - UserLAndのsshやTermuxを使うときは自動で英語キーボードになる
- Hacker's Keyboard
    - GBoardの英語キーボードで足りない場合はこちらを使う
    - https://play.google.com/store/apps/details?id=org.pocketworkstation.pckeyboard

# ハードウェアキーボード

- ハードウェアキーボードを使う場合は、キーマップを変更するためにKCMリマップを入れる
- KCMリマップ： https://play.google.com/store/apps/details?id=jp.kcm.thumbctrl
- 設定
    - ハードウェアキーボードをBluetooth接続した状態で、設定アプリの物理キーボードの設定を開く
    - 自分が使っているキーボードをタップするとレイアウトが選べる
    - 日：[Caps]→[Ctrl]を選ぶとCapsキーをCtrlとして使えるようになる
        - 他にもいくつかのキーマップがあるのでお好みで。

# Termux

- Google PlayとF-Droidで配布されているがF-Droidが最新版
    - 今後、最新版はF-Droidのみとのこと
        - https://wiki.termux.com/wiki/Termux_Google_Play
- F-Droidはブラウザで公式ページを開いてアプリをダウンロードしてインストールする
    - F-Droid公式ページ： https://www.f-droid.org/
- Termuxの設定
    - android9以降はデフォルトではCtrl-spaceが使えない
    - ~/.termux/termux.properties に以下を書いておくとCtrl-spaceが使えるようになる
    - 公式情報: https://wiki.termux.com/wiki/Terminal_Settings
        - この設定はversion 0.105からなので、Google PlayのTermuxでは使えない

```text
ctrl-space-workaround = true
```


# UserLAnd ssh

- UserLAndのsshで使用している端末はTermuxの実装を流用したもの
- v2.8.1(2021/10/1リリース)からctrl-space-workaroundが取り込まれた
    - /host-rootfs/data/data/tech.ula/files/home/.termux/termux.properteis に設定を書けるようになった
- ~~残念ながら不具合でtermux.propertiesを読んでくれないのと、ctrl-space-workaroundの実装が組み込まれていない~~
- ~~パッチを作ったので、興味のある人はソースコードをダウンロードして自前でビルドすれば使えるようになる~~
    - ~~https://github.com/CypherpunkArmory/UserLAnd/pull/1397~~
    - ~~向にマージされる気配がないのでバイナリを公開する~~
        - ~~https://github.com/yas99en/UserLAnd/releases/tag/v.2.7.3-yas99en-1~~
- 上~~記のカスタム版のUserLAndだと以下の場所からtermux.propertiesを読むようになる~~
    - ~~/host-rootfs/data/data/tech.ula/files/home/.termux/termux.properteis~~
- termux.propertiesは以下のように記述する

```
ctrl-space-workaround=true
extra-keys = [['TAB','CTRL','ALT','ESC','/','\\\\','_']]
```
- extra-keysは端末内に固定表示されるソフトキーボードの設定
    - 公式情報： https://wiki.termux.com/wiki/Touch_Keyboard

# UserLAnd VNC

- Google PlayからRealVNCの「VNC Viewer」を入れておく
    - https://play.google.com/store/apps/details?id=com.realvnc.viewer.android
- Gogole Playを検索するとVNC ViewerとbVNCが見つかるが、bVNCはCtrl-spaceが使えないが、VNC Viewerは使える

- UserLAndでvncを立ち上げるとALTキーをMetaキーとしても使えないのでxmodmapで修正する
- エディタで~/.Xmodmapを作成して ``clear mod4`` を書いておく
- /support/startVNCServerStep2.sh をエディタで開いて以下を書いておく

```
export DISPLAY=localhost:51
xmodmap /home/$INITIAL_USERNAME/.Xmodmap
```
Apache RewriteCondでRewrite Ruleに条件を付与する

＃はじめに

ApacheでRewriteruleを使用するときに、条件を付与するRewriteCondについての備忘録

#RewriteCond

```
RewriteCond 変数名 条件(正規表現[フラグ] または　特定の構文(-fや-dなど))
RewriteRule URL書換＆転送の記述
``` 

変数名に指定されたものが、条件にあっている場合、したのRewriteRuleを評価する

```
# RewriteCond %(REQUEST_FILENAME) !-f 

# RewriteRule rewrite-test/sub2/(.+) sub1/$1
```

この場合、リクエストに送られたファイルの名前が、存在しない場合、 sub2ではなくsub1というディレクトリの方で同様のファイルを探して開いて、という命令になる。

RewriteCondの変数名は、ネットで調べると一覧が結構出てくる。

また、正規表現の横につけるフラグには3種類あり、NC、OR、NVの三つがある。

正規表現ではなく、特定の構文で条件をつける場合は、
その特定の構文もネットで調べると一覧が載っているサイトがあったりする。
特定の構文の例は、-fや-bなど（-fは、ファイルが存在する、という意味）

#まとめ

Apache全然まだまだ理解追いつかないので、書き殴ってる感じになってます。
自分以外が見ても、多分参考にならないかも、、、。
pythonでジェネレータを繰り返し利用する

# ジェネレータを繰り返し利用する

python 3.7

## 結論

自作のクラスを作成する

```python
class MyGen:
    def __init__(self.num):
        self.num = num

    def __iter__(self):
        for i in range(self.num):
            yield i

gen = MyGen(10)
for i in range(3):
    for j in gen:
        print(i, j)
```

## 目次

- ジェネレータを繰り返し利用したい理由
- ジェネレータの作成
- 実際に画像を都度読み込むジェネレータ
- tqdmで使う

## ジェネレータを繰り返し利用したい理由

画像認識用のAIでの学習でIter毎に画像を読み込む処理をする必要がありジェネレータを利用した。
AIの学習ではエポックと呼ばれる全てのデータを1回利用することを1単位と取るモノを複数利用しなければならない。
故に繰り返し使えるジェネレータが必要とされた

## ジェネレータの作成

関数におけるジェネレータは繰り返し使うことができない（僕が知っている限りでは）。
次のプログラムは最初の繰り返しのみ結果を返す。

```python

def mygenerator(num:int) -> int:
    for i in range(num):
        yield i

gen = mygenerator(10)
for i in range(3):
    for j in gen:
        print(i, j)
```

そこでクラスの`__iter__`メソッドを利用する。参考：[Pythonのイテレータとジェネレータ](https://qiita.com/tomotaka_ito/items/35f3eb108f587022fa09)

```python
class MyGen:
    def __init__(self.num):
        self.num = num

    def __iter__(self):
        for i in range(self.num):
            yield i

gen = MyGen(10)
for i in range(3):
    for j in gen:
        print(i, j)

```

## 実際に画像を都度読み込むジェネレータ

```python
import cv2
import numpy as np

class MyGen:
    def __init__(self, paths:list):
        self.paths = paths

    def __iter__(self) -> np.ndarray:
        for path in self.paths:
            img = cv2.imread(path)
            # 前処理とかココに記述してもいいかも
            yield img

img_paths = ["./0001.jpg",
             "./0002.jpg",
             "./0003.jpg",]

gen = MyGen(img_paths)

epoch = 3
for ei in range(epoch):
    for img in gen:
        print(img.shape) 
```

## tqdmで使う

繰り返し動作を視覚的に表示してくれるtqdmライブラリという物がある。
コレを利用することで1エポックの時間等が把握できる

```python
# おためし
import tqdm
import time

# １重ループ
for i in tqdm.trange(10):
    time.sleep(0.1)

# ２重ループ
for i in tqdm.trange(3):
    for j in tqdm.trange(10)
        time.sleep(0.1)

# リスト
items = [i for i in range(10)]
for item in tqdm.tqdm(items):
    time.sleep(0.1)
```

これをジェネレータでも利用できるようにするには`__len__`メソッドを利用する。

```python
import tqdm
import time
# 省略のために継承を利用
class MyGen2(MyGen):
    def __len__(self):
        return len(self.paths)

gen = MyGen2(img_paths)

for ei in tqdm.trange(epoch):
    for img in tqdm.tqdm(gen):
        print(img.shape)
        time.sleep(0.5)
```
C#(Windows Formアプリケーション)でコンソールの表示、非表示、出力方法(Console.WriteLine())

## 前書き

アプリケーション作っていると、デバッガからしか使えないDebug.WriteLine()ではなく、コンソールに表示したいと思う時があります。コンソールの表示、表示はWindows APIを直接呼び出す必要がありますが、組み込むと下記の用途に使うことができて便利です。

・Formアプリケーションでコンソールウィンドウを表示して、ログ出力の代わりにしたい
・常に出しておきたいわけではないので、コンソールウィンドウの表示、非表示を切り替えたい

https://github.com/murasuke/AllocConsoleCSharp

![alloccosole.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/40fa1a7d-c7a7-9f06-51c9-0c9e2d58daa0.png)

Trace.WriteLine() + [DebugView](https://docs.microsoft.com/en-us/sysinternals/downloads/debugview) という方法もあります。
Consoleを使うと別ツールが不要で、お手軽です。

## 注意点

デバッガから実行すると、Console.Write()の出力がデバッガ「出力」ウィンドウにリダイレクトされてしまうのでご注意ください。
(コンソールに出力されないなーと小一時間悩んでしまいました)

## ソース

フォームにボタンを3つ配置し、コンソール表示、出力、コンソール非表示を行います。
短いソースですので、説明はインラインのコメントをご確認ください。(フォーム生成もMain()メソッドでやっています)

```C#
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace AllocConsole
{
    static class Program
    {
        [DllImport("kernel32.dll")]
        private static extern bool AllocConsole();

        [DllImport("kernel32.dll")]
        private static extern bool FreeConsole();

        /// <summary>
        /// Windows FormアプリケーションでConsoleを利用する最低限のサンプル
        /// </summary>
        [STAThread]
        static void Main()
        {
            // VisualStudioでデバッグすると、デバッガの「出力」にリダイレクトされることに注意
            // Consoleに出力させるためには、デバッガを利用せずに起動すること。

            // コンソール表示ボタン
            var btnShow = new Button() { Location = new Point(10, 10), Text = "Show cons" };
            btnShow.Click += (sender, e) =>
            {
                // Console表示
                AllocConsole();
                // コンソールとstdoutの紐づけを行う。無くても初回は出力できるが、表示、非表示を繰り返すとエラーになる。
                Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true });
            };

            // コンソール出力ボタン
            var btnWrite = new Button() { Location = new Point(10, 60), Text = "Write cons" };
            btnWrite.Click += (sender, e) => Console.WriteLine(DateTime.Now);
            // コンソール非表示ボタン
            var btnHide = new Button() { Location = new Point(10, 110), Text = "Hide cons" };
            btnHide.Click += (sender, e) => FreeConsole();

            // フォームに表示
            var form1 = new Form();
            form1.Controls.Add(btnShow);
            form1.Controls.Add(btnWrite);
            form1.Controls.Add(btnHide);

            Application.Run(form1);
        }
    }
}
```
残プロ　第-30回　~BootStrapでタスク一覧を表示する~

# for文でhtmlを操作

タスク一覧をcsvファイルから読み取ります．なので．前もって**タスク数**を知ることはできません(タスク数に上限を設けることはできますが)．HTMLに工夫が必要なわけです．

今回はFlask経由でHTMLを扱っているためjinja2が利用できます．[公式ドキュメント](https://jinja.palletsprojects.com/en/3.0.x/nativetypes/#examples)に使用例が示されています．

実際には{% for task in tasks %}と書くことで配列を1つづつ取り出すことができます．


~~~ html:
{% extends "layout.html" %}
{% block body %}

<h2>Task List</h2>
<br>
<br>
<table class='table table-striped table-responsive-sm'>
    <thead class='thead-light'>
        <tr>
            <th scope='col'>タスク名</th>
            <th scope='col'>期限[日]</th>
            <th scope='col'>期限[時間]</th>
            <th scope='col'>繰り返し</th>
            <th scope='col'>重要度</th>
        </tr>
    </thead>
    <tbody>
        {% for task in tasks_csv[1:] %}
        <tr>
            <th scope='row'>{{ task[0] }}</th>
            <td>{{ task[1] }}</td>
            <td>{{ task[2] }}</td>
            <td>{{ task[3] }}</td>
            <td>{{ task[4] }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

{% endblock %}
~~~

### 実行結果
![task_html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578927/c9ba8e7d-7cd8-2bf0-b091-6537ec590169.png)

無事表示できました！
define の実体 ― J 言語入門

explicit definition に使う `define` という単語は実はキーワードではなく、標準ライブラリで定義されています。この記事では、どういった仕組みになっているのかを確認します。

# define の定義

REPL に `define` を入力してみましょう。

```j
   define
 :0
```

見慣れない記号が出てきました。`0` は普通に数値の 0 ですが、その前に `:` があります。

`:` は conjunction で、`:0` は部分適用によって作られた adverb です。つまり、`monad define` は `define` という adverb に被演算子 `monad` を渡していることになります。

となると、今度は `monad` の定義が気になりますね。

```j
   monad
3
   dyad
4
   verb , adverb , conjunction , noun
3 1 2 0
```

なんと、全て整数になっています。(ちなみに `monad` と `verb` は同じ値です。) そのため、`monad define` の代わりに `3 : 0` と書くこともできます。

# conjunction `:`

`:` には、いくつかの異なる使い方があります。

## `m : 0`

explicit definition を開始します。conjunction なので、式の一部として使えます。

```j
   NB. noun define は 0 : 0
   <noun define
***
)
┌────┐
│*** │
└────┘
   NB. monad define は 3 : 0
   monad define i.5
      2 * y
   )
0 2 4 6 8
```

## `m : n`

explicit definition の定義が短いとき、`m : n` (*`n` は文字列*) を使うと一行で書くことができます。この用途のために、`def` という名前が定義されています。

```j
   def
 :
   NB. 括弧 ( ) は無くても同じ
   'left' (dyad def 'x ; y') 'right'
┌────┬─────┐
│left│right│
└────┴─────┘
   NB. ' のエスケープに注意
   (monad def 'y $ ''text''') 2 2
te
xt
```

`m : n` は explicit definition (`m : 0`) の内部でも使えます。

## `u : v`

`u : v` は、上の 2 種類とは全く違う意味で、dual-valence [^1] の verb を作る機能です。monad として使われたときは `u` が実行され、dyad の場合は `v` が実行されます。

```j
   sum=: +/ : ([: +/ ,)
   NB. +/
   sum 2 5 4 7
18
   NB. [: +/ ,
   1 10 sum 2 5 4 7
29
```

explicit definition と組み合わせることもできます。これによって**省略可能な引数**を実現できます。

```j
   increment=: 1&$: : (dyad def 'x + y')  NB. この括弧は必須 (modifier は左から右)
   increment 2
3
   2 increment 3
5
```

`$:` は、verb を作る train の中で使うと**その train 自身を返す** verb です。tacit definition で再帰呼び出しをするのにも使われます [^2]。

ここでは `$:` は train `1&$: : (dyad def 'x + y')` を指し、`1&` で `$:` に左の引数 (デフォルト引数) を与えているので最終的には dyad 側が実行されます。

`u : v` のどちらかの被演算子を `[:` にすると、monad もしくは dyad の**一方の使い方のみに限定**することができます。`[:` の、実行されると必ずエラーが発生するという性質を利用しています。

```j
   NB. dyad として使ってほしい
   multiply=: [: : *
   2 multiply 3
6
   NB. [: が実行されるのでエラー
   multiply 2
|domain error: multiply
|       multiply 2
```

---

\[ 前 : [複数行のリテラル](https://qiita.com/unsigned-wrong-wrong-int/items/4f63903f7ae00b145ee6) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [direct definition](https://qiita.com/unsigned-wrong-wrong-int/items/6214e76feb92d7c2e756) \]

[^1]: monad としても dyad としても実行できること。
[^2]: train 以外で使うと無限に再帰してしまうので explicit definition には使えません。
phpのexec() 関数で日本語戻り値の受け取り方

# 概要
phpのexec関数でコマンドを実行できるという話を聞いて、
pythonでテキストマイニングのプログラムを書き、
その結果をphpに返すということをしてみたんですが、、、
まぁめっちゃ苦戦したよね。
返り値として日本語をphpに渡すことを考えてる人の一助になればと思います。
# exec関数の使用例
実行したいコマンドと返り値を受け取る変数を指定する場合の例。

```php:sample.php
#ここには実行したいコマンドを指定（この例では.pyを指定）
$command=" ./test.py ";

#実行結果が$outputにリスト形式で格納される。
#格納されるのは標準出力の内容
exec($command,$output);
#結果の確認
print_r($output);
```

#  前提条件
さて、ざっくりexec関数の使い方を見たところで本題のexec関数の返り値として日本語を受け取る方法を見ていく。前提としては、以下２つ。
・ブラウザ上でphpを動かした際に日本語が表示できる
・実行させたいプログラムをブラウザ上で動かした際に結果を日本語で表示できる
(各動作で日本語表示できない場合は、exec関数で値を受け渡す以前の問題である可能性が高い)

#  exec()関数で日本語返り値の受け取り方
$command に export LANG=ja_JP.UTF-8; っていう設定を渡すことで日本語を返り値として受け取れる。

```php:sample.php
#ここには実行したいコマンドを指定（この例では.pyを指定）
$command="export LANG=ja_JP.UTF-8; ./test.py ";

#実行結果が$outputにリスト形式で格納される。
#格納されるのは標準出力の内容
exec($command,$output);
#結果の確認
print_r($output);
```
ちなみに、
export LANG=ja_JP.UTF-8; はサーバーの設定によっては export　LANG="en_US.UTF-8" になったりもする。サーバーの設定に合わせる必要があるけど、どんな設定になってるかを調べるには、正常に動いているphpでこれを実行すると確認できる。

```php:LANG.php
php -r "echo shell_exec('echo $LANG');"#LANG設定が確認できるよ
```

# 最後に
こうゆうおまじない的な設定は知ってるとすぐ対応出来るけど、知らないとめちゃくちゃ時間かかるよね。。。解決しても達成感ないし、、、なんなんだよほんとに！ってことで最後までお付き合いいただきありがとうございました。今後ともよろしくお願いします。
バージョン指定でLaravelのプロジェクトをインストール

Laravelのプロジェクトをインストールする方法は、2通りあります。

1. Laravelインストーラー経由からインストールする方法。
2. Composer経由からインストールする方法。

1のLaravelインストーラー経由からインストールすると、常に最新版がインストールされます。
バージョン指定で開発ができないので、バージョン指定したい場合、必ず、2でインストールしましょう。

今回は、2だけ紹介します。

# Composer経由からインストールする

1：Composerをインストールする。


```
curl -sS https://getcomposer.org/installer | php
```

2：ダウンロードしたファイルを「usr/local/bin」に移動させます。

```
sudo mv composer.phar /usr/local/bin/composer
```

3：配置したComposerのパーミッションを変更します。

```
chmod a+x /usr/local/bin/composer
```

4：Composer経由からLaravelプロジェクトをインストール

```
composer create-project laravel/laravel PROJECT_NAME 5.8 --prefer-dist
```

PROJECT_NAMEで、プロジェクトの名前を記述し、5.8と書かれているところでインストールしたバージョンを指定することができます。
AtCoderログ：0002 - ABC 086 A

# 問題

https://atcoder.jp/contests/abc086/tasks/abc086_a

## 問題文
> シカのAtCoDeerくんは二つの正整数 $a, b$ を見つけました。$a$ と $b$ の積が偶数か奇数か判定してください。

## 制約
> ・$1 \le a, b \le 10000$
> ・$a,b$ は整数

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067)([第01問](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-1-%E5%95%8F--abc-086-a---product-100-%E7%82%B9))
- [AtCoder Beginner Selection](https://atcoder.jp/contests/abs)

# 回答
## 回答1 (AC)

AtCoder で最初に解いた問題です。正整数 $a,b$ を受け取り、積が偶数か奇数かを判定する流れをそのままコーディングすれば良さそうです。以下のようなコードで無事ACとなりました。

```C++:abc086a-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int a, b;
  cin >> a >> b;

  if ( (a*b)%2==1 ) {
    cout << "Odd" << endl;
  } else {
    cout << "Even" << endl;
  }
}
```

## 回答2 (AC)

２つの整数の積は、両方の整数が奇数なら奇数、それ以外は偶数になるので、積が偶数か奇数かの判定をする上で積計算は必要ありません。この性質を利用したコードは以下のようになり、もちろんＡＣとなりました。

```C++:abc086a-2.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int a, b;
  cin >> a >> b;
 
  if ( a%2==1 && b%2==1 ) {
    cout << "Odd" << endl;
  } else {
    cout << "Even" << endl;
  }
}
```

今回の場合、正整数 $a,b$ は高々14ビット(10000以下)なので、積は高々28ビットであり、C++ の整数型(int)は32ビットであることから、積を計算しても桁あふれは起きません。従ってこのコードは用心しすぎなのですが、一般に計算せずに計算結果の性質を判定できる場合には、計算せずに判定すべきです。

# 調べたこと
## [AtCoderに登録したら次にやることの解説](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-1-%E5%95%8F--abc-086-a---product-100-%E7%82%B9)
回答とほぼ同じ解法でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc086/tasks/abc086_a/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/arc089/editorial.pdf)
こちらも同じ解法でした。

# 学んだこと
- C++ の標準入力 (整数型)
- C++ の整数型(int)は32ビット

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0001 - AtCoderはじめました](https://qiita.com/RoadLynton/items/82fa87b8b0cedb62d7e7)
- 次の記事 → [AtCoderログ：0003 - ABC 064 A](https://qiita.com/RoadLynton/items/bc4ef08c45e0bf485d77)
量子コンピューティングの資格取得

##はじめに
これは私が知識ゼロから、量子コンピューティングの資格である[Fundamentals of Quantum Computation Using Qiskit v0.2X Developer](https://www.ibm.com/certify/exam?id=C1000-112)を受験＆取得するまでの記録です。
もし同じような境遇のかたいらっしゃいましたら、一緒に頑張りましょう！


##経歴紹介
私の経歴は以下のような感じです。

* インフラエンジニア歴10年以上
* プロジェクトマネージャー歴はそこそこ。最近はマネジメントの仕事が多い。
* 最近数年はPublic Cloud（Microsoft Azure）の設計構築なんでもOK！SaaSも組み合わせて設計します。
* 未知の技術には興味津々
* プログラミング能力はゼロ、シェルスクリプトも怪しいレベル。。。
* 量子力学、古典力学などの知識ゼロ。もちろん量子コンピュータって何？ってレベルです。
* 英語力はほとんど無しだが、英語に抵抗もない（DeepLやGoogle翻訳を駆使）

##量子コンピュータに興味を持ったきっかけ
特に誇れる学歴も無く、飛び抜けたスキルも無い、最新技術は若い人に任せたほうが上手くいく、、、上位レイヤー目指してプロジェクトマネジメント、ビジネスアナリシスのスキルを磨いてきたけど、もっと何かやりたい、、、と考えていた時に、以下の記事を見ました。

[IBM、量子コンピューター業界初の開発者認定資格を提供開始](https://www.ibm.com/blogs/think/jp-ja/quantum-developer-certification/)

見た時、次に取得する資格はこれだ！！！と直感で決めました。
理由は以下です。

* 量子コンピューターってなんか格好いい
* 「業界初」というキーワードに惹かれた
* 量子コンピューターが実用化されれば革命が起きそう！そこに自分も関わりたい

こんな感じです。
あとは、私の勤めている会社/業界(SIer)では量子コンピューターの勉強している人はいないだろうなー私が一番乗りになれそうだなー、という理由もありますね。

##参考にした（している）書籍など
知識が何もない状態で何から始めて良いか分からなかったので、Kindleで以下の書籍購入して量子コンピューターとはなんぞや？というところから勉強しています。

***
[量子コンピュータが本当にわかる！ ― 第一線開発者がやさしく明かすしくみと可能性](https://www.amazon.co.jp/gp/product/4297111357/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4297111357&linkCode=as2&tag=grnhjytrg5648-22&linkId=5737e73211ee058e596ebc668d1f5e91)
<img width="140" alt="qiita-square" src="https://m.media-amazon.com/images/I/51C+dMU94PL.jpg">
量子コンピューター初心者の方にはお勧めの本です。量子コンピュータとは何か？どういう仕組みなの？サイン情報は？などなど読み応えありです。
***

[Qiskit 量子プログラミング入門](https://www.amazon.co.jp/gp/product/B07NB942LL/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B07NB942LL&linkCode=as2&tag=grnhjytrg5648-22&linkId=43056916e9dac9646bef629eba864668)
<img width="140" alt="qiita-square" src="https://m.media-amazon.com/images/I/51LZ4NuDwgL.jpg">
資格取得目的のためにQiskitの本を購入しましたが、、、突然内容の難易度が跳ね上がりましたw
まだ４割くらいしか読みながら実践していませんが、Pythonや量子力学の知識無しでは？？？な状態です。
***

## 最後に
最短で資格取得することを目的に、本買って実践してましたが、やはり基礎が必要なことがわかりました。
[Qiskit 量子プログラミング入門](https://www.amazon.co.jp/gp/product/B07NB942LL/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B07NB942LL&linkCode=as2&tag=grnhjytrg5648-22&linkId=43056916e9dac9646bef629eba864668)は少しずつ進めるにしても、量子力学、古典力学、Pythonも並行して勉強したいと考えています。
AtCoderログ：0001 - AtCoderはじめました

# ごあいさつ
こんにちは、RoadLynton です。AtCoder に挑戦することを思い立ったので、Qiita にログを記録していきます。IT系の企業の会社員ですが、プログラミングは趣味で取り組んでいます。これまで C や Python をいじってきました。AtCoder をはじめるにあたり、今回は新たに C++ にチャレンジします。大学でアルゴリズムやデータ構造を勉強した記憶はありますが、その程度です。知識より気合いで勝負、という感じです。おつきあいのほど、よろしくお願いします。

# 取り組み方
[AtCoder](https://atcoder.jp/) についていろいろ調べてみたところ、本を買うよりはウェブを使って勉強するのが良さそうなこと、初心者はまず[「AtCoder Beginners  Selection」](https://atcoder.jp/contests/abs)を解くのが良さそうなことがわかりました。
しかし、そこで紹介されている問題は[「AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～」](https://qiita.com/drken/items/fd4e5e3630d0f5859067)からピックアップされたようなので、問題数が多い[「AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～」](https://qiita.com/drken/items/fd4e5e3630d0f5859067)で言及されている問題を１日１問のペースで解き、そのログを Qiita に記録していきたいと思います。
なお、C++の習得については、空き時間に [C++入門 AtCoder Programming Guide for beginners (APG4b)](https://atcoder.jp/contests/APG4b) を進めていこうと思います。 
登録などが面倒なので、AtCoder のウェブサイトで学習可能な問題だけに注力しようと思います。毎週、開催される ABC にもリアルタイムで参加しようと思っています。全ての問題を解き終えたらば、またその時に次の方針を考えようと思います。目指せ１日１AtCoder & １日1 Qiita (語呂悪っ)。

# リンク
## 前後の記事
- 次の記事 → [AtCoderログ：0002 - ABC 086 A](https://qiita.com/RoadLynton/items/b50fcf597e2a12083fa0)

## まとめ記事
- [AtCoderログ：0032 - 「AtCoder に登録したら次にやること」のまとめ](https://qiita.com/RoadLynton/items/be2bb98e5d0c0f30628b)
cookie session cacheの違い

##初めに
webアプリを作成する中でcookie、session、cacheの違いが気になったので調べてみました。

##cookie
・webサイト訪問者の情報を一時的に保存する仕組み。ユーザーの識別を目的としている。
・テキストファイルとしてwebブラウザに保存される。
・ページに再訪問した際に、保存したcookieを使用することでユーザーを特定することができる

具体的にはwebサーバーにアクセスする度に、webサーバーからブラウザへのHTTPレスポンスのヘッダーを利用して、```名前=値```の形式でデータを送信します。送信されたデータはブラウザが同じサーバーにアクセスする際にサーバーへ送信されます。
##session
>コンピューターネットワークにおけるセッションとは、通信の開始から終了までを指します。クライアントとサーバーで通信を行う場合であれば、クライアントからサーバーへ接続した時点でセッションが始まり、サーバーから切断するとセッションが終了します。この一連の流れを管理することをセッション管理と言います。

https://www.ntt.com/bizon/glossary/j-s/session.html

セッションはwebブラウザが閉じるまで保存されます。
 上記のセッション管理の仕組みとして、webサーバーは セッションを識別するためのIDを作成し、そのIDをcookieに格納してクライアントに送信します。クライアントはwebサーバーにアクセスする際に、サーバーにcookieを送信します。
サーバーは、cookie中のセッションIDからユーザーの情報(買い物かごに入れた商品情報、ログイン情報等)を識別します。このようにブラウザに保存されたIDからサーバーの保存されたユーザー情報を識別仕組みが存在することにより、クレジットカード情報などの個人情報を送信することなく通信することが可能です。

##cache
キャッシュとは、一度表示したページのデータ(HTMLや画像)をブラウザに一時的に保存する仕組みです。
頻繁に訪れるサイト情報を保存することでサーバーと通信することなく表示することができるので、表示速度を向上させルことができます。
また一度アクセスしたことのある(キャッシュを持つ)サーバーの異なるページにアクセスする際には、ページのデータを受け取る必要はありますが、DNSサーバーによって行われる名前解決は、キャッシュにより省略されます。


##終わりに
今まで何となくしか理解できていませんでしたが、調べてみるとそれぞれの違いが見えて面白いですね!


参考　

https://ssaits.jp/promapedia/technology/cookie-session-cache.html
【nginx】ローカルDockerでリバースプロキシを設定する

「nginxでリバースプロキシの設定が動かない！助けて！」という依頼を受けた際に、ローカルDockerで環境を作って動作確認した際のメモ

## 環境
- macOS BigSur(11.2.3) ※ Intelチップ
- docker desktop(3.2.2)

## 手順
#### 1. リバースプロキシ用の設定ファイルを用意

```conf:default.conf
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    
    location ^~ /sub_directory/ {
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-Proto https;
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass {{ 接続先URL or IP }};
    }
}
```

#### 2. nginxコンテナ立ち上げ
```bash
docker run --name hogehoge -v /Users/user_name/default.conf:/etc/nginx/conf.d/default.conf:ro -p 8080:80 nginx
```

### 3. 動作確認

confファイルの`proxy_pass`に

```
proxy_pass http://hogehoge.com/test
```

上記のような設定をしている場合は、
http://localhost:8080/sub_directory のアクセスが
http://hogehoge.com/test にリバースプロキシされる

## 参考
- [docker hub - nginx](https://hub.docker.com/_/nginx)
[02] PowerShell実践例 ... Samba 認証の自動化



|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/0b0605257ad39bc22895|

|その他 - 関連記事|
|:--|
|[[備忘録] Samba サーバおよびクライアントの実践例](https://qiita.com/robozushi10/items/47ea76140de4d3605cf3)|


# はじめに

CI/CD の中で Samba 認証の自動化が必要になったので、書き残しておく.

　

# 環境

```
Windows 10 Pro
PowerShell バージョン 6系
```

　

# 接続条件

| 項目 | 値 |
|:------:|:----:|
| サーバ名 | myserver |
| ユーザ名 | myname |
| パスワード | mypassword |
| 所属ドメイン | mydomain |

# コード

```powershell
try
{
  $local:SVR = '\\myserver'
  $RET = (New-SMBMapping -RemotePath $local:SVR -Username 'mydomain\myname' -Password mypassword)
  if($($RET.Status) -ne 'OK')
  {
    throw "$local:SVR へのアクセスに失敗しました"
  }
}
catch
{
  Write-Host "$($_.Exception.Message)"
}
```
iOSとandroidでウィジェットを切り替える方法

##インポートする
```dart
import 'dart:io' show Platform;
```

show　をつけることで必要なクラスだけを読み込める


##ウィジェットの表示切替え

```dart
class ChangeWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Platform.isIOS ? IOSWidget() : AndroidWidget(), //ここで切り替え
    );
  }
}

class IOSWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: () {},
      child: Text('sample iOS button'),
    );
  }
}

class AndroidWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: () {},
      child: Text('sample Android button'),
    );
  }
}
```

bool型で

isAndroid 
isFuchsia
isIOS
isLinux
isMacOS
isWindows

が使える。



<a href="https://www.buymeacoffee.com/neruk" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" width=200></a>
USBをクリーンする．パティーション削除．windows10

Usb内部にできたパティーションを削除するのは，GUIではできない．コマンドプロンプトなら標準でできる．

コマンドプロンプトでdiskpartを起動する．

```:cmd
diskpart
list disk
```

スリーンしたいディスクを選択し，全消去する．注意！！

```:cmd
select disk 1
detail disk
clean
```

スタート画面右クリック，「ディスクの管理」を起動し，結果を確認する．



#USBから起動する方法　付録
BIOSを起動させずに，起動ディスクをUSBにする方法．
1 スタートメニュー，電源ボタン，右クリックしながら再起動．
2 デバイスの使用
3 EFI USB Device
USBからOSが起動する．
JavaScriptで指定回数分の処理を繰り返す


# 概要
元の配列がないけど、指定回数分繰り返し処理を行った上で配列を作成する方法を探していました。

# 結論
個人的に最も簡潔に記述できるのは、Arrayオブジェクトをスプレッド構文で展開して配列を作成し、map(もしくは、forEach)を用いてループする方法だと思います。

```javascript
[...Array(10)].map(() => console.log('10回実行されます'));
```

ちなみにArray(ｎ)で生成されるのは空のスロットを持つ配列であり、実際の値(undefinedや空文字を含む)が入ったスロットではない。mapやforEachは空の要素に対しては呼び出しを実行しないため、以下のケースではループ処理が実行されません。

```javascript
Array(10).map(() => console.log('ループ処理が実行されません'));

const arr = new Array(10);
arr.map(() => console.log('ループ処理が実行されません'));
```

# その他のループ処理方法
```javascript
// Array(n).fill()
// 記述が短くて良さげ
Array(10).fill().map(() => console.log('10回実行されます'));

// Array.from({ length: n })
// ぱっと見でわかりやすい
Array.from({ length: 10 }).map(() => console.log('10回実行されます'));
Array.from({ length: 10 }, () => console.log('10回実行されます'));

// Array.apply(any, Array(n))
// 古い環境でも使えるのが利点
Array.apply(undefined, Array(10)).map(() => console.log('10回実行されます'));
```

# 最後に
個人的にはやはり[...Array(n)].map(fn)を使うのがいいと思います。
【キャッチアップ】zabbix

### zabbix5.0の紹介
https://www.youtube.com/watch?v=fPvszqWf-gI&list=WL&index=3

### 入門的な動画
https://www.youtube.com/watch?v=xkAA6vnH8gs

https://www.youtube.com/watch?v=GktOmjQlwH0&t=0s

https://youtu.be/PnHZk0-lJLE

### ダウンロードサイト
https://www.zabbix.com/jp/download
週刊Transformer（画像認識向け）4号

凄まじい勢いで増殖中のTransformer論文＋αにとりあえず、目を通しつつコメントを残していく。内容があっている保証はない。

[Vision Permutator: A Permutable MLP-Like Architecture for Visual Recognition](https://arxiv.org/pdf/2106.12368.pdf)
ViTのAttentionパーツをPermute-MLPに変換。MLP-mixerと違って、パッチをTokenとして行列化させずに絵の場所情報は取っておく。追加データなしで学習出来て、他のよりかなり良い。

[VOLO: Vision Outlooker for Visual Recognition](https://arxiv.org/pdf/2106.13112.pdf)
ViTで、パッチを取らないでLocal WindowをつかったOutlook Attentionというのを提案して、追加データなしでSOTA達成。

[Self-Supervised Learning with Swin Transformers](https://arxiv.org/pdf/2105.04553v2.pdf)
マイクロソフト論文。Self-supervised learningのMoCo V2とBYOLにTransformerのバックボーンを入れたMoBYをTuning。MoCo V3とDINO（バックボーンがDeiT)よりちょっと良い。

[SODA10M: Towards Large-Scale Object Detection Benchmark for Autonomous Driving](https://deepai.org/publication/soda10m-towards-large-scale-object-detection-benchmark-for-autonomous-driving)
自動運転向けのデータセット。semi-supervisedをやるにあたり、今までのはタグなしデータがないので増やした。1000万のラベルなしデータ、2万のラベル（カテゴリーは6種）ありデータ。

[Are Self-Driving Cars Really Safer Than Human Drivers?](https://thegradient.pub/are-self-driving-cars-really-safer-than-human-drivers/)
自動運転の安全性について。面白い！

[Gradient-Based Interpretability Methods and Binarized Neural Networks](https://arxiv.org/pdf/2106.12569.pdf)
Binarized Neural Networksはエッジに良いけど、うまく行くのかは未だに謎。いろんなSaliency mapで出来てるかチェックしてみた。

[Quantization Aware Training, ERNIE and Kurtosis Regularizer: an empirical study](https://arxiv.org/pdf/2106.13035.pdf)
すでに学習済みのネットワークがあるときに、量子化を考えた学習手法は使えないが、なんとかする方法見せるよ。

___

[PVTv2: Improved Baselines with Pyramid Vision Transformer](https://arxiv.org/pdf/2106.13797v2.pdf)
[Pyramid vision transformer](https://export.arxiv.org/abs/2102.12122)のVersion 2.いろいろConvとか混ぜて、更に良くなった。

[P2T: Pyramid Pooling Transformer for Scene Understanding](https://arxiv.org/pdf/2106.12011.pdf)
PoolingとDownsamplingを含めたViTで、Classification以外にも強い。このバックボーンでいろんなタスクでSOTA。

[Real-time Semantic Segmentation via Spatial-detail Guided Context Propagation](https://arxiv.org/pdf/2005.11034.pdf)
Convベースで、Downsampling中のデータも使って細かいところまで色塗り出来るリアルタイムのSemantic Segmentation。

[Capsule Network is Not More Robust than Convolutional Network](https://arxiv.org/pdf/2103.15459.pdf)
カプセルネットは実はCNNよりRobustではないらしい？

[Exploring Corruption Robustness: Inductive Biases in Vision Transformers and MLP-Mixers](https://arxiv.org/pdf/2106.13122.pdf)
ViTはMLP-mixer、ResNet-50よりもCorruptionにRobust。

[Student-Teacher Learning from Clean Inputs to Noisy Inputs](https://arxiv.org/pdf/2103.07600.pdf)
studentのデータがくっきりしなくてもtransfer learningが出来る理由をTheoreticalに調べた。

[Deep Gaussian Processes: A Survey](https://arxiv.org/pdf/2106.12135.pdf)
Power Query グループ化した中身をN点取得する方法

# 概要
「グループ化」する対象の上位二点だけをフィルターしたい、って時などにこの方法を使ってます。

## 元データ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/724bb4d4-7a19-fc1f-208e-fb57be6e14a9.png)

## インデックス追加後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/376486ce-c7b3-e0bf-107e-9a2a41c8e58c.png)

# やり方
1. グループ化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/03cfbf65-454f-2204-0ab0-b5d76ad6585f.png)

1. インデックス列を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/ea469aa2-f10a-8aa0-0581-e567021856b5.png)

1. ↑で追加した数式を以下のように変更
     >     = Table.AddIndexColumn(グループ化された行, "インデックス", 0, 1, Int64.Type)
↑　から　↓　へ

     >       = Table.AddColumn(グループ化された行, "UpdatedData", each Table.AddIndexColumn([Data], "インデックス", 0, 1))

1. 展開するとこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/bc0646f8-2eae-54e2-c4f5-e51444c55693.png)

# 補足
カスタム関数の追加がもっと簡単に行えれば、テーブル展開時に使えるんですが・・良い方法あれば教えてくださいな。
【Rails】カラムの追加方法とカラム型のまとめ

#対象者

カラムの追加方法に関して知りたい方

#手順目次
1.コマンドの入力をする


#実際の手順と実例
###1.コマンドの入力

以下のコマンドを入力

```````
rails g migration Addカラム名Toテーブル名 カラム名:型名
````````


実例を上げると、


Usersというテーブルでtitleというカラムを追加したいと考えた時は

```````
rails g migration AddTitleToUsers　title:string
```````
と入力します。
テーブル名はschema．rbを確認しましょう。
カラム追加後の**rails db:migrate**でデータベースに反映するのを忘れずに！


以下カラム型まとめです！
データ型	　種類
integer  数値（整数）
decimal  数値（精度の高い小数）
float  数値（浮動小数）
string  文字（短い文字列）255文字まで
text  文字（長い文字列）
date  日付
datetime 日時
time 時刻
timestamp タイムスタンプ
binary バイナリ
boolean 真偽
Unityでnullセーフに書く

Unity 2020.2からC#のバージョンがあがり、C#をnullセーフで書くことができます。

# 有効にするには
using文とclass宣言の前にnullセーフを有効にする特別なフラグを書きます。

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#nullable enable

public class Hoge : MonoBehaviour
{
}
```

# nullセーフとは
nullセーフだったりnullセーフティだったりnull安全だったりと若干表記揺れがありますが、ざっくりいうとオブジェクトを格納している変数がnullになることがあるのかを明示できる言語の機能です。
これがあると、いわゆるヌルポになる原因をより簡単に見つけられるようになります。

C#でnullセーフを有効にするとオブジェクトを格納する変数は原則nullの代入を許しません。そのような箇所があると**ビルド時に警告が表示されます。**

```csharp
// 警告
List<DateTime> date = null;
```

これは今までのC#ではできたことなのでかなりの破壊的変更になります。なのでエラーではなく警告止まりなのだと思います。ですが、これがあることによりif文でnullチェックをする必要がほとんどの場合でなくなります。

ただいくつかの場合どうしてもnullにしなければならないものや、なってしまうものもあります。
例えば循環参照を断ち切るためにOnDestroyでnullを代入することがあります。
PlayerとEnemyがそれぞれに攻撃し合う処理をお互いのクラスの中で書く場合、PlayerはEnemyを、EnemyはPlayerを参照する必要があります。
どちらかが負けてフィールドから消滅する場合、OnDestroyのタイミングで循環参照を切る必要があります。

```csharp
public class Enemy : MonoBehaviour
{
    public Player player;

    private void OnDestroy()
    {
        player = null;
    }
}
```

しかしこのコードはnullセーフでは警告となります。変数playerはnullになってはならないからです。これを回避するためには2種類の方法があります。

## Optional型
1つめはnullになることがあることを示すオプショナル型にします。

```csharp
private Player? player;
```

?をつけると変数にnullを代入できます。でもこれではnullセーフを導入する意味はないのでは？と思ったかもしれませんが、nullになる可能性があるとわかったので、変数にアクセスする前にnullチェックをしなければならないのをコンパイル時に検証することができます。

```csharp
// 警告
player.hp -= atk;

// OK
if (player != null)
{
    player.hp -= atk;
}

// OK
player = null;
```

オプショナル型は処理の途中でnullになる可能性がある変数につけるとヌルポ対策にとても効きます。

## Force null
もう一つは強制的にnullを代入する方法です。

```csharp
[SerializeField]
private Player player = null!;
```

nullの後ろに!をつけるとnullセーフ型でもnullで初期化できます。

```csharp
// OK
player.hp -= atk;

// 警告
player = null;
// OK
player = null!;
```

こちらは変数の初期化時にはどうしてもnullになってしまうが、処理を始める前には必ず値が入っているので毎回nullチェックをするのは面倒というシチュエーションの時に使います。
例のようにSerializeFieldでUnityが値を入れてくれる箇所に使うとnullチェック不要で変数にアクセスできます。ただC#的にはUnityが入れるまではnullであることは変わりないので、このように書く必要があります。

# まとめ
どうしてもnullにせざるをえない箇所は例外的な書き方をしつつ、基本はnullを許容しないように書くことでバグを大幅に減らすことができます。nullセーフの機能は1ファイル毎に有効/無効にできるので導入できそうなところかできるというのも嬉しいですね。

# 余談
ちなみにiOSのSwiftでもSwiftUI以前は

```swift
private weak var UILabel! label
```

のようにシステムで後から値を入れてくれる箇所は!をつけていたのでnullセーフ言語でこのような回避方法はどうなのか？についてはあまり気にしなくていいと思います。
「python 変数の入った行列式を求めよう」を参考にWolframAlphaでやってみた。 

(オリジナルポスト)

https://qiita.com/yudaiyamashita/items/5794294b02db65d762a5


#WolframAlphaで


https://www.wolframalpha.com/input/?i=det%28%5B%5Bx%2C+3%5D%2C+%5B4%2C+-1%5D%5D%29&lang=ja

結果:
-x - 12
とりあえずRDBの全レコードをMongoDB(DocumentDB)に突っ込んでみる方法

※元ネタのブログは[こちら](https://mattylogs.com/blog/16/)

MongoDBとRDBはそもそもの思想が異なるので、RDBに持っているレコードをそのままMongoDBに移すというパターンは稀で、本来はDocumentDBらしいスキーマ構成などを考えるべきだとは思います。  
しかし、RDBからMongoDBへの以降などを検討している状態で、**「RDBに入ってるデータを全てMongoDBに移したら、データ量的にちゃんとさばけるんだろうか」「一旦テストデータとして、RDBのデータを使ってみたい」**というニーズが出てきたので、私と同じような境遇にある方に向けて、この記事を送ります。

方法としては以下の通り

1. RDBからSelectした結果をjsonファイルで取り出す（この時にユニークキーを基にIDを生成）
2. JSONファイルをMongoDBのinsert文に変換
3. MongoDBに流す

## RDBからSelectした結果をjsonファイルで取り出す

今回は以下の従業員リストを想定して行ってみます

- テーブル名 : employeeList
    - 事業所ID : officeId(主キー)
    - 従業員ID : employeeId(主キー)
    - 苗字 : lastName
    - 名前 : firstName
    - 性別 : sex
    - 年齢 : age

以下のコマンドで、employeeListから全レコードをJSONで取り出します。

```sql
-- 取得結果を書き込むファイルを宣言
\o employee_list.json

-- 全件取得結果をJSONで取り出す
WITH trimedEmployeeList AS (
SELECT 
    officeId || '_' || employeeId AS "_id",
    * 
FROM employeeList
)
SELECT to_json(trimedEmployeeList) from trimedEmployeeList;

-- 終了
\q
```

この時に、RDBの主キーを文字列結合で繋げて、MongoDBのidにしています。

idを指定しなければ、MongoDB側でユニークなオブジェクトIDが発行されるので、なくても大丈夫です。

## JSONファイルをMongoDBのinsert文に変換

JSONファイルが吐き出されたら、中身をMongoDBのinsert文にうまいこと加工します。

主にやったことは以下の通りです。

- RDBのカラム名削除
- カラムとレコードの境の線削除
- JSONの最後の}を},に変換（コンマを付けた）
- JSONを以下で囲む

```jsx
db.employeeList.insertMany([ ここにJSON ])
```

employeeListの部分はMongoDBのコレクション名にあたるので、お好みで変更ください。

## MongoDBに流す

上記で作成したMongoDBのinsert文をCLIで流したら完成！

皆が慣れ親しんだ、RDBのレコードをMongoDBに入れるとこうなるよ！みたいなモックとしてもご利用いただけるかと思います。

改めてですが、本当にMongoDBを使うとなった時には、改めてスキーマ設計をしましょうね。
SvelteでReactのCustom Hooksみたいなことをしたい

# TL;DR
svelte/storeを使いましょう。

# はじめに
カスタムフックは次のようなやつです。

```tsx:カスタムフックの例(React)
// カスタムフックの定義
const useCounter = () => {
  const [count, setCount] = useCounter(0)
  const increment = () => setCount(prev => prev + 1)
  return { count, increment }
}

// 使う側
const App = () => {
  const { count, increment } = useCounter()

  return (
    <>
      <span>{count}</span>
      <button onClick={increment}>+1</button>
   </>
  )
}
```
(シンプルさを求めて簡略化しています。実際はuseCallbackを使うかなどを考える必要があると思います。)
カスタムフックにより、ステートとロジックを外部に切り出して再利用可能にしたり、複雑なロジックを隠蔽して見通しを良くしたりすることができます。

これを、Svelteでもやりたい。VueだとCompositionAPIでカスタムフックを実現できるますが、Svelteではどうでしょうか。

# 普通に書いてみると(うまく行かない例)
SvelteではReactでいうステートを表現するのにletを使います

```html:svelte
<script>
  let count = 0
</script>
```
これを外部のファイルに切り出して見ましょう。

```js:外部のjsファイル
export const useCounter = () => {
  let count = 0
  const increment = () => count++
  return { count, increment }
}
```
svelteファイルで使ってみます。

```html:svelteファイル
<script>
  import { useCounter } from './counter'

  const { count, increment } = useCounter()
</script>

<span>{count}</span>
<button on:click={increment}>+1</button>
```
実行結果
![Kapture 2021-07-01 at 21.15.26.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297745/6c08e6cf-de13-b132-402b-fa8f2c3b00de.gif)
カウントが全く増えません。
svelteファイルのscript部分でletを使えばリアクティブな値になりますが、外部のjsファイルでletで宣言してもただの変数です。

# 外部に切り出せるものといえば、、、
Svelteで外部に切り出せる、リアクティブな値といえば標準搭載されているstoreです。
storeを使えば、以下のように動作させることができます。


```js:外部のjsファイル
import { writable } from 'svelte/store'

export const useCounter = () => {
  const { subscribe, update } = writable(0)
  const increment = () => update(prev => prev + 1)
  return { count: { subscribe }, increment }
}
```

```html:svelteファイル
<script>
  import { useCounter } from './counter'

  const { count, increment } = useCounter()
</script>

<span>{$count}</span>
<button on:click={increment}>+1</button>
```
こちらで試せます。(REPLで共有しやすいのもsvelteの良いところ)
https://svelte.dev/repl/7580c4426c1947d8aa3d149a05bdc895?version=3.38.3

![Kapture 2021-07-01 at 21.27.39.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297745/c6f54782-d738-f100-d41b-8b3d01b2da34.gif)


svelteファイル内で使うときは、`$count`と$マークを付ける必要があることに注意しましょう。
また、subscribeの挙動がわからない場合は、公式ドキュメントの[custom-store](https://svelte.dev/tutorial/custom-stores)の章を読みましょう。

ちなみに、このようにsvelte/storeを使って外部にリアクティブな値を切り出しているSvelteライブラリも多いです。
フォームライブラリの [felte](https://felte.dev/)や[svelte-use-form](https://github.com/noahsalvi/svelte-use-form)などが一例です。

# あとがき
Svelteでカスタムフックを使いたくなったらstoreを使うのが一つの方法です。
つまるところ、SvelteのstoreはReduxやVuexのストアみたいなグローバルステート以外の役割も持っているということです。
ということもあり、筆者はSvelteのstoreをグローバルステートとして使う場合は`~Store`もしくは`~State`などの命名するのが良いと考えています。こうすることで、カスタムフックで使うstore(グローバルステートではない)と区別しやすくなるはずです。
Linuxのパッケージ管理、yumコマンドまとめ


# 1. 概要

Linuxのパッケージ管理システムについて、`yum`と`RPM`をなんとなく使用していた
仕組みが気になったので、仕組みと`yum`の用途別でコマンド操作をまとめてみた

### 参考資料：[yum installで学ぶ！ yum の仕組み](https://tech-blog.rakus.co.jp/entry/2017/12/14/105052) ここ見たら流れが細部まで書いてあるので内部構造が気になった時用

# 2. パッケージ管理とは

OSや言語、等の単位当りの環境でパッケージという単位でソフトウェアを導入、削除、それらの依存関係解決を行うことができるシステム
以下ではRedHat系Linuxの標準パッケージマネージャーである`RPM`と`yum`を前提(ただしコマンド系の解説は`yum`のみ)

# 3. yumとは

パッケージ管理システムの1つで、`RPM`をラップして使っている
`RPM`の機能のほかに自動更新機能や依存関係の管理も行っている

# 4. リポジトリとは

Linuxが必要なパッケージ(アプリ∈パッケージ)を見つけ出せるようにインターネット上のどこのサーバーにパッケージが格納されているかを記載したファイルのこと

## 4.1. yumとリポジトリの関係

### 4.1.1. etc/yum.repos.d/*.repo について

`yum`が`RPM`経由でインストールや依存関係解決を行う際にここに記載されているリポジトリの場所に存在するパッケージ群に対してのみ行うことができる
記載のリポジトリ以外に対する処理はできないので注意

### 4.1.2. yumリポジトリを追加する

`etc/yum.repos.d/`ディレクトリに`～.repo`というファイルを作成し、以下最低三項目を設定する

```repo:sample.repo
[リポジトリID]
name=リポジトリ名
baseurl=リポジトリのURL
```

参考：[yum リポジトリの設定と追加](https://kazmax.zpp.jp/linux_beginner/yum_repository.html)

## 4.2. インストールまでの流れ

1. コマンドを打つ

```
$ yum -y install php
```
2. etc/yum.repos.d/*.repoを検索
3. ミラーサイト[^1]の中で一番地理的に近いサイトを選択する
4. 必要なパッケージ情報を取得する

コマンドで指定したパッケージのほかに、依存関係にあるパッケージも一緒にインストールする

# 5. 用途別コマンド集

## 5.1. パッケージ一覧の表示

```
$ yum list		#全てのパッケージを表示
>

$ yum list chmod	#chmodパッケージを表示
>

$ yum list ch*		#ワイルドカードで表示
>

$ yum list installed	#インストール済みのものだけ表示
>

$ yum list available	#未インストールの利用可能なパッケージを表示
>
```

## 5.2. パッケージ(コマンド)の検索

```
$ yum search bind	#bindパッケージの検索
>

$ yum provides chmod	#chmodコマンドが含まれるパッケージの検索
>
```

## 5.3. パッケージ情報の確認

```
$ yum info bind		#bindパッケージ情報の確認
>
```

## 5.4. パッケージのインストール

他にも種々インストール方法があるが、これだけ覚える

```
$ yum install chmod
```

## 5.5. パッケージの更新

```
$ yum check-update	#更新があるかの確認　いきなりupdateは怖いのでこれで確認してから
>

$ yum update <pkg>	#pkgをupdate

$ yum update 		#全体をupdate
```

## 5.6. パッケージの削除

```
$ yum remove <pkg>	#pkgを削除
```


[^1]: 耐障害性を考慮した、本サイトのバックアップサイトのこと
【Python】jmespathでandやor条件を使いたい

### はじめに
<バージョン>
Python: 3.6.8
jmespath: 0.10.0

　以下のようなymlから、一部だけを取り出す場合にはjmespathが便利です。

```test_data.yml
---
sample:
  - id: 1
    name: "test1"
  - id: 2
    name: "test2"
  - id: 3
    name: "test3"
```

### 1. インストール方法
　jmespathはデフォルトでは入っていないのでインストールしましょう。

```text
pip install jmespath
```

### 2. 今回紹介するパターン

- パターン1
  - __idが1 かつ nameがtest1__のデータを抽出（and条件）
- パターン2
  - __idが1 または idが2__のデータを抽出（or条件）
- パターン2
  - __idが1 または idが2__のデータから、__nameの項目だけをリストで抽出__

### 3. 変数抽出時の構文
　変数を抽出する場合は以下のように記載します。検索文字列は複雑になりがちなので、
別途変数として記載した方が良いです。

```text
jmespath.search(検索文字列, 検索する元となるデータ)
```


### 4. コードの内容
　以下が実際に作成したコードです。わかりやすさ重視で書いているので、
重複した変数宣言や行があることについてはご了承ください。
jmespathで抽出する前に、変数（jmespath_str）に検索文字列を定義することで
コードが読みやすくなります。検索条件の書き方は、

- and条件の場合
  - 条件1 && 条件2
- or条件の場合 
  - 条件1 || 条件2

なので覚えておきましょう。

```python:test_jmespath.py
import jmespath
import yaml


def main():

    # load yaml
    with open("test_data.yml", "r") as yml:
        test_data = yaml.load(yml, Loader=yaml.SafeLoader)

    # pattern1
    jmespath_str = "sample[?(id == `{}` && name == `{}`)]".format(1, "test1")
    print("pattern1:", jmespath_str)
    print(jmespath.search(jmespath_str, test_data))

    # pattern2
    jmespath_str = "sample[?(id == `{}` || id == `{}`)]".format(1, 2)
    print("pattern2:", jmespath_str)
    print(jmespath.search(jmespath_str, test_data))

    # pattern3
    jmespath_str = "sample[?(id == `{}` || id == `{}`)].name".format(1, 2)
    print("pattern3:", jmespath_str)
    print(jmespath.search(jmespath_str, test_data))


if __name__ == "__main__":
    main()
```

### 5. 実行結果

　想定通りの結果を得ることが出来ました。

```text
pattern1: sample[?(id == `1` && name == `test1`)]
[{'id': 1, 'name': 'test1'}]
pattern2: sample[?(id == `1` || id == `2`)]
[{'id': 1, 'name': 'test1'}, {'id': 2, 'name': 'test2'}]
pattern3: sample[?(id == `1` || id == `2`)].name
['test1', 'test2']
```

### 参考記事

[Improved Filters — JMESPath](https://jmespath.org/proposals/improved-filters.html)
CSRF とは

## 勉強前イメージ

クロスサイトスクリプトと似たようなやつ・・・

## 調査

### CSRF とは

Cross Site Request Forgeries の略で、クロスサイトリクエストフォージェリとよみます。
webアプリケーションの脆弱性を使った攻撃で
`Cross Site` : 横断的
`Request Forgeries` : リクエストを偽装
サイトを横断してリクエストを偽装する方法です。


### 攻撃の流れ

![1# CSRF とは - diagrams.net - Google Chrome 2021-07-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/82b5980b-44df-660e-e1e4-5060b52dadb2.png)


1. 対象サイトへログイン
2. 利用者はセッションIDを取得
3. 攻撃者はどうにかして利用者を罠サイトへ誘導し、閲覧させ、データを取得
4. 利用者のセッションIDやクッキーなどを利用して攻撃対象サイトへリクエストを送信

ログイン後に利用可能な、購入や設定の変更などが行われ不正に改ざんされます。


### XSSとの違い

似たような攻撃でXSS(クロスサイトスクリプティング) があります。
XSSの詳細は [こちら](https://qiita.com/miyuki_samitani/items/f9d7feaf06aff447c691) をご覧ください

XSSとの違いは、
不正な処理の実行場所がXSSはクライアントであったのに対し、CSRFはサーバ側になります。
また、不正な処理の実行は利用者が対象のwebアプリケーションにログイン済みなことが前提となります。

### 対策

- 個別ユーザが取れる対策

利用後はログアウトを行う
また、見に覚えのないSNSへの投稿や購入などあれば即連絡

- サービス側が取れる対策

攻撃者に推測されにくい情報の称号を行う
画像化されたチェックコードをユーザに入力させる機能の実装

## 勉強後イメージ

似たような攻撃・・・
確かにログインしっぱなしだと、そのまま気づかないまま利用されてしまう可能性がある。

## 参考

- [クロスサイトリクエストフォージェリ（CSRF）](https://www.trendmicro.com/ja_jp/security-intelligence/research-reports/threat-solution/csrf.html)
- [安全なウェブサイトの作り方 - 1.6 CSRF（クロスサイト・リクエスト・フォージェリ）](https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_6.html)
- [CSRF対策をひよっこエンジニアがまとめてみた(随時更新予定)](https://html-coding.co.jp/knowhow/security/csrf/)
[CSS]チェックマーク作ってみた

##はじめに
以下のようにFontAwesomeで使えるマークに重なるチェックマークを実装したかったのでやってみました。

![スクリーンショット 2021-06-28 22.42.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991598/694f90db-5da3-ffbb-a8be-b3e56a192525.png)


##やり方
枠線を使って表現していきます。

```:CSS
.check {
  width: 23px;
  height: 13px;
  border-left: 4px solid #25af01;
  border-bottom: 4px solid #25af01;
  transform: rotate(-45deg);
  position: absolute;
}
```

`width`と`height`で長さを調整 `border-left`と`border-bottom`で太さを調整しています。そして`transform`で角度調整して終わりです。

あとはHTMLに記述するだけです

```:HTML
<div id="check"></div><i class="fas fa-map-marker-alt respond-button "></i>
```
もし位置がずれているなどがあれば`top`や`left`などを駆使して実装していければ良いと思います。

デザインのバリエーションとして使ってみてはいかがでしょうか

##参考
https://beeyanblog.com/css-make-checkmark/
CSVHelper(27.1.1)書き込み・読み込みサンプル(VS2019で)

<h3> 経緯と目的等

.net環境でCSVHelperを利用することがあったため、自分用の覚え書きとして残しました。
一応ジェネリッククラス化してあるので、CSVから読み込んだデータをモデルクラスに格納できるし、逆にモデルクラスのListをCSV形式に変換できる。

<h3> CSVHelperを使えるようにする

この時の最新はVersion27.1.1でした。
使用するためには、ソリューションエクスプローラー／NuGetパッケージの管理から”CSVHelper”で検索してインストールでOK（詳細は省略）



<h3> サンプル

CSVHelperをインストールした前提としますが、以下のコード

```vb:CsvHelperWrap.vb

Imports System.IO
Imports CsvHelper

Public Class CsvHelperWrap(Of TYPE)
    Public Property CsvConfig As New Configuration.CsvConfiguration(Globalization.CultureInfo.InvariantCulture)
    Public Property FilePath As String = ".\file.csv"

    Private SWriter As StreamWriter
    Private CSVHelpWriter As CsvWriter

    Public Sub New()
        Me.CsvConfig.HasHeaderRecord = False
    End Sub


    ''' <summary>
    ''' CSVHelper用のWriteStreamをオープンする
    ''' </summary>
    Public Sub WriteOpen()
        SWriter = New StreamWriter(Me.FilePath, True, Text.Encoding.GetEncoding("SHIFT_JIS"))
        CSVHelpWriter = New CsvWriter(SWriter, CsvConfig)
    End Sub
    ''' <summary>
    ''' CSVHelper用のWriteStreamをクローズする
    ''' </summary>
    Public Sub WriteClose()
        SWriter.Dispose()
        SWriter = Nothing
    End Sub


    ''' <summary>
    ''' 指定したモデルクラスのListをCSVに書き込む
    ''' </summary>
    ''' <param name="dat"></param>
    ''' <remarks>書き込み後は、手動でクローズする前提だが、オープンだけはしてくれる</remarks>
    Public Sub Write(ByVal dat As List(Of TYPE))
        Try
            If SWriter Is Nothing Then
                Call Me.WriteOpen()
            End If
            CSVHelpWriter.WriteRecords(dat)
        Catch ex As Exception
            Throw ex
        End Try
    End Sub
    ''' <summary>
    ''' 指定したCSVファイルをモデルクラスのListに読み込む
    ''' </summary>
    ''' <returns></returns>
    Public Function Read() As List(Of TYPE)
        Dim records As New List(Of TYPE)()
        Try
            Using SReader As New StreamReader(Me.FilePath, Text.Encoding.GetEncoding("SHIFT_JIS"))
                Using CSVHelpReader As New CsvReader(SReader, CsvConfig)
                    records = CSVHelpReader.GetRecords(Of TYPE)().ToList
                End Using
            End Using
        Catch ex As Exception
            Throw ex
        End Try
        Return records
    End Function
End Class


```
python 変数の入った行列式を求め, 根を求めよう。

7/3　編集

python 変数の入った行列式を求め, 根を求めよう。
※根とは多項式に対して　右辺が0となるような方程式を考えたときの解、のこと。

用途：固有多項式を求めたいとき、など


```python
import sympy as sp

x = sp.Symbol("x")
M = sp.Matrix([[x, 3], [4, -1]])


ret = sp.solve(M.det())
print(M.det())

print(ret) 
```
Nginxでhttpからhttpsへの（リバース）プロクシ動作を行う

## これはなんですか
AWSのApi Gateway上のAPIが提供されましたが、IPアドレス制限をかけられたせいで自宅の手元PCからアクセスできないため、暫定処置として 許可されているIPアドレスのところに http -> httpsへのプロクシを nginx で立てた。
その際にどはまりしたのでなぜはまったのかのと、どうすればいいかを記録として残す。

なお、リダイレクトじゃなくてよプロクシ動作だよと、先に申し添えておきます。

## 構成

手元PCのREST Client(http) -> nginx -> (https)APIGW
`/proxy/api/getResource` というパスで受けて、 APIGW上の `/api/getResource` というエンドポイントにつなぐ。

## まず最初に解答
```
    set $backend_https_server xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com;
    location /proxy/api/getResource {
      resolver 8.8.8.8;
      proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      proxy_ssl_server_name on;
      proxy_ssl_name $backend_https_server;

      proxy_set_header    Host    "xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com:443";
      proxy_pass https://$backend_https_server:443/api/getResource;
    }
```

## 解説
1. API Gatewayの仕様で10分周期前後でIPアドレスが変わる
    1. nginxは設定にそのままホスト名を埋めると、IPアドレスをキャッシュするという挙動をするため、一度変数にしてから(１行目)URLを組み立てるようにする。そうすると毎回DNSを参照してくれる。
1. API Gatewayの仕様でSNIと呼ばれる仕組みを用いている
    1. 一つのIPアドレスで複数のVirtualHostを受け付けているので `proxy_ssl_server_name`, `proxy_ssl_name` は必須。
    1. あと何故かSSLv3で通信しようとしていたので `proxy_ssl_protocols` も必要。
1. API Gatewayはhttpsで公開されていた
1. `proxy_set_header` 相手はHostヘッダでどのapiにつなげばいいか判断しているので、きちんと埋めてあげること。

## おわりに
もしかしたら２，３個省いてもいい構文があるかもしれません。これで接続しました、記事書いてる時間すら惜しい状況下残しとくと有益そうなのでメモとして置いときます。

ネット上にhttpからhttpsはあまり例がなく、上記のマルチスペクトル防御シー・・すぐ変わるIPアドレスのやり方とhttp->httpsのプロクシを組み合わせたものが見つからなかった。（upstreamの構文もためしましたがIPアドレスをキャッシュしていました）
行末尾に区切りコードを付加（cut -fコマンド用シェルスクリプト）

こんにちは
```cut -f```コマンド用に、行末尾に区切りコードを付加するシェルスクリプトを作りました。

```console
$ echo 1 2 3 | ./append_delimiter.sh | cut -f3

$ echo 1 2 3 | ./append_delimiter.sh " " | cut -d" " -f4

$ echo 1 2 3 | ./append_delimiter.sh " " | cut -d" " -f3
3
```

作った理由は、```cut -f```コマンドは区切りコードを含まない行を受け取るとその行全体を出力する動作を避けたかったからです（あたかも```-f1```を指定したような動作となる）：

```console
$ echo 1 2 3 | cut -f3
1 2 3
```


#####ソース
```append_delimiter.sh
#!/bin/sh
DELIMITER="$(printf '\t')"
[ -n "$1" ] && DELIMITER="$1"
while IFS= read -r line; do
  echo "$line$DELIMITER" 
done
```
株情報を取得するAPIどれが良い

# 株情報を取得するAPIどれが良いのか

株価情報などをAPIで取得したいニーズはすごいあると思う。株式会社東京証券取引所が今年1月(2021年)に東証APIサービスの提供を始めたみたい。日本株のデータ取得に関しては、本家本元、取引所の東証が提供するAPIなのでデータの正確性では他のAPIベンダーが追随することはできないだろう。でも有料。使いたいのは無料API。
ということで、外国株も含めて株価情報を取得できる無料で使える(オープンソースで公開されている)APIの紹介です。

## pandas_datareader
pip できる
元々pandasの一部だった。(いろんなデータベースへのアクセスにも使える)

```python:get_stock_info.py
import pandas_datareader.data as web
import datetime as datetime
import matplotlib.pyplot as plt
import pandas as pd

#取得期間を指定
start = datetime.datetime(2021,1,1)
end = datetime.datetime(2021,6,30)

#欲しい銘柄のティッカーを指定
stockList = ["AAPL","AMZN","FB","MSFT","GOOGL"]

df = web.DataReader(stockList, 'yahoo', start=start, end=end)
df.to_csv("raw-data.csv")
```

Rederenceで
>Functions from pandas_datareader.data and pandas_datareader.wb extract data from various Internet sources into a pandas DataFrame. Currently the following sources are supported: ......

とあるように

```
web.DataReader( param1, param2, param3, param4)
```

で、param2でどこのデータベースから取得するかを選択する。
pandas_datareaderは元々pandasモジュールの一部だったのが分離したものらしい。（ある時pandasバージョンから対応しなくなった）
よくあるデータベースのアドレスとAPI-Keyを割り当てるデータ取得法とは異なり、pandas_datareaderではキーワードを与えるだけでデータベースを取得できる。だが、このキーワードで取得できるデータベースはpandas_datareaderリファレンスに載っている対応データベースに限られる。(結構多い)

https://pandas-datareader.readthedocs.io/en/latest/index.html

ただ、帰ってくるデータ表式はバラバラだったり、株価情報の取得が目的ならそんな多くのデータベースに対応している必要はない。ちなみに、pandas_dadareader には

<strong>Requirement</strong>

* pandas>=0.23
* lxml
* requests>=2.19.0

なので、データベースにアクセスしてデータを取得するのには結局、requestsが使われているっぽい。
んで、pandas_datareaderの開発者が主要なデータベースからそれぞれに適したデータ表式をpandasで個別に設定しているっぽい。

株価情報の取得なら params2が 'yahoo' で良い。米国株と日本株の取得ができる。

```python
web.DataReader('^DJI', 'yahoo', start, end) #米国株ならparams1をTicker_Symbolに
web.DataReader('6758.T', 'yahoo', start, end) #日本株ならparams1をTicker_numebr.T or Ticker_numebr.JPに
```

params1はリストにも対応。一度に複数の株価情報を取得できる。


## yahoo_finance_api2

ほぼ、pandas_datareaderのyahoo financeだけ版。ただ、こちらは

```python
my_share = share.Share('MSFT')
symbol_data = None

try:
    symbol_data = my_share.get_historical(share.PERIOD_TYPE_DAY, 10, share.FREQUENCY_TYPE_MINUTE, 5)
except YahooFinanceError as e:
    print(e.message)
    sys.exit(1)
```

のように、取得する銘柄はもちろんだが、

* 時間軸(分、時間、日、週、月など)
* 最新のものから取得する期間(分、時間、日、週、月で指定可能)

が指定できる。ただ、最新のものからデータを取ってくる期間は銘柄により異なるようで数十年のものもあれば、数年のものもあり。（最古データは上場年月日と必ずしも一致しない）

pandas_datareaderのように取得開始～終了の期間を指定できるわけではない。ただこれから、保有株に対する何らかの分析、Alexaスキルを作って朝に報告してくれるようなモニタリング用途であれば十分。

https://pypi.org/project/yahoo-finance-api2/


## おわりと他にもあるよAPI

ここでは、 pandas_datareaderとyahoo_finance_api2を紹介したが、実はyahoo_financeからデータを取得できるよう、この他にも幾つかプロジェクトがあるみたい。

Pypiで yahoo financeとか検索してみると沢山見つかる。結局は、Descriptionを見て
自分の優先したい

* データ表式
* パラメータ

などの条件に合ったモジュールを使えば良い。

***
ps

朝起きたら、SF映画のブリーフィングみたいに、Alexaに自分の保有銘柄のレポート伝えてもらうの面白そう。