OmniAICreator/Qiita-1.07M huggingface dataset:
Study History

個人学習履歴の記録、資料などまとめ

## 2020.09 - 試験勉強
- **Microsoft Azure Architect Technologies (AZ-300)**
  - https://www.examtopics.com/exams/microsoft/az-300/
  - https://www.whizlabs.com/
- **[AWS Summit Online](https://aws.amazon.com/jp/summits/2020/)**

## 2020.08 - 読書
- **[マイクロサービスアーキテクチャ](https://www.amazon.co.jp/%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3-Sam-Newman/dp/4873117607/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3&qid=1600306754&s=books&sr=1-1)**
- **[Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎](https://www.amazon.co.jp/Python%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92-%E2%80%95scikit-learn%E3%81%A7%E5%AD%A6%E3%81%B6%E7%89%B9%E5%BE%B4%E9%87%8F%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%A8%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AE%E5%9F%BA%E7%A4%8E-Andreas-C-Muller/dp/4873117984/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1BUTN6MGU08JO&dchild=1&keywords=%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92&qid=1600306834&s=books&sprefix=%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%2Cstripbooks%2C265&sr=1-3)**
- **[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/Python%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92-%E2%80%95scikit-learn%E3%81%A7%E5%AD%A6%E3%81%B6%E7%89%B9%E5%BE%B4%E9%87%8F%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%A8%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AE%E5%9F%BA%E7%A4%8E-Andreas-C-Muller/dp/4873117984/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1BUTN6MGU08JO&dchild=1&keywords=%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92&qid=1600306834&s=books&sprefix=%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%2Cstripbooks%2C265&sr=1-3)**

## 2020.07 - 試験勉強 → 合格
- **Microsoft Azure Architect Design (AZ-301)**
    - https://www.examtopics.com/exams/microsoft/az-301/
    - https://www.whizlabs.com/
xlwingsでアドインが有効なExcelインスタンスを生成する

ニッチすぎるけど、xlwingsでExcelインスタンスを生成するときの問題点とその解決方法を紹介。

# 0. 環境
以下で確認しています。

- OS: Windows 10 (1809)
- Office 2016
- xlwings 0.20.7

# 1. 問題点
xlwingsでExcelインスタンスを生成するには、 `xw.apps.add()` や `xw.App()` を使用する。しかし、この方法の場合、以下の問題点がある。

- なぜかアドインが読み込まれない。
- そのインスタンを閉じた後、エクスプローラーからブックを開いてもアドインが読み込まれない。
- まれに`pywintypes.com_error`エラーが発生（しかもtry exceptで制御不可）

なお、ブックを開かずにExcelだけを開けば（スタートメニューから起動）、アドインは正常に読み込まれるようになる。

# 2. 解決方法
`xw.apps.add()` や `xw.App()` を使わずに、シェルからExcelインスタンスを生成し、xlwingsに渡す。

```python
from pathlib import Path
import re
import subprocess
import time
import winreg

import xlwings as xw


def get_path_to_xl() -> Path:
    path = r'SOFTWARE\MICROSOFT\Windows\CurrentVersion\App Paths\Excel.exe'
    key = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, path)
    data, _ = winreg.QueryValueEx(key, 'Path')

    return Path(rf'{data}\EXCEL.EXE')


def get_path_to_xl2() -> Path:
    #Excelのインストール先パスを返す関数
    subprocess_rtn = (
        subprocess
        .run(['assoc','.xlsx'], shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
        .stdout.decode("utf8")
    )
    assoc_to = re.search('Excel.Sheet.[0-9]+', subprocess_rtn).group()

    subprocess_rtn = (
        subprocess
        .run(['ftype', assoc_to], shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
        .stdout.decode('utf-8')
    )
    xl_path = re.search('C:.*EXCEL.EXE', subprocess_rtn).group()

    return Path(xl_path)


def add_xl_app(add_book: bool=True) -> xw.App:
    command = f'"{str(get_path_to_xl())}" /x /e'
    proc = subprocess.Popen(command)

    while True:
        try:
            xl_app = xw.apps[proc.pid]
            break
        except:
            time.sleep(0.5)

    if add_book:
        xl_app.books.add()

    return xl_app

app = add_xl_app()
```

# 参考
- [Windowsのコマンドプロンプトでファイル拡張子の関連付けを変更する](https://www.atmarkit.co.jp/ait/articles/0701/27/news021.html)
【PythonのORM】SQLAlchemyでIN句にサブクエリを用いたSQLを書くときの記法

## ORM? SQLAlchemy?
既に下記のようなQiita記事でもまとめているため、省略して本題のみ
https://qiita.com/tomo0/items/a762b1bc0f192a55eae8
https://qiita.com/ariku/items/75799665acd09520bed2

## コード
```python
url = 'mysql+pymysql://%s:%s@%s:%s/%s?charset=%s' % (
    self.user,
    self.password,
    self.host,
    int(self.port),
    self.db,
    self.charset
)
self.engine = create_engine(url)
self.session = sessionmaker(bind=self.engine, autocommit=False, autoflush=True)()`

# IN句にサブクエリを含める
rows = db.session.query(User).filter(
  User.id.in_(
    db.session.query(UserItem.user_id).filter(
      UserItem.item_id == 1, UserItem.numbers > 10
    )
  )
).all()
```

下記のような

```sql
SELECT * FROM users WHERE id IN (
   SELECT user_id FROM user_items WHERE item_id = 1 AND numbers > 10
)
```


## まとめ
SQLAlchemyではIN句にサブクエリを用いるSQLなどの複雑なSQLも表現可能

注意点として、ORMでは裏側でどういったSQLが発行されるかがブラックボックスであるため、微妙なSQLになっていないかデバッグ時は`create_engine`時に下記のようなオプションを追加しSQLを出力するようにしてチェックすることをオススメします

```python
echo_option = 'DEBUG' in os.environ and os.environ['DEBUG'] == 'on'
self.engine = create_engine(url, echo=echo_option)
self.session = sessionmaker(bind=self.engine, autocommit=False, autoflush=True)()`
```
[GCP認証] プログラミング言語のクライアントライブラリからユーザアカウントを用いて認証する方法

### やりたいこと

個人用途で、Pythonのクライアントライブラリ(google-cloud-bigquery)からBigQueryのAPIを叩きたいみたいなケースを考えてください。

インターネット上のブログの多くでは、サービスアカウントを発行して、jsonの鍵を取得し、`GOOGLE_APPLICATION_CREDENTIALS`の環境変数に指定する方法が紹介されています。

ですが、個人ごとにサービスアカウントを発行するのは面倒です。

### こうすればできる

個人の権限（＝ユーザアカウント）を用いて、プログラミング言語のクライアントライブラリからGCPを利用する場合は `gcloud auth application-default login` コマンドを利用します

やり方は簡単で、ターミナルなどで以下のコマンドを実行します

```
$ gcloud auth application-default login
```

そうするとWebブラウザに飛ばされ、そこで個人の権限でGCPの認証をすれば、ローカルの `~/.config/gcloud/application_default_credentials.json` にトークンが保存されます。

これがあれば`GOOGLE_APPLICATION_CREDENTIALS`の環境変数がなくても、プログラミング言語のクライアントライブラリからGCPを利用できます。

[gcloud auth application-default loginコマンドの公式マニュアル](https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login)

### 注意

似たようなコマンドに `gcloud auth login`や`gcloud longin`がありますが、これはgcloud, gsutil, bqなどのCLIコマンドの認証にしか使われません。

[gcloud auth loginコマンドの公式マニュアル](https://cloud.google.com/sdk/gcloud/reference/auth/login)

### 詳細

整理すると、GCPの認証は四通りあります。

タイプが
* ユーザアカウント
* サービスアカウント 
の二種類があり、

対象が
* CLIコマンド (gcloud, gsutil, bq)
* プログラミング言語のクライアントライブラリ等 ( pythonのgoogle-cloud-bigquery等)
の二種類があります。

|            | CLIコマンド(gcloud, gsutil, bq) | プログラミング言語のクライアントライブラリ等 |
|:-----------|:------------|:------------|
| ユーザーアカウント | gcloud login       | gcloud auth application-default login|
| サービスアカウント | gcloud auth activate-service-account --key-file JSONのキー | サービスアカウントのJSONのキーをGOOGLE_APPLICATION_CREDENTIALSに指定       |

詳細については https://medium.com/google-cloud-jp/gcp-%E3%81%A8-oauth2-91476f2b3d7f がとてもわかり易いです。

### 他にも以下のリンクは参考になります

* https://stackoverflow.com/questions/53306131/difference-between-gcloud-auth-application-default-login-and-gcloud-auth-logi

* https://dev.to/seizans/gcp-api--429k
エンジニアが効率よく仕事を進めるためのメモ術

## 1.目的
社会人になりメモを取る場面が多くなりました。
私は新卒研修でのメモ術の研修を受けメモの大切さを知りましたが、未だにメモを取る習慣がなかなか身につきません。
なので、改めて効率よく仕事を進めるためのメモ術についての著書を読んで、特に重要だなと感じたところをまとめて記事にしていこうと思います。

## 2.メモを取る理由
メモを取る理由は大きく分けて2つあります。

- **記憶に残すため**<br>ドイツの心理学者ヘルマン・エビングハウスの実験によると人は**前日に伝えたことを何もせずに覚えておくと次の日には74%も忘れている**そうです。
覚えている割合が100%に限りなく近いタイミングでメモすることがミスをなくすことにつながります。

- **安心感を持つため**<br>「覚えていられるかな」,「あの時何と言ってたっけ」と**不安になることが既に気持ちの面で効率を悪くして**しまいます。
余裕を持ち自分の中で「覚えている！」,「忘れてもメモがある！」という**自信を持つこと**が他のことをする上でも大事になります。

## 3.メモ術
### ToDoリスト
- **時間見積もりと実際にかかった時間を書き出す**<br>午前、午後でやるべき仕事を挙げたらどれくらいの時間でできそうかを予想し、作業が終わったら実際の時間を記入します。そうすることで**その仕事を自分がどのくらいでできるのか、また今後どのくらい早くできるのかが分かり**仕事の効率が上がります。
<img width="300" alt="イラスト1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669189/c0655ae9-c255-ebab-a5c3-01eadcbcfa99.png">

- **ToDoリストに書く事は適量にする**<br>無理な仕事量にするとケアレスミスや納期遅延の可能性が高くなり仕事の効率が落ちるので、自分のできる仕事量をしっかりと理解することが大事です。

- **前日にやり残したことをもう一度次の日のリストに書き足すことが大事**<br>そもそもToDoリストをすべてこなせる人はあまり多くはありません。また、できなかった仕事は先送りにしがちになります。なので**その日にできなかったことは翌日のToDoリストに追記すること**を忘れないようにその日に追記することが大事です。
<img width="300" alt="イラスト2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669189/739eadc4-f2f0-5d68-f682-e92f4bc5eb6a.png">

- **できなかった仕事は色ペンで目立つように囲い、翌日のリストの先頭に色ペンで転記する**<br>やり残した仕事が納期が近いものや、緊急でやらなければならないものである場合は**特に目立つように翌日のToDoリストの先頭に追記すること**が大事です。またそうすることで、忘れる心配がなくなり帰宅後安心して眠りにつくことができます。

### 付箋
- **付箋の枚数が増えると優先順位がつけにくくなる**<br>パソコンに付箋がたくさん貼ってある人はそれがToDoリストになってることが多いですが、付箋であると**落ちたり、順番がわからなかったりしてうっかりミスの原因**になります。なので付箋で管理したい人は**３枚まで**で管理しその中でできたらはがし新しいタスクを追加するようにすることでわかりやすくかつ優先順位をつけることができます。
<img width="400" alt="ラスト3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669189/4661a30e-e3e9-11a4-f0a1-f57c910c7eee.png">

- **付箋は何種類か備えておく**<br>**本や書類に直接メモを書き足したくない人**や**口頭で指示を出すだけだと心配な人**は付箋を使うと良いとされています。そんな時にノーマルの付箋だけでなく、**方眼タイプの付箋**や、**大きめの付箋**を使うことで場面によって使い分けることができます。

### 早くメモを取るコツ
- **メモは丁寧である必要はない**<br>メモは基本的に自分しか見ないものなので、**決して丁寧に書く必要はありません**。自分が読める範囲内で速く書くことが重要なので**わかりやすくより速く**を心がけることが大事です。

- **カタカナで書くのがベスト**<br>漢字より平仮名、平仮名よりカタカナと画数の面で**カタカナは非常に速く書くことができ、また余白が目立つので読み間違えが少ない**です。さらに、人の名前になると同じ漢字で違う読み方のケースがあり相手側の名前を間違って呼ぶ可能性があるので**相手の名前もカタカナでメモする**ようにしましょう。

### 気づきメモ
- **資料や参考書にメモするときは吹き出しにして、これまで知らなかったこと、感想をメモする**<br>研修やセミナー時に資料やテキストなどにメモする時はどこで何のメモをしたのかがわかるように書くことが大事です。一番良い方法は吹き出しにしてメモすると良い。特に講師の人が喋っていたことは吹き出しでメモすると良いでしょう。**資料や参考書はカスタマイズするつもりでメモをとること**が大事です。

### メモの後処理
- **手でちぎりバラバラにして処理するか、シュレッダーにかけて処理する**<br>メモは重要なこと、大切なことを自分が忘れないように書くものでありそれは他の人にも重要である可能性が大いにあります。社内の人であれば問題ないが、その他の人にもしもメモから情報を盗み取られては大変なので、メモの後処理は**シュレッダーにかけるなどし、わからないようにする**ことが大事です。

## 4.まとめ
メモは大事、メモを取らないと忘れる、メモを取らないと印象が悪いなど、色々な理由でメモを取らなければいけないとわかっているが、なかなか習慣にならないのがメモなのかもしれません。
また、メモと並行して手帳やノートを使うとなるとさらに難易度が上がります。
まずはメモを習慣付けれるようにできるところから実践していこうと思います。

## 参考
・[仕事のミスが激減する「手帳」「メモ」「ノート」術](https://www.amazon.co.jp/%E4%BB%95%E4%BA%8B%E3%81%AE%E3%83%9F%E3%82%B9%E3%81%8C%E6%BF%80%E6%B8%9B%E3%81%99%E3%82%8B%E3%80%8C%E6%89%8B%E5%B8%B3%E3%80%8D%E3%80%8C%E3%83%A1%E3%83%A2%E3%80%8D%E3%80%8C%E3%83%8E%E3%83%BC%E3%83%88%E3%80%8D%E8%A1%93-%E3%82%A2%E3%82%B9%E3%82%AB%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9-%E9%88%B4%E6%9C%A8-%E7%9C%9F%E7%90%86%E5%AD%90/dp/4756918654)
Gitのコンフリクトを正しく恐れる

# 前置き
誰かが言ってました。
「正しく恐れよ、恐れ自体それが恐れなのである」

# コンフリクトが発生するということ
（間違い）ソースの同じところを触ったからですね
（正しい）仕様の競合が起きているからですね

# コンフリクトを解消するためのマージ作業
（間違い）ソースをマージしましょう
（正しい）仕様をマージしましょう

# 競合の恐怖
(間違い)　コンフリクトが起きないように事前にお互いにソースを把握して気を付けよう
(正しく)　コンフリクトが起きないように事前にお互いに仕様を把握して気を付けよう

# ソースの競合と仕様の競合の関係
（間違い）仕様が競合していれば、ソースが競合している
（正しい）ソースが競合していると、仕様が競合している

# プルリクで競合が起きていない
（間違い）よかった特に問題ないですね。
（正しい）もしかしたら漏れがある可能性があるので仕様をきちんと確認する。

# あとがき
コンフリクトを恐れるあまり、
誰かの手を止めることのないようにしてほしいという思いです。
Javaでcronのプログラムを作ろう！！(TaskScheduler)

#Java(cron4j)

・cronとは、多くのUNIX系OSで標準的に利用される常駐プログラム（デーモン）の一種で、利用者の設定したスケジュールに従って指定されたプログラムを定期的に起動してくれるもの。(*IT用語辞典参照)

##jar
下記リンクからjarファイルをダウンロードしてIDEに設定しよう！！
https://www.sauronsoftware.it/projects/cron4j/download.php

##Taskクラス

まず、実行したい処理を書くクラスを作ろう！！

```java:CronTask
import java.util.Date;

public class CronTask implements Runnable{

	@Override
	  public void run() {
	    System.out.println(new Date()+": Hiiiii! cron4j!");
	  }

}
```

##Schedulerクラス

```java:MyCronAppTest
import it.sauronsoftware.cron4j.Scheduler;

public class MyCronAppTest {

	  public static void main(String[] args) {
	    MyCronAppTest app = new MyCronAppTest();
	    try {
	      app.schedulerSimple();
	      System.out.println("Press Ctrl+C to stop.");
	      Thread.sleep(100000000);
	    } catch (InterruptedException e) {
	      e.printStackTrace();
	    }
	  }

	  public  void schedulerSimple() {
	    Scheduler scheduler = new Scheduler();
	    // every minute.
	    scheduler.schedule("* * * * *", new CronTask());
	    // start cron4j scheduler.
	    scheduler.start();
	  }
}
```

##おまけ（Servletを使ったScheduler）

```java:HelloServlet
import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import it.sauronsoftware.cron4j.Scheduler;

public class HelloServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

		public  void schedulerSimple() {
	    Scheduler scheduler = new Scheduler();
	    // every minute.
	    scheduler.schedule("* * * * *", new CronTask());
	    // start cron4j scheduler.
	    scheduler.start();
	  }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		MyCronApp app = new MyCronApp();
	    try {
	      app.schedulerSimple();
	      System.out.println("Press Ctrl+C to stop.");
	      Thread.sleep(100000000);
	    } catch (InterruptedException e) {
	      e.printStackTrace();
	    }
		response.getWriter().append("Hello Servlet");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
```
OracleからAzure DB（PostgreSQL）へ移行する~⑥VACUUM/VACUUM FULL

今回はVACUUMについて記載します。個人的な意見としまして、PostgreSQLで１番の有名で特徴的な機能な気がします。

#VACUUMを行わなければいけない理由
そもそも、VACUUMはなぜ実施していかなければならないのか？VACUUMを実施する大きな理由は以下の4つです。

* 更新、あるいは削除された行によって利用されているディスク領域の再利用
* PostgreSQL問い合わせプランになによって使用されるデータ統計情報の更新
* インデックスオンリースキャンを高速化するためのVisibility MAPの更新
* トランザクションIDの周回問題に対する対応

PostgreSQLはOracleとは異なり、追記型データベースです。更新、削除のあった行は物理的に削除されず、そのまま残ってしまいます。この不要な領域を再利用可能にするためであったり、内部的な様々なメンテナンスを行うためにVACUUMは必ず実行しなければなりません。

#VACUUMの種類
VACUUMに関しては大きく`VACUUM`と`VACUUM FULL`の２つの種類が存在します。この２つのVACUUMはまったく異なる働きをします。ざっくりと言うと、不要になった空き領域にフラグを立て、再利用可能にするのがVACUUMであり、削除されていないデータをファイル内で前方に移動し、解放された領域をOSに返す動作をするのがVACUUM FULLです。なので、VACUUMを実行してもOSから見たとき空き領域は増えませんが、VACUUM FULLを実行すれば空き領域が増えるという動作になります。

* VACUUM
テーブルをスキャンし、新しく挿入または更新されるデータで上書きすることができるように、不要になった空き領域にフラグを立てる。

* VACUUM FULL
VACUUMとは異なり、削除されていないデータをファイル内で前方にある解放済みの場所へ移動する。移動により解放された領域はOSより解放済みと認識され、再利用可能となる。

#AutoVacuum関連パラメータ
PostgreSQL 8.1よりautovacuum機能が追加されました。以下の条件にてautovacuumが実行されます。（autovacuumが推奨）
自動VACUUMで実行してくれるVACUUMはVACUUM FULLではなく通常のVACUUMです。一般的には__VACUUM FULLはAUTO VACUUMを実行していれば不要__であるといわれております。

AUTO VACUUMに関連するパラメータは`autovacuum_vacuum_threshold`と`autovacuum_vacuum_scale_factor`となります。この２つのパラメータによってバキュームする対象を決定します。この２つの閾値から算出される値よりもdead tuple(削除、更新により不要となったレコード)が大きくなった場合にAUTO VACUUMの対象となりますが、巨大なテーブルだと１/5がdead tupleにならないとVACUUMされないので、設定値を見直す必要があります。

AUTO VACUUMの関連パラメータは以下のとおりです。（テーブル単位で指定可能）

* __autovacuum_vacuum_threshold__
autovaccum実行のしきい値となる、dead tuple(updateやdeleteされた行数)の最小数。（デフォルトは50）

* __autovacuum_vacuum_scale_factor__
autovaccum実行のしきい値となる、テーブル内でdead tupleとなっているレコード数の割合。（デフォルトは0.2）

* __閾値__
autovacuum_vacuum_threshold + (テーブル行数 * autovacuum_vacuum_scale_factor) < dead tuple数

#統計情報の更新
AUTO VACUUM処理では、同時に統計情報の更新も行われます。別途ANALYZEコマンドも用意されていますが、こちらも自動処理に任せてしまうのが推奨となります。

AUTO ANALYZEの関連パラメータは以下のとおりです。(テーブル単位で指定可能)

* __autovacuum_analyze_threshold__
autoanalyzeのしきい値となる、更新レコードの最小数。（デフォルトは50）

* __autovacuum_analyze_scale_factor__
autoanalyzeのしきい値となる、テーブル内で更新されたレコード数の割合。（デフォルトは0.1）

* __閾値__
autovacuum_analyze_threshold + (テーブル行数 * autovacuum_analyze_scale_factor) < 更新レコード数


#VACUUMとVACUUM FULLの違い
ここまで、VACUUMとVACUUM FULL、AUTO VACUUMの話をしてきましたが、VACUUMとVACUUM FULLの違いについて、少し触れたいと思います。
まず、VACUUMですが、VACUUMは先ほどの説明の通り、AUTO VACUUMで実行されるコマンドです。実行しても再利用可能領域はOSへ返されません。一方でDMLなども並列実行可能であり、I/Oの負荷もVACUUM FULLに比べて確実に小さいコマンドです。

一方VACUUM　FULLはAUTO VACUUMで実行されません。実行すると再利用可能な領域としてOSへ領域を返しますが、実行はI/Oの負荷が高まり、処理時間も比較的長いです。また、実行中排他ロックをとるので、SELECTも行う事が出来ません。

一般的にAUTO VACUUMが正常に動作していれば、VACUUM　FULLを実行する必要は無いと言われており、AUTO　VACUUMは設定することを強く推奨されている設定となります。

* __VACUUM__
 ・auto vacuumコマンドで実行されるコマンド
 ・再利用可能領域をOSへ返却しない
 ・DML系のコマンドは並列可能

* __VACUUM FULL__
　・auto vacuumでは実行されない。（明示的な実行が必要。）
　・再利用可能領域をOSへ返却する。
　　　-再利用可能領域を圧縮することで、テーブルファイルの容量を最小化していく
　　　-処理対象のテーブルをコピーして実行するため、コピー用のDISK領域が必要となる
　　　-処理が長い
　　　-DISK I/Oへの負荷が高い
　・テーブルの排他ロックを取得する

#最後に
PostgreSQLの代表的な処理VACUUMに関して説明しました。VACUUMと正しく付き合う事で、PostgreSQLを常に良い状態に保っていただければと思います。

##次回
文字コードとロケールに関する情報を記載したいと思います。
Mac環境でnpm startでエラー。

```
create-react-app アプリ名
```

でアプリを作り、いざ起動。

```
npm start
```

あれ、実行できない？？

以下エラー文。

```
Starting the development server...

dyld: lazy symbol binding failed: Symbol not found: _FSEventStreamCreate
  Referenced from: /Users/user/Documents/cycle/node_modules/webpack-dev-server/node_modules/fsevents/build/Release/fse.node
  Expected in: flat namespace

dyld: Symbol not found: _FSEventStreamCreate
  Referenced from: /Users/user/Documents/cycle/node_modules/webpack-dev-server/node_modules/fsevents/build/Release/fse.node
  Expected in: flat namespace

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! cycle@0.1.0 start: `react-scripts start`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the cycle@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/user/.npm/_logs/2020-09-10T15_49_19_237Z-debug.log
```

まずはいかに注目。

```
npm ERR! code ELIFECYCLE
npm ERR! errno 1
(以下略)
```

Google検索にエラー文を貼り付けてみたが、解決する方法が見つからない。。。。

次にいかに注目して検索。。。


```
dyld: lazy symbol binding failed: Symbol not found: _FSEventStreamCreate
  Referenced from: /Users/user/Documents/cycle/node_modules/webpack-dev-server/node_modules/fsevents/build/Release/fse.node
  Expected in: flat namespace

dyld: Symbol not found: _FSEventStreamCreate
  Referenced from: /Users/user/Documents/cycle/node_modules/webpack-dev-server/node_modules/fsevents/build/Release/fse.node
  Expected in: flat namespace
```

[解決できそうな記事](dyld: lazy symbol binding failed: Symbol not found: _FSEventStreamCreate · Issue #313 · fsevents/fsevents)を発見！！

でも、

```
記事のエラー文
  Referenced from: /Users/bunnyxt/Projects/njauiot-frontend/node_modules/fsevents/build/Release/fse.node

実際のエラー文
 Referenced from: /Users/user/Documents/cycle/node_modules/webpack-dev-server/node_modules/fsevents/build/Release/fse.node
```

と微妙に異なっていて、うまく解決しない。。。

うーん困った。。。。

```
node_modules/webpack-dev-server/node_modules/fsevents/build/Release/fse.node
```

いっそfsevents以下のディレクトリを削除すればいいのでは？　との記事を発見。

実行。

###解決！！

ついでに、HOSTが固定されていたので

```
unset HOST
```

これでサーバーの指定を解除。

この状態で再度

```
npm start
```

を実行。

###プレビューがうまく表示されました！！！
ページングのSQL実行時にハマった事　

### 商品テーブルから名前の情報を取ってくる際のSQL
  
    SELECT name FROM product LIMIT :span OFFSET :p_num

いつものように

    $data = array(':span' => $span,'p_num' => $p_num);

と書いてexecuteすると

    ERROR!SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near

というエラーが出てきて怒られる。

要は`':span' => $span`　のようにすると、入れられる値は文字の数字になってしまうので、
数値を入れるべきSQL文でエラーが起きた。

### 解消法

    $stmt->bindValue(':span', $span, PDO::PARAM_INT);
    $stmt->bindValue('p_num', $p_id, PDO::PARAM_INT);

とすることで、数値として値をSQLに入れられる。
似たもので`bindParam`というものがあるが、違いは後で調べて追記しておく。
go.modの参照先をローカルのパスに向けてデバッグする

Goは依存ライブラリを `go.mod` で管理しますが、依存ライブラリの中にバグがあった場合に、一時的にライブラリコード内にデバッグ用のコードを差し込みたいことがあります。

例えば、 `github.com/hashicorp/hcl/v2` => `/path/to/hcl` に参照先を変えるには、こんなかんじで `go.mod` に `replace` を書きます。手元の環境はGo 1.14です。

```go.mod
module tmp

go 1.14

require (
	github.com/davecgh/go-spew v1.1.1
	github.com/hashicorp/hcl/v2 v2.6.1-0.20200915195656-bf0a7fe4fe09
	github.com/zclconf/go-cty v1.2.0
)

replace github.com/hashicorp/hcl/v2 => /path/to/hcl
```

```main.go
package main

import (
	"fmt"

	"github.com/davecgh/go-spew/spew"
	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/hclwrite"
)

func main() {
	src := `
resource "foo_bar" "baz" {
  disabled = (true)
}
`
	f, _ := hclwrite.ParseConfig([]byte(src), "", hcl.Pos{Line: 1, Column: 1})
	got := f.BuildTokens(nil)
	fmt.Printf("got:\n%s\n", string(got.Bytes()))
	fmt.Printf("dump:\n%s\n", spew.Sdump(got))
}
```

あとは `/path/to/hcl` のコードを適当にいじればよいだけ。

参考: https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive
VSCodeの認証付きプロキシの入力を省略する暫定ハック

# 現在は不要
[1.51](https://code.visualstudio.com/updates/v1_51#_remember-proxy-credentials)にて認証保持できるようになったので不要です。
どうしても事情が無い限りはアップデートしましょう。

----
以下旧バージョンによる情報

## 背景
起動引数の--proxy-serverにユーザー・パスワード付きにしてもダメだった、、、
追加ソフトなどなしでこれを行いたい事情があるときに、、、
アップデートのたびにこのハックは消えます。

## やりかた

```cmd:対象ファイル
【VSCodeインストールディレクトリルート】\Microsoft VS Code\resources\app\out\vs\code\electron-sandbox\proxy\auth.js
```

```javascript:auth.js
window.vscode.ipcRenderer.send("vscode:proxyAuthResponse",{username:"【ユーザー】",password:"【パスワード】"})});
```
まるっと上書きして、【】をそれぞれ置換します。※気になる人は元ファイルのバックアップ取っておくこと

## 余談

1.47以前だと[100907](https://github.com/microsoft/vscode/pull/100907)がマージされてないのでauth.htmlを直いじりで同じ効果が得られるはず
ホントはsettings.jsonあたりから読むようにさせるのが正攻法と思う。
表示自体はされるようで若干入力画面がちらつく
OSI参照モデルとプロトコルスタック

自分用のメモとmarkdounの練習して、学んだことをちょろっと書いときます。
***
# OSI参照モデル
お互いが参照・被参照関係にあるレイヤによるモデルであり、上位層は下位層に対して抽象化されている。
OSI参照モデルは、1977年から1984年にかけて定義されたOSIのために策定されたが、OSI自体は普及せずに、OSI参照モデルだけがネットワークの基本モデルとして広く参照されるようになった。 OSI参照モデルはISO/IEC 7498として規格化され、後にITU-TではX.200、JISではJIS X5003として、同一内容を定義している。
なお、いくつかの教科書や、以下の「#例」の節で「理解を助けるための参考資料」などとして、SNAの7階層や、TCP/IPのDARPAモデルに沿っているプロトコルなどを、このOSIのモデルに対応付けした表などが見られるが、IETFなどがインターネット・プロトコル・スイートと構造の開発はOSIに準拠する意図はないとしているように、そういった対応付けはたいてい公式には存在していないものである。
- [参照：wikipedia_OSI参照モデル](https://ja.wikipedia.org/wiki/OSI%E5%8F%82%E7%85%A7%E3%83%A2%E3%83%87%E3%83%AB)
***
# プロトコルスタック
スタック（階層）やスイート（一組）内の、個々の通信プロトコルはある1つの目的のために設計されることが多い。
このようなモジュール化によって設計や評価をより容易にする。各プロトコルモジュールは上下の他のモジュールと互いに通信するので、一般にこれをプロトコルが積み重ねられたものとして見ることになる。最下層のプロトコルはハードウェアとのやり取りを行う層である。より高い層はさらに様々な機能をそれに付与していく。ユーザーアプリケーションは最上層とだけやり取りする。（OSI参照モデルを参照）
- [参照：wikipedia_プロトコルスタック](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF)
***
# 大体こんな関係性
※本来はTCP/IPのプロトコルスタックはOSI参照モデルに準拠しない。あくまでも理解用のイメージとして

|OSI参照モデル|TCP/IPプロトコルスタック|
|:----|:----|
|レイヤー7:アプリケーション層|アプリケーション層|
|レイヤー6:プレゼンテーション層|アプリケーション層|
|レイヤー5:セッション層|アプリケーション層|
|レイヤー4:トランスポート層|トランスポート層|
|レイヤー3:ネットワーク層|インターネット層|
|レイヤー2:データリンク層|ネットワークアクセス層|
|レイヤー1:物理層|ネットワークアクセス層|
***
vSphere 7.0 U1 へのアップグレード

# vSphere 7.0 U1 が登場しました
vSphere 7.0 Update1 （U1）が登場したので、いつもの「vSphere 7 へのアップグレード」資料を更新しました。今現在の情報でしか追記や変更していないので、ひとつ前の「vSphere 7 へのアップグレード」とあまり変わり映えしませんが、徐々に修正していこうと思っています。

## 資料のダウンロード先
とりあえず色々な所に散らかっていますが、バージョンごとにダウンロード可能です。

[vSphere 7 へのアップグレードについて（vSphere 7.0 U1 版）]
(https://drive.google.com/file/d/1e_c5SNIZDSAZhz_2510g-DegJbJIYS51/view?usp=sharing)

ちなみに、ひとつ前の vSphere 7 へのアップグレードは、こちらからダウンロード可能です。
[「vSphere 7 へのアップグレードについて」まとめてみた](https://imaisato.hatenablog.jp/entry/2020/05/06/050110)

その前の vSphere 6.7 へのアップグレードはこちらです。これも執筆していました。
[vSphere のアップグレード]
(https://vmware-juku.jp/resource/form_157/)

その前の vSphere 6.5 へのアップグレードはこちらです。これも私の執筆です。
[やってみれば意外に簡単！「VMware vSphere 6.5」へのアップグレード] (https://vmware-juku.jp/solutions/vsphere6-5-upgrade/)

VMware パートナーの場合は専用のダウンロード先から社員が書いたものがダウンロード可能ですが、一般人の人はそれができません。なので、私の所では一般人の私が VMware で公開された情報を調べた範囲でのものを、IT 技術者引退するまでの間はまとめていこうと思っています。
GCP Ubuntu14.04以上：システム言語・タイムゾーンの日本語化

<h2>GCPのインスタンスUbuntu14.04の言語を日本語に設定する</h2>

<h4> ＜システム言語の変更＞</h4>
1.日本語パックのインストール
```$ sudo apt-get install language-pack-ja```
2.localctl実行
```$ sudo localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"```

<h4>＜タイムゾーンの変更＞</h4>
1.timedatectl実行
```$ sudo timedatectl set-timezone Asia/Tokyo```
2.インスタンス再起動（少ししてから再ログインで反映されている）
```$ sudo shutdown -r now```
Pipenv+VSCodeで外部ライブラリのインテリセンスを有効にする

## 検証した環境

![macOS-10.15.5](https://img.shields.io/badge/macOS-10.15.5-brightgreen) ![Python-3.8.5](https://img.shields.io/badge/Python-3.8.5-brightgreen) ![Pipenv-1.2.20](https://img.shields.io/badge/Pipenv-1.2.20-brightgreen) ![VisualStudioCode-1.48.1](https://img.shields.io/badge/VisualStudioCode-1.48.1-brightgreen)

## 概要

VSCodeでPythonの開発をする際に特に設定を行わないと
標準ライブラリしかインテリセンスが有効になっていないので開発スピードが下がってしまう。
標準ライブラリだけではなく外部ライブラリを使用した場合でもインテリセンスが有効になるように設定を行う。

## 手順

### 1. Pipenvで作成した仮想環境を調べる

```bash
pipenv --venv
```

```bash:コマンド実行結果イメージ
# 仮想環境のパスが表示される
/Users/xxx/work/fastapi-demo/.venv
```

### 2. 外部ライブラリがあるパスを調べる

`.venv`配下にある`site-packages`に外部ライブラリがある

```bash:パス
/Users/xxx/work/fastapi-demo/.venv/lib/python3.8/site-packages/
```

### 3. VSCodeの基本設定で2のパスを設定する

`python.autoComplete.extraPaths`に2のパスを設定する

![スクリーンショット 2020-09-17 8.38.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252241/13e41c65-11d7-1c76-663c-63c6495de334.png)
![スクリーンショット 2020-09-17 8.40.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252241/dc07f251-66fd-055a-7b5d-0a90d8e5252a.png)
![スクリーンショット 2020-09-17 9.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252241/7e3c9425-3b75-3e09-8afb-6a13bdcd3261.png)


### 4. インテリセンスが有効になっていること確認する

![スクリーンショット 2020-09-17 8.49.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252241/920c4b54-20f3-ac83-e4fe-751553fa3743.png)


## 参考

- https://pipenv-ja.readthedocs.io/ja/translate-ja/cli.html#pipenv
- https://code.visualstudio.com/docs/python/editing#_enable-intellisense-for-custom-package-locations
- https://kic-yuuki.hatenablog.com/entry/vscode-python-autocomplete
MySQL入門！データ型 編

##MySQLが扱えるデータ型（一部）

###整数

+ TINYINT ⇒ -128 ~ +127
+ INT ⇒ -21億 ~ +21億
+ BIGINT ⇒ -922京 ~ +922京

**マイナスの値を扱うことがない場合は、データ型に`UNSIGNED`キーワードを付けてあげることによってプラスの値しか扱わずなおかつ、扱える数字の幅が広くなる。**
例
TINYINT UNSIGNED ⇒ 0 ~ 255

###実数

+ DECIMAL ⇒ 固定小数点
+ FLOAT ⇒ 浮動小数点
+ DOUBLE ⇒ 浮動小数点（高精度）

###文字列

+ CHAR ⇒ 0 ~ 255文字（主に商品コードなど固定長のデータに使用）
+ VARCHAR ⇒ 0 ~ 65535文字（文字数がバラバラになるようなデータに使用）
+ TEXT ⇒ 65535文字以上（VARCHARよりも長くなるようなデータに使用）
+ ENUM ⇒ 特定の文字列の内、1つだけの値を格納したいときに使用



        CREATE TABLE posts (
          greeting ENUM("Hello", "Bye", "Hey")
        );

        INSERT INTO posts (greeting) VALUES 
          ("Hello"),
          ("Bye"),
          ("Hey");

ちなみに、インデックス番号を指定しても値の取り出しは可能

    CREATE TABLE posts (
      greeting ENUM("Hello", "Bye", "Hey")
    );
    -- インデックス番号でも取り出せる
    INSERT INTO posts (greeting) VALUES 
      (1),
      (2),
      (3);

+ SET ⇒ 特定の文字列の内、複数の値を格納したいときに使用



        CREATE TABLE posts (
          greetings SET("Hello", "Bye", "Hey")
        );

        INSERT INTO posts (greetings) VALUES 
          ("Hello,Bye"),
          ("Hey"),
          ("Hey,Hello");

わかりやすいようにフィールド名を複数形に
データを挿入する際、`,`以外に空白などを入れてはいけないので注意

SET型は内部的に値を数値で管理していて、その数値を利用して値を取り出せる

    CREATE TABLE posts (
      greetings SET("Hello", "Bye", "Hey") -- 左から2の0乗,2の1乗,2の2乗...
    );

    -- INSERT INTO posts (greetings) VALUES 
    --   ("Hello,Bye"),
    --   ("Hey"),
    --   ("Hey,Hello");
    -- 2つ並んだ値はそれぞれが持つ内部数字を足す
    INSERT INTO posts (greetings) VALUES 
      (3),
      (4),
      (5);

###真偽値

+ BOOL ⇒ TRUE / FALSE（1がTRUE、0がFALSEで表される）

        CREATE TABLE posts (
          boolean BOOL
          );

        INSERT INTO posts (boolean) VALUES 
          (TRUE),
          (FALSE),
          (0);

###日時

+ DATE ⇒「日付」を扱いたいときに使用
+ TIME ⇒「時間」を扱いたいときに使用
+ DATETIME ⇒「日時」を扱いたいときに使用


        CREATE TABLE posts (
          created DATETIME
        );

        INSERT INTO posts (created) VALUES 
          ("2020-11-11 12:22:03"),
          ("2020-03-03"),
          (NOW());

##終わりに
ここで紹介したデータ型は**ごく一部です。**
データ型はまだまだたくさんあります。
MySQLを勉強する中で、わかりやすくまとまっているなーと思うサイトを見つけたので、こちらもぜひ見てみてください。

+ [DBOnline](https://www.dbonline.jp/mysql/type/)

+ 2020/10/16 追記を追加しました。
独学中に見たことがなかった**SERIAL**なるものと遭遇したので、備忘録の意味も込めて追記しました。


##追記
**SERIAL**
`BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE`  の別名。

*実装例*

    mysql> create table serial
        -> (
        -> id SERIAL
        -> );
    Query OK, 0 rows affected (0.03 sec)

    mysql> desc serial;
    +-------+---------------------+------+-----+---------+----------------+
    | Field | Type                | Null | Key | Default | Extra          |
    +-------+---------------------+------+-----+---------+----------------+
    | id    | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
    +-------+---------------------+------+-----+---------+----------------+

上記のようにfield名に`SERIAL`を付けると、**データ型**、**NOT NULL**、**PRIMARY KEY**、**AUTO_INCREMENT**の設定をやってくれる。
webブラウザのタブが開ける仕組みは？

## 確認前の疑問

httpは80番ポート、httpsは443番ポート。
webブラウザでタブをいっぱい開いていたら、80,443ポートに別々のタブのアクセスが来てごっちゃにならないの？

## 調査

### 参考サイト

- [知っておきたいネットワーク・トレンド（12）第5回---Webブラウザはなぜ同時にいくつものサイトにアクセスできる？](https://xtech.nikkei.com/it/members/NNW/NETPOINT/20020716/5/)
- [Webサーバは80番ポート以外使ってはいけないの？](https://ascii.jp/elem/000/000/458/458706/2/)
- [Webブラウザのウインドウを複数立ち上げてい](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1096725415)
- [サーバの要塞化とTCP/IPの基礎知識 (2/3)](https://www.atmarkit.co.jp/ait/articles/0106/19/news002_2.html)
- [Webサーバに接続するまでの流れとポート番号](https://itsakura.com/network-server-port)

### ポイント
- webサーバが受信するときの宛先ポートは80番,443番と決まっている
- webブラウザ側のポート番号は任意
- webブラウザはTCPのコネクションを確立する際にwebサーバに(エフェメラルポートの範囲で)任意のポート番号を知らせる

### 要するに

下記のようにwebブラウザでタブを開いてたとする
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/e31ef6f6-3d73-a513-f2de-bc548c2c23b8.png)

- `YouTubeタブ` ...  [webサーバ]443ポート ←→ [クライアントPC]50000ポート
- `Facebookタブ` ...  [webサーバ]443ポート ←→ [クライアントPC]50001ポート
- `Googleタブ` ...  [webサーバ]443ポート ←→ [クライアントPC]50002ポート
- `Qiitaタブ` ...  [webサーバ]443ポート ←→ [クライアントPC]50003ポート



## おまけ

- ポートの範囲

|     ポート番号    |                                        説明                                       |
|:-----------------:|:---------------------------------------------------------------------------------:|
| 0番 - 1023番      | ウェルノウンポート                                                                |
| 1024番 - 49151番  | 登録済みポート番号                                                                |
| 49152番 - 65535番 | ダイナミックポート、エフェメラルポート クライアント側で使用されるポート番号 |



## 確認後の認識

httpは80番ポート、httpsは443番ポート → これは`サーバ側`
webブラウザでタブをいっぱい開いても、クライアント側のポートはかぶらないようになっているので、ごっちゃにならない
Trackpad は TipTap で幸せになれる

# Apple は板を売っている。
最初見たときは、何かの冗談かと思った。
![211iiZECniL._AC_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/b820ed06-be84-3ec2-bdc9-8e9b24a111e4.jpeg)
Apple Magic Trackpad 2
https://www.amazon.co.jp/gp/product/B07DPGK3B3/

ガースー黒光りの板を 15,600 円で売るとは！！
さすが！！天下のアップル様やで！！

斜に構えて感心していたところ、[弊社エンジニア](https://www.wantedly.com/users/126386528)がこれをスイスイ使っているのを見て好奇心を抑えられなくなり、気づいたら Amazon さんがトラックで運んで来てくれた。

**これで俺もスーパーエンジニアの仲間入りだぜ！！**
ガハハ！！！

# マウスジェスチャーはどうするのか
たとえ Mac で Trackpad を使おうとも、インターネッツをだらだらブラウジングするためには、マウスジェスチャーに相当するものが必要だ。

例えば、私は Windows で「かざぐるマウス」という高度なマウスジェスチャーを可能にするアプリを愛用しているが、Chrome の上で、
・右クリック（押したまま）→ 左クリックでタブを閉じる
・左クリック（押したまま）→ 右クリックで新規タブを開く
というジェスチャーを割り当てている。

もちろん、右クリックしたままホイールを上下に転がせば、パタパタとタブが切り替わる。

実に便利だ。手になじんだこの動作が欲しい。
これがないと、私はインターネッツできん。そうすると、どうするんだこの板は。

# BetterTouchTool で TipTap する
自然な成り行きで [BetterTouchTool](https://folivora.ai/) にたどり着く。
いろいろとリッチに機能を備えているが、正直いまのところ**「TipTap さえあればよい」**と考えている。それくらいこの TipTap は秀逸だ。

このように TipTap を設定するだけでいい。
![スクリーンショット 2020-09-16 22.43.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/283f9f94-2c99-2516-ab40-3fa9aa7e225f.png)
「TipTap 左（１本指修正）」とは、「まず中指でタッチし、そのまま離さずに人差し指でタッチすること」だ。このとき、Command＋w のショートカットキーが入るようにしている。つまり「タブを閉じる」のキーだ。

逆に「TipTap 右（１本指修正）」は、「まず人差し指でタッチし、そのまま離さずに中指でタッチすること」だ。このとき、Command+T のショートカットキー（＝新規タブ）が入る。

「TipTap 左（２本指修正）」は、「まず中指・薬指でタッチし、そのまま離さずに人差し指でタッチすること」、「TipTap 右（２本指修正）」は、「まず人差し指・中指でタッチし、そのまま離さずに薬指でタッチすること」。このとき、それぞれ「Command＋↑」（左のタブに切り替え）、「Command＋↓」（右のタブに切り替え）のショートカットキーが入る。

これで**だらだらブラウジングが捗る捗る**。

# めちゃくちゃ快適
この TipTap で Trackpad の操作性がえげつないほど向上する。なぜこれがアップル公式で標準搭載されていないのかが不思議なくらいに。

それにしても、センサを詰めただけの黒い板が 15,600 円……ホンハイにいくらで OEM しているのかは分からんけど、すんごい利益率なことは間違いない。
未経験者にプログラムとは何かを自分なりに伝えてみる

#未経験者にプログラムとは何かを自分なりに伝えてみる

初めての投稿で、試し書きしてみました。
私が研修の時にいつも教えている内容です。
「細かいことを言えば違う」と思われる方もおられるかもしれません。
しかし、「自分はこのように認識している」といった内容です。

## この記事で理解できること
**プログラムとはファイルの１つ**だということ

「Qiitaでエンジニアなら誰でも知ってること書くなんて...」と思う人もいるかもしれません。
おっしゃる通り！！
まぁ、気にせず本題に入ります。

## 一般的なプログラムとは？
一般的なプログラムとは**「順番の書かれた紙」**です！
ただし、**この順番に従って行動しなさいと「命令を記載した紙」**なんですよね。

例えば、学芸会や運動会でも使われる「イベントの順番が書かれた紙」もプログラムですよね。
まさに、我々はその紙が存在することで、**記載された順番に従って行動することを命令されています。**

![undoukai-prg-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667225/77465a49-bb7a-72a9-9d3d-3979fcb2c018.gif)

そう、なので、プログラムは「紙の一つ」です。
ただし、「命令が順番に記載されている紙」なんですよね。
※電子化されてて紙でなくなってたら、すいませんm(_ _)m

## コンピュータでのプログラムとは？
コンピュータでのプログラムは**「ファイルの１つ」**です。
そう、一般的な「紙」は、コンピュータでは「ファイル」なんですよ。

実際に、次の"sample.php"というファイル（プログラム）を一例としてみます。

~~~php:sample.php

  //sample.txtというファイルを作成して開いてください。
  $fp = fopen('sample.txt','w');

  //開いたファイルにhelloと記載してください。
  fwrite($fp, 'hello');

  //記載したらファイルを閉じてください。
  fclose($fp);

  //このプログラムを終了してください。
  exit;
~~~

このプログラムでは、次の４つの命令が順番に記載されています。

  1. sample.txtというファイルを作成して開いてください。
  2. 開いたファイルにhelloと記載してください。
  3. 記載したらファイルを閉じてください。
  4. このプログラムを終了してください。

そして、実際にプログラムを実行してみると、sample.txtというファイルが作成されています。

~~~php:sample.txt
hello
~~~

このように、コンピュータでのプログラムは**「命令が順番に記載されているファイル」**なんですよ。
実行したら、中に書いてある命令通りにPCが動いてくれるんです。

##結論
プログラムとは**「命令が順番に書いてあるファイル」**です。
実行したら、中に書いてある命令通りにPCが動いてくれるんです。
それだけの理解で良いです！！

今回は、完全未経験者向けにプログラムとは何かについて記事を書きました。
というのも、未経験者はどの情報を切り捨てて良いかの判断ができないんですよね。
なので、学者が研究するような細かい言葉の定義まで調べようとする人がいるんですよ。
でも、コンピュターの世界では、曖昧な意味の単語はたくさん出てきます。
それを事細かに調べたところで、プロダクトを作ったり、アイデアを提案できるようにはなりません。
なので、プログラムとは何かを調べるなら。これだけの理解で大丈夫ですよって記事を書いてみました。

調べることは良いことですが、コンピュータの世界は使ってみないと理解できないことが多いです。
なので、最初はとにかく手を動かして学習して欲しいと私は願っています。


以上です。
最後まで読んでいただきありがとうございます。
Selenium Python VBA　プルダウンで選択されている値を取得する

#Selenium Python Vba　プルダウン(Select)で選択されている値を取得する

検索しても、Selectに値を設定するものばかりで、みつけるのに多少時間がかかったのでこちらでもメモします。

前提
Windows
Python　3.8
Selenium　は既に使えていて、 driver　の変数で扱うものとする


##Selenium Python　プルダウンで選択されている値を取得する
###Selectクラスを使います。
なのでSelectクラスをインポートする必要があります。
Select要素を参照するWebElementをSelect型にすると、様々なことができます。

<b>Select要素を操作する詳しい説明公式サイト</b>
https://www.selenium.dev/documentation/ja/support_packages/working_with_select_elements/

```python:プルダウンから選択されている値を取得する
from selenium.webdriver.support.select import Select
#Select要素を操作するにはSelectクラスをインポートする

AA = driver.find_element_by_id("A")  #IDがAのSelect要素を取得する      
AAA=Select(AA)　　　　　　　　　　　　　#Selectオブジェクトを作成　このオブジェクトから様々な操作ができます。

#プルダウンで選択されている値は
print(AAA.first_selected_option.text)

#複数選択できるプルダウンの場合リストで取得できます。
all_selected = AAA.all_selected_options　　#all_selectedはリストになります。

```

##SeleniumBasic 　VBA　プルダウンで選択されている値を取得する

こちらは簡単

```vba:プルダウンで選択されている値を取得する

Dim AA As WebElement　　'WebElement型で宣言

’IDがAのSelect要素を取得
Set AA = driver.FindElementById("A").AsSelect.SelectedOption

Debug.Print (A.Text)　　’選択されている値が出力されました。できたー

```

今日のつぶやき
そういえばテキストボックスやチェックボックスの値取得ばかりで
Selectの選択値をスクレイピングで取得することは久しぶりです。
最近また依頼が増えてきたので、スピードをもって取得していこう。
もっと考える暇がほしいです。
Responderをdeamon(service)化する

# 前書き

「うおーーresponder楽しいーー！」
と、興味本位でresponderでアプリを作ったはいいものの、
「あれ？これってどうやって常駐させんの？？？」
と問題にぶち当たり、調べてもなかなかHITせず苦労したのでまとめます。

結論から言うとめっちゃ簡単でした。
環境はubuntu 18.04です。

# .serviceファイルを作成する

`service_name`はご自身のサービス名に置き換えてください。※重複しなければ何でもOK

```shell
sudo vim /etc/systemd/system/service_name.service
```

```shell:/etc/systemd/system/[service_name.service
[Unit]
Description = Responder Service #daemonの説明
After = network.target

[Service]
User = # 実行ユーザ名
WorkingDirectory = /opt/responder_path/ # pythonスクリプトがあるpath
ExecStart = /opt/responder_path/app.py # pythonスクリプトのpath
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
```

```shell
sudo systemctl daemon-reload
sudo systemctl restart service_name.service
sudo systemctl status service_name.service
```

Webアクセスできれば成功。

同様のやり方でDaemon化する記事はちらほらあるものの、うまくいかなかったんですよね。
ハマりポイントとして、Userを指定してなかったのが問題。
自分のインストール方法が悪いのかもしれないのですが、rootだとresponderまでパスが通ってないので実行ユーザを指定する必要がありました…。

# 参考にしたサイト

https://blog.miguelgrinberg.com/post/running-a-flask-application-as-a-service-with-systemd
CSSでpaddingの異なる要素同士をそろえる

# 結論
`box-sizing: border-box;`を使います。

#解説

例えば、以下のように指定すると、`.class2`では中の要素の幅が`50%`になるように表示されるので、`border`で囲われる範囲は`padding`の分だけ大きくなってしまいます。言い換えると、`1rem+50%+1rem`の幅になってしまいます。

```style.css
.class1 {
  width: 50%;
  margin: 0;
  padding: 0;
  border: solid;
}
.class2 {
  width: 50%;
  margin: 0;
  padding: 1rem;
  border: solid;
}
```

そこで、以下のように、`box-sizing: border-box;`を追加することで、要素の幅と`padding`を足したものが`width: 50%`になるので、`padding`の異なる要素同士で、幅をそろえることができます。

```style.css
.class1 {
  width: 50%;
  margin: 0;
  padding: 0;
  border: solid;
}
.class2 {
  width: 50%;
  margin: 0;
  padding: 1rem;
  border: solid;
  box-sizing: border-box;
}
```
【rails】　rails　newの使用方法

rails　newを使用する際に、何度も検索をかけてしまっているため、こちらに一連の流れを掲載いたします。

その①　railsのアプリを作成


```
rails _5.2.1_ new pictweet -d mysql
```
のように
rails railsのバージョン　new アプリケーション名　-d 使用するデータベース

の順で記載する


その②　コントローラーを作成
アプリ内で必要なコントローラーを作成する

```
rails g tweets controller
```


その③　データベースを作成する

```
rails db:create
```


その④　モデルを作成する

```
rails g model tweet
```
DOMとは　〜ググわか〜

#DOM::「Document Object Model」::(ドキュメント　オブジェクト　モデル)

###DOMとはこう言うもの


:point_down_tone1:一つググってもの分からないのでいろんなサイトの一言まとめを集めてみた！

_"DOMとはマークアップがなされたリソース（Document）をリソース要素（Object）の木構造（Model）で表現し操作可能にする仕組み、またそのモデル"_

_"DOMとはJavaScriptでhtmlの要素を操作するための仕組みのこと"_

_"DOMはブラウザがWebページを解釈したもの_"

_"DOMは、文書のためのプログラミングAPI"_

う〜ん、意味がよくわからない・・・


#と言うわけで！　いろいろなまとめから分かりやすくまとめてみた。
つまり・・・

###１、Webページの基本的なHTML構造を表現したものでページごとに発行されている
###２、ツリー構造（のモデル）で表現されていること
###３、jqueryやVue.jsとかは、これを参照して操作する対象を探すことができる！

と言うこと！
※初心者向けにイメージしやすく書いているので、多少の語弊があるかもしれません。



#実際に見てみよう！
見るのは簡単！DOMを調べるくらいのあなたなら、すぐに理解できる・・・はず！

このページを右クリック　→　検証　→　Elements(検証クリックしたら最初に出てくる左側の部分)
![スクリーンショット 2020-09-17 5.54.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516809/ce5e1954-4498-fda9-d90d-3c5b7cd2d4d8.png)

これこれ！

単純なモデルですが、＜html＞のなかに＜head＞と＜body＞が入っていて、
＜head＞...＜/head＞の中にはたくさんの設定が入っていたり、
＜body＞...＜/body＞の中にもdivとかaとかpとかいろいろな要素が階層的（ツリー構造）になって書かれていますね！
![スクリーンショット 2020-09-17 6.17.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516809/3ea93087-5a72-f7b8-64dd-b8a2b43b802a.png)


もはやツリー構造の説明になってる・・・
htmlでidやclassをつけると、それがDOMに反映され、目印になっていて、JSなどの言語によってブラウザ上で操作ができるわけです！

言い換えると、ブラウザ上での何かを変更する際は、JSでDOMにアクセスし、その内容やプロパティを変更しているわけです。

ソースコードを書き換えるわけではありません。

#もう一度まとめると

###DOMとは、
####ページごとに発行されるページの詳細な内容を操作可能にするもの

であることがわかった！
ElasticBeanstalkへアプリケーションをデプロイする

[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/GettingStarted.CreateApp.html)

ElasticBeanstalkへのデプロイ

# 目次
 - アプリケーションと環境を作成
 - 環境に関する情報の確認
 - アプリケーションの最新バージョンをデプロイする環境で実行中の他の更新オペレーションがなければいつでも最新バージョンをデプロイ可能

# アプリケーションと環境を作成
ウェブアプリ作成のコンソールウィザードを使用する
1. ElasticBeanstalkアプリケーションを作成
2. アプリケーション内にに環境を起動
*環境・・・アプリケーションコードを実行するために比喩ようなAWSリソースのコレクション*

アプリケーションを作成
1. [ElasticBeanstalkコンソール](https://console.aws.amazon.com/elasticbeanstalk/home#/gettingStarted?applicationName=getting-started-app)を開く
2. 必要に応じて[アプリケーションタグ](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/applications-tagging.html)を追加
3. プラットフォームを選択し、アプリケーションの作成を選択
EB側の処理、作成されるリソースについては割愛

# 環境に関する情報の確認
[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/GettingStarted.Explore.html)を参照

# アプリケーションの最新バージョンをデプロイする環境で実行中の他の更新オペレーションがなければいつでも最新バージョンをデプロイ可能
1. EBコンソールを開き、リージョンを選択
2. ナビゲーションペインで環境を選択
3. 環境の概要ページで[アップロードとデプロイ]を選択
4. [ファイルの選択]からアプリケーションソースバンドルをアップロード
バージョンラベルに新しい一意のラベルが自動生成されるが、ユニークであれば独自に設定も可能
5. [デプロイ]を選択
Device Orientationで迷ったときに見る記事

##向きの一覧

デバイスの向き一覧はこちらの記事にあります。
[Orientationのパラメータのまとめ(UIDeviceOrientation, UIInterfaceOrientation)](https://qiita.com/emperorProgKen/items/bdaeab5d690f985613b2)
![スクリーンショット 2020-09-17 6.01.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/31bc1925-6490-e79e-4959-a38aad2137e8.png)

##起動してすぐはデバイスの向きが取れない

UIDevice.current.orientationでデバイスの向きは取れるのですが、**アプリを起動してすぐは.unKnownを返すようになっています。**

起動してすぐの向きはUIInterfaceOrientationで確認できます。

iOS12まで

```swift
UIApplication.shared.statusBarOrientation
```
iOS13以降

```swift
self.view.window?.windowScene!.interfaceOrientation
```

＊ただし、画面内のインターフェイスの向きなので、
**viewが現れていない状態でUIInterfaceOrientationを確認するとnilになります。**
**viewDidAppear ~ viewWillDisAppear　の間で確認するようにします。**
また、デバイスを寝かせて置いた状態（.faceUp, .faceDown）は認識できません。

****
Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[MLBoysチャンネル]
(https://www.youtube.com/channel/UCbHff-wfjTnB3rtXIP6y0xg)
[Medium](https://medium.com/@rockyshikoku)

[相棒](https://twitter.com/oka_yuuji)
[note](https://note.com/oka_yuuji)

contact:
rockyshikoku@gmail.com
新サービスZennが面白い！

## Zennとは
プログラマーのための新しい情報共有コミュニティサービスです。
知見を記事にして公開したり、より深い知見は本として有料(無料)で公開することのできるサービスです。

情報を発信するプログラマーが対価を得られるようにというのが、このサービスを作られた方の想いなのだと思います。
サイト→ [https://zenn.dev/](https://zenn.dev/)
公式Twitter→ [https://twitter.com/zenn_dev](https://twitter.com/zenn_dev)

![はじめ方1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/319ccb84-3cce-2c1b-6a82-9e56281b2c86.png)

## Zennってどんな感じ？
### ログインはGoogleアカウントのみ！
ログインについては、Googleアカウントでのログインのみのようです。(シンプルで良いね😊)
![はじめ方2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/6047f53b-7a4c-d8c9-b02f-5d5cfbffc76b.png)

### 書ける記事は2種類！
Add Newをクリックすると、記事(Article)と本(Book)の2種類から書きたい方を選べます。
![記事執筆1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/b488b755-3c8d-b693-a369-749a6417a1e2.png)

### 記事はマークダウンで書ける！
プログラマーには嬉しいマークダウンで記事が書けちゃいます。
![記事執筆3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/f9f0a57c-db22-6ca1-0129-47c43d730626.png)

### プレビュー機能！
▷ボタンをクリックするとマークダウンで書いたものをプレビュー出来ます。
![記事執筆4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/9d791379-d37b-45f8-00d7-a4f393b4db1d.png)

### 豊富な挿入機能！
Twiiter、CodePen、JSFiddle、YouTube、SlideShare、SpeakerDeckと記事執筆に役立つ他サービスを埋め込み出来ます。
![記事執筆6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/64c4716a-7c5c-81d0-695b-af66f30f6245.png)

### 記事の設定はシンプル！
アイコンは好きなものに変えられます。カテゴリーはテック系とアイデア系。
トピックスはQiitaを活用している皆さんならよくご存知のやつですね😊
![記事執筆5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/8a0b0419-95cf-5fb2-e74a-0f34a36583d9.png)

### 本はチャプター式！
本の書き方としては、記事(Article)の書き方と変わらない感じで、記事をいくつか書いたのを合わせていく感じです。
![本執筆2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/952f39c8-bdd2-f2c5-382e-2d4331842523.png)

### 本のプレビューはこんな感じ！
本のプレビューはPCだとこんな感じです。Teckpitのような感じですね😊
![本執筆5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/a7b4f84e-4c1c-d02e-07b3-59400f8dc101.png)


これは非常に面白いサービスだと思った方も多いのではないでしょうか？(^^)
僕もさっそく使ってみました。本も執筆しようかなと思ってます。良かったらチェックしてね😊
https://zenn.dev/engineerhikaru

※この記事は勝手に書いたもので、決して何かをもらっているから書いているものではございません笑
複数の 通信先に対して、同一TCPポートで ポートフォワードさせる。(IPエイリアスで、ssh ポートフォワード出来る)

聞いてみると、けっこう知らない人が多かったので、書いときます。

### タイトルに書いたとおり、IPエイリアスに対して ssh でポートフォワードが出来ます！

これだけだと、ちょっと意味わかりにくいですよね。
つまり、複数の宛先に対して、同一ポート番号で同時に フォワード処理が出来るってことです。

例えば、サーバAの 443番(https)に向けた通信と サーバBの 443番(https)に向けた通信を、物理NIC を追加することなく、また、ローカルの監視ポート番号を変えることなく、１台のサーバで、単一コマンドにてフォワード出来るんです。
もちろん、443番に限らず、どんなポート番号でも同じです。

## 例

```
# ifconfig eth0 aaa.aaa.aaa.aaa ...
```
と 物理NICに設定されていたとして、

```
# ifconfig eth0:0 xxx.xxx.xxx.xxx
# ifconfig eth0:1 yyy.yyy.yyy.yyy
# ifconfig eth0:2 zzz.zzz.zzz.zzz
```
と、IPエイリアスを追加設定したとします。

ここで、特権ポートなんで root で、

```
# ssh -L aaa.aaa.aaa.aaa:443:localhost:1443 -L xxx.xxx.xxx.xxx:443:localhost:2443 -L yyy.yyy.yyy.yyy:443:localhost:3443 -L zzz.zzz.zzz.zzz:443:localhost:4443 user@server
```
と 出来るということです。

当然 このあと、多段転送で 目的のサーバにフォワードさせていくわけですが、
`上の転送が出来るメリット`は、**通信ポートが変えられないアプリケーションを使っていた場合に、威力を発揮します。**
`特に、Windowsアプリは ポートを変えられないケースが多いですね。`
そんな場合にも、aaa.aaa.aaa.aaa の 443番と、xxx.xxx.xxx.xxx の 443番 等を、**同時に 使えるんです！**

例えば、古い ESXi を使っていて、vSphere Client でしか繋げない場合に、複数ESXi に対して同時接続したいときなど。
シチュエーションは 少なくなってきていますが、Windowsアプリの制限で ポートを変えられないケースは、まだまだ多いハズ。

## さらに、Windows 上にて！

コントロールパネルの ネットワーク設定で、`物理NIC に 複数のIPアドレスを付与`できますよね？
ここで、**Cygwin の ssh でも 同様の処理が出来ます**。

## 例えば これと併用すると...

[OpenBlocks を使い、遠隔地のインターネット公開されていない内部ドメインのWebサーバを、SSL-VPN装置を使わずに 安全に利用するには（OpenBlocks を、簡易VPN機器っぽく使う）](https://qiita.com/shinya-kurioka/items/bb8b1ebce897d0a26965)
遠隔地から 内部ネットワークの複数サーバに向けて、**さらに VPN っぽく**遠隔利用できるわけです。

### 便利な世の中になったもんです。（って、昔から です）
pandocをやめて、md-to-pdfとvscodeでマークダウンからPDFを作成した

# はじめに

技術書展９で本を頒布する際に`md-to-pdf`を使ったので、備忘録もかねて、書きたいと思います。

初めて、技術書展を見に行ったのが[第4回](https://techbookfest.org/event/tbf04)、当時エンジニアですらなかったのに「いつかは技術書展で本を頒布してみたいな」と思って、技術通の人たちがごった返す秋葉原の会場にで考えていました。

それから2年以上経ち、今回はオンラインのみの開催ですが、技術書典9でやっと[「実践 Vue.jsでスマホアプリをつくろう」](https://techbookfest.org/product/6353829262000128?productVariantID=4691857575510016)という本（PDF）を頒布しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106459/74bc7ccc-4866-3832-3529-4daaccd2d7a2.png" width="300px" />

もし興味のある方は手にとってみてください！

初めて頒布したということもあり、思い入れも強く細かいところにこだわるために、色々悩んだことを残します。

## 概要

執筆環境は、ソースコードもあったため開発と並行するため`vscode`を選択しました。
また、マークダウンで書けば最悪PDFにどうやっても変換できるだろうと考え、マークダウンで書くことにしました。

Wordとか使うとマークダウンでもなくて良いのかなと思います。

## Pandocを最初に選択したが。。。。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106459/4e186b3d-cd33-21bc-d55c-42cd8e1d8f57.png" width="300px" />

マークダウンをPDF化するにあたり、最初に候補にあがるのが`pandoc`です。

私もpandocでイケると思ってました、当時は。

正直言うと、カスタマイズにするには学習コストが少し高い印象を受けました。「ページ番号付けたいのに」とか「章の見出しをカスタマイズしたい」という時に一々調査してという感じだったので諦めました。

修得できれば便利だとは思います。

## md-to-pdfに出会う

何か、シンプルで使い方がわかりやすいものがないかなと思い、[MarkdownをPDFに変換する「md-to-pdf」は痒いところに手が届く素敵ツール](https://dev.classmethod.jp/articles/md-to-pdf/)でmd-to-pdfを見つけました。困った時のクラスメソッドさんw

[md-to-pdf](https://github.com/simonhaenisch/md-to-pdf)はシンプルなマークダウンからPDFに変換するライブラリです。npmでインストール可能です。

```bash
npm i -g md-to-pdf
```

下記のように、対象のマークダウンを指定して、スタイルシートを当てることできます。

求めているのは、最低限のマークダウンを変換し、スタイルシートでデザインをつけること。md-to-pdfがもっとも合っているように感じました。

```bash
npx md-to-pdf tmp/*.md --stylesheet styles/style.css
```

`devtools`オプションをつけることで、ChroniumでHTMLとCSSの状態を確認することも可能です。
一々、PDF変換して確認だと時間がかかるので、地味に便利です。

※ホットリロードは効かないです。

```bash
npx md-to-pdf <マークダウン> --devtools --stylesheet styles/style.css"
```

## 工夫した点

### 表紙と裏表紙はあとでマージする

md-to-pdfでは、冒頭に設定を書くことができ、ページのサイズや余白を指定できます。

```md
---
pdf_options:
  format: A4
  margin: 20mm 10mm
  displayHeaderFooter: true
---
```

しかし、これが全部に入ると表紙や裏表紙にも余白が入ってしまいます。なので、表紙と裏表紙は別で`md-to-pdf`でpdf化し、その後PDFをマージしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106459/7340c02d-182a-b6df-038e-aa276c5c09ee.jpeg" width="300px" /><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106459/605a27a3-a110-e686-6fcd-14b03fa4a683.png" width="300px" />


## 手作業になってしまったところ

目次や章番号が手動になってしまいました。`markdown-index`や`Markdown TOC`で自動的で作成することができるのですが、章番号が`1.1.1 `のようなフォーマットだったり、目次にスタイルを当てる関係で手動にしました。

## おわりに

本を執筆するのも大変だけど、装丁も大変でした。。。
表紙・裏表紙の設定、目次、章番号、著者紹介、章ページなど思ったよりもデザインする箇所がたくさんあります。

シンプルなツールにして、CSSでカスタマイズが簡単にできる`md-to-pdf`一度試してみてください！
【超個人的備忘録】julia の . の使い方

# julia では . を使ってベクトル化できるらしい

[公式doc](https://docs.julialang.org/en/v1/manual/functions/#man-vectorized)では，以下のように言っている．

>In technical-computing languages, it is common to have "vectorized" versions of functions, which simply apply a given function f(x) to each element of an array A to yield a new array via f(A). This kind of syntax is convenient for data processing, but in other languages vectorization is also often required for performance: if loops are slow, the "vectorized" version of a function can call fast library code written in a low-level language. In Julia, vectorized functions are not required for performance, and indeed it is often beneficial to write your own loops (see Performance Tips), but they can still be convenient. Therefore, any Julia function f can be applied elementwise to any array (or other collection) with the syntax f.(A). 

# どういうこと？

実際にコードを書いてみよう．





```julia:vectorize.jl
julia> A = [1.0 , 2.0 , 3.0]
3-element Array{Float64,1}:
 1.0
 2.0
 3.0

julia> sin(A) #配列を代入している．これだとエラーを吐く．
ERROR: MethodError: no method matching sin(::Array{Float64,1})
Closest candidates are:
  sin(::BigFloat) at mpfr.jl:727
  sin(::Missing) at math.jl:1197
  sin(::Complex{Float16}) at math.jl:1145
  ...
Stacktrace:
 [1] top-level scope at REPL[2]:1

julia> sin.(A) #このように . を用いると配列を代入できる．
3-element Array{Float64,1}:
 0.8414709848078965
 0.9092974268256817
 0.1411200080598672
```


上で見るように，`.` を用いると配列すなわちベクトル成分を代入できる．


## もう１つ例を

こちらの方がイメージしやすかったかもしれない．

```julia:vectorize.jl
julia> f(x,y) = 3x + 4y
f (generic function with 1 method)

julia> A = [1.0 , 2.0 , 3.0]
3-element Array{Float64,1}:
 1.0
 2.0
 3.0

julia> B = [4.0 , 5.0 , 6.0]
3-element Array{Float64,1}:
 4.0
 5.0
 6.0

julia> f.(π , A)
3-element Array{Float64,1}:
 13.42477796076938
 17.42477796076938
 21.42477796076938

julia> f.(A , B)
3-element Array{Float64,1}:
 19.0
 26.0
 33.0
```