OmniAICreator/Qiita-1.07M huggingface dataset:
[Elm] DOM更新後にJSコードを実行する



この内容は Elm 0.18, 0.19 を対象にしています。
また、[Elm Discourseの回答](https://discourse.elm-lang.org/t/when-is-cmd-actually-processed/1008/2?u=arowm) が元ネタです。

## 結論

`update` 関数で DOM を更新した後に JavaScript を実行したい場合、

```javascript
elm.app.ports.foo.subscribe(function (id) {
  requestAnimationFrame(function () {
    /* when this callback executes, the view should have rendered. */
  })
})
```

のように ports を登録する必要があります。

## 問題提起

Elm の `update` 関数は、型 `update : Model -> Msg -> (Model, Cmd Msg)` で示されるように、なんらかのイベント (`Msg` で示されるもの) に応じて、更新後のDOM構造 (厳密にはDOM構造そのものではなく `Model`) と副作用 (`Cmd Msg`) を同時に指定します。

ports を用いて JavaScript を実行する場合、`Cmd Msg` の部分にその処理を記述しますが、
更新後のDOMに依存する JavaScript コードを実行したい場合はどうしたらいいでしょうか？

## 画面更新と Cmd の処理タイミング

`update` 関数によって新しい DOM 構造が指定されると、Elm はその更新処理を [`animation-frame`](https://developer.mozilla.org/ja/docs/Web/API/Window/requestAnimationFrame) に登録します。
その直後に、`Cmd Msg` として指定された処理を行います。

`animation-frame` はブラウザ画面のリフレッシュレートに応じた間隔で処理を呼び出すため、
特に工夫なく ports を使って JavaScript の処理を Cmd として登録した場合、画面の更新処理よりも先にその JavaScript が実行されてしまう可能性があります。

## 解決方法

画面の更新処理を `animation-frame` に登録しているので、実行したい JavaScript も同じように `animation-frame` に登録すれば、 `animation-frame` がタスクキューとして実行順を保証してくれます。

具体的には、冒頭で「結論」として示したように

```javascript
elm.app.ports.foo.subscribe(function (id) {
  requestAnimationFrame(function () {
    /* when this callback executes, the view should have rendered. */
  })
})
```

のような形式で、実行したい処理を `animation-frame` に登録する処理を記述すれば良いことになります。


[`elm-lang/dom`](http://package.elm-lang.org/packages/elm-lang/dom/latest) などは内部的に `animation-frame` に処理を登録する実装になっているため、更新後に初めて作成される HTML タグに対して `elm-lang/dom` で定義されているスクロールやフォーカスなどの処理を適用する際には、特に気にすることなく `update` の返り値に更新後のModelとともに処理を登録すればうまく動きます。

## 危険🐐スクリプト芸との関わり

実は[危険🐐スクリプト芸](https://qiita.com/arowM/items/93201dd5aded6e264e19)を使っても「DOM 構造に依存するJavaScriptを実行する」という需要を叶えることができます。

単純に、View に `script` タグを直接埋め込むだけです。

```haskell

someView : Model -> Html Msg
someView { showPart } =
    div
        []
        [ if showPart then
            div
                []
                [ anotherView
                , node "script" [] [ text """ /* JavaScript code */ """ ]
                ]
          else
            text ""
        ]
```

ただ、この手法は[「バグ」としてあつかわれており](https://github.com/elm-lang/html/issues/56)、次のバージョンの Elm では使えなくなる可能性が高いです。

非推奨な危険🐐スクリプト芸ではなく、`animation-frame` を使った方法を今のバージョンでも使うことをオススメします。


[![さくらちゃん](https://qiita-image-store.s3.amazonaws.com/0/16345/86b98051-3fd0-d773-523f-8546b63606e6.jpeg)](https://twitter.com/hashtag/%E3%81%95%E3%81%8F%E3%82%89%E3%81%A1%E3%82%83%E3%82%93%E6%97%A5%E8%A8%98?src=hash)
日本測地系からWGS84へ変換

こんにちは。
日本測地系からWGS84へ変換するプログラムを作りました。
* 測地系 WGS84[^1] から Tokyo Datum へ3パラメータ変換[^2] [^3]で変換された日本測地系[^4] 経緯度座標値（多くのGPS受信機の日本測地系出力）を、WGS84へ戻す変換に相当します。
* なお高度値も用いるならば、同じく3パラメータ変換で戻すのは容易ですが、ここでは高度値不要の変換を求めることとし、その代わりに内部でその地点の地表面高度を算出しています（楕円体高はパラメータファイルを入手して計算）。
* 変換式は近似多項式の形で求めました。この2次式の変換の正確度は下記のように島嶼を含む陸域で概ね 80cm 以下です（これに対し 1次式では 10m を超える地点が生じます）。

[^1]: WGS84 とは米国国防省策定の [World Geodetic System](https://en.wikipedia.org/wiki/World_Geodetic_System) （世界測地系）（1984年版）を指します。
[^2]: 「[日本測地系と JGD2000 との変換について](https://qiita.com/kkdd/items/1a64c6fb46315e3b669a)」の中の (3) です。
[^3]: 「[日本測地系における離島位置の補正量](https://www.jstage.jst.go.jp/article/sokuchi1954/49/3/49_3_181/_pdf)」（測地学会誌）の後半にも説明があります。
[^4]: なお 3パラメータ変換による変換だけでは正しくは日本測地系と呼ぶべきではなく、日本測地系の内部歪みも付加する必要があります。すなわち正しい日本測地系とは「[TKY2JGD](https://www.gsi.go.jp/sokuchikijun/tky2jgd_download.html)」（国土地理院）で取り扱われているものです。

![tky2wgs.jpg](https://qiita-image-store.s3.amazonaws.com/0/54617/b23a5036-b695-d332-e54d-33c2f276392e.jpeg)

```tky2wgs_approx.py
# angle units in degrees
def tky2wgs_approx(lon_tky, lat_tky, degree=2):
    L = lon_tky - 135
    B = lat_tky - 35
    if degree == 1:
        dL = -2.80641517e-3 - 4.98891541e-5*B - 8.33469263e-5*L
        dB =  3.20321021e-3 - 1.15452990e-4*B + 2.47032059e-5*L
    elif degree == 2:
        a00,a01,a02,a03,a04,a05,a10,a11,a12,a13,a14,a15 = -2.79648156e-03, -3.64571151e-05, -1.00958714e-06, -8.83091873e-05, -8.33002662e-07, 3.54561248e-07, 3.19774649e-03, -1.13997082e-04, -7.51313530e-07, 2.34640477e-05, 6.06731757e-07, 3.28340222e-07
        dL = a00+a01*B+a02*B**2+a03*L+a04*B*L+a05*L**2
        dB = a10+a11*B+a12*B**2+a13*L+a14*B*L+a15*L**2
    return lon_tky + dL, lat_tky + dB
```
Neovimでclipboardにunnamedを設定してるとペーストした際にレイアウトが崩れるのを回避する方法

### Summary

`clipboard`に`unnamed or unnamedplus`を設定していると `put(paste)`した際にレイアウトが崩れる

レイアウトが崩れるのを回避する方法

```
// init.vim
set clipboard=unnamed
```

### Workaround

`put(paste)`するさい`unnamed registers`を指定する


`""p`




### Environment

```
$ sw_vers 
ProductName:	Mac OS X
ProductVersion:	10.13.4
BuildVersion:	17E199

$ nvim --version
NVIM v0.2.3-dev
Build type: Release
```

### たとえば・・・

このテーブルに

```
| foo | bar |
| --- | --- |
| aaa | bbb | 
```

このカラムを右に足して

```
| baz |
| --- |
| ccc |
```

こんな感じのテーブルにしたい

```
| foo | bar | baz |
| --- | --- | --- |
| aaa | bbb | ccc |
```

現状（`p`)

```
| foo | bar |
 baz |
 --- |
 ccc |
| --- | --- |
| aaa | bbb |
```

workaround（`""p`）

```
| foo | bar | baz |
| --- | --- | --- |
| aaa | bbb | ccc |
```

### よければ・・

こんな回避方法あるよ！とかあれば下記の`issue`に追記してくださると嬉しいです！

https://github.com/neovim/neovim/issues/8272
EXCEL VBA Split関数の文字列を縦に並んだセルからイミディエイトに出力するマクロ

ユニコード文字、コンマがあるとうまくいきませんが、ちまちまと打つよりはExcelにいれて出力すると楽だと思います。
450文字程度で折り返します。
Sheet1にA列に項目を縦に並べて継続文字(アンダーバー）が24を超えたら、別のSplitが始まります。
Sheet1ってファイルを新作成したときにできるシートです。
横に並んでいるデータは形式を選択して貼り付けで行列を入れ替え、縦に並べてください。

```visualbasic

Sub CraeateSplitString()
'For Excel

Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim str As String
Dim iLen As Long
Dim Cnt As Long
Dim LastRow As Long : LastRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count,1).End(xlUp).Row
Dim ar: ar = ThisWorkbook.Worksheets("Sheet1").Range("A1:A" & LastRow) 'A列に並べる 横に並んでいる場合にはコピーして形式を選択で貼り付けで行列を入れ替え、値だけ複写して縦にする。
str = "Split(" & Chr(34)
Cnt = 0
For i = LBound(ar) To UBound(ar)
iLen = iLen + Len(ar(i, 1) & ",")
str = str & ar(i, 1) & ","
If iLen > 450 Then
iLen = 0
str = str & Chr(34) & " & vbCrLf & _ " & vbCrLf & Chr(34)
Cnt = Cnt + 1
If Cnt = 25 Then
str = Left(str, Len(str) - 1) & Chr(34) & "," & Chr(34) & "," & Chr(34) & ")" '改行は24までなので、25になった場合はいったんSplit関数としてイミディエイトに出力してクリアする。
Debug.Print str
Cnt = 0
str = ""
str = "Split(" & Chr(34)
iLen = 0
End If
End If
Next i
str = Left(str, Len(str) - 1) & Chr(34) & "," & Chr(34) & "," & Chr(34) & ")"
Debug.Print str
End Sub
```
GitLabを試してみるメモ

# DockerでGitLabを試してみる

GitLabをDockerで動かしてみたときのメモ。
一応、データは永続化のためVolumeに保存します。
なお、環境はWindowsでDocker Toolboxを使用しています。

# docker-compose.yml

データ永続化のため、一部Volumeに切り出します。

```docker-compose.yml
version: '2'
# volume定義
volumes:
  config-vol:
    driver: 'local'
  logs-vol:
    driver: 'local'
  data-vol:
    driver: 'local'
# service定義
services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    volumes:
            # ${volumesに定義したkey}:{マウントパス}
            - config-vol:/etc/gitlab
            - logs-vol:/var/log/gitlab
            - data-vol:/var/opt/gitlab
    ports:
     - "443:443"
     - "80:80"
     - "2222:22"
    restart: always
```

ポートは、エラーが出たので、22ポートのみ2222ポートに変更。
（おそらく、Docker用仮想マシンとのsshですでに使っていることが原因かと思いますが、深堀はしていない...）


docker-compose.ymlファイルが用意できたら、下記コマンドでサービス開始。

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

ちょっと時間がかかるので、しばらく待つ。


# GitLabへアクセス

Dockerが起動している仮想マシンへアクセスすると、GitLabの画面が表示されます。
まだ起動が終わってない場合は、500エラーが表示されますので、しばらく待機。
（Volumeの設定がミスっている場合などでも500エラーは出ます。）

設定などは、GitLabについてまとめているサイトを参考に。


# ssh設定変更

Windowsなのでgit bashを実行し、作業します。

docker-compose.ymlで、sshをDockerが起動しているマシンの2222ポートで行うように設定したため、sshの設定ファイル`~/.ssh/config`を下記の通りに変更します。

```
Host 192.168.99.100
  HostName 192.168.99.100
  User git
  Port 2222
  IdentityFile ~/.ssh/id_rsa.pub
  TCPKeepAlive yes
  IdentitiesOnly yes
```

`Host`と`HostName`にはDockerが起動しているマシンのIPを入れます。
`IdentityFile`には、このあと作成するssh公開キーのパスを指定します。

# リモートリポジトリの登録
Git管理下のディレクトリにて、リモートリポジトリとして作成したGitLabコンテナを登録します。

GitLabにて、プロジェクトを作成し、画面に表示されるURIをコピーします。

手元ではこんな感じ。
`git@2ca1d50bd3da:Y-Kanoh/{プロジェクト名}.git`

これでは、ホスト名のところにコンテナのハッシュ値が指定されているので、ハッシュ値をDockerが起動しているマシンのIPに変更します。
`git@192.168.99.100:Y-Kanoh/{プロジェクト名}.git`


この編集したURIをもとに、リモートリポジトリを登録します。

```bash
git remote add origin git@192.168.99.100:Y-Kanoh/{プロジェクト名}.git
```

# sshキーの登録

ここで詰まりました。
sshキーを作成し、登録します。
何回キーを登録しなおしてもうまくいかなかったのですが、下記サイトを参考にして、ようやく接続できました。

参考：[git公開鍵の追加方法](https://qiita.com/u1and0/items/b9ca6496045b961f097f)


接続確認コマンドは以下の通りです。
（ssh用の22ポートを2222ポートに変更している点に注意）
`Permission denied (publickey).`などが表示されず、`Welcome to GitLab`と言われれば成功です。

```bash
 ssh -T 192.168.99.100 -p 2222
```


あとはGit管理下のソースをpushすれば完了です。


# 追記
上記、sshキーを発行するときに、以下のコマンドを忘れるのでメモ。

```bash
$ eval $(ssh-agent -s)
$ ssh-add ~/.ssh/id_rsa
```
Java 10 で、gradle eclipse して、JavaSE-1.10 と出ちゃう時は、、、

# 問題
古いgradle を使っていて、build.gradle に sourceCompatibility = 10 を指定しているとき、gradle eclipseすると、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/25176/3a2cbc4c-775f-6db8-6fca-d556a48730ae.png)

なエラーが発生してしまいます。

# 対応
そんな時はgradleのバージョンを4.3以上に上げましょう。
gradle 4.3の[この対応](https://github.com/gradle/gradle/pull/3099)で治ってます。
Python3.5.1 + Django2.0.3 で、簡単なCRUDアプリを作る（３）

#削除機能を追加しよう

さて、前回までで登録・更新までが出来るようになりました。
あとは削除ですね。では早速やっていきましょう。
前回、前々回もそうですが、下記のサイトを参考にしながら、python3.5とDjango2.0に対応させた記述にしています。
https://eiry.bitbucket.io/tutorials/tutorial/crud_delete.html

##一覧画面に削除ボタンを追加

```index.html
{% extends 'crud/base.html' %}
{% block body %}
<a href="/add">登録画面へ</a>
<form method="post" action="/delete"> #追加
    <table border="1">
      <thead>
        <tr>
          <th>部門名</th>
          <th>略称</th>
          <th>登録日</th>
          <th>　</th>　#追加
        </tr>
      </thead>
      <tbody>
        {% for department in departments %}
          <tr>
            <td><a href="/edit/{{ department.id }}/">{{ department.name }}</a></td>
            <td>{{ department.name_short }}</td>
            <td>{{ department.created_at }}</td>
            <td><input type="checkbox" name="delete_ids" value="{{ department.id }}"></td>　#追加
          </tr>
        {% endfor %}
      </tbody>
    </table>
    {% csrf_token %}　#追加
    <input type="submit" value="チェックしたものを削除">　#追加
</form>#追加
{% endblock %}
```

「#追加」と書いているところを追加しています。
今回初めてformタグでtableタグで囲むようにしました。
これまでは実はこのformタグはありませんでしたが、普通に動いていました。
formタグに関する一般的な説明は、こちらに良記事がありましたので参照してください。
https://qiita.com/mikuhonda/items/f3126380d3340f3d8a2b

ひとまずこれで削除ボタンを押すと、/deleteに遷移すると思いますので、試してみてください。

##削除処理を書く

まずはviews.pyに追加します。

```crud/views.py
from django.views.decorators.http import require_POST
```

そしてdelete処理を書きます。

```views.py
@require_POST
def delete(request):
    delete_ids = request.POST.getlist('delete_ids')
    if delete_ids:
        Department.objects.filter(id__in=delete_ids).delete()
    return redirect('/')
```

これで確認をしてみてください。チェックしたものだけが削除されるようになっているはずです。

実際のアプリケーションでは、削除前に確認を入れるのが普通ですが、今回はとりあえず簡単にCRUD処理を実現するということに主眼を置いていますので、クリックしたらすぐに削除されます。
RedmineをDockerで建てる in Mac

Mac（High Sierra）で、RedmineをDockerにて構築したメモです。
プライベート環境での利用を想定しています。

# 構築概要

- Redmine 3.4.4、 MySQL 5.7で構築します。
- 下記のプラグインを入れています。
  - backlogs
  - wiki extensions
  - redmine dmsf
  - clipboard image paste
  - absolute dates
  - redmine slack
  - highlightjs
  - knowledgebase
- backlogs / dmsfがうまく動作せず、バージョンを落としたり、パッチを当てたりしています。
- 下記を修正する際は、docker-compose.ymlを編集してください。
  - データはベースOSの~/var/redmine配下に保存されます。
  - ポート番号は10080です。
  - DBパスワードはPASSWORDに設定されています。

# 構築

githubからスクリプトをcloneして実行します。

```zsh
% git clone https://github.com/boyaki-machine/dockers.git
% cd dockers/redmine
% ./make.sh
DockerでRedmineを構築するスクリプト
データは ~/var/redmine 配下に保存されます
構築を開始します。 [yes/no] yes
...
略
...
以下を実施してください。
 1) ブラウザにてhttp://0.0.0.0:10080にアクセス、admin / adminでログイン
 2) 管理メニューよりデフォルト設定をロード
 3) 管理メニューより  トラッカー ＞ 新しいトラッカー  を選択。下記２つのトラッカーを追加
      a: ストーリー
      b: タスク
先に進めるにはenterを押下して下さい。
```

ここまで来たら、ブラウザで　[http://0.0.0.0:10080](http://0.0.0.0:10080)　にアクセスします。うまく行っていれば、redmineの画面が表示されます。　ログインボタンを押下して、初期ユーザのadmin / adminでログインします。

![スクリーンショット 2018-04-14 14.17.14.png](https://qiita-image-store.s3.amazonaws.com/0/123906/c0b53de0-0ee4-f335-f0ff-abdd34865b4c.png)

パスワード変更処理を行い、ログインが完了したら、上部メニュから管理メニューを選択します。すると、デフォルト設定ロードのメニューが出るので押下します。

![スクリーンショット 2018-04-14 14.18.16.png](https://qiita-image-store.s3.amazonaws.com/0/123906/cb217153-6475-6f3b-52f4-06a009ba0902.png)

デフォルト設定ロードが完了したら、トラッカーメニューに移り、新しいトラッカーとして「ストーリー」「タスク」を登録します。（利用に合わせて適宜修正してください）

![スクリーンショット 2018-04-14 14.27.38.png](https://qiita-image-store.s3.amazonaws.com/0/123906/02c731d7-4539-0e52-f258-41b0de7a377b.png)

ここまで完了したら、再びコンソールに戻りEnterを押下します。
pluginの設定が始まるので、途中に出てくるbacklogsの設定を下記のように入力します。

```zsh
...略
-----------------------------------------------------
Which trackers do you want to use for your stories?
  1. バグ
  2. 機能
  3. サポート
  4. ストーリー
  5. タスク
Separate values with a space (e.g. 1 3): 4
You selected the following trackers:  ストーリー. Is this correct? (y/n) y
-----------------------------------------------------
Which tracker do you want to use for your tasks?
  1. バグ
  2. 機能
  3. サポート
  4. タスク
Choose one from above (or choose none to create a new tracker): 4
You selected タスク. Is this correct? (y/n) y
...
略
...
Restarting redmime_redmine_1 ... done
Restarting redmime_db_1      ... done

構築完了!!
```

これで構築完了です。コンテナの再起動をしているので、ブラウザでアクセス可能になるのは少し待つ必要があるかもしれません。
アリババクラウドをはじめてみます

# アリババクラウドとは
中国のアリババ（阿里巴巴）という会社が
展開しているクラウドコンピューティングサービス、
アリババクラウドコンピューティング（阿里雲）です。

アリババには他にも

- [alibaba.com](http://www.alibaba.com/)
- [淘宝网(淘寶網) 日本站](https://world.taobao.com/)
- [Alipay](https://intl.alipay.com/)

などのBtoBや決済のサービスなど色々あります。

Wikipediaを見てみますと
[阿里巴巴集団 - Wikipedia](https://ja.wikipedia.org/wiki/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4%E9%9B%86%E5%9B%A3)

> アリババクラウドコンピューティング（阿里雲）
> クラウド・コンピューティングサービスを提供するために、2009年9月に設立。

とあります。
すでに８年、今９年目のようです。

# アリババクラウドのサイトを訪問

[Alibaba Cloud 公式サイト](https://jp.alibabacloud.com/)

です。 ブラウザは、**Chrome** で開いてください。

# アカウント登録

アリババクラウドを開始するには、アカウント登録からですね。
まずは、ドキュメントを読んでみましょう。

[アカウント登録手順 - 操作ガイド| Alibaba Cloud ドキュメントセンター](https://jp.alibabacloud.com/help/faq-detail/52962.htm?spm=a3c0i.l35469ja.a3.6.7df267e3VcXQjb)

を開くと

[日本サイトアカウント登録方法](https://www.sbcloud.co.jp/assets/Aliyun_Account_Registration.pdf?spm=a3c0i.q52962ja.a3.1.41e17ea36rfH0g&file=Aliyun_Account_Registration.pdf&_ga=2.201058862.1649422141.1523459725-957905782.1523286449)

というのがあります。
こちらを参考に進めてもらえれば作成できますので
アカウント登録まで３つの作業となります。

- アカウントプロフィール登録（メアド/パスワードなど）
- クレジットカード認証
- 本人確認

アカウントプロフィール登録はWEB上でできますが
そのあとでハマったポイントがあったので紹介したいと思います。

# ハマりポイント

## 使用ブラウザ
決済する際に _Safari_ だとリダイレクトされて、中国語サイトに移動されます。
PDFの **P9** から進みません。Chromeで画面操作を行ってください。

## 本人確認資料の用意
**P12**にある
**お支払い方法有効化のための本人確認**
のため、あるのでスマホなどで写真を保存して
PCに移動させる作業が必要になります。
または、プリンタなどスキャンとかですかね。

今回は個人でアカウント登録をしたのですが
PCの操作だけですぐにサーバを起動するとはいかないようです。

# 本人確認にかかる時間は？

チケットを起票してかかった時間を紹介します。

## 開始
2018-04-12(金) 07:50:26 JST

## 終了 & 有効化
2018-04-12(金) 08:01:30 JST

とても早いですね。
営業日でないときはどうなるか気になるところです。
どなたか知っていたらコメントで教えてください。

# まとめ
ということでこれでアリババクラウドが使えるようになりました。これから使っていきます。
Macでdocker exec -it hoge bashしてコマンドラインが壊れた時やること

Docker for Macでdocker exec -it hoge bash(あるいは docker-compose exec hoge bash)して、長いコマンドを入力したら変なところで折り返して、その上次の行に折り返すんじゃなくて同じ行で折り返してコマンドラインがぶっ壊れることがあって困ってたけど、ターミナルのウィンドウのサイズを変えると直った。

参考: https://github.com/docker/compose/issues/253#issuecomment-361888888
オブジェクト指向設計の原則

# オブジェクト指向設計の原則(SOLID原則)
SOLID原則はクラス設計に関わる原則

[1. SRP(単一責任の原則)](#1-srpthe-single-responsibility-principle)
[2. OCP(オープン・クローズドの原則)](#2-ocpthe-open-closed-principle)
[3. LSP(リスコフの置換原則)](#3-lspthe-liskov-substitution-principle)
[4. DIP(依存関係逆転の原則)](#4-dipthe-dependency-inversion-principle)
[5. ISP(インタフェース分離の原則)](#5-ispthe-interface-segregation-principle)

# 1. SRP(The Single Responsibility Principle)
クラスに与える責務は一つだけ。
# 2. OCP(The Open-Closed Principle)
修正なしで拡張可能にする。
# 3. LSP(The Liskov Substitution Principle)
# 4. DIP(The Dependency Inversion Principle)
# 5. ISP(The Interface Segregation Principle)

# SOLID原則以外のオブジェクト指向設計の原則
パッケージに関するものなどの原則が存在する

- REP(The Reuse/Release Equivalence Principle)
- DRY(Don't Repeat Yourself)
- PIE(Program Intently and Expressively)
- SDP(Stable Dependencies Principle)
- ADP(Acyclic Dependencies Principle)


# 参考
- [オブジェクト指向の法則集](http://objectclub.jp/community/memorial/homepage3.nifty.com/masarl/article/oo-principles.html)
- [アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技](https://www.amazon.co.jp/アジャイルソフトウェア開発の奥義-第2版-オブジェクト指向開発の神髄と匠の技-ロバート・C・マーチン/dp/4797347783)
kuromoji.js（日本語形態素解析）の使い方

# kuromoji.js（日本語形態素解析）の使い方
kuromoji.jsをシンプルに使う為のサンプル

デモは以下で可能。
Furigana Extension（chrome拡張）
https://chrome.google.com/webstore/detail/furigana-extension/kenooeijfmebjimghhoijpdbednpnpbl

## kuromojiオブジェクトの作成

```js
// kuromojiオブジェクト
let kuromojiObj;

// kuromojiオブジェクトの作成
kuromoji.builder({
	dicPath : 'dict/'
}).build(function(error, _tokenizer) {
	if (error != null) {
		console.log(error);
	}
	kuromojiObj = _tokenizer;
});

// kuromojiオブジェクトの取得
let getKuromojiObj = function() {
	return kuromojiObj;
};
```
## 形態素解析
```js
// 形態素解析
function analyze(str) {
	// kuromojiオブジェクトの取得
	let tokenizer = getKuromojiObj();
	// 形態素解析実行
	tokenize = tokenizer.tokenize(str);
	for (let j = 0; j < tokenize.length; j++) {
		alert(tokenize[j].surface_form);
	}
}
```
Docker：Basic Level



```
$ sudo yum -y install docker
```

```
$ sudo systemctl start docker
```

```
$ sudo systemctl enable docker
```

```
Docker　HPよりイメージのダウンロード　　　　　　　　　　※ 例えば、次で実験
Docker Hub　のCentOSのdetailsにあるRolling buildsのコマンド入力
```

```
$ sudo docker pull イメージ名：タグ　（ex. orange:6)
```

```
$ sudo docker images　　　　　　　　　　　#作成したイメージを表示
```

```
$ sudo docker run orange:6 cat /etc/redhot-release
  => CentOS release 6.8(Final)　　　　　　　#作成したイメージのコンテナを起動
```

```
$ sudo docker ps　　　　　　　　　　　　　　　#起動のコンテナ一覧
　=> CONTAINER ID       IMAGE     COMMAND     CREATED
    STATUS             PORTS     NAMES
```

```
$ sudo docker ps -a    #起動コンテナの履歴
　　=> CentOS release 6.8(Final)
```

```
$ sudo docker rm コンテナID 　　　　　　#コンテナの削除
```

```
$ sudo docker run -it --name コンテナ名 orange:6 /bin/bash
   #runコマンドでコンテナ起動の状態にする

=> [root@~    ]#          #プロンプトが特権ユーザーへ移動
=> [root@~    ]# pwd
=> /                      #コンテナのrootにいる状態 
=> [root@~    ]# ls
=>  bin  etc  lib  lost+found  mnt   proc  run  selinuxなど
=> [root@~    ]# cd etc
=> [root@~    ]# ls
=> etcディレクトリのファイルが一覧表示される

ここで例えば、
=> [root@~    ]# vi nsswitch.conf　　　　　　　　　#viエディタで確認
=> [root@~    ]# ifconfig -a　　　　　　　　　#コンテナインターフェイスの確認
などでコンテナのファイルを確認してみる。
rootから抜けるには　　　　　　　control+PQ　　　
```

```
$ sudo docker start コンテナID
```

```
$ sudo docker stop           #一時停止コマンド
```

```
$ sudo docker attach コンテナID 　　　　　#control+PQ　からの再接続
=> [root@~    ]# cd root
=> [root@~    ]# vi EXSAMPLE.txt　
例えば、EXSAMPLE.txtにviエディタ上で "This sample is docker test."などと編集。
```

```
$ sudo docker commit コンテナID 新しいイメージ名：タグ　　　　　　　　#イメージの作成
$ sudo docker images　　　　　　　　　にてイメージが追加されていることを確認
```

```
$ sudo docker run 新しいイメージ名：タグ　　cat /root/EXSAMPLE.txt
=>  This sample is docker test.
```

```
$ sudo docker rm コンテナID        #作成されたコンテナの削除
$ sudo docker rmi イメージID　　　　　　　　　　　　　　#作成されたイメージの削除
```
他人のコミットをgit merge --squashするべきでないのではという話

最近某OSSに出された[PR](https://github.com/Microsoft/winfile/pull/42)が、`git merge --squash <branch>` でマージされたことにより、コミットのAuthorが書き換えられてしまったことが一部界隈で話題になっていました。この件にはマージを行った人に悪意はなかったようなのですが、gitの理解不足により生じてしまった案件だとすると悲しい話なので一応メモ


# 何が起きたか
1. コミッターが複数の内容が含まれたPRを送った

1. 管理者はその中の一部の内容だけをマージするために、管理者はgit merge --squashを実施し、コミットを改変した上でmergeを実施した　←**これが問題**

1. コードの内容はコミッターのものなのに、Authorだけ管理者にすげ変わってしまいコミッターのモチベを損ねた

# そもそもsquashするとどうなるの

ここに分かりやすくまとまっています。
[アジャイルSEを目指すブログ  図で分かるgit-mergeの--ff, --no-ff, --squashの違い  ](http://d.hatena.ne.jp/sinsoku/20111025/1319497900)

>![image.png](https://qiita-image-store.s3.amazonaws.com/0/35276/22f2eb7c-0394-f0ce-6417-77613ef3d403.png)
>http://d.hatena.ne.jp/sinsoku/20111025/1319497900

上の図のように、他ブランチを取り込んだ状態の差分をワークツリーとインデックスに反映させるコマンドです。
この状態はまだ未コミットの状態であるため以下のような操作が可能となります。

1. 複数のコミットによる差分を１つのコミットにまとめた形でコミットできる
1. まだ未コミットの状態なので、**取り入れた差分を編集できる

しかし、下記の理由で自分以外のコミットに対してはsquashは望ましくないと考えられます。

1. 　**デフォルトではsquash後の差分をコミットした人がAuthorになってしまう。→本来のコミッタのcontributionを消してしまう**
2. 　**Author云々の前に、人のコミットした歴史を別の人が改変するのは望ましくない**

# どうすればよいか

とはいえ、他人のコミットマージしたいけど一部はマージしたくないよ、って時はどうすれば良いのか。
色んな方法があると思いますが、見たことがあるのを４つくらいあげてみます。

## `git cherry-pick <commit id>`を使う
コミット単位でマージするかしないかが切り分けられる場合はcherry-pickを使う方法があります。
`git cherry-pick <commit id>`は別ブランチの特定のコミットをマージする機能です。

```bash
git cherry-pick fadb18b1771895b5fd8f11114514dd951decb67d #指定のコミットをマージ
git cherry-pick develop~3..develop #範囲指定　最新から3つ目までのコミットをマージ
```

これは勿論既に存在するcommitをマージした形にするので、authorなどが書き換わるなども当然ないです。

[[技術][Git]git-cherry-pickを掘り下げる](http://d.hatena.ne.jp/idesaku/20091230/1262159267)

## rebase --interactiveを使う
@wataashさんのコメントを受けて追加
git rebase --interactiveを使うと、squashコミットの最初の著者になるそうです。
どうしてもsquashしたい際はこれがよさそう。
詳しくは@wataashさんの記事を
[git rebase --interactive で誰がauthorになるか問題](https://qiita.com/wataash/items/f5425df7cb9d205d604b)

## コミッターにsquashしてもらう
どうしても１つのコミットにまとめたいんだって話であったり、コミット単位じゃマージするかしないかが切り分けられないよって話であればコントリビュータにお願いしてsquashしてもらうのも１つです。
某OSSでは、コントリビュータである@mattnさん側から指示通りにsquashするよ〜って提案をしてらっしゃいますね。

## mergeした後に自分で編集してコミットする
まぁ正攻法ですかね。commitを１つにまとまられなかったり、ログが汚くなってしまうかもしれませんがそれも１つの歴史なので無理やり改変しなくてもいいのではと思える人はこちらの選択肢も。

## co-author機能を使う

そこまでする必要あるかという話もありますが、話のたねに。

一応githubにはco-author機能というものがあり、コミットメッセージにco-authorの情報を記述すればcontributionの一覧にそのユーザを明記することができます。

```bash
git commit -m "Refactor usability tests.
>
>
Co-authored-by: name <name@example.com>
Co-authored-by: another-name <another-name@example.com>"
```

詳しくは↓を
https://help.github.com/articles/creating-a-commit-with-multiple-authors/

## ポエム

なんか色々面倒だし、authorとか誰でもいいしとりあえずログを綺麗にしたいぜ！って人もいるかもしれませんが、個人的にはコントリビュータには最大限の敬意を払ったほうが良いと思うし、他人の成果を横取りする人間だと誤解されたくもないので注意しても損ではないかなと思ったり思わなかったり。

# 参考になる記事:
[git rebase --interactive で誰がauthorになるか問題](https://qiita.com/wataash/items/f5425df7cb9d205d604b)
[GitHubの3種類のマージを理解する](https://qiita.com/wataash/items/ab7828a1bc452b665f94)


[c++の未定義バグ](https://qiita.com/pshiko/items/835907b89c08a185e5f6)
Unityプロジェクト内にある、すべてのC#スクリプトのステップ数をカウントするEditor拡張

今関わっているUnityプロジェクトのスクリプトって全部でどれくらいのステップ数あるのかなと思い、計算している人を探したのですが、見当たらなかったので自作しました。Editor拡張になります。
コードは以下です。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;

public class CountLine : EditorWindow {

    [MenuItem("Window/LineCount")]
    public static void Init()
    {
        CountLine window = EditorWindow.GetWindow<CountLine>("CountLine");
        window.Show();
        window.Focus();
    }

    private void OnGUI()
    { 
        if (GUILayout.Button("Count All Script line"))
        {
            DirectoryInfo dir = new DirectoryInfo(Application.dataPath);
            FileInfo[] info = dir.GetFiles("*.cs", System.IO.SearchOption.AllDirectories);
            if(info == null || info.Length == 0)
            {
                return;
            }
            
            int allLineCount = 0;
            info.Where((x) => x.Name != "CountLine.cs").ToList().ForEach((x) => {
                
                using (StreamReader sr = x.OpenText())
                {
                    while(sr.ReadLine() != null)
                    {
                        allLineCount++;
                    }
                }
            });

            Debug.LogFormat("Number of All Scripts line is {0}", allLineCount);
            
        }
    }
}
```

自身のスクリプトはカウントしていないようにしています。
こちらのスクリプトを、適当なEditorフォルダにつっこんでもらって、Windowタブ->LineCountを開き、「Count All Script line」というボタンを押せば計算が始まります。結果はコンソールに出力されます。
ささっと作ったものなので、もし不具合ある場合は教えていただけると幸いです。。
Installing go kernel for jupyterlab on Windows

# install go on conda an environment
```
conda install -c conda-forge go
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/ec66918c-e136-283a-701a-ccb9dc29bc1e.png)


# add GOPATH to the environment variables
we need environment variable GOPATH to do `go get` command
```
vim %conda_prefix%\etc\conda\activate.d\go_activate.bat
```
append the below at the bottom of the file
```
@set "GOPATH=%CONDA_PREFIX%\.go"
@set "PATH=%PATH;%CONDA_PREFIX%\.go\bin"
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/5d47b17d-b182-92dd-aed1-28ad13e9e85c.png)

```
REM to reload go_activate.bat
conda activate jupyter lab
echo %gopath%
mkdir -p %gopath%
mkdir -p %gopath%\bin
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/2851ad87-7eb0-5e4b-7850-83dddc2d20c0.png)

# install gopherdata
```
go get -d github.com/gopherdata/gophernotes
cd %GOPATH%\src\github.com\gopherdata\gophernotes\zmq-win
``

# install MinGW
```
conda install -c conda-forge mingw
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/69f1065e-0150-3118-0573-ee6666382fcb.png)

Proceed ([y]/n)? y

```
build.bat amd64
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/3cdc2e75-4dc7-2bc3-3a29-1c0af4c9251e.png)

```
ls -la
move gophernotes.exe %GOPATH%\bin
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/e2e53c71-c67b-587b-c4c5-0d93bce33c3e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/0a0d4508-3320-9ab4-f242-fa4b9f78a530.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/46c1efde-8014-0658-8372-378d2d3fe382.png)

# copy the kernel config

mkdir %APPDATA%\jupyter\kernels\gophernotes
xcopy %GOPATH%\src\github.com\gopherdata\gophernotes\kernel %APPDATA%\jupyter\kernels\gophernotes /s

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/84fa4123-c364-e482-eef4-2a2febae0e07.png)

update kernel.json with the FULL PATH
vim %APPDATA%\jupyter\kernels\gophernotes\kernel.json

```
"C:\\ProgramData\\Anaconda3\\envs\\jupyterlab\\.go\\bin\\gophernotes.exe",
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/59e785f5-b071-66ee-7bcc-5a1953fbfcfe.png)

# run jupyterlab
```
jupyter lab
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/8012abcf-3110-e4b4-8b14-c3194b6e96d9.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/73bab4ba-958a-323a-5531-0b8507e12cbe.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/a4ac209e-3527-c019-d33b-2a07e2147098.png)


# ref
https://github.com/gopherdata/gophernotes#windows
Macにphpenvを導入する際のメモ

## はじめに
似たような記事があるので、投稿どうしようかと思っていましたが、自分用に残そうかと。
新しいMacBookに久しぶりにphpenvを入れようとした際にハマってしまったときの解消メモです。

## phpenvを入れる
試行錯誤したものの、Homebrew経由では上手くいかなかったので、直接入れました。

```bash
$ git clone https://github.com/CHH/phpenv.git
$ phpenv/bin/phpenv-install.sh
```

## .bash_profileに追記する
.bash_profileの末尾に追記し、反映します。

```bash
$ export PATH="$HOME/.phpenv/bin:$PATH"
$ eval "$(phpenv init -)"
$ source .bash_profile
```
## php-buildを入れる
```bash
$ git clone https://github.com/CHH/php-build.git $HOME/.phpenv/plugins/php-build
```

## インストール可能なバージョンを確認する
pyenv、nodenvと同じなので、これらを普段使っている人は見なくても打てますが、念のため。

```bash
$ phpenv install --list
```

## 事前にインストールするもの
phpenvでインストールする際に色々足りないと出るので、Homebrew経由で、以下をインストールします。

```bash
$ brew install re2c
$ brew install openssl
$ brew install bison
$ brew install libxml2
```

新しい環境には、以下が足りなかったので後で以下を追加インストールしました。

```bash
$ brew install autoconf
$ brew install automake
$ brew install icu4c
$ brew install libjpeg
$ brew install libpng
$ brew install libmcrypt
```

## 任意のバージョンをインストールする
（一般的には）以下のコマンドでインストールできます。
※ 下記では、5.6.35を指定しています。

```bash
$ phpenv install 5.6.35
```

足りないものを入れてもエラーが消えず、brew linkで指定するもエラーが消えず、結局、入れる際は以下のコマンドで入れました。
いつも覚えられない。。

```bash
$ PHP_BUILD_CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl) --with-libxml-dir=$(brew --prefix libxml2)" phpenv install 5.6.35
```

## バージョンを指定する
あとはバージョンを指定します。pyenv、nodenvと同じなので、これらを普段使っている人は見なくても打てますが、念のため。

```bash
$ phpenv versions
$ phpenv global 5.6.35
$ phpenv rehash
```

## その他
10回以上やってますが、いつも同じopensslのエラーやicuのエラーで（前に何をやったのか忘れて）試行錯誤している気がします。
今日も午前中は、この作業で終わってしまった。
【JavaScript】管理しやすい二次元配列の組み方

#【JavaScript】管理しやすい二次元配列の組み方
JavaScriptでCSVファイルを読み込んで何かするときに、良い感じの組み方を考えてみました。

1. インデックスの作成
2. 二次元配列の構成
3. 二次元配列の使い方
4. まとめ

##インデックスの作成
```sample.js

const index = {
  number: 0,
  string: 1,
  boolean: 2
}

```
CSV側で列が変更されたときにも対応するためインデックスを作成する。

##二次元配列の作成
```sample.js

const index = {
  number: 0,
  string: 1,
  boolean: 2
}

//------------ ▼ 追加 ▼ ------------
const array = [
  [ 0, 'Hello HTML/CSS', false ],
  [ 1, 'Hello JavaScript', true ],
  [ 2, 'Hello TypeScript', false ],
  [ 3, 'Hello Node.js', true ]
]

```
こんな感じに組むと、行と列がわかりやすい。

##二次元配列の使い方
```sample.js

const index = {
  number: 0,
  string: 1,
  boolean: 2
}

const array = [
  [ 0, 'Hello HTML/CSS', false ],
  [ 1, 'Hello JavaScript', true ],
  [ 2, 'Hello TypeScript', false ],
  [ 3, 'Hello Node.js', true ]
]

//------------ ▼ 追加 ▼ ------------
for ( let i = 0; i < array.length; i++ ) {
  const number = `number: ${array[i][index.number]} \n`;
  const string = `string: ${array[i][index.string]} \n`;
  const boolean = `boolean: ${array[i][index.boolean]} \n`;
  console.log( number + string + boolean );
}
```
```
/* consoleの結果 */

  number: 0 
  string: Hello HTML/CSS 
  boolean: false 

  number: 1 
  string: Hello JavaScript 
  boolean: true 

  number: 2 
  string: Hello TypeScript 
  boolean: false 

  number: 3 
  string: Hello Node.js 
  boolean: true 
```
iで行を選択して、indexで列を選択する。

##まとめ
インデックスを作成すると、配列に何が入っているかわかりやすくなる。
例：`array[i][0]` → `array[i][index.number]`

配列を使うときの参考になればと思います。
Emacs: calendar の 1年分 TeX 出力に休日表示を追加

# `M-x calendar` で `t Y`
`M-x calendar` の `t Y` で出力される年間カレンダーに祝日のマークが付きます。

Emacs の calendar の TeX 出力は A4 1枚に 1年分のカレンダーがプリントでき、デスク脇に貼ったり便利に使っていたのですが、休日設定が連動して表記されない処に不満があり機能追加したものです。

この拡張をインストールすると デフォルトは 日曜が `()` で括られ、祝祭日が `[]` で括られます。
祝祭日は文字にすることもできて `japanese-holidays` が等がインストールされていれば通常その名前の1文字目を使います。
"元日" なら "元"、"振替休日" なら "振" となるといった具合です。
"こどもの日" 等 1文字になると判り難いもののために、出力時に置き換える文字の設定をできるようにしてあります。

![カラーサンプル](https://qiita-image-store.s3.amazonaws.com/0/239081/d000d536-a982-5d04-1256-2c71e9df90c5.png)

![モノクロサンプル](https://qiita-image-store.s3.amazonaws.com/0/239081/b0dbdf4c-8a15-b61c-2088-bb4226495584.png)

# ダウンロードとインストール

[ここからダウンロードして](https://gist.github.com/s-fubuki/d5a6d14fe0662f8c4fdbdee19f747fef) `load-path` の通ったディレクトリに置いて `init.el` に以下の1行を追加します。

```emacs-lisp:sample
(require 'col-tex-color)
```


# PDF 化の手順

calndar buffer で `t Y` で 生成出力されたバッファをそのまま TeX file としてセーブし eshell 等から以下の手順で LaTeX コマンドを実行します。
ワーニングがワラワラ出ますがとりあえず無視します。
勿論 TeX がインストールされていないとできません。

```shell:source.sh
$ platex calendar.tex
$ dvipdfmx calendar.dvi
```

# 設定できる主な変数

## cal-tex-color-mode
`'mono` と `'color` が設定できます。デフォルトは  `'color` です。
カラーだと `()` 等の代りに色が変わりそれが印になります。

## cal-tex-holiday-mark
祝祭日の表示法を指定します。
`nil`   か  `'digi` か  `'char`  を設定でき、デフォルトは  `'char` です。

|シンボル|効果|
|:-------+:------------------------------------------|
| nil   | 休日マークなし(システムデフォルトと同じ) |
| 'digi | 数値                                     |
| 'char | 文字になります                           |

## cal-tex-holiday-name-alias
祝祭日を文字表記にするとき、変更したいものを alist で設定します。
`'(("元の文字列1文字目" . "置き換える文字") ...)` という形式です。

```emacs-lisp
;; 例
(setq cal-tex-holiday-name-alias
      '(("み" . "緑") ("こ" . "子") ("敬" . "老") ("天" . "皇")))
```

# 出力される PDF の余白について
頒布されている日本語に対応調整されたクラスファイル附属の TeX をインストールしてあると、基本的に A4 前提でレイアウトされますが、A4 を主に使うのは日本の文化で、元の Source は A4 で調整されていないようで出力に余白が結構出ます。

その辺がきれいに納まるようなマージン等の細かい調整までしていないので、ズームで印字したい範囲を表示しておき(画面の最大化にしないほうがうまくできます)、PDF のリーダー側の印刷ダイアログの「印刷するページ」の「詳細」に
「現在の表示範囲」というのがあるので、それで印字します。

# 動作確認している Emacs のバージョン
> GNU Emacs 25.3.1 (i686-w64-mingw32)
>  of 2017-09-18
geometry > numpy > pentagon (五角形）の座標を得る | Matplotlibでの描画 > v0.1, v0.2

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
PyMieScatt v1.7.0
```

### 処理概要

- Pentagonの形状を得る
- Matplotlibで描画する

### code v0.1

```py:geometry_starShaped_180414.ipynb
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

'''
v0.1 Apr. 14, 2018
  - add get_pentagon()
      + to obtain pentagon geometry
'''

NUM_VERT = 5  # number of vertices (5: for pentagon)


def get_pentagon(radius):
    xs, ys = [], []
    for idx in range(NUM_VERT):
        theta = 2.0 * np.pi * idx / NUM_VERT
        theta += np.pi / 2.0  # to put the one vertex upward
        xs += [np.cos(theta)]
        ys += [np.sin(theta)]
    return xs, ys

RAD_INNER = 5
RAD_OUTER = 10
xs, ys = get_pentagon(RAD_INNER)

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

ax.scatter(xs, ys)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(True)

```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/9616c71f-e83e-690e-a565-710d10f49bf2.png)


### code v0.2

- Pentagonを上向き、下向きにする引数を追加
- fix bug: get_pentagon() did not use [radius] arg


```py:geometry_starShaped_180414.ipynb
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

'''
v0.2 Apr. 14, 2018
  - fix bug: get_pentagon() did not use [radius] arg
  - get_pentagon() takes [upward] arg
v0.1 Apr. 14, 2018
  - add get_pentagon()
      + to obtain pentagon geometry
'''

NUM_VERT = 5  # number of vertices (5: for pentagon)


def get_pentagon(radius, upward):
    xs, ys = [], []
    for idx in range(NUM_VERT):
        theta = 2.0 * np.pi * idx / NUM_VERT
        if upward:
            theta += np.pi / 2.0  # to put the one vertex upward
        else:
            theta -= np.pi / 2.0  # to put the one vertex downward
        xs += [radius * np.cos(theta)]
        ys += [radius * np.sin(theta)]
    return xs, ys

RAD_INNER = 5
RAD_OUTER = 10
xs, ys = get_pentagon(RAD_INNER, upward=False)

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

ax.scatter(xs, ys)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(True)

```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/7ad510f8-2be2-927c-0b8a-b6fc3a450c8a.png)
【Officeアドイン】設定値を保存する2つの方法

## ■はじめに
Officeアドインで、設定値を保存したい場合。
例えば、アプリの表示言語を変更・設定できるようにしたい場合、 設定値を保持することが出来れば、アプリを再起動した場合でもわざわざ再設定する必要が無くなって便利ですね。
[![1](https://hirossyi.net/wp-content/uploads/2016/06/1-768x339.png)](https://hirossyi.net/wp-content/uploads/2016/06/1.png)
このような機能を実装したい場合、果たしてどのように開発すればいいでしょうか？
その方法について、実は2つの方法があります。
その2つの方法はどのようなものか？ その使い分けも含め、今回はその開発方法について解説します。 
## ■解説
上記でも記載した通り、Officeアドインで設定値を保存する方法は主に2つあります。
それぞれメリット・デメリットあるので、それぞれ見てみましょう。 　
### ①Officeアドインの関数"Settings.set"を使用する
"Office.context.document.settings.set"というメソッドを使用することで、 Officeのドキュメントに名前/値のペアとして設定値を格納します。
参考：[https://msdn.microsoft.com/ja-jp/library/office/fp161063.aspx](https://msdn.microsoft.com/ja-jp/library/office/fp161063.aspx) 
イメージとしては、<span class="font-red">Officeファイルに</span>名前/値のペアとして設定値を格納することになります。
[![2](https://hirossyi.net/wp-content/uploads/2016/06/2-768x419.png)](https://hirossyi.net/wp-content/uploads/2016/06/2.png) 
Officeファイルに格納するので、<span class="font-red">保存時とは別のOfficeファイルを開いた場合は、その設定値を読み込むことは出来ません</span>。別の値として扱われます。
[![3](https://hirossyi.net/wp-content/uploads/2016/06/3-768x281.png)](https://hirossyi.net/wp-content/uploads/2016/06/3.png)
一方で、<span class="font-red">別ユーザーが同じファイルを読み込んだ場合は、すでに保存済みの設定値を読み込むことができます</span>。
これはファイルそのものに設定値を書き込みしているので、どのユーザーが開いても同じ設定値を利用することが出来るのです。
[![4](https://hirossyi.net/wp-content/uploads/2016/06/4-768x253.png)](https://hirossyi.net/wp-content/uploads/2016/06/4.png)
### ②HTML5の機能"LocalStorage"を使用する
LocalStorageは、HTML5で新たに追加された機能です。
ブラウザ側に名前/値のペアとして設定値を格納する事ができます。
[http://wp.tech-style.info/archives/742](http://wp.tech-style.info/archives/742)
[![5](https://hirossyi.net/wp-content/uploads/2016/06/5.png)](https://hirossyi.net/wp-content/uploads/2016/06/5.png) 
「OfficeなのにHTML5の機能を利用できるの？」と思う方もいるかもしれませんが、 OfficeアドインはれっきとしたWebアプリケーションなので、問題なくLocalStorageを使用できます。
OfficeアドインでLocalStorageを使用した場合、そのアプリ内では共通して同じ値として管理されます。
つまり、<span class="font-red">別のOfficeドキュメントでアプリを起動した場合でも、同じ設定値を保存・読込することが出来ます</span>。わざわざ保存し直す必要がなくて便利ですね。 
[![6](https://hirossyi.net/wp-content/uploads/2016/06/6-768x258.png)](https://hirossyi.net/wp-content/uploads/2016/06/6.png)
しかし、別ユーザーが同じファイルを開いたとしても、同じ設定値を使用することは出来ません。 そこはご注意下さい。
[![7](https://hirossyi.net/wp-content/uploads/2016/06/7-768x235.png)](https://hirossyi.net/wp-content/uploads/2016/06/7.png)
### ③結局どっちがいいの？
ぶっちゃけ用途によります。 以下、簡単にまとめてみました。
※Settings.set関数
・ドキュメントに設定値を格納する
・同じファイルを開いた場合、どのユーザーであっても同じ設定値を保存・読み込むことができる
・別のファイルを使用した場合、設定値は共有されない
・Excelセルに記載された金額・人物名など、各Officeファイルに紐付いた値を保持しておきたい場合におすすめ 
※LocalStorage
・ブラウザに設定値を格納する
・保存時とは別のファイルを開いた場合でも、設定値を共有することができる
・別のユーザーが保存時のファイルを開いた場合、設定値は共有されない
・アプリの表示言語など、実行したユーザーごとに異なる設定を保持しておきたい場合におすすめ 
開発したいアプリの用途によって使い分けることをおすすめします。 もちろん両方使用することもアリでしょう！ あなたの開発にお役立て下さい。
## ■おわりに（自己紹介）
まだまだマイナーながら、無限の可能性を秘めた「Officeアドイン」の解説記事を少しずつ執筆しています。
もっと詳しく知りたい！といったことや、この内容を解説して欲しい！ということがありましたら、 コメントなどにてお気軽にご連絡ください。
Python3.5.1 + Django2.0.3 で、簡単なCRUDアプリを作る（２）

#新規登録、更新を出来るようにしよう

前回は、setting.py, views.py, urls.py（2つありますね）, models.py, などの基本的な設定をして、一覧画面を表示するところまで行いました。
https://qiita.com/Liverty/items/f0d076e142c6a716ffcd

今回はその続きをやっていきます。

##新規登録画面へのリンクを貼る
まず、index.htmlのテーブル開始タグのすぐ上に、下記のようなリンクを記述しましょう。

```templates/crud/index.html
<a href="/add">登録画面へ</a>
```

記載したら、正しく画面遷移することを確認してください。

##Djangoフォームを作る
続いて、models.pyと同じフォルダに、forms.pyを作り、下記のように記述します。

```forms.py
from django import forms
from .models import Department

class DepartmentForm(forms.ModelForm):
    class Meta:
        model = Department
        fields = ('name', 'name_short', 'created_date',)
        widgets = {'name': forms.TextInput(),
                    'name_short': forms.TextInput(),
                    'created_date': forms.DateTimeInput(),
                    }
```

このフォームの書き方は、バージョンの違いが結構あります。

フォームの内容を出力するために、viwes.pyを編集します。

```views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import Department
from .forms import DepartmentForm

def index(request):
    contexts = {
        'departments': Department.objects.all(),
    }
    return render(request, 'crud/index.html', contexts)

def add(request):
    form = DepartmentForm(request.POST or None)
    if form.is_valid():
        Department.objects.create(**form.cleaned_data)
        return redirect('/')
    form = DepartmentForm()
    return render(request, 'crud/edit.html', {'form': form})

```

新規追加画面で登録後に、一覧画面で確認してみてください。
データが追加されていればOKですね。

##一覧画面から更新画面へのリンクを作る

一覧画面で、部門名をクリックしたら更新画面に遷移するようにしましょう。

```index.html
{% extends 'crud/base.html' %}
{% block body %}
<a href="/add">登録画面へ</a>
    <table border="1">
      <thead>
        <tr>
          <th>部門名</th>
          <th>略称</th>
          <th>登録日</th>
        </tr>
      </thead>
      <tbody>
        {% for department in departments %}
          <tr>
            <td><a href="/edit/{{ department.id }}/">{{ department.name }}</a></td>
            <td>{{ department.name_short }}</td>
            <td>{{ department.created_at }}</td>
          </tr>
        {% endfor %}
      </tbody>
    </table>
{% endblock %}
```

この書き方がベストかどうかわかりませんが、とりあえず動きます。

##更新処理を書く
まずcrud/urls.pyの先頭を更新します。

```crud/urls.py
from django.shortcuts import render, redirect, get_object_or_404
```

get_object_or_404 を追加するだけです。
続いて、edit処理を書きます。

```views.py
def edit(request, pk):
    department = get_object_or_404(Department, pk=pk)
    if request.method == 'POST':
        form = DepartmentForm(request.POST)
        if form.is_valid():
            department.name = form.cleaned_data['name']
            department.name_short = form.cleaned_data['name_short']
            department.save()
            return redirect('/', pk=department.pk)　#更新をしたらトップページへ

    else:
        form = DepartmentForm(instance=department)
    return render(request, 'crud/edit.html', {'form': form})
```

更新をしたらトップページに戻る設定にしています。
Jupyter Notebookの背景色やフォントをかっこよく変更する

#概要


![image.png](https://qiita-image-store.s3.amazonaws.com/0/250105/471f1fd1-7cc6-45d2-98fe-d285d4497de0.png)

白背景でちょっと疲れるjupyternotebookの背景色を変更する。

追記:好みの設定を追記。セル幅は-cellw 90% のような感じでブラウザの表示領域に対する比率で指定も可能で、なかなか使い勝手がよさそう。

```
jt -t onedork -f inconsolata -T -N -cellw 90% -tfs 11
```

#環境
- Windows10 64bit
- Anaconda3-5.1.0-Windows-x86_64

#背景色やフォントの変更
##jupyterthemesのインストール
コマンドプロンプトでAnaconda3のディレクトリに移動し、pipでjupyterthemesをインストールする。

```
$ pip install jupyterthemes
``` 
以下コマンドでアップグレードできる

```
$ pip install --upgrade jupyterthemes
``` 

ちなみに現在利用可能なテーマは以下の通り

```
$ jt -l
Available Themes:
   chesterish
   grade3
   gruvboxd
   gruvboxl
   monokai
   oceans16
   onedork
   solarizedd
   solarizedl
```

詳しくはこちら
[jupyter-themes](https://github.com/dunovank/jupyter-themes)

##テーマ・フォントの変更

```
$ jt -t onedork -f Ricty Diminished -T -N
``` 

-tでテーマをonedork、フォントはRicty Diminished(よく使われるプログラミング用のフォント)
[Ricty Diminished](https://github.com/edihbrandon/RictyDiminished)
にする。
-T -N でツールバーやファイル名を表示できる。

※追記
https://qiita.com/damyarou/items/e1204d9f58bf86b4a4c9
で指摘されているように、-f Ricty Diminished が効かないようなので，フォントの変更について、 custom.css を直接変更する方法を追記します。

.jupyter\custom\custom.css （私の環境だとC:\Users\下にありました。）を編集モードで開き、

```
# ソースコードセル
div.CodeMirror,
div.CodeMirror pre {
 font-family: "Ricty Diminished";
 font-size: 13pt;
}
# 結果出力セル
div.output_subarea.output_text.output_stream.output_stdout,
div.output_subarea.output_text {
 font-family: "Ricty Diminished";
 font-size: 13pt;
}
div.output_area pre {
 font-family: "Ricty Diminished";
 font-size: 13pt;
}
# テキスト、MarkDownセル
div.text_cell,
div.text_cell_render pre,
div.text_cell_render {
 font-family: "Ricty Diminished";
 font-size: 13pt;
}
``` 
いろいろカスタマイズしたい場合は、cssをいじればいろいろできるはずです。

上のコマンドで設定したjupyternotebookはこんな感じ

![jupyterthemes_sample.png](https://qiita-image-store.s3.amazonaws.com/0/250105/cd90f708-1e1b-3a79-061a-e2c171d9794e.png)
連載[3/3] いちから学ぶOfficeアドイン – Officeアドインの生きる道とは（考察）

## はじめに
[その1](https://qiita.com/hirossyi73/items/e2616a6dccdd82443303)
[その2](https://qiita.com/hirossyi73/items/13f30bb8a164ca1bbf4f)
前々回でOfficeアドインの紹介、およびメリット。 前回は、Officeアドインの現状抱える課題、デメリット。 これらについてまとめてきました。
特に前回は、ある意味致命的ともいえる「**Officeでやる必要ない**」という欠点についても紹介しました。
……こんな事言ってしまって、今回ひっくり返せるのかすごく心配ですが(ﾟoﾟ;笑
さて！連載最終回となる今回は、「**<font color="Red">Officeアドインの生きる道とは</font>**」をテーマにまとめていきたいと思います！
VBAほどの柔軟さは無く、Webアプリであればブラウザで十分。 そんな中で、Officeアドインが今後広まっていくにはどうすればいいか？
一筋の光となるかもしれない、そんな提起をしようと思います。 
**※今回は今までより更に、私見が大量にあります。 その点ご理解いただける方のみ続きをお読みください。**
## これがOfficeアドインの生きる道
結論から言いましょう。それはズバリ、
<span class="font-red font-larger font-bold">「そのアプリでしか出来ない価値を提供する」 「Officeの機能を拡張する事を徹底追及する」</font>** という事です！
………？(´･ω･`) なに当たり前の事を言ってるんだ……？と思う方もいるでしょう、多分笑
どういう事か？今からこれを説明していきますが、その前に。
前回の課題で挙げた、「Officeでやる必要ない」。
これがどうして発生するのか、もう少し深堀りして考えてみます。
## 失敗パターン
前回の記事の例ですと、「家計簿サイトをアプリで実行し、内容をExcelに出力できるアプリ」。これを作ることを想定します。 
[![1468355556_calc](https://hirossyi.net/wp-content/uploads/2016/07/1468355556_calc.png)](https://hirossyi.net/wp-content/uploads/2016/07/1468355556_calc.png)
①すでに完成されている家計簿サイトをアプリで呼び出して、
②1ヶ月に1回ぐらいの頻度で内容を出力する。こんなフローになります。
……もうお分かりだと思いますが、**Officeアドインである必要がまったくありません。** 
①は通常のWebブラウザ、またはスマホあたりで登録すればいいし、
②もやっぱり、WebアプリケーションでExcelファイルを作成する仕組みの方が、よっぽど柔軟性があるはず。 
改めてこういう風にまとめると、Officeアドインの必要が無いことが良く分かると思います。
ただ現実の話、今完成されているサービス・アプリを見て、
「家計簿→Excel→Officeアドイン…… **あっ！これOfficeアドインに向いてそう！！**」と思い、開発に飛び付いてしまうと、きっと失敗します。
何故ならば、そのサービスは大抵がすでに完成されていて、Officeアドインである必要がないから。
開発をする前に、本当にOfficeアドインでやる必要あるか？という点を、改めて改めて改めて考慮してみてください。 
## 改めて、Officeアドインの生きる道
以上のように、失敗パターンをまとめてみました。
それを踏まえた上で、もう一度Officeアドインの生きる道である **「そのアプリでしか出来ない価値を提供する」「Officeの機能を拡張する事を徹底追及する」** を見てみましょう。 
### 普段のOffice業務を中心軸に
失敗パターンが「普段のWeb業務をOfficeでやろう」だとするならば、その逆です。
<span class="font-red font-large">「普段のOffice業務をアプリで補助する」</font>** 
**これが唯一の、当たり前とも思える、Officeアドインを開発する上で唯一の最大の鍵だと思います。** 
皆さんの普段のOffice業務は何でしょうか？ プレゼン資料作成？設計書作成？勤怠管理？経費精算？
色んな業務があるはずですが、その普段やっている業務を補助するためのアプリを作ることが超大切。
×Officeアドインの為にOfficeを開かせよう（絶対めんどくなる） 
**○OfficeをサポートするOfficeアドインを使わせよう**
この考え方を持ち続けて設計・開発すること。
そして、開発者がこれを常に意識して、開発したアプリがOfficeストアに公開され続ければ、皆さんの普段の業務を網羅する、「なんか便利なものがあるらしいぞ」と広がっていくことになるでしょう。
Microsoftもきっと、キラーアプリを待ち望んでいるんじゃないかと思います。
どんな人、どんな業務でも使える、Microsoftきってのオススメアプリを！ そんなアプリを、あなたの手で開発してみましょう。 　
## まとめ
あくまでもOfficeアドインは、Officeのアプリなんです。Webアプリケーションとは基本はOffice。
Officeを使った業務を活かすアプリ、これを作れば、きっとOfficeアドインも、作ったあなたも、知名度が変わってくるでしょう。
貴重なビジネスチャンスを作っていけるはずです！
PostmanでWEB API（お天気Webサービス）を試す

#Postman をインストールする
Chromeアドオンで追加するか、サイトからダウンロードしてインストールします。

Postman
https://www.getpostman.com/

#お天気Webサービスから情報を取得する
Livedoor のお天気Webサービス（Livedoor Weather Web Service / LWWS）を利用してみます。
全国の地点定義表で取得したい地域のidを確認してください。

livedoor お天気Webサービス仕様
http://weather.livedoor.com/weather_hacks/webservice

全国の地点定義表（RSS）
http://weather.livedoor.com/forecast/rss/primary_area.xml

（例）「福岡県・久留米の天気」を取得する場合
http://weather.livedoor.com/forecast/webservice/json/v1?city=400040

JSON文字列が返ってきますが、ブラウザでは意味不明です。
Postmanから発行するとこんな感じです。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/240467/2f471608-ac08-8eaa-2281-20e4402da7d4.png)

今回は名古屋の天気を取得してみました。
Unicode 文字列も確認できます。
右下の[Raw]を選択すると整形前のJSONが確認できます。
左の[History]で履歴が確認できます。
dockerでgolangの実行ファイル1個だけを含むイメージを作って動かす

# はじめに

[前回の記事](https://qiita.com/tetsu_koba/items/d861d4bab3bb88612ef4) でdockerではネットワークのアクセスとUTCの現在時刻の設定に関しては自動でやってもらえるということがわかった。
ということなので、今回はbusyboxの代わりにgolangで書いた簡単なhttp file serverを1個だけを含むイメージを作って動かしてみる。

# http file server のビルド

```golang:httpfileserver.go
package main

import (
	"log"
	"net/http"
)

func main() {
	log.Fatal(http.ListenAndServe(":80", http.FileServer(http.Dir("/"))))
}
`````

static linkになるように、`CGO_ENABLED=0` をつけてビルドする。

```
CGO_ENABLED=0 go build
```
static link になっていることを確認。

```
$ file httpfileserver
httpfileserver: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
```

# docker のイメージを作成して実行

テンポラリなディレクトリに `httpfileserver` を一個だけ入れて、それで　dockerのイメージを作成する。

```
mkdir /tmp/a
cp httpfileserver /tmp/a
cd /tmp/a
tar cf - . | docker import - httpfileserver0:latest
```

コンテナ内のport:80が外から見えるようにbindして実行する。

```
docker run -p 0.0.0.0:80:80/tcp httpfileserver0 /httpfileserver
```

# 実行結果

http://localhost/

```
.dockerenv
dev/
etc/
httpfileserver
proc/
sys/
```

http://localhost/etc/

```
hostname
hosts
mtab
resolv.conf
```

http://localhost/proc/

```
1/
acpi/
buddyinfo
bus/
cgroups
cmdline
consoles
cpuinfo
crypto
devices
diskstats
dma
driver/
execdomains
fb
filesystems
fs/
interrupts
iomem
ioports
irq/
kallsyms
kcore
key-users
keys
kmsg
kpagecgroup
kpagecount
kpageflags
loadavg
locks
mdstat
meminfo
misc
modules
mounts
mtrr
net
pagetypeinfo
partitions
sched_debug
schedstat
scsi/
self
slabinfo
softirqs
stat
swaps
sys/
sysrq-trigger
sysvipc/
thread-self
timer_list
tty/
uptime
version
version_signature
vmallocinfo
vmstat
zoneinfo
```

当然だが、このコンテナの中で動いているプロセスは1個だけ。

```
$ curl -I http://localhost/
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Last-Modified: Sat, 14 Apr 2018 01:09:59 GMT
Date: Sat, 14 Apr 2018 01:18:31 GMT
Content-Length: 191
```

HTTPのレスポンスヘッダの中の時刻も特に問題無し。

#追加ファイル

golangの実行ファイル1個だけで動かす場合には制限があります。
時刻はUTCでしか扱えませんし、TLS(暗号化通信)は使用できません。
これらのためには/etc にファイルを追加する必要があります。
以下の記事の「追加ファイル」の章を参考にしてください。
[minimumgo: Linuxでgolangの実行ファイルをひとつだけ動かすときに必要最小限の初期化処理をしてくれるgolangのパッケージ](https://qiita.com/tetsu_koba/items/059849c0871a7e3bd94f)
【PHP】処理順を取得・表示 デバッグ用

#デバッグ時に使える処理ファイルの探索
##debug_backtrace()

<pre>
$bt = debug_backtrace();
foreach ($bt as $num => $row) {
    $dt[] = [
        $row['file'],
        $row['line']
    ];
}
krsort($dt);
$dt= array_values($dt);
var_dump($dt);
</pre>
await 地獄 誰のせい？

元ネタ: async/await地獄
https://qiita.com/rana_kualu/items/e6c5c0e4f60b0d18799d

後ろにいくほど手戻りが多くなる

# コードが悪い
- 原因
   - 安易な直列化（元記事での主張）
- 対策
    - 必要な直列関係の明確化と分割
    - Promise の生成 と `await` のタイミングをずらす
    - 例: `Promise.all`, `p = new Promise; .... await p`

# 画面設計・機能設計が悪い
- 原因
    - 1 機能/1 画面が担う担務が多い
- 対策
    - 機能分割
    - 例: 
        - 前: 商品データ取得＋在庫データ取得 で画面生成
        - 後: 商品データ取得で画面生成 + 在庫データ取得で画面修正
    - 並列性は実行環境にまかせる（**これがJSの王道**）

# インターフェース設計が悪い

- 原因
    - インターフェースミスマッチによるAPIコール多発
- 対策
    - サーバサイドのインターフェース変更
    - 例: REST でなく GraphQL を使う