OmniAICreator/Qiita-1.07M huggingface dataset:
非エンジニアがAR Kitを触ってみた【入門その1】

これはGeek Women Japan Advent Calendar 2017 8日目の記事です。
<a href="https://qiita.com/advent-calendar/2017/geekwomenjapan">GeekWomenJapan Advent Calendar 2017</a>


非エンジニアが、AR開発を勉強してみようと、まずはiOS11から公開されたARKitのサンプルプログラムをビルドしてみましたので手順を公開します。

##前提
筆者：プログラミング超超入門レベル、職種はなんちゃって事業開発担当。

仕事でVR/ARに携わっており、市場規模やグローバルのマーケットトレンドについてのリサーチなんかをさせていただくことが多いのですが、今年はiOS11に「ARKit」が搭載されARが一気に来ましたよね！
超初心者ですがAR開発も勉強してみようプロジェクトです。本記事はあくまで【入門その1】なので、これがいつまで続いてどこまでできるようになるかは期待せず見守ってください。

##準備
###Xcodeのインストール
iOSアプリを開発するためにはXcodeが必要です。
AppStoreからバージョン9.2(2017/12最新版)をインストールします。

###AppleIDの取得
Xcodeを開き、Preference>Account＞左下の+ボタンから自分のAppleIDを登録しておきます。
<img width="300" alt="Screen Shot 2017-12-08 at 15.30.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/c0ba82b7-14bd-7495-3843-63c6c0cb515e.png">

###ARkitのダウンロード
こちらの<a href="https://developer.apple.com/arkit/">ARKit紹介ページ</a>よりARKitのサンプルコードをダウンロード。
<img width="300" alt="Screen Shot 2017-12-08 at 15.40.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/3ad05259-1701-bc79-0c85-0370108e8813.png">

ダウンロードしたzipを解凍する。

##実践
解凍したzip内のARKitBasics.xcodeprojを、Xcodeで開きます。
<img width="300" alt="Screen Shot 2017-12-08 at 15.47.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/e0670463-becc-66f3-c709-ac4bb2e0d549.png">


画面はこんな感じ。Generalタブから、Signing項目にあるAutomatically manage signingのチェックをONに、Teamの項目で自分の名前(Personal Team)を選択します。

Build Phasesタブを選択し、Link Binary With Libraries項目にある＋ボタンを選択すると選べるframeworkの一覧が表示されるので、
<img width="300" alt="Screen Shot 2017-12-08 at 15.51.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/5213104b-7e88-ca51-dfd2-da3542c8992e.png">

ARKit.frameworkを選択し追加。
<img width="300" alt="Screen Shot 2017-12-08 at 15.51.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/1bd4ff5e-ad9f-768d-a328-0308dd3cdbac.png">


iOS11のデバイスをmacに接続し、実行ボタンよりプログラムを実行するとデバイスにプロジェクトがインストールされます。
<img width="300" alt="Screen Shot 2017-12-08 at 15.54.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/e46ffb30-eb04-ecff-1ea5-c63dd60b1b18.png">


<img width="347" alt="Screen Shot 2017-12-08 at 19.52.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/623fd431-6a67-dc44-e853-7a91fbb7757e.png">

入ったー:girl_tone2:
<img width="286" alt="Screen Shot 2017-12-08 at 19.52.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/180725ca-b59f-da54-e717-59407dcaabd8.png">

目の前のテーブルも
<img width="268" alt="Screen Shot 2017-12-08 at 19.52.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/123515/a954f46e-e39b-6472-3473-fd46d5e351e8.png">
お隣の方のテーブルもちゃんと認識されました。（隣の人にiPhone向けながらスクショ撮ってて怪しまれました）

ここからいろいろ試していきたい気持ち。
カメラが映すものを低解像度に設定する

レンダーテクスチャーを設定して表示物の解像度を落とす機能。
処理負荷軽減に使ったり、むやみに解像度が高い端末の負荷が上がるのを制御したりするために使う。（iPadやAndroid）
カメラにコンポーネントを設定するだけでＯＫ。

http://wordpress.notargs.com/blog/blog/2016/10/03/unityたった1個のスクリプトだけで画面解像度を下げ/
※これをカスタムしました

▼こんな感じ
![8b9a1da1-e58e-63c6-76b3-4b73fd7e2c12.gif](https://qiita-image-store.s3.amazonaws.com/0/184294/151da50f-90d4-f2c6-22bc-02210c0c51dd.gif)

```C#:LowResolutionCamera.cs
using UnityEngine;
using UnityEngine.Rendering;

/// <summary>
/// カメラが映すものを低解像度に設定できるようにするコンポーネント
/// </summary>
[RequireComponent(typeof(Camera))]
public class LowResolutionCamera : MonoBehaviour {
	/// <summary>
	/// デフォルト解像度
	/// </summary>
	private readonly Vector2 RESOLUTION = new Vector2(750, 1334);

	/// <summary>
	/// 解像度係数
	/// </summary>
	[SerializeField, Range(0.1f, 1)]
	private float _resolutionWeight = 1f;

	private float _currentResolutionWeight = 1f;

	private RenderTexture _renderTexture;
	private Camera _camera;
	private Camera _subCamera;

	private void Start() {
		SetResolution(_resolutionWeight);
	}

	/// <summary>
	/// 解像度を設定
	/// </summary>
	public void SetResolution(float resolutionWeight) {
		_resolutionWeight = resolutionWeight;
		_currentResolutionWeight = resolutionWeight;

		// 指定解像度に合わせたレンダーテクスチャーを作成
		_renderTexture = new RenderTexture(
			width: (int)(RESOLUTION.x * _currentResolutionWeight),
			height: (int)(RESOLUTION.y * _currentResolutionWeight),
			depth: 24
		);
		_renderTexture.useMipMap = false;
		_renderTexture.filterMode = FilterMode.Point;
		// カメラのレンダーテクスチャーを設定
		if (_camera == null) {
			_camera = GetComponent<Camera>();
		}
		_camera.targetTexture = _renderTexture;

		// レンダーテクスチャーを表示するサブカメラを設定
		if (_subCamera == null) {
			GameObject cameraObject = new GameObject("SubCamera");
			_subCamera = cameraObject.AddComponent<Camera>();
			_subCamera.cullingMask = 0;
			_subCamera.transform.parent = transform;
		}
		CommandBuffer commandBuffer = new CommandBuffer();
		commandBuffer.Blit((RenderTargetIdentifier)_renderTexture, BuiltinRenderTextureType.CameraTarget);
		_subCamera.AddCommandBuffer(CameraEvent.AfterEverything, commandBuffer);
	}

	private void Update() {
		if (_currentResolutionWeight == _resolutionWeight) return;
		// _resolutionWeightの値が更新された時だけ解像度変更処理を呼ぶ
		// Inspector上で_resolutionWeightを操作するとき用の処理
		SetResolution(_resolutionWeight);
	}
}
```

・Inspector上で調整できるようにしているが、リリース時には無駄なのでifdefで囲んだり、消したりを推奨
・クラス内で定義しているRESOLUTIONも、ゲーム内のいろんなところで使うので、共通の定数用のクラスに外だししたほうが良い
・Auto Orientation（端末を傾けて画面向き変更）を対応させるときもRenderTextureの解像度変更しないといけない
とある昔あったカードゲームを作った話

# とある昔あったカードゲームを作った話

## そもそも
会社で合宿に行かせていただいたんですが、その中に**記事を書く**という縛りがございまして、、、

やるネタは初めから決めてたんですけど、マジでどうやって記事にしようかと超悩んでおりました。。。

かといって合宿でやることを、記事を書くからって理由で変えるのはなしだなーと思って合宿は**とあること**を決行いたしました。

結果こんな記事を投稿するわけですｗ

~~こんなの会社のアドベントカレンダーで書いていいんだろうか。しかもクリスマスイブ~~

## その結果がこちらです。。。!

![表裏加工.png](https://qiita-image-store.s3.amazonaws.com/0/54588/12cf6be3-fe42-3e93-cf60-174a79936c4d.png)

![P表裏加工.png](https://qiita-image-store.s3.amazonaws.com/0/54588/4873dc2f-63a4-436e-a58a-3a3fa2c2392a.png)

はい、わかる人には何のゲームか一発でわかりますね。。。

（問題があったら言ってください。即消します。。。

ちなみに名前とか消してるのはとあるゲームのキャラクターとか使ってるからです。。。

(なので写真ももちろん実際はゲームの絵です。。。）

一応このカードCSSで頑張ってます。
~~だからなんなのか~~

## 他に何やってんの

カードがガチャで引けたり、スタメンを作ったり、自動でいい感じのスタメンが組まれたり、スキルを張ったりできます。

この某ゲームにおいて、試合はまったくをもってどうでもよくて、カードが引けることとスタメンが組めることが楽しみだったので、そこだけ作りました。

**つまり、スタメンは組めるけど、実際に試合とかは全然やりませんｗ**

別に目新しい技術とか、自分にとって初めて触る技術とかは一切なくいつも通りCakePHPとjQueryで**かなり**適当に書いています。

(技術的には何も語るべきことはないｗ）


## 最後に
コード見たいという超奇特な人がいたら見てもいいけど、、、きれいに書くとか人に見せるとか全く考えてないので、、、うん・・・

・

・

・

・

・

・

・

・

・

・


https://github.com/satthi/pawapuro-league

(名前見てわかる通り、このシステム元々は某野球ゲーム(隠れてないけど）のリーグ戦を管理するシステムDEATH)

コードはくそったれだけど、罵らないでNE☆
あと問題があったらマジで言ってください。。。即消します。。。
Visual Studio | WPF > UI > タブインデックスを割当てる実装 (code behind)

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
```

Tabキーを押したときの切替わり順番は、XAMLにおいてTabIndexを指定することでできるようだ。
[Control.TabIndex プロパティ](https://msdn.microsoft.com/ja-jp/library/system.windows.controls.control.tabindex(v=vs.110).aspx)

しかしながら、コントロールの数が多くなったときに、他のプロパティも記載されている中でTabIndexをXAML内に書くのはメンテナンス性が悪い。

code behindでTabIndexを割当ててみる。

### code

```MainWindow.xaml
<Window x:Class="_171208_t1930_tabIndex.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_171208_t1930_tabIndex"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Name="Button1" Content="Button1" HorizontalAlignment="Left" 
                Margin="83,89,0,0" VerticalAlignment="Top" Width="75"/>
        <Button Name="Button3" Content="Button3" HorizontalAlignment="Left" 
                Margin="205,153,0,0" VerticalAlignment="Top" Width="75"/>
        <Button Name="Button2" Content="Button2" HorizontalAlignment="Left" 
                Margin="351,79,0,0" VerticalAlignment="Top" Width="75"/>

    </Grid>
</Window>
```

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace _171208_t1930_tabIndex
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            setTabOrder();
        }

        private void setTabOrder()
        {
            string[] names = {
                "Button1",
                "Button2",
                "Button3",
            };

            int tabidx = 1;
            foreach(var elem in names)
            {
                Console.WriteLine(elem);
                var obj = FindName(elem);
                if (obj != null)
                {
                    var ctrl = (Control)obj;
                    ctrl.TabIndex = tabidx++;
                }
            }
        }
    }
}
```

`setTabOrder()`の`names[]`に指定した順番通りのタブインデックスになる。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/cd9bb087-26a8-45b9-9a67-5584043c90ec.png)

### 関連

[Visual Studio | WPF > 名前からコントロールを見つける > FindName()](https://qiita.com/7of9/items/2dd05738a66a71bb3c11)
組合せ最適化でチョコナを解く


Advent Calendar 8日目の記事 [組合せ最適化でのりのりを解く](https://qiita.com/SaitoTsutomu/items/7e7a6e5e0dbc396c35b6)
Advent Calendar 10日目の記事 [組合せ最適化でクリークを解く](https://qiita.com/SaitoTsutomu/items/d6897d8ec72fdfe7370e)

## これなに

**チョコナ**を、Pythonで[組合せ最適化](https://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)モデルを作って解きます。
解く楽しみは、モデル化を工夫することになります。

自分でも試してみたい人は、下記を参考にしてください。

- [数独を通して組合せ最適化を学ぼう](https://qiita.com/SaitoTsutomu/items/bd09190d8a02432b3f16)

## 問題

- 国(太線で区切られた部分)の数は、国内の黒マスの合計とする。国の数がない場合はいくつでもよい。
- 黒マスの連なりは、長方形とする。

下図の薄いグレーが解です。

![](https://raw.githubusercontent.com/SaitoTsutomu/opt4puzzle/master/pic/chokona.png)

Pythonでは、`data`（黒マスの数）、`area`（国のグループ）を使うことにします。

```py3:python
import pandas as pd, matplotlib.pyplot as plt
from pulp import LpProblem, lpSum, value
from ortoolpy import addbinvars
data = """\
3.3...
.1....
22.21.
......
....3.
.2....""".splitlines()
area = """\
001111
022222
345677
345677
355899
3aa889""".splitlines()
```

## 変数表

下記のような変数表を作成します。各行の変数は0または1をとります。
変数の値が1ならば、該当行 該当列のマスが黒になります。

<table><tr><th></th><th>行</th><th>列</th><th>字</th><th>国</th><th>Var</th></tr>
<tr><th>0</th><td>0</td><td>0</td><td>3</td><td>0</td><td>v000001</td></tr>
<tr><th>1</th><td>0</td><td>1</td><td>0</td><td>0</td><td>v000002</td></tr>
<tr><th>...</th><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td></tr>
</table>

```py3:python
ni, nj = len(data), len(data[0])
a = pd.DataFrame([(i,j,data[i][j],area[i][j]) for i in range(ni)
    for j in range(nj)], columns=list('行列字国'))
a.字 = a.字.apply(lambda c: int(c) if c.isdigit() else 0)
a['Var'] = addbinvars(len(a))
a[:2]
```


## 数理モデルを作り解く

変数表ができたので、チョコナの解になるように、制約条件を追加し数理モデルを作成し、解きましょう。

- 各国の黒の数を指定した数に。
    - 数字は1つだけなので、合計をとれます。注意点として、合計が0なら制約条件にしないことです。
- 黒の形を長方形にする。
    - 任意の2x2の4マスの黒の合計が3にならないということです。
    - 合計を3にしてはいけないという制約条件は、「`4マスの黒の合計` <= 2+2*`1マスの黒の合計`」を4マスの中の各マスで見れば、OKです。
        - 何故なら、3のときだけ、「3<=2」という状態が出て成り立たないためです。

```py3:python
m = LpProblem()
for g,v in a.groupby('国'):
    if v.字.sum():
        m += lpSum(v.Var) == v.字.sum()
for i in range(ni-1):
    for j in range(nj-1):
        v = a.query(f'{i}<=行<={i+1}&{j}<=列<={j+1}').Var
        for x in v:
            m += lpSum(v) <= 2+2*x
m.solve()
```

### 結果の表示

```py3:python
a['Val'] = a.Var.apply(value)
plt.imshow((a.Val<0.5).values.reshape(ni,nj), cmap='gray', interpolation='none')
plt.show()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/13955/0cf5a49f-488d-a7ee-76d1-7eeba8799149.png)

解けていることが確認できます。

以上
Vagrantのsnapshotでディスクの容量を増やす

Vagrantのsnapshotでディスクの容量を増やす
===

# はじめに
vagrantのディスクサイズを増やす場合vmdkをvdiに変換してサイズを増やし…等をするが
snapshotを使用している場合は同じようにやっても`fdisk -l`に数字が反映されず容量を増やすことができなかった。

# plugin vagrant-disksizeを使う

まず`vagrant-disksize`をインストール

```shell
$ vagrant plugin install vagrant-disksize
```

次にVagrantfileに変更するサイズを指定する

```ruby
  if Vagrant.has_plugin?("vagrant-disksize")
    config.disksize.size = '230GB'
  end
```

このサイズは`VBoxManage modifyhd xxxx.vdi --resize xxxx`で指定したサイズと合わせる。

またここまでやって、わたしの環境ではVirtualBox上のストレージに表示されるディスクのサイズが反映されなかったので
一旦ストレージを削除して再度追加しなおしたら反映された。

```shell
$ fdisk -l
Disk /dev/sda: 247.0 GB, 246960619520 bytes, 482344960 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x0009a268

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    20971519     9436160   8e  Linux LVM

Disk /dev/mapper/centos-root: 8585 MB, 8585740288 bytes, 16769024 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/mapper/centos-swap: 1073 MB, 1073741824 bytes, 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
```

# 参考
Vagratfileに一行書くだけでVMのディスク容量を増やす方法
https://qiita.com/yut_h1979/items/c84c490053877beee5c1
railsでの画像ダウンロードがテキストになってしまう問題

## 画像のダウンロード

下記のように画像をダウンロードさせるのを実装したのに、何度やっても画像のrawのtextが表示されてしまう。
しかも、そのページでブラウザをリロードするとちゃんと画像はダウンロードされる。

```hoge_controller.rb
def download
  image = "何かの画像"
  send_data image, type: "image/png",disposition: "attachment", filename: "hoge.png"
end
```


## 解決策

こちらを参考にした。
http://tkrd.hatenablog.com/entry/2017/07/17/202446

`turbolinks`のgemが原因であったので

```hoge.html.erb
<%= link_to "hoge.png", file_path, data: { turbolinks: false } %>
```

このようにturbolinksを無効を指定した。
csvファイルから取得した値を名前にしたディレクトリをたくさん作る

### はじめに
csvファイルから値を取得し、それらを名前にしたディレクトリをたくさん作るための、Linuxコマンドの使用例です。
タイトルに「たくさん作る」とありますが、今回は10行だけのサンプルデータを使っています。
3項目目にoccupationとありますが、この値を名前にしたディレクトリを作成しました。

### コマンド実行前のディレクトリの構成
最初はdataディレクトリにcsvファイルが１つあるだけです。

```
$ tree
.
└── data
    └── members.csv
```

### CSVファイルの中身
csvファイルの中身は次の通りです。名前、年齢、職業が格納されています。
scientist, engineerのみ複数現れ、他のoccupationはそれぞれ１度のみ現れます。

```:members.csv
name,age,occupation
akira,23,scientist
hana,31,chemist
taro,56,engineer
jun,30,engineer
takeshi,40,programmer
tsuru,28,statistician
jiro,42,engineer
suzuki,65,scientist
mitsu,34,doctor
chika,25,student
```

### コマンド作る際の方針
- 1行目のタイトルは使わない。
- scientistやengineerなど複数ある場合は複数作らず、1つだけ作成する。

### このようなコマンドを作った

```
cat data/members.csv | awk -F',' '{if(NR>1)print $3}' | sort | uniq | xargs -I{} mkdir ./{}
```

1. catでcsvファイルの中身を読み込みます。
2. awkで1行目をスキップし、3番目の値をプリントします。
3. sortで整列します。
4. uniqで複数ある値を1つにします。
5. xargsで標準入力の値を使ってmkdirによりディレクトリを作成します。-Iオプションで標準入力の値に置き換える文字列を指定します。

### コマンド実行後のディレクトリの構成
treeを使ってディレクトリ構成を見てみます。

```
$ tree
.
├── chemist
├── data
│   └── members.csv
├── doctor
├── engineer
├── programmer
├── scientist
├── statistician
└── student
```

コマンドが正しく動いていることが分かりました。

### おわりに
csvファイルから取得した値を名前にしたディレクトリをたくさん作りました。
基本的なコマンドだけで作成できました。
Google Apps Scriptでの業界ニュース通知を社内で運用した話

[Apps Script Advent Calendar 2017](https://qiita.com/advent-calendar/2017/gas)に空いている日があったので参加します。

以前にブログを書きましたが、自社のIRなどのニュース更新の通知プログラムをGoogle Apps Scriptで作ったところ、割と評判が良く運用できています。

* [自社のIRをGoogle Apps ScriptでChatWorkに通知する](https://qiita.com/ninomiyt/items/0ba732b91ac08d13f55d)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/127762/de9986c0-294d-2a4c-bc45-fe04961a46d8.png)

簡単に要点を説明すると、以下のようなプログラムです。

1. HTMLを取得する
2. 正規表現でニュースのタイトルとURLを取り出す
3. 前回投稿したURLまでをチャットに投稿する
4. 今回投稿したURLをSpread Sheetに残す

今回は、大小様々な問題と、「できるだけ楽に対応する」という方針で暫定的に対処してきた結果をまとめておきます。

# User-Agentを指定しないと通知できないサイトの通知

[UrlFetchAppではUser-Agentヘッダーを指定するオプションが無い](https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object))ため、User-Agentを指定しないとエラーページを返すようなサイトはクロールできません。

これは良い方法が見つからず、他のページから同じ情報をクロールする方法で対応しました。同じ問題が多ければ、AWS Lambda等、もっと自由度の高い環境に移行したほうが楽でしょう。

# HTMLのDOM要素が変わる

当然ながら、サイトのデザインが変わるとエラーが発生するようになります。

そのため度々コードの変更が発生するのですが、以下の工夫で最小限の手間で済むようにしました。

1. 「一覧要素をパースする正規表現」と「その中のURLとページタイトルを取得する正規表現」を指定するよう、元々汎用的に使えるコードを作る
2. エラー時にエラー内容をマイチャットに投稿することで気づきやすくする

詳しくは『[自社のIRをGoogle Apps ScriptでChatWorkに通知する](https://qiita.com/ninomiyt/items/0ba732b91ac08d13f55d)』を見てください。

# クローリング先とのサイトの通信に失敗する

クロール先のサイトが落ちている場合があり、これは度々発生します。

ニュースの通知が目的だと割り切って、次の実行で成功すればニュースがきちんと通知されるように作りました。

様々なレイヤーのエラーが通知されるのでネットワーク通信周りの勉強にもなると思います。

# 最新のニュースが削除されるケースがある

「一つ前に投稿されたニュースURLが出てくるまで通知する」ように作ってしまったので、最新ニュースが削除されたときにページ全体分のURLが投稿されてしまいます。

これは、「投稿する件数が5件以上ならマイチャットに投稿する」という対応で乗り切りました。自分には通知が来てしまうのですが、他のメンバーには迷惑をかけません:slight_smile:

# 「正規表現の操作が実行時間の上限を超えた」エラーへの対応



運用していた間、急に以下のエラーが発生するようになりました。

> InternalError: 正規表現の操作が実行時間の上限を超えました。

[Atomフィードをパースしていた](http://www.futomi.com/lecture/japanese/rfc4287.html)サイトがあったのですが、記事のHTMLの一部で正規表現のパースに時間がかかっていたようです。

実は一部のサイトでHTMLからの情報抽出でXMLServiceでパースできない場合があり、汎用性のために正規表現を利用していました。

XMLServiceを使う方法は、以下のサイトを参考にすると良いと思います。

* [Google Apps ScriptでHTML・XMLのスクレイピングをするライブラリを公開してみた - Relax and Enjoy Programming](http://tadaken3.hatenablog.jp/entry/parser-for-gas)
* [XMLService公式ドキュメント](https://developers.google.com/apps-script/reference/xml-service/)

この際は、スクレイピングするページを変えることで対応しました。「より高速な正規表現で実装した」とかならかっこいいですが、ちょっとそこまで手が回りませんでした。

# チャットワークAPIの自動投稿に未読がつかなくなる

そのため、自分が自動投稿したニュース記事に自分で気づかない状態になってしまいました。

自動投稿後に「未読をつけるAPI」を追加で叩くように変更しました。

* [チャットワークAPIの自動投稿に未読を付ける](https://qiita.com/ninomiyt/items/71e8beb54b43aa9cc92d)

# 最後に

Google Apps Scriptでは便利なスクリプトをサクッと書けるのが魅力で、業務の空き時間に便利なプログラムを作ってしまうことも可能です。

そのため機能が制限されており、どうしても知恵や工夫が必要な面があります。がんばっていきましょう。
WEBブログ執筆に重宝するアプリ＆サービス5選

只今ご紹介に預かりました蓮子です。
アドベントカレンダー9日目です。
LIGではブログを月イチで書く習慣があるのですが、その時に重宝するツールやサービスをご紹介しようと思います。
ちなみに実機はmacOSを想定します。

# MindNode
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47240/37a4d4d6-e68c-dd86-07f9-db454e877b2b.png)

ブログを書く前に、まずは何を書くか考える必要がありますね。
それにはマインドマップを書くことをおすすめします。
マインドマップを正しく使うと

- 頭がすっきりと整理される
- アイデアが沢山出るようになる
- 深く自分の考えを知ることが出来る
- 思考が楽しくラクになる
- 目標がはっきりするのでモチベーションが上がる

など、ブログのアイデアを出すのに効果的です。

マインドマップアプリは様々なものがありますが私は[MindNode](https://mindnode.com/)をおすすめします。
、有料ですが、以下のようなところに優れています。

- UIがわかりやすく、直感で操作できる
- デザインも綺麗
- Mac版MindNodeで作ったマインドマップを、iOS版MindNodeで編集可能

何をするにもまず準備が大事です。
MindNodeを使って効率よく楽しくブログを書きましょう。

Mac版 4,800円
https://itunes.apple.com/app/mindnode-5/id1289197285?l=en&mt=12&ign-mpt=uo%3D4

iOS版 1,800円
https://itunes.apple.com/app/mindnode-5/id1218718027?l=en&mt=8&ign-mpt=uo%3D4

# Quiver
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47240/54f8e576-1ac1-3e0c-d646-99134a2169ec.png)

次に、下書き用のアプリを紹介します。
実際にWordpressなで記事を書くと、プレビューをしないと実際のデザインで見れないので、もっとスムーズに書きたくなりますよね。

そんな時私は[Quiver](http://happenapps.com/)を使っています。
Quiverは、プログラミングのメモやスニペットの記録に最適なMacアプリで、以下のような特徴があります。

- Markdownとリアルタイムプレビューで快適に入力
- カスタムCSSで、任意のスタイルを適用させることができる

ここで、画像や動画埋め込み以外の文章を快適に下書きしてから、CMSに移して残りの要素を埋め込みます。

最近は見た目がかっこいいという理由で[Byword](https://bywordapp.com/)を使うことも多いです。

# Skitch
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47240/6ffbe633-90e4-d370-10d3-a42a6c7649ab.png)

次は画像に説明を書き加えたりするアプリですね。
有名ですが、私は[Skitch](https://evernote.com/intl/jp/products/skitch)を使っています。
SkitchはEvernote社が提供する画像編集アプリで、矢印や図形、スタンプなどの注釈を描き込むことができます。

以下の理由から使用しています。

- 機能が絞られていて迷わない
- 読み込み → 加工 → 書き出しまでが早い

画像に注釈などを入れることで、文章で説明するよりも、素早く、明確にメッセージが伝わります。

# Gyazo
![150400562444555600_81.gif](https://qiita-image-store.s3.amazonaws.com/0/47240/c7e86b13-e38a-c9bc-9006-c680fd8ecb27.gif)

次は、画面を動画のスクリーンショットとして書き出すアプリ、[Gyazo](https://gyazo.com/ja)ですね。
部分的な動きを見せたい時に使用しています。
画面上で範囲を選択すると、数秒間その範囲内の変化をmp4で書き出すことが出来ます。
それを[handbreak](https://ja.osdn.net/projects/handbrake-jp/)でGIFに変換します。

# Codepen
最後に、[CODEPEN](https://codepen.io/)を使ってデモを作成します。
CODEPENは、HTML・CSS・JSなどのソースコードを保存・公開・共有できるWEBサービスで、作ったものをブログに貼り付けることもできます。
ですが、あまり貼り付けすぎるとブログが重くなるので要注意です…。

# まとめ
有名なアプリが多かったかもしれませんが、参考になりましたでしょうか？
アプリを効率よく使って、これからも楽しくブログを書いていきたいですね！
文系卒アプリケーションエンジニアもJavaで始める機械学習

こんにちは、blackawaです。

何年か「はじめたいなー」と思いながらも全然始められずに数年経った機械学習を、さすがに始めようと決心し、実際に手を動かしてみました。

弊社はPHP、Rubyが中心の会社ですが、わたし自身はJVM言語が好きなので今回はJava製の機械学習ライブラリ、[DL4J](https://deeplearning4j.org)を使って機械学習に入門してみます。

## 目標


## クイックスタートをキメる
まずは[クイックスタート](https://deeplearning4j.org/ja/quickstart)をキメます。
が、自分は[sdkman](http://sdkman.io/)でOpenJDKを入れており、OpenJDKにはJavaFXが含まれないのでいきなりビルドが落ちました。

<img width="1308" alt="スクリーンショット 2017-12-08 17.01.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/57085/695dad83-820d-9578-3709-2fd07d1f61dd.png">


[同様のIssue](https://github.com/dice-group/LIMES/issues/56)が経っていたので、まずは[OpenJFX](https://wiki.openjdk.java.net/display/OpenJFX/Building+OpenJFX#BuildingOpenJFX-Mac)を使えるようにします。
ちょっとググってみたらOpenJDKでOpenJFXをビルドする記事が出てきたのでビビってOracle JDKを使うようにしたら解決しました。(examplesのpom.xmlに、oracleのjavafxを依存に追加するプロファイルがあったから、こっちを使ってもよかったのかも。)

言われるがままに `MLPClassifierLinear` を起動するとコンソールに学習中のログがガーッと走って、JavaFXで描画されたグラフが表示されます。

<img width="684" alt="スクリーンショット 2017-12-08 17.11.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/57085/26b90e80-3df8-7f26-7035-1ae566dd8285.png">

### これは何をやっているんだ...？

機械学習の基礎知識がゼロなので何を学んでいるのか全くわからないのですが、雰囲気は味わえてます。楽しんでいきましょう。

とはいえこのままだと本当に雰囲気でやっているだけになってしまうのでちょっと調べてみます。

クイックスタートいわく、これは「多層パーセプトロン（MLP）」によってデータを分類するサンプルのようです。これは学習中にエラースコアを表示できて、それがある程度まで下がると学習が完了したと判断するようです。

[高卒でもわかる機械学習 (3) 多層パーセプトロン | 頭の中に思い浮かべた時には](http://hokuts.com/2015/12/04/ml3-mlp/)、[ニューラルネットワークとパーセプトロン | Sideswipe](http://kazoo04.hatenablog.com/entry/agi-ac-15)、[多層パーセプトロン | Wikipedia](https://ja.wikipedia.org/wiki/%E5%A4%9A%E5%B1%A4%E3%83%91%E3%83%BC%E3%82%BB%E3%83%97%E3%83%88%E3%83%AD%E3%83%B3)あたりを雑読みした感じ、MLPとは、ニューロンをモデル化してどのパラメータにどんな重み付けをすべきか学習させる方法のようです。ふんわりしすぎていて恥ずかしいですが、わからないなりに進めないと話が終わらないので先に進みます。

## MNIST for Beginners
次に、クイックスタートに促されるままに[DL4JでMNISTを試す](https://deeplearning4j.org/ja/mnist-for-beginners)ことにします。MNISTはさすがに聞いたことがあります。手書きの数字を認識できるようになる機械学習界のHello worldですね。

[サンプルのClassには学習に使う設定値が定義されていて](https://github.com/deeplearning4j/dl4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/feedforward/mnist/MLPMnistSingleLayerExample.java#L47-L52)、これを変えると精度が向上したり学習速度が上がったりするようです。

では実際に動かしてみます。
数分間の学習の後に結果が表示されました。

<img width="841" alt="スクリーンショット 2017-12-08 19.16.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/57085/53107412-cf21-436a-5f2b-0f6b02c8724c.png">

- Accuray(正答率 = テストデータセットに何%正解したか): 97.3%
- Precision(適合率 = 正解したケース数 ÷ 間違ってある文字だと判定したケース数): 97.3%
- Recall(再現率 = 正解したケース数 ÷ 間違ってある文字でないと判定したケース数): 97.27%
- F1 Score(適合率と再現率の加重平均): 97.28%

のようです。ここの解説には「真陽性」「偽陰性」などの統計用語が出てきており、理解が正確でない気がします。

## 明日からやること
とりあえずDL4Jを触ってみましたが、まだ何がなんだか全然わかりません。
統計も数学も機械学習アルゴリズムへの理解も足りないので当然ですね。
とはいえ「とりあえず」で動かしてみる環境がある今の時代には感謝して、ここからどこまでいけるか勉強を始めていきます。
まずは[仕事で始める機械学習](https://www.oreilly.co.jp/books/9784873118215/)をとりあえず一周読むのと、12/11から始まる[Coursera Machine Learning](https://www.coursera.org/learn/machine-learning/home/welcome)を3度目の正直で制覇してみようと思います。
ArchLinux環境の更新をサボってると...とその対策

元ネタは[こちら](https://natural966.wordpress.com/2016/02/04/%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%82%92%E6%80%A0%E3%81%91%E3%82%8B%E3%81%A8%E3%82%A2%E3%82%AB%E3%83%B3%E4%BA%8B%E3%81%AB/)。

# 起きること

「エラー: 処理を完了できませんでした (無効または破損したパッケージ)」と言われてpacmanが終了してしまう。パッケージの鍵が古くなって無効になり、その結果パッケージの検証に失敗して破損しているとみなされて更新できなくなる。

# 原因

「pacman -Syu」するとパッケージを片っ端からアップデートするが、archlinux-keyringもその他のパッケージと同じ扱いなのでアップデートが終わらないと鍵束が古くてアップデートできないという缶詰の中の缶切り状態になる。

# 対策

先に「pacman -Sy archlinux-keyring」して鍵だけ先にアップデートする。そして「pacman自体は先にアップデートさせるんだから鍵束もやれや」感に満たされる。
jqueryを使ってformのデータをAJAXで送る時にFormDataを使うならappendに気を配る

###基本的にFormDataを使って一括で送信する。

```js
var formData_ = new FormData($('#send_form').get(0));
```
###formData_とセットで別の値を贈りたいときは、appendして加える。

```js
formData_.append('birthday' , $('#birth_day').attr("data-birth_day"));　//YMDの8桁をname=“birthday”
```
###画像を送信する時
`contentType`と`processData`は必ず設置。

```js

contentType: false,
processData: false
```

```js
var args = {
    url: url,
    data: formData_,
    contentType: false,
    processData: false
};
```

##form名は、enctype属性をつけておく。

```html
<form enctype="multipart/form-data" method="post" id=“任意のID名” action="">
```

###各inputは、バックエンドが作成したパラメータ名をname属性に入れておく。

```html
<input type="text" name="バックエンドがほしいパラメータ名">
```

###FormDataが使えない機種やブラウザがあるので、ajax通信する時は全体を囲っておく必要がある。

```js
if (window.FormData) {
    //使える時のajax処理
}else{
    //使えない時のajax処理
}
//成功失敗の処理：共通
```

##FromDataの注意点
基本的にFormDataを使って一括で送信する時、***FormDataの中から何かを省く***ということができない。
１つでも省きたい時は***１つづつ送る***必要がある。

```js
data: {
    name: $('#status_name').text(),                      　// 名前
    birthday: $('#birth_day').attr("data-birth_day"),      // 誕生日
    job: $('#status_job').text(),　                        // 仕事
    location: $('#status_live_no').attr("data-live_no"),   // 住まい
    avatarId: $('#chara_check').attr("data-chara_check")   // アバターID
}
```

##Androidの注意点
アンドロイドはinput fileで画像を添付することができないのでformDataにappendする必要がある。

```html
//クッキーを使ってwebviewを判定用JS
<script type="text/javascript" src="{{ $siteBaseUrl }}/js/lib/jquery.cookie.js"></script>
```

```js
(function() {
    //クッキーを使ってwebview判別
    var isAndroidApp = ($.cookie('webview') === 'android');
    //androidならformData_にspendする
    if (isAndroidApp && (0 < imageBlob.size)) {
        formData_.append('属性name', imageBlob, 'filename.jpg');
    }
});
InterlockedIncrementを使用してマルチスレッド化

Windowsの古いプログラムの性能を改善するために、マルチスレッド化する方法を考えてみた。プログラムでは、配列の各要素に対してある処理を順番に実行している。処理はメモリの読み書きのみで互いに独立。
`InterlockedIncrement`と`Sleep`を使うと比較的簡単に実装できることが分かった。

サンプルプログラムの親スレッドでは、開始スレッド数と終了スレッド数の差が上限値未満ならば、新しい子スレッドを開始して、開始スレッド数をカウントアップする。そうでなければ一定時間`Sleep`する。
サンプルプログラムの子スレッドでは、ある時間`Sleep`してからデータの一部を更新する。終了する際に終了スレッド数をカウントアップする。`Sleep`する時間は乱数で決定。
当初、乱数は子スレッドで生成していたが、常に同じ値が返ってきた。乱数の初期化は親スレッドで実行していて、子スレッドはその環境をコピーするため。乱数を親スレッドで生成して引数で渡すように修正。

```c
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <errno.h>
#include <string.h>

// thread parameters
struct cparam {
    LONG* p_end;
    LONG* p_error;
    int no;
    int sleep;
    int* data;
};

// thread function
void __cdecl fun(void *p) {
    cparam* pp = (cparam*)p;
    try {
        printf("start,%d,%d\n", pp->no, pp->sleep);
        Sleep(pp->sleep * 1000);
        pp->data[pp->no] = pp->no;
        printf("end,%d,%d\n", pp->no, pp->sleep);
    }
    catch (...) {
        InterlockedIncrement(pp->p_error);
    }
    InterlockedIncrement(pp->p_end);
    delete pp;
}

void main_thread() {
    const int N = 10;
    int data[N];
    for (int i = 0; i < N; i++) data[i] = 0;
    srand(10);
    LONG n_start = 0;
    LONG n_end = 0;
    LONG n_error = 0;
    int limit = 5;
    // execute function for each element
    int n = 0;
    while (N > n) {
        if (n_start - n_end < limit) {
            cparam* pp = new cparam();
            pp->p_end = &n_end;
            pp->p_error = &n_error;
            pp->no = n;
            pp->sleep = (rand() % 10) + 1;
            pp->data = data;
            uintptr_t th = _beginthread(fun, 0, pp);
            if (th == -1L) {
                // error
                int errnum = errno;
                printf("errno,%d,%s\n", errnum, strerror(errnum));
                delete pp;
            }
            else {
                n_start++;
            }
            n++;
        }
        else {
            Sleep(250);
            printf(".\n");
        }
    }
    // wait for child threads
    while (n_start > n_end) {
        Sleep(250);
        printf(".\n");
    }
    printf("%d,%d,%d\n", n_start, n_end, n_error);
}
```

- 子スレッドのハンドルは必要ないので、`_beginthreadex`の代わりに、`_beginthread`を使用。
- `_endthread`は、`fun`が終了すると自動的に呼び出されるため、省略。
- `InterlockedDecrement`を使用してスレッド数を一つにまとめるのもあり。

実行結果

```
start,0,2
start,1,10
start,3,5
start,4,8
start,2,3
.
.
.
.
.
.
.
end,0,2
.
start,5,7
.
.
.
end,2,3
.
start,6,3
.
.
.
.
.
.
end,3,5
.
start,7,3
.
.
.
.
end,6,3
.
start,8,7
.
.
.
.
.
.
end,4,8
end,7,3
.
start,9,10
.
.
.
end,5,7
.
.
.
end,1,10
.
.
.
.
.
.
.
.
.
.
.
.
.
end,8,7
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
end,9,10
.
10,10,0
```
Adobe XDで300超のアートボードを管理していると何が起こるのか

一体どうなっちゃうの〜！？

[モバイルファクトリー Advent Calendar 2017](https://qiita.com/advent-calendar/2017/mobilefactory) 8日目の記事です。

## なぜこんなことになったのか

ゲームのUIをAdobe XD(以下XD)で作ってるんですけど、XDの画面をそのまま実装仕様として使えるようにするぞ！という方針にしてみたところ、プロジェクトの画面を丸ごと突っ込んだ情報設計だけでなく更に条件分岐も網羅してしまっています。ゲームは画面数がとても多い。そこに条件分岐が追加されると300は余裕で突破します。しない？

## 重さと領域限界

全然重くない。とても快適です。
XDの作業領域も、とても広大なので300のアートボードを置いても1/2も使っていない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/27889/0bfae86d-bfd9-3afd-77a0-0261afa4ecbe.png)
※ 中心にiOS6 375x667アートボードを置いた場合と全体の使用可能領域（更に上下にもう少し余裕がある）
※ 実際の画面はお見せできません

## 困ったこと

### プロトタイプでアートボード同士を繋ぐ際、設定するターゲット一覧のビューが貧弱すぎて迷う

左上部から計算した位置によるソートでリストが並んでいるものの、複雑になってくると順番に一列で並べるなんてしないので、リンク先のアートボード一覧が使い物にならなくなる。
位置順だと整理が難しいので、せめて名前順にしてほしい。もしくはタグ付けさせて。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27889/a11bde29-074a-6637-efce-ca991fbc0bed.png)
※ ひたすらこれが300並ぶと目的のアートボードを探せない

リストに並んでいる名前による管理が難しいため、アートボードの置き方に工夫が必要になってくる。
基本は左から右に進んでいき、分岐があったら上下に分かれるなどのルールで配置していますが、平面上でのこういう並べ方はスケールしない。自然と樹形図的模様になっていくのですが、下の枝と上の枝が衝突しそうになるとまた再配置が必要になってくるなどしてとても面倒。
前述の通り一覧から探すのは無理なので、リンクを繋ぐ際は「確かショップ画面は右上にあったな...」という感覚でリンクを繋いでいくことになります。

### 鳥瞰図はXDを持っている人間しか見れない

エンジニアにXDの成果物を見せても「本当にこの進み方で分岐が網羅できているか分からない」と言われてなるほどと思ったことが。アプリがあると全体を見ることもできるものの、無い人は迷う。

## 共同作業は可能か

Google Driveに管理して誰でも.xdファイルにアクセス出来るようにしていますが、複数人が一つのファイルを弄るのに向いてはいません。複数人で一つのプロダクトUIを編集する場合では、一つの纏まりごとにファイルを作ってから統合するためのファイルに合体という方法を採っています。
XDファイルは別ウィンドウで開いていても、プロトタイプモードでコピーすればリンクが保たれたまま別のXDウィンドウにペースト出来る。便利。

## まとめ

Adobe XDは動作が軽量かつ出来ることが単純なため、仕様の変更に対して即座に対応できます。
そのためこのような大きなXDプロジェクトを管理するという選択を採用してみましたが、経過としては大量のアートボードを管理するのには機能が足りないなという印象です。
小さめのプロダクトの情報設計を最速で作るならばとても有用なのですが、アートボードが100を超え、しかもそれを管理するとなると厳しいものがありました。（特にアートボード一覧）
改善策としては、大量の画面数が予想されるならばファイルを機能ごとの小分けにして運用していくのが良いのではないでしょうか。
【小ネタメモ】htmlのcheckboxをreadonlyにする

# 経緯

1. 管理画面でON/OFFを表すユーザーデータの表示にチェックボックスを使いたい
2. 表示だけだから編集できない方がいいな
3. `disabled`だと薄灰色になって見にくいから使いたくないな
4. checkbox「`readonly`？いえ、知らない子ですね」
5. たっけてぐーぐる先生
6. ぐーぐる先生「ほらよ」
7. やったー、メモっとこ


# やり方

`checkbox`の`onclick`に`return false;`を書く。


# 例

![readonly_check_box.png](https://qiita-image-store.s3.amazonaws.com/0/59250/a48da630-66dc-6c6e-e4ee-bc024429fd7c.png)

```html
<input type='checkbox' disabled>
<input type='checkbox' disabled checked>
<br>
<input type='checkbox' onclick='return false;'>
<input type='checkbox' onclick='return false;' checked>
```
HTML5ではこのタグにあのタグを入れていいんだっけ？という時に便利なサービス

ちょっと感動したので普及活動をしたいと思います。

## まえがき
フロージングコンテンツ？フレージングコンテンツ？
なんかそんな感じので内包できる要素決まってたよね・・・
でもそこから調べるの大変だしなー。手っ取り早く内包できる要素調べられないかなー。
という時に見つけ、感動したサービスです。

## サービス紹介
[HTML5 コンテンツモデル ガイド](https://webgoto.net/html5/)

## 視覚的に内包できる要素を確認する
まずサイトに訪問するとこのようになっています。

![image1.png](https://qiita-image-store.s3.amazonaws.com/0/100188/42068259-9d90-3e37-205e-ff458410d8d4.png)

そして、確認したいタグ（何の要素 **に** 内包できるのか、何の要素 **を** 内包できるのか）をクリックします。

![image2.png](https://qiita-image-store.s3.amazonaws.com/0/100188/c5cc4ec8-2830-5ecb-281f-4ecaa25b9c36.png)

今回は`section`タグをクリックしました。
すると上の画像のように右カラムに`section`タグについての情報が出てきます。

そして「**親となる要素**」もしくは「**子となる要素**」にホバーすると

![image3.png](https://qiita-image-store.s3.amazonaws.com/0/100188/c4644dbe-ea22-1693-16d8-86e705d86f42.png)

左カラムの対応しないタグがグレーアウトし、視覚的に内包できる要素を確認できることができます。
素晴らしい、感動した！

## あとがき
業務PCにPhotoshopが入っておらず、私は画像編集といったらPhotoshopな人間なので、仕方なくmac標準のプレビューツール？を使っているんですが、今回の画像くらいのものなら簡単に出来て良い感じです。
serial通信 arduino, processing

# 1 byte
## settings
```
pin 2 : SW (release:OFF / push:ON)
pin 3 : LED
```

![setting.png](https://qiita-image-store.s3.amazonaws.com/0/102253/2b6b3c16-abdb-fea3-1d54-39232039c372.png)

![setting-photo.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/48aa86b3-0e50-5e5f-c249-325c8d8797f4.jpeg)


## arduino > processing
https://youtu.be/FydeVeVlqkw

```serial_write_1byte_with_sw.ino
const int pin = 2;
const int pinLED = 3;
int stateSW;

void setup(){
  Serial.begin(9600);
  pinMode(pin, INPUT);
  pinMode(pinLED, OUTPUT);
  stateSW = 0;
}

void loop(){
  stateSW = digitalRead(pin);
  //Serial.println(stateSW);
  if(stateSW == 1){
    Serial.write(1);
    digitalWrite(pinLED,HIGH);
  }else{
    Serial.write(0);
    digitalWrite(pinLED,LOW);
  }
}
```

```serial_read_1byte.pde
import processing.serial.*;

Serial myPort;       

//user definitions
String COM_PORT="/dev/tty.usbmodem1421"; //change this!
int myByte = 0;

void setup(){
  size(400,400);
  //printArray(Serial.list());
  //myPort = new Serial(this, Serial.list()[2], 9600);
  myPort = new Serial(this, COM_PORT, 9600);

}

void draw(){
  background(255);
  while (myPort.available() > 0) {
    myByte = myPort.read();
    println(myByte);
    
    if(myByte == 1){
      background(0);
      fill(255);
      ellipse(200, 200, 100, 100);
    }
  }
}
```

## processing > arduino
https://youtu.be/ty6ImOZLEP4

```serial_read_1byte_led.ino
const int pinLED = 3;
int readByte = 0;

void setup(){
  Serial.begin(9600);
  pinMode(pinLED, OUTPUT);
}

void loop(){
  if (Serial.available() > 0) {
    readByte = Serial.read();
    Serial.println(readByte, DEC);
    if(readByte == 1){
      digitalWrite(pinLED,HIGH);
    }else{
      digitalWrite(pinLED,LOW);
    }

  }
}
```

```serial_write_1byte.pde
import processing.serial.*;

Serial myPort;       
String COM_PORT="/dev/tty.usbmodem1421"; //change this!
int value = 0;

void setup(){
  size(400,400);
  //printArray(Serial.list());
  //myPort = new Serial(this, Serial.list()[2], 9600);
  myPort = new Serial(this, COM_PORT, 9600);
}

void draw(){
  background(255);
    
  if (keyPressed) {
    if (key == 'b') {
      value = 1;
      background(0);
      fill(255);
      ellipse(200, 200, 100, 100);
    }
  }else{
    value = 0;
  }
  myPort.write(value);
}

```
GitHub Webhookを簡単に使える ghooks-cmd-runner のご紹介

この記事は[OSS紹介 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/favorite-oss)の8日目の記事です。OSS紹介 Advent Calendar　2017では、使っている便利なOSSを紹介したい方や、自分のOSSを広めたいという方の投稿をお待ちしております。

---

今回はGitHub Webhookを簡単に使えるghooks-cmd-runnerを紹介します。

https://github.com/tkuchiki/ghooks-cmd-runner

## 特徴

* ワンバイナリで動作
* GitHubからのHTTPリクエストを受け付けるWebサーバとして動作
* TOML形式の設定ファイルにwebhookが来たときに起動するコマンドを記述する
    * 標準入力にWebhookで来たリクエストのJSONが流し込まれる
    * 特にWebサーバを記述しなくてもコマンドを書くだけでWebhookを作ることが出来る

## 使いみち

* JenkinsなどのCIをpluginを用いずにジョブを起動する
    * masterブランチだけジョブを起動するなどの柔軟な設定が可能
* pushなどのタイミングで特定のコマンドを走らせる
    * githubのissueなどを更新するコマンドのトリガーに使える

## 使い方

### インストール

これも[katsubushi](https://qiita.com/mackee_w/items/f3c0181f57b472592460)と同様、releaseバイナリがあります。

https://github.com/tkuchiki/ghooks-cmd-runner/releases

こちらからプラットフォームにあったバイナリを落とすか、やはり[ghg](http://www.songmu.jp/riji/entry/2016-07-06-ghg.html)を使うと簡単にインストールできます。

```shell-session
$ ghg tkuchiki/ghooks-cmd-runner
```

### 設定

```toml:config.toml
# port = 18889 (default: 18889)
# host = "0.0.0.0 (default: 127.0.0.1)"
# secret = "your webhook secret"
# logfile = "path to logfile (default: stdout)"
# pidfile = "path to pidfile"

[[hook]]
event = "push"
command = "/path/to/script"

[[hook]]
event = "pull_request"
command = "/path/to/script"
```

以上のような形でコマンドを記述し、

```shell-session
$ ghooks-cmd-runner -config=config.toml
```

でサーバが立ち上がります。

GitHubからのHTTPリクエストを受け付ける必要があるため、ドメインなどを割り当てる必要があります。

GitHub側のWebhookの設定は[公式ドキュメント](https://developer.github.com/webhooks/)などをご覧ください。具体的にはリポジトリの`settings` -> `webhooks`で設定します。

### シェルスクリプトでWebhookを受ける

jqなどを使うとshell scriptでもwebhookで何かアクションを起こすことが出来ます。以下はブランチを指定しつつJenkinsの特定のジョブをbuildWithParameterで起動するシェルスクリプトです。

```bash:invoke_jenkins_job.sh
#!/bin/bash

set -ex

JOB_NAME=${1:-default_job}
GIT_BRANCH=$(cat - | jq -r '.ref' | sed 's/^refs\/heads\///g')
curl -X POST -s "http://internal.jenkins/job/$JOB_NAME/buildWithParameters?GIT_BRANCH=$GIT_BRANCH"
```

### release-requestでdevelopブランチにpushがあったらmasterブランチへのPull Requestを更新する

拙作の[release-request](https://qiita.com/mackee_w/items/54db54c4389bbc33879f)を用いて、masterに更新があったら、デプロイPull Requestを更新することが出来ます。

```toml:conifg.toml
[[hook]]
event = "push"
command = "release-request"
branch = "^develop$"
```

### 他のアイディア

* [reviewdog](http://haya14busa.com/reviewdog/)を起動してlintのログなどをPull　　Requestに書き込む
* 特定のブランチが更新されたら開発サーバのコンテナを入れ替える

---

以上ユースケースなどを紹介させていただきました。GitHubを中心にワークフローを組んでいる方にはとても有用なプロダクトだと思います。あなたの街のGitHub活用術を教えてくれたら幸いです。
新卒がプルリクで100コメント貰って学んだこと

リブセンス17新卒の山下です。未経験エンジニアとして入社して早8ヶ月、毎日ひーひー言いながら修行しています。
本日はLivesenseAdventCalendarの10日目、テーマは「学」ということで、僕が入社してから気づいた「学び」を書いていこうと思います。

自分は普段、Livesenseの中でも[転職会議](https://jobtalk.jp/)というサービスで開発を行っています。
僕達のチームでは、裁量労働制を取っており、リモートワークも推奨しているので直接の会話よりもチャットやプルリクでのやり取りが多いです。
その為、プルリクでは（僕が新卒というのもあり）丁寧に皆さんコードレビューをしてくださいます。

今日は、そんな僕がプルリクエストで100ものコメントを貰って気づいたことを書いていこうと思います。
新米エンジニアで「プルリク通らないなー」と悩んでいる方や、後輩の指導で悩んでいるベテランエンジニアの方など、読んでコメントいただけるとうれしいです。


# 普段の開発フロー
僕達のチームでは、コードを書いたらgithubのプルリクエストを利用してコードレビューをしてもらいます。レビュワーは、チーム内のベテランエンジニアや、関連タスクを行っている人に入ってもらい、承認をもらってからマージするというフローをとっています。
経験の浅い自分は、技術的なコメントや[設計思想の話](http://made.livesense.co.jp/entry/2017/10/10/101000)、更には英語の文法まで、幅広くコメントを貰います。

比較的コメントをたくさんもらう僕は「経験が浅いから、これだけコメントがつくのは当然。たくさん経験を積んで知識をつけるしかない！」と思っていました。
がむしゃらに知識をつけようと、社内の勉強会には積極的に参加したり、様々なチュートリアルを触ったりをひたすら繰り返していました。


# 俺めっちゃ成長できてる！...よね？？？
入社してしばらくが経ち、自分でもできることが増えてきたなと思い始めてきた矢先、ふとプルリクのコメント数を見てみると、なんと昔と変わらない、それどころか増えてるではないかということに気づきました。
実装にも自信がついてきて、プルリクも「すごくきれいに書けた！」と思いながら出しているにもかかわらず、依然コメント数は変わらない、、。
入社して結構コード書いてきたのに、僕はこんなにも成長していないのかと、落ち込むこともありました。

そんな中、落ち込んでいる自分を察してか、[チームの先輩](https://qiita.com/masahixixi/items/0b9ecc00e26afd8015c1)が飲みに誘ってくれるようになりました。
「コメント数減らないね。何で減らないんだろうね？」との問いかけに、うまく答えられない僕を見て「自分のプルリクもう一回見直してみな」とのアドバイスをいただきました。

# 見返してびっくり「何言ってんだこいつ？？」
僕は大変素直なので、アドバイス通り今までの僕のプルリクを見返してみることにしました。
見返しながら「入社当初よりは絶対実装力付いたぞႭ(๑ ⁼̴̀ݖ⁼̴́๑)Ⴓｸﾞｯ」と自分を慰めつつ、なんでこのプルリク出したんだっけ？？とプルリクの冒頭のコメントを遡ってみると、書いた本人もびっくりするほどの難解な日本語が並んでいました。

おそらく、プルリクを出した当時は、「自分が受けた説明はみんな知っているだろう」と、レビューイとしての説明の責務を放棄し、理解するのをすべてレビュワーの皆さんに負担してもらっていたんだなと気づきました。

まともな説明ができていない状態でのコードレビューはやり辛いことこの上ないはず。その上で、僕がしっかり論理だてて説明ができるよう誘導するように「なぜこの変更を加えたのですか？」「他の方法は考えましたか？」「この実装に至るまでの説明が抜けていませんか？」と、コメントをしてくださっていました。

僕のプルリクのコメントが減らないの原因は、単に技術力や経験が少ないからではなく、ロジカルシンキング（ライティング）ができていなことにありました。


# 新卒一年目で最も学ぶべきスキルは？
技術力もエンジニアとしてすごく大事だし、磨くべきスキルであることに変わりはないです。ただ、これらは日々コードを書いて、プロダクトに触れて、先輩方と話していれば嫌でも身につくような気がしています。
それに対して、ロジカルシンキングは、自分から学ぼうとしないと身につきません。
しかもこれらは一朝一夕で身につけられるようなものでもなく、勉強し始めてから身につくまで、かなりの時間がかかります。

また、ロジカルシンキングさえしっかりできていれば、プルリクだけでなく設計や要件定理、バグ修正も効率良く行えることができます。
そうなればエンジニアとしての技術力も、確実に上がるはずです。

なので、僕がこの記事で一番伝えたいことは、新卒エンジニアは技術力よりもロジカルシンキングを意識して学ぶべきだ！といいうことでした。

ということで、来年は「新卒が１年間ロジカルシンキングを学んで変わったこと」 or 「新卒がプルリクで200コメント貰って学んだこと」のどちらかを書いていこうと思います。

長くなりましたが、最後まで読んでくださった方、ありがとうございました！
SEOを意識したheaderタグまとめ＋α

SEOとかLPOとかをやっているので、
その辺り意識して作っている時に気をつけていることをざっとまとめていこうと思います。

## headerタグ編
`header`にはサイトに適したタグを埋め込むことで、検索エンジンがきちんと情報を取り組んでくれます。

### 基本セット
```html
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>サイトタイトル</title>
<meta name="description" content="サイトの説明文">
<link rel="canonical" href="http://xxx.xxx">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
```

#### title
SEOで最も重要なタグです。以下に気をつけて設定すると良いです。
- 30文字前後（スマホ最適の場合は50文字程度）
- 複数ページで重複しないように全ページ固有のタイトルにする

#### discription
タイトルの下部にはいる補足になる文章です。
シンプルにユーザーがクリックしやすいような内容で。
最長120文字程度が目安。（スマホの場合は20文字）

### OGP関連
```html
// headタグは以下推奨
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
  <meta property="og:title" content="タイトル">
  <meta property="og:type" content="blog">
  <meta property="og:url" content="http://xxx.xxx">
  <meta property="og:image" content="images/xxx.png">
  <meta property="og:site_name" content="サイト名">
  <meta property="og:description" content="サイト概要">
  // Facebook App IDを入れるかた
  <meta property="fb:app_id" content="">
</head>
```

### スマホ対応系
```html
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png">
<meta name="apple-itunes-app" content="">
<meta name="google-play-app" content="">
// アドレスやメールを自動判定でリンクさせない
<meta name="format-detection" content="telephone=no,address=no,email=no">
```

#### viewport
レスポンシブ対応しているサイトには必ず必要になる。
width = 横幅。初期値は980px。
height = 縦幅。
initial-scale = 倍率。
minimum-scale = 最小縮小比率
maximum-scale = 最小拡大比率
user-scalable = ユーザーが拡大表示できるかどうか。デフォルトは`yes`

## HTMLタグ

### H1
記事のタイトル。`title`タグの次に重要。
32文字程度で解りやすい言葉でキーワードを意識して作る。
1ページに1つまで。
html5から原則的に、複数個おけるようになったが、価値は分散してしまうので、結果1つのほうが良さそうだとか。）

### a
リンクのアンカーテキストはキーワードを含めると良い。
「こちら」とかにするのはSEO的によろしくない。

### strong
強く強調したいキーワードに。

### em
重要なキーワードに。

### img
きちんと`alt`をつけること。

## その他考慮したいこと

### 利用する画像サイズを下げる
必ず圧縮した画像をアップロードすることでサイトの速度があがります。
大きな画像は特に意識して圧縮することを推奨します。
http://optimizilla.com/ja/
http://compressjpeg.com/ja/

### シンプルなアイコンはSVGで！
イラレがないからSVG作れないよ！っていうかたも多いかと思いますが、
webで簡単につくれるサイトがあります。
画像と違って拡大縮小で劣化しないので出来る限りSVG化したいところ。
http://editor.method.ac/

### ページ下部の画像は後読み込みにする
あとで読み込んでも良いものはどんどん後読み込みに・・・
ライブラリ、いっぱいあります。他記事参考で。
[LP高速化のために5つの画像の遅延読み込みライブラリを比較した](https://qiita.com/tkhr/items/4b5e7f2a384dc4fccb20)


## あとがき
アトラエでは一緒にプロダクトを作る仲間を募集しております！
どんなことしているのか、宜しければご覧いただければ嬉しいです！

[新規事業yenta/wevoxも急成長中！求人メディアGreenを運営するHRTechベンチャー](https://www.green-japan.com/company/172)

エンジニア・デザイナー・コーダー・・・みなさん仲間になってください！
EC-CUBEで複数DBで会員データを共通化する

EC-CUBEで複数の店舗(データベース)を作ったけど、会員データは共通化したい、というケースはよくあるかと思います。

MySQLのみですが、同一のDBサーバに複数のDBがある構成であれば、かんたんに共通化することができます。

店舗Aと店舗Bがあり、店舗Aの会員データを両方の店舗で使いたい、というケースであれば、次のような対応になります。

店舗Bの、doctrineのdcm.ymlファイルを以下のように編集します。

```src/Resource/doctrine/Eccube.Entity.Customer.dcm.yml
Eccube\Entity\Customer:
    type: entity
    table: [店舗Aのデータベース名].dtb_customer
    repositoryClass: Eccube\Repository\CustomerRepository
    ...
```

```src/Resource/doctrine/Eccube.Entity.CustomerAddress.dcm.yml
Eccube\Entity\CustomerAddress:
    type: entity
    table: [店舗Aのデータベース名].dtb_customer_address
    repositoryClass: Eccube\Repository\CustomerAddressRepository
    ...
```

```src/Resource/doctrine/Eccube.Entity.CustomerFavoriteProducuct.dcm.yml
Eccube\Entity\CustomerFavoriteProduct:
    type: entity
    table: [店舗Aのデータベース名].dtb_customer_favorite_product
    repositoryClass: Eccube\Repository\CustomerFavoriteProductRepository
```

次に、`app/config/eccube/config.yml`の`auth_magic`を店舗Aと同じ値に設定します。

```app/config/eccube/config.yml
auth_magic: xxxxx <- 店舗Aの値を設定
password_hash_algos: sha256
shop_name: 'EC-CUBE SHOP'
...
```

以上です。

これで会員データは共通化され、どちらのサイトでもログインすることができます。

今回はMySQLの例ですが、PostgreSQLの場合は、同じデータベース内でスキーマを変更すれば同様の対応が可能です。
composerだけxdebugを無効にする（Windows版）

## はじめに

composer が XDEBUG が有効になっていると致命的に遅くなることは composer のサイトにも書かれています。実行前に php.ini を編集して XDEBUG を無効化しておきたいところですが、日々の開発で XDEBUG さんにお世話になるほどに composer は実行しないので、つい忘れてしまいます。

そのために、XDEBUG を無効にした「専用の php.ini」を作り、それを参照するように composer コマンドをあらかじめ作っておきます。

## コマンドを作る際に

Windows に Composer をインストールするときに [コマンドラインツールの composer.bat を作る](https://getcomposer.org/doc/00-intro.md#manual-installation) と思いますが、その際に XDEBUG を無効にした ini ファイルを指定します。

```
C:\bin>echo @php -c "C:\path\to\php-noXdebug.ini" "%~dp0composer.phar" %*>composer.bat
```

## Windows 以外の方

[composerだけxdebugを無効にする - Qiita](https://qiita.com/m-seikou/items/0492a0cf35bae9dd6450)

言うまでもなく、本記事は上記記事の~~パクリ~~ Windows 版であります。

## ついでに

php7cc も、やはり XDEBUG が有効だと致命的に遅いので同様にしました。composer に限らず基本的にコマンドラインで使う PHP は全て XDEBUG を無効にして実行した方が良さそうですね。

```php7cc.cmd

@php -c "C:\PHP\php-noxdebug.ini" "C:\Users\YourName\AppData\Roaming\Composer\vendor\sstalle\php7cc\bin\php7cc.php" %* 

```

## さらに

もっと高速化情報です。

[Composerの実行速度を高速化する方法 - Qiita](https://qiita.com/keita-nishimoto/items/37f0fac49442b72c403e)
Node.js で AWS IOT に Pub/Sub する

Publish
エンドポイントは変更して下さい。

>エンドポイントは次のコマンドで調べます。

>```bash
aws iot describe-endpoint --endpoint-type iot:Data-ATS
```


```js:publish.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	publish.js
//
//					Dec/08/2017
//
// ---------------------------------------------------------------
var awsIot = require('aws-iot-device-sdk')

console.error ("*** 開始 ***")

const topic = 'sdk/test/Python'

const KEY =  './r10001.private.key'
const CERT =  './r10001.cert.pem'
const TRUSTED_CA = './root-CA.crt'

var device = awsIot.device({
	keyPath: KEY,
	certPath: CERT,
	caPath: TRUSTED_CA,
	host: 'abcd6goq68zt4o-ats.iot.ap-northeast-1.amazonaws.com'
})

device.on('connect', function() {
		console.log('connect')
		device.publish(topic, 'Hello mqtt PM 18:08\n\n', {'qos': 1})
		console.error ("*** 終了 ***")
	})

// ---------------------------------------------------------------
```

Subscribe

```js:subscribe.sh
#! /usr/bin/node
// ---------------------------------------------------------------
//	subscribe.js
//
//					Dec/08/2017
//
// ---------------------------------------------------------------
var awsIot = require('aws-iot-device-sdk')

const KEY = './r10001.private.key'
const CERT = './r10001.cert.pem'
const TRUSTED_CA = './root-CA.crt'

var device = awsIot.device(
{
	keyPath: KEY,
	certPath: CERT,
	caPath: TRUSTED_CA,
	clientId: '+',
	host: 'abcd6goq68zt4o-ats.iot.ap-northeast-1.amazonaws.com'
})

device.on('connect', function() {
	console.log('connect')
        const topic = 'sdk/test/Python'
	device.subscribe(topic, {'qos': 1})
	})

device.on('message', function(topic, payload) {
	console.log('message', topic, payload.toString())
	})
// ---------------------------------------------------------------
```
C++でメンバ変数に別名をつける方法まとめ

#はじめに
例としてD言語では`alias`を使うことで変数等に別名をつけれます。

```d
struct Float4
{
    float x,y,z,w;
    
    alias r=x,g=y,b=z,a=w;
};
```
この場合、`Float4`型に対して、xyzwで扱うだけでなくrbgaでのアクセスも可能になります。(HLSLの`float4`のようなイメージ)

同じようなことをC++でやるにはどうすればよいか考えてみます。

#方法1：define

```cpp:main.cpp
#define r x
#define g y
#define b z
#define a w

struct Float4 
{
	float x,y,z,w;
};
```

**こんなコードを書く人は島流しの刑にすべきです。**
やめてください。

論外。

#方法2： 参照

```cpp:main.cpp
struct Float4 
{
	float x,y,z,w;
	float& r=x, g=y, b=z, a=w;

	Float4() = default;

	Float4(const Float4& other):
		x(other.x),
		y(other.y),
		z(other.z),
		w(other.w),
		r(x),
		g(y),
		b(z),
		a(w)
	{}
	Float4& operator =(const Float4& other) 
	{
		this->x = other.x;
		this->y = other.y;
		this->z = other.z;
		this->w = other.w;
		return *this;
	}
};

```

メンバに参照型を持てば似たようなことができるかもしません。
しかし、参照型の分**メモリサイズが増えてしまう**ことや、ただしくコピーコンストラクタをかかないとディープコピーできない等の問題があります。

あんまりオススメはできない。

#方法3：共用体

```cpp:main.cpp
struct Float4 
{
	union
	{
		struct
		{
			float x, y, z, w;
		};
		struct
		{
			float r, g, b, a;
		};
	};
};

```
共用体と無名構造体を利用してxyzwとrbgaでメモリ領域を共有する方法。
状況次第ではメモリサイズのこととか意識しないといけないかもですが、それなりにオススメできそう？

#方法4：プロパティ

もし**Visual Studio**を使っているならプロパティを利用するのもありかもしれません

```cpp:main.cpp
#define PropertyAlias(base,name,...)\
__declspec(property(get = get_##base, put = set_##base)) __VA_ARGS__ name;\
__VA_ARGS__ & get_##base(){return base;}\
void set_##base(const __VA_ARGS__& value){base = value;}


struct Float4 
{


	float x, y, z, w;

	//書くのがめんどくせえのでとりあえずマクロで許して
	PropertyAlias(x, r, float)
	PropertyAlias(y, g, float)
	PropertyAlias(z, b, float)
	PropertyAlias(w, a, float)

};
```
個人的に書くのがめんどくさいです。

VSのプロパティの詳しい説明は[こちら](https://msdn.microsoft.com/ja-jp/library/yhfk0thd.aspx)

#まとめ

今回は思いついた4つの方法を紹介しましたが他にもいい方法があったら教えてください。

そもそも、こんな事がしたい状況にそんなにならないとは思いますが…？
Python AND検索 OR検索

# AND検索

検索文字列はリストで渡す
検索文字列が対象文字列にあったら1,なければ0として結果リストにする
全て1であれば(全要素掛け合わせて1であれば)True

```python3:code
from functools import reduce

def search_and(search_words, target_string):
    result_list = [ 1 if i in target_string else 0 for i in search_words ]
    result = reduce(lambda x, y: x*y, result_list)
    return True if result == 1 else False
```
```bash:実行結果
>>> print(search_and(['a','b'], 'abcde'))
True
>>> print(search_and(['a','b','f'], 'abcde'))
False
```

# OR検索

ほぼ同じ。最後に全て0であれば(全要素足し合わせて0であれば)False

```python3:code
from functools import reduce

def search_or(search_words, target_string):
    result_list = [ 1 if i in target_string else 0 for i in search_words ]
    result = reduce(lambda x, y: x+y, result_list)
    return False if result == 0 else True
```
```bash:実行結果
>>> print(search_or(['a','b','f'], 'abcde'))
True
>>> print(search_or(['f','g','h'], 'abcde'))
False
```

## +α
検索自体はinでやってるので、高度なことをしたければfindやre.matchとかでどうぞ。

### どうでもいいやつ
python3この頃使い始めたけど、reduceはモジュール読み込まないといけなくなったのか。