OmniAICreator/Qiita-1.07M huggingface dataset:
sessionに保存されたHashを別アクションで利用しようとした際にデータ型の変更によりハマった件[Rails]

# **はじめに**
Railsアプリでsessionを利用し、データをビューで表示する際、エラーが発生しました。
そのエラーの原因と解決策をここで共有しておきます。

# **コードで説明**

```session_controller.rb
def session_store
  controller_data = Hash.new
  .
  .
  # controller_data = {name: 'takuyanin', email: 'takuyanin@gmail.com'} のようなデータが途中で挿入されたとしておきます。
  .
  session[:view_data] = controller_data
end
```

キーはシンボル型で代入されましたが、**sessionに保存されたHashはストア後に、別のアクションで使用する際、文字列型に変化します**。
理由は、ブラウザにjsonで保存されるためだそうです。
[Session : Symbols hash keys getting converted to literals keys in next request (Rails 4.2.3 · Issue #22796 · rails/rails](https://github.com/rails/rails/issues/22796)

ですので、別アクションで利用する際は、先ほどのHashが、次のように変化していることを踏まえて、文字列型で取り出す必要があるみたいです。

```session_controller.rb
session[:view_data] = {'name' => 'takuyanin', 'email' => 'takuyanin@gmail.com'}

```
# **終わりに**
セッションでデータ保持し、別アクションで利用する際には、自動的に型変化が行われていることは、知らないとハマってしまいそうなところですよね。
気をつけたいと思います。

少しでも役にたったよーて方はいいねお願いします(^^)


# **Rails関連記事**
[正規表現まとめ（基礎）[Ruby編]](https://qiita.com/takuyanin/items/2918ffb3151dcfa88565)
[配列で利用できる主なメソッドをまとめてみた[Ruby編]](https://qiita.com/takuyanin/items/3ca4cd7067b7b9e7e9b6)
[Mysql2::Error: Duplicate entry for key.. エラーを撃退した話(validationの設定)](https://qiita.com/takuyanin/items/b28d5111447d4dedc39d)
[Rails5でJqueryを利用しようとして少しハマった件（Uncaught ReferenceError: $ is not defined）](https://qiita.com/takuyanin/items/24444ec3005098471f3b)
[change_columnでの設定はrollbackできない話(This migration uses change_column, which is not automatically reversible.)[Rails: migration]](https://qiita.com/takuyanin/items/6d51ffb4078a417fed35)
ElementUIを日本語で使う方法をまとめてみた.

#この記事では.
最近vueでお仕事をしていて,コンポーネントライブラリ?にElementUIも使っています.
基本的に日本語にする方法はググればでるけど,オンデマンドな場合(ボタンのみ読み込む場合)は見つからなかったからまとめておく.

#ElementUI
多分中国製のライブラリ,デフォルトが中国語だから..
詳しくは↓
http://element.eleme.io/#/en-US

#日本語にする方法
```javascript:全て読み込む場合
import Vue from 'vue'
import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/ja'

Vue.use(ElementUI, { locale })
```
こいつは調べると結構でてくる.

#とある日異変が..
pullしていろいろテストしてたら,テーブルのデータ無し時.???なんて読むの???
![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/116239ed-20c8-6500-d21c-5e37c474dab8.png)
とりあえず,gitLogをたどると軽量化のためにオンデマンドな読み込みに変わっていた.

```javascript:オンデマンドで読み込む場合
import Vue from 'vue'
import {Table, TableColumn} from 'element-ui'
import locale from 'element-ui/lib/locale/lang/ja'

Vue.use(Table, { locale })
Vue.use(TableColumn, { locale })
```
元の記載に沿って上記のようになっていた.
公式docを読むとポイ記載があったので書き直すと動いた.

```javascript:正解
import Vue from 'vue'
import { Button, TableColumn} from 'element-ui'
import lang from 'element-ui/lib/locale/lang/ja'
import locale from 'element-ui/lib/locale'

// configure language
locale.use(lang)

// import components
Vue.use(Table)
Vue.use(TableColumn)
```

詳しくは↓
http://element.eleme.io/#/en-US/component/i18n#internationalization
wikipediaっぽくリンク先プレビューを出したい。jQueryプラグイン導入

wikipediaっぽくに
マウスオーバーした時にリンク先のプレビュー画像を表示させたい。

wordpressプラグインでは見つからなかったので、

jQueryプラグインをwordpress内に導入してみた。
イメージはなんとなくできたけども、実際手を動かすとかなり手こずった。


まずはプラグイン探しから、minipreviewというプラグインが良さげだったのでそれを
フォルダごとmini-preview-masteインストール。
https://github.com/lonekorean/mini-preview

次に
wordpress内を見ていく
ダッシュボード→外観→テーマの編集

ここからコードをいじっていくわけだが、直接いじることはしないで
FTPソフトを使って、一度ローカル環境に落とし込んでエディターで編集しよう。
この時にいじるファイルのバックアップを必ず取っておく！

インストールしたプラグインの必要なファイルもFTPソフトを通じて
wordpress内に入れておこう。
wo-contentの中に、相対パスを書く上で大事になってくるから入れる場所も要チェック
私の場合はフォルダを作っていたのでそちらに入れた。
 jsフォルダに　jquery.minipreview.js　を追加
 cssフォルダに　jquery.minipreview.css　を追加


それではコードをいじっていく
いじっていくファイルは、　header.php と　footer.php
header.phpのheadタグに　
minipreviw実装に必要な記述を書き込んでいく
インストールしたmini-preview-masterフォルダ内にindex.htmlがあるのでそちらを参考に
（jquery.minipreview.css　も忘れずに）



次にfooter.phpをいじっていく
bodyタグの下の方に
scriptタグを貼り付けて　jquery.minipreview.js　を読み込ませる

common.jsにminipreviewの内容を記述したかったが、動かなかったので
今回はfooterに直書きした。とりあえず動くことを優先した。



とりあえず動いた。


何か質問や気になることがあれば
コメントください！！！
RubyのTime系の型は小数点以下も保持するので気をつける

Rubyなら `Time.now` 、Railsなら `Time.zone.now` などで使う `Time` や `TimeWithZone` 意識して使わないと思わぬバグを生む原因なのでその事例を箸休め的にご紹介。

## 環境

```sh
$ ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]
```

```sh
$ bundle exec rails -v
Rails 5.2.1
```


## 例

[ISO8601](https://ja.wikipedia.org/wiki/ISO_8601)の形式に沿う形式出力がRubyにあり、オプションとして引数に値を入れると小数点以下の値も付随してくれるので、そこで確認することができる。

```ruby
require 'time'
=> true

now_time = Time.now
#=> 2018-12-01 11:42:01 +0900

now_time.iso8601
#=> "2018-12-01T11:42:01+09:00"

# .iso8601({{小数点以下の桁数}})で確認できる
now_time.iso8601(5)
#=> "2018-12-01T11:42:01.69147+09:00"
```

`11:42:01.69147` となり小数点以下の秒数を保持していることがわかる


## 起こりうるケース

日時だけ保存するデータ（主にMySQLなどのRDSのDateTime等）は小数点以下の秒数をもっていないことが多い。そのため範囲比較をするときに目に見えにくい範囲も比較してしまい。予期せぬ挙動をすることがある。


### 例
期間の終了を `term_end` として人が設定した値として持ち、それに対して特定の月の最終日と合致するかを確認する。


```ruby
## 期間の終了日（今回はStringから起こす形）
term_end = "2018/12/31 23:59:59".in_time_zone
# => Mon, 31 Dec 2018 23:59:59 JST +09:00

## 特定の月
month_start_at =  "2018/12/01 00:00:00".in_time_zone
# => Sat, 01 Dec 2018 00:00:00 JST +09:00

## 特定の月の最終日
month_start_at.end_of_month
# => Mon, 31 Dec 2018 23:59:59 JST +09:00
```

irb上で出力される見た目は同じだからイコールになりそうだが…

```ruby
month_start_at.end_of_month == term_end
=> false
```

小数点のレベルで相違があるのでそうはならないのでそうはならない。

```ruby
month_start_at.end_of_month.iso8601(5)
# => "2018-12-31T23:59:59.99999+09:00"

term_end.iso8601(5)
# => "2018-12-31T23:59:59.00000+09:00"
```

## 関連リンク

* [ActvieSupportのend\_of\_\*\*はミリ秒まで設定される \- コード日進月歩](https://shinkufencer.hateblo.jp/entry/2018/11/28/000000)
かき氷器

```

Adoin.prototype = new RazorEdgeObject();
function Adjoin() {

     this.agent;
     this.patient;

     this.loEl = {
         {type: "agent pose update"}: {
             alpha: (e) => {
                 let choreography = e.detail;
                 // choreography
                 //     [
                 //         [() => {    this.agent.rotate(1);    }],
                 //         [() => {    this.agent.rotate(2);    }],
                 //         [() => {    this.agent.rotate(1);    }],
                 //     ]
                let converted = this.patient.convert(choreography);
                this.patient.receive(converted);
             }
         },
     };
}

function KakigouriVendor() {
    this.c = ["wheel >> cutter >> bard"];
    this.bard = {c: ["block of ice"], cubage: {height, width, depth}, materials: ["water"]};
    this.receive = (lop) => {
        if (lop.contains(choreography)) {
            // TODO: loadChreography
        }
    }

    this.rotate = (lop) => {
        let reply = 0;
        for (let i = 0; i <= 0; lop.degree - 1;) {
            reply += (2 * this.bard.shift());
        }
        return reply;
    }
}

var agent, patient, adjoin;
window.onload = (e) => {
    
    agent = new Person();
    patient = new KakigouriVendor();
    adjoin = new Adjoin({agent, patient.wheel});

    let vendor = {
        patient,
        booster: {
            execute: (lop) => {
                return 360 * lop.round;
            }
        },
        execute: (lop) => {
            let degree = 0;
            if (lop.contains("unit") && lop.unit == "round") {
                degree = this.booster.execute(lop.value);
            } else {
                degree = lop.value;
            }
            
            repeat(degree, this.patient.receive({selector: "rotate", lop: {degree: 1}}));
        },
    };


};

```
引数にURLクエリのkeyをいれると、jsが評価できる値を返す

```js

/**

@param {string} name - 引数にURLクエリのkeyをいれると、jsが評価できる値を返す

例)クエリが次の場合: `?hoge={}&foo=[1,2]&bar=true&piyo&fuga=hensu`
- getUrlParameter('hoge') // {}
- getUrlParameter('foo') // [1,2]
- getUrlParameter('bar') // true
- getUrlParameter('piyo') // null
- getUrlParameter('fuga') // エラー
- getUrlParameter('hogera') // null
*/
function getUrlParameter(name) {
    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
    var results = regex.exec(location.search);
    return results === null ? null : JSON.parse(decodeURIComponent( results[1].replace(/\+/g, ' ') ));
}

/**
@return {boolean} - そのkeyがあるかないか
*/
function existParameter(name) {
	var v = location.search.match(name)
	return v ? true : false;
}

// 素朴な質問でも受付中。即座に回答します
```
チーム開発〜開発ディレクターって何者？〜

こんにちは〜
6期iPhoneコースのさきんちょです🍣
![topic.jpg](https://qiita-image-store.s3.amazonaws.com/0/84087/1ca53453-3dca-5b2f-d36d-00c3296cf4fc.jpeg)

#はじめに
みなさんチーム開発をした経験はありますか？？
Life is Tech !で活躍するメンターの中には、ハッカソンなどでチーム開発をした経験があるメンターも多いはず(^○^)

この記事は、アプリやWebなどをチーム開発する時に役立ちます。
具体的には、さっき書いたようにチームでハッカソンに参加する時や、サービスを作る会社で働いた時などですかね。

今回は、チーム開発における
開発ディレクターの役割や、普段考えていることを、
開発ディレクター修行中の私から少し紹介したいと思います。

# そもそもチーム開発って？
複数人でアプリやWebなどの開発を行うことです。
サービスにもよりますが、チームのメンバーはだいたいこんな感じで構成されることが多いです！

![pj.jpg](https://qiita-image-store.s3.amazonaws.com/0/84087/80b40f31-0574-ccc3-9eb0-00c18a3384b2.jpeg)



開発ディレクターは、Directorと呼ばれることも多くあります。
今回は統一して、開発ディレクターと呼ぶことにします。

# 開発ディレクターって何者？
一言でいうと、**開発をディレクション(指揮)する人**です！（まんま！！笑）

先ほどの画像にもあったように、1つのプロジェクトを作るチームの中には
デザイナー、エンジニア、開発ディレクターがいます！

開発ディレクターとは、チームでの開発がスムーズに進むように
**デザイナーとエンジニアをまとめ、チームをディレクションする存在なのです！**
また、企画・設計や開発チームのマネジメントだけでなく、マーケティング戦略やビジネス戦略を考えたり、サービスの方向性に関する意志決定に関わることもできます。

ちょっと難しい話になりましたが、
サービスがどんどん大きくなってくると、開発ディレクターはチーム開発をするうえで必要不可欠な存在なんです！！✨

# どんなことをするの？
開発ディレクターは、企画を練り、実際のモノ・カタチにする仕事をしています。

企画案に対して要件を作り、様々な仕様をデザイナーやエンジニアと一緒に固めて、最終的にはリリースされるまで立ち会います。要はアイデアが生まれてからそのサービスや機能がリリースするまでの、全ての工程に関わっていると言っても過言ではないと思います。

# どんなスキルが必要か？
必要でないスキルってあるのか？？？？っていうくらい、色々なスキルが求められています。

- コミュニケーション能力
- アイデアのセンス
- 企画力
- スケジュール管理能力
- デザインやプログラミングの知識
- プレゼンスキル
- データ分析力

などなどなどなど。

こちらには、Webディレクターに必要な22のスキルが記載されています。
参考：https://mynavi-creator.jp/blog/article/skills-necessary-to-web-director

今回はその中でも、企画を考える上でのアイデアのセンスについて紹介しようかなと思います（＾ν＾）

# アイデアのセンス
<img width="227" alt="スクリーンショット 2018-12-07 18.24.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/84087/ad3e15d7-598c-63fd-64fe-a95271ffed4d.png">
「アイデアのつくり方」著者：ジェームス・W・ヤング 

<img width="248" alt="スクリーンショット 2018-12-07 1.13.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/84087/785037d9-0cef-fc65-b633-13c4d1d3a369.png">
「観察の練習」著者：菅 俊一

基本的に私は1週間に1冊を本を読むことを目標にしているのですが、
上記の本を読んで、私はアイデアのセンスを身に付けたいと思いました。

2つ目にあげた「観察の練習」の本で行っている観察の練習を、実際にここで少しだけ行ってみたいと思います。

----

> 私たちの身の回りでは日々、さまざまな「おや？」と違和感を抱くような出来事が起こっています。(中略)それは、あまりにも膨大なため、普段は無意識に見過ごしてしまっています。しかし、このような「日常の中の小さな違和感」にこそ、私たちを驚かせたりワクワクさせたりするアイデアを生むためのヒントが隠されているのです。

みなさんまずは写真だけを見て、この写真が捉えた違和感が一体何なのか、少し考えて見てください。
![IMG_1084.JPG](https://qiita-image-store.s3.amazonaws.com/0/84087/8363fa5a-c309-d94d-325b-a2727743dcef.jpeg)

違和感に気がつきましたか？？

## 「痕跡から推測する」
この写真は私が今度引っ越す予定があり、照明器具を買うために、新居の照明設置部分を写真に収めたものです。
最初はおしゃれな照明器具を買うという目的のためだけに、ささっとiPhoneで写真をとりました。

何日かして写真をもう一度見返した時に、私は小さな違和感に気がつきました。
設置部分の周りにある黄色っぽい丸枠に気がついたのです。
これはおそらく、前に住んでいた住人が、楕円形の照明を使用していた痕跡でしょう。
オレンジっぽい照明を使用していて、壁紙がすこし日焼けしてしまったのかもしれません。
まあそれでもこれは全部、推測ですが。

### 観察の練習
この「観察の練習」という本は、各ページに写真が一枚あって、それを見て**日常の中の小さな違和感**を考える構成になっています。
今回は、「痕跡から推測する」という、私が感じた日常の中の小さな違和感を紹介しました。

私は日常的に「おや？」とか、「いいね！」を探しています。
この本に興味を持った方は、是非読んで見て欲しいです！

# 最後に
今回は、開発ディレクターとは何ぞや？というところから、
（開発ディレクター修行中の）私が日常的にアイデアのセンスを磨くために行っていることを紹介しました。

長文読んでいただきありがとうございます🌸
今回書いた内容は、サービスや会社によって言葉の定義や役割が違う可能性もあるのでそこはご了承ください。

今も内定者アルバイトで開発ディレクターしているので、がんばるど〜〜！

お次は、同期のザイル（@Seil）くん！楽しみだ〜⭐️
Docker for Windows Windows10Homeじゃむりっぽい


https://github.com/docker/for-win/issues/1263

上記リンク中で

>Windows 10 Home is unfortunately not supported, as it does not have the features required for Docker to run (see https://docs.docker.com/docker-for-windows/install/#what-to-know-before-you-install).

とあり、googleさんによると

Windows 10 HomeはDockerの実行に必要な機能がないため、残念ながらサポートされていません（https://docs.docker.com/docker-for-windows/install/#what-to-know-before-あなたがインストールする）。

とのことです。

Windows10Homeじゃむりでした残念。

Docker Toolbox　ならOK？ぽい

https://docs.docker.com/toolbox/overview/#whats-in-the-box

今からやってみます！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/253014/aef2026a-d475-ac6a-c62c-ad78727ff390.png)

行けたー

toolboxなら使えそうです。

>Hyper-Vなしで利用できる
代わりに、VirtualBoxが使われる

https://blog.brains-tech.co.jp/entry/2018/05/15/080000

なるほど。

home => Proにアップグレードも考えたけど（ちょっと下の記事みてビビった。ちょうどパソコンカスタマイズしようとしてた。。。もう大丈夫らしいけど）

http://blog.mobilehackerz.jp/2016/06/windowswindows-10-homepro.html
http://blog.mobilehackerz.jp/2016/06/windowswindows-10-homepro_26.html

よく見たら、このサイトのファビコン？携帯動画変換君じゃないか。なつかし。
Laravel + Lighthouse + React + TypeScript + GraphQL 構成で雑にGraphQLに入門する

## はじめに

こちらは、[GraphQL Advent Calendar 2018](https://qiita.com/advent-calendar/2018/graphql) 8日目の記事になります。
いきなりですが、ものすごい雑に解説していきます。

完成品がこちら。
https://github.com/rascate/lara-gql-sample

laravelとnginx入れてdocker化だけしてるので、docker-compose up した後は
よしなにセットアップすれば動きます。
フロント側はしていないので、ローカルでyarnすればとりあえず動きます。

#### やること
 - 雑にGraphQL環境を揃えてとりあえず動かす
 - フロントエンドの楽さを伝える

#### やらないこと
 - GraphQLとは？
 - Lighthouseの使い方
 - リポジトリの解説

## Lighthouseのサンプルリポジトリを使う

まず、Laravel環境をセットアップします。

サンプルリポジトリは、 [これ](https://github.com/nuwave/lighthouse-example)です
とりあえずクローンして `composer install` しとけばOK

完成品には、
https://github.com/mll-lab/laravel-graphql-playground
が入れてあります。

## ReactでApolloを使う

https://qiita.com/ehr174/items/85b7cb7e7c93efef8889
こちらを参考に、create-react-appでtypescript環境のreactをセットアップします。

Apollo-boostを入れておきます。
Apollo-boostは、apollo関連ライブラリ全部入りのスゴイやつみたいな感じ（雑

`yarn add abollo-boost`

## SchemaからTypescriptで使えるモデルを生成する

Lighthouseのサンプルリポジトには、以下のようなスキーマがサンプルで入っています

```graphql
type Task {
  title: String!
}

type User {
  name: String!
  email: String!
  jobs: [Job!]! @hasMany
}

type Job {
  title: String!
  user: User @belongsTo
  tasks: [Task!]! @hasMany(type: "paginator")
}
(省略)
```

このschemaから、自動的にtypescriptで使えるinterfaceを生成できそうだなって思った方、あります。 [graphql-code-generator](https://github.com/dotansimha/graphql-code-generator) です。

https://graphql-code-generator.com/docs/plugins/typescript-react-apollo

ここのドキュメントに簡単に使い方が書いてありますので、見てください（雑）

まず、codegen.ymlというものを用意します

```coddegen.yml
schema:
- "http://localhost:9022/graphql"
documents:
- "./src/**/*.graphql"
generates:
  ./src/generated-models.tsx:
    plugins:
    - "typescript-common"
    - "typescript-client"
    - "typescript-react-apollo"
```

そして、Queryを用意します

```graphql
query JobQuery {
    jobs (count:10, page:1) {
        data {
            title
            user {
                name
                email
            }
        }
    }
}
```

そして、`gpl-gen`してあげれば・・・

[こんなもの](https://github.com/rascate/lara-gql-sample/blob/master/my-app/src/generated-models.tsx)が自動生成されちゃいます
（tslintに引っかかたりするので、対象外にした方が良いです）

後は、こんな感じで、コンポーネントとして使えます。

```react
import * as React from 'react';

import { JobQuery } from "./generated-models";

class JobList extends React.Component {
  public render() {
    return (
      <JobQuery.Component>
        {({loading, error, data}) => {
          if (loading) { return <div>Loading...</div>; }
          if (error) { return <div>Error :(</div>; }

          return <div>
            <ul>
              {data && data.jobs && data.jobs.data.map((job: any, idx: any) => {
                return <li key={idx}>
                    {job.title}
                  </li>;
              })}
            </ul>
          </div>;
        }}
      </JobQuery.Component>
    )
  }
}

export default JobList;
```


めちゃくちゃ便利ですね！


はい、いかがでしたでしょうか。
ほとんどgraphql-code-generatorの紹介みたいになって申し訳ないのですが、これから死ぬ気で追記していく所存です。
Searchkickの設定

RailsでSearchkickを使う設定

# インストールと設定

## 基本設定

### Elasticsearchをインストール

brewでelasticsearchをインストール

```sh
$ brew install elasticsearch
```

### Searchkickをインストール

Gemfileに以下を追記

```sh:Gemfile
gem 'searchkick'
```

ターミナルからgemをインストール

```sh
bundle install
```

### Modelに設定を追加


```ruby:product.rb
class Product < ApplicationRecord
  searchkick
```

### インデックスを作成

```sh
Product.reindex
```

## 関連付けされたデータの追加

`product` has_many `comments` があるとした時、以下のように設定することでインデックス対象を設定できます。

```ruby:product.rb
def search_data
  as_json(
    only: [:id, :name], # productで検索対象にしたいカラム名
    include: {
      comments: { only: [:id, :body] } # commentで検索対象にしたいカラム名
    })
end
```

# 使い方

## 簡単な検索

`apples` という文字を含むレコードを検索

```ruby
products = Product.search("apples")
products.each do |product|
  puts product.name
end
```

## クエリの使い方

ActiveRecordライクに書けます

```ruby
Product.search("apples", where: {in_stock: true}, limit: 10, offset: 50)
```

fieldsを指定することで検索するカラムを指定できます

```ruby
fields: [:name, :brand]
```

### where

`gt`, `lt`, `gte`, `lte` で大なり小なりや
`not` で否定
正規表現なども使えます

```ruby
where: {
  expires_at: {gt: Time.now}, # lt, gte, lte also available
  orders_count: 1..10,        # equivalent to {gte: 1, lte: 10}
  aisle_id: [25, 30],         # in
  store_id: {not: 2},         # not
  aisle_id: {not: [25, 30]},  # not in
  user_ids: {all: [1, 3]},    # all elements in array
  category: /frozen .+/,      # regexp
  _or: [{in_stock: true}, {backordered: true}]
}
```

#### 関連付けされたデータの検索

`product` has_many `comments` の場合
キーに関連するリレーション名（has_oneの場合は単数）を入れる必要があります。

```ruby
where {
  'comments.id': 1
}
```

### Order

orderはActiveRecordとほぼ同じ。
頭の`_`無くても動きます

```ruby
order: {_score: :desc} # most relevant first - default
```

##### idでorderしたい時の罠

※2020/12/12追記
Searchkick4.4.2だと `[]` 無しでも動くことを確認しました。
ですが、 `_id` カラムに変換されdeprecatedになってしまうため `[]` ありの方が適切そうです。
検証コメント
https://qiita.com/akinov/items/e29c3f3802c3d7ef5ac5#comment-6897e5b1bb349b2bdd86
※追記ここまで


ハマりました
idでorderする場合には配列で囲むとのこと…

```ruby
order: [{id: :ask}]
```

https://github.com/ankane/searchkick/issues/203#issuecomment-186176516
Amazon DynamoDB ちゅーとりある まとめ

# Amazon DynamoDB とは

フルマネージド型の NoSQL データベースサービス
データベースの分散とスケーリングを自動で管理してくれるAWSのサービス
また、書き込み読み込みにどれだけのリソースを割り当てるかを制御できパフォーマンスの管理を簡単に行うことができる。

----

# なぜ DynamoDB を使うか
AWSの他のサービスと連携しやすいDBというのが一番の理由
また、サービスの規模が拡大してアクセスが増大してもプログラムの変更なしでスケール可能というのも大きい。

----

# DynamoDB の開発

開発ではいちいちブラウザでアクセスしてどうこうは面倒なためcliツールを利用します。

## aws-cli のインストールと設定
はとりあえず本題とは異なるためリンクでお茶を濁します。

[AWS CLI をインストール](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html)
[AWS CLI を設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)

（各自セットアップをよろしくお願いいたします。）

----

## aws-cliでの操作

### テーブル作成
```bash
#! /usr/bin/env bash
aws dynamodb create-table \
    --table-name Music \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
```

### アイテム追加
```bash
#! /usr/bin/env bash
aws dynamodb put-item \
--table-name Music  \
--item \
    '{"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Call Me Today"}, "AlbumTitle": {"S": "Somewhat Famous"}}' \
--return-consumed-capacity TOTAL  

aws dynamodb put-item \
    --table-name Music \
    --item '{ \
        "Artist": {"S": "Acme Band"}, \
        "SongTitle": {"S": "Happy Day"}, \
        "AlbumTitle": {"S": "Songs About Life"} }' \
    --return-consumed-capacity TOTAL 
```

### Query実行 with jsonファイル

このコマンドを実行する前にjsonファイルの作成が必要になります。

```bash
aws dynamodb query --table-name Music --key-conditions file://key-conditions.json
```

以下のようにkey-conditions.jsonファイルを作成してください。

```json
{
    "Artist": {
        "AttributeValueList": [
            {   
                "S": "No One You Know"
            }   
        ],  
        "ComparisonOperator": "EQ"
    },  
    "SongTitle": {
        "AttributeValueList": [
            {   
                "S": "Call Me Today"
            }   
        ],  
        "ComparisonOperator": "EQ"
    }
}
```

----

## ローカルのDynamoDBでの開発
ローカルでDynamoDBを構築しAWSへのアクセスなしで開発をしたいという状況があることと思います。
その場合は**docker**を利用することでローカルの環境構築が可能です。

難しいことはありません。
以下のコマンドを実行してください。

```docker
docker run -d -p 8000:8000 amazon/dynamodb-local
```

このコマンドで起動したローカルのDynamoDBにアクセスするには以下のように--endpoint-urlパラメータにローカルDynamoDBのURLを指定します。

```bash
aws dynamodb list-tables --endpoint-url http://localhost:8000
```

----

# 後日更新予定
Vivado の VIO を使う

# VIO を追加
今まで使ってきた Diagram に VIO を追加します。VIO はバーチャル IO で Vivado の GUI をつかって FPGA とやりとりができます。

## IP Catalog
左のメニューから Project Manager -> IP Catalog をクリックすると IP Catalog のメニューが出てきます。サーチボックスがあるので VIO をと入れて VIO を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/5cdfb8e3-ea6d-e82c-2a81-4bc252db7d74.png)

ダブルクリックで選択ウィンドウが出てくるので左の選択肢（なぜか中央がハイライトされているが）の Add IP to Block Diagram を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/7cbcc987-3ad1-1d14-55a5-165bf9a7cdd9.png)

## 配線
VIO が現れたら配線します。VIO の output を Blink_blink_1 の rst に接続、input を Blink_blink_1 の led から分岐させて接続します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/f6a65e33-b05b-c87a-b14c-72b5e0fbfb92.png)

## 合成＆実行
合成して実行します。FPGA 側では普通に動作すると思います。

## VIO の操作
Hardware Manager には hw_vio_1 という空のウィンドウが現れます。+ ボタンを押して VIO の２つの端子を追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/0bb62ebd-8dcd-eca5-3322-78b9f29cc1f9.png)

## Input (Blink_1_blink_led)
Input は led を見ているので 0 と 1 に変化します。

## Output
Output は rst に繋がっているので、値(Value)を1にすると、点滅がとまり消灯します。
メールサーバを構築してみる - CentOS

###1.PostfixとSMTP-AUTH###

メール送信にパスワード認証を設け事で認証された場合のみメールの送信を許可します。

cyrus-sasl をインストールする。

```
yum install -y cyrus-sasl
```

起動、自動設定。

```
systemctl start saslauthd
systemctl enable saslauthd
```

smtpd.conf を編集する。

```
vim /etc/sasl2/smtpd.conf
```

pwcheck_method: auxprop　にします。
*auxprop	SASL独自のパスワードデータベースsasldbを用意して認証に利用する方法*

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/b3ef587a-8497-347e-bd37-429aedd37d4e.png)

postfix をインストールする。

```
yum install -y postfix
```

main.cf　を編集する。

```
vim /etc/postfix/main.cf
```

`message_size_limit = 5242880`
*受け取れるメールのサイズを5MBにする*
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/51f875bd-69a5-b36e-e9a1-1124785bf520.png)

`inet_interfaces = all`
*all のメールを受け取れるようにする*
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/c33ad96d-d92a-e128-2592-5e65a84b41d5.png)

`myhostname = mail.ドメイン`
*メールサーバーのホスト名を設定する*
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/c8006c0b-d8d9-c311-5d1f-6d16f3f5f020.png)

`mydomain = ドメイン`
ドメインを設定する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/0612247b-80a2-e59c-4b8c-d81e5f8ba865.png)

`myorigin = $mydomain`
ローカルで配送依頼されたメールの送信元アドレスに付加するドメイン名を設定する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/9ef212cb-f8ef-0d7a-0cc7-b30d06fbdbe1.png)

`mydestination ＝ $myhostname localhost.$mydomain localhost $mydomain`
ローカルに配送するドメインを指定する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/b92247a9-3000-154b-8d40-db951bcd29fb.png)

`home_mailbox = Maildir/`
メールボックスファイルのユーザーのホームディレクトリからの相対パス名を指定。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/2ed63a16-b15c-c102-5452-9f31a3f7e7c0.png)

`smtpd_sasl_auth_enable`
smtpd_sasl　を有効にする。
permit_mynetworks	「mynetwork」で指定したアドレスの許可。
permit_sasl_authenticated	SASL認証が通れば許可。
reject_unauth_destination	自分宛もしくは自分から送信されたものなら許可。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/295c4619-fb52-2835-a111-6303a72a99ea.png)

postfix を起動、自動設定する
`systemctl restart postfix
systemctl enable postfix`


###2.dovecot###

dovecot をインストールする。

```
yum install dovecot`
```

10-mail.conf を編集する。

```
vim /etc/dovecot/conf.d/10-mail.conf
```

`mail_location = maildir:~/Maildir`
メールボックス形式を追加する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/c377441d-0bfe-c3be-fe58-a09bfee89d8c.png)

10-auth.conf を編集する。

```
vim /etc/dovecot/conf.d/10-auth.conf
```

`disable_plaintext_auth = no`
プレインテキスト認証を追加する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/361e059b-d103-e3c0-a721-9cdcb1e1dee0.png)

10-ssl.conf を編集する。

```
vim /etc/dovecot/conf.d/10-ssl.conf
```

SSL接続を無効化する。
`ssl = no`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/b18ef42b-2269-9358-c71d-4cc99a8447f8.png)

dovecotの起動自動設定

```
systemctl start dovecot
systemctl enable dovecot
```


###3.メールユーザーの追加###

adminユーザを追加する。

```
useradd -s /sbin/nologin admin
```

パスワードを設定する。

```
passwd admin
```

Authユーザーを設定する。

```
echo "[パスワード]" | saslpasswd2 -p -u ドメイン -c admin
```

ユーザーの登録を確認する。

```
sasldblistusers2
```

権限変更する。

```
chgrp postfix /etc/sasldb2
```
GYOMUハックでAPI叩くときにCommonLisp使うと便利だった話

これは[GYOMUハック/業務ハック Advent Calendar 2018](https://adventar.org/calendars/3167)の7日目の記事です。

昨日はDataSpiderの記事でした。
私はその一つ前（？）のiDIVOというのを触っていたので、ちょっとだけいいところと大変だったところの気持ちがわかるような気がします。

# 今日の結論
CommonLisp使うと便利でした。

その中でも今回はClozureCLを使っています。


# 背景
## その１
- A) GYOMUハックっていろんなシステムと連携するよね
- B) REST APIだよね
- A) あれって何を送ったら何が返ってくるかイメージしにくいよね
- B) REPLがある言語でやるといいんじゃない？

(Postman使え？ごもっとも)

## その２
- A) Authorization面倒だよね
- B) メモリをダンプできる言語でやるといいんじゃない？

# CommonLispでZendeskにアクセスする

## トークンの作成

```common-lisp
(ql:quickload :cl-base64)

(defvar *zendesk-token* nil)
(defun set-zendesk-token (email token)
  (setf *zendesk-token*
        (format NIL "Basic ~A"
                (cl-base64:string-to-base64-string
                 (format NIL "~A/token:~A" emai token)))))

;; トークンを設定する
;; メールアドレスとAPIトークンを渡すとZendeskにアクセスする際に使うトークンが得られます
(set-zendesk-token "test@xxxxxx.com" "xxxxxxxxxxxxxxxxxxxxxxx")
;; => "Basic dGVzdEB4eHh4eHguY29tL3Rva2VuOnh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4"
```

これでトークンができました。

## メモリのダンプ（コアファイルの作成）

メールアドレスとかAPIトークンとかを毎回入力するのも面倒なのでメモリをダンプしておきます。
CommonLispではメモリをダンプして次回読み込むことで、前回と同じ環境を作ることができます。

OAuth2とかだとAccessTokenやRefreshTokenをメモリに持っておくだけで、次回以降も使い回しができるので便利です。

```common-lisp
(ccl:save-application "/path/to/core/zendesk.core"
                      :purify t
                      :prepend-kernel t)
```

これを実行するとREPLが終了します。

## メモリの読み込み
処理系を起動する際にダンプしたコアファイルを指定することでメモリに乗った状態で立ち上がります。

```bash
dx86cl64 --image-name /path/to/core/zendesk.core
```

で、SLIMEとかを使いたい場合はここから`swank`サーバを起動させておきます。

```common-lisp
(ql:quickload :swank)
(swank:create-server)
```

Emacsとかからは`slime-connect`などを使って接続します。

`swank`サーバに接続したら変数を見てみます。

```common-lisp
CL-USER> *zendesk-token*
"Basic dGVzdEB4eHh4eHguY29tL3Rva2VuOnh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4"
```

無事に値が残っていました。
あとは毎回このコアファイルを使えばZendeskにアクセスできます。

余談ですが、関数`set-zendesk-token`も残っているので、APIトークンを新しく発行し直した時はもう一度セットすることができます。

## Zendeskへの接続

```common-lisp
(dex:get "https://xxxxxxx.zendesk.com/api/v2/users.json"
         :headers `(("Authorization" . ,*zendesk-token*)))
```

REPLに結果がだーーーっと出てきます。

![一気に出すぎて大変なことになっている図](https://qiita-image-store.s3.amazonaws.com/0/13469/c4bf350f-8a2d-fa92-1791-80a2966d161c.png)


> ~~余談ですが、SLIMEだと`*`に直前の出力がバインドされているので、いったん目で構造を確認したのちに`*`を評価し直して整形する、というやり方が使えます。~~
(2018.12.09 誤りの訂正。`*`はCommonLispの仕様でした。
http://www.lispworks.com/documentation/lw51/CLHS/Body/v__stst_.htm
@nfunato さん情報ありがとうございます)

余談ですが、`*`に直前の出力がバインドされているので、いったん目で構造を確認したのちに`*`を評価し直して整形する、というやり方が使えます。
REPL最高ですね。

# 応用
いろいろな外部サービスへの接続の変数を設定したコアファイルを用意しておくと、いざという時の調査とかにサッと取りかかることができます。
[ServiceWorker] ブラウザのjsからServiceWorkerに値を渡す

# 前提

1. hoge.phpにリクエストを投げる。
2. そのレスポンスにあるfugaというデータをServiceWorkerの中で使いたい。

# ソース

レスポンスを受け取ったxxx.jsからmessageイベントを利用すると、たぶん一番簡便。

```js:xxx.js
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.controller.postMessage({type: 'hoge', fuga: xxx});
}
```

ブラウザ側ではこうやっておいて…

```js:ServiceWorker.js
self.addEventListener('message', event => {
    switch (event.data.type) {
        case 'hoge':
            console.log(event.data.fuga);
            break;
    }
});
```

こうやる、と (´･ω･｀)
[ServiceWorker] ブラウザのjsからServiceWorkerに値を渡す

# 前提

1. hoge.phpにリクエストを投げる。
2. そのレスポンスにあるfugaというデータをServiceWorkerの中で使いたい。

# ソース

fetchイベントをlistenしてfetchしてあれしてこれして`event.respondWith()` (´･ω･｀)ﾄﾞｰﾝ
DeferredとかPromiseとかなんですかそれ？ってところから調べたので、むしろそっち方面の理解に時間がかかったかも。

理解すると非常に便利なのだろうなということは、理解できたかなぁというところ (´･ω･｀)

```js:service_worker.js
self.addEventListener('fetch', event => {
    var requestURL = new URL(event.request.url);

    if(requestURL.pathname.match("/hoge.php")) {
        console.log(requestURL.pathname);

        event.respondWith(
            fetch(event.request)
                .then(response => {
                    var res_clone = response.clone();

                    res_clone.json()
                        .then(json => {
                            if (json.data.fuga) {
                                console.log(fuga);
                            }
                        });

                    return response;
                })
        );
    }
});

```

躓いたのは、`event.respondWith()`かなぁ。
使わずにresponseをreturnしてたら、リクエストが二重になりやがんの。
`event.respondWith()`を使うことで、「これをレスポンスとします」ってことになるようで。
なるほどわからん。

あとは、Promiseたちの取り回しがわかってきたら、なんとなくでけた (* ´ω｀ *)
「responseはストリームだから一回しか読めませんよ～」っていう説明もよくわからんけど、確かに読めないから、レスポンスの何かを使って何か処理をしたいなら`clone()`で複製すべし。

jQueryでajaxを使って来てるけど、Fetch APIもおもしろいなぁ。
最近興味津々でござる (´･ω･｀)

---

## 参考情報

- [Service Worker で横取りしたリクエストをネットワークにフォールバックさせたい時はただ return するべき] (https://qiita.com/nhiroki/items/6d3f79930bb5c7164d6e)  
投稿してから改めて自分の記事を見たときに、下にあったリンクを辿ると…勉強になりました (´･ω･｀)  
`event.respondWith()`するよりも、単純に`return`する方が速いよというお話。  
処理時間４割減と言われたら、そっち使うかなぁ (´･ω･｀)
【ejs】パンくずをパーツ化し、条件分岐で階層の表示を分けよう

#概要
_breadcrumb.ejsというファイルを作り、各ページに読み込ませてページタイトルをパンくずに表示したい。以前投稿した[こちらの記事](https://qiita.com/irie_toku/items/9551c9001bf66d87c7d0)の発展型。

#ソース

```javascript:_breadcrumb.ejs
<div id="breadcrumb_box">
  <ol id="breadcrumb" itemscope itemtype="https://data-vocabulary.org/Breadcrumb">
    <li class="home"><a href="/" itemprop="url"><span itemprop="title">トップページ</span></a>&nbsp;&gt;</li>
    <li>
      <%- page['title'] %>
    </li>
  </ol>
</div>
```

_breadcrumb.ejsのソース自体はこんな感じ。
それを各ページに読み込ませる際

```javascript:_exsample.ejs
  <%- include('../includes/_breadcrumb', {
     page: json['exsample']
   }); %>
```

こんな形で読み込む。

2階層しかないサイトの場合(トップ > 会社概要　等)、ただタイトルを表示させるだけで問題はないが、3階層以上の場合(トップ > 商品一覧 > 商品詳細　等)はまた条件分岐を行わせる必要がでてくる。

```javascript:_breadcrumb.ejs
<div id="breadcrumb_box" class="center_box">
  <ol id="breadcrumb" itemscope itemtype="https://data-vocabulary.org/Breadcrumb">
    <li class="home"><a href="/" itemprop="url"><span itemprop="title">トップページ</span></a>&nbsp;&gt;</li>
    <%
      var status; //statusを宣言
      if(status == 'exsample_detail') {　//_exsample.ejsにて設定されたstatusがexsample_detailの場合下記liを出力
    %>
    <li><a href="../" itemprop="url"><span itemprop="title">
          <%- page['middleLayer'] %></span></a>&nbsp;&gt;</li> 
    <% }  %>
    <li>
      <%- page['title'] %>
    </li>
  </ol>
</div>
```

```javascript:_exsample.ejs
  <%- include('../includes/_breadcrumb', {
    status:'exsample_detail', //statusにexsample_detailを設定
    page: json['exsample']
  }); %>
```

3階層目のページにstatus:'exsample_detail'という値を持たせ、それを_breadcrumb.ejsを読み込ませる際に照合し、もし一致したら中間層を表示する。

パンくずの最下層はそのままページタイトルを出力すればよいので、中間層に表示させたいページのタイトルを設ける。meta.jsonにmiddlelayerなど値を追加し、指定すれば良い。

#他にも

この原理を利用すれば、特定のページのみ要素を変更できたりする。

例えばseo対策として、各配下ページの大見出しにh1を使用し、トップページのみヘッダー(共通部分)のロゴにh1を使用したい場合は

```javascript:_header.ejs
   <%
      var status;
      if(status == 'top') {
    %>
    <h1 class="head_logo"><a href="/"><img src="/common_img/logo.png" alt=""></a></h1>
    <% } else { %>
      <div class="head_logo"><a href="/"><img src="/common_img/logo.png" alt=""></a></div>
    <% } %>
```
```javascript:_index.ejs
<%- include('includes/_header',
 {
  status:'top',
  page: json['top']
 }); 
%>
 ```

こうすれば大丈夫。
こうする事でトップページのみロゴにh1が適用され、その他のページはロゴがdivで囲まれる。

#まとめ
この様にパンくずだけでなくejsで条件分岐を使えれば色々と便利な事ができそう。
共通化できる部分はとことん共通化して、汎用的なパーツの管理を行っていきたい。
Python で FPGA/Zybo Z7編 (Vivado の Diagram を使う)


# GUI を使うと後々便利かも？
前回の環境を引き継ぎつつ回路図エディター(Diagram) を使えるようにします。

## Diagram に追加
Diagram 右クリックのメニューから Add Module.. を選択し Blink_blink を追加。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/b00eb6d0-db39-b5c4-b244-97248917cc99.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/ab9bb107-7cd2-cdbf-556f-6221d62e3416.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/7e3c749b-29c9-fe8f-6fbd-d0f07b63372b.png)

## Diagram の完成
まずは3つの線を外に出すために Make External を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/d4ad95b7-2b93-e148-b08f-cf5f34b12bef.png)

clk_0, rst_0, led_0 という名前になってしまったので _0 を取り除きます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/90ae95e9-4f13-85c8-d6fa-81a4748f52cc.png)


## デザインの入れ替え
トップが Verilog になっているのでそれを入れ替えます。

Create HDL Wrapper を選択します（普通に Verilog 追加した方がよかった？
![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/c70e2f09-8440-96e3-5776-6b6eb163d720.png)

Set As TOP でトップモジュールに指定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/190a5db5-1add-3439-84ae-693de3a9f00f.png)

## 合成&実行
xdc は前作と同じでよいので、そのままで合成&実行です。
念のため再掲。

```tcl:blink.xdc
set_property -dict { PACKAGE_PIN K17   IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=sysclk
create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports { clk }];

#LED
set_property -dict { PACKAGE_PIN M14   IOSTANDARD LVCMOS33 } [get_ports { led }]; #IO_L23P_T3_35 

set_property -dict { PACKAGE_PIN K18   IOSTANDARD LVCMOS33 } [get_ports { rst }]; #IO_L12N_T1_MRCC_35
```

行時にビットストリームが見つからないと言ってくることがあるので、その時はファイル選択をあらためてしてください。Vivado の TCL の Console に debug_hub に関するワーニングが出ますがこれは（clk の設定の問題）気にしなくてよいでしょう。

#　Lチカにする
clk が早すぎて LED が点灯しっぱなしに見えるのは Diagram を使っても変わりません。そこで、Blink_blink 二段重ねにしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/92583dc5-b2ce-3959-f937-027a18177677.png)

GUI なので比較的簡単に絵のようにできるのではないでしょうか？Blink_blink_0 をコピー＆ペーストすれば Blink_blink_1 ができます。後は絵の通りにつなぎなおすだけです。再合成して実行してみるとうまく Lチカになりました。クロックは 125MHz のはずでこれを 1/10000 の 1/10000 にしているので 1.25 秒で点滅している”はず"です。
webpackでビルドしたbundle.jsの関数をonclickで動かしたかった話。

久々にjsを直接書く機会が偶々あって、「webpackとかなにこれめっちゃ便利じゃん」とか思って使ってみたらindex.jsに定義してるはずの関数をonclickで呼ぼうとするとnot definedになったので解決方法の記録

【やりたかったこと】

index.html

```html
<input type="button" value="送信" onclick="hoge()"/>
```

これをクリックしたときに↓を動かしたかった

index.js

```javascript
function hoge() {
    console.log("ウオアアアアアアア");
};
```

とりあえず試したらnot definedとか言われたので、bundle.js開いてみたらそもそも定義した関数が存在してないっていうｗ

【解決法】

index.js

```javascript
var hoge = function hoge() {
    console.log("ウオアアアアアアア");
};

//↓こいつが必要みたい
window.hoge = hoge;
```

↓でもできるんじゃね？って思ったけど、多分またしばらくjs書かないので試しませんでした。

index.js

```javascript
window.hoge = function a() {
    console.log("ウオアアアアアアア");
};
```
複数バージョンsbt混合のマルチプロジェクト

`sbt0.13` でビルドされているマルチプロジェクトを `sbt1` に上げようとしたとき、一部 `sbt0.13` でしか提供されていないlibraryがあって対応に困った。  
最終的にsbtが複数バージョン混じった状態に落ち着けたので、その対応メモ

### 確認に用いたsbtのバージョン
sbt1 => 1.2.7
sbt0.13 => 0.13.17

### 概要
元の状態は以下の通り。  
`projectA` `projectB` でそれぞれ `common` を参照している。`common` は `sbt1` への対応ができるとする。
`projectB` は `sbt0.13` のままにする。

```
.
├── common
├── projectA
└── projectB
```

対応後のイメージは以下。

```
.
├── common
├── projectA-sbt1
└── projectB-sbt0.13
```

### 対応方法

`common` を `common-src` , `common-sbt1` , `common-sbt0_13` の3つのディレクトリに分ける。

- `common-src`: ソースコードを格納する
- `common-sbt1`: sbt1用のビルド設定を格納する
- `common-sbt0_13`: sbt0.13用のビルド設定を格納する

```
.
├── common-src
│   ├── main
│   └── test
├── common-sbt1
│   ├── project
│   │  ├── build.properties
│   │  └── plugins.sbt
│   └── build.sbt
├── common-sbt0_13
│   ├── project
│   │  ├── build.properties
│   │  └── plugins.sbt
│   └── build.sbt
├── projectA-sbt1
└── projectB-sbt0_13
```

`common-sbt1` , `common-sbt0_13` のビルドは、ビルドパスを `common-src` を向くようにしてやればいい。

[Customizing paths](https://www.scala-sbt.org/1.0/docs/Howto-Customizing-Paths.html)

**common-sbt1/build.sbt**
**common-sbt0_13/build.sbt**

```
sourcesInBase := false
scalaSource in Compile := (baseDirectory(_ / "../common-src/main")).value
scalaSource in Test := (baseDirectory(_ / "../common-src/test")).value
resourceDirectory in Compile := (baseDirectory(_ / "../common-src/main/resources")).value
resourceDirectory in Test := (baseDirectory(_ / "../common-src/test/resources")).value

// 以下はそれぞれのsbtに合わせてscalaVersionなどを修正
```

**projectA-sbt1/build.sbt**

```
lazy val projectA = (project in file("."))
  .dependsOn(RootProject(file("../common-sbt1")))
```

**projectB-sbt0_13/build.sbt**

```
lazy val projectB = (project in file("."))
  .dependsOn(RootProject(file("../common-sbt0_13")))
```

`sbt-scalariform` などを使っていて、sbt1に上げるタイミングで `sbt-scalafmt` に変えたいとき、 `common` は `sbt-scalariform` の最新バージョン(sbt1, sbt0.13の両方が提供されている)のままにして、sbt1に上げたプロジェクトのみ `sbt-scalafmt` に変えるのが良さそう。`neo-sbt-scalafmt` でもいいかも。  
common-sbt1にのみ `sbt-scalafmt` を設定して、common-sbt0_13からフォーマット用のプラグイン設定を取り除いても動作しますが、common-sbt0_13側からフォーマッタが起動しないので微妙そう。
RxJS mapとmergeMapの違い

# 前提
rxjsについて、まだ何もわからない方は、こちらの記事を一度読んでいただけたらと思います。
https://tech.recruit-mp.co.jp/front-end/rxjs-intro/
と同時にこの記事では、

* ストリーム
* メッセージ
* pipe
* subscribe



について少し解説します。
特にストリーム、メッセージは、mapとmergeMapの説明でよく使います。

## ストリーム
observableのことを指します。
 `const source = of(1,2)`
上記は、ofによって、変数がsourceがobservableになっているので、変数sourceはストリームといえます。

## メッセージ
ストリームの中に存在する値を指します。
`const source = of(1,2)`
ofの引数に、1と2を入れていることから、ストリームであるsourceは、メッセージ1と2をもつといえます。

## pipeについて
 **オペレータ**を呼び出すためのメソッドです。
オペレータは、ストリームを操作します。
今回の主題である、map,mergeMapもオペレーターの区分に該当します。

```typescript
//ストリームを作る
const number = of(1,2)
//numberのメッセージで、オペレータを使うことができる。
const map = number.pipe(
    map((x) => x ** 2))
//subscribeで値を購読
map.subscribe( val => console.log(val);
```

```typescript
1
4
```

##結局pipeとsubscribeの違いは？
* pipeがオペレータを呼び出すためのメソッド
* subscribeがストリームを購読するメソッドです。

# Map 
メッセージを処理して、新たなストリームを作成します。

```typescript

//ストリーム作成
const source = of(1,2);
//各メッセージに10を足します。
const example = source.pipe(map(val => val + 10));

const subscribe = example.subscribe(val => console.log(val));
```

```typescript
11
12
```


# MergeMap 
複数のストリームを一つのストリームにまとめます。


```typescript

// ストリーム作成
const numbers = of(1,2,3);

//mergeMapの引数の中では、numbersストリームのメッセージごとに、新たなストリームを作成しています。
//つまり、ストリームの中で、複数のストリームができています。
//mergeMapによって、それを一つにまとめます。
const result = numbers.pipe(mergeMap(x => of(x)));

result.subscribe(x => console.log(x));
 
```

```typescript
1
2
3
```

# まとめ
* mapは、メッセージを処理して、新たなストリームを作成します。
* mergeMapは複数のストリームを一つのストリームにまとめます。

# 引用
http://reactivex.io/documentation/observable.html
https://t-cr.jp/article/3551640ea6a96e173
http://wilfrem.github.io/learn_rx/operators.html
http://reactivex.io/rxjs/file/es6/operator/mergeMap.js.html
DynamoDBへのバッチ書き込みをSQSとLambdaを使ってサーバレスに実現する

この記事は[Serverless Advent Calendar 2018](https://qiita.com/advent-calendar/2018/serverless)の7日目の記事です。

# あらすじ

S3に出力したJSONファイルをもとにDynamoDBのデータをバッチ的に更新する仕組みをサーバレスで作ったので、その際に考えた事などを共有します。

# 作った構成

S3にデータが置かれた後はS3 -> Lambda -> SQS -> Lambda -> DynamoDBと処理が遷移します。

![qiita-Page-1.png](https://qiita-image-store.s3.amazonaws.com/0/87808/9e63c393-bb1b-2ab8-607c-2291637f353c.png)


- 書き込み処理は上書きのみで処置を冪等にしている
- 書き込み順序を特に気にしない

ことを前提とした構成です。

# 考慮事項

この構成を取る上で以下のような考慮事項がありました。

- S3に置かれるファイルのサイズが不定
- DynamoDBの書き込みスループットに制限がある
    - オートスケールするけど迅速にスケールしない
 - Lambdaにはタイムアウト時間がある

つまり単純にLambdaでS3のデータを引っ張ってDynamoDBに書き込もうとした場合、タイムアウトが発生してしまう可能性が高くなってしまいます。
そこでS3からDynamoDBに直接書き込む構成でなく、一度SQSを経由することで書き込むデータの粒度を細かくする構成としました。


# この構成の利点 

## リトライが簡単になる

SQSをLambdaのイベントソースとした場合、Lambdaは処理が正常に終了するとSQSからメッセージを削除して、正常に終了しなければメッセージを消さない、といった動きをします。
そのためDynamoDBへの書き込み時にタイムアウト等のなんらかのエラーが発生した場合でも、何もしなくても可視性タイムアウト時間が過ぎた後に再度Lambdaによって取り込みされてリトライされます。

もし、不正なフォーマットなどメッセージ自体に問題がある場合は、再送回数がRedriveポリシーの`maxReceiveCount`を超えた後にDeadLetterキューに移されます。DeadLetterのメッセージ件数をCloudWatchで監視することで書き込みの失敗を検知することが可能です。

このようにリトライ周りの処理を完全にSQSとLambdaの機構自体に任せることでリトライ処理をLambdaのプログラム側で書かなくても済むようになります。

# おわりに

以上、DynamoDBへのバッチ書き込みをサーバレスで実現した構成の紹介でした。
LambdaのイベントソースにSQSを指定するとメッセージのハンドリングをAWS側でやってくれるので楽ですね。
アラビア数字をローマ数字に変換する

引数のアラビア数字をローマ数字にして返す処理です。

# コードとやっていること

```C#
/// 整数しかローマ数字で表現できないので引数はint
public static string ToRomanNo(int arabicNo)
{
    //0はローマ数字で表現できないので空文字を返す
    if(arabicNo == 0)
    {
        return string.Empty;
    }

    //3９99より大きい数字もローマ数字で表現できないry
    if(arabicNo > 3999)
    {
        return string.Empty;
    }

    //アラビア数字とローマ数字のペアを用意する
    Dictionary<int, string> romanArabicNum = new Dictionary<int, string>();
    romanArabicNum.Add(1000, "M");
    romanArabicNum.Add(900, "CM");
    romanArabicNum.Add(500, "D");
    romanArabicNum.Add(400, "CD");
    romanArabicNum.Add(100, "C");
    romanArabicNum.Add(90, "XC");
    romanArabicNum.Add(50, "L");
    romanArabicNum.Add(40, "XL");
    romanArabicNum.Add(10, "X");
    romanArabicNum.Add(9, "IX");
    romanArabicNum.Add(5, "V");
    romanArabicNum.Add(4, "IV");
    romanArabicNum.Add(1, "I");

    //戻り値を宣言する
    string ret = string.Empty;

    //アラビア数字とローマ数字のペアを大きい値から回す
    foreach(KeyValuePair<int,string> pair in romanArabicNum)
    {
        //arabicNoをペアの数字割って商を求める
        //商＝ローマ数字で出力する数となる
        int romanCount = arabicNo / pair.Key;

        //商の分の数をarabicNoから引く
        arabicNo -= romanCount * pair.Key;

        //商の数だけ、ローマ数字を戻り値に追加する
        for (int i = 0; i < romanCount; i++) 
        {
            ret += pair.Value;
        }
    }
    return ret;
}
```
ドロップした既存図イメージの中心を原点に合わせるスクリプト

Procedure CropMove;
VAR
x1,x2,y1,y2:REAL;
BEGIN
GetBBox( FSActLayer,  x1,y1,x2, y2);
MoveObjs( -(x1+x2)/2, -(y1+y2)/2,FALSE,FALSE );
END;
Run(CropMove);
【最速】５分で実施OpenFOAM@Google Colaboratory

# はじめに
**OpenFOAMの環境構築からCavityチュートリアルを実施までを５分で終える方法**を提示します。  
下記のようなユーザを対象に、環境の準備なしに、とにかく手軽にOpenFOAMを実行してみたい人向けの記事です。

* OpenFOAMを実行したことのない初心者
* Linux環境を持っていないけどOpenFOAMをやってみたい初心者
* スマホで計算(計算の準備をしたい、ソルバ開発)したい中毒者

# 最速OpenFOAMの実行

### 1. Google Colaboratoryで新しいNotebook
Googleのアカウントでログインした状態で、
[Google Colaboratory](https://colab.research.google.com/ "Google Colaboratory")にアクセス。 
「PYTHON 3 の新しいノートブック」をクリック
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/6f191cf3-1cb5-e4fb-7ab2-60bbb6536f71.png width=500px>


### 2. OpenFOAMのインストール
1つめのセルに下記を入力し、「Shift + Enter」(もしくは三角マーク)で実行

```bash
%%bash
sh -c "wget -O - http://dl.openfoam.org/gpg.key | apt-key add -"
add-apt-repository http://dl.openfoam.org/ubuntu
apt-get update
apt-get -y install openfoam6
```

### 3. 計算Caseを準備
２つめのセルに下記を入力し「Shift + Enter」(もしくは三角マーク)で実行。  
これにより、cavityチュートリアルがカレントディレクトリにコピーされる

```bash
%%bash
. /opt/openfoam6/etc/bashrc
cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavity ./
```

### 4. 計算実行
３つめのセルに下記を入力し、計算を実行する(「Shift + Enter」(もしく、、、)

```bash
%%bash
. /opt/openfoam6/etc/bashrc
cd ./cavity
blockMesh >log.blockMesh 2>&1
icoFoam >log.icoFoam 2>&1 
ls
```

下記のような出力が確認できればOK
<img src="https://qiita-image-store.s3.amazonaws.com/0/132571/c0ce662e-9e16-eaba-9f35-7c88a8564be7.png" width=250px>



### 5. 計算結果のダウンロード
下記のコマンドを実行し、解析ケースのzip圧縮を行う。

```bash
%%bash
zip -r cavity.zip ./cavity
```

圧縮したzipファイルをダウンロード。
コード実行後ダウンロードが始まる。

```python
from google.colab import files
files.download('cavity.zip')
```

あとは、ローカルマシンのParaViewなどで結果を確認すればよい。

# まとめ
* 私の環境(in新幹線)で、実測3分43秒でした。
* 計算環境はGoogle Colaboratoryを使う(90分ルール、12時間ルールには注意)
* 行頭に`` %%bash ``を入力し、bashコマンドを存分に使う!

タイムアタックのポイントは各セルの終了を待たず次のセルを実行しておくことと実行する時間帯かな？  
GoogleのColaboratoryの使い方としていいのかわかりませんが、一度お試しあれ。  
他の方法で最速記録を塗り替えた場合、連絡ください。【最速】の看板を下ろします
cronの設定方法について（初心者向け）

#はじめに

cronはUNIX系OSにおいて、スケジュールを登録しておくことで定期的にジョブを
実行してくれるため、決まったスケジュールや間隔でプログラムを動作させたい
といった際に便利です。

今回は新人にcronの設定を教えることがあったので「crontab」について簡単に記載します。

##cronの設定内容を確認する

```bash
crontab -l
```

##cronの登録／編集

```bash
crontab -e
```

ユーザーごとにcronの設定が行え、上記コマンドを実行したユーザーの設定ファイルに
スケジュールが登録されます。そのため、プログラム等を実行させる場合は、該当プロ
グラムの実行権限を持っているユーザーで設定を行います。

ユーザーごとの設定ファイルは下記に保存されます。
/var/spool/cron/ユーザー名

##cronファイルの記述

```bash
* * * * * コマンド
```

左から、
「分（0-59） 時（0-23） 日（1-31） 月（1-12） 曜日（0-7）※0、7は日曜」
が基本的な形になります。

「*」は省略のため、上記の例では毎分コマンドが実行されます。

 - 記述例
 
カンマ区切り・・ 0,30（分に記載すると0分、30分と30分ごとに実行されます）
間隔指定　　・・ */15（分に記載すると0分、15分、30分、45分と15分ごとに実行されます）
範囲指定　　・・ 1-10（分に記載すると1分から10分まで1分ごとに実行されます）


##cronを秒単位で実行したい場合

例：15秒ごとに実行

```bash
* * * * * コマンド
* * * * * sleep 15; コマンド
* * * * * sleep 30; コマンド
* * * * * sleep 45; コマンド
```

sleepを入れて開始時間を遅らせるなど工夫をすれば可能です。
但し、処理によっては前のコマンドが終わる前に次のコマンドが実行されてしまう
場合があるので注意が必要です。


##cronでコマンドが動作しないとき

コマンドラインでは実行できるのにcronから実行出来ない場合、環境変数のパスが
通っていないことが考えられます。

下記の方法で必要な環境変数を指定することが出来ます。
crontabに環境変数を記載する（crontab -e）

- cron全体のコマンドに設定する

```bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/user/bin/

* * * * * コマンド
```

- コマンドごとに設定する

```bash
* * * * * PATH="/sbin:/bin:/usr/sbin:/usr/bin:/home/user/bin/" コマンド
```

#おわりに

cronは定期実行のジョブ登録に便利な機能ですが、
誤った登録をすると思いもよらない間隔で実行されてしまいますので、
設定後はちゃんと動作しているか確認しましょう。
【getElementsByClassName】CLASSの検索どっちが早い！？【querySelector】

業務でjavascriptを書いていたらふと疑問に感じたので実験してみました。
#実験方法
Yahoo!トップページの中のクラス「clfix」の存在確認を1000回１セットで１０回実施。
1セットごとに念のためブラウザのキャッシュクリアリロード。

##getElementsByClassName('CLASSNAME')
```javascript
console.time('計測ByClassName')
for(var i=0; i<1000; i++){
  if(document.getElementsByClassName('clfix') != null){
    console.log('exist');
  }
}
console.timeEnd('計測ByClassName')
```

###実験結果
|test |result   |average  |
|-----|---------|---------|
|1    |134s     |0.134s   |
|2    |125s     |0.125s   |
|3    |126s     |0.126s   |
|4    |130s     |0.130s   |
|5    |127s     |0.127s   |
|6    |114s     |0.114s   |
|7    |134s     |0.134s   |
|8    |136s     |0.136s   |
|9    |142s     |0.142s   |
|10   |121s     |0.121s   |
|total|1289s    |0.1289s  |

##querySelector('.CLASSNAME')
```javascript
console.time('計測querySelector')
for(var i=0; i<1000; i++){
  if(document.querySelector('.clfix') != null){
    console.log('exist');
  }
}
console.timeEnd('計測querySelector')
```
###実験結果
|test |result   |average  |
|-----|---------|---------|
|1    |124s     |0.124s   |
|2    |142s     |0.142s   |
|3    |137s     |0.137s   |
|4    |139s     |0.139s   |
|5    |129s     |0.129s   |
|6    |126s     |0.126s   |
|7    |118s     |0.118s   |
|8    |142s     |0.142s   |
|9    |140s     |0.140s   |
|10   |131s     |0.131s   |
|total|1328s    |01328.s  |

#結論
まぁCLASS検索専用の方がそりゃ早いよねｗ
スッキリ！！
C++ Builder XE4 | FastReport VCL 5 > IDE > パスの設定

```txt:動作環境
C++ Builder XE4
FastReport VCL 5
```

XE4にてFastReport VCL 5をインストール時に行ったパス設定。

10.2 Tokyoでの設定も踏まえて記事にしておく。

### ツール > オプション

下記の設定をする。
(<font color=red>**.C++オプションで「32ビット Windows」の場合、タブは「コンパイラ」と「従来のコンパイラ」がある。どちらで設定するかは、作業対象となるプロジェクトによる。32ビットでなく64ビットアプリケーションの場合、このような選択はない**</font>)

- 環境オプション > .Delphiオプション
    - ライブラリ
        - 32ビット Windows
            - ライブラリパス(B) : `C:\Program Files\FastReport\FastReport 5\LibD18`
            - ブラウザ検索パス(W) : `C:\Program Files\FastReport\FastReport 5\LibD18`
        - 64ビット Windows
            - ライブラリパス(B) : `C:\Program Files\FastReports\FastReport 5\LibD18x64`
            - ブラウザ検索パス(W) : `C:\Program Files\FastReports\FastReport 5\LibD18x64`
- 環境オプション > .C++オプション
    - ライブラリ
        - 32ビット Windows
            - システムインクルードパス(I) : `C:\Program Files\FastReport\FastReport 5\LibD18`
            - ライブラリパス(B) : `C:\Program Files\FastReport\FastReport 5\LibD18`
            - ブラウザ検索パス(W) : `C:\Program Files\FastReport\FastReport 5\LibD18`
        - 64ビット Windows
            - システムインクルードパス(I) : `C:\Program Files\FastReports\FastReport 5\LibD18x64`
            - ライブラリパス(B) : `C:\Program Files\FastReports\FastReport 5\LibD18x64`
            - ブラウザ検索パス(W) : `C:\Program Files\FastReports\FastReport 5\LibD18x64`