OmniAICreator/Qiita-1.07M huggingface dataset:
Kubernetes: CronJob で Secrets を使う

CronJob で認証付きの WebAPI を叩きたい。Secrets に秘匿情報を入れて、それを環境変数として参照するのが良さそうということでやってみた。

まず、`key=value` の形式でファイルを作る。

```sh
$ cat > env-secrets.txt
USER=hoge
PASSWORD=fugafuga
```

`kubectl create secret generic <名前> --from-env-file <filename>` で登録する。

```sh
$ kubectl create secret generic secrets-sample --from-env-file env-secrets.txt
secret/secrets-sample created
```

これを `secretRef` で参照すると、そのまま環境変数として参照できるようになる

```yaml:secretstest.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: secretstest
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: busybox
            image: busybox
            envFrom:
            - secretRef:
                name: secrets-sample
            args:
            - /bin/sh
            - -c
            - echo $USER; echo $PASSWORD
          restartPolicy: OnFailure
```

```sh
$ kubectl apply -f secretstest.yaml
$ kubectl get pods  # 実行されるまで最大1分待つ
NAME                           READY   STATUS      RESTARTS   AGE
secretstest-1234567890-ababa   0/1     Completed   0          10s
$ kubectl logs secretstest-1234567890-ababa
hoge
fugafuga
```


## 後片付け

```sh
$ rm env-secrets.txt
$ kubectl delete cronjob secretstest
$ kubectl delete secrets secrets-sample
```

## 参考
https://cloud.google.com/kubernetes-engine/docs/concepts/secret?hl=ja
Vue-Routerの異なる呼び出し方のメモ

## その①

vueのコンポーネントをimportしてからルーティングを指定する

```
import Home from './components/Home.vue';

export const routes = [
     {
         path: '/',
         component: Home,
     },
];
```

## その②

component: 以降にrequireをつけ、componentのパスまで指定して書く

 ```
export const routes = [
    {
      path: '/home',
      component: require('./components/Home.vue'),
      name: 'home'
    }
];
```

SPAを構築するには、
シングルページとして登録するvueファイルを呼び出しroutesという変数に入れてexportする必要があるよということですね！
ビジネスサイドにシステム開発の常識が全然通じなくてワロタ

## はじめに
[モチベーションクラウドシリーズ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/mcs)の9日目担当の柴田です。

ぼくは、[チームワーククラウド](https://www.motivation-cloud.com/teamwork-cloud/)という製品のプロダクトマネージャーをやっています。

さて、プロダクトマネージャーという職業柄、ビジネスサイドと開発サイドを接続するコミュニケーションも大事な仕事の1つです。ただ、そのなかで、以下のことで苦労することが多くあります。

###「ビジネスサイドにシステム開発の常識が通じない！」

というものです。

弊社に限らず多くの企業において、営業やコンサルタントなど現場のビジネスサイドの方と開発サイドでは、求められる知識や経験が当然異なっています。したがって、ぼくら開発側が常識だと思っていることが、まったく理解されないといった場面は多々発生します。

ただ、そのまま自分たちの尺度を押し付けてしまうと、関係性が悪化しがちです。本来はお互いに協力関係であるべきところを、「アイツラには話が通じない」と溝を深め、現場と開発が対立するという残念な状況になりかねません。

ここで大事なのは、**ギャップからではなく、共有できる部分に目を向ける**ということです。

異なる領域の人たちがコミュニケーションをすると、「あれも通じない」「これも知らない」と両者が交わらない部分ばかりが気になります。ただ、それよりは「これはお互いが理解できる」という部分をまず見つけるべきです。すぐに見つからない場合は、新たに共通の基準やゴールをつくってもよいでしょう。

と言われても、具体例がないとイメージできないですよね？

では、ぼくの経験したケースにおいて、どのようなときに「システム開発の常識」が通じず、それをどんなやり方で「共通の常識」を見出していったか、それぞれ解説していきます！

## ケース１：システム用語は知っておくべきという常識

まずは、言葉が伝わらないというものです。

例えば、「製品デモをする環境が使えないんですけど」という現場からの問い合わせに対し、「stagingはいまdeploy中なんで、productionのmigration環境ならsandbox的に使っていいですよ」といった回答しても、相手には１ミリも通じません。ルー大柴と思われます。

では、現場の人たちにシステム用語の知識がまったく不要かといえば、そんなことはありません。というのも、顧客に聞かれたら回答しないといけない場面は多くあるからです。

したがって、システム用語も自分たちの常識を押しつけるのではなく、「顧客が使ってくる用語」をベースに共通のリテラシーを設けるとよいでしょう。さらに、FAQや用語集なんかを作っておくと喜ばれますし、何度も同じ説明を繰り返さなくて済むようになります。

**⇒対策：顧客が使う用語をベースに、FAQや用語集をつくろう！**

## ケース2：不具合はすぐには直らないという常識

システム開発に一度でも関わっていると、単に「不具合を直す」とうものがいかに大変なものか、その「システム開発の常識」はよくご存知だと思います。ごく単純なプロセスに分解しても、少なくとも以下のステップを踏む必要がありますよね。

再現調査 ⇒ 原因特定　⇒　影響調査　⇒　コード修正　⇒　テスト　⇒　リリース

ただ、そのプロセスは自身で体験しないと、上記のステップがイメージできません。不具合を見つけたら、以下で直ると捉えています。

直す　⇒　出す

したがって、不具合をなぜすぐに直さないのか、と現場は「常識的」に思うわけです。

これは、不具合を修正することに対するトレードオフが伝わっていないことが、現場と開発の認識齟齬を生み出しています。

人によっては、システムの不具合を、単なる誤字脱字のようなミスと思っている人も少なくありません。そこには、不具合を修正することによる開発工数への圧迫や、デグレ発生のリスクなど、システム開発全体への影響という観点を持ちあわせていないわけです。

したがって、不具合を「ミス」ではなく、「ビジネス上の課題」として扱って、共通の「ビジネスの常識」にしたがってコミュニケーションすることを心がけましょう。そうすると、その課題の解決が、ビジネス全体にトレードオフで影響を与えるというのは、とても自然な考え方になります。

システム開発が特殊な営みではなく、一般的なビジネス活動そのものであるという前提で話したほうが、同じ目線で議論ができるようになるはずです。

**⇒対策：システム開発を、トレードオフが存在する一般的なビジネス活動と同じものとして話そう！**


## ケース3：時間が経っても、すべての課題は解決されないという常識

確かにSaaSはローンチしてからもどんどんアップデートを行い、機能は追加され、UXも改善されていきます。

ただ、その表層上の印象で、「使いづらい」「機能が足りない」「不具合が多い」などシステムに対するあるゆる課題は、時間さえ経てばすべて解決していくはずと思われがちです。

「時間をかけても解決しづらい課題がある」あるいは「時間が経つにつれ、もっと複雑化する課題が多くある」というシステム開発の闇は、なかなかビジネスサイドの人たちには理解されづらいものがあります。

つまり、あんなにたくさんのお金を投じて開発してきたソフトウェアが、「資産」になることはあっても、まさか多くの「負債」を抱えることになっていたとは、夢にも思わないわけです。こうして書くと、たしかに非常識な気もします。。。

だからこそ、システム側だけでは「時間をかけても、解決しづらい課題」であることを理解してもらったうえで、開発以外のチームも巻き込んで問題を解決していくことが非常に大切です。つまり、システムの資産の部分も負債の部分も、みんなで抱えていくという発想を持つべきです。

例えば、営業には顧客の期待値を調整してもらったり、カスタマーサクセスには現行機能の範囲での推奨運用で誘導してもらったり、サポートで不具合の回避方法を案内してもらったり、などいくらでもやり方はあります。

システムの課題は、チームの課題です。自分たちだけで抱え込まず、バリューチェーン全体で解決していきましょう。

**⇒対策：課題はみんなで解決しよう！**

## まとめ

言葉が違う、常識が違う、バックボーンが違う。

そんなのは大した差異ではありません。きちんと共通部分を見出して歩み寄れば、これらは適切にすり合わせることができます。

もっとも大切なのは、バリューチェーンに関わる全員が同じゴールを見ていることです。実現したい世界観、ユーザーに届けたい価値など、それさえ一致していれば、どんな問題も組織で解決することができます。

目線があえば、それぞれの「異なる常識」も理解が深まってきます。もちろん、完全にはわかりえない部分があっても、そこは互いの専門性として任せるというリスペクトが生まれます。

このようなビジネスサイドとエンジニアサイドが相互信頼しあうチームワークこそが、企業やサービスにおける競争力の源泉となっていくはずです！

みんな、仲良くしましょう！

以上です。ありがとうございました。
【PHP】変数のスコープのお話

#関数の内部から、グローバルスコープの変数へアクセスすることはできない。#
まずは、このコードをご覧ください。

```php
$a = 0;
function hoge () {
    $a++; // Undefined variable: a
}

hoge();
echo $a; // 0
```

期待した動作としては、関数の中で変数`$a`の値をインクリメントして、1増えた値を出力してくれるものでした。
どうして期待とは異なった動作をしたのでしょうか。

それは、関数の中と外で変数のスコープが異なることに原因があります。

通常、関数の外側で定義された変数は**グローバルスコープ**となり、関数の内部で定義された変数は、**ローカルスコープ**となります。
（ちなみに、PHPにブロックスコープはありません）

```php
// グローバルスコープ
$a = 0; 
function hoge () {
    // ローカルスコープ
    $a++;
}
//グローバルスコープ
hoge();
echo $a;
```
しかし、特に他の言語を学んだことのある方なら、グローバルスコープとローカルスコープの関係について、このようなイメージをお持ちではないでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496565/12082501-7b33-d8d2-1f91-566e2fa787f8.png)

グローバルスコープからローカルスコープへのアクセスは禁止されているけれど、ローカルスコープはグローバルスコープの一部なので、グローバル変数も使用可能、といった感じです。

しかし、実際にはこんなだいたいこんなイメージだと思ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496565/ba2ec28f-fa65-8abd-01ca-23a612f3c5e1.png)

そもそも、お互いに離れているので、通常はアクセスすることができないといった感じです。

通常は、引数として渡してやるのが一般的です。

```php

$a = 0; 
function hoge ($a) {
    $a++;
}

hoge();
echo $a; // 0
```

エラーはでなくなりましたが、以前出力される値は0のままです。
これは、関数に変数を渡すときは、変数そのものを受け渡しているのではなく、変数の中身をコピーして渡している(**値渡し**)からです。

変数そのものを渡す(**参照渡し**)ときには、`&`をつけてあげます。

```php

$a = 0; 
function hoge (&$a) {
    $a++; // グローバルスコープの変数と同じもの
}

hoge();
echo $a; // 1
```

また、あまり使われませんが変数の前に`global`と宣言することで、引数として渡さなくても関数の内部からグローバル変数へアクセスすることが可能です。

```php

$a = 0; 
function hoge () {
    global $a; // 明示的にグローバルな変数にアクセスする
    $a++; 
}

hoge();
echo $a; // 1
```
話は少々横道にそれますが、PHPには**スーパーグローバル変数**というものがあります。
スーパーとついているだけあって、この変数はグローバルスコープだろうがローカルスコープだろうが、どんな場所でもアクセスすることが可能です。

```php

$a = 0; 
function hoge () {
    // これはグローバルスコープに現在定義されているすべての変数への参照を含む連想配列
    $GLOBALS['a']++;

    // これらもグローバススコープの一種
    $_GET['address'];
    $_POST['address'];
}

hoge();
echo $a; // 1
```

#無名関数の内部から外の変数を使う#
無名関数の内部で、親のスコープから変数を引き継ぐ場合には、`use`を使います。

```php
<?php

$array = ['APPLE', 'LEMON', 'BANANA'];
$case_insensitive = true;

$red_fruits = array_filter($array, function($value) use($case_insensitive) {
	if ($case_insensitive) {
		$value = mb_strtolower($value);
	}
	return $value === 'apple';
});

print_r($red_fruits);
// Array ( [0] => APPLE )
```

これは、先程の例のように、グローバルスコープの変数にアクセスする場合とは、違うことに注意しましょう。

```php
<?php
$array = ['APPLE', 'LEMON', 'BANANA'];
$case_insensitive = true;

function func($array) {
	$case_insensitive = false;

	$red_fruits = array_filter($array, function($value) use($case_insensitive) {
		if ($case_insensitive) {
			$value = mb_strtolower($value);
		}
		return $value === 'apple'
	});

    print_r($red_fruits);
}
func($array);
// Array ( )
```

無名関数を関数の中に閉じ込めてあげると、先程とはことなり、そのスコープ内の変数を取り込んでいることがわかります。
グローバルスコープの変数は使われておりません。
ブログにGitHub issuesを使うコメントシステムutterancを設置する

基本的には[utteranc.es](https://utteranc.es/)にアクセスして、GitHubにアプリをインストールします。

https://github.com/utterance/utterances

そして、コメントを載せたい場所にコードを貼り付ければOKです。

```html
<script src="https://utteranc.es/client.js"
        repo="[ENTER REPO HERE]"
        issue-term="pathname"
        theme="github-light"
        crossorigin="anonymous"
        async>
</script>
```

コメントは指定したリポジトリのissuesに投稿されます。なお、リポジトリのissueは有効にしておいてください。
hugoでその日の記事がビルドされない問題を回避する

hugoは、その日の記事がビルドされない問題があります。その回避法です。

```toml:config.toml
[frontmatter]
date  = [":filename", ":default"]
```

ファイルは`content/post/2019-12-09-test.md`(その日の日付)とします。

```md:content/post/2019-12-09-test.md
date = "2019-12-09T08:00:00JST"
```

## hugoでその日の記事がビルドされない問題

これは、UTCがデフォルトになっているためだと思いますが、hugoでは、通常、`.Date.Local`を使っても、その日の記事がビルドされない問題があります。


```html:layout/_default/list.html
{{ dateFormat "2006-01-02T15:04:05JST" .Date.Local }}
```

そこで、dateをファイル名から取得する方法に切り替えると、回避できます。
Ionic4(ionic/angular)でnem2-sdkを動かした話

どうも @scrpgilです。
突然ですが、半年以上前から、私はある問題を抱えていました。
それは、Ionic4(ionic/angular)の環境でnem2-sdkが動かないという問題です。nem2-sdkとはNEMという暗号通貨を扱いやすくするためのモジュールです。私は、個人プロダクトに、NEMを使うことがおおいんですが、Ionic4にアップグレードしてからnem2-sdkが動かなくなってしまっていたので、途方にくれてました。

しかしながら、昨日、Ionic4の環境でnem2-sdkを動かす方法がわかったので、その知見をまとめておきます。

＊NEMとは
余談ですが、NEMは、暗号通貨を扱うためのIFをAPIとして公開しており、もっぱらWeb開発やってる人でも扱いやすい暗号通過ですので、ブロックチェーンに興味がある方は是非、触ってみてください。


## 結論
次のリンクのプロジェクトを参考にしてください。
`ionic start` でblankで作成したプロジェクトでnem2-sdkを動かせるようにしたものを、GitHubにアップしています。
https://github.com/scrpgil/ionic4-angular8-nem2-sdk


これは、@44uk_i3 さんが、Angularでnem2-sdkを動かせるリポジトリをアップしていたので、それを参考にしたものです。本家は、Angular8とnem2-sdkの組み合わせですが、Ionic4(ionic/angular)にも応用できます。
https://github.com/44uk/ng2-with-nem-sample

変更したソースコード、patchsフォルダについては、`patch-package`をググってみてください。
今回初めて使ったけど、便利。

## 問題点：なぜnem2-sdkは動かないのか？
そもそも、Ionic3の時代は動いていました。なぜ、Ionic4(ionic/angular)で動かなくなったかというと、ずばり、Angular8に上がったことによるWebpackの設定のせいです。

Ionic3の時代は、Ionicチームが作成した@ionic/app-scriptのWebpackの設定を利用していました。その時の設定では、nodeモジュールで利用するが、ブラウザで利用しないモジュールは、空のモジュールを利用するようにしていました。

```javascript
   // Some libraries import Node modules but don't use them in the browser. 
   // Tell Webpack to provide empty mocks for them so importing them works. 
   node: { 
     fs: 'empty', 
     net: 'empty', 
     tls: 'empty' 
   }
```

[ソースコードのリンク](https://github.com/ionic-team/ionic-app-scripts/blob/53fc341daaafac5ddee61e9008b7ed749f1060c2/config/webpack.config.js#L104)

この設定が、Angular8の@angular-devkit/build-angularでは見当たりません。そのため、ビルド時（ionic serveのとき）にエラーが発生するのでした。
<img width="1644" alt="Screen Shot 2019-12-09 at 3.47.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165335/b88d0216-9a44-91c6-81eb-fd9f3fc83814.png">


正直、なぜこの設定が@angular-devkit/build-angularにないのかは、まだ調べきれていませんが、 react-scriptsにも同様の記載があり、この内容を拝借して、@angular-devkit/build-angularのWebpackの設定に追記すれば、無事利用することができました。

[react-scriptsのソースコードのリンク](https://github.com/facebook/create-react-app/blob/58b4738a490f9643f540e9fdb74431c4d73e3ad7/packages/react-scripts/config/webpack.config.js#L723)

## 自分の学びまとめ
これで、nem2-sdkを使えるようになりました。また、今までなんとなく使っていたWebpackを書き換える方法、それを、patch-packageを使って、Gitで管理できることを学びました。

今後、Webpack周りを強化したいので、patch-packageを使ってガンガン触っていきたいと思います。
それでは。
ヘッダーのページ名を簡単に設定する

どうもこんばんは、みかんです。

**！！！！とつぜんですがたいせつなおしらせ！！！！**

2020年1月27日
App Maker の提供終了に向けた対応のご案内
https://support.google.com/a/answer/9682494?p=am_announcement&visit_id=637157414793613981-426262357&rd=1


??!???!?!?!???!?

残念ながら2021年1月19日には終了してしまうそうです(涙)
移行先はAppSheetかApp EngineかGoogleフォームだそうです・・・

消すのは忍びないので記事は残して置きますが、何かの間違いじゃ無い限り役に立つことはないでしょう・・・


**！！！！おしらせはおわりです！！！！！**

今回は「ヘッダーのページ名を簡単に設定する」方法を書いてみます。
下記ステップでやっていきます。

* 1 下準備
* 2 Starter Appの動作確認をしてみる
* 3 新しいページを追加してみる
* 4 トリックの確認
* 5 (小ネタ) ログインユーザーのメールアドレスを表示する

# 1 下準備

今回はStarter Appをいじる形で解説します。
とりあえず新しくアプリを作りましょう。

|![gif001-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/8ae587ec-5aa6-3d5b-3cf3-f1870b899f4d.gif)|
|:-:|

# 2 Starter Appの動作確認をしてみる

Starter Appには既に2枚の画面が用意されています。
どう動くか、Previewで見てみましょう。

|![gif002-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/cf31bccd-e6e4-6116-b1c7-37a4c8bc8baf.gif)|
|:-:|

ヘッダー左上のタイトルが、ページを切り替えると変わっていることがわかると思います。

# 3 新しいページを追加してみる

新しいページを追加してみます。
ページを追加する時、ヘッダーなどがそのままあってほしい場合は、既にあるページからduplicateして作ったほうが楽です。
作成後、名前を変えて、previewしてみます。

|![gif003-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/a1e9a619-bd85-af20-7cba-186211794f2f.gif)|
|:-:|

これもページ名がキチンと変わっていますね。

# 4 トリックの確認

では、ネタバレに進みます。

表示されている名前こそ、各画面の名前ですが、パーツとしてはヘッダーの要素になります。
ということでヘッダーの該当箇所を見てみましょう。

|![ap001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/e7fed3d4-a7a1-c476-5aa0-010d2ab60224.png)|
|:-:|


`@displayName` と表示されていますね。
これはデータバインディングです。
さらに設定を深堀りすると、`currentPage`というプロパティに属している値だということがわかります。

|![ap002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/3b14beb1-b748-4a47-e0e8-344234d6a901.png)|
|:-:|

設定をそのまま読むと、「現在のページのdisplayNameを参照する」となります。

各ページのトップレベルのプロパティを確認してみると、displayNameという項目があることがわかります。
ヘッダーの左上に置いてあるラベルは、常にこのdisplayNameを参照しているというわけです。

|![ap003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/2adbce2d-3e2c-0844-7ff5-6002f49535bc.png)|
|:-:|

このようなトリックがあるおかげで、ヘッダーの設定一つで、各ページごとにページ名を設定したラベルを置く手間が省かれています。

# 5 (小ネタ) ログインユーザーのメールアドレスを表示する

Starter Appのヘッダーで気になるポイントがあると思います。
それは右端のメールアドレス部分です。一見ログインユーザーのアドレスが表示されそうなものですが、previewしてみると表示されていません。
設定を見るとベタ書きされています。
(サイズに応じて表示/非表示がかかるCSSトリックが仕掛けられているので、少し横に伸ばさないとラベルが出てきません)

|![ap004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/55f40ec3-ab7f-f965-2bc9-011be6221dd1.png)|
|:-:|

これをログインユーザーのアドレスにするのは簡単です。
currentPageと同じように、`user`というプロパティがあるので、その子要素のemailをバインディングしてあげるだけで完了です。

|![gif004-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/03962e95-a4ab-64bb-1b83-5965512fb170.gif)|
|:-:|

|![gif005-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/df7553a5-ae61-801a-2707-b277f7b6c0c4.gif)|
|:-:|


なぜこれが設定されていないかは定かではありません。
また、同じノリでユーザーの画像も設定できるのでは？という気分になりますがそれはAPIを叩いてURLを引っ張る必要があり、少々面倒です。

データバインディングは、　モデルとUIをつなげてくれるものという印象が強いですが、App Makerはモデル以外にも参照できる情報を持っています。今回のような、現在のページやログインしているユーザーの情報などですね。使い方次第では、今回のように設定箇所を削減できるパターンもありますので、色々と試してみることをおすすめします。

以上です。良いApp Makerライフを!
可読性なぞ捨てた！言語"brainfuck"

#what the F!
なんか面白い言語を見つけたので書こうと思います。他に理由はないです。以上。
名前からして「何を言ってるんだ？」と思われるでしょうが、brainfuckはプログラミング言語の一種であり、難解プログラミング言語"esolang"と呼ばれるモノの一つだそうで、お察しの通り実用性はありません。
esolangってなんだそれって思ったら、冗談言語と呼ばれるもので、wikipedia先生によると

>ハッカーの間では嗜み

ah....right?

#what the specification!
さて仕様の説明とまいりましょう。
brainfuckは(実質)長さ無制限の配列が１つ用意され、ポインタによって配列を操作していきます。
用意されている命令は８個のみであり、すべての命令は１文字で表されます。明らかに可読性を捨てている

|文字|動作|C言語|
|---|---|---|
|>|ポインタを１進める|ptr++|
|<|ポインタを１戻す|ptr--|
|+|ポインタが示す要素を１増やす|*ptr++|
|-|ポインタが示す要素を１減らす|*ptr--|
|.|ポインタが示す要素を出力|putchar(*ptr)|
|,|入力された値をポインタの示す要素へ入れる|*ptr=getchar()|
|[|ポインタが示す要素の値が0ならば、対応する"]"までジャンプする|while(*ptr){|
|]|対応する"["までジャンプする|}|

以上。
#HOW TO DO THIS?
実行環境を整えて見ましょう。Windows?知らん

`$brew install brainfuck`

以上。

#THIS IS HELL WORLD?
とりあえずhello worldをしてみましょう

>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.


実行結果は以下の通り

Hello World!

初見で読める人はまずいないであろうこのコード。

#START FROM EASY ONE

"H"のASCIIコードは"72"なので

>+++++++++[<++++++++>-]<.

これでHが出力される。「は？」って言われるだろうからもう少し詳しく解説すると

>+++++++++
[<++++++++>-]
<.

１行目の`>+++++++++`は配列[1]に移動した後、9回要素をインクリメントしている。
２桁目の`[<++++++++>-]`は配列[0]に移動し、8回要素をインクリメントした後、配列[1]に移動してデクリメント
ここまでで感のいい諸君はお気づきだろうが、つまりは

for(int i=9; !i ;i--){
  for(int j=8; !j ;j--){
    *ptr++;
  }
}

これと全く同じなのである。

#SRY BRO...
力尽きたのでこの先は後程書きます・・・
HTMLでテーブルを使って表を作成してみた



```
<!DOCTYPE html>
<html lang="ja">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Document</title>
</head>

<body>
	<!-- ここからテーブル（お仕事） -->
	<table>
		<caption>仕事メニュー一覧
			<details>
				<summary>列の構成</summary>
				<p>仕事メニュー一覧化した表。
					<br>1列目が出来ること、2列目が詳細、3列目が価格</p>
			</details>
		</caption>

		<thead>
			<tr>
				<th scope="col">出来ること</th>
				<th scope="col">詳細</th>
				<th scope="col">価格</th>
			</tr>
		</thead>
		
		<tfoot>
			<tr>
				<td colspan="3">2099年1月1日の日本</td>

			</tr>
		</tfoot>

		<tbody>
			<tr>
				<th scope="row" rowspan="2" >残飯処理</th>
				<td>あなたの食べ残しを私が食べます。</td>
				<td>500円～</td>
			</tr>
			<tr>

				<td>あなたの犬の食べ残しを私が食べます。</td>
				<td>500円～</td>
			</tr>
			<tr>
				<th scope="row">週2回のゴミ捨て</th>
				<td>あなたの家のゴミ捨てを代行します</td>
				<td>600円～</td>
			</tr>
			<tr>
				<th>犬の散歩</th>
				<td>あなたのワンちゃんと散歩します</td>
				<td>1000円/1h</td>
			</tr>
		</tbody>

	</table>
	<!-- ここまでテーブル -->
</body>

</html>
```
ABC147

[ABC147](https://atcoder.jp/contests/abc147)に参加しました。

自分が時間内に解けた問題プラス１問書きます。

##  A問題
標準入出力と足し算とif使うだけ

```python
a1, a2, a3 = (int(i) for i in input().split())

if(a1 + a2 + a3 > 21):
    print("bust")
    exit()
print("win")
```

## B問題
Pythonでは文字列の後ろからi番目を`s[-i]`とかで指定できることを知っていれば、あとは文字列の頭と尻尾から違う文字になっているものを数えて行くだけ。

```python
s = input()

length = len(s)
ans = 0
for i in range(int(length/2)):
    if(s[i] != s[-1*i-1]):
        ans += 1
print(ans)
```
時間内で解けたのはここまででした。
C問題はbit全探索をすればいいのはわかったが、判定処理を無駄に難しく考えてしまって、書けなかった。

## C問題
「正直者」と「不親切な人」の全パターンが高々$2^{15} = 32768$通りしかないので全探索できます。
ここでの全探索はYES/NOの選択など状態が$2^n$ある二値変数のパターンを全て列挙するのに使えるbit全探索ってやつですね。
bit全探索について詳しくは[こちら](https://qiita.com/gogotealove/items/11f9e83218926211083a)が参考になるかと。

ちなみに、実行制限時間内に、全探索できるかできないかの判断はfor文なりwhile文がどれくらい回るかを考えれば大体わかって、[こちらのブログ](https://cppx.hatenablog.com/entry/2017/08/06/104144)によるとAtCoderの実行制限時間2秒では、$10^7$程度が限度ということなので今回は問題なく全探索できる！

```python
n = int(input())
a = []
x = [[] for i in range(n)]
y = [[] for i in range(n)]
for i in range(n):
    a.append(int(input()))
    for j in range(a[i]):
        xx, yy = (int(i) for i in input().split())
        x[i].append(xx)
        y[i].append(yy)

testimony = [[2]*n for i in range(n)]

for i in range(n):
    for j in range(a[i]):
        if(y[i][j] == 1):
            testimony[i][x[i][j]-1] = 1
        elif(y[i][j] == 0):
            testimony[i][x[i][j]-1] = 0

ans = 0
for i in range(2**n):
    bit_list = []
    for j in range(n):
        if ((i >> j) & 1):
            bit_list.append(1)
        else:
            bit_list.append(0)
    flag = 1
    for k in range(n):
        if(bit_list[k] == 1):
            for l in range(n):
                if(testimony[k][l] != 2):
                    if(testimony[k][l] != bit_list[l]):
                        flag = 0
                        break
    if(flag == 1):
        ans = max(sum(bit_list), ans)
print(ans)
```

ある「正直者」と「不親切な人」のパターンに対して、正直者である人が証言していることが今の「正直者」と「不親切な人」パターンと食い違っていないかをチェックして、食い違っていなければ正直者の人数を数える。
その最大値が答え。

という流れですね。

## 今回のコンテストの感想
最近はC問題までは安定して解けていて、D問題が解けたり解けなかったりという感じだったので
C問題が解けないと言うのは久々だった、、、非常に悔しい。
次回は頑張りたい。
dockerで立てたMySQLコンテナに外部から接続できずにハマった時の話

## 概要
dockerを触り始めてMySQLのコンテナを立ててみたものの、Macのターミナルから接続できずに結構ハマった話。似たような事象に陥ってる人が、もしこれで解消できる人がいればと思い記事にしました。

## 結論
コンテナの3306ポートをEXPOSEしていなかった。docker runで-Pオプションを付けて実行すると上手く接続できた。

```bash:before
$ docker run -d --name test-db -e MYSQL_ROOT_PASSWORD=password mysql/mysql-server
```

```bash:after
$ docker run -d --name test-db -e MYSQL_ROOT_PASSWORD=password -P --expose=3306 mysql/mysql-server
```


## 経緯とか

### 症状
作成したdockerコンテナに対して、Macのターミナルからmysqlコマンドで入ろうとしても、以下の通りエラー

```bash
$ mysql -h 127.0.0.1 -u user -p
Enter password: 
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (61)
```

エラー内容的にそもそもIPアドレスがわからないと言われている。
ネットで上手く接続できている人たちの記事を見ると、docker ps時のPORTSに```0.0.0.0```があることに気がつく。というわけで、以下の記事を参考にEXPOSEしてみた。

[MySQLに外部接続できない時のチェックポイント](https://web.plus-idea.net/on/docker-web-server-access-denied/)


```bash:EXPOSEする前
$ docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                       PORTS                                               NAMES
35b706562745        mysql/mysql-server   "/entrypoint.sh mysq…"   About an hour ago   Up About an hour (healthy)   3306/tcp, 33060/tcp                                 test-db
```

```bash:EXPOSEした後
$ docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                       PORTS                                               NAMES
42a9d040091a        mysql/mysql-server   "/entrypoint.sh mysq…"   14 minutes ago      Up 14 minutes (healthy)      0.0.0.0:3306->3306/tcp, 0.0.0.0:32772->33060/tcp    test-db
```

EXPOSE後のPORTS欄を見ると```0.0.0.0:3306->3306/tcp```となっており、ローカルホストから接続できていることがわかる。

コピペで適当に作業していると何かあったときにハマりますね...
AWS UltraWarm 詳細解説

re:invent 2019 で発表された Elasticsearch service の新しいデータノード **UltraWarm** について解説していきたいと思います。
ですが、[AWS New Blog](https://aws.amazon.com/jp/blogs/aws/announcing-ultrawarm-preview-for-amazon-elasticsearch-service/) に書いてあることをここで書いてもしょうがないので、 Chalk Talk [^1]で仕入れてきた、ブログには載っていない情報も書いておきます。

## UltraWarm とは
とはいえ基本的なことは書いておきます。
UltraWarmは 巨大なサイズのログ解析を低コストで可能とする、新しいタイプのデータノードです。
下記に UltraWarm の特徴を書いていきます。

### 低コスト
UltraWarm はいわゆるウォームストレージと呼ばれるものです。
アクセス頻度の低いデータを保管コストの安いストレージに保存することで、コスト削減を測ります。
UltraWarm はウォームストレージとしてS3にデータを保管します。これにより90%程度のコスト削減を図ることの出来る、画期的なデータノードであるわけです。
UltraWarm データノードは二つのストレージティアをもっており、アクセス頻度の低いデータをS3へ自動的に移動するようです。

### 高可用性
ストレージティアーにS3を選択することで、低コスト化と同時に高い可用性を実現しました。
その可用性はつまりS3と同じ、99.99%となります。

### 高速アクセス
Nitro System をフル活用することで、既存のデータノードに引けを取らないどころか、それ以上に高速なデータアクセスを可能としているようです。

## FAQ
Chalk Talk セッションが開かれた時にはすでにブログに情報は上がっていました。
よって下記FAQの内容はブログには載っていないものです。

### Q: 既存のデータノードを使う理由はあるの？
A: ありません。
もちろんプレビュー段階で対応している Elasticsearch のバージョンが6.8なので、それ以上を使うのであればそもそも UltraWarm は使えないのですが。
開発者曰く、現状使っているD2インスタンスはコストも高く、データノードしては不適格であると認識していたそうです。
よって UltraWarm が利用できるようになったのであれば、これを使わないという選択肢はありません。
とはいえデータが1TBにおさまるようならば、D2ノードで運用した場合と値段が変わらないらしいです。
ですが UltraWarm を使うデメリットはないので、使っておけば間違いないでしょう。

### Q: なんで現状のESでサポートする7.1には対応しないの？
A: GA(General Availability)ではないから。
ようは安定版じゃないからってことですね。つまり7系のGAでてからじゃないと、 UltraWarm 対応はないってことです。

### Q: １つの UltraWarm データノードでサポートされるデータサイズは？
A: medium だと1.5TB、 large だと2TBとなるようです。
S3の容量が無制限とはいえ、インデックスサイズ等の理由で最大のデータサイズがあるようです。

### Q: S3に移動されるデータの基準は？
A: ７日間アクセスがなかったデータ。
言い換えると７日間検索の対象にならなかったデータは、７日間で自動的にS3へ移動されるようです。

## 参考
[AWS Blog のアナウンス記事](https://aws.amazon.com/jp/blogs/aws/announcing-ultrawarm-preview-for-amazon-elasticsearch-service/)

## おまけ; Chalk Talk について
今回は ~~会社の金で~~ re:invent へ行ってきたわけですが、英語力に自信があるならば Chalk Talk はおすすめです。
上記のようにサービスの詳細な仕様を、公開できる範囲で説明してくれます。特に制約などの話です。
リリース記事ではわざわざネガティブな制約については書いてくれないので、導入を検討するのならば制約については抑えておく必要があります。
2020の参加を考えているあなたの re:invent をより良いものにしたいのであれば、是非とも Chalk Talk へ行ってみましょう。

[^1]: 開発者やプロダクトマネージャーと直接会話して、サービスの詳細を質問、利用方法を議論できるタイプのセッション 。
Linux が ブートしないとき (grub > で止まる）

ふと久しぶりに再起動したら黒い画面に `grub >` と表示されて起動しませんでした。

* 手動で起動する場合にRootデバイスが不明でした（忘れていた）
* そういえばこのディスクはGPTでした

久しぶりなことは色々忘れていてとっさに何をして良いのかわからなくなるのでQiitaにメモ代わりに書いておくことにします。2度あることは3度ある。

## 最終的に入力したコマンド

```
set root=(hd1,gpt2)
insmod gzio
insmod part_gpt
insmod ext2
linux	/boot/vmlinuz-5.3.0-23-generic root=UUID=4d128010-4e97-4343-9eb1-e082ae9d7e0e ro
initrd	/boot/initrd.img-5.3.0-23-generic
boot
```

## メモ
* rootディスクは `ls (hd1` で \<tab\> すれば中身が表示されるのでなんとなくわかるはず。または `ls (hd1,gpt2)/` で中身が表示されるので 色々Linuxのファイルシステムっぽいのが見れればそれが当たり。
* UUIDで指定する。最近のLinuxはUUIDで指定しているのでよくググるとでてくる /dev/sda みたいな感じになっていなことが多い。Bootの段階だと blkid とか使えないのですがこれは単純に `(hd1,gpt2)/etc/fstab` にあるので表示させるとわかる
* 今回のように gptとかだと insmod でカーネルモジュール呼び出す必要が合ったりするのだがこれはそれぞれ違うと思うので確認したい場合には、 `(hd1,gpt2)/boot/grub/grub.cfg` などをあたると実行コマンドが記載されているケースもあるので手がかりになる。私の場合には `insmod part_gpt` する必要があるのを気が付かず何度も device not found 的なエラー で kernel panic になっていた。

## Boot loader の再導入？

何度色々やっても `grub >` だったんだけど、結局PCのブートディスクでLinuxが入っているディスクのEFIからBootしないようにいつの間にか設定されていた？順番を整理したらGrubメニューが表示されました。原因は不明です。

* grub-install  の実施
* [grub-customizer](https://launchpad.net/grub-customizer)を利用してMBRを上書き


## 補足
実際のディスク構成

```
/dev/nvme0n1p1: UUID="FB8D-BB2F" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="32eef918-d013-4098-94aa-fe46df5ef080"
/dev/nvme0n1p2: UUID="4d128010-4e97-4343-9eb1-e082ae9d7e0e" TYPE="ext4" PARTUUID="01b3c925-4a71-484d-b243-0b438acd9a3e"
/dev/sda1: LABEL="ESP" UUID="DE11-B257" TYPE="vfat" PARTUUID="6fd54d60-bd98-4831-91af-c06f8a6fdc00"
/dev/sda3: UUID="01D495160FB2C420" TYPE="ntfs" PARTUUID="dc4664b0-f0f2-4b66-9626-f4238c4030a8"
/dev/sda4: UUID="3692A8F492A8B9AF" TYPE="ntfs" PARTUUID="e1cfede5-ad68-4f5c-81c8-10a36d8559d9"
/dev/sda5: LABEL="WinRE" UUID="01D4955493BD8690" TYPE="ntfs" PARTUUID="7fa07c77-1502-445c-a844-f49878f2c0a6"
```

* 最近は `/dev/sdX` ですら無いのだがこの文字列 `/dev/nvmeX` をよく忘れる
* これ晒していても問題ないよね？
WSLにkubectlコマンドをインストールする

```
sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - 
sudo touch /etc/apt/sources.list.d/kubernetes.list
echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get update && sudo apt-get install -y kubectl
kubectl version
```
AtCoder Beginner Contest 147

https://atcoder.jp/contests/abc147
[解説](https://img.atcoder.jp/abc147/editorial.pdf)
numpyを利用できるかよ！今度注意する。

AとBを書くまでもない。

###C - HonestOrUnkind2

bit全探索で解く。

3
1
2 1
1
1 1
1
2 0
を例としてやりましょう。
n = 3で、全員のH(Honest)(Unkind)状況は、$2^{3}=8$つ可能性がある。
例えば、101は、人1と人3が正直者、人2が不親切者である状況を示す。
ならば正直者の証言に矛盾があるかどうか、それをチェックすればいい。
人1の「人2が1です」証言は、101に矛盾するので、101が不可能であることがわかる。

```python

n = int(input())
lst = []  # 証言list
for _ in range(n):
    a = int(input())
    lst.append([[int(i) for i in input().split()] for _ in range(a)])

m = 0
for i in range(2 ** n):
    a = True  # bin(i)が示す状況をTrueと仮定する。
    for j in range(n):
        if i >> j & 1:
'''
bin(i)のどの位が1か、現時点では私がこれをしか利用できない
101の場合、j=0,2の時条件を満たす(101>>0=1, 101>>1=10, 101>>2=1)
'''
            for x, y in lst[j]:  # 人jの証言をチェックする。ここでlst[0] = [2, 1]
                if (i >> (x - 1) & 1) != y:  # 101>>1&1=0, y=1, 矛盾
                    a = False  # iがだめだ
                    break
'''
011の場合、j=0,1：
j=0: [x,y]=[2,1], 011>>1&1=1, y=1, OK
j=1: [x,y]=[1,1], 011>>0&1=1, y=1, OK
aがTrueのまま
'''
    if a:
        m = max(m, sum(map(int, bin(i)[2:])))
# 011に1が幾つあるか、現時点では私がこれをしか利用できない

print(m)
```

###D - Xor Sum 4

10
3 1 4 1 5 9 2 6 5 3
を例として計算しよう。
3 = 0011
1 = 0001
4 = 0100
1 = 0001
5 = 0101
9 = 1001
2 = 0010
6 = 0110
5 = 0101
3 = 0011
各数字の各bitが、他の数字とN-1回XOR算しなければならない。
XOR算は、
1 xor 1 = 0 xor 0 = 0, 1 xor 0 = 0 xor 1 = 1
です。
1位を見ると、７つ'1'と３つ'0'があることがわかる。
つまり、全部45回のXOR算に、結果の1位が1になったのは21回。
2、3、4位には、別々24回、24回、9回ある。

つまり、最後の結果は、
21 * 1 + 24 * 2 + 24 * 4 + 9 * 8 = 237
です。

よって、

```python

import numpy as np
 
n = int(input())
arr = np.array([int(i) for i in input().split()])
mod = 10 ** 9 + 7
s = 0

for i in range(60):
    c1 = np.count_nonzero(arr & 1) # 自分がnp.sumを利用したがどうしても正解になれなかった。なぜ？
    s += 2 ** i * c1 * (n - c1)
    arr >>= 1

print(s % mod)
```

###E - Balanced Path

自分ができないから他人のコードを拝見し参考した。
https://atcoder.jp/contests/abc147/submissions/8874312

先ずはarrayを作る。

```python

import numpy as np
H, W = map(int, input().split())
lst1 = []
lst2 = []
for _ in range(H):
    lst1.append([int(i) for i in input().split()])
for _ in range(H):
    lst2.append([int(i) for i in input().split()])
arr1, arr2 = np.array(lst1), np.array(lst2)
arr = np.abs(arr1 - arr2)
'''
2 3
1 10 80
80 10 1
1 2 3
4 5 6
を例として、
arr = array([[0, 8, 77], [76, 5, 5]])
'''
```
つぎにbitを使う。
0<=A,B<=80ので、偏りは最大で80(H+W)まで考える必要がある。(by解説、実は80(H+W-1)まででも構わない)

```python

d = [[0] * W for _ in range(H)]
m = 80 * (H + W)  # 400
d[0][0] = 1 << m  # 最初の「位置」
for h in range(H):
    for w in range(W):
        x = arr[h][w]  # 現在地の偏りを取る
        if h > 0:
            d[h][w] |= d[h - 1][w]  # 前回のすべて可能な位置を継承する
        if w > 0:
            d[h][w] |= d[h][w - 1]  # 前回のすべて可能な位置を継承する
        d[h][w] = d[h][w] << x | d[h][w] >> x
'''
今回可能な移動を記録する。
例えば前回の記録は、
00010(0,ここは最初の位置)01000で、
xは2の時、偏りは2と-2の二つ可能性がある。
ならば今回の記録は、
01000(1,ここは最初の位置)00000 | 00000(1,ここは最初の位置)00010
= 01000(1,ここは最初の位置)00010
になる。
これは、「偏りが4,0,-4の３つ可能性がある」を表示する。
最後、d[H - 1][W - 1]がすべて可能な偏りを記録したことがわかる。
'''
x, y= 1 << m, 1 << m  # 最初の「位置」で偏りが0
for i in range(m + 1):  # 最小のx,yを見つけ出す。
    if d[H - 1][W - 1] & x or d[H - 1][W - 1] & y:
        print(i)
        quit()
    x<<=1
    y>>=1
```
最新の Microsoft Information Protection ソリューションによる機密データの保護

# セッション説明

https://tokyo.myignitetour.techcommunity.microsoft.com/sessions/83683

# メモ

- 2016年と比較して2025年までに作成および保存されるデータ量は10倍になる
- データ中心の保護をしないと
- 機密データとビジネス上の重要データを保護、管理するための戦略
  - 機密性の高いデータはどこにありどのように処理しているか
  - 機密性の高い組織内、組織外を移動するときにアクセスを管理できているか
  - データの分類、ラベル付け、保護するためのソリューションを使っているか
- MIPの機能
  - 機密ラベル
    - 情報に合ったラベルを付ける
    - 特性
      - カスタマイズ可能
      - コンテナやファイルのメタデータとして永続化
      - 他システムで読み取り可能
      - ラベルに基づいてDLPポリシーを適用
      - パートナーソリューションへの拡張
    - アプライ
      - 手動または自動での適用
      - コンテナやファイルへの適用
      - 保管中、使用中、転送中のデータへのラベル付け
      - ラベルに基づいた保護アクションの適用
- 情報保護ライフサイクル全体にわたる利害関係者を理解する
  - 色々なロールの人と連携していく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/eafa2528-11e2-9f28-6d9c-a2ed9e6b81f4.png)
    - CISO
      - 理想的なセキュリティを定義する人
    - コンプライアンスオフィサー
      - 理想的なセキュリティを定義する人
    - データ管理者
      - 実際にポリシーを作成する人
      - 理想的なセキュリティを定義する人
    - データ所有者
      - ビジネスの観点で要不要の判断ができる
      - 持っているひとではない
      - ポリシーをチューニングする人
    - ヘルプデスク
      - 技術的に対応する人
      - ポリシーをチューニングする人
    - 利用ユーザー
      - この方たちからのフィードバックが重要
      - ポリシーをチューニングする人
  - 分類の定義
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/4d08ca73-fe84-25cf-25e4-0d186c054d29.png)
  - データセキュリティと生産性のバランス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/74c1d117-2ae1-82ce-3cd8-03bbd1052fc6.png)
  - ポリシーは小さく始めてチューニングしていく
- ベストプラクティス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/47906755-37be-b8fa-07a1-33dbeafb8c7e.png)
- データ保護ストラテジー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/4c11d6fa-bef7-b549-10c6-1cedc74a9f75.png)
  - ラベルをサイバーセキュリティの戦略として用いることもできる
- ソリューション全体で構築する利点
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/ce965f50-f6de-9c02-c32e-939a9585f8c1.png)
  - サービス側で色々な制限をする
- デプロイメント（継続する）
  - ラベルとポリシーの作成を支援したグループ
    - 彼らとコミュニケーションをとりましょう
  - 組織内でチャンピオン、リーダーとインフルエンサーを育成する
  - 監視と分析結果のデータを確認することも重要ですが、実際の利用ユーザーやヘルプデスクの声を直接聞くことも重要です。
  - キープレイヤーやチャンピオンの意見、分析結果などを総合的に踏まえてポリシーを強制するポイントを調整します。
- MIPを使用する利点
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/0a0ad4b9-04e2-bb1f-b4f0-1617da4d1d67.png)
- MIPの始め方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/eb9bb2a7-2782-ea29-ba0d-67fa5591557e.png)
  - AIPを使っている場合は移行作業が必要になる可能性がある
- MIPの原則
  - 統合
  - インテリジェンス
    - 人手を使わないAI
  - 拡張可能
    - SDKで開発
    - パートナーと連携
  - 自動化
  - ユーザー中心
キャラクターライセンスをブロックチェーン管理するメモ

## 背景

キャラクターのライセンス管理をきちんとやりたい

* ロイヤリティ計算の証憑として
  * 税務計算, ライセンス契約で必要 

=> ブロックチェーンでかしこく管理したい

## 既存法律

まず, ブロックチェーンだけでは法律上はあまり効力をもたないので, 既存法律とからめる必要がある.

* 商標権 : 商標の登録
* 著作権 : 著作権登録制度はあるが... あんまり使われていない? http://www.bunka.go.jp/seisaku/chosakuken/seidokaisetsu/toroku_seido/
* 意匠権 : 意匠の登録
* 物権 : グッズなど. 動産譲渡登記制度があるが... http://www.moj.go.jp/MINJI/DOUSANTOUKI/seido.html 
* 電子契約
  * 都度契約締結というのがキャラクター権利者とやりやすくなる.
  * 電子署名 + 日本データ通信協会から認定された事業者から発行されたタイムスタンプが必要
  * タイムスタンプは, ブロックチェーン上のタイムスタンプを使う方が技術上より確実ではあるのだが... 法律で決まっているのでしょうがない 
* ライセンサー : エージェントを立てる, 特別目的会社（SPC)を作る?

## 物品

たとえばキャラクターのステッカーを販売することを考える.

ERC721 などの Non fungible token を発行する.

物体への特殊加工や印刷などの一意識別技術とブロックチェーンの記録(ERC721 トークンなど)を組み合わせることで, ステッカーが本物であることを証明できるとよい.

## 出演料

出演料など, バーチャルなキャラクターの権利を一時的に使うとき.

レンタルトークンで管理とか.

ERC809/1201: Tokenizing Non-fungible Access
https://medium.com/coinmonks/erc809-1201-tokenizing-non-fungible-access-abdc5018c49?

## キャラクターのボイス

画像と同じように音声のハッシュあたりを求め, ERC721 管理.

音声データは JASRAC 的な感じのところに登録して管理するのかしらん?

## その他

エスクローサービスを ETH 上で構築するとか.

ソフトウェア・エスクロウとは?
http://www.softic.or.jp/escrow/
あらゆる XaaS リソースに対応するエンド ツー エンドのクラウド セキュリティ

# セッション説明

https://tokyo.myignitetour.techcommunity.microsoft.com/sessions/83687

# メモ

- 変化とトランスフォーメーションの時代
  - 今やすべての人がテクノロジーに携わる
  - 時代についていけなくなりつつある従来のセキュリティツール
  - セキュリティ専門家だけでは埋められないギャップ
  - 法的な規制とコスト
- インテリジェントセキュリティ
  - AIやクラウドを活用して人に頼らなくても大丈夫なセキュリティを考えている
  - どう実現していくか
	  - IDおよびアクセス管理
	  - 脅威の防御
	  - 情報の保護
	  - クラウドセキュリティ
    - 複数クラウドにまたがる事が当たり前になりその時にどのようなセキュリティが必要か
- データ漏洩を引き起こす様々な露出
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/800bae78-0cb9-3136-1f2d-4cd3eb68108d.png)
- チームとユーザーがクラウドを操作すると発生する問題点
  - ユーザー
	  - ID侵害
	  - データ漏洩
	  - 悪意または事故
  - 開発者
	  - シークレットの漏洩
	  - アプリケーションの脆弱性
	  - オープンソースの脆弱性
  - DevOps
	  - リソースの設定ミス
	  - インフラストラクチャの脆弱性
	  - 解放されたネットワーク
- インフラストラクチャの保護
  - Azure Security Center（CSP）
	  - Platformおよびワークロード全体にわたるセキュリティ態勢
    - セキュリティスコアの提示
      - 問題点を早期に気づいてもらう
      - 是正の対象
	  - ネットワークマップ
    - ネットワークの構成一覧
	  - Just IN Access
    - 時間を指定してアクセス可能にする
	  - アダプティブ ネットワーク ハンドリング
    - NSGをモニタリング
	  - ライセンス
    - 無償
    - スタンダード
	  - AWSも対象として管理できる
  - 開発プロセスの一環としてポリシーの強制ができる
  - クラウドセキュリティ態勢の強化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/70bf3746-1bc9-4701-92c5-4785bc4090ef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/7d1a4afe-3fba-56ae-8063-6f939de39a66.png)
- 脅威からのワークロードの保護
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/840f9bf1-a44c-8870-eedd-e9610295e743.png)
- コンテナーのクラウドワークロード保護
  - コンテナサービスのアドオンを使用可能に
- クラウドでのセキュアアプリの開発・運用
  - セキュアアプリケーションの配送
	  - GitHub
    - 安全なアプリケーションの迅速な構築
    - アプリケーションのすべてのレイヤー保護
	  - GitHubを使用したコードベースの保護
    - エンタープライズプロジェクトの99%が何かのOSSを利用している
      - 色々なツールがある
- 使用の保護
  - Microsoft Cloud App Security
    - ガートナー社の調査でリーダーになった
    - 使用の保護
      - 未承認のアプリ
      - 承認済みのアプリ
      - クラウドの脅威
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/96bb5ddb-90cd-7dad-e66b-9ff9d3ed353d.png)
    - シャドウITの発見と統制
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/229639ec-2bc3-0124-3597-eddc14fadf90.png)
    - データの保護
      - 露出の把握
      - 違反の監視のモニタリング
      - 漏洩回避
    - 複数のクラウドアプリにわたる検出
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/eefb8d7e-c52e-468a-8af8-500629da81e2.png)
    - クラウドプラットフォームの監視（機能強化）
      - GCPとAWSへの対応
        - 条件付きアクセス
    - UEBA
    - いつもと違う端末からWord文書などをダウンロードできないような設定もできる
- クラウドセキュリティ
  - 複数のクラウドにわたるリソースの保護
    - ハイブリッドクラウドインフラストラクチャをASCで保護
    - GitHubおよびAzureを使用したセキュアなアプリケーションのリリース
    - CASを使用してシャドウITを検出クラウドの使用状況を保護
[Golang][競プロ]与えられた1~9の数値4つで任意に2桁の整数を2つ作り、それらの和が最大になる場合の、その和を求める問題について解説

# 問題

**1〜9までの数値が4つ与えられ**、あなたはその4つの数値で、**自由に2桁の整数を2つつくる**とします。
様々な組み合わせがあるかと考えられますが、**2つの2桁の整数を合計したときの、最も大きい値**を調べて下さい。

## 例

**たとえば、`1 2 3 4`という数値を与えられた場合、**「12+34」や「13+24」などさまざまな組み合わせができます。
しかし、合計が最も大きくなるのは、この場合だと「42＋31」であり、その合計は`73`です。
**この場合の答えは`73`として下さい。**

なお、この値は以下のような形で標準入力で渡されることとし、全て同じ値であることもありえるものとします。

```text:与えられる数値の標準入力例1
1 2 3 4
```

```text:与えられる数値の標準入力例1に対しての期待する回答
73
```

↑この場合、42+31= 「73」 が正解になります。

```text:与えられる数値の標準入力例2
9 2 7 5
```

```text:与えられる数値の標準入力例2に対しての期待する回答
167
```

↑この場合、92+75= 「167」 が正解になります。

```text:与えられる数値の標準入力例2
9 9 9 9
```

```text:与えられる数値の標準入力例2に対しての期待する回答
198
```

↑この場合、99+99= 「198」 が正解になります。

# 回答と解説

それでは解説していきます。

## コード

```golang:回答したコード
package main
import "fmt"
func main(){
    
    s := []int{0,0,0,0}
    fmt.Scanf("%d %d %d %d", &s[0], &s[1], &s[2], &s[3])
    
    var 1st, 2nd, 3rd, 4th int
    for _, v := range s {
        if 1st <= v {
            4th = 3rd
            3rd = 2nd
            2nd = 1st
            1st = v
        } else if 2nd <= v {
            4th = 3rd
            3rd = 2nd
            2nd = v
        } else if 3rd <= v {
            4th = 3rd
            3rd = v
        } else {
            4th = v
        }
        
    }
    
    r := 1st * 10 + 3rd + 2nd * 10 + 4th
    fmt.Println(r)   
}
```

## 解説

### 基本的な考え方

今回は、与えられた数値の**組み合わせについてはあまり考えませんでした**。

私が考えたポイントとしては…

- 与えられた数値を、それぞれ**大きい順に認識する**。
- 「最も大きい数値」と「その次に大きい数値」を十の位にする必要があるので、**10倍する**。
- **残りの小さい2つの数値は一の位ということで、そのまま**。（1倍する）
- こうした上で、**全部合計すれば求められている値が出る**。

という感じです。

```golang:解説用にコメント書きまくったコード
package main
import "fmt"
func main(){
    
    s := []int{0,0,0,0} // 標準入力をスライスに格納する形で受け取りたいと考えたので、0が4つ入ったスライス「s」を準備します。

    fmt.Scanf("%d %d %d %d", &s[0], &s[1], &s[2], &s[3]) // ここで標準入力を受け取っています。
    
    var 1st, 2nd, 3rd, 4th int // 最も大きいものからこの変数に入る想定で、1位〜4位までの「席」を準備します。

    for _, v := range s { // 受け取った標準入力をループで回します。
        
        if 1st <= v { // もし渡ってきた数値が、暫定1位にいる値より大きければ…

            4th = 3rd // 3位が4位に、2位が3位に、1位が2位にそれぞれ順位を落とします。
            3rd = 2nd
            2nd = 1st
            1st = v // そして1位の席に、渡ってきた数値が座ります。

        } else if 2nd <= v { // もし渡ってきた数値が、暫定1位よりは小さいけれど、暫定2位より大きければ…

            4th = 3rd // 3位と4位が順位を落とします。
            3rd = 2nd
            2nd = v // そして2位の席に、渡ってきた数値が座ります。

        } else if 3rd <= v {// もし渡ってきた数値が、暫定1位、2位よりは小さいけれど、暫定3位より大きければ…

            4th = 3rd //3位が4位に順位を落とします。
            3rd = v // そして3位の席には、渡ってきた数値が座ります。

        } else { // 最後に、暫定1、2、3位より小さい場合…

            4th = v // 渡ってきた数値は4位確定なので、4位の席に座ります。
        }
        
    }
    
    r := 1st * 10 + 3rd + 2nd * 10 + 4th // 1位と2位は十の位になる必要があるので10倍、3位と4位は一の位で良いので1倍して、全て合計します。

    fmt.Println(r) // 最後に結果を出力しておしまい！
}
```

## さいごに

最後まで読んで頂き、ありがとうございます。
問題の解き方としての考え方は悪くない…と思うのですが、コードのロジックとしてはなんだか微妙な感じもします…
こうした方がもっと効率的だよ！とか、そういった意見があれば、ぜひお気軽にコメントして頂けると嬉しいです！

ありがとうございました！
固有値・固有ベクトルの使いみち（７．同時対角化とブロック化行列）

# はじめに

この記事では、前回の記事[固有値・固有ベクトルの使いみち（６．対角化の一般化と単純・直既約・可約）](https://qiita.com/sasanquaneuf/items/b2f5e98481392136cc73)に続いて、複数の行列の同時対角化、ブロック化を考えます。
ただ、実際に一番内容があるのは、おまけの複素数と転置についての話かもしれません。

# 同時対角化

## 同時対角化はできません（出オチ）

任意の2つの行列が与えられた時、これらを同時対角化する方法を考えましょう...と言いたいところですが、一般には同時対角化をすることはできません。例えば、

$$\left(\begin{matrix}
 0& 1\\\ 
 0& 0\end{matrix}\right), \left(\begin{matrix}
 0& 0\\\ 
 1& 0\end{matrix}\right)$$

という2つの行列が与えられた時、この2つの行列に対して同時に固有ベクトルになるようなベクトルは無く、実はこれ以上簡単にすることができません。
これらの行列について、作用するベクトル空間を$V$と表現することにすれば、$V$は"単純"、これ以上簡単にしようが無いという状態だったのでした。

## でも、ブロック対角化なら...？

一方で、例えば
$$
\left(\begin{matrix}
 0& 1& 0\\\ 
 0& 0& 0\\\ 
 0& 0& 1\end{matrix}\right),
\left(\begin{matrix}
 0& 0& 0\\\ 
 1& 0& 0\\\ 
 0& 0& 2\end{matrix}\right)
$$
という2つの行列が与えられたとすると、この2つの行列は対角化はできませんが、先程の作用の
$$
\left(\begin{matrix}
 0& 1& \\\ 
 0& 0& \\\ 
 & & \end{matrix}\right),
\left(\begin{matrix}
 0& 0& \\\ 
 1& 0& \\\ 
 & & \end{matrix}\right)
$$
という部分と、
$$
\left(\begin{matrix}
 & & \\\ 
 & & \\\ 
 & & 1\end{matrix}\right),
\left(\begin{matrix}
 & & \\\ 
 & & \\\ 
 & & 2\end{matrix}\right)
$$
という部分の２つの作用の直和であると思うことができます。
Jordan標準形のような形での対角化ではないですが、いくつかの行列が与えられたとき、それらの作用をこのように"同時直和分解"することで、固有値・固有空間のある種の一般化を考えることができます。

# 正方行列のブロック化

これまで、何度か「ブロック化」という言葉を使っていますが、（正方）行列の著しい特徴として、「成分の一部を行列として考えても、和・積が成立する」というものがあります。（和については自明かと思いますが）

例えば、次のような行列があったとします。
$$
\left(\begin{matrix}
 a_{11}& a_{12}& b_{11}\\\ 
 a_{21}& a_{22}& b_{21}\\\ 
 c_{11}& c_{12}& d_{11}\end{matrix}\right)
$$
これは、
$$\left(\begin{matrix}
 A& B\\\ 
 C& D\end{matrix}\right)
$$
という行列をイメージしていて、$A$は2行2列、$B$は2行1列、$C$は1行2列、$D$は1行1列の行列になります。これに、同じ形の別の行列
$$\left(\begin{matrix}
 P& Q\\\ 
 R& S\end{matrix}\right)
$$
を右からかけたとすると、単純に行列の積のルールに従えば
$$\left(\begin{matrix}
 AP + BR & AQ + BS\\\ 
 CP + DR & CQ + DS\end{matrix}\right)
$$
になります。
この左上は2行2列、右上は2行1列、左下は1行2列、右下は1行1列になりますが、これを"展開"して普通の3行3列の行列としてみると、実は上の3$\times$3行列として見た時の計算と一致しています。
例えば、一番左上の成分は、$a_{11}p_{11} + a_{12}p_{21} + b_{11}q_{11}$で、他もすべて一致することが計算をすればわかります。

一般に、行と列について同じ区切り方をすれば、このようなブロック化が成立して、このようなある意味で再帰的な構造が成立します。とても興味深いですね。

# ブロック対角化

このようなブロック化において、特にブロック対角成分となる各正方行列以外はすべて0(零行列)になっているとき、そのような行列はブロック対角化されていると言えます。
ただし、広義で考えれば任意の行列は既にブロック対角化された状態であるとも言えるので、特に"細かい"ブロック対角化を目指すのが良さそうです。


というような事を素朴に考えてきましたが、このブロック対角化を考えるには、単純に行列そのものを考えるのではなく、それを含む**代数**から考えた方が見通しが遥かに良くなります。代数で考えるとき、作用するベクトル空間は**加群**と呼ばれ、また作用を与える行列（または、その行列と代数の対応）を**表現**と呼びます。
そこで、次回以降は代数の基本的な事実から、このようなブロック対角化＝**加群（表現）の直和分解**について考えを進めていきたいと思います。

# おまけ

## 複素数を含む行列の転置（随伴行列）

随伴行列を取る時、行列を転置して、さらに複素数について複素共役をとる＝"虚数成分の正負を反対にする"という操作を取ります。
これは一見不自然な操作ですが、実は次のような考えをブロック行列と合わせて考えると、自然な操作であると思えます。

$$\left(\begin{matrix}
 0& 1\\\ 
 -1& 0\end{matrix}\right)$$
という行列を考えると、これは2乗すると
$$\left(\begin{matrix}
 0& 1\\\ 
 -1& 0\end{matrix}\right)^2 = \left(\begin{matrix}
 -1& 0\\\ 
 0& -1\end{matrix}\right)$$
となって、$\sqrt{-1}$と同一視できることがわかります。
そこで、$$
1=\left(\begin{matrix}
 1& 0\\\ 
 0& 1\end{matrix}\right),i=\left(\begin{matrix}
 0& 1\\\ 
 -1& 0\end{matrix}\right)$$
と思うことにして、**複素数の行列は$2 \times 2$の行列が隠れたブロック行列だった**と思うことにします。
そうすると、例えば$i$の転置を取ると$$
\left(\begin{matrix}
 0& -1\\\ 
 1& 0\end{matrix}\right)=-i
$$
となり、複素共役が自然に出てくるのでした。
Amazon API GatewayとAWS LambdaでつくるインタラクティブなSlackAppその２（Interactive Components）

[昨日](https://qiita.com/ikeisuke/items/097fee72073a26ee4d9d)はコマンドを作成し、レスポンスによってボタンを表示しましたが、
今回の記事ではSlackAppにおける機能として`Interactive Components`を利用しています。

また、この記事では以下の要素を利用して、SlackAppを構築するための基本的な部分を実装していますが、
個々の要素の具体的な利用方法や言語の実装についてはあまり触れません。

- Amazon API Gateway
- AWS Lambda (Golang)
- CloudFormation (AWS SAM)

# TL;DR

[昨日](https://qiita.com/ikeisuke/items/097fee72073a26ee4d9d)の続き
ボットが送信したボタンのクリックに対して対応した内容にメッセージを書き換える仕組み

以下の動作を参考にしてください。
![command.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/69c75178-edaf-c910-9939-ceb130fd47b5.gif)


# 前提条件

[昨日](https://qiita.com/ikeisuke/items/097fee72073a26ee4d9d)の記事を読んでいる事

# Interactive Componentsの有効化

有効化しないで実行するとこのような状態になります
![failed.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/1c76ba0c-296f-4958-a3a7-7f57b12a49e4.gif)

アプリの設定の左メニューから「Interactive Components」を選択し、OFFになっているのをONに変更します。
変更すると以下のような画面になるので、「Request URL」に昨日利用したAPIのURLとその後ろに`interactive`と入力して保存してください。

![スクリーンショット 2019-12-08 21.49.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/b24f3cbd-469d-8bf4-47cc-190377e38795.png)


## 動作確認

エラーになっているところをもう一度クリックすることで設定のURLにリクエストが飛んでメッセージの書き換えの処理が走りました。
![success.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/5c6a670d-c782-5e39-c4d4-c523a368465f.gif)

# アプリケーション全体の流れ

思ったより内容薄すぎるので、前回のものと合わせアプリケーションの全体の流れを整理しました。

![slackappdiagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/e2cfc609-617c-347a-bc4d-6f3f59acc072.png)

1. SlackのUIからコマンド`/chatops channel list`送信
2. APIGateway(slash command用)が受けてLambdaに転送
3. LambdaはSlackAPIをコールしてチャネルのリストを取得し[インタラクティブ用ボタンのメッセージ](https://github.com/ikeisuke/slack-app-example/blob/master/internal/application/command/channel.go#L23)を作成して返却
4. APIGatewayはその内容をそのまま返却
5. SlackのUI側で返却値を元にメッセージを表示（※成功時は全員に表示するが、エラー時は送信者のみになるよう制御している）
6. ユーザーがUI上に表示されたボタンをクリック
7. APIGateway(interactive components用)が受けてLambdaに転送（送信者やレスポンス送信用のURLなどが渡されている）
8. Lambdaはレスポンス送信用URLに[書き換え用メッセージ](https://github.com/ikeisuke/slack-app-example/blob/master/internal/repository/intaractive.go#L32)を送信（非同期で３０分以内に5回まで送信可能）し、200 OKと空レスポンスを返却
9. APIGatewayはその内容をそのまま返却（リクエストから3秒以内に返さないとエラーになる）

なお、リクエストをうける側として[Slackからのリクエストが正しいものかどうかを検証する処理](https://github.com/ikeisuke/slack-app-example/blob/master/internal/application/slash_command.go#L36)が必要です。
詳しくは[公式の説明](https://api.slack.com/docs/verifying-requests-from-slack)を確認してください

# あとがき

サンプル実装において`slash command`はサブコマンド毎に分岐できるようにアプリケーションを作ってますが、`interactive components`はアクション毎の分岐をするように作っていません。
本来はアクション毎の分岐を実装しないといけないのでもし実装を参考にされる場合にはその点をご注意ください。
なお、コマンドとインタラクションの両方ともがアプリケーション内の分岐をしっかり制御しないとif文だらけの実装になりますので、注意してください。
プロパティやメソッドの並び順テンプレート(Swift)

## はじめに

SwiftLintには、クラスやプロパティなどの並び順を強制するルールがあります。

|ルール名|概要|
|:--|:--|
|file_types_order|ファイル内の型の並び順を強制する|
|type_contents_order|型内のプロパティやメソッドの並び順を強制する|

これらのルールを適用することで、必然的にコードが整理されて可読性が上がります。

しかし、並び順を覚えるのは大変です。
ぱっと見でどこに何を書けば(書いてあるか)わかるよう、テンプレートを作成しました。

ルールの例からほぼ変えていないので、公式を見るだけでもいいと思います。
https://github.com/realm/SwiftLint/blob/0.38.0/Rules.md#file-types-order
https://github.com/realm/SwiftLint/blob/0.38.0/Rules.md#type-contents-order

## 自分ルール

同じグループの場合、アクセス修飾子の大きいものから順に書きます。
( `open` → `public` → `internal` → `fileprivate` → `private` )

アクセス修飾子も同じ場合、読み下しやすい順に書きます。

```swift:例
class TestViewController: UIViewController {

    // MARK: Other Methods

    // privateよりinternalメソッドから先に書く
    func hoge() {}

    // 呼び出し側から先に書くと読み下しやすい
    private func foo() {
        bar()
    }

    private func bar() { }
}
```

準拠したプロトコルのメソッドは、 `// MARK: {プロトコル名}` としてOther Methodsの上に書きます。

```swift:例
// MARK: Protocols

protocol TestViewControllerDelegate: AnyObject {
    func didPressTrackedButton()
}

// MARK: Main Type

class TestViewController: UIViewController, TestViewControllerDelegate {

    // MARK: TestViewControllerDelegate

    func didPressTrackedButton() {
        // some code
    }

    // MARK: Other Methods

}
```

## 環境

- SwiftLint：0.38.0

## テンプレート

```swift
// MARK: Protocols

protocol TestViewControllerDelegate: AnyObject {
    func didPressTrackedButton()
}

// MARK: Main Type

class TestViewController: UIViewController, TestViewControllerDelegate {

    // MARK: Type Aliases

    // MARK: Classes

    // MARK: Structs

    // MARK: Enums

    // MARK: Stored Type Properties

    // MARK: Stored Instance Properties

    // MARK: Computed Instance Properties

    // MARK: IBOutlets

    // MARK: Initializers

    // MARK: Type Methods

    // MARK: View Life-Cycle Methods

    // MARK: IBActions

    // MARK: TestViewControllerDelegate

    // MARK: Other Methods

    // MARK: Subscripts

}

// MARK: Extensions

extension TestViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell()
    }
}
```

## おわりに

Xcode上で新しくファイルを追加したら、まず上記のコメントをコピペするのがオススメです。
コーディング後、未実装のグループのコメントを削除すると見通しがよくなります。
dbの指定を忘れてrails newしてしまった。しにたい。

#症状
アプリを作成している時、いつもの如くSequel Pro確認したらdbがない

#原因
いつもはrails newする時に

```
rails new -d mysql
```
としていたのだが

```
rails new
```
というやり方でディレクトリを作成してしまった。


#処置

```ruby:Gemfile
gem 'mysql'
#gem 'sqlite3'
```
上記のようにgemfileにmysqlを追記。
sqlite3は念のためコメントアウトして置いて

```
bundle install
```

そしてdatabase.ymlを下記のように編集

```database.yml
default: &default
  adapter: sqlite3
  pool: 5
  timeout: 5000

development:
  adapter: mysql2
  encoding: utf8
  database: [データベース名]
  pool: 5
  username: root
  password:
  host: localhost
```

その後

```
rake db:create
```
でデータベースを作成。これでなんとかデータベースはmysqlになった。


#まとめ
色々中途半端な対策かもしれません。今回はまだデータベースにデータを入れてない状態だったのでこれで済んだ。あとアプリを仕上げて本番環境とかになったら後遺症見たいのが出てくるのかもしれないがそれはその時対策します。
備忘録としてですが、
ご指摘あればぜひよろしくお願いします。
C - HonestOrUnkind2

#感想
今日出たABC147は2問しか解けなかった
解けなさすぎて涙出てくるホント
bit全探索だってさ。なにそれ
あと配列の個数を死ぬほど間違えて死にたくなる


#問題
<img width="751" alt="スクリーンショット 2019-12-09 1.04.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/17506a60-ddbb-085a-2011-c085379103f2.png">

#回答
```ruby
N = gets.to_i
I = 2**N - 1
alist=[]
xlist=[]
ylist=[]
for i in 0..N-1
  A = gets.to_i
  X,Y = A.times.map{gets.split.map(&:to_i)}.transpose
  alist.push(A)
  xlist.push(X)
  ylist.push(Y)
end
result = 0
for i in 0..I
  breakflag = false
  S = []
  N.times do |j|
    if i & 1 == 1
      S.push(1)
    else
      S.push(0)
    end
    i = i >> 1
  end
  # 検査開始
  for n in 0..N-1
    if S[n] == 1
      for a in 0..alist[n]-1
        if S[xlist[n][a]-1] != ylist[n][a]
          breakflag = true
          break
        end
      end
    end
    break if breakflag
  end
  if breakflag == false
    if result < S.count(1)
      result = S.count(1)
    end
  end
end
p result
```

#結果
<img width="1089" alt="スクリーンショット 2019-12-09 1.05.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/632ee1b3-8f4b-2f87-30ec-d083b4174974.png">

# 追記　教えていただいたメソッドで
# 回答
```ruby
N = gets.to_i
I = 2**N - 1
alist=[]
xlist=[]
ylist=[]
for i in 0..N-1
  A = gets.to_i
  X,Y = A.times.map{gets.split.map(&:to_i)}.transpose
  alist.push(A)
  xlist.push(X)
  ylist.push(Y)
end
result = 0
Slist = [0,1].repeated_permutation(N).to_a
for S in Slist
  breakflag = false
  for n in 0..N-1
    if S[n] == 1
      for a in 0..alist[n]-1
        if S[xlist[n][a]-1] != ylist[n][a]
          breakflag = true
          break
        end
      end
    end
    break if breakflag
  end
  if breakflag == false
    if result < S.count(1)
      result = S.count(1)
    end
  end
end
p result
```
#結果
<img width="1090" alt="スクリーンショット 2019-12-11 17.07.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/13bf0fac-944a-a21c-5d12-66a8cd0d1068.png">