OmniAICreator/Qiita-1.07M huggingface dataset:
Vuetify 2.0へのアップグレード時にやったこと

# 概要
2019/7/23に Vuetify 2.0が正式リリースされました。
旧バージョン(1.5.5)からアップグレードする際に少し詰まったので、やったことを備忘録としてまとめておきます。

# やったこと

### package.json
バージョンアップするためにpackage.jsonを修正。
修正後に npm install します。

```diff:package.json抜粋
"dependencies": {
-    "vuetify": "^1.5.5"
+    "vuetify": "^2.0.0"
},
"devDependencies": {
-    "@vue/cli-plugin-babel": "^3.9.0",
-    "@vue/cli-plugin-eslint": "^3.9.0",
-    "@vue/cli-service": "^3.9.0",
+    "@vue/cli-plugin-babel": "^3.10.0",
+    "@vue/cli-plugin-eslint": "^3.10.0",
+    "@vue/cli-service": "^3.10.0",
-    "stylus": "^0.54.5",
-    "stylus-loader": "^3.0.1",
+    "sass": "^1.17.4",
+    "sass-loader": "^7.1.0",
-    "vuetify-loader": "^1.0.5"
+    "vuetify-loader": "^1.2.2"
}
``` 

### main.js
Vueインスタンスの作成時に、Vuetifyのインスタンスをオプションで渡すようにしました。

```diff:main.js
import Vue from 'vue'
import 'material-icons/iconfont/material-icons.css'
-import './plugins/vuetify'
+import vuetify from './plugins/vuetify'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
+ vuetify,
  render: h => h(App)
}).$mount('#app')
```

### vuetify.js
Vuetifyのインスタンスをexportするようにしました。
これをmain.jsでimportします。

```diff:vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
-import 'vuetify/src/stylus/app.styl'
+import 'vuetify/src/styles/main.sass'
-
-Vue.use(Vuetify, {
-  iconfont: 'md',
-}) 
+
+Vue.use(Vuetify);
+export default new Vuetify({
+  icons: {
+    iconfont: 'mdi',
+  },
+});
```

### App.vue
\<v-app>で全体を囲うようにします。
これがないと、配下の全要素でcolor属性が反映されなくなりましたので注意。

```diff:App.vue
<template>
+  <v-app>
    ~~~
+  </v-app>
</template>
```

### その他vueファイル

コンポ名や属性名が変わった部分を修正しました。
私の場合では、下記を修正。

|修正前                 |修正後                |
|:--------------------:|:--------------------:|
|\<v-list-tile>        |\<v-list-item>        |
|\<v-list-tile-content>|\<v-list-item-content>|
|\<v-list-tile-action> |\<v-list-item-action> |
|\<v-btn flat>         |\<v-btn text>         |

動かなくなったコンポがあれば、下記ドキュメントページでコンポ名の変更等がないかを調べてみましょう。
[v1.5のドキュメント](https://v15.vuetifyjs.com/ja/components/api-explorer)
[最新のドキュメント](https://vuetifyjs.com/ja/components/api-explorer)

# おわりに
上記修正で、バージョンアップ後も問題なくアプリが動作するようになりました。
が、理由がよく分かっていないところも多いです。。
細かい仕様は追々調べていく予定。
Unreal C++のビルドエラー 「Exhausted all retries!」の解決方法

#はじめに
VisualStudioでビルドする際に出た

```
Exhausted all retries!
```
というエラーの解決方法について備忘録も兼ねて記事を書きます。
#解決方法
VisualStudioではなくUnrealエディタでコンパイルをします。
一度Unrealエディタ側でコンパイルすると通常通りVisualStudio側でもビルドできるようになります。
#おわりに
「Exhausted all retries!」は直訳すると「すべての再試行を使い果たしました！」ですが、何のことだか良く分からないですね。
詳しい内容が気になるので分かる方が居ましたら、コメントなどで教えて頂けると嬉しいです！
Node.jsにてMySQLのORM:sequelize

#はじめに

JAVAではRDBのデータのCURD処理はJDBC経由で操作できます。自由度が高い反面、SQL書く際に可読性、保守性が弱い問題があります。
ORMの発達でHibernate、MyBatis、jOOQなどのライブラリを利用して仕組み上はよくなります。

Node.jsからMySQLなどのRDBを操作する場合もORMを利用したほうが良いと思います。
特にテーブルのカラム数が多い場合は、？の数など一致しないミスが発生しやすいからです。また、SQLインジェクションも注意する必要があります。

Node.jsのMySQLのORMとしてSequelizeは有名です。
SequelizeはMySQL、MariaDB、PostgreSQL、SQL Serverもサポートします。

Sequelize：https://sequelize.org/

#インストール
`npm install --save sequelize`
`npm install --save mysql2`

#使い方
##sequelize定義
```javascript
const Sequelize = require('sequelize');

const sequelize = new Sequelize('database', 'username', 'password', {
  dialect: 'mysql'
})
```

##sequelizeプールの場合
```javascript
const sequelize = new Sequelize('database', 'username', 'password', {
  dialect: 'mysql',
  host: 'localhost',
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
});
```

#モデル定義
```javascript
const UserModel = sequelize.define(
  'users',
  {
    userId: {
      field: 'user_id',
      type: Sequelize.INTEGER(11),
      primaryKey: true,
      autoIncrement: true
    }, // INT(11)       NOT NULL  PRIMARY KEY  AUTO_INCREMENT
    lastName: {
      field: 'last_name',
      type: Sequelize.STRING(32),
      allowNull: true
    },
    firstName: {
      field: 'first_name',
      type: Sequelize.STRING(32),
      allowNull: true
    }
  },
  {
    timestamps: true,
    createdAt: false, //デフォルト項目を生成しないように
    updatedAt: false,  //デフォルト項目を生成しないように
    tableName: "users" //明示的にテーブル名を指定
  }
)

```

データタイプ：https://sequelize.org/master/manual/data-types.html

#CURDメソッドを用意
```javascript
exports.find = async function(whereData) {
  return await UserModel.findAll({
    where: whereData
  })
}

exports.get = async function(userId) {
  return await UserModel.findByPk(userId)
}

exports.update = async function(updateData, whereCondition, updateFields) {
  return await UserModel.update(updateData, {
    where: whereCondition,
    fields: updateFields
  })
}

exports.create = async function(userData) {
  return await UserModel.create(userData)
}

```

詳しく説明：https://sequelize.org/master/manual/models-definition.html

#ユーザー更新例
```javascript
  const whereCondition = {
    userId: 10000  //更新条件
  }
  const updateFields = ['lastName', 'firstName']  //指定したカラムのみ更新
  const updateData = { lastName: 'yamata', firstName: 'tarou' } //更新データ

  const result = await mysqlUser.update(updateData, whereCondition, updateFields)

```

updateのSQLを書くより楽です。

以上
シェルで書くshebangのオプションはsetにつけた方が便利な話 

#はじめに
シェルのshebangって難しいですよね。

ぶっちゃけ私も完全に理解しているわけではありませんが、使い方がわかると意外と便利です。

今回はshファイルを実行する場合に、shebangに渡すオプションをsetに渡すようにするだけで便利になる話をご紹介します！

#例
サンプルコードとして下記を用意しました。test.shというファイルを作成してコードを書きます。

```:test.sh
cp sample.txt test/
echo "つづくよー"
```

処理内容は、ファイルをコピーして文字列を出力するだけです。ですがsample.txtもtestディレクトリも用意してないので、当然エラーになります。

下記コマンドで実行できますので、ぜひローカルでも試してみてください！

```
$ sh test.sh
```

##shebangにオプションをつけた場合

```:test.sh
##!/bin/bash -xe

cp sample.txt test/
echo "つづくよー"
```

実行結果は下記になりました。

```
cp: directory test does not exist
つづくよー
```

って、エラーなのに次の処理が続いちゃっとるー！wwwww

##setにオプションをつけた場合

```:test.sh
##!/bin/bash
set -xe

cp sample.txt test/
echo "つづくよー"
```

実行結果は下記になりました。

```
+ cp sample.txt test/
cp: directory test does not exist
```
エラーが出た行でちゃんと止まりました！

ちなみにxオプションで実行するコード自体を出力しています。eオプションによってエラーで処理が止まるようになっています。

##原理
聞けば当然ですが、shebangに渡したオプションはshebang経由で起動しないと有効になりません。

そしてファイル名指定で起動した場合は有効になりません。


#用途
私の周りではJenkinsのJob内で使うshファイルに使っています。

大体の場合、途中で1行でも失敗したらその後の処理もおかしくなりますが、shebangにオプション付けると一番最後の行が成功したら成功ステータスで終わっちゃうんですよね。

setにオプションをつけることによって、スクリプトが1行でも失敗したらJobを失敗ステータスにすることができます。
Dockerコンテナ内から同一ホストの別コンテナにホストを経由してアクセスできない

世の中、覚えなければ上手く行かないことが多すぎる。だから、全てを覚えてから始めるんじゃなくて、やってみて失敗してから掘り下げるアプローチが好きです。まどかママの「上手な転び方を覚え」るってのは至言だと思う。

そんな訳で、Keycloakで認証を行うWebアプリを開発していて、動作確認も終わり、いざ検証環境で動かそうとしたら、Webアプリの起動が失敗してしまった。

システムの構成と経緯は以下のようなイメージ。
![](http://www.plantuml.com/plantuml/png/oymhIIrAIqnELSWeAIbGI2nMo4wjJCx9Jyps0FAvCZ6aanAJirFpKi2oNCdvkGNvUQbv9GhUK5r8Ge-R9pnkRdxSjFvnquh7pPiVDtSYwKTHD_LnyrgmYWuKfMb5-K3hWMg10DbL2he8wv2S0nI66Sx51TEheATdX-ncAw1rgnutxNtSlETnqyx7ZJiUDwvxtBG8xChTG15KZSYsWdHsWBMj1pcnSTtJ_cbFzqs7kK21aF9dI-QyMB470000)

* Keycloakサーバは、検証環境でdocker-composeを使って構築。
* Webアプリは、バックエンドをSpring Boot、フロントエンドをAngularで開発。
    * Angularアプリではkeycloak-angularを使用。
    * Spring Bootアプリはリソースサーバとして動作するのでspring-boot-starter-oauth2-resource-serverを使い、Angularアプリから送られてきたトークンを検証。

* 開発中は、検証環境のKeycloakサーバに接続して動作を確認。
* __Webアプリをコンテナにして、検証環境のKeycloakサーバと同じホストのDocker上で起動すると、Spring BootアプリからKeycloakサーバへの経路がない(no route to host)とのエラーで終了していた。__

## まず試したこと
そこでKeycloakコンテナとWebアプリコンテナを同じDockerネットワークに参加させ、Spring BootアプリからDockerネットワーク経由で接続するようにしてみた。

1. ```docker network create ${ネットワーク名}```でネットワークを作成。
2. KeycloakとWebアプリのdocker-compose.ymlで、上記のネットワークに参加するように設定。

```yaml:例)Webアプリのdocker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
    container_name: app
    ports:
      - 50010:8080
    networks:
      - ${ネットワーク名}
networks:
  ${ネットワーク名}:
    external: true
```
```yaml:SpringBootアプリのapplication.yml
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://${keycloakコンテナ名}.${ネットワーク名}:8080/auth/realms/${レルム名}
```

これでSpring Bootアプリは、Keycloakサーバと通信が成功して、正常に起動するようにはなった。
が、Angularアプリでログインを行うと、keycloakサーバへのログインに成功するものの、その後で__AngularアプリからSpring BootアプリへのAjax通信で 401 Unauthorizedとなってしまった。__

ブラウザでレスポンスを見てみると、ヘッダに以下の情報があった。

```
WWW-Authenticate: Bearer error="invalid_token",
                  error_description="This iss claim is not equal to the configured issuer", 
                  error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"
```
どうやらAngularアプリとSpring BootアプリがアクセスするKeycloakサーバのURLは一致していないとのこと。
__なので、どうしてもDockerコンテナ内部から外部ネット経由でアクセスする必要だった。__

## 根本の原因
そこでネットから情報を漁ると、Dockerがiptablesを設定していて、それによって通信ができないらしい。
[こちらの記事](https://blog.tiqwab.com/2018/02/12/learniing-iptables.html)とか参考にしてiptablesの見方を勉強してみた。
まだ完全に理解できていないが、自ホストからパケットを送信する場合のチェインを辿ってみると、、、

```
# iptables -t nat -nvL POSTROUTING
Chain POSTROUTING (policy ACCEPT 12 packets, 853 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
 ※あとは割愛
```
Dockerkコンテナにデフォルトで割り当てられるbridgeネットワークのアドレス172.17.0.0/16からの通信は、docker0ブリッジには戻れない設定だと思えた。


## 回避策
現状の理解ではiptablesを弄るのもハードルが高いので、WebアプリのDockerコンテナがデフォルトのbridgeドライバを使ったネットワークではなく、hostドライバを使うように指定した。

```yaml:docker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
    container_name: app
    network_mode: host     # 追加
# ポートマッピングは使えなくなるので削除
#    ports:
#      - 50010:8080
```

これによりコンテナ内部で使うポートが、直接ホストで使われてしまうが、そこはSpring Bootの設定ファイルで簡単にポート番号を変更できるので良しとしました。
3x3の○×ゲーム（三目並べ）の全事象

# はじめに
peing のサイトに『3×3の○×ゲームの全事象は何通りあるのでしょうか』と質問がきました。面白そうなので，考えてみることにしました。

# ざっくりと

先手を○，後手を×とする。9個のマス


1 2 3
4 5 6
7 8 9

に○×○×○×○×○を順に入れていくこと考えます。

そうすると，
$$9!=362880\text{（通り）}$$
となります。

## 例 1

|1|3|6|4|7|5|9|2|8|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|○|×|○|×|○|×|○|×|○|

のケースは


![IMG_1395.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426542/8db8227d-ddcd-ea98-56ca-73780cc87c30.jpeg)


で9回目で先手の勝利となります。


## 例 2


|1|3|5|4|9|6|7|2|8|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|○|×|○|×|○|×|○|×|○|

のケースは


![IMG_1396.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426542/16c8a42e-bbd0-1654-9b6a-af0a9a45e4ff.jpeg)

で5回目で先手の勝利となります。通常は6手目から9手目はやりません。
6手目から9手目を変更しても，5回目で先手の勝利であることは変わらないので，
5回目までのところで，終了すると，例1のケースよりも$4!=24$倍の重みがあることになります。

# 本格的に数える！


まず，それぞれゲームの終わる回数別に分けていきます。

- 先手が勝つ場合
５手目，７手目，９手目

- 後手が勝つ場合
６手目，８手目

- 引き分けの場合
９手目

です。この６パターンで場合の数を計算します。

# コーディング

```3x3game.jl
function eva(X)
    a,b,c,d,e,f,g,h,i=X[1],X[2],X[3],X[4],X[5],X[6],X[7],X[8],X[9]
    abs(a+b+c)==3 || abs(d+e+f)==3 || abs(g+h+i)==3 || abs(a+d+g)==3 || abs(b+e+h)==3 || abs(c+f+i)==3 || abs(a+e+i)==3 || abs(c+e+g)==3
end

using Combinatorics
X=[1,2,3,4,5,6,7,8,9]
Y=collect(permutations(X))
Z=[]
for i=1:length(Y)
    A=Y[i]
    B=[0,0,0,0,0,0,0,0,0]
    for k in [1,3]
        B[A[k]]=1
        B[A[k+1]]=-1   
    end

    B[A[5]]=1
    if eva(B)
        append!(Z,5)
        continue
    end
    

    B[A[6]]=-1
    if eva(B)
        append!(Z,6)
        continue
    end 


    B[A[7]]=1
    if eva(B)
        append!(Z,7)
        continue
    end  


    B[A[8]]=-1
    if eva(B)
        append!(Z,8)
        continue
    end 
    
    
    B[A[9]]=1
    if eva(B)
        append!(Z,9)
        else append!(Z,10)
    end 
end

println("5手目で先手が勝つのは",Int(count(Z.==5)/24),"通り")
println("6手目で後手が勝つのは",Int(count(Z.==6)/6),"通り")
println("7手目で先手が勝つのは",Int(count(Z.==7)/2),"通り")
println("8手目で後手が勝つのは",count(Z.==8),"通り")
println("9手目で先手が勝つのは",count(Z.==9),"通り")
println("9手目で引き分けとなるのは",count(Z.==10),"通り")
println("先手の勝つ確率は",(count(Z.==5)+count(Z.==7)+count(Z.==9))/factorial(9))
println("後手の勝つ確率は",(count(Z.==6)+count(Z.==8))/factorial(9))
println("引き分けの確率は",(count(Z.==10))/factorial(9))

```

 # 結果

5手目で先手が勝つのは1440通り
6手目で後手が勝つのは5328通り
7手目で先手が勝つのは47952通り
8手目で後手が勝つのは72576通り
9手目で先手が勝つのは81792通り
9手目で引き分けとなるのは46080通り
先手の勝つ確率は0.584920634920635
後手の勝つ確率は0.28809523809523807
引き分けの確率は0.12698412698412698

全事象の個数は
$$1440+5328+47952+72576+81792+46080=255168\text{（通り）}$$
です。

重みが違うので確率を求めるときは注意です。重みを考えると，
$$1440\times24+5328\times6+47952\times2+72576+81792+46080=362880=9!\text{（通り）}$$
となります。
先手の勝つ確率は
$$\frac{1440\times 24+47952\times2+81792}{362880}=0.584920634920635$$

後手の勝つ確率は
$$\frac{5328\times 6+72576}{362880}=0.28809523809523807$$

引き分けの確率は

$$\frac{46080}{362880}=0.12698412698412698$$

# 戦略的に進めると

確率は求まりましたが，実際にはゲームは先手・後手が必ず負けないように戦略的に配置することができるので，うまくやると，ずっと引き分けが続きます。

○と×を書く場所を戻さない形のくじ引きで決めていくと，それぞれの確率は前述のようになります。

＜参考＞
https://ja.wikipedia.org/wiki/三目並べ
NanoPi NEO2のヒートシンクを強力にしてみた。

##はじめに
市販のNanoPi用ヒートシンクだけではCPU温度が上昇し動作クロックが低下することがあります。
ヒートシンクをパワーアップしてよく冷えるようにしてみました。

##材料
　4cm×4cm　角座金　6枚　　（ホームセンターに売っています。）

##製作時間
　約5分

##作り方
　角座金の一辺に瞬間接着材をつけて、NanoPi用ヒートシンクの溝に差し込むだけでできあがり。

##完成形
　![IMG_20190729_221304_973.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466195/7c60a4ab-c1ca-d6dd-7551-105d3ce2d47c.jpeg)

##結果
 室温や負荷によりますが、CPU温度は摂氏35度～45度くらいです。
Xcodeを消してから入れ直したらSimulator(シミュレータ)が消えた

##Xcodeを入れ直した
私はAppleのサイトから直接Xcodeをダウンロードしていた為、更新が楽な様にAppleStoreの方からダウンロードをし直しました。その後、ビルドしてSimulator(シミュレータ)を起動しようとしたら**デバイスが一つも見当たらなかった**のです。

<img width="938" alt="15152e70c4f59d8fcfaea58f5e8edc67.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456470/adb235b9-7c82-8b63-fe16-48e30b558db9.jpeg">
##Simulator(シミュレータ)が入ってない
結果としては、**新しいXcodeの方にSimulator(シミュレータ)が入ってなかった**のが原因でした。入れ直す方法は、Xcodeを起動し、Xcode→Preferences→Componentsとクリックしていき、ダウンロードしたいSimulator(シミュレータ)のバージョンをクリックするだけです。

<img width="797" alt="10daf20f99bcb60d6d3b8f7dde4b49cf.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456470/1ffee09e-a61f-5b41-f453-c18c8fcc624f.png">
##ダウンロード後
<img width="1440" alt="c6fcc9035efdd90d49450b9fb3d2e340.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456470/85b1e0bc-2994-fcf5-f136-ab6c2b692bfb.jpeg">
<img width="1438" alt="f26080022ac8520e73f7d1ce138fe487.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456470/8f751ce2-0b0b-0307-3cea-7088cf2b8e4f.jpeg">
**Xcode側のiosのバージョンを二箇所、ダウンロードしたSimulator(シミュレータ)のバージョンに合わせれば無事に反映されます。**
<img width="1440" alt="87e2cdbc77617a937fe07180004e14c9.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456470/bb7a3402-255a-546f-2209-11031743e6f6.jpeg">

**左上にiPhoneXsが反映されています。**
**ちなみに、アップデート後は変なエラーが出る可能性があるので、macを再起動した方が良いです**
FSx for Windowsでvssやってみたら日本語EC2(Windows)だと失敗する件

すごく久しぶりに投稿です。
サボってました。1年ぶりです。

#Amazon FSx for Windowsでvss設定をEC2 Windows 日本語からやる方法
FSx for WindowsでVolume Shadow Copyがサポートされたとのことでやってみました。

参考：[AWSドキュメント](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/shadow-copies-fsxW.html)

FSx for Windowsの作成等は、みなさんいろいろ記事かかれてるので、割愛します。

実施環境は以下です。

- AWS MicrosoftAD
- 管理用EC2(AMI：Windows_Server-2016-Japanese-Full-Base-2019.07.12 - ami-0bc8442658e36a4d2)
  - AWS MicrosoftAD参加後、FSx fow WindowsボリュームをZドライブにマウントした状態
- FSx for Windowsボリューム 1つ

**ドキュメントのとおり実施しても失敗します。(タイトルどおり)**

<img width="1076" alt="fsx_vss_result.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191445/60845c6c-b83d-aa24-1249-0054c4cf9d0c.png">

#英語OSだと成功します。
やることは上記URLのリンクにあるようにするだけです。

`FSxFileSystem-DNS-Name`は環境毎の実際のDNS名に置き換えてください。
例：fs-xxxxxxxxx.ドメイン名

```
Invoke-Command -ComputerName FSxFileSystem-DNS-Name -ConfigurationName FSxRemoteAdmin -scriptblock {Set-FsxShadowStorage -Default}
```

```
Invoke-Command -ComputerName FSxFileSystem-DNS-Name -ConfigurationName FSxRemoteAdmin -scriptblock {Set-FsxShadowCopySchedule -Default}
```

**補足**
`Invoke-Command`
コマンド、スクリプトを対象のサーバ(ローカル or リモート)で実行し、結果をローカルに返す

`scriptblock`
実行したいコマンド、スクリプト

#日本語OSから実施するには！？
エラー内容から、要はセッション先とのローカライズの問題っぽいです。

これでいけます。

```
$usSession = New-PSSessionOption -Culture en-US -UICulture en-US
Invoke-Command -ComputerName FSxFileSystem-DNS-Name -SessionOption $usSession -ConfigurationName FSxRemoteAdmin -scriptblock {Set-FsxShadowStorage -Default}
```

```
Invoke-Command -ComputerName FSxFileSystem-DNS-Name -SessionOption $usSession -ConfigurationName FSxRemoteAdmin -scriptblock {Set-FsxShadowCopySchedule -Default}
```

vssの実行スケジュールを変更したい場合は[ここ](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/manage-shadow-cpy.html)を参照すればオッケーです。
Oracleスタッツパックの注意点

#Oracleスタッツパックの注意点
Oracleで夜間処理でパフォーマンス障害が起きたときに困ったので記録。
数万件を更新する処理が何時間も終わらない。
何が悪いかを調べようと、statspackを取得してみたものの、残念ながらPLSQLやpackageを使用していると、StatsPackではPLSQL名１つしか出てこない。
数万件のデータを、Javaとかで更新するととんでもなく時間がかかるので、普通はPLSQLにすると思うんですが、これじゃあ何が悪いかわからない。。。
CSVファイルを使用してRailsアプリに反映させる

# csvファイルを使用してrailsアプリに初期データを投入
チーム開発をしていて、seeds.rbからデータベースに初期データを投入する際にコードをひたすら書くのではなくcsvファイルに大量のデータを落とし込んでそれをseed.rbに読み込む記述をするという方法を使用したので、そのやり方を記録として残しておく！！

# CSVファイルの作成手順
1.今回は某サイトよりデータをお借りしました
まずはデータを抽出
commnd + aで全選択コピー
<img width="583" alt="スクリーンショット 2019-08-21 18.23.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485253/285673de-da06-e039-323b-51d2cf084895.png">

2.適当な整形ツールでデータを整える
<img width="965" alt="スクリーンショット 2019-08-21 18.26.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485253/d6b399cb-3090-6f4a-8d26-d12ca3ddbea2.png">

3.整えたデータをgoogle スプレッドシートで貼り付け
ツールからフィルターを作成
 改行を取り除くために空白セル以外を表示
空白セル以外を表示させる
コピーして貼り付け
改行がないデータの出来上がり！！
　<img width="206" alt="スクリーンショット 2019-08-21 18.36.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485253/ef2e9a0f-be0f-2533-dd61-50be692d8c21.png">

4.numbersアプリでcsv書き起こし
データをnumbersアプリでcsvファイルとして書き起こしました
<img width="261" alt="スクリーンショット 2019-08-21 18.44.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485253/05ca7305-ad0b-9655-3a2c-9ef0b1314be4.png">

# Railsに保存
今回の目的として、rake db:seedをした時にデータをデータベースに投入したいのが目的のため下記の図のファイル構成とする

<img width="251" alt="スクリーンショット 2019-08-21 18.48.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485253/b7b31a0b-de6f-7cbe-7e21-5ac78e35f847.png">
dbの中に上記csvを入れてやれば良いと思います。
**ブランドはデータ量が多かったのでbrandフォルダを作成してます**

# Seeds.rbにデータベースに反映するコードを記述
```
#左辺nameがデータベースのカラム、右辺Nameがcsvのカラム
CSV.foreach('db/brand/men_brand.csv', headers: true) do |row|
  Brand.create(
    name: row['Name'],
  )
end
```

<img width="138" alt="スクリーンショット 2019-08-21 18.56.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485253/5a1214e2-4574-dd00-65fb-d2f62bd596df.png">


# 最後に
これで`rake db:seed`をすればデータが反映されるはずです
親があって、子があって、孫があるなどの階層が深い場合のseeds.rbの記載方法はそれぞれ紐付けるのが難しいですよね汗
余力があればそのコードもアウトプットとして書こうと思います！！

# 追加
vs codeの拡張機能でExcel Viewer機能を追加するとcsvファイルがみやすくなります
Oracleリスナーログのローテーション（linux版）

#　リスナーログのローテーション
日々溜まっていき、自動でローテーションしてくれず、そのうち爆発するリスナーログのローテーション方法です。

#　シェルで下記のように記載

```bash

#!/usr/bin/bash
#■リスナーログを別ファイルとする。
lsnrctl set log_file /u01/app/oracle/diag/tnslsnr/hogehoge/listener/trace/listener1.log
#■次にファイルを移動。
mv /u01/app/oracle/diag/tnslsnr/hogehoge/listener/trace/listener.log /var/ora/lsnrlog/listener_`date "+%Y%m%d_%H%M%S"`.log
#■元のリスナーログに戻す。
lsnrctl set log_file /u01/app/oracle/diag/tnslsnr/hogehoge/listener/trace/listener.log
#■ファイルを削除。
rm /u01/app/oracle/diag/tnslsnr/hogehoge/listener/trace/listener1.log

```

varlogにバックアップしてますが、たまに削除したほうがいいです。
これをcronに登録しておけばバッチリ！
ユーザはOracleユーザで行うことを忘れずに。
データベースについてのお勉強

こんにちは！
未来電子で長期インターン中の竹内です。
今回はプログラミングのカリキュラムを進めていく中でデータベースについての勉強をしなくてはいけないので、そのアウトプットをここでしていこうかなと考えています。
興味のある方はぜひ最後まで読んでください

##データベースとは
データベースとは`大量の情報をコンピュータ上で扱えるようにしたもの`です。
そして、そのデータベースの読み書きを効率よくするために使われているソフトウェアのことを***データベース管理システム（DBMS）***と呼ばれています。
そして、僕が勉強しているのが***PostgreSQL***というものです。
つぎにこのPostgreSQLについてご紹介します。

##PostgreSQLとは
PostgreSQLとは`フリーなオープンソースのリレーショナル管理システム`です。
フリーでオープンソースであるということは、つまり、利用に際して対価を支払う必要がなく、ソースコードを公開しているということです。

##PostgreSQLのコマンド(端末上)
###サーバーの起動

```
$ pg_ctl start -D /usr/local/var/postgres
```
###サーバーの終了

```
$ pg_ctl stop -D /usr/local/var/postgres
```
###サーバーが起動しているかの確認

```
$ ps aux | grep postgres
```
###データベース接続
```
$ psql -d database -U user -h host
```
-d: データベース名(未指定だと、ログインユーザー名のデータベースに接続する)
-U: ユーザ名(未指定だと、ログインユーザー名になる)
-h: ホスト名(未指定だと、localhostになる)

##まとめ
今回はデータベースについてご紹介しました。
上記のコマンドやデータベースについての説明はほぼコピペなのでもっと詳しく知りたという方は参考文献のところにURLを載せておくので見てみてください。
最後まで読んでいただきありがとうございました！！

##参考文献
[PostgreSQLコマンドチートシート
](https://qiita.com/Shitimi_613/items/bcd6a7f4134e6a8f0621)
[PostgreSQL 超入門](https://lets.postgresql.jp/documents/tutorial/postgresql-abc/2-1)
file_get_contents('php://stdin') で、標準入力を渡さないとどうなるか。

## ハマったこと

PHPの入出力ストリームラッパーを使って、標準入力を受け取る場合。(手元のPHP7.1で動作確認)
https://www.php.net/manual/ja/wrappers.php.php

たとえばこんなスクリプトで

```php
<?php
$str = file_get_contents('php://stdin');
echo $str;
```

標準入力を渡すと、その文字列をそのまま表示します。

```console
$ echo 'hoge' | php test.php 
hoge
```

では、このスクリプトに標準入力を渡さなかった場合どうなるでしょう？

```console
$ php test.php 
```

空の文字列でも帰ってくるのかなと思ってたのですが。。。
実は、 **処理が止まってプロンプトが帰ってきません**。
（正確には、パイプを渡してない時は標準入力が入力待ちになってブロックされている）

## 対処策

`posix_isatty（）` 関数を利用します。
http://php.net/manual/ja/function.posix-isatty.php

この関数を使って、 STDINがオープンされていて、 かつ端末に接続されているか否かを判定します。
（標準入力が渡っている場合はfalseになる）

```php
<?php
$str = (posix_isatty(STDIN)) ? 'default' : file_get_contents('php://stdin');
echo $str;
```

動作検証

```console
$ echo 'hoge' | php test.php 
hoge

$ php test.php 
default
```
【Airflow on Kubernetes】トラブルシューティング - AttributeError: '_jpype.PyJPField' object has no attribute 'getStaticAttribute'

## 概要
`JPype1==0.7.0`を利用して`JdbcOperator()`を実行すると表題のエラーが出力される。

## 目次
- [【Airflow on Kubernetes】目次](https://qiita.com/Esfahan/items/cd6b3dc0f724b84361d2)

## バージョン
- [airflow-1.10.4](https://github.com/apache/airflow/releases/tag/1.10.4)
- [JPype1==0.7.0](https://pypi.org/project/JPype1/0.7.0/)

### DAG
一部抜粋

```py
from airflow.operators.jdbc_operator import JdbcOperator

sql_task = JdbcOperator(
    task_id='sql_cmd',
    jdbc_conn_id='my_connection_id',
    #template_searchpath='/etc/dev/airflow/templates',
    #sql=['sample.sql'],
    sql=['select id,name from sample_table'],
    params={"db":'MY_DBNAME'},
    dag=dag
)
```

## エラー詳細
ログの見方：[DAGの実行結果ログを確認する](https://qiita.com/Esfahan/items/e533c357d31cccde97cd#dag%E3%81%AE%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C%E3%83%AD%E3%82%B0%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B)

```
[2019-08-21 09:30:48,913] {taskinstance.py:1047} ERROR - '_jpype.PyJPField' object has no attribute 'getStaticAttribute'
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/airflow/models/taskinstance.py", line 922, in _run_raw_task
    result = task_copy.execute(context=context)
  File "/usr/local/lib/python2.7/dist-packages/airflow/operators/jdbc_operator.py", line 63, in execute
    self.hook.run(self.sql, self.autocommit, parameters=self.parameters)
  File "/usr/local/lib/python2.7/dist-packages/airflow/hooks/dbapi_hook.py", line 159, in run
    with closing(self.get_conn()) as conn:
  File "/usr/local/lib/python2.7/dist-packages/airflow/hooks/jdbc_hook.py", line 51, in get_conn
    jars=jdbc_driver_loc.split(","))
  File "/usr/local/lib/python2.7/dist-packages/jaydebeapi/__init__.py", line 381, in connect
    jconn = _jdbc_connect(jclassname, url, driver_args, jars, libs)
  File "/usr/local/lib/python2.7/dist-packages/jaydebeapi/__init__.py", line 183, in _jdbc_connect_jpype
    types_map[i.getName()] = i.getStaticAttribute()
AttributeError: '_jpype.PyJPField' object has no attribute 'getStaticAttribute'
```

## 対策
[JPype1==0.6.3](https://pypi.org/project/JPype1/0.6.3/)ではエラーにならないのでダウングレードをする。

## 参考
https://github.com/baztian/jaydebeapi/issues/99
ubuntu16.04 KVM VM に新規インターフェースを追加する

ubuntu16.04 KVM VM に新規インターフェースを追加する.

参考
https://qiita.com/masahixixi/items/4eb014eff723d39552ec


#作業内容
1.インターフェースを追加する仮想マシンを停止する。
2.インターフェースを追加する仮想マシンのxmlファイルを編集する。
ファイルのディレクトリが分からなければ

```
$locate VM名.xml
```
を使用して探す。

```
 </interface>
    <interface type='bridge'>
      <source bridge='追加したいインターフェース'/>
      <model type='virtio'/>
    </interface>
```

3.設定ファイルの反映

```
$ virsh define xmlファイル
```

4.仮想マシンを起動してログインする
インターフェースが増えているか確認する。
リンクダウンされて追加されていたので、ifconfigしても出てこなくて
無駄な時間がかかった

```
$ip a
```
[Unity] アニメーションのブレンド

アニメーションを同じステート内でブレンドしながら変更する方法です。
複数のアニメーション間を0-1の数値で表現できるのでいろいろと便利です。

![_gif_animation_001.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/2f6a3821-f4cf-bb46-36de-63a9b00f945e.gif)

まずは新しいステートを作ります。ここではRun_endとしました。
![2019-08-21_175030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/79a4d451-9e50-97f3-b9f0-6a483a54e147.png)

作成したステートを右クリック->Create BlendTree in State を選択します
![2019-08-21_180315.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/1f6d6f4e-4b3c-b51a-a56c-5ffe376e871e.jpeg)

するとMotionのところがBlend Tree になるので、これをダブルクリック
![2019-08-21_180633.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/7447e041-6e69-e76d-ce28-2f471c9104da.jpeg)

＋ボタン-Add Motion Field を押してモーションを追加します
![2019-08-21_180814.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/84bcfc60-cebc-4e32-efae-423ba7fe0a51.jpeg)

モーションを追加すると自動的にブレンドパラメーターを設定してくれます。
![2019-08-21_181435.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/87f40bdc-660d-ee51-52ab-4743e4c0a3d2.gif)


アニメーションのブレンドは"Blend"というパラメータを変更することで行います。

```
animator.SetFloat("Blend", [0f-1f]);
```

アニメーションのあるオブジェクトに下記を張り付けて
moveSpeedスライダーバーを動かすとモーションが滑らかにブレンドします。


```AnimationBrendTreeTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimationBrendTreeTest : MonoBehaviour
{
    [SerializeField,Range(0,1)] float m_moveSpeed=0f;
    Animator m_animator;

    // Start is called before the first frame update
    void Start()
    {
        m_animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        m_animator.SetFloat("Blend", m_moveSpeed);
    }
}
```
2つ以上のモーションブレンドも可能です
![2019-08-21_183148.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/6405c000-3dd9-23ef-0315-57f5a814b9dc.jpeg)

![gif_animation_004.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/d3cd52e9-d7a1-d257-a15e-1f638b6251a0.gif)
運動方程式のガリレイ変換のメモ

$\displaystyle xyz$ 座標から $\displaystyle x'y'z'$ 座標への変換がガリレイ変換のとき，

```math

\begin{equation*}
t'=t\ ,\ x'=x-V_{x} t\ ,\ y'=y-V_{y} t\ ,\ z'=z-V_{z} t
\end{equation*}
```

```math

\begin{equation*}
\frac{dx'}{dt'} =\frac{dx}{dt} -V_{x} \ ,\ \frac{dy'}{dt'} =\frac{dy}{dt} -V_{y} \ ,\ \frac{dz'}{dt'} =\frac{dz}{dt} -V_{z}
\end{equation*}
```

```math

\begin{equation*}
\frac{d^{2} x'}{dt^{\prime 2}} =\frac{d^{2} x}{dt^{2}} \ ,\ \frac{d^{2} y'}{dt^{\prime 2}} =\frac{d^{2} y}{dt^{2}} \ ,\ \frac{d^{2} z'}{dt^{\prime 2}} \ =\frac{d^{2} z}{dt^{2}}
\end{equation*}
```

ここで，$\displaystyle xyz$ 座標での運動方程式は，

```math

\begin{equation*}
m\frac{d^{2} x}{dt^{2}} =F_{x} \ ,\ m\frac{d^{2} y}{dt^{2}} =F_{y} \ ,\ m\frac{d^{2} z}{dt^{2}} =F_{z}
\end{equation*}
```

つまり，

```math

\begin{equation*}
F_{x'} =F_{x} \ ,\ F_{y'} =F_{y} \ ,\ F_{z'} =F_{z}
\end{equation*}
```

以上より，

```math

\begin{equation*}
m\frac{d^{2} x'}{dt^{\prime 2}} =F_{x'} \ ,\ m\frac{d^{2} y'}{dt^{\prime 2}} =F_{y'} \ ,\ m\frac{d^{2} z'}{dt^{\prime 2}} =F_{z'}
\end{equation*}
```

となり，$\displaystyle x'y'z' $座標における運動方程式は $\displaystyle xyz$ 座標におけるものと同じ形になる．
したがって運動方程式はガリレイ変換に関して**共変性がある**といえる．
Nanopi NEO2にDrupalにインストールする方法

###今回導入したバージョン
・Armbian Linux 4.19.63-sunxi64
・Apache 2.4.29
・PHP 7.2.19
・MySQL 5.2.27

###導入の前提
/var/www/drupal にdrupalを導入します。
apacheのプロセスオーナは、www-dataとします。

###ログイン
rootでログイン

###ソフトのインストール
>apt-get install apache2 libapache2-mod-php
apt-get install mysql-server
apt-get install php php-mysql php-gd php-mbstring php-xml  php-cgi php-common php-pear php-cli  php-gd php-mysqlnd php-pear php-soap php-xml php-xmlrpc php-fpm 
apt-get install wget unzip

###Drupalのインストール
>cd /var/www
wget https://ftp.drupal.org/files/projects/drupal-8.7.6.zip
unzip drupal-8.7.6.zip
mv drupal-8.7.6.zip drupal

###Drupalの設定
>mkdir /var/www/drupal/sites/default/files
>cp /var/www/drupal/sites/default/default.settings.php /var/www/drupal/sites/default/setting.php
>chown -R www-data:www-data /var/www/drupal
>chmod -R 766 /var/www/drupal

###/etc/apache2/sites-enabled/000-default.confの編集
 DocumentRoot /var/www    に変更
 次の３行をVirtualHostのセクションに追記
\<Directory "var/www/drupal">
 AllowOverride All
\</Directory>

###apacheキャッシュの有効化
>a2enmod expires
>a2enmod proxy_fcgi setenvi
>a2enconf php7.0-fpm

###MySQLにデータベースとユーザを作成する
mysqlにログイン
>create database drupaldb;
>grant all privileges on drupaldb.* to 'drupal'@'localhost' IDENTIFIED BY '******' ;     
パスワード「*******」の部分は自分で設定

###/var/www/drupal.htaccssの編集
RewiteBaseの行を下記に変更　 
>RewiteBase /drupal   

###/etc/php/7.2/apache2/php.ini編集して、アップロードできるファイルサイズ上限を8MBにする
upload_max_filesize の行を下記に変更
upload_max_filesize = 8M   

###Trusted Hostのため、/var/www/drupal/sites/default/settings.phpの編集　
（アドレス部分は自分の環境に合わせて変更）
 サンプルは、コメントブロックの中にあるのでコメントブロックから出す。
  settins['trusted_host_patters']= [
  '\192\.168\.3\.0$',
  '\127\.0\.0\.1$',
  '\localhost$',
  ];

###/etc/mysql/mysql.conf.dを編集してMySQLのメモリをチューニング
query_cache_limitの行を次のように修正
>query_cache_limit = 10M

query_cache_sizeの行を次のように修正
>query_cache_size = 20M

###Apache,MySQLの自動起動有効化
>systemctl enable mysql
>systemctl enable apahce2

###Apache,MySQLの再起動
>systemctl restart mysql
>systemctl restart apahce2

###Drupalセットアップ画面へアクセス
http://(サーバIPアドレス）/drupal
DB設定が表示されたら、
>DB名：drupaldb
>ユーザ：drupal
>パスワード:*****   (MySQLのgrantコマンドで設定したパスワード）

以上
【C#】C#言語仕様を翻訳してみた 〜 はじめに 〜

# はじめに
この記事はC#言語仕様を翻訳してみたシリーズの第1項である。
他の項の翻訳も見たい場合は以下のリンクから確認できる。

1. [はじめに](https://qiita.com/TomoProg/items/20699ef4e9ae807596f8)
1. [Hello World](https://qiita.com/TomoProg/items/f9b4830a7fbf16cc3798)

# 経緯
公式ドキュメントを読むことが苦手なため、克服するために[C#の言語仕様](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/language-specification/introduction)を読み始めた。
しかし、機械翻訳があまり読みやすいものでなかったため、英語で読みながら翻訳して読むことにした。

# 翻訳の方針
もともと書かれている機械翻訳より分かりやすくなるように翻訳することを目標とする。
ただし、機械翻訳でも読めそうな部分はそのまま使用する。
また、Google翻訳などの翻訳アプリもフルに活用することとする。
間違いやもっと良い翻訳など指摘があれば、コメントを頂ければ幸いだ。

# この記事の翻訳対象
セクションごとに記事を分けて書くこととする。
この記事では[**Introduction**](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/language-specification/introduction)を翻訳する。

# 翻訳文
### はじめに
C#（読み方は"シーシャープ"）はシンプル、モダン、オブジェクト指向かつタイプセーフなプログラミング言語です。
C#はC言語系がルーツであり、C、C++、Javaのプログラマーにすぐ馴染みます。
C#はECMA Internationで**ECMA-334**として、ISO/IECで**ISO/IEC 23270**として標準化されています。
.NET Framework用のMicrosoftのC#コンパイラはこれら両方の標準に準拠した実装です。

C#はオブジェクト指向言語ですが、さらに**コンポーネント指向**のプログラミングのサポートも含まれています。
最近のソフトウェア設計では、機能を自己完結型および自己記述型パッケージの形式にしたソフトウェアコンポーネントにますます依存するようになっています。
そのようなコンポーネントの鍵となるのは、プロパティ、メソッド、イベントを使用してプログラミングモデルを表すこと、コンポーネントについての宣言的な情報を提供する属性があること、独自のドキュメントが組み込まれていることです。
C# はこれらの概念を直接サポートする言語構造を提供しているので、非常に自然にソフトウェアコンポーネントを作成して使用することができます。

いくつかのC#の機能は堅牢で耐久性のあるアプリケーションの構築を支援します。
**ガベージコレクション**は使用していないオブジェクトによって占領されたメモリを自動的に再利用します。
**例外処理**は、エラーの検出と回復に構造化された拡張可能なアプローチを提供します。
**タイプセーフ**な設計により、初期化されていない変数の読み込み、配列の境界を超えたアクセスまたは型チェックされていない型へのキャストはできません。

C#は**統一された型システム**を持っています。
C#の型は`int`や`double`のようなプリミティブな型を含め、すべて`object`型から派生しています。
そのため、すべての型は共通の操作を共有し、任意の型の値を一貫した方法で保存、転送、および操作できます。
さらに、C#はユーザ定義の参照型、値型の両方をサポートしており、オブジェクトを動的に割り当てることも、軽量の構造体をインラインで格納することもできます。

C#のプログラムとライブラリが互換性を保ちながら進化できることを保証するために、**バージョン管理**に重点が置かれています。
多くのプログラミング言語がこの問題を軽視しており、その結果、それらの言語で書かれたプログラムは依存しているライブラリの最新バージョンが導入されると必要以上に壊れます。
バージョン管理の考慮に影響を受けたC#の設計の側面として、`virtual`と`override`修飾子が分かれている、メソッドのオーバーロードの解決ルール、明示的なインターフェースメンバの宣言のサポートがあります。

この章の残りの部分では、C#の重要な機能を説明します。
後の章はルールと例外を詳細に、ときどき数学的な方法で説明しますが、この章では完璧さを犠牲にして、明確さと簡潔さを追求しています。
目的は最初のプログラムの作成方法と後の章の読みを促進するための言語の導入部を読み手に提供することです。

# 次回
[Hello World](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/language-specification/introduction#hello-world)を翻訳予定。

[2019/09/03]
Hello Worldの翻訳は[こちら](https://qiita.com/TomoProg/items/f9b4830a7fbf16cc3798)。

それではまた。
TomoProg
この一冊で全部わかるWEB技術の基本 chapter６セキュリティ

##はじめに
業務研修の中でタイトルにある本を読むことになったのでまとめとして書いています。
この記事が僕と同じような初心者エンジニアさんのお役に立てれば幸いです。

##情報セキュリティ
情報セキュリティは、情報の「機密性」、「完全性」、「可用性」を維持することと定義されている。
 >機密性＝第三者にアクセスさせない
完全性＝情報が破壊、改ざん、消去されていない状態を確保
可用性＝情報へのアクセスがいつでもできる

何らかの損失が発生する可能性を「リスク」、リスクを現実化させる要因が「脅威」、脅威に対する弱みが「脆弱性」。
情報セキュリティの維持には脅威と脆弱性を洗い出し、リスクの顕在化を防ぐことが必要。

###パスワードクラッキング
IDとパスワードによる認証をする会員制Webサイトから個人のパスワードを抜き出そうとする攻撃
>辞書攻撃＝よく使われるパスワードの一覧を試す
ブルートフォールス攻撃＝全組み合わせを試す

数度間違えればアカウント停止などが対策となる

###Dos攻撃
大量のアクセスを送りサービス停止に陥らせる攻撃
>SYN Flood攻撃＝SYNパケットを大量に送る（別のユーザがアクセスできない）
>F5攻撃＝繰り返しアクセスを送る、再度読み込みをする

不自然なアクセスの増加を検知して送信元からのアクセスを断ち切ることが対策となる


##Webシステムの特徴を利用した攻撃

###セッションハイジャック
会員系のサービスでCookieやセッションIDの値を抜き取られ、個人情報が取得されてしまう攻撃

対策として通信を暗号化する、急に異なるIPアドレスから接続してきた場合にログアウトさせる

###ディレクトリトラバーサル
URLからWeb公開ディレクトリより上の階層へたどり、パスワードなどを抜き出す攻撃

公開していないディレクトリやファイルが指定されていないかを確認することが対策となる

##Webアプリケーション脆弱性を狙う攻撃
動的サイトは処理の自由が高い分、脆弱性をつかれた場合は攻撃者の自由度も高くなる
###クロスサイトスクリプティング(XSS)
悪意あるサイトのリンクを踏ませて、脆弱性のあるサイトでユーザのブラウザにスクリプトを読み込ませクライアント・スクリプトとして実行させる。送りこませるスクリプトとしてはセッションハイジャックのためのCookie情報を抜き出すものやウイルス系のものなど。

###クロスサイトリクエストフォージェリ(CSRF)
XSSと同じくスクリプトが実行されるもの。違いとしてCSRFの場合はログイン情報を抜き取って本人を装いSNSなどにログインするというとこ。

###SQLインジェクション
検索画面やログイン画面で実際のSQL文を打ち込み、DBを操作する。

##Webシステムの脆弱性
###セキュリティホール
ソフトウェア欠陥により本来できないはずの操作がユーザにできてしまったりする不具合のこと。
OS、webサーバ、DBから日々見つかっている。
製作元は脆弱性情報データベースを元に修正プログラムを作って配布する。
修正プログラムが開発される前に再度同じ攻撃を仕掛けることをゼロデイ攻撃という。
対策としてはっきりとしたものはなく、攻撃の可能性のある通信を遮断するようなセキュリティ製品もある。

##ファイアーウォール
インターネットと内部ネットワークの間に位置し、通信に対して許可・拒否を行うもの。
違うセキュリティソフトウェアと併用することが多い。
EX>インターネットからの場合はDBはアクセスできない、など
####パケットフィルタ型ファイアーウォール
IPアドレスとポート番号から通信の許可・拒否の判断を行う

##IDS,IPS
ファイアウォールの次の手として、IDSとIPSがある。これらは通信を監視し、不正アクセスとみられる通信や普段と異なる異常な通信を検知する装置です。
IDSは通信をそのまま通し管理者にメールを通知するもの
IPSは該当の通信を遮断する
これらはシステムの用途や性質によって使い分けられる。

不正アクセスの検知方法は二つある。
**シグネチャ型**＝既知の攻撃手法における通信パターンが登録されたデータベースのものと一致する通信を不正アクセスと判断する、SYN Flood攻撃のような特徴的なものを検出できる
**アノマリー型**＝普段の通信とは大きく異なる通信を不正アクセスとして判断する、F5攻撃などを検出できる

##WAF
IDSやIPSを使うことで、DoS(F5,SYN Flood)のようなあからさまなものは防げるが、通信の中身まで確認しないためXSSやSQLインジェクションを検知することはできない。
そこでやり取りされるパケットの中身を見て悪意のあるデータが含まれていないかをチェックするWAF(Web Application Firewall)がある。運用にも手間やコストがかかるが高機能である。
####ブラックリスト型
IDSのシグネチャ型と同じように、特定のパターンのデータを持つ通信を遮断する
基本的に開発元が提供するものを利用するため新たな攻撃手法があった場合はそのパターンが追加されるまで対応できない。
####ホワイトリスト型
正常なデータのパターンを登録しておき、それに適合する通信のみ通す。

##公開鍵証明書
やり取りの相手が本物であることを証明するものが公開鍵証明書、 SSL通信に使われることが多いためSSL証明書とも呼ばれている。

HTTPS通信に使うための公開鍵の持ち主が誰なのかを証明すること
公開鍵の持ち主が実在することを証明すること
役割は上記の二つ。
第三者機関の認証局が公開鍵証明書を発行するので一定の信頼はある。

##認証
###認証API
提供する側は認証の処理の仕組みをAPIとして提供する。
各社ごとにAPIの仕様が統一されていないため複数の認証APIを実装するのは手間がかかる。
###OpenID
認証APIの問題を解決するため、認証処理を標準化したプロトコルがOpenID。

##認可
認証によって確認した結果によりユーザごとの権限に従って利用できるサービスの許可を行うことを「認可」という。

###OAuth
OAuthはサイトをまたいだ認可を可能にするプロトコル。

利用したいサービスは「リソース」と呼ばれ、サービスを提供するサーバが「リソースサーバ」、そのユーザが「リソースオーナー」、実際に使用するWEBサイトやアプリを「クライアント」と呼ぶ。
この一冊で全部わかるWEB技術の基本 chapter5 WEB

##はじめに
業務研修の中でタイトルにある本を読むことになったのでまとめとして書いています。
この記事が僕と同じような初心者エンジニアさんのお役に立てれば幸いです。

##Webアプリケーションの三層構造
Webアプリケーションは基本的に三層に別れている
>-プレゼンテーション層=Webブラウザ&Webサーバ
ユーザーへの表示、操作受け付け
-アプリケーション層=アプリケーションサーバ
ユーザからの命令実行、表示画面の作成
-データ層=DBサーバ
データの抽出、更新、保管

三層にすることでのメリットは二点
①負荷分散
層別されていないAPであれば全ての処理を実施することになる、小規模なシステムでは大丈夫だが複雑な処理になると負荷が大きくなる。
三層に分けることで負荷を分散できる。
②改修範囲の限定
改修が必要になった時、例えばデータの改修であればデータ層だけを改修すればいいので、コストを抑えれらる。

##MVCモデル
Model(データ処理)、View(ユーザに出力)、Cntorller(ユーザからの命令をモデルとヴューに指示)の三つの部分からなる。
MVCモデルのメリットは上記の三層構造と似ているが、異なる点として以下が挙げられる。

・三層アーキテクチャはWebシステム全体の設計方針であり、MVCはサーバサイド・スクリプトの設計方針だから対象とする範囲が違う
・三層アーキテクチャは階層構造だが、MVCは相互に関わりあう

##Webサーバ
Webクライアントに対する窓口の役割を果たし、静的ページのデータやAPサーバから転送された動的ページのデータをクライアントに転送する。
Webサーバが動作しなくなるとサービスが提供できなくなるため、冗長化という構成をとっている。
・冗長化＝サーバの機器台数を多くし、一台当たりの負担を少なくするとともに一台が故障しても別のサーバだけでサービスを続けられるようにする

##Webクライアント
Webサーバから送られてきた「HTTPレスポンスを解釈し、ユーザに表示する役割を持つ。
代表的なものが、Webブラウザだがこれ以外にもFacebookやTwitter専用クライアントもある。
　
##アプリケーションサーバ
サーバーサイド・スクリプトを実行し、DBへデータ検索や更新、Webサーバに動的ページの転送をしたりする。
三層アーキテクチャの中では一番処理の複雑で負荷が高い。
###セッション管理
ログインが必要なサイトなどの場合は、APサーバがセッションIDを発行して一つのセッションとして管理する
###トランザクション管理
予約サイトなどの「全てのやり取りが成功するまで完了しない処理」はリクエスト/レスポンス単位でなく、複数の処理をトランザクション単位で管理している
##データベース管理システム
データの扱いは非常に注意を払う必要があり、冗長化構成をとっている。
手法として、ミラーリング・レプリケーション・シェアードティスクなどがある。

##キャッシュサーバ
キャッシュサーバは「リクエストに対するレスポンスを覚えておく」という役割を持つ。
その覚えておいた記憶を「キャッシュ」と呼び、文書や画像、動画といったコンテンツのキャッシュを「コンテンツキャッシュ」、DBMSのデータ検索要求（クエリ）の結果のキャッシュが「クエリキャッシュ」と呼ばれる。
コンテンツやデータの変動を加味した有効期限が定められている。

##Ajax
以前のWEBサイトは同期通信が主だった。同期通信とはクライアントとサーバーが交互に処理を行い、同調して通信を行うこと。
問題点としてレスを待つ間、クライアントは待つことしかできないから効率が悪くなってしまう。
この欠点を補うために登場したのがAjax。
JavaScriptが直接Webサーバと通信を行い、XMLデータとして更新に必要なデータのみをやり取りするため、サーバの負担が少ない。
また、AjaxはWebブラウザの代わりにブラウザ上で動くJSだけが通信を行うため、非同期通信を実現できる。よってレスポンスを待つ間もユーザからの入力などレスポンスに左右されないところは操作することができる。

##WebAPI
プログラムがクライアントとしてデータを送信し、サーバからデータを返送してもらう窓口がWebAPI。
EX>Twitter投稿いボタンを押すと指定している投稿もされる。
APIの様々な手法＝XML-RPC,Atom,SOAP

##マッシュアップ
複数のWebサービスを組み合わせて新たなWebサービスを生み出すこと。
よく使うAP「googleの位置情報」や「アマゾンの購入状況」など。


##CGI
Webサーバがクライアントからの要求に応じてサーバサイド・スクリプトを起動すルための仕組みがCGI。
GCP AI platform上のJupyterLabでtensorboardのランチャーが404を吐くときの対処法

# 3行で
GCPのAI platformでnotebook作って作業してたけどtensorboardを起動しようとすると404になった
trained modelをcloud storageのbucketに入れるようにすればcloud shellで簡単にアクセスできる
cloud shellのweb preview機能を使えばtensorboardにすぐアクセスできる

# モチベーション
GCPのnotebookを使って機械学習をしたい。
当然学習の経過も追いたいのでtensorboardを使いたい。
notebookにはデフォルトでhttps://github.com/chaoleili/jupyterlab_tensorboard の拡張機能が入っているようだが、なぜか404になってしまう。（私が悪い気もする）


# 環境
GCPのAI platformのnotebook
インスタンスタイプはtensorflow 1.14(without GPU)


# 方針
とりあえずなんでもいいから経過を観察したい。
notebookの機能を使わずにtensorboardにアクセスする。
cloud shellがweb preview機能を持っているので便利そう。


# やり方
1. storageのbucketを作成し、そこに学習のアウトプットを吐かせるようにする。
2. cloud shellを立ち上げて

```
tensorboard --logdir=<your bucket> --port=8080
```

でtensorboardを起動する。（your bucketには学習のアウトプットを吐かせているbucketのアドレスを指定。gs://hogehogeのやつ）
3. cloud shellのweb previewを起動。cloud shellの右上にあるアイコンのこれ。preview on 8080をする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373785/13060936-a7af-9467-51ba-cefffc4fe8e8.png)


# ぼやき
実は https://www.coursera.org/learn/end-to-end-ml-tensorflow-gcp このコースを受講してるときにこの問題に遭遇した。
GCPのnotebook、環境構築の手間いらずでいきなりコードのことを考えられて良さがあるなあと思っているけど
どうもドキュメントが少なくてトラブルにどう対応していいかわからん。
tensorboardのランチャーは単に404返すだけで何もエラーのヒントくれないし。

# お願い
もっといい方法があったらぜひ教えて下さい！
kubeadmコマンドのオプションと、yaml定義との対応関係がどう繋がっているか分からない

動作検証してませんので間違ってたらごめんなさい。
(とりあえず自分が納得するためのものです)

参考資料
--------------------
[kubeadm v1beta2 ClusterConfiguration (godoc.org)](https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2#ClusterConfiguration)
[kubernetes (github.com)](https://github.com/kubernetes/kubernetes)

### 事前準備

ここ
[kubernetes (github.com)](https://github.com/kubernetes/kubernetes)
からソースコードをダウンロードし、解凍しました。
(開発用は1.16.x, 安定版は1.15.xのようでした)


### 調査 : オプション`--pod-network-cidr`とyaml定義`networking.podSubnet`の対応

まずは`grep`でyaml(JSON)側の文字列から探しました。

```sh
grep -rn kubernetes-master/cmd -e "PodSubnet"

...
kubernetes-master/cmd/kubeadm/app/apis/kubeadm/v1beta2/types.go:222:    PodSubnet string `json:"podSubnet,omitempty"`
...
kubernetes-master/cmd/kubeadm/app/cmd/options/constant.go:75:   NetworkingPodSubnet = "pod-network-cidr"
...
kubernetes-master/cmd/kubeadm/app/cmd/init.go:225:              &cfg.Networking.PodSubnet, options.NetworkingPodSubnet, cfg.Networking.PodSubnet,
```

yaml(Goでの定義はJSON)は`Networking`構造体にありました(`Networking.PodSubnet`)。

`kubernetes-master/cmd/kubeadm/app/apis/kubeadm/v1beta2/types.go`の`222`行目

```go
package v1beta2

type Networking struct {
  ...
  // PodSubnet is the subnet used by pods.
  PodSubnet string `json:"podSubnet,omitempty"`
```

次に、`kubeadm`でのオプション`--pod-network-cidr`は`options.NetworkingPodSubnet`で定数定義されていました。

`kubernetes-master/cmd/kubeadm/app/cmd/options/constant.go`の`75`行目

```go
package options

const (
  ...
  // NetworkingPodSubnet flag sets the range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node.
  NetworkingPodSubnet = "pod-network-cidr"
```

最後に、`kubeadm`の初期処理において、`options.NetworkingPodSubnet`から`Networking.PodSubnet`へのマッピングが行われていました。
ただし、`kubeadm init`に渡したオプションの値が実際に`ClusterConfiguration`まで渡されたかどうかを追跡する事は出来ませんでした。
(処理が共通化されていて、あっちゃこっちゃ調べる必要があったため)

`kubernetes-master/cmd/kubeadm/app/cmd/init.go`の`225`行目

```go
// AddClusterConfigFlags adds cluster flags bound to the config to the specified flagset
func AddClusterConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.ClusterConfiguration, featureGatesString *string) {
  ...
  flagSet.StringVar(
    &cfg.Networking.PodSubnet, options.NetworkingPodSubnet, cfg.Networking.PodSubnet,
    "Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node.",
  )
```

一応の納得が出来たので、これから先を追跡するかどうかは、
kubeadm自体の理解を進める時にやろうかなと考えています。以上です。
超シンプルなタイマーを作る-02　購入編

# タイマーIC「555」はおいくら？
購入にあたり、現在(2019年8月20日時点)の価格を調査してみました。
といっても高い物でもないので、あまり気合入れて調べてませんのでご容赦を。
ちなみに値段は10円単位・消費税はわかる範囲で書いてます。
ネットで軽く調べると、だいたい1個あたり20～100円といった価格感ですね。

# aitendo　5個約100円
★UTC★汎用タイマーIC（5個入） [NE555L-D08-T] - aitendo
http://www.aitendo.com/product/17474

ご存知aitendo。
前回のスイッチ付USBケーブルのパーツも大半はここで購入しました。

いやー相変わらず安いなー。ここ一択！
と思って仕事終わりに店舗を訪れると、定休日・・・。
ちゃんと営業日と営業時間は調べましょう。

かろうじて19時前の秋葉原だったので、
代わりにマルツへ行ってこちらを購入。

# マルツ　1個約50円
NE555P Texas Instruments - DigiKey
https://www.digikey.jp/product-detail/ja/texas-instruments/NE555P/296-1411-5-ND/277057

1個約50円。念のため2個購入しました。
ちなみに、マルツはDigi-Keyの正規代理店で、全製品を1個から購入可能というチラシが入っていた。
へぇ～、そうなんだ。

あと、最終工程を見越してICソケットも購入。
2個セットで約100円。

ICソケットDIP 8ピン【ICC05-008-360T-F】
https://www.marutsu.co.jp/pc/i/13893/

やはり秋葉原で仕事終わりに電子工作パーツを購入するなら、
20時まで営業しているマルツが一番いいかなーと思いました。
駅からも遠くないし、商品の陳列も整然としていて探しやすい。
あと2階のマイコンキットとか眺めるの楽しい。

# ネット購入の場合
私は秋葉原の実店舗で購入する前提だったので調査対象外だったが、
以下は購入後に調べたネットでの価格。
やはり秋月は安い。

## 秋月電子　1個20円(税込)
タイマーＩＣ　ＮＥ５５５Ｐ - 秋月電子通商
http://akizukidenshi.com/catalog/g/gI-08344/

aitendoと同率1位。さすが秋月。
しかも税込価格なので5個買っても税込で100円ポッキリ。
私は営業時間的に仕事終わりだと厳しいので除外してしまっている。

## Amazon　10個288円
10pcs NE555P NE555 DIP-8 シングルバイポーラ ICタイマー - Amazon
https://www.amazon.co.jp/10pcs-NE555P-NE555-シングルバイポーラ-ICタイマー/dp/B016UE3LQ4

ちなみにAmazon's Choiceはこちら。
1個あたり30円を切る上、送料無料なのでマルツよりはお買い得。
ただし10個中8個が不良品だったとのレビューもあるので、その辺りはご注意を。
もちろん10個とも良品だったというレビューもあるし、
さすがに8個も不良品だったら返金か交換対応してくれそうだけどね。

# あとがき
他にもいくつか有名どころのパーツ通販サイトを調べたが、
調べた限りでは50円オーバーばかりだったのであえて掲載しません。
もっとちゃんと調べれば20円を切る物もあるかも？
あとは大量購入するなら1個あたり15円ぐらいにはなりそう。

購入後。
よくよく考えれば、あらかじめタイマーの時間を考えといてコンデンサも一緒に購入すれば良かったなーと反省。
手元には33μFの電解コンしかなかった・・・。

とりあえず手持ちの電解コンで555の動作確認をしたので、次回はその辺りを。
Firebase functionsはサブフォルダにはアクセスできない

Firebase 7.2.4時点での記事です
###結論
CloudFunctionsはサブフォルダに直接アクセスできない。
ファイルのサブセットに処理を限定したければ、バケットを分けるかフォルダ名を使ったif文で分岐してあげる必要がある。

###やりたいこと
筆者は現在、ストレージ内の画像を加工して、同一バケットの別フォルダに結果を保存するアプリを制作している。
その過程で[クックパッドさんの例](https://techlife.cookpad.com/entry/2018/11/02/100000)を参考にして画像に対応するデータベースを持たせることにした。

データベースを一々作成するのは現実的ではないので、[musatarosuさんの記事](https://qiita.com/musatarosu/items/2a0f3915afbd9e717cff)を参考にして、ストレージに画像がアップロードされたタイミングで必要な情報をデータベースに追加するように記述した。

ここまではよかった・・・

###詰まったところ
上述の記事やCloudFunctionsに関するその他多くの参考ページでは

```javascript
exports.createInfoDB = functions.storage.object().onFinalize((object) =>{...})
```

のようにデフォルトのストレージ全体の変更を検知している。

このため、加工前の画像をストレージにアップロードしたタイミングだけでなく、加工後の画像を保存したタイミングでも関数が呼ばれてしまいデータベースに不要な情報が追加されてしまった。
そこでサブフォルダに直接アクセスする方法はないかなと解決策を探したところstackoverflowにこんな記事を見つけた。
[Is it possible to scope Firebase functions to a folder inside a storage bucket?](https://stackoverflow.com/questions/45404270/is-it-possible-to-scope-firebase-functions-to-a-folder-inside-a-storage-bucket)
どうやら2019年5月時点でCloud Functionsはサブフォルダだけを対象にはできないらしい。

###結局
回答者はバケットを分ける方法や画像のメタデータで判別する方法を提案している。
が、今回はファイルパスをスライシングして以下のように単純なif文で分岐させることにした。

```javascript
exports.createInfoDB = functions.region("asia-northeast1").storage.object().onFinalize((object) =>{
  const bucketName = [app.com];
  const filePath = object.name;
  var answered = false;
  if (filePath.slice(0,11) =="test_images"){ //test_imagesの更新は通して、answer_imagesの更新は通さない
    db.collection("test_images").add({
      filePath,
      downloadUrl: "https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(img_name)}?alt=media",
      answered,
    }).then(() => console.log("Done"));
  }else {
    console.log("not test_image")
  }
});
```

参照で言うところの.child()のようなものが実装されたら便利なのだが・・・ねぇ
Pythonのスクレイピング

# Pythonを使用したスクレイピング
Pythonのスクレイピングのメモです。

**動作環境**

- Mac OS Mojave
- Python 3.6.5


### HTML要素にclass、idセレクタが付いていない場合
name属性が付いていると仮定しますが、以下のようなタグだった場合

```html
<input type="text" name="hoge" value="fuga" autocomplete="off">
```

上記を取得するには以下のようなPythonコードであれば取得可能
HTTPS対応とかは別途必要。

```python
# アクセス先のURL
url = 'http://hoge.com'
# レスポンス取得
res = requests.get(url)
# BeautifulSoupで形成
soup = BeautifulSoup(res.text, "html.parser")
# inputタグのname属性"hoge"のvalueを取得する
name_hoge_val = soup.find('input', {'name':'hoge'})['value']
```

### Pythonスクレイピング【SEO要素を取得する】
ちょっとエラー処理とかやっていないので、取得できなかった場合とかエラーになりますがとりあえず。。。後々修正する（予定）

inputでターミナルからURLを受け付けます。
ターミナルからURLを入力したら、入力したURLでスクレイピングを仕掛けます。

スクレイピング先のサイトのSEO要素（Tilte,　Description, Keywords）を取得します。


```python
import requests;
from bs4 import BeautifulSoup;

# ターミナルからURLを受け付ける
input_url = input("検索したいワードを入力: ")
res = requests.get(input_url)
soup = BeautifulSoup(res.text, 'html.parser')

def get_seo_content(input_url, soup):
    # headタグの中身を取得
    head_info = soup.find('head')

    # titleの取得
    title = head_info.find('title').getText()

    # Descriptionの取得
    meta_description = head_info.find('meta', {'name' : 'description'})
    description = meta_description['content']

    # Keywordsの取得
    meta_keywords = head_info.find('meta', {'name' : 'keywords'})
    keywords = meta_keywords['content']

    '''
        結果の出力
    '''
    print(
        '''
        ###############################
        Title: {0}
        description {1}
        Keywords {2}
        ###############################
        '''
        .format(title, description, keywords)
    )


get_seo_content(input_url, soup)
```
Pythonのmedian_grouped()

初歩的なことかもしれませんがハマったのでメモ。

#statistics.median_grouped([1, 2.4])の値はなーんだ？

答えは1.9。

通常のメジアンmedian()は偶数個のデータがあるとき真ん中2つの中間値になります。

```python
import statistics
print(statistics.median([1, 2.4]))
```

結果

```output
1.7
```

しかし、**median_grouped()は[補間メジアン](https://en.wikipedia.org/wiki/Median#Interpolated_median)**なのでこうなります。

```python
import statistics
print(statistics.median_grouped([1, 2.4]))
```
結果

```output
1.9
```

#なぜ？

まず、次のように実際のデータから仮に「中央の値」をとってきて、

```python:Python37/Lib/statistics.py
    # Find the value at the midpoint. Remember this corresponds to the
    # centre of the class interval.
    x = data[n//2]
```

これを中点とする区間(**メジアン区間**と仮に呼ぶ)を考えます。幅はmedian_grouped(data, interval=1)の
intervalです。そして線形補間で算出です。

median_grouped([1, 2.4])の場合は、2.4を中央とする半開区間 [1.9, 2.9) をとり、
1.9と求まります((n+1)/2番目の値を考えるmedian()と違って、n/2個になる点を考えるところに注意)。


#別の例

```python
import statistics
print(statistics.median_grouped([1,2,2]))
```
結果

```
1.75
```

位置1を中点として区間[1.5, 2.5)を考えると、そこで累計データ数が1個から3個に増えているので、
1.5個になる点は、線形補間で、1.5+{1*(1.5-1)/(3-1)}=1.75です。**通常のメジアン(2)よりも"中央っぽい"**です。


#注意点

ここで**メジアン区間内には他の値が含まれないほどintervalが小さいことが想定されている**ようです。
[Pythonドキュメントの例](https://docs.python.org/3/library/statistics.html#statistics.median_grouped)もそうですし、[Wikipediaの計算式](https://en.wikipedia.org/wiki/Median#Interpolated_median)もそうなっています。
Pythonでも、もし他の値が含まれても存在しないかのように計算されます。

```statistics.py
    # Uses bisection search to search for x in data with log(n) time complexity
    # Find the position of leftmost occurrence of x in data
    l1 = _find_lteq(data, x)
    # Find the position of rightmost occurrence of x in data[l1...len(data)]
    # Assuming always l1 <= l2
    l2 = _find_rteq(data, l1, x)
    cf = l1
    f = l2 - l1 + 1
    return L + interval*(n/2 - cf)/f
```

しかし**この計算方式は唯一のものではなく**、区間内の他の値も加味する定義もあるようです。

(何しろ、[分位数には10種類もの定義があるそうで、Wolfram言語のQuantile[ ]にはどの計算法を用いるかを
指定する4つのパラメーターがある](https://reference.wolfram.com/language/tutorial/BasicStatistics.html.ja?source=footer)そうですし、[pandasのquantile()にもパラメーターがあるようです](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.quantile.html))

median_grouped()という名前は、データをいくつかの階級(class)にグループ分けした連続分布とみなす
というニュアンスを込め、あとはこういう関数を使う人には説明不要という判断での命名な気がしますが、
定義が混在していて計算が食い違ったりして統計に不慣れな人には少しややこしいかもしれません。
環境変数へのAPI KEY の記載

# 概要
自分でアプリを作成した時にapi keyを取得していて、local環境で使用していたものの,
いざgithubにpush使用と思った際に、不正利用されないようにどうやって設定するのかと思い、調べてみました。
忘れないように書いておきます。

# 作業
### 1.gemのインストール

```
gem 'dotenv-rails'
```

bundle installを実行

### 2.env fileを作成
<img width="97" alt="スクリーンショット 2019-08-21 17.12.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485253/4e84c6c6-c11f-c3a9-20bb-beca89228915.png">

### 3.envにkeyを記載

```
API_KEY =xxxxxxxxxxx
```

ここは右辺には個人的には""などは使用しないほうがいいと思います。

### 4.viewのapi keyを埋め込む場所に環境変数を呼び込む

```
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['API_KEY']%>"></script>
```

　今回はgoogle map apiを使用しているので上記のような記述になりました。

### 5.gitignoreに追加
隠しておきたいデータを定義した.envファイルをGitHubに公開ししたくないから、追加します。
<img width="557" alt="スクリーンショット 2019-08-21 17.25.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485253/d7be413c-a7e1-2bee-4939-9b2348e17319.png">

# 最後に
bash_fileに書くほうが一般的みたいです。
調べてまとめたら記載していきたいです。
間違いがあるかもしれません。指摘して頂けると助かります。
AzureのAppServiceのリモートデバッグ起動時にエラー

VS2017のサーバーエクスプローラーから、AzureにデプロイしているAppServiceを選択。｢デバッガーのアタッチ｣を選択してしばらく待つと次のようなエラーが発生。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102784/d5866a66-ad09-0157-1b0d-6198fee8879d.png)

文面からするとApp Service が32ビットのプロセスになっているかと思い、AzureのPortalで設定をチェック。
設定は64Bitになってる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102784/185a4ca5-74e1-7e6a-54d4-377a4b96e190.png)

しばらく考えてみてよくわからないので、App Serviceのプラットフォームを32Bitに変更して再度サービスを起動。その後、再度プロセスにアタッチしてみると、今度はうまくいってリモートデバッグも無事できた。

サービスを32Bitにすることで、リモートデバッガーも自動的に32Bitが起動したのだろうか？