OmniAICreator/Qiita-1.07M huggingface dataset:
markdownを閲覧するための簡易サーバを立てたいと思ったらmarkservというnpmのモジュールが楽

## なんのために

mdファイルを編集しているときに、開発環境（linux）上でサーバ立ててプレビューみたいときのため
emacsとかcli上で動くエディタ使ってる人には需要があるかも

## markservとは

https://www.npmjs.com/package/markserv
npmモジュールです
markdownを閲覧するサーバを立ててくれる
ディレクトリも閲覧できるし見た目もよし
もちろん外部ネットワークから閲覧できるようにするオプションもある

## インストール方法

```console
npm install markserv
```

## ディレクトリ構造（参考）

```
/
|- home
  |- user_name
    |- node-modules
    |- package.json
    |- project_name
      |- README.md
```

## 使い方

パスを通すのが面倒なのでやってない

```console
cd /home/user_name
node_modules/.bin/markserv project_name/README.md -p 8642 -a 0.0.0.0
```
`-a`オプションが外部ネットワークから見れる設定みたいです
下記のように表示されたら多分うまくいってる

```console
  Markserv   boot: starting Markserv...
  Markserv   address: http://0.0.0.0:8642
  Markserv   path: /home/user_name/project_name/README.md
  Markserv   livereload: communicating on port: 35729
  Markserv   process: your pid is: 6037
  Markserv   stop: press [Ctrl + C] or type "sudo kill -9 6037"
    GitHub   Contribute on Github - github.com/markserv
 ▕● PATREON  Help support Markserv - Become a Patreon! patreon.com/f1lt3r
  Markserv   upgrade: checking for upgrade...
  Markserv   markdown: /home/user_name/project_name/README.md
  Markserv   upgrade: no upgrade available
```

## 閲覧方法

開発サーバ上で`ifconfig`
表示されたipアドレスにポートを付与してブラウザアクセスすれば見れる

https://111.11.1.11:8642

のように

もちろんホストos上で実行しているならlocalhost:8642で問題ない

## 参考

https://www.npmjs.com/package/markserv
Vagrantを久しぶりに触ったのでメモ

久しぶりにvagrantで開発を行ったのでメモ

#### VirtualBoxとVagrantのインストール
- 最近は最新版入れておけば基本問題ないらしい

### vagrantのbox追加～起動まで
- バージョン確認
  - `vagrant -v`
- boxファイルを入手
  - データやら何やらが諸々詰まっている。容量すごい
- vagrantfileを入手
  - 起動時設定やマシンの基本設定を管理
  - フォルダのsync設定はvagrantfileに記載してある
- boxを追加
  - box、vagrantfileを格納しているディレクトリで以下のコマンドを実行
  - `vagrant box add つけたいボックス名 boxファイル名`
- `vagrant box list` で確認
- `vagrant up` で起動
- `vagrant ssh` で仮想マシンへログイン

### 終了、再起動
- `vagrant halt`
  - マシンのシャットダウン
- `vagrant reload`
  - vagrant halt + vagrant up
- `vagrant destroy`
  - 環境削除
Laravelでスレッド型BBSをつくってみた② - ソース公開中

# はじめに

[Laravelでスレッド型BBSをつくってみた①](https://qiita.com/yamaji_daisuke/items/aa3c09f7df121a7f5e48)の続きです。

今回は前回作ったスレッド型BBSにユーザー認証機能をつけたいと思います。

# 軽く仕様策定 & 設計

- ユーザー認証機能はLaravelの標準認証を利用します。
- 自分の投稿のみ削除可能とします。
- マイページは自分のスレッド/投稿の一覧が表示されることとします。

# 開発

https://github.com/new-japan-orders/bbs

## まずはユーザー登録とログインできるところまで。

以下の作業はphase-2-1ブランチで行いました。

### 標準認証のセットアップ

標準認証のセットアップをします。artisanコマンドで簡単です。layouts/app.blade.phpを上書きするかどうか確認されるので、先に別名で保存しておいてからyesとしましょう。

```
$ php artisan make:auth

The [layouts/app.blade.php] view already exists. Do you want to replace it? (yes/no) [no]:

 > yes
```

別名で保存しておいたものと新しいlayouts/app.blade.phpの中身をガッチャンコします。（画面丈夫のナビバーだを生かしてあとは元々のレイアウトファイルと同じ形です。）

これだけでユーザー登録とログインができるようになってます。

### リダイレクト先修正

登録/ログイン/パスワードリセット後のリダイレクト先をスレッド一覧ページに変更します。

``` App\Http\Contorollers\Auth\LoginController.php
protected $redirectTo = '/threads';
```

``` App\Http\Contorollers\Auth\RegisterController.php
protected $redirectTo = '/threads';
```

``` App\Http\Contorollers\Auth\ResetPasswordController.php
protected $redirectTo = '/threads';
```

### ボタンなどの日本語化

一部のボタンなどが日本語化してないので日本語ファイルを作りましょう。翻訳は適当です。

``` resources/lang/ja.json
{
    "Name": "名前",
    "Login": "ログイン",
    "Logout": "ログアウト",
    "Register": "登録",
    "E-Mail Address": "Eメールアドレス",
    "Password": "パスワード",
    "Forgot Your Password?": "パスワードを忘れたら？",
    "Remember Me": "ログイン情報を記憶する",
    "Send Password Reset Link": "パスワードリセット用URLを送る",
    "Confirm Password": "パスワード（確認）", 
    "Verify Your Email Address": "Eメールアドレスを確認する",
    "A fresh verification link has been sent to your email address.": "あなたのEメールアドレスに新しい確認URLを送りました",
    "Before proceeding, please check your email for a verification link.": "次に進む前に、あなたのEメールアドレスをチェックしてください。",
    "If you did not receive the email": "もしあなたがメールを受け取れないのなら、",
    "click here to request another": "メールを再送信するために、ここを押して"
}
```

作業完了後、phase-2ブランチにマージしました。

## ログインしている際の動きを追加

以下の作業はphase-2-2にて行います。

さて、ログインしている際にどういった変化が起こるかというと、


- スレッド作成/投稿時の名前を入力しなくてよくなる。（ログインしているユーザーの名前が自動で利用される）
- 投稿の削除が可能になる
 
といった感じなるかと思います。1つずつ対応していきます。

### スレッド作成/投稿時の名前を入力しなくてよくなる

#### カラム追加

まずはスレッド/投稿とuserを結びつける必要がありますので、threadsテーブルとentriesテーブルにuser_idカラムを追加します。2018_12_25_031734_add_user_id_to_entries_tableというマイグレーションファイルを作成してマイグレーションします。

EntryモデルとUserモデルに各々のリレーションも追加します。

#### スレッド作成/投稿時の処理

スレッド作成/投稿の際に、ログインしていた場合にはuser_idを記録し、nameはnullにする形にします。フォーム上ではログインしてた場合には名前の入力欄は決してユーザー名を表示するようにしました。

スレッド詳細ページ＝投稿一覧ページでは、user_idがあるものについてはuser_idに紐づくuserの名前を表示する形に変更します。

### 投稿の削除が可能になる

ThreadsControllerにdestroyEntryメソッドを追加して、ルートに追加しました。また、ミドルウェアを使って認証していないとこのメソッドにはアクセスできないようにしています。

ボタンは投稿日時の隣あたりに追加しておきました（適当）

作業完了後、phase-2ブランチにマージしました。

## マイページ追加

UsersControllerと画面を作成します。表示するものは自分が作成したスレッドと投稿です。簡単。マイページへのリンクはナビバーに追加しておきました。

作業完了後、phase-2ブランチにマージしました。

# とりあえず完了

ミニマムなスレッド掲示板に簡単な認証機能をつけてみたました。

作業の各工程を各ブランチに残してありますので、branch切り替えながらどんな作業しているのか確認したりしつつコードを読んでみてください。

## 予定

+ MultiAuth
+ EntriesControllerの追加と管理機能の追加
wpa_supplicantを組み込みで使う方法

すぐにどうのというつもりはないが、ちょっと調べてみた。

wpa_supplicantはWPAをサポートするためのコードで、WPAの接続処理とデータの送受信での暗号化の処理を行う。

ソースコードでOSやplatformに依存する部分のスケルトンはnoneというファイルで用意されている。

```
$ find src -name '*none.c'
src/crypto/crypto_none.c
src/crypto/tls_none.c
src/drivers/driver_none.c
src/l2_packet/l2_packet_none.c
src/utils/os_none.c
```

os,l2_packet,driverは下位レベルのコードと思われる。

cryptoとtldはsslライブラリのヘルパーでgnutls,openssl,wolfsslが用意されている。bearsslのものはまだない。mbedでWIFIサポートしているものがあるような気がするがmbed tlsのヘルパーも本家のツリーにはない。

これらを作り込めば組み込みでも使えると思われる。

EPS32はFreeRTOSを使ってlwipとwpa_supplicantを組み込んでいる。wifiに関係しそうなcomponentsはesp_wifi,wpa_supplicant,wifi_provisioningがある。またローレベルのnetwork関係はesp_netif,lwipがある。ESP32にはEthernet MACが入っていてPHY(LAN8720)をつなぐとEthernetが使えるようになるようだ。そのコードはesp_ethにある。wpa_supplicantはmbedtlsを使っているようだが、l2_packet,driverのディレクトリがなく、esp_supplicantというディレクトリがある。おそらくチップの機能を使いwpa_supplicantの機能の一部を使うような実装になっているのではないかと思われる。

https://github.com/espressif/esp-idf

Hardwareサポートなしに処理する場合はこのような流れになると思われる。

![wpa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d6aee506-874b-865f-5d4f-0333e6fa8fc2.png)

11bのWEPしかサポートしてないデバイスを利用する場合はこのような流れになるが、WPAをサポートしたデバイスでハードウエアサポートを利用すると初期の処理のみをwpa_supplicant経由にして、データの送受信はハードウエアから直接lwIPに渡す実装になるものと思われる。
Google Analyticsは、単なる「アクセス解析ツール」・・・ではない

# はじめに

Adventカレンダー「エンジニアのためのWebマーケティング」の15日目です。
サクッと読める記事を目標に。異論・ツッコミ大歓迎。
できるだけ専門用語を使わないように気をつけます。

それでは参りましょう

![GAとコーヒー](https://qiita-image-store.s3.amazonaws.com/0/72413/51ad838c-996c-f795-afb4-4040bdddb8bc.jpeg)

# Google Analyticsとは？

みなさんにお聞きしたら、だいたい上がってくる内容は以下のものでしょうか

* Webのアクセス解析ツール
* アプリ計測もできるツール
* 顧客動線・傾向解析ツール
* 広告の効果を解析できるツール
* **無料で使えるツール**

**※当記事では、Google Analyticsを呼ぶ際に「Google Analytics」「GA」の表現を使用します**

## GAの歴史

GAは元々、Urchin Software社が開発したツールでした。
しかし、GoogleがUrchin社を買収。Google Analyticsとして新しくリリースがされました。現在はUniversal Analyticsとよばれ、様々な計測ができるツールとして生まれ変わっています。

### utmの正体

ちなみに・・・

使用したことがある人は、**utm_campaign** とか **utm_source** などのパラメーターに見覚えがあるかもしれません。これはUrchin社時代の名残がそのまま生きていて、utmは

* Urchin
* Tracking
* Module

の略であることを表しています。歴史を感じますね。

## GAはなぜ無料なのか？

ちなみに、GAがなぜ無料なのかみなさんご存知ですか？
それはズバリ、**「Google広告（元Adwords）を売るためのツール」**だからです。

Googleの売上の大半を担っている広告の効果測定をするために作られたツールなのです。

他にも、フリーミアムのビジネスモデルとして、上位のプレミアムモデル「Google Analytics 360」へ誘導するポジションとしても活躍しています。

プレミアムモデルは月額130万程度の高額サービスではありますが、1ヶ月のPVが10億アクセスまでその料金で利用できるので、PV数が大きいアカウントだととても有利になります。


# GAのレポートメニュー

GAの管理画面は以下のような構造になっています

* ユーザー
* 集客
* 行動
* コンバージョン

![管理画面](https://qiita-image-store.s3.amazonaws.com/0/72413/4b3f287f-1765-1013-5ea9-7370404ced14.png)

ECで例えるとするなら、

* どんなユーザーが
    * PCやスマホなど様々な人が
* 何がキッカケで
    * 広告の内容に釣られたり、口コミの評判をきっかけに
* どのような手段で
    * Web検索や広告クリック、お気に入り登録で来訪
* どう行動し
    * 様々な商品ページをまわり
* どこまで至ったか
    * 実際に購入を行う

この一連の流れを計測ツールになります。

つまり、**マーケティング施策が本当に成功しているかを計測するツール**なのです。もちろん、アクセス解析もできるツールなのですが、それで終わらせるにはもったいなすぎます。

# GAはマーケティングツール

GoogleはGAと連携できるサービスを増やしていってます。

* AdWords（むしろしないと意味が無い）
* AdSense
* AdExchange
* BigQuery（プレミアムのみ）
* DoubleClick
* Google Play
* Search Console（ウェブマスターツール）

この連携しているサービスを見ればわかるように、Googleは**Webのマーケティングに自社の製品を無くてはならないものにしようとしている**ことがわかります。

GAはその足がかりとするためのツールなのです。無料ですしね。
でも、非常に多くの機能と得られる情報があるので使って損はないです。

GAの機能については、別途記事を組みたいと思います。


# どうでもいい話

我々エンジニアからすると、GAと聞くと**「遺伝的アルゴリズム（genetic algorithm）」**の方が聞き覚えがあるかもしれませんね。もう忘れましたが。交叉とか。

あと、**ガボン共和国という国のドメインも.ga**らしいです。
・・・どこにあるねん。と思ったら、[アフリカの中部](https://ja.wikipedia.org/wiki/%E3%82%AC%E3%83%9C%E3%83%B3)らしいです

# おわりに

次の記事は、広告効果測定ツールを知るPart2です。
【rails5】renderとredirect_toについて

##renderとredirect_toについて

###render

一覧画面や新規登録画面を表示する際のように、アクションの後にビューを表示させること。

一つのリクエスト(newアクションやindexアクション)で画面が表示される。

###redirect_to

アクションを処理した後にビューを表示せず、別のURLに遷移する動き。
（編集ページから編集を実行すると、ユーザーのトップページに戻るような動き）

一つ目のリクエスト(updateアクションやcreateアクション)でデータを更新し、その後リダイレクトによって２つ目のリクエスト（ビューを表示させるアクション）が発生し、ページが表示される。

どちらも指定しない場合は、アクションに対応する場所、名前のビューファイルをrenderする。

redirect_toにはFlashメッセージを添えることが出来る。
vuex+SPA+firebaseで物理的に近い人とチャットできるサービス作った

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

クリスマスイブの日の担当は、新卒2年目の小川がお送りします。
業務は事業企画を主に行っており、必要な時は開発も行っています。

#はじめに
タイトルにも書きましたが、物理的に近い人とチャットできるサービスを作りました!
下記にそのサービスを作ろうと思った経緯と使用した技術について書いていきます。

# サービス立案の経緯
この世は便利になったもので、どんなに遠く離れていてもメッセージのやりとりやビデオ通話なんてすぐできます。
とはいえ、普通に過ごしてたら永遠に交流できない人もたくさんいます。エンジニアなんかは、基本的に悲しい生き物なので、なおのこと生活ルーティン外の人とは交流できません。

そんな中でも現在知らない人と交流できるサービスはたくさんあります。
- SNS
- マッチングアプリ
- ランダムな人とチャットできるサービス
- etc...

色々ありますが、SNSはコミュニティを作るまで時間がかかるし、マッチングアプリは気軽に登録できない。
ランダムチャット系はユーザーの共通点・目的がなかなか一致しないのもあるのか、盛り上がっている印象はありません。

**共通点・目的が一致していて絶対交流できなかっただろう人とを、気軽に引き合わせられるサービス**作ってみたいと考え、物理的に近い人とチャットできるサービスを作成しました！

共通点を自分らがいる場所（例えば新宿駅前）とし、目的をチャットルーム（例えば新宿付近の電源あるカフェ教えて）で分け、よりスモールな2ch的な感じで盛り上がることってあるかな？と思いました。会員登録も特にさせず、めっちゃ気軽さも重視させます。

あとは後述してますが、firebase × vue × SPAで何か作ってみたかったというのがでかいです。

# 使用技術
## サーバサイド
チャットが主になるので、速攻で開発ができるfirebaseを使いました。
firestorageとhostingを使っています。

## フロントエンド
フレームワークはvueを選択しました。
遷移スピードも早めにしたいし、挙動を少しでもネイティブに近づけたいので、SPAを採用しました。

# 出来上がったもの

https://area-chat-d74ed.firebaseapp.com/#/

<img width="238" alt="スクリーンショット 2018-12-25 9.44.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/119715/e3b9e7e5-cd87-a3f4-ea0e-29648474e5f8.png">

上記のチャットサービスが出来上がりました。全体的な機能は、
・ユーザーはニックネームの入力のみで参加可能。
・誰でもチャットルームを作成可能。
・チャットルームが作られた地点から半径500m以内の人がチャットルームに入れる。
・チャットルームは作られてから24時間だけ有効。
以上のような感じになりました。

位置情報を使うサービスなので、位置情報取得を許可しないと使えません。

ニックネームを入力すると、

<img width="237" alt="スクリーンショット 2018-12-25 9.58.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/119715/8bb34b4b-580c-46aa-e504-09203c15b532.png">


のように、今いる場所周辺のチャットルーム一覧が出てきて、

<img width="238" alt="スクリーンショット 2018-12-25 9.58.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/119715/92b4a548-ab72-9236-c680-4a4b3b38228d.png">


チャットルームに入ると、チャットに参加できます。

# 作ってみての反省
## ディテールコミット
いくら必要最低限の機能しかなく急ぎで作ったとはいえ、他のチャットツールと比べて細かいUXがよくない。
投稿フォームの改行時はフォームを縦に広げてあげる。そもそもメッセージ投稿のフォームがスマホの時バグる。まだ画面に現れてないメッセージに印つける（ここまで読んだ的な）。上への無限スクロール。その他諸々。
今のいろんなアプリをみていると、顕在的には気づかないところまでストレスなく作られていることに気づく。

## NoSQLのデータベース設計
RDB脳。今はコレクション数が少ないのでなんとかなっているが、多くなってきたら不整合起きそう。
いろんな記事とか読んだが、やっぱりまだ正規化しようとしちゃう。単純なクエリだけじゃなく、2~4のコレクションを使うようなクエリを実際に投げて、取得しやすいしずらいを開発の中で体感していくことが大切と実感。

# 最後に
もっとしっかりサービスとして打ち出していくには色々な懸念点とかを洗い出さなければ行けなそうですが、firebase使うと速攻でチャットサービスって作れちゃうんですね。
今回でなんとなく知っているSPAも、実装の経験できて楽しかったです。

最初にサービス立案の経緯とか大げさなこと言ってますが、ほんとの経緯はクリスマスとかで待ち合わせしている人の可処分時間奪うにはどうしたらいいかという、くだらない起点からのただのジャストアイデアです。
2018年Xmas！AppleStoreはScrapBoxに学びなさい。Twitterなど拡散ボタン不要論

[macbookair yumainaura - Google Search](https://www.google.co.jp/search?q=macbookair+yumainaura&oq=macbookair+yumainaura&aqs=chrome..69i57j69i60l3.5353j0j7&sourceid=chrome&ie=UTF-8)

# Twitterソーシャル対策には力を入れてないことが判明。

ユーザーは「買った喜び」を拡散したかった！！！！！！！！！！！

うおおおおおおおおおおおおおお！！！！！！！！！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/a5800ab7-921d-c415-692c-4f5c3471c92d.png)

# その5分前の話

クリスマスで購買意欲最強のMacBookAiryを日本で一番愛するWeb開発エンジニアは。

# 2018年クリスマス、自分へのクリスマスプレゼント

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/6454ac7d-d5a3-d907-95ae-7caf50d4e772.png)

# MacBookAir 2018 13inch 512GB 16GB SpaceGray !!!

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/62fee46c-164f-9d3d-944d-2d24e288e18d.png)

# 買ったぜ！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/906d5bad-208c-2c79-cca4-12ac14a15ba9.png)


# Twitter拡散しようとすると‥？

「買いました！」「やったぜ！」的なツイートができるかと思いきや、そっけないテキストがあるだけ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/2650afd6-55f1-cbec-cef0-cb33b3cea25f.png)

# ユーザーが自由入力できるように考慮されている？

考慮されていない気がする。

# なぜそう思うか？

かんがえてみよう。答えは言わない。

# なぜAppleStoreがソーシャル拡散ボタンを付けているのか？

拡散するユーザーは勝手に拡散する。

言われなくてもやる。

結論。共有ボタンは不要。

# AppleStoreはScrapBox を見習おう

「ユーザーは勝手に拡散するからボタンなんて不要」









<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
金融データAPIのMT LINK

私はマネーツリー株式会社のマーク マクダッドと申します。
弊社が提供している金融データAPIである「[MT LINK](https://link.getmoneytree.com/jp)」をご紹介したいと思います。

技術的な側面からいうと、MT LINKとは、日本の金融サービス及びポイント業者（合計2,770社以上）の口座残高や利用明細データをOAuth 2.0の認可によって第三者に共有ができるREST APIです。現在、銀行業界、会計ソフト業界、クレジットカード業界及びFintech企業に幅広くご利用をいただいております。

と言われても、「ん？何それ」という方もいらっしゃると思いますので、背景を説明します。

## APIの背景

私自身は国産ではありませんが、2011年ごろに「なぜ僕が使っている日本の金融機関は利用明細の情報をAPIで出していないのか」という素朴な不満から起業して、その悩みを解決する「Moneytree」というアプリを作りました。（宣伝で恐縮ですが、１）広告がない、２）無料で、 ３）個人情報をしっかり守るビジネスモデルなので、[来年こそ資産管理を自動化してみませんか](https://moneytree.jp/)？）

Moneytreeのアプリを出したら、企業の方から「御社の金融データをうちのサービスでも利用したい」という要望をいただきました。ただ、弊社の理念上、個人のデータを勝手に売買するものではありません。そういったビジネスモデルはそろそろバイバイですね。

代わりに、OAuth 2.0の認可に基づいて、利用者本人が自らの金融データを共有したい時に限り、第三者にアクセスさせる仕組みを開発しました。それを「MT LINK API」と言います。

「自分の金融データを第三者に共有したいのか？！」と疑問に思う方に、一番わかりやすい例で申し上げると、そろそろ「確定申告」の繁忙期に入りますが、会計ソフトに全ての仕訳データを一つ一つ打ち込みたいですか？おそらくそうではないでしょう。

たまにエンジニアがマネタイズを疑問にするので、はっきり書きます：連携先の企業から収益を上げる仕組みです。利用者と企業、両方にメリットがなければ、ビジネスモデルは成り立ちませんし、利用者に怪しいことをするような連携先は全てお断りしております。

## MT LINK APIを活かして

さて、APIのご紹介だけではなく、実際に実装していきたいと思います。ただ、「ローマは一日にして成らず」とも言いますが、まだできていません。近日、またここを確認してください。随時アップしていきます。
「Xcodeで一旦関連付け消去した後、ソースコードからなぜか再び関連付けできない…」って時の対処法

##前提

① 関連付けを間違えた(黄色三角がある状態)から消去した

<img width="188" alt="スクリーンショット 2018-12-25 8.28.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/260056/2b06e79b-29f7-7d45-f905-5e0b64e8dccf.png">


② ソースコードに白丸出現

<img width="505" alt="スクリーンショット 2018-12-25 8.29.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/260056/894ba7e4-b78a-61d4-3f92-c131cf5a69ea.png">


③ 関連付けするぞ！！

##問題点

ソースコードからなぜか関連付けができない…

##解決策

ViewControllerを選択した状態でコネクション・インスペクタを開く

<img width="259" alt="スクリーンショット 2018-12-25 9.03.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/260056/55ab1818-b44a-663a-fa30-8a05122bcc28.png">


そして関連付けしたら…

**できた！！**

終わり( ・∇・)
drizzleのチュートリアルを最新バージョン(truffle v5.0.0)でやる場合のエラーとその変更点

##この記事について
[drizzleのチュートリアル](https://truffleframework.com/tutorials/getting-started-with-drizzle-and-react)を以下のバージョンでやるときに詰まった点を書いていきます．


- truffle v5.0.0
- solidity v0.5.0

自身の環境は`truffle --version`コマンドで確認できます．


##バージョンアップによる変更点

#### コンパイラの指定方法の変更
 - `pragama solidity ^0.4.24;`ではなく`pragma solidity >0.4.99 <0.6.0;`という記法になった．
 
#### 関数の引数はmemoryに
 - `function set(string) public{}`ではなく`function set(memory string) public{}`

####migrationフォルダに作成`2_deploy_MyStringStore.js`をmigrationフォルダに作成

- truffleでの開発に慣れている場合は，migrateフォルダにコントラクトをデプロイする`2_deploy_MyStringStore.js`を作成すれば良いとわかるが，チュートリアルにはこのファイルの作成について言及されていないので，一応書いておく．

```javascript:migrations/2_deploy_MyStringStore.js
//  ファイル名は2が最初に付いていればなんでも良い
//  （わかりやすくここではMyStringStoreにした）
const MyStringStore = artifacts.require("MyStringStore"); 

module.exports = (deployer,accounts) =>{ 
     deployer.deploy(MyStringStore); 
}; 

```


## 参考資料
- [truffle](https://github.com/trufflesuite/truffle/releases/tag/v5.0.0-beta.0#breaking-changes)

- [Solidity v0.5.0 Breaking Changes](https://solidity.readthedocs.io/en/latest/050-breaking-changes.html)
復習 Django チュートリアル ：views.py と urls.py はどうつながっているか

## 目的
現段階（チュートリアル(4))までを復習して、使いこなせるという実感を持ちたい。自分が納得するための備忘録。作業場はtestdirectory、プロジェクト名は littleproject、アプリ名はlitteleappとする。

※注意※ 初心者がわずかな知識で自分なりに解釈しております。間違いが多分に含まれている可能性大いにあります。

## 環境
ThinkPad T440p
Ubuntu Linux 18.04 日本語 Remix
Python 3.6.7
pip 18.1
Django 2.1.4

## view.py と urls.py を言われるがままに作ってきたが…
使いこなせるとは口が裂けても言えない。どこがどうつながり、何をどう変えていいのかさっぱりわからなかったから。urls.pyが２つありごっちゃになってしまう。まずはファイル構成から復習する。

![Screenshot from 2018-12-24 22-27-58.png](https://qiita-image-store.s3.amazonaws.com/0/321085/12c6e8b8-8e48-2fc9-e353-a1f91e67cd68.png)


単にアドレスを指定しているだけなので、本社・支社という例えは間違えているのかもしれないが、本社に向かうと出てきたおっちゃんに「よう来たな、兄ちゃん。欲しい情報はアッチにあるからそっちに行ってみてや」と言われてる、そんな感じ。ごっちゃになりがちなurls.pyを単に区別したかったというのもある。ではその本社でやってることは…

![Screenshot from 2018-12-24 21-46-55.png](https://qiita-image-store.s3.amazonaws.com/0/321085/492b6913-40c3-a145-bd24-a60e30801943.png)

django.urls という部署から、「include」 とか 「path」 とかいう助っ人を召喚して、この命令を遂行させている、みたいな感じ。で、支社では何をやっているのか…

![Screenshot from 2018-12-24 21-47-07.png](https://qiita-image-store.s3.amazonaws.com/0/321085/aba83451-9531-0fbb-d9a9-92090e6f4080.png)

同じく助っ人「path」を召喚、同じフロアから「view」さんもやってきている。で、本社よりもさらに詳しく情報の在り処を指示している。そして最終的に現場のview.pyでは…

![Screenshot from 2018-12-24 21-47-20.png](https://qiita-image-store.s3.amazonaws.com/0/321085/0ca46aac-b941-a53a-4a48-47c2140c3404.png)

「HttpResponse」召喚。index関数をつくってる。これが今までのindex.htmlに相当するものらしい。HttpResponseさんは、表示する中身を抱え込んでて、要望があったときのために待機、呼ばれたらお届けします〜と出ていくという感じ。…別に無理に擬人化する必要もなかったな。

## views.py と urls.py はどうつながっているか

参考サイト → [DJangoのお勉強(1)](https://qiita.com/ShimantoAkira/items/ec1130fbd2a65cd5b7f3) が私の疑問を解消してくれた。感謝。以下図解してみた。

![Screenshot from 2018-12-24 21-47-34.png](https://qiita-image-store.s3.amazonaws.com/0/321085/a84b53af-40fd-d104-c495-d7657a4e0dca.png)

* littleapp/urls.py の name て何のためにあるんだろうと思っていたら、パスに名前をつけてアドレスと一致させてる（変数にアドレスの文字列を入れてる）ということらしい。reverse関数を使ってアドレスを表示させることも[参考サイト](https://qiita.com/ShimantoAkira/items/ec1130fbd2a65cd5b7f3)に書いてあった。
* littleapp.urls = littleapp/urls.py だった。
* views.index は views.py の index関数のこと。馴染みあるindex.htmlはどこにあるんだろうと疑問だったが関数になっていたのね。

で、この３つの関係がわかったので、こういう改変もできるわけだ。

![Screenshot from 2018-12-24 21-47-49.png](https://qiita-image-store.s3.amazonaws.com/0/321085/6f558f51-b674-7dec-d018-e5f4bd03ae4f.png)


変更は赤字の部分。見えにくいので下に変更表…って全然大切でもなんでもない。Markdown記法でテーブルを書いてみたかっただけ。

| 変更前      | 変更後              |
|:----------:|:------------------:|
| littleapp/ | littleaaappp/plus/ |
|  index     | this_is_top_page   |
|  indextop  | indextoptop        |

## 結論
* つながりは図を参照のこと
* アドレスはどんな風に変えてもOK
* サイトトップは絶対にindexという名前じゃないといけないわけでもない
* パスのnameも関数名と同じにしないといけないわけでもない

このあたりけっこう無意識の思いこみがあって、それが理解の邪魔をしたりする。アドレスは作成したフォルダと同じ名前じゃなきゃいけないとか、サイトトップはindex.htmlにしなきゃいけないだとか思いこんでた。実はそうでもなくて意外と自由なんだと実感。チュートリアルでは関数名とパスの名前を一緒にしていた。これは簡潔にわかりやすく命名しているということなのだろうけど、同じ名前ゆえに関数がnameにも紐付けられているのかどうかわからなかったんだよなぁ。変数名やらいろいろ変えてみたことで正体がはっきり見えた。あらためてチュートリアルを読み直すと、以前は全然読み取れてなかったところがポロポロ出てきて、オレはいったい何を読んでたのかと。復習大切。

今なら言える、**初心者はviews.pyとurls.pyを手に入れた！(…たぶん)**、 かしこさが1あがった！（…はず）。
HTMLのinputタグ[type=file]のブラウザごとの挙動について調べてみた

# はじめに
みなさんHTMLタグの一つである`input`タグはご存知だと思います。
その中でも[type="file"](http://www.htmq.com/html/input_file.shtml)についてぼくはこんな疑問を持ちました。

**選択したファイルはどこのファイル？コピーとかされているの？**

これみなさん知っていますか？
ちょこっと調べたんですがなかなか情報がなかったので
いろいろ自分で調査してみました。

（本音は調査が面白そうだったのでそんなに本気で調べてないだけです

# 仮説を立てる
まずは仮説をいくつか立ててそれぞれを検証していきます

A. ブラウザはファイル参照だけ持っている
B. ファイル選択時にTemp領域へコピーしている
C. メモリ上に抱えている

たぶんこれらのどれかじゃないかなと思っており、
個人的にはBが濃厚だと勝手に考えています。

# 調査開始
ファイルアップロード機能が必要なので
簡単にファイルをアップロードするだけのアプリを自前で作りました。
https://github.com/taqm/go-simple-fileup

<img width="604" alt="スクリーンショット 2018-12-24 2.03.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/122918/6bd0ed51-4d82-99cf-2f03-2ef0d3b77f1e.png">

これは・・・雑の極みっ・・・！
気にせずこれで検証を行っていきましょう

## A. ブラウザはファイル参照だけ持っている 説

まずはこちら検証していきましょう

### 説の内容
- ブラウザはアップロード対象ファイルへの参照だけを保持
- ファイルをアップロードする際は実際のファイルがそのまま送信される

こんなところでしょうか

### 検証内容
もしブラウザがファイルへの参照を持っているだけならば、
ファイル選択後にファイルを更新したときに更新後のファイルが送信されるはず！

作った検証用アプリを使って検証してみます

まずは適当なテキストファイルを用意します。


```:sample.txt
hoge
```

そしてこのファイルを選択後に更新してから送信してみます。

```:sample.txt（更新後
fuga
```

### 結果
送信されたファイルの中身は以下でした

```:sample.txt
fuga
```

更新されてる...
あれー？
一番ないと思っていた仮説だったのにいきなりヒット？

では更新だけでなくファイル選択後に、対象ファイルを削除してみましょう

<img width="483" alt="スクリーンショット 2018-12-24 3.00.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/122918/ab08635b-42ee-b472-bdc0-e389db916cee.png">

なんと！リクエストに失敗してしまいました。

やはりただファイル参照を持っているだけで
実際のファイルへの更新を行うと、選択しているファイルにも影響が起きるようです。

## ブラウザごとの挙動
こういう問題はブラウザごとに違うのでは？という疑問が出てきます。
先に述べた実証はChromeで行っていたため
他のブラウザではどうなっているのか見てみましょう

### Safari

**選択後に、更新した場合**
やはり送信されたファイルは更新後の内容になっていました。
Chromeと同じ動きです。

**選択後に、削除した場合**
削除後に送信した結果、
同名の空ファイルが送信されてしまいました。

### Firefox

**選択後に、更新した場合**
送信されたファイルは更新後の内容になっていました。
ChromeやSafariと同じ動きです。

**選択後に、削除した場合**
ファイルの送信が行われませんでした。
そもそもファイルが選択されていないような動きになっています。

### Microsoft Edge
**選択後に、更新した場合**
なんと同名の空ファイルが送信されてしまいました。

**選択後に、削除した場合**
削除の場合も、更新と同様に空ファイルが送信されています。

### Internet Exproler 11

**選択後に、更新した場合**
ChromeやSafari同様に更新後の内容が送信されました。

**選択後に、削除した場合**
なんと削除前のファイルが正常に送信されるではありませんか。
そして

選択　→　更新　→　削除　→　送信

と操作を行った場合には更新されたファイルが送信されていました。

### ブラウザ別の挙動まとめ

ブラウザごとに送信されたファイルをまとめてみます。

　|選択後に更新|選択後に削除
---|---|---
Chrome|更新後のファイル|<font color="red">エラー発生<span>
Safari|更新後のファイル|空ファイル
Firefox|更新後のファイル|<font color="red">送信せず<span>
Edge|空ファイル|空ファイル
IE11|更新後のファイル|削除前のファイル

バラバラだ

# 結論
`input(type=file)`でファイルを選択した場合は
ファイルのへの参照を持っているだけであり、
選択後にファイルを更新・削除を行うと選択したファイルへ反映される。

ただし、反映のされ方はブラウザごとに挙動が異なる。

# あとがき
正直ファイルの参照を持っているだけだとは思っていませんでした。
改めて考えてみると、コピーなんてしていたら容量も時間もかかるのでありえないんですが・・・ｗ

でもまあ調査した結果としてはとても面白い内容となったので満足感ありです！
まだIEの細かな仕様やスマホだとどうなのかなど色々気になることもあるので
時間ができたら記事を更新していきます！

#### 追記　

2018/12/25時点での検証結果になるため、ブラウザの更新により挙動が変更される可能性があります。

---
おしまい
配列のローテーションを線形時間でin-placeに実行せよ

|問題|
|:---|
|配列$A[1...n]$と位置$i$が与えられたとき$A$をローテションさせた$A[i...n]A[1...(i-1)]$を線形時間で作れ、但し使える領域は$A$と定数個のポインタ（つまりin-place）、使用可能な操作は$swap(i, j)$: $A[i]$と$A[j]$の入れ替えのみとする。|

![fig1.png](https://qiita-image-store.s3.amazonaws.com/0/67384/1dcf9172-66de-6d31-8e6b-9cb4c3e04530.png)


難易度的には優しく解法もたくさんあり頭の体操レベルかと思います。何人かの知り合いに出題して傾向をみると、「こうすれば解けそう」というアイディアは結構すぐ思いつくようですが、正当性を説明することがなかなか難しいようです。

正当性とは以下の２点です。

1. 操作は正しいか？（正しくローテションされているか？）
2. 線形時間で動作するか？

正当性を説明することはとても重要です。この問題について取り組むときには、アルゴリズムとその正当性の説明もセットで考えてみてください。

これは答えがすぐ見えないための画像です。自力で解きたい方はここで一旦考えてみてください。
![text_yattemiyou.png](https://qiita-image-store.s3.amazonaws.com/0/67384/503b6b1b-bcda-8274-f21d-3da168b00ee7.png)


## 解法1

それでは解法を見ていきましょう。

![fig2.png](https://qiita-image-store.s3.amazonaws.com/0/67384/fa950fa4-5f01-d3ac-a7d2-693f86bb99d2.png)

はい、単純ですね。そしてこの解法を思いついた人が一番多いのではないでしょうか。

それでは正当性について考えていきましょう。
まず$|B|=|C|$について考えると、この操作で$B$も$C$も正しい位置に保存され、swap回数も$|B|$回だけですので、ポイント1、2について正当性が言えることが分かるかと思います。

それでは$|B|>|C|$の場合を考えてみましょう（$|B|<|C|$はその逆なので略します）。

### 正しくローテション出来ているか
- $C$の位置は最終状態の正しい位置に保存されますので、$C$に関しては正しくローテションされます
- $B$に関してはローテションが必要なので、同様に再帰的に処理を行います
- 上記２つより全体のローテションが正しく行われます（問題サイズは単調減少ですのできちんと停止します）

### 線形時間で動作しているか
- 再帰処理の各ステップで必要なswap回数は$|C|$回
- $C$は最終状態の位置にあり、その後の再起ステップではswapされない
- よってswap回数は高々出力配列のサイズ$|A|$回となる

はい、スッキリですね。
では解法2に移っていきましょう！

## 解法2
解法2は定数回のreverse操作のみで配列のローテションを行います。配列$A[1...n]$をreverseするとは$A^R=A[n]A[n-1]...A[1]$を作る操作です。$A$のreverse操作は左端、右端から等距離にある$A[i]$と$A[n-i+1]$をswapすることにより線形時間でin-placeに実行可能です。
興味がある方はここで一旦読むのをやめて、reverse操作のみでローテションを行う方法を考えてみてください。

![text_yattemiyou.png](https://qiita-image-store.s3.amazonaws.com/0/67384/503b6b1b-bcda-8274-f21d-3da168b00ee7.png)

それでは解法を見ていきましょう。

![fig3.png](https://qiita-image-store.s3.amazonaws.com/0/67384/f2781dfd-bc6f-d0bd-17f8-ef8e1e71d39e.png)

Step1の状態でA全体をreverseすると、後方の$C^R$がreverseされて$C$が前方に、前方の$B^R$がreverseされて$B$が後方に移動され、最終的にStep2の状態になります。

この方法のすごいところは単純かつ正当性が一目瞭然なところです。素晴らしいですね。

## おわりに

どうですか？問題は単純ですが、色々な解き方がありなかなか面白い問題ではないでしょうか？

in-place計算は可能な計算が限られており、パズル的な発想で解く方法がとても多く、個人的に気に入っているタイプの問題です。

最後に面白そうなin-placeな問題を出題して終わりにしたいと思います。

|問題|
|:---|
|ソート済みの配列$B[1...n]$と$C[1...n]$が配列$A$に連続して$A=BC$の形式で保存されています。線形時間でin-placeに$A$を安定ソートしてください。|

![fig4.png](https://qiita-image-store.s3.amazonaws.com/0/67384/9c766d29-4489-1c62-c6d5-92f5a3e4c755.png)

この問題はローテーションほど簡単ではないですが、いくつか仮定（配列の長さ、安定の条件をなくす）をおいていけば難易度は下がっていきますので、ぜひ取り組んでみてください。ちなみにこれが出来るとマージソートが$O(n \log n)$時間でin-placeに実行可能になります。

安定でないバージョンは[Practical In-Place Merging, Huang and Langston, 1994]の論文でシンプルに解かれていますので気になる方は参照してみてください。
オススメの言語はなにか？

※2024/03/06 この記事は移動しました。
[オススメの言語はなにか？](https://qiita.com/moonWalf/items/c7c4d29731361da21bc8)

名前がカッコいいやつをやればいいと思う。
半分冗談、半分本気。
あまりオススメとかはない。
好きなのをやればいいと思う。
それだけだと物足りないので、ちょっとだけまとめてみる。
大きく分けると「2種類+コマンド+SQL」を学ぶと良いと思う。

## 言語2種類

いろんな分類方法はあれども、
プログラムは大きく分けて

- 静的型付け言語
- 動的型付け言語

に分かれる。
これらを一つづつ覚えておくと、何かと便利。

動的型付けだけだと、型への意識が薄くなるので、
DBが絡みで困る場面が出てきそう。
特に日付書式まわりで、エラーの原因を特定するのが
苦手になりそうな感じがする。

静的型付けだけだと、、、
うーん、困る場面は思いつかないけど、
RubyやJavaScriptは幅広く使われているから、
キャリアや面白さという意味で幅が狭まるかな。

### 静的型付け言語

- C#
- Java
- Go
- Swift
- Scala
- C/C++

代表的なのはこの辺りかな。
個人的に好きなのはC#。
VisualStudioがなんといっても優秀すぎる。
これは他の言語にない最大のメリット。
IntelliSenseの優秀ぶりがすごい。
今はVisualStudio for Macもあるし、
ザマリンを使えばWin,Mac,Android,iOSのアプリを
C#で書くことが出来るという強みがある。

そういと、Javaにも同じような強みがある。
プラットフォームを選ばないので、
未だに幅広く人気がある。

C/C++はやや難易度が異なるけども、
言語の王様という意味で学習しておくのは良いと思う。
メモリ管理とか、仕組みを学べる。

###動的型付け

- Python
- Ruby
- JavaScript
- PHP

好きなのはPython。
入門に最適でいて、いま絶好調の言語でもある。
Rubyはとても優しくて良い言語。
単独で用いるというよりはRailsとセットなイメージ。
JavaScriptはWeb関連なら必須。
PHPはディスられがちだけど、WordPressが優秀だし、
デザイン系なら覚えて損はなし。

##コマンド

- bash
- コマンドプロンプト(正式名忘れた)
- PowerShell
- zah

Windows10ならbashが使えるし、
PowerShellはオープンになったからMacでも使える。
この辺どれかひとつ、扱える様になると生産性が格段に上がる。
ファイルのリネームやコピー、ファイル名をまとめて抽出など、
細かい作業をコマンドでちゃちゃっと出来ると、
早くてカッコいい。
ん?RubyでもPythonでも出来るって？
環境があるならばそれでも良いと思うけど、
非エンジニアのPC/Macに、
Ruby/Pythonの環境が果たして入っているかな？

##SQL

Sier系ならば、言語よりも何よりも先に覚えたほうがいいやつ。
書き方は覚えなくてもいいけど(私は未だにInsert文の書き方覚えてない)、
一通り使えることは必須。パフォーマンスにも大きく影響する。
最低限、分析関数(ウィンドウ関数)とCASE式を覚えればなんとかなる。
SQLは極めれば、そのままデータ解析もできる。
ちなみに、Sier系はよく「この処理をSQLで書くか、コードで書くか」を迷うことが多い。
いわゆる富豪プログラミングができないケースが多いからだと思う。

##結論

好きな言語をやればいいと思う。
どのみち業務では、業務にあった言語を使うんだし。
どんな言語でも対応できるようになってると強い。
gorm で現在接続している DB の種類を取得する

には，```Dialect().GetName()```を呼ぶとよいです。
つまり，以下のようなコードになります。

```go
package main

import (
	"fmt"
	"log"

	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
)

func main() {
	db, err := gorm.Open("sqlite3", "test.db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	fmt.Println(db.Dialect().GetName())
	// => "sqlite3"
}
```

種類ごとに動作を変えたい場合に便利…かもしれない。
Linux Shell周りの機能

shell周りの機能についてまとめます。

#コマンドの実行制御
複数コマンドを実行するときの実行制御についてです。

| コマンド | 説明 |
|:--|:--|
| コマンド1 ; コマンド2 | コマンド1に続いてコマンド2を実行する |
| コマンド1 && コマンド2 | コマンド1が正常終了したときのみコマンド2を実行する |
| コマンド1 &#x7c;&#x7c; コマンド2 | コマンド1が正常終了しなかったときのみコマンド2を実行する |
| (コマンド1 ; コマンド2) | コマンド1とコマンド2をひとまとまりのコマンドとして実行する |

```bash
$ ls
a.txt  b.txt  c.txt  test  test2
$ cat a.txt
this is a.txt.

$ cat a.txt ; ls
this is a.txt.
a.txt  b.txt  c.txt  test  test2

$ cat a.txt && ls
this is a.txt.
a.txt  b.txt  c.txt  test  test2
# 「cat a.txt」が成功しているので「ls」も実行されている

$ cat a.txt || ls
this is a.txt.
# 「cat a.txt」が成功しているので「ls」は実行されていない

$ cat d.txt && ls
cat: d.txt: No such file or directory
# 「cat d.txt」が失敗しているので「ls」も実行されていない

$ cat d.txt || ls
cat: d.txt: No such file or directory
a.txt  b.txt  c.txt  test  test2
# 「cat d.txt」が失敗しているので「ls」が実行されている

$ (cat a.txt ; ls) > c.txt
$ cat c.txt
this is a.txt.
a.txt
b.txt
c.txt
test
test2
```

#引用句
shell内で引用句を使ったときには、引用句の種類によって挙動が変わる。

| 引用句 | 説明 |
|:--|:--|
| シングルクォーテーション | シングルクォーテーションで囲まれた部分はすべて文字列として解釈される。 |
| ダブルクォーテーション | ダブルクォーテーションで囲まれた部分はすべて文字列として解釈される。ただし、変数が含まれていればその変数は展開される。 |
| バッククォーテーション | バッククォーテーションで囲まれた部分にコマンドがあれば、そのコマンドが実行されて表示される。また、変数があり、その中身がコマンドのときもそのコマンドが実行される。 |

```bash:sample
$ echo $PWD
/root/test

$ echo 'This directory is $PWD' 
This directory is $PWD
# すべて文字列として解釈される

$ echo "This directory is $PWD"
This directory is /root/test
# 変数は展開され、それ以外は文字列として解釈される

$ echo "This directory is `pwd`"
This directory is /root/test
# pwdコマンドが実行されて表示される　(全体をシングルクォーテーションで囲むとすべて文字列として認識される)
```

# メタキャラクタ
shell内で使用できるメタキャラクタは以下の通り。

| メタキャラクタ | 説明 |
|:--|:--|
| * | 0文字以上の文字、文字列にマッチする |
| ? | 任意の一文字にマッチする |
| [] | []内の文字のどれかにマッチする<br>-：連続した範囲を指定できる<br>!：マッチしない範囲を指定できる|
| {} | ,で区切られた文字列を、ファイル名にマッチするかどうかに関わらず展開する<br>展開した上で他のメタキャラがあれば、改めてマッチを判断する |
| \ | メタキャラクタのエスケープ |

```bash:sample
$ ls
a.txt  aaa.txt  b.txt  c.txt  test  test2

$ ls *.txt
a.txt  aaa.txt  b.txt  c.txt

$ ls ?.txt
a.txt  b.txt  c.txt

$  ls [a-c].txt
a.txt  b.txt  c.txt

$ ls {a,aaa}.txt
a.txt  aaa.txt

$ ls {a,d}.txt  # d.txtが存在しなくても展開はされる
ls: cannot access 'd.txt': No such file or directory
a.txt

```

# リダイレクト
コマンドへの入力元や主力先を変更することができる。

| 入力出力 | 説明 |
|:--|:--|
| 標準出力先の変更 | ><br>>> 追記 |
| 標準入力元の変更 | < |
| ヒアドキュメント | << 終了文字<br>終了文字が入力されるまで入力を続ける |

```bash:sample
$ ls > log.txt    # ls の結果をlog.txtに書き込む
$ cat log.txt
log.txt
test.txt
test1.txt

$ ls -l >> log.txt    # ls -l の結果をlog.txtに追記する
$ cat log.txt
log.txt
test.txt
test1.txt
total 4
-rw-r--r-- 1 root root 27 Dec 24 06:14 log.txt
-rw-r--r-- 1 root root  0 Dec 23 13:24 test.txt
-rw-r--r-- 1 root root  0 Dec 23 13:24 test1.txt

$ grep "log.txt" < log.txt    # grep コマンドへの入力をlog.txtにする
log.txt
-rw-r--r-- 1 root root 27 Dec 24 06:14 log.txt

$ cat << EOF > test.txt    # EOF という入力があるまで入力を受け付け、結果をtest.txtに書き込む
> aaa
> bbb
> ccc
> EOF
$ cat test.txt
aaa
bbb
ccc
```
HTMLファイルだけでVue.jsを利用する

多分これが一番シンプルだと思います。


## 実装

```html
<html>
  <body>
    <div id="app">
      <custom-component :msg='msg' v-on:hello-hoge="msg = 'OK!!!'" />
    </div>

    <script type="text/x-template" id="custom-component">
      <div>
        <span>{{msg}}</span>
        <button v-on:click="$emit('hello-hoge')">ボタン</button>
      </div>
    </script>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

    <script>
      Vue.component("customComponent", {
        props: ["msg"],
        template: "#custom-component",
      })
    </script>

    <script>
      new Vue({
        el: "#app",
        data: {
          msg: 'hoge'
        },
      })
    </script>
  </body>
</html>
```

## まとめ

ライブラリなどは利用しにくいので、ちょっとした検証をする際には便利かも。
ConoHaでWindows Server立ててみる

この記事は、[ConoHa Advent Calendar2018](http://qiita.com/advent-calendar/2018/conoha)の24日目の記事です。
24日目担当のSusumu[@susumu_taka](https://twitter.com/susumu_taka)です。

皆様メリークリスマス！
ワケ有ってクリスマスの朝に書いてますよ！


# 「ちょっとお願い！」な依頼
最近ですね、**「FXの自動取引したいからWindowsサーバー設定してよ！」** という内容がチラホラ来ます。
「リモート」と「サーバー」という単語が組み合わさると難しく思えるようで。。。
まぁ、大した作業ではないのでお小遣い稼ぎ程度に引き受けますｗ

Windowsサーバーを提供するホスティングサービスはいくつかありますが・・・

**「ギータカさんチョイスでお願いします！」**

と言われた時は迷わずConoHaを利用しています。


という事で今回はConoHaでのWindows Serverの追加の仕方を・・・


# ConoHaでWindows Serverを追加する
ConoHaで選べるWindows Serverは2タイプありますが、今回はRemote Desktopを選択します

リモートデスクトップ（RDS）SALは必須で、1個以上を選択します

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/100025/8d87add2-c0a9-f17e-6785-4fa0ee980f3c.png)

基本的にはこれで終わり。

何とも簡単な・・・

# ConoHaのWindows Serverにつないでみる
今回は「リモートデスクトップ」を使用します。
コンピューターにConoHaで追加したWindows ServerのIPアドレスを入力し「接続」します。
ユーザー名は「Administrator」です。

一般の方には実はここが最大の難関のようで・・・

**あどみにすとれーたーのつづりが分らないよ！！！**

という悲鳴がちらほら

**Administrator**ですからねｗ


![無題2.png](https://qiita-image-store.s3.amazonaws.com/0/100025/3d93db68-f429-fc49-0d50-ea01d6ce44c5.png)

また基本的にはこれで終わり。
無事ログイン出来ました

![無題4.png](https://qiita-image-store.s3.amazonaws.com/0/100025/9afa9c53-afa2-a0ae-dedf-29373d89fee6.png)

何とも何とも、簡単な・・・
後はFX取引ツールをインストールして完了です。


# よく聞かれる質問
・クリップボードは共有出来るの？
　リモートデスクトップの設定でクリップボードは共有出来ます。
　設定はローカルリソースから変更可能です。
　※以外に知らない人が多い
　![無題6.png](https://qiita-image-store.s3.amazonaws.com/0/100025/0f4168c7-6db6-c41d-e404-a6dc5e0d8497.png)
　
・Windows Updateは有効にすべき？
　システム運用の場合、Windows Updateは手動で行っています。
　予期せぬアップデートを起因としたシステム障害を防ぐためです。
　FXの自動取引で使用する場合、そこまでヒステリックになる必要はないかもしれませんが、個人的に「無効」にするのはどうかと思います・・・

・スタートアップにExeのショートカット入れたいの！
　ここですｗ
  C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp

# 個人的に・・・
リモートデスクトップでつなぐサーバーの壁紙は必ず変えています
壁紙を変えないと、通常のPCと間違えちゃうんですよねぇ・・・

今回もちゃんと変えてみました！
　![無題5.png](https://qiita-image-store.s3.amazonaws.com/0/100025/9e4888a1-cadc-46e6-abe9-d711e3106eb5.png)

このはちゃんの壁紙フルセット最初から入れといてもよいのにねｗ
VS Code 1.30 の気になった変更点

[Visual Studio Code](https://code.visualstudio.com) の バージョン 1.30（2018年11月分アップデート）がリリースされたので、[リリースノート](https://code.visualstudio.com/updates/v1_30)を眺めてみて気になった変更点をチェックしてみた。(以前のバージョンを眺めてみた時のやつはこちら。[1.29](https://qiita.com/12345/items/6993dc21f310e1b5dd99) / [1.28](https://qiita.com/12345/items/b53d93fcb225abfc702d) / [1.27](https://qiita.com/12345/items/6a3967dd424b2be57104) / [1.26](https://qiita.com/12345/items/8ce4b6e045d50a6049ce) / [1.25](https://qiita.com/12345/items/e7b5b9954f5d721be2c8) / [1.24](https://qiita.com/12345/items/935770c6a3515ca80472) / [1.23](https://qiita.com/12345/items/627298550aab19f1d8a6) / [1.22](https://qiita.com/12345/items/8253a1eee38b6741905e) / [1.21](https://qiita.com/12345/items/71ce73c52cf2232fc10c) / [1.20](https://qiita.com/12345/items/1390c7cab11d968e7691) / [1.19](https://qiita.com/12345/items/a331c014a9d3fa9dac0e) / [1.18](https://qiita.com/12345/items/9b827138b5044ca82482) / [1.17](http://qiita.com/12345/items/28d83361341ce3ff3c9c) / [1.16](http://qiita.com/12345/items/5215293977dde2149c0f) / [1.15](http://qiita.com/12345/items/cebf4b4e9bfb2d2ef771))

# メニューの縦スクロール機能
https://code.visualstudio.com/updates/v1_30#_scrolling-menus
VS Codeのウィンドウの縦幅が狭くてメニューバーのメニューが表示しきれない場合、これまではウィンドウからはみ出た部分は表示が隠れてしまっていたが、メニューがスクロール可能になった。
![scroll_menu.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/f5151fee-6015-3f67-47e6-72d377fdfe9f.gif)
細やかな配慮！

# 表示あふれしたメニューバーの操作
https://code.visualstudio.com/updates/v1_30#_menu-bar-overflow-menu
ウィンドウの横幅が狭くてメニューバーが表示しきれない場合、これまではキー操作を使わないと隠れたメニューを操作できなかったが、表示しきれないメニューを`...`から表示できるようになった。
![narrow_menubar.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/5d42a962-beeb-e513-e28b-08b3a09f2f13.gif)
細やかな配慮！

# 設定画面、ショートカットキー設定画面のメニューの移動
https://code.visualstudio.com/updates/v1_30#_moved-settings-editor-actions
設定画面およびショートカットキー設定画面のメニューは、従来は独自の`...`メニューを持っていたが、エディタタブの右横にある`...`メニューに統合された。
また、`settings.jsonを開く`メニューは`{}`というメニューバーボタンに変更になった。

v1.29|v1.30
:-:|:-:
![settings_before.jpg](https://qiita-image-store.s3.amazonaws.com/0/181011/083a2db4-f206-dc32-9aa3-b85ef5e63830.jpeg)|![settings_after.jpg](https://qiita-image-store.s3.amazonaws.com/0/181011/ef332a9d-aef6-4da8-65f5-846276046d1c.jpeg)

# スニペットのコメント変数の追加
https://code.visualstudio.com/updates/v1_30#_snippet-comment-variables
行コメント、ブロックコメントの変数が用意され、展開時に言語ごとのコメント記法に変換してくれる。
![snippet_comment.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/ca1bc562-6e7e-5edf-b702-74224a5608e9.gif)
すげー！
ぱっと使い道思いつかないけどすげー！

# カーソル移動のアニメーション
https://code.visualstudio.com/updates/v1_30#_smooth-cursor-animation
新しい設定`Editor: Cursor Smooth Caret Animation`をオンにするとカーソル移動がアニメーションになる。
![anime_cursor.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/e15e9ae7-cae6-c779-ba72-f5d6d37343c7.gif)
びよーん！びよーん！
GitHubのプロジェクトをGitLab CEにインポート～EHW2018「アプリ⑥」 

# 概要

このエントリは、「Enterprise "hello, world" 2018 Advent Calendar 2018」の12/20向けのものです。このAdvent Calendarでは、複数個のエントリにまたがる話の流れも鑑みつつ、なるべく1エントリで1つのトピックをカバーできるようにする予定です。

このエントリで記載するトピックは、GitHubのプロジェクトをGitLab Community Edition(以下、GitLabと略します。GitLab.comのことではありません)にインポートすることです。

第10日目のエントリ、[GitLabをコンテナで動かしてSamba4のActiveDirectoryで認証～EHW2018「開発環境整備③」](https://qiita.com/hrkt/items/0927fc45fe515d86346d)で作ったGitLabで作業します。

# 前提

## おことわり

- このEnterpfise "hello, world"シリーズは、ネタのためのエントリです。実環境でそのまま利用ことを目的とはしていません。
- 動かしやすさを優先してセキュリティを意図的に低くする設定など入れてありますのでご注意ください。

## 想定読者

「Enterprise "hello, world" 2018」的なネタとしては、下記のような状況を想定しています。

> ~~(実は今まで、Advent Calendarシリーズにおいては便利さ優先でGitHubで作業していたので、デプロイを考えるとそろそろ)~~GitLab上にアプリをコミットする必要がある。

# GitHubからリポジトリをインポート

## GitLabにログイン

第10日目に作ったGitLabにログインし、ダッシュボードで「import project」を選びます。

![Screenshot_2018-12-25_06-26-08.png](https://qiita-image-store.s3.amazonaws.com/0/65002/9a801fde-122d-7712-5a0b-29e0527b7a22.png)

## GitHub側でトークンを発行

メニューから「Settings」、左下に出てくる「Developer settings」と進み、「Personal access tokens」を選択します。


![Screenshot_2018-12-25_06-26-08.png](https://qiita-image-store.s3.amazonaws.com/0/65002/d82d6ec9-ad01-99a9-e51e-8d5e69b25d0d.png)

「Generate new token」を押すと、トークンに許可する内容（スコープ）の一覧が現れるので、必要なものだけ選択します。

![Screenshot_2018-12-25_06-57-19.png](https://qiita-image-store.s3.amazonaws.com/0/65002/7c4d6cfd-521a-b9ed-2f65-eb8a833b47ea.png)

このエントリでは、必要なのはpublic_repoへのアクセスだけです。

![Screenshot_2018-12-25_06-59-39.png](https://qiita-image-store.s3.amazonaws.com/0/65002/157a6666-fc84-f4e9-8e75-38ba32e2d89e.png)

「Generate Token」します。

出来上がったアクセストークンをメモしておきます。

![Screenshot_2018-12-25_07-01-36.png](https://qiita-image-store.s3.amazonaws.com/0/65002/a40224d4-bac9-b136-bfcd-b3eb69ba4de7.png)


## GitLab側でトークンを登録してインポート

![Screenshot_2018-12-25_07-04-51.png](https://qiita-image-store.s3.amazonaws.com/0/65002/53d56c6e-afe8-4991-00af-5135ba71473f.png)

前述の過程でメモしたアクセストークンを入力します。

「List your GitHub repositories」を押します。

少し待つと、GitHub側のリポジトリ一覧が表示されるので、今回関係があるものを「import」します。

![Screenshot_2018-12-25_07-08-27.png](https://qiita-image-store.s3.amazonaws.com/0/65002/d02a06f4-b539-b93e-f2d9-74f218a7c0b1.png)

少し待つと、StatusがDoneになり、インポートできています。

![Screenshot_2018-12-25_07-10-25.png](https://qiita-image-store.s3.amazonaws.com/0/65002/21198c57-652a-b361-2af6-656e93137d94.png)

インポート画面にあるリンクをクリックすると、インポートされたリポジトリを確認することができます。

![Screenshot_2018-12-25_07-14-26.png](https://qiita-image-store.s3.amazonaws.com/0/65002/792d2528-0ae6-1c18-1c44-70396172a4f3.png)

インポートされました。


# まとめ

このエントリでは、「Enterprise "hello, world" 2018 Advent Calendar 2018」(EHW2018)20日目として、GitHubのプロジェクトをGitLab CEにインポートすることをトピックとして取り上げました。

EHW2018のネタとしては、このあと、もう少しデプロイの準備を進めることを考えています。
組込エンジニアのおすすめする本

#組み込み系エンジニアのおすすめする本
IT系エンジニアの中でも組み込み系エンジニアは希少品種かもしれません。そんな筆者が最近読んでいる本を紹介します。
###対象読者
組み込み系の開発に従事している方々
##はじめに
最近、いい本が出始めてきた組み込み系の本の紹介をしたいと思います。

C/C++による組み込みシステムプログラミング
古い本ですが、LEDチカあたりから組み込み系の基本的なプログラミングがなぞれる本です。
一点難点としては、書かれているコードを実際に動かす事ができないがあります。
しかし、いまはラズベリーパイとかを使えば、Lチカとかも確認することができます。

テスト駆動開発による組み込みプログラミング+―C言語とオブジェクト指向で学ぶアジャイルな設計
TDDをC言語を使って組み込み分野で行うことを実践できる本です。
当方の職場もテストコードは必須になりつつあるので購入しました。
CUnitを使ったガイドブックはなかなか見かけないんじゃないのかと思いますので、なかなか貴重なのではないかと思います。
実際の組み込みのプロジェクトはC言語を使っていることが多いので、本の記載がそのまま業務に使えるかもしれません。
#まとめ
このあたりを読んだあとでインターフェースの興味のある特集記事あたりから読み始めれば、なんとなく雰囲気が感じられるようになるんじゃないでしょうか？
[Bootstrap-Table] JavaScriptでテーブル表示（その4）イベント

Bootstrap Table のイベントについて紹介します。

Bootstrap Table
http://bootstrap-table.wenzhixin.net.cn/

```Markdown:JavaScriptライブラリ
Bootstrap Table: 1.12.1
```

# テーブルの描画

`pre-body.bs.table`は、テーブルを描画が始まる前に発火するイベントです。

```JavaScript:テーブルの描画前イベント
}).on('pre-body.bs.table', function (data) {
    log('[pre-body.bs.table]');
})
```

`post-body.bs.table`は、テーブルを描画が終わったときに発火するイベントです。

```JavaScript:テーブルの描画後イベント
}).on('post-body.bs.table', function (data) {
    log('[post-body.bs.table]');
})
```

# クリック

`click-row.bs.table`は、テーブルの行をクリックしたときに発火するイベントです。

```JavaScript:行のクリックイベント
}).on('click-row.bs.table', function (element, row) {
    log('[click-row.bs.table] row=' + JSON.stringify(row));
})
```

`click-cell.bs.table`は、テーブルのセルをクリックしたときに発火するイベントです。

```JavaScript:セルのクリックイベント
}).on('click-cell.bs.table', function (element, field, value) {
    log('[click-cell.bs.table] field=' + field + ', value=' + value);
})
```

# チェックボックス

`check.bs.table`は、チェックボックスのチェック（あり）のときに発火するイベントです。

```JavaScript:チェックボックスありイベント
}).on('check.bs.table', function (element, row) {
    log('[check.bs.table] row=' + JSON.stringify(row));
})
```

`uncheck.bs.table`は、チェックボックスのチェック（なし）のときに発火するイベントです。

```JavaScript:チェックボックスなしイベント
}).on('uncheck.bs.table', function (element, row) {
    log('[uncheck.bs.table] row=' + JSON.stringify(row));
})
```


# ソート

`sort.bs.table`は、テーブルのカラムをクリックしてソートしたときに発火するイベントです。

```JavaScript:ソートイベント
}).on('sort.bs.table', function (element, name, order) {
    log('[sort.bs.table] name=' + name + ', order=' + order);
})
```

# ページング

`page-change.bs.table`は、テーブルのページを変更したときに発火するイベントです。

```JavaScript:ページングイベント
}).on('page-change.bs.table', function (event, size) {
    log('[page-change.bs.table] page=' + size);
})
```

[デモはこちら](https://yunbow.github.io/sample-bootstrap-table/04/01/)
[ソースファイルはこちら](https://github.com/yunbow/sample-bootstrap-table/tree/master/04/01/)

以上です。

# 関連記事

[[Bootstrap-Table] JavaScriptでテーブル表示（その1）](https://qiita.com/yun_bow/items/f3f70b42584b7fb56ea5)
[[Bootstrap-Table] JavaScriptでテーブル表示（その2）](https://qiita.com/yun_bow/items/f95e67c0bdec8923b315)
[[Bootstrap-Table] JavaScriptでテーブル表示（その3）](https://qiita.com/yun_bow/items/4ca4620da895b131edb9)
[[Bootstrap-Table] JavaScriptでテーブル表示（その4）](https://qiita.com/yun_bow/items/c84acb7fd45fdd481d46)
[[Bootstrap-Table] JavaScriptでテーブル表示（その5）](https://qiita.com/yun_bow/items/d845a2b3389fc8ca7ae1)
macだけでRaspberry Piに接続してみた

ZOZOテクノロジーズ新卒のむーさん([@murs313](https://twitter.com/murs313))です。
Raspberry Piを有線で繋いでセットアップするつもりが、アダプタの端子を間違えて購入してしまい繋げませんでした＼(^o^)／

というわけで、ディスプレイなし、キーボードなし、マウスなし、LANケーブルなしの4重苦の中で、線も使わずにRaspberry Piに接続して画面をmacに共有するところまでしたメモです。

# 必要なもの
- Raspberry Pi 3
- Raspbianが入ったmicroSD (私はラズパイのキットのプリインストールされているmicroSDをそのまま使用しました)
- Mac (microSDが読めればOK)

以上！！

# 手順
### 1. ラズパイにSSH接続する準備
raspbianの[リリースノート](https://downloads.raspberrypi.org/raspbian/release_notes.txt)を見ると下記のように書かれおり、`2016-11-25`のバージョンからSSH接続がデフォルトでオフになっているようです。
> 2016-11-25:
  * SSH disabled by default; can be enabled by creating a file with name "ssh" in boot partition

言われた通り、microSDのルートである`boot`に`ssh`という名前の空ファイルを作ってSSH接続を有効にします。
microSDをmacで読み込んで、macのTerminalを立ち上げ、下記を実行します。

```shell:macOS
$ touch /Volumes/boot/ssh
```

### 2. ラズパイをWi-Fiに接続する準備
ラスパイと無線で通信するために、ラズパイにWi-Fiの設定を書き込みます。
繋ぐWi-FiのSSID(ネットワーク名)が`hoge`、パスワードが`fuga`のとき、下記のようなファイルを作成し、同じくmicroSDのルートディレクトリ`boot`に配置します。

```text:wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
	ssid="hoge"
	psk="fuga"
}
```
これでラズパイが起動した時に指定したWi-Fiに繋がってくれます。

### 3. SSH接続する
いよいよ無線でSSH接続します。
microSDをラズパイに刺して電源を入れます。OSが起動するまで1分ほど待ちます。
その後、macのTerminalで下記を実行。

```shell:macOS
$ ssh pi@raspberrypi.local
```
(@以降でラズパイのIPアドレスを指定しても接続できますが、このようにホスト名でもアクセスできます。)
パスワードを聞かれるので、 `raspberry`(初期パスワード)と入力してreturnキーを押すと、下記のように表示され、ラズパイに接続されたことが確認できるはずです。

```shell:Raspbian
pi@raspberrypi:~ $
```

### 4. IPアドレスを調べる
画面共有に必要なのでラズパイのIPアドレスを調べます。せっかくSSH接続しましたが、一度`$ exit`で抜けて、macのTerminalで下記のarpコマンドを実行します。

```shell:macOS
$ arp -a
```
LAN内のIPアドレスやMACアドレス等が下記のように表示されます。

```text
? (IPアドレス) at MACアドレス on ~~~~~ [ethernet]
```
`at xx:xx:xx:xx:xx:xx`部分がMACアドレスです。[ラズパイのMACアドレスはb8:27:ebから始まるので](https://www.raspberrypi.org/forums/viewtopic.php?t=55804)、`b8:27:eb`から始まるMACアドレスを探して、その行頭の括弧()に囲われているIPアドレスをメモしておきましょう。


### 5. VNC接続(画面共有)する
再度ラズパイにSSH接続します。

```shell:macOS
$ ssh pi@raspberrypi.local
```
SSH接続したまま、下記コマンドを叩いてVNCサーバーをインストールします。

```shell:Raspbian
pi@raspberrypi:~ $ sudo apt-get install tightvncserver
```
インストール後、下記コマンドでサーバーを立ち上げます。

```shell:Raspbian
pi@raspberrypi:~ $ sudo tightvncserver
```

初めての立ち上げの場合、パスワードを設定します。接続の際に使います。
`New 'X' desktop is raspberrypi:1`のように表示されたことを確認します。
この末尾の数字プラス5900の、5901がポート番号となります。このあと使います。

VNC接続をします。
Finderの移動タブから「サーバーへ接続」
<img width="500" alt="スクリーンショット.png" src="https://qiita-image-store.s3.amazonaws.com/0/309128/64300ba2-91bc-4e57-5a5f-4cf08f17115a.png">
「サーバアドレス」の欄に`vnc://IPアドレス:ポート番号`と入力して、接続。
<img width="500" alt="スクリーンショット.png" src="https://qiita-image-store.s3.amazonaws.com/0/309128/7967c34f-963c-9185-d29d-86a3b4e40546.png">
パスワードを求められるので先ほど設定したパスワードを入力すると、画面共有が立ち上がってRaspbianの画面が映し出されるはずです。
![スクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/309128/7700d0d9-1397-28b1-bd4d-5b732442b583.png)

# まとめ
ラズパイを使うのに、新しくキーボードやLANアダプタを買う必要はなさそう！！ヤッター！！！
巨大CSVインポート処理を見直して50分短縮

割と手垢のついたテーマではありますが、Railsを使ったCSVインポート処理を、1時間->10分に短縮したので、その時のポイントを列挙します。

### 前提
- CSVは1万件のレコードかつ、100程度の列数
- CSVインポートはRooを使用 https://github.com/roo-rb/roo
- `Parent`のhas_many関係に`Child`がある

### 見直し前のコード（重要な部分のみ）

```ruby

xlsx = Roo::Spreadsheet.open(file)
xlsx.sheet(0).each(
  column1: '列1',
  column2: '列2',
  ...
).with_index do |item, i|
  parent = Parent.find_or_create_by(id: xxx)
  child = Child.new
  child.column1 = item[:column1]
  master_item = MasterItem.find_by(name: item[:column2]) ...(1)
  child.column2 = master_item.item
  parent.children << child ...(3)
  parent.save ...(2)
end
```

### 見直し(1): いちいちDBにアクセスしない
コード上の(1)ですが、DBから条件に一致するデータを取り出しています。1万件近いCSVデータのループ内なので、同数のselect文が走ることに。そのselect対象のテーブルのレコード数にもよりますが、あらかじめ配列等に格納していた方が良さげです。

### 見直し(2): こまめにsaveしない
重要な書類の作業中には定期的に保存した方が吉ですが、このケースではかえって逆効果です。

bulk insert を使って一気にinsertを行います。
https://github.com/zdennis/activerecord-import


### 見直し(3): `<<`を使うとその時にsaveされる
`parent.children << child`といった書き方で子データを格納すると、この瞬間にsaveが走ります。どのみちsaveされるので別にこれでもいいのですが、bulk insertで一気に保存しようとしているのに、この部分で足を引っ張ることになります。


### 見直し後のコード
```ruby
master_items = MasterItem.all.pluck(:name, :item) ...(1)
parents = []
xlsx = Roo::Spreadsheet.open(file)
xlsx.sheet(0).each(
  column1: '列1',
  column2: '列2',
  ...
).with_index do |item, i|
  parent = Parent.find_or_create_by(id: xxx)
  master_item = master_items.find{|m| m[0]==item[:column2]} ...(1)
  parent.children.build(
    column1: item[:column1]
    column2: master_item[1]
  ) ...(3)
  parents << parent...(2)
end
Parent.import parents, recursive: true, on_duplicate_key_update: [:id] ...(2)

```

### 見直し後(1): 必要なDBのデータだけメモリ常にもつ
今回のケースで欲しかったのは、`MasterItem`の`name`に条件が一致する`item`なので、この2つだけ配列で格納して、検索自体はその配列上で行うことにしました。

### 見直し後(2): bulk insert & bulk update
saveしたい`parent`を配列に格納して、`Parent.import parents` とするだけで bulk insertが走ります。
ここでのポイントは `recursive`と`on_duplicate_key_update`です。
has_many関係にあるchildrenも一緒にinsertしたい場合は、`recursive: true`というオプションを渡します。
また、今回は条件によってはupdateにしたいため、`on_duplicate_key_update: [:id]`でupdateにも対応します。


### 見直し(3): buildを使う
せっかくのbulk insertを活かすために`build`を使って子モデルデータを格納します。


### 結果
冒頭にも書いてますが、見直し前のコードでは1時間ほどかかっていた処理が50分近く短縮され、約10分で完了しました。
バリデーションやロールバックなどの整備をすると速度に変動が出てくるかもしれませんが、十分問題ないレベルかなと思います。
\futurelet のお勉強で作った漢文訓点スタイル

 * CTAN にも[gckanbun](https://www.ctan.org/pkg/gckanbun)パッケージを登録されました。TeX Live 2021から、`gckanbun` パッケージとして利用可能になるはずです。
 * [munepi/gckanbun - GitHub](https://github.com/munepi/gckanbun) にて、 `gckanbun.sty` 2021/03/25 v1.0 をリリースしました。

> これは「[TeX ＆ LaTeX Advent Caleandar 2018](https://adventar.org/calendars/3382)」の23日目の記事です。
> 22日目は、[zr_tex8rさん](http://d.hatena.ne.jp/zrbabbler/20181222/1545495849)でした。24日目は、[golden_luckyさん](https://github.com/k16shikano/yafootnote/tree/master)です。

みなさん、[#テフライブ！](https://twitter.com/search?f=realtime&q=%23%E3%83%86%E3%83%95%E3%83%A9%E3%82%A4%E3%83%96%EF%BC%81) していますか？

この記事では、（LuaTeXと全く関係ありませんが、）十数年前の若かりし頃に、「 `\futurelet` のお勉強がてらに作った漢文訓点スタイル」（の昔話）を紹介します。



## `\futurelet` ってよく分からん（かった）

`\futurelet` の解説は、例えば、本田さんと吉永さんとの共著『LaTeX2eマクロ＆クラスプログラミング基礎解説』の10ページにある。

それによると、`\futurelet` は、その後ろに3つのトークンを従って、

``` tex
\futurelet〈token1〉〈proc〉〈token2〉
```

のように用いる。これは、

``` tex
\let〈token1〉= 〈token2〉〈proc〉〈token2〉
```

と等価である。サンプルとして、

```
\def\@test{[\@nexttoken]}
\futurelet\@nexttoken\@test\LaTeX
=> [LaTeX]LaTeX
```

とある。十数年前の当時、これを読んで試行したり、マクロの展開を追っても、 `\futurelet` の嬉しさが正直よく分からなかった。

## あれ？　これ、漢文の訓点の入力に使えるんじゃない！？

しばらくの間、 `\futurelet` となんとなくで使っていたんだけど、それでも嬉しさが実感として分からなかった。

十数年前のある日、ふとしたときに、漢文の訓点を入力する必要があって、巷にはいくつか訓点スタイルがあったけれども、訓点コマンドに決まった引数を必ずつけるマクロなものが多く、これは入力するのが大変だなーと思っていた。

そのとき、あっ、「 `\futurelet` で次に訓点の何がくるかどうかで見ていけば…、」と気づいた。
しかも、「ルビ→送り仮名→返り点→句読点」を全部 `\futurelet` で追えばええやんと。

## 初めて作った `\futurelet` の応用例：漢文訓点の入力マクロ

~~GitHubGistに https://gist.github.com/munepi/5c9e53936e3540b8374b4ab14e6b7832~~ [munepi/gckanbun - GitHub](https://github.com/munepi/gckanbun) を公開してみました。

作った当時よりも、接頭辞 `\gcknbn@` を入れたり、 `\dimexpr` で計算するように書き換えたりしていますが、実際の処理は当時のままです。
（今だったら、もう少し綺麗に書けますが、リファクタリングせずに晒します :-) ）

`uplatex+dvipdfmx` で `test-gckanbun.tex` をタイプセットすると、以下のスクリーンショットのようにPDFへ出力されます。

![スクリーンショット 2018-12-25 4.54.46.png](https://qiita-image-store.s3.amazonaws.com/0/43618/7f6e7add-1a0a-6b09-c411-08cd8687796e.png)

簡単な `\futurelet` の例だけど、訓点入力コマンドとしては、面白い応用例だと思っているのですが、どうでしょうか？

（すみません、時間の都合上、 2018年12月25日段階で、この漢文訓点スタイルの詳しい解説を省きますm(_ _)m オモロイところは、簡単な `\ruby` マクロに `\futurelet` と使って「送り仮名」を見に行っているところです。これにより、漢文訓点マクロの引数をすべて構えなくても良くなっています。すみません、詳細を省きます。）

<!--
## ある日ふと気づいたときに見ていたもの

[青空文庫作業マニュアル【入力編】](https://www.aozora.gr.jp/aozora-manual/index-input.html) の [訓点](https://www.aozora.gr.jp/annotation/kunten.html) の入力仕様を見ていたときに、「ビビビッ！！」と来ました！

いま、このページを見て、ふと気づいたことがあって、このページの一番下に「再読文字」があるんですけど、 アレ！？  `gckanbun.sty` に実装していませんね（笑） （左側にルビをつけるだけですから、同じような感じでやれば、実装できるとは思います。）
-->

## まとめ

 * 最初はよく分からない物事だったとしても、ある日ふと、自分で何かの嬉しい応用例を作れたときの楽しさは格別！
 * でも、歳を食ってきて、昔話ばかりを語るようになったら、終わり！
 * なので、**ナウなヤング** はLuaTeXを使いましょう！