OmniAICreator/Qiita-1.07M huggingface dataset:
OpenFOAMで場所ごとの残差を出力

# 使用環境
- OpenFOAM v1806
- Ubuntu 18.04

# はじめに
　OpenFOAMで定常計算をしていてなかなか収束しないときに、どの場所で発散しているかを知りたいことがあるかもしれない。そんなときは`fvMatrix::residual()`という関数を使うとその時の各セルの残差を返してくれる。
　以下はsimpleFoamに追加する場合の例。

# 例
simpleFoamのpとUの初期残差(initial residual)を各timeStepで出力する。
https://github.com/inabower/residualSimpleFoam
![residual.gif](https://qiita-image-store.s3.amazonaws.com/0/151450/95333a9d-6175-bb6e-4d0f-1f0aefcec46f.gif)

# 解説
- 変えた場所は"*createFields.H*"と"*(p|U)Eqn.H*"。
- `fvMatrix::residual()`という関数でその時の各セルにおける左右辺の差（残差）を求める。
- `vol(Scalar|Vector)Field`に無次元のfieldを代入する際には`primitiveFieldRef()`関数を使用する。
- 今回のコードはinitial residualの出力ですが、各Eqn.Hの中のsolve()の後に置けばfinal residualを求めることも可能。

```C++:residualSimpleFoam/createFields.H
// 元々のcreateFields.Hに以下を追記

Info<< "Creating residual field of p and U\n" << endl;
volScalarField rp // pの残差
(
    IOobject
    (
        "residual_p",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedScalar("resp", dimless, 0.)
);

volVectorField rU // Uの残差
(
    IOobject
    (
        "residual_U",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedVector("resU", dimless, Zero)
);
```

```C++:residualSimpleFoam/UEqn.H
    // Momentum predictor

    MRF.correctBoundaryVelocity(U);

    tmp<fvVectorMatrix> tUEqn
    (
        fvm::div(phi, U)
      + MRF.DDt(U)
      + turbulence->divDevReff(U)
     ==
        fvOptions(U)
    );
    fvVectorMatrix& UEqn = tUEqn.ref();
    
    // ここを追加（最終残差を見たい場合はsolveの後に置く）
    rU.primitiveFieldRef() = UEqn.residual();

    UEqn.relax();

    fvOptions.constrain(UEqn);

    if (simple.momentumPredictor())
    {
        solve(UEqn == -fvc::grad(p));

        fvOptions.correct(U);
    }

```

```C++:residualSimpleFoam/pEqn.H
    // 前略

    tUEqn.clear();

    // ここを追加（初期残差が欲しい場合）
    bool isInitialResidual = true;
    
    // Non-orthogonal pressure corrector loop
    while (simple.correctNonOrthogonal())
    {
        fvScalarMatrix pEqn
        (
            fvm::laplacian(rAtU(), p) == fvc::div(phiHbyA)
        );

        // ここを追加（初期残差が欲しい場合）
        if(isInitialResidual)
        {
            rp.primitiveFieldRef() = pEqn.residual();
            isInitialResidual = false;
        }

        pEqn.setReference(pRefCell, pRefValue);

        pEqn.solve();

        if (simple.finalNonOrthogonalIter())
        {
            phi = phiHbyA - pEqn.flux();
        }
    }

    // 後略
```

# 最後に
　全然収束しないときに役立つかもしれません。
構想 自分の体調検知システム

## 機械の故障検知システム
展示会にいくとAIを用いて機械の故障検知システムできます！というものが沢山ある。
機械の故障検知できるなら
体の体調検知もできるはず！！

## 構成
データは、活動量計を使用。
心拍数やストレス、睡眠やステップ数の日付データと生データがGetできる。
活動量計のサーバとAWSをつないで(AWS Direct Connect )
dataspiderでデータ同期。
sagemakerを使用して体調が悪くなるデータを機械学習！
体調が悪くなりそうならdataspider使ってLine通知で知らせる！
コンストラクタは何のためにある？

##コンストラクタとは？
インスタンスが生成されるときに自動で実行される特殊なメソッドで
**インスタンスの初期状態を自由に操ることが出来る！**

と、言ってもピンとこないし実際にコードを実行してみよう。


##コンストラクタがないとどうなる？
**型ごとのデフォルトが値に入る**
たとえば、顧客情報を引き出すプログラムがあったとする。

```java
	//顧客情報を定義
	class CustomerCard {
		int id; //顧客id
		String name; // 顧客名
	}

	class CustomerManager {
		public static void main(String[] args) {
			CustomerCard out = new CustomerCard(); //インスタンス作成
			System.out.println(out.id); //顧客idを出力
			System.out.println(out.name); //顧客名を出力
		}
	}

```

これを実行すると、結果は以下の通りだ。

```java
0 //顧客id
null //顧客名
```

###なぜこうなるか
クラスをインスタンス化（new）した時に、何の値も入れられていないメンバ変数は、勝手に初期化されるようになっているから。
intなどの数値系の型は0に、boolean型はfalseに、Stringのような参照型はnullに初期化されるというルールがあることを憶えておこう。

##コンストラクタを入れてみる
さっきのプログラムにコンストラクタを入れて**初期状態**を設定して実行してみよう。


```java
	class CustomerCard {
		int id; //顧客id
		String name; // 顧客名

	//**コンストラクタで初期値を設定**
	CustomerCard() {
			this.id = 1111;
			this.name = "taylor";
		}
	}

	class CustomerManager {
		public static void main(String[] args) {
			CustomerCard out = new CustomerCard(); //インスタンス作成
			System.out.println(out.id); //顧客idを出力
			System.out.println(out.name); //顧客名を出力
		}
	}
```

結果はこうなった。

```java
1111 //顧客id
taylor //顧客名
```

うん、いい感じにコンストラクタで指定した値が初期値になった。
こんな感じでインスタンスの初期値を設定できるのがコンストラクタってのをざっくり理解しておけるといいかも。
Flash Gordonについて

#Flash Gordonについて
もうほとんど需要がないかもしれないが、Linerge OSの前身である、CyanogenModは、リカバリーを吹っ飛ばしてくれる困りもので、別のROMに書き換えようとすると、詰むことがある。特に私のカスタムROM遊び用のGlaxy S2はUSBがいかれかかっているので、リカバリーを焼き直すのが難しい。そこでFlash Gordonというアプリの出番になる。ずいぶん前に入れたので確証はないが多分ここからダウンロードした気がする。
https://forum.xda-developers.com/showthread.php?t=2250555
このアプリは、リカバリーを経由せずにアプリ上でリカバリーを更新することができるので、これでTWRPに書き換えることができる。
今はTWRPの専用アプリがあるのでいらないかも。試してないが。
https://hazilog.com/twrp-android-app
VLANのメリット

## VLANとは
VLAN（ Virtual LAN ）とは、物理的な接続形態とは独立して、仮想的なLANセグメントを作る技術です。 VLANはスイッチ内部で論理的にLANセグメントを分割するために使用されます。

## 事例　私生活編
集合マンションのルータを想像する。
GWは1つで各部屋にLANの口がある。
そこには固定ローカルIPアドレスがふられている。
このLANの口にWiFiのアクセスポイントを設置すると
マンションの部屋ごとのIPアドレスが、1個付与されているにもかかわらず、
沢山のローカルIPアドレスをgetできる。
これって当たり前ですよね。

## 事例　仕事編
お客様のネットワーク内にIoT機器を設置。
お客様からIPアドレスを1個だけもらいました。
そのIPアドレスをルータのWANに付けて
ローカルなネットワークを組む。
機器ごとにIPアドレスくれーとお客様に言うより
このやり方が通るとIPアドレスは1個でOKになりお互いに設定が楽になります。
テスターの使い方

## テスターを使って+-を調べる
テスター
・ＤＣ　直流　　”－”　マークで表される
・ＡＣ　交流　　”～”　マークで表される

例えば
下図のコードを切断して別コネクタにつなげるとする
![pw-eh30j-pw-eh30j.jpg](https://qiita-image-store.s3.amazonaws.com/0/153317/b8254027-ec96-8c63-9b8b-ae73607c3d7b.jpeg)


## こんな感じ
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/153317/06ad2ff0-f553-8f38-f246-dd4822c1790f.jpeg)

あとはハンダ付けしたり熱収縮チューブを入れてば完成
MySQL8.0になって変わったこと

# 概要
データベースのメジャーバージョンがあがっても業務ですぐ採用とはならないと思いますが、
せっかく便利に進化しているのに、使わないのはもったいないということで。
とりあえず、内容だけ把握しておいて使えるチャンスを待とうというスタンスでまとめました。

もちろん[公式に特徴の記載](https://www.mysql.com/jp/products/enterprise/database/)はありますが、「〜が高速！」とかは、使用する環境とかに依存すると思うのであまり注目していません。
「できるようになったこと」「できなくなったこと」のほうが興味があるし、実際にデータベース選定時の判断基準にもなるはずです。

以下そういう観点で過去のバージョンと比較した内容を記載しています。

# MySQL8.0でできるようになったこと
## CTE(Common Table Expressions)：With句が使用可能に
もともとPostgreSQLを使っていた身としてはwith句が使えてSQL書く際にネスト地獄を解消できて嬉しいですね。
（他のRDBではすでに実装されていましたが、MySQLはこれまで実装されていませんでした。）

SQLをエディタで書いていると、一応改行やスペースで見やすい形で書くようにはしてましたがネストが続くとどうしてもテーブルの見通しが悪くなるのでありがたいです。

## Window関数が使用可能に
集計時とかに使うと複雑なSelectを簡潔にSQLで実現できて便利ですよね。
個人的にはFIRST_VALUE()やRANK()が便利でこれまでにもお世話になっています。
RDB初心者？というかなれていない人からすると「Window関数なにそれ？言ってることがよくわかんない」ってなりやすいので（昔の自分はそうでした。）、安直に多用するのは問題かもしれません。

## 権限管理がロール単位で可能に
運用保守担当者というかサーバ・インフラ管理を明確にしている場合はかなり便利ですよね。
複数のユーザやシステムが同じデータベースを利用する際に、いちいちユーザごとに権限設定すると事故が起きやすいと思うので助かりますね。むしろなぜ今までなかったのか。

## ドキュメントストアが追加
これによってNoSQLドキュメントデータベースを別に用意する必要がなくなります。
RDBにNoSQLDBの機能が追加されましたっていうイメージですが、どこまで実用的なのかはまだ不透明だと思っています。
一見両方の機能を１つのデータベースで管理できて負担が減りそうですが、規模が小さい場合やお試しの場合はともかく、結局MySQL+Cassandraみたいにそれぞれわけたほうが、実運用向きなのではないかと。
RDBとNoSQLDBでそれぞれ役割が異なるはずなので、それぞれ分業したほうがシステム全体のパフォーマンスは上がると思います。

## JSONサポート強化
JSONデータを受け取り、それをリレーショナルテーブルとして返すJSON_TABLE関数などが追加されました。
JSONデータを取り扱わないシステムっていうのも珍しくなってきているので必然かもしれませんが、個人的にココらへんはまだ使いこなせていないため、感動は薄いです。
（MySQLで無理してjsonしなくても、他のNoSQLDBを並行で使うのでもよいかなあと。そもそもRDBに保存するならjsonをパースして必要な値をそれぞれ適切な型で保存したほうが管理しやすい気がします）

## GIS(Geographic Information System )： SRS(Spatial Reference Systems)をサポート
緯度経度を使ってマップ上にポイントしたりすることはよくあるので、位置の計算や管理がしやすくなるのはいいことですよね。便利そうなのはわかっていますが、こちらも使いこなせていないため、感動は薄いです。
（便利な例があれば知りたいです。）

# MySQL8.0でできなくなったこと

## クエリーキャッシュ廃止
実行したSQLとその結果をメモリ上にキャッシュしておいて、同じSQLが実装された場合に使用することで高速化できるやつですが、廃止されたようです。
新しく利用する場合は問題ないかもしれませんが、バージョンアップした場合で、過去のバージョンでこの機能を使用していた場合に起動しなくなるらしいです。
これ知らないとはまりそうです。

## 古いTIME型やTIMESTAMP型の廃止
古いTIME型やTIMESTAMP型が廃止されたみたいで、もし該当する場合は型の変更が必要みたいです。([参考](https://mysqlserverteam.com/mysql-8-0-removing-support-for-old-temporal-datatypes/))

# 感想
MySQL5.6→MySQL5.7への変更でもだいぶ慎重になっている自分なので、MySQL8.0の実践投入はいつになるかわかりませんが、なるべく早く使ってみたいです。
しばらくはローカル環境の趣味アプリで使うレベルでとまったまま、気づいたら新しいバージョンでることになりそうです。
破綻しない jQuery コーディング

時代は一周まわってjQueryなんですよ。わかりますか？私はわかりません。
これは私がjQuery使うならこう書くし指導する、という記事です。

## selectorの変数化は1つだけ

出典はよく分からないんですが、selectorやDOMを全部変数化する文化がそこかしこにあるようです。

```javascript
// selectorを定数化
var HOGE = '.hoge';
var FUGA = '.fuga';

// jQueryで取得
var $hoge = $(HOGE);
var $fuga = $hoge.find(FUGA);

// なにかしらの処理
$fuga.html('٩( ᐛ )و');
```

定数化はいいことなんですが、DOM要素においてはroot要素のみ変数化しておく方が保守しやすいです。

```javascript
// モジュールのrootとなる要素のみ変数化
var $container = $('.hoge');

// 都度findする
$container.find('.fuga').html('٩( ᐛ )و')
```

これのいい所は .fuga を検索したときに、ちゃんと .fuga が検索に引っかかるところですね。

## SEO無関係なDOMはJSで作る

SEOが絡むとserverでレンダリングしないといけないですが、関係ない部分はJSで作った方が影響範囲をより閉じ込められるのでいいです。

```javascript
// シンプルにDOMを作る
var $container = $('\
  <div class="container">\
    <ul class="hoge">\
      <li>Hello</li>\
      <li>World</li>\
      <li class="fuga">!</li>\
    </ul>\
  </div>\
');

// なにかしらの処理
$container.find('.fuga').html('٩( ᐛ )و')
```

改行をエスケープすると結構見やすく文字列作れます。この方がモジューラビリティが高まるのでいいと思います（テンプレートリテラル使える環境の方はテンプレートリテラルでどうぞ）。こだわってappendとかで頑張ってDOM構築する人もいますが、早すぎる最適化なのでパフォーマンスが問題になったときにチューニングすればOKです。

## selectorを乱用しない

parentやclosestなど、子から親に向かったセレクタを使い始めると地獄がダンスってしまいます。

```javascript
$('.hoge').closest('.container').find('.fuga').html('<li>地獄</li>')
```

親から子をfindするようにした方がいいです。

```javascript
$('.container').find('.fuga').html('<li>٩( ᐛ )و</li>')
```

複雑になってきたときparentやclosestを使ってしまいそうになったら、きっと設計がマズいので、身近なJSマスターに設計の相談をしましょう。

## DOMにデータを持たせない

DOMの状態を参照して、その状態に応じて何かしらの処理を書くパターンもよく見られます。しかしそれって「DOMが状態を持つ」ということなので、状態がいろんなところに散って保守しずらいコードになります。

```javascript
// DOMの状態をもとに処理をする
var isActive = $('.hoge').hasClass('active')
if (isActive) {
  $('.fuga').html('active')
}
```

状態は1ヶ所に集約されていた方がコードが綺麗になるので、基本はJSで状態を持って、JSでその状態を変更し、その状態に応じてDOMを変更した方がいろんな処理がスッキリ書けることが多いです。

```javascript
// JSの状態をもとに処理をする
var isActive = true;
if (isActive) {
  $('.hoge').addClass('active');
  $('.fuga').html('active')
}
```

## Babelで最新のJS構文を使う

で、出〜〜〜！！Babel〜〜！！と妙に拒否反応を示す人もいるかもしれませんが、Babel使うだけならwebpackやgulpは必要ありません。node入れてbabel-cliでコンパイルするだけです。

```
npm install -g @babel/core @babel/cli
babel foo.js --out-file foo.compiled.js
```

実際にはglobal installはしないですけども、とくに複雑なことをせずとも、ただ単純にBabelを通すだけでOKです。gulpやgruntを使っているなら、そのbuild処理にBabelを混ぜ込むだけです。たったこれだけで最新JS構文使えるBabelお得じゃありませんか？

## 無理せずReactを利用する

ReactってViewライブラリ（マサカリ飛んできそう）なので、実はjQuery感覚で気軽に使えるんですよね。Babelを使えるプロジェクトなら大丈夫！簡単です！

```
npm install -g @babel/core @babel/cli babel-preset-react-app
NODE_ENV=production babel foo.js --out-file foo.compiled.js --presets=react-app
```

Reactで必要になるJSXを使うためには、Babelの設定をちょっと追加してコンパイルすればよくて、あとはReactとReactDOMを外部から読み込んでおけばOKです

```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/cjs/react-dom.production.min.js"></script>
```

これだけでReactが使える環境が整いました。簡単ですよね。状態が入り混じりがちなコードになったとき無理してjQueryを使う必要はなくて、サクっとReact使えばOKです。（実際はReactよりもファイルサイズの小さいpreactを使うといいかもしれません！）。

それから私としては、jQueryとReactが入り混じっていても全然気になりません。だって用途が違うんですもの。VueとjQueryが共存できる理由と同じです。

以上！それでは！
ゼロからのkaggleチャレンジ #2 - Digit Recognizer(概要)

Kerasを使ってkaggleのDigit Recognizerに挑戦したので実践内容を順次紹介していきたいと思います。

# はじめに
- kaggleのDigit Recognizerとは？  
Digit Recognizerはkaggleが用意している画像分類の入門となるCompetitionです。
MNISTと呼ばれる手書き数字画像(０〜９)のデータセットに対して予測モデルを構築し分類を行います。
そして分類精度がスコアになり順位を競います。

- 挑戦結果  
まず結果がどうなったのかを紹介しておきたいと思います。
今回はKerasを用いてモデル構造としてはシンプルな２層のCNNモデルを構築し、
分類精度：99.442%を達成しました。
確率上は、200枚の０〜９画像を判定すると199枚は正解することになります。

- 挑戦したDigit Recognizerのソースコード
[Digit Recognizerに挑戦した際のソースコードをkaggleで公開しています。](https://www.kaggle.com/yuta0001/keras-cnn-in-japanese-score-0-99442)
kaggleが用意しているkernelを活用すればすぐに自分で動作させることが可能です。
まずは動かしてみたいという方は利用してみてください。

# Digit Recognizerへの挑戦
## CNNモデル
画像分類の問題なのでCNN(Convolutional Neural Network)でモデルを構築しました。
今回はアーキテクチャの全容について紹介し、次回以降で個々の詳細について順次紹介していきたいと思います。

###アーキテクチャ

Input -> Conv -> Activation -> Pooling -> Dropout -> 
Conv -> Activation -> Pooling -> Dropout -> Flatten -> Softmax

- Input
入力層。入力する画像データです。MNISTの場合サイズは(画像数, 28, 28, 1)になります。

- Conv
畳み込み層(Convolutional Layer)。入力にフィルタを通すことで、特徴を抽出します。
このフィルタを良くするのが今回の学習の目的になります。

- Activation
活性化層。畳み込み層の結果に活性化関数を適用します。今回はReLUを使用しています。

- Pooling
プーリング層。２＊２のMaxPoolingを使用しています。

- Dropout
ドロップアウト層。ドロップアウト率0.1を使用しています。

- Flatten
２次元で扱っていたデータをフラット(１次元)にします。

- Softmax
10クラスの分類問題なので出力層にはソフトマックス関数を使用しています。


次回以降で詳細について順次説明していきたいと思います。

# 終わりに
ご質問や補足してほしい内容や要望などありましたらコメントいただけると幸いです。
google maps api+geocoderの本番環境でGeocoder::RequestDenied

住所から緯度経度を取得し、mapを表示しその位置にピンを立てたい
緯度経度取得時にrailsのgeocoderでGeocoder::RequestDeniedが出た時の対処法

* geocoder 1.4.9
* ruby 2.4.2p198
* Rails 5.1.6

# 問題点
[google maps api](https://cloud.google.com/maps-platform/?hl=ja)のkeyを習得後
以下の様に本番環境用に設定
開発環境用は特に制限なし(公開しない方針で)

アプリケーションの制限
https://www.myapp.com/*
https://myapp.com/*

APIの制限
Maps JavaScript API
Geocoding API
Places API

geocoderを使うためにapi keyを渡します
gem configを使ってます

```xml:config/settings/production.local.yml
google:
  map_key: 'Your api key for production'
```

```xml:config/settings/development.local.yml
google:
  map_key: 'Your api key for development'
```

先頭に0をつけていないと、geocoder.rbを読み込む前にconfig.rbを読み込まない場合があります

```ruby:config/initializer/0config.rb
Config.setup do |config|
  config.const_name = 'Settings'
end
```

```ruby:config/initializer/geocoder.rb
if Rails.env.production? then
Geocoder.configure(
  lookup: :google,
  always_raise: [
    Geocoder::OverQueryLimitError,
    Geocoder::RequestDenied,
    Geocoder::InvalidRequest,
    Geocoder::InvalidApiKey
  ],
  api_key: Settings.google.map_key,
  use_https: true
)
else
Geocoder.configure(
  lookup: :google,
  always_raise: [
    Geocoder::OverQueryLimitError,
    Geocoder::RequestDenied,
    Geocoder::InvalidRequest,
    Geocoder::InvalidApiKey
  ],
  api_key: Settings.google.map_key
)
end
```

```html:show.html.erb

<script type="text/javascript" src=<%= "https://maps.googleapis.com/maps/api/js?key="+Settings.google.map_key+"&libraries=places&callback=initMap" %> ></script>
```

表示はうまくいったことを確認し、本番環境で以下のコマンドを実行するとエラーが、、
開発環境ではうまくいくのになぜだとしばらく悩みました

```
geolocation = Geocoder.coordinates(`tokyo`)
Geocoder::RequestDenied
```

# 解決策

google mapの表示用のkeyはhttpリファラーで制限し、geocoderに渡す用のkeyはipアドレスで制限をする

よく考えたら当たり前のことでしたが妙に詰まったのでメモ

```xml:config/settings/production.local.yml
google:
  map_key: 'httpリファラーで制限をしたgoogle api key'
+ geocorder_key: 'サーバーのIPアドレスで制限をしたgoogle api key'
```

```ruby:config/initializer/geocoder.rb
if Rails.env.production? then
...
- api_key: Settings.google.map_key,
+ api_key: Settings.google.geocorder_key,
...
else
...
end
```

```ruby:console
geolocation = Geocoder.coordinates(`tokyo`)
=> [35.6894875, 139.6917064]
```

無事成功しました
reveal.js - スライドデザインのカスタマイズ

スライド作成ツールであるreveal.jsのデザインの変更方法です
[reveal.jsのテーマのREADME](https://github.com/hakimel/reveal.js/tree/master/css/theme)も参考にしてください

背景画像やアニメーションなどは[reveal.js](https://github.com/hakimel/reveal.js/)自体のREADMEで説明されています
日本語での説明は[【翻訳】reveal.js - README.md](https://qiita.com/takayu90/items/0af9bd125e6704803c0d)をご覧ください

# テーマの作成手順
reveal.jsのテーマはSass(SCSS記法)で書きます
SassはCSSを拡張した言語で、CSSで書くと冗長になりがちなセレクタやプロパティをスッキリ表現することができます

## .scssファイルコピー
基本的に[/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source)にデフォルトで用意されているテーマの```.scss```ファイルをコピーして新たなテーマを作成してください

## .scssファイル編集
.scssファイルは以下のような内容となっています
以下のstep3の部分だけ編集します

1. **[/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)**をインクルードする
共通の関数が定義されています

2. **[/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)**をインクルードする
共通の変数がデフォルト値と共に定義されています

3. **オーバーライド**
デフォルトの設定をオーバーライドします
ユーザーはこの部分を変更するだけでテーマをカスタマイズできます
上記step2の変数を指定する([settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)を参照)か、セレクタを追加してもいいです

4. **[/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)**をインクルードする
step1からstep3で設定した変数を元に、最終的なCSSを生成するテーマファイルです

## コンパイル

以下のコマンドを実行すると、[Grunt](https://gruntjs.com)ツールがSassをコンパイルし、CSSファイルを作成します([Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js)を参照)
`npm run build -- css-themes`

`css/theme`に最終的なCSSファイルが出力されるので、index.htmlで読み込むようにすればOKです

# フォントの変更方法
デフォルトでは2つのフォントが使えるようです
`lib/font`にフォントごとの設定ディレクトリがあります

```
lib
  └─ font
    ├─ league-gothic
    └─ source-sans-pro
```

## フォントを選ぶ
無料で使えるフォントが以下のサイトにまとまっているのでおすすめです
各配布サイトへのリンクからダウンロードできます
大抵の場合、`.otf`または`.ttf`で配布されています
フォント作成者への感謝を忘れず、個人利用・商用利用にかかわらず利用規約やライセンスを必ず読むようにしましょう
[FONT FREE](http://fontfree.me/)

例として、[やさしさゴシックボールド](http://www.fontna.com/blog/736/)に変更してみます

## フォントのCSS作成
`yasashisa-bold`ディレクトリを作成し、CSSファイルとダウンロードしたフォントファイルを配置します
デフォルトのように、LICENCEファイルも含めておいたほうがいいかもしれません

```
lib
  └─ font
    └─ yasashisa-bold
      ├─ yasashisa-bold.css
      └─ YasashisaBold.otf
```

CSSファイルを編集します
独自のフォントを指定するための標準化された書き方なので、以下のサイトを参考にしてください
[https://developer.mozilla.org/ja/docs/Web/CSS/@font-face](https://developer.mozilla.org/ja/docs/Web/CSS/@font-face)

```css
@font-face {
  /* フォントの名前 */
  font-family: 'yasashisa-bold'; 
  /* フォントファイル */
  src: url('YasashisaBold.otf') format('opentype');

  font-weight: normal;
  font-style: normal;
}
```

## テーマに指定する
`css/theme/source`のカスタマイズしたいテーマの`.scss`ファイルに以下のように記述してコンパイルします
生成したCSSでスライドを表示するとフォントが変わっていることを確認できるはずです

```scss
// Include theme-specific fonts
@import url(../../lib/font/yasashisa-bold/yasashisa-bold.css);
```

![sampleslide.png](https://qiita-image-store.s3.amazonaws.com/0/265526/535703a9-47fa-00e3-68a0-4dbded5e4fdf.png)

```sh:動作確認環境
$ uname -a
Linux laputa 4.19.2-arch1-1-ARCH #1 SMP PREEMPT Tue Nov 13 21:16:19 UTC 2018 x86_64 GNU/Linux
$ firefox -v
Mozilla Firefox 63.0.3
```

reveal.jsはHTML/Markdown/JavaScript/CSSでスライドを作成できるオープンソースのツールです
様々なカスタマイズができますので、是非利用してみてください
AWS Cloud9でYour web browser does not have third-party cookies enabledが出る場合の対処 (Google Chrome)

# 前提
2018/12/21時点の情報
Google Chrome バージョン: 70.0.3538.110（Official Build） （64 ビット）

# エラー内容

Environment Error
-
Your web browser does not have third-party cookies enabled

Enable third-party cookies in your web browser, and then try opening the 
environment again. For more information, see your web browser's documentation.

![image.png](https://qiita-image-store.s3.amazonaws.com/0/184997/31f08c5a-d1ae-b36c-6e32-049afb4b90d2.png)

#　対応方法
Chromeの設定画面を開く
プライバシーとセキュリティ
コンテンツの設定
Cookie

許可の追加ボタンをクリックする
[*.]amazonaws.comを入力する
追加ボタンをクリックする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/184997/6b578d0d-23e7-fd6f-e61e-05544660502f.png)

# 補足
## リージョンごとに許可したい場合
https://docs.aws.amazon.com/cloud9/latest/user-guide/troubleshooting.html#troubleshooting-env-loading

| AWS Region | Domains |
|:--|:--|
| Asia Pacific (Singapore) | *.vfs.cloud9.ap-southeast-1.amazonaws.com vfs.cloud9.ap-southeast-1.amazonaws.com |
| EU (Ireland) | *.vfs.cloud9.eu-west-1.amazonaws.com vfs.cloud9.eu-west-1.amazonaws.com |
| US East (N. Virginia) | *.vfs.cloud9.us-east-1.amazonaws.com vfs.cloud9.us-east-1.amazonaws.com |
| US East (Ohio) | *.vfs.cloud9.us-east-2.amazonaws.com vfs.cloud9.us-east-2.amazonaws.com |
| US West (Oregon) | *.vfs.cloud9.us-west-2.amazonaws.com vfs.cloud9.us-west-2.amazonaws.com |

## サードパーティクッキーを全部許可するのはやめた方が良い
http://ascii.jp/elem/000/000/654/654929/
一部のディレクトリを除いて「https://～」へリダイレクトする方法を試してみた

# 背景
WebサイトをSSL化させる機会があったのですが、**SSL化させたいサイトが設置してある数十個のサブディレクトリにそれぞれサイトが設置してあり、**今まで何十サイトとSSL化させてきたにも関わらず、初経験だったのですが、**一部のディレクトリを除いて「https://～」へリダイレクトさせる**ことにしました。

色々ネット上で調べてみて上手く動作したので、メモです。

# .htaccessにするコード
```
<IfModule mod_rewrite.c>

RewriteEngine On
RewriteBase /

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} www.example.com
RewriteCond %{REQUEST_URI} !^/サブディレクトリ名1/.*$
RewriteCond %{REQUEST_URI} !^/サブディレクトリ名2/.*$
RewriteCond %{REQUEST_URI} !^/サブディレクトリ名3/.*$
RewriteCond %{REQUEST_URI} !^.*\.(js|css|gif|jpg|png|ico)$
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

</IfModule>
```

# まとめ
という感じです。
参考記事によると、マルチディレクトリにも応用できるそうで、機会があれば試してみようかなと思います。

# 参考サイト
特定ディレクトリのみ共有SSL化する.htaccess設定
https://office-obata.com/report/memorandum/post-682/

一部ディレクトリ以外をSSL（https）へリダイレクトしたい
https://teratail.com/questions/54658

mod_rewriteでHTTP / HTTPSの切り替え
https://qiita.com/gotohiro55/items/7daa988db23a5a8355c1
〜超初心者が行く！ conoHa Wing体験記〜

# conoHa Wing 使ってみた！

## Introduction

本記事では ConoHa Wing および Qiita を今まで使ったことない初心者が
初めて使ってみた！と言う記事です。

だから、__「今まで使ったことないよ！」__とか__「どんななのかな!」__と言った方向けの記事になると
いいな〜と思います。

## 先ずはconoHaカード購入！

清算にはクレジットカードも利用できるらしいけど、、、
__「conoHaカードが欲しい！」__


ということで購入しました！
カードは「デジタル版」と「パッケージ版」があるわけだ！。。。

__リアルこのはちゃんが欲しい!__(￣∇￣)

ということでパッケージ版ConoHaカード「5000円」を買うぜ！

カードはconoHaショップで買えるよ！
あと今回はコンビニで購入してみたよ〜

![3fHzQATdR+izyFOGpt2fDw.jpg](https://qiita-image-store.s3.amazonaws.com/0/309537/aeac5273-d0f3-e5b8-7762-f079f2997e8d.jpeg)



__かわゆす!◟꒰◍´Д‵◍꒱◞__

## conoHa Wing サービス申し込み！

よし！準備ができたので、あとは会員登録していこう！

プランの指定はとりあえず一番安い__「ベーシック」__
リザーブドにすれば、CPU・メモリが安定確保できるらしいが
今回はこのプランでやってみよう！

初期ドメインとサーバー名を入力すると...

お！プリビジョニングが始まったぞ
すぐに終わった〜

「ドメインの追加して〜」ってでたから追加するよ！

おっ　無料独自SSLというものが使える！
__「利用する」__にして__「保存」__する！

ありゃ　できないな　汗

まいっか、一旦置いておいて、WordPressをインスコしてみるよ！
「サイト管理」から適当にぽちぽち...

おー！あっという間にできたよ〜！
よっしゃ　管理画面へアクセスっとってあれ、、、
できない！！(￣◇￣;)

うーんとですね。。。はい。アホでしたw

ドメインを削除して、初期ドメインで再構築して、、、

はい　つながりました、って__そりゃそうだろ！w__
__存在しないドメインを追加してました__　あほす(~_~;)

でも流石にSSL通信できないホームページはセキュリティ上問題ありで、
公開できないだろってことで。。。

## お名前.com より 独自ドメイン取得！
恥ずかしながら、今までドメインを取得したことはございませんですよ。。。
これを機に取得ということでね！( ・∇・)

そしてまた勉強になったんだけどさ、、、
__ICANNへのWhois情報公開代行サービスっていうのがあるのね！__
ドメインを取得した人ってどんな人かをICANNへ申請する必要があるんだけど、
個人でやる場合って個人情報登録するのって嫌じゃん。誰でも見れるわけだし...

そこで！Whois情報公開代行というので、お名前.comさんの情報で代わりに
whoisへ登録してくれるというもの！！

楽チンな上に個人情報を登録しなくて良いなんて。。。イイね！(・∇・)

じゃぁ、早速お名前.comにログインして、
__「ネームサーバの変更」__でさっきの作ったドメインの
NSレコードとして、conoHaのNSを設定するよ！
そしてしばらく待つ！！

無事完了したので、先ほどやろうとした通りに
__「ドメインの追加」__をするよ！

そして、無料独自SSLも設定！　できたね！
でも今はSSL接続はできなさそう。SSLの設定には時間がかかるのかな？
設定していますとわでた。とりあえず放置。

ちなみにWAFの設定はデフォルトで有効になってた！((o(^∇^)o))

そんなこんなしてるうちに、SSLの設定が終わったっぽい！
もう一回サイトセキュリティを確認してみたら、
__「設定中」__から__「利用中」__になってた！
サイト設定を開くと、httpsになっとる！OKOK〜


##Wordpress 管理コンソールへ接続
これで安心してWordpressへログインしてあれこれできるね〜(´ω｀)

ログインと。。。。

キター！！♪───Ｏ（≧∇≦）Ｏ────♪

__ブログ開設！__


>ショボボんな俺的備忘録
〜Let's try anything〜
https://www.syobobon.site/orebibo/


#感想

そのあとはテーマを変えてみたり
SEO対策用のプラグイン入れたり〜っとやって
何個か記事を投稿してみました！！
(近々で一週間ぐらいサボっちゃってるけどw

今までホームページ開設なんてやったことなかったし
情報を発信するということを積極的にやったことがなかったので
いい経験になりました！

これからも何かしらの情報（くだらないこと含むw）
の発信はやっていこうかなっと思います！

また、そういう意味では今回人生で初めてホームページ開設しましたが
非常に導入しやすかったですね。
ここまでは個人的にはそんなに難しくなかった。

思ってたよりもシンプルにセキュアなサイトが構築できてるという印象です。

せっかくなんで今回開設した自分のホームページにこの記事を書こうかなって
思ったけど、こっちに投稿することにしました。

Qiitaを利用するためのマナーとして__「HRT」__というものがあります。

>Humility(謙虚)
Respect(尊敬)
Trust(信頼)

上を意識した上でどのように情報発信をし、コミュニケーションを図るべきかが
Qiitaのガイドラインに記載してあります。

その内容に感銘を受けたのもあってあえてこっちに投稿しました。
今回の活動は個人的には学びが大きかったな！

次はせっかく作ったホームページをうまく生かすのと、
継続するための努力をしなくてはw

といったところでこの記事は以上とさせていただきます。


ここまで見ていただきありがとうございました！(⌒▽⌒)

#追伸
どうやら、ConoHa VPSにテラリアのアプリケーションイメージが
追加されたようです！

マイクラだけでなくテラリアも！

テラリアでも多人数でのマルチプレイが簡単にできるようになりましたね！
。。。人集めてやりたい！

人集めの方が大変そうだけど！！ww

>ご利用ガイド　「テラリアアプリケーションイメージの使い方」
https://support.conoha.jp/v/terraria/?btn_id=terraria_news&_ga=2.252276169.1345199597.1543715152-1276776179.1541943461
Dockerのイメージを削除ができない時は「-f」オプションを使う

# 不要なイメージを削除しようとしたらエラーメッセージが返ってた
Dockerの不要なコンテナやイメージを削除しようとしたら以下のようなエラーメッセージが返ってきました。

    #$ docker rmi id名
    #Error response from daemon: conflict: unable to delete id名 (must be forced) - image is referenced in multiple repositories


ネットで調べてみて、以下の記事がネットでヒットしました。
ありがとうございます、感謝！

>複数のリポジトリから参照されているイメージだから削除できないよ。強制的にやってとあります。
>(参考：[Docker不要なコンテナ、イメージを大掃除！コンテナとイメージの一括削除](http://www.kaasan.info/archives/3953))

とのことでしたので、-fをつけたコマンドを実行


    #$ docker rmi id名 -f

すると見事削除に成功しました。

-f→forceという意味だそうで、強制的に削除ができるとのこと。
セッションとCookieをざっくり学んだ

# セッションとは？
広義の意味ではこんな感じ。
>1.《名》会合や授業を行う期間（時間）的な一続き。 「この―で解決しよう」
2.《名・ス自》ジャズなどで、演奏者が集まって演奏すること。

コンピュータにおいては、**一連の処理の始まりから終わりまでを表す概念**のことですね。

## 「会話」が一番わかりやすい例え
2人が、

- 出会って
- 会話して
- バイバイする

ここまでで「1セッション」となります。


コンピュータにおいては、

- サイトにアクセス
- そのサイトのページをいくつか閲覧する
- そのサイトから離れる(ブラウザを閉じるetc)

この流れで「1セッション」ですね。

次は、**HTTPセッション**について少し学んでみましょう。

## HTTPセッションとは

HTTPセッションは「セッションID」を使って、[セッション管理](https://f5.com/jp/education/glossary/glossary059-21540)を行います。

具体例でいうと、

- 通販サイトにおいての、「ログイン状態か否か」「カートに入った商品」「購入処理」
    - ex) カートに商品を入れる際、ログインしていなければ、ログイン画面に遷移する。
- mixiの日記サービスにおいての、「ログイン状態か否か」「日記を書いている」

それぞれの状態をセッションIDを用いて、管理する。といった感じです。

HTTPセッションにおけるセッション管理には、**Cookie**が主に用いられます。


# Cookieとは？
https://boxil.jp/mag/a2856/#2856-1 から引用
>Cookie（クッキー）とは、ユーザーのWebブラウザとWebサーバー間で特定の情報をやり取りするファイルであり、HTTPヘッダーに含まれた識別子です。

とどのつまり、**自分が今どのような状態(どんな商品をカートに入れたかetc)かを表したファイル**です。

セッションIDはCookieに保存され。そのCookieは、ブラウザごとに保存されます。(参考: https://aprico-media.com/posts/1557)

セッションIDはサーバー側で生成されますが、この辺は[こちら](https://qiita.com/7968/items/ce03feb17c8eaa6e4672)を参考に。
[年末大掃除]  まだGASで苦しんでるの? Zapierで楽しようよ!

(本記事は、エンジニアというより、現場の仕事をとりあえず自動化・効率化する仕事"も"しています、という方向けです。)

## まだGASで苦しんでるの?
なんだか挑発的なタイトルになってしまいました。
実のところ、私もGAS (Google Apps Script)の運用・保守に苦しんでいる一人です。(現在進行系)

### なぜ、GASの運用・保守はきついのか
- **トリガーの数に制限がある**
- **誰がトリガー持ってるか分かりづらい**
- **そもそも、何作ったか忘れる**

### kintone入れたら? 内製したら?
そんな声が聞こえてきそうです。 (たぶんその批判は正しい。)
とはいえ、そうもいかないところもあるわけです。
貴重なエンジニアリソースを使うほどではないし、当座の実現にはそこまで技術力がいるわけでもない。
そして、やったらやったで、現場はそこそこ楽になるわけです。

### ということで。
開発リソースを喰わずにいけることと、トリガー問題が解消されることの2点からZapier有料版を導入してます。
移せるものからGASをZapierに移行中。

## そもそもZapierとは
タスク自動化を支援してくるれツール・サービス。
(一応、RPAツールと呼ばれてるようです。個人的には若干違和感ありますが・・・。)

<img src="https://qiita-image-store.s3.amazonaws.com/0/219427/aa7ae20d-f593-36bb-a3b5-2fc58b370694.png" height=70>
出典 : https://zapier.com

特徴は、

- APIを読み込んで～
- サーバー立てて～
- コーディングして～

などが必要なところをGUIポチポチしていけば自動化できるところ。
Zapier側が登録してくれているアプリもどんどん増えていて、使い勝手はどんどん向上しています。
名前は「ザピアー」「ザピエル」などと呼ばれるらしいです。

## どうやって自動化するの
概要のみ。

### 工程
1. Make a Zap!
2. Set a Trigger!
3. Connect a Action!

とってもシンプル。 (有料版は、Actionをたくさん紐づけできる。)

<img src="https://qiita-image-store.s3.amazonaws.com/0/219427/fe4b1799-909a-0d0a-c201-b09937b181e1.png" width=600>


### Make a Zap!
Zapierで自動化する1つのタスクは、Zapと呼ばれます。

### Set a Trigger!
Zapにトリガーを設定します。

### Connect a Action!
トリガーに対して、実行するアクションを設定します。

- FilterやPathなどの標準機能
- 登録されているアプリケーション
- POST

など、かなり使い勝手が良い。

## どういうことやってるの? (事例集)
### GoogleForm → Slack, カレンダー
<img src="https://qiita-image-store.s3.amazonaws.com/0/219427/ec4baefc-4ff4-b26e-a710-04a5fb96f143.jpeg" width=800>

- トリガー
    - Google Form
    - (Google Sheetに新しい行作成)
- アクション
    - Filter
    - Slack
    - Google Calendar

### MailChimp → Treasure Data
<img src="https://qiita-image-store.s3.amazonaws.com/0/219427/9b3b4518-2434-5f5d-e80c-a6f148a91a59.png" width=800>

- トリガー
    - Mailchimp : 配信停止
- アクション
    - API POST : Treasure Data レコード追加

### Trello → Slack, SpreadSheet
<img src="https://qiita-image-store.s3.amazonaws.com/0/219427/fc5551ff-09be-bf54-950c-7a2dc44920fe.png" width=800>

- トリガー
    - Trello : Create / Move
- アクション
    - Slack : 追加通知
    - SpreadSheet : 履歴発行

## 運用で気をつけていること
### アカウント
- 編集権限、誰持ってます?
- 〇〇さん、退職だけど、引き継ぎしました?
- XXさん、お休みで対応できない

というのを避けたいので、共有アカウントでログインしています。
ただ、Zapier触れる人が全部沢れるのも怖いので、部署ごとに分けています。

### フォルダ管理
- PrivateにZapを作成しない

編集はできなくとも、なにが動いているかの透明性を担保するために、すべてのZapはPublicにする思想でいます。

### 命名規則
`トリガーになるアプリ名:条件 to アクションアプリ名:動作`
というような形を基本形にしています。

### 講習
完全な資格制ではないですが、始めたいという方は

- 上長承認
- (有志作成の) 講習を受講

するような流れで、使用人数を制限しています。

## 使ってみて
### メリット
- トリガー管理しなくていいので安心できる
- 共有アカウントなので、管理も楽になった
- Zapierが思いの外、使いやすい
    - 慣れるまでは機能足りないと感じるかもしれない
    - 組み合わせ方がわかってくると実現できることの幅が広がる

### デメリット
- 即時実行ではない
    - 5分間隔
- テストを行いづらい
    - パターンがいくつか別れているものなどの本番テストに時間がかかる
- エラー処理を細かく行えない
    - これは方法があるのかもしれないが、GASのがたぶん楽
    - そもそもエラー処理前提をZapierにもっていくなという意見もあると思う

## まとめ
すべてのGASをZapierに移行したわけではないし、Zapierで完全に満足しているわけでもないです。
ただ、今までGASで苦しんできたことから、少しは開放されました。
管理できている感覚があるというのは、素晴らしい!

同じような苦しみを抱えていれば、ぜひ試してみてください。
リバースプロキシの背後に設置したWordPressのアクセス解析で、閲覧者IPアドレスを正しく取得する方法

## やりたいこと

「リバースプロキシの背後に設置したWordPressのアクセス解析で、閲覧者IPアドレスを正しく取得したい」

リバースプロキシの背後に設置したWordPressで、slimstatなどのアクセス解析プラグインを使うと、slimstatが閲覧者IPアドレスを理解できず、全てのIPアドレスが同じになってしまいます。

## やり方

以下のプラグインを使うと良い。
https://wordpress.org/plugins/proxy-real-ip/

検索して出てくる多くの解説では、wp-config.phpを直接いじれと書いているが、プラグインのほうが保守性が良いと思う。

- https://blog.trippyboy.com/2011/wordpress/wordpress%E3%81%A8reverseproxy%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E6%8E%A5%E7%B6%9A%E5%85%83%E3%82%92%E6%AD%A3%E3%81%97%E3%81%8F%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/

### ソースコード

利用者が少ないので心配だったが、ソースコードを見た所、変な実装ではない。

```php
<?php
/*
Plugin Name: Proxy Real IP
Plugin URI: http://wordpress.org/extend/plugins/proxy-real-ip/
Description: Correct the user's IP address if you are behind a proxy or load balancer. It should start working as soon as you activate it. Based on 'Real IP' plugin (v1.3) by Yejun Yang that is no longer updated.
Version: 1.1
Author: Sam Parsons
Author URI: http://sjparsons.com/
License: GPL2
*/

/*  Copyright 2012 Sam Parsons (sjparsons -at- gmail.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

$ip_match = '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/';

$http_headers = array(
    'HTTP_X_FORWARDED_FOR',
    'HTTP_X_FORWARDED',
    'HTTP_FORWARDED_FOR',
    'HTTP_FORWARDED',
    'HTTP_X_REAL_IP',
);

foreach($http_headers as $h) {
    if (isset($_SERVER[$h]) && preg_match($ip_match,$_SERVER[$h])){
       $_SERVER['REMOTE_ADDR'] = $_SERVER[$h];
       break;
   }
}    

// Set Server variables so that is_ssl() reports correctly.
// If HTTPS server variable is not set and the HTTP_X_FORWARDED_PROTO is set, then
// set HTTPS = 1 if HTTP_X_FORWARDED_PROTO is set

if (!isset($_SERVER['HTTPS'])) {
    if ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
        $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
        $_SERVER['HTTPS'] = 1;
    }
    else {
        $_SERVER['HTTPS'] = 0;       
    }
}
```
CdSで部屋空き状況をGmailで送信

CdS（硫化カドミウム）を使用した光センサを用いて、部屋の明かりのON,OFFを検知。

明かりの切り替えがあるとメールで知らせてくれるというシステム。


使用する製品
・RaspberryPi
・Arduino
・CdS
・ブレッドボード
・10kΩ抵抗器
・ジャンパワイヤー



#システム構成図

・大まかなシステム構成図
![5555.PNG](https://qiita-image-store.s3.amazonaws.com/0/275246/454e8e0e-baa0-4bc0-0564-0a334a78750a.png)

#実装手順

1. Arduinoの設定
2. Gmailの設定
3. RaspbeeryPiの設定




##1. Arduinoの設定

###1.下の回路図を参考にジャンパ線をつなげる

![44.PNG](https://qiita-image-store.s3.amazonaws.com/0/275246/a417b87c-4072-d153-6d2d-7e90c13a7558.png)

###2.プログラムをArduinoに書き込む

[Arduino Web Editor](https://create.arduino.cc/editor/)のページに行き、下記ファイルをArduinoに書き込む。
※Arduino Web Editorの使い方がわからない方は別途参照が必須

```CdS.ino
const int led_pin = 9;
const int vol_pin = 0;

int vol_value = 0;
int temp=0;

void setup() {
  Serial.begin( 9600 );
    temp = analogRead( vol_pin );
}

void loop() {
  vol_value = analogRead( vol_pin );

  analogWrite( led_pin, vol_value );

  if(abs(temp-vol_value)>10){　//一つ前に入ったtemp変数とvol_value変数の値が10より差が開いているか確認
  Serial.println("0");
  }else{
  Serial.println("1");
  }
  temp = analogRead( vol_pin );
  delay( 2000 );
}
```
接触の問題かわからないが、CdSの出力する値(vol_value変数)が接続するたびに異なることが起きたので、temp変数とvol_value変数の差から明かりのON,OFFを判別

###3.Arduinoのテスト

無事に書き込みが完了後、部屋の明かりをON,OFFに切り替えた時にだけ0が出力されるか確認

![7894.PNG](https://qiita-image-store.s3.amazonaws.com/0/275246/06ae778f-a5af-281d-eba3-27e3453b5836.png)

##2.Gamilの設定

Gmailでメールを送信するときに設定が必要になる。

1.Gmailにログイン後2段階認証プロセスをON
2.[アプリパスワードを作成](https://support.google.com/accounts/answer/185833?hl=ja)、16桁のパスワードを取得

アプリ パスワードを使用すると、2 段階認証プロセスに対応していない端末上のアプリから Google アカウントにログインできるようになる。このとき作成したパスワードはRaspbeeryPiで作成するメール送信pythonプログラムに入力が必要になる。

![Capture.PNG](https://qiita-image-store.s3.amazonaws.com/0/275246/25094d44-66af-bc9e-6d27-fc7dc4791c9a.png)

##3.RaspbeeryPiの設定

###1.下記pythonプログラムをRaspberryPi上に作成

```mail_send.py
import serial
import smtplib
import time
from email.mime.text import MIMEText

ser = serial.Serial('/dev/ttyACM0',9600,timeout=None) #Arduinoとシリアル通信
while True:
 line = ser.readline()
 x = int(line) #型変換　stringからint
 if x==0:
  if __name__ == '__main__':
    to_addr = 'xxxxxxxxxxxxxxxxxxx@gmail.com' #送信先メールアドレス
    from_addr = 'yyyyyyyyyyyyyyyyyyyy@gmail.com' #アプリパスワードを作成したメールアドレス
    mail_id = from_addr

    mail_pass = 'zzzzzzzzzzzzzzzz'  #作成したアプリパスワード(16桁)に置き換える

    message = MIMEText('Hello')
    message['Subject'] = 'Hello'
    message['From'] = from_addr
    message['To'] = to_addr

    sender = smtplib.SMTP_SSL('smtp.gmail.com')
    sender.login(mail_id, mail_pass)
    sender.sendmail(from_addr, to_addr, message.as_string())
    sender.quit()
ser.close()
```

###2.システムが正常に動作するか確認

```
$python mail_send.py
```

エラーが検出されず部屋の照明を切り替えた時に送信先メールアドレスにメールが届いていれば完了

###3.nohupコマンドでプログラムを裏で動作させる

最後にターミナルを消しても裏でプログラムが動作しているようにするために、nohupコマンドを使用

```
$nohup python mail_send.py &
```

jobsコマンドを使用、現在実行しているジョブを確認。

```
$jobs
```

nohupの使い方についてわからない方は別途参照することをお勧めする。
ScalaでCollection内オブジェクトの任意の条件で集合演算をする

※この記事は仕事用アカウントから個人用アカウントに移行した記事になります。

# 動機
Collection内のObjectのKeyだけ比較して集合演算したい！みたいなことって割とあると思います。

# 試してみた
`key`と`value`をもつcase classを定義し、keyの値で集合演算をしたい場合で考えます。
何も考えずにやると以下のようにうまくいきません。
list内の `Obj(b,1)` と del内の `Obj(b,2)` を同じオブジェクトと判定できず除外してくれません。

```scala:
case class Obj(key: String, value: Int)

val list = List(
  Obj("a", 1),
  Obj("b", 2),
  Obj("c", 3)
)

val del = List(
  Obj("b", 11),
  Obj("b", 12),
  Obj("d", 13)
)

list diff del // => res0: List[Obj] = List(Obj(a,1), Obj(b,2), Obj(c,3))
```

# 直してみた
`Obj` の `equals` と`hashCode` をoverrideしてやればうまくいきます。良かったですね。
（equals内の実装は適当なのでプロダクションに入れるときはinstanceが異なる場合なども考慮してちゃんと実装しましょう）

```scala
case class Obj(key: String, value: Int) {
  override def equals(arg0: Any): Boolean = {
    key == arg0.asInstanceOf[Obj].key
  }

  override def hashCode(): Int = {
    key.hashCode
  }
}

val list = List(
  Obj("a", 1),
  Obj("b", 2),
  Obj("c", 3)
)

val del = List(
  Obj("b", 11),
  Obj("b", 12),
  Obj("d", 13)
)

list diff del // => res0: List[Obj] = List(Obj(a,1), Obj(c,3))
```

# 説明
Javaオブジェクトの比較には `Object#equals`, `Object#hashCode` を利用します。
Scalaでも同様にこれらのメソッドを任意に書き換えてあげれば良いようです。
今回は `diff` でしか検証してませんが、恐らく他の集合演算メソッドでも同様だと思います。

## 追記
コメントでご指摘頂いたとおり、case classの`equals()`, `hashCode()` をoverrideするのは注意が必要です。
特に理由が無ければ別の方法を取るべきだと思います。~~詳細はコメントを御覧ください。~~
↑
元記事をアカウントごと消してしまったのでコメントが閲覧できなくなりました。
移行前にコメントだけ引用しておくべきだった・・・。

以上です。
若草春男の考えるKuinの問題点

「くいなちゃんは語らず、ただ微笑むのみである。」　－　若草春男

# はじめに

Kuin言語は初心者向けのゲーム制作に特化した言語です。具体的にはHSPの代替を目標としています。しかしこの目論見は成功するのでしょうか。今の状況では成功するとは思えないというのが正直なところです。私はKuin言語に3か月ほどしか触っていない新参者ですが、一応くいなちゃんにプルリクエストを送って承認された実績を持っていますので、Kuin言語に関していくばくかの提言を行うことができるものと考えます。したがってこのような通常のアドベントカレンダーでは扱わないトピックを取り上げさせていただく次第となったわけです。

# くいなちゃんのロードマップ

Kuin言語は言語のフォーマットこそPascalライクとはいえ、ライブラリやKuinエディタなどの環境を総じてみればVisual Studioのサブセットです。2018/12/17のアップデートではKuinエディタの入力補完機能を強化するのだそうです。したがって、くいなちゃんの目論見としては、Kuin言語とはVisual StudioのC++に触れるためのとっかかりを作るためのステップであり、またはUnityなどの別の言語・処理系でもいいのだけど、Kuin言語自体であまり多くのことをさせるつもりはないようです。この後のトピックにおいてこのことを詳述いたします。

# Kuin言語の長所

Kuin言語のよいところは、インストール手順が単純であること、処理系のファイルサイズがとても小さい(<20MB)こと、文法とライブラリが簡潔であること、Windows環境に適した言語設計であることです。

# パッケージ管理システムがない

Kuin言語にはサードパーティ製のライブラリを提供する仕組みがありません。この仕組みはPerlをはじめ、現代的な言語においては標準的に搭載されている機能です。

パッケージ管理システムは、言語の標準ライブラリの他に、パッケージの置き場所を提供します。パッケージ置き場にパッケージとなるディレクトリを置いておけばソースコードの中からパッケージの関数やクラスを呼び出すことができます。

パッケージ管理システムは、言語が推奨するパッケージの一覧と、パッケージを簡単に導入する手段も提供します。これは言語のメンテナーの負担を増加させる結果にもなります。メンテナーがパッケージのレビューを行わなければならないからです。パッケージのなかでパッケージを使うといった依存関係や、パッケージを改修させる手間などを考えるとパッケージ管理システムに問題点がないわけでもありません。

しかしパッケージ管理システムにはそれらの弱点にあまりある強力な可用性をもたらします。パッケージ管理システムはプログラミング言語にパワーと混乱をもたらすといえるでしょう。

# ドキュメントがオンラインで管理されている

これはMicrosoftのドキュメント提供方法にならっているのだと思います。つまり、最新のドキュメントしか提供しないのです。しかし本来であればソースコードとバイナリとドキュメントは同一のプロジェクトにて管理されるべきです。

# ライセンス

Kuin言語はくいなちゃんライセンスで提供されています。しかしKuinのリポジトリ内ではサードパーティのライセンスを使用しており、本来であればそれらのライセンスを明記すべきです。もしそういったことをしたくないのであればそれらのライブラリを標準ライブラリではなくパッケージとして取り扱うべきでしょう。

# オブジェクト指向言語機能が不足している

これはKuinユーザーのなかにそういう考えの人もいるということであって、別に現状維持で問題ないと考えます。少し説明します。C++やC#は充実したオブジェクト指向言語機能をもっています。しかしそういった本格的なオブジェクト指向の機能を実装すれば、コンパイル速度が低下するしドキュメントも難解になるでしょう。したがってオブジェクト指向言語機能の追加については私は反対なのです。

# ドキュメントが不足している

これはKuin以外のプログラミング言語でもあることであって、おかしいことではありません。これは、「ドキュメントに記載されていることに関しては仕様変更をできるだけ行わないがドキュメントに記載されていないことは変更しうる」ということです。これはプログラミングにおける不文律です。

# Kuinエディタが貧弱

枝葉末節の問題です。例えばKuinエディタでは右クリックメニューが実装されていないのですが、それはCtrl+CやCtrl+Vを使えばいいだけの話です。また、マウスの範囲指定選択時にエディタ画面の上部または下部にマウスを持っていてもエディタ画面がその方向にスクロールしてくれないので一画面以上のソースコードを選択するときは矢印キーを使うのですが、まったくそれで問題がないのです。ただ、そのことはチュートリアルのどこかに書いておくと親切ではあるかとは思います。

# 並行処理関連が手付かずである

この問題はプログラミング言語に２つの選択肢をせまることになります。OSと同等の機能を提供するか、OSとは全く異なる強力な並行処理機構を実装するかの２択です。しかし、強力な並行処理機構を実装すればKuinのファイルサイズは大幅に増大し、実行速度も低下することでしょう。したがって、この問題に対してはOSと同等の並行処理機能を実装することにとどまるのがよろしいかと思います。

# MacOS, Linuxとの互換性

これについては、「無理」としか言いようがありません。Kuin言語をオワコンにするという解しかないのです。しかし他の言語はWindows, MacOS, Linuxの３つに対応しています。これはどうしてなのでしょうか。.net FrameworkやQt, Unityについていえば、企業努力としか言いようがありません。あれはKuin言語の1000～100000倍くらいのマンパワーをかけて行っているものです。

では、Rubyなどその他の言語はどうしているかというと、MinGWというライブラリを使って、LinuxバイナリをWindowsで動かしているのです。つまり、Windowsの機能を使いたければMinGW経由でなければ操作できないのです。だけどKuinはWindowsの機能を100%引き出したい、というか、MinGWを使わずVisual StudioでビルドされているのでKuinがWindowsで快適に動作するというところがあるのです。

だから、KuinがMacOS, Linuxで動くことは期待しないでください。または、くいなちゃんが機転を利かせてDirectXベースのウィンドウシステムをオワコンにしてOpenGLでやりなおすかもしれません。または、多重管理（という本当の闇）。

もう一度言います。KuinがMacOS, Linuxで動くことは期待しないでください。

# まとめ

Kuin言語に欠落しているのは、パッケージ管理システムです。これさえあればKuinはHSPを凌駕することができるでしょう。
"GO GLOBAL" meetup #1 に行ってきた

先日["GO GLOBAL" meetup #1](https://go-global.connpass.com/event/108021/)というイベントに参加してきました。

#### "GO GLOBAL" meetup とは
>海外での活動や海外のエンジニア文化に興味のあるエンジニアが集まり、知見の共有や交流を目的としたコミュニティです。海外の話を参加者の間で積極的に共有し、日本のテック業界が世界に躍進するのを後押しする存在となることを目標にしております。

今回が第1回ということなので、今後も継続的に開催されていくのだと思われます。
第1回のテーマは、**「エンジニアのためのコーディング面接・オンラインテスト勉強会」**でした。企業側、応募者側双方の話が聞けて有益な時間でした。

LTなどの詳細は[こちら](https://go-global.connpass.com/event/108021/)を見ていただくとして、印象に残った話や学びなどを書いていきます。


# 技術課題の話(企業側)
やり方はいろいろあるそうなのでそれぞれ書きます。

## 課題を出す
- 課題を解決するコードを期限内に提出してもらう
    - アプリ作成、ML、セキュリティ
- Pros
    - 非同期的なので、限られた時間＆対面よりもプレッシャーが低い
    - 好きな環境(IDE/エディタ)で書ける
- Cons
    - 非同期的なので、どういった志向をたどったアウトプットなのか把握し辛い
    - 課題の自由度が高すぎると評価に時間がかかる

## コーディング試験
コーディング試験について

- コンピュータサイエンスの基本理解度を見るために行う
- コードテストだけで実力を測ることは不可能であり、真の実力は面接で確認することが必須
- 採用プロセスは「書類選考+コードテスト→面接」が多い

### Codility
スマートニュース社では[Codility](https://www.codility.com/)というコーディング試験サービスを利用している。

- コーディングプロセスが見える
- 自動採点
- デモテストがある
- 人事が見るためのレポートもある(例：https://app.codility.com/public-report-detail/)

ちなみに運用実績は

- 期間：4年以上
- 平均スコア：相当低い
    - 満点：3.1%
    - ゼロ点：16.7%

チートしちゃうと…

- similarity checkがあり、過去のコードと似ていたら人事にメールが飛ぶ
- あやしいなと思ったら面接でコードの中身について話を聞いている


### truck
リクルートテクノロジーズ社では、インターン生の選考に[truck](https://tracks.run/)を利用している。

課題の内容は

- DB操作
- HTTP API送信・受信
- アルゴリズム問題

全部回答するのに2-3時間はかかるが、これはある程度実力だけじゃなくて、入社意欲も見れる
技術力 + モチベーションが大事。


trackのいいところ
=> 解けても解けなくても自由にアピールができる

だめなところ
=> エディタが使いにくい


なので点数だけを見てフィルタはしない。面接時の参考値にする。


# 技術課題の話(応募者側)
## コーディング試験
- 1つのスキルである＝練習すればできるようになる
- 通常の業務では鍛えられないスキル
- [Cracking the Coding Interview](https://www.amazon.co.jp/dp/0984782850)という本を参考にしている企業は多い

## ホワイトボード試験
面接官の前で、ホワイトボードにコードを書いていく。

- on site面接だと大抵ホワイトボードの試験がある
- 人前で書くのつらい
- コーディング+ホワイトボードに書くスキルが必要
- 静的型付け言語よりも動的型付けの方が楽(書く量が少ない)
- 練習が大事


# 書籍・サービスなど
言及されていたものはこちら。

## 企業側
- [Codility](https://www.codility.com/)
    - コーディング試験・採点自動化サービス
- [truck](https://tracks.run/)
    - コーディング試験・採点自動化サービス

## 応募者側
- Cracking the Coding Interview: 189 Programming Questions and Solutions
    - コーディング試験問題集
    - 英語　https://www.amazon.co.jp/dp/0984782850
    - 日本語 https://www.amazon.co.jp/dp/4839960100
- [HackerRank](https://www.hackerrank.com/)
    - 英語でコーディング試験の練習ができるサービス
- [LeetCode](https://leetcode.com/)
    - 英語でコーディング試験の練習ができるサービス
    - GAFAなどの選考で実際に使用された問題などもある
- [Pramp](https://www.pramp.com/)
    - オンラインコーディング面接の練習が英語でできる
    - 世界中の求職者とマッチングしてそれぞれ面接官・応募者となって疑似コーディング試験を行う
AVAssetTrackの向き判定を調べたのでメモ（画面録画も）

画面録画機能も増えて、動画の向き判定がさらに増えたのでメモ。

`AVMutableVideoCompositionLayerInstruction`の`setCropRectangle`で切り出す時とか考慮が必要なのでご参考にどうぞ。


```swift
extension AVAssetTrack {
    ///
    // MARK: ------------------------------ properties
    ///
    /// 動画の向き確認
    ///
    var type: String {
        if 0 < self.preferredTransform.b && self.preferredTransform.c < 0 && self.preferredTransform.tx == self.naturalSize.height {
            return "ホーム下 or フロントホーム下"
        }
        if self.preferredTransform.b < 0 && 0 < self.preferredTransform.c && self.preferredTransform.ty == self.naturalSize.width {
            return "ホーム上 or フロントホーム上"
        }
        if 0 < self.preferredTransform.a && 0 < self.preferredTransform.d && self.preferredTransform.tx == 0 && self.preferredTransform.ty == 0 {
            return "ホーム右 or フロントホーム左 or 画面録画ホーム下"
        }
        if self.preferredTransform.a < 0 && self.preferredTransform.d < 0 && self.preferredTransform.tx == self.naturalSize.width && self.preferredTransform.ty == self.naturalSize.height {
            return "ホーム左 or フロントホーム右"
        }
        if self.preferredTransform.a < 0 && self.preferredTransform.d < 0 && self.preferredTransform.tx == 0 && self.preferredTransform.ty == 0 {
            return "画面録画ホーム上"
        }
        if self.preferredTransform.b < 0 && 0 < self.preferredTransform.c && self.preferredTransform.tx == 0 && self.preferredTransform.ty == 0 {
            return "画面録画ホーム右"
        }
        if 0 < self.preferredTransform.b && self.preferredTransform.c < 0 && self.preferredTransform.tx == 0 && self.preferredTransform.ty == 0 {
            return "画面録画ホーム左"
        }
        return "不明"
    }
}
```

2つの動画を同時に再生できるiOS（iPhone／iPad）アプリ「MultiVideo」でも、上記分岐処理を利用して動画切り取り処理を実装しています😄
[MultiVideo - ２つの動画を重ねて並べて再生 -](https://itunes.apple.com/jp/app/multivideo-%EF%BC%92%E3%81%A4%E3%81%AE%E5%8B%95%E7%94%BB%E3%82%92%E9%87%8D%E3%81%AD%E3%81%A6%E4%B8%A6%E3%81%B9%E3%81%A6%E5%86%8D%E7%94%9F/id651397153?mt=8)
Object detection実装：image processing utility実装

[作業レポジトリ](https://github.com/festa78/objdet-tf)

前回までは、bounding box処理に必要なutilityを実装してきた。

今回の[コミット](https://github.com/festa78/objdet-tf/commit/a75ff65bb46ad51627e48f6a56ffa1c5067dc92b)では一般的な訓練データの拡張機能を実装する。
特に、ランダムな画像の左右フリッピング、ランダムなクロッピング、画像のリサイズ機能を実装した。
これらは、画像とそのラベル（bounding boxとclass）のペアを同時に処理できる。
またこれらはtf.dataset.mapに組み込んで使える事を想定している。
ksnctf 2 Easy Cipher 50pt

#問題

http://ksnctf.sweetduet.info/problem/2

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/2f46d6f8-0aed-5f94-a208-135d4c58d568.png)

#解いてみた

- 文字が暗号化されている風です。
- それぞれスペースが入っているので英単語単位で区切られているっぽいですね。
- 「vf n」が「is a」っぽいです。
- 文字数見てみると13文字ずれているのでROT13ぽいです。
- 全文ROT13やってみましょう。
- CyberChef https://gchq.github.io/CyberChef/ 使います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/6e95bb08-da86-29e7-7f11-6382fbb9e99b.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/fd137578-8dc4-350e-3a5d-8cd8b8f8b053.png)
ksnctf 1 Test Problem 1pt

#問題

http://ksnctf.sweetduet.info/problem/1

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/1e4a6df0-78a2-3424-c2e6-8d3a0586a47a.png)

#解いてみた

- この問題はテストなので書いてある文字列をそのまま入力すれば良いです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/cfdb4fc9-cd0b-bbe4-8ee3-ab83862a8d86.png)
個人的によく忘れがちな Ruby イディオム Tips

[Ruby Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ruby "Ruby Advent Calendar 2018")の 2 日目です。

「何かすごいテクいことを書かなくちゃ！」と気負っていたのですが、もともと Advent Calendar は[「5分で書けるようなTipsをやりとりするイベント」として行われていた](https://yhara.jp/2016/12/01/history-adcal-jp "日本における技術系アドベントカレンダーの歴史")らしいので、これにあやかってハードルを下げることに従事したいと思います。

# きっかけ

もともと C や Java を使う仕事に就いていたのですが、転職を機に Ruby を触るようになって早数年。未だにコードレビューで指摘される個人的に忘れがちな Ruby イディオムを Tips として残そうと思いました。

# 個人的によく指摘をうけるイディオム

## ||=

nil チェックと代入を一緒にやってくれる操作。

```ruby
x ||= 1
```

自分はよくこう書いてしまいます。

```ruby
x = 1 if x.nil?
```

この後置 if も慣れない人にはこう書くと分かりやすいかと思います。

```ruby
if x.nil?
  x = 1
end
```

`x ||= 1` は `x || (x = 1)` と同義なのですが、nil チェックを明示的に書く癖が未だに抜けません。毎度毎度「Ruby っぽくないなぁ〜」というような指摘を受けます。

## File.open

ファイルの読み書きをする際の操作。

```ruby
File.open(filepath, 'w') do |f|
  f.write("hoge")
end
```

こう書いてしまう場合があります。

```ruby
f = File.open(filepath, 'w')
f.write("hoge")
f.close
```

malloc/free 同様、メモリー領域を確保したら最後に解放しなければならないのは当然なのですが、ブロックを使えば明示的に `close` しなくても解放してくれますよ、というもの。主にコピペしたコードの自己レビューで見落としてしまうことが多いです。

## private の適用範囲

「private を宣言したクラス内のみで利用可能」と勘違いする Java 脳です。

実際には継承先にも使うことは可能です。ただし、クラスメソッドの場合は同一クラスでも private なインスタンスメソッドを呼び出すことが出来ません（レシーバー経由での　private メソッドアクセスが言語仕様として認められていないため）。

これもついつい「継承先で使うから」と public に定義し、後々「private でいいじゃん！」とレビューで指摘受けることが多いです。

# 指摘されないけど Ruby っぽくないと思われているんじゃないかと勝手に思い込んでいるイディオム

## 範囲指定表記

```ruby
if x > 0 && x < 10
  # 何かの処理
end
```

自分はこう書きます。

```ruby
if 0 < x && x < 10
  # 何かの処理
end
```

宗教論争を巻き起こしそうな話ではありますが、「ローカル変数との比較の際、『ローカル変数 op 値』とする方が Ruby っぽい」というもの。（元ネタを探したが見つからず。るびまだった気がするが…）

それに対し、自分のコードは数学の数直線に則ったもの。以前の職場で「この方が可読性高いんだ！」という理念のもと、この記述がその職場でのコーディング規約に記載されていたので体に染み付いています。

# 結局…

「Ruby っぽさ」とはどういうものなんでしょう？Ruby 歴が浅い自分からすると未だによく分からず、これからも先理解できるものなのかもよく分かりません。「こういう方言（言語仕様）なんだ」とすんなり受け入れられるものもあれば、「複数の表現方法があるが、Ruby 固有の表記を良とする」と言われているようなものもあったりするので、個人的にさじ加減が難しく感じます。

プロダクトでは「誰でも（≒Ruby を知らずとも）メンテできる読みやすいコード」が良いのではないかと思う反面、「エレガントな　Ruby のコードを書きたいなぁ」という個人的な願望が出てきたりします。「コード量を減らす記述が必ずしも良なのか？」ということに日々悩みながら今後もコードを書いていくと思います。
8946 Take#１９

#問題

http://www.hackerschool.jp/hack/take19.php

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/fa0e17f2-1cc6-b140-0032-48d7ba046b0a.png)

#解いてみた

- 「送信ボタンを押した先のphpがこういうソースコードになってますよ」ということですよね。
- 必要なパラメータは以下です。
    - id＝1
    - id2=99
    - input_id=abcd
    - ymd=date('Y/m/d')
    - pass="whitehackerz"をROT13したもの
- いくつか先にやっておかなくてはいけないことがあります。
- 1つめ。
    - date('Y/m/d')は今日の日付ということだと思いますが、2018/12/2なのか2018/12/02なのかわかりません。
    - いろいろ調べてみると2018/12/02のようです。
    - まぁ一発で当てる必要はないので、違ったらもう一つをやってみればいいでしょう。
- 2つめ。
    - whitehackerzをROT13しておく。
    - CyberChef https://gchq.github.io/CyberChef/ 使います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/56593a11-d205-f559-ee05-9c6b38c043c9.png)

- これで準備は整ったので、それぞれパラメータに追加です。
- F12使ってさくっと追加しましょう。
- ちなみにGETとPOSTの2種類あるのでそこは注意が必要です。
- GETのものはSubmitされるURLの後ろにつけます。
- POSTはパラメータ追加すればいいでしょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/40c0485b-cc32-9ba1-dfac-09979210a6fd.png)


- こんな感じで。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/bc6f3234-302f-c767-b9c8-a2b6ddcf6d57.png)
発表会の投票の順位計算を1瞬で終えるSQL



こんにちは。
ジーズアカデミーでスタッフをさせていただいております木村です。
遅くなりすみません(> <)

今回は、去年書いた記事「 [GoogleフォームとGoogle Apps Scriptで課題提出期限を過ぎた人に煽りメールが来るスクリプト](https://qiita.com/yoshoo/items/57f11fdfcee137be9807)」に引き続き、学校で日々行われている身近な業務の課題をテクノロジーの力で解決していきたいと思います。

# 今回のテーマ

Global Geek Auditionという卒業制作の発表会をテーマにしたいと思います。
[動画](https://www.youtube.com/embed/4dK3A0Hnodc)にある通り毎回100名を超える投資家、採用担当者が集まり、数々の投資、採用実績があります。

ルールはオーディエンスの企業が(約100人)すべての登壇者に５段階でサービス点、テクノロジー点を投票します。
1に近づくにつれて高い評価で、点数の平均が１番低い人が優勝という形です。

毎回の登壇者が20人前後、オーディエンスの企業は毎回約100人程度参加して頂いております。

実際の投票フォーム画面はこちら。

[]()
<img width="394" alt="Screen Shot 2018-12-02 at 1.08.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/135287/5e44c84d-159c-8c9c-916a-6d9d0c54f55f.png">

上記の通り、企業No,プレゼンターNo,サービス点、技術点、アドバイス、個別の話希望チェックという形です。
(個別の話にチェックすると追加の項目が表示されて、会社名を入力できるという裏機能もあり)

# 背景


結果を発表する用で毎回csvデータにダウンロードした後はフィルターをかけて一人一人の平均を集計するのに時間がかかってしまっていました。

「csvをSQLに変換すれば、ランキングを1瞬で表示できれば他の分析に時間をかけられるようになるのでは？」
と思い致り、今回のテーマを選びました。

(LAB5の鵜飼さんに多大なるご協力を頂きました。ありがとうございました！！)

# 要件

`gga_pollsテーブル`

id  (int)
company_id(int) 
presenter_no  (int)
service (int)
techlogy (int)
advice (VARCHAR)
is_want_talk (BOOL)
company_name (VARCHAR)

アプローチは以下の３つです。

①それぞれのpresenterのレコードの平均を「total_score」を出す

②GROUP BYを使って個別にすべての登壇者idの合計点の平均値を出す

③合計点が少ないスコアの順番に並べる

①については、

``SELECT id, `presenter_no`, (`techlogy` + `service`) / 2 AS avg FROM gga_polls;
``
こちらでいけそうです。

②については、先程のSQLを使った表示された結果を使って、SQL文を入れ子にするサブクエリを使います。
``SELECT `presenter_no`, AVG(avg) AS total_score FROM ( SELECT id, `presenter_no`, (`techlogy` + `service`) / 2 AS avg FROM gga_polls ) AS test_table GROUP BY `presenter_no` ``

③については 
``ORDER BY total_score ASC``
``
ですね。


これを組み合わせ、、

```SELECT `presenter_no`, AVG(avg) 
    AS total_score FROM 
( SELECT id, `presenter_no`, (`techlogy` + `service`) / 2 AS avg FROM gga_polls )
AS test_table 
GROUP BY `presenter_no` 
ORDER BY total_score ASC```

取れました！！！！

<img width="408" alt="Screen Shot 2018-12-02 at 8.48.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/135287/cddceb81-f207-a430-cf04-f162de770d50.png">


途中、「導出表には別名が必須です」のようなエラーが出たのですが、こちらはAS句が抜けていることによるエラーでした。

参考記事はこちら
http://blog.kimuradb.com/?eid=636543
https://teratail.com/questions/1433

ぜひ近くのGGAの集計に困っている方がいらっしゃったらこの記事を共有してみてください(^^)


次はLABの田中さんです！
よろしくお願い致します！