OmniAICreator/Qiita-1.07M huggingface dataset:
sshできなくなったのでarpingコマンドでトラブルシュートっぽいことをした話

## 0. はじめに

ssh hoge@ipでサーバーの対向のネットワーク機器にsshでログインできなくなってしまい、泣く泣くトラブルシュートする羽目になりました。
普段触らないARPコマンドを調べながら、なんとかログインすることが出来たので、備忘録として本記事をしたためることとしました。


## 1. 環境/バージョン情報

- ssh接続元(何台か踏み台サーバーの先にあるリモート開発環境) 
  - CentOS Linux release 7.4
- 接続先
  - Junos QFX (バージョン、機器情報など不明)


## 2. 事象の確認

```
sshで接続できなくなりました。
$ ssh hoge@$ip

ssh -vでデバッグさせようも何も反応がありません。
$ ssh -v hoge@$ip

pingでも疎通が取れないことを確認できました。
$ ping $ip -c 3 -w 5
```

## 3. 原因調査
先日私用のubuntu pcにて同じようなネットワーク周りの不具合に出くわし、なんとかトラブルシュートした経験があったので、まずその記事を参照しました。

ありがとう！おれ！笑。

[ubuntu19.04でpingとnslookupができなくなり、DNSサーバーを変更するのにめちゃくちゃハマった話](https://qiita.com/gkzz/items/5ac6648e87339e1dd883)

### ARPテーブルの更新状況を確認 
記事にARPテーブルを確認することという記述があったので、みてみました。


```
$ ip nei | grep $ip
$ip dev eth1 lladdr xxxxx(MAC Address) STALE
```

STALEとは、ARPテーブルの更新がしばらく行われていない状態のことのようです。

>ARPによる更新が最近行われたばかり、もしくは自デバイスであれば REACHABLE になります。STALE は"腐ってる≒新鮮じゃない"という意味ですが ARP による更新を行ってから幾分か時間が経過している、というだけです。実際には疎通できていることがほとんどのはずです。

参考: [Linuxコマンド【ip neigh】ARPテーブル表示の見方やflush,Static ARPエントリ追加/削除の設定](https://milestone-of-se.nesuke.com/sv-basic/linux-basic/arp-ip-neighbour/)


参考
http://www.hachim.jp/network/arp.html


### ARPテーブルを更新
どうもARPテーブルを更新するには、arpingコマンドを使うとよいのかなと思ったのですが、改めて思うと、結局`更新とは何を指している`のでしょうか？？

``` 
$ arping == ARPテーブルの更新?
```

>端末から実際にarpを投げてみて返してくる端末がいるか、周辺機器のarpが更新されるかなどを確認します。　

参考: [ARP 纏め](http://www.hachim.jp/network/arp.html)

```
$ arping -I eth1 $ip -c3 -w 5
ARPING $ip from $srcIp eth1
Unicast reply from $ip [MAC Address]  1.323ms
Unicast reply from $ip [MAC Address]  1.688ms
Unicast reply from $ip [MAC Address]  1.568ms
Sent 3 probes (1 broadcast(s))
Received 3 response(s)
```

```
$ arping -help
Usage: arping [-fqbDUAV] [-c count] [-w timeout] [-I device] [-s source] destination
  -f : quit on first reply
  -q : be quiet
  -b : keep broadcasting, don't go unicast
  -D : duplicate address detection mode
  -U : Unsolicited ARP mode, update your neighbours
  -A : ARP answer mode, update your neighbours
  -V : print version and exit
  -c count : how many packets to send
  -w timeout : how long to wait for a reply
  -I device : which ethernet device to use
  -s source : source ip address
  destination : ask for what ip address
```

なにはともあれ、arpingコマンドを叩いてからはsshで対向のNW機器に接続することが出来ました。
なお、ip neiでステータスを確かめてみると、なおも`STALE`でした。

ネットワーク。難しいけどそこそこ楽しいですね。

結局どうして接続できなくなり、また`ARPテーブルを更新の更新とは何を指しているのか？`については分からないままです汗。

またトラブったら調べます。。。

## P.S. Twitterもやってるのでフォローしていただけると泣いて喜びます:)
[@gkzvoice](https://twitter.com/gkzvoice)
【React】フォーカスアウトするとカンマ区切りで表示される入力欄

# 経緯
* 数値を入力する項目がある
* 桁が大きくなると額がわからなくなる
* だからカンマ区切りで表示したい
* それを実現可能な要素はHTMLには無い
  * input=text だと数値以外を入力できる
  * input=number だとカンマを表示できない
* じゃあ作ろう

# 仕様
* input=textをベースとする
* 入力値は右寄せで表示する
* バリデーション機能を追加する
  * 正の数、および負の数を入力可とする
  * マイナスは先頭のみ入力可とする
  * 小数点は一度のみ入力可とする
  * 小数点の前には必ず数値の入力があるものとする
  * 末尾が小数点で終わる場合を許容する
* 未入力、及びバリデーション通過時の背景色を #FFF とする
* バリデーション不通過時の背景色を #FFBEDA とする
* 入力欄にフォーカス時に入力した文字列をそのまま表示する
* 入力欄からフォーカスアウト時にバリデーションを通過した場合はカンマ区切りの文字列を表示する
* 入力欄からフォーカスアウト時にバリデーションが不通過となる場合は入力した文字列をそのまま表示する

```jsx
import React, { useState } from 'react';

const InputText = ({ ...rest }) => {
  const [value, setValue] = useState('');
  const [isFocus, setFocus] = useState(false);
  const handleFocus = () => setFocus(true);
  const handleBlur = () => setFocus(false);
  const handleChange = e => setValue(e.target.value);
  const isBlank = value === '';
  const isValid = /^[-]?(\d+)[.]?(\d+)?$/.test(value);
  const displayValue = (() => {
    if (isFocus || !isValid) {
      return value;
    }
    if (isValid) {
      return (+value).toLocaleString();
    }
    return '';
  })();
  const displayStyle = {
    textAlign: 'right',
    backgroundColor: isValid || isBlank ? '#FFF' : '#FFBEDA'
  }

  return (
    <input
      {...rest}
      type="text"
      onFocus={handleFocus}
      onBlur={handleBlur}
      onChange={handleChange}
      value={displayValue}
      style={displayStyle}
    />
  );
}

export default InputText;
```
belongs_toの効力を舐めちゃいかん。

ふとモデルをいじっていて「こいつなんでおるん？」という型に出会った。reward = product.rewards,,,のproductだ。もともとこいつがいる理由は知っていたのだが、忘れていた。そこで失礼ながら「なんでおるんや！」と投げかけてしまったのだ。

```rb

def donation_error
    reward = product.rewards.order(price: :desc).last
    errors.add(:base, "最低金額に達していません") if self.donation != nil && self.donation < reward.price
  end
```
```rb

class Patron < ApplicationRecord
  belongs_to :user
  belongs_to :product
  validates :donation, presence: true
  validate :donation_error
  belongs_to :reward
  has_many :notifications
  private

  def donation_error
    reward = product.rewards.order(price: :desc).last
    errors.add(:base, "最低金額に達していません") if self.donation != nil && self.donation < reward.price
  end
end
```

##　結論

####   belongs_toによってメソッドが与えられてる

Railsガイドさんによると

>1 belongs_toで追加されるメソッド
belongs_to関連付けを宣言したクラスでは、以下の6つのメソッドを自動的に利用できるようになります。
association
association=(associate)
build_association(attributes = {})
create_association(attributes = {})
create_association!(attributes = {})
reload_association
[Railsガイドさん](https://railsguides.jp/association_basics.html#belongs-to%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%81%AE%E8%A9%B3%E7%B4%B0)
【vue-js-modal】を使ってNuxt.js（vue.js）でモーダルを実装してみた

【[vue-js-modal](https://github.com/euvl/vue-js-modal)】は簡単にモーダルウィンドウを実装できるコンポーネントです。
Nuxt.jsでの使い方をまとめました。
イメージは下記の感じです。
![lightbox.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/fe64b08f-03cb-0c37-e802-e6e3896815ef.gif)


まずは【vue-js-modal】インストールします。

```
npm install vue-js-modal --save
```

Nuxt.jsのディレクトリ構成は下記のようになっています。
![nuxt.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/0bc818f2-7818-c3b8-1fe5-76b82e718ece.jpeg)

pluginsディレクトリにファイルを作成し【vue-js-modal】をインポートします。

今回はmain.jsと言うファイルを作成しました。

```
├── plugin
│   ├── main.js
```

```js:main.js
import Vue from 'vue'
import VModal from 'vue-js-modal'

Vue.use(VModal)

```

次にnuxt.config.jsを編集していきます。

```js:nuxt.config.js
export default {
  plugins: [
    { src: '~/plugins/main.js'}
  ],
}
```

これで【vue-js-modal】が使用可能になりました。あとは使いたいコンポーネントで使用していきます。

```vue
<template>
 <div>
   <button @click="show">クリックする</button>

   <modal name="modal-content">
      <p>モーダルウィンドウで表示されるコンテンツ</p>
   </modal>
 </div>
</template>

<script>
export default {
  methods: {
    show() {
      this.$modal.show("modal-content");
    },
    hide() {
      this.$modal.hide("modal-content");
    }
  }
};
</script>

```
this.$modal.show()がモーダルウィンドウを開くメソッド、
this.$modal.hide()がモーダルウィンドウを閉じるメソッドになっています。

これだけでモーダルウィンドウができちゃいます。
【vue-js-modal】にはオプションも複数あり、モーダルウィンドウに動きなども追加できます。

例えば下記のような感じです。

```vue
   <modal name="modal-content" width="80%" height="auto" :scrollable="true" :draggable="true">
      <p>モーダルウィンドウで表示されるコンテンツ</p>
   </modal>
```
横幅を指定したり、スクロールバーの有無やモーダルウィンドウをドラッグ可能にすることもできます。

詳しいオプションの種類は下記に記載されています。

【[vue-js-modal](https://github.com/euvl/vue-js-modal#readme)】

##最後に

今回はvue.jsで簡単にモーダルウィンドウが実装できる【vue-js-modal】を使ってみました。
ちょうどポートフォリオサイトをNuxt.jsで作っており、作品の紹介などでモーダルウィンドウを実装したかったので・・・
オプションも豊富なので、かなり便利でした。

![lightbox.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/fe64b08f-03cb-0c37-e802-e6e3896815ef.gif)
僕のSparkARメモ

# ここに大体書いている
https://sparkar.facebook.com/ar-studio/learn/documentation/reference/scripting/summary

# 指定ミリ秒毎functionを呼び出す
```javascript

const Time = require('Time');
const intervalTimer = Time.setInterval(HogeFunc, 100);
```
# 指定ミリ秒Delayして匿名関数を呼び出す
```javascript

const Time = require('Time');
const Diagnostics = require('Diagnostics');

Time.setTimeout(()=>{
    Diagnostics.log("hogeee");
},800);
```

#アニメーション
```javascript

const Animation = require('Animation');
const plane = Scene.root.find('plane0');

const TimeDriverParameters = {
    // 何ミリ秒でアニメーションさせるか
    durationMilliseconds: 500,
    //ループ何回するか
    loopCount: 1,
    //falseじゃなかったら、yoyoするので指定数値までアニメーションしなかったりする
    mirror: false
};
const TimeDriver = Animation.timeDriver(TimeDriverParameters);
const Sampler = Animation.samplers.easeInBounce(1,0); //イージングとアニメーション範囲
const Animation = Animation.animate(TimeDriver, Sampler);
plane.transform.scaleX = Animation;

TimeDriver.start(); //アニメーション開始
TimeDriver.reverse(); //逆再生
```

#Patchと連携
### スクリプト側
```javascript

const Patches = require('Patches');
Patches.setPulseValue("StartSound", Reactive.once());
```
### エディタ側
スクリプト作って選択してからの...
<img width="218" alt="スクリーンショット 2020-02-17 20.47.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587952/b70c4f4b-5993-c939-d745-061677ecff47.png">

FromScriptに変数の型とfunction名を記入して...
<img width="280" alt="スクリーンショット 2020-02-17 20.47.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587952/1929c0ab-e8b5-1718-69c7-d24ae86f023e.png">

Patch Editorにドラッグしたらスクリプトのタイミングでpatchに命令が飛ぶ
<img width="574" alt="スクリーンショット 2020-02-17 20.52.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587952/f7c235ad-5b4e-f014-a9e6-69ceebbffd9e.png">

#別ファイルから呼び出し

定義側

```javascript
//script1.js

export const Diagnostics = require('Diagnostics');

export function Say(){
    return Diagnostics.log('hoge');
}
```

呼び出し側

```javascript
//script2.js

const hoge = require('./script1');

hoge.Say();
```

#Scriptから音を出す
どこかのアップデートのタイミングで、PatchEditorからしか任意のタイミングで音が出力できなくなったらしい？
スクリプトでタイミングを取りたい場合は、PulseをPatchEditorに投げる処理をスクリプトに記述して、↓みたいなpatchを作成する
<img width="589" alt="スクリーンショット 2020-02-17 21.21.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587952/aac64b5b-4b75-605d-6a8f-37fa85ad7eb3.png">

#結論
↓に大体書いている
https://sparkar.facebook.com/ar-studio/learn/documentation/reference/scripting/summary
App Store Connectで、提出準備中のAPPのバージョン番号を変更する方法

- 調べないとわからなかったので記録しておく

1. AppStoreConnectにログイン
2. iOS App x.x.x 提出準備中の画面を下にスクロールする
3. 「バージョン」という項目があるので書き換える

- 簡単なことだが　意外と見つけられない。ここを見てわかった=> https://stackoverflow.com/questions/7439338/removing-a-new-app-version-from-itunes-connect
ACIモードになっているCisco NexusのデバイスにAnsibleでコマンドを実行する

<h1>背景</h1>
Leaf間の疎通テストをするために、ACIモードになっているCisco Nexusのデバイスからipingを自動で実行したい状況になったため、Ansibleで試してみました。

ですが、Ansible2.9現在ではACIモードになっているCisco Nexusでコマンドを実行するための
<a href=https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html>Ansible os platform type</a>が用意されていないため手を加える必要がありました。
※ansible_network_os: nxosをそのまま使うと、pingモジュールの応答は返ってきますがコマンドの実行は<a href=https://tekunabe.hatenablog.jp/entry/2018/08/23/ansible_ios_terminal_error>こちらと同じエラーとなりできません。</a>

<h1>結論</h1>
結論としてaciモードではterminal lengthのコマンドが実行できない事が原因で上記のエラーとなっていたので、ACIモードのNexusでコマンドを実行するには以下のようにします。

host_vars/leaf01.yml(ファイル名は一例)

```
---
ansible_network_os: nxos

## 以下省略
```



そして以下のファイルの以下の箇所をコメントアウトします。
※どこでAnsibleが動いているかによって編集するファイルが異なります。
 私の場合は以下のパスを編集しました。
~/pyenv/lib/python3.7/site-packages/ansible/plugins/terminal/nxos.py

```python

def on_open_shell(self):
    try:
        for cmd in ('terminal length 0', 'terminal width 511'):
            self._exec_cli_command(cmd)
        except AnsibleConnectionFailure:
            raise AnsibleConnectionFailure('unable to set terminal parameters')

```

site.yml(ファイル名は一例)

```yaml
---
- hosts: leaf01
  gather_facts: no
  # このままでは管理者権限がyesになっていると失敗するのでnoにする
  become: no

  tasks:
    - name: iPingを実行する
      nxos_command:
        commands: 
          - iping -V my_tenant:my_vrf 192.168.0.1
```

コメントにも記載しましたように、このままではbecome: yesになっていると失敗するのでbecome: noにして使います。おそらく、先ほど編集したnxos.pyで管理者権限に昇格する処理がaciモード用となっていないのが原因です。

以上、あくまでも暫定的な使い方ではありますがこのようにする事でコマンドの実行ができましたので投稿した次第です。
機械学習のアルゴリズム（線形回帰の一般化）

# はじめに
以前、「[機械学習の分類](https://qiita.com/hiro88hyo/items/c00dcf8f083ba3d76af8)」で取り上げたアルゴリズムについて、その理論とpythonでの実装、scikit-learnを使った分析についてステップバイステップで学習していく。個人の学習用として書いてるので間違いなんかは大目に見て欲しいと思います。

これまで、「単回帰」、「重回帰」と見てきたが、どちらも線形回帰という同じ分野の中で話をしてきた。今回は、線形回帰を一般化した「**線形基底回帰モデル**」と損失関数を最適化するための「**勾配降下法**」についてまとめたいと思う。今回参考にしたのは以下のサイトです。

* [PRMLの線形回帰モデル（線形基底関数モデル）](https://www.slideshare.net/yasunoriozaki12/prml-29439402)


# 基本
データ列に対する近似曲線を引くために、単回帰モデルは$$y=Ax+B$$重回帰モデルは

```math
y=w_0x_0+w_1x_1+\cdots+w_nx_n
```
で近似させるものだった。さらにいうと、単回帰については、重回帰の式の2項目までを使ったに過ぎないことがわかる。

さて、各項の重み$(w_0,w_1,\cdots,w_n)$とすると、モデルの関数は実はなんでもよくて、これを$y=\phi(x)$とおくと、

```math
y(\boldsymbol{x}, \boldsymbol{w}) = \sum_{j=0}^{M-1}w_j\phi_{j}(\boldsymbol{x})
```
と表される。$\boldsymbol{w}=(w_0,w_1,\cdots,w_{M-1})^T$、$\boldsymbol{\phi}=(\phi_0,\phi_1,\cdots,\phi_{M-1})^T$、とおく。$\phi_0=1$(切片項)とすると、

```math
y(\boldsymbol{x}, \boldsymbol{w}) = \boldsymbol{w}^T\phi(x)
```
になる。この$\phi(x)$を**基底関数**という。

# 様々な基底関数
一般化された式の意味するところは、線形回帰というのはつまり、ある基底関数を組み合わせて与えられたデータ列をもっともよく表す係数の列$\boldsymbol{w}$を見つけること、ということです。

* 単回帰、重回帰。回帰直線で近似する際に使う。$$\phi_j(x)=x$$
* 多項式回帰。多項式で近似。$$\phi_j(x)=x^j$$
* ガウス基底関数$$\phi_j(x)=\exp\left\\{-\frac{(x-\mu_j)^2}{2s^2}\right\\}$$
* シグモイド基底関数。ニューラルネットでよく使われる。$$\phi_j(x)=\sigma(\frac{x-\mu_j}{2s})$$
* フーリエ基底。フーリエ変換で使われる。$$\phi_j(x)=\exp(i\theta)$$

scikit-learnでは回帰に様々な基底関数が使えるようになっています。

* [https://scikit-learn.org/stable/modules/classes.html#sklearn-metrics-metrics](https://scikit-learn.org/stable/modules/classes.html#sklearn-metrics-metrics)


# 回帰係数を求める
単回帰や重回帰では、残差二乗和を最小にするような係数を求めました。単回帰では数学的にwを求めることが可能でしたが、基底関数が複雑な場合や、データの次元が多い場合には解析的に解を求めることが非常に困難な場合が多いです。そういう場合に、近似的に係数を見つける必要があります。その際に用いるのが「**勾配降下法**」です。文字通り、坂(勾配)を下がっていきながら最適な値を見つける手法です。

数学的に解く方法も含め、係数をどう見つけるか考えてみましょう。なお、以下に詳しく書かれています。

* [確率的勾配降下法のメリットについて考えてみた](https://qiita.com/koshian2/items/028c457880c0ec576e27)

## 数学的解法

単回帰や重回帰で述べたような式変形で解を探すやり方です。平方完成や偏微分から連立方程式を解くやり方です。数式が簡単なら問題はありませんが、モデルが複雑な場合は解けないケースが出てきます。

## 勾配降下法

勾配法は、文字通り損失関数の勾配を下っていく方法です。最適なパラメータを求めるためには損失関数の値が小さい必要があるが、小さい値に向かって坂を下っていくイメージです。

よく機械学習のサイトで紹介されるのは最急降下法と確率的勾配降下法だが、ディープラーニングの世界になると、使われる勾配降下法が増えます。ディープラーニングが盛んになってさらに発展している分野と言えるかもしれません。

### 最急降下法

損失関数$f(x,y)$が与えられた場合に、その勾配ベクトルは$x$と$y$それぞれで偏微分すると、$$ \nabla f(x,y) = \biggl(\frac{\partial f}{\partial x},\frac{\partial f}{\partial y}\biggr) $$なので、初期位置$(x_0,y_0)$を適当に決めて$f[(x_0,y_0)-\eta\nabla f(x_0,y_0)]$を次の点にして結果が収束するまで繰り返します。$\eta$は学習率と呼ばれます。

ただ、この方法の弱点は、損失関数は必ずしも一つではないということです。初期値の取り方を帰ると収束する位置も変わります（局所解に収束する）。

### 確率的勾配降下法(Stochastic Gradient Descent:SGD)

最急降下法では、参照する点は1つでしたが、確率的勾配降下法では、複数のサンプルを参照します。任意の数のサンプルを抽出しシャッフルしたものを用い、$$ w := w-\eta\sum_{i=1}^n \nabla Q_i(w)$$を計算していきます。

ほとんどの場合はSGDの方が収束が早いらしいですが、最急降下法の方が計算は早いです。ほとんどの場合はSGDを使っていれば問題ないのではないかと思います([Wikipedia談](https://ja.wikipedia.org/wiki/%E7%A2%BA%E7%8E%87%E7%9A%84%E5%8B%BE%E9%85%8D%E9%99%8D%E4%B8%8B%E6%B3%95))。

# まとめ

単回帰や重回帰を発展させて、一般的な回帰と解法について書きました。これまでの理論を用いることで、いろんなサンプルに対する回帰が求められると思います。

本当はpythonの実装も試してみようと思ったんですが力尽きました。次は、pythonでの実装をいくつか試して見たあとに、過学習(overfitting)や正則化(regularization)についてまとめてみたいと思います。
ヘルプファイル(.chm)の手動コンパイルについて

業務アプリケーションのFAQなどを.chmファイルとしてユーザーに提供する場合、フリーソフトのヘルプましんなどを使用する場合が多いと思う。
そんな便利なフリーソフトがあるにも関わらず、手動で.chmファイルをコンパイルする機会があったので、需要は少ないが、ナレッジを残す。

##ヘルプファイルを手動コンパイルするために必要なもの
| No|ファイル|備考|
|--:|:--|:--|
|1|.html|ヘルプページそのもの|
|2|.hhc|ヘルプファイルの左側にあるTreeViewの階層を定義するファイル|
|3|.hhp|プロジェクトファイル。コンパイル時のオプションなどを定義するファイル|
|4|hhc.exe|ヘルプファイルをコンパイルしてくれる.exe|

##htmlファイル
html形式でヘルプページを作成しよう。cssも使用できる。

（ヘルプファイルもある意味、ブラウザといえるのだろうか。）

##hhcファイル
ヘルプファイルの左側にはファイルの階層をTreeViewで表示している。
この階層の定義や、各階層ごとのアイコンの設定などを.hhcファイルに記述しよう。

基本的な構成は以下の通り。

```html:hoge.hhc
<!--1階層目-->
<UL>
    <LI><OBJECT type="text/sitemap">
    <param name="Name" value="Title"/> <!--表示される名前-->
    <param name="Local" value="htmlFilePath"/> <!--ヘルプページのパス-->
    <param name="ImageNumber" value="1"/> <!--アイコン-->
    </OBJECT></LI>

    <!--2階層目--> 
　　<UL>  
        <LI><OBJECT type="…">
　　　　 　　　…
        </OBJECT></LI>

        <!--以下無限に繰り返せる-->
        <UL> 
　　　　     <LI><OBJECT type="…">　
　　　　　　　　   …
            </OBJECT></LI>
        </UL>
    </UL>　
</UL>
```

\<UL>タグで階層の段階を表し、\<LI>タグで一つのヘルプページを表す。

###ハマったポイント
\<LI>タグと\<OBJECT>タグが同一行に存在しないとコンパイラが認識してくれず、メニュー階層に表示されない。
コンパイルログにエラー表記されないため、注意が必要である。
　
##hhpファイル
ヘルプファイルをコンパイルするための設定情報を定義する。
あまりナレッジがなく、ヘルプましんで作成された.hhpファイルから不必要な設定を削っただけなので、詳しい説明はできない。

```text:hoge.hhp
[OPTIONS]
Auto Index=Yes
Binary Index=Yes
Compatibility=1.1 or later
Compiled file=FAQ.chm
Contents file=FAQ.hhc
Default Font=MS UI Gothic,16,138
Default Window=XHP
Default topic=htmlPath
Display compile progress=No
Error log file=Compile.Log
Flat=No
Full-text　search=Yes
Language=0x0411 Japanese
Title=FAQ
```

[OPTION]以外にも設定できるが、コンパイルを通すだけならば、上記で十分である。

##hhc.exe
HTML Help Workshopをダウンロード、インストールする。
hhc.exeはC:\System32\hha.dllを使用するため、インストールした方が無難である。

##コンパイル
```text
>hhc.exe hoge.hhp
```

脆弱性の問題で、ネットワークドライブ上の.chmは正常に表示できない仕様になっている。
ローカルで内容を確認しよう。

##起動
hh.exeで起動する。
起動時の初期ページを変更するためには「::」のあとに表示したいhtmlファイルのchmファイルからの相対パスを記述する。

```text
>hh.exe hoge.chm
>hh.exe hoge.chm::fuga.html
```
【rubyonrails初心者】データの受け渡しの流れedit→controller→edit

自分用にrails チュートリアルのプロフィールを更新する部分をまとめます。


```app/views/users/edit.html.erb
<% provide(:title, "Edit user") %>
<h1>プロフィールを更新する</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user) do |f| %> 
      <%= render 'shared/error_messages', object: f.object %> →view内のshared/error_messages.html.erbを表示する

      <%= f.label :name %> 　　　　　　　　　　　　　　　　　　　　　#fはformの略。 nameはuserモデルの属性。指定する属性はモデルを作成する際に追加したものを指定する。
      <%= f.text_field :name, class: 'form-control' %> #      #  _fieldメソッドで入力できる。 nameはuerモデルの属性。以下同文。

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Save changes", class: "btn btn-primary" %>  #app/controllers/users_controller.rbに送られて、ファイル内にあるshowアクション、updateアクションを状況に応じて呼び出す。
    <% end %>

    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="http://gravatar.com/emails" target="_blank">change</a>
    </div>
  </div>
</div>
```

次はコントローラーの処理。


```app/controllers/users_controller.rb
class UsersController < ApplicationController

省略

  def edit
    @user = User.find(params[:id])   #@userはインスタンス変数。rubyの決まりでインスタンス変数は@から始めなければいけない。
  end                                #インスタンス変数を経由することでcontorollerからviewへ変数を渡すことができる。
　　　　　　　　　　　　　　　　　　　　　　#findはモデルの検索機能を持つメソッド。モデルと紐づいているデータベースのテーブルからレコードを1つ取り出す際に使う。                                  #paramsとはrailsで送られてきた値を受け取るためのメソッド。updateアクションがupdate_attributesを使って送信されたparamsハッシュに基づいてUserを更新するために使う。
省略　　　　　　　　　　　　　　　　　　　　#コロン（:）はシンボルの意味を持つ。使うと処理が高速になるのでハッシュのキーとしてよく使われる

end
```

参考
https://qiita.com/ryosuketter/items/44005785f47136a83ae1
セキュリティマネジメントの勉強ーISMS

#情報セキュリティマネジメントシステム
ISMS(Information Security Management System)はセキュリティ管理のための仕組み
PDCAサイクルを回す

##適用範囲
最初に行うのは、組織の状況を理解してISMSの適用範囲を定義すること
事業継続のために必要な、保護すべき情報を考えて範囲を定義する
事業・組織・物理・ネットワークなど様々な観点から決定する
特に境界を決めることが大事

##リーダシップ
トップマネジメントのリーダーシップが必要
一般的には社長とか
情報セキュリティ方針と情報セキュリティ目的を確立する

これは経営の一環として全社で組織的に行うことなので
情シス部ではなく経営にかかわる企業トップがリーダーシップをとってやる必要がある
トップマネジメントが必要な責任や権限を割り当てて指揮を取り、支援を行う。

##適用宣言書
適用宣言書には必要な管理策、それを含めた理由、実施しているか否かが記述される[^1]
[^1]: 否をつけるやついんのか・・・？
リーダは責任を持つ

##計画
情報セキュリティ目的を策定し、対処すべきリスクを決定する必要がある
セキュリティ目的では実施事項、必要な資源、責任者、達成期限、結果の評価方法を決定する

リスクを決定するために、情報セキュリティアセスメントのプロセスを定めて運用する
その結果を考慮して情報セキュリティリスク対応を選択する

##組織人が持つべき認識
JIS Q 27001:2014の「7.3 認識」では、３つの事項に対して認識をもたなければいけない

a) 情報セキュリティ方針
b) 情報セキュリティパフォーマンスの向上によって得られる便益を含む、ISMSの有効性に対する自らの貢献
c) ISMS要求事項に適合しないことの意味

##運用
計画したことを継続実施して、管理する必要がある
定期的に組織に重大な変化があった場合には、改めて情報セキュリティアセスメント、リスク対応を実施して
新しいリスクに対応できるようにする必要がある

##パフォーマンス評価
ISMSの実施においては有効かどうかの評価のために内部監査を行う必要がある
トップマネジメントがマネジメントレビュー[^2]を行い、定期的に確認する
[^2]: 経営層の見直しらしい

##改善（不適合及び是正処理、継続的改善）
パフォーマンス評価の結果を踏まえて是正処置を実行し、それを改善する
不適合の原因を除去し、再発を防止するための是正処置を実行して有効性のレビューを行う
これも継続改善が必要

##管理目的及び管理策
管理目的及び管理策のリストが附属書Aとして示されている
これは情報セキュリティのための方針、組織、人的資源のセキュリティ、アクセス制御や暗号、物理的及び環境的セキュリティについて
その目的や管理策がまとめられている
ISMSでは必要なすべての管理策を決定し、必要な管理策が見落とされていないことを検証する

##ISMS適合性評価制度
企業のISMSが国際規格に準拠しているかを評価して認定する日本情報経済社会推進協会(JIPDEC)の評価制度

* 認証機関・・・ISMSに適合しているかを審査して登録
* 要員認証機関・・・ISMS審査員の資格を付与する
* 認定機関・・・上記の２機関がその業務を行う能力を備えているか

##ISMS認証
審査の結果取得できると、対外的に信頼性を証明できる
官公庁の入札や電子商取引の前提条件になることもある

##ISO/IEC 27000
ISO(International Organization for Standardization)とIEC(International Electrotechnical Commision)が共同で策定する情報セキュリティ規格郡
日本ではJIS Q 27000として定義されている

* 27000:2018・・・ファミリー規格の概要や用語の説明
* 27001:2013・・・組織がISMSを確立、導入、運用、監視、レビュー、維持、継続改善のための要求事項
* 27002:2013・・・セキュリティ対策の管理策（ベストプラクティス）
* 27003:2010・・・ISMSを確立、導入、運用、監視、レビュー、維持および改善のためのガイダンス規格
* 27004:2016・・・管理策の有効性を評価するための測定方法の開発および使用に関するガイダンス規格
* 27005:2018・・・認証機関のための要求事項
* 27007:2017・・・ISMS監査に関するガイドライン
* 27014:2013・・・情報セキュリティのガバナンス（統治）のプロセスが記述
* 27017:2015・・・クラウドサービスの情報セキュリティ管理策の実施に関する規格
* 27010:2015・・・部門間及び組織間コミュニケーションのためのISMSに関する規格
* 27011:2016・・・電気通信業界内の組織でのISO27002に基づくセキュリティマネジメント導入を支援するガイドライン規格

##ISMSユーザーズガイド
ISMSの適合性評価制度を実施しているJIPDECが提供するガイド
27001:2014の要求事項について説明がある
初心者によるプログラミング学習ログ 241日目

#100日チャレンジの241日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

241日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>241日目<br>・youtubeでvue.jsミニアプリ模写<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1229139494479097856?ref_src=twsrc%5Etfw">February 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
2/17 授業ノート

#テストに出る！範囲
・CSS(Cascading Style Sheets)：HTML文書に装飾・レイアウトを施すための言語のこと
・HTML5文書にてスタイルシート”style.css”(同ディレクトリCSSフォルダ内)へのリンクを記述
　→```<link rel="stylesheet" href="css/style.css">```
・CSSの基本書式
　→**「セレクタ{プロパティ:値;}」**という流れで書く。
　ex:)```h1{color: #ff0000;}```
　　☆**h1部分→セレクタ、color部分→プロパティ、#ff0000部分→値と呼ぶ**
・HTMLとCSSの違い
　HTMLはコンテンツに意味づけをして文書構造を作る
　CSSはコンテンツに対して見栄えを作る
・text-align:centerとmargin:0 autoの違い
　text...は文字や画像をBoxに対して中央揃えにすること
　**marginは横幅のあるブロック要素が親Boxに対して中央揃えにする**
・ボーダーまたは背景色が設定された要素に対して設定するもの
　padding(見やすくするため)
・グループセレクタ＝CSS内で複数のセレクタに共通する装飾をまとめて記述すること
　ex:)```h1,h2,p{…}```
・横幅Apx、親Boxに対して上下余白0、中央揃えのdivをCSSで記述
　→```div{width:Apx; margin:0 auto;}```


#今日習ったこと
・header/footerには上下に初期値のマージンがない＝footerはすぐ上のコンテンツと隣接している

#自分の課題
marginとpaddingの認識、navの構造を洗い直す

#感想
もうすぐテストなので、明日あたりにテスト用まとめ記事を1本書いて復習しよう。
特にCSSはあやふやな理解のまま放置している箇所が多い…。
あと先週金曜のノートがひどすぎて我ながら引く。
デザインの勉強が全然進んでないのもやばい。
まだ始まったばかりだけど焦りが無限に生まれてくるので、
今やるべきことを見極めて取捨選択しよう。
2/14 授業ノート

#お話
・自分が習ったこと、できること、やったことを出来る限り日本語で書き出す
　(リストアップして説明できるようにする)
　→実際説明しようとすると何をどこまでできます、と話すのがとても難しい＝理解不足

#今日習ったこと
**SEOについて**
・検索エンジンはCSSまで読んでいる→読みにくいHTML/CSSを使うと上位表示されない
　ex:)文字の大きさが小さすぎる、リンクとリンクの間が空いていないなど

**CSSの記述**
・1w=16px
・1.5w=24px→20px
・2w=32px→30px
h1タグ→pタグの倍の大きさが初期値
・文字の共通とユニークについて
　共通→h2,p{…}
　ユニーク→p{…}

・line-heightの考え方について
　→line-heightは文字の大きさ+上下の余白のことである。
・emについて
　→16px≒1em(1文字分)。
　ex:)padding: 10px 1.0rem 8px;→10px(上) 1.0rem(左右) 8px(下)という余白を空ける
　・emを使うメリット
　→em=親要素の大文字の高さ(フォントサイズ)を1emとする単位。
　つまり文字の大きさを変更したいとき、font-sizeを修正すれば自動的にemがそれを拾って調整してくれるため、修正箇所が減る
　ex:)
```h2{
    padding: 10px 1.0em 8px; /* emがfont-sizeの値を反映してpadding(この場合は左右の余白)を自動調整する */
    font-size: 28px;
    text-align: center;
}```

・**class名の命名規則について←まとめきれなかった！**

[HTML]
```<div class="box">
<div class="box box2">```

[CSS]
```.box{
    width: 500px;
    margin: 50px auto;
    padding: 40px;
    background-color: #ccefff;
}
.box2{
    background-color: #ffccf1;
}
.box2>h2{
    background-color: #f02121;
}```

・「index.html」というファイル名はリンクで表示されない
　検索エンジンは子ページは拾わず、index.html文書のみを読み込んで表示する

#感想
今回全然まとめられなかった。
幹ではなく枝葉の情報が多かったから、という感想。
もう少し学習が進めばあの時のあれはそうだったのか！現象が起こると祈ります。
SpringでExitCodeを返す

## よくわからないで始めるとこうなる

Java(Spring)を触って３ヶ月、いろんなことを片手間にやってきたので、ちゃんと理解せず実装している今日この頃です。

SpringBatchでバッチを組んでください、と言われてガリガリとバッチを作りました。
Rundeck上で定期実行させて、エラーがあればSlack通知投げるという、ごく単純なバッチです（SpringBatchでジョブのDB管理しないとか、ちょこちょこ細かい前提はありました）。

で、実装に気を取られガツガツ作っていざジョブスケジューラに載せてみると、上司がサンプルにくれたテンプレートはExitCodeが必ず0で返ってきます。
というのも、もらったテンプレートもそうでしたが、各所にあがっている下記のような記述は、当然っちゃ当然ですが、runしているだけなので、ExitCodeなんてなにもハンドリングしてくれていないみたいです（SpringApplicationが起動するまでに生じたエラー（DB接続できなかったとか）は拾えますが）。

```Application.java
@SpringBootApplication
@RestController
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
```
単純に、エラーだったらExitCodeを0以外で返せればいい。
初めはCommandLineJobRunnerを使おうとしてうまく起動せず(Commandから呼び出すとDataSourceが云々のエラーで進まず。たぶん、jobPathの設定方法を間違えたのだと思います）。
次に苦し紛れにSpringBatchのJobListenerでJobのステータスをみながらSystem.exitを返していたのですが、Job実行時の想定外のエラーなど、Listenerまでたどり着かない処理は当然ExitCode=0になるのです。
ググりまくって出てきた通りにやってみたら、一応のハンドリングはできました。

```Application.java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        var context = SpringApplication.run(Application.class, args);
        System.exit(SpringApplication.exit(context, () -> 0));
    }
}
```

- https://github.com/MariMurotani/SpringDemo/blob/1_withprop/src/main/java/demo/MongExample.java
- https://www.techiedelight.com/shutdown-a-spring-boot-application/

上記が思った挙動かどうか確かめるため、下記２点をなんとなーく中身をみて、なんとなーく確認しました。
（詳細は、時間があるときに読めたら。。。）

## ConfigurableApplicationContext

SpringApplication.runで作成される、アプリケーションの振る舞いが記述されたオブジェクトのようです。
startup/shutdownを外から操作できるようにしてあるインターフェースで、パラメータの設定などのメソッドがありました。
なので、おそらくアプリケーションを終了するときの挙動と結果もここに記載されているのだと思います。

なお、run実行中にエラーになったらIlligalExceptionを返すところが、Spring起動時にエラーならExitCode=0にならない理由だと思われます。


## SpringApplication.exit
ヘッダのコメント
> * Static helper that can be used to exit a {@link SpringApplication} and obtain a
> * code indicating success (0) or otherwise. Does not throw exceptions but should

翻訳
> {@link SpringApplication}を終了し、成功（0）などを示すコードを取得するために使用できる静的ヘルパー。

SpringApplicationのExitCodeを管理するための処理のようです。
ExitCodeGeneratorsではExitCodeのカスタムができます。
- https://www.codeflow.site/ja/article/spring-boot-exit-codes

で、中ではこのExitCodeGeneratorsをつかってExitCodeを作成しています。
何もカスタムしない状態で実行時エラーにすると、generators(SpringApplication.java:Line1290)でgenerator.addAll(beans)したときに登録されるJobExecutionExitCodeGeneratorが実行時エラーをキャッチしてExitCodeを返していました。
SpringApplication.java:Line1301でexitCode != 0の場合には、contextからExitCodeEventを発行してくれて、これが実行したシステム側に返ってくるようです。

JobExecutionExitCodeGeneratorは、JobExecution単位でもっているので、Job単位にExitCodeをキャッチしてくれているようです。
ちゃんとStepでFailになっていればエラーを履いてくれるはず！

## 最後に

ものすごく大雑把な理解ですが、JobExecutionごとのエラーをキャッチしてExitCodeを出力しているようです。
afterStepで、Success以外はFailにする処理をいれているため、Stepが失敗して入れば、Jobもエラーとして判断できるようになりました。
いったん、動けばいいからこんなもので！

ご指摘があればコメントいただけるとありがたいです！！
機械学習アンサンブル・ランダムフォレストの仕組み

###ランダムフォレストとは
「決定木」と呼ばれる判定モデルを沢山作って、それぞれの決定木で予測結果を出し、その多数決により最終的にどれに分類されるのかを判定するモデルです。決定木を作る度にデータの中からランダムに特徴量を選んでいくことから、ランダムフォレストと言われます。

決定木はデータセットに対して質問を繰り返して、うまく分類できるように作ります。その中でどういう質問をすれば正解の精度が高くなるか、アルゴリズムの中で工夫されています。

###アンサンブルの効果
複数のモデルを組み合わせて学習することを、アンサンブル学習といいます。ランダムフォレストは決定木で多数決を取るアンサンブル学習です。一つのモデルのみで判断するよりも精度がよくなることが知られています。

今から２値分類でのランダムフォレストを考えます。ランダムフォレストでの$n$個の個々の決定木の正解率は全て$p$であったとします。このとき、ランダムフォレストでの正解率はどうなるか考えてみます。

個々の決定木に確率変数$X_{i}(i=1,2,3,..,n)$を対応させて考えます。$X_{i}$は$i$番目の決定木で、正解したら(確率$p$で)$1$、不正解なら(確率$1-p$で)$0$を取るとします。そうすると、各$X_{i}$はパラメータ$p$のベルヌーイ分布に従います。さらに
$$S_n:=\sum_{i=1}^{n}X_{i}$$
のように和をとると、ベルヌーイ分布の性質により$S_n$はパラメータ$n$と$p$の二項分布に従います。一方、ランダムフォレストでは多数決なので、各$X_i$で正解である$1$の方が過半数を取ればいいことになり、$S$で言えば$\frac{n}{2}$より大きくなればランダムフォレストとして正解します。よってランダムフォレストでの正解率は
$$
P(S_n>\frac{n}{2})
$$
で表せます。

◆それでは具体的な数値を入れて効果を見てみます。

例１：$p=0.6,n=50$とします
⇒$S_n$はパラメータ$50$と$0.6$の二項分布に従い、正解率$P(S_{50}>25)$は二項分布の上側累積確率となり、小数点第２位までとして計算すると$0.90$となります。$0.6$よりかなり正解率が上がったことが分かります。単独の決定木の精度が良くなくても、その組み合わせであるランダムフォレストでは正解率の向上が見込めます。

例２：$p=0.6,n=100$とします
⇒$S_n$はパラメータ$100$と$0.6$の二項分布に従い、正解率$P(S_{100}>50)$は二項分布の上側累積確率となり、$0.97$となります。

例３：$p=0.7,n=50$とします
⇒$S_n$はパラメータ$50$と$0.7$の二項分布に従い、正解率$P(S_{50}>25)$は二項分布の上側累積確率となり、$0.99$となります。

個々の正解率$p$が高くなるほど、また$n$が大きくなるほどランダムフォレストの正解率は高くなりました。この$n$は木の数であり、ランダムフォレストのハイパーパラメータです。$n$を大きくすれば精度は良くなりやすいですが、計算量が増えます。

また、精度が良くなりすぎると過学習に注意が必要です。データ全体の中から学習に使うデータを選んでモデルを作っていきますが、精度が良すぎるということは、その学習データにのみ沿ったモデルになりやすいということです。そのため、学習データ以外には合わないモデルに成りえます。

機械学習では、学習データとテストデータの組み合わせを変えて平均的に評価する方法（クロスバリデーション）などを駆使して、他のデータがきても正解率を維持できるようにすることが一般的な手法として知られています。
SnowflakeのManaged Access Schemaを使う

# SnowflakeのManaged Access Schemaとは

snowflakeはDWH。https://www.snowflake.com/

Managed Access SchemaはSchemaのOWNERにSchema内のオブジェクトの権限を管理させるもの。
通常TableやViewなどSchema内のオブジェクト作成すると、作成者がOWNERとなりそのオブジェクトに対してのGrant権限を持つが、このSchemaではオブジェクトのOWNERでもGrant権限を持つことはできない。
良くある運用ケースではSchemaの管理者とは別に、利用者がそのSchema以下のTableやViewの作成を好きにやって良いということがある。ただし、他の利用者には好き勝手に権限を付与しないで欲しいという時に使える。

細かいアクセスコントロールについてはsnowflakeのドキュメントを参照
https://docs.snowflake.net/manuals/user-guide/security-access-control-configure.html#creating-managed-access-schemas

# Managed Access Schemaの作成方法
https://docs.snowflake.net/manuals/sql-reference/sql/create-schema.html#create-schema
`WITH MANAGED ACCESS` を付けるだけ

```sql

CREATE [ OR REPLACE ] [ TRANSIENT ] SCHEMA [ IF NOT EXISTS ] <name>
  [ CLONE <source_schema>
        [ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ] ]
  [ WITH MANAGED ACCESS ]
```
# 作成例

スキーマ管理者側の操作

```sql
use database testdb;
-- managed_testスキーマを作成
create schema managed_test with managed access;
-- managed_testスキーマのALL権限をtest_roleに対して付与
grant all on schema managed_test to test_role;
```

スキーマ利用者(テーブル作成)側の操作

```sql
use database testdb;
use schema managed_test;
-- table作成
create table aa_table (kkk string , rrr string);
-- table確認
select TABLE_SCHEMA, TABLE_NAME, TABLE_OWNER from information_schema.tables where TABLE_SCHEMA= 'MANAGED_TEST';
-- information_schemaのselect結果
-- Row TABLE_SCHEMA TABLE_NAME TABLE_OWNER
-- 1 MANAGED_TEST AA_TABLE TEST_ROLE

-- aa_tableの権限付与
grant select on table aa_table to sysadmin;
SQL execution error: Not authorized in a managed access schema. Use the schema owner role or a role with the MANAGE GRANTS privilege.
```

information_schemaの値は大文字でしかヒットしないので注意です。
iPhoneにプッシュ通知をしたかっただけなのに


## プッシュ通知したかった

普段は社内用のシステム開発を担当してます。
ある日「社内のメンバーが気づけるように、内部向けの通知機能を開発して欲しい」という要望をいただきました。
・・・頑張ります！ということでWebとAndroidにはFCMからプッシュ通知できるようにして解決しました！！！！！！！！

・・・と思ったらおやおや？iPhoneでも受け取りたい？
いやいや、一筋縄ではいかないのですよ。
iPhoneはわがままなので、APNsで証明書を発行した端末でしか通知を受け取れないんですよ；；；；
と半泣きになったので、代替え案をたくさん調べたのでメモに残しておきます。


## Slackで通知？

- 通知したくなったらSlackでお知らせしてあげる方法です

### メリット

- 追加の費用を発生させずに通知を送ることができます
- 全デバイスに対応可能で開発工数も極小です
- 新たにアプリのインストール作業が不要です

### デメリット

- 気づけないから嫌だと言われました
- 大量に通知を流す都合上、Slackのrate limitで送信が制限される可能性があります
- 明確な基準はないが、公式によると秒間1通で短時間ならバースト可能程度の記載がありました
- 現在の運用上、Slackでメンションがあっても気づかないパターンがあります
- ユーザが増減する度に個人Slackチャンネルを追加・削除した上でシステム上で作業する管理・運用工数が発生します

## ネイティブアプリを開発して限定配布？

- 通知を受け取るためだけのネイティブアプリを開発する方法です（FCM→受信用アプリ）
- 審査を通さなければどんなアプリでも良いよね、という発想w

### メリット

- 通信制限にかかる恐れがないです
- 利用ユーザが増えても月額の費用がほぼブレない
- 将来的な機能拡張が見込めます

### デメリット

- 限定配布するため、100台までか、Apple の Enterprise 登録する必要があります
- iPhoneはアプリのインストール作業が必要です


## メールアプリの受信設定で通知？

- iPhoneにデフォルトでインストールされている連絡帳アプリとメールアプリでVIP設定をしておくと、特定のアドレスからの受信時だけ端末にプッシュ通知を飛ばすことができます（SMS）

https://support.apple.com/ja-jp/guide/mail/mail40589/mac

### メリット

- メールの機能が使えるようになるので、通知の種類がたくさんある場合は分類分けして集計することが可能です

### デメリット

- 送信用のドメインを管理する必要があります
- フィルターをかけたり設定をうまくしないと、受信箱が大変なことになります
- プッシュ通知を押したら指定のURLに飛ばす、といったことはできません


## IFTTTアプリ？

IFTTTというサービスとサービスを連携してくれるサービスのwebhookでNotificationを発動させるイベントを作成する方法です。もしWebhookを叩かれたら、URLKeyを指定した端末にプッシュ通知してーというイベントを作成すると通知させることができます

https://www.digitaltrends.com/cool-tech/what-is-ifttt-and-how-does-it-work/


### メリット

- 無料で何通でもプッシュ通知を送信できます
- 実際に、1日で1500通飛ばしてみたんですが問題ありませんでした

### デメリット

- 100通を一斉送信すると、途中の60件以降が届かないことがあってエラーにもなってないから不思議？ってことがありました→特にエラーは出ないため、連続で何通も確実に届けたい時は不向きかも
- IFTTTアプリをダウンロードする必要があります
- 以前は作成したイベントをシェアする機能がありましたが、数年前からなくなってしまったので、「WebhookがきたらNotificationを発動させる」というイベントの設定を、プッシュを受け取りたい全員が設定する必要があります

## 外部サービスの利用？

### メリット

本業に専念できます

### デメリット

- お高い。月額50,000円や、通数によって〜50万件：39800円などと料金が変動するプランのサービスもありました。まとまっているサイトを発見しました。これ以外にもたくさんサービスがあるみたいです。https://liskul.com/push-notification-25520
- 内製化したい場合は不向きです

## SMSで通知っぽく見せかける？

### メリット

- 全デバイスで対応可能です
- アプリのインストール作業が不要です

### デメリット

- 1通が高い！AWSの場合で見ると1通訳10円くらい→https://aws.amazon.com/jp/sns/sms-pricing/

```
Softbank Mobile Corp / 440 000        $0.08575
Softbank Mobile Corp / 441 001        $0.09792
```


iPhoneにプッシュ通知送るだけなのにこんなに大変なんて思ってませんでした；
最終的にどうするかはまだ決まっていないので、引き続き頑張ります＞＜
セキュリティマネジメントの勉強ーセキュリティ管理

#情報セキュリティマネジメント
組織のセキュリティ確保のため体系的に取り組むこと

##情報セキュリティ管理
なにをどのように守るのか企業や組織として明確にしておく
そのために情報セキュリティポリシとして明文化する

##情報の洗い出し
情報資産です
・物理的資産・・・装置
・ソフトウェア資産・・・開発ツールなど
・人的資産・・・経験や技能
・無形資産・・・組織のイメージや評判
・サービス資産・・・通信や計算処理サービスなど
・直接的情報資産・・・DBやメールなど

これは情報資産台帳にまとめておく

##情報セキュリティインシデント
情報セキュリティを脅かす事件や事故
インシデントとだけいうこともある
発生したときの報告・管理体制が明確で、インシデント対応方法が文書化されていて
関係者に周知徹底されていることが求められる

##情報セキュリティ事象
インシデントの他に、発生するかもしれない状況のこと
要はヒヤリハットかな
ウイルス対策ソフト入れてないとかね
そういうの見つけたら管理者に報告する義務があるらしい

##セキュリティマネジメントの監視とレビュー
放置してもダメなので日常的に監視する

#情報セキュリティ諸規定
情報セキュリティポリシに関する文書は方針、対策基準、実施手順、手続き、規定など

##構成
###情報セキュリティ方針（基本方針）
組織の基本的な考え方と方針を示す
経営陣によって承認される
秘密にせず、全従業員や関係者に公表する

###情報セキュリティ対策基準
リスクアセスメントの結果に基づいて対策基準を決める
（※リスク特定、分析、評価を網羅するプロセス全体のこと）

####規定
代表的な規定は如何の通り
* 情報管理規定
* 秘密情報管理規定
* 情報セキュリティインシデント対応規定
* 情報セキュリティ教育の規定
* プライバシーポリシ[^1]
* 雇用契約、職務規定、罰則の規定
* 対外説明の規定
* 例外の規定
* 規則更新の規定
* 規定の承認手続き
* ソーシャルメディアガイドライン

[^1]: プライバシポリシじゃないの？一貫性が・・・

##個人情報とプライバシーポリシ
個人情報とは、氏名、住所、メルアドなど
それ単体、もしくは組み合わせるコトで個人を特定できる情報のコト
プライバシーポリシは収集した個人情報をどう扱うかを定義したもので
個人情報保護方針ともいう
GASのV8では [JavaObject] が [Object] になる

# 概要
GAS で V8ランタイムが使えるようになった件について：[(V8 Runtime Overview)](https://developers.google.com/apps-script/guides/v8-runtime)

[G Suite Services](https://developers.google.com/apps-script/reference) の FoobarApp 系オブジェクトは
```Object.prototype.toString.call()``` でタイプ名を取得すると
従来の Rhino では ```[object JavaObject]``` が返ってきましたが・・・

V8ランタイムに切り替えると ```[object Object]``` になります。

# 確認
```javascript
function foo(){
  var objects = {
    calendar : CalendarApp.getDefaultCalendar(),
    folder   : DriveApp.getFolderById( 'root' ),
    file     : DriveApp.createFile( 'test', '' ),
    document : DocumentApp.create( 'test' ),
    spread   : SpreadsheetApp.create( 'test' )
  }
  
  for ( item in objects ){
    console.log( item + ' : ' 
      + Object.prototype.toString.call( objects[ item ] ) );
  }
  /*
  --- Rhino ---
  calendar : [object JavaObject]
  folder : [object JavaObject]
  file : [object JavaObject]
  document : [object JavaObject]
  spread : [object JavaObject]

  --- V8 ---
  calendar : [object Object]
  folder : [object Object]
  file : [object Object]
  document : [object Object]
  spread : [object Object]
  */
}
```

# 影響
```[object Object]``` になることで、従来使えなかったメソッドが使えたりします。
例えばプロパティ名の列挙に使う ```Object.getOwnPropertyNames()```：

```javascript
function bar(){
  var obj = CalendarApp.getDefaultCalendar();
  console.log( Object.getOwnPropertyNames( obj ).length );
  /*
  --- Rhino ---
  TypeError: オブジェクト型の引数が必要ですが、object 型が返されました。
                         ↑ 何言ってんのお前
  --- V8 ---
  28.0
  */
}
```

# 注意
型名チェックに ```=== '[object JavaObject]'``` などとやっている場合は
挙動が変わるので修正が必要です。

# その他
従来の Rhino から V8 へ切り替える為のポイントがまとめられていますが
この件についてはどこにも記載を見つけられませんでした。少なくとも今は。

[Migrating scripts to the V8 runtime](https://developers.google.com/apps-script/guides/v8-runtime/migration)
[(Qiita) GASがV8エンジンに対応したのでドキュメント読んだ](https://qiita.com/UtaMori/items/ce83672cecca20964899)


以上
php + ajax でDBからデータを取得・出力するためのちょっとした話

# 概要
案件で、2000ぐらいのファイルをそれぞれダウンロードするサイトを制作しました。
クライアントからDB仕様指示はないので、静的htmlで制作することも可でしたが、量が多すぎるのでDBを使用にすることに至りました。
DBを使った案件は初めてで(WPを除く)、PHPもWPのテーマ作成ぐらいしか実戦経験がなかったので、キツかった。。。
振り返りを兼ねての自分メモで。
DBはMySQLでphpMyAdminを使用しています。

# 仕様
目的：
製品サイト内にて、製品の資料ファイルをダウンロードする。サイト自体は1ページです。
サイトを上下に2分割した際に、上に製品カテゴリのナビがあり、選択したカテゴリのダウンロードリンクを搭載した下にテーブルが表示される。
上で選択したアイテムをパラメータとして渡すことで、下のテーブルをajaxで動的に出力します。

# Ajax
「エイジャックス」派です。
基本的な書き方はこんな感じでしょうか。

```js:ajax.js
$(function() {
 $('.btn').on('click', function() {
  $.ajax({
   url: ('path/to/file.php'), // ajax通信をするファイル
   type: 'GET', // GET or POST
   data: { f: $(this).value(); },　// パラメータとして渡す値の指定
   dataType: 'html', // 今回は直接htmlを出力したかったのでhtml。受け取ったデータで更に処理したい場合はjson
   cache: true, // 通信のキャッシュを残すか
   // ajax通信成功
   success: function(data) {
　　// 引数でデータを受け取り
    $('#content').html(data);
   },
   // ajax通信失敗
   error: function() {
    console.log('fail');
   }
  });
 });
});
```
コードの意図としては、ボタンをクリックした際にajax通信を行う。押したボタン`button`の`value`を取得しパラメータ`f`として`path/to/file.php`に渡します。
一連の流れが成功すれば、`#content`に`html`を出力します。ボタンを押すたびにhtmlを動的に書き換えることができます。
`data`の取得方法がよくわからず苦戦しました。他にフォームであれば、`inputの値`などを指定します。

ちなみにナウい書き方だとこんな感じ

```ajax_new.js
$(function() {
 $('.btn').on('click', function() {
  $.ajax({
   // options 略
  }).then(
   function(data) {
    // success
    console.log(data)
   },
   function() {
    // fail 
    console.log('error');
   }
  );
 });
});
```

# PHP
ajax通信時の設定を行う。

```php:connect.php
// DB settings
$host = 'localhost';
$dbname = 'dbname';
$dbusr = 'dbusr';
$dbpass = 'dbpass';

//↑ settingsからDBに接続する
try {
  // 成功
  $dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);
} catch (PDOException $e) {
  // 失敗
  var_dump('データベース接続失敗' . $e->getMessage());
  exit;
}

// SQL実行準備
$stmt = $dbh->prepare("SELECT * FROM table");
// SQL実行
$stmt->execute();

// 受け取りデータを配列に格納
$dataList = array();

// あらかじめ作成した配列にwhuileで格納する
// FETCH_ASSOCで連想配列化する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
  $productList[] = array(
   'id' => $row['id'];
   'name' => $row['name'];
  );
}

// XSS対策
function hsc($str){
  return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

// htmlをそのままechoするので以下指定。Content-typeは適宜変更
header('Content-type:text/plain; charset=utf8');

// urlパラメータ「p」のGETが実行されているか
if (isset($_GET['p'])) {
 // パラメータを受け取ったら変数化  
 $format = $_GET['p'];

 // ここでhtml出力します
 echo '通信成功です！';
}
```

ひとまず完成して動いたので、営業にテストアップ報告を行ったのですが
まだまだわからないことが多い。。。
can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)の解決方法

rbenvで複数のrubyバージョンが存在する時に、bundle installを行うと、以下のエラーが発生。

```
can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
```
該当するrubyのバージョンを再インストールするも状況は改善されず。

いろいろと探した結果、bundlerのバージョンとGemfile.lock側のbundlerのバージョンが異なることで発生していたようなので、

```

$ gem install bundler -v 該当バージョン
```

これで、バージョンの相違を解消してあげればOK。
【Android】Adaptive Launcher Icon の作り方と注意点

Androidでは、GooglePlayストアアイコンとは別に、デバイス側で使うアプリアイコンも作成する必要があります。
Android 8.0（API レベル 26）でアダプティブランチャーアイコンが導入されました。

これがまたやっかいで、過去OSにも対応したい場合、新旧の2パターンのアダプティブアイコンを作成しなければなりません。
新旧で仕様が全く異なるのでその作成方法をメモしておきます。アイコンを作成する際の参考になれば嬉しいです。

【2/17追記】
コメントを頂いて初めて知ったのですが、アダプティブランチャーアイコンを作成するための機能がなんとAndroidStudioに元からあるとの情報を頂きました。
なんてこったい、次はこのツールで是非作成してみたいと思います（感謝！）
https://developer.android.com/studio/write/image-asset-studio.html?hl=ja#access

#アダプティブランチャーアイコンの仕組み

![adaptive_icon_img.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486362/f59b02ae-fc50-f38f-f0fe-6ff8fb9a9438.jpeg)


Adaptive Launcher iconは、foreground、background画像と、その上にMaskがかかった３枚構成となっています。
backgroundはエンジニア側でカラーを設定し、マスクは自動でかかるので、デザイナーは基本真ん中の**Foreground**の画像を作成すればOKです。

#アダプティブランチャーアイコンの作り方

![adaptive icon rule copy.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486362/78590549-486e-1fb4-76a1-bb58a084b6d5.jpeg)

１：108pxの正方形透明レイヤーを作成する
２：72pｘの正方形オブジェクトを1のレイヤーの上に重ねる
３：直径66ｐｘの正円オブジェクトを作成し2の上に重ねる
４：アイコンを正円内に配置する（丸内が表示保証されているエリア）
５：2と3のレイヤーを非表示にし、アイコンが表示された状態で1の正方形を書き出し設定する


**・foregroundの画像は直径66dpの範囲外はアニメーションで隠れる可能性がある**
**・マスクはランチャー次第で正円形から四角まで色々ある**

####【注意点】
Risky zoneはマスクによっては範囲に含まれるので、**外周にデザインがある場合は72dpまでデザインを入れること。**そうしないとやり直すことになるので要注意！


###用意する画像サイズ
Adaptive Launcher Iconを作る時に必要な画像サイズは下記の通り。
「背面」も「前面」も画像の場合は各サイズ2つずつ作成する。
「背面」はbackground-colorで指定することも可能なので、背景がベタ塗りの場合は、Foregroundの画像を各サイズ1つずつ用意すればOK。

| 解像度       |       比率 |    Adaptive Launcher icon(px)    |
|:-----------------|------------------:|:------------------:|
| mdpi             |             1 |        108×108      |
| hdpi             |           1.5 |       162×162       |
| xhdpi            |             2 |        216×216      |
| xxhdpi           |             3 |        324×324      |
| xxxhdpi          |             4 |       432×432       |

ファイル名：ic_launcher_foreground.png

[Google Developers公式サイトはこちら](https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive?hl=ja)

#レガシーランチャーアイコンの作り方(おまけ）

![98_03__ランチャーアイコン copy 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486362/b363b3f7-e93e-e919-a3f2-bb814892a4ca.jpeg)

**・書き出し画像サイズ:48dp×48dp**
**・inner size:44dp (上下左右に2dpずつの余白をとる)**

###用意する画像サイズ

| 解像度       |       比率 |    Adaptive icon(px)    |
|:-----------------|------------------:|:------------------:|
| mdpi             |             1 |        48×48      |
| hdpi             |           1.5 |       72×72       |
| xhdpi            |             2 |        96×96      |
| xxhdpi           |             3 |        144×144      |
| xxxhdpi          |             4 |       192×192       |

ファイル名：ic_launcher.png

###参考サイト
Google Developers▼
https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive

ソースコードなどのご参照▼
https://qiita.com/takahirom/items/696fb5ecaa230fa8f755

GooglePlayStoreのアイコンの仕様はこちら▼
https://developer.android.com/google-play/resources/icon-design-specifications

#おわりに
Adaptive Launcher Iconが追加されて表現は自由になったものの、まだ旧アイコンにも対応しないといけない場合、期間限定のアイコンなどを作成するのが意外と大変だということがわかりました。

今後ここらへんが統一されていけば、もう少し楽になるのではと期待しています。

以上、Adaptive iconで苦戦したkannaでした！
なぜかid列がinteger型になっているRailsのテーブルをserial型に変更する手順

## 困っていたこと

ローカル環境で`rails db:migrate`を実行すると、何もマイグレーションを適用していないテーブルに以下のようなdiffが発生しました。（RDBMSはPostgreSQLです）

```diff
-create_table "brands", id: :serial, force: :cascade do |t|
+create_table "brands", id: :integer, default: nil, force: :cascade do |t|
```

原因を探ってみると、本来serial型であるべきid列のデータ型がただのinteger型になっているのが原因でした。（以下はRubyMineが生成したDDL文で確認した結果）

```sql
-- serial型なら正しい
create table brands
(
  id serial not null
    constraint brands_pkey
      primary key,

-- integer型なのはおかしい
create table brands
(
  id integer not null
    constraint brands_pkey
      primary key,
```

`rails dbconsole`（または`raild db`）で`\d some_table`のようにして確認するのもありです。

serial型になっている場合（sequenceが設定されている）↓

```
\d brands
                                        Table "public.brands"
      Column      |            Type             |                      Modifiers                      
------------------+-----------------------------+-----------------------------------------------------
 id               | integer                     | not null default nextval('brands_id_seq'::regclass)
```

integer型になっている場合（sequenceが設定されていない）↓

```
\d brands
                         Table "public.brands"
      Column      |            Type             |       Modifiers       
------------------+-----------------------------+-----------------------
 id               | integer                     | not null
```

なぜinteger型になっていたのかは僕もよくわかりません。
が、integer型のままでは困るので以下の手順で修正しました。

## 修正手順

### 1. 本当にserial型で正しいか確認する

念のため本番環境のデータ型を確認するなどして、本当にそのテーブルのid列がserial型でいいのかどうか確認してください。
（本番環境もinteger型だったりしたら、そっちが正になってしまいます）

### 2. DBのバックアップを取る

作業に失敗したときにそなえてDBのバックアップ（ダンプ）を取っておきます。

```console
$ pg_dump your_app_development > your_app.dump
```

作業に失敗したときは以下のコマンドでリストアします。

```console
$ psql -h localhost -d your_app_development < your_app.dump
```

### 3. 「次のid値」を確認する

`rails dbconsole`で対象テーブルの「次のid値」を確認します。

```sql
SELECT MAX(id)+1 FROM brands;
 ?column? 
----------
        7
(1 row)
```

### 4. sequenceを設定する（＝serial型に変更する）

そのまま続けて対象テーブルのid列にsequenceを設定し、dbconsoleを終了します。

```sql
-- 7は上で取得した「次のid値」
CREATE SEQUENCE brands_id_seq MINVALUE 7;
ALTER TABLE brands ALTER id SET DEFAULT nextval('brands_id_seq');
ALTER SEQUENCE brands_id_seq OWNED BY brands.id;

-- dbconsole（psql）を終了
\q
```

### 5. 動作確認

`rails db:migrate`を実行し、`schema.rb`が変更されなければ修正完了です。

もし`rails db:migrate`実行後にまだ以下のようなdiffが発生するようであれば、serial型に変更できていません。

```diff
-create_table "brands", id: :serial, force: :cascade do |t|
+create_table "brands", id: :integer, default: nil, force: :cascade do |t|
```

念のため、Rails上から対象のモデルを新しく作成したあとに正しいidが設定されていることを確認します。

```
# sandboxモードでrails consoleを起動
$ rails c --sandbox
> brand = Brands.new(...)
> brand.save!
> brand.id #=> 7が返ってくればOK
```

## 参考文献

- [postgresql \- Changing primary key int type to serial \- Stack Overflow](https://stackoverflow.com/questions/23578427/changing-primary-key-int-type-to-serial)
プロジェクト・ファセット Java バージョン 13 はサポートされません。となった時の対応方法

- 環境
    - Windows10 Pro 64bit バージョン1903
    - Eclipse Version: 2019-12 (4.14.0)
    - Tomcat 9.0.31
    - プロジェクトのJava 13.0.2

# 事象 : EclipseでTomcat9を設定中にプロジェクトを選択したら怒られた
新規にTomcat9を追加した時のこと・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/cbc3e9a8-393c-768d-3c59-85e141ede8de.png)

# 原因 : Tomcat9のJREのバージョンがプロジェクトと違うから
今回は、JRE11になっていました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/4a34fedf-cfd9-a91e-d99a-7095b77f8d78.png)

## 対応 : Tomcat9のJREをプロジェクトに合わせる
1. [ランタイム環境の構成...]リンクからダイアログを表示する
2. [Tomcat9]を選択して[編集]ボタンでダイアログを表示する
3. JREからJava13を選択する
4. 後で間違えないように[名前]を「Tomcat9 (Java13)」に変更して[完了]ボタンでダイアログを閉じる
1. [適用して閉じる]ボタンでダイアログを閉じる
2. [次へ] > プロジェクトを追加 > [完了]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/b48aa1d1-a148-ac45-efa8-c0efa6750d70.png)
【CSS】様々なドットの実装方法 Dotted

## 様々なドットの実装方法 Dotted

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="sa-nitawaki" data-slug-hash="oNXxaWg" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="oNXxaWg">
  <span>See the Pen <a href="https://codepen.io/sa-nitawaki/pen/oNXxaWg">
  oNXxaWg</a> by Satoshi Nitawaki (<a href="https://codepen.io/sa-nitawaki">@sa-nitawaki</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
社内向け　Kubernetes Hands On(第１回 Pod編)

# Kubernetes Hands On(第１回)

## Podの考え方

Podとは大まかに
Containerの集合体と考えることが出来ます。
簡単に考えると、
docker-composeで作成されるContainer群がPodだと考えることが可能です。

では、実際にPodを作成してみましょう。

```yaml:pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: demo
  labels:
    name: demo
spec:
  selector:
    matchLabels:
      app: demo
  containers:
    - name: demo
      image: ncsnozominishinohara/demo:v1
      resources: {}
      ports:
        - containerPort: 80
```

解説

### apiVersion

kubernetesのバージョンによって使用できる値は変わります。
kubernetesの所属しているAPIGROUPによって書き方が異なります。
- 特定のApiGroupに属している場合・・・ `apiVersion: ApiGroup/ApiVersion`
- 特定のApiGroupに属していない場合(CoreGroupに属している)・・・ `apiVersion: ApiVersion`
対応しているApiGroupの調べ方は以下のコマンドを実行することで確認出来ます。(v1.17.2)

`kubectl api-resource`

### kind

どのオブジェクトであるかを設定します。
今回であれば`kind: Pod`を指定しているため、
`Podオブジェクト`が作成されます。

### metadata

このオブジェクトのメタ情報を設定します。

`name: 任意の命名(後に他のkindオブジェクトで指定される値)`
`labels: 任意の命名が可能(但し制限もあるため、公式を参考に)`

### spec

オブジェクトの仕様を表します。

- containers
    - name     
    Pod名
    - image  
    使用するコンテナイメージ名
    - resources  
    CPU/メモリ等を設定
    - ports
        - containerPort  
        コンテナ内からExposeされるポート番号

## デプロイ方法

`kubectl apply -f pod.yaml`
npm run tscした時にnpm ERR! missing script: tscと出た時の対処法

## 現象
typescriptの環境構築をやっていたら`npm ERR! missing script: tsc`というエラーが出た

## 解決策
package.jsonの中にある記述を下記のように変更

```package.json

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "tsc": "tsc"  //この行を追加
  },
```

tscはtypescriptのコンパイラを示しています。

意外と単純なところで引っかかることもあるんですね。
abc155参戦レポ

## A

地味に実装が面倒臭かった。解説を聞いて反例を取り除けば実装が簡単そう。私はCounterを使った。

```python
from collections import Counter
a = Counter(map(int,input().split()))
if 2 in a.values():
    print("Yes")
else:
    print("No")

```

## B
入力数の上限的に実装はそこまで難しくない。if文を一つにまとめられるようになりたい。

```python
N = int(input())
A = list(map(int,input().split()))
for a in A:
    if a % 2 == 1:
        continue
    if a % 3 != 0 and a % 5 != 0:
        print("DENIED")
        exit()
print("APPROVED")

```

## C
もっとも出現回数が多い回数を変数に保存。その後ソートした文字列のうち、maxの回数と一致するもののみを表示。

```python

from collections import Counter
N = int(input())
S = Counter(input() for _ in range(N))
S = S.most_common()
most_count = S[0][1]
S.sort()
for i in range(len(S)):
    if S[i][1] == most_count:
        print(S[i][0])
```

## D
問題文を見て嫌な予感がしたので、順位表へ。ほとんどの人がDよりもEを優先して解いていたのでスキップ

## E
Dを飛ばしたは良いが実装できず。これは良くない。