OmniAICreator/Qiita-1.07M huggingface dataset:
5分でわかる、プログラミングの潮流

# 目的

書籍「リーダブルコード」など、構文・関数レベルでの具体的な方法論はあるものの、ソフトウェアのアーキテクチャ・実装方針レベルで、「運用しやすい（＝複数人で理解しやすい）」ソフトウェアってなんなのと思い、整理してみました。
ツッコミ・参考資料の共有など、コメント大歓迎です。

## 要約

* 「オブジェクト指向」「関数型プログラミング」の思想をまとめ、各文脈（サーバー,フロントエンド,アプリ）における現時点での動向までまとめた。
* いずれにしても重要な要素を知ることが大切で、１つの言語に絞ってその思想を体現することが大切だと感じた。アーキテクチャ設計思想についてももっと知りたい。

## オブジェクト指向

### キーワード

* カプセル化
  * オブジェクトのフィールドにはアクセスせず、メソッドだけを通してオブジェクトを操作する手法
* 継承
  * 似たクラス間の共通機能を、スーパークラスとして実装できる機能

* ポリモーフィズム
  * スーパークラスには汎用的な名前をつけておき、実際にはそのオブジェクトの型に応じたメソッドが実行される

### メリット

* 変更に対して柔軟に対応できる
  * オブジェクト指向では、変更されない箇所を軸に、頻繁に変更されるであろう箇所をクラスに抽出する
  * サンプルプログラム: [勇者に学ぶ](https://eng-entrance.com/what-oop#i-13),  [オブジェクト指向プログラミング実践](
https://qiita.com/lamrongol/items/8a339721ee20a1c81e3c#実践編)

* 直観的で、なじみやすい＝チームに浸透させやすい
  * ここは、人によって感覚が分かれそうなところですが

### デメリット

* 「変更されない箇所」を見分けるのは人間
 * 上記（モデル設計）が根本的に変更されるとつらい

* 参照透過性が低い
  * 「手続き型」で、オブジェクトに状態を保持させるため、関数の入力が同じでも、状態によって異なる結果が得られる場合がある

## 関数型プログラミング

### キーワード

* 暗黙的状態
  * 明示的状態：プログラム中で動的に変化する状態をオブジェクトや構造体、変数の粒度で管理される状態
  * 暗黙的状態：プログラム中で変数間の関係性が宣言的に記述され、イミュータブル性（変更できない状態）が維持される状態。（または「宣言的状態」とも）

* 参照透過性の担保
  * Curry化
  * 関数合成

* 「関数型」言語はあるが、「関数型」の思想はどの言語でも使える
  * 例：javascriptにおける実践例
     * lambdajs：　compose などのライブラリ集
     * immutable.js：　Data structure (参照透過性をたもつため)
     * おすすめ本：[関数型プログラミングの基礎 JavaScriptを使って学ぶ](　http://amzn.asia/7uSSEOD)
     * おすすめweb本： [Mostly adequate Guide to FP]( https://github.com/MostlyAdequate/mostly-adequate-guide)


### メリット

* 関数型プログラミングの良さ
　* コードのモジュール性
　* 読みやすくなって、運用が楽になる
* 参照透過性の担保 
   * バグが減る。理論的にはUnitTestだけでバグがつぶせる

### デメリット

* 学習コスト。慣れるまで書くのが大変
  * 特に、暗黙的状態の扱い方は、慣れていないと理解が難しい印象
  * ゆえに、チームとしての導入は、現時点でハードルが高かったり

# 各文脈において

* フロントエンド（Javascriptなど）や、アプリ（iOS）界隈では、関数型プログラミングへの移行が高まっているようにみえる

* 一方、サーバーサイドでは、Haskell推奨な方は多々見受けられますが、最近だと
「go言語」の利用が高まっている（docker、merucari・・）
  * 「go言語」は手続き型で、関数型プログラミングの思想とは別のところを目指していそう
  * 具体的には、「go言語」は静的型付け言語であったり、インターフェースの考え方、不要な変数が残っていたら実行時にエラーにするなど

* 「go言語」のインターフェースの考え方は、[Go言語における埋め込みによるインタフェースの部分実装パターン](https://qiita.com/tenntenn/items/e04441a40aeb9c31dbaf)が分かりやすい

## まとめ

いずれにしても重要な要素を知ることが大切で、１つの言語に絞ってその思想を体現することが大切だと感じた。アーキテクチャ設計思想の文脈でも考察を深めたい。


# 文献

* [オブジェクト指向と10年戦ってわかったこと]
(https://qiita.com/tutinoco/items/6952b01e5fc38914ec4e)
* [15分でわかる かんたんオブジェクト指向](https://qiita.com/koher/items/6878c80014992900add7)

* [プログラミングに関する原則](https://qiita.com/hirokidaichi/items/d6c473d8011bd9330e63)
* [「オブジェクト指向プログラミング」と「関数型プログラミング」のたった一つのシンプルな違い](https://qiita.com/hirokidaichi/items/efeee20917ee2b478ec9)
Vue.jsのrouter-link要素で@clickが効くようにする方法

```html
<router-link
    class="btn btn-success"
    @click.native="doSomethingBeforeMove"
    :to="{name: 'somewhere'}">リンク<router-link>
```

参考
[Binding Native Events to Components](https://vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components)
Vue.js 2でBootstrapのmodalを開閉する方法

```vue:SampleModal.vue
<template lang="pug">
  .modal(v-show="value")
    .modal-dialog
      .modal-content
        .modal-header
          button.close(type="button", @click="close"): span &times;
          h4.modal-title サンプルモーダル
        .modal-body
          ハローワールド
        .modal-footer
          button.btn.btn-default(type="button", @click="close") 閉じる
</template>

<script>
export default {
  name: 'sample-modal',
  props: {
    value: {type: Boolean, required: false, default: false} // 開閉状態
  },
  methods: {
    close: function () {
      // 開閉状態をfalseにする
      this.$emit('input', false)
    }
  }
}
</script>
```

```vue:SamplePage.vue
<template lang="pug">
  div
    button(type="button" @click="openSampleModal")
    sample-modal(v-model="SampleModaiIsOpen")
</template>

<script>
import SampleModal from @/SampleModal
export default {
  name: 'sample-page',
  components: { SampleModal },
  data: function () {
    sampleModalIsOpen: false
  },
  methods: {
    openSampleModal: function () {
        this.sampelModalIsOpen = true
    }
  }
}
</script>
```

`value`という名前が嫌なら任意の名前に変えてもOK。
以下2つは同じことなので。

```pug
input(v-model="sampleModalIsOpen")
```

```pug
input(
  :value="sampleModalIsOpen"
  @input="sampleModalIsOpen = $event.target.value"
)
```

↓

```pug
input(
  :isOpen="sampleModalIsOpen"
  @input="sampleModalIsOpen = $event.target.value"
)
```
PythonでWebAPIコール

前回は呼び出される側のコードを書いたので、今回は呼び出す側

コード内で使用しているWebAPIは、livedoorの「Weather Hacks」
登録不要で使えます。
http://weather.livedoor.com/weather_hacks/webservice

# ソースコード
```python:call_web_api.py
# -*- coding: utf-8 -*-
import requests
import json

import sys
import codecs


if __name__ == "__main__":

    # WebAPIのURL
    # 天気予報取得(Weather Hacks : http://weather.livedoor.com/weather_hacks/webservice)
    base_url = "http://weather.livedoor.com/forecast/webservice/json/v1"

    # 天気予報を取得したい地点(http://weather.livedoor.com/forecast/rss/primary_area.xml)
    param_city = "?city=230010"
    
    # GET通信でリクエストを送り、レスポンスを受け取る
    response = requests.get(base_url + param_city)

    # レスポンスはJSON 読み込む
    data = json.loads(response.text, "utf-8")

    # JSONからタイトルと天気予報のテキスト取得
    title = data["title"]
    forecast_text = data["description"]["text"]

    # 自分の環境(Windows)だと文字化けするので
    sys.stdout = codecs.getwriter('shift-jis')(sys.stdout)

    # 出力
    print title
    print forecast_text
```

# 実行結果
改行は少し修正してます。
>愛知県 名古屋 の天気
 前線を伴った発達中の低気圧が福島県沖にあって北東に進んでいます。
一方、華中に中心をもつ高気圧が西日本に張り出しています。
 東海地方は、晴れまたは曇りとなっています。
 今夜の東海地方は、高気圧におおわれるため、おおむね晴れますが、岐阜県の飛騨地方では、寒気の影響で曇りとなるでしょう。
 明日の東海地方は、高気圧におおわれるため、おおむね晴れますが、上空の気圧の谷や寒気の影響で雲が広がる所があるでしょう。
ReactJS+TypeScriptで実装してるときに「名前divが見つかりません」と表示されたら確認すること

<img width="311" alt="スクリーンショット 2018-04-25 20.47.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/121911/56f62535-409c-2e3a-43ee-782bfa7a3b5f.png">

上ようなLintエラーが出たら不正な`拡張子`のファイルがないか確認してみてください。

`tsconfig.json`で`compilerOptions.jsx = react`と設定していると、対象ファイルまたは対象ファイルを含むグループの中に拡張子が`.ts`になっているファイルがあると上のようなエラーが出るときがあります。なのでそのようなファイルがあったら拡張子を`.tsx`に直してみてください。
Haskellでリストをシャッフル

# 何を書いたか
HaskellのRandomモジュールでリストのシャッフル関数が無かったので少しQiitaで調べてみた。すると[Array版](https://qiita.com/penguinshunya/items/f90a1df5fdb6ee7962e5)や[Vector版](https://qiita.com/yutasth/items/69519cbac7279e36a03b)は見つかったがどちらもIO[a]といった結果が返ってきていた。なので[a]が返ってくるような```shuffle```関数を作りたくなった。そしてできたので投稿することにした。コード全体(というよりData/Random/Shuffle.hsさえあれば十分)は[こちら](https://github.com/ogata-k/shuffle)。実行速度は気にしない。

# コード

``` haskell:Data/Random/Shuffle.hs
module Data.Random.Shuffle(
  shuffle
, autoShuffle
)where

import System.Random
import Data.List (nub, sortOn)
import Control.Applicative ((<$>), (<*>))

getNubRandomRs :: RandomGen g => g -> (Int, Int) -> [Int]
getNubRandomRs g (l, h) = take (abs (h - l) + 1) $ nub $ randomRs (l, h) g

shuffle :: RandomGen g => g -> [a] -> [a]
shuffle _ [] = []
shuffle g xs = map fst $ sortOn snd $ zip xs rs
    where
        rs = getNubRandomRs g (1, length xs)

autoShuffle ::[a] -> IO [a]
autoShuffle [] = pure []
autoShuffle xs = shuffle <$> newStdGen <*> (pure xs)

```
# 何をしているか
まず```getNubRandomRs```関数について説明します。この関数はrandomパッケージ内にある```randomRs```関数によって得た結果を重複をなくして出力する関数。つまりlからhまでをランダムに並び替える関数です。これでも目的を達成しそうですがこの関数ですと連続した範囲内でしかシャッフルできない。なので目的は達成できない。
次に```shuffle```関数について説明します。この関数は先ほど紹介した```getNubRandomRs```関数によって得たシャッフルしたいリストと同じ長さのシャッフルされたインデックスのリストを基にシャッフルする関数です。つまりそのインデックスリストをソート関数のソート条件に与えてやることで、基のリストがシャッフルされる実装になっている。そしていちいち乱数のタネ```g```を与えるのは面倒なので```newStdGen```を使うことで使うたびにタネを与えずに```shuffle```を使えるようにした関数が```autoShuffle```関数です。```newStdGen```を使う弊害として結果が```IO```で包まれています。

# 使用例

```
*Data.Random.Shuffle> shuffle (mkStdGen 12) [1 .. 10]
[3,7,6,10,4,9,8,5,2,1]
*Data.Random.Shuffle> shuffle (mkStdGen 12) [1 .. 10]
[3,7,6,10,4,9,8,5,2,1]
*Data.Random.Shuffle> shuffle (mkStdGen 12) [1 .. 10]
[3,7,6,10,4,9,8,5,2,1]
*Data.Random.Shuffle> autoShuffle [1 .. 10]
[7,10,9,6,8,3,4,2,5,1]
*Data.Random.Shuffle> autoShuffle [1 .. 10]
[10,8,6,7,2,9,1,5,3,4]
*Data.Random.Shuffle> autoShuffle [1 .. 10]
[2,1,4,10,8,9,7,6,5,3]
*Data.Random.Shuffle> autoShuffle [1 .. 10]
[7,9,3,8,2,4,1,10,6,5]
*Data.Random.Shuffle> data TTT = A | B | C | Dderiving Show
*Data.Random.Shuffle> shuffle (mkStdGen 12) [A, B, C, D]
[D,A,B,C]
```

# まとめ
Haskellでトランプゲーム等のシャッフル関数作成の一助になればいいなと思います。
Azure Notebooks V.S. Google Colaboratory（2018.10.21最新版）

# Azure Notebooks V.S Google Colaboratory
今話題の、SaaS型Jupyter Notebookでメジャーどころの２つを比較してみました。

Azure Notebooks
https://notebooks.azure.com/

Google Colaboratory
https://colab.research.google.com/


# <font color="LightSeaGreen">2018.10.21 最新情報に更新しました．</font>
## 更新部分
- Google Colaboratory
  - Google Colaboratoryの，ファイル連携がとても簡単になりました．以前は認証とかいろいろ面倒だったのですが，もはやたった2ステップです……素晴らしい……  
     - [参考公式URL](https://colab.research.google.com/notebooks/io.ipynb)
     - [google Colaboratoryでファイルを読み込む方法](https://qiita.com/uni-3/items/201aaa2708260cc790b8)
  - 比較項目の外部データ連携として，BigQueryを追加しました．
- Azure Notebooks  
  - [Pytorch対応が発表](http://ascii.jp/elem/000/001/759/1759782/)されました．
  - connect to azureボタンができたので，押してみたのですが何も起きず（認証はしてるっぽい）．簡単にAzure Storageや，Azure SQL Databaseと接続できるようになれば，訴求ポイントになりそうですが．

# 結論
PythonならGoogle Colaboratory。
それ以外の言語ならAzure Notebooks。

# 比較
||Azure Notebooks|Google Colaboratory|
|---|---|---|
|料金|無料|無料|
|アカウント|Azureアカウント|Googleアカウント|
|作成ファイルの保管場所|AzureNoteBookのストレージ|GoogleDrive|
|データ連携|アップロード|GoogleDrive,アップロード, BigQuery|
|Python|〇|〇|
|R|〇|×|
|F#|〇|×|
|pip install|〇|〇|
|apt-get|×（rootが取れない）|〇|
|GitHub連携|〇|gitコマンドが使える|
|JupytarLab|〇|×|
|メモリ|4GB|13GB|
|データ保持期間|60日放置で削除|GoogleDriveなら無制限|
|共有|Azure Notebooks Library|GoogleDrive（リアルタイムに共同編集可能）|
|.ipnybダウンロード|〇|〇（GoogleDriveだから）|
|OS|Ubuntu 16|Ubuntu 17|
|GPU|×|GPU NVIDIA Tesla K80|
|連続学習時間|無制限?|12時間|
|アイドル時接続リミット|60分|90分|

# 所管
- 個人的にはapt-getインストールできてGPUが使えるgoogleの方が魅力的。
- Azure Notebooksは生のJupyter Notebookという感じだが、Googleの方はより洗練された独自のUIになっている。  
- Azureの文化的にはユーザーの意見は積極的に取り入れてくれるので、言えば将来的にapt-getさせてくれる可能性もある(参考：https://github.com/Microsoft/AzureNotebooks/issues/303)。
- GoogleはPython以外にまだ未対応なので、Python以外を使うならAzureNotebooksか（参考：https://research.google.com/colaboratory/faq.html）。

以上です。
間違いなどあればご指摘ください。
CakePHP 3で複数のOR条件をANDで連結する方法

## 要件

こういうSQLを発行したい場合の方法。

```SQL
SELECT id, name, age
FROM users
WHERE (name LIKE 'さとう%' OR kana = 'さとう%')
AND (stateA = 'a' OR stateB = 'b');
```

## `$paginate`を使う例

```PHP
// 1つ目のOR条件
$this->paginate['conditions'][]['or'] = [
    'name LIKE' => '%さとう',
    'kana LIKE' => '%さとう'
];
// 2つ目のOR条件
$this->paginate['conditions'][]['or'] = [
    'stateA' => 'a',
    'stateB' => 'b'
];
```

## `$query`を使う例

```PHP
// 1つ目のOR条件
$query->where([
    0 => [
        'or' => [
            'name LIKE' => '%さとう',
            'kana LIKE' => '%さとう'
        ]
    ],
    1 => [
        'or' => [
            'stateA' => 'a',
            'stateB' => 'b'
        ]
    ]
]);
```
SpringBoot 2.0 マルチ・プロジェクトのビルド



Spring Bootのバージョン 2 で 依存関係のあるプロジェクトを指定してビルドする場合、
Jarファイルを作るのか？実行可能Jarファイルを作るのか？を指定する必要があります。


以下は、batchプロジェクトをビルドするために、shareプロジェクトのビルドも必要な場合の例。

```gradle:build.gradle
buildscript {
	ext {
		springBootVersion = '2.0.1.RELEASE'
	}
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

//途中省略

project(':batch'){
	archivesBaseName = 'batch'
	ext.mainClass = 'xxx.xxx.xxx.SampleApplication'

	dependencies {
		compile project(':share') //依存関係のあるプロジェクトを指定
    }
}

project(':share'){
	archivesBaseName = 'share'

	bootJar {
		enabled = false //実行可能Jarを作成しない
	}

	jar {
		enabled = true //Jarを作成する
	}
}

```

上記のjarの設定を記述しないと、ビルドした時にJarファイルが作成されず
パッケージの依存関係を解決できずにエラーが発生します。
Docker for Mac の CPU 使用率が異常に高いままになる問題

Macbook のバッテリがやけに減るなあと思っていたら、`com.docker.hyperkit` プロセスの CPU 使用率が、200% から 300% を維持したままになった。

GitHub にも同様の issue がいくつかある。
https://github.com/docker/for-mac/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+cpu

issue を眺めていると、File Sharing に問題がありそうというコメントがあったので、試しに `Preferences - File Sharing` で `/Users/` を削除してみると CPU 使用率が一気に落ち着いた。

ただ、このままでは、Mac のファイルをコンテナにマウントできないので、`/Users/` を戻そうとするとエラーで受け付けられなかった。（Docker に reserved だから云々）

結局、`Preferences - Reset` で `Reset to factory defaults` をクリックしてインストール状態に戻して解決した。（ `/Users/` はデフォルトで File Sharing に含まれるので復帰している。）

<img width="497" alt="Untitled 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/12272/b410cbfb-7989-4dde-9843-4e9d1574839f.png">

`docker-compose` でいくつかコンテナを上げてみたが、CPU 使用率は数 % に落ち着いている。

<img width="364" alt="Untitled.png" src="https://qiita-image-store.s3.amazonaws.com/0/12272/abb410c7-eb18-9923-56b9-0cb95d5c7116.png">
ページ内にalt属性の無いimg要素（と、alt=""になっているもの）をカウントするブックマークレット

タイトルそのままです。
実行すると表示中のページのimg要素を走査して、alt属性の有無と、空のalt属性（`alt=""`）の有無をアラート出力します。

## 導入方法

下記のコードをブックマークレットに登録してください。

```js
javascript:(function(){var noAltImg=document.querySelectorAll("img:not([alt])"),blankAltImg=document.querySelectorAll("img[alt='']");alert("alt属性の無いimg要素："+noAltImg.length+"個, alt属性が空のimg要素："+blankAltImg.length+"個");})();
```

ブックマークレットの登録方法はこちらを参照↓
https://qiita.com/AQRiL_1132/items/b5f9040ccb8cbc705d04

## 実行結果

![名称未設定 1.png](https://qiita-image-store.s3.amazonaws.com/0/75864/2eea43aa-5026-f857-a70f-3df17a4e70fe.png)
Rails + deviseで、confirmableモジュールが有効のときに、仮登録後のアクションを変更する方法

# より良いUIのために
ユーザー登録にメール認証を導入してくれるdeviseのconfirmableモジュール。仮登録後、デフォルトではflashメッセージと共にafter_sign_in_path_forに設定されているパスにredirectされる。しかし、flashメッセージだけではユーザーに優しくないので、きちんとメールを確認して欲しい旨のビューを作りたい。

# 手順
## 1. deviseのコントローラーをカスタマイズするための準備をする
[Rails4でdeviseのControllerをカスタマイズする](https://qiita.com/akasakas/items/138c29fa2cecd271cfe4)を参考に、オーバーライドするdeviseのコントローラを生成し、ルーティングを設定する。

## 2. 新しく作るページ(confirm_email)のルーティング・コントローラー・ビューを作る
deviseのコントローラーに新たなアクションを追加するには、devise_scopeを使う。:usersではなく:userな点に注意

```ruby:routes.rb
  devise_for :users, controllers: { registrations: 'users/registrations',
                                    sessions: 'users/sessions',
                                    omniauth_callbacks: 'users/omniauth_callbacks' }
  # 追加
  devise_scope :user do
    get 'confirm_email', to: 'users/registrations#confirm_email'
  end
```
```ruby:users/registration_controller.rb
 # 追加
 def confirm_email
 end
```
```erb:devise/registrations/confirm_email.html.erb
 <div>
   メールを確認してね！
 </div>
```

## 3. registration_controllerのafter_inactive_sign_up_path_forに、上記アクションのパスを指定する
confirmableを有効にしている場合は、after_sign_up_path_forではなくafter_inactive_sign_up_path_forに指定する。まだ仮登録で、アカウントが有効になってないため。

```ruby:users/registration_controller.rb
  # コメントアウトを外す
  # The path used after sign up for inactive accounts.
  def after_inactive_sign_up_path_for(resource)
    confirm_email_path
  end
```

# 備考
deviseのコントローラーに作らなくても普通にusers_controllerに作ればいいのではと思うかもしれないが、それでは上手くいかない。仮登録後、/users/confirm_emailにアクセスはするが、Completed 401 Unauthorizedとなって弾かれてしまう。
空文字をexplode()で分割した時の返り値


PHPで `explode()` 使う時に第2引数に空文字入ってるとどうなるんだ？と思い調べてみましたが、
マニュアルの該当箇所分かりづらかったので、残しておきます。結構初心者向けです。

#サンプルコード
下記コードで返り値を確かめます。
 
```php
$str = '';
$res = explode(',', $str);
print_r($res);
```

( [PHPマニュアル][link1] より引用 )

#返り値
結果は以下の通りです。

```
array(1) {
    [0] => 
    string(0) ""
}
```

`key`として0を、`value`として空の文字列を持つ1要素の配列が返されます。

**え、なんで1要素いれた！？ 空配列でいいじゃん！！**

ちなみに私は、この後 `$res` を `empty()` で判定しようとして失敗しましたｗ


#参考
PHPマニュアル：http://php.net/manual/ja/function.explode.php#99830

[link1]:http://php.net/manual/ja/function.explode.php#99830
REST API 内で別のサービスからファイルをダウンロードし、APIのクライアントに返す

# 要件

* Aアプリケーションが、Bアプリケーションに登録されているファイルをダウンロードする機能を作る
* Bアプリには、ファイルに対するリンクが既定されており、Aアプリ内にそのリンクを貼ればダウンロードは可能
* ただし、Bアプリにアクセスするためには、Bアプリの認証情報が必要で、Aアプリのユーザにその情報は公開されていない。また、公開もしない。
* AアプリからBアプリのファイルをダウンロードする際、ユーザにはBアプリの認証情報を意識せずダウンロードさせたい
* AアプリはAngular製のSPAで、バックエンドはDjango製のAPI

# 実現方法

* Aアプリのバックエンドに、Bアプリの認証情報を持たせる
* AアプリAPIをコールする際、Bアプリのダウンロードリンクを渡す
* サーバ上で持っている認証情報＋渡されたダウンロードリンクで、サーバ上でBアプリからファイルをダウンロードする
* ダウンロードしたファイルをbase64エンコードして、Aアプリへ返す
* Aアプリ内でbase64デコードして、バイナリ形式してダウンロードさせる

# 言語、フレームワークのバージョン

* python 3.6.x
* Django 1.11.x
* typescript 2.4.x
* Angular 5.0.x


## ダウンロード用API

```python:views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

import requests
import base64
from urllib import parse


class DownloadDocment(APIView):
    def get(self, request, format=None):
        # クエリストリングの取得
        params = {}
        params.update(self.request.query_params.dict())
        try:
            # fileuri に 格納されたファイルのURIが設定されている(パラメータ uri にサーバ上の格納場所が入っている）
            file_uri = params["file_uri"]
            file_list = parse.parse_qs(parse.urlparse(file_uri).query)["uri"]
        except KeyError:
            return Response('{message:ファイルURIの指定がありません。 指定クエリ: ' +
                            str(params) + '}',
                            status=status.HTTP_400_BAD_REQUEST)

        # 上記で取得出来るのはリストなので、リストの最初の要素を取り出す
        file_name = ""
        if file_list:
            file_name = file_list[0].split("/")[-1]

        # 認証情報設定(HTTPヘッダーに認証情報を埋め込む形, AUTH_KEY は別途定義されている前提）
        HEADERS = {'Authorization': AUTH_KEY}
        # ファイル取得
        r = requests.get(encoded_uri, headers=HEADERS)

        # リクエストのステータス判定が要りそう
        # base64にエンコードしたファイルの中身とファイル名を返す
        return Response({'body': base64.b64encode(r.content),
                         'filename': file_name})
```

## Angular画面ダウンロード処理

* ダウンロードの処理以外は割愛（テンプレート、サービスなど）
* base64からのデコードが意外と厄介だった

```typescript:xxx.component.ts
  base64ToArrayBuffer(base64) {
    /* base64形式の文字列をバイナリに変換する
    https://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string
    */

    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++)        {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
  }

  fileDownload(uri: string){
    let downloadFile: DownloadFile;
    //getFile で上記APIを呼び出し、ファイル名とファイルの中身(base64形式）を取得する
    this.xxxService.getFile(uri).subscribe(downloadFile=> {
      //base64 decode
      var b = this.base64ToArrayBuffer(downloadFile.body);
      var blob = new Blob([b], {"type" : "application/octet-stream"});
      //IEとそれ以外で処理を分ける
      if (window.navigator.msSaveBlob) {
        window.navigator.msSaveOrOpenBlob(blob, downloadFile.filename);
      } else {
        var a = document.createElement("a");
        a.href = URL.createObjectURL(blob);
        a.target = '_blank';
        a.download = downloadFile.filename;
        a.click();
    }
    });
  }

```
laravel5.5 フォームリクエストのバリデーションエラーをjsonで返す方法


日本語の[laravel5.5](https://readouble.com/laravel/5.5/ja/) のドキュメントを参考にweb APIの実装をしているが、
バリデーションを行う時に、[フォームリクエスト](https://readouble.com/laravel/5.5/ja/validation.html#rule-json)を使用した場合、
バリデーションエラーをjsonで返す方法は書いていないため困った

http://www.coding4developers.com/tag/how-to-make-a-custom-formrequest-error-response-in-laravel-5-5/
上記URLによると
laravel5.5からカスタムバリデーションのバリデーションエラーからjsonを返す方法が変わったらしい




解決方法

フォームリクエストを作成しているクラスで
以下を記載すればjsonでバリデーションエラーを返してくれた。

例ファイル）/app/Http/Requests/UserFormRequest.php

```
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
```

```
protected function failedValidation(Validator $validator) 
　　　　　　　　{
        throw new HttpResponseException(response()->json($validator->errors(), 422));
    }

```


---

参考サイト
Tag: How to make a custom FormRequest error response in Laravel 5.5
http://www.coding4developers.com/tag/how-to-make-a-custom-formrequest-error-response-in-laravel-5-5/
Electronのインストールでエラーになる時の対処法

Electronのインストールは

```bash
$ sudo npm install -g electron
```

で行うという記事を見つけたので、実行したところ、以下のエラーが発生。

```
/usr/local/bin/electron -> /usr/local/lib/node_modules/electron/cli.js

> electron@1.8.4 postinstall /usr/local/lib/node_modules/electron
> node install.js

/usr/local/lib/node_modules/electron/install.js:47
  throw err
  ^

Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/electron/dist'
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! electron@1.8.4 postinstall: `node install.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the electron@1.8.4 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
```

エラーメッセージでいろいろと検索したところ、[GithubのIssue](https://github.com/npm/npm/issues/17268 "Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/electron/.electron' · Issue #17268 · npm/npm")で解決策を発見。
以下のコマンドで無事インストールできた。

```bash
$ sudo npm install -g electron --unsafe-perm=true --allow-root
```
【随時更新】gasを利用してlinebotを作ってみた。

linebotを始めるようと思い立ったまでは良かったんですが
C言語以外まともにやった事もなく、そのC言語にしても仕事で使う以外
まともに調べたこともないプログラマーモドキみたいなもんだった為とにかく進められない。
こんなんでもコミュニケーションとgoogle先生さえあれば生きて行けたんですが。。。

フリーランスでやってきたいと思ったらこれじゃ当たり前だけど何も出来ない。
なんとなくで生きてきたツケみたいなもんだと思うんですが
これから少しでも取り戻したいと思いました。

これはその備忘録みたいなもんです。
本題とずれそうなので以下自分がlinebotを学んだことのメモを書いていきます。

linebotが始まってから一度色々変わったらしく、なかなか最新の情報が見つからない。
最新じゃなくても分かっている人ならばあぁここだなってのはすぐ出てくるくらい
情報量はあると思うんだけど、如何せん糞プログラマーの私じゃ分からないんです。
ということで2018年4月現在使えそうなサイトをメモ代わりに載せてます。


◆lineの登録とオウム返し作成まで学べたところ
https://note.mu/tatsuaki_w/n/nfed622429f4a?creator_urlname=tatsuaki_w

とにかく分かりやすい、Qiitaに書いてるのにnoteのアドレスですが。
自分が見つけられた他の記事はやり方は書いてあるのですがエラー時とかに
どうしたら良いなど書いてあるところがなく、コケたらとにかく時間が掛かる。
その点上記サイトはかなり丁寧に書いてくださっているのでオウム返しまでがスムーズでした。



以下はあとで更新予定
zshとPreztoを導入 [備忘録]

#はじめに
この記事は，初心者が，MacOSでVPSにSSH接続する前準備として，頑張って色々調べて，巡り回った結果，TerminalにzshとPretzoを導入したときの過程を見直せるようにメモしたものです．SSH接続にzshやpreztoは関係ありません．

全体的に[こちらの記事](https://qiita.com/kinchiki/items/57e9391128d07819c321)を大いに参考にさせていただきました．ありがとうございます．


#シェルの変更
シェルをbashからzshに変更しました．

まずは，以下のコマンドで，zshをインストールします．

```sh
# Homebrew
$ brew update
$ brew install zsh

# yum
sudo yum -y install zsh
```

ちなみに，Homebrewって初めから入ってたのか忘れました...
使ったことない方は，もしかしたらHomebrewのインストールから始める必要があるかもしれません．

次にターミナルを開いた時に起動するシェル（ログインシェル）をzshに変更します．
zshをログインシェルにするには，パスを`/etc/shells`に書く必要があるため，
初めに，以下のコマンドで，`/etc/shells`で編集します．

```
$ sudo vim /etc/shells
```

このコマンドを実行すると，以下のファイルが出てくると思うので，

```shells:/etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
```

このファイルの一番下に`/usr/local/bin/zsh`を追加します．
ちなみに，`sudo`をつけずに編集しようとすると，読み込み専用となるため，編集できません．

> 2018/10/06更新
`cat /etc/shells`で`/bin/zsh`があれば，インストールせず`chsh`するだけで変更可能かもしれません．
近々，更新します．

次に以下のコマンドでログインシェルを変更します．

```
$ chsh -s /usr/local/bin/zsh
```

`chsh`は，change shellの略で，ログインシェルを変更するコマンドです．
オプション`-s`でシェルを指定します．

以上で，zshへの変更は終わりです．次回以降，ターミナルを起動した時，zshが起動するようになります．

#Preztoの導入
Preztoというシェルのフレームワーク(?)を導入します．ただ，この節で扱うコマンドやスクリプトに関しては，個人的な要勉強事項です．
まず，以下のコマンドで，gitHubからcloneしてきます．

```
$ git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
```

次に以下のシェルスクリプトを実行します．

```
$ setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
```

再起動すると，Preztoの設定が反映され，導入が完了です．
後は，テーマやプラグインを編集して，自分仕様にしましょう．

###疑問
テーマの一つであるpureを使用した状態だとたまにzshが二重で起動することがあります．`ps`コマンドでプロセスを表示すると，zshプロセスが二つある状態です．
ただ，テーマを別のに変更すると，その現象が起きないのです．
これに関して原因がわかる方，よろしければコメントお願いします．


#終わりに
Qiita投稿も初めてで，この記事を自身のメモ，備忘録として書きましたが，これが何かの形で，どなたかのお役に立てば幸いです．

#参考サイト
1. [お前らのターミナルはダサい - Qiita](https://qiita.com/kinchiki/items/57e9391128d07819c321)
2. [【超初心者向け】Macにモダンなコマンドライン環境を構築【zsh&amp;Prezto編】 - キモく生きよう](http://kinchiki-it.hatenablog.jp/entry/build-command-line-environment-mac-2)
3. [bashからzshに移行したときのメモ - Qiita](https://qiita.com/hiroyuki827/items/4e87ce517a4894f092e8)
4. [oh-my-zshを使っていて重いと感じている方、preztoはいかが？ - Qiita](https://qiita.com/kei_q/items/814ec412b3c28f580927)
Android 8.0のTextViewでワードラップがおかしい件のワークアラウンド

# はじめに

皆さんの端末にはOreo来ましたか？　私のZenfone3には先週Oreoが降ってきました。基本的には問題ないのですが、いくつかのアプリで妙なことに気が付きました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89529/1a667cd6-4719-fbe8-edf3-e71fc55f5a08.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89529/44c4c139-4cd4-8006-4f57-35166c2973de.png)

ワードラップがおかしいのです。明らかに禁則処理とは関係ないところで行末が折り返されています。

#てことで

調べました。
APIレベル23で、TextViewに以下のメソッドが追加されました。

https://developer.android.com/reference/android/widget/TextView.html#setBreakStrategy(int)

このメソッドでTextView/EditTextのワードラップアルゴリズムが変更可能になっています。
上記リファレンスによると、TextViewでは BREAK_STRATEGY_HIGH_QUALITY が、EditTextでは BREAK_STRATEGY_SIMPLE がデフォルト値として使用されます。

それぞれ、設定して長文を表示させたものが以下のスクショです。
＜BREAK_STRATEGY_HIGH_QUALITY＞
<img src="https://qiita-image-store.s3.amazonaws.com/0/89529/0f06881f-c89c-263e-0904-754fd1e8cd4b.png" width=50%>
＜BREAK_STRATEGY_SIMPLE＞
<img src="https://qiita-image-store.s3.amazonaws.com/0/89529/5672949a-f33a-4e6d-ffd7-247da5c51ef7.png" width=50%>

HIGH_QUALITYでは行末の折り返しがおかしいことが分かります。

#それで

このバグはAOSP由来のもので、Android 8.0 Emulatorでも同様に発生します。また、8.1では修正されている模様です。

```xml
    <TextView
        android:breakStrategy="simple"
    />
```
これで対策が出来ます。
ワードラップに拘る場合は、8.0に限りsetBreakStrategy()を呼び出してやる、などの対応で良いと思います。

以上です。
SimpleXMLでsitemap.xmlを作成する時にモバイルのURLも載せる

sitemap.xml をイチから作る機会があったので。

今回はスマホ向けのサイトが別URLだったので、alternateタグ（`<link rel="alternate">`)を入れるついでにサイトマップにも入れてみました。

サイトマップ内にアノテーションを含めることができるそうです。
https://developers.google.com/search/mobile-sites/mobile-seo/separate-urls?hl=ja

```xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>http://www.example.com/page-1/</loc>
    <xhtml:link
      rel="alternate"
      media="only screen and (max-width: 640px)"
      href="http://m.example.com/page-1" />
  </url>
</urlset>
```

そしてPHPでSimpleXMLを利用している場合に、以下を入れる方法です。

```xml
<xhtml:link rel="alternate" media="only screen and (max-width: 640px)" href="http://m.example.com/page-1" />
```

以下コード

```php
<?php
$xmlData = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');

$urlTag = $xml_data->addChild('url');
$urlTag->addChild('loc', 'http://www.example.com/page-1/');
$alternate = $url->addChild('xhtml:link', NULL, 'http://www.w3.org/1999/xhtml');
$alternate->addAttribute('rel', 'alternate');
$alternate->addAttribute('media', 'only screen and (max-width: 640px)');
$alternate->addAttribute('href', 'http://m.example.com/page-1');
$xml_data->asXML(__DIR__ . '/sitemap.xml');
```

xhtml:link でnamespaceを入れないと `link`として追加されて思い通りにならないですよー、というお話でした。
Angularチュートリアル（8.HTTP）でエラー（angular-in-memory-web-api起因でした）

Angular のチュートリアルをやっていたのですが、
「8.HTTP」の章でつまづいてしまったので、共有します。

▼ Angular チュートリアル　8.HTTP
https://angular-ja.firebaseapp.com/tutorial/toh-pt6

## 事象

はじめに、angular-in-memory-web-apiをインストールする手順があるのですが、

```
npm install angular-in-memory-web-api --save
```

インストールを行い、チュートリアルを進めていくと、以下のエラーが発生してしまいます。

![スクリーンショット 2018-04-25 17.27.52.png](https://qiita-image-store.s3.amazonaws.com/0/151710/59792420-f2ef-79ce-9c36-09239760a6ff.png)

## 原因

angular-in-memory-web-apiのばーじょんが、0.5→0.6にバージョンアップされていて、
0.6をインストールすると、正常に動作しないようです。

## 解決方法

### 1. サンプルソースに合わせて、「./package.json」を以下に変更

```
vi ./package.json

"angular-in-memory-web-api": "^0.6.0",

　　↓

"angular-in-memory-web-api": "~0.5.0",
```

### 2. ライブラリの更新を実施

```
$ npm update 
```

これで、正常にチュートリアルが実行できました。


## 参考情報

こちらも参考にさせていただきました。

https://stackoverflow.com/questions/49474048/angular-in-memory-web-api-internal-server-error
Rで外れ値(3σ外の値)を弾いて結果をファイル出力

メモがわりとして

外れ値の除去

```R:remove.R
m <- mean(x)
s <- sd(x)
removed <- x[(x>=m-3*s)&(x<=m+3*s),]
```

ファイルへの出力

```R:output.R
write.csv(removed,"~/Desktop/write.csv",row.names = FALSE)
```

write.csv()は引数でrow.names = FALSEを渡さないと1列目を行名として扱おうとするので注意
AWS Systems Managerを利用しているとinodeが枯渇するはなし

# 環境
AMI version

```
Amazon Linux AMI release 2017.09
```
SSM agent version

```
2.2.45.0
```
# 概要
AWSでSystems Manager(以下ssm)を利用していたら、inodeが枯渇して、新規ファイルが作れなくなりました。
もちろん現象発生以降のssmの実行もコンソールで「失敗」ステータスになっていました。
# エラーメッセージ
```
failed to open stream: No space left on device
```
# 原因
amazon-ssm-agentのGithubにissueが上がっていました。
https://github.com/aws/amazon-ssm-agent/issues/94
ssm実行時のファイルが削除されずにずっと残ってしまうようです。最新のamazon-ssm-agentでも直っていないようです。
# 解決法
issueにも記載のあるように、findで一定日数以上経過したものを削除するコマンドをcronに仕込むと良いと思います。

```
0 0 * * * find /var/lib/amazon/ssm/i-*/document/orchestration -mindepth 2 -maxdepth 2 -type d -mtime +3 -print0 | xargs -0 rm -rf
```
winAppDev > Link > Windows 10 > invisible border > 1px: visible, 8px: invisible

### 関連

- [C++ Builder 10.2 Tokyo > Forms > Bug > 8個の子フォームを親フォームの下に4行 x 2列で配置する > 空白があいてしまう > 10.2 Tokyoの問題ではなさそう](https://qiita.com/7of9/items/426360c66715d276bc0d)
- [winAppDev > Windows7とWindows10の違い > CaptionHeightとCaptionWidth > 15異なる (Windows 8.1はWindows 10と同じ)](https://qiita.com/7of9/items/4261fe362b58d2f268f0)

### invisible border

上記のリンク先にてウィンドウ間のマージンができる件について、以下を見つけた。

[Is it possible to turn visible the invisible window's borders of Windows 10?](https://superuser.com/questions/1098708/is-it-possible-to-turn-visible-the-invisible-windows-borders-of-windows-10)

> At this point, knowing that In Windows 10 the real border width is 8 px, but only 1 px. is shown, and the rest of the border is just... invisible,

boder自体は8 pxあるが、見えるのは1 pxのようだ。

ウィンドウのWidth(やHeight)を取った時、invisible borderの幅(や高さ)も含めたサイズが返っていると認識している。

Windows 10の場合のみ、この埋め合わせをしないといけないのだろうか。

### link

"invisible border"のキーワードで以下を見つけた。

- [WPF and WIndows 10. Invisible border around windows?](https://stackoverflow.com/questions/35259756/wpf-and-windows-10-invisible-border-around-windows)

> answered May 18 '16 at 23:59
mikew
> The resizable border on the left/right/bottom is now invisible on Windows 10

左、右、下がinvisibleとのこと。

### 対応
(追記 2018/04/26)

[C++ Builder 10.2 Tokyo > Forms > フォームを並べたときに空白がないように配置する (Windows 7, 8.1, 10)](https://qiita.com/7of9/items/cc7abbdd0f11b16d9ed9)
に記載の`GetVisibleWindowSize()`にてvisible borderの情報を取るようにして対応した。
C++のtemplateのチューリング完全性について

#まずはソースコードを見てましょう

```c++
#include <iostream>
using namespace std;

template <int N>
class Turing{
public:
	void print(){
		cout << N << endl;
	}
	
	Turing<N + 1> incl(){
		return Turing<N + 1>();
	}
	
	template<int M>
	Turing<N + M> add(Turing<M> a){
		return Turing<N + M>();
	}

            void fizzbuzz(){
        if(N > 0){
            Turing<N - 1>().fizzbuzz();
        }

        if(N % 15 == 0){
            cout << "fizzbuzz" << endl;
        }if(N % 3 == 0){
            cout << "fizz" << endl;
        }if(N % 5 == 0){
            cout << "buzz" << endl;
        } else {
            cout << N << endl;
        }
    }
};

template<>
class Turing<0>{
public:
    void fizzbuzz(){
    }
};


int main() {
	Turing<5> a;
	Turing<6> b;
	Turing<100>().add(b).print();
	Turing<-1> t;
	t.fizzbuzz();
	// your code goes here
	return 0;
}
```

#解説
上のソースコードではtemplateの<N>のNの部分をチューリングマシンのテープとして扱い、関数内部の処理をチューリングマシンのヘッダとして扱います。なので、二つ変数を使いたいときは template <N, M>のようにしたり、配列を使いたいときは可変長引数にすればいいですよね。関数の名前はLisp風にしたので比較的直感的に理解できると思います

```c++

#include <iostream>

using namespace std;


template<int head = 0, int... tail>
class Turing{
public:
    template <int new_head>
    Turing<new_head, head, tail...> cons(){
        return Turing<new_head, head, tail...>();
    }

    void print(){
        cout << head << " ";
        if(sizeof...(tail) != 0){
            Turing<tail...>().print();
        }else{
            cout << endl;
        }
    }

    Turing<head * 2, (tail * 2)...> map_double(){
        return Turing<head * 2, (tail * 2)...>();
    }

    template<int... appended>
    Turing<head, tail..., appended...> append(){
        return Turing<head, tail..., appended...>();
    }
    
    Turing<head> car(){
        return Turing<head>();
    }

    Turing<tail...> cdr(){
        return Turing<tail...>();
    }
};

int main(){
    Turing<1, 2, 3>().map_double().print();
    return 0;
}

```
TortoiseSVNでリポジトリを作成／公開する

WindowsサーバにSVNリポジトリを作成した際のメモ(TortoiseSVN(svnserve)利用)
### 基本情報
- 執筆：2018/2/13
- OS：WindowsServer2008R2(64bit)
- TortoiseSVN：Ver.1.9.7.27907

### プロトコルの選択
SVNのリポジトリにアクセスする際のプロトコルは以下の４種類がある模様。

- file
- http
- https
- svn
- svn+ssh

一番お手軽そうなsvnを利用。

### ソフトウェアインストール
お手軽、且つ今まで利用経験のあるTortoiseSVNを利用。svnserveを利用する際はcommand line clienttoolsをインストールする必要があります。
(デフォルトではインストールされないので、svnserveの実行モジュールが存在しない点でまずハマりました。)
<img src="https://qiita-image-store.s3.amazonaws.com/0/237065/0bfb6902-41d1-f88c-398a-14105393c02a.png" width=50%>

### リポジトリの新規作成
任意フォルダで右クリックしても、TortoiseSVNのメニューが出ない。これは再起動で出現するように。

### svnserveの実行
以下のページを参考にsvnserveの実行を試みるもエラーが発生、別マシンからsvnプロトコルでのアクセスができない。よく読んでみると「※anon-accessとかauth-accessとかの#コメントをはずすときは行の<font color ="red">先頭に空白は入れずに左詰</font>にしないとsvnserve起動時にエラーになるみたいなので注意。」
http://npnl.hatenablog.jp/entry/20070312/1173726110

svnserve.confの#を外して有効化する際、半角スペースを除去していないことが原因でした。半角スペースを除去し、svnserveを再起動したところ、無事アクセスできるように。執筆された方ありがとうございます。
PythonスクリプトからSlackにファイルを投稿する

Python と Slack API の学習がてら、サンプルプログラムを書いてみました。

## 解決したい課題
サーバ上の Pythonスクリプトを実行して、SlackのChannelに添付ファイルを投稿したい

## 実装例

```python
# coding:utf-8
import requests

TOKEN = 'Bot用のAPI token を入れてください'
CHANNEL = 'Channel IDを入れてください'

files = {'file': open("送りたいファイルをフルパスで記載", 'rb')}
param = {
    'token':TOKEN,
    'channels':CHANNEL,
    'filename':"filename",
    'initial_comment': "initial_comment",
    'title': "title"
}
requests.post(url="https://slack.com/api/files.upload",params=param, files=files)
```

## 実行例

```shell-session
$ python server2slack.py
```

## その他
・`pip` を使って `requests` を導入しておきましょう

```shell-session
$ curl -kL https://bootstrap.pypa.io/get-pip.py | python
$ pip install requests
```

・Bot用のAPI token は [App ディレクトリ](https://mamedeppo.slack.com/apps) から `Bots`を作成して、`Bots`の管理画面から取得してください

・Channelをブラウザで開いて、`https://xxx.slack.com/messages/{ChannelID}` が Chennel ID です。


・Private Channelに投稿したい時は、BotをそのChannelに `/invite` するのを忘れずに。

## 参考
[プログラムからSlackに画像投稿する方法まとめ](https://qiita.com/stkdev/items/992921572eefc7de4ad8#_reference-316ee8db418fa5f0ef2c)
[pipのインストール方法](https://qiita.com/suzuki_y/items/3261ffa9b67410803443)
長期インターンシップでpythonによるデータ分析を基礎から学習した

#はじめに
こんにちは。

私は新宿区にある大学に通う学生で、計量経済学を専攻しています。
データサイエンスに興味があり、この2月からプログラミング、さらに
機械学習について勉強を始めました。

この度、レッドフォックス株式会社の長期インターンシップに参加し、
pythonを用いたデータ分析について実践させていただいています。

その中で、学んだことを備忘録として、また私同様に初学者である方
の役に立つ様、まとめていきたいと思います。


#研修で行ったこと
Numpy, Pandas, seabornなど各種ライブラリの使用に
ついて、体系的に総ざらいしました。また、janome, Word2vecを
使った形態素解析、モデルへの書き出しを学びました。

自分で機械学習を学んでいた時には不要だった関数やメソッドが多く
出てきたため、自発的にドキュメントを参照するようになりました.

以下に、各ライブラリの機能で、私が学んだものを記そうと思います。

##Numpy

```python:インポート
import numpy as np
```

```python:アレイの作成
arr1 = np.array([1,2,3,4,5,6])
arr2 = np.arange(25).reshape((5,5))
arr3 = np.random.randn(10)
```

```python:アレイの計算
arr.T #転置
np.sqrt(arr) #平方根
np.add(arr1, arr2) #和
np.dot(arr1, arr2) #積
```

##Pandas

```python:インポート
import pandas as pd
```
```python:Series
ser = pd.Series([3,6,9,12], index = [a,b,c,d])
ser[ser>7] #条件を指定して要素を取り出す
ser_dict = ser.to_dict() #辞書型に変換
```
```python:DataFrame
df = pd.read_csv('a.csv')
df.describe() #統計量の表示
df.groupby('a') #aを基準にグループ分け
```
```python:欠損値処理
df.isnull() #データフレームの各項目がNaNであるかどうかをbool型で出力する
df.dropna(axis=0) #欠損値を含む行を取り除く

df.fillna(0) #欠損値を0で埋める

values = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
df.fillna(value=values)#欠損値を辞書のように置き換え

```
```python:データフレームをtsvとして保存
df.to_csv('df.tsv', sep='\t')
```
```python:データフレームの結合
pd.merge(df_1, df_2, 'inner')
#あるいは
df = pd.concat([df_1, df_2, df_3, d_4], axis=1)
```


##seaborn
```python:インポート
import seaborn as sns
```

```pythono:統計データの可視化
sns.lmplot(x='a', y='b', data=df, hue='c')
sns.pairplot()
sns.kdeplot(x, y, cmap=cmap, shade=True, cut=5, ax=ax)
sns.pairplot(df, hue="a")
sns.countplot()
sns,heatmap()
```

##機械学習
* 単回帰分析
* 多項式回帰
* ロジスティック回帰
* SVM
* 決定木分析


##形態素解析
* janome 日本語の文を形態素解析（文章を最小単位ごとに分け、
品詞を判別する）

* word2vec 形態素解析のモデル。

```python:
model.most_similar(positive=['a'])
```

というメソッドを用いて、aという単語と関連の深い単語を探すこと
ができる。

#おわりに
初学者の方はかえってドキュメントを見ずにできないことを諦めて
しまうことが多いと思いますが、各ライブラリはとても高機能なので
大抵のことができます。ここに書いた機能はよく使用されるものかも
しれませんが、ほんの一部です。

ネットで調べてわからないことでも、ドキュメントを見ることで一瞬で
解決することがあります。積極的にドキュメントを参照するといいと
思います。
winAppDev > Windows7とWindows10の違い > CaptionHeightとCaptionWidth > 15異なる (Windows 8.1はWindows 10と同じ)

### 関連

- [C++ Builder 10.2 Tokyo > Forms > Bug > 8個の子フォームを親フォームの下に4行 x 2列で配置する > 空白があいてしまう > 10.2 Tokyoの問題ではなさそう](https://qiita.com/7of9/items/426360c66715d276bc0d)

## OSによる値の違い

レジストリの下記を確認した。

`\HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics`

### Windows 7

- BorderWidth: -15
- CaptionHeight: -315
- CaptionWidth: -315
- PaddedBorderWidth: -60

### Windows 10 v1709

- BorderWidth: -15
- CaptionHeight: -330
- CaptionWidth: -330
- PaddedBorderWidth: -60

Windows 7とWindows 10でCaptionHeightとCaptionWidthが異なる。

### Windows 8.1 Pro 

- BorderWidth: -15
- CaptionHeight: -330
- CaptionWidth: -330
- PaddedBorderWidth: -60

Windows 8.1はWindows 10と同じ値になっている。

- Windows 8.1: マージンなし
- Windows 10: マージンあり

配置時のマージンの有無にはCaptionHeightとCaptionWidthは関係ないのだろう。

やはり、ウィンドウ自体の周りの枠の有無が効いているのだろう。

- Windows 8.1: 周りの枠あり
- Windows 10: 周りの枠なし
【jQuery】Syntax error, unrecognized expression とは

jQueryではバージョンが違うと、今まで正常に動作していたものでもエラーが出ることがあります。
「Syntax error, unrecognized expression」はそういった場合にありがちなエラーメッセージで、多くは引用符に問題がある場合に出現します。

例）` $('a[href^=#]').click(function(){` 

これは、jQuery1.11.2では正常に動作したコードですが、jQuery3.1.1では上記のエラーメッセージが出たコードです。
この場合下記のように修正することで、エラーは解消されます。

正）` $('a[href^="#"]').click(function(){`
CoreOSをインストール後に設定を変える

久しぶりにCoreOSを使おうとしたらインストール後に設定を変える方法が分からなかったのでメモしておきます．

* CoreOSの設定方法の変更について，どうやら2015年ぐらいから徐々にcloud-configからignitionに切り替わった様子
* cloud-config時代は `/var/lib/coreos-install/user_data` を書き換えて再起動していた
    * ignitionでインストールするとそんなファイルはないと怒られる
* インストール時に使用した `ignition.json` は `/usr/share/oem/coreos-install.json` にある
* 上記 `coreos-install.json` を書き換えただけでは設定が反映されない
    * cloud-configと違ってignitionでは初回ブート時のみプロビジョニングが実行される模様（こちらの方がスマート）
    * ignitionをもう一度行うためには `sudo touch /boot/coreos/first_boot` を実行してファイルを作成すれば良い
        * 何故かこの説明が分かりやすいところにはなくCoreOSの [Disk Layout](https://coreos.com/os/docs/latest/sdk-disk-partitions.html)の説明にある
0425授業

C#の基本文法を覚えるというのがメインでした。

元々ゲーム専攻でC++をメインに使っていたので書き方が少し違う程度で考え方は変わらないように思えました授業についていけないと思うことはありませんでした。




```c#:c#
using // 名前空間の指定

namespace MyConsoleApp// 名前空間
{
    class program// クラス名
    {
        static void Main(string[] args)//Mainというメソッドの定義
        {
            
        }
    }

}
```
↑　これが基本形になります。
C#の簡単な基礎とおまけ

#はじめに
いよいよ本格的にC#学んでいくことになりました！
今日は授業でやった内容を丸々書いていこうと思います。

開発環境
OS:windows10 64bit
IDE:visualStudio2012
##今日授業でやった内容
1.変数の定義
2.簡単な制御文
3.独自で作った誰得プログラム

#1.変数の定義
int,long,string,double,varを今日は使いました。
intやstringやlongなどは、前に何度か使ったことあるのである程度の理解はできていましたが。
longからintに変換することはできないというのは初めて知りました。
例えば
int a = 11;

long b=a;
だとlongに入ります。ですが
long a=11;

int b=a;
ですと、longの方が大きいのでintに入らないようです。
メロンの器にリンゴの器は入りますが、リンゴの器にはメロンの器は入らない、と自分の中で解釈してしまいました（笑）
##簡単な制御文や繰り返し分
ifとwhileとswitchとforを今日は使いました。
どれもこれもC言語と使い方は変わらないと感じました。

```program.cs
Console.Write("数字を入力してください：");
            var a = int.Parse(Console.ReadLine());
            Console.Write("割る数値を入力してください：");
            var b = int.Parse(Console.ReadLine());
            //int c =0;
            if (a % b == 0)
            {
                Console.WriteLine(a + "は、偶数です。");
            }
            else
            {
                Console.WriteLine(a + "は、奇数です。");
            }
```
やることはC言語とあまり変わらないし見た目もVBに似ているのですごいやりやすいです('ω')
**次はswitch文です**

![22png.png](https://qiita-image-store.s3.amazonaws.com/0/249281/eb39ddc3-8423-4cb7-c658-964ca17f5484.png)

四季を表示する簡単なプログラムです！12以上や0を入力した際に
エラーが出るように作っています。
forとwhileは改造しすぎて見せれる状態じゃないので完成したらまた載せます('ω')
#3.独自で作った誰得プログラム
毎回恒例のおまけコーナーです（笑）
Beepのことをサラッと先生が説明してくれたので少し自分で勉強して
カエルの歌の途中までをピープ音で鳴らしてみました( ﾟДﾟ)
よかったらコピーして聞いてみてください（笑）

```csharp:Program.cs
        static void Main(string[] args)
        {
            //BEEPでカエルの歌の途中まで作成
            Console.Beep(540, 250);
            Console.Beep(594, 250);
            Console.Beep(654, 250);
            Console.Beep(687, 250);
            Console.Beep(654, 250);
            Console.Beep(594, 250);
            Console.Beep(540, 250);
            System.Threading.Thread.Sleep(250);
            Console.Beep(654, 250);
            Console.Beep(687, 250);
            Console.Beep(759, 250);
            Console.Beep(840, 250);
            Console.Beep(759, 250);
            Console.Beep(687, 250);
            Console.Beep(654, 250);
            System.Threading.Thread.Sleep(500);
            Console.Beep(540, 600);
            System.Threading.Thread.Sleep(500);
            Console.Beep(540, 600);
            System.Threading.Thread.Sleep(500);
            Console.Beep(540, 600);
            System.Threading.Thread.Sleep(500);
            Console.Beep(540, 600);
        }
```
それとなぜか微妙にいい感じになった分も載せておきます

```csharp:first.cs
static void Beep()
{
Console.ReadKey();
Console.Beep();
Console.Beep(1000,2000);
Console.Beep(750,1000);
Console.Beep(650,1000);
Console.Beep(550,500);
Console.Beep(650,500);
System.Threading.Thread.Sleep(500);
Console.ReadKey();
Console.WriteLine("\r\n何かのキーを押すと終了します。");
Console.ReadKey();
}
```
ビープ音も周波数などを変えればなかなか面白いものになるんですね( *´艸｀)
【SpatiaLite】Intersection、Intersects関数の例

`Intersection`関数は2つのジオメトリを引数にとり、それら2つのジオメトリの重なっている領域を返します。

```sql

SELECT
	AsText(
		Intersection(
			GeomFromText(
				'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))',
				4326
			),
			GeomFromText(
				'POLYGON((0.8 0.8, 1.2 0.8, 1.2 1.2, 0.8 1.2, 0.8 0.8))',
				4326
			)
		)
	)
;

-- POLYGON((0.8 1, 1 1, 1 0.8, 0.8 0.8, 0.8 1))
```

2つの`POLYGON`がある一点で重なっている場合、`POINT`が返されます。

```sql

SELECT
	AsText(
		Intersection(
			GeomFromText(
				'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))',
				4326
			),
			GeomFromText(
				'POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))',
				4326
			)
		)
	)
;
-- POINT(1 1)
```

全く重なっている領域がない場合は、`NULL`が返されます。

```sql
SELECT
	AsText(
		Intersects(
			GeomFromText(
				'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))',
				4326
			),
			GeomFromText(
				'POLYGON((1.1 1.1, 2 1, 2 2, 1 2, 1.1 1.1))',
				4326
			)
		)
	)
;
-- NULL
```

`Intersects`関数は、`Intersection`関数と同様に2つのジオメトリを引数にとり、それらに重なっている領域があれば`1`を、なければ`0`を返します。
上記の例と同じジオメトリに対して、`Intersects`を呼び出すと以下のようになります。

```sql
SELECT
	Intersects(
		GeomFromText(
			'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))',
			4326
		),
		GeomFromText(
			'POLYGON((0.8 0.8, 1.2 0.8, 1.2 1.2, 0.8 1.2, 0.8 0.8))',
			4326
		)
	)
;
-- 1

SELECT
	Intersects(
		GeomFromText(
			'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))',
			4326
		),
		GeomFromText(
			'POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))',
			4326
		)
	)
;
-- 1

SELECT
	Intersects(
		GeomFromText(
			'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))',
			4326
		),
		GeomFromText(
			'POLYGON((1.1 1.1, 2 1, 2 2, 1 2, 1.1 1.1))',
			4326
		)
	)
;
-- 0
```
プロジェクトの目的

授業でした内容を自分のメモとして書き残します。

---

■ アプリケーションを開発する目的

『 世の中の課題や問題をその人の立場になって解決し、人を幸せにすること。 』

① ターゲット
② ニーズ
③ 目的

⇒ 上記の三つを合わせて考えることが大切であり、それによって製品の価値が決まる

■ シーズとニーズ

シーズ：技術、種
ニーズ：必要とされるもの、要望

⇒ シーズとニーズが合わないと**目的**は達成されない

■ 開発の仕方の変化

- ウォーターフォール
    - 上流から下流へと開発
    - 大規模開発向け
- アジャイル開発
    - 一番大切なことを先に開発

■ ターゲット設定

今回は 『 ペルソナ設定 』 を使用し、世の中の問題解決を目指す
⇒ 次工程、『 カスタマージャーニーマップ 』 のために、できるだけ細かく設定すること

※ カスタマージャーニーマップ ※
企画や事業などを立ち上げる際にあらかじめ設定した ペルソナの動きを可視化したもの

---

最後までお読みいただきありがとうございました。
C#の基本文法メモ

####VisualStudio2012のC#のコンソールアプリケーションを選択。
するとProgram.csというソースが生成される。
中身はこんな感じ
```using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;```

```namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}```

####まず最初に一番上に5つほどあるusing System～というのは名前空間というのを宣言するためのもの。
名前空間とは大量にあるクラスを入れてるファイルみたいなものでこれがなければ使えないクラスが出てくるので消さないように。

####次にnamespace ConsoleApplication2とclass Programについて。まずこれは両方namespace helloやclass bye　のように後ろの部分は自分で名前を付けられる。
また、namespaceの｛｝の中にはクラスを、classの中にはクラスの内容を書き込める。

####次にstatic void Main(string[] args)について。
これはMainというメゾッドを定義するもの。
これで様々な処理や働きを作成していつでも呼び出せるようにしている。
このMainメゾッド直下の｛｝にソースコードを書く。

ちなみにこんなのは全部覚える必要はなく、ただ何となくあーこれ消したら使えない機能でてくるなーくらいの認識でいいのではと思う。

####次に値について。
値にはいろいろなものがある。
大まかにテキスト、整数、実数、真偽値、文字などがある。

####リテラルとは
リテラルとは直接コード内に書かれている値のこと。

####変数について。
変数とは値を入れる入れ物のことである。
例:int a
a = 10
みたいな感じなものである
なおこの例は int a = 10という風にまとめて書くことができる。
#####変数のタイプについて
変数にもタイプがある。
例のint a というのはaというものの中に整数が入るよっていう感じのタイプ。
int以外にも実数ではdouble、文字、テキストはchar,stringまた、真偽値を入れるboolなどほかにもいろいろある。
次回は実際にプログラムを書いていく。
Atomに変えてみた結果の感想

### はじめに

VScode使っている私でしたがエンジニア界ではAtomユーザの数が非常に多いという印象を受けています。

なので長いものに巻かれろの言葉が示すように、マイノリティを貫かず多数派の一員になることしました。


### 実際に導入したパッケージ
導入方法等は割愛します。私書いたのより調べて出てきた方が間違いなくわかりやすいです。

ここでは導入して良かったパッケージ書いおこうと思います。

* markdown-preview

 左右で分割しマーダウンで書いたファイルの表示結果を見ることができます。

* markdown-scroll-sync

分割表示された表示結果編集画スクロール同期するようになります。

この2つ入れるだけ記事作成が非常に楽になりました(元々の文章能力が低いのは変わらない…)


### 導入した感想
VScodeよりも直感的な操作がしやすく、今回は触れてませんがgitとの連携も簡単にできたので変えてよかったと思います。

VScodeでも調べたらできるようなことだと思いますが、特に時間もかけず使い方を把握できるという点でAtomの方が使いやすいと感じます。

### おまけ
キーボート設定は弄ってますか？

私は、このまとめ作成するにあたって初めて本格的に変更しました。


何が駄目ったかというと、マークダウン記法書いているのです記号の入力が手間！

そのままだと全角設定なので「#」も「＃」なるし「*」も「＊」なるのちゃん記号は半角設変えておくのおすすめします。


あと全角スペースは滅んでいいです。何をするにも半角スペースが必要なのに、日本語入力キーボードだと全角スペース挿入される…
邪魔なんだ……






#### 謝罪
もっと書きたいことあると思うのですが、文面に起こせなかったのでこれからがんばります。
laravel5.4クエリビルダのwhereとorWhereをfor文で使う

##はじめに
渡されたキーワードの数によってwhere文を変えたいということがありました。
具体的には、2つ以上キーワードがあるときは、2つ目からはorWhereにするという感じです。
クエリビルダで書くと結構長くなりました。

##コード
```catsController.php
    public static function getName($keyWords)
    {
        $result = array();
        return $result = DB::table('Cats')
        ->select('Name')
        ->where(function ($query) use ($keyWords){
            if(count($keyWords) > 1)
            {
                $query->where('Description', 'like', "%$keyWords[0]%");
                for($i=1;$i<count($keyWords);$i++)
                {
                    $query->orWhere('Description', 'like', "%$keyWords[$i]%");
                }
            }
            else if(count($keyWords) == 1)
            {
                $query->where('Description', 'like', "%$keyWords%");
            }
        })
        ->orderBy('Name', 'asc')
        ->get();
    }
```
#####Catsテーブル
| ID | Name | Description |
|:----------------:|:----------------:|:----------------:|
|1| blossom | blossomは茶トラです。 |
|2| bubbles | bubblesは白と灰色です。 |
|3| buttercup | buttercupは茶トラです。 |

渡されたキーワードが1つだった場合と、1つを超える場合で出しわけをしています。
1つを超える場合は、そのキーワードの2つ目からはorWhereをfor文でまわしています。
発行されるSQLと実行結果は、以下のような感じになります。

##キーワードが2つ以上だった場合
```
select Name from Cats where (Description like "%bubbles%" or Description like "%blossom%") order by Name asc
```
| Name |
|:----------------:|
| blossom |
| bubbles |
##キーワードが1つだった場合
```
select Name from Cats where (Description like "%bubbles%") order by Name asc
```
| Name |
|:----------------:|
| bubbles |
Azure MobileApp に Azure AD B2C のアカウントでサインインしてデータ同期する

# Azure MobileApp に Azure AD B2C のアカウントでサインインしてデータ同期する

今回は前に取り上げた [Azure B2C によるユーザ管理の外出し](https://qiita.com/yossy6954/items/f21cef297106e3c05e45)と同じく取り上げた [Azure MobileApp によるユーザ個別データ管理](https://qiita.com/yossy6954/items/089a1f602f45cf686a3c)の合わせ技、Azure B2C アカウントごとのユーザ個別データの同期方法についてまとめます。


## モバイルアプリ側に AzureB2C サインイン機能を追加

Xamarin.Forms のAzureB2Cサインイン実装方法に関しては [公式ドキュメント](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/azure-ad-b2c) を参照。

重要なのは、MobileServiceClient.LoginAsync() に AzureB2C から取得したアクセストークンを渡すとログイン画面を出さず、渡したトークンを使ってアクセスしてくれる事です。
MSALで取得したトークンを使いまわす事ができるので、MSALでログインした後 MobileApp へのログインでもう一度ログイン画面を出す～ というような事は必要ありません。

```cs
public async Task<bool> LoginAsync(string accessToken) {
    var payload = new JObject();
    payload["access_token"] = accessToken;

    var User = await CurrentClient.LoginAsync(
        MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory,
        payload);
    return true;
}
```

記事の最後にクイックスタートのTodoアプリの認証をB2Cログインに変更したもののソースを貼っておきます。

## サーバ側変更

MobileApp の "認証/承認" で Azure Active Directory の認証プロバイダーを設定します。同じサブスクリプション上の Azure AD に登録されたアプリなら"簡易"から設定できますが、Azure B2C のアプリは対応していないので、"詳細"でクライアントIDと発行者URLを設定する事になります。

![activedirectory-setup.png](https://qiita-image-store.s3.amazonaws.com/0/246831/0f5c0454-5dcb-11e7-07cf-9597eb95ce5d.png)

"詳細"での設定項目は上画像の通り。

* クライアントID - Azure B2C に登録したアプリのアプリケーションIDです。クライアントIDとアプリケーションIDは用語が統一されていなくて気持ち悪いですね。

* 発行者のURL - 発行者のURLです。書式ですが、"https://login.microsoftonline.com/tfp/{テナントID(xxxx.onmicrosoft.com)}/{サインイン用ポリシー名}/v2.0/.well-known/openid-configuration" と入れるのが正しいみたいです。

![enable-native-client.png](https://qiita-image-store.s3.amazonaws.com/0/246831/bafc06ce-45e1-b53e-7ff9-8ce6241762d3.png)

あと今回はネイティブアプリからのサインインになるので、AzureB2C側に登録したアプリケーションの"ネイティブ クライアントを含める"もONにしておきましょう。

## リソース

* [Integrating Azure Active Directory B2C with Azure Mobile Apps](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/azure-ad-b2c-mobile-app)
* [今回実験したB2C対応Todoアプリ(UWPのみ)のソース](https://github.com/yossy6954/MobileApp_Xamarin_Forms_Example/tree/b2c_integration)