OmniAICreator/Qiita-1.07M huggingface dataset:
herokuメモ

1 java ソース解析
2 heroku　テーブルER図
     MK2 UIツールを使う　https://a5m2.mmatsubara.com/
　　　　ホスト
　　　　ポート
　　　　DB名
　　　　ユーザ	
　　　　パスワード

3 heroku　SQLツール連携
Storyboardからインスタンスを生成する便利なメソッドを作る

## 環境

* Xcode10.2
* Swift5.0

## Storyboardからインスタンスを生成する

Storyboardで作成したViewControllerをコードからインスタンス化したいときは該当ViewControllerに以下のようなメソッドを用意すると便利です。
Storyboardで該当VCの **identifierをクラス名と同じ** にしておくことをお勧めします。


```swift

class MainViewController: UIViewController {

  /// Storyboardから生成したMainViewControllerのインスタンスを返す
  static func instance() -> MainViewController {
    let storyboard = UIStoryboard(name: "MainViewController", bundle: nil)
    let instance = storyboard.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
    
    return instance
  }
}
```

[R.swift](https://github.com/mac-cain13/R.swift)を使っている導入している方は以下のようにも書けます。
より簡潔に書けます。

```swift

  /// Storyboardから生成したMainViewControllerのインスタンスを返す
  static func instance() -> MainViewController {
    return R.storyboard.mainViewController.mainViewController()!
  }
```

### 使い方

以下のようにインスタンス化して画面遷移するなり自由に扱えます。

```swift
let mainViewController = MainViewController.instance()
```

## 最後に

StoryboardからVCのインスタンスを都度生成するのは面倒 + コードでUIの構築に慣れている方は
Storyboardで作ったUIをコードで扱えるようにするところが苦労すると思いますので是非試してみてください
ngrokよりserveoがすごい。０秒で localhostを固定URLで公開

## 注意 serveoがサービス停止中です。

みんな大好きcloud functionには欠点があります。
それは、実際にコードをデプロイしないと、httpsで公開できないこと。
そのため、slackのコマンドを作ったり、ラズベリーパイとかを開発するのに不便だったりします。

以前私はngrokというcliアプリを使っていました。
とても使いやすく、ユーザー登録＋ngrokのインストール＋セットアップだけで使い始めることができます。
お金を払えば固定URLもゲットできます。

しかし、今回もっと良いものを見つけたので紹介します。
[serveo](https://serveo.net/)です。

なんとこのserveoインストールもセットアップも不要です。

ターミナルで、以下のように

ssh -R 80:localhost:3000 serveo.net

と打つだけで自分のPCのlocalhost:3000を、固定URLでhttpsとして公開してくれます。
しかも無料で！
詳しくは、[公式サイト](https://serveo.net/)を読んでください。

これは革命ぜよ!
PythonエラーAttributeError: module 'xxx' has no attribute 'yyy'。こんなケースも。。。

#目的
AttributeError: module 'xxx' has no attribute 'yyy'
というエラーメッセージに関しては、いろいろな解説がある。
どこかの記事とは重複すると思うが、以下の観点で、
このエラーメッセージのことを記載する。

　・**attributeそもそもの定義**にかかわる内容
　　　→そのため、「has no」と言われたり言われなかったり、
　　　　　　　　　呼び方により変わるケース

記載の目的は、エラーメッセージを読み間違うと、対策に無駄な時間を要する場合があるので、それの回避のための情報共有。


# attributeなのか、attributeじゃないのか？

## attributeの定義

(出典：
　https://docs.python.org/3/glossary.html
　https://docs.python.org/ja/3/glossary.html
）

|attribute|
|:---|
|(属性) オブジェクトに関連付けられ、ドット表記式によって名前で参照される値です。例えば、オブジェクト o が属性 a を持っているとき、その属性は o.a で参照されます。|
|A value associated with an object which is referenced by name using dotted expressions. For example, if an object o has an attribute a it would be referenced as o.a.|


## エラーが出たり出なかったりするケース

上記のattributeの定義は、広義だと思う。ドットでつながれば、、、という定義。
ご存じのように、パッケージとかも、ドットでつながる。

さて、

ちょっと、古いモジュールを例にします。

```
>>> import scipy.misc
>>> scipy.__version__
'1.1.0'
```

***pilutilは、 'scipy.misc' のattributeなんでしょうか？違うのでしょうか？***

```
>>>
>>> help(scipy.misc.pilutil)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'scipy.misc' has no attribute 'pilutil'
>>>
>>>
>>> import scipy.misc.pilutil as tmppil
>>> help(tmppil)
Help on module scipy.misc.pilutil in scipy.misc:

NAME
    scipy.misc.pilutil - A collection of image utilities using the Python Imaging Library (PIL).

DESCRIPTION
    Note that PIL is not a dependency of SciPy and this module is not
    available on systems that don't have PIL installed.

FUNCTIONS
    bytescale(*args, **kwds)
        `bytescale` is deprecated!
        `bytescale` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.


            Byte scales an array (image).

            Byte scaling means converting the input image to uint8 dtype and scaling
            the range to ``(low, high)`` (default 0-255).
            If the input image already has dtype uint8, no scaling is done.

            This function is only available if Python Imaging Library (PIL) is installed.

            Parameters

>>>


```

:memo:パッケージとかで、違う(AttributeError)と言われても、必ずしも、そうじゃない
んじゃないかな？と思います。

ここでは、attributeとして扱えません、ぐらいの意味で解釈したほうがいいときもあるのでは？
**importはタフに処理してくれる**ので、そこで、処理して(仲介して）使えばいい気がしています。


#まとめ
***Pythonのエラーメッセージはわかり易い***と思っており、
ちょっと、変なのがあると、少し、傾向をつかんでおきたいので、
やや細かいことをケアしました。


#関連（本人）

[pythonをストレスなく使う！（結局docs.python.orgのreferenceが納得感が高い気が、、、)](https://qiita.com/enoughspacefor/items/9f714c9d4a13b6f1eaa9)
[pythonをストレスなく使う！（generatorに詳しくなる。since1975らしい。)](https://qiita.com/enoughspacefor/items/524a76fcde2610b9da8a)
[pythonをストレスなく使う！（Pythonでは、すべてがオブジェクトとして実装されている)](https://qiita.com/enoughspacefor/items/0c6118da4c228226a65f)
[pythonをストレスなく使う！（Pylintに寄り添う)](https://qiita.com/enoughspacefor/items/df692b27bb58ca1ffa1d)
[pythonをストレスなく使う！（ExpressionとStatement)](https://qiita.com/enoughspacefor/items/1a11f553c265a2c703f2)
[英語と日本語、両方使ってPythonを丁寧に学ぶ。](https://qiita.com/enoughspacefor/items/d4b49747773e2d0285f9)

#今後
コメントなどあれば、お願いします。:candy:
勉強します、、、、
iOS/AndroidのOSバージョンシェア情報まとめ

iOS / Android アプリの開発をしていると、アプリの最小サポートバージョンをどこまでにするかで悩むことが多いですよね。その判断材料となる各OSのバージョン別シェア情報の参照先をまとめます。

### iOS (Apple公式)

https://developer.apple.com/jp/support/app-store

- Apple公式の全世界でのiOSシェア情報です
- 過去4年間にリリースされたデバイスでのシェア情報、全デバイスでのシェア情報の２パターンを確認できます

### Android (Google公式)

https://developer.android.com/about/dashboards/?hl=ja

- Google公式の全世界でのAndroidシェア情報です
- 画面サイズと密度の組み合わせ、OpenGLバージョンの相対数データもあります

### iOS/Android (スマタブInfo)

http://smatabinfo.jp/os

- 株式会社KSK が日本国内に絞って独自に収集しているシェア情報です
- 特にAndroidは、Google公式の全世界のデータに比べて、日本では新しめのバージョンに寄っている傾向にあるため、日本国内中心に展開されるアプリの場合はこちらの方を参考にすると良さそうです
2019-07-29 Windows 10 > 設計ミス > Microsoft Teamsをアンインストール後にインストールされる > 対処: Teams Machine-Wide installerをアンインストール

```txt:動作環境
Windows 10 v1903
```

### 経緯

1. Microsoft Teamsをアンインストール（ユーザログインから)
    - =>再起動するとMicrosoft Teamsが「ようこそ」画面を表示
2. Microsoft Teamsをアンインストール（管理者ログインから)
    - =>再起動するとMicrosoft Teamsが「ようこそ」画面を表示
3. Microsoft Teamsをアンインストール（管理者ログインから)
    - =>再起動するとMicrosoft Teamsが「ようこそ」画面を表示

:thinking: 

### 情報

- Microsoft teams won't stay uninstalled
    - https://www.reddit.com/r/sysadmin/comments/aq72e4/microsoft_teams_wont_stay_uninstalled/

>  the Microsoft Teams Machine-Wide installer. What this does is installs Teams every time a user logs in. 

「Teams Machine-Wide installer」がある限り、Microsoft Teamsがインストールされ続ける。

### 対処

1. Teams Machine-Wide installerアンインストール (管理者ログイン)
    - => Microsoft Teamsもアンインストールされる

一般ユーザでログイン時、スタートアップを見ると「Microsoft Teams: 有効」が残るが、Microsoft Teamsの起動時ダイアログは表示されないので、これで対処を終了とする。


### 所感

Windows 10になってからUIが色々おかしくなった。
APIドキュメントのブラウザ "Dash" をIntellijに連携する

`Dash` では、ユーザーが登録したドキュメントを検索することができます。  
また、Intellijと連携することで、コマンド一つで選択範囲をDashで検索できます。

公式のガイド通りに連携できたので、手短にやり方をまとめます。

# 1. Kotlinのドキュメントをインストールする
https://github.com/Kapeli/Dash-User-Contributions
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/6220cc4b-118e-5cc6-d21e-fedc24daf30d.png)

# 2. IntellijにDashのプラグインを導入する
https://github.com/gdelmas/IntelliJDashPlugin#readme
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/695909a9-00ea-b67c-55ac-236a78fc9a6c.png)

# 3. Intellij上で Command + Ctrl + Dで検索する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/b75fcb0b-125d-278b-229d-9e54d21a58bd.png)

以上です。
SQL基本構文まとめ

# はじめに
SQLについて学習している入社1年目のSEです。『SQL書き方ドリル』のテーブルデータをMariaDBに移してクエリの練習をしています。アウトプットのために学んだクエリを書いていきます。今回はSELECT文の中でも超超基本的な内容です。
間違っていたら優しくご指摘をいただければと思います。

#SELECT
SQLで一番最初に使ったクエリ。初めて見たときは、SELECTよりもカラムって何だ!?となりました。column（行）とrow（列）のことだったんですね。いろいろ恥ずかしい…。
データが入っているテーブルを指定して、指定したカラムを表示することができます。

```sql
SELECT カラム名 FROM テーブル名;
```

#WHERE
WHERE句を使うとSELECTする対象を絞り込むことができます。

```sql
SELECT カラム名 FROM テーブル名 WHERE 条件式;

--文字列を指定したいとき（完全一致）
SELECT カラム名 FROM テーブル名 WHERE 対象 LIKE '文字列';

--文字列を指定したいとき（部分一致）
SELECT カラム名 FROM テーブル名 WHERE 対象 LIKE '%文字列%';
```

#GROUP BY
GROUP BY句を使うことによって、特定のカラムで行をグループ分けできる。

```sql
SELECT カラム名 FROM テーブル名 GROUP BY まとめたいカラム名;
```
以下の文では、StudentClassでグループ化して、SCHOOLテーブルから、クラスごとに生徒の数をカウントしています。

```sql
SELECT StudentClass AS クラス, COUNT(*) AS 生徒数  FROM SCHOOL GROUP BY StudentClass;
```
結果として、下の表が得られました。

```
+-----------+-----------+
| クラス    | 生徒数    |
+-----------+-----------+
| A         |         2 |
| B         |         3 |
| C         |         1 |
+-----------+-----------+
```
このように、GROUP BY句は集合関数（AVG、SUM、COUNTなど）と一緒に使ってグループ化⇒集計までやることができます。

#HAVING句
つい最近まで、WHERE句とHAVING句の区別がついていませんでした…。恥ずかしい…。
WHERE句の対象はカラムに入っている値ですが、HAVING句の対象は集合関数の計算結果です。
WHERE句ではカラムの値ごとに、条件に当てはまっているか真偽を判定しますが、HAVING句では、集合関数の計算結果をフィルタにかけることができます。
たとえば、先ほどのSCHOOLテーブルで、生徒の数が2人以上のクラスを調べたいときに使います。

例えば、先ほどのSCHOOLテーブルで、HAVING句を使うことによって生徒数が2人以上のクラスを調べることができます。

```sql
SELECT StudentClass AS クラス, COUNT(*) AS 生徒数 FROM SCHOOL GROUP BY StudentClass HAVING COUNT(*) >= 2;
```

マンツーマンレッスンのCクラスが除外されて表が出力されます。

```
+-----------+-----------+
| クラス    | 生徒数    |
+-----------+-----------+
| A         |         2 |
| B         |         3 |
+-----------+-----------+
```

#おわりに
初めての記事で、超初歩的なうえに短いですが、Qiitaの記事を書くのはとても大変ですね…。記事を書かれている先輩方を心の底からリスペクトします。SQLに関してはまだまだ入り口にも立ってないくらいですが、とても奥が深く、面白いので知識を深めて使えるようになりたいと思います。
Pythonでジオコーディング(Geocoder/Googlemaps)

## はじめに
以下の投稿で、場所の名称から緯度経度の情報を取得することをしました(JavaScript)

https://qiita.com/yoshi_yast/items/521c1f36306a180f45dd

Pythonライブラリを使用し、より簡単に複数の場所の緯度経度を取得してみたいと思います。今回使用するのは、Geocoder/OpenStreetMap と Googlemapsです。

## 前提
Google Maps API keyの取得

## 環境
python 3.7

インストール
`$pip install geocoder`
`$pip install googlemaps`

## やったこと・コード
### ①Pythonでジオコーディング(Geocoder/OpenStreetMap）

~~~geo01.py
import geocoder

place = '清水寺'
ret = geocoder.osm(place, timeout=5.0)
print(place, ret.latlng)
~~~

~~~
清水寺 [34.994303, 135.784438886419]
~~~

複数の場所をローカルのtxtファイルからアップロードして、結果を見てみる

~~~geo02.py
import geocoder
import csv

with open("./mylist1.txt", "r", encoding="utf-8_sig") as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader:
        print(row[0])
        ret = geocoder.osm(row[0], timeout=5.0)
        print(ret.latlng)
~~~

~~~
アマゾン川
[43.197963, 141.771885]
アマルフィ海岸
[35.7728747, 139.519887]
アルダブラ環礁
None
アルベロベッロのトゥルッリ
None
アンコールワット
[13.41249965, 103.866569373055]
アンダルシアのひまわり畑
None
アンテロープ・キャニオン
None
アンナプルナ
[34.47401005, 133.30666803559]
イースター島
[-27.12595935, -109.349576422058]
イエローストーン国立公園
None
イエローナイフのオーロラ
None
イグアスの滝
[-25.73602815, -54.4746500826546]
~~~
- OpenStreetMapでは、結果がとれない、結果がとれていても精度がよくなかったです。
- 同じ内容をgooglemapsでもやってみようと思います。

### ②Pythonでジオコーディング(Googlemaps)
~~~geo03.py
import googlemaps
import csv
import time

googleapikey = 'API keyを設定する'
gmaps = googlemaps.Client(key=googleapikey)

with open("./mylist1.txt", "r", encoding="utf-8_sig") as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader:
        print(row[0])
        result = gmaps.geocode(row[0])
        lat = result[0]["geometry"]["location"]["lat"]
        lng = result[0]["geometry"]["location"]["lng"]
        print (lat,lng)
        time.sleep(0.5)
~~~

~~~
アマゾン川
-3.2996216 -60.6646509
アマルフィ海岸
40.6333389 14.6028963
アルダブラ環礁
-9.4236984 46.3432781
アルベロベッロのトゥルッリ
40.7826344 17.2363428
アンコールワット
13.4124693 103.8669857
アンダルシアのひまわり畑
37.5442706 -4.7277528
アンテロープ・キャニオン
36.8619103 -111.3743302
アンナプルナ
28.596111 83.820278
イースター島
-27.112723 -109.3496865
イエローストーン国立公園
44.427963 -110.588455
イエローナイフのオーロラ
62.4551975 -114.3688018
イグアスの滝
-25.695259 -54.4366662
~~~
- OpenStreetMapよりも結果の取得、取れた結果の精度、ともに上回りました。
- ただ、Googlemapsでは、ジオコーディングを短時間に実施するとエラーになりましたので、すこし時間を開けています。

## まとめ
- pythonライブラリを使用するととても簡単にジオコーディングできることがわかりました。
- 以下の投稿で、場所のピン打ちをしていますが、緯度経度情報がなく、場所名称しかわからない場合は、ジオコーディングが有効ですが、「緯度経度を算出すること」と「地図への表示」はプログラムをわけることもありかとも思いました。

https://qiita.com/yoshi_yast/items/4f0be22bfcf2d63412ee

## 参考URL

- Geocodeing API

https://developers.google.com/maps/documentation/geocoding/start

- Python 製ジオコーディングライブラリ Geocoder を試す

https://astropengu.in/blog/18/
[Spigot Build Tool] Spigotを簡単にビルドできるツール

# 使い方
1. SpigotBuilderを以下からDLする  
https://github.com/Seaoftrees08/SpigotBuilder

2. DLしたヤツを起動する
   - 電子署名行ってないので、警告が出る。無視してok 
3. `Minecraft Version`の項目から好きなバージョンを選択
4. `Build`というボタンを押すと、SpigotBuilderと同じフォルダに勝手にビルドしてくれる

以上です。ね？簡単でしょ?  

# 経緯
本家のSpigot BuildTools GUIが使えなくなったので作ったもの。  
日本非公式ユーザーフォーラムでのトピックがなぜか消えていたのでQiitaで再掲
Sphinx ではどのようにラベルとキャプションを結びつけているのか

https://tk0miya.hatenablog.com/entry/2014/08/11/003957

なんか
```
C:\Users\hogehogetool\manual\source\manual\procedure.rst:68: WARNING: undefined label: replace (if the link has no caption the label must precede a section header)
C:\Users\hogehogetool\manual\source\manual\procedure.rst:79: WARNING: undefined label: replace (if the link has no caption the label must precede a section header)
C:\Users\hogehogetool\manual\source\manual\procedure.rst:108: WARNING: undefined label: replace (if the link has no caption the label must precede a section header)
C:\Users\hogehogetool\manual\source\manual\procedure.rst:138: WARNING: undefined label: replace (if the link has no caption the label must precede a section header)
C:\Users\hogehogetool\manual\source\manual\procedure.rst:158: WARNING: undefined label: replace (if the link has no caption the label must precede a section header)
generating i
```
って出るから上記URLを参考にして見てみるっ


と

```
.. _target:

section


セクションへの :ref:`参照 <target>` を作ります。
```
って書いてあったからこれっぽい……なんか　
.. _target:
って使ってないから消した予感っ
CSSだけで、tableの中にある行(row)の順番を変更して左右反転させる

### やりたいこと
HTMLで作られたテーブルがあり、これを通常(デフォルト)の設定である「左から右へと行の内容が続いていく」状態をひっくりかえし、順番を入れ替えたい、しかもCSSの記述だけでどうにかしたい！という場面にあり、まぁ出来なくはないのか...と見つけた手法です。


### CSSをこう書く
`tr (table row)`が横向きの行なので、まずこれを`transform`で左右反転させます。これだけだと鏡文字になってしまい読めないので、それぞれの構成要素である`td (table data)`を再度左右反転させることで、正常に表示されるようになります。

```css
.reversed table tr {
    transform: scale(-1, 1);
}

.reversed table td {
    transform: scale(-1, 1);
}
```

上記の要素以外に、`th (table header)`などががある場合は追記が必要です。`table tr`という具合に子要素で指定しているのは、`caption`などはそのままにしておく狙いがあります。


### フルサンプル

```HTML:table.html
<!doctype html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
	<table>
	<caption>通常のテーブル</caption>
		<tr>
			<th>ヘッダー左上</th>		<th>ヘッダー中央</th>		<th>ヘッダー右上</th>
		</tr>
		<tr>
			<td>A1</td>		<td>B1</td>		<td>C1</td>
		</tr>
		<tr>
			<td>A2</td>		<td>B2</td>		<td>C2</td>
		</tr>
	</table>
	<br>
	<div class="container reversed">
	<table>
	<caption>反転しているテーブル</caption>
		<tr>
			<th>ヘッダー左上</th>		<th>ヘッダー中央</th>		<th>ヘッダー右上</th>
		</tr>
		<tr>
			<td>A1</td>		<td>B1</td>		<td>C1</td>
		</tr>
		<tr>
			<td>A2</td>		<td>B2</td>		<td>C2</td>
	</table>
	</div>
</body>
</html>

```
```css:style.css
.reversed table tr {
    transform: scale(-1, 1);
}

.reversed table th {
    transform: scale(-1, 1);
}

.reversed table td {
    transform: scale(-1, 1);
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390679/91ff413d-0335-113c-199e-c101cea1df65.png)
最短2文でLibraのテストネットを立ち上げるDockerイメージ作りました

6月28日、29日に開催されたG20でも議論されたと言われる話題のLibra、登場早々さまざまな方面に影響を与えています。そんなLibraを手軽に体感できるように、最短で2文で実行できるDockerイメージを作ったので紹介します！

#前提知識と下準備
前提としてお使いのPCにDockerがインストールされている必要があります。Dockerはコンテナ技術を使った仮想環境を構築でき、スクラップ＆ビルドがしやすいため、今回のような実験的なプログラムを動かしやすいメリットがあります。また、Dockerイメージと呼ばれるファイルシステムを利用することで同じ環境を構築することができるため配布がしやすいという長所もあります。

DockerイメージはDockerfileと呼ばれるファイルによって定義されます。
#Dockerイメージの紹介
今回作成したDockerイメージは以下のようなDockerfileで定義されています。こちらのファイルはGitHubでも確認できるようにしています。
https://github.com/Naokiakazawa/libratest-docker

```Dockerfile:Dockerfile
FROM ubuntu:19.04
SHELL ["/bin/bash", "-c"]
RUN apt-get update \
    && apt-get -y upgrade \
    && apt-get -y install \
        cmake \
        curl \
        git \
        golang \
        libssl-dev \
        protobuf-compiler \
        sudo \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    && git clone https://github.com/libra/libra.git
WORKDIR /libra
RUN yes | ./scripts/dev_setup.sh \
    && source /root/.cargo/env \
    && cargo build
CMD [ "./scripts/cli/start_cli_testnet.sh" ]
```

#使い方
今回作成したDockerイメージは、DockerHub上で公開しています。
https://hub.docker.com/r/naokiakazawa/libra-test

DockerHubはさまざまなDockerイメージが公開されているプラットフォームで、ログインすれば便利なイメージを利用することができます。Dockerのインストールやログインなどが問題なければ、この節にある2つのコマンドでテストネットを立ち上げることができます。

まず、DockerHubのDockerイメージをローカル環境にプルしましょう。まず１つ目のコマンドは`docker pull`を使って以下のようになります。

```terminal:コマンド1つ目
docker pull naokiakazawa/libra-test 
```
プルできたら次に`docker run`を使って、以下のコマンドでイメージからコンテナを立ち上げます。これが２つ目のコマンドになります。

```terminal:コマンド2つ目
docker run --name libratestnet -it naokiakazawa/libra-test 
```

なお、`--name libratestnet`では立ち上げるコンテナの名前をlibratestnetとすることを定義しています。また、この時、`docker run`の末尾に`/bin/bash`などのようなコマンドをつけないようにしてください。Dockerfileの最後にあるCMD命令の内容が上書きされるため、正しく動作しません。

うまく起動すればLibraコマンドが実行できるようになります。`libra#`というプロンプトが出れば問題ありません。

ただし、２点注意があります

- Dockerイメージのデータサイズが約15GBほどあります。テストネットの環境を丸ごとコンテナの中に展開しているのでデータが少々大きくなります。
- データサイズが大きいため、イメージをプルする時間が少しかかります。

#まとめ
この度は、PCのローカル環境を汚すことなく、手軽に試せるようにするためDockerイメージを作ってDockerHubで公開しました。

ただ少しデータサイズが大きくなってしまうため、今後小さくしてみたいと思います。（たぶんベースイメージを小さいものにしたり、マルチステージビルドをしてみたりするとうまくいくはず…）
コードとコメントだけのtypeorm入門

# コードだけしかないtypeorm入門

```ts
/*
//TypeScriptの基本以外で必要なパッケージ
sqlite3
typeorm

//tsconfig.jsonに必要な追加設定
{
  "compilerOptions": {
    "experimentalDecorators":true,
    "emitDecoratorMetadata":true
  }
}
*/
import * as typeorm from "typeorm";

/**
 *データ構造の定義
 *
 * @export
 * @class TestModel01
 */
@typeorm.Entity()
export class TestModel01 {
  @typeorm.PrimaryGeneratedColumn() //自動番号
  id!: number;

  @typeorm.Column() //一般データ
  name?: string;

  @typeorm.Column({
    default: () => "CURRENT_TIMESTAMP"
  }) //default値の指定:()=>"命令" でCURRENT_TIMESTAMPが文字列にならないように設定
  date!: Date;
}

/**
 *非同期主処理
 *
 */
async function Main() {
  //DBへ接続
  const con = await typeorm.createConnection({
    type: "sqlite",
    database: `test.sqlite`,
    entities: [TestModel01],
    logging: true
  });
  //DBの構造を初期化
  await con.synchronize();
  //テーブルアクセス用インスタンスの取得
  const testModel01 = con.getRepository(TestModel01);
  //テーブルへ挿入
  await testModel01.insert({ name: "あいうえお" });
  await testModel01.insert({ name: "かきくけこ" });
  //データの取得と表示
  const testValue01 = await testModel01.find();
  console.log("[出力結果]\n%s",JSON.stringify(testValue01,null , "  "));
  await con.close();
}

//主処理の呼び出し
Main();

/*
[出力結果]
[
  {
    "id": 1,
    "name": "あいうえお",
    "date": "2019-07-29T01:09:03.000Z"
  },
  {
    "id": 2,
    "name": "かきくけこ",
    "date": "2019-07-29T01:09:03.000Z"
  }
]
*/
```
私の_vimrc

```vim:_vimrc
set encoding=utf-8
set nobackup
set noundofile
set noswapfile
set number
set cursorline
set cursorcolumn
set clipboard=unnamed,autoselect
set guifont=Ricty_Diminished:h12
set guifontwide=Ricty_Diminished:h12
set expandtab
set softtabstop=4
```
ERROR 1045 (28000): Access denied for user 'root'@'localhost' ←(ﾟДﾟ)ﾊｧ?

# 朝会社に来たらこんなエラーが出るようになっていた
・・・と言うのは言い訳で、何もしないで壊れるわけがないこの世界。過失は120％この自分にあるわけで・・・
恐らく、間違えてyum updateをかけてしまい、rpmのyumを経由してインストールしたパッケージが軒並みAmazon Linuxのパッケージに入れ替わった時に再起動がかかり、mysqlテーブルのユーザーやパスワードを吹っ飛ばした可能性が高いです。

## 直した
直し方はそこまで大変ではなかった。問題発生の原因解明に時間がかかった。

### まず止める。

```
# service mysqld stop
```

###セーフティモードで起動
プロセスが動き続けるので、この時点でターミナルの別タブ開いて他のプロンプトからssh。

```
# mysqld_safe --skip-grant-tables &
```

###別のプロンプトからsshしたところでmysqlにログイン。

```
$ mysql -u root
```

###mysqlへ切り替え

```
mysql> use mysql;
```

### 設定をUpdate

```
mysql> update user set password=PASSWORD("ここにパスワードを記述") where User='root';
```

### 反映

```
mysql> flush privileges;
```

これでいつも通りmysql -u root -pで入れるようになる。
Ryzenのチューニングに関する情報

[英文によるRyzenアーキテクチャの解説](https://gpuopen.com/gdc-presentations/2019/gdc-2019-s2-amd-ryzen-processor-software-optimization.pdf)
[RyzenでSTREAMベンチする場合の注意点](https://twitter.com/ogawa_tter/status/1146980797875810305) (twitter)
[その他参考資料](https://twitter.com/ogawa_tter/status/1003282146239209478) (twitter)
[AMD Developer Guides, Manuals & ISA Documents](https://developer.amd.com/resources/developer-guides-manuals/)
[AMD Tech Docs](https://www.amd.com/en/support/tech-docs)
GCEのubuntu 18.04でタイムゾーンをJSTにする

久々に10ヶ月前に書いたAnsibleソースをubuntu 18.04に実行したら、以下のエラーが発生した。

#### エラー内容

```
fatal: [111.111.111.111]: FAILED! => {"changed": false, "msg": "src file does not exist, use \"force=yes\" if you really want
to create the link: /usr/share/zoneinfo/Japan", "path": "/etc/localtime", "src": "/usr/share/zoneinfo/Japan", "state": "abse
nt"}
```

#### 該当ソース

```
- name: setup JST
  file:
    src: /usr/share/zoneinfo/Japan
    dest: /etc/localtime
    state: link
```

最近は、 `timedatectl`使うみたいですね。
で、以下のコマンドを調べて、見るとUTCしかない。

```
$ timedatectl list-timezones 
UTC
```

ということで`tzdata`をいれて以下のようにして、解決しました。

```
- name: Add Timezone
  apt:
    name: "{{ item.name }}"
    update_cache: yes
    cache_valid_time: 3600
  with_items:
    - { name: tzdata }
  ignore_errors: aptget_ignore_errors

- name: Set timezone to Asia/Tokyo
  timezone:
    name: Asia/Tokyo
```
Python で Design by Contract する方法を調べてみた。

# 環境

- Python 3.6.5
- Windows 10 201903


# Design By Contract?

そもそもご存知ない方は [ホーア論理](https://ja.wikipedia.org/wiki/%E3%83%9B%E3%83%BC%E3%82%A2%E8%AB%96%E7%90%86) を勉強したほういいと思います。私もこの理論を勉強するまで、事前条件と事後条件の関係を理論的に理解していませんでした。

# どんな方法があるのか?
[PEP 316](https://www.python.org/dev/peps/pep-0316/)で inv を含む Design by Contract の言語拡張提案がなされています。が、Status が Deferred となっていて、言語拡張として DbC がサポートされる見込みはかなり薄そうです。

上記提案を調べていたら、[Contracts for Python](http://www.wayforward.net/pycontract/)というページを見つけました。PEP 316を意識した実装に見えますが、更新時期が古くちょっと心配です。

[PyDBC](https://pypi.org/project/PyDBC/)も更新が2003年と古いです。

[PyContracts](https://andreacensi.github.io/contracts/)は最近更新されていて、比較的安心感がありました。Contract の書き方も何パターンかあって面白そうなので見てみました。ただ、invariant や post は書けそうにありません。invariant はパフォーマンス的に不利ですし、invariant をサポートするには atom などさらに拡張が必要なはずなので、致し方ないかと思います。さらに interpreter 側に手を入れる必要があるでしょうから、パッケージで実装することは難しいのではないでしょうか。

# 始めよう

pip で入れられます。

```
>pip install PyContracts
```

サンプルコードを書きました。

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

from contracts import contract, ContractsMeta, with_metaclass

@contract
def foo(a, b):
    """ Function description.
        :type a: int
        :type b: int,!=0
    """
    return (a/b)

print(foo(1,2))
print(foo(1,0))
```

後者が契約違反を表示してくれます。いいね。

# いいのか？

ホーア理論を教えてくれた先生も言っていたのですが、これなら assert を書くのと何が違うのか？とも思ったりします。ちゃんとできることの差分を調べようと思います。
tigでvimdiffツールを起動する

tigは慣れると便利なのですが、標準の差分表示がUnified形式なのが、あまり好きではないです。

なので、vimdiffを使って差分表示できるようにキーバインドを変更してみました。


```shell:~/.tigrc
# vimdiffで確認をする
bind generic D      !git difftool --tool=vimdiff --no-prompt --trust-exit-code %(commit)^!

```

ついでに、`~/.vimrc`の設定もします。
（既に設定してあれば不要です）

```~/.vimrc
" vimdiffの色設定
highlight DiffAdd    cterm=bold ctermfg=10 ctermbg=22
highlight DiffDelete cterm=bold ctermfg=10 ctermbg=52
highlight DiffChange cterm=bold ctermfg=10 ctermbg=17
highlight DiffText   cterm=bold ctermfg=10 ctermbg=21
```

設定ができたので、
main view で `Shift+d`を押して、差分表示をしてみます。

### 追加差分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168063/de91228b-3674-b4ce-d3e1-8ed0d06e70fc.png)

### 行に差分がある場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168063/a4f598d4-2d3b-936b-61ad-60f857c18d6e.png)

### Unified形式で差分表示した場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168063/a18ec26d-fb62-d671-d4c6-8d930c7b6f41.png)



差分が左右に表示されて、見やすくなりました。
好みの問題だとは思いますが、個人的にはこちらの方が好きです。
一応main viewの状態で`d`を押せば、今まで通りUnified形式でも表示出来るので、必要に応じて使い分けができそうです。




# 参考URL

[vimdiff-like Diff View](https://github.com/jonas/tig/issues/26)
[vimdiffの色設定を変更して見やすくする（黒背景用）](https://qiita.com/takaakikasai/items/b46a0b8c94e476e57e31)
【Mac】踏み台サーバ経由でリモートデスクトップ接続する方法

##概要

Macから踏み台サーバ経由でWindowsサーバにリモートデスクトップする方法です。
Windowsサーバは踏み台サーバからのアクセスのみを許可しています。

##実行環境

踏み台サーバ
 - Amazon Linux release 2 (Karoo)

接続先サーバ
 - Windows 

##手順

#### 前提条件
 - Macから踏み台サーバへsshできること
 - 踏み台サーバからWindowsサーバにsshできること
 - MacにWindowsにアクセスするためのアプリを入れていること。ここでは「Microsoft Remote Desktop 10」を使います。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265708/04f7718b-d86c-bb5e-08ea-e0c6563ec14a.png)


#### ポートフォワード

下記のsshコマンドを実行します。
"-i シークレットアクセスキー" は、鍵があれば指定してください。

```
ssh ユーザ名@踏み台サーバIP -i シークレットアクセスキー -L 13389:windowsサーバのIP:3389
```

#### アプリの設定

PC nameは localhost:13389 とし、 User account はWindowsサーバにアクセスするためのユーザとパスワードを設定してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265708/5b79cfe4-2fdd-6070-0990-4f130628626f.png)

設定が終わったら接続します。

以上
WSL2がWindowsからlocalhostで接続できるようになる

# WSL2がWindowsからlocalhostで接続できるようになる

## １．今までのWSL

　*Windows 10 Insider Preview Build 18945* によって、WSL2がWindows側からlocalhost接続を受け入れるようになりました。それ以前のバージョンではコロコロ変わるIPアドレスによって、httpやssh接続の際に面倒な確認作業が生じていました。

　私は対処法として[WSL2のコロコロ変わるIPをMyDNSで何とかする](https://qiita.com/SoraKumo/items/388a1315a6bdc16b4d2e)で書いた記事の通り、プライベートIPをMyDNSに通知して、ドメイン名で接続するように対処をしていました。しかしもうそんな必要はありません。localhostで接続できるようになったのです。

## ２．NICの状態

　まず、基本的なネットワークの仕組みは以前のバージョンから変化していません。

Windows側で生成される仮想NIC

```.sh
イーサネット アダプター vEthernet (WSL):
   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: fe80::b562:8151:888c:3033%37
   IPv4 アドレス . . . . . . . . . . . .: 172.27.176.1
   サブネット マスク . . . . . . . . . .: 255.255.240.0
   デフォルト ゲートウェイ . . . . . . .:
```

Linux側のNICの状態

```.sh
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether de:50:74:6e:56:5c brd ff:ff:ff:ff:ff:ff
3: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 76:c0:1f:cc:27:f3 brd ff:ff:ff:ff:ff:ff
4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:9d:b5:ff brd ff:ff:ff:ff:ff:ff
    inet 172.27.191.103/16 brd 172.27.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fe9d:b5ff/64 scope link
       valid_lft forever preferred_lft forever
5: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
```

　以前と同じようのプライベートIPが割り当てられており、Linuxから外へ出る場合はeth0を経由する形になります。

## localhostの検証

- WindowsのWSL2仮想NICを無効化してみた結果  
WindowsからLinuxへのlocalhost接続は生きたままです。 
しかしLinuxから外部ネットワークへの接続は不可能になります。

- LinuxからWindowsへのlocalhost接続  
出来ません。現時点ではWindowsがlocalhostに対して、LinuxへのNATのような動作をしていると思われます。 
そのため逆は出来ません。 
今後のバージョンで対応される可能性があります。

## WSL2を使うときに便利なbat

　全然話は変わりますがWSLの再起動ごとに、sshやWebサーバの起動が面倒だという人のためのおすすめbatファイルがこれです。

```wsl_start.bat
start /b wsl -u root ^
for file in `\find /etc/rc3.d/* -maxdepth 1`; do $file start; done 
```

　RunLevel3の起動スクリプトを実行するBATです。これをWindowsから使えばsystemctlで有効化したサービスを起動することが出来ます。

## まとめ

　今回のネットワーク問題の改善により、WSL2がかなり使いやすくなりました。起動が速く軽量なので、実験環境としては有用になりました。今後のバージョンアップでどういう進化を遂げていくのかが楽しみです。ところで7月末の「Docker Desktop for WSL 2」はどうなったんでしょう？
php-master-changes 2019-07-28

今日はドキュメントの typo の修正があった！

# 2019-07-28
## TysonAndre: nit: Fix a typo in UPGRADING
- https://github.com/php/php-src/commit/99fe0471ed03b068763e0b8bf84f3a52fc8a784f
- [7.4~]
- UPGRADING で、typo の修正
Excel資料の参照を少しでも楽にするための小道具マクロ

# なにこれ
Excelで作られた資料は往々にして見づらい。
そんなストレスを軽減するための小道具マクロを3つほど。

# 更新履歴
2021-09-23 ソースのリンク先URLが死んでた・・・ので直した

# 本文

## 1. シート一覧作成

### 効く症状
シートがたくさんあって、目当てのシートを探すにも一苦労するようなとき
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282159/f7fa3709-b4c1-e76d-a501-c542ebc2ee65.png)

### 何をする
シート一覧をリンク付きで出力する

### どうなる
ワンクリックでシートに飛べるようになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282159/a08b20ec-9c5e-b51e-455b-e3d77e1b9f13.png)
おまけで、各シートのA1セルあたりから一覧に戻れるようにするのも便利。(Alt+←でも戻れるけど)
### コード
https://github.com/kumanobori/VBA_props/blob/master/src/work.xlsm/m_listIndex.bas

### ぼやき
シート数が5か10を越えたあたりで、作成者が一覧を作るべきだよ・・・

## 2. 表示方法を揃える
### 効く症状
シートごとに表示倍率が違ったり、表示方法が通常表示と改ページプレビューが混在してたり、開いたときに最初のセルじゃなくてシートの途中くらいを脈絡なく表示してたりするようなとき
### 何をする
全てのシートで、表示倍率と表示方法を揃えてA1セルを選択する
### どうなる
シートを開くたびにCtrl+Homeや倍率設定をする必要がなくなる
### コード
https://github.com/kumanobori/VBA_props/blob/master/src/work.xlsm/prepareAppearance.bas
### ぼやき
作成者が揃えておいてくれ・・・

## 検索してヒットしたセルに色をつける
### 効く症状
検索をしたいが、一画面に収まらない広大なシートのあちこちに該当文字列があったり、セル内の文字列が多すぎたりして、目当ての文字列がどこにあるかわからないようなとき
### 何をする
検索でヒットしたセルに背景色をつけ、該当する部分文字列にも色をつける
オプションで、A列を結果専用列とした場合、A列に見つかった文字列を出力する
### どうなる
こんなかんじ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282159/6fa63562-9e55-e5de-5927-123aa27e6dca.png)
### コード
https://github.com/kumanobori/VBA_props/blob/master/src/work.xlsm/m_searchAndPaint.bas
### 制限
全角半角を区別しない検索、かつ半角カナに濁点半濁点がある場合は、部分文字列の装飾が不完全。そこまでやる必要性と気力がなかった。
### 蛇足
コード調査にメモ帳しか使えない環境だったときに作った。
その後、見づらい資料を見る用途に流用した。
図形検索もできたらいいなとか思うけどそこまでの必要性と気力が（ｒｙ

# ぼやき
最初の2つは、資料作る側がちゃんとしてくれれば不要なものなんだよな・・・
自分が資料作るときにも役立つけど。
str.encode()でエンコードに失敗した文字を任意の文字で置き換える

## 概要
`str.encode()` でエンコードに失敗すると `UnicodeEncodeError` が発生する。
引数 `errors` でエラーハンドラを明示的に指定することで、発生時の挙動を変更し、Exceptionをraiseせずに処理することができる。
使用可能な標準エラーハンドラと、エラーハンドラの追加方法について記述する。
`str.encode()` についてはこちら
https://docs.python.org/ja/3/library/stdtypes.html#str.encode

## 標準エラーハンドラ
標準で用意されている主なハンドラは以下の通り。

- strict
    - デフォルト。エンコード失敗時に `UnicodeEncodeError` を発生させる。
- ignore
    - エンコード失敗した文字を無視（除去）して処理を継続する。
- replace
    - エンコード失敗した文字を `?` に置換して処理を継続する。

他のエラーハンドラについてはこちらを参照。
https://docs.python.org/ja/3/library/codecs.html#error-handlers

## エラーハンドラの追加
stringクラスが持っているcodecsクラスに対してエラーハンドラを追加することで、
エラー時の挙動を変えられる。

エラーハンドラの追加には `codec.register_error()` を使う。
https://docs.python.org/ja/3/library/codecs.html#codecs.register_error

登録例は以下の通り。

```
import codecs

replace_char = 'hoge'
def my_error_handler(exc):
    return ((exc.end - exc.start) * replace_char, exc.end)

codecs.register_error('original_handler', my_error_handler)
```

第一引数 `name` は呼び出す際に使う名前を登録し、
第二引数にはエラー時に呼び出すコールバックを渡す。

第二引数はコールバックであれば何でもよいので、lambdaでももちろん可。
（この例は前後のコードに関係ないサンプルです）

```
codecs.register_error('handler_name', lambda exc: 'hoge')
```

`original_handler` をエラーハンドラに指定してエンコードした結果が下記。
Shift-jisはカタカナの「ヴ」は表示できるが、ひらがなの「ゔ」は表示できないので、
ひらがなの「ゔ」が「hoge」に置き換わったことが確認できる。

```
>>> text = 'ヴァルゔレイヴ'

>>> text.encode('shift_jis', errors='original_handler')
b'\x83\x94\x83@\x83\x8bhoge\x83\x8c\x83C\x83\x94'

>>> text.encode('shift_jis', errors='original_handler').decode('shift_jis')
'ヴァルhogeレイヴ'
```

#### その他
`name` を標準エラーハンドラと同じにした場合、挙動が上書きされるはずなのだけど、うまくいかないのでもうちょっと調べたら追記します
私はタピオカミルクティーを一日にどれだけ摂取できるか?Vue.js+Vuetifyで計算ツール書いてみる

みなさんこんにちは
突然ですが、みなさんは自分が一日に摂取できるタピオカミルクティーの量を知っていますか?
知りたいと思いませんか?私は知りたい。

というわけで、Vue初心者でもあり筋トレ初心者でもある私の学習も兼ねて、VueとVeutifyを使って簡単なツールを作ってみました。ちなみにVue歴は3日、筋トレ歴は2年ほどの初心者です。

### 一日のタピオカミルクティー量をどうやって計算するか
計算は単純に一日の消費カロリー量をタピオカミルクティーのカロリーで割ります。

まず一日の基礎代謝(BMR)、消費カロリー量(TDEE)を求めます。
これらを求める式は色々あるようですが、ここではミフリンセントJeor式で計算します。(他にはハリスベネディクト式などがございます。)
ご存知ない方はググるか、この[マイプロの記事](https://www.myprotein.jp/thezone/nutrition/how-to-calculate-bmr-tdee-energy-expenditure/)見てください。

男性と女性で式が違うのでこれもツールに反映します。
男性 `10×Weight（㎏） + 6.25×Height（㎝） - 5×Age + 5`
女性 `10×Weight（㎏） + 6.25×Height（㎝） - 5×Age - 161`

### タピオカミルクティーのカロリー
タピオカミルクティーのカロリーですが、純粋なタピオカとミルクティーのみでおおよそ400kcalとします。
え？もっとカロリーあるだろって？こまけぇこたぁいいんだよ!!

### Vueで書いてみる
お勉強も兼ねて、Vue.js + Vuetifyで書いてみました。

[１日に摂取できるタピオカミルクティーの計算機](https://hidesakai.github.io/vue-tapioca-calc/index.html)
[github: vue-tapioca-calc](https://github.com/hidesakai/vue-tapioca-calc)

### 計算結果
私は一日6.4杯飲めるらしいです。
![tapioca-daily.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121487/6ee8ce16-ac34-491c-331c-8a47a3c6fa01.png)

ちなみにタピオカミルクティーは糖質もだけど脂質も案外多いんじゃないかと思いますので、普段の食事の変わりに置き換えたりしちゃダメなんだからね!
[Rust] ワークスペースでcargo releaseを使う

# はじめに
[cargo release](https://github.com/sunng87/cargo-release)とはpublishにまつわる作業（gitのタグ付けやバージョン書き換えなど）を自動化してくれるcargoのサブコマンドです。2019-07-17リリースの0.12.0にてワークスペースに対応したのですが、いろいろと罠があるのでまとめておきます。

# ワークスペースとは
ワークスペースとは複数のクレートを1つのディレクトリにまとめることができる機能です。詳細は"[Cargoのワークスペース](https://doc.rust-jp.rs/book/second-edition/ch14-03-cargo-workspaces.html)"を見てください。

使い道ですが、ドキュメントに書いてあるように「大規模なクレートを分割したい」ということはそれほどない気がします。よくあるのが次の2つです。
（これらもまぁ滅多にないといえばないですが…）

* procedural macro
* FFI

まずprocedural macroは必ず専用のクレートが必要です。そのためprocedural macroを使ったプロジェクトは（procedural macroのみのクレートでない限り）必ず2つ以上のクレートに分かれることになります。またFFIの場合は、`-sys`というsuffixの付いたクレートでCの関数を単にRustに変換しただけのものを提供して、別クレートで安全なラッパーを提供する、ということがよく行われます。

大規模なクレートからライブラリを切り出したようなケース（例えばripgrepというgrepツールから汎用ライブラリとしてgrepを切り出したような）は各クレートのバージョンは独立に設定したいと思います。しかし先に挙げたようなケースでは、分かれたクレートは密接に関連していることが多いので、バージョンも同時に上げたいところです。cargo releaseがワークスペースを扱えるようになったことで、複数のクレートのバージョンアップを1コマンドで行えるようになりました。

# 0.12.0時点の問題点

## pre-releaseが使えない

pre-releaseとはバージョンのsuffixに"-alpha.0"や"-rc"などを付けるフローです。これはcargo releaseのデフォルトのフローになっていて、以下のような動作をします。

* version = "0.1.0-alpha.0"で開発
* cargo releaseを実行
* （cargo releaseが）version = "0.1.0" に書き換え
* （cargo releaseが）コミット
* （cargo releaseが）タグ付け
* （cargo releaseが）cargo publish
* （cargo releaseが）version = "0.1.1-alpha.0" に書き換え

つまり普段の開発はずっとpre-releaseバージョンで行って、cargo release実行の瞬間だけ正式バージョンになる、というフローです。単一クレートの場合はこれで問題ないのですが、ワークスペースで複数クレートになって依存関係があると問題になります。

詳細は細かい話になるので関連するIssueだけ挙げておきます。

* [Verify / update corresponding version for path dependencies](https://github.com/sunng87/cargo-release/issues/77)

これを避けるには、pre-releaseを使わずに正式バージョンだけで運用すれば良いです。ワークスペース直下のrelease.tomlに

```toml:release.toml
no-dev-version = true
```

とするとワークスペース全体でpre-releaseが無効になります。
この状態で`cargo release patch`とするとパッチバージョンを上げてくれます。
普通に`cargo release`とするとバージョンを上げずにpublishしようとするので注意が必要です。

## タグ付けが複数回行われる

gitのタグを付けるようにしている場合、各クレート毎に同じタグを付けようとしてエラーになります。

解決方法ですが、クレート毎のCargo.tomlにて

```toml:Cargo.toml
[package.metadata.release]
disable-tag = true
```

としてタグ付けを無効にして、ワークスペース全体で1回だけタグ付けが発生するように調整するといいでしょう。
タグ付けを有効にするクレートは、ワークスペース内の依存関係的にツリーのルートに位置するクレートがいいと思います。cargo releaseは依存関係ツリーの末端から順に処理していくので、ルートでタグ付けするとちょうど全クレートのバージョンが上がったところでタグ付けできます。

## pre-release-replacementsのパス

pre-release-replacementsとはcargo releaseの機能の一つで、README.mdなどに書かれたバージョン番号を上げるのに使います。
ワークスペースを使う場合、これはワークスペース直下のrelease.tomlではなく、各クレートに書く必要があります。
（ワークスペース直下に書いた場合、単に無視されるようです）

さらに、対象となるファイルパスはそのクレートからの相対パスなので、ワークスペース直下のREADME.mdなら../README.mdになります。
現状のcargo releaseはエラー表示がいまいちで、パスを間違えた場合

```
Fatal: IO Error: No such file or directory (os error 2)
```

としか出ず、どのtomlファイルのどのパスが間違っているか全くわかりません。
試行錯誤で乗り切りましょう…。（これはそのうち修正PRを出したいです）

## ワークスペースのディレクトリ構成

ワークスペースのディレクトリ構成として、公式ドキュメントではワークスペース直下に各クレートのディレクトリを配置する方法が書かれています。しかし、普通のクレートディレクトリ内に別クレートのディレクトリを置いて、ワークスペースとすることもできます。
（例えばripgrepはこのパターンです）

前者と後者では`cargo release`したときの挙動が違います。前者は`cargo release`すると全クレートが処理されますが、後者はルートになっているクレートしか処理されません。後者のパターンで全クレート処理したい場合は`cargo release --all`とする必要があります。

# まとめ

ここまでで紹介したworkaroundを適用したプロジェクトが以下になります。具体的な構成例を知りたい方は参考にしてください。

https://github.com/dalance/nom-packrat

cargo releaseのワークスペース対応はまだ出来たばかりなので、ここに挙げた問題点も仕様なのかバグなのかよく分かりません。
おそらくバージョンアップでいろいろ変わると思いますのでご注意下さい。
【web開発 CSS】基本的なwebサイトフレームワーク

webサイトを作る際のフレームワークに毎回時間をかけることがもったいないと感じたのでメモしておく。


![スクリーンショット 2019-07-28 午後3.33.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458915/26b3e847-8de6-763b-1c8c-87aa7c084963.png)

```html:html
<header>
   header
</header>

<main>
   main
   <br> <!--sectionを横並びにするための改行、mainの文字列が邪魔するのでつけただけ-->
   <section class="maincontent">
      main content
   </section>

   <section class="submenu">
      submenu
   </section>
</main>

<footer>
   footer
</footer>
```

```css:css
body{
	margin: 0; /*要素を画面幅いっぱいに表示*/
	min-height: 100vh; /*最低でも画面縦のサイズ*/
}

header{
	height: 100px;
	width: 100%;
	background-color: #696969;
}

main{
	min-height: calc(100vh - 150px); /*headerとfooter以外をmainで占める*/
	width: 100%;
	overflow: hidden; /*はみ出たら非表示(デザインを保つ)*/
	background-color: #b0c4de;
}

footer{
	height: 50px;
	width: 100%;
	background-color: #696969;
}

.maincontent{
	float: left;
	height: 550px;
	width: 80%; /*submenuとの比率*/
	background-color: #778899;
}

.submenu{
	float: right;
	height: 550px;
	width: 20%; /*maincontentとの比率*/
	background-color: #e6e6fa;
}
```
Create React App で SVG をコンポーネントとしてimport して使用する

Create React App を使用している場合、 svgファイルをコンポーネントとして import して使用できるということを今日知ったのでメモしておきます。[公式ドキュメントはこちら](https://facebook.github.io/create-react-app/docs/adding-images-fonts-and-files)になります。

## SVG をコンポーネントとして import

svgファイルから`ReactComponent`をimportする形式を取ることでコンポーネントとして扱えます。

```jsx
import { ReactComponent as Logo } from './logo.svg';
const App = () => (
  <div>
    {/* Logo is an actual React component */}
    <Logo />
  </div>
);
```

## 対応バージョン

`react-scripts@2.0.0`以上かつ、`react@16.3.0`以上の場合に使用可能です。

##参考URL
Create React App documents (https://facebook.github.io/create-react-app/docs/adding-images-fonts-and-files)
Unityメモ：UGUIのドロップダウンメニューに簡単にEnum型を適用する

下記のプログラムでエディタ上から任意のプルダウンメニューに任意の型のEnum型でドロップダウンメニューを組めます。Enum型の中身が5個くらいまでなら手動で入れても良いですけど50個以上とかになると面倒ですよね。

enumNameにはタイプのフルネームを指定する必要があります。
インナーEnum型の場合は「"クラス名+Enum型名"」となるはずですのでご注意ください。

```c#:DropDownEnumSetter.cs
////////////////////////////////////////////////////////////////////////////////
//
// Light Wings GameProject
//
// (C) 2009 Light Wings GameProject.
//
// https://twitter.com/LightWings_gp
// https://twitter.com/sy_game_
//
////////////////////////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DropDownEnumSetter : MonoBehaviour
{
	[SerializeField]
	Dropdown dropDown;

	[SerializeField]
	string enumName;

	void Awake()
	{
		var type = Type.GetType(enumName);
		if (type == null && !type.IsEnum) {
			Debug.LogError("指定のEnum型は存在しません");
			return;
		}

		//EnumをStringの配列に変換
		string[] enumNames = System.Enum.GetNames(type);

		//Stringの配列をリストに変換
		var names = new List<string>(enumNames);

		if(dropDown == null) {
			Debug.LogError("ドロップダウンメニューが存在しません");
			return;
		}

		// 一旦クリア
		dropDown.ClearOptions();

		//DropDownの要素にリストを追加
		dropDown.AddOptions(names);
	}
}

```

```
MIT License

Copyright (c) 2009 Light Wings GameProject.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
Wordを〇す

# はじめに
> Word提出

それはこの世で最も人を不幸にする．

# やりたいこと
漢はLaTeX．Wordなど使わない．
しかし単位を落とすわけにもいかない．
せやっ！PDFを埋め込めばええんや！

# やったこと
`python-docx`と`pdf2image`を使ってPDFを埋め込みます．
コードは下記においてあります．pipenv使えます．
https://github.com/S-aiueo32/kill-docx

(追記) 若干コード修正したのでmasterにあるコードとは別の違う感じになってます．READMEを参照されたし．

## コード
置いてあるコードと順番とかは異なりますが，ざっくりと説明します．

まずは使うものだけインポートします．

```python
from docx import Document
from docx.shared import Mm  # 寸法
from pdf2image import convert_from_path
```

Documentインスタンス生成とマージン&用紙サイズの指定．今回はA4を想定しています．

```python
# Documentのインスタンス
doc = Document()

# セクションごとにマージン&用紙サイズの指定
# 今回は空のDocumentなので1つしかセクションは入ってない
sections = doc.sections
for section in sections:
	section.top_margin = 0
	section.bottom_margin = 0
	section.left_margin = 0
	section.right_margin = 0
	section.page_height = Mm(297)
	section.page_width = Mm(210)
```

Documentにパラグラフを追加して，パラグラフの操作用インスタンスを生成．

```python
p = doc.add_paragraph()	
r = p.add_run()
```

PDFファイルをビットマップ画像に変換して，出力ファイルリストを返却するヘルパーを定義します．

```python
def save_pages(filename):
	pages = convert_from_path(str(src_dir / filename))  # PILイメージのリストを返してくる
	out_files = []
	for i, page in enumerate(pages):
		out_file = src_dir / f'{filename.replace(".pdf", "")}_{i:0>4}.png'
		out_files.append(out_file)
		page.save(out_file)  # 保存
	return out_files
```

ページの画像化と画像の追加．

```python
image_paths = save_pages(args.filename)
	
for image_path in image_paths:
	r.add_picture(str(image_path), height=Mm(297), width=Mm(210))
```

ファイルの保存．終わり．

```python
doc.save('./output.docx')
```

## 結果
こうなる．
![chicken.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274187/1d4ec856-b8fd-ef49-a94b-42e25c4ce185.jpeg)

# まとめ
良い子はマネしないでね．

# Special Thanks
🐓

```
Zongker, Doug. "Chicken chicken chicken: Chicken chicken." Annals of Improbable Research 12 , no. 5 (2006): 16--21.
```
Laravel(5.7) SubmitでのPOST時に配列構造のデータをコントローラで受け取るためのname指定

# 要件
一つのページで1:Nの親子関係にある入力項目がある。
これをsubmitしてサーバ側にPOSTする。ただしNは可変で、1であったり8であったりする。
サーバ側のロジックを簡潔にするために、例えば以下のようなオブジェクトをコントローラ側で取得したい。

```php:post.php
{
    company_name:会社名
    company_sections:[
        {
            section_name:部署１
        },
        {
            section_name:部署２
        },
    ]
}
```

# 解答
以下のようなname指定にしてformで括ってsubmitすればOK。
コントローラの$request->post()で先述のオブジェクトが取得できる。

```html:comp_sect.html
<input type="text" name="company_name" value="会社名"></div>
<input type="text" name="company_sections[0][section_name]" value="部署１"></div>
<input type="text" name="company_sections[1][section_name]" value="部署２"></div>
```
PHPは内部的には配列と連想配列の区別がない（全て連想配列）ので、
company_sections[0]の指定でcompany_sectionsはキー0を持つ。
company_sections[0]のキーsection_nameの値は部署１。
として解釈されるのだろう。
他言語・フレームワークで同じことをするとどうなるかは今の所不明。

# 補足

### バリデーションのかけ方
[Laravel 配列で渡されたリクエストデータにバリデーションをかける](https://qiita.com/kmt/items/27465facc09287ecbb3d)
以下のような指定が可能。

```php
'company_sections.0.section_name' => ''
```

### バリデーションエラーで前画面に戻った際にまとめて前回入力値をセットする
[JS作りました。連想配列のキーと同名のHTML要素が連想配列のvalueを返すようにHTMLを編集する.](https://qiita.com/PlanetBear/items/f3096db7e0a46eeb8d08)
のset-old-input.blade.phpを`@include`すればマッピングされます。

## 配列の数が不明な場合
バリデーションをコントローラー内でループで回すしか無いかなと思っています。
より良い解法があればコメント頂けると助かります。

```php:exampleController.php

$company_data = $request->post();
$company_validator = Validator::make($company_data , ['company_name'=>'required']);
if (!$company_validator ->passes()) {
    return $company_validator;//会社単位でバリデーションをかけて検証NGならこの時点で返す
}
$sections_data = $company_data ['company_sections'];
foreach($sections_data as $section_data){
    $section_validator = Validator::make($section_data, ['section_name'=>'required']);
    if (!$section_validator ->passes()) {
        return $office_validator;//部署単位でバリデーションをかけて検証NGならこの時点で返す
    }
}
```
※まとめてバリデーションを全てにかけてエラーメッセージを結合したいケースが多い気もしますがここでは省略。

# その他同様の問題への解決策

## [【JavaScript】「formをjsonにしてpost」する。](https://qiita.com/hnkyi/items/3f2faf2848cc2de0cf8c)
チェックボックス、ラジオボタンなどの対応などが気にかかったが、サーバー側の挙動に依らない一般的な解決策。
nameが冗長にならないのも利点。
WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる その５

# はじめに
ローカルサイトを表示する上で下記3つのメソッドを使用してみました。

* Loadメソッド
* LoadHtmlメソッド
* LoadStringメソッド

## 前記事
* [WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる](https://qiita.com/yaju/items/97b61d0d8bc3f9ed044d)
* [WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる その２](https://qiita.com/yaju/items/6fc1b72e60dbcc031669)
* [WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる その３](https://qiita.com/yaju/items/b2c64f364efd3e347359)
* [WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる その４](https://qiita.com/yaju/items/58db821778d9f640900b)

# Loadメソッド
```html:HelloWorld.html
<html>
<head>
    <meta charset='utf-8' />
    <title>Hello World</title>
</head>
<body>
    <h1>Hello World!!</h1>
</body>
</html>
```

作成したHTMLを選択し、プロパティで「常にコピーする」に変更します。

```vb
_webBrowser.Load(Application.StartupPath + "\HelloWorld.html")
```

参照：[4.CefSharpを使って、ローカルで動くWebアプリケーションを作る。](https://agrimo.jp/wp/?page_id=19748)

# LoadHtmlメソッド

第2引数のUrlは、指定がない場合はダミーのURLを指定します。

```vb
Dim sb As New StringBuilder()
sb.AppendLine("<html>")
sb.AppendLine("<head>")
sb.AppendLine("<meta charset ='utf-8' />")
sb.AppendLine("<title>Hello World</title>")
sb.AppendLine("</head>")
sb.AppendLine("<body>")
sb.AppendLine("<h1>Hello World!!</h1>")
sb.AppendLine("</body>")
sb.AppendLine("</html>")
_webBrowser.LoadHtml(sb.ToString(), "http://example/")
```

# LoadStringメソッド

第2引数のUrlは、指定がない場合はダミーのURLを指定します。
参照:[CefSharp LoadHtml - stackoverflow](https://stackoverflow.com/questions/27659086/cefsharp-loadhtml)

```vb
Dim sb As New StringBuilder()
sb.AppendLine("<html>")
sb.AppendLine("<head>")
sb.AppendLine("<meta charset ='utf-8' />")
sb.AppendLine("<title>Hello World</title>")
sb.AppendLine("</head>")
sb.AppendLine("<body>")
sb.AppendLine("<h1>Hello World!!</h1>")
sb.AppendLine("</body>")
sb.AppendLine("</html>")
_webBrowser.LoadString(sb.ToString(), "about:")
```

## 問題点
ネット接続が出来ない場合にエラーページを表示したいと思って、`LoadString`メソッドでHTMLの文字列を指定するも真っ白なページのまま表示が出来ないという現象がありました。

## 調査
接続チェックを先にしており、接続出来ない場合はChromiumWebBrowserコンストラクタのURLに空白で指定していました。

```vb
_webBrowser = New ChromiumWebBrowser("")

Private Sub ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItem.Click
        Dim str As String
        str = "<HTML><BODY>Hello Wolrd!</BODY></HTML>"
        _webBrowser.LoadString(str, "about:")
End Sub
```

しかし、ChromiumWebBrowserコンストラクタのURLを空白ではないアドレスを指定すると`Hello Wolrd!`が表示されるようになります。

```vb
_webBrowser = New ChromiumWebBrowser("https://www.google.co.jp/")
```

また、次のようなURL「dummy:」を指定しても`Hello Wolrd!`が表示されるようになりますが、その場合にエラー「ERR_UNKNOWN_URL_SCHEME」になるのでエラーイベントで無視するようにします。
参照：[LoadString() ignoring string_value?](https://magpcss.org/ceforum/viewtopic.php?f=6&t=5901)

```vb
_webBrowser = New ChromiumWebBrowser("dummy:")
AddHandler _webBrowser.LoadError, AddressOf OnLoadError

Private Sub OnLoadError(sender As Object, e As LoadErrorEventArgs)
    If e.FailedUrl = "dummy:" Then Return
End Sub
```

# 最後に
ネット接続が出来ない場合にLoadStringメソッドを使用してエラーページを表示しようとするも真っ白のまま、調べている時間がなく仕方なくエラーページをキャプチャーして画像で表示するというトリッキーな方法でリリースしてしまいました。
その反省を込めて今回調べました。LoadHtmlメソッドがあることに気がつけば良かったな。また改修することがあれば、その時にこの部分も修正してリリースするようにします。
pkg_resources.ContextualVersionConflict: (notebook 5.2.2 (/usr/lib/python3/dist-packages), Requirement.parse('notebook>=5.5.0'), {'rise'})

# pkg_resources.ContextualVersionConflict: (notebook 5.2.2 (/usr/lib/python3/dist-packages), Requirement.parse('notebook>=5.5.0'), {'rise'}) への対処

## なにが起こったか
* jupyterでreveal.jsを使える`RISE`というのがあるらしいので入れて動かしてみようとした
* [最近のRISEは`jupyter-nbextension install rise --py --sys-prefix`をする必要がないらしい](https://rise.readthedocs.io/en/stable/installation.html#disable-and-removal)

> Note:
Before RISE 5.4.2, it was necessary to perform one more step to install the JS and CSS in the proper places with
`jupyter-nbextension install rise --py --sys-prefix`
This is not needed anymore because those resources are installed automatically by the setup.py when you pip install the package.

* jupyterの起動後、スライド用のボタンがないため、色々調べたところ、裏で動いている`jupyter-nbextension install rise --py --sys-prefix`がエラーを吐いているらしい。

## 解決法
**RISEのバージョンを下げる**

```console
$ pip3 uninstall RISE
$ pip3 install RISE==5.4.1
$ sudo jupyter-nbextension install rise --py --sys-prefix
$ sudo jupyter-nbextension enable rise --py --sys-prefix
```

## 余談

* sudoでやらないとpermissionErrorになるのでsudoするとpipでいれたjupyterが動かないのはなんで？
    * aptで入れたjupyterなら動いた
【Rails】日付入力フォームをカレンダー式にしたい（date型, datetime型）

Railsの日付入力をカレンダー式で入力したいと思った(date型)

## 完成イメージ

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/b4ead844-fc03-218b-26a3-48cc1e6b0c75.gif)

## 背景

最初、以下のように **date_select** で書いていたのですが

```erb
<%= form.date_select :sample_at, Date.today %>
```

こんな感じになってなんかイケてなかったので

<img width="200" alt="スクリーンショット 2019-07-29 2.02.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/911bb062-32e8-ee8e-5e8b-5618f9ec84ee.png">

以下に変更

```erb
<%= form.date_field :sample_at %>
```

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/b4ead844-fc03-218b-26a3-48cc1e6b0c75.gif)

## 追記（datetime型の場合はこっち）

```erb
<%= form.datetime_field :sample_at %>
```

![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F94029%2F7970cef9-d87b-d078-2c18-ecb6ab853a47.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=42e022d602c27d2880fab53f66ad9243)

参考
https://qiita.com/yatakan/items/3a359b2beef28fedb3c5
https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-date_field
https://qiita.com/pyon_kiti_jp/items/747496d02bdb1eff1ce8