OmniAICreator/Qiita-1.07M huggingface dataset:
Docker + BEAR.Sundayで開発するときはdocker-syncを使おう

# この記事について
BEAR.Sundayは依存関係などをコンパイルして保存するようになっています。

普段はこのおかげで高速に動作するのですが、

Docker for Mac はFILEのIOが遅く、Sundayのコンパイル結果を保存する処理、結果から読み戻す処理が致命的に時間がかかります。

開発効率をあげるために、どういう設定で利用するのが知りたかったため、各種方法を試し、計測結果をまとめた記事です。

# docker-syncについて

コードをホストとコンテナ間で高速に同期させるためのツール

同期方法もrsyncやunisonなどが選択可能

## インストール
```
gem install docker-sync
brew install eugenmayer/dockersync/unox
brew install fswatch unison rsync
```

## run & stop
```
### run
docker-sync start
docker-compose up

### stop
docker-compose stop
docker-sync stop
```

## 設定ファイル
```
version: "2"
syncs:
  sync-volume:
    src: './'
    sync_strategy: 'unison'
    sync_excludes: ['.idea']
```
```
version: '3'

services:
  app:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    expose:
      - '9000'
    volumes:
      - sync-volume:/var/www/html/:z

  web:
    build: docker/nginx/
    ports:
      - '1758:80'
    volumes:
      - ./public:/var/www/html/public:cached
    links:
      - app

volumes:
  sync-volume:
    external: true
```

詳細は[リポジトリ](https://github.com/gamu1012/Container.Sunday)をご確認ください。

# キャッシュオプションについて
## cached
ホストの更新についてコンテナ反映時の遅延を許可する。

## delegated
コンテナ内の更新についてホスト反映時の遅延を許可する。

[詳細はこちら](https://docs.docker.com/docker-for-mac/osxfs-caching/)

# 計測方法
nginx + php-fpm のコンテナ環境でスケルトンからインストールした直後のBEAR.Sundayで行う。

実際に計測した設定などは[こちらのリポジトリ](https://github.com/gamu1012/Container.Sunday)をご確認ください。

計測種別は4パターン

- volume mountのオプションなし
- volume mountのcachedオプションあり
- volume mountのdelegatedオプションあり
- unisonを利用したdocker-sync

処理にかかった時間の計測は実際の開発環境においての速度を測りたいため、nginxのrequest_timeとupstream_response_timeで行う。

# 結果

|計測種別|request_time(s)|upstream_response_time(s)|
|:-----|:-----|:-----|
| オプションなし |6.015|6.013|
| cached     |2.850|2.849|
| delegated  |2.945|2.943|
| docker-sync|0.290|0.288|

# まとめ

今回の条件だと圧倒的に docker-sync がはやかったです。

実際のプロジェクトでも試していますが、docker-sync がはやく、特に不便な点はありません。

少しだけインストールの手間はありますが、その価値は十分にあります。

またそれぞれの環境やどういうModuleを実装しているかによって結果は違うかと思いますので、是非お手元で計測してみてください。

# 参考リンク
[Performance tuning for volume mounts (shared filesystems)](https://docs.docker.com/docker-for-mac/osxfs-caching/)
[docker-sync](https://docker-sync.readthedocs.io/en/latest/index.html)
[計測したコード](https://github.com/gamu1012/Container.Sunday)
最低限やっておいたほうがいい構造化マークアップ

# 概要
構造化マークアップでGoogle検索してもらった時にサイトをもっと目立たせましょう。
最低限は Product と パンくずリストです。
この２つは作成すると１週間ほどで反映されます。
他は、かなり頑張って作ってもGoogleさんに反映してもらえないことが多いです。

## Product 商品 `(最低限)`
![スクリーンショット 2019-12-13 15.50.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/d8178b41-1ec6-5f97-f0b7-c76e013d4554.png)

・評価（★マークで点数表示）
・価格（金額があれば記載）
・在庫あり/なしも表示できる


https://developers.google.com/search/docs/data-types/product?hl=ja

## Breadcrumbs パンくずリスト `(最低限)`

![スクリーンショット 2019-12-13 17.08.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/7f7857e3-2437-cd2d-48a5-7b2e12df34ed.png)

英語のURLが表示されちゃうときは、パンくずリストで日本語に変更することができます。

https://developers.google.com/search/docs/data-types/breadcrumb?hl=ja

## NewsArticle ニュース `(サイトによっては重要)`
![スクリーンショット 2019-12-13 15.50.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/e86775cc-f6fa-440f-8a3c-2ec3a9a69791.png)

更新頻度が高いサイトには是非オススメ。
記事を投稿しているサイトならGoogle検索した時に表示される可能性も高いです。
AMPと組み合わせると更に良い。

## Recipe (レシピ)`(料理レシピサイト以外は使わない)`
![スクリーンショット 2019-12-13 15.50.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/2d9ed830-ba0a-ad62-adb3-c5b872950be1.png)

レシピサイトにはオススメしますが、レシピは料理系サイト以外では使わないほうが良いかと思います。
設定も大変。


## アプリインストール`(反映されないことが多い)`

![スクリーンショット 2019-12-13 17.30.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/a18ccfe0-b01b-6ac0-2fbb-1abe5b95fa06.png)

サイト内にアプリへのリンクが有るとそこから拾ってくる様子。
`manifest.json` 内に `applications` を記載するとヒントにしてくれるかも。
https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/manifest.json

## Book 書籍　`(大規模の電子書籍サイトのみ)`
作品名で検索するとGoogleの書籍というタブで表示されることがある。
表示されるためには  `必ず申請が必要` 
https://developers.google.com/search/docs/data-types/book?hl=ja
![スクリーンショット 2019-12-13 17.40.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/4651a51b-1572-168f-8b36-48bf55109a42.png)

## カルーセル`(反映されないことが多い)`
![スクリーンショット 2019-12-13 17.41.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/74650cd8-ba00-136f-b1c1-b516e76ce157.png)

## Googleでの投稿
![スクリーンショット 2019-12-13 17.44.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/2d9fbfe2-4643-4805-065d-cf88d489187b.png)
ローカルビジネスを運用していると出ることがある。マークアップではないが地道な運用が効果的なこともある。

# 反映された？
構造化マークアップを作成したら反映されたかをSearch Consoleで確認しましょう。
![スクリーンショット 2019-12-13 17.45.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40127/ae0495df-c395-03d4-4233-7d44eac6ac14.png)

# 構造化マークアップの効果
構造化マークアップを頑張ってもサイトへの誘導は大きな効果は期待しづらいところもあります。
というのも構造化マークアップを充実させてもGoogleさんに表示してもらえないことの方が多いです。
時間があれば充実させていく。という気持ちでやっていきましょう。
【Mac】コピーした文章を翻訳してポップアップしてくれるスクリプト

英語の勉強のため英論文を読むが、何よりもテンポ感が大切。

時にはGoogle翻訳様に頼ることで、睡魔に打ち勝つ。

その際、いちいちコピペするよりは、コピーのみで翻訳結果をポップアップ表示してくれたら便利。

ということで作ってみました。
(動作するアプリを選べるようにしたので、関係ないアプリでポップアップが出てイライラすることもない←地味に大切)

## こんな感じの動き
![スクリーンショット 2019-12-13 17.24.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392425/46219fa2-1fbf-32e9-27ec-61b6145357a7.png)
↓↓↓↓↓↓↓↓↓↓↓↓↓[Cmd+c]↓↓↓↓↓↓↓↓↓↓↓↓↓
![スクリーンショット 2019-12-13 17.23.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392425/6615b020-9b53-b396-852b-2208874f0bca.png)
やった!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

## 手元の環境
- macOS Catalina 10.15.1
- Python 3.7.4

## 必要なパケ
~~~bash
pip install pyperclip
pip install googletrans
~~~

## 実装
~~~python3:translator.py
import os
import time
import pyperclip
from googletrans import Translator
from AppKit import NSWorkspace

# アクティブウィンドウ取得用
workspace=NSWorkspace.sharedWorkspace()

log, sentence = None, None
while True:
    # クリップボードが更新されると抜ける
    while sentence is None or sentence == log:
        time.sleep(0.1)

        # クリップボード取得
        sentence = pyperclip.paste()

        # 放置するとNoneになるので回避
        if sentence is None:
            continue

        # 初期起動時にはポップアップしない
        if log is None:
            log = sentence
            continue

        # ちょっとした整形 (不要なら消してもいい。)
        sentence = sentence.replace("\n"," ")
        sentence = sentence.replace("- ","")

    log = sentence

    # アクティブウィンドウを取得+フィルタ
    appname=workspace.activeApplication()["NSApplicationName"]
    if appname not in ["プレビュー"]:
        continue

    # google翻訳
    translated = Translator().translate(sentence,src = "en" ,dest = "ja").text

    # 翻訳結果をアラート表示
    os.system("osascript -e 'display dialog \"{}\"'".format(translated))
~~~

## 実行
基本動かしっぱなし。

~~~bash
python3 translator.py
~~~

## ちょっとした解説

### pyperclip
クリップボードを取得できます。

~~~python3
import pyperclip
sentence = pyperclip.paste()
~~~

### googletrans
google翻訳のAPIを叩いてくれるパッケージ。
srcに元の言語、destに翻訳先の言語を入れれば、英和訳以外にも使えます。

~~~python3
from googletrans import Translator
translated = Translator().translate(sentence,src = "en" ,dest = "ja").text
~~~

### AppKit NSWorkspace
現在のアクティブウィンドウ名を取得できます。
これで翻訳を動作させるアプリを選択。
プレビュー以外で動作させたい場合は、とりあえず`appname`を表示してみるべし。

~~~python3
from AppKit import NSWorkspace
workspace=NSWorkspace.sharedWorkspace()
# アクティブウィンドウを取得+フィルタ
appname=workspace.activeApplication()["NSApplicationName"]
# アクティブウィンドウ取得用
if appname not in ["プレビュー"]:
    continue
~~~

### クリップボード監視
キー入力監視まですればベターかもしれないけれど、とりあえず0.1秒ごとにクリップボードを監視する形で乗り切った。
(バックグラウンドで動くキー監視用のpython3パッケージあったら教えてください。。。)

~~~python3
#クリップボードが更新されると抜ける
# クリップボードが更新されると抜ける
while sentence is None or sentence == log:
    time.sleep(0.1)

    # クリップボード取得
    sentence = pyperclip.paste()

    # 放置するとNoneになるので回避
    if sentence is None:
        continue

    # ちょっとした整形 (不要なら消してもいい。)
    sentence = sentence.replace("\n"," ")
    sentence = sentence.replace("- ","")
log = sentence
~~~

### ポップアップ通知
色々試した結果、`AppleScript`経由に落ち着いた。
os.systemを使って、コマンドラインに投げるとポップアップしてくれます。
いと便利あはれたてまつる。

~~~python3
os.system("osascript -e 'display dialog \"{}\"'".format(translated))
~~~

## 最後に
超便利。。。
人としてどんどんダメになっていく気がする。。。
VS2019でC#でコンソールアプリをはじめて作る

C#でコンソールアプリを作ろうとする・・・

すると、一見すると

 .net framework と .net core でコンソールアプリどちらでも作れそうな・・・

また調べようとすると、見つからないか、分かりにくい、で時間を取らるのも馬鹿馬鹿しい。

使えればいいのだ。


調べればわかる、だけではなく、即効性ですぐにやりたい。プログラム以外に別件でやりたいことはたくさんある。

で、検索方法を頭から考え直す。

チュートリアルを探せばいいだけだ。

あった。
https://docs.microsoft.com/ja-jp/visualstudio/get-started/csharp/tutorial-console?view=vs-2019

.net core を使えばいいようだ。

VisualStudio 2010 のC#ではとかではそういうモードがなかったような？

まあ YAGNIベースで考えよう


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/20f4b0db-08d5-ff12-efbd-f082a9639ffe.png)

あああ？C#の新規作成のつもりが、F#になってる？
目が悪いのか？

確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/3901f9ef-0353-09a7-cdbd-21fea601f156.png)
F#になっている、なんか操作ミスしていたようだ。ところで前からF#あるけど、使っている人を聞いたことがない。
Qiitaは画像の貼り付けが簡単でいい！いや～楽だ！貼り付け利便性の良さはすばらしい！

とりあえず、再挑戦とミスの確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/ed8ec444-423d-02e5-72fd-7fa12cde9eb7.png)

F#はメニューに無かったが、マウスがずれてLinuxになったか、まちがえてコンソールを選んだか、どちらかだろう。いやそんなことはない。カーソルがまとまったこれ一択なので違う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/05fd48f6-e47d-01e4-711f-e9d0d1a5d1aa.png)

うまくいっているようにみえるが、とりあえず作成ボタンを押す

ソースが自動的に出来上がっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/dac6be09-6f88-5992-9f19-75e8fbdea77b.png)

まだ安心できない・・・ビルド実行だ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/7be24c1b-4388-de81-9319-38f53cc54e15.png)

#  Hello World！

うまくいった。2010,2012,2013 でC#を使った時より若干分かりにくくなったような

そういえばUnityで2015も使っていたか・・・忘れてた


なぜはじめにやったときF#のプロジェクト作成になったか？
全く同じ操作をしたつもりだったし謎すぎる？？？？
Laravelでリサイズした画像をdropboxにアップロードする

#はじめに
iPhoneで撮った写真をDropboxにアップロードする機能を導入する際に、無料で使える容量が2Gしかなかったのでサイズを小さくしてアップロードしようとしたけど詰まったので備忘録としてやり方を載せておきます。
#環境・事前準備
- Laravel 6.0
- Dropboxアカウント

#Dropbox接続手順
composerでDropboxを操作するためのライブラリをインストール。

```
composer require benjamincrozat/laravel-dropbox-driver
```
```config/app.php
'providers' => [
    BC\Laravel\DropboxDriver\ServiceProvider::class,
],
```
```filesystems.php
'disk' => [
     'dropbox' => [
         'driver' => 'dropbox',
         'token' => env('DROPBOX_TOKEN'),
     ],
```
dropboxのaccessTokenを環境変数にセット。

```..env
DROPBOX_TOKEN=accessToken
```
#Intervention Image導入手順
画像をリサイズするためにパッケージをcomposerでインストール

```
php aritsan require intervention/image
```
```config/app.php
'providers' => [
    Intervention\Image\ImageServiceProvider::class,
],

'alianses' => [
    'Image' => Intervention\Image\Facades\Image::class,
],
```
#画像アップロード処理
```Controllers/HelloController.php
//画像のリサイズとアップロードするために下記2つを追加
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;

public function store(Request $request)
{
     //アップロードされたリクエストの中に画像があるかチェック
     if($request->hasFile('image')){
         $file = $request->file('image');
         $imgName = $file->getClientOriginalName();
         //画像リサイズ処理（横幅を1200pxに指定）
         $image = Image::make($file)
               ->resize(1200,null,function($constraint{
                    $constraint->aspectRatio();//aspectRatio、縦幅アスペクト比維持で自動調整
                });   
         //putメソッドの第一引数にパスを指定（下記のコードではdropboxデベロッパーで設定したフォルダ直下に保存される）
         Storage::disk('dropbox')->put($imgName,(string)$image->encode('jpg',100),'public');
        }
      
        return view('Hello');
    }
```
#おしまい
AWS s3がアカウント認証でこけたので今回Dropboxを使うことにしました！
エンジニアとしてまだ未熟なので間違っているところがあればコメントいただけると助かります！
Thymeleafでヘッダーフッターを共通化する方法

# 概要
Spring BootとThymeleafを使って作るWebアプリで、各htmlのページに共通しているヘッダーやフッターを共通化する方法

## 環境
- Java8
- Spring Boot
 - version: 2.1.9.RELEASE
- Thymeleaf
 - version: 3.0.11.RELEASE
- Eclipse
 - version: 2018-09 (4.9.0)

# サンプル
## ディレクトリ構成
Java側は省略しますが、templateと静的コンテンツの配置はこんな感じ。

```plaintext:dir
src/main/resources
├── static
│   ├── css
│   │   ├── common.css
│   │   └── top.css
│   └── js
│       └── datepicker.js
└── templates
    ├── common.html
    └── index.html
```
SpringBootは`templates`配下のHTMLからCSSやJSファイルを参照する場合、
`static`がルートディレクトリになるので、このような構成にしてます。

## 共通部品用のcommon.htmlを作成する

```html:common.html
<html xmlns:th="http://www.thymeleaf.org">
<!-- (1)共通にしたいheadをfragment化する -->
<head th:fragment="meta_header(title,links,scripts)">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <!-- (2)共通で読み込むCSS/JS -->
    <link rel="stylesheet" href="/css/common.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <!-- (3)タイトルのフォーマット -->
    <title th:text="${title}+' | sample app'">各ページタイトル | sample app</title>

    <!-- (4)各View固有で読み込むもの -->
    <th:block th:replace="${links} ?: _" />
    <th:block th:replace="${scripts} ?: _" />
</head>
<body>
    <!-- (5)body内で共通化したい部品をfragment化する -->
    <header th:fragment="header">
        <h1><a th:href="@{'/'}">sample app</a></h1>
    </header>
</body>
</html>
```
### 解説
(1) fragment名は引数を取れるので`title,links,scripts`を引数に設定する
(2) 各ページで共通に読み込むCSS/JSを記載する
(3) 引数のtitleを使って`th:text=""`にページタイトルのフォーマットを設定する
(4) 各ページで読み込むCSS/JSを`th:replace`を使って差し込む
処理なしトークン(`?: _`)を使うことで、`${links}`がnullだった場合は`th:block`自体が無かったものになる
(5) body内でも共通化したいものがあったら`th:fragment`を使って部品化する

## 各html側で呼び出す
```html:index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!-- (1)共通headerで置き換える -->
<head th:replace="common :: meta_header('top',~{::link},~{::script})">
    <!-- (2)このページ固有で読み込むCSS/JS -->
    <link rel="stylesheet" th:href="@{/css/top.css}" />
    <script type="text/javascript" th:src="@{/js/datepicker.js}"></script>
</head>
<body>
    <!-- (3)共通部品を呼び出す -->
    <div th:replace="common :: header"></div>
    <h2>top page</h2>
</body>
```
### 解説
(1) `header`を`common.html`で定義したものに引数を渡して置き換える
(2) このページ(このサンプルでは`index.html`)固有で読み込むファイルを定義する
(3) 共通部品も`th:replace="ページ名::fragment名"`で置き換える

# 参考
[Spring Bootでヘッダ・フッタの共通化する方法](https://www.saka-en.com/java/spring-boot-thymeleaf-header-footer/)
[Tutorial: Using Thymeleaf](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html)
Notionでデータベースを作る


[アルプ株式会社](https://thealp.co.jp/)でエンジニアをしています、集約のエンティティ@pictinyです。
これは[Notion Advent Calendar 2019](https://qiita.com/advent-calendar/2019/notion) 13日目のエントリです。
12日目は[NotionでSQLを管理する](https://qiita.com/pictiny/items/51a52c976e15430414d4)でした。

# データベース
Notionの最重要機能の一つがデータベースです。
[Notion Advent Calender 2019](https://qiita.com/advent-calendar/2019/notion) 1日目の[プロジェクト管理やドキュメンテーションにNotionを使おう](https://qiita.com/pictiny/items/1f442697bac06bde0205)の例で紹介した開発バックログもデータベースを使っています。

<img width="1180" alt="プロジェクト管理" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/5ed9d939-933c-7860-10d4-98bc544314d0.png">

## 作り方

ページを作成したときに表示されるDATABASEの項目から作ることができます。
**スラッシュコマンド**の`/database`でも作ることができます。

<img width="621" alt="データベース1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/63c57c25-82ef-5438-829a-64fe47e88a27.png">

## プロパティ
データベースのデータが持つ項目のことを**プロパティ**といいます。
表計算アプリケーションのカラムに相当します。

<img width="735" alt="データベース2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/be97bb86-c7bb-0479-473a-1c38b20ef5d6.png">

この例では

- Assign
- Status
- 対象チーム
- Story Point
- 締切

が**プロパティ**です。

## View
データベースは表示を切り替えることができ、この機能を**View**といいます。
現在は5種類の表示方法があります。

- [Tables](https://www.notion.so/Tables-66a1cce8fb6f4f64b9996f4146c51fad)
- [Boards](https://www.notion.so/Boards-50c5758a474b4cca96e7f8cdf4b2bd8f)
- [Lists](https://www.notion.so/Lists-f66c8f11f79a4844a9ca414fee992aba)
- [Calendars](https://www.notion.so/Calendars-c00c23c26e31471496b540583e1b8c47)
- [Galleries](https://www.notion.so/Galleries-91ff852bc42b4d26bd1e8d7b568844d2)

データベースの左上から、データベースに対して**View**を追加することができます。

<img width="310" alt="View追加" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/8e69651a-e617-72ae-cb68-a423e9a4594f.png">

**View**は表示方法を切り替えるだけではなく、表示プロパティなどの設定も持っています。

<img width="313" alt="プロパティ項目" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/9140a0ce-d6a2-3f62-8477-8a0e90e1aecd.png">

目的に応じた表示設定の**View**を作っておけば、目的に合わせて切り替えられるのでとっても便利です。

# まとめ
Notionの真髄であるデータベースの基本的な機能について紹介をしました。
データベースを使いこなせれば、これまでEXCELやGoogle Spreadsheetsを使っていた業務のほとんどをNotionでできるようになります。
EXCELなどの表計算アプリケーションと比較したときの弱点は、グラフで描画する機能がないことと、集計に弱いことでしょうか。
しかしViewによる表示の柔軟さは、EXCELなどにはない強力な機能ではないかと思います。

データベース導入のドキュメントは[Intro to databases](https://www.notion.so/Intro-to-databases-fd8cd2d212f74c50954c11086d85997e)にありますので、そちらもご覧ください。
Pugでルート相対パスを使うにはbasedirオプションでルートを指定する

Pugをgulpでコンパイルする想定です。

## ディレクトリ構成
```
root/
  ├ dest/
  │  └ index.html
  ├ src/
  │  ├ _include/
  │  │  ├ _header.pug
  │  │  └ _footer.pug
  │  └ index.pug
  └ gulpfile.js
```

## タスクを書く
pugのところに`basedir`オプションを指定します。値はルートにしたいディレクトリへのパスです。今回は`src`へのパスにします。

```js:gulpfile.js
const { src, dest } = require('gulp')
const pug = require('gulp-pug')
const path = require('path')

const pugCompile = () => (
  src('./src/**/!(_)*.pug')
  .pipe(pug({
    basedir: path.resolve(__dirname, 'src')
  }))
  .pipe(dest('./dest/'))
)

exports.default = pugCompile
```

## Pugを書いてみる
```:_header.pug
header
  h1 header.
```
```:_footer.pug
footer
  p footer.
```
```:index.pug
doctype html
html(lang='ja')
  head
    title document
  body
    include /_include/_header.pug
    include /_include/_footer.pug
```

コンパイルすると、以下のようなHTMLが出力されます。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>document</title>
</head>
<body>
  <header>
    <h1>header.</h1>
  </header>
  <footer>
    <p>footer.</p>
  </footer>
</body>
</html>
```
Flutter生活4日目~Dartでズンドコキヨシ！~

## おさらい
Flutterの用語やフォルダ構成など、Flutter生活をエンジョイするための知識を少しだけ身につけました。
しかしこのふんわり感ではまだまだ検証に入ることができません！！
今日はひとまずDartという言語を知ってみたいと思います。

## 題材
もちろんズンドコキヨシです。

> ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ！」って出力した後終了

([ズンドコキヨシまとめ](https://qiita.com/shunsugai@github/items/971a15461de29563bf90))

## やってみた

こんな感じです。
処理の内容は特に解説する必要とかないですね！完成！

``` ZunDokoKiyoshi.dart
import 'dart:math';

main(List<String> args) {

  List<String> zunDokoStack = new List<String>();

  final rand = new Random();
  while(zunDokoStack.join() != "ズンズンズンズンドコ") {
    String value = "";
    if (rand.nextInt(2) == 0) {
      value = "ズン";
    } else {
      value = "ドコ";
    }

    zunDokoStack.add(value);

    if (zunDokoStack.length > 5) {
      zunDokoStack.removeAt(0);
    }
    print(value);
  }
  print("キ・ヨ・シ！");
}
```

## もっとやってみた
ここで終わってはつまらないですよね。
色々なパーツに分けてみましょう！

まずは「ズン」と「ドコ」をenumで定義してみます。

``` ZunDokoKiyoshi.dart
enum ZunDoko {
  Zun,
  Doko
}
```

Dartのenumはとても機能が乏しく、文字列を定義して返すことができないようです。
しかも、Classのinnerに定義することができません。

仕方がないので、enumをいい感じにしてくれるHelperクラスを作ってみました。
これでenumを好きな文字列にできます。(みなさんこの辺はどうやってるんですかね？詳しい人教えてください。)

``` ZunDokoKiyoshi.dart
class ZundokoHelper {
  static String getStringValue(ZunDoko zundoko) {
    switch(zundoko) {
      case ZunDoko.Zun:
        return "ズン";
      case ZunDoko.Doko:
        return "ドコ";
    }
  }
}
```

次はベタが記されている色々な処理をClassを用意して突っ込んでいきます。
Viewで業務ロジックしたくないですしね！

``` ZunDokoKiyoshi.dart
class ZunDokoKiyoshiModel {

  String getRandomZundokoString() {
    final rand = new Random();
    return ZundokoHelper.getStringValue(ZunDoko.values[rand.nextInt(ZunDoko.values.length)]);
  }

  String successMessage() {
    return "キ・ヨ・シ！";
  }

  bool isZunDokoKiyoshi(List<String> stack) {
    return stack.join() == expectedZunDokoKiyoshi().join();
  }

  List<String> expectedZunDokoKiyoshi() {
    List<String> expected = List<String>();
    expected.add(ZundokoHelper.getStringValue(ZunDoko.Zun));
    expected.add(ZundokoHelper.getStringValue(ZunDoko.Zun));
    expected.add(ZundokoHelper.getStringValue(ZunDoko.Zun));
    expected.add(ZundokoHelper.getStringValue(ZunDoko.Zun));
    expected.add(ZundokoHelper.getStringValue(ZunDoko.Doko));
    return expected;
  }
}
```

main処理を書き換えれば完成！
かなりそれっぽくなりました！

``` ZunDokoKiyoshi.dart
import 'dart:math';

main(List<String> args) {

  ZunDokoKiyoshiModel zunDokoKiyoshi = ZunDokoKiyoshiModel();

  List<String> zunDokoStack = new List<String>();

  while(!zunDokoKiyoshi.isZunDokoKiyoshi(zunDokoStack)) {
    String value = zunDokoKiyoshi.getRandomZundokoString();
    zunDokoStack.add(value);
    if (zunDokoStack.length > zunDokoKiyoshi.expectedZunDokoKiyoshi().length) {
      zunDokoStack.removeAt(0);
    }
    print(value);
  }
  print(zunDokoKiyoshi.successMessage());
}
```

全体的にJavaの書き方によく似ていますし、かといって古すぎずに良いですね！
Flutterが流行る理由がわかった気がします！
Python A問題対策（Atcorder）

#きっかけ
インターン先でPythonを用いた機械学習をする業務が増えたので、C++だけでなくAtcorderでPython3でも解けるように慣れていきたい！
ホントにPythonしらない（笑）

#map関数、split関数
https://atcoder.jp/contests/abc147/tasks/abc147_a

```python

a,b,c=map(int,input().split())

if a+b+c>=22:
    print("bust")
else:
    print("win")

#入力条件　3 4 7(空白を挟んで数値を代入している点に注目！)
```
**map関数...複数値を入力するときに使われる！**
**split関数...何を基準に分けるか**

#文字列扱い
https://atcoder.jp/contests/abc070/tasks/abc070_a

```python
N=input() 
#int(input())と書かないことで、文字列（配列）となり、文字指定できる！
if N[0]==N[2]:
    print("Yes")
else:
    print("No")
```

# and, orの使い方
https://atcoder.jp/contests/abc067/tasks/abc067_a

```py
A,B=map(int,input().split())

if((A+B)%3==0 or A%3==0 or B%3==0):
    print("Possible")
else:
    print("Impossible")
```
**C++とPythonの対応...&& == and , || == or**

#改行の扱い方


```py
N=int(input())
print(2*N)#改行している
```
**改行したくない場合**

```py
N=int(input())
print(2*N,end="")#改行してない
```

#型名取得

```python
r,g,b=map(int,input().split())
ans=r*100+g*10+b
print(type(ans))

#出力結果
#>>> <class 'int'>
```

**type関数を使えば一目瞭然!**

#まとめ
大体この4問を解いていれば、C++の経験があるとPythonでも全部解ける感じがする。次回はB問題からPythonの知識を埋めていこうと思う。
UniVRMでOVRLipSyncが使えない (OVRLipSyncのダウングレードで解決)

特定バージョンでOVRLipSyncが動作しない問題に遭遇したのでメモ。
2019/12/13 時点、当該問題に遭遇している人を見つけられなかったので記事に残しておきます。

##環境
- Unity 2018.4.11 Windows64bit
- UniVRM 0.53.0
- OVRLipSync 1.42.0

##原因
OVRLipSyncの変更によるもの。
1.30.0にダウングレードしてLipSync復活。

- [Oculus Lipsync Unity 1.30.0](https://developer.oculus.com/downloads/package/oculus-lipsync-unity/1.30.0/)

VRMでのOVRLipSyncは坪倉さんの下記のスクリプトを使用させていただきました。

- [TsubokuLab/VRMLipSyncContextMorphTarget](https://github.com/TsubokuLab/VRMLipSyncContextMorphTarget)

##参考リンク・謝辞
- [【アーカイブ】VRMモデルをOVRLipSyncに対応させる方法](https://qiita.com/Nekomasu/items/104808f7ecd26f1e362a)
- [ようてんさんのツイート (OVRLipSyncのScriptExecutionOrder設定)](https://twitter.com/youten_redo/status/984598867336282112)
- @sh_akira さんありがとうございます！！
React　まとめ①

#Reactを自分なりにまとめてみた①

初めての投稿です。
Reactの復習用メモとして残します。

まず前提としてReactはJavascriptのライブラリなので、Javascriptの最低限の理解が必要というのは言うまでもないことなのですが、他の言語をやったことがある方でしたら、入りやすいのかなと思います。

Javascriptを完璧にやってからReactをやるというのも良いと思いますが、ES6の記法をさらってReactを触り始めてもいいんじゃないかなって思います。

ここで重要なのは、分かんないのはJavascriptなのかReactなのかを明確にする必要があるということです。

最初ということでJSXについての記述がほとんどになりますのでご存知のかたは②にお進み下さい。

```jsx
const element = <h1>Hello, world!</h1>;
```

この構文はJSXと呼ばれるJavascriptの拡張構文です。
ReactではこのJSXを多用します。



```jsx
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
ReactDOM.render(
  element,
  document.getElementById('root')
);
```

constでnameを宣言して、中括弧に囲んでJSX内で使用しています。
PHPで言うところの
$name = “Josh Perez”;
のようなものですが、Javascriptにはlet,const,varが存在しているので差異は理解する必要があります。

```jsx
const element = <div tabIndex="0"></div>;
```


文字列リテラルを属性として指定するために引用符を使用できます。
JSXではキャメルケースのプロパティ命名規則を使用します。
キャメルケースとは、アルファベットで複合語やフレーズを表記する際、各単語や要素語の先頭の文字を大文字で表記する手法のことです。
例えばtabindexはtabIndexとなります。



```jsx
const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;
```


RectDOMはJSXに埋め込まれた値をレンダリングされる前にエスケープするので、
ユーザーの入力したあらゆるコードが注入できないことが保証されています。
PHPで言うところのhtmlspecialchars（）のようなものが、JSXでは担保されているということでしょうか。
BitbucketのprivateリポジトリをGitHubへ移行(import)する方法

# はじめに
基本的にはポチッとするだけですが、Bitbucketのログインが「Googleでログインする」を利用していて、ログインIDとパスワードを利用していない場合に少し分かりづらいと感じたので手順を残しておきます。
２要素認証などの場合も同じ手順でいける気がします（未検証）

# 移行手順
## 事前準備
移行時に利用する**Bitbucketの**ログインIDとパスワードを用意しておきます。
こちらはBitbucket上での作業です。

### ログインID
**設定＞アカウント設定画面**(https://bitbucket.org/account/user/<ユーザー名>/)に書いてあるユーザー名です。メールアドレスではありません。

### パスワード
**設定＞アプリパスワード**の「アプリパスワードの作成」からread権限のついたパスワードを作成。不安なので一通りread権限がついたパスワードを作成しました。このパスワードをメモっておく。

## 移行
ここからGitHub上での作業です。

- [移行画面](https://github.com/new/import)で移行するリポジトリのURL、新しいリポジトリの情報を入力して「Begin import」を押す
<img width="787" alt="スクリーンショット 2019-12-13 16.58.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22205/12b65320-96aa-6bde-dcec-1eeae45095b3.png">

- 少し待つとログインIDとパスワードを求められるので、事前準備で用意したログインIDとパスワードを入力する
<img width="550" alt="スクリーンショット 2019-12-13 17.05.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22205/b5c742e1-50f9-a3de-2bf5-c8db3cda16cc.png">


autocompleteが有効だとGitHubの情報が入っている場合があるが、
「Your old project requires credentials for read-only access.」
とあるように求められているのは移行前のリポジトリの情報なので、
BitbucketのIDとパスワードが必要。

問題なければ、これで完了です。

# おまけ
progressがおしゃれ
<img width="658" alt="スクリーンショット 2019-12-13 17.10.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22205/4792f0cf-8afc-c4f9-8c47-5de1c3c15082.png">
Android端末から開発PCに向けてポート転送を行う

本記事は、[サムザップ Advent Calendar 2019 #2](https://qiita.com/advent-calendar/2019/sumzap2) の12/13の記事です。
昨日は @kazuhiro1128 さんの [Next.js + FirebaseAuthでサインイン機能を実装してみた](https://qiita.com/kazuhiro1128/items/4fb6c5162116615bd045) でした。

本日はAndroid端末での実機デバッグで役立つコマンドと、その使用例をご紹介したいと思います。

## adb reverseコマンド
`adb reverse`コマンドは端末からPCへのポート転送を行うコマンドです。

この逆、PCから端末へポート転送する`adb forward`コマンドは、
UnityのProfilerを繋ぐために使うのでよく知られているのではないでしょうか。

私はこのコマンドを、

* PCでProxyサーバを立てて、通信内容を確認したり書き換えてデバッグする
* PCでWebページをホスティングして、端末での動作を確認しつつ内容を編集する

と活用しています。

## 使用例
### サーバの準備
まずPCで動かすサーバアプリケーションを用意します。
言語は何でもいいですが、簡単に記述できるのでgoを選びました。

ローカルホストのポート`8080`番を待ち受けて、固定の文字列を返すAPIとファイル配信機能のある単純なサーバアプリケーションです。
説明の簡略化のためにエラーハンドリングは省いています。

```go
package main

import "net/http"

func main() {
	http.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok"))
	})
	http.Handle("/resource/", http.StripPrefix("/resource/", http.FileServer(http.Dir("./resource/"))))

	http.ListenAndServe("127.0.0.1:8080", nil)
}
```

ディレクトリ構成は下記のようにしました、スクリプト以外にクライアントへ渡すための画像ファイルも配置しています。

```
.
├── main.go
└── resource
    └── red.png
```

### クライアントの準備
クライアントにはUnityを使用して、こちらも動作に必要な最低限のコードを用意します。　　

ボタンが2つと、通信の結果を確認するためTextとRawImageを持つ単純な構成です。
接続先アドレスは`127.0.0.1`を、ポートは`8080`番を指定しています。

```csharp
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class MainBehaviour : MonoBehaviour
{
    [SerializeField] private Button _callApiButton;
    [SerializeField] private Button _getResourceButton;
    [SerializeField] private Text _text;
    [SerializeField] private RawImage _image;

    private void Awake() {
        _callApiButton.onClick.AddListener(() => StartCoroutine(CallApi()));
        _getResourceButton.onClick.AddListener(() => StartCoroutine(GetResource()));
    }

    public IEnumerator CallApi() {
        using (var request = UnityWebRequest.Get("http://127.0.0.1:8080/api/")) {
            yield return request.SendWebRequest();
            _text.text = request.downloadHandler.text;
        }
    }

    public IEnumerator GetResource() {
        using (var request = UnityWebRequestTexture.GetTexture("http://127.0.0.1:8080/resource/red.png")) {
            yield return request.SendWebRequest();
            _image.texture = DownloadHandlerTexture.GetContent(request);
        }
    }
}
```

### 接続準備
端末をUSBケーブルでPCに接続して、開発者オプションとUSBデバッグをONにします。
`adb devices`コマンドで端末がアタッチされていることを確認したら、`adb reverse`コマンドを実行してみましょう。
このときローカル、リモート共に`tcp`で、ポートは`8080`を指定します。

```sh
$ adb reverse tcp:8080 tcp:8080
```

転送設定が有効化できたか、コマンドの`--list`オプションで確かめてみます。

```sh
$ adb reverse --list
(reverse) tcp:8080 tcp:8080
```

ここまで確認できましたら、PCでサーバを立ち上げて、端末でビルドしたクライアントを動かします。

### 結果
こちらは実機で動作しているのをキャプチャしたものになります。
各ボタンの押下で通信が走り、結果がTextとRawImageに反映されているのが分かると思います。
![action.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201332/8eb5c69f-626a-05db-73b1-5f11f9497893.gif)


### まとめ
以上、`adb reverse`コマンドのご紹介でした。
用途は限定的ですが、ローカルPCと端末との間で通信を完結できる点が便利だと思います。

明日は、@kojima_akira さんの記事です。
Fast JSON API の Serializer で定義したキーから任意のキーを指定して使う



### 概要
Ruby 向け JSON:API シリアライザー である Fast JSON API を使用して json を生成する際に、Serializer で定義したキーのうち一部のものだけ指定して使いたいときの話。


### 前提

以下のような Serializer が定義されているとする。

```rb
class PostSerializer
  include FastJsonapi::ObjectSerializer

  belongs_to :user
  attributes :title, :content, :created_at
end
```

```rb
class UserSerializer
  include FastJsonapi::ObjectSerializer

  atrributes :name, :birth_date
end
```

### 手順
上記の Serializer を使って json を生成する処理は以下の通り。

```rb
@posts = Post.all
PostSerializer.new(@posts, { include: %i(user) })
```

このままだと Selializer で定義したキーがすべて使われる。

```json
{
  "data": [
    {
      "id": "1",
      "type": "post",
      "attributes": {
        "title": "post 1",
        "content": "hogehogehoge",
        "created_at": "2019-12-13T15:00:00.000+09:00"
      },
      "relationships": {
        "user": {
          "data": {
            "id": "1",
            "type": "user"
          }
        }
      },
      {
      "id": "2",
      "type": "post",
      "attributes": {
        "title": "post 2",
        "content": "hogehogehoge",
        "created_at": "2019-12-13T15:00:00.000+09:00"
      },
      "relationships": {
        "user": {
          "data": {
            "id": "2",
            "type": "user"
          }
        }
      }
  ],
  "included": [
    {
      "id": "1",
      "type": "user",
      "attributes": {
        "name": "Alice",
        "birth_date": "2019-12-01"
      }
    },
    {
      "id": "2",
      "type": "user",
      "attributes": {
        "name": "Bob",
        "birth_date": "2019-12-02"
      }
    }
  ]
}
```

ただ、これが色々な箇所から呼び出されるようになると、一部のキーだけ使いたいということが出てくる。
そこで、`options` (`Serializer.new` の第2引数) に `fileds` というキーワードで必要な要素を指定する。
アソシエーション先のモデルを include している場合、そちらも指定する必要がある（下の例で言うと user）ので注意。

```rb
@posts = Post.all
options = {
  include: %i(user),
  fields: {
    post: %i(title user)
    user: %i(name)
  }
}
PostSerializer.new(@posts, options)
```

上のように `fileds` を使ってキーを指定してみると

```json
{
  "data": [
    {
      "id": "1",
      "type": "post",
      "attributes": {
        "title": "post 1"
      },
      "relationships": {
        "user": {
          "data": {
            "id": "1",
            "type": "user"
          }
        }
      },
      {
      "id": "2",
      "type": "post",
      "attributes": {
        "title": "post 2"
      },
      "relationships": {
        "user": {
          "data": {
            "id": "2",
            "type": "user"
          }
        }
      }
  ],
  "included": [
    {
      "id": "1",
      "type": "user",
      "attributes": {
        "name": "Alice"
      }
    },
    {
      "id": "2",
      "type": "user",
      "attributes": {
        "name": "Bob"
      }
    }
  ]
}
```

といったように出力される要素を制御することができる。

### 参考
https://github.com/Netflix/fast_jsonapi#sparse-fieldsets
プログラムを悪用してメールを100件送るプログラムを書いてみる

**※これはいかにプログラムを簡単に悪用できるかの例を示したものであってサイバー犯罪を推進する記事ではございません。よろしくお願いします。**
##作業開始

```python:itazura.py

  1import smtplib
  2 from email.mime.text import MIMEText
  3
  4 for i in range(100):
  5 #ヤフーメールからメールを送信する関数
  6     def send_mail(co_msg):
  7         SMTP_SERVER = "smtp.mail.yahoo.co.jp"
  8         SMTP_PORT = 587
  9         SMTP_USERNAME = "test@yahoo.co.jp"#自分のユーザーネームor登録アドレス
 10         SMTP_PASSWORD = "test"#自分のパスワード
 11         EMAIL_FROM ="test@yahoo.co.jp"#自分も送信元メールアドレス
 12         EMAIL_TO = "oya@icloud.com"#送信先メールアドレス
 13         EMAIL_SUBJECT = "pythontest"#題名
 14         msg = MIMEText(co_msg)
 15         msg['Subject'] = EMAIL_SUBJECT
 16         msg['From'] = EMAIL_FROM
 17         msg['To'] = EMAIL_TO
 18         mail=smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
 19         mail.login(SMTP_USERNAME, SMTP_PASSWORD)
 20         mail.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string())
 21         mail.quit()
 22         return
 23
 24
 25     #関数の実行
 26     text='俺の勝ち！なんで負けたか明日までに考えといてください。'
 28     send_mail(co_msg=text)
~
```

以上です。4行目に回数のがあるので調整してください。次にヤフーメールの設定です。
##YAHOO側の設定
![スクリーンショット 2019-12-13 16.51.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534096/0907494e-0380-f125-3fac-343b48e2addf.png)

このようにしてください。プログラムを実行すると、その送信先にメールが100件きます。きます。**いきます。絶対に悪用しないでください。**
PHPの生みの親、ラスマス氏のインタビューの紹介

空いてたので・・・。

私の好きなインタビューです。

PHPの生みの親，ラスマス・ラードフ氏インタビュー
https://gihyo.jp/news/report/2015/12/1401

PHPをやって、なぜ、implodeとexplodeの引数の順番が違うのか、
array_mapとarray_filterの引数の順番が違うのか、
<?phpはなんで閉じちゃいけないんだとか、
この統一性のない言語に疑問を持った人も、このインタビューを読めば、
そんなことはどうでもいいと思えます。

私はもっとよいハンマーを使いたいですが、
でもすごく共感できる考え方です。

もう一つ、好きなインタビューです。

Linuxの背後にある精神
http://www.aoky.net/articles/linus_torvalds/the_mind_behind_linux.htm

何が面白いかといえば、
日頃お世話になっているLinuxの世界本部が見られることです。
でもセンスのいいプログラムはかけません・・・

ただのインタビューの紹介でした。
Rubyの変数の定義(クラス変数)

## Rubyの変数の定義について、今回はクラス変数
前回までに[ローカル変数](https://qiita.com/nyan_tech_24/items/bf52e294e86910d23570)と[インスタンス変数](https://qiita.com/nyan_tech_24/items/7bd5bb0bd5e092dbb778)について書きました。

そして今回はクラス変数について書こうと思います。

## 命名規則
- 先頭は@@をつける
- 変数の構成は英数字と_が使える

```ruby
@@student = 'Taro'
warning: class variable access from toplevel  ##なぜかwarningが出る
=> "Taro"
@@_STUDENT_2 = 'Jiro'
=> "Jiro"
@@1_STUDENT_3 = 'Sabu'  #@@のすぐ後ろに数字は定義できない
SyntaxError:`@@1' is not allowed as a class variable name

@@student5  #クラス変数に何も値を代入しないとエラーになる
NameError: uninitialized class variable @@student5 in Object

class Students
  puts @@student  
end
Taro
```
ちなみに
warning: class variable access from toplevel
が毎回でるのはなんででしょうか？？
これはObjectクラスに直下書きはよくないよってことらしいです。
詳しくはまた後日まとめます。

##スコープ
そのクラスの全インスタンスから参照することができる

```ruby
class Students
  @@student = 'Taro'
  def greet
    puts "Hi,#{@@student}"
  end
end
a = Students.new
a.greet
Hi,Taro
=> nil
```
となります。
クラス変数はインスタンスメソッド外部で定義されているクラス変数を、インスタンスメソッド内で参照できる。

ではインスタンス変数で同様なコードで検証してみる。

```ruby
class Students
  @student = 'Taro'
  def greet
    puts "Hi,#{@student}"
  end
end
a = Students.new
a.greet
Hi,
=> nil
```
@studentがnilになっている。
インスタンスの外で定義されているので参照できないというのがインスタンス変数との違いです。

また他にもクラス変数を使うと

```ruby
class Students
  @@student = 'Taro'
  def greet  
    puts "Hi,#{@@student}"
  end
  def replace=(name)
    @@student = name 
  end
end
class MedicalStudents < Students
end

a = Students.new
a.greet
Hi,Taro
=> nil
a.replace = 'Jiro'
a.greet
Hi,Jiro
=> nil

#さならにここからが面白い

b =  MedicalStudents.new
b.greet
b.replace = 'Hanako'
b.greet
Hi,Hanako
=> nil
a.greet
Hi,Hanako
=> nil
```
というかんじで何故か全くちがくインスタンスや親クラスを操作できてしまいまいます。

一見便利ですが、例えばユーザーを作成するときは1つ１つインスタンスを作成してデータを管理する場合、クラス変数で定義するとインスタンスを作成するごとにすべてのインスタンスに変更を加えるので危険ですね。

とうわけでクラス変数のまとめでした。

ちなみにRuby技術者認定試験のシルバーではこのあたりが狙われるので注意ですね！！
なぜ我々はネコに癒しを求めるのだろうか？ 

この記事は、[MAヒーローズ・リーグ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/heroesleague)の19日目の記事になります。

# はじめに
こんにちは、ひで (@blue_islands)です。
毎年、この時期になるとヒーローたちは燃え尽き、傷つき、灰になる現象の「**MAロス**」に陥ります。
そんなヒーローたちのために傷のいやし方を毎年模索して、現在に至りますが、今年の傷のいやし方、ネコについて綴っておきます。

# ネコと癒し
ネコと癒しの関係を調べているとこんな記事に遭遇しました。

 * [猫様すげぇ！人間にとって猫が必要な25の理由](http://karapaia.com/archives/52168115.html)

ネコってすごいですね。
癒しどころか、健康、魅力アップなんでもござれのスペシャルな関係がわかります。

# ネコの住みやすい場所
そんなネコ達に逢いに行くためにどんなところがネコにとって、住みやすい場所なのかを調べてみました。

* [路地裏とねこと人の素敵な関係]
(https://note.com/livlog_llc/n/n2da482b72446)

路地裏が地元の人にとって過ごしやすいということは、ねこにとっても居心地がよく、人と人、人とねこのコミュニティが作られているのがわかります。

# ネコの住みやすい路地裏を機械学習で発見する
では、ネコの住みやすい路地裏はどこに存在するか？
そこを機械学習で特定したいと思います。

キーワードは「路地裏」と「昔ながらの町並み≒ノスタルジー」と定義して、**路地裏度**と**ノスタルジー度**を算出していきます。

## 1. 路地裏度
路地裏のデータの土台として、「**[国土数値情報　道路密度・道路延長メッシュデータ](http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N04.html)**」を利用します。
![FireShot Capture 008 - 国土数値情報　道路密度・道路延長メッシュデータの詳細 - nlftp.mlit.go.jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/25acbd00-65cc-b71c-958d-bd6e2e8adf8e.png)

こちらのデータから「幅員3.0m(2.5m)未満」と「幅員未調査」の項目の合計値を対象に抽出して「路地裏度」算出をします。
※ちなみにこちらのデータ加工については割愛しますが、ファイル数とかファイル圧縮とかデータフォーマットとか中々の曲者で、利用する場合は大変な苦労があることをお知らせします。

## 2. ノスタルジー度
ノスタルジー度の算出には二つのデータを利用しています。

* [国土交通省土地総合情報システム（不動産取引価格情報取得API）](https://www.land.mlit.go.jp/webland/api.html)

![FireShot Capture 009 - API操作説明　｜　国土交通省　土地総合情報システム - www.land.mlit.go.jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/83d172d1-d9d7-46e9-fa04-fe9bc9e6a1b6.png)

* [RESAS API（人口構成）](https://opendata.resas-portal.go.jp/)
![FireShot Capture 010 - RESAS-API - 地域経済分析システム（RESAS）のAPI提供情報 - opendata.resas-portal.go.jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/3869653b-43ae-c5f1-248a-0d196184fb69.png)


不動産取引価格情報取得APIを使って、取引情報を取得して、周りの平均築年数を算出する。
人口構成から人口増減を計算して、人口減の地域を特定する。
この二つの値を合算してノスタルジー度とする。
※むつかしい計算とかはあまりしていないのですが、絶対的な道路判定の母数が多いため、実行するとそれなりに時間はかかります。

そして、出来上がった「**[ネコの住みやすい場所マップ](https://haoshima.carto.com/builder/320fb1e6-ad8a-41d4-9fed-448c426a0a23/embed)**」
![FireShot Capture 011 - ねこの住みやすい場所 - haoshima.carto.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/ea13f986-bbbd-aed5-a7f1-b11daf1abebe.png)

# 最後に

細かいことは、ネコの住みやすい場所マップを見ればわかると思いますが、昔栄えていた城下町とか、漁村的な感じのところとか、いい感じの場所が抽出されていますので、こちらのデータを使って作った「**[ロジねこ](https://rojine.co/)**」を使ってネコ探しの旅に出かけてみてください。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ネコを見つけるために作ったサービス！ <a href="https://twitter.com/blue_islands/status/1205391345092681729?ref_src=twsrc%5Etfw">2019年12月13日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
docker(102) RESAS-API をdockerで

Ruby + RESAS-API で観光資源の位置情報(緯度経度)を取得する
https://qiita.com/niwasawa/items/608bbac1fbef3e086210

```shell-session:macOS
$ docker run -v /Users/administrator/Downloads/ruby:/tmp/ruby -p 8080:8080 -it ruby /bin/bash
```

```docker:ubuntu
# apt update; apt -y upgrade
# apt install -y vim wget apt-utils sudo
# vi resas.rb
# ruby resas.rb
{"statusCode"=>"403", "message"=>"Forbidden.", "description"=>""}
Traceback (most recent call last):
resas.rb:34:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)
```


市区町村一覧
https://opendata.resas-portal.go.jp/docs/api/v1/cities.html

GET  api/v1/cities


| 都道府県 | 市町村 | 支庁市郡 | 区町村 | ふりがな | 変更 |
|:--|:--|:--|:--|:--|:--|:--|:--|:--|
| 23 | 100 |    名古屋市 |   | なごやし |   |   | 政令指定都市 |
| 23 | 101 |   千種区 | ちくさく |
| 23 | 102 |    東区 | ひがしく |
| 23 | 103 |    北区 | きたく |
| 23 | 104 |    西区 | にしく |
| 23 | 105 |    中村区 | なかむらく |
| 23 | 106 |    中区 | なかく |
| 23 | 107 |    昭和区 | しょうわく |
| 23 | 108 |    瑞穂区 | みずほく |
| 23 | 109 |    熱田区 | あつたく |
| 23 | 110 |    中川区 | なかがわく |
| 23 | 111 |    港区 | みなとく |
| 23 | 112 |    南区 | みなみく |
| 23 | 113 |    守山区 | もりやまく |
| 23 | 114 |    緑区 | みどりく |
| 23 | 115 |    名東区 | めいとうく | 1975.0201 | 分離 | ←千種区，昭和区 |
| 23 | 116 |    天白区 | てんぱくく | 1975.0201 | 分離 | ←昭和区 |

```shell-session
require 'net/http'
require 'uri'
require 'json'

def get(url, params, headers)

  if params != nil && !params.empty?
    url += '?' + URI.encode_www_form(params)
  end

  uri = URI.parse(url)

  https = Net::HTTP.new(uri.host, uri.port)
  https.use_ssl = true

  req = Net::HTTP::Get.new(uri.request_uri, headers)
  res = https.request(req)

  json = res.body
  return JSON.parse(json)

end

url = 'https://opendata.resas-portal.go.jp/api/v1/tourism/attractions'
params = {
  'prefCode' => '23',
  'cityCode' => '100',
}
headers = {
  'X-API-KEY' => 'id'
}
data = get(url, params, headers)
puts data
data['result']['data'].each do |v|
  puts "#{v['resourceName']}: #{v['lat']},#{v['lng']}"
end
```


```shell-session
# ruby resas.rb
400
Traceback (most recent call last):
resas.rb:34:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)
```

docker hubに保存

```
docker run -v /Users/administrator/Downloads/ruby:/tmp/ruby -p 8080:8080 -it kaizenjapan/ruby_resas /bin/bash
```

# 文書履歴(document history)
ver. 0.01 初稿 20191213
ver. 0.02 加筆 20191214
ver. 0.03 標題加筆 20200101
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
SQS,SNS,SESの用語を整理しよう

#正確に用語を覚えよう
こんにちは．
AWSには似ている用語がたくさんあって，何がなんだかわからなくなりませんか？

とりあえずSが先頭につくものはシンプルです．
EはElasiticです．


ややこしいな．全く．
いちいち先頭につけるからわからなくなる．


特に，SNSなんてわかりそうな単語!!
って思ったら
私たちの知ってるTwitterやFacebookのSNSとは全然意味が違う！！

っていうパターンもありますしね．

それでは，一つ一つ説明していきましょう!

##SQS
![queue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/99e59a88-db8b-92e8-83c0-62bbb980d739.png)

**Simple Queue Service**
キューだけ覚えましょう．
###キューのおさらい
キューとスタックって勉強しましたか？
溜め込んだものを取り出す操作なんですが，
キューは穴あきの箱に，
スタックは底ありの箱に溜め込む
と覚えましょう．

今回はキューなので，![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/3c30cda2-296f-1ab0-0520-3f49e1d7977a.png)

穴あきの溜め込み操作です．

##SQSのお仕事
SQSはメッセージのやりとりを非同期で行うサービスです．
非同期は，レスポンスを待たずにクライアント処理を行ってくれるものでしたね！

DBに書き込むのに時間がかかる場合なんかが，
SQSに溜め込んで，Dequeueをすることで通信速度の遅延を防ぐことが出来ます．

キューには2種類あって，
標準キューとFirst In First Out キューがあります．
標準キューは早い順
First In First Out は順番通り
に処理が行われます．

##SNS
**Simple Notification Service **
![sns.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/747ec123-32e3-2bec-1f02-010aa82b6c58.png)
Notification と言うことで通知です．
図のようなサービスに通知させます．

Cloud Watch/SES/S3/Elastic Tramscoderと連携して通知をさせるのが一般的な使い方です．

##SNSの用語を押さえておこう
SNSには初耳な用語が関わってきます．
まずはそれらの定義から．

**パブリッシャ** ... メッセージ送信者のこと サービスの管理者など
**サブスクライバ** ... メッセージ受信者　メールやsms,httpなど(チャネル)．
**トピック** ... 複数のサブスクライバをまとめたもの．

###SNSの使い方
1. パブリッシャがトピックを作成
2. トピックからサブスクライバを登録->urlやメアドをここで登録
3. パブリッシャがトピックに向けてメッセージをパブリッシュすると，選択したチャネルでメッセージ送信!!


##SES
**Simple Email Service**
メールサービスです．
僕は従来はsendgridというサービスを使っていたのですが，
![sendgrid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/4ce3c8a6-4409-0667-a1cb-40b27aad41d1.png)

sesも同様にAPIもあるみたいで，AWSでメールサービスも完結．

顧客に対して，サービスの状況をメールで自動で送ってくれます．
また，受信したメールトリガーにしてSNSと連携なども出来てしまいます．

メールサービスでよくある，
1. HTTP REST API
2. Simple Mail Transfer Protocol(SMTP)


という2つの利用方法があります．


1は言語によってAPI経由で呼び起こします．(コードにapiを使って書き込む)
どの言語にも対応しているので，言語SDKから選択すればテンプレ通りに簡単に埋め込めます！

2はサーバーポートでSMTPリクエストを受け付けます．
手動で書き込むタイプ．

自動化するなら1でしょう.
てか，実用するなら迷わず1でしょう．

##SWF
**Simple Workflow Service**
タスク(ひとかたまりの処理)の管理とワークフローの管理を行う為のサービス．
すなわち，AWSが提供するジョブ管理システム．

###何ができるの?
例えば，jsでコーディングをする場合．
jsでは非同期で処理を行っていますが，
戻り値が欲しい時はpromiseやコールバックを使って同期的に処理を行う時などがあります．

そのような，
同期/非同期タスクを一連のフローとして設計し，対象障害性を高めることが可能になります．



このようにシンプルから始まるこんがらがりやすい単語をまとめておきました．
AWSのより深いサービスを使うには，これらの用語を覚えていないと，
わけがわからなくなるので，メモとして使ってみてくださいませ．
TypescriptでExact（完全一致）を実現する方法

型が完全一致しないとエラーにする方法です。
そこで、以下のような`Exact`というGenericを定義して使います。

```typescript
type Exact<T, R> = T extends R
  ? R extends T
    ? T
    : never
  : never

type Base = {
  b: number
}

type Derived = Base & {
  d: number
}

function baseFunc(base: Base) {}
function exactBaseFunc<T = Base>(b: Exact<T, Base>) {}

const base: Base = { b: 1 }
const derived: Derived = { b: 1, d: 2 }

baseFunc(base)          // ok
baseFunc(derived)       // ok
exactBaseFunc(base)     // ok
exactBaseFunc(derived)  // error
```

補足ですが、派生の型に基本の型を入れるとエラーになります。

```typescript
function derivedFunc(derived: Derived) {}
derivedFunc(base)       // error
derivedFunc(derived)    // ok
```

APIやストレージなど、特定のプロパティしか保存したくないという時にこのようにしておくと型でエラーが出るので安心。
Xcodeの再インストール

# Xcodeを完全に削除する

```
sudo rm -rf /Applications/Xcode.app
sudo rm -rf /Library/Preferences/com.apple.dt.Xcode.plist
sudo rm -rf ~/Library/Preferences/com.apple.dt.Xcode.plist
sudo rm -rf ~/Library/Caches/com.apple.dt.Xcode
sudo rm -rf ~/Library/Application Support/Xcode
sudo rm -rf ~/Library/Developer/Xcode
sudo rm -rf ~/Library/Developer/CoreSimulator
```

# Xcodeをインストール

下記のURLからダウンロード
https://developer.apple.com/download/

<img width="1440" alt="スクリーンショット 2019-12-13 16.40.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/d958f240-c1cd-1999-7d75-19c1f82b070d.png">


参考
https://qiita.com/UJIPOID/items/015805c89bddca540129
https://qiita.com/TAByasu/items/47c6cfbeeafad39eda07
Mavenのローカルリポジトリを確認する



mavenはリモートリポジトリからダウンロードしたライブラリをローカルリポジトリに保存する。
ローカルリポジトリのパスは、設定ファイル"conf/settings.xml"内に"localRepository"で指定する。
この"localRepository"が未定義の場合はデフォルト値を適用する。
（Windowsの場合は"C:\Users\{ログインユーザー名}\.m2\repository"）
また、次のコマンドでもローカルリポジトリのパスを確認出来る。

```shell:
　　mvn help:evaluate -Dexpression=settings.localRepository
```
intra-martで簡易的なjavascript実行ページを作ってみる

#はじめに
javascriptをちょっと書いて確認したいなーと思うことがありますが、エディタでプログラム書いて保存してブラウザで表示して確認…というのも面倒だと感じてしまいます。
そういうわけで、画面上で簡単なコードを書いて実行できるようなものをintra-martのローコード開発（FormaDesigner）で作ってみようかと。

#作り方
FormaDesignerでテキストエリアとボタンを配置します。
![q01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322795/6b353a87-f265-500b-8c1d-ccd7e6ab1684.png)

実行ボタンをクリックしたら、テキストエリアの内容をJavaScript コードとして評価します。
![q02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322795/6b5c61dd-d16a-8b85-67ae-b05e30135007.png)

FormaDesignerに配置した画面項目の値を取得する方法は、以下に記載されています。
https://www.intra-mart.jp/document/library/bis/public/bis_specification/texts/spec/csjs_script.html


こんな感じで画面を作成したら、javascriptの簡易実行画面ができます。
![q03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322795/fd534ea1-9bde-73dd-5b81-d732d42f6a9e.png)

#おわりに
今回作成したのは単純に書いたコードを動かすだけでしたが、コードのほかに件名欄を追加して画面に登録ボタンを配置して内容保存できるようにしてあげると、javascriptのサンプルコード集のようなものを手軽に用意することも可能です。

ローコード開発ツールを利用すると、簡単な画面はパパッと作れていいですね。
16インチMacbookProの辞書.appで英和辞典が使えない時の対処法

# 問題

辞書.app（Dictionary.app）の環境設定において、以下のキャプチャのように「ウィズダム英和辞典 / ウィズダム和英辞典」が選べない。選べたとしても「何も見つかりませんでした」または「No entries found」と表示される。同様の現象が日本語以外でも報告されている：[リンク](https://discussions.apple.com/thread/250861549?answerId=251679363022#251679363022)

![Screen Shot 2019-12-13 at 16.05.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149738/9d2585ca-d767-4a8b-a528-13d721edb810.png)


# 解決策

以下のディレクトリ

```
/System/Library/AssetsV2/PreinstalledAssetsV2/InstallWithOs/com_apple_MobileAsset_DictionaryServices_dictionaryOSX/
```

のどこかに「Sanseido The WISDOM English-Japanese Japanese-English Dictionary.dictionary」がある。私の場合は

```
/System/Library/AssetsV2/PreinstalledAssetsV2/InstallWithOs/com_apple_MobileAsset_DictionaryServices_dictionaryOSX/a27242716aafc5bee8a3c7290fb4c1cec87ed5fd.asset/AssetData/Sanseido The WISDOM English-Japanese Japanese-English Dictionary.dictionary
```

にあった。これを適当な場所にコピーし、リネームして（例えば Wisdom.dictionary）、以下の場所にコピーする。

```
/Users/<username>/Library/Dictionaries/WISDOM.dictionary
```

すると以下のように、環境設定の一番下にウィズダム英和辞典が現れ選択できるようになる。

![Screen Shot 2019-12-13 at 16.12.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149738/20b9e327-110a-8785-fc73-7148d86e80b7.png)