OmniAICreator/Qiita-1.07M huggingface dataset:
標高PNGタイルとWebGLで浸水シミュレーション

これは [FOSS4G Advent Calendar 2018](https://qiita.com/advent-calendar/2018/foss4g) 六日目の記事です。

# はじめに

標高PNGタイルを使ってブラウザ上で浸水シミュレーション(もどき) をやってみたいと思います。ただしあくまで技術紹介のための試作ですのでご注意ください。くれぐれもこのシミュレーション結果そのものを、生命や財産に影響のある行動の参考にはなされませんように。

# デモ

こちらからどうぞ。スマホでも動くのではないかと思います。

- <https://frogcat.github.io/flood/>

**Step1** 起動するとまず地図が表示されるので、適当に見たい地域まで移動します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/08a2e83f-3f4c-c535-dbb6-e8500e309475.png)

**Step2** 今見ている地図の標高PNGタイルのロードが完了すると **Click to Run** の帯が表示されるので、これをクリックするとシミュレーション開始です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/e8e1ed70-0317-be3e-da88-0ddab7bafe5a.png)

**Step3** 最初は地図上の全面に水が撒かれた状態でスタートしますが、徐々に水が低いほうに移動していきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/ad3f8a90-fd2d-0eb0-fe37-55a4cec5b84f.png)

濃淡が水の深さに対応しています。水がなくなったところは透明に。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/32329ff4-c5aa-c62d-ff75-7b5fc58d77f3.png)

時間とともに徐々に収束していきます。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/d698ead5-6cbe-a8ea-3d07-5a71d204fd83.png)

最後はこんなかんじに。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/6c6a0079-ebcf-4351-5773-7349018f762c.png)

# 解説

## 標高PNGタイル

地図の表示と並行して地理院標高PNGタイルを取得しています。その結果、画面上の全ピクセルについて標高値がわかるような状況を作っています。詳しくは [過去記事](https://qiita.com/frogcat/items/7e91d3070a7a8d3e2c94) などをどうぞ。

## 水の移動

Web GL の描画ループをぐるぐる回す中で、以下のような処理をしています。

1. このターンの水の移動方向 (8方向のうちいずれか) をランダムに決めます
2. 全ピクセルについて、流出・流入・現状維持のいずれかを判定します
3. 流出なら水量を一単位減らし、流入なら水量を一単位増やします
4. ピクセルの総水量に応じてピクセルを着色して描画

やっていることは簡単なのですが計算量が膨大です。ふつうの JS/Canvas では処理できないのですが WebGL なら大丈夫でした。



# まとめ

今年も標高 PNG タイルと WebGL の応用ネタでした。
a=1,b=2,c=3...Rubyなのにカンマ区切りで代入しようとしたあなたへ送る1文字

## Ruby以外触っていると...

Rubyに戻った時、うっかりカンマ区切りで以下のように書いちゃいませんか？
そして、

```Ruby
a = 1, b = 2, c = 3
#=> [1, 2, 3]
a
#=> [1, 2, 3]
```

ってなってビビってませんか？

そんなあなたに送る一文字は`,`です。

```Ruby
a ,= 1, b = 2, c = 3
#=> [1, 2, 3]
a
#=> 1
```

## ところで
そんなの知っているよという方、一瞬、なんでbは[2,3]にならないんだ？
と思いませんか？

多重代入でネストした配列を表現するなら、ちゃんと括弧でくくらないとだから、
`b = (2, c = 3)`
とは解釈されないんですね。

```Ruby
a ,= 1, (b = 2, c = 3)
#=> [1, [2, 3]]
```
【AWS cloud9】cookie を消して、プレビュー画面を表示しようとすると「VFS connecion does not exist」と表示される

# 開発環境
- Windows 8.1 64bit
- Rails 5.0.7
- Chrome 70.0.3538.110

# 状況
ページが読み込めないバグを調査中、バグ再現させようとブラウザのキャッシュを消しても上手くいかない。
そこで「Cookieを消してみたら何か変わるのかなあ・・・」と試してみようと思い立つ。
Chromeで「cookie と他のサイトデータ」を削除し、プレビュー画面を表示しようとすると「VFS connection does not exist」と表示される。
VFS(仮想ファイルシステム)ってEFSの事かなと考えつつ、コネクションに cookie（or セッション？） 使ってるのかなと思ったのでメモ。

# 解決方法
このエラーについては、該当のAmazon EC2インスタンスを再起動すればOK。
Cloud Scheduler + Cloud Pub/Sub + Cloud Functions でGCEのインスタンスの自動起動or停止させてみた

## 経緯

これまでGAEのcronでGCEのインスタンスの自動起動、停止させてたけど、Cloud Scheduler出たからそちらで自動起動、停止の管理できないかと思ってやってみた。

## システム構成

すごい単純

![system.png](https://qiita-image-store.s3.amazonaws.com/0/88290/01a8f21b-2145-64a7-dc59-eacac4e5276e.png)

## 構築手順

### 1. Pub/SubのTopic作成

GCPのコンソールからPub/Subの画面を開いて、switcherという名のtopicを作成します。

![pubsub.png](https://qiita-image-store.s3.amazonaws.com/0/88290/02c479e5-35be-fad7-acbd-f578e43e8ea1.png)


### 2. Cloud Functionsの作成

[uu4k/compute-instances-switcher](https://github.com/uu4k/compute-instances-switcher)

インスタンスの起動、停止を行うFunctionの作成を行います。

今回はCloud Shellからのデプロイを行います。

1. コンソールからCloud Shellを起動
2. githubからリポジトリをcloneしてきてデプロイ

```deploy.sh
git clone https://github.com/uu4k/compute-instances-switcher
cd compute-instances-switcher
./deploy.sh
# APIが有効になってないと有効にするか効かれるのでyを入力
# 2分くらい経てばデプロイ完了
```

![cloudshell.png](https://qiita-image-store.s3.amazonaws.com/0/88290/1e666434-fa6a-6d67-04d8-e68661a3b0cb.png)

#### compute-instances-switcherの解説

compute-instances-switcherはPub/Subからインスタンスの起動or停止の情報と対象インスタンスの名前(ワイルドカード可)をjsonで受け取り、インスタンスの起動or停止を行います。

```pubsub.json
{"switch": "off", "target": "dev-*"}
```

今回のものはインスタンス名しか指定できませんが、インスタンス一覧の取得APIのフィルターパラメータをカスタマイズすればlabelなど他の情報での対象指定もできるので、このあたりは必要に応じて変えてみてください。

### 3. Cloud Schedulerの設定

1. コンソールからCloud Schedulerの画面を開いてCREATE JOBのリンクをクリック
2. 初回だとリージョン選択してと言われるので日本リージョン選択
3. JOBの詳細を入力する(下記参照)

- Name: switch-on(自由)
- Description: (自由)
- Frequency: (起動させたいタイミングをCRONのフォーマットで指定)
    - 平日9時の場合は `0 9 * * 1-5`
- Target: Pub/Sub
- Topic: switcher
- Payload: `{"switch": "on", "target": "dev-*"}`
    - switchがonなら起動、offなら停止のためのジョブになる
    - targetはインスタンス名を指定(ワイルドカード可)

![scheduler-region.png](https://qiita-image-store.s3.amazonaws.com/0/88290/915c9fb5-553e-1678-49db-c4be6088cf79.png)
![scheduler.png](https://qiita-image-store.s3.amazonaws.com/0/88290/15a20972-5fea-2cf0-06a8-2a15c24209b9.png)


### 4. 動作確認

Cloud Schedulerの画面から手動実行ができるので、手動実行して対象インスタンスがちゃんと起動or停止するか確認できます。

![scheduler3.png](https://qiita-image-store.s3.amazonaws.com/0/88290/2425bbb7-f324-c6e9-4a73-27317b3e35ce.png)

うまくいかない場合は、Cloud Functionsの画面からエラーの発生有無やエラーログの確認ができるので、そちらで原因を調査してみましょう。

## あとがき

pythonのAPI Clientの使い方につまった以外は割と簡単にできた。今回の件以外でも簡単な定期実行ジョブにも使えそう。

ただ、Cloud Schedulerの設定変更ができない(毎回削除・作成)のでそのあたりが面倒くさい。

あと、はじめFunctionsを実行するServiceAccoutにcompute.startとかの権限与えないといけないのかなと思ってたけど今回は必要なかった。やりたいことによっては権限エラー出るかもしれないのでそのあたりは確認が必要そう。
【Ruby on Rails】Active Recordについて【プログラミング学習100日目】

# はじめに
- プログラミング学習を開始して3ヶ月の初学者が、Ruby on Railsの学習を進めていく中で気になった点を調査、言語化することで知識の定着・深化させることを目的とした記事です。
- 今回は[Ruby on Rails ガイド](https://railsguides.jp/)や[Ruby on Rails 5 アプリケーションプログラミング](https://www.amazon.co.jp/Ruby-Rails-5%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4774188832/ref=sr_1_1?ie=UTF8&qid=1543902179&sr=8-1&keywords=rails+%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)を中心に勉強を進めながら、よく分かっていないまま使っていたActive Recordについて、概要を簡潔にまとめました。

# Active Recordの概要
> Active Recordとは、MVCで言うところのM、つまりモデルに相当するものであり、ビジネスデータとビジネスロジックを表すシステムの階層です。Active Recordは、データベースに恒久的に保存される必要のあるビジネスオブジェクトの作成と利用を円滑に行なえるようにします。Active Recordは、ORM (オブジェクトリレーショナルマッピング) システムに記述されている「Active Recordパターン」を実装したものであり、同じ名前が付けられています。

- 上記内容を初学者の自分なりに咀嚼し、分かりやすく書き換えると以下のようになりました。

 - Active Recordとは、データベースとやり取りするときに使われるメソッドなどが用意されているもの

 - ORMとは、オブジェクト指向言語とリレーショナルデータベースとの橋渡しを受け持つシステムのこと

 - Active RecordはORMを利用することにより、インピーダンスミスマッチを防ぎ、また、SQLを直に実行することなく簡便にデータを取り出すことが可能となっている

（ORMのイメージ図）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/307533/cd91f33e-4262-4be4-0ea4-5f7918c3630b.png)

- また、Active Recordの機能の中でも重要なのは下記5項目とのことです。（詳細を書いていくと長くなりそうなので、以下に関してはまたの機会にまとめて行こうかと思います。）

>
1. モデルおよびモデル内のデータを表現する
2. モデル間の関連付け(アソシエーション)を表現する
3. 関連するモデルを介した継承階層を表現する
4. データがデータベースに永続的に保存される前に検証(validation)を行なう
5. オブジェクト指向の表記方法でデータベースを操作する

# まとめ
Active Recordを理解する上で、まずは以下3つのポイントを押さえておく必要があると分かりました。

1. Active Recordとは、データベースとやり取りするときに使われるメソッドなどが用意されているものである
2. ORMとは、オブジェクト指向言語とリレーショナルデータベースとの橋渡しを受け持つシステムである
3. Active RecordはORMを利用することにより、インピーダンスミスマッチを防ぎ、また、SQLを直に実行することなく簡便にデータを取り出すことが可能となっている
[ruby]seleniumでTwitterに自動ログイン、自動ツイート

この記事は学生団体P&DのAdventCalendar2018 4日目の投稿です。

# はじめに
当初はTwitterAPIを使った簡単なWEBアプリケーションを開発して、それを記事にしようと思ったのですが、それを思いついたのがこの記事を書く前日で、TwitterAPIの使用を認可されるまでに数日かかるようなので惜しくも断念...
(追記： いざTwitterAPI登録してみると、登録自体はめんどくさいけど一瞬で認可された。)

他にネタもなかったので、憎きTwitterAPIを使わずにseleniumを使って無理やりTwitterにログインして、自動ツイートすることにした。

# seleniumのinstall
まずはgemのseleniumをインストールします。

```
> gem install selenium-webdriver
```
# chromedriverのダウンロード
[chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads)をダウンロードします。
ダウンロードしたchromedriverは以下のようにrubyのbinaryと同じディレクトリ内に配置します。

```
> which ruby
/Users/username/.rbenv/shims/ruby

> mv chromedriver /Users/username/.rbenv/shims/
```

# 実装

```ruby:tweet.rb

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

url = 'https://twitter.com/login?lang=ja'

# Twitterログインページに移動
driver.get url

# Twitter登録情報
email = "hogehoge@example.com"
password = "xxxxxxxx"

# Twitterにログイン
driver.find_element(:xpath, '//*[@id="page-container"]/div/div[1]/form/fieldset/div[1]/input').send_keys email
driver.find_element(:xpath, '//*[@id="page-container"]/div/div[1]/form/fieldset/div[2]/input').send_keys password
driver.find_element(:xpath, '//*[@id="page-container"]/div/div[1]/form/div[2]/button').click

sleep 1

# ツイートする内容
message = "WoW"

# ツイート
driver.find_element(:xpath, '//*[@id="tweet-box-home-timeline"]').send_keys message
driver.find_element(:xpath, '//*[@id="timeline"]/div[2]/div/form/div[3]/div[2]/button').click

sleep 1

# 終了
driver.quit
```

# 実行
```
> ruby tweet.rb
```

実行するとseleniumで制御されたchromeが開き、以下のように勝手にTwitterにログイン、ツイートします。

<img width="1185" alt="twitter_login.png" src="https://qiita-image-store.s3.amazonaws.com/0/199827/087f846f-2266-6f55-4471-36d3c280076b.png">
<img width="1278" alt="スクリーンショット 2018-12-04 20.15.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/199827/8a5fa2ca-7d6b-dfde-c897-9f244c9f8ff9.png">
<img width="1283" alt="スクリーンショット 2018-12-04 20.15.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/199827/faf4f4cd-241d-c5d6-4278-b271d7ad07ce.png">
<img width="1308" alt="スクリーンショット 2018-12-04 20.16.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/199827/cb0270bc-8a0c-8022-254a-3820aa09da76.png">

無事、投稿ができました！👏

# 詰まったところ
### ログイン画面でのElementの指定にcssを使うとエラーが出る
最初は以下のように、nameで指定していたのですが、

```
driver.find_element(:name, "session[password]").send_keys password
```

このようにelementがインタラクティブじゃねぇと怒られる。

```
element not interactable (Selenium::WebDriver::Error::ElementNotVisibleError)
```

試行錯誤した結果、xpathで指定してあげるとうまく動いた。

```
driver.find_element(:xpath, '//*[@id="page-container"]/div/div[1]/form/fieldset/div[2]/input').send_keys password
```
なぜだ!?!?

# おわりに
絶対、Twitterの規約に反してるよね...
Next.jsの_app.jsと_document.js

Next.jsで基本的な挙動が理解できたら、次に考えることは実践で使う細かい設定だ思います。つまり、ページ全体の共通の設定や、状態管理、エラーハンドリング（これは明日のアドベントカレンダーでまとめます。）などです。
全体設定のためのインターフェイスとしてNext.jsが用意しているのが、`pages/_app.js`と`pages/_document.js`になります。
それぞれの役割と実際に使われる場面を見ていきましょう。

一部、公式ドキュメントを翻訳しています。
https://nextjs.org/docs/#custom-app


# _app.js

まずは`pages/_app.js`のサンプルです：

```react:pages/_app.js
import React from 'react'
import App, { Container } from 'next/app'

export default class MyApp extends App {
  static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx)
    }

    return { pageProps }
  }

  render () {
    const { Component, pageProps } = this.props

    return (
      <Container>
        <Component {...pageProps} />
      </Container>
    )
  }
}
```

Next.jsはすべてのページにおいて、ページを初期化するために`App`コンポーネントを使用しています。`pages/_app.js`ファイルで`App`コンポーネントをオーバーライドすることで、ページの初期化をコントロールできます。
つまりは以下の設定が可能になります：

- [ページ移動間の固定レイアウト](https://github.com/zeit/next.js/tree/master/examples/with-app-layout)
- [`componentDidCatch`を使用したカスタムエラーハンドリング](https://github.com/zeit/next.js/tree/master/examples/with-componentdidcatch)
- 状態管理ライブラリとの結合
    - [Reduxの `<Provider>`でラップする](https://github.com/zeit/next.js/blob/master/examples/with-redux/pages/_app.js)など

全ページで必要な挙動を書ける場所なので、他にも広告まわりの関数の実行や、[NProgressなどのローディングを設定](https://github.com/zeit/next.js/blob/master/examples/with-loading/pages/_app.js)したりしています。

注意すべき点はNext.jsが用意するページコンポーネントと同じ挙動を取るので、**_app.jsはサーバーサイドでレンダリング（getInitialPropsの実行を含む）され、ライフサイクルのイベントはクライアントサイドでも実行されます。**


## _document.js
まずは`pages/_document.js`のサンプルです：

```react:pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <html>
        <Head>
          <style>{`body { margin: 0 } /* custom!*/`}</style>
        </Head>
        <body className="custom_class">
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}
```

Next.jsのページでは`<html>`や`<body>`などの基本的なマークアップはデフォルトで書かなくてよい設定になっています。もし全体の文書構造をカスタマイズしたいのなら`pages/_document.js`ファイルで`<Document>`コンポーネントを拡張しましょう。

`<head>`タグ内の記述だけでなく、[styled-componentsをSSR時に`<head>`に埋め込む処理なども書けます。](https://github.com/zeit/next.js/blob/master/examples/with-styled-components/pages/_document.js)

注意すべき点は**_document.jsはサーバーサイドのみでレンダリングされ、クライアントサイドでは使われません。onClickのようなイベントハンドラはここに追加しないでください。**すべてのページで共通のコンポーネントは`<App>`コンポーネントに書くようにしましょう。

# おわりに
Next.jsを実践で使う第一歩としての_app.jsと_document.jsを取り扱いました。明日はエラーハンドリングまわりをまとめます。
SSLでできること、できないこと

Webシステムで「セキュリティ」といってまず最初に名前が上がるのがSSLかと思いますが、SSLはどういう攻撃を防げて、どのような攻撃には耐えられないのでしょうか。

## SSL/TLSの概要

SSL/TLSの通信を確立する際には、以下のような処理が行われます（[参考](https://qiita.com/jkr_2255/items/62d8d15d206c60f37d30)）。

* 証明書の提示、相手の認証[^1]
* 暗号鍵の交換

暗号接続が失敗すれば、（きちんと設定して[^2]）接続自体が成立しないということになります。逆に接続が成立すれば、あとの通信は暗号化した通信路上で行なわれます。

## 防げる攻撃

これで防げる攻撃としては、「相手の認証」によるものと「暗号化・認証符号」によるものに分けられます。

* 相手先を認証することによるもの→なりすましや中間者攻撃によって、**一時的に**接続を奪った第三者が本来のサイトになりすますのを防ぐ、EV SSLとして団体名を表示するなど
* 暗号化・認証符号によるもの…第三者の盗聴・改ざんに対する対策となる

## 防げない攻撃

ほぼすべてのセキュリティ対策[^3]は、ある特定の攻撃に対しての対策でしかありません。SSLのプロトコルやその実装に脆弱性が出ることもありますし、そうでなくても以下のような攻撃は成立します。

* SSLのかかっていない、サーバそのもの、あるいはブラウザ～ユーザーに対する攻撃（サーバへの不正侵入、Man in the Browser、ソーシャルエンジニアリングなど）
* SSLに載せたリクエスト上から行える攻撃（SQLインジェクション、XSS、CSRFなど）
* ルート証明書の不正追加（Superfishなど、実際に問題となりました）
* 中間者による通信の切断
* 攻撃者自身が自分のサイトでSSLを適用する、という手段もあります（間違ったドメインで来た人を相手に攻撃を仕掛ける）
* 証明書発行時にDNS偽装を行うことで、不適切なSSL証明書を発行させる



[^1]: もちろんクライアント証明書もSSLで使うことは可能ですが、不特定多数のユーザーがアクセスするWebサイトで使えるものではないので、以下では省略します。
[^2]: 規格上は暗号化なしや認証なしなども存在はしますが、現実問題としてはライブラリレベルで実装していない、あるいは設定で除外しているなどで、実用されることは通常ありません。
[^3]: 「サービスの提供そのものを取りやめる」という、完璧にリスク回避が可能な手段もありますが、もちろん「サービスを提供する」ことが前提であればこの手は使えません。
WikidataからWikipedia記事の下書きを自動生成するMbabel

[Mbabel](https://en.wikipedia.org/wiki/Template:Mbabel)はブラジルのウィキメディアンが開発したテンプレートで、ウィキデータに登録されたデータを元にウィキペディア記事の下書きを自動生成するもの。（[オリジナルのツールページ（ポルトガル語）](https://pt.wikipedia.org/wiki/Wikip%C3%A9dia:Mbabel)、[紹介記事（英語）](https://outreach.wikimedia.org/wiki/GLAM/Newsletter/August_2018/Contents/Brazil_report)）

これまでウィキペディアからinfoboxの内容などをウィキデータにインポートすることはよく行われてきたが、これはその逆。ウィキデータに登録された項目でまだウィキペディア記事になっていないものを選んで、ウィキペディア記事の下書きをサンドボックス内で作成する。以後は通常のウィキペディア記事作成手順通りだ。jawikiではまだ使えないようだが、enwikiでは使えるようになっているので以下にひとつ試してみる。

喜多川歌麿の版画「婦女人相十品　文読美人」は[ウィキデータ上にあって（Q番号：Q18689402）](
https://www.wikidata.org/wiki/Q18689402)enwikiに無いので、enwiki上の自分のsandboxページに以下のように記述する。頭にQの付いた数字はウィキデータ項目の識別子で、この部分を適宜入れ替えて使用する。

`{{Mbabel
|1 = Q18689402
}}`

これをプレビューすると以下のように赤くリンク切れ表示されるのでこれをクリック（ウィキデータ上で英語のタイトルは「Untitled」となっているのでそれが表示されている）
![sandbox_preview_enwiki.png](https://qiita-image-store.s3.amazonaws.com/0/35320/4947bd38-c0b6-8be1-7c10-be06005b20b1.png)

[英語記事の下書き](https://en.wikipedia.org/w/index.php?title=Draft:Untitled_(Kitagawa_Utamaro)&action=edit&preview=yes&redlink=1&editintro=Template:Mbabel/intro&preload=Template:Mbabel/MET&preloadparams%5b%5d=Q18689402)がinfoboxや出典などとともに表示された。
![Draft Untitled  Kitagawa Utamaro .png](https://qiita-image-store.s3.amazonaws.com/0/35320/da14c4f9-6da8-fde3-cca7-8e08851b611f.png)

単体記事を書くのであれば、過去に書いた記事や分野にあったひな形をコピーして使うのとさほど変わりはない。しかしながら使い方によっては2点ほどメリットが考えられる。

1.効率性
類似の記事、例えば市内の小学校の記事を全て整備しようとする時などに、

- 主要項目をCSVで作成
- ウィキデータに一括登録
- Mbabelで下書き作成
- サンドボックスで編集して正式版へ

といった流れで作業すればウィキデータとウィキペディアの双方に登録しつつ、結果的にはひとつずつ記事を書くより効率的にやれるのではないだろうか。もちろん効率だけが全てでは無いことは言うまでもない。

この手順を洗練させてウィキデータの候補項目を種類ごとにリストアップして、リンク切れに見える赤いタイトル文字のワンタッチだけで下書きを作れるようにしたのが[メトロポリタン美術館の例](https://en.wikipedia.org/wiki/Wikipedia:GLAM/Metropolitan_Museum_of_Art/Artworks)。
![Wikipedia GLAM Metropolitan Museum of Art Artworks   Wikipedia.png](https://qiita-image-store.s3.amazonaws.com/0/35320/4d8f45dc-a7c5-f4b9-28b5-0667a9110980.png)

2.他人の文章コピペの懸念が減る
上記の実例では本文の記述が少ないが、テンプレートの作り方によっては本文もかなりの部分自動生成できることが予想される。
参考文献から事実情報（学校であれば創立年、住所、モットー、公式サイトなど）を抽出してウィキデータに登録し、それらを元に主観の混じらない文章を自動生成する、という流れはウィキペディアンなら誰でも頭の中でやっていることに相当するのではないだろうか。この部分は経験の浅い人にとっては最初の関門である。それを曖昧さなしに機械的な作業にブレイクダウンできるので、とりわけ不慣れな方には他人の文章をうっかりコピペしてしまう懸念が減るのではないだろうか。

jawikiでも使えるようになることを楽しみにしている :)
CocoaPodsとCarthageの両方に対応した自作Swiftライブラリを作る


- Swiftの自作ライブラリを作る
- そのライブラリをCocoaPodsとCarthageに対応させる

以下の例ではライブラリ名を```MyLib```としてます．

# プロジェクトを作成する

ライブラリの開発と公開するためのプロジェクトを作成します．ファイル構成は以下のように作ります．
<img width="309" alt="スクリーンショット 2018-12-04 19.52.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/4e542a1b-6cb4-29bf-cc94-62d3ccabecc9.png">
XcodeのProjectの新規作成でCocoa Touch Frameworkを選びます．
<img width="736" alt="スクリーンショット 2018-12-04 19.31.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/eedec036-f379-7969-326b-33c2eef3024f.png">
<img width="732" alt="スクリーンショット 2018-12-04 19.32.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/27282ec6-7cb8-5ddf-ebf3-b1723d45e785.png">
ライブラリの検証のために Target ```Example``` を追加します．
<img width="479" alt="スクリーンショット 2018-12-04 19.32.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/9be9f6f4-6c04-14bf-1ede-a055a8fcb5b5.png">
<img width="732" alt="スクリーンショット 2018-12-04 19.33.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/afd8cc80-4531-7e33-93fe-597e98ac630b.png">
<img width="732" alt="スクリーンショット 2018-12-04 19.42.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/80cdbe87-0615-e933-1cf0-ce6da84e4679.png">
```Example``` の General の Linked Frameworks... にて，```MyLib.framework``` を追加します
<img width="776" alt="スクリーンショット 2018-12-04 19.34.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/194ac927-2fed-b484-ea87-2b509d5c7c80.png">
```Example``` 内で ```import MyLib``` を読み込めば，```MyLib``` で作成したクラスなどを実行することができます．
<img width="700" alt="スクリーンショット 2018-12-04 19.44.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/91b9b28b-af34-0e0c-48a5-20be3bacf45b.png">

作成したプロジェクトの ```MyLib``` でライブラリを開発して，```Example``` 内で検証およびサンプルコードを書いていきます．開発が終わったら，プロジェクトをGithubにpushします．

# Carthageを設定する

ライブラリの schemeをsharedにします（最近は最初からsharedになっている？）．そして，以下のコマンドで Carthage 向けにビルドを行います．

```
$ carthage build --no-skip-current
```

その後，pushして，releaseタグを設定すれば完了です（更新時も同様）．


<img width="728" alt="スクリーンショット 2018-12-04 20.14.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/24345/8e7ab7ee-92a4-0ba8-ccf0-7e504332e049.png">


# CocoaPodsを設定する

ユーザー登録を行う．このセッションの効期限はよく分からないですが公式サイトを見ると端末ごとに保存される感じでしょうか（ [CocoaPods Guides - Getting setup with Trunk](https://guides.cocoapods.org/making/getting-setup-with-trunk.html)）

```
$ pod trunk register {email} '{name}'
```

ライブラリにCocoaPodsを設定する．

```
$ pod spec create https://github.com/{user}/{repo}
```

生成されたpodspecファイルを編集します

```
$ pod lib lint {repo}.podspec
```

podspecファイルの確認を行い，完了したら以下で登録します．

```
$ pod trunk push {repo}.podspec
```

更新するときは，podspecファイルのversionを書き換えて，再びpushする．


# 参考

- [Swiftでライブラリを公開する - Qiita](https://qiita.com/morizotter/items/2e45f8f94c1010ebd69f)
- [CocoaPods, Carthage対応の自作ライブラリをアップデートする方法 - Qiita](https://qiita.com/HideakiTouhara/items/3e261541cc1deda1d7cf)
Unityで伝える思い

Hello, World! ちぇるです．
この記事はLife is Tech! Tokai Mentors Advent Calendar 2018 4日目の記事です.

#はじめに
Unityと聞いて真っ先に思い浮かべるのは「ゲーム作りのソフト」です．
あらかじめ物性が定められており，AssetStoreでクオリティが高い素材もImportできます．
そんなUnityだからこそ，ゲーム以外にも応用できるのでは・・・ 
そんな訳でこの記事ではUnityで開発したゲームの特殊な応用例についてご紹介します．

#メンター紹介ビンゴ

最初に紹介する例は，僕が現在作っているビンゴマシーンです．
ただのビンゴマシーンではなくメンターの名前を使ったビンゴになっており，
メンターの紹介を見ることができます．

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.amazonaws.com/0/248631/86e3cfc0-7664-7d68-f1bf-55be867f9d40.gif)


ビンゴマシーンを回す　▶︎ 球が出る　▶︎ メンターの紹介文がでる
といった 流れになっています．

このビンゴは自分が所属していたサークルの同窓会で行なっていた「名前ビンゴ」から発想を得ました．
名前ビンゴとはビンゴで扱う数字をビンゴ参加者の名前にしたものです．
ビンゴのマスに参加者の名前を埋めるためにはその人にサインをもらわなければいけません．
よ知らない人とも会話してもらう目的で行なっていました．

そのときのビンゴはスクリーン上ではなく
実際のビンゴマシーンを回して行なっていました．
従って出た目の人の紹介は口頭なので，
話に花が咲いている人は紹介を聞いていないということもありました．

しかしUnityでビンゴマシーンを作ることで
出た目の人の紹介文を画面に表示することができます
またビンゴマシーンを人に回してもらえば
ビンゴを行わなかったとしても仲間を紹介することができます．
また自分が仲間に抱く印象を仲間にも知ってもらいたいという思いもありました．

このビンゴは「この人に仲間を紹介したい」「仲間に自分が抱いている印象を知ってほしい」という思いで作り始めました．

#誕生日のOPムービー
次に紹介する例はメンターが僕の誕生日の日に送ってくれた映像です(感謝)

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3136303434362f65313361376264362d346231392d363465342d653962612d6131663439623234393564372e676966.gif](https://qiita-image-store.s3.amazonaws.com/0/248631/d77fdc9b-fa9d-2936-d7c8-474fc51d6495.gif)


上の映像は誕生日の動画のOPで用いられており，
グッとテンションも上がりました．
映像はUnityのプロジェクト「ユニティちゃんライブステージ！ -Candy Rock Star-」を使っています．

誕生日じゃなくても盛り上がる演出だったし，
何より時間をかけて作ってくれたことが嬉しかったです．

#最後に
この記事ではUnityで開発したもので特殊な応用例について紹介しました．
上で紹介した二例は別にUnityのソフトじゃなくでも作れます．
結局この記事でなにが言いたいかというと
「ゲームを作ること」は手段であって目的ではないということです．
世に出ているUnityで作られた有名なゲームだって
何かしら人に伝えたい思い，して欲しい行動があって開発されていると思います．

ここまで記事を読んでいただきありがとうございます．
「どんなゲームを作ろう」と悩んでいる方、まずは自分がやりたいことに目を向けて下さい．
やりたいこととをUnityでできる喜びをぜひ感じて欲しいなと思います．

#参考記事
「ほっそー生誕祭OPの裏側」
https://qiita.com/netty/private/77575ab998a74cb21be2
便利なenum　初心者→中級者へのSTEP5/25

#便利なenum
**はじめに**
[前回の記事](https://qiita.com/kamohicokamo/private/ebbe4aa01c92a8ff4c78)でenumが出てきましたね。てな訳でenumです。僕もあんまり触ったとこないです。そんなenumの何が便利なのか調べていきましょう。

##enumの活用例##
`enum`とは簡単にいうと、　Railsのintegerクラスの属性の整数値にテキストでアクセスできる様にしてくれるものです。

```schema.rb
ActiveRecord::Schema.define(version: 20181202084037) do

  create_table "users", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "name"
    t.string "email"
    t.string "user_id"
    t.integer "status"
    t.text "discription"
  end

end
```
上の`User.rb `にてstatus属性で会員の状態を判断する場合。enumを使わない場合。数字で判断する羽目になり、可読性が悪いです。

```member_status.rb
  if @user.status == 0
    #通常会員の処理
  elsif @user.status == 1
    #プレミアム会員の処理
  end

```
コメントがないとなんの処理をしているかわかりませんよね？

ではenumを使ってみましょう。
まず`User.rb`にて`status`属性をenumとして定義します。

```User.rb
class User < ApplicationRecord

  enum status: {
    normal:  0, #通常会員
    premium: 1, #プレミアム会員
  }

end
```

これで`status`属性にテキストの`normal`と`premium`でアクセスできます。

```member_status.rb
  if @user.normal?
    #通常会員の処理
  elsif @user.premium? 
    #プレミアム会員の処理
  end

```

これなら、コードを見るだけでここでなんの処理が書かれているかわかりますよね！

##enumで使えるメソッド

```User.rb
class User < ApplicationRecord
  enum status: {
    normal:  0, #通常会員
    premium: 1, #プレミアム会員
  }
end

  user.premium!   # => userのstatusをpremiumでupdateする
  user.premium?   # => true
  user.status     # => "premium"
```

上記３つのメソッドは基本的によく使うであろうもの、下記のはある状況下で必要なもの。

```User.rb
class User < ApplicationRecord
  enum course_status: {
    normal:  0, #通常会員コース
    premium: 1, #プレミアム会員コース
  }, _suffix: true

  enum age_group: {
    normal:  0,  #通常
    minority: 1, #未成年
  },  _prefix: :age_group
end

  user.normal_course_status!   # => userのcourse_statusをnormalでupdateする
  user.normal_course_status?   # => true

  user.age_group_normal!   # => userのage_groupをnormalでupdateする
  user.age_group_normal?   # => true
```

上の例では`course_status`と`age_group`で`normal`が被っています。その場合は`_suffix:`か`_prefix`を用いて接頭辞・接尾辞を指定できるようにします。
`_suffix:`が接尾辞、`_prefix`が接頭辞です。


##enumでの注意点##
明示的に対応する整数値を指定しないと、識別子のリストの先頭から順に0,1,...と対応づけられていくので、以下の様に明示的に記載してない場合、例えば`cat`を削除する場合、`kamo`の対応する整数値が3から2になってしまいます。しかしDBに保存された値は3なので、対応する識別子がなくnillになってしまいます。


```User.rb
class User < ApplicationRecord
  enum course_status: [pig:, dog:, cat:, kamo:]
end
```

上記から猫ちゃんを削除する時、その後、明示的に元の整数を指定してあげましょう。

```User.rb
class User < ApplicationRecord
  enum course_status: {pig: 0, dog: 1, kamo: 3}
end
```

というより最初から明示的に書きましょう。


##まとめ
いやあ便利、非常にコードが見やすくなります。是非使っていきましょう。
明日はscopeとやらについて掘り下げるンゴ

##参考にしたの

ActiveRecord::Enum
https://api.rubyonrails.org/v5.2.1/classes/ActiveRecord/Enum.html

ActiveRecordのenumで気をつけたい３つのポイント
https://tech.misoca.jp/entry/2015/08/10/132419
DevRel が海外スタッフとやり取りする際によく見かける略語など

この記事は [DevRel Advent Calendar 2018](https://qiita.com/advent-calendar/2018/devrelmeetup) の、11日目の記事です。

DevRel 担当者として海外の技術者とやり取りする際に、ひと目ではよくわからない、略語に出くわすことがあります。

ここでは、自分が「なんだこれ？」と思ったことがある略語や、メールで使うフレーズなどをランダムに書いてみます。


###  AFAIK

As far as I know,「自分が知っている範囲では」の略となります。
「As far as」は「…の限り」という意味で、他の単語と組み合わせることで別な言い回しになります。
例えば

- As far as the law allows
    - 法律が許す限り
- As far as the eye can reach
    - 目に見える限り(目が届く限り)

など。


### IMO(IMHO)

In my opinionの略で「私の見解としては」という意味です。自分の意見を表す場合に使います。
IMHOだと In my humble opinion となり、「愚見ではありますが」など、よりへりくだった感じになります。

### SSIA

Subject says it all、「件名(タイトル)が全てです」という意味です。
BTSなどにissueを登録する際、もしくはメールで不具合を報告する際など、内容をタイトルに書き、本文は「SSIA」だけで済ますケースがあります、


### TBD
To be determined, 「後で決める」という意味の略です。
資料や仕様書が完全に完成していないが、後で決めても良い箇所の場合、「TBD」とだけ書いて、全体像を先に共有する場合に使われたりします。


### LGTM
Looks good to me. 「大丈夫のようです」という意味の略語です。
コードレビューやクライアントへ回答文章のレビューなど、レビューの結果が良い場合に使います。

### TIA
Thanks in advance, 「ありがとう！」という意味の略語です。
何かを頼むときに末文として使う場合があります。

ある意味、相手の了承を得ずに「やってくれるよね、ありがとう」という意味合いがあるので、親しい仲以外に使う場合は要注意。


### Many Thanks
略語ではありませんが、日本人にはあまり馴染みがない表現ということでご紹介。
Many thanks は「大変感謝します」「多謝！」という意味になります。

最初に見たときはちょっと不思議な言葉に見えたのですが、メールの末文としてはよく使われるようです。

余談ですが、手紙の英例文では、末尾に「Best Regards」や「Sincerely」という言葉を見かけることがありますが、メールで書くとずいぶんかしこまった言い方で、かなり改まった場合でないと使われないようです。

(以前海外のスタッフ送ったメールを「Sincerely」で締めたところ、「ずいぶんかしこまってるね」的な返信があり、そういうものなのか、と思ったことがありました)

以上、メールや英語掲示板でよく見かける略語などについて書いてみました。

(※本文章は、自分が以前に[会社ブログに投稿した内容](https://blog.sixapart.jp/2016-10/lgtm-github.html)のリライト版となります)
SimpleCalendarを用いて、カレンダー内にスケジュールを表示させた

#はじめに
　　
　Simplecalendarというgemを使用して表示したカレンダー内に、スケジュール情報を表示させる際、苦労しましたので備忘録として残します。

よろしければ参考にしてください。


#SimpleCalendarとは
　　viewにコードを記述することにより、カレンダーを表示させる gemです。詳しくは下記URLをご覧ください。


　　　参考：http://excid3.github.io/simple_calendar/


##カレンダー内に、meetingモデル内のすべてのレコードを表示させる

これは、参考URLのままでうまくいきました。
※Meetingモデルはscaffoldを用いて作成

```ruby:users.show.html.erb
<%= month_calendar events: @meetings do |date, meetings| %>
  <%= date %>

  <% meetings.each do |meeting| %>
    <div>
      <%= meeting.name %>
    </div>
  <% end %>
<% end %>
```
```ruby:users_controller.rb
def show
  @meetings = Meeting.all
end
```

##meetingモデル内の指定ユーザのレコードを表示
find_byメソッドでは、レコードが１件しか取得できないため、whereメソッドを使用。
※meetingモデルには、useridカラムを追加しました。

```ruby:users_controller.rb
def show
  @meetings = Meeting.where(userid: params[:id])
end
```
##上記のレコードに加え、[指定ユーザーと相互フォロー状態にあるユーザー]のレコードを表示
ここで苦労しました。

①インスタンス@meetingsに「指定ユーザー」のスケジュールを代入
②「①で作成したインスタンス@meetings」に対し、「指定ユーザーと相互フォロー状態にあるユーザー」のスケジュールを追加

上記の流れでコーディングを進めましたが、下記の問題が発生しました。
・pushメソッドでデータを追加しようとしたがうまくいかない。

原因は２つありました。
・whereメソッドの戻り値はActiveRecord_Relationのインスタンスなので、Arrayクラスのメソッドであるpushメソッドは使用できない。
　　　→to_aryメソッドを用いてArrayクラスに変換することにより解決。

・to_aryメソッドにより変換したインスタンスは「freezeプロパティがtrue」となっているため、編集が効かない。
　　→dupメソッドを用いて、コピーを作成することにより解決。


```ruby:users_controller.rb
  def show
    #[表示しているユーザー]のMeetingモデルのレコードを取得
    @meetings = Meeting.where(userid: params[:id]).to_ary().dup()
    
    #[表示しているユーザーと相互フォロー状態にあるユーザー]のMeetingモデルのレコードを追加
    relationships_each(params[:id]).each do |relation|
      tmp = Meeting.where(userid: relation).to_ary

      tmp.each do |record|
        @meetings.push(record)
      end
    end
 
  end

  private

    def relationships_each(userid)
      #[指定されたidのユーザー]と相互フォロー状態にあるユーザーの一覧を配列形式で返す
      relationships_follower = Relationship.where(follower_id: userid).pluck(:followed_id)
      Relationship.where(followed_id: userid).where(follower_id: relationships_follower).pluck(:follower_id)      
    end
```


参考URL：　
https://qiita.com/7coco/items/b08c842aece4b7f28f55　
https://qiita.com/tsuchinoko_run/items/f3926caaec461cfa1ca3
https://qiita.com/iwamot/items/2ddf8de09d5dbcad2df9
たった2つのコマンドで1000枚の画像をダウンロードする

機械学習のための学習データセットとして、はたまた観賞用として、たくさんの画像が欲しくなる時があると思います。
そんな時に便利なPythonパッケージをGitHubで発見したので、紹介します。

# 結論

せっかち方のために、まずは結論から。
ターミナルを開き、以下の2つのコマンドを順に入力することで、猫の画像が1000枚ダウンロードされます。
![cat.PNG](https://qiita-image-store.s3.amazonaws.com/0/131737/d3d4f432-9b5d-f18a-4754-7d2921202736.png)

```
pip install google_images_download
googleimagesdownload -ri -cd "chromedriver.exe" -l 1000  -k "猫"
```

ただし、**準備しなければ2つ目のコマンドでエラー**が出ます。
# 準備

- Google Chromeをインストールする

説明不要だと思います。

- Pythonをインストールする

これも説明は省略します。筆者は[公式のインストーラー](https://www.python.org/downloads/)でインストールしました。

- chromedriverをダウンロードする

使用するPythonパッケージの動作に必要なものです。以下リンクからダウンロード可能です。
http://chromedriver.chromium.org/downloads
ダウンロード後は、カレントディレクトリ(ターミナルが開いているディレクトリ)に解凍してください。

- コマンドを入力

準備は完了です。2つのコマンドを入力してください。

```
pip install google_images_download
googleimagesdownload -ri -cd "chromedriver.exe" -l 1000  -k "猫"
```



# 解説

- コマンドその1

```
pip install google_images_download
```

[**google_images_download**](https://github.com/hardikvasa/google-images-download)というPythonパッケージをあなたのPython環境にインストールしています。

このパッケージでは、Google画像検索を利用して画像をダウンロードすることができます。

Python-2.xと3.xの両方のバージョンに互換性があるようです。

- コマンドその2

```
googleimagesdownload -ri -cd "chromedriver.exe" -l 1000  -k "猫"
```

**google_images_download**では、オプションで何の画像を、どのようにダウンロードするかを指定することができます。

オプションとは、 **-ri** のように **-** を付けてパッケージに渡される引数のことです。

**-ri**
related_imagesの略で、大量の画像(100枚～)をダウンロードする場合に必要なようです。

**-cd "chromedriver.exe"**
chromedriverの略で、**-ri**オプションを使用する場合に必要なようです。**-cd**に続いて、準備でダウンロードした**chromedriver.exe**へのパス(場所)を入力する必要があります。このパスは、絶対パスでも相対パスでも良いようで、今回は相対パスで入力しています。

**-l 1000**
limitの略で、ダウンロードする画像の枚数上限を設定できます。今回は上限を1000枚に設定しています。

**-k "猫"**
keywordsの略で、Google画像検索に使うキーワードを設定できます。今回は**猫**に設定しています。

これ以外にもたくさんのオプションが用意してあるので、別な使い方をしたい方は、[README(英語)](https://github.com/hardikvasa/google-images-download/blob/master/README.rst)を見て試してみるといいと思います。

# 感想

検索関係のAPIや、有名なスクレイピング関係のPythonパッケージでは、ここまで簡単に、大量の画像を入手することは難しいと思うので、**google_images_download**を作成してくださった方には感謝したいです。

筆者は、これで学習データを収集して、Google Cloud Auto MLで分類モデルを作成し、ユーザの入力した画像を分類できるようなWebアプリを作ろうと考えています。
Visual Studio CodeでLatex使えるようにしたらウホウホ論文書けた話

# ※WindowsでTexがインストールされている前提です．

# ウホウホした内容

 - ショートカットキーが使えまくる(Ctrl+[とか便利)
 - インデントとかカッコとか自動でやってくれる
 - 環境名打ったらbegin,end自動で出してくれる
 - 参照の候補を出してくれる  
  - labelで書いてrefで呼び出す
  - bibtexで書いてciteで呼び出す
 - 数式プレビューしてくれる(地味に嬉しい)

# セットアップ
色んな拡張機能を入れて，コンパイルできるようにしていきます．

## 拡張機能のインストール

1.PowerShellを管理者で起動します．
2.実行ポリシーを変更します．下記コマンドを実行すると変更するか聞かれるので`y`しておきます．

```
Set-ExecutionPolicy RemoteSigned
```

3.拡張機能を一気にインストールします．コピペでいけます．

```
code --install-extension coenraads.bracket-pair-colorizer
code --install-extension kisstkondoros.vscode-gutter-preview
code --install-extension oderwat.indent-rainbow
code --install-extension sgryjp.japanese-word-handler
code --install-extension torn4dom4n.latex-support
code --install-extension james-yu.latex-workshop
code --install-extension christian-kohler.path-intellisense
```

4.実行ポリシーを元に戻します．下記コマンドを実行すると変更するか聞かれるので`y`しておきます．

```
Set-ExecutionPolicy Restricted
```

## VS Codeのコンパイル設定
ここまで来たら[【Visual Studio CodeでTeXのコンパイルをできるようにする方法】](https://qiita.com/SUZUKI_Masaya/items/7fb5509006163e7e671f)のコンパイル設定をなぞっていきます．
少しだけ補足しておきます．

  1. VS Codeを起動します．
  2. `Ctrl`+`,`でユーザ設定を起動します．
  3. 検索窓の下の`・・・`を押してsettings.jsonを開きます．

あとは思いっきり書いてある通りにやりました．

## おまけのスニペット

スニペット入れたらさらにウホウホできたのでおまけで置いときます．
`ファイル`->`基本設定`->`ユーザ スニペット`->`latex`
これでjsonファイルが開かれるのでそこにこれをコピペです．
みなさんのtexの環境で登録してください．

```latex.json
"include figure": {
	"prefix": "figure",
	"body": [
		"\\\\begin{figure}[tb]",
		"\t\\\\begin{center}",
		"\t\t\\\\includegraphics[height=5.6cm]{$1.eps}",
		"\t\t\\\\caption{$2}",
		"\t\t\\\\label{$3}",
		"\t\\\\end{center}",
		"\\\\end{figure}",
	],
	"description": "include graphics"
	},
	"include table": {
	"prefix": "table",
	"body": [
		"\\\\begin{table}[tb]",
		"\t\\\\begin{center}",
		"\t\t\\\\begin{tabular}{c|c} \\\\hline",
		"\t\t\t$1&$2",
		"\t\t\\\\end{tabular}",
		"\t\\\\end{center}",
		"\\\\end{figure}",
	],
	"description": "tabular"
},
```
python環境を引っ越しする

# はじめに
pythonを動かしている分析兼開発環境を、サーバー間で引っ越しした。そのときの手順をまとめた。

# 引越し元
## 環境
今回は以下のような環境からの引っ越しを目論んだ。
OS：CentOS 7.4
シェル：bash
python環境：pyenv + miniconda + python3.6

## 作業
### conda環境の保存
```conda create py36 ``` のようにして作っていた環境を以下のようにエクスポートする。

``` bash
conda env export -n py36 > py36.yml
```
### scpするための準備
上で作成したymlファイルを引越し先にscpするための準備として、例えば以下のようなconfigファイルを```~/.ssh```に作成する。

```config
IdentityFile ~/.ssh/<鍵のファイル名>
AddKeysToAgent yes

Host <引っ越し先のホスト名>
  Hostname <引っ越し先のIPアドレス>
  User <引越し先での自分のユーザ名>
```
### ymlファイルを引越し先に送る
先ほと作成したymlファイルを、引越し先のホームディレクトリにscpで送る。

``` bash
scp py36.yml <user_name>@<host_name>:/home/<user_name>/
``` 

# 引越し先
## 環境
今回の引越し先は引越し元と同じサーバー環境であった。ここに引越し元と同じ環境を作ろうとしている。
OS：CentOS 7.4
シェル：bash

## 作業
### pyenvのインストール
ホームディレクトリで以下を実行してpyenvをインストール

```bash
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```
続いて以下のようにbash_prifileを設定する

```bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
```

```bash
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
```
最後に .bash_proifleをsourceしておく。

```bash
source .bash_profile
```


### condaのインストール
ここでは引越し元に合わせて Miniconda をインストールしておく。

```bash
# install
pyenv install miniconda3-4.3.30
pyenv rehash

# check
pyenv versions

# switch global environment
pyenv global miniconda3-4.3.30
```
### condaで仮想環境を復元
通常は ```conda create hoge``` のようにして環境を作成するが、ここでは引越し元から持ってきたymlファイルを使って作成する。

```bash
conda env create -f=py36.yml
```
```conda activate <環境名>``` のようにしてactivateできるようにするため以下のように.bashrcを編集する。これを設定する前に ```conda activate <環境名>```　として実行すれば以下のようなコマンドを含むエラーメッセージが出力されるので、そこからコピペして実行すればよい。

```terminal
echo ". /Users/<user_name>/.pyenv/versions/miniconda3-4.3.30/etc/profile.d/conda.sh" >> ~/.bashrc

source .bashrc
```

最後に、引越し元と同様に仮想環境 py36 をactivateできることを確認しよう。

```terminal
conda activate py36
```
Smarty で連想配列に値を assign する


あんまりいい記事じゃないけど、情報ないので書きます

## やりたいこと

Smarty では連想配列を表現するとき、ドットを使える
でも変数の代入 (assign) のときには使えない

たとえば、
`{assign var="app.hoge" value="$app.fuga.hoge"}`
は内部的には次の処理になる
`$vars['app.hoge'] = $vars['app']['fuga']['hoge']`

取り出すときは、`$vars['app']['hoge']` となるので取り出すことができない

調べてみても内部触るのが多い

```smarty
{php}
$this->_tpl_vars['app']['hoge'] = $this->_tpl_vars['app']['huga']['hoge'];
{/php}
```

## そこで思いついたのがこれ

```smarty
{assign var="app" value=$app|array_merge:$app.fuga}
```

`$app.fuga`に`hoge`がいるので`$app.hoge`で取り出すことができる

## でもこれが使われることはなかった

すごく限定的な使い方だし、
最終的には、配列を使わない構造に PHP 側を直したので使われなかった

おしまい
DXOpalで作ったゲームを無料で公開する

DXOpalはRubyでブラウザゲームを作れるライブラリです。チュートリアルが以下にあります。

- [Rubyで始めるゲームプログラミング \- DXOpal編 \-](https://magazine.rubyist.net/articles/0057/0057-GameProgramingWithDXOpal.html)

ところでゲームができたらみんなに遊んでもらいたいですよね。VPS等を借りるという方法もありますが、今回はお金をかけずに公開する方法として、GitHub Pagesを使ってDXOpal製ゲームを公開する手順を紹介します。gitの使い方を知っていてGitHubのアカウントがあれば簡単に利用できます。

## GitHub Pagesとは

[GitHub Pages](https://pages.github.com/)はGitHubのサービスの一つで、GitHub上のリポジトリにHTMLを置くと公開してくれるというものです。

利用にはGitHubのアカウントが必要です。

- https://github.com/

## リポジトリを作る

https://github.com/new からリポジトリを作ります。Repository nameのところに適当な名前を入れて(今回は「adcal2018」にしました)、Create repositoryを押します。

![スクリーンショット 2018-12-04 18.34.51.png](https://qiita-image-store.s3.amazonaws.com/0/43/e921f7c4-9ddc-6828-9742-6211682a2da0.png)

## 作品をgit pushする

リポジトリができたら、作品を置きましょう。DXOpalでは[スターターキット](https://github.com/yhara/dxopal-starter-kit)を使う方法とdxopalコマンドを使う方法がありますが、いずれの場合も手順は同じです。

以下のファイルをmasterブランチにpushします。

- index.html (必須)
- main.rb (必須)
- dxopal.min.js (必須)
- 画像や音声ファイル(ゲーム内で使う場合)

あとはREADME.txtというファイルを入れておくと、githubのリポジトリ画面を開いたときに最初に表示されます。markdownで書く場合はREADME.mdという名前にします。

## GitHub Pagesを有効化する

GitHub Pagesはリポジトリごとにオンにする必要があります。SettingsタブのOptions欄の下の方に、GitHub Pagesという項目があります。

Sourceのところで「master branch」を選んで、Saveを押します。

![スクリーンショット 2018-12-04 19.09.54.png](https://qiita-image-store.s3.amazonaws.com/0/43/7ee2085c-209f-c528-d7c7-b7d882fd46fc.png)

## アクセスしてみる

Saveできたら、`https://<githubユーザ名>.github.io/<リポジトリ名>/` というアドレスでアクセスできるようになります。

作品が複数ある場合はディレクトリを分けることも可能です。例えば今回は[`04`というディレクトリにファイルを置いた](https://github.com/yhara/adcal2018)ので、アドレスは以下の

https://yhara.github.io/adcal2018/04/index.html

## まとめ

今回はGitHub Pagesを使ってDXOpal製ゲームを公開する方法を紹介しました。昔のGitHub Pagesはgh-pagesブランチを作らないといけなかったりしたんですが、最近はmaster置くような設定もできて、シンプルで良いですね。
Dapps開発をして感じたこと１

弊社では現在CryptoKanojoというDappsゲームを作っています。

Dappsゲームの開発は初めての試みのため、試行錯誤の毎日です。

「こうしておけばよかった」などちょっと出てきたのでまとめてみようと思います。



## 1.　初心者に優しくすべきだった
CryptoKanojoはブロックチェーン技術に多少知識があるエンジニアが企画したプロジェクトです。

前提知識があるエンジニアで企画したため"ウォレットアドレス"はもちろん、"Metamask"や"ERCほにゃらら"など当然知っている人がしかアクセスしてこないだろう前提で設計した箇所が多々でてしまいました。

ただプレスリリースを打てばそれなりにユーザーのアクセスがきますし、上記のような知識を持たいないユーザーもわんさか来ます。

せっかく興味を持ってサイトにアクセスしてくれたのに、サイトには説明情報がほとんどなく、知らない人からしたら意味不明な単語だらけ。

**「さあ！あなたの持っている知識を使って勝手に遊んでください！」**

と言われて遊び方がわからなかったら、二度とサイトにアクセスしてくれない＋Dappsに対するイメージは最悪なものになるでしょう。

そんなのでは新規のDappsゲームユーザーを増やすことができず、Dappsの将来が危ぶまれます。

初心者向けの入り口（チュートリアル等）に力を入れるべきでした。

## 2.　情報公開頻度を上げるべきだった

開発にほとんどリソースを割り当てた結果、開発状況の情報公開に手が回りませんでした。

結果、購入者様からプロジェクトの心配をさせてしまいました（詐欺なのでは？等）。

他Dappsで人気が出ているプロジェクトはSNSやMediumの定期的な投稿はもちろん、MeetUpや色々な勉強会に登壇しています。

情報公開頻度が非常に高く、それが故にユーザーコミュニティも盛り上がって結果沢山のユーザーが集まってきます。

Dappsゲームにおいてはゲーム自体の魅力よりも、むしろ情報発信の頻度が高く、沢山の活動を行っているという点のほうが重要だと確信しました。

（予算内でなんとかしなければならい前提だと）プロジェクトの開発内容をスケールダウンし、もっと情報公開に関する活動にリソースを当てるべきでした。


## 3.　セールの価格をオークション方式にするべきだった

CryptoKanojoのセールは「プレセール」と「クラウドセール」の2回やりました。

どちらも値段付けは固定価格でした。

プレセールの段階では価格設定を安すぎにしたため、一人が複数購入して速攻で完売してしまうなどの問題が発生しました。

MyCryptoHeroesさんのような在庫連動型ダッチオークション方式のような、時間経過と購入アクションによって価格変動する仕組みを取り入れれば、買い占め問題も解決できますし、CryptoKanojoのプロジェクトの売上も上がったと思います。

在庫連動型ダッチオークションはMyCryptoHeroesさんが特許出願中のようなのですが、イングリッシュ・オークション形式（競上げオークション）を取り入れるだけでもずいぶん変わったと思います。


## 4.　ETHの現金化のタイミングをもっと考えるべきだった

CryptoKanojoは会社の１事業としてやっているためPLを作りますが、PLは法定通貨円で引くので、１ヶ月で50%も価格変動するようなETHベースで書いても全くあてになりません。

ETHを月１回月末締めで円に変換するなどのオペレーションを立てた場合は、月初で好調だと思っていても月末に円に変えたら悲惨な結果になったなどがあります。

これが正しい方法なのかはわかりませんが、１日１回のタイミングで円に変えていれば、暴落リスクの回避が取れたかもしれません。

また、他Dappsではステーブルコインのような「法定通貨連動式」のDappsゲーム用ERC20またはERC721を発行したりしているものも目にします。

こちらは法律的に「前払式支払手段発行者」の登録が必要な気もしますので、簡単にそうしよう！とはいかないとは思います。[参考リンク](https://bitdays.jp/news/14085/)

ただ暴落リスクを考えておき、それに対してどう立ち向かうかを事前にもっと考えるべきでした。

## 5.　デバッグ工数を沢山積むべきだった

本番環境（メインネット）でのデバッグが非常に大変でした。

具体的には実際にETHをつかった購入などをする際のGAS設定をデフォルトのままにして、トランザクション承認まで非常に長い時間待たなければなかった等。

Etherscanとの照らし合わせやTrus、TokenPocketなどの数あるウォレットブラウザでの挙動確認等。

通常のWebアプリケーションのデバッグの２〜３倍は見積もるべきでした。

---
ネガティブな記事になってしまったので次回は「こうしててよかった！」といポジティブな記事を書きます
[Vue.js] input要素の入力値を数値変換したいときは number修飾子を使う

##本記事の目的
vueを書いていてどハマりしたので、覚え書き。
初心者向けです。筆者も初心者です。

##どハマり
説明用に簡略化。
input要素にtype="number"を指定して、
入力された数値が0ならアラートを出すよう実装するとします。

```vuejs
<template>
  <div class="root">
    <input type="number" v-model="num">
  </div>
</template>
<script>
  data: function() {
    return {
      num: null
    }
  },
  watch: {
    num: function(newNum) {
      if (newNum === 0) {
        alert("0が入力されています")
      }
    }
  }
</script>
```

これでうまく行くと思ったのですが、0を入力してみるとアラートがでません。

色々デバッグしてみると、入力値が文字列になっていることがわかりました。
HTML5でinput要素にtype="number"を指定したとしても、入力値を取得すると文字列が返ってくるんですね・・・。
newNum === 0 と厳密等価演算子を使用していたので、
"0" === 0 => falseとなり、アラートがでなかったんですね。

（ここで　newNum == 0　なら自動で型変換されてtrueになるのですが、
暗黙の型変換はちょっと怖いので、===でいきたい）

##解決
公式ドキュメントを見ると、ちゃんとのってました！
参照URL：
https://jp.vuejs.org/v2/guide/forms.html#%E4%BF%AE%E9%A3%BE%E5%AD%90

input要素の入力値を数値にするには、通常のJSならparseIntなんかを使うとおもうのですが、
vueにおいてはv-model.numberとするといいらしいです。


```
 <input type="number" v-model.number="num">
```
便利ですね！

※number修飾子はあくまで入力値を数値変換するだけなので、フォームでバリデーションをかける
type="number"も残さねばなりません。

以上です。
Donkey Car Simulator

# 関連Qiita

- [Donkey Carの作り方(RasPi側)
](https://qiita.com/akira-sasaki/items/c37468e88c9bbd739a65)
- [Donkey Car PS3 Joystick(RasPi側)](https://qiita.com/akira-sasaki/items/987ba17060637cff2c3e)
- [Donkey Carで動きそうなラジコン](https://qiita.com/akira-sasaki/items/753106d6ad9f62a31a40)
- [Donkey Carの作り方(Mac側)
](https://qiita.com/akira-sasaki/items/66f31a969712d8dea758)
- [Donkey Carの作り方(Windows側)](https://qiita.com/akira-sasaki/items/dc06b0ca21821fc8ef48)
- [Donkey Car Emulator(Mac側)](https://qiita.com/akira-sasaki/items/5e838b4f5125e25b4523)
- [Donkey Car学習(Mac側)](https://qiita.com/akira-sasaki/items/e0cc64dae5565b38987d)
- [Donkey Car Commandメモ](https://qiita.com/akira-sasaki/items/4097f9bdea46fb654a04)
- [Donkey Car Officialのドキュメント(リンク)](https://docs.donkeycar.com/)
- [AWS DeepRacerまとめ](https://qiita.com/akira-sasaki/items/c29282c281ca274d2691)

コンテンツは、
https://faboplatform.github.io/DonkeyDocs/3.Simulator/2.sim/
にUpdateしています。
バッチ処理システムとストリーム処理システムのコツ

今年胃カメラ初挑戦して泣きそうになった片居木です。いつの間にかエンジニアになって10年以上経ってしまいました。思い返すとプレイドに来る前は主にバッチ処理による集計を書いてました。プレイドに入ってからはもっぱらフロントエンドやリアルタイム集計などのストリーム処理を作る日々です。せっかく両方を経験しているので、それぞれの処理の特徴についてまとめてみたいと思います。

なお、ここでのバッチ処理は、１時間に１度や１日に１度、その時間帯に発生したデータ全部を対象に処理するものをさします。また、ストリーム処理は発生した１データごとに逐次処理するものをさします。また、今回は主に、データの集計処理をするシステムを想定しています。

「ストリーム処理って、バッチ処理の実行間隔を最小まで短くしたものでしょ？」と言われることも多いです。１データごとにバッチ処理を回せば一緒でしょ、ということですね。処理にかかる「コスト」が０の理想的な世界ならばそれは正しいです。ただ、現実世界ではその「コスト」が大きいため、バッチ処理とストリーム処理では全く別のアーキテクチャが使われます。

ここでは、処理のロジックではなく、バッチ処理やストリーム処理を運用面で気をつけるべき「気にするポイント」の違いについて考えてみます。


# バッチ処理は１回の処理に時間がかかる
![batch.png](https://qiita-image-store.s3.amazonaws.com/0/103059/209e72e1-cf61-c0d7-b101-18cb90272a8e.png)


## パイプラインの管理する

バッチ処理はまとめて多くのデータを処理するため、１回の実行時間が長くなりやすいです。複数のバッチ処理でパイプラインを組んでいる場合、１つの処理の実行遅れが他のバッチ処理にも波及してしまいます。そのため、その影響をなるべく早く把握するために、バッチ処理の実行時間アラートを丁寧に設計したり、ジョブの実行状況の可視化をしたりします。そのため、パイプラインの管理を行うOSSのフレームワークも登場しています。

![](https://raw.githubusercontent.com/spotify/luigi/master/doc/user_recs.png)
https://raw.githubusercontent.com/spotify/luigi/master/doc/user_recs.png

- [Luigi](https://github.com/spotify/luigi)
- [Airflow](https://airflow.apache.org/)

## 多くの実行ログを出す

正常な場合でも、入力データがスパイクした場合（セールを行ったとか）、実行時間が急に増えることがあります。この場合、「正常に動いているが長い時間かかっている」のか「途中で失敗しているが、エラー終了していない」のか、見分けがつかなくなります。また、いつ終わるのか見積もれないため、パイプライン上での影響が見積もれなくなってしまいます。そのため、どこまで実行されたかを監視できることが重要になります。私の場合、1000件に1回程度の頻度でプログレスを表示するためのログ（全件○件/現在○件処理済みたいな形）を出力していました。

```perl
print "$line_count / $line_total" if $line % 1000 == 0;
```

また、１回の処理時間が長いため、処理が途中で失敗してしまった時に、再度実行させてみるかどうかの判断が難しいです。外的要因で処理できなかったのか（同時に別の処理が走っていてロックを取得できなかったとか）、データ起因で処理ができなかったのか（データのフォーマットが壊れていたなど）。データが原因の場合は再度実行したところで、同じ場所で処理が失敗するだけです。エラーが起きた状況を再現するにも長い処理時間がかかるので、試しに再度実行するというのは、あまり現実的ではありません。そのため、なるべく実行時のログは大目に出すようにして、エラーが発生した瞬間がどうなっていたのかをなるべく詳細に残すようにしていました。

## 事前に見積もる

バッチ処理の場合、事前に入力データ量がわかっていることが多いです。そのため、実行前にある程度のパフォーマンス計画ができます。時間あたりに必要な処理量がわかるため、そこから必要なインスタンス数が計算できます。事前に十分なシステムリソースを準備をしてから処理実行開始することができます。


# ストリーム処理は待っていられない
![stream.png](https://qiita-image-store.s3.amazonaws.com/0/103059/ec99bef9-a5f5-d3c9-fa81-42b2e101e279.png)

## 流量制御する

ストリーム処理の場合、入力データ量がスパイクした時の変化の幅が格段に大きくなります。スパイクした時のデータ量でも耐えられるシステムにできれば良いのですが、現実的にはスパイク時も耐えられるほどのシステムは、通常時にはオーバースペックとなり、コスト増になります。そのため、多くの場合はシステム内に流れるデータ量を均等化する、という方法が取られます。

例えば、ストリーム処理のパイプラインの間にジョブキューを入れることで、流量が増えた場合でも一時的にジョブキューに入力データを貯めることで、ストリーム処理自体のデータ処理量はほぼ一定を保つことができます。

## ログはエラーになってから

再実行することに時間がかからないため、実行ログは「エラーが発生してから入れる」という方法も比較的現実的です。特にストリーム処理の場合、１処理の実行時間は短いため、実行ログを出力しすぎると処理パフォーマンスに大きく影響します。そのため、開発時には運用のための実行ログはあまり設計せずに、運用中にエラーが発生したところを中心に実行ログを増やす、とした方が適切なことも多いです。

```js
if (IS_DEBUG) {
  console.log("user_id = " + user_id);
}
```

また、ストリーム処理の場合、前述のジョブキューを使っているため、集計が止まるとジョブキューが溢れてしまいます。そのため、たとえ1データがエラーになったとしても、基本的には停止はしないようにしています。

## 動的に計画する

ストリーム処理は常に動かし続けるため、処理の開始時に将来のパフォーマンスの見積もりをすることが難しいです。そのため、見積もりできることより、動的にシステム拡張できるようにすることが優先されます。


# まとめ

実際にはKARTEでは、バッチ処理とストリーム処理の両方が組み合わされて使われています。いろんな集計システムを組み合わせて最適なものを作りたい、という人はぜひプレイドへ！
[PHP] WordをPDFに変換する

##　環境
centos 7
php 7.0
yumやcomposerはinstall済みとします

## composer.json

```composer.jsonを用意
{
    "require": {
       "phpoffice/phpword": "dev-master",
       "gears/pdf":"*"
    },
    "scripts":
    {
	"post-install-cmd": ["PhantomInstaller\\Installer::installPhantomJS"],
	"post-update-cmd": ["PhantomInstaller\\Installer::installPhantomJS"]
    }
}
```


## cmdでの作業
```
$yum -y install libreoffice libreoffice-langpack-ja
$yum -y install php-pecl-zip.x86_64
$composer install #composer.jsonがあるディレクトリで行う
```

## 変換処理を行うphpを作る
```convert.php
<?php
require './vendor/autoload.php';
Gears\Pdf::convert('./test.docx', './test.pdf');
```

※ test.docxは適当なテスト用のwordファイルです

convert.phpを実行すれば完了！


### dockerで起動する
https://github.com/rnoguchi/convert_word_to_pdf


### 参考文献

https://packagist.org/packages/gears/pdf
https://www.ka-net.org/blog/?p=6952
:terminal に関する小さい Tips

空いてたので割り込み。

# 君は Tapi を知っているか

Vim に `:terminal` 機能が実装されている事は全国1億5千万人が知っている事実なのですが、`:terminal` の Tapi (Terminal API)機能をご存じの方はそのうち300人くらいしかいません。今日はその Tapi 機能について説明します。

# Tapi 機能とは

`:terminal` は仮想 pty を用意してコマンドを実行する物で、コマンドを実行した後は `:terminal` が自発的に画面を更新します。Vim からはキーボードの操作がそのコマンドに対して渡されます。一見これだけで便利そうなのですが、`:terminal` を使っているユーザはよくこう思います。いや、必ずこう思います。

> この :terminal で起動したシェルの中から親の Vim に対してファイルを開かせたいよなぁ

ね、思いましたよね。

これを実現するのが Tapi 機能です。

# Tapi の仕組み

Tapi は Vim と `:terminal` との間でやりとりされるエスケープシーケンスです。詳しくは `:help terminal.txt` を参照下さい。フォーマットは以下の通り。

```
<ESC>]51;msg<07>
```

msg は JSON の配列を指定します。要素の1つ目がアクション名、それ以降が引数です。現在用意されているアクションは2つあります。

## drop

`:terminal` の中からそれを実行した Vim に対して「このファイルを開け」を指示します。

## call

`:terminal` の中からそれを実行した Vim に対して「この関数を実行しろ」を指示します。ただし呼び出せる関数は `Tapi_` で始まるユーザ関数でなければなりません。

# 活用方法

今日はこの drop を利用した便利な Tips を紹介します。全国5千万人くらいは [gof](https://github.com/mattn/gof) というコマンドを知っていると思います。このコマンドは一般的には peco 等と同じセレクタとして働きますが、このコマンドの実行結果を drop に渡す事で `:terminal` の中から親の Vim に簡単にファイルを開かせる事が出来ます。

```sh
#!/bin/sh

/bin/echo -e "\x1b]51;[\"drop\",\"`gof`\"]\x07"
```

実行するとこんな感じになります。

![gofv](https://qiita-image-store.s3.amazonaws.com/0/665/bdd9d4af-f0b8-fee7-bd74-96fc72627c46.gif)

注目して欲しいのは `:terminal` の中で Vim が起動したのではなく、`:terminal` を起動した Vim 側で新しくウィンドウが作られバッファが開いている所です。

つまり Vim から gof の UI を利用してファイルを開きたいのであれば

```
:terminal ++close gofv
```

と起動すれば良い事になりますね。

ぜひご活用下さい。
MT7のコンテンツタイプって何？？

自分のブログを一年ぶりに更新しようとしたら、管理画面にすらログインできず、画面開くのにも1分くらいかかっていて嫌になったのでこちらで書いてみます。

ある日の出来事、MT3の時代からMTでサイトを作っていたという人とお会いして、その人と話していた時に出てきたのがタイトルの言葉でした。
**「MT7のコンテンツタイプって何？？カスタムフィールドみたいなやつだよね？」**

おそらくMT3〜６まで使っていた方からすると、カスタムフィールドとコンテンツタイプの違いがわからないといったことが起こっているようなので、今日はその辺りを自分なりに整理してお伝えできればと思ってます。

# MT7のコンテンツタイプはカスタムフィールドと同じ？
これは合っているようで違います。
カスタムフィールドはあくまで記事投稿やウェブページ投稿画面に項目を追加して、付加情報を追加しているだけです。
たとえばよくあるニュース記事ページに外部リンクを追加する場合、こんな構造にしていたかもしれません。

### ニュース記事投稿画面
タイトル：ニュースのタイトル
本文：ニュースの一覧で表示する概要
続き：ニュースの詳細で表示するニュース本文

カスタムフィールド
外部リンク：ニュースに関連する外部のリンク先

ブログ記事を利用して、そこに外部リンクという情報を追加してそれを表示できるようになっています。

それではここで、もしお客様から「社長がブログを書きたいのでブログを作ってください」と言われたとします。
ブログ記事はニュース用にカスタムフィールドを使ってしまっているので別のブログを作成して社長ブログとすることにします。

- ウェブサイト
    - ニュースブログ
    - 社長ブログ
   
社長は写真をかならず追加したいが、リッチエディタは使い方がわからないので、画像が追加できるカスタムフィールドを用意します。

### 社長ブログ記事投稿画面
タイトル：記事のタイトル
本文：記事の本文
続き：使用しません

カスタムフィールド
写真：入力があった場合に本文の前に写真を表示

今まではニュースと社長ブログだけでしたが、一部商品情報コンテンツをCMSとして更新したいとお客様から要望がありました。

- ウェブサイト
    - ニュースブログ
    - 社長ブログ
    - 商品情報ブログ
    
### 商品情報ブログ記事投稿画面
タイトル：商品の名前
本文：商品の説明（一覧用の説明文）
続き：商品の説明（詳細用の説明文）
カテゴリ：第一階層が商品種別、第二階層が商品の色、第三階層が商品の・・・

カスタムフィールド
写真1：商品の写真1
写真1説明：商品の写真1の説明
写真2：商品の写真2
写真2説明：商品の写真2の説明
価格：商品価格
割引：割引率
...
...
... (カスタムフィールドいっぱい)

この繰り返しで、管理するコンテンツが増えれば増えるほど、ブログを増やし続ける必要があります。
また、本文というラベルがついたフィールドを別の目的で使用しているため非常にややこしくなっています。
商品情報を更新して、それをニュースで出したい場合は、それぞれのブログでそれぞれの記事を更新して、それぞれのブログを再構築します。
更新したのにウェブサイトに反映されていないんだけど！！とお問い合わせを貰う際にはため息をつきながら再構築ボタンをクリック。
これは大げさに書いていて、プラグインなどを使うことでもっと使いやすくもありますが、あくまで記事を利用してしまっているため、ブログを分けない限りは、まったく別のコンテンツを管理することは難しくなります。

#MT7のコンテンツタイプを使うと何が嬉しいの？

今までブログ記事にカスタムフィールドを用いて付加情報を与えていたのとは全く別で、そのコンテンツを管理するための画面を作りだします。
上記の例だと。。。

### コンテンツタイプ：ニュース
ニュースタイトル：ニュース一覧用タイトル
ニュース概要：一覧に表示する概要
ニュース詳細：詳細画面に表示する内容
外部リンク先：ニュースに関連する外部のリンク先

### コンテンツタイプ：商品情報
商品名称：商品の名前
商品の説明：一覧用の説明文
商品の説明（詳細）：詳細用の説明文
カテゴリセット - 商品種別
    - バッグ
    - 財布
    - アクセサリ
カテゴリセット - 商品の色
    - ブラウン
    - レッド
    - ブルー
カテゴリセット - 商品の在庫
    - 在庫あり
    - 在庫なし
    - 在庫小
    - お取り寄せ
写真1：商品の写真1
写真1説明：商品の写真1の説明
写真2：商品の写真2
写真2説明：商品の写真2の説明
価格：商品価格
割引：割引率
・・・
・・・(コンテンツフィールド)

このコンテンツタイプを作るためにブログを作る必要はなく、ウェブサイト1つで解決します。
当然ブログ記事画面には手を入れていないため、ブログ記事としてそのまま使えます。
再構築もウェブサイトを再構築するだけで完了です。

運用もニュースを更新したい時にはニュースの編集画面から、商品情報は商品情報の編集画面からと案内すればよく、
制作　「ニュースブログに切り替えて」
お客様　「ブログ？ってどこ？」
制作　「メニューから選択できます」
お客様　「メニューってどのメニュー？」

というようなやり取りから解放されます。

# コンテンツタイプにあるカテゴリセットって何？
今まではブログ記事にカテゴリを1つ使えましたが、コンテンツタイプではカテゴリセットという仕組みを使って、複数のカテゴリを編集画面から登録できるようになりました。
上記例はちょっとテキトウですが、今までは階層で大カテゴリ、中カテゴリ、小カテゴリなど分けていたり、別々の関連付けをしたい場合タグにする必要があったりしましたが、
カテゴリセットを複数つけることで解決します。
またカテゴリセットは他のコンテンツタイプにも使うことができます。

商品でもバッグなのかパソコンなのかで入力したいフィールドが異なるのでコンテンツタイプを別にしたい。
でもカテゴリはどちらも同じものを使いたいといった場合にはカテゴリフィールドが便利です。

# MT6で作成したサイトはどうしたらアップグレードできる？
そのままアップグレードすることはもちろんできますが、僕は折角の機会なのでコンテンツ管理方法含めて考えて、
新しいコンテンツタイプを作成して新規でサイト作成することをおすすめしてます。
そういえばカスタムフィールドをコンテンツタイプにコンバートしてくれるプラグインとかだれか作らないのかな・・・

# MT7のコンテンツタイプとは
コンテンツをそのコンテンツとしてちゃんと管理できるもの。
記事でもウェブページでもなくコンテンツとして。