OmniAICreator/Qiita-1.07M huggingface dataset:
整数の高速パースに関する提案

# はじめに
この記事を読んで嬉しくなるのは一部の人だけだと思います．

# 問題
8 桁の整数を表す文字列が与えられます．それに対応する整数を返す関数を作ってください．

以下において，`int` は 32-bit であるとか `long` は 64-bit であるとか，そういったことを仮定します．仮定してまずい場合は適宜よしなに．

# 愚直な解法
```parse.cpp
int parseIntNaive(const std::string& in) {
  int out = 0;
  for (size_t i = 0; i < 8; ++i)
    out = out*10 + in[i] - '0';
  return out;
}
```

それはそう．なんだけど，`char` 1 つが表現できる範囲の演算を細々やっていて，もっと効率よくできるんじゃないかなぁ，という気持ちになってきます．

// 実際には，コンパイラしゃんに投げると LEA 命令を駆使したりループアンロールしたりしてめちゃ高速になるんだよね．

# ワード単位での並列化
たとえば，`char` 8 つは `long` 1 つで表せるので，表したくなってきます．
以下では ASCII でエンコードされることとリトルエンディアンを仮定しますが，適宜よしなに．

```
"31415926" --> 0x3632393531343133
```
（`'0'` から `'9'` は `0x30` から `0x39` に対応しています．）

この形式にできたとすると，`parseIntNaive()` ではループごとに `'0'` を引いていたところを `0x3030303030303030` をまとめて引く操作に置き換えられます．

```
0x0602090501040103
```

えー，うーん，これうまく説明できないんですが，がんばります．

まず，（変換後の）右側の桁が（入力文字列の）上位桁に対応しているので，右を 10 倍し，それと左のものを足し合わせます（まずは 2 桁ごとに区切って考えます）．

```
   0x0602090501040103 * 10
+) 0x0602090501040103 >> 8
--------------------------
   0x3c1a5c3b0f290e1f
```

もう左側の桁は不要になったので，マスクをかけて消します．

```
   0x3c1a5c3b0f290e1f
&) 0x00ff00ff00ff00ff
---------------------
   0x001a003b0029001f
```

ここで，`31 == 0x1f`，`41 == 0x29`，`59 == 0x3b`，`26 == 0x1a` です（もう流れがわかってきましたか）．

同じことを繰り返します．今度は 100 倍ですね．

```
   0x001a003b0029001f * 100
+) 0x001a003b0029001f >> 16
---------------------------
   0x0a281726103f0c45
```

マスクをかけます．

```
   0x0a281726103f0c45
&) 0x0000ffff0000ffff
---------------------
   0x0000172600000c45
```

ここで，`0x0c45 == 3141`，`0x1726 == 5926` です．
ラスト一回．最後は 10000 倍です．

```
   0x0000172600000c45 * 10000
+) 0x0000172600000c45 >> 32
-----------------------------
   0x03883c6001df5e76
```

マスクも忘れずに．

```
   0x03883c6001df5e76
&) 0x00000000ffffffff
---------------------
   0x0000000001df5e76
```

さて，`0x01df5e76 == 31415926` でありますので，求めたい数値が得られていることがわかります．

// 各操作で足し算を行う際，特に最初の操作では，隣の桁とは 256 倍の差があるので，10 倍しても隣の桁まではみ出さないことが一つの重要なポイントです．

コードにすると，次のようになります．

```parse.cpp
int parseIntParallel(const std::string& in) {
  long out = *(long*)in.c_str();
  out -= 0x3030303030303030;
  out = (out * 10 + (out >> 8)) & 0x00FF00FF00FF00FF;
  out = (out * 100 + (out >> 16)) & 0x0000FFFF0000FFFF;
  out = (out * 10000 + (out >> 32)) & 0x00000000FFFFFFFF;
  return out;
}
```

なお，今回の方法では，8 桁に決め打ちしていましたが，実際の入力はそうとは限らないので，適宜よしなにする必要があります．

# 実験
[いつもの](https://atcoder.jp/contests/abc022/tasks/abc022_b) をやって速度比較をしました．

[愚直な方法](https://atcoder.jp/contests/abc022/submissions/4139425) と [並列の方法](https://atcoder.jp/contests/abc022/submissions/4139405) です．並列の方が 1 ms 勝っています．しょっぱいですね．

愚直な方法でも，スペースや改行区切りのパースなら終端の判定は `>= '0'` で済む，みたいな工夫をやっています．

並列の手法では，たかだか 8 桁以下という仮定を置いています（10 桁になりうる場合のやつは未実装）．適宜ビットシフトをする必要があるので注意です．

# 今後の課題
たくさんの桁がくるとき，まだ数字が残っているのか？ 区切り文字に到達したか？ などを判定するのに時間がかかりそうなので大変そう．なんとかしたいです．
あと負数についてもちゃんとやらなきゃで大変です．

あと，こんな感じでワードで並列にしたり，ビット演算で賢くやるのを自分の中で bit magic と呼んでいたのですが，どこで見た用語だったか（あるいは自分で考えた？ それとも別の意味の用語を勘違いした？）わからなくなりました．知っている方がいればよしなに．
【Django】Hello World

# 概要
DjangoでHello Worldを表示する。
最小構成での実装を行います。

# 環境設定
- OS X
- python3
- Django

# 実装
1 . プロジェクトを作成する。

プロジェクト名を`tutorial`とし、プロジェクトの雛形を作る。

```none:プロジェクトの雛形を生成
django-admin startproject [プロジェクト名]
```

```none:プロジェクトの雛形を生成
django-admin startproject tutorial
```

```none:実行結果
tutorial
|
├── manage.py
|
└── tutorial
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
```

2 . アプリを作成する。

Djangoでは、1つのプロジェクトに対し、複数のアプリを作成する。
アプリ名を`hello`とし、アプリの雛形を作成する。

```none:アプリの雛形を生成
python manage.py startapp [アプリ名]
```

```none:アプリの雛形を生成
python manage.py startapp hello
```

```none:実行結果
tutorial
|
├── manage.py
|
├── tutorial
|   ├── __init__.py
|   ├── settings.py
|   ├── urls.py
|   └── wsgi.py
|
└── hello
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py
```

3 . プロジェクトのルーティングを設定する。
URLのルーティングは、２段階で行う。
はじめに、プロジェクトから各アプリへのルーティングを設定する。
`tutorial/urls.py` から `hello/urls.py` にルーティングする。

```diff:tutorial/urls.py
- from django.conf.urls import url
+ from django.conf.urls import url, include
  from django.contrib import admin

  urlpatterns = [
    url(r'^admin/', admin.site.urls),
+   url(r'^hello/', include('hello.urls')),
  ]
```

4 . アプリのルーティングを設定する。
views.pyの各メソッドへのルーティングを設定する。
`hello/urls.py` を作成し、`hello/views` の `index` メソッドを呼び出す。

```py:hello/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^world$', views.index),
]
```

5 . `hello/views.py` の `index` メソッドで、Hello Worldを返す。

```diff:hello/views.py
  from __future__ import unicode_literals
  from django.db import models
+ from django.http import HttpResponse

+ def index(request):
+   return HttpResponse("Hello World")
```

6 . サーバを起動する。

```none:サーバの起動
python manage.py runserver
```

7 . `127.0.0.1:8000/hello/world` で確認する。

```none:動作確認
open 127.0.0.1:8000/hello/world
```

# 解説
  ① ユーザが、/hello/worldにリクエストする。
  ② APサーバは、プロジェクトの `urls.py` である `tutorial/urls.py` を確認する。
  ③ `urlpatterns`より、ルーティング先を `hello/urls.py`に決定 。
  ④ アプリの `urls.py` である `hello/urls.py` を確認する。
  ⑤ `urlpatterns`より、ルーティング先を `hello/views.py` の　`index`　メソッド決定。
  ⑥ `hello/views.py` の　`index`　メソッドより、Hello World を返す。
[![alt](http://www.plantuml.com/plantuml/svg/dP8nIyH048Nx_8ebbHPw_HM2dQMTJPhLB1XODaUovsbdPb1EAn51j5D1mSDJ4KL4ySSyJlmPRd8fRb62f0ipNzwyzrYvOTDCXE1hy3le9GnYQUMwp9K8brT1p-MOZy8Wc674mfA_5LtHsLHQfvr1ckauy9Sb3Ju5tu5UGJUWU_0GnRYVwNonjnEPETjtDXAfE_Le_fTa2uMsTzrtJrghCfE3Xg13x1QH0O-gGFkWA_0Jw66ovvR7aPdQh1LGZBuUtoRZyzQEwRBwyTQ3gnkUosajJNY3y5QY1XvQ3veAy44d4fd4n6eRV07w03FumAN_gwdWtyUTqTc7rXKh9I7Moh2kxE_F4nHdFm00)](http://www.plantuml.com/plantuml/svg/dP8nIyH048Nx_8ebbHPw_HM2dQMTJPhLB1XODaUovsbdPb1EAn51j5D1mSDJ4KL4ySSyJlmPRd8fRb62f0ipNzwyzrYvOTDCXE1hy3le9GnYQUMwp9K8brT1p-MOZy8Wc674mfA_5LtHsLHQfvr1ckauy9Sb3Ju5tu5UGJUWU_0GnRYVwNonjnEPETjtDXAfE_Le_fTa2uMsTzrtJrghCfE3Xg13x1QH0O-gGFkWA_0Jw66ovvR7aPdQh1LGZBuUtoRZyzQEwRBwyTQ3gnkUosajJNY3y5QY1XvQ3veAy44d4fd4n6eRV07w03FumAN_gwdWtyUTqTc7rXKh9I7Moh2kxE_F4nHdFm00)

# まとめ
最小構成でHello Worldを表示しました。
シーケンス図より、処理順を説明しました。
間違い・指摘等があればコメントお願いします。

# 参考文献
- [はじめに · Django Girls Tutorial](https://tutorial.djangogirls.org/ja/)
AEを英語版で起動する

#今回何をするのか
パソコンを入れ替えたので、AEの環境構築してます。
普段ノートパソコンでは英語版のAEを起動させているため、新しいPCのAEも英語版に直します。

# メリットは？
AEは海外産のプラグインが多く、動かなかったり十分なパフォーマンスが発揮されなくなる可能性があります。
例　FX Console（無料）など
また、Youtubeなど英語版でのチュートリアル解説が多く、日本語版ではどのエフェクトが対応しているのかわからないって時に役に立ちます。

#デメリット
逆に日本語がわかんなくなります。(Magnifyってなんて訳するんだっけ？）
英弱な人はアレルギー反応起こすかも。

#やり方
##Step1
AEをいれる。日本語表記になっているか確認。
![スクリーンショット (3).png](https://qiita-image-store.s3.amazonaws.com/0/318447/99541b10-fd37-3a9a-2623-dd71f99b019f.png)

##Step2
メモ帳を起動
何も書かずに名前を付けて保存を選択
![スクリーンショット (4).png](https://qiita-image-store.s3.amazonaws.com/0/318447/85920a1b-2d7f-de36-eb3c-3882fdbc7d80.png)

ファイル名を以下のようにする。

```
ae_force_english.txt
```
Windowsユーザーなら、ドキュメントフォルダー
Macユーザーなら、書類フォルダーに保存

##Step3
AEを再起動
![スクリーンショット (6).png](https://qiita-image-store.s3.amazonaws.com/0/318447/df5163c9-c1c2-9333-dcb3-4e22011b6579.png)

これで完了です。
Vue.js 環境構築時エラーの対処法　　　(npm install -g vue-cli)

#はじめに

Vue.jsの環境構築をターミナルで実施した際に発生したエラーの対処法についてまとめた記事です。
環境構築時にnpmコマンド実施してvue-cli のパッケージをインストールする(以下コマンド参照)

```terminal
npm install -g vue-cli
```
上のやり方をいろんな記事で紹介しているのですが、それがうまくいかなかった時の対処方法についてまとめました。

#エラー文

```terminal
$ npm install -g vue-cli
npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
npm ERR! path /usr/local/lib/node_modules
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall access
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
npm ERR!  { [Error: EACCES: permission denied, access '/usr/local/lib/node_modules']
npm ERR!   stack:
npm ERR!    "Error: EACCES: permission denied, access '/usr/local/lib/node_modules'",
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'access',
npm ERR!   path: '/usr/local/lib/node_modules' }
npm ERR! 
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR! 
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator (though this is not recommended).

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/fisherman0825/.npm/_logs/2019-01-29T14_00_50_007Z-debug.log

```

#原因

エラーの内容を見た感じ、permission deniedとなっているのでnpmコマンドを実施する上での権限が足りていないのが原因。

#実施したこと

###①npmのディレクトリパスの確認
npmがどこのディレクトリを使っているのかを確認します。

```terminal
$ npm config get prefix
/usr/local
```


###②パーミッション変更

```terminal
$ sudo chown -R $(whoami) $(npm config get prefix) / {lib/node_modules,bin,share}
```

ここでパスワードが求められるのでパスワード入れたら色々npmや他のディレクトリのパーミッションを有効にしていくのでしばらく待ちます。

#再確認

```terminal
$ npm install -g vue-cli
npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
/usr/local/bin/vue -> /usr/local/lib/node_modules/vue-cli/bin/vue
/usr/local/bin/vue-list -> /usr/local/lib/node_modules/vue-cli/bin/vue-list
/usr/local/bin/vue-init -> /usr/local/lib/node_modules/vue-cli/bin/vue-init
+ vue-cli@2.9.6
added 239 packages from 206 contributors in 22.001s
```

無事エラーが出ず、vue-cliのパッケージのインストールができました。

```terminal
$ vue --version
2.9.6
```

最後にちゃんとvueコマンドが使えるかどうかバージョンの確認も行いました。

##参考サイト
[npmでパッケージをインストールする]
(https://www.storange.jp/2017/02/npm.html)
[npmでpermission deniedになった時の対処法[mac]](https://qiita.com/okoysm/items/ced3c3de30af1035242d)
配列の中にオブジェクトが入っている場合のvalue値の取得方法二次元配列　Javascript

備忘録として残しておきます。
以下のような配列で、key値のvalue値を取得した時に使うmap関数について、今日教わったのでメモメモ。

```js
  const ArrayTest = [{
            id: 1,
            name: "callen"
        }, {
            id: 2,
            name: "Tom"
        }, {
            id: 3,
            name: "John"
        }];
        const list = ArrayTest.map(obj => obj.name);
        console.log(list);
```
結果
![スクリーンショット 2019-02-05 22.20.30.png](https://qiita-image-store.s3.amazonaws.com/0/127391/3d699d35-98ff-7570-499f-43e4b3852509.png)

APIでJSONを扱う時に使える。
超絶便利。

# 参考資料
[配列内のオブジェクトをフォーマットするために map を使用する MDN web docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map#%E9%85%8D%E5%88%97%E5%86%85%E3%81%AE%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AB_map_%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B)
C++ で CPU のコア数を調べる方法

本文書は、マルチコア対応 Forth 系言語 [Paraphrase](http://github.com/iigura/Paraphrase/) の開発作業からのスピンオフ企画です（C++ 教材としての Paraphrase / Paraphrase 解体新書プロジェクト）。

# まさかのプラットフォーム非依存
　依存ではなく、依存しない方法です。本文書のタイトルでは CPU のコア数とかいちゃっていますが、正確には CPU スレッド数のことです（4 コア 8 CPU スレッドなら 8）。

# C++11 の標準機能で取得可能
　C++11 であれば、特にプラットフォームに依存した書き方をしなくても、thread ヘッダを読み込んで、std::thread::hardware_concurrency() にて取得可能です（[https://cpprefjp.github.io/reference/thread/thread/hardware_concurrency.html](https://cpprefjp.github.io/reference/thread/thread/hardware_concurrency.html)）。[Parahrase](http://github.com/iigura/Paraphrase/) のコードではこんな感じに書いております（って、そのままですね…）：

```C++11
#include <thread>
unsigned int G_NumOfCores=std::thread::hardware_concurrency();
```

# 余談
　しばらく C++ でコードを書いていなかったら、どんどん便利になっており、非常に助かります。便利な機能を標準として取り込んでくれてありがとう。感謝・感謝なのです。
【Protage】HTML＆CSS中級編の学びと正直な感想

Protageを使ってプログラミングの勉強を始めて四日になる**くぼた**と申します。
(僕がしているインターン→[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/))
今回はProtageのHTML＆CSS中級編を終えたので、そこで得た学びをアウトプットしようと思います。

###中級編でやったこと
前回の初級編では超初歩的なHTMLとCSSの基礎や簡単なホームページの作成などを行いました。
今回の中級編は少し応用的な内容を取り扱いました。

・複数クラスの指定
ボタンのように、「共通の部分があるが、それぞれ小さい変化をつけたいとき」にはクラスの名前を複数指定すると便利です。
下図のように、半角スペースで区切って複数のクラスを指定することができます。 

・インラインブロック
ブロック要素とインライン要素の特徴を併せ持つインラインブロック要素というものがあります。
インラインブロック要素はインライン要素と同様に横に並びますが、ブロック要素のように幅や高さをもちます。
ブロック要素(divタグなど)とインラインブロック要素はpadding、margin、width、heightを指定することができますが、インライン要素(aタグなど）はwidth、heightを指定することができません。
padding、marginついては左右のみ指定できます。

・Font Awesomeとは？
アイコンを表示するにはFont Awesomeというものを使うと便利です。
たくさんのアイコンが用意されており、自分の気に入ったアイコンを簡単に使うことが出来ます。
https://fontawesome.com に詳しい使い方やアイコンの一覧が載っています。

・aタグをクリックできる範囲

aタグはインライン要素なので、中身のテキストの部分しか大きさを持ちません。その結果、aタグをクリックできる範囲はテキストの部分だけになってしまいます。
aタグをブロック要素にすると、大きさが親要素いっぱいに広がるので、全体をクリックできるようになります。

###おわりに
中級編で得た学びについてご紹介しましたが、実際のところProtageのカリキュラムにのっとって進めていただけで、これらのアウトプットが再現できるかといわれれば正直にいってまだできないです。
まだまだ未熟者ですが、コツコツと学習を続けていきます。
最後まで見ていただいた方ありがとうございました。
ZIPはなぜストリーミングできるのか

ZIPがストリーミング出来るのを知らなかったばかりに、痛い目にあった...
誰でもそんな体験をすると思うので、ZIPのストリーミングの概要について書きます。

# ストリーミングとは
様々な意味がありますが、ここでは

- ZIPファイルが完成する前に出来た部分から逐次ファイルを送信する

ことを指します。

# ZIPとは
ZIPはファイルフォーマットの一つで、複数のファイルを1つのファイルとしてまとめるためのフォーマットです。
意外にも、ZIPは圧縮方式を指すものではなく無圧縮のZIPも作ることが出来ます。

ZIPにファイルを追加する際は、先頭にファイル本体のデータを追加していき、圧縮もファイル単位で行います。
ファイル単位で先頭から順に追加されていくため、複数ファイルをZIPに登録する際でも順次ZIPファイルを書き出すことが出来ます。
ファイルのメタデータなどは、ZIPの末尾に付与されます。このメタデータを参照することにより、

- ファイルを実際に解凍しなくてもファイルの情報を見る
- ZIPの一部のみを解凍する

のような処理が可能となります。
多くのZIPは"deflate"と呼ばれる圧縮アルゴリズムを採用しています。

# Deflateについて

DeflateはLZ77とハフマン符号を使用していて、RFCで規格が規定されています。
詳細は省略しますが、

- LZ77はデータの繰り返し部分を検知して圧縮する手法

- ハフマン符号は、よく出るバイトのパターンを検知してより短い記号で置き換える手法

になっています。解説記事がたくさんあるので見てね！

重要なのは、Deflateはストリーミングが可能な圧縮方式ということです。
圧縮対象のファイルをすべて読まなくても、圧縮ブロック単位で書き出すことが出来ます。
固定ハフマン符号ならブロック単位ですらなくバイト単位で逐次圧縮可能です。

# 結論 - ZIPとストリーミングについて

- ZIPはファイルデータが先頭から順に並んでいるので、一部ファイルのみ追加されている状態でもファイル単位でストリーミングできる

- ZIPで使われているDeflateは、暗号化方式にもよるがファイル全体を圧縮し終わる前でもストリーミング可能

- 以上２つにより、ZIPはアーカイブのファイルを圧縮しながらストリーミングをすることが出来る

圧縮しながら送信できるなんて、便利ですね！
AngularでのCropper.jsの使い方とハマりポイント

Webアプリを作る際に、画像をトリミングして、サーバーに送信したい時があると思います。こんな時にトリミングをするUIと、トリミング機能を提供してくれるのがCropper.jsです。
とても簡単なライブラリなのですが、Angularで使用する際少しハマったので記録を残しておきます。
#Cropperとは
Cropperはトリミングライブラリで、jQuery用と素のJavaScript用があります。

* [jquery-cropper](https://fengyuanchen.github.io/jquery-cropper/)
    * jQuery用
* [Cropper.js](https://fengyuanchen.github.io/cropperjs/)
    * 素のJavaScript用

今回はAngularで使いたいので、Cropper.jsを使います。

#使い方
##インストール

```npm install --save cropperjs```

##jsとcssの読み込み
公式サイトには

```test.html
<link  href="/path/to/cropper.css" rel="stylesheet">
<script src="/path/to/cropper.js"></script>
````
と書いてありますが、Angularなのでstyleファイルとcomponentファイルで下記のようimportします。

```style.scss
@import "~cropperjs/dist/cropper.css";
```


```test-cropper.component.ts
import Cropper from 'cropperjs';
```


##HTMLとComponent
```test-cropper.html
  <p><img #img alt="トリミング画像" id="trimed_image" [src]="preview" (load)="imageLoaded($event)"/></p>
```
```test-cropper.component.ts
import Cropper from 'cropperjs';

export class TestCropperComponent{

  const preview = 'https://....'

  imageLoaded(ev: Event) {
    logger().log('imageLoaded');

    let croppable = false;

    if (this.cropper) {
      this.cropper.destroy();
    }

    const image = ev.target as HTMLImageElement;

    this.cropper = new Cropper(image, {
      aspectRatio: 1,
      viewMode: 1,
      ready: function () {
        logger().log('ready');
        croppable = true;
      },
    });
  }
}
```
ここでのポイントは、`new Cropper()`を、画像のload後に行うことです。**ngOnInitやngAfterViewInitの中で呼んでも動きません**（ここでだいぶハマりました）

##表示
こんな感じで表示されます。青枠を自由に動かしたり、サイズを変えたりできます。
<img width="274" alt="スクリーンショット 2019-02-05 21.31.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/51160/059574c2-45eb-4bee-df83-e2628df4dac4.png">
私の個人開発している性格診断おまとめSNS、[Sotty](https://sotty.me)では、プロフィール画像を登録する際に下記のように使用しています。
<img width="318" alt="スクリーンショット 2019-02-05 21.29.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/51160/783b1bd7-54f9-739f-9852-34c3a3326962.png">
##終わりに
トリミングウインドウのアスペクト比を変えたり、画像を回転させたりと、他にも色々な機能があるみたいなので、お試しください。
Rust と Node.js の文字列やり取り、そして Callback

##環境
rustc 1.32.0 (9fda7c223 2019-01-16)
Node.js 10.15.1

##Rust から Node.js に Callback したい
というわけで、Cargo.toml です。`cdylib`ってやると動的ライブラリができます。Windows では dll ってやつですね。

```toml:Cargo.toml
[package]
name = "callback"
version = "0.1.0"
authors = ["benki"]
edition = "2018"

[dependencies]

[lib]
name = "callback"
crate-type = ["cdylib"]
```

続いて、lib.rs です。`rust_func`っていう関数は第一引数に C の文字列へのポインタ、第二引数にコールバック関数へのポインタを受け取るようになってます。

`rust_func`関数の1行目で Node.js の世界からやってきた C 文字列へのポインタを Rust の世界の文字列に変換して、2行目で`dbg!`マクロでその内容を表示しています。

その後の処理はカレントディレクトリにあるファイルのパスをコールバック関数の引数に渡しています。Rust の世界の文字列は NULL 終端文字がないので、そのまま Node.js の世界に渡すと結果がおかしなことになります。~~なので、`path.push('\0');`で NULL 終端文字を追加する必要があります。（もうちょっとうまいことできる方法があったら教えてください）~~なので、`std::ffi::CString`で C の世界の文字列に変換してます。（[tatsuya6502](https://qiita.com/tatsuya6502)さんにコメントで教えてもらいました）

```rust:lib.rs
use std::fs;
use std::os::raw::c_char;
use std::ffi::{CStr, CString};

type CallBack = fn(*const c_char);

#[no_mangle]
pub fn rust_func(string: *const c_char, cb: CallBack) {
    let str_from_node = unsafe { CStr::from_ptr(string).to_str().unwrap() };
    dbg!(str_from_node);

    fs::read_dir(".").unwrap()
        .for_each(|r| {
            if let Ok(r) = r {
                // let mut path = r.path().to_string_lossy().to_owned().to_string();
                // path.push('\0');
                // cb(path.as_ptr() as *const c_char);
                if let Ok(path) = CString::new(r.path().to_string_lossy().as_bytes()) {
                    cb(path.as_ptr() as *const c_char);
                }
            }
        });
}
```

最後に Node.js 側のコードです。

```javascript:index.js
let ffi = require("ffi");
let util = require("util");

let lib = ffi.Library("<path to callback.dll or so>",
    {"rust_func": // Rust の世界の関数の名前
        ["void", // 戻り値
            ["string", // 第一引数
            "pointer"] // 第二引数（コールバック関数へのポインタ）
        ]
    }
);

let callback = ffi.Callback("void", ["string"], (path) => {
    console.log(path);
});

let rust_func = util.promisify(lib.rust_func.async);

(async () => {
    await rust_func("Hello from Node!", callback);    
})().catch(e => {
    console.log(e);
});
```
mybatisにhavingはなく、trimで代用できる

mybatisでgroup byの際のhaving句を記載しようとした時に、
whereタグのような便利なhavingタグ的なのがあると思ったら、なくて困ったという話です

ドキュメントをよく読むと、trimタグを使用して、whereタグのhaving版を作成できました

# havingはtrimタグで作れる

mybatisの動的SQLのドキュメントに次のように書いてあります
http://www.mybatis.org/mybatis-3/ja/dynamic-sql.html

> where 要素の動作が期待と異なる場合は、trim 要素を定義することで処理内容をカスタマイズすることができます。

 **つまり、trimタグで下記のように記載することでwhereタグと同じ動作ができます** 。
trimっていうだけに、前後のスペースとか除く的なやつだと思って、今まで読み飛ばしてました。。。

```
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
</trim>
```

- prefixには、trimタグ内の結果がある場合に先頭に出力する文字を指定します
つまり検索条件があればWHEREを先頭につける、なければなにもつけない
- prefixOverridesには、trimタグ内の結果がパイプで区切った文字で始まる場合にその文字を削除します
つまりWHERE以下がANDで始まったら、そのANDを除去する


なので、これをhavingで応用すると、

例えば、

- チームの所属人数を出す
- チーム内の最年長者の年齢を条件として範囲指定できる

ようなSQLを作る場合、trimタグを使用して、次のように書けます

```
<select id="sample" resultType="Account">
  SELECT team,count(*) FROM ACCOUNT GROUP BY team
  <trim prefix="HAVINNG" prefixOverrides="AND |OR ">
      <if test="search_max_age_from != null">
        max(age) > #{search_max_age_from }
      </if> 
      <if test="search_max_age_to != null">
        AND max(age) < #{search_max_age_to }
      </if>
  </trim >
</select>
```

whereタグを使用した場合と同様に大分スッキリ書くことができました
#ssh コマンドで直接パスワードを記憶・指定する方法。公開鍵を使わないパターン。

sshpass コマンドを使う。コマンド内に直接パスワードを記載するので、扱いは要注意。

```
sshpass -pPASSWORD ssh user@server
```


# Original by Github issue

<a href="https://github.com/YumaInaura/YumaInaura/issues/553">https://github.com/YumaInaura/YumaInaura/issues/553</a>








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Raspberry Pi（Raspbian）で写真を撮る方法

#はじめに
Raspberry Pi（Raspbian）で写真を撮る方法です。

raspistillコマンドを使用する方法は実用的ではないので、
写真を撮るプログラムを作成する前の準備だと思って下さい。

#必要なもの
- RaspbianがインストールされているRaspberry Pi
- Raspberry Pi用のカメラモジュール
- 変換ケーブル（Raspberry Pi Zeroを使用する場合のみ）

#Raspberry Piにカメラモジュールを接続する
1. Raspberry Piの電源をOFFにする
2. Raspberry PiのCAMERAと書かれている部分にカメラモジュールを接続する![DSC_0156.JPG](https://qiita-image-store.s3.amazonaws.com/0/263360/037de6d4-acfe-9de6-4221-3cfc0865bf82.jpeg)
3. カメラが基盤などに触れないようスタンドに設置する（壊れなければOK）![DSC_0159.JPG](https://qiita-image-store.s3.amazonaws.com/0/263360/22048fe7-034d-0bac-2038-f425830b8d77.jpeg)

#Raspberry Pi（Raspbian）のカメラを有効にする
1. 「Raspberry Piの設定」を開く![2019-02-05-130530_1824x984_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/263360/5f89374d-3bfc-da50-bd3a-b64121932153.png)
2. `インターフェイス`→`カメラ`を`有効`にする![2019-02-05-130600_826x441_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/263360/7cbfdcef-b212-1487-4c3c-7e7ffdc1d485.png)
3. Raspberry Piを再起動する

#写真を撮る方法
1. LXTerminalを起動する
2. 被写体にカメラを向ける
3. `raspistill -o ファイル名.jpg`コマンドを実行する![2019-02-05-130838_659x422_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/263360/03f6033a-663a-1f4f-3ca9-323f2ba002d0.png)
4. `/home/pi`直下に写真が保存される![2019-02-05-131715_947x685_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/263360/57feb292-6c88-df4c-f921-f60262a552f3.png)
5. 写真撮影完了![photo.jpg](https://qiita-image-store.s3.amazonaws.com/0/263360/60106555-f873-cfc3-c61f-e3039baeba7d.jpeg)

#動画を撮る方法
1. `raspivid -o ファイル名.h264`コマンドを実行する

#写真の上下が逆になる場合の対処法
- raspistillコマンドのオプションに`-vf`と`-hf`を追加して上下左右を反転させる

#参考
- [Raspberry Pi Add-ons Guide | Raspberry Pi Learning Resources](https://www.raspberrypi.org/learning/addons-guide/picamera/)
- [Camera Module - Raspberry Pi Documentation](https://www.raspberrypi.org/documentation/hardware/camera/README.md)
Lambda×pythonでコネクションクローズのエラーが発生

# はじまり

Lambda×pythonでRDS接続する処理が必要になったので、AWSチュートリアルを
元々あるテーブルからselectして返す感じにちょい変更して作成
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/vpc-rds-deployment-pkg.html

チュートリアルではコネクションをクローズしている様子がなく、
「おいおい、コネクションクローズしないとかバカかよ」とか思いながらコネクションクローズをいれる
俺がバカでした。。。

```python
# -*- coding: utf-8 -*-

import json
import datetime


import sys
import logging
import rds_config
import pymysql
#rds settings
rds_host  = "DBのエンドポイント"
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name


logger = logging.getLogger()
logger.setLevel(logging.INFO)

try:
    conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except:
    logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
    sys.exit()

logger.info("SUCCESS: Connection to RDS mysql instance succeeded")
def handler(event, context):
    """
    This function fetches content from mysql RDS instance
    """

    item_count = 0

    with conn.cursor() as cur:
        cur.execute("select id from table limit 1")
        for row in cur:
            data = row
            #print(row)
    conn.close()

    return {'statusCode': 200,
            'body': json.dumps(data),
            'headers': {'Content-Type': 'application/json'}}

```

# 試し

1回目の処理は成功
おぉ！上手く行ったと感動
2回目たたくとInternalServerエラー
へっ？とログを確認
すると、1回目の処理時はコネクション作成OKのログがでているけど、
2回目の処理時はコネクション作成のログがでていない

![CloudWatchLog.JPG](https://qiita-image-store.s3.amazonaws.com/0/237984/db17efa5-d545-c001-17c7-093e042a70e8.jpeg)

# 原因

わかってみると当たり前なんですけど、
Lambdaコンテナーロード時はhandler以外の部分も実施されるけど、
Lambdaコンテナーにある間はhandlerしか呼ばれないんですね

だから、チュートリアルには、下記のように書かれていたのかと納得
> パフォーマンス向上のために、ここに示されているように pymysql.connect() はハンドラー外で実行することをお勧めします。

コンテナーロードされた初回は、
コネクション作成（というかPGロード）⇒handler実行⇒SELECT⇒コネクションクローズ
コンテナーロードされている状態の2回目以降は
handler実行⇒SELECTするがコネクションクローズされているのでエラー
という状況でした

[conn.close()]を外して、処理実施すると、初回も2回目以降もエラーなく処理できるようになりました

Lambda、pythonとも初心者な状態で、調子のってコネクションクローズいれてみたおかけで、
勉強になりました。。。
yet another mackerel-plugin-proxysqlのご紹介


# はじめに
私の所属しているリブセンスでは、[ProxySQL](https://proxysql.com/)の `v1` を2017年から利用しています。
本番投入に合わせて私が作ったMackerel用のmetricsプラグインがあるのですが、作りが雑だったのでリポジトリ非公開で利用していました。

時は流れて2019年1月末、ProxySQLの `v2.0.1` が公開されました。
こちらはProxySQL **v2** から「 **RC** 」が取れた最初のリリースです。

ということで、 **ProxySQLはv2を本番投入が可能になったと言える** でしょう。
この機会に、上述のMackerelプラグインを更新してちゃんとGitHubにアップし、バージョン管理するようにしました。

今回はそのご紹介です。

# プラグイン紹介

## 最初に注意事項

[Mackerel公式プラグインレジストリ](https://github.com/mackerelio/plugin-registry)に同名の「 `mackerel-plugin-proxysql` 」が登録されていますが、そちらは[hfm氏作成のもの](https://github.com/hfm/mackerel-plugin-proxysql)です。
同じ目的で同じようなものを書いているので、 **とても似ていますが別物です** のでご理解ください。互換性は、有りそうで無いと思います。

*※ 同名であることで支障が出てきたら、名前を変えます。*

## プラグインのリポジトリ
前置きが長くなりましたが、プラグインはこちらです。

- https://github.com/livesense-inc/mackerel-plugin-proxysql

## インストール

ProxySQLのサーバーで利用するのが基本形です。
インストールする場合は、 `mkr` インストール済みの環境であれば、以下でOKです。

```bash
sudo mkr plugin install livesense-inc/mackerel-plugin-proxysql
```

mackerel-agentの設定ファイルに以下のように追記しましょう。（パスやオプションは注意）

```text:mackerel-agent.conf
[plugin.metrics.proxysql]
command = "/opt/mackerel-agent/plugins/bin/mackerel-plugin-proxysql -connection-pool -monitor-stats -username xxxx -password xxxx"
```

*※ 使い方について、詳しくはREADME or ヘルプを見てください。*

エージェントを再起動すれば、Mackerelでグラフが描かれるはずです。

![mackerel-plugin-proxysql.png](https://qiita-image-store.s3.amazonaws.com/0/82212/d2252817-6b31-614c-3553-812734bfa500.png)


## プラグインの機能の補足説明

ProxySQLは取得可能なステータスが多い特徴があります。加えて、2017年頃のProxySQLのバージョンに比べると、v2になるまでの間に追加で取得可能になったステータスがいくつかあります。それらも今回のプラグインのアップデートにあわせ、取得できるようにしました。

その結果、 このプラグインを利用すると **標準で15グラフ、63メトリックが追加されます。**

加えて、 **モニター関連** のステータスを `-monitor-stats` オプションで追加できます。
有効化すると **更に２グラフ、7メトリックが追加** されます。

さらに、**コネクションプール関連** のステータスを　`-connection-pool` オプションで追加できます。
有効化した場合、 **5グラフ、バックエンドの数x8メトリックが追加** されます。

つまり、 **全ての出力を行うとホストメトリック数が爆発的に増加します。**
メトリック増は課金増にも繋がるので、ご利用の際はご注意を・・・ 

# 終わりに

グラフとして見にくい箇所、メトリックのまとめ方が気に食わないこと、そもそもバグもあるかもしれません。OSSの精神でよろしくお願いします。
プロキシ経由で新たなgitサーバにアクセスした際にアカウント聞かれず、はまった

標題のとおり、Windows＆プロキシ経由で異なるgitサーバにアクセスした際にはまりました

# 環境＆状況

- Windows7
- 社内ネットワークで外部に出る際にプロキシ使用
- 自分のgitサーバと会社のgitサーバを使用（いずれも外部へのアクセス）
- 自分のgitサーバの初回アクセス時にユーザ／パスワードを聞かれ、以降は良きに保存してくれてるのか聞かれない
- 会社のgitサーバに初回アクセスした際に、ユーザ／パスワードを聞かれずエラー

# 原因

gitサーバにアクセスした際のアカウント／パスワード
Windowsだと良きに保存してくれて、初回以降は入力なしにアクセスできます

非常に便利で嬉しいのですが、httpプロキシ経由でアクセスする場合、
プロキシに対し資格情報を保存されてしまっていて、
異なるgitサーバにアクセスした際にエラーになってました

gitの資格ヘルパーが良きにやってくれてるのかと、gitconfigとかみてたけど、
何も資格情報保持している感なくて、Windowsが資格情報保持してるのに気付くのに時間かかってしまいました。。。

# 資格情報の保存場所

- 資格情報マネージャって機能で管理しています
- Windowsメニューの[プログラムとファイルの検索]で「資格情報」っていれると資格情報マネージャがでてきます
- [コントロールパネル]⇒[ユーザとアカウント]⇒[資格情報の管理]でもいけます
- プロキシのURLで資格情報保持されているので、こいつを一端削除すればOK
（下記だと、git:http://proxy.hogehoge.jp）

![Windows資格情報.JPG](https://qiita-image-store.s3.amazonaws.com/0/237984/d98b3a55-4d00-d914-acc4-2c9eb2f29eb4.jpeg)
Centosでプログラムがコアダンプを吐く場所

環境：Vagrantでcentos 7.6.1810 (Core)

#プログラムがエラーの場合にコアダンプを吐く

何らかの理由（セグメンテーション違反とか）でプログラムがエラーで終了した場合、
デフォルトではそのプロセスのカレントのディレクトリにcore.PIDという形で吐かれる。

```
#cat /proc/sys/kernel/core_pattern
core
```

なおcentosではデフォルトではコアダンプは吐かない設定となっているので

```
 vi /etc/systemd/system.conf
```
で 

```
DumpCore=yes
DefaultLimitCORE=infinity
```

を設定する必要がある。
・ダンプコアを吐かせる
・ダンプコアのデフォルトの最大値を無制限にする。

#プログラムのカレントディレクトリってどこ？

テストしてみる

```
#sleep 1000000000000&
[1] 11043
```
sleepコマンドがPID 11043が動いているので
何のファイルがあるか確認してみる。

```
#ls -l /proc/11043/cwd/
total 8
-rw-r--r--. 1 vagrant vagrant   31 Jan 22 13:32 test.txt
-rw-r--r--. 1 vagrant vagrant 3009 Jan 14 07:48 Vagrantfile
```
vagrantユーザのホームディレクトリが表示された。
実際にプロセスをセグメンテーション違反させる。
killコマンドでシグナルを送る

```
kill -l 
```
で遅れるシグナル確認できる。

```
1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

```

11番がセグメンテーション違反のシグナルなので
11043のプロセスにシグナルを送る。

```
$ kill -11 11043
```


vagrantユーザのホームディレクトリを確認すると、

```
#ls
core.11043  test.txt  Vagrantfile
```
対象のプロセスIDのcoreファイルが作成された。
あとはgdbとかで解析したりなんなりする。

#参考
https://0x0c.info/?p=151
前向き　能天気な　プログラマ　で　いいじゃないか　

プログラムを書いていて、うまくいっているとき、
発想も前向きになる。

プログラムを書いていて、思ったとおりいっているとき、
どんどん進む。

#経験談

# BASIC編

ミニコン、メインフレームのPCの端末エミュレータ(BASIC)を移植した。

basic標準票

を見て、書き換えていった。

ホスト側のエディタと、BASICのエディタが継ぎ目なく利用できるようになった。

自分がどちらで作業しているかを意識しなくてもよい。


##basic残課題
作業の途中で、印刷しようとすると、改行を２回づつして、印刷量が半分になってしまった。
不具合は取れず、STOPを押して、もういちどRUNすると現象が出ない。
BASICまたは通信の初期化の過程で端末側のプリンタの設定を初期化するらしい。

#FORTRAN
連立微分方程式のPade近似の解法をFORTRANで初設計し、卒業研究発表した。

高速化、省資源化をねらい、前半と後半で配列を再利用した。


##FORTRAN残課題
コンパイラの最適化オプションをつけると、配列の再利用のところが、値がじゃまをする。
利用するときは、最適化するより、小さくて早いから最適化しないようにお願いした。
手で最適化したものの保守を他人に頼むのは

#アセンブラ編

VZエディタをN5200という機種のMS-DOSに移植。

知人が書いてくれた割り込みベクタテーブルの設定を調べるソフトウェアを動かして、
割り込みベクタのひとつづつのアドレスを書き換えていった。

次に、すべてのアセンブラを、１行づつ注釈にして、どういう動作をするか確かめていった。
 
必要な機能の説明をして手助けしてくれる人、動作させて不具合を報告してくれる人、どんどん作業が進む。

ある行を注釈にしたら、ただでさえ、早いぬめぬめスクロールが、画面が上に暴走していく。
まったく文字が見えず、ひとえに、キーを押すタイミングで何十行、何百行スクロールするかを体感していく。

この１行注釈にしたことで、一躍、ネット上で、「プログラマとして」有名になれた。

それまでは、通信ソフトの移植や、教育用ソフトウェアの作成をしていた。
特定の数十人から数百人が使うものだった。

何千人、何万人使うソフトウェアに関われたことは経験として幸せ。

SF作家の高千穂遥とか、中村正三郎とかと、VZ倶楽部発売記念パーティで、共著者としてため口きけるようになったのも、たった１行を註釈したことによる。それも、お二人がVZの利用者側であるのに、自分は開発側として口をきくという。

前向き、能天気な　プログラマ　で　いいじゃないか。

##VZ残課題
移植が終わった頃、SDK相当の資料を見せてもらったことがある。
該当する部分の仕様は見なかった。
お金を払っていない人には開示できない資料を読んで、ネットに書いてしまうとまずい。
知らなきゃ書きようがない。

#参考資料(reference)

私がプログラミングの勉強をするときの手順とか使うサービスとか
https://qiita.com/nanaki11/items/c1f339df959667cdad4e

コードを書く際の指針として見返すサイトまとめ
https://qiita.com/kenichi_cc/items/c3ecca7b7d5fc5c6bf2e


#文書履歴(document history)
ver. 0.01 初稿 20190205
ver. 0.02 参考資料追記 20190210
ver. 0.03 参考資料追記 20190212
dotnet-formatでC#ソースコードを整形する

# はじめに

roslynのリポジトリを見ていたら、[dotnet-format](https://github.com/dotnet/roslyn/tree/master/src/Tools/dotnet-format)なるツールがあって、ちょうど良さそうなツールだったので紹介してみる。

# なぜ必要か

昨今IDEの発達により、ソースコードのかなりの部分が自動的に整形されるようになり、あまり自分のコーディングスタイルというものを意識しない人も増えてきたと思う。
しかし、それでも自分でも無意識のうちに持っているコーディングスタイルというものはどうしても存在する。

一人で開発しているうちは好きにしたらいいと思うが、これが複数人での開発となると、各々のコーディングスタイルの違いから、本来の修正以上の差分が発生してノイズになってしまう場合がある。
特にIDEの設定が各々異なるものを持っていた場合、自動的に整形されて余計な差分だらけになってしまうという悲劇はある(あった)。

対策として、[EditorConfig](https://editorconfig.org/)を設定するという手があるが、現状対応していないエディタというのもあるにはある。
また、都度都度エディタに任せて変換するよりも、コミット時に、確認の意味も含めて一括で変換したい場合もあるだろう。

そこで、そういう時は今回紹介するdotnet-formatが役に立つんじゃないかと思う。

# インストール

## 事前準備

dotnet-formatは [.NET Core グローバルツール](https://docs.microsoft.com/ja-jp/dotnet/core/tools/global-tools)として作られている。
また、内部的にmsbuildも使用しているため、[dotnet-sdk 2.1以降](https://dotnet.microsoft.com/download)が必要となる。

## インストールの実行

READMEにも書いてあるが、コマンドプロンプトで下記コマンドを実行する。

### 安定版、またはプレリリースバージョンを入れる場合

`dotnet tool install -g dotnet-format --version [パッケージバージョン]`と入力すれば良い。
使えるバージョンは、[dotnet-formatのページを参照](https://www.nuget.org/packages/dotnet-format/)

### 開発版を入れる場合

`dotnet tool install -g dotnet-format --version [NuGetバージョン] --add-source https://dotnet.myget.org/F/roslyn/api/v3/index.json`
実行後、`dotnet format --help`でヘルプが出力されればOK。されない場合、PATHが通っているか確認すること(Winの場合、`%USERPROFILE%\.dotnet\tools`、LinuxとMacの場合は`$HOME/.dotnet/tools`)。
バージョン番号は、実際に[roslynのmygetサイト](https://dotnet.myget.org/feed/roslyn/package/nuget/dotnet-format)を見て確認すること。
この方法でインストールした場合、最新のものを使用可能だが、代わりに予期しない不具合や、仕様変更等があるかもしれないので注意すること。

# 使い方

## EditorConfigの作成

基本的に無ければデフォルトの設定で動作するが、そのままだと`unset`で何もしない設定がかなり多いため、予め作成しておいた方がいいだろう。
`.editorconfig`は基本的にslnファイルと同じ場所に置くのが良いと思う。基本的な書き方は[EditorConfig本サイト](https://editorconfig.org/)や、それこそ"EditorConfig"で検索すればかなりの数出てくると思うので、ここで説明はしない。

C#独自の設定項目としては、[MS公式サイト](https://docs.microsoft.com/ja-jp/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017#formatting-conventions)が参考になる。ただし、**自分が試した限りでは使えるのは書式規則だけで、言語コード スタイル等は使えなかったので注意してほしい。**この辺り、使えた人がいたら情報求む。
後、**charsetとend_of_lineも挙動が怪しかった(効いてなさそう)**ので、多少注意が必要だろう。
この辺りはdotnet-formatの問題というよりは、ソースを見る限りはroslynの`Workspace.TryApplyChanges`辺りの問題と思われる。

### 使用可能な設定

dotnet-formatで使用可能な設定の一覧は、下記URLに記載してある。
https://github.com/dotnet/format/wiki/Supported-.editorconfig-options

## フォーマットの実行

フォーマットの実行は、`dotnet format -w [ソリューションファイル又はプロジェクトファイル]`で良い。
実行すると、ソリューション配下またはプロジェクト配下のC#ソースとVBソース全てに整形が適用される。
**F#ソースやXML等その他のファイルには適用されないことに注意。**

### 対象ファイルの絞込

デフォルトではプロジェクト配下全てのファイルを対象にするが、3.0.4からは`--files`オプションが有効になり、これによって対象ファイルを明示的に指定できるようになった。
複数指定する場合は、`,`で区切る。
ただし、今の所対象外ファイルの指定や、ワイルドカード等は使えない模様。

# 終りに

dotnet-formatは、フォーマットしかしない。この点、gofmt等と比べると不足を感じるかもしれないが、それでも単機能ツールとしては十分だと思う。
複数人プロジェクトで開発する時、PRレビュー等で書式関連の余計なノイズを減らしたいという場合は、検討してみるのもいいのではないかと思う。
Goで特定のテストケースだけ実行しない方法

go test で「特定のテストケースだけ実行しない」ということをしたい。

もっといいやり方あったら教えてください。

## 方法

ビルドタグを使う

### 手順

### 1. 実行したくないテストケースを別ファイルにする

パッケージは変えなくていいです。



### 2. ビルドタグを追加

除外したいテストケースを書いたファイルの冒頭にビルドタグを追加します。

```go
// +build !abnormal_test

package foo
...
```

### 3. tag 指定で `go test`

```console
$ go test -tags="abnormal_test" ./...
```

おわり
CentOS7にGoogle Chromeをインストール

##はじめに
Linux丸腰初心者の備忘録です。


##環境
####ホスト
OS：CentOS7 GNOME

####クライアント
OS：high Sierra

##手順
基本的には\[1\][CentOS7にGoogle Chromeを簡単にインストールする方法](https://www.karelie.net/how-to-install-google-chrome-on-centos7/)に準じます。

```sh:su
$ su
```

<font color="blue">ここで警告が出るが、無視。</font>

```sh:vi
$ vi /etc/yum.repos.d/google-chrome.repo
```
`vi`コマンドでvimのノーマルモードになるので、`i`を押して編集モードに切り替え、以下をコピペ。
`ctrl`+`shift`+`C`,`V`

```sh:write
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
```

**Escを押して`:wq`と入力**
`:wq`は変更を保存して終了という意味。

```sh:install
$ yum install -y google-chrome-stable
```
最初に`su`としているので`sudo yum...`とする必要はなし。

##終わりに
筆者はこのあと`reboot`で失敗、再起動不能になり<font color=FF3333>Ubuntu  18.04</font>に乗り換えます。リンク切れとか、結構きつい。

###参考文献
[CentOS7にGoogle Chromeを簡単にインストールする方法](https://www.karelie.net/how-to-install-google-chrome-on-centos7/)
[viコマンド（vimコマンド）リファレンス](https://qiita.com/TD3P/items/0510bee10bcfd88afeee)
Pythonの変数はイミュータブルなのでポインタみたくはできない

#はじめに

[C - Not so Diverse](https://atcoder.jp/contests/abc081/tasks/arc086_a)を解いている際に引っかかった初歩的なことついてメモとして残しておきます。
~~結論を先にいうと、Pythonのint型はイミュータブルな型なのでメモリの節約はできません。~~
[追記2019/2/7]構造体を使えば同じ領域を参照することは出来る。とご指摘いただきました。ありがとうございます。


##ポインタ渡し

もともとやりたかったことはこんな感じ。

```sorce.c
#include <stdio.h>

void plus();

int main(void){
    int num2 = 5;
    plus(&num2);
    printf("%d \n",num2);
    return 0;
}

void plus(int *x){
    *x += 2;
}
```

```c
>>>7
```
##Pythonで値を保持し続ける
そして、Pythonでポインタ渡しと同じことをしようと試みるも...

```sorce.py
def main():
    num2 = 5
    plus(num2)
    print(num2)

def plus(num2):
    num2 += 2
    return num2

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

```python
>>>5
```
となってしまいます。`plus()`を受け取れていないからですね。Cに慣れているとやりがちでしょうか。
正しくは`num2 = plus(num2)`としてnum2を出力すれば良い。

```python
def main():
    num2 = 5
    num2 = plus(num2)
    print(num2)

def plus(num2):
    num2 += 2
    return num2

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

```python
>>>7
```
これでひとまず値が保存されているので、良さそう。

##ポインタ渡しになっていない
メモリの節約を試みたいので以下のようにしてみます。

```sorce2.py
num2 = 0
def main():
    global num2
    num2 = 5
    plus()
    print(num2)

def plus():
    global num2
    num2 += 2


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

```python
>>>7
```
たとえmain関数であってもglobal宣言はマストです。

`sorce2.py`↑でポインタ渡しになっているかしらべてみます。

```sorce3.py
num2 = 0
def main():
    global num2
    print(id(num2))
    num2 = 5
    print(id(num2))
    plus()
    print(id(num2))
    print(num2)

def plus():
    global num2
    num2 += 2

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

```python
>>>4393719184
>>>4393719344
>>>4393719408
>>>7
```
この通り、識別値が変わってしまっています。
[Pythonの値渡しと参照渡し](http://amacbee.hatenablog.com/entry/2016/12/07/004510)によると
>渡された値を変更した際に元の値自体も変更されてしまうかどうかは，オブジェクトの型に依存します．
>変更不可（Immutable）な型
>int, float, str, tuple, bytes, frozenset 等
>変更可能（Mutable）な型
>list, dict, set, bytearray 等
>変更可能な型では，渡された値が変更されると元の値も変更されてしまいます．（新しく領域が確保されません）

ということなので、ﾀﾞﾒです！ﾃﾞｷﾏｾﾝ!!
<font color="red">イミュータブルな型では別領域が確保されてしまいます。</font>

##引数にglobal変数を入れてはいけない


```argument.py
num2 = 0
def main():
    
    num2 = 5
    num2 = plus()
    print(num2)

def plus(num2):
    global num2
    num2 += 2
    return num2

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

```python
>>>  global num2
     ^
SyntaxError: name 'num2' is parameter and global
```
引数 <font color="orange">and</font> global変数にしているよ〜と怒られます。<font color="red">global変数として使いたいのにglobal変数として宣言しているところを指摘される</font>と混乱しがちですが、`plus(num2)`の方が上に書いているため当然といえば当然。


##おわりに
わざわざ同じ領域を使い続けなくても数字は受け渡し続けられるので値を更新するだけでよさそう。
プログラミング初心者のHTMLとCSS

<h1>はじめに</h1>
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているHiromasa030911です。
この度、プログラミングを学習することになったので、初心者目線で学習の進捗を書いていきます！
今回は、プログラミングの基礎であろうHTMLとCSSについて書いていこうと思います。
<h2>HTMLとは</h2>
HTMLとは、文字列に「タグ」と呼ばれるカッコのようなものをつけることで、見出しやリンクなどの意味を持たせていく仕組みである。
いわば、ホームページの骨格にあたるものを作る
例えば、`<h1>　はじめに　</h1>`　で見出しができる。
このタグにはいろいろな種類があって、画像を示す[img]とか、要素を示す[li]とかがある。
これから自力でホームページをスムーズに作るには、これらのタグを覚えておく必要がある。
<h3>CSSとは</h3>
CSSとは、HTMLでできた文字に色や形などのアレンジを加える。
よくあるホームページのかっこいいフォントやデザインはCSSによって作られているのだ。
HTMLの「タグ」のように、CSSにも「プロパティ」というものがある。
例えば、文字の大きさを変えるには「font-size」種類を変えるには「font-family」などがそれにあたる。
これらのプロパティも覚えておくと円滑に操作ができる。
<h4>まとめ</h4>
今回は、プログラミングの基礎である、HTMLとCSSについてまとめてみた。
作業中は覚えることが多くて大変だけど、自分でページが作れたときはとても嬉しかった。
まだまだ、覚えることがたくさんあるけど、これからの学習も頑張っていきたい。
Why e-commerce Mobile apps will trend in 2019

The inception of the e-commerce industry has given a paradigm shift to the way people shop. Online shopping has gained popularity due to many reasons, but one of the most prime reasons is that it offers utmost convenience and luxury to people. They have a wide variety of options to choose from and that too while sitting at home sipping their favorite drinks. Read from here.. https://www.prismetric.com/why-e-commerce-mobile-apps-will-trend-in-2019/
Goでマイナス表示されたint32を「２の補数」で16進数表示をする

# 32bitの2の補数を求めたい

タイトルが長くてわかりにくいですが、要するには整数の`-100`が`ffffff9c`という表記になって欲しい（32bitの2の補数:tows complement）ということです。簡単な方法が見つからなかったので、binary経由の正攻法(?)を使用しました。

※ コメント欄に最適な方法を頂きましたので、そちらをご覧ください。

```go
package main

import (
	"fmt"
	"bytes"
	"encoding/binary"
)

func main() {
	buf := new(bytes.Buffer)
	var num int32 = -100
	err := binary.Write(buf, binary.BigEndian, num)
	if err != nil {
	    fmt.Println("", err)
	}
	fmt.Printf("%x", buf.Bytes())	
}

```

実行結果

```
ffffff9c
```

## 補足

-1を16bitで2の補数表記をすると`0xffff`。32bitの場合は`0xffffffff`となります。C言語など整数のオーバーフローチェックがない言語では、キャストするだけで2の補数が取れるのですが、Goは実行時型チェックが強いがために遠回りをする必要がありました。
【AWS】Private環境におけるSESを利用したメール配送


■2020年5月26日追記
awsが公式にSESのprivatelinkをサポートしたのでこちらの記事は陳腐化しました。
今後、こちらを試して記事にしてみます。
https://aws.amazon.com/jp/about-aws/whats-new/2020/04/amazon-ses-now-offers-vpc-endpoint-support-for-smtp-endpoints/



※本記事はSESのPrivateLinkが存在していない時点での記事となりますので、今後サービスとして利用可能になった時点で古い記事になります。

#目的
本記事では、以下2点についての共有を目的とします。

　①．Privateセグメントに設置されているWEBサーバより、Amazon Simple Email Service（以下、SESと記載する）を利用したメール配送を行えるデザインパターン
　②．①の作成過程で判明した事柄

#はじめに
エンタープライズ向けのaws開発では、PrivateセグメントにWEBサーバを配置し、外部へメール送信する必要があるシステムを要求される事があるかも知れません。
外部へのトラフィックについては、厳重なセキュリティ設計が要求されるかも知れません。
私はそのようなシステムを要求され開発を行ったのですが、その中で分かった事を以下に記載致します。

#当初想定していたシステム構成
awsでは、PrivateセグメントからInternetを経由せず、awsのサービスへ接続する事が出来る仕組みがあると聞いた事があったので
SESでも同様の事が出来るだろうと思っていました。
インターネットで調べても記事は見つからなかったのですが、SESのインターフェースの名前がSMTPエンドポイントと呼ばれている事が分かりました。
脳内でSMTPエンドポイント＝エンドポイント≒PrivateLinkと同等の機能がある？と勝手に変換し、以下システム構成にて接続を試みました。

![pic01.jpg](https://qiita-image-store.s3.amazonaws.com/0/339486/765cc558-4e2c-441a-f9bd-5564c4bab138.jpeg)



SESの各種カウントが上がっていなかったので、送信出来ていない事が分かりました。。。

#システム構成を再検討
公式ドキュメントやアンオフィシャルのブログ等を調べた結果以下の事が分かりました。

　・SES用のPrivateLinkは現時点では存在していない。
　・NATゲートウェイ、インターネットゲートウェイが必要そう。
　・VPCピアリングをして、ピアリング先のVPCのNATゲートウェイを利用する事も検討したが、ピアリング元からピアリング先のNATゲートウェイは使えない仕様でした。
　・インターネット経由の通信トラフィックは、メールのみに通信ポートを絞る方がセキュリティ的に良い。
　・NATゲートウェイ、インターネットゲートウェイに対してセキュリティグループ、ネットワークACLをアタッチする事は出来ない。
　・VPC、サブネットに対してセキュリティグループをアタッチする事はできないが、ネットワークACLをアタッチする事は出来る。

これらを踏まえて、以下システム構成にて接続を試みました。



![02.png](https://qiita-image-store.s3.amazonaws.com/0/339486/3a62f08a-cd82-5ef2-3715-993615f9930c.png)



SESの各種カウントが上がっていなかったので、送信出来ていない事が分かりました。。。

#システム構成を再々検討
ネットワークACLにて、587ポートのinbound,outboundについて開放したが、なぜか通信できないので、
VPCフローログを確認すると謎のポート（1万番台や5万番台など）が利用されていた。
色々調べた結果、NATゲートウェイは動的NAPTという形態のNATである事が判明した。（動的にポートを変える仕様？）
公式ドキュメントにも1024-65535の範囲のポートを使う旨の記載がありました。
（NATインスタンスはポート転送機能に対応している記載があったので、恐らく587ポートのみで通信が可能。（未検証））
また、SESは有料オプションで固定IPアドレスが利用可能である事が判明した。（24.95USD/月）

#デザインパターン
これまでの調査結果を踏まえて完成したデザインパターンを以下に記載します
（机上評価しか実施しておりませんので、動作保障は致しません）

2019/2/8 修正　ネットワークACLはステートレスなので、行き・帰り両方の通信に対しての定義が必要。
　　　　　　　　ルートテーブルの記載も追記。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/339486/2996edb4-c8ca-d4a7-1c86-f9fdd2a5cf59.png)
エンジニア以外もバッチをたたけるようにしたいって？Jenkinsなら簡単だよ

# エンジニア以外もバッチをたたけるようにしたい

例えば

* マスタデータを反映したりとか
* キャラクターデータをdevelopサーバーからstagingサーバーへ反映したいとか
* 時々サイトのバナーの画像を入れ替えたいとか
* etc,etc,etc

のようなちょっとした作業をバッチファイルにして持っているプロダクトは多いと思います。(僕の想像力が欠如しているのですが皆さんはきっといろいろ持っているでしょう)

で, 毎回この作業をするときに毎回エンジニアがなんか依頼されてsshで入ってバッチたたいてってめんどくさいじゃないですか。なんならssh入れるようにしたところで, わかんなーいこわーいとか言われるわけですよ。

なんか管理画面があってそれに毎回実装とかもめんどくさいじゃないですか, なんなら特定の環境でしか使わないこともあるわけで, 本番では出しません！とかもうUIつくるのすらめんどくさいじゃないですか。しかも使うのは月一以下だったりするわけですよ。

そういうちょっとしたたまにある作業に対しての一つの回答です。

# 非エンジニア向けバッチは全部Jenkinsにしなよ

Jenkinsなら簡単にwebGUIを作成できます。
作業サーバーをスレーブにしちゃえばそこにcloneしてもいいし, 最悪サービスを動かしているディレクトリ上で動かしてもOKです。

なんならパラメータを指定することもできます。
実行後に本当に実行していいのかの確認ボタンを出すこともできます。

1度方法を教えてしまえば全て使い方は一緒です。

## メリット

* エンジニアはちょっと～これやってくださいよ～みたいなのが減る
* 非エンジニアは自分でできるようになるのでお願いするコミュニケーションコストが減る

## ちょっと気を付けること

* 名前はわかりやすくしましょう。
* パラメータはできる限り減らしましょう。（増えると拒否感強くなる）
* このジョブを実行すると何が起こるのかをいつもより詳しく書きましょう。
* できれば一回（メインで使う人と）一緒にやってみましょう。

# 別にJenkinsである必要はないよ

僕がJenkinsが得意なので表題にはJenkinsと書いていますが, 他のCIツールでも大丈夫ですし, 当然Jenkins等のCIツール以外を使用することがいい結果になる場合もあります。

* ローカルで使うバッチ
    * CIツールが基本サーバーなので各人のPCで動かすのは大変
        * ダブルクリックでバッチファイル動かすとかでもいい
        * Windowsなら簡単にC#でGUIが作れるので簡単にかぶせてもいい(バッチ呼び出しが少し面倒くさいけれど)
* グラフや集計
    * DBのデータを加工したり検索するのはJenkins等のCIツールだけではちょっと辛い
        * Re:dash,Superset等が適当
* 3Dや2D等
    * 3DならMayaやUnity等のスクリプトがいいことがある
    * 2DならPhotoshop等のスクリプトがいいことがある

また, 利用人数が多いなどがあれば, 普通に管理画面等を作成したほうがいい場合も多いです。

# 言いたかったこと

コミュニケーションコストはエンジニアが減らせるよ！
そのために適当なツール使うと割と便利よ
システム開発系でスクラム（アジャイル）を導入するために参考にしたページ

# スクラム導入系記事
[アジャイルな組織って？サービスとチームづくりに最適な開発手法の選び方 #GWD_Nulab | ヌーラボ](https://nulab-inc.com/ja/blog/nulab/geeks-who-drink-tokyo-agile-edition-2018-06-22/ "アジャイルな組織って？サービスとチームづくりに最適な開発手法の選び方 #GWD_Nulab | ヌーラボ")

[実例に学ぶスクラム導入手順 - タスク属人化を避け、チーム開発力向上のためにRettyがやったこと - エンジニアHub｜若手Webエンジニアのキャリアを考える！](https://employment.en-japan.com/engineerhub/entry/2018/11/16/110000 "実例に学ぶスクラム導入手順 - タスク属人化を避け、チーム開発力向上のためにRettyがやったこと - エンジニアHub｜若手Webエンジニアのキャリアを考える！")

ツール群が比較、紹介されているのがすごくありがたいです。
[スクラム向けプロジェクトマネジメントツールを比較した結果 Zube.io を推してみる - Witch on the Other Shore](https://iktakahiro.hatenablog.com/entry/2018/07/12/192213 "スクラム向けプロジェクトマネジメントツールを比較した結果 Zube.io を推してみる - Witch on the Other Shore")

[スクラム導入時の6つのコツ - Qiita](https://qiita.com/thiroi/items/9bbd43fbad79d3c7b31c "スクラム導入時の6つのコツ - Qiita")

[スクラムを導入してみた話 - くらしのマーケット開発ブログ](https://tech.curama.jp/entry/2018/05/18/140000 "スクラムを導入してみた話 - くらしのマーケット開発ブログ")

[スクラム開発の手法とは？ スクラム開発の歴史や事例 | TeamHackers](https://teamhackers.io/about-scrum-agile "スクラム開発の手法とは？ スクラム開発の歴史や事例 | TeamHackers")

# ZenHub
[ZenHub を使って Kanban 方式をプロジェクトに取り入れる - Qiita](https://qiita.com/yoheimuta/items/ddf4b278f3db79ce2a8f "ZenHub を使って Kanban 方式をプロジェクトに取り入れる - Qiita")

[スクラムにおけるGitHub/ZenHubの使い方の例(discussion-sidebar編) ｜ DevelopersIO](https://dev.classmethod.jp/etc/github-discussion-sidebar/ "スクラムにおけるGitHub/ZenHubの使い方の例(discussion-sidebar編) ｜ DevelopersIO")

[GitHub Project機能が強化されたのでZenHubから移行することを検討してみた | feedforce Engineers' blog](http://tech.feedforce.jp/discuss-moving-from-zenhub-to-github-project.html "GitHub Project機能が強化されたのでZenHubから移行することを検討してみた | feedforce Engineers' blog")
逆にGitHub Projectへ移行したお話しです。

[Mackerelチームのリモートワーク体制における日報とデイリースクラム - Hatena Developer Blog](http://developer.hatenastaff.com/entry/2015/07/05/174343 "Mackerelチームのリモートワーク体制における日報とデイリースクラム - Hatena Developer Blog")
dockerでnginxを使ったときのメモ

dockerでnginxのコンテナを作成した時のメモを残す。

#前提
nginxはド素人。PHP(Laravel)の環境を作る必要があり、使ったことが無いnginxで動かしてみようという軽いノリで始めたメモ。

#docker pull nginx
```bash:command
$ docker pull nginx
$ docker run --name nginx00 -d -p 8080:80 nginx:latest
```

基本はこんな感じで、 **とりあえず**動かして喜ぶ。
で、以前の僕は必要なオプションを追加追加追加追加しながら自分に合ったオプションを含めてコマンドを覚えていた。

##よく使ったオプション[-v]
ローカルのディレクトリとコンテナ内のディレクトリをマウントしていた。
##よく使ったオプション[--link]
他のコンテナと連携するために使っていた。が、今は非推奨になっていた。調べてみると、コンテナで使用する専用のネットワークを予め作る事でコンテナ間の連携が出来るらしい。

```bash:command
$ docker network create <NETWORKNAME>
$ docker run --name nginx00 -d -p 8080:80 nginx:latest --net=<NETWORKNAME>
```

同じネットワークを利用したコンテナ同士で連携が出来ると言うことなんだろう。

#docker-compose
コマンドとオプションを揃えて忘れないようにメモ帳に残していたときもあったけど。多分、スマートじゃ無い。薄々わかっていたので今回はそれは避ける。
どうやら、 **docker-compose**という機能があるらしいので挑戦。

##docker-compose.yml
作りたい環境の構成を **docker-compose.yml** にYAML形式で記しておけばいいらしい。

```yaml:docker-compose.yml
version: '3'

services:
  web:
    build:
#     context: <dockerfileのパス:./hogehoge>
#     dockerfile: <dockerfile名:xxx.dokerfile>
      context: ./docker
      dockerfile: web.docker
#   container_name: <作成するコンテナ名?>
    container_name: web00
#   depends_on:
#     - <連携したいコンテナ名?>
    ports:
      - 8080:80
    volumes:
      - ./proj/var/www/html:/var/www/html
      - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf
    networks:
      - <所属するネットワーク名?>
network:
  - <作成するネットワーク名(所属するネットワーク名)?>
```

docker-compose.yml と dockerfile を適切な場所に用意したら __docker-compose__コマンド実行すると自動でコンテナが出来上がる。

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

__-d__オプションを付加しないとバックグラウンド実行にならない。
環境が不要になったら、 __up__を __down__に変えて実行。

```bash:command
$ docker-compose down
```

コンテナが停止し、 __コンテナが削除される__。

docker-compose.ymlについては、改めて調べてから別途メモを残したい。

##./docker/web.docker
今はとりあえず動かすことが優先なので一行だけしか書いていない。

```dockerfile:web.docker
FROM nginx:latest
```
これだけなら、docker-compose.ymlでimageを指定すれば済んだはず。


##./docker/nginx.conf
nginxの設定を予め用意する。これで上書く。
このファイルを書くまで気付かなかったが、nginxのドキュメントルートの標準は __/usr/share/nginx/html__らしいので、 __/var/www/html__に変更した。


```conf:nginx.conf
server {
    listen       80;
    server_name  web00;
    root         /var/www/html;

    location / {
        # root   /usr/share/nginx/html;
        # index  index.html index.htm;
        root   /var/www/html;
        index  index.php index.html index.htm;
    }

    
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        # root   /usr/share/nginx/html;
		root   /var/www/html;
    }

}
```
Sequel Proが落ちる場合、テスト版を使うと落ちない

~~この記事を書いた2019年2月5日現在の`Sequel Pro v1.1.2`の場合のお話です。~~
もう`Sequel Pro`は本家の更新が2016年以降止まっているようです。

先日Mojaveにアップグレードして以来、Sequel Proのタブを閉じたりする度にアプリ自体が終了してしまい、
予期せぬ終了のダイアログが立ち上がるようになりました。
その後BigSurでも同様の現象にあったので、おそらくMojave以降のOSで起きるのだと思います。

https://sequelpro.com/test-builds
にあるテスト版をダウンロードして使ってみたところ落ちずに使えました。
安定版ではないだろうということと、アイコンのホットケーキにシロップがかかってなかったりしますが、
僕の環境では今の所問題なく使えているようなので、落ちずに使い続けたい場合は試してみても良いかもしれません。

参考
[keep crashing on Mac OS Mojave](https://github.com/sequelpro/sequelpro/issues/3177)
WebPが苦手とする画像の一例

基本的にJpegからのLossy変換でも再現性の高いWebPですが、珍しく劣化の目立つ画像を見つけました。

それが次のJpeg画像です。

<img width="240" alt="oshirase.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/35178/ec23aca9-2303-c693-256a-86e62f07f258.jpeg">

弊社のブログで使ったポリゴン調の背景画像を持つOGP画像兼バナーです。
https://blog.ideamans.com/

PNG向きな絵面ですが実際はJpeg画像で、WebPにLossy変換しました。
(WebPに変換された結果をQiitaにアップロードするためPNGに再変換してます)

![oshirase.png](https://qiita-image-store.s3.amazonaws.com/0/35178/fb31ca55-1085-7320-c303-262f207179f4.png)

これはちょっとキツいなぁ…という結果になりました。
ポリゴンの境界がずいぶんギザギザしてます。

WebPへの変換は数多く見てきましたが、ここまで印象が変わる例は初めてでした。

たぶん淡いコントラストの直線的な稜線が苦手なのではないだろうか、と推測してます。

レアケースだとは思うので、自動変換の場合は除外するパターンを定義できるとリスクを回避できそうです。
JavaScriptで13桁のISBNを10桁に変換する

前回書いた[JavaScriptで10桁のISBNを13桁に変換する](https://qiita.com/iz-j/items/27b9656ebed1a4516ee1)の逆バージョン。
13桁も10桁にすることが可能。

```javascript
const toISBN10 = (isbn13) => {
  // 1. 先頭３文字と末尾１文字を除く
  const src = isbn13.slice(3, 12);

  // 2. 先頭の桁から順に10、9、8…2を掛けて合計する
  const sum = src.split('').map(s => parseInt(s))
    .reduce((p, c, i) => (i === 1 ? p * 10 : p) + c * (10 - i));

  // 3. 合計を11で割った余りを11から引く（※引き算の結果が11の場合は0、10の時はアルファベットのXにする）
  const rem = 11 - sum % 11;
  const checkdigit = rem === 11 ? 0 : (rem === 10 ? 'X' : rem);

  // 1.の末尾に3.の値を添えて出来上がり
  return `${src}${checkdigit}`;
};
```