OmniAICreator/Qiita-1.07M huggingface dataset:
Numpy を使わない多次元配列計算 その２

#Numpyを使わない多次元配列計算
以前に、<http://qiita.com/ponnhide/items/c919f3bc549d1228c800> の記事で、numpyを用いない配列計算について取り扱ったが、この記事はその発展版

##なぜnumpyを使わないか。
numpyを使えばできるのに、何故使わない方法を考えるか。ただの趣味という側面もあるが、単にpypy上でnumpyを使うと異常に実行が遅くなるためである。まぁきっと他にも使い道はあると思う。

##前回の復習(加減乗除）
前回の記事で、「mapとlambdaを駆使すれば、配列同士の演算はおちゃのこさいさい」とか書いてしまったがぶっちゃけlambdaよりは、operatar モジュールを使った方がはるかにスクリプトが簡素ですむ。operator モジュールを使うと、演算子を関数形式で用いることができる。例えば、`operator.add(a,b)` は `a+b` と同義である。  

まずは
__1次元配列の和__

```python
from operator import add
>>> array1 = [4,5,6]
>>> array2 = [1,2,3]
>>> list(map(add, array1, array2))
[5,7,9]
```

__2次元配列の和__
結局、ここではlambdaを使うわけだが、

```python
>>> array1 = [[1,2,3],[1,2,3]]
>>> array2 = [[2,3,4],[2,3,4]]
>>> list(map(lambda x,y: list(map(add, x,y)), array1, array2))
[[3, 5, 7], [3, 5, 7]]
```

どうしてもlambdaには頼らないぞっていう場合は、リスト内包表記をつかって、

```python
>>> [list(map(add, x,y)) for x,y in zip(array1,array2)]
[[3, 5, 7], [3, 5, 7]]
```
みたいな書き方もできる。こっちの方がスッキリしてるか。

##行列の掛け算
前回は扱わなかったが、__numpyを使わずに__と豪語するなら、やっぱり行列の掛け算(要素同士の積じゃなくてdot積)もやるべきだろということで、無理やり考えてみた。

```python
>>> from operator import mul
>>> array1 = [[2,3],[1,4],[2,1]]
>>> array2 = [[3,1,2],[2,4,2]]
>>> [[sum(map(mul, row, col)) for col in zip(*array2)] for row in array1]
[[12, 14, 10], [11, 17, 10], [8, 6, 6]]
```

よしできた。しかし、array1が 1行xn列 の場合だと上記の書き方ではできない。array1が 1行xn列 場合は、

```python
>>> from operator import mul
>>> array1 = [1,0,0,1]
>>> array2 = [[0,1],[1,1],[1,0],[1,0]]
>>> [sum(map(mul, array1, col)) for col in zip(*array2)]
[1,1]
```

うーむ。lambdaや、三項演算子を駆使すれば、統一した書き方もできるかな。。

##統計関連
特に使い方には触れないが、python3.4以降の環境ならデフォルトで、statistics モジュールが入っている。これを使えば、list型のまま基本的な統計量は計算が可能。
<https://docs.python.jp/3/library/statistics.html>
.NET Core で静的ファイルが見つからなかったときの対処法

Live2D Cubism SDK for JavaScript のアーリーアクセスがはじまりました！
https://live2d.github.io/#js

さっそく、.NET Core で作成していたWebアプリに組み込んでみました。

# モデルファイルが Not Found!?
なぜか、データが Not Found となり、モデルが表示される気配がありません。
テクスチャファイルは読めているのに・・・

# 原因は、MIME でした。
Live2D Cubismモデルは".moc3"、モーションは".motion3.json"です（Cubism 2.x系は".moc" ".mtn"）
要は、このファイルの拡張子が不明のため、読めなかったようです。

StartUp.cs に下記の記述を記載すれば、全ての拡張子が読めるようになります。

```StartUp.cs
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(new StaticFileOptions()
    {
        ServeUnknownFileTypes = true
    });
}
```

本当はセキュリティ的な意味でも、特定の拡張子だけを反映するようにしたほうがいいかなーとは思います。

## 余談：IISでいうと...
これですね。
![2017-08-24_15h40_30.png](https://qiita-image-store.s3.amazonaws.com/0/93282/2cdac61e-8090-0ee7-4080-dc2cc2c133c9.png)

# 参考
[Introduction to working with static files in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files)
mac pcのスペックを調べるコマンド

一度も投稿したことがなかったので、使ってみようと思い書いてみた。
ターミナルで以下を入力すると

    $ system_profiler SPHardwareDataType

Hardware:

    Hardware Overview:

      :
      Model Name: MacBook Pro
      Model Identifier: MacBookPro11,4
      Processor Name: Intel Core i7
      Processor Speed: 2.5 GHz
      Number of Processors: 1
      Total Number of Cores: 4
      :

こんな感じでCPUとかコアの数とか色々確認できる。
ngx-translateとDatePipeを組み合わせて使いたい時 (カスタムパイプもあるよ)

結論テンプレート側ではできなかったです。
なのでコントローラ側でパイプなしで実装しました。さらに、それ用にカスタムパイプも作りました。

##やりたかったこと

ngx-translateを使って、

| 言語       | 表記          | フォーマット    |
|------------|--------------|-------------|
| 日本語     | 2017年8月24日 | YYYY年M月D日 |
| 英語       | Aug 24, 2017 | MMM DD, YYYY |

こんな感じで表示の出し分けをしたくて、ngx-translateとdatePipeを強引に組み合わせて、以下みたいな感じで書いてみたところ。。。

```html
<p>{{ date | date: {{ 'DATE_FORMAT' | translate }} }}</p>
```

通常 `date: 'YYYY-MM-DD'` ってするところを、強引にフォーマット部分に文字列を突っ込んでみましたが、ダメでした。やっぱダメかー。

そもそもそういう機能は無いみたいですねngx-translateには。

##実装
なので、コントローラ側で実装してあげました。
`DATE_FORMAT` ていうのに、英語だと`"MMM DD, YYYY"`, 日本語だと`"YYYY年M月D日"`という文字列が指定されてて、`translate.get()`で取得してきます。
translateっていうのはngx-translateのサービスのObjectですね。
ここらへんのngx-translate実装の詳細は以下を参考にして下さい。
http://qiita.com/jyjoestrummer/items/4ee5f28e0843bd7c70bb

ほんでDateのコードですが、こんな感じでコントローラ側で言語に応じて日付を整形します。

```ts
      // 日付を言語によって整形する
      this.translate.get("DATE_FORMAT").subscribe((res: string) => {
        let dateTranslated = moment(this.date).format(res);
        this.dateTranslated = dateTranslated;
      });
```

今回はionic3で実装しましたが、constructorとかionViewWillEnterで実行するようにしました。
以上っすわ〜。

##追記　カスタムパイプ作りました

なんかいろんな画面で使う感じになったので、カスタムパイプにしました。

```ts:date-translated-pipe.ts
import { PipeTransform, Pipe } from '@angular/core';
import * as moment from 'moment';
import { TranslateService, LangChangeEvent } from '@ngx-translate/core';

// 言語によってDateを整形するPipe
@Pipe({
  name: "dateTranslated"
})
export class DateTranslatedPipe implements PipeTransform {
  constructor(
    public translate: TranslateService) {
  }
  transform(date: string): string {
    let dateTranslated;
    this.translate.get("DATE_FORMAT").subscribe((res: string) => {
      dateTranslated = moment(date).format(res);
    });
    return dateTranslated;
  }
}
```

こんな感じで使います。

```html:test-template.html
<p>{{ date | dateTranslated }}</p>
```
PHPの親クラスと子クラスに同じ定数(const)があった時のselfとstaticの違い。

- selfの場合、親にしかないメソッド呼んだときは親の定数が使われる。
- staticの場合、親にしかないメソッドでも子の方が採用。

```php
<?php
class OYA {
    const TEST = '親';

    public function getSelfOverride() {
        return self::TEST;
    }

    public function getSelfOya() {
        return self::TEST;
    }

    public function getStaticOverride() {
        return static::TEST;
    }

    public function getStaticOya() {
        return static::TEST;
    }
        
}

class KO extends OYA {
    const TEST = '子'; 

    public function getSelfOverride() {
        return self::TEST;
    }

    public function getSelfKo() {
        return self::TEST;
    }

    public function getStaticOverride() {
        return static::TEST;
    }

    public function getStaticKo() {
        return static::TEST;
    }    
}

var_dump(phpversion() === "7.0.15-0ubuntu0.16.04.4");

var_dump(OYA::TEST === '親');
var_dump(KO::TEST  === '子');

$ko = new KO;
var_dump($ko::TEST === '子');

var_dump($ko->getSelfOverride() === '子');
var_dump($ko->getSelfKo()       === '子');
var_dump($ko->getSelfOya()      === '親');

var_dump($ko->getStaticOverride() === '子');
var_dump($ko->getStaticKo()       === '子');
var_dump($ko->getStaticOya()      === '子');

```
はじめての Go言語、Windows環境 Visual Studio Codeで編集とdebugger使う方法を試してみる　その２

# Go言語、規約に厳しい…
例えばですが、import で fmt するもプログラム内で fmtメソッドを使用していない場合、Go言語だと ```imported and not used:``` と怒られます（回避方法あり）。厳しいなと。
そこで Visual Studio Code を使って快適プログラミング環境を作ってみたいと思います。

# Windows環境で開発環境を作成 (2017/08/24時点)
Go, Git, Vsual Studio Code のインストール説明は省きます。

+ Windows 8.1(察してｗ)
+ [Go 1.8.3](https://golang.org/dl/)
+ [Microsoft Vsual Studio Code 1.15.1](https://code.visualstudio.com/download)
+ [Git for Windows 2.14.1](https://git-for-windows.github.io/)

# Go の GOROOT, GOPATH でﾊﾏﾙ
後々、ﾊﾏﾙのがこの GOROOT, GOPATH です。システム環境変数でもユーザー環境変数でもどちら好きな方に設定しましょ。※私は、ユーザー環境変数に設定しました

| 環境変数 | 値 | 備考 |
|:--|:--|:--|
|GOROOT|C:\Go|Goデフォルトインストールパス |
|GOPATH|%USERPROFILE%\goroot|go getなどインストール先また、アプリパス|
|PATH|;%GOROOT%\bin;%GOPATH%\bin|追加する|

# Visual Studio Code の設定
Go拡張機能を入れるのとdebuggerまでの設定です。拡張機能の入れ方は割愛します。

## Go拡張機能を入れる
入れるだけですｗ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/0f976e8c-08bd-38e5-6503-0ddb53009a34.png)

## 自動補完できるか確認
おお

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/d4f4a25a-bfee-a0fd-19a0-f4f456790524.png)

## import 、、これが
書き忘れたりメソッドを使用しない場合、自動的に補完してくれます。これ便利ですね。
IDEやっぱり便利だなと思う時ですね。

## Delve(debugger) をインストール
debuggerで実行ボタンを押下して下記のエラーが表示される場合は、```%GOPATH%/bin``` に ```dlv.exe``` が[無いときです](https://github.com/Microsoft/vscode-go/issues/832)。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/f755c0b9-ff81-90c5-a595-6e27a91735f4.png)

なので必要なgoパッケージをインストールします。

```go:command
go get -u -v github.com/derekparker/delve/cmd/dlv
```

あと必要と思われる便利なものもインストールします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/00211fd5-7c34-5ede-e79d-3c385e3c5dd9.png)

```go:command
go get -v github.com/nsf/gocode

他に
go get -u -v github.com/zmb3/gogetdoc
go get -u -v github.com/golang/lint/golint
go get -u -v sourcegraph.com/sqs/goreturns
go get -u -v golang.org/x/tools/cmd/gorename
go get -u -v github.com/tpng/gopkgs
```

## できたー
結構楽に設定でき、debugger も簡単に使えるやん。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/2c7afd9e-1de0-a4c6-88f4-25b313183810.png)

## 感想
プログラムコードを修正し保存ボタンを押下すると画面がチラチラします。何かの設定がいるのかな？

# クロスコンパイル
Javaより簡単にできる。

```
set GOOS=linux
set GOARCH=386
go build -o test_linux_386 test.go

set GOOS=windows
set GOARCH=amd64
go build -o test_win_64.exe test.go
```

すごいね。


# 参考にさせて頂いたサイト様

>+ [WindowsのVisual Studio CodeでGo言語の開発環境を作る](http://blog.shibata.tech/entry/2016/07/23/024613)
>+ [Visual Studio CodeによるGo言語のデバッグ](http://dev.classmethod.jp/go/visual-studio-code-golang-debug/)
>+ [gometalinter で楽々 lint](http://qiita.com/spiegel-im-spiegel/items/238f6f0ee27bdf1de2a0)
Cognos Analytics でのログオフ時のリダイレクト

##概要
Cognos でSSOを実装する時など、ログオフ時の自動再ログインを避けるために、ログオフ先のリダイレクト指定をします。
Cognos BIまでは、system.xmlを変更する以下の手順だったのですが、Cognos Analyticsからは手順が違ってます。

**Redirect User to a Web Site When They Log Off**
https://www.ibm.com/support/knowledgecenter/SSEP7J_10.2.0/com.ibm.swg.ba.cognos.ug_cra.10.2.0.doc/t_customize_logoff.html

よくやる構成だと思いますので、手順を投稿します。

##手順
基本はこちらのTechnote、手順はCognos Analytics 11.0.6以降の場合です。
**How to redirect users after Sign Out in Cognos Analytics?**
http://www-01.ibm.com/support/docview.wss?uid=swg21995296

C:\Program Files\ibm\cognos\analytics\webcontentに、logoff.html を以下の内容で作成します。

```html
<html> 
<head><title>log off</title></head> 
<body> 
    <span>You have been logged off.</span><br/> 
    <span>Click <a href="/bi/">here</a> to log in again.</span> 
</html>
```
![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/44184c0b-65d9-7781-6466-cf502a1deb3b.png)

C:\Program Files\ibm\cognos\analytics\configurationに、local-server.xml を以下の内容で作成します。

```html
<server><jndiEntry jndiName="glass/sso/logout" value="/logoff.html"/></server>
```

Cognos Analytics再起動後、ログインして、サインアウトします。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/c4d2088d-3fa2-26c0-9c19-3dca23da1e0d.png)

このように、ログオフ時に自作のlogoff.htmlにリダイレクトされました。
![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/2eb0da9f-460a-4cae-b7b6-3650923ec8d5.png)
Pandas で四分位数を基準に外れ値を NaN で埋める

Pandas は便利ですよね。Pandas の DataFrame から四分位範囲の 1.5 倍を超えるデータを外れ値として削除したいと思います。ある列の値を基準に、その行まるごと削除するのではなく、列ごとに外れ値を検出し、それらを NaN で埋めてみます。

参考: [相関分析の時に四分位範囲(IQR)で外れ値を見つける（Python） - 俺、サービス売って家買うんだ](http://www.ie-kau.net/entry/2016/04/14/%E7%9B%B8%E9%96%A2%E5%88%86%E6%9E%90%E3%81%AE%E6%99%82%E3%81%AB%E5%9B%9B%E5%88%86%E4%BD%8D%E7%AF%84%E5%9B%B2%28IQR%29%E3%81%A7%E5%A4%96%E3%82%8C%E5%80%A4%E3%82%92%E8%A6%8B%E3%81%A4%E3%81%91%E3%82%8B%EF%BC%88Pyt)


```py3:drop_outlier.py
def drop_outlier(df):
  for i, col in df.iteritems():
    #四分位数
    q1 = col.describe()['25%']
    q3 = col.describe()['75%']
    iqr = q3 - q1 #四分位範囲

    #外れ値の基準点
    outlier_min = q1 - (iqr) * 1.5
    outlier_max = q3 + (iqr) * 1.5

    #範囲から外れている値を除く
    col[col < outlier_min] = None
    col[col > outlier_max] = None
```

データを scikit-learn などの機械学習の関数に入れる場合は `fillna` などで削除したデータを埋めましょう。このやり方だと外れ値のデータが別の値に置き換わってしまうので、その点は考慮した上で使いましょう :joy:

```pyt3
df.fillna(method='bfill')
```

楽しい Pandas ライフを。
【るびまメモ】StructとHash（おまけ：Rubyで型付けができるTypeStruct）

栗原勇樹さん（[@_ksss_](https://twitter.com/_ksss_)）
> どんな key があるか固定なら Struct、不定なら Hash

## Struct
> ・class 名が付いているのでデバッグしやすい
  ・key 名を typo しても即座にわかるのでデバッグしやすい
  ・メンバー呼び出しの syntax が書きやすい

メンバー呼び出しのsyntaxが書きやすいっていうのはどういうことだろう？

## Hash
> ・リテラルがあるので生成 syntax が書きやすい
・未知の key でも格納できる
・keyword argument など、言語組み込みの機能が豊富

これはメリットがわかりやすい。


[Rubyist Magazine 0054 号 「Ruby に型があると便利か」 - 【おまけ Hash? それとも Struct?】](http://magazine.rubyist.net/?0054-typestruct)

## 余談

[Rubyist Magazine 0054 号 「Ruby に型があると便利か」](http://magazine.rubyist.net/?0054-typestruct)にある、[TypeStruct](https://github.com/ksss/type_struct)というgemの利用シーンとして**JSON API のサーバー側実装**が挙げられているけれど、ReactやSwiftでクライアントが動いていて、そっちでJSONオブジェクトの型付けがされている場合、API側でも型付けする必要はないかな？

しかし果たして、型付けをするのはクライアントとAPI側どちらが良いのだろう？
API側はバリデーションやデータベース制約があるから、ある程度型が曖昧でも、致命的な障害とかは発生しない？
すると、やはりクライアント側で型付けをする方が予期せぬバグを防ぐことができるのだろうか？
MongoDBに保存



MongoDBに自分でkey-valueを作って保存する方法

## pymongoでmongoにレコード追加
pythonです。

```py3
cli = pymongo.MongoClient('localhost', 27018)
# hogeというDBに接続
db = cli.hoge

dict = {'key': "one", 'value': {'1','2','3'}}

# fugaというコレクションにdictを追加
db.fuga.save(dict)

```

このdictを変更してkeyが"one"のvalueを変更するには、

```py3
db.hist.update_one({
  'key': "one"}, {'$set': {'value': {'a','b','c'}}
}, upsert=True)

```

こういう風にレコードを追加すると、oneをkeyとするレコードの内容が上書きされる。
もしkeyがなければ、新しく作ってくれる。
save()を用いるとkeyが重複していても、上書きされないので注意。
2020年次期学習指導要領 教科「情報」を紐解く

## はじめに
IT技術と言えば「言語」とか「資格」とか「IOT」とか着目されがちですが、
今回は教科「情報」という技術が今後どう変わるのか、次期学習指導要領の
観点から記載します。

なお、2020年次期学習指導要領はまだ<font color="OrangeRed">「案」</font>でしかありません。
とはいえ、現状を知るために紐解いてみようと思います。

## 学習指導要領とは
学習指導要領とは、国のどの地域で教育を受けても一定の水準の教育を
受けられるようにするため、文部科学省で学校教育法等に基づき、
各学校で教育課程（カリキュラム）を編成する際の基準を定めたもののこと。

教師は学習指導要領を参考にしてシラバスを作成し、授業を行います。
つまり、<font color="OrangeRed">学習指導要領が変わるということは教育そのものが変わる</font>ということです。

個人的には学校教育のことを知りたい場合は、各教科の学習指導要領を
一読してみるとよいと思っています。。
学習指導要領は文部科学省のHPからダウンロードできます。
また、本屋や通販で購入することもできます。

## 学習指導要領の改訂
学習指導要領は<font color="OrangeRed">およそ10年サイクル</font>で大きく改訂されます。
平成に入ってからだと
1992年
2002年
2011年
2020年(予定)
に改訂されています。
学習指導要領の改訂にはPISA学力調査が関わってくるのですが、それはまた別のお話。

## 教科「情報」の必修科目
【現行】
・社会と情報
・情報の化学
<font color="OrangeRed">どちらか選択</font>で必修。
【改訂案】
・情報Ⅰ
・情報Ⅱ
<font color="OrangeRed">固定で</font>情報Ⅰが必修。

現行と異なり、必ず特定の情報の課目を履修する必要があります。
これにより、生徒全員が共通の教育を履修するというメリットが生まれます。

## 2020年次期学習指導要領の答申（概要）
2020年次期学習指導要領の答申が要約されているので、まずは原文のまま。

> ・ 共通必履修科目として、問題の発見・解決に向けて、事象を情報とその結び付きとして捉え、情報技術を適切かつ効果的に活用する力を全ての生徒に育む「情報Ⅰ」を設定。<font color="OrangeRed">全ての高校生がプログラミングによりコンピュータを活用する力を身に付けられるようにする。</font>
> ・ 選択科目として、「情報Ⅰ」の基礎の上に、情報システムや多様なデータを適切かつ効果的に活用する力や、情報コンテンツを創造する力を育む「情報Ⅱ」を設定。
> ・ コンピュータについての本質的な理解に資する学習活動としてのプログラミングや、より科学的な理解に基づく情報セキュリティに関する学習活動などを充実するとともに、統計的な手法の活用も含め、情報技術を用いた問題発見・解決の手法や過程に関する学習を充実する。

共通必履修科目を設ける理由が明記されています。
プログラミングの活用についても記載してあり、これまでとは一線を画す教育を
行おうという姿勢が見えます。

ただ、本当にこの要約通りの教育を行うようになった場合、教師の負担は確実に大きくなります。
正直、情報の専任教員が不足している現状でこれは出来る気がしません。
情報は兼任教員が多いため、抱えられる重みの教育方針とは思えません。

## 2020年次期学習指導要領の答申
<font color="OrangeRed">概要は5ページを8行にまとめたもの</font>なので、全文の答申で気になる部分を
ピックアップしました。

> 情報を<font color="OrangeRed">主体的に</font>収集・判断・表現・処理・創造し、受け手の状況などを踏まえて発信・伝達できる力や情報モラル等、<font color="OrangeRed">情報活用能力</font>を育む学習を一層充実する

教育的に重要なのは「主体的に」と「情報活用能力」でしょうか。
「主体的に」は指示を待つだけの人間に育ってほしくないこと。
「情報活用能力」はメディアリテラシーを身につけて欲しいこと。
だと思います。

> 情報科の学習は、社会、産業、生活、自然等の種々の事象の中から問題を発見し、<font color="OrangeRed">プログラムを作成・実行</font>したりシミュレーションを実行したりする

要約より明確に「プログラムを作成・実行」と記載されています。
コーディングのことだけではないと思いますが、高校生・教師にとっては未知であり、
不安を覚えるものだと感じます。

> データベースの基礎といった基本的な情報技術と情報を扱う方法とを扱う

DBについても言及されていました。
DBの概念について早いうちに教育をすることは良いことだと思います。
ただ、扱うとなった場合、少し敷居が高い気がしなくもないです。

> <font color="OrangeRed">プログラムの制作・実行環境等</font>については、情報科の趣旨を踏まえた授業の実施に適したアプリケーション等の開発・提供が必要であり、国等においては<font color="OrangeRed">民間等におけるそれらの開発・提供を促していく</font>必要がある。

さらっと、IT業界にとって重要なこと記載してますね。
教育業界向けの開発環境の構築や保守・開発の仕事が生まれそうです。
個人的には教育業界向けに一番必要なのはユーザビリティだと思います。

## さいごに
2020年次期学習指導要領に関する情報はまだほとんど出ておらず、
確実なことが言える状況ではありません。
だからこそ、情報を今のうちに集め、今後どのような教育を受けた人が
社会人となり、IT業界に参画してくるのか見極める必要があります。
IT業界にとって「学習指導要領の改訂」というのは単に教育方針が変わるだけなく、
営業のチャンス（リスク）となる一大イベントです。

今回は教員側の観点で記事を書きましたが、学習指導要領が変更されることで
一番影響を受けるのは教員ではなく、授業を履修する「生徒」です。
授業の履修者である生徒がきちんとやりがいや能力を身につけられる授業になる
学習指導要領の変更であることを望みます。

## 参考
<a href="http://www.mext.go.jp/component/b_menu/shingi/toushin/__icsFiles/afieldfile/2016/12/27/1380902_1.pdf">幼稚園、小学校、中学校、高等学校及び特別支援学校の学習指導要領等の改善及び必要な方策等について（答申）【概要】 </a>
<a href="http://www.mext.go.jp/b_menu/shingi/chukyo/chukyo0/toushin/__icsFiles/afieldfile/2017/01/10/1380902_0.pdf">幼稚園、小学校、中学校、高等学校及び特別支援学校の学習指導要領等の改善及び必要な方策等について（答申）</a>
フロントエンドでdotenvを使えるようにしてみた

# 目的
フロントエンドで```process.env.NODE_ENV==="development"```とかで条件分岐したかったので、コンパイル時にprocess.env.NODE_ENVを.envファイルにあるNODE_ENVの値を引っ張ってきて```"development"==="development"```と"使われてる値だけ"埋め込むようにする。

# 対象
webpack2が導入できている。

## STEP1 dotenvをインストール
dotenvは.envファイルをパースして読み込んでくれます。
optionを指定すれば、.env.productionなどをそのまま読み込めるようにできます。

```
$ npm install dotenv --save-dev
```

## STEP2 envを展開するモジュールを作成

```js
// .envを展開
dotenv = require('dotenv');
let options = {};
if (process.env.NODE_ENV === 'production') {
    options.path = '.env.production';
}
dotenv.config(options);

function middleware(value) {
    if (value === "true") return true;
    if (value === "false") return false;
    if (value === "0" || value === 0) return 0;
    return value || null;
}

exports.getEnvs = () => {
    let env = {};
    for (let key in process.env) {
        if (process.env[key]) {
            env['process.env.' + key] = JSON.stringify(middleware(process.env[key]));
        }
    }
    return env;
};
```

## STEP3 webpack.DefinePluginを使ってみる
```js:webpack.config.js
const path = require('path'),
    webpack = require('webpack'),
    env = require(path.join(__dirname, '/src/config/env.js'));

module.exports = {
    entry: {
        app: [
            'babel-polyfill',
            path.resolve(__dirname, 'src/index.js')
        ]
    },
    plugins: [
        new webpack.DefinePlugin(env.getEnvs())
    ],
    output: {
        path: path.resolve(__dirname, 'public/assets/js/dist/'),
        filename: 'game.js'
    },
};
```

これで好きなところでprocess.env.*を使えるよになりました！
気に入ったらいいねとストックとフォローお願いします！
#### 注意：envの値を変更したら毎回コンパイルし直してください。
Python入門①（はじめの一歩）


# HelloWorld


## PythonでHelloWorld

Pythonの**HelloWorld**は、以下の通り。

```HelloWorld.py
# HelloWorld
print("Hello World.")
```
これで、以下のように表示されます。
```実行結果
Hello World.
```

\#は、コメントを表します。

**print()**で、()内の内容を表示します。""および''で文字列を表します。

# 演算と変数


## 算術演算

pythonの基本的な算術演算は以下の通り

```calc.py
# pythonの算術演算
print(15 + 4)  # 足し算
print(15 - 4)  # 引き算
print(15 * 4)  # 乗算
print(15 / 4)  # 除算
print(15 // 4) # 切り捨て除算
print(15 % 4)  # 剰余
print(15 ** 4) # 15の4乗
```
実行結果は、以下の通りになります。
```実行結果
19
11
60
3.75
3
3
50625
```
Python言語は、原則的に他の言語と違い、**型指定が無い**ため、除算の結果は、割り切れなければ小数点以下の数値が表示されます。

小数点以下を省略したい場合には、切り捨て除算（//）が必要です。

### 計算の制限

Pythonで扱える数値は、**整数**と**浮動小数点**。

**整数で扱える範囲には上限がありません**。

```calc2.py
10 ** 100
```
実行結果は以下のようになります。
```実行結果
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
```

このような大きな数値は他の言語では扱えませんが、Pythonでは可能です。


## 変数の利用

変数は、以下の通り。

|演算子 　　　|意味         |使用例         |結果         |
|:-----------|------------:|:------------:|:-----------:|
|      +     |         加算|    1 + 4     | 5           |
|      -     |         減算|   13 - 14    |-1           |
|      *     |         乗算|    6 * 5     |30           |
|      /     |         除算|    7 / 8     |0.875        |
|      %     |         剰余|   11 % 3     |2            |
|     //     |  切り捨て除算|   9 // 2     |4            |
|     **     |         指数|   11 ** 2    |121          |
|   divmod   |     商と余り| divmod(10,7) |(1,3)        |

## 変数

### 簡単な変数

以下のように変数を扱うことが出来ます。**型指定はありません。**

```variable1.py
a = 2
b = 3
c = a - b
print(a + b)
print(c)
```
実行結果は以下のようになります。
```実行結果
5
-1
```


### 文字列の扱い

Pythonの文字列はすべてUnicodeで扱われます。文字列も変数で扱うことが出来ます。

```variable2.py
text="I love programming in Python."
print(text)
```

```実行結果
I love programming in Python.
```

###キーボードからの文字列の入力

キーボードから文字列を入力して変数に入れる処理を簡単に実現できます。

```input1.py
str = input("文字列を入力してください:")
print(str)
```
実行結果は以下のようになります。
```実行結果
文字列を入力してください:aaa　
aaa
```

キーボードから入力した数値は、**文字列**扱いになります。整数などに変更するには、以下のような処理が必要です。

```input2.py
# 文字列として、整数x,yを入力
x = input("x=")
y = input("y=")
# x,yを整数にして計算
sum = int(x) + int(y)
# 計算結果の出力
print(x + "+" + y + "=" + str(sum)) 
```
実行結果は次の通りです。
```実行結果
x=3
y=2
3+2=5
```

文字列の結合は、**＋**で行います。
```文字列の結合
'ABC'+'DEF'
'ABCDEF'
```
また、文字列を数値にするのは**int()**、逆に数値を文字列にするには**str()**を用います。

これで、基本的なpythonの書式の説明を終わります。

次は条件分岐について説明します。

[→ Python入門②（条件分岐編）](http://qiita.com/kameda05/items/35e4105fe5f69845e6e7)
Railsヘルパーメソッドのまとめ（よく使うもの）

##  ヘルパーメソッドとは？
ViewをよりシンプルにDRYに書くための、Railsで用意されたモジュール。
基本的にはviewをhelpしてくれるもの。自分で作ることもできる。

## 基本的なヘルパーたちの例
### form_tag
* フォームをどうにかしたい時に使う。
* name, value属性が必要。

### submit_tag
* submit機能をつけたいときに使う。
* `  <input name="****" type="submit" value="***" />`


```erb:form_tag/submit_tagの例
<%= form_tag,{ method:'path'}  do %>
// # method指定しない場合、デフォルトでpostになる,{}省略可能
  <%= text_field_tag :title, @note.title %>
// :title がname
// @note.titleがvalue
 <%= submit_tag '保存' %>
<% end %>
```

### text_field_tag
* テキストフィールド
* name,value属性が必要

### text_area_tag
* テキストエリア(行数のあるもの)
* `text_field_tag`と同じ使い方
      
### link_to ヘルパー
* リンク挿入の時に使う。
* "URL"部分には、名前付きルート　`root_XXXX`のしても可能
* 'テキスト'の部分は変数でもOK。
* idとclassはハッシュとして与えるが、｛｝省略可能

```erb:link_to
<%=link_to ’テキスト', "URL" , ｛id:"top-link", class: "btn top-btn"｝ %>
```


## How to Use
つくったヘルパーをコントローラで使えるようにするには、コントローラでヘルパーを定義したヘルパーファイルを
`include ヘルパー名`で読み込む必要がある。

helper定義

```rb:application_helper.rb
module ApplicationHelper

def current_user?(user)
  current_user.id == user.id
  end
end

```

helper呼び出し

```rb:users_controller.rb

class UsersController
     include ApplicationHelper
end

if !current_user?
```
```erb:show.htmr.erb
<% if current_user.id == @note.user.id %>

<% if current_user?(@note.user) %>

```
```rb:notes_controller.rb
if current_user.id != note.user.id
  redirect_to root_oath
end

def create
  @note = Note.new(note_params)
  @note.user_id = current_user.id
end
```
.htaccessでハマった事メモ

# どうした
今までググってなんとなく書いてた.htaccess。
当たり前すぎて出てこない事とかハマった事をメモ程度に書き残しておく。
※ 間違ってることとか一杯ありそうだけど指摘貰えると有り難い 

やっぱりちゃんと本読んだほうが良いよね……

# RedirectMatchは変数が使えない
なんとなく使ってたRedirectMatch。
特定のディレクトリをhttpsの新パスに転送…という動作をさせたかったので
ググったら変数でホスト名だけ引っ張れば楽じゃね？と思い実行してみた。

```
RedirectMatch   permanent   /test/ https://%{HTTP_HOST}/xxxx/
```
結果は「**https://%{HTTP_HOST}/xxxx/**」がそのまま返ってくる。
ああ使えないんだ…
正規表現もうまく動かないのでwebを参考にRewriteRuleで記述してみることに。

# RewriteRuleは行頭に/要らない
こんなのを書いて見たが全くマッチしない。
```
RewriteRule ^(/test/)$  %{HTTP_HOST}/xxxx/ [R=301,L]
```
なんでだお前どうした。さっきまでマッチはしてただろおい。

色々試行錯誤してみると
```
RewriteRule ^(test/)$  %{HTTP_HOST}/xxxx/ [R=301,L]
```
頭に**/**が要らないって言う。
こぴぺはダメだ。

# RewriteRuleで変換後、URIスキームを付けないとローカルパスに
先程の定義で実行してみると結果が、
**http://test.jp/home/user/www/test.jp/test/**
は？っと見てみるとなんか足りない。
```
RewriteRule ^(test/)$  %{HTTP_HOST}/xxxx/ [R=301,L]
```
スキーム無い。
**コピペしたんじゃねえのかよ**

```
RewriteRule ^(test/)$  https://%{HTTP_HOST}/xxxx/ [R=301,L]
```
スキームを付けて実行した所期待どおりのURLに。
スキーム無いとローカル指すのか…
gemをbuild & release の 2つの方法と違い

gemを作った後、buildしてreleaseする事で公開することができます。  

その際の２つの方法と違いを書いていきます。  


## bundlerを使う
１つ目はbundlerを使う方法です。  

**build**

```
$ bundle exec rake build
```

**release**

```
$ bundle exec rake release
```

こちらの方法では、buildした後にできる`.gem`ファイルが`pkg/`の下に作られます。


## gemコマンドを使う
2つ目はgemコマンドを使う方法です。

**build**

```
gem build xxxx.gemspac
```

**release**

```
gem push xxx-x.x.x.gem
```

こちらの方法だと、`.gem`ファイルがプロジェクトのルートディレクトリに作られます。  

## まとめ
`pkg`の下に作られる方が僕は好きです。
python3のrequestsを使って画像を保存



# requests を用いて画像を保存



```py3
# -*- coding: utf-8 -*-

import requests
import shutil

def download_img(url, file_name):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        with open(file_name, 'wb') as f:
            r.raw.decode_content = True
            shutil.copyfileobj(r.raw, f)

if __name__ == '__main__':
    download_img('ここにURLを書く', '保存したいファイル名を書く')

```

以下のような内容の編集リクエストを頂いたので合わせて載せておきます。（若干変更を加えました。）
こっちのほうがスマートかもしれません。

```py3
# -*- coding: utf-8 -*-

import requests

def download_img(url, file_name):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        with open(file_name, 'wb') as f:
            f.write(r.content)

if __name__ == '__main__':
    download_img('ここにURLを書く', '保存したいファイル名を書く')

```

# 参考

https://stackoverflow.com/questions/13137817/how-to-download-image-using-requests

https://torina.top/detail/161/

<a href='https://docs.python.jp/3/library/urllib.request.html'>urllib.request.urlretrieveについて</a>

<a href='http://requests-docs-ja.readthedocs.io/en/latest/user/quickstart/'>requests（クイックスタート）</a>

<a href='https://docs.python.jp/3/library/shutil.html'>shutilのドキュメントページ</a>
[S3]GUIでフォルダ以下のオブジェクトのメタデータ（e.g Cache-Control）を一括で変更する

S3であるフォルダ以下のすべてのオブジェクトはGUIでは操作できなかった気がしますが、GUIでも操作できるようになったようです。
今回はあるフォルダ以下のオブジェクトにCache-Controlをつけてみた手順をまとめました。

この記事は個人ブログにも掲載しています。
http://tackeyy.com/blog/posts/how-to-change-all-of-objects-metadata-under-the-folder-with-s3-gui

# 0. Cache-Control が設定されていないことを確認する

レスポンスに ` Cache-Control ` がないことをcurlで確認します。

```
$ curl -I https://hoge.cloudfront.net/path/file_name.jpg
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 4029
Connection: keep-alive
Date: Wed, 23 Aug 2017 14:04:16 GMT
Last-Modified: Wed, 23 Aug 2017 09:21:59 GMT
ETag: "7f3cdedd668a9e441dc3a72f6bcf791a"
Accept-Ranges: bytes
Server: AmazonS3
X-Cache: Miss from cloudfront
Via: 1.1 39d343f70d4ae3c992fb92c90e2bb741.cloudfront.net (CloudFront)
X-Amz-Cf-Id: TkQIRlmFhzCWTQDdUETXJlZBFSI7qysH0_COp1y-TKOnGS1_qlgM7g==
```

S3をオリジンにしてCloudFrontを使っているのでCloudFrontのURLをcurlでリクエストしていますが、もちろんS3のURLでも大丈夫です。

# 1. フォルダを選択してメタデータを変更する

[![https://gyazo.com/40b869005c64452017c6b927e209888c](https://i.gyazo.com/40b869005c64452017c6b927e209888c.png)](https://gyazo.com/40b869005c64452017c6b927e209888c)

# 2. ` Cache-Control ` ` max-age=604800 ` を追加する

> 静的なリソースのキャッシュの有効期間は 1 週間以上にしてください。
> https://developers.google.com/speed/docs/insights/LeverageBrowserCaching

特に理由がない場合は、上記の記述に従って 604800秒 = 7日 を設定すれば良いかなと思います。

[![https://gyazo.com/f1f2894fc62ccf29c29e73290293815d](https://i.gyazo.com/f1f2894fc62ccf29c29e73290293815d.png)](https://gyazo.com/f1f2894fc62ccf29c29e73290293815d)

# 3. CloudFrontを利用している場合は、キャッシュを削除する

CloudFrontを利用してる場合は、キャッシュが効いてしまうのでキャッシュをクリアします。
` Create invalidation `  をクリック後にURLを入れます。

[![https://gyazo.com/f6a4278b38142021ac3d5be207e06f55](https://i.gyazo.com/f6a4278b38142021ac3d5be207e06f55.png)](https://gyazo.com/f6a4278b38142021ac3d5be207e06f55)

すべてのディレクトリ以下を対象とするので ` /* ` とします・
` /uploads/hoge/* ` などのように階層を限定したりしても良いです。

[![https://gyazo.com/d03c286e50b98201d0dade216fe80de6](https://i.gyazo.com/d03c286e50b98201d0dade216fe80de6.png)](https://gyazo.com/d03c286e50b98201d0dade216fe80de6)

` in progress ` が ` completed ` になれば完了です。

[![https://gyazo.com/f6a4278b38142021ac3d5be207e06f55](https://i.gyazo.com/f6a4278b38142021ac3d5be207e06f55.png)](https://gyazo.com/f6a4278b38142021ac3d5be207e06f55)

最初と同じコマンドで ` Cache-Control ` が含まれているか確認します。

```
$ curl -I https://hoge.cloudfront.net/path/file_name.jpg
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 4029
Connection: keep-alive
Date: Wed, 23 Aug 2017 14:04:16 GMT
Last-Modified: Wed, 23 Aug 2017 09:21:59 GMT
ETag: "7f3cdedd668a9e441dc3a72f6bcf791a"
Cache-Control: max-age=604800 # これ
Accept-Ranges: bytes
Server: AmazonS3
X-Cache: Miss from cloudfront
Via: 1.1 39d343f70d4ae3c992fb92c90e2bb741.cloudfront.net (CloudFront)
X-Amz-Cf-Id: TkQIRlmFhzCWTQDdUETXJlZBFSI7qysH0_COp1y-TKOnGS1_qlgM7g==
```

# さいごに

すべてのディレクトリ以下のオブジェクトのメタデータを変更するのは怖かったので、僕の場合はディレクトリを限定して上記のプロセスを一通り試した後で、すべての階層以下のオブジェクトにCache-Controlをつけました。
とくに事故らなかったので良かったです。
[Terraform] CloudTrail作成時に発生した InvalidCloudWatchLogsRoleArnException を解消。

# 発生事象
Terraform で CloudTrail を作成しようとした際に、下記のエラーが発生した。

```
* aws_cloudtrail.trail: InvalidCloudWatchLogsRoleArnException: Access denied. Check the trust relationships for your role.
```

もう一度実行すると正常終了するため、タイミングの問題ですね。
（リソース作成完了と、そのリソースを参照する後続リソース作成処理のタイミング）

尚、これは CloudWatchLogs にログを出力するよう設定するときに発生する。
使用するtfリソースは以下。

* aws_cloudtrail
* aws_cloudwatch_log_group
* aws_iam_role
* aws_iam_role_policy


# 解消方法

これが問題解消のための必要最低限の設定か？と言われると「No」かもしれません。
冗長なところがあるかも。

① CloudWatchLogGroup 作成後にsleep。
作成完了して使えるようになるまで待つ。

~~~
resource "aws_cloudwatch_log_group" "cloudtrail" {
  ...
  provisioner "local-exec" {
    command = "sleep 10"
  }
}
~~~

②CloudTrailに付与するロールを作成し、ポリシーアタッチして、sleep。
権限付与して使えるようになるまで待つ。

~~~
resource "aws_iam_role" "cloudtrail" {
  ...
}

resource "aws_iam_role_policy" "cloudtrail" {
  role = "${aws_iam_role.cloudtrail.id}"
  ...
  provisioner "local-exec" {
    command = "sleep 10"
  }
}
~~~

③CloudTrailの作成は、LogGroupの作成とロールへのポリシー付与が完了するまで待つ。
「depend_on」で、sleepまで含めたリソース設定が完了してから走り出すようにする。

~~~
resource "aws_cloudtrail" "trail" {
  ...
  depends_on = ["aws_iam_role_policy.cloudtrail", "aws_cloudwatch_log_group.cloudtrail"]
}
~~~



# 考慮点

Terraform は、tfファイルに書かれた内容を解析して依存関係順に処理してくれる。
依存関係がないものは並列処理してくれる。

だが、依存関係があっても、リソースが確実に使える状態になっていることまでは確認してくれない。
時間の掛かるリソース作成処理がある場合は、明示的に待たせないとエラーになる可能性がある。

CloudTrail作成時にはロールに権限が付与されている必要があり、AWS的には依存関係がある。
だが、tfファイルの aws_cloudtrail に書くのは role_arn であるため、Terraformの解釈としてはポリシー付与までは依存関係に含まれない。
そのためCloudTrail作成とポリシー付与とが並列で動き、権限がないままCloudTrailを作成しようとしてエラーが発生する。
application:openURL:sourceApplication:annotation

以下のメソッドはiOS9までのもので代わりにapplication:openURL:options:を使うことになる。

```
- (BOOL)application:(UIApplication *)application 
            openURL:(NSURL *)url 
  sourceApplication:(NSString *)sourceApplication 
         annotation:(id)annotation;
```
# 詳細

URLで指定されたリソースを開くかたずねられている。	
このメソッドについての実装は特定のURLについて開き、それに従ってUIを更新する必要がある。

URLを開くためにアプリを起動する必要がある場合、
アプリはapplication:willFinishLaunchingWithOptions:とapplication:didFinishLaunchingWithOptions:をまず最初に読み出し、その後にこのメソッドを続けて呼び出す。

これらの２つのメソッドの返却を用いて、このopenURLのメソッドが呼ばれないようにすることができる。

(もし、アプリがすでに起動している場合は単にこのopenURLメソッドが呼ばれる。)

## UIDocumentInteractionController
もし、URLがUIDocumentInteractionControllerによってopenURLされていたものなら、annotationにはsourceアプリがURLとともに送りたいデータが入っている可能性がある。このデータの形式は送信したアプリによって定義されるが、プロパティリストに入れることができるオブジェクトで構成していなければならない。

AirDropやUIDocumentInteractionControllerを通して送られたファイルはアプリのホームディレクトリのDocuments/Inbox directoryに入れられる。

アプリはこのディレクトのファイルを読んだり消したりする権限を持つが、書き込む権限を持たない。ファイルを修正したい場合はまず違うディレクトリに動かす必要がある。

くわえて、ディレクトリ内のファイルはデータプロテクションを用いてたいてい暗号化されている。もしファイルがプロテクトされていて、ユーザがこのメソッドが呼ばれる前にデバイスをロックをした場合、このファイルの内容は直ちに読むことができなくなる。その場合はこのメソッドでNOを返却するのではなく、URLを一度保存して、あとでファイルを開くことを試みるようにすべきである。

データのプロテクションが現在有効かどうかの判断には
アプリのprotectedDataAvailableプロパティからわかる。

## Notification
このメソッドに対するnotificationは存在しない。


# Parameters	
application
自分のアプリ(シングルトン)

url
開かれるURL。ネットワークでもファルでも良い。Apple URL Scheme Reference参照。

sourceApplication
リクエストを送ったアプリのbundle ID。

annotation
アプリ間で情報を交換するために送信側から提供されるプロパティリスト。

Returns	
URLが対応できるものならYES、対応できないURLならNO;
連番のファイルが存在するか否かをチェックする．

## 概要

大量の連番のファイルがあったとき，途中の番号が抜けているかを目で確認するのは面倒です．
それを確認するシェルスクリプトを作成しました．

ファイル名のフォーマットを指定し，```seq```コマンドで連番になっているかを確認します．

## スクリプトファイル

以下のスクリプトを exists などのファイルに保存し，実行権限を与えてください．

```bash
#! /bin/sh

check_range () {
    # echo "check_range($1, $2, $3, $4)"

    for i in $(seq $1 $2)
    do
        FILENAME=$(printf "$4" $i)
        if [ ! -f "$3/$FILENAME" ] ; then
            echo "$3/$FILENAME skipped"
        fi
    done
}

show_help () {
    echo "${0##*/} [OPTIONS] [FROM] <TO> <DIR...>"
    echo "OPTIONS"
    echo "  -f <FORMAT> ファイル名のフォーマットをprintf形式で指定する．デフォルトは %d．"
    echo "  -h          このメッセージを表示して終了する．"
    echo "ARGUMENTS"
    echo "  FROM        連番の最初の数値．デフォルトは1．"
    echo "  TO          連番の最後の数値．"
    echo "  DIR         調査するディレクトリのリスト．"
}

FORMAT="%d"
START=1

while getopts hf: OPT
do
      case $OPT in
          "h" ) SHOW_HELP="TRUE" ;;
          "f" ) FORMAT="$OPTARG" ;;
      esac
done

shift $((OPTIND - 1))

if [ "$SHOW_HELP" = "TRUE" ] || [ $# -le 1 ]; then
    show_help
    exit 0
fi

if [ $# -ge 3 ]; then
    START=$1
    shift
fi

END=$1

while [ $# -ne 1 ]
do
    shift
    TARGET=$1

    check_range "$START" "$END" "$TARGET" "$FORMAT"
done
```

### 参考サイト

* [引数を処理する](http://shellscript.sunone.me/parameter.html)
* [bash によるオプション解析](http://qiita.com/b4b4r07/items/dcd6be0bb9c9185475bb)
* [シェルスクリプトで関数を利用する](http://qiita.com/kaw/items/034bc4221c4526fe8866)
軽量ORMの Idiorm でデータベーステーブルのカラム一覧を取得する

Idiormにかぎらず、LaravelなどのORMでも使える手法と思います。

# ちゃんとSQLする方法

改めて調べてみないとなかなかパッと出てこない、SQLでカラム名を取得する方法。出てくるのがカラム名だけではないので、SELECTしてやることと、出て来る配列がちょっとキモチワルイので、array_column でカラム名だけの配列に直しています。

```php
$result = \Database\Idiorm\ORM::for_table( 'information_schema.columns' )
->select('column_name')
->where('table_name','my_table_name') // ここにテーブル名
->order_by_expr('ordinal_position')
->find_array();

$columns = array_column($result,'column_name');
```

# 難しいことを考えない方法

レコードを１つ配列で取得して、そのインデックスを拾えばいいじゃん、というネタ。あまりに巨大なデータが入っているとパフォーマンスが悪くなるかもしれないのと、そもそもレコード数がゼロだと動かないという致命的デメリットがあります。

```php
$record = MyModel::factoryModel()->limit(1)->find_array();

$columns = array_keys($record[0]);
```

メリットは、テーブル名が必要ないこと、かな。

# ベストプラクティス？

でもそれだったら、最初から「ちゃんとSQLする方法」でメソッドを作っておけばいいと、個人的には思います……。

```php
class MyModel extends Model {

  public static function getColumns(){
    $result = \Database\Idiorm\ORM::for_table( 'information_schema.columns' )
    ->select('column_name')
    ->where('table_name', $this->_table ) 
    ->order_by_expr('ordinal_position')
    ->find_array();

    return array_column($result,'column_name');
  }
}

$columns = MyModel::getColumns();
```


# 余談

以上、難しいことを考えない方法でやってるコードを見つけて、ちゃんとSQLする方法を調べてみた、という闘いの記録でした……。
半角空白ありの一列の数値の入力値を変数に入れる

### 分解しないで変数に入れる場合
配列aに数値群をそのまま入れる。

```rb:
# input => 1 2 3
a = gets.split.map(&:to_i)
p a
# output => [1,2,3]
```

### 1つずつに分解して変数に入れる場合

個数がもし決まって入れば、`.map`して複数の変数に入れたいとき、変数をカンマで区切ることができる。
splitはデフォルトで空白で区切ってくれる。

```rb:
# input => 1 2 3
s1,s2,s3=gets.split.map(&:to_i) 
p s2 + s3
# output => 5
```

.mapの部分を分解するとこう。

```rb:
.map{|item| item.to_i}
```
RDSへのnc疎通確認方法


bastionなり何なりに接続（inboundされてるならどこでもええ）

`nc endpoint port -v`

-vはバージョン確認

## redisの場合

```
[xxxxx@xx-xx-prd-mgr ~]$ nc xx-xx-xxx-ca-002.xxxxxx.ng.0001.xxx.cache.amazonaws.com 6379 -v
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connected to 10.xx.xxx.xx:6379.
```

こんな感じで出力される。
んで
info
と打つとそのredisの情報が見れる。

## RDSの場合

```
[xxxxx@xx-xx-prd-mgr ~]$ nc xx-xx-xx-dba-userxx-xx.xxxxxxx.us-west-2.rds.amazonaws.com 3306 -v
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connected to 10.xx.xxx.xxx:3306.
```

こんな感じ
CentOS 7.3でyum install nodejsが失敗するので回避する

# はじめに
2017/08/13頃から**yum -y install nodejs**すると**http-parser**の依存関係でコケるようです。
**http-parser**がRedHat Baseリポジトリに7.4で追加されたため、EPELから削除され、そのために失敗するようです。
参考URLの情報では**http-parser**を別にインストールすれば問題ないということなので対応してみました。

# 環境
- CentOS Linux release 7.3.1611 (Core)

# コケる
```
# yum -y install nodejs

～省略～

エラー: パッケージ: 1:nodejs-6.11.1-1.el7.x86_64 (epel)
             要求: http-parser >= 2.7.0
エラー: パッケージ: 1:nodejs-6.11.1-1.el7.x86_64 (epel)
             要求: libhttp_parser.so.2()(64bit)

～省略～
```

# 回避策
```
# rpm -ivh https://kojipkgs.fedoraproject.org//packages/http-parser/2.7.1/3.el7/x86_64/http-parser-2.7.1-3.el7.x86_64.rpm
https://kojipkgs.fedoraproject.org//packages/http-parser/2.7.1/3.el7/x86_64/http-parser-2.7.1-3.el7.x86_64.rpm を取得中
準備しています...              ################################# [100%]
更新中 / インストール中...
   1:http-parser-2.7.1-3.el7          ################################# [100%]
```

# 再度実行
```
# yum -y install nodejs
～省略～
インストール:
  nodejs.x86_64 1:6.11.1-1.el7                                                                                                                                                

依存性関連をインストールしました:
  libicu.x86_64 0:50.1.2-15.el7                           libuv.x86_64 1:1.10.2-1.el7                           npm.x86_64 1:3.10.10-1.6.11.1.1.el7                          

完了しました!
```

# おわりに
無事インストールできた。
CentOS7.4がリリースされたら起きなくなるっぽいんですかね？
[ブログにも書いてます](https://toshi.click/workaround-0001/)

# 参考
[https://bugzilla.redhat.com/show_bug.cgi?id=1481008](https://bugzilla.redhat.com/show_bug.cgi?id=1481008)
CentOS7  CEPH测试环境搭建步骤

使用的官方的教程，ceph-deploy进行安装和部署。

## 环境准备
最小要求是准备4台虚拟机。1台作为管理机，作用是安装程序和创建服务应用。
1台为mon节点，2台为node节点。mon和node节点都需要挂载一块除系统使用外的硬盘，用来做存储用。

为了安装能顺利进行，还要准备相应的账号、sudo权限、镜像站点、安全配置

测试环境使用的是CENTOS7，安装按照默认即可。

## 系统参数配置

* 账号。ceph需要一个统一的不是ceph的账号，这个普通账号需要具有sudo权限，并且sudo应该是免密码的。本测试使用qyceph。

创建账号

```shell
useradd qyceph
passwd qyceph
```
* sudo配置

使用visudo编辑sudo配置

```
#comment the tty conf
#Defaults    requiretty

#add
qyceph	ALL=(ALL)	NOPASSWD: ALL

```

* 镜像站点

找了几个镜像站点

```
https://mirrors.163.com/ceph/
https://mirrors.aliyun.com/ceph/
```

* 关闭selinux和firewalld
* 为了方便访问配置hostname 以及 hosts

每个节点都写一样的hosts，例如：

```
192.168.1.240 ceph-admin
192.168.1.241 ceph-node1
192.168.1.242 ceph-node2
192.168.1.243 ceph-node3

```
*统一配置timezone和ntpserver
为了保持时间一直需要安装ntpdate并配置crontab做时间同步

```shell

timedatectl set-timezone 'Asia/Shanghai'
yum install ntpdate -y

#crontab add 
*/10 * * * * ntpdate cn.pool.ntp.org
```

* admin节点需要生成ssh-key，并同步到其他节点

```
ssh-keygen

ssh-copy-id qyceph@192.168.1.241
ssh-copy-id qyceph@192.168.1.242
ssh-copy-id qyceph@192.168.1.243
```

## 安装
###Admin节点上

```shell
mkdir my-cluster
cd my-cluster
```

* 创建ceph集群并定义mon节点，命令会创建ceph.conf并将ceph-node1节点定义为mon

```shell
ceph-deploy new ceph-node1 ceph-node2
```
> 默认的osd是3份，为了测试可以修改ceph.conf，在[global]下增加配置改为2.
> 另外一个就是最好增加 public network={ip-address}/{netmask}

  ```
  osd pool default size = 2
  public network={ip-address}/{netmask}
  ```
  
* 给每个节点安装ceph程序

```shell
ceph-deploy install ceph-node1 ceph-node2 ceph-node3
```

>如果这样安装比较慢，可以直接手动在节点上安装好epel和ceph的安装包。
> 
```
rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
#ceph.repo需要自己配置
yum install ceph-osd ceph-common ceph-selinux ceph-release ceph-mds ceph-mon ceph-radosgw ceph-base -y
```

* 初始化mon节点

```
ceph-deploy mon create-initial
```
> 此命令会将之前定义的mon节点进行初始化配置，新的版本会自动启动mon节点，完成选举。
> 此命令完成后，会在my-cluster目录创建keyrings
> {cluster-name}.client.admin.keyring
> {cluster-name}.bootstrap-osd.keyring
> {cluster-name}.bootstrap-mds.keyring


* 创建osd。格式是  主机:磁盘  

```shell
ceph-deploy osd prepare ceph-node1:/dev/vdb ceph-node2:/dev/vdb ceph-node3:/dev/vdb
```


### 在ceph-node1节点上

* 查看集群状态

```shell
ssh ceph-node1 
ceph health
```

至此，一个测试集群就已经可以测试使用了。不过，现在只能做object storage，其他的还不能做。需要在mon节地上部署增加功能才能支持rbd和cephfs。




## ceph集群扩展

### 增加一个mon节点

可以新配置一个节点，只要系统配置和软件都配置好了，可以使用ceph-deploy方便的将节点加入。

**注意事项：一定要注意机器的时间保持一致，尤其是时区。**

```shell
ceph-deploy mon create ceph-node4
```

>如果增加过程都正常，最后会提示
ceph-node4 is not defined in `mon initial members`

>这主要是ceph动态的将ceph-node4加入到mon里。一下命令查看mon信息

```shell
ceph quorum_status --format json-pretty

```
gitのprivateレポジトリからのcloneにはまった件を晒す

# githubのprivateレポジトリをcloneする

- このprivate repoのuserは自分じゃない。
- membersの中に自分がいる。
- 新しいアカウントを仕事用につくったばっかりだった

この三点を踏まえた上で
gitをcloneするととにかくうまくいかない。
もしや権限ない。はぶかれてる、、、、？と人を疑い、そしてmembersのところを確認しに行く迷走ぷりをして
ついに、耐えられずに他の人に質問にいった。

そして、なんどもconfigファイルを見直し、、

結局は鍵の登録がされてなくて、
cloneできなかった。

新しいアカウント作ったら鍵の登録を最初にやろう、と決めた夏の日でした。
calabash android on windows

# install
## install ruby
Install ruby runtime from https://rubyinstaller.org/.
I installed ruby 2.4.1 x64 and msys2 with dev kit.

## install ansicon
Download archive from below URL.
https://github.com/adoxa/ansicon/downloads

And extract it. Then move to x64 dir in extract dir and type below command to automatically start ansicon.

    $ ansicon.exe -i

## install bundler

    $ gem install bundler

# run
## prepare calabash

Make Gemfile in Android project root as below.

    # Contents of Gemfile
    source "https://rubygems.org"
    
    gem 'calabash-android'
    gem 'cucumber'

And run bundle install command

    $ bundle install

## sign apk

    $ bundle exec calabash-android resign ${apk_path}


## run

  bundle exec calabash-android run ${apk_path}
Amazon Athenaのパーティション追加めんどくさい

S3のバケットに
```
s3://バケット名/HOGE/20170824/00_0.gz
s3://バケット名/HOGE/20170824/00_1.gz
```
みたいな感じでログを置いています。

Athenaを利用して軽く集計してみようかなーと思ったところ、パーティションを分ける必要がありました。
(分けないでも実行できるけど、よりお金かかるから分けたほうがいい）

Hiveフォーマットに沿って格納されていれば簡単だけど、上記のように `20170824` だとそれぞれでAlter Tableを叩かないといけないのでめんどくさい・・・

ので、開始日と終了日を指定してわーっとAlter Table叩いてくれるShell Scriptを書きました。

```
#!/bin/sh

STARTDATE=2016-11-01
ENDDATE=2020-10-31

CURRENTDATE=$STARTDATE
while [ 1 ] ; do
        CURRENTYEAR=`date -d "$CURRENTDATE" "+%Y"`
        CURRENTMONTH=`date -d "$CURRENTDATE" "+%m"`
        CURRENTDAY=`date -d "$CURRENTDATE" "+%d"`

        aws --region ap-northeast-1 athena start-query-execution --query-string "ALTER TABLE データベース名.テーブル名 ADD PARTITION (year=$CURRENTYEAR,month=$CURRENTMONTH,day=$CURRENTDAY) location 's3://バケット名/HOGE/$CURRENTYEAR$CURRENTMONTH$CURRENTDAY/'" --result-configuration OutputLocation=s3://結果出力先

        if [ $CURRENTDATE = $ENDDATE ] ; then
                break
        fi

        CURRENTDATE=`date -d "$CURRENTDATE 1day" "+%Y-%m-%d"`
done
```

おしまい。
onlineで図を作成

オブジェクト図：
plantuml.com

シーケンス図：
https://www.websequencediagrams.com

ER図：
https://github.com/BurntSushi/erd
https://github.com/ftomassetti/erd-web-server

---
<pre>
centos：
sudo yum install haskell-platform
sudo yum install graphviz
cabal install
cabal update
cabal configure
cabal build
cd dist/build/
./erd -i ../../../examples/simple.er -o simple.pdf

---web-server
cabal update
cabal install
erd-web-server -p 8000
# or
dist/build/erd-web-server/erd-web-server -p 8000
---

Windows：
 githubからソースをクローン
 http://www.haskell.org/platform/からWindows版をインストール
 Graphvizをインストール
  環境変数のpathに「C:\Program Files (x86)\Graphviz2.38\bin」を追加

 cmdで以下のコマンドを実行
   cd D:\work\erd
   cabal update
   不要かもcabal install graphviz
   cabal configure
   cabal build
   cd dist\build\erd\
   erd -i examples/nfldb.er -o nfldb.pdf
</pre>
ZRouterでIPv6

なんとなく思いついてZRouterにIPv6なプロファイルを作ってみました。

ipv6のプロファイルを選択するとINET6のoptionが設定されたカーネルができあがります。ライブラリなどの作り直しも必要なので、objディレクトリのtmpの下のファイルを消してフルビルドした方が良いです。

とりあえずちょうどいじっていたAR7240(mips)でビルドしてみました。最近margeした12-Currentベースでもちろんすんなりビルドは通ります。

| INET6 | カーネルサイズ |
|:---|:---|
| なし | 3970340 |
| なし(圧縮) | 938876 |
| あり | 4268736 |
| あり(圧縮) | 1012733 |

素の状態で7%くらい大きくなっています。

```
# ifconfig arge1
arge1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 62:73:64:5a:22:54
        inet 10.10.10.70 netmask 0xffffff00 broadcast 10.10.10.255 
        inet6 fe80::6073:64ff:fe5a:2254%arge1 prefixlen 64 scopeid 0x6 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        media: Ethernet 1000baseT <full-duplex>
        status: active
# ping6 -c 10 fe80::213:3bff:fe12:8104%arge1
PING6(56=40+8+8 bytes) fe80::6073:64ff:fe5a:2254%arge1 --> fe80::213:3bff:fe12:8
104%arge1
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=0 hlim=64 time=1.107 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=1 hlim=64 time=0.624 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=2 hlim=64 time=0.660 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=3 hlim=64 time=0.664 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=4 hlim=64 time=0.652 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=5 hlim=64 time=0.643 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=6 hlim=64 time=0.644 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=7 hlim=64 time=0.664 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=8 hlim=64 time=0.624 ms
16 bytes from fe80::213:3bff:fe12:8104%arge1, icmp_seq=9 hlim=64 time=0.658 ms

--- fe80::213:3bff:fe12:8104%arge1 ping6 statistics ---
10 packets transmitted, 10 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.624/0.694/1.107/0.138 ms
# 
```

無職で貧乏なので、光とか使えないので、外とv6な通信ができません。T T
ここがすごいよ Hsakell の $ 演算子

[ブログ記事](http://secret-garden.hatenablog.com/entry/2017/08/11/003727)からの転載です。

最近ちょろっと Haskell を書いてて 『$ 演算子すげー』ってなったので勢いでまとめてみる。  
Haskell に明るくないのでゆるふわな感じで書いていくよー。  
（ちなみに `$` 自体の具体的な解説はしない。


## 関数適用と演算子の優先順位

他言語をやってから Haskell を学び始めると次のようなコードを書いてしまうことが多いと思う。  

```haskell
main = do
	-- 1 + 2 の結果を出力したいなっ
	print 1 + 2
```

しかし、上記のコードでは次のようなエラーになってしまう。

```
test.hs:3:16:
    No instance for (Num (IO ())) arising from a use of ‘+’
    In the expression: print 1 + 2
    In an equation for ‘main’: main = print 1 + 2
```

これは Haskell では『演算子よりも関数適用の優先順位が高い』ためである。  
どういうことかというと括弧がない場合、 Haskell では以下のように解釈してしまうからである。  

```haskell
(print 1) + 2
```

つまり

* `1 + 2` の結果を `print` に渡す

のではなくて

* `print 1` の結果を `+ 2` する

という処理になる。  
こういう場合は括弧を使用して処理の優先順位を明示化して回避する必要がある。

```haskell
main = do
	-- 先に 1 + 2 を処理するよ！
	print (1 + 2)
```


## 括弧の代わりに $ を使う

さて、括弧を使うことで回避することは出来た。  
しかし、『いちいち括弧を書きたくない！！』というのが人の性でである。  
そういう場合によく利用されているのが `$` 演算子である。  
この `$` 演算子を使うことで次のようにして括弧を記述することなく適切に処理を行う事が出来る。  

```haskell
main = do
	-- 1 + 2 が先に処理されるよ！
	print $ 1 + 2
```

やったね！！これで括弧を書かなくてよくなったよ！！


## `$` 演算子の仕組みを解説

と、いうだけだと物足りないのでもう少し `$` 演算子の仕組みについて解説。  
先ほど『関数適用よ演算子よりも関数適用の優先順位が高い』とかいた。  
なので

```haskell
f 20 + f 10
```

みたいな処理は

```haskell
(f 20) + (f 10)
```

のように『`f` 関数を先に適用してから』 `+` 演算子が呼び出されることになる。  
これを別の視点から考えてみると演算子の『左辺』と『右辺』を先に処理するという風に解釈する事が出来る。  
同様に `+` 演算子を $` 演算子に置き換えて考えてみると

```haskell
f $ g 10
```

は

```haskell
(f) $ (g 10)
```

のように処理される。  
つまり `$` 演算子を使うことで『左辺と右辺を別々に処理する』という事ができるようになるのである。  
これにより `$` 演算子で括弧を使わなくても処理の優先順位を制御することが出来ることになる。    
ちなみに `$` 演算子は演算子の中で優先順位が低いので

```haskell
print $ 1 + 2
```

は

```haskell
(print $ (1 + 2))
```

となる。


## まとめ

* `$` 演算子は処理の優先順位を制御できる
  * これにより括弧の記述を省略する事が出来る
* Haskell において演算子よりも関数適用のほうが優先順位が高い
  * `f a + g h` は `(f a) + (g h)` となる
* 式が複雑になってくるなら素直に括弧を書こう

あと `$` が具体的にどういう関数なのかはあえてここではかかないけど、気になったら調べてみてね！！
Highchartsで各チャートアニメーション完了後にSVGを描画する。

## Highchartsで各グラフアニメーション描画後Event設定。

- 折れ線を5本、時間ずらして描画する。
- afterAnimateイベントでSVG描画する。

```js

    plotOptions: {
        series: {
            pointStart: 2010,
            'events': {
                'afterAnimate': function () {
                    this.chart.renderer.text(this.name + ' completed', this.chart.plotLeft, 100 + this.index * 20)
                        .css({
                            color: this.color,
                            fontSize: '16px'
                        }).add();
                }
            }
        }
    },

    series: [{
        name: 'A市',
        'animation': {
            'duration': 1000,
            'easing': 'linear'
        },
        data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
    }, {
        name: 'B市',
        'animation': {
            'duration': 2000,
            'easing': 'linear'
        },
        data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
    }, {
        name: 'C市',
        'animation': {
            'duration': 3000,
            'easing': 'linear'
        },
        data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
    }, {
        name: 'D市',
        'animation': {
            'duration': 4000,
            'easing': 'linear'
        },
        data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
    }, {
        name: 'E町',
        'animation': {
            'duration': 5000,
            'easing': 'linear'
        },
        data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
    }]
```

- デモ: http://jsfiddle.net/niiyz/0hjrLonu/
ngrokをubuntu16.04上にインストール

参考　
[how to install ngrok in linux/ubuntu - YouTube](https://www.youtube.com/watch?v=-t6Fvcxhbaw)
[Mac上にngrokをインストール - Qiita](https://qiita.com/BeMarble/items/295109dadf92ff560a58)

ngrok を使って気軽に手元のサーバを外部に公開する方法です
###ngrok とは

ngrok
https://ngrok.com/

自分の手元の環境をそのまま外部からアクセスできるようにするためのツールです。

公開用サーバを立てるのがめんどくさいときなどに便利です。

###インストール (ngrok公式サイトのやり方ではunzipできない。)
https://ngrok.com/download へ行き、

>
Step 1: Download ngrok
Mac OS X 64-Bit 	Download
Windows 64-Bit 	Download
Linux 64-Bit 	Download
Linux ARM 	Download
FreeBSD 64-Bit 	Download

というボタンがあるのでlinux 64-bitのdownloadボタンをクリックしてダウンロードして好きな場所に解凍。

$ ngrokのあるフォルダに移動。
`$ sudo cp ngrok /usr/bin/`

終了

起動

80番ポートを外部に公開する

`$ ngrok http 80`
アクセスする

`$ curl http://[ランダムな文字列].ngrok.io`

ユーザー登録

Github, Twitter で認証可能

`$ ngrok authtoken [サイト上で発行された文字列]
Authtoken saved to configuration file: /Users/[ユーザー]/.ngrok2/ngrok.yml`
サブドメイン名を指定して利用

有償プランのみ可能 ($5/month~)
https://dashboard.ngrok.com/billing/plan

`$ ngrok http 80 --subdomain=hogehogehoge
$ curl hogehogehoge.ngrok.io`

ビジネスプランに入るとIPアドレスのホワイトリスト設定ができます。

## mac編

ngrokコマンドが使えないときは、
usr/local/binに、ngrokアプリが存在しない時。
そのため、
sudo mv ngrok usr/local/bin
とすると、ngrokコマンドが使えるようになる。
Windows 10 IoTの備忘メモ

# コマンド色々(ホスト名はminiwinpcにしてます)
PowerShellを管理者で実行

```
# Remote Service を起動
net start WinRM

# 信頼する端末に登録(最初のみ)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value minwinpc

# コンソールに接続
Enter-PsSession -ComputerName minwinpc -Credential minwinpc\Administrator
```

# Visual Studio 2015色々
・ユニバーサルWindowsプラットフォーム開発をインストールすること
・デバッグ時に「Command failed: 0x800705b4」とエラーになったら
　コンソールに接続して以下のことをするとOK
```kill.exe msvsmon```
HighchartsでY軸目盛をゼロを中央、最大値、最小値をデータ値の絶対値から算出して一定間隔にする。

## HighchartsY軸目盛の設定。

- yAxis.tickPositionerを設定。
- this.dataMin, this.dataMaxでデータの最小値、最大値が取得できる。
- 一定間隔（必ず8等分）

``` js
"yAxis":[
{
    "tickPositioner": function () {
         var dataMax = Math.max(Math.abs(this.dataMin), Math.abs(this.dataMax));
         return [-1, -0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75, 1].map(function (n) {
      	    return Math.round(dataMax * n);
         });
    },
}
```

<img width="551" alt="スクリーンショット 2017-08-24 8.39.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/9907/104ae5e9-eaf9-727d-344a-ef9c446d39d4.png">


- デモ
http://jsfiddle.net/niiyz/2oyh1kjj/