OmniAICreator/Qiita-1.07M huggingface dataset:
[Java]JDKのコンパイラのバグを踏む

## たぶん踏んだやつ

**[JDK-8143647]** [Javac compiles method reference that allows results in an IllegalAccessError](https://bugs.openjdk.java.net/browse/JDK-8143647)

~~※後述のとおり、OpenJDK ではなく **Oracle JDK** で起きた事象なので、同じバグかどうかは正直微妙なところ。。。~~

#### 追記
Oracle JDK の Bug Database にも、同じ Issue がありました。
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8143647

## 起きたこと

Solaris 上の **Oracle JDK 8u92** でコンパイルしたクラスが、なぜか実行時に `IllegalAccessError` で落ちてしまう。

同じソースを Windows 7 (x64) 上の Eclipse Mars 2 (4.5.2) でコンパイルしたクラスだとちゃんと動く。。。

`javap -c` でバイトコードを覗いてみると、**メソッド参照** を使っている箇所が、ソースコード上の具象クラスではなく、その親クラスである不可視（`package private`）な抽象クラスに置き換わっていた。

上記の issue の再現手順は以下の通り。

```
1) Create default-scoped abstract class with concrete method
2) Create a concrete public class extending the above class in the same package
3) Use a method reference to this inherited method in a class outside of the package 
```

対して、問題の起きたクラスとメソッド参照先のクラスを簡略化したソースは、

```java:simplification
package inner;
abstract class AbstractHoge {
    public String getSomething() {
        ...
    }
}

package inner;
public class Hoge extends AbstractHoge {
}

package outer;
import inner.Hoge;
...
public class Fuga {
    public void doSomething(List<Hoge> list) {
        Map<String, List<Hoge>> map = 
            list.stream().collect(Collectors.groupingBy(Hoge::getSomething));
        ...
    }
}
```

といった感じで、見事に発動条件を満たしてしまっている。。。

## 解決策

上記の issue だと、`8u102` だか `8u111` あたりでバックポート済みのようなので、それより新しいバージョンの Oracle JDK にアップデートする。
⇒実際に **Oracle JDK 8u161** でコンパイルしたクラスでは問題が解消していた。

※何らかの制約があって JDK をアップデートができない場合は、抽象クラスのスコープを `public` に変更することで暫定的に回避可能。
プリプロセッサの代わりにConditionalAttributeを使う

　Unityの環境別プログラミングに便利そうなConditionalAttributeを使ってみました。Editor上のみで使う関数、Androidのみで使う関数、といった記述をスマートに行えます。
参考：http://d.hatena.ne.jp/nakamura001/20151202/1449029637

# 長所1 プリプロセッサよりも可読性が高い
　プリプロセッサを使ったサンプルコードと、ConditionalAttributeを使ったサンプルコードを比べてみましょう。まず、プリプロセッサを使った場合。

```csharp
using UnityEngine;

public class TestPreprocessor : MonoBehaviour
{
	void Start ()
	{
#if UNITY_ANDROID
		TestAndroid();
#endif
#if UNITY_WEBGL
		TestWebgl();
#endif
#if UNITY_EDITOR
		TestEditor();
#endif
	}

#if UNITY_ANDROID
	void TestAndroid()
	{
		Debug.Log("Android");
	}
#endif

#if UNITY_WEBGL
	void TestWebgl()
	{
		Debug.Log("WebGL");
	}
#endif

#if UNITY_EDITOR
	void TestEditor()
	{
		Debug.Log("Editor");
	}
#endif
}
```

　単純な記述なのでまだ読めます。しかし、長大な処理になると、終点のendifが見当たらないまま読むことになったりして快適さはかなり損なわれます。続いて、ConditionalAttributeを使った場合。

```csharp
using UnityEngine;

public class TestConditional : MonoBehaviour
{
	void Start ()
	{
		TestAndroid();
		TestWebgl();
		TestEditor();
	}

	[System.Diagnostics.Conditional("UNITY_ANDROID")]
	void TestAndroid()
	{
		Debug.Log("Android");
	}

	[System.Diagnostics.Conditional("UNITY_WEBGL")]
	void TestWebgl()
	{
		Debug.Log("WebGL");
	}

	[System.Diagnostics.Conditional("UNITY_EDITOR")]
	void TestEditor()
	{
		Debug.Log("Editor");
	}
}
```

　かなりスッキリしたのではないでしょうか。呼び出し元に分岐条件を書く必要が無いので記述も楽です。ただ、分岐記述が無い分、特定環境下でしか呼ばれないことがわかりにくいので、ちょっとコメントを追加する必要があるかな、と思います。

# 長所2 プリプロセッサで引き起こされるコンパイルエラーが無い
　Editorのみで使う関数をプリプロセッサで囲い忘れてコンパイルエラー、というのはプリプロセッサを使ってたら一度は遭遇すると思います。GitのメインブランチにMergeした後にCIツールがコンパイルエラーで動かなくなって気まずい思いをしたことが自分はあります。ConditionalAttributeでは前述のように呼び出し元については自動でSkipされるので、その心配はありません。

# 短所1 if not的な記述をできない
　iOS以外、Editor以外、みたいな記述はできないようです。プリプロセッサはelse節があるので可能です。
参考： https://stackoverflow.com/questions/8230191/c-sharp-conditional-attribute

# 短所2 通常MethodとAttributeクラスにしか使えない
　interfaceに対しては使えません。Constructor、Destructor、Operator、interface指定Methodにも使えません。interfaceに使えれば、Editor上でしか使わないinterfaceを用意して色々できそうだったのですが残念です。
Rails+Devise+Pundit 多対多実装の備忘録

初心者による、Railsの認可GemであるPunditの備忘録です。

## 導入
インストールします。

```ruby
gem "pundit"
```

application_controllerにincludeしときます。

```ruby:application_controller.rb
class ApplicationController < ActionController::Base
  include Pundit

end
```

Punditで使うファイルを生成します。

```
$ rails g pundit:install
```
これで app/policies/application_policy.rbができます。ほぼ準備完了です。


## 概要
Punditとはご存知の通り、リソースベースで認可の仕組みを提供します。

私は多対多の関係をうまく動作させるのに利用させていただきました。
以下、拙いですが勘弁してください。
ユーザは複数のプロジェクトに参加し、プロジェクトは複数のユーザに参加されるというのを中間テーブルを利用し実現します。

ユーザ 1-* プロジェクト参加ユーザ *-1 プロジェクト

のようなイメージです。

例えば、「プロジェクトの詳細ページはプロジェクトに参加しているユーザしか閲覧することができない」という要件があったとします。
きっとProjectコントローラのshowメソッドらへんでうまいことやれば良いのでしょうね。
Punditではこれをコントローラとポリシーファイルで制御します。

```ruby:projects_controller.rb
class ProjectsController < ApplicationController

  def show
    @project = Project.find(params[:id])
    authorize @project
  end

end

```

```ruby:project_policy.rb
class ProjectPolicy < ApplicationPolicy

  def show?
    !!@record.users.find_by(id: @user.id)
  end

end
```

上記コードの動作はこんな感じです。

1. projects_controllerのshowが呼ばれる
2. show内で引数@projectを渡してauthorizeメソッドを呼ぶ
3. 自動的にproject_policyのshow?メソッドが呼ばれる
4. 検証を行い、boolを返す
5. falseだった場合、NotAuthorizedErrorが発生する


## 動作

autorizeメソッドは```authorize(user, record, query)```と定義されていますが、上記コードでは@projectのみ渡しています。userには暗黙でcurrent_userが渡されているので渡さなくて大丈夫です。
queryには、policy内で呼びたいメソッドを指定する時のみシンボルを指定しますが、詳しくは[github](https://github.com/varvet/pundit)を参照してください。
これらはそれぞれ@user, @recordに入ります。

今回はprojectモデルに関連した認可を扱いたいので、application_policyを継承したproject_policyを作成しました。
ここに「どんな時そのコントローラのメソッド実行を許可するのか」ということを定義します。


```ruby:project_policy.rb
class ProjectPolicy < ApplicationPolicy

  def show?
    !!@record.users.find_by(id: @user.id)
  end

end
```

あとは先述の通りです。project_controller#showのauthorize(@project)は自動的にproject_policyのshow?メソッドを呼びます。show?では、渡された@record(=@project)と@user(=current_user)を用いて検証を行います。
上記コードではcurrent_userが@projectに(中間テーブルを通して)ひもづくユーザかどうか検索し、存在すればtrueを返します。つまり、プロジェクト参加者かどうか検証しているわけです。

## 検証失敗時

もし参加者でないユーザがプロジェクトをみようとしたら、falseが返ります。
するとauthorizeはNotAuthorizedErrorを投げます。拾いましょう。

```ruby:application_controller.rb
class ApplicationController < ActionController::Base
  include Pundit

  rescue_from NotAuthorizedError, with: :render_404

  def render_404(exception = nil)
    if exception
      logger.info "Rendering 404 with exception: #{exception.message}"
    end

    render file: "#{Rails.root}/public/404.html", status: 404, content_type: 'text/html'
  end

end

```

404に飛ぶようにしました。
(参考)
[るびま http://magazine.rubyist.net/articles/0047/0047-IntroductionToPundit.html](http://magazine.rubyist.net/articles/0047/0047-IntroductionToPundit.html)


## おしまい
本当にざっくりとこんな感じです。書き間違いとか追記したいこととかあったらまた書きます。
参考URLもあとで載せます。
karabiner-element, 英かな。どちらもうまく動作しない？

#問題発生
macbookProのusキーを使っています。日本語入力をスムーズに行うためにkarabiner等を試してみたのですが、うまく動作してくれませんでした。
preferenceもしっかり設定したのになんででしょう。。。。

#解決
1. 「システム環境設定」から「キーボード」、「入力ソース」と進む。
2. 左下の＋マークを押して、「日本語」を追加したら、解決しました。
Sphero miniをRaspberry pi ZERO Wで操作する　～導入編～

#はじめに

Sphero miniをRaspberry pi ZERO W(3でも同じだと思います）で動作させる方法について簡単にまとめておきます。

Spheroを制御するライブラリは公式、公式以外でも探せばいろいろとでてきますが、製品ごとに制御が若干異なるようで、すべてが新し目の製品であるminiに対応しているようではなさそうです。
※ちゃんと調べてないので憶測レベル

今回は、以下のGitリポジトリのもので動作することが確認できました。

https://github.com/igbopie/spherov2.js

#準備

OSは、RASPBIAN STRETCHです。念のため、apt-get upgradeで最新化しておきました。

Node.jsのバージョンは8.10を使用しています。
デフォルトは割と古め（v4.8.xあたり）だと思うので、以下の記事等を参考に更新しておくのがいいかと思います。

- [Raspberry PiにNode.jsとnpmの最新版をインストールする](https://qiita.com/mascii/items/77c685df65c4cbca9315)

あと、gitもインストールしておきます。

#準備　その２

次に、パッケージマネージャとして[yarn](https://yarnpkg.com/ja/)を使うので、インストールしておく必要があります。

その際ですが、そのまま`sudo apt-get install yarn`とかすると、cmdtestがインストールされちゃってお目当てのyarnがインストールされないので、[yarnの公式サイトにあるinstall方法](https://yarnpkg.com/lang/en/docs/install/#debian-stable)に従ってリポジトリを設定してからインストールします。

また、この後`yarn install`で依存パッケージを取得・設定(コンパイル）することになるのですが、このままだとエラーになります。
そのエラーを回避する為に必要な以下のパッケージを先にインストールしておきます。

- libudev-dev
- libusb-1.0-0-dev

インストールは普通にapt-getでできます。

```
$ sudo apt-get install libudev-dev libusb-1.0-0-dev
```

#リポジトリの取得とインストール

ここまでくれば、Gitリポジトリを取得してyarn installすれば完了です。

```
git clone https://github.com/igbopie/spherov2.js
cd sphero2.js
yarn install
```

Gitリポジトリにはいくつかのサンプルがあるので、

```
cd sphero2.js
yarn patrol-sm
```

という感じで実行すると、Sphero miniが充電されていれば、そのままつながって動き始めます。

以上となります。

#補足
今回実際にあったのですが、Raspberry pi ZERO WのBluetoothがハード的に故障していたようで、Bluetoothデバイス(hci0)としてはアクティブ(up)になるのですが、BLEのビーコンを拾わないという現象に出会いました。Raspberry pi ZERO Wを複数もっていて、SDを入れ替えることで動作したため、そのことがわかったのですが、その解析で時間を奪われてしまいました。

正しく動作している場合は、hcitoolでBLEのビーコンをスキャンすれば、SM-C741のアドバタイズを拾うので、それで確認できますので、ご参考まで。

```
$ sudo hcitool lescan
LE Scan ...

・・・
XX:XX:XX:XX:XX:XX SM-C741
・・・
```
【Unity】カメラから見えなくなったときの判定方法

VRやってるときに見えなくなっているときの判定が気になった。
なので、調べたら意外と簡単だったので書いてみた。

# 環境
Unity2017.1.0f3

# 書き方

レンダラー(カメラ)から
`OnBecameVisible()`見えた瞬間
`OnBecameInvisible()`見えなくなった瞬間
`OnWillRenderObject()`見えている時(`Camera.current.name`でカメラのオブジェクト名を取得できる)
で判定することができる。

いずれもSceneViewでも判定されてしまうため、SceneViewで確認したければ
`OnWillRenderObject()`を使って`Camera.current.name`から"SceneCamera"を判定外にする必要があるようだ。[^1]

判定側にはRendererがアタッチされていないと判定されないみたいだ。[^2]

# 例

`OnBecameInvisible()`を使った例

```csharp:LoockChange.cs

using UnityEngine;

public class LookChange : MonoBehaviour {  //MonoBehaviourは呼ばれていないといけない

  private bool flag = false;

  void OnBecameInvisible()  // カメラから見えなくなった時
  {
    if(flag==true)  // 偶数回に見えなくなったときの処理
    {
      
    }
    else  // 最初、奇数回に見えなくなったときの処理
    {
      
    }
    flag = !flag;
  }
}
```

例えばカメラから見えなくなる度に色を変える場合は

```csharp:LoockChange.cs

using UnityEngine;

public class LookChange : MonoBehaviour {

  private bool fMaterial = false;
  [SerializeField]
  private Material mat01;
  [SerializeField]
  private Material mat02;

  void OnBecameInvisible()
  {
    if(fMaterial==true)
    {
      this.GetComponent<Renderer>().material=mat01;
    }
    else
    {
      this.GetComponent<Renderer>().material=mat02;
    }
    fMaterial = !fMaterial;
  }
}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/46612/4b374bc0-1605-c8b3-bc06-125897391796.png)

とすると見えなくなる度にオブジェクトの色が変わる。


### 参考
[^1]: [カメラに写っている間のみ処理を行う \- テラシュールブログ](http://tsubakit1.hateblo.jp/entry/20131007/1381156232)

[^2]: [【Unity】オブジェクトがカメラに写っているかと注意点 \- ヘチマのノート](http://hetima333.hatenablog.com/entry/2017/02/13/161150)
ロリポップ！にNextcloudをインストール

##概要
ほんの数時間前、[【Raspberry Pi】ownCloudのインストール](https://qiita.com/sunaga70/items/558d9dfd11b809934666)という記事を書いたばかりですが、レンタルサーバのロリポップ！にもインストール可能なことが判明。
どうせなら、ownCloudじゃなくNextcloudのほうをインストールしてみました。

##参考にしたサイト
[LolipopにNextcloudをインストールした話](https://you-and-me.xyz/study/nextcloud-install.html)

##手順
笑っちゃうほど簡単でした。参考サイトそのままです。

- [NextcloudのWebsite](https://nextcloud.com/)のダウンロードページから[Web Installer](https://download.nextcloud.com/server/installer/setup-nextcloud.php)をダウンロードします。
- Web Installer（setup-nextcloud.php）を任意の場所（例：nextcloudフォルダ）にアップロードします。
- ブラウザでWeb Installer（例：http://xxx.xxx.xxx/nextcloud/setup-nextcloud.php ）にアクセスします。
- 画面の指示に従ってください（スクショ取ってないです。ごめんなさい）。

以上です。

ラズパイ＋ownCloudは試行錯誤したけど、ロリポ＋Nextcloudは10分もかからないで構築完了です。
しかも、ロリポ＋Nextcloudのほうがサクサク動いてる感がある。
ルーターの穴あけもいらないし、SSLも簡単に使えるし、空き容量も48GBくらいあるのでこれで十分かな？
recpt1の更新-2-

## 背景
4k, 8k 放送開始に関連して、BS放送の再編が始まっている。録画サーバを自前で立てている場合には、設定変更が必要だ。無料放送についてはBSジャパン(BS171)とBSプレミアム(BS103)が対象になる。各種パラメタが変更された([総務省によるイメージ図](http://www.soumu.go.jp/main_content/000487868.pdf#page=5))。

## recpt1 を利用している場合
Linux で recpt1 を利用している場合には、BSプレミアム・BSジャパンに対するパッチがメインテナーの方から提供されているので、ありがたく、これを利用する。
http://hg.honeyplanet.jp/pt1/
【SQL】関数（四捨五入・切り捨て/現在の日時/データ型変換）


##指定桁で四捨五入
###ROUND関数を使います。

```sql
round(数値格納カラムB, 有効とする桁数)
```

☆有効とする桁数
・正の場合は、少数桁の数
・負の場合は、整数桁の数

↓イメージ

```sql
//10の位で四捨五入される
select food, round(price, -2)
from foodtable;
```

##指定桁で切り捨て
###TRUNC関数を使います。
```sql
trunc(数値格納カラムB, 有効とする桁数)
```
☆有効とする桁数
・正の場合は、少数桁の数
・負の場合は、整数桁の数

↓イメージ

```sql
//10の位で切り捨てされる
select food, trunc(price, -2)
from foodtable;
```

##指定乗で返す
###POWER関数を使います。
```sql
power(数値格納カラムB, 何乗にするか指定)
```

↓イメージ

```sql
//priceに３乗した数値を返す
select food, power(price, 3)
from foodtable;
```

##現在の日時を記録
###（日付：CURRENT_DATE関数）（　時刻：CURRENT_TIME関数）を使います。

☆現在の日時（CURRENT_DATE）
→YYYY-MM-DD
☆現在の時刻（CURRENT_TIME）
→HH:MM:SS

！！！２つとも、引数の指定不要！！！

↓イメージ

```sql
//現在の日付を登録
insert into foodtable
values (current_date, 'ドーナツ', 300);
```

##データ型変換
###CAST関数を使います。

データ型が違う者同士を演算子で連結したいときなどに使える。

```sql
cast(数値格納カラムB as 変換したいデータ型)
```

↓イメージ

```sql
update foodtable
set price = cast(price as varchar(20)) + '円';
```


以上。
enable_shared_from_this の C++2011(14) と C++2017 との相違点

クラステンプレート ```std::enable_shared_from_this``` とは、```std::shared_ptr``` で所有権を管理している場合、これを継承するとインスタンス自身から ```shared_ptr``` を逆引きすることができる（```shared_from_this()``` メンバ関数を基底クラスに持つ）という便利なテンプレートです。
なぜこのようなものが必要になるのかは、下のオージス総研さんの記事が詳しいです（2009年の記事なので boost ライブラリの説明ですが、内容は後に追加された標準ライブラリにも通用します）。

-  [1. boost::weak_ptrを利用するケース](https://www.ogis-ri.co.jp/otc/hiroba/technical/boost/part1/index.html) 
-  [コラム2. enable_shared_from_this](https://www.ogis-ri.co.jp/otc/hiroba/technical/boost/column/enable_shared_from_this.html)

さて、このテンプレートは C++11 で ```shared_ptr``` と共に追加されたのですが、C++17 で微妙ながら重要な変更があることに気づいたのでご紹介します。

# C++11

```shared_ptr``` を逆引きするという性質上、当然ながら ```shared_ptr``` で所有権を管理されていないインスタンスからは取得することができません。
ここまではいいのですが、C++11 では ```shared_from_this()``` 関数の制約として、```shared_ptr``` で所有権を管理されていることを「必須 (Requirements)」としました。
これが何を意味するかと言うと、```shared_ptr``` で管理されていない場合、```shared_from_this()``` の動作は **未定義動作** であるということです。
それにも関わらず、```enable_shared_from_this``` には、**今現在 ```shared_ptr``` で管理されているかどうかを判別する方法が存在しません**。
この2つから、```enable_shared_from_this``` は少し使い方を誤っただけで**容易に未定義動作を引き起こしうる**という問題が存在しました。

# C++17

これが C++17 で以下のように変わりました。

- ```shared_ptr``` で管理されていることが「必須」ではなくなった
- ```enable_shared_from_this``` に新しいメンバ関数 ```weak_from_this()``` が追加され、さらにメンバ変数 ```std::weak_ptr<T> weak_this``` があることが明示された
- ```shared_ptr``` のコンストラクタで ```enable_shared_from_this::weak_this``` に参照を格納することが明示された
- ```shared_from_this()``` の戻り値は、```weak_this``` を ```shared_ptr``` に変換したものであることが明示された

この仕様変更によって、以下のように状況が変わりました。

- ```weak_from_this()``` の戻り値を使って、今現在 ```shared_ptr``` で管理されているかどうかを判別することができるようになった（```weak_ptr::use_count()``` や ```expired()``` などを使えばよい）
- ```shared_ptr``` で管理されていないインスタンスの ```shared_from_this()``` を呼んだ場合、```std::bad_weak_ptr``` 例外が（未代入の ```weak_ptr``` を ```shared_ptr``` に変換したときに）発生することが保証され、未定義動作ではなくなった

# 結論

C++17 はいいぞ
Visual Studio IntelliCode〜AIの力を借りてサクサク開発？〜

## Visual Studio IntelliCodeって？
2018/5/7に発表された、コーディング支援ソリューションのこと。
補完機能があるIntelliSenseとは何が違うの？というと、**機械学習**を用いているところがミソ。IntelliSenseは記述したコードに沿って候補をリスト化してくれるが、その中でもよく使われる候補がリストの上部に★付きで表示される。GitHubなどの公開されているコードを元に学習しているのだとか。
Preview版ではVisual Studio2017バージョン15.7以上、C#のみサポートしています。

##早速使ってみよう！の前に、バージョン確認。
私はVisual Studio2017 Communityを使用しました。
バージョンは下図のように[ヘルプ]のところから確認しましょう。
![VSversion.png](https://qiita-image-store.s3.amazonaws.com/0/176805/ee3f3a33-5040-dc35-2040-a5566b75e452.png)
アップデートが必要な場合はVisual Studioの右上の:triangular_flag_on_post:通知 を押してアップデート情報を確認しましょう。詳細は以下のURLを参考に。
https://docs.microsoft.com/ja-jp/visualstudio/install/update-visual-studio
（私はなぜかアップデートに40分ほどかかってしまいました。。ご利用は計画的に。）

##いざ。IntelliCodeをダウンロード
Visual Studioの拡張機能を自分で追加したことないな、、と思ったので細かく。
[ツール]から[拡張機能と更新プログラム]を選択
![VStool.png](https://qiita-image-store.s3.amazonaws.com/0/176805/ed82a840-d718-c41a-cab9-ddc3c3a95205.png)
その中で左のメニューから[オンライン]を選択
「intellicode」で検索:mag_right:すると出てきます。
![VSIntelliCode.png](https://qiita-image-store.s3.amazonaws.com/0/176805/c6ceca1b-eabe-cab6-0bd7-33898f58e490.png)
あとはダウンロードしてVisual Studioを再起動すればOK！

##やっとこさ使ってみました。
HttpClientを使ってGetして応答が知りたいなぁ。
![VSsample.png](https://qiita-image-store.s3.amazonaws.com/0/176805/098ea9b6-5c24-1628-b9a7-0284f01debe3.png)
おっ。そうそうそれそれ。っていうのが上位に来てくれました。
Console.ってやったらWriteLineってでてくる感じ。（伝われ。）

##感想
1日使ってみての感想なので、参考にならないかもしれないですが。。
普段使っていてなんで一番下にあるかなぁ、だとかそういうのは解消される気がしました。上の例のようにね。ただ、、公開されているコードを元に学習しているそうですが、逆に言うとあまり学習していないもの（まだ開発している人が少なかったりするもの）に関しては★の候補が出ないんですよね。（Azure関連のメソッドとかとか。）むしろあまりわかっていないことに対してサポートしてほしい！と強く思いました:relieved:

単純に候補を上位に出してくれるだけでなく、コードに対してのアドバイスもくれるそうなので、分かり次第記事を更新できたらと思います。
ubuntuにmysqlをインストール、ユーザ作成＆権限追加するときのメモ

## ubuntuにmysqlをインストール、ユーザ作成＆権限追加するときのメモ
mysql-serverをインストールして、とりあえずrootでログイン。

```
$ sudo apt install mysql-server
$ ...
$ sudo mysql -u root -p
$ ...
```

テキトーなユーザを作成、テキトーなDBを作って権限を与える。

```
mysql> CREATE USER public;
mysql> CREATE DATABASE test;
mysql> GRANT ALL ON test.* TO public;
mysql> EXIT;
```

作ったユーザでログインしなおして、パスワード変更。

```
$ sudo mysql -u public -p
$ ...

mysql> SET PASSWORD = PASSWORD('password');
```
Node.js で Hello World - Visual Studio 2017

#環境
- Windows 7 Professional 64bit
- Visual Studio 2017
- Node.js 8.11.1 (Node.jsのインストール手順は[こちら](https://qiita.com/East_san/items/de66c7d816034ad67ec4)から)

#プロジェクト作成からHello Worldまで
visual studioを起動し下記画像の手順に沿っていく

![ws001.png](https://qiita-image-store.s3.amazonaws.com/0/92978/0d2adabb-8236-b01f-a2d7-c09547d5d678.png)

![ws002.png](https://qiita-image-store.s3.amazonaws.com/0/92978/1d41d17d-3f76-1ba2-af60-9b83bf29cbf5.png)

![ws003.png](https://qiita-image-store.s3.amazonaws.com/0/92978/83e286de-cdba-1437-5000-d8cb85ab84c3.png)

コードは自動で生成されるので、そのまま実行
![ws004.png](https://qiita-image-store.s3.amazonaws.com/0/92978/59072345-f444-c984-7142-a6e758764e0d.png)

無事、Hello Worldが表示されれば完了！
![ws005.png](https://qiita-image-store.s3.amazonaws.com/0/92978/bd550292-6f5f-7d80-6564-541c7542bfdb.png)

とても、簡単。
メール認証で利用する英数文字列をどのように取り扱うか


悩むケースが多いのでメモ。取り敢えず普通にDBに突っ込むほうがよさそう

## なんらかの ストレージ上の Map として実装する方法

Database なり何なりを使って 何らかのMap を代表するキーとしてのトークンを利用する方法。

おそらく一般的でわかりやすい形式だと思う。

ランダムで生成した文字列をトークンとして、それをユーザ情報なりと紐付ける。

```
Data = token(token_str)
```

的な形式のストレージ読み込み関数を作成して、トークンからデータを取得できるようにすれば完成。

トークンをもっている人がユーザデータの適正な持ち主と判断できる。

## 複雑なチェックサムを用いる方法

独自ロジックのチェックサム関数を作成して、ユーザデータから一意の文字列を生成する。

```
checksum(userData,now) = checksum_str
```

now を入れることによってデータは常に変化するように見える。

ユーザは、 checksum_str の他に自分のユーザデータと now を再度提出しなければならない。

checksum_str と userData,now のペアが一致すれば、適正なユーザデータの持ち主と判断できる。

### メリット

- ストレージ構造が不要
- ストレージを用いない分、構造はよりシンプルになるはず
- ユーザは、checksum_str に加え、ユーザ情報と checksum_str 発行時間を提示しないといけない
- 理論上は、オフラインでのトークン発行が可能

### デメリット

- checksum_str の有効期限内にロジックの修正を行った場合、対応が面倒
- 発行されたchecksum_strの総数を知りたい場合、別途対応が必要
- チェックサムロジックが漏れた場合終わり。修正も面倒
Windows 上にある秘密鍵を、WSL 上の git から使うメモ

git で使う秘密鍵を、Windows と WSL で共有するときのメモ。
これをやっておくと、Windows と WSL のそれぞれの git コマンドで、秘密鍵をバラバラに管理しないで済む。

# 前提
秘密鍵は、Windows 上の `C:\Users\<Windowsでのユーザ名>\.ssh\id_rsa` に配置する。
この秘密鍵は、WSL からは `/mnt/c/Users/<Windowsでのユーザ名>/.ssh/id_rsa` として見える。

この秘密鍵を WSL 上の git から参照する。

# git@WSL の設定
ターミナルは bash を使っているので、`.bashrc` に追記。

```sh:.bashrc
# git が使う ssh コマンドの設定
# ここで Windows 上の秘密鍵を指定
export GIT_SSH_COMMAND="ssh -i /mnt/c/Users/<Windowsでのユーザ名>/.ssh/id_rsa"
```
ほぼ、これだけ。

ちなみに、上の設定は `git` コマンドで使う秘密鍵だけを共有する場合で、もし `git` に限らず `ssh` コマンド全般に共有したければ、シンボリック リンクを作った方が楽かも。

## 秘密鍵のパーミッションで怒られた時の呪文
Windows 10 April 2018 Update を適用したタイミングから、秘密鍵のパーミッションで怒られるようになった気が知る。

パーミッションとオーナーを変更するためのコマンド

```sh
# 一度 Windows のボリューム？をアンマウント
$ sudo umount /mnt/c

# パーミッション管理用のメタデータが利用できる形で再マウント
$ sudo mount -t drvfs C: /mnt/c -o metadata

# 秘密鍵のオーナーを設定
$ sudo chown ${USER} /mnt/c/Users/<Windowsでのユーザ名>/.ssh/id_rsa

# 秘密鍵のパーミッションを変更
$ sudo chmod 600 /mnt/c/Users/<Windowsでのユーザ名>/.ssh/id_rsa
```
Progateで学習を続けて半年、初学者の学習を支援するアプリをリリースしました！

Ruby on Railsでアプリをリリースしました。
https://ort.herokuapp.com
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【アプリリリース】<br>学習支援アプリORT.（オルト）、リリースしました！！ポモドーロテクニックを活用し、「タイマーで25分集中し、時間になったら学習内容をメモ」を繰り返すことで爆速で学習効率と生産性を向上させるアプリです！プログラミング学習に是非使ってください！<a href="https://t.co/Jh2LDHkVkc">https://t.co/Jh2LDHkVkc</a> <a href="https://t.co/Vum94gsGb1">pic.twitter.com/Vum94gsGb1</a></p>&mdash; みや (@gifu_w) <a href="https://twitter.com/gifu_w/status/989504383049129986?ref_src=twsrc%5Etfw">2018年4月26日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


ぜひ学習の際に使ってみてください🙏🏻

## どんなアプリ？
- 25分間タイマーをセットし、終了時間になったらその時間で何を学んだかを記録（投稿）するだけのシンプルなアプリです
- 終了時にブラウザ通知が出ます（iOSは非対応です）
- タイマーの時間は5分単位で自由に変えられます
- 投稿には、学習時間・タグ・学習内容を記入できます
- アプリ内の投稿と同時にツイートもできます
- 累計学習時間の表示と、タグでのソートができます


## このアプリの何がいいの？
「25分間集中し、5分休憩するを繰り返す」というポモドーロテクニックを採用しています。
集中力が持続する、自身の作業時間を見積もりやすくなるなど、生産性を高めることができるメソッドです。
さらに1回のポモドーロの内容を終了時にアウトプットすることで、学習内容の整理と定着が期待できます。

つまり、学習習慣の形成にフォーカスを当てたアプリで、短時間の一点集中と細かなアウトプットで学習効率を爆速で上げて行こう！！というストイックなアプリです！

## 何のために作ったのか
プログラミング初学者こそどんどんアウトプットすべきと言われますが、実際のところqiitaやブログを書くのは初学者にとってはハードルが高いように思えます。僕自身技術的な文章をqiitaに書くのはまだ自信がありません…
しかし、アウトプットが学習においてめちゃ大事なのは確かです。思考の整理、外部化だったり、フィードバックを貰えることはモチベーションにも繋がります。もし間違っていたとしてもインターネットの強いエンジニアの方々が優しく指摘してくれる優しい世界です。
まずは小さくてもいい、ツイートでもいい、100文字でもいいからとにかく初学者のアウトプットが増えたらいいなと思ってこのアプリを作りました。


「#インターネット勉強班」でツイートしてるので、みんなで一緒に勉強しようぜ！



## どうやって作ったか
2017年の12月に全くの初心者から勉強を始めて、それからずっとProgateという学習サービスにお世話になっています。Progateがなければ独学じゃ続いていなかったんじゃないかと思えるくらいです…にんじゃわんこありがとう

6割くらいはProgateのカリキュラムで学んだ技術でできています。HTML,CSS,jQuery,Ruby on Railsのコースを終わらせ、Railsのコースで作ったSNSアプリのコードをそのままお借りして、そこから機能を追加する形で作られています。（投稿画面のデザインなどはそのままです）

タイマー機能はJavaScriptで作られており、これはドットインストールのタイマーを作ろうコースで作ったものを改変して作りました。

その他の機能は、こういう機能がほしい！と思ったらその都度ググって実装しました。賛否は分かれるかもしれませんが、できるだけ早くリリースするために、便利なGemやライブラリを多く利用しています。

ActsAsTaggableOn…手軽にタグ機能を実装できる
Devise…手軽にユーザー認証機能を実装できる
Omniauth-twitter…twitterログインができるようになる
Push.js…手軽にブラウザ通知を実装できる

今は初心者が何か作ろうとしたときに、何から何まで揃っている優しい世界です（強調）、みんなとにかく作り始めてみるべき

## 今後について
- タイマーまだ使いづらい

タイマー機能は投稿画面にモーダルで出していて、モーダルを閉じたらタイマー画面に戻れないなどいまいち使いづらい
Vue.jsやReactを勉強して、ページ遷移してもタイマーは常駐するようにしたい


- iOSからの閲覧が6割を占めているのに、iOSはタイマー終了時の通知に非対応

なんとかしたい…
SwiftかReact nativeを勉強して、iOSアプリにしようか検討中



作りたいものがあると、勉強が捗って楽しいですね！！


##最後に
以上です。ORT.、是非使ってみてください！
https://ort.herokuapp.com

アプリの製作過程はできるだけツイートするようにしていて、製作中の1ヶ月間のツイートをまとめました
https://togetter.com/li/1220727

よかったらこちらも読んでください🙏🏻
git reset HEAD^を取り消す方法

通常、addしたファイルを取り消したい時は、git reset HEADでファイルを指定する。

しかし、addしたファイルを戻すつもりが間違って git reset --soft HEAD^をしてしまい、HEADが一つ前に戻ってしまった。

つまり、特に変更点も無いままHEADを一つ前に戻したため、過去の内容が自分のステージングに残ってしまったのである。

```
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   app/assets/stylesheets/test.sass #最新(HEAD)のファイル
	modified:   app/assets/stylesheets/hoge.sass #最新(HEAD)のファイル
	modified:   app/assets/stylesheets/fuga.sass #最新(HEAD)のファイル
    modified:   app/model/sample.rb #ワークツリーに戻すはずだったファイル。。。
```

なので、git resetをなかったことにする必要がある。
ここからは以下のコマンドを打ちましょう。

```
git reflog
```

これを打てば過去のいろんなコミット履歴を見ることができる。

```
2cd8dd2 HEAD@{0}: reset: moving to HEAD^ #pullした最新コミットを取り込んでしまった...
9dacb9a HEAD@{1}: checkout: moving from master to fix_test #このコミット状態に戻したい
9dacb9a HEAD@{2}: checkout: moving from fix_sample to master #masterに移動した
01394a8 HEAD@{3}: commit: 一括表示をconcatで呼べるように変更
```

最後に戻したいコミットを --softの次に指定してあげましょう。

```
git reset --soft HEAD@{1}
```
今回はfix_testに戻したいのでHEAD@{1}を指定しました。
するとしっかりと元に戻っているはずです。

```
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   app/models/sample.rb
```

参考記事：https://qiita.com/shosho/items/1f53b1fcf5fd876f309b
mac OS HighSierraでのCOBOL環境構築

# about
ナウい環境でのCOBOOL環境の構築について。
会社の研修でCOBOLに触れたら意外と面白かったから書く。

# どのCOBOLを入れたらいいの？
brew search cobolをしたらたくさん出て来る

```
$ brew search cobol
==> Searching local taps...
gnu-cobol                                open-cobol
==> Searching taps on GitHub...
==> Searching blacklisted, migrated and deleted formulae...
```

GnuCOBOLの[HP](https://sourceforge.net/projects/open-cobol/)を見てみるとコウ書いてあるから、GnuCOBOLを入れたらいいだろう。
>GnuCOBOL (formerly OpenCOBOL) is a free COBOL compiler

# 導入
私の環境ではチョー簡単だった
```$ brew install gnu-cobol``` 
一発

```
$ cobc -V
cobc (GnuCOBOL) 2.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart
Built     Feb 27 2018 09:40:48
Packaged  Sep 06 2017 18:48:43 UTC
C version "4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)"
```

# 動作確認
動作確認のために、hello worldする

```cobol:hello.cob
       identification division.
       program-id. hello.

       environment division.

       data division.

       procedure division.

       hello.
        display "HELLO"
        stop run.

```

**TIPS**
COBOLプログラムは最終行が空行であることを求められるため、最終行を空行のEOFにしないと以下のようなエラーが出るから注意。

```
hello.cob: 12: warning: line not terminated by a newline
```


ほんでもってコンパイル

```
$ cobc -x -Wall -debug hello.cob
$ ./hello
HELLO
```

めでたしめでたし、いえ〜〜〜い
tikzDeviceの書き出しを高速化する

# 問題提議
[tikzDevice](https://cran.r-project.org/web/packages/tikzDevice/index.html)はRのグラフをTeXのグラフィックフレームワークであるTikZ形式を出力するパッケージです。
基本的には普通の画像形式(pdf,pngなど)のデバイスを指定するかわりに`tikz()`を使用するだけで`.tex`形式で書き出しができますが、書き出しが非常に遅いという問題点があります。

以下はpdf,png,tikzで10000個の点をプロットした結果です(＠MacBook Air Early 2015)。

```bash:(bash)

$ time Rscript -e "library(tikzDevice); pdf('out'); plot(1:10000); dev.off();"
real    0m0.529s
$ time Rscript -e "library(tikzDevice); png('out'); plot(1:10000); dev.off();"
real    0m0.604s
$ time Rscript -e "library(tikzDevice); tikz('out'); plot(1:10000); dev.off();"
real    0m3.884s
```

このように、TikZにするだけで約7倍も時間がかかってしまいます。

# 原因
書き出しが遅くなる理由は、`tikz`関数内でTeXで使用される文字や文字列の幅を実行時に`pdflatex`を使用してチェックするためです。
対話形式で実行時に表示されるログを見ると以下のようなファイルが処理されることが確認できます。

```R:(R)
> plot(1:10000)
Measuring dimensions of: m
Running command: '/path/to/pdflatex' ... '/var/.../tikzDevice15ad45b476a03/tikzStringWidthCalc.tex'
Measuring dimensions of: 0
Running command: '/path/to/pdflatex' ... '/var/.../tikzDevice15ad42d8119c6/tikzStringWidthCalc.tex'
Measuring dimensions of: \char77
Running command: '/path/to/pdflatex' ... '/var/.../tikzDevice15ad476c32d80/tikzStringWidthCalc.tex'
Measuring dimensions of: 2000
Running command: '/path/to/pdflatex' ... '/var/.../tikzDevice15ad47e06b6a/tikzStringWidthCalc.tex'
...
```

# 対策1
`tikzDevice`ではこの計測結果をファイルにキャッシュするための`tikzMetricsDictionary`オプションを提供しています(正確には未指定時にはランダムなパスでキャッシュファイルが作成され、Rの終了時に削除されます)。

```bash:(bash)
$ time Rscript -e "library(tikzDevice); options(tikzMetricsDictionary='/tmp/dict'); tikz('out'); plot(1:10000); dev.off()"
real    0m3.815s
$ time Rscript -e "library(tikzDevice); options(tikzMetricsDictionary='/tmp/dict'); tikz('out'); plot(1:10000); dev.off()"
real    0m0.512s
```

これを常に静的なパスに設定すれば2回目以降の出力は高速化されますが、複数のRプロセスを同時に動かす場合に競合してエラーが発生する場合があります。

```bash:(bash)
$ Rscript -e "library(tikzDevice); options(tikzMetricsDictionary='/tmp/dict'); tikz('1'); plot(1:10000); dev.off()" &
$ Rscript -e "library(tikzDevice); options(tikzMetricsDictionary='/tmp/dict'); tikz('2'); plot(1:10000); dev.off()" &
$ Rscript -e "library(tikzDevice); options(tikzMetricsDictionary='/tmp/dict'); tikz('3'); plot(1:10000); dev.off()" &
$ Rscript -e "library(tikzDevice); options(tikzMetricsDictionary='/tmp/dict'); tikz('4'); plot(1:10000); dev.off()" &
$ wait
 createLockFile(lockname) でエラー:
  cannot create lock file ‘/private/tmp/dict___LOCK’
 呼び出し:  plot ... evalWithoutInterrupts -> dbInsert -> dbInsert -> createLockFile
 実行が停止されました
```

`tikzDevice`の使い方としては論文中の複数のグラフをRで生成することが想定されるため、このままでは並列コンパイル(`make -j`)が正常に動かなくなります。

# 対策2
上記のエラーは、Rscript実行時のコマンドライン引数等を使ってハッシュをとることで簡易的に対策することができます。

```R:.Rprofile
library(openssl) # md5を使用
pwd.and.args = paste(c(getwd(), commandArgs(trailingOnly=F)), collapse="")
pwd.and.args.hash = md5(pwd.and.args)
options(tikzMetricsDictionary=paste0("/tmp/tikz-", pwd.and.args.hash))
```
以上を`.Rprofile`などに書いておくと`/tmp/tikz-[適当なハッシュ値]`にキャッシュされます。
vim で 日記をつける ( Dropbox 連携 )

# code

ユーザーホームの直下に `Dropbox` のディレクトリを作り、
その中に `diary` というディレクトリを作りました。
`diary`のなかには、テンプレートとなる文字列を入れた`template.md`をおきます。
( Dropbox をいれると、基本はユーザーホームの直下にディレクトリができたはず ... )

`.bashrc` もしくは `.bash_profile` に以下のような記述を追加すれば
今日から vim で日記をつけることができます！


```.bashrc
#-------------------------------
#          Function
#-------------------------------
function createDialy(){
	TODAY_DIR=~/Dropbox/diary/$(date "+%Y_%m");
	TODAY_FILE=~/Dropbox/diary/$(date "+%Y_%m")/$(date "+%Y_%m_%d.md");

	if [ ! -e $TODAY_DIR ]; then
		mkdir -p $TODAY_DIR
	fi

	if [ ! -e $TODAY_FILE ]; then
		cp ~/Dropbox/diary/template.md $TODAY_FILE
	fi

	gsed -i -e "s/yyyy年mm月dd日/$(date '+%Y年%m月%d日')/g" $TODAY_FILE
	vim $TODAY_FILE
}

alias dia=createDialy;
```

これで、 `dia` と打つだけで毎日新しい日記がつけられます。

日記以外にも、今日のTODOとかをつけるのにも応用できるのでおすすめです。

Dropbox 連携することで、他のデバイスからも見れるので
自宅のデスクトップでつけた日記を、外で使用するラップトップからすぐに見ることができます。
もちろん、モバイル端末でも Dropbox アプリがあれば見れます。

しばらくつけていると、こんな感じになっていきます。

```
.
├── 2017_09
├── 2017_10
├── 2017_11
├── 2017_12
├── 2018_01
├── 2018_02
├── 2018_03
├── 2018_04
├── 2018_05
└── template.md

9 directories, 1 file
```

シンタックスハイライトをいれたかったので md にしていますが、
拡張子は普通に txt のほうが何かと便利かもしれないですね。

# まとめ

たのしい。
プログラマと数学と

私の周りでもプログラマに数学の知識が必要になるかどうかということがちょくちょく議論になったりするんで私なりのポエムを書いてみます。<br>

# 数学の素養はプログラミングに必要か？
私個人の考え方としては「ただコードを書く」だけであれば正直必要ないのではないかと思います。ただ、設計や最適化などを意図したプログラミングを行うのであれば、数学の知識があって損することはないのではないかと思ったりします。<br>
例えば

```math
\sum_{k=1}^{n} k
```
という式をPythonのコードで書いた場合、以下のような関数で表せます。

```sigma.py
def sigma(n:int):
    ans = 0
    for k in range(n):
        ans = ans + k
    return ans
```

しかしながら、（ここでは細かい詳細を省きますが）、上記の式は以下のような公式が成り立ちます。

```math
\sum_{k=1}^{n} k = n(n+1)/2
```

上の例ですと、計算時間はO(n)となりますが、上の公式を当てはめると、O(1)の計算量で済むことになります。<br>
これは極端な例かもしれません、しかしながら、最適なアルゴリズムの設計を考えるのであれば、このような数学的な素養が必要になると私は考えています。

#数学の知識は必要か
これに関しては正直分野によると思います。上で上げたのはあくまで数学的な素養であって、直接的に数学の知識が必要になるかどうかという点に関しては別問題であるともいえます。<br>しかしながら、数学の知識があれば、例えば物理演算を行うようなプログラムの設計に携わることができます。また、最近流行っている機械学習はまさに統計学や線形数学などの数学を応用したものの代表例と言えます。

#結局のところ
今からプログラマになりたいんだったら数学学んでおいて損はしないんじゃないかなぁ…と私のポジショントークも交えて思った次第ですw
Ruby on Rails 開発初学者に向けて環境構築方法をまとめてみた ( for Mac ユーザー )

#ガイドライン
Ruby on Rails導入に際して、ruby導入とrails導入の大きく二つに分けて手順を追っていく
# Ruby導入手順
実はMacには標準でrubyがインストールされている。
`ruby -v`で現在のバージョンが確認できる。
実際の開発現場などではrubyのバージョンをプロジェクトごとに変更して使用することが多いので**rbenv**というバージョン管理ツールを用いてrubyを導入する。さらに**rbenv**は**Homebrew**を用いてインストールできるので、まずはじめに**Homebrew**をインストールする。
1. 「**Homebrew**」をインストール
2. 「**Homebrew**」で「**rbenv**」をインストール
3. 「**rbenv**」でRubyをインストール
という手順に分かれる

さらに、Homebrewのコマンド`brew`を使えるようにするには、Command Line Toolsが入手済みでなければならず、さらにさらにCommand Line Tools を入手するためにはxcodeのインストールが必要になってくる。まとめると、
1. 「**xcode**」をインストール
2. 「**xcode**」で「**Command Line Tools**」をインストール
3. 「**Homebrew**」をインストール
4. 「**Homebrew**」で「**rbenv**」をインストール
5. 「**rbenv**」でRubyをインストール

たぶんこの解釈であってるはず。。。
##xcodeインストール
~~App Storeからxcodeを検索し入手してインストールしておく
(xcodeのサイズが大きく30分程要する)~~
必ずしもxcodeが必要ではないみたいです。(xcodeをインストールしなくてもCommand Line Tools単体でインストールが可能だということです。参考URL:http://osxdaily.com/2014/02/12/install-command-line-tools-mac-os-x/)
##Command Line Toolsインストール
ターミナルを開いて以下のコマンドを打つ
`xcode-select --install`
その後画面の指示に従う
![スクリーンショット 2018-05-08 19.30.43.png](https://qiita-image-store.s3.amazonaws.com/0/234751/714af677-eb80-a527-f353-e585158e664d.png)

##Homebrewインストール
`brew -v`
未インストールの場合は
`brew: command not found`
と出る
`/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`
でインストール
その後は画面の指示にしたがって「Enterキー」連打
xcodeのライセンスへの同意を求められた場合は
`sudo xcodebuild -license`
でagreeしてからインストールを開始する

`brew -v`
でバージョンが表示されれば成功
（例）`Homebrew 1.6.3`

##rbenvインストール
`rbenv -v`
未インストールの場合は
`rbenv: command not found`
と出る
`brew install rbenv ruby-build`
でインストール

`rbenv -v`
でバージョンが表示されれば成功
（例）`rbenv 1.1.1`

その後パスを通しておく
`echo 'eval "$(rbenv init -)"' >> ~/.bash_profile`
に続いて
`source ~/.bash_profile`
と入力
特になにもおこらない

##Rubyインストール
`rbenv install --list`
でインストール可能なrubyのバージョンがズラーっと羅列されている
執筆時点で2.5.0が最新なので、
`rbenv install 2.5.0`
でインストール開始

`rbenv versions`
で`2.5.0`が表示されていればOK
この時点で`ruby -v`は標準インストールされているバージョンのままであることに注意

`rbenv global 2.5.0`
で使用するrubyのバージョンを適応させられる
`ruby -v`は`2.5.0`が表示される
#Rails導入手順
続いてrailsのインストールを行う
railsは**gem**というrubyを便利に扱うためのアプリケーションの一種なので、gemでインストールする。
さらにgemはbundlerによって管理されるので、bundlerのインストールを先に行う。ちなみにbundlerもgem
の一種である。
##bundlerインストール
`gem install bundler`
でインストール
`bundle -v`でバージョン確認しておく
##railsインストール
`gem install rails --version="~> 5.1.6"`
でインストール(執筆時点の最新版)
`rails -v`でバージョン確認
`Rails 5.1.6`が表示されていれば終了!!

#Railsプロジェクトを立ち上げて確認してみる
プロジェクト名を決める。ここでは「testapp」
ホームディレクトリで
`rails new testapp`
と打ち込み「testapp」フォルダが新規作成されるので
`cd testapp`
で作業ディレクトリに移動し
`rails s`
とすると以下のようにサーバーが立ち上がる
![スクリーンショット 2018-05-08 20.39.31.png](https://qiita-image-store.s3.amazonaws.com/0/234751/a4292f0d-cd69-68ce-7e5e-ac256132dcc9.png)
http://localhost:3000/
にアクセスして
![スクリーンショット 2018-05-08 20.33.20.png](https://qiita-image-store.s3.amazonaws.com/0/234751/77f3f3ec-905c-7be5-b06c-d19953eb93d8.png)
が立ち上がれば成功

##おまけ
エディタはAtomでおk
[Install a Package]から日本語化可能 
https://atom.io/
python3でMeCabがinstallできない！

Mecabはこのコマンドを入力すればインストールできると書いてあったので実行

```
pip install mecab-python3
```

結果

```
Collecting mecab-python3
  Using cached https://files.pythonhosted.org/packages/25/e9/bbf5fc790a2bedd96fbaf47a84afa060bfb0b3e0217e5f64b32bd4bbad69/mecab-python3-0.7.tar.gz
    Complete output from command python setup.py egg_info:
    /bin/sh: mecab-config: command not found
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/private/var/folders/db/zj9vr1xx11vdn8yzb3bvp6xw0000gn/T/pip-install-31zuvfh1/mecab-python3/setup.py", line 41, in <module>
        include_dirs=cmd2("mecab-config --inc-dir"),
      File "/private/var/folders/db/zj9vr1xx11vdn8yzb3bvp6xw0000gn/T/pip-install-31zuvfh1/mecab-python3/setup.py", line 21, in cmd2
        return cmd1(strings).split()
      File "/private/var/folders/db/zj9vr1xx11vdn8yzb3bvp6xw0000gn/T/pip-install-31zuvfh1/mecab-python3/setup.py", line 18, in cmd1
        return os.popen(strings).readlines()[0][:-1]
    IndexError: list index out of range
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/db/zj9vr1xx11vdn8yzb3bvp6xw0000gn/T/pip-install-31zuvfh1/mecab-python3/
```
すると最後に、次のエラーが出てインストールができない！！！

```
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/db/zj9vr1xx11vdn8yzb3bvp6xw0000gn/T/pip-install-31zuvfh1/mecab-python3/
```

setup.pyを書き換えればよいみたいな記事もあったのですが、自分は以下のコマンドを実行した後に、再び実行したらエラーが発生せず、無事にインストールすることができました。

```
brew install mecab-ipadic

==> Installing dependencies for mecab-ipadic: mecab
==> Installing mecab-ipadic dependency: mecab
==> Downloading https://homebrew.bintray.com/bottles/mecab-0.996.el_capitan.bottle.3.tar.gz
######################################################################## 100.0%
==> Pouring mecab-0.996.el_capitan.bottle.3.tar.gz
🍺  /usr/local/Cellar/mecab/0.996: 20 files, 4.2MB
==> Installing mecab-ipadic
==> Downloading https://homebrew.bintray.com/bottles/mecab-ipadic-2.7.0-20070801.el_capitan.bottle.tar.gz
######################################################################## 100.0%
==> Pouring mecab-ipadic-2.7.0-20070801.el_capitan.bottle.tar.gz
==> Caveats
To enable mecab-ipadic dictionary, add to /usr/local/etc/mecabrc:
  dicdir = /usr/local/lib/mecab/dic/ipadic
==> Summary
🍺  /usr/local/Cellar/mecab-ipadic/2.7.0-20070801: 15 files, 50.6MB


pip install mecab-python3

Collecting mecab-python3
  Using cached https://files.pythonhosted.org/packages/25/e9/bbf5fc790a2bedd96fbaf47a84afa060bfb0b3e0217e5f64b32bd4bbad69/mecab-python3-0.7.tar.gz
Building wheels for collected packages: mecab-python3
  Running setup.py bdist_wheel for mecab-python3 ... done
  Stored in directory: /Users/admin/Library/Caches/pip/wheels/4c/07/3a/5f22ccc9f381f3bc01fa023202061cd1e0e9af855292f005dd
Successfully built mecab-python3
Installing collected packages: mecab-python3
Successfully installed mecab-python3-0.7
```

解決👍
TypeScriptでMap ⇔ Object変換

TypeScriptで型を保ちつつMapとオブジェクト（連想配列）を変換するには以下のようにすればよさそうです。

```util.ts
import * as _ from "lodash";

function mapToObj<V>(map: Map<number, V>): { [key: number]: V };
function mapToObj<V>(map: Map<string, V>): { [key: string]: V };
function mapToObj<V>(map: Map<any, V>): { [key: string]: V } {
    return _.fromPairs([...map]);
}

function objToMap<V>(obj: { [key: number]: V }): Map<number, V>;
function objToMap<V>(obj: { [key: string]: V }): Map<string, V>;
function objToMap<V>(obj: { [key: string]: V }): Map<any, V> {
    return new Map(Object.entries(obj));
}
```

または

```util.ts
import * as _ from "lodash";

function mapToObj<V>(map: Map<number, V>): _.NumericDictionary<V>;
function mapToObj<V>(map: Map<string, V>): _.Dictionary<V>;
function mapToObj<V>(map: Map<any, V>): _.Dictionary<V> {
    return _.fromPairs([...map]);
}

function objToMap<V>(obj: _.NumericDictionary<V>): Map<number, V>;
function objToMap<V>(obj: _.Dictionary<V>): Map<string, V>;
function objToMap<V>(obj: _.Dictionary<V>): Map<any, V> {
    return new Map(Object.entries(obj));
}
```

`_.NumericDictionary<V>`と`_.Dictionary<V>`はそれぞれ
`{ [key: number]: V }`と`{ [key: string]: V }`なので同じです。
教授「タイトルは『学生番号+pdf』としてください」

教授「レポートのタイトルは『学生番号+pdf』としてください。」
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「ファイル名を学籍番号+pdf（たとえば12345678.pdf）にしてください」と指示したら，「12345678.pdf.docx」が大量発生した。「そ～いう意味ではなく，pdfがほしい」って言ったら，今度は「12345678.pdf（ただし実体はword）」が発生した。笑い話ではあるが，リテラシーという点ではちょっと不安・・・</p>&mdash; 川口俊明 (@K_Toshiosan) <a href="https://twitter.com/K_Toshiosan/status/991098271270453250?ref_src=twsrc%5Etfw">2018年4月30日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#PCに疎い学生X君
「名前をつけて保存で、「12345671.pdf」と。これで提出しよう！」

出てきたのは```12345671.pdf.docx```というファイルでした。X君は拡張子というものをそもそも知らなかったので「拡張子を表示しない」にチェックをしたまま使っていました。

#X君よりはPCができるY君
Y「名前変えたらええんやろw」

出てきたのは```12345672.pdf```というタイトルで実態はdocx形式のファイルでした。Y君は拡張子というものがあるのは知っていましたが、意味はよくわかってませんでした。

#全部文字列と解釈してしまうB君
B「$がないってことは、まあ"+pdf"って文字列に決まってるよな」

B君は```12345673+pdf```というファイルを提出しました。B君は何でも言われた通りに取ってしまいます。

#何かとつけて型宣言が要るC君
C「pdfは引用符がないし変数だろうけど定義してませんよ」

C君は「```pdf is undeclared```」とエラーを出しました。C君は力があるのは確かですが、頑固で取っつきにくいところがある学生です。ですがきっちりしていることで大事故を防いでくれたりもしたことがあります。

#型がないようで実はあるP君
P「pdfは引用符がないし変数だろうけど定義してませんよ

P君も「```name pdf is not defined```」というエラーを出しました。P君は普段はとても気が利くいい学生で言わなくてもわかってくれるのですが、たまにこういうことをしてしまうのでした。
[Unity] G2Uを少しだけ使いやすくする

ゲームデータを管理するのに便利なG2U。
シート数が増えてくるとUnity側での読み込みに時間がかかるようになる。
G2Uはファイル毎の非表示設定はできるのに、シート毎の非表示設定ができない。

以下を実施すると少しだけ使いやすくなる。

#スプレッドシートを二つ用意する
・全てのデータを管理するスプレッドシート（例：GameDB）
・Unity側で実際に読み込むスプレッドシート（例：GameDBlite）

#スクリプトを作成する
・GameDBliteのsheetIDをコピーしておく
・GameDB側で以下のスクリプトを作成する
・スクリプト内のPaste_Destination_SheetID_Hereのところに、GameDBliteのsheetIDを記入する（1箇所だけ）

```javascript:g2u.gs
//ここにコピー先のsheetIDを入力
var sheetID = 'Paste_Destination_SheetID_Here';

function onOpen(){
  //メニューの配列
  var myMenu=[
    {name: "別のワークブックにコピー", functionName: "copySheetTo"},
    {name: "別のワークブックにコピー(クリア)", functionName: "copySheetToWithClear"},
  ];
  //メニューを追加
  SpreadsheetApp.getActiveSpreadsheet().addMenu("G2U",myMenu); 
}

function copySheetTo(){
  //現在のアクティブなシートを取得する
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  //sheetIDで指定したのスプレッドシート(コピー先)を取得する
  var destination = SpreadsheetApp.openById(sheetID);
  //コピー先に同名のシートがあるか確認する
  var destSheet = destination.getSheetByName(sheet.getName());
  //同名のシートがある場合
  if(destSheet != null){
    //現在のシートをコピー先に一旦コピーする(コピーすると余計な文字列がつく)
    var newSheet = sheet.copyTo(destination);
    //元からあるシートを削除して
    destination.deleteSheet(destSheet);
    //さっきコピーしたシートを元の名前に戻す
    newSheet.setName(sheet.getName());
    //トースト表示
    SpreadsheetApp.getActiveSpreadsheet().toast('上書きしました : ' + destination.getName() );
  }
  //同名のシートがない場合
  else{
    //現在のシートをコピー先にコピー、名前を変更する(コピーすると余計な文字列がつく)
    sheet.copyTo(destination).setName(sheet.getName());
    //トースト表示
    SpreadsheetApp.getActiveSpreadsheet().toast('コピーしました : ' + destination.getName() );  
  }
}

function copySheetToWithClear(){
  //まずコピー
  copySheetTo();  

  //sheetIDで指定したのスプレッドシート(コピー先)を取得する
  var destination = SpreadsheetApp.openById(sheetID);
    
  //コピー先のシート数を取得
  var cnt = destination.getNumSheets();
  //(シート数-1)回、1番目のシートを削除する
  for(var i = 0; i < cnt - 1; i++){
    var sh = destination.getSheets()[0];
    destination.deleteSheet(sh);
  }

}
```

#スクリプトを実行する
GameDBのメニュー内に**G2U**が追加される

**別のワークブックにコピー**
現在アクティブになっているシートがGameDBliteにコピーされる。
GameDBliteにすでに同名のシートがある場合は上書きされる。
なければ新規作成される。

**別のワークブックにコピー（クリア）**
GameDBliteにコピーされたシート以外をすべて削除できる。
GameDBliteが膨らんでしまった時に使う。

#Unity側でやること
GameDBliteのみを表示する。
（GameDBは目玉アイコンを押して非表示にしておく）

#スプレッドシート側でやること
GameDBのみを編集し、GameDBliteは開かない。
コピー作業は全てスクリプト経由にする。

こうすることで、間違ってGameDBliteを編集してしまうことがなくなるのでおすすめ。
AMP のために Rails で Carrierwave と MiniMagick を使って 画像のサイズを取得する


## はじめに
### AMP対応
SEO対策のためAMP対応をしようと思ったのですが、AMPでは画像の縦横の幅を指定する必要があります。
今回はCarrierwaveとMiniMagickを使って画像をアップロードするときに画像の縦横幅も同時に保存し、
また、既存の画像のサイズも取得する処理をしたいと思います。
## 実装
### 前提
`carrierwave`と`minimagick`は既にインストールしているものとします。
また、`Article`というモデルがあり、Articleが`image`というカラムを持っていて、下記のように`ImageUploader`を使っているとします。

```app/models/article.rb
class Article < ApplicationRecord
  mount_upload :image, ImageUploader
end
```

### 画像サイズの取得
実際に画像を表示するには、

```app/views/articles/show.amp.haml
%amp-img{src: @article.image, width: @article.image_width, height: @article.image_height}
```
のような形で表示させたいので、まずは`Article`モデルに`image_width`と`image_height`というカラムを追加します。
(実際に画像を保存しなくてもMiniMagickを使って画像サイズを取得することはできるのですが、画像を表示するたび、画像の枚数だけサイズを取得する処理が走るのは微妙なのでカラムを作って保存することにしました。)

```
$ rails g migration AddImageWidthAndImageHeightToArticles
```
```db/migrate/20180101_add_image_width_and_image_height_to_articles.rb
class AddImageWidthAndImageHeightToArticles < ActiveRecord::Migration[5.0]
  def change
    add_column :articles, :image_width, :integer
    add_column :articles, :image_height, :integer
  end
end
```
```
rails db:migrate
```

画像サイズを取得し、保存するタイミングはCarrierwaveの`after store`のコールバックのタイミングにし、
`save_image_size`というメソッドを走らせるようにします。

```app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include Carrierwave::Minimagick
  
  after :store, :save_image_size
  
  def save_image_size(file)
    image_sizes = MiniMagick::Image.open(self.url).dimensions
    self.model.update(image_width: image_sizes[0], image_height: image_sizes[1])
  end
end
```

これでArticleを保存し、Carrierwaveのstoreが終わったタイミングで画像のサイズが保存されるようになります。
<br>
また、既存の画像のサイズも取得し直さないといけないのでその処理も書いておくので、コンソールで走らせるなり、ファイルを作って`ruby runner`で走らせるなりしてやってみてください。
処理で何らかのエラーが出たときのために、エラーが出たデータのIDを見えるようにしておく。

```
Article.where.not(image: nil).find_each do |article|
  if article.image_width.blank? || article.image_height.blank?
    error_article_ids = []
    begin
      image_sizes = MiniMagick::Image.open(article.image.url).dimensions
      article.update(image_width: image_sizes[0], image_height: image_sizes[1])
    rescue
      error_article_ids.push(article.id)
    end
    puts error_article_ids
  end
end
```
## まとめ
なんというか、こんなこといちいちしなくていいようにAMPでもよきに計らって画像を表示してほしいなと切に願います。。
MySQLのevent_schedulerでテーブルパーティションを追加

## CREATE TABLE
```sql
CREATE TABLE `t1` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE  COLUMNS(created_at)
(PARTITION p201711 VALUES LESS THAN ('2017-12-01 00:00:00') ENGINE = InnoDB,
 PARTITION p201712 VALUES LESS THAN ('2018-01-01 00:00:00') ENGINE = InnoDB,
 PARTITION p201801 VALUES LESS THAN ('2018-02-01 00:00:00') ENGINE = InnoDB) */;
```
## CREATE PROCEDURE
プロシージャの関数として定義しておいた方が、デバッグとか楽だった。
関数の引数にテーブル名とか渡せるようにすれば、同様のパーティションロジックのテーブルについては対応できる。

```sql
DELIMITER $$
  CREATE PROCEDURE add_partition()
  BEGIN
      -- 翌月のパーティション名
      SET @pname  = CONCAT('p', DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y%m'));
      -- パーティション名が定義済みか取得
      SELECT COUNT(*) INTO @is_parted
        FROM INFORMATION_SCHEMA.PARTITIONS
       WHERE TABLE_NAME = 't1' AND PARTITION_NAME = @pname;

      IF @is_parted = 0 THEN
        SET @lt = DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 2 MONTH), '%Y-%m-01 00:00:00');

        SET @query = CONCAT('ALTER TABLE t1 ADD PARTITION (PARTITION ', @pname);
        SET @query = CONCAT(@query, ' VALUES LESS THAN (''', @lt, '''))');
        PREPARE s FROM @query;
        EXECUTE s;
      END IF;
  END $$
DELIMITER ;
```
## CREATE EVENT
```sql
DELIMITER |
CREATE EVENT IF NOT EXISTS `e_partition`
    ON SCHEDULE EVERY 1 DAY ENABLE
    COMMENT 'monthly patitioning for t1'
    DO BEGIN
      CALL add_partition();
    END|
DELIMITER ;
```
MySQLのイベントスケジューラを使ったことが無かったけど、こういう局所的な用途とかだと手軽で良いかもと思った、
困ったのは、プロシージャのデバッグ方法、以下のコメントでデバッグ用の関数を用意してデバッグする方法が良い感じだった
https://stackoverflow.com/a/15687954
LightGBMをインストールしたまでの色々なこと


まず、LightGBMとはMicrosoftが開発した高速な勾配ブースティング木が実行可能なものです。同様のものではXGBoostが有名らしいですが、それよりも数倍高速という話があり今回使ってみることにしました。

ただ、使ってみるにあたり色々とエラーが起こって大変だったので備忘録として残しておきます。。

まず```pip install lightgbm```でインストールして行ったところ下記のエラーが出るところが始まりでした。

```エラーメッセージ
OSError: dlopen(/Users/ldap/.pyenv/versions/3.6.5/lib/python3.6/site-packages/lightgbm/lib_lightgbm.so, 6): Library not loaded: /usr/local/opt/gcc/lib/gcc/7/libgomp.1.dylib
  Referenced from: /Users/ldap/.pyenv/versions/3.6.5/lib/python3.6/site-packages/lightgbm/lib_lightgbm.so
  Reason: image not found
```

とりあえずgcc環境については何もした記憶がなかったので、早速brewでインストールし用途したところ、これもエラーとなり上手くいかなかったのでMacPortsからインストールすることにしました。。

```環境
macOS High Sierra 10.13
Python 3.6.5
```

<hr>

<b>MacPortsインストール</b>

MacPortsとはOSXで利用可能なパッケージ管理システムです。
インストールは下記のサイトのメニュー「vailable Downloads」から自身のOSにあったものを選んでインストーラの指示に従って行くだけでできました。
https://www.macports.org/install.php


インストール後パスを```vi ~/.profile```で以下を記述。

```~/.profile
export PATH="/opt/local/bin:/opt/local/sbin:$PATH"
export MANPATH="/opt/local/man:$MANPATH"
```

```ターミナル
#設定を反映させる
source ~/.profile
#反映を確認
port version
Version: 2.4.4
#一応最新版に更新しておく
sudo port selfupdate
sudo port sync
```

■参考サイト
http://tweeeety.hateblo.jp/entry/2014/10/01/223700


<HR>
<b>gcc環境インストール</b>
gccはC言語プログラムを作成するためのコンパイラです。MacPortsからインストールを試みます。

```ターミナル
sudo port install gcc6 openmpi-gcc6

#それぞれのバージョンを確認（おそらく何も表示されません）
g++-mp-6 -v
gcc-mp-6 -v
```


どうもリンクを通しておかないとダメなようです。コンパイル時に必要そうだった下記の２つのリンクを通します。


```ターミナル
sudo ln -sf /opt/local/bin/g++-mp-6  /usr/bin/g++
sudo ln -sf /opt/local/bin/gcc-mp-6  /usr/local/bin/gcc
```

リンクを通した後、それぞれのバージョンを確認するときちんと反映されている事が確認できました。

■参考サイト
https://qiita.com/Hiroki11x/items/261612c142da176bbba5


<HR>
<B>LightGBMインストール</B>
ようやくLightGBMをインストールできる環境が整いました。ただ、ここでもインストール時に色々と設定をしないといけなくて大変でした。

ビルドする時にコンパイラを指定するのがポイントのようです。

```ターミナル
#LightGBMを取ってきてそのディレクトリに移動
git clone --recursive https://github.com/Microsoft/LightGBM; cd LightGBM
#buildディレクトリを作り、そのディレクトリに移動
mkdir build
cd build
#ビルド
cmake -DCMAKE_CXX_COMPILER=g++-mp-6 -DCMAKE_C_COMPILER=gcc-mp-6 ..
make -j4
```

buildした後、setup.pyがあるLightGBM直下のディレクトリに移動してインストールしますが、ここでもsetup.pyの記述の変更が必要でした。


```ターミナル
#python-packageディレクトリに移動
cd python-package
```

ここにsetup.pyがありますで、このファイルを開いて```vi setup.py```で以下の２行を追加します。追加する場所は```compile_cpp()```内のelse文の所です。


```setup.py
    else:  # Linux, Darwin (macOS), etc.
        logger.info("Starting to compile with CMake.")
        cmake_cmd.append("-DCMAKE_CXX_COMPILER=clang++-mp-6.0") #ここにこれを追加
        cmake_cmd.append("-DCMAKE_C_COMPILER=clang-mp-6.0") #ここにこれを追加
        silent_call(cmake_cmd, raise_error=True, error_msg='Please install CMake and all required dependencies first')
```

記述した後インストール

```ターミナル
sudo python setup.py install --precompile
```

これでようやくLightGBMが利用できるようになりました。

■参考サイト
https://github.com/Microsoft/LightGBM/issues/710


<HR> 
正直、色々し過ぎて何が正しくて何が悪かったかなどはよくわかっていません。。
間違ったことやもっと簡単な方法がありましたら教えて頂けますとありがたいです。