OmniAICreator/Qiita-1.07M huggingface dataset:
【Python3基礎】同じモジュール内のファイルを呼ぶときはfrom <相対パス> import <ファイル名>じゃないとダメ


# はじめに結論

以下の構成のPythonプロジェクトがあるとします。

```
├── module1
│   ├── __init__.py
│   ├── filename.py
│   └── program.py
├── main.py
```

このとき、Pythonモジュール内のプログラム`program.py`が同モジュール内の`filename.py`を呼び出したいとき

```python:program.py
# import filename # “ImportError: No module named” のエラーが出る ①
# import .filename # SyntaxError: invalid syntax のエラーが出る ②

from . import filename # 正解
```

上記のようにPython3以降では、`from . import filename`とする必要があります。

# ① 絶対パス読み込みではダメな理由

[こちらの開発者用公式ガイド](https://www.python.org/dev/peps/pep-0328/#guido-s-decision)に経緯を含めて記述されています。

はじめの要約として

> Imports can be ambiguous in the face of packages; within a package, it's not clear whether import foo refers to a module within the package or some module outside the package. (More precisely, a local module or package can shadow another hanging directly off sys.path.)

と理由が端的に説明されています。
つまり、Pythonのモジュールにとって自身内のファイルは`sys.path`のパススコープとは別扱いなので、`import filename`とするとそのfilenameが、自身の外にある別パッケージにあるもの(sys.path内にあるもの)なのか、自身内のパッケージにあるファイル名なのか、が曖昧なのです。
そのため、Pythonコミュニティのメンバーたちは議論の結果、上述の方針を取ることにしたとのことです。

# ② 相対パス読み込みが`import .filename`ではダメな理由

[こちらの記載](https://www.python.org/dev/peps/pep-0328/#guido-s-decision)によると、

> The reason import .foo is prohibited is because after
import XXX.YYY.ZZZ
then
XXX.YYY.ZZZ
is usable in an expression. But
.moduleY
is not usable in an expression.

とあります。
つまり、絶対パス指定では、その後の式(expression)内でそのままの表現で利用できるようにするのがPython3での仕様なので、相対パスだとそれができないから、という理由のことのようです。

# 参考

* https://www.python.org/dev/peps/pep-0328/
* https://stackoverflow.com/questions/27365273/python-3-module-in-same-directory-as-script-importerror-no-module-named
ニコニコのユーザー検索API

## きっかけ

> 配信者や動画投稿者を検索できる「ユーザー検索」を追加しました【Android版nicocasアプリ】
https://blog.nicovideo.jp/niconews/105098.html

## リクエスト

ログインセッションは不要で

`https://api.cas.nicovideo.jp/v1/search/users?searchWord={検索キーワード}`

にGETリクエストを送ることでjsonテキストが返ってくる。

## レスポンスの例

`https://api.cas.nicovideo.jp/v1/search/users?searchWord=Sin` 

とリクエストした場合のレスポンス例（2019/05/04時点）

```json
{
	"meta": {
		"status": 200,
		"totalCount": 960,
		"ssId": "64269989-b416-4929-914e-a3980dfe8f21"
	},
	"data": {
		"users": [{
			"id": "8174142",
			"nickname": "Sin",
			"icons": {
				"urls": {
					"150x150": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/817/8174142.jpg?1489936219",
					"50x50": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/s/817/8174142.jpg?1489936219"
				}
			},
			"description": "主に東方×FFのクロスオーバー二次創作や<br>\nテイルズオブシリーズの秘奥義集や<br>\n少年ジャンプ関連ゲームのトーナメント企画を投稿しています<br><br>\n動画の進捗報告等しているツイッター<br>\n@Sin_ncd",
			"followerCount": 5646,
			"videoCount": 438,
			"liveCount": 0
		}, {
			"id": "21219275",
			"nickname": "sin",
			"icons": {
				"urls": {
					"150x150": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/2121/21219275.jpg?1453635625",
					"50x50": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/s/2121/21219275.jpg?1453635625"
				}
			},
			"description": "",
			"followerCount": 520,
			"videoCount": 36,
			"liveCount": 0
		}, {
			"id": "4697825",
			"nickname": "SIN",
			"icons": {
				"urls": {
					"150x150": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/469/4697825.jpg?1380033478",
					"50x50": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/s/469/4697825.jpg?1380033478"
				}
			},
			"description": "MHF3鯖で活動しているSINです<br>\n<br>\n主にMHFの動画を上げていますがたまに他の動画を上げることも…<br>\n<br>\nMHF動画一覧→mylist/20382131\n",
			"followerCount": 678,
			"videoCount": 85,
			"liveCount": 1261
		}, {
			"id": "27385303",
			"nickname": "Sin_2",
			"icons": {
				"urls": {
					"150x150": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/2738/27385303.jpg?1336016823",
					"50x50": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/s/2738/27385303.jpg?1336016823"
				}
			},
			"description": "メインのアカウントはこちらです→user/8174142<br><br>\n何かあった場合の連絡はこちらまで<br>\nhttps://twitter.com/Sin_ncd",
			"followerCount": 1847,
			"videoCount": 65,
			"liveCount": 0
		}, {
			"id": "13155337",
			"nickname": "Sin",
			"icons": {
				"urls": {
					"150x150": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/1315/13155337.jpg?1527254787",
					"50x50": "https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/s/1315/13155337.jpg?1527254787"
				}
			},
			"description": "Sinと申します。",
			"followerCount": 76,
			"videoCount": 270,
			"liveCount": 3
		}]
	}
}
```

## URLパラメータの説明

### searchWord
文字列、必須
検索キーワード、URLパラメータエスケープが必要

### offset 
0以上の整数、オプション
受け取りたい検索結果の先頭位置を指定
デフォルトは0

### limit
0以上の整数、オプション
受け取りたい検索結果の最大数を指定
デフォルトは5

### sort
文字列？、オプション
`followerCount` `videoCount` `liveCount` は指定可能と確認。
デフォルトは不明

### order
`asc` または `desc` を指定、オプション
デフォルトは desc （大きい値のものが先頭に来る）


## 参考

https://jsonlint.com/ 
Jsonを綺麗に見れる
【Python】PythonプログラムをHerokuにデプロイする方法

# 結論（何ができるようになるか）
PythonのプログラムをHerokuにデプロイできるようになる

## 背景
Pythonの学習をしはじめて、Herokuを使用する機会が増えてきた。デプロイする際に毎回やり方を調べてやっている。エラーが出たりすることもある。一連の流れをまとめることで、自分自身の知識の定着とHerokuデプロイ時にまとまった情報を確認できるようにするため、今回まとめることにする。

## 全体の流れ
① プロジェクトフォルダを作成する
② プロジェクトフォルダにデプロイするためのファイルを準備する
　・ main.py(プログラムファイル)
　・ runtime.txt（Pythonのバージョンを記載）
　・ requirements.txt（インストールするモジュールを記載）
　・ Procfile（プログラムの実行方法を記載）
　　※ 構成は状況により異なる
③ Herokuにアプリを作成する
④ Herokuにデプロイする

## デプロイ
① プロジェクトフォルダを作成する

```
# 任意のフォルダを作成
mkdir project
```
② プロジェクトフォルダにデプロイするためのファイルを準備する
・ main.py(プログラムファイル)
　Pythonの実行ファイル

・ runtime.txt（Pythonのバージョンを記載）
 　Pythonのバージョンを記載するテキストファイル

```
# 環境に合わせてPythonのバージョンを記載
echo python-3.6.5 > runtime.txt
```
※Herokuがサポートしているバージョンを記載すること

・ requirements.txt（インストールするモジュールを記載）
　実行ファイルに関連するモジュールを記載する
 
```
# 関連モジュールの一覧を作成
pip freeze > requirements.txt
```
※ローカルにインストールしたモジュールがすべてが出力されてしまうので、不要なものは削除すること

・ Procfile（プログラムの実行方法を記載）
　プログラムの実行方法を記載するファイル

```
# なんの言語で何を実行するかを記載
echo web: python main.py > Procfile
```
③ Herokuにアプリを作成する
・ Herokuにログインし、アプリを作成する

```
# herokuにログイン
heroku login
# アプリを作成（createの後に名前を入れることで任意の名前をつけられる）
heroku create
```
④ Herokuにデプロイする
・ リポジトリの作成とリモートリポジトリのひもづけ（一番最初だけ）

```
# gitの初期ファイルを作成
git init
# ローカルリポジトリに結びつくリモートリポジトリを設定
heroku git:remote -a アプリ名
```
・ デプロイ
  　実行プログラム等の変更があった場合はここから↓

```
# 変更したファイルをインデックスに登録
git add .
# 変更したファイルをリポジトリに書き込む
git commit -am "コメント"
# herokuにローカルで作成したファイルをpush(デプロイ)
git push heroku master
```

## エラー対応
git push heroku masterを実行した時、以下のようなエラーが発生

```
git push heroku master

fatal: 'heroku' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
下記のコマンドで参照先を追加

```
git remote add heroku https://git.heroku.com/アプリ名.git
```

## 環境変数設定
LINE等のトークンなどを設定する場合

```
heroku config:set LINE_CHANNEL_ACCESS_TOKEN=***********************
```

## プログラムの定期実行
herokuのスケジューラーを使用（heroku scheduler）

アドオンとして提供されている。簡単にセットアップできてコンソールでも使用できる。
※アドオンを使用する場合にはクレカの登録が必須

時間はUTCなので日本時間の場合は9時間足す。

## Dynoの使用量確認
freeプランで運用するために気になるDyonの使用量確認

```
heroku ps
```

## その他のherokuコマンド
herokuコマンド一覧

| コマンド       　　　　 | 内容         | 
|:---------------------|:------------|
| heroku logout        |ログアウト     |
| heroku list          |アプリ一覧を表示|
| heroku logs          |ログを確認     | 
| heroku config        |環境変数を確認  | 
| heroku run "コマンド" |コマンドを実行  | 

## まとめ
gitやherokuはプログラム初心者にはとっつきにくい。英語で記載されていることで、さらにとっつきにくさを助長している。ただ、慣れてしまえば便利なもので、なくてはならないものになる。ここに記載されている内容は基礎的な内容だが、ここに書かれていることが理解できれば、Pythonで実現したいことの範囲が格段に広くなる。Webサービスを公開したり、LINE BOTを作ったり。楽しいことが待っている。

## 参考にした情報
[【初心者向け】PythonによるHeroku環境で簡単LINEBot開発](https://miyabi-lab.space/blog/21)
[Herokuでお天気Pythonの定期実行](https://qiita.com/seigo-pon/items/ca9951dac0b7fa29cce0)
[herokuのDynoの使用量確認](https://teratail.com/questions/64566)
[Herokuにpush時にdoes not appear to be a git repository出た時の対処](https://qiita.com/sayama0402/items/e2c9e65786259dc55e11)
[【Git】新人エンジニア、git pushまでの道](https://qiita.com/33yuki/items/9ef9d54f2e7d53cfb51c)
Leetcode #99: Recover Binary Search Tree

Solution: Use inorder traversal to trace the tree and then sort. Trace the tree again to assign the correct value. O(n) space is needed.

```swift
func recoverTree(_ root: TreeNode?) {
    var sortedAr = inorderTraversal(root).sorted()
    var stack = [TreeNode]()
    var node = root
    while !stack.isEmpty || node != nil {
        if node != nil {
            stack.append(node!)
            node = node?.left
        } else {
            node = stack.removeLast()
            let tmp = sortedAr.removeFirst()
            if node!.val != tmp {
                node!.val = tmp
            }
            node = node?.right
        }
    }
}

private func inorderTraversal(_ root: TreeNode?) -> [Int] {
    var stack = [TreeNode]()
    var ar = [Int]()
    var node = root
    while !stack.isEmpty || node != nil {
        if node != nil {
            stack.append(node!)
            node = node?.left
        } else {
            node = stack.removeLast()
            ar.append(node!.val)
            node = node?.right
        }
    }
    return ar
}
```

Solution: O(1) solution

```swift
func recoverTree(_ root: TreeNode?) {
    var stack = [TreeNode]()
    var node = root
    var pre = TreeNode(Int.min)
    var first: TreeNode?
    var second: TreeNode?
    while !stack.isEmpty || node != nil {
        if node != nil {
            stack.append(node!)
            node = node?.left
        } else {
            node = stack.removeLast()
            if node!.val < pre.val {
                second = node!
            }
            if first == nil && node!.val < pre.val {
                first = pre
            }
            pre = node!
            node = node?.right
        }
    }
    let tmp = first!.val
    first?.val = second!.val
    second?.val = tmp
}
```
Java Scriptの学習方法【GW連投企画】

# Java ScriptはIT業界の縁の下の力持ち
元々ウェブサイトをダイナミックに使えるようにする機能がメインでしたが、
今やNode.jsでウェブアプリを作ったり、ブロックチェーンのスマートコントラクトを書けたり、Google App Script等いろんな場面で活躍してます。

# PHPやRubyより先に習得してしまいましょう
PHPやRubyどちららを使ってもウェブアプリを作る際には結局Java Scriptを使うので
先に習得してしまいましょう。

# Chromeで書いてみましょう
Node.jsを入れずともChrome等のブラウザのコンソールから直接書けるのでやってみましょう

# 進め方
[JavaScriptの絵本 第2版 Webプログラミングを始める新しい9つの扉 ](https://www.amazon.co.jp/JavaScript%E3%81%AE%E7%B5%B5%E6%9C%AC-%E7%AC%AC2%E7%89%88-Web%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%92%E5%A7%8B%E3%82%81%E3%82%8B%E6%96%B0%E3%81%97%E3%81%849%E3%81%A4%E3%81%AE%E6%89%89-%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%82%A2%E3%83%B3%E3%82%AF-ebook/dp/B07428G6FT/ref=sr_1_26?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=javascript&qid=1556934505&s=gateway&sr=8-26)
[スラスラ読める JavaScriptふりがなプログラミング](https://www.amazon.co.jp/%E3%82%B9%E3%83%A9%E3%82%B9%E3%83%A9%E8%AA%AD%E3%82%81%E3%82%8B-JavaScript%E3%81%B5%E3%82%8A%E3%81%8C%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%8F%8A%E5%B7%9D%E5%8D%93%E4%B9%9F-ebook/dp/B07DR76HSG/ref=sr_1_25_sspa?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=javascript&qid=1556934505&s=gateway&sr=8-25-spons&psc=1)

[はじめてのJavaScript (全11回)](https://dotinstall.com/lessons/basic_javascript_v3)
[JavaScriptでおみくじを作ろう (全8回)](https://dotinstall.com/lessons/omikuji_js_v4)
[JavaScriptで三択クイズを作ろう (全20回)](https://dotinstall.com/lessons/quiz_js_v2)

[JavaScriptの理解を深めた人がさらにもう一歩先に進むための本](https://www.amazon.co.jp/JavaScript%E3%81%AE%E7%90%86%E8%A7%A3%E3%82%92%E6%B7%B1%E3%82%81%E3%81%9F%E4%BA%BA%E3%81%8C%E3%81%95%E3%82%89%E3%81%AB%E3%82%82%E3%81%86%E4%B8%80%E6%AD%A9%E5%85%88%E3%81%AB%E9%80%B2%E3%82%80%E3%81%9F%E3%82%81%E3%81%AE%E6%9C%AC-%E4%BA%94%E5%8D%81%E5%B5%90%E8%82%87-ebook/dp/B01HUNYZNW/ref=sr_1_45?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=javascript&qid=1556934505&s=gateway&sr=8-45)


[JavaScript Web開発パーフェクトマスター (Perfect Master)](https://www.amazon.co.jp/JavaScript-Web%E9%96%8B%E7%99%BA%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-Perfect-Master-%E9%87%91%E5%9F%8E/dp/4798043885/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=javascript+%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88&qid=1556934820&s=gateway&sr=8-2)
少し古い

# 環境
[codepen](https://codepen.io/)
Node.jsをインストールする前にこちらで試してみるのもあり
IEではtransformで斜めにした親要素とCSSアニメーション(transition／animation)を指定した子要素は相性が悪い


#起きた現象

wow.jsとAnimate.cssでいつものようにclass属性とdata属性を使用していました。

※wow.jsとAnimate.cssについて
[Animate.cssとwow.jsを使ってサイトにアニメーションをつける](https://qiita.com/tiwu_official/items/989834406c25deccee8b)

今回は背景を斜めにする必要があり、親要素に以下のようなプロパティを指定して子要素にアニメーションの指定をしていました。

サンプル
https://codepen.io/ShimokawaChan/pen/qGWxPV

※背景斜めについて
[斜めの背景を作るためのCSSは「回転させて元に戻す」で書く！](https://haniwaman.com/background-skew/)

他のブラウザでは問題なかったのですが、、、IEだと要素が消えるもしくはチカチカする、、、現象が起きました。


#対処
いい解決策が見つからず、背景を斜めにしているところを通常にもどして上部と下部に三角形をつけるような形で対処しました。

###こちらの方がやっているような方法

[斜め背景でカッコいいフロントエンドデザイン](https://qiita.com/sho012b/items/3478ca65fe5b6de0450a)

#おしまい

IEはまだまだ不安定なのでCSS3のプロパティを使う際は注意したいものです。。。
意外と使える【Photoshop】レイヤーパネルの検索機能（フィルター）が便利！！


社内のデザイナーさんから教わってこれは使える！！と思ったPhotoshopのレイヤーパネルの検索機能を紹介します。
地味ではありますがかゆいところに手が届いてる感じがしてたまーに使います。
普段、使っている機能以外にもいろいろあったので勉強のつもりで残します。

#どこにあるの？？

この検索フィルターはCS6からついている機能みたいで以下の画像の場所にあります。
レイヤーパネル上に初期表示で出ています。

![スクリーンショット 2019-05-04 9.56.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409259/df192091-9887-da13-31f6-603eb6427954.png)

一番右にある、スイッチでON／OFFを切り替えることができます。

#各種アイコンについて

各アイコンを選択すると選んだ種類のレイヤーだけ表示することができます。

![2017_1110_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409259/3bcb309f-c957-57fd-7ab8-0b5852db8f15.png)
(出典：https://handywebdesign.net/2017/11/photoshop-layer-search/)

特にテキストレイヤーなどはテキストの抽出やフォントの調査などで僕はよく使います。

フィルター機能を使っている時は一番右側のON／OFFボタンの色が赤になります。

###フィルター使用時

![スクリーンショット 2019-05-04 10.08.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409259/6176afb9-fc68-b760-aec3-e9b05f29706c.png)

###フィルターなし

![スクリーンショット 2019-05-04 10.08.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409259/8793e293-8992-8c4c-4a6b-095a914730e9.png)

#名前や属性、モードなど様々な条件で検索できる

名前や属性、モードなど様々な条件からも検索できます。

一番左にある虫眼鏡マークをクリックするとプルダウンが開いて様々な条件で検索できます。

![スクリーンショット 2019-05-04 10.13.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409259/c30014e9-905b-89e3-0621-14f4f5f08aed.png)


###名前検索時

試しにレイヤーの名前で検索フィルターを使うと以下のようになります。

![スクリーンショット 2019-05-04 10.12.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409259/89a4ee3b-6936-6066-ae60-4612af6c6eb8.png)

#おしまい

フロントエンドだと特定のレイヤーのみ画像で書き出したいときやレイヤーの情報抽出、テキストの検索などあのフィルターどこにあるかな？という場面が非常に多いのでぜひ使ってみてください！！

#参考

[【Photoshop】レイヤーパネルの検索機能（フィルター）を使うと、特定のレイヤーがすぐに見つかって便利](https://handywebdesign.net/2017/11/photoshop-layer-search/)
githackでGitHub上のWebアプリをお手軽実行

##### githack
　GitHub に上がっているHTMLやJavascriptは
　　[raw.githubusercontent.com](https://raw.githubusercontent.com/)
 でアクセスできるが、text/plain として返却されるため、ブラウザで直接実行できない([例](https://raw.githubusercontent.com/washikawau/html5_apps/3b5e6e6557c127a673eed9cf211e9fd685a9a30d/tetris/index.html))。しかし、
　　[raw.githack.com](https://raw.githack.com/)
を経由すると、適切な Content-Type を返してくれるため、直接実行できる([例](https://rawcdn.githack.com/washikawau/html5_apps/3b5e6e6557c127a673eed9cf211e9fd685a9a30d/tetris/index.html))。

##### ファイル指定方法
1. rawcdn.githack.com/{GitHubユーザ名}/{リポジトリ名}/{コミットハッシュ}/ファイルパス
2. rawcdn.githack.com/{GitHubユーザ名}/{リポジトリ名}/{タグ}/ファイルパス
3. rawcdn.githack.com/{GitHubユーザ名}/{リポジトリ名}/{ブランチ名}/ファイルパス

##### 備考
* ブランチ名で指定すると、最新のコミットを参照してくれ、反映のラグも数10秒程度。
* Bitbucket や GitLab にも対応している。
* 無料サービスなので、今後大きな変更が起こるかもしれない。
1日の中で子どもがコケて頭を打つ確率を求める。

# 概要
つかまり立ちができるようになった子どもが
ステンとコケて頭を打つ確率を求めて、
amazonで頭を守ってくれる可愛いクッションを買うかどうかの検討材料にする。

# 前提

- sample数は十分と考える
- コケるだけの回数は無視して、コケて頭を打つ回数のみ考える。
- 頭を打つ程度は無視して頭を打ったら1回とする。
- 6時間に平均して2回頭を打つ。

# 確率を求める

## 5回ちょうど頭を打つ確率を求める

``` python
>>> from scipy.stats import poisson
>>> mu = 2
>>> poisson.pmf(5, mu)
0.03608940886309672
```

小数点第四位を四捨五入して100掛けて、
3.6%の確率で5回ちょうど頭を打つらしい。

## 5回を超える回数頭を打つ確率を求める

0~5回頭を打つ確率を求めて、1(100%) からその確率を引くことで求める。

``` python
>>> from scipy.stats import poisson
>>> mu = 2
>>> cdf_poiss = poisson.cdf(5, mu)
>>> cdf_poiss
0.9834363915193856
"""
0~5回頭を打つ確率を全部足して小数点第四位を四捨五入すると
98.3%になる。
"""
>>> (1 - cdf_poiss) * 100
1.6563608480614445
"""
5回を超える回数頭を打つ確率は1.6%になる。
"""
```

# 確率の分布を可視化する

0~30回まで頭を確率の分布を可視化する。

``` python
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.stats import poisson
>>> 
>>> k = np.arange(31)
>>> k
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])
>>> mu = 2
>>> pmf_poiss = poisson.pmf(k, mu)
>>> plt.bar(k, pmf_poiss)
<BarContainer object of 31 artists>
>>> plt.show()
```
こんなグラフが出ます。
画像なので見ようがないのですが、お手元でやってみて10のあたりを拡大表示してみると
すごく短いですがbinがあることがわかります。
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86853/ad5c4393-da3a-af73-8e5b-7b2e88a2b178.png)

# 結論

頭を打つと痛いし、可哀相なので回数に限らず買ってあげたほうが良い。
見た目もかわいいし。
【openFramewroks】Xcodeでよく使用したショートカットキーや実装のコツ

openFrameworksを使い始めて約１ヶ月、プロダクトを作れるようになりました。

ここでは私自身が忘れないように、開発エディタで使用したXcodeのショートカットキーや、開発でつまずきやすいポイントを備忘録としてまとめます！
## デバックの方法
```
float value = 0.2;
std::cout << "value: " << value << endl;

float value = 0.2;
std::printf("value: %f\n", value);
std::printf("value: %.0f\n", value);
std::printf("value: %.3f\n", value);
```
引用：[公式：変数の値を見る](https://openframeworks.cc/ja/learning/01_basics/how_to_view_value/)

## よくあるエラー(自分の場合)
- キャッシュ残っているとエラー出ることある
- Xcodeで複数のファイルを開くと、iosのビルドエラーが出たりする
- OSC通信でエラーでるときは、セキュリティが原因の場合あり

関連リンク：[openFrameworksでOSC通信できない時はセキュリティソフトが問題かも](https://qiita.com/guru_taka/items/74c80d54cbd19dd1a727)

## ショートカット
- cmd + R：ビルド＋ラン
- cmd + shift + k：キャッシュクリア
- cmd + .：中断
- cmd + opt + Enter：2画面
- cmd + ctl + プログラムをクリック：定義場所に移動
- cmd + shift + O：ファイル名を指定して開く(opt+enterで分割表示)
- cmd + shift + f：全体検索
- esc or ctl + space：入力補完
- cmd + opt + f：置換
- cmd + 0：ナビゲーター表示切り替え
- cmd + opt + 0：ユーティリティー表示切り替え
- ctl + i：インデントの調整
- cmd + z:戻る
- cmd + shift + z：進む
- cmd + ファイル選択：左画面のファイル切り替え
- opt + ファイル選択：右画面のファイル切り替え

## Sampleを探して、そこから実装する方が速い
openFrameworksは公式のサンプルが豊富なので

1. Finderなどで試したいコードを検索
2. 該当するサンプルファイルを開いて解読
3. 自分のコードで試してみる

という開発フローが手っ取り早く実装できました。これはaddonにもいえます。何か実装したいときはサンプルを最初にみてみると良いです(自戒)

## 参考リンク
- [oFを書くためのc++メモ](https://qiita.com/kitasenjudesign/items/726114585c731f0d4c37)
- [yoppa.org](https://yoppa.org/)
- [Xcodeチートシート](https://qiita.com/dondoko-susumu/items/2d124e315f898b3c94c0)
パスワード変更システムの製作（Java）その３

それぞれのクラス・インターフェース、ＵＩをパッケージ配下に
（中身はともあれ）作成し、準備が整った。

注意点であるが、クラス「BLImple_passwordupdate」は、
インターフェース「BL_passwordupdate」記載の仕様を引き継いでいる。

・「インターフェース」とは…具体的な処理内容を書かず、大まかな処理内容を
　記載したメモのようなもの
・「インターフェースを実装したクラス」とは…上述の「インターフェース」を
　の処理内容を反映し、実際の処理内容を記載したクラスのこと

「Entity_passwordupdate」から作り始める。

エンティティとはデータベースをコピーしたものだから、
データベースと同じ構成要素が無ければならない。

その構成要素とは、

1.user_id（ユーザーＩＤ）
2.user_password（ユーザーパスワード）
3.update_date（アップデート日付）
4.update_user（アップデートした人）

になる。それらを、プログラム（クラス）に定義しなくてはならない。

文字列形式で表現が可能である為、上記3以外はString形式で定義される。

3.のupdate_date（アップデート日付）はSQL搭載の機能？である為
Timestamp型となる。

また、カプセル化する為にアクセス修飾子はprivateとする。

※アクセス修飾子とは、その修飾子がついたクラス以外からのアクセス可否を
　設定し、表すもの。

※カプセル化とは、外部からのアクセスを制限して、中身のオブジェクトを
　保護することを言う？

さっそく上記1~4を定義する。

private String user_id;

private String user_password;

private Timestamp update_date;

private String update_user;

スーパークラスからコンストラクターを生成する。

スーパークラスとはすべてのクラスの親の様なもの。

コンストラクターとは、クラス（主語となるプログラム処理の）に実体を
与えるメソッドのこと


一旦アップする。。。
Uniform binary variant (uABS)の紹介

この記事は、<a href="http://creativecommons.org/licenses/by-sa/3.0/">クリエイティブ・コモンズ・表示・継承ライセンス3.0</a>のもとで公表されたウィキペディアの項目<a href="https://en.wikipedia.org/wiki/Asymmetric_numeral_systems">「Asymmetric_numeral_systems」</a>を素材として二次利用しています。

https://en.wikipedia.org/wiki/Asymmetric_numeral_systems

- [前回] introduction
- [前回] Entropy coding
- [前回] Basic concepts of ANS
- Uniform binary variant(uABS)
- [次回] Range variants(rANS) and streaming
- [次回] Tabled variant(tANS)
- [次回] Remark


# Uniform binary variant (uABS)

２値のalphabetで、密度分布が$Pr(1)=p$, $Pr(0)=1-p$から考える。奇数(s=1)に対するアナロジーから、$x$の最大値はおおよそ$ p\cdot x$となる。つまり、$ s=\lceil (x+1)\cdot p\rceil -\lceil x\cdot p\rceil $が得られる。これが uABS varoamtであり、以下の復号関数と符号関数が導き出される。


Decoding:
>s = ceil((x+1)*p) - ceil(x*p)  // 0 if fract(x*p) < 1-p, else 1
>if s = 0 then new_x = x - ceil(x*p)   // D(x) = (new_x, 0)
>if s = 1 then new_x = ceil(x*p)  // D(x) = (new_x, 1)

Encoding:
>if s = 0 then new_x = ceil((x+1)/(1-p)) - 1 // C(x,0) = new_x
>if s = 1 then new_x = floor(x/p)  // C(x,1) = new_x

$p=1/2$であれば、これは(0と1が入れ替わった) standard binary systemである。そして、異なる $p$に対しては、与えられた密度分布に応じて最適な物となる。例えば、 $p=0.3$であれは、この式からより小さなxのテーブルが導き出せる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89434/82897dab-7d9d-b69a-f73a-9054b13635f2.png)

（訳者補足）図面に補足を書き込むと…
元々の図面にいろいろ書き足すとこういう関係になる。ポイントは「s=0,s=1と書かれているのが入力で、C(x,s)と書かれているのが出力」。、

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89434/deccbaf9-ccbb-2f0d-c343-b8bf1bf28811.png)

Symbol $s=1$ は、分布 $p=0.3$ の自然数の部分集合に対応している。つまり、このケースでは、 $ \\{0,3,6,10,13,16,20,23,26,\ldots \\} $である。 $ 1/4<0.3<1/3$を満たす場合、位置は3もしくは4ずつ増えていく。 $p=3/10$であるから、symbolsのパターンは毎10位置ごとに繰り返される。

$C(x,s)$は、symbol $s$が与えられたときのrowの関連性と、このrowに対する$x$から、導き出すことができる、その結果、top rowは$C(x,s)$を与える。例えば、中央のtop rowから$C(7,0)=11$である。

$x=1$から初めて、'0100'のシーケンスを符号化することを考える。まず、$s=0$であるので、$x=2$となる。次に、$s=1$から$x=6$が、$s=0$から$x=9$が、そして、$s=0$から$x=14$となる。


最終的な$x$に対して、復号関数 $D(x')$を適用する場合、シンボルシーケンスを逆順に追う。この目的のためにテーブルを使う場合、最初のrowのxは、columnを決定する。そして、空ではないrowで$s$と$x$の関連がある、書かれた値を決定する。
IEではPaddingのcalc計算時に%が利いてくれないバグがある

#起きたバグ

IEだとpaddingに%を含むcalcの計算をすると、ウィンドウリサイズしても反映されないバグが発生しました。
ページ読み込みの時の%の値をリサイズしても保持し続けていて、レスポンシブルに値が変化しません。。。

サンプルはこちら
https://codepen.io/ShimokawaChan/pen/RmbxqL

％→vwに変更すれば解決しました。

#参考

[IEとcalcとpaddingのバグ](https://qiita.com/ln-north/items/b4d24a7397a047507d52)
Raspberry Piでsamba!

Raspberry PiでSambaを使う方法です。
ちょっとした所でつまづいてしまったのでその情報を少しでも共有できたら嬉しいです。

# sambaのインストール

まずはsambaのインストールからです。

```terminal
sudo apt-get update
sudo apt-get install samba
```

これでインストールは完了です。

# sambaの設定

sambaの設定をするのですが、その前に共有用のディレクトリを作ります。

今回は*`~/Public`*を共有用のディレクトリにしました。

`sudo chmod 777 ~/Public`を実行してディレクトリのパーミッションを変更します。今回はとりあえず全て許可する設定にします。

そしてsambaの設定ファイルを書き換えます。

sambaの設定は、*`/etc/samba/smb.conf`*にあります。

`nano /etc/samba/smb.conf`を実行して、以下を追記します。

```/etc/samba/smb.conf
[public]
        comment = RaspberryPiServer
        path = /home/pi/Public
        public = Yes
        guest ok = Yes
        read only = No
        writable = Yes
        browsable = Yes

```

`[public]`ははpublicというフォルダ名で共有するという意味です。

`comment`はただのコメントなので自由です。

`path`は、自分の共有用のディレクトリを設定します。**このとき`~/Public`のようにチルダ(`~`)をつけたパスにしないでください。**フルパスにしないとフォルダにアクセスすることができません。自分はこれで失敗しました。

`guest ok`の行はゲストログインができるようにしています。

`read only`と`writable`の行で読み書きできるように設定しています。

`browsable`の行は他のパソコンのネットワークに表示させるようにしています。



*`/etc/samba/smb.conf`*を保存した後、`testparm`と実行すると、文法ミスをチェックして、みやすい形でファイルを出力してくれます。



# sambaへのアクセス

エクスプローラーやFinderのネットワークの項目から、自分のRaspberry Piを選択してゲストでアクセスすると、sambaの共有フォルダにアクセスすることができます。

# 最後に

sambaのやり方を書いているサイトはたくさんあるので、やり方というよりは`path`の所をフルパスにしないとダメだということが伝われば幸いです。
yield って何？！

# yield を調べてみました

## yieldを使うメリットについて解説します。

例えば、return文でそのまま値を返す関数を作ったとします。一度に大きなリストが返ってくるような関数だと、たくさんのメモリを一度に消費してしまうことになります。

そのようなときは、yieldを使う事でその莫大な量の戻り値を小分けにして返すことが出来ます。これによって関数の実行をその都度中断し、少量ずつデータを返す事でメモリの消費量を抑えることが出来るようになります。

## python の場合

```python:リスト1

def myfunc():
  yield 'one'
  yield 'two'
  yield 'three'

for x in myfunc():
  print(x)
```

実行結果

```
one
two
three
```

yieldが呼ばれると、その時点でのジェネレーター内部の状態を保存したうえで生成した値を呼び出し元に返しつつ、制御も呼び出し元にいったん返します。
そして、再度ジェネレーターが呼ばれたとき、yieldの次の行から実行が再開されます。
forループは関数内で使用したyieldを全て処理するまで作動し続けます。
rubyでJWT検証時の話

## 前提
状況が激しくニッチ

## 状況
検証に利用する公開情報と、jwtデータの前半2つ(header, payload)はあるが肝心の署名データのサンプルがもらえてなくて開発時の検証テストが出来ない

## ならせめて
公開情報のインタフェースを踏襲してstub化し、実際の製品のjwt検証コードの内容を変えずに検証処理を通したい
algはRS256

## コード
実際の検証コードはtokenとx5nに相当するcerを容易に入れ替えられるしておき、
自前で署名つきjwtをこさえて、それを自前で検証できる状態にする。
※検証にはX509証明書チェーンを利用、e, nを利用する場合は[ここ](https://qiita.com/yossy6954/items/823df33b401d62e53345)が参考になるかと思います

```ruby
def tukuru
  dn = OpenSSL::X509::Name.new
  dn.add_entry 'C', 'JP'
  dn.add_entry 'ST', 'Kanagawa'
  dn.add_entry 'DC', 'Kawasaki'
  dn.add_entry 'O', 'foo'
  dn.add_entry 'CN', 'bar'

  rsa = OpenSSL::PKey::RSA.generate 2048

  cer = OpenSSL::X509::Certificate.new
  cer.not_before = Time.now
  cer.not_after  = Time.now + 20 * 365 * 24 * 60 * 60 # 有効期限は適当に(これは20年)
  cer.public_key = rsa.public_key
  cer.serial  = 1
  cer.issuer  = dn
  cer.subject = dn
  ex = OpenSSL::X509::Extension.new 'basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(true)])
  cer.add_extension ex
  cer.sign rsa, OpenSSL::Digest::SHA1.new

  File.open('yourpath/test_private.pem', 'wb') { |f| f.write(rsa.export) }
  File.open('yourpath/test_cer.pem', 'wb') { |f| f.write(cer.to_pem) }

  nil
end

def siraberu
  cer = File.read('yourpath/test_cer.pem') # 実検証時はここを外部から取得する
  rsa = OpenSSL::PKey::RSA.new(File.read('yourpath/test_private.pem'))

  header = {
    'foo': 'bar'
  }
  claims = {
    'daichi': 'oppore'
  }
  token = JWT.encode(claims, rsa, 'RS256', header) # 実検証時はここが他人が作ったtokenとなる

  public_key = OpenSSL::X509::Certificate.new(cer).public_key
  JWT.decode(token, public_key, true, algorithm: 'RS256')
end
```
サンプルなので1メソッドの中でグチャグチャやってますがノリは伝わるかと

こんな状態に陥る人はそうはいないと思いますが、同一の状態で困ったらとりあえずこれでゴリ押せます
わざわざファイルにしてるのは、実際にはfixture的にこの鍵ファイルを保持してそいつをテストコードの中で読み出して使うケースのが多そうだからです
テストコードでしか利用しない、機密にする理由がゼロの鍵やしね
Qiita(4)書きなぐっている分野、読み漁っている分野

Qiitaでは、５つ記事を読んで、１つ記事を書く感じ。

 <この項は書きかけです。順次追記します。>

読んでいるのは、今着手しはじめた分野。
書いているのは、昔からやっていたことと、最近やりはじめたこと。

タグを整理するために分野名を順次タグにしていく予定。
なお、書いている分野の記事は、なるべく全部読むように努力中。

git, dockerに注力中。その次がC, python

git
. github
. gitlab
. bitbucket

docker
. ubuntu
. debian
. apt

c/c++
. gcc/g++
. clang/clang++
. vscode/visual C/C++

python
. pip
. anaconda
.. conda

# 読んでいる分野

git: GitHub, gitlab, bitbucket
自然言語処理：機械翻訳ソフトの開発要員
macOS:今主に使っている機材
C#: C#の使い手から便利だよと勧められ周りに使い手が増えてきた。
Windows:お仕事展開上必要
JavaScript: Web系の作業で必須。
クラウド:AWSなどへの移植の助言のお仕事
PHP:使っているシステムの検査のお仕事
LISP: Emacs, Mule開発者の研究室の研究生で常駐。
IchigoJam: これから使う予定

# 書いている分野

安全：分析、HAZOP、交通事故
通信：Wi-Fi, RFC, 遅延
プログラミング言語：アセンブラ
IoT: RaspberryPI
導入：docker, brew, apt, shell
機械学習：Python, R
機敏：作業改善(process improvement)、事業管理(project management)
エラー：成功した事例より、失敗した事例に参考になることがある。失敗事例の中に、最終的に成功した事例があれば、成功事例だけの事例はいらない。

なぜdockerで機械学習するか 書籍・ソース一覧作成中 (目標100)
https://qiita.com/kaizen_nagoya/items/ddd12477544bf5ba85e2

言語処理100本ノックをdockerで。python覚えるのに最適。
https://qiita.com/kaizen_nagoya/items/7e7eb7c543e0c18438c4

プログラミング言語教育のXYZ
https://qiita.com/kaizen_nagoya/items/1950c5810fb5c0b07be4

Qiitaで組立語(assembler)・機械語(machine language)・CPU「アセンブラへの道」
https://qiita.com/kaizen_nagoya/items/46f2333c2647b0e692b2

# 書いている量と読んでいる量が均衡しているとかってに自分で思っている分野

C: gcc, clang, visual c
C++: g++, clang++ visual c++
Python: Anaconda
docker
brew
apt
shell: 主にエラー



# 読み書きしないことにしている内容

自己啓発本：自己啓発本はよむものではなく書くものとの趣旨から読む人とは会話しない。

株価：インサイダー取引の疑いをかけられるといけない。李下に冠を正さず。

仮想通貨：どういう仕事をお願いされるかわからない。立場を透明にしておきたい。

マルチ商法・ネズミ講：駄目だと言っている人が、実は張本人のことあり

政党・宗教：１８歳くらいまでプロテスタントの教会に通っていました。キリスト教に関する事項は英語、ラテン語等の言語理解で言及することあります。それ以外の宗教については、文化調査などの目的で調べることはあります。内容については、言語分析の場合は言及するかもしれません。かってでごめんなさい。

インド、インドネシアとJava、Javascript:接尾辞がついて別物と言うが共通点は多い。
https://qiita.com/kaizen_nagoya/items/2c331ff6654d41d5e157

 Qiita(0)Qiita関連記事一覧（自分）
https://qiita.com/kaizen_nagoya/items/58db5fbf036b28e9dfa6

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
# 文書履歴(document history)
ver. 0.01 初稿 20190504
ver. 0.02 「読み書きしない」追記 20190505 朝
ver. 0.03 仮想通貨追記 20190505 午前
ver. 0.04 例追記 20190509 
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.

<a href="http://b.hatena.ne.jp/entry/s/qiita.com/kaizen_nagoya/items/4fb239e122b7cc583332" class="hatena-bookmark-button" data-hatena-bookmark-layout="basic-label-counter" data-hatena-bookmark-lang="ja" title="このエントリーをはてなブックマークに追加"><img src="https://b.st-hatena.com/images/v4/public/entry-button/button-only@2x.png" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a><script type="text/javascript" src="https://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>
http://b.hatena.ne.jp/guide/bbutton
順番が変わってしまった文字列を元に戻そう

今日はプログラミングの問題を解いてみました。

<b>問題</b>
２つの文字列が与えられる。
１つ目は一見するとよくわらない文字列、２つ目には１つめの文字列の最後尾を何回か先頭に持ってくるとできる意味のある文字列
文字列の最後尾を何回先頭に持って来れば２個目の文字列になるかを出力する
例　'byru', 'ruby'　=>　2回

僕の解答

```rb
def rotation_str(str1,str2)
  str1_array = str_to_array(str1)
  i = 0
  while str1_array.join != str2
    rotation(str1_array)
    i += 1
  end
  i
end
#文字列を分割して配列に入れるメソッド
def str_to_array(str)
  str.split('').map { |s| s }
end
#要素の最後を先頭に持ってくるメソッド
def rotation(array)
  array.prepend(array[-1]).delete_at(-1)
end
```

このような解答になりました！！
もっとこうすれば良くなるよといったアドバイスがあればぜひコメントをして頂きたいです！！！

<b>追記</b>
Str#chars,Str#rotateという便利なメソッドを教えて頂いたのでそれを基にリファクタリングをしてみました。

```rb
def rotation_str(str1,str2)
  i = 0
  rotate_str = ''
  while rotate_str != str2
    if rotate_str.empty?
      rotate_str = rotate_join(str1)
    else
      rotate_str = rotate_join(rotate_str)
    end
    i += 1
  end
  i
end


def rotate_join(str)
  str.chars.rotate(-1).join
end
```

while文内でjoinしても破壊的ではなく無限ループになるので変数に格納することにしました。

また、他にもrindexを使うやり方もコメントで頂きましたが、そちらはサンプルコードまで頂いたので気になる方はぜひコメント欄をご覧ください！！！
Kubernetesのマニフェストファイルのフォーマットを調べる

Kubernetesの情報を本なりWebなりで見ていると、マニフェストファイルの例はたくさん出てきます。でもやっているうちに結局どんなパラメーターがあるの？と思ってフォーマットについて調べてみたけど、ちょっと辿り着きづらかったのでメモ。

## Web上で確認する
マニフェストファイルではなく、APIのドキュメントとしてまとまっていました。
たとえば現時点で最新のv1.14はこちら。
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/

## kubectlで確認する
`kubectl explain`を使うと、現在のコンテキストのバージョンに沿った情報を出してくれます。

### 全体の階層を確認する
`kubectl explain <リソース> --recursive`で全体の階層を表示。
Webだとこんな形で見れないのでとても便利！

```
$ kubectl explain service --recursive
KIND:     Service
VERSION:  v1

DESCRIPTION:
     Service is a named abstraction of software service (for example, mysql)
     consisting of local port (for example 3306) that the proxy listens on, and
     the selector that determines which pods will answer requests sent through
     the proxy.

FIELDS:
   apiVersion   <string>
   kind <string>
   metadata     <Object>
      annotations       <map[string]string>
(略)
```

### 特定のパラメーターについての説明を表示
`kubectl explain <リソース>.<階層>(.<階層>…)`でパラメーターの説明を表示。

```
$ kubectl explain service.spec.type
KIND:     Service
VERSION:  v1

FIELD:    type <string>

DESCRIPTION:
     type determines how the Service is exposed. Defaults to ClusterIP. Valid
     options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
(略)
```
flutterでfirestoreを使えるようにする

flutterのバージョンは下記の通り

```
$ flutter --version
Flutter 1.5.8 • channel dev • git@github.com:flutter/flutter.git
Framework • revision 0ba67226ee (8 days ago) • 2019-04-24 17:18:28 -0700
Engine • revision c63d1cf9c9
Tools • Dart 2.3.0 (build 2.3.0-dev.0.1 1f1592edce)
```

firebaseの設定は[ドキュメント](https://firebase.google.com/docs/flutter/setup?hl=ja)通りで問題ないが、一部変更しないとcloud_firestoreはつかえなかったのでその分を追記してある。

普通にfirebaseのプロジェクトを作成して
<img width="565" alt="スクリーンショット 2019-05-03 17.49.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117867/1053f3e1-d877-131e-7c65-fc15118f4fb4.png">

下記の枠で囲ってあるところからiOSとAndroidの設定を行う。
<img width="1038" alt="firebase-project.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117867/6050ba69-020d-7eb4-e8fb-d680fdc4d9ca.png">

Androidはパッケージ名を設定して設定ファイルをダウンロード。
パッケージ名にはandroid/app/build.gradle内のdefaultConfigに記載されているapplicationIdの内容を記述する。
<img width="1039" alt="スクリーンショット 2019-05-03 17.50.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117867/a96c563d-f3d6-bdce-13e9-977b170d3dbe.png">

iOSはバンドルIDを設定して設定ファイルをダウンロード。
<img width="1039" alt="スクリーンショット 2019-05-03 17.50.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117867/f97388aa-9aae-fd64-b63c-af592cd19060.png">

iOSのバンドルIDは下記の白枠で囲まれているところを使用する。
<img width="1400" alt="xcode.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117867/4f63c938-78ed-58f8-c9c8-0d1b0465ba6e.png">

firebaseでiOSの設定をした際にダウンロードした設定ファイル(GoogleService-Info.plist)を、Xcodeを開いてRunner/Runnerディレクトリに追加する。GoogleService-Info.plistはXcodeから追加しないと認識されないようなのでそこだけ注意する。  
Androidの設定をした際にダウンロードした設定ファイル（google-services.json）はandroid/appディレクトリに追加する

Androidは下記のようにandroid/app/build.gradleとandroid/build.gradleを変更する。ドキュメントと一部異なる部分はAndroid側のcloud_firestoreで「dex file cannot exceed 64K」が発生することへの対応のために必要。
<img width="994" alt="スクリーンショット 2019-05-03 18.10.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117867/a1c5efea-af89-196a-6b5c-61380c0a817e.png">

<img width="994" alt="スクリーンショット 2019-05-03 18.10.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117867/874cb819-0a56-2e15-1014-cb07a730ad23.png">
Ruby練習問題１[ボーナスドリンク問題]

#ボーナスドリンク問題#
**今回は[アウトプットのネタに困ったらこれ！？Ruby初心者向けのプログラミング問題を集めてみた（全10問）](https://blog.jnito.com/entry/2019/05/03/121235)から[ボーナスドリンク問題](https://github.com/JunichiIto/bonus-drink)を解いてみました！**


`＃この問題文は上の記事から引用しています
問題
ある駄菓子屋で飲み物を買うと、空き瓶3本で新しい飲み物を1本プレゼントしてくれる。
最初に購入した飲み物の本数から、トータルで飲める本数を算出するプログラムを作成せよ。
また、最初に100本購入した場合、トータルで何本飲めるか。`

`備考
この問題は小学校3年生の算数の問題をベースとしている。`


すごく簡単な問題、、、のはずなんだけどアルゴリズムに弱すぎて１５分くらいの見積もりが３時間くらいかかりました。。。

ではコードの解説をしていきます。
`100.times`のところは最初に`while文`を試したんですが１００回までというところの書き方がわからなくて、まず１００回繰り返すというところでわかりやすい`timesメソッド`を選択しました（ここまでで１時間くらい泣）。
次に引っかかったのはここも初心者まる出しで恥ずかしいんですけど、３本毎に１つ追加というところを（単に３で割るだけなんですが、、、）

```
n += 1 if n %= 3

n += 1 if n /= 3
```
最初は上で書いていてなんか変だなと思い、次に下の割り方書いてたんですがどうも数値が期待と違い、なんだろうなとチェリー本をめくっていたら
```
n % 3 == 0
```
という記述を見つけて”ああこれだ！”と。
計算式を使うところが基本的に`n += 1`ばかりでほとんど他に書いてこなかったので基本のキから抜けていました。

そして最後まで躓いたのがここで

```
100.times do |n|
n += 1
n += 1 if n % 3 == 0
puts n
end
1
2
4
4
5
7
7
8
.
.
.
97
97
98
100
100
```
３の倍数のところはちゃんと＋１が出来てるがその後は＋１されずにそのまま繰り返されてました。
そして考えに考えた結果、３の倍数以外のとこで別に加算するための変数が必要なのに気づいて最終的に

```
n = 0
m = 0

100.times do |n|
n += 1
m += 1 if n % 3 == 0
n = n + m
puts n
end
1
2
4
5
6
8
9
10
12
13
14
16
17
18
20
21
22
24
25
26
28
29
30
32
33
34
36
37
38
40
41
42
44
45
46
48
49
50
52
53
54
56
57
58
60
61
62
64
65
66
68
69
70
72
73
74
76
77
78
80
81
82
84
85
86
88
89
90
92
93
94
96
97
98
100
101
102
104
105
106
108
109
110
112
113
114
116
117
118
120
121
122
124
125
126
128
129
130
132
133
=> 100
```
こちらのコードになりました。
書いてみたら大したことないコードになったので、設計のところでちゃんと考えて気がつけるかどうかって感じでした。

まだリファクタリングやテストコードを書いてちゃんとやるってのが出来ていないのでまた改善して再度更新します.

---

#5/6時点#
コメントで[@jnchito](https://qiita.com/jnchito)さんに指摘を頂いて、
`最初に100本購入した場合、トータルで何本飲めるか。`の
ところも誤った認識で違うコードを書いていました。
考えとしては
`３本買ったら１つ無料`だと思ってたのが誤りで、文章通り
`空き瓶3本で新しい飲み物を1本無料`が正しいのと、
`最初に購入した飲み物の本数から、トータルで飲める本数を算出するプログラムを作成せよ。
また、最初に100本購入した場合、トータルで何本飲めるか。`
と求めている式が違っていました。

以下はまず`最初に100本購入した場合、トータルで何本飲めるか。`を求める式を考えることにしました。
まずは`n = 購入した本数`, `m = ボーナスボトル`, `sum = 合計の本数`と置き換えて考えたんですが、

```
100.times do |sum|
n += 1
m += 1 if n % 3 == 0
sum = n + m
sum += 1 if sum % 3 == 0
puts sum
end
1
2
4
5
7
8
10
10
13
13
14
.
.
.
127
128
130
130
133
133
```

コードの解説をすると、
１００回繰り返す（ボトルを買う）中で
`n += 1`がボトルを購入、
`m += 1 if n % 3 == 0`がボトルを３本になる毎にボーナスボトルを１本追加するという意味で、
`sum = n + m`が（購入したボトル + ボーナスボトル）の合計になります。
`sum += 1 if sum % 3 == 0`でボトルの合計が３の本数であれば+1でボーナスボトルを追加というものになってます。

ただこれで出力結果に３の倍数はなくなったものの、数字が重複してしまい１００本購入した時の結果も期待とは異なるもののままです。

この後も色々考えて試してみたんですが結局この問題を解くことはできなかったです（小３の算数の問題...）。
２日で５ｈ以上考えたんですが最終的には上記のコードで少し前回のものから表示結果が変わっただけで期待する結果が出るコードを今の所を書くことができませんでした。

学習効率の観点で今回でこの問題は一旦解くのを中断してまた新しい繰り返しや上手な処理の仕方を知ったり閃いたら解答を再開しようかなと思います。
1対多の関連付け時に失敗したこと

# 環境
- Ruby 2.6.1
- Ruby on Rails 5.2.3

# 起こった事象
1対多の関連付けを行うために以下のようなコードを書いた。

```ruby:user.rb
class User < ApplicationRecord
  has_many :footprints, foreign_key: 'user_id', dependent: :destroy
end
```
```ruby:footprint.rb
class Footprint < ApplicationRecord
	belongs_to :users
end
```

この状態でfootprintモデルのcreateを行うと、以下のエラーが出る。

```
ActiveRecord::RecordInvalid (バリデーションに失敗しました: Usersを入力してください)
```


# 原因
belongs_toで指定するモデル名は**単数形で指定**しないといけなかったため、
footprintモデルと関連するモデルが存在しないことになっていた模様。

そのため、以下のように修正する必要がある。

```ruby:footprint.rb
class Footprint < ApplicationRecord
	belongs_to :user
end
```
マイグレーションファイルでは普通に複数形で書いていたので、
こちらも同じだろうと複数形で書いた結果、こうなってしまった。

単数形でなければいけないのか、複数形でなければいけないのか、
気をつけようと思う。
TypeScript: 配列から要素の型を取得する

`number`型の添字を使うと配列から要素の型を取得可能。

```ts
const MyArray = [
    { name: "Alice", age: 15 },
    { name: "Bob", age: 23 },
    { name: "Eve", age: 38 }
];

type T = (typeof MyArray)[number];
// => type T = { name: string; age: number; }

```

---

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">添字にnumber型のこの挙動本気で初めて知った <a href="https://t.co/EnKcsSHsd0">pic.twitter.com/EnKcsSHsd0</a></p>&mdash; あかめ@グダグダ言ってないでコード書けハゲ.js (@akameco) <a href="https://twitter.com/akameco/status/1124278078518120450?ref_src=twsrc%5Etfw">May 3, 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
UbuntuでC, C++の開発環境をインストールしてHelloWorldしよう！

# はじめに

この記事では、  
1. UbuntuにC/C++言語の開発環境をインストールする
2. HelloWorldする  
の2つについて書いていきまーす

# 前提環境

* Ubuntu 18.04.2 LTS

# 1. UbuntuにC/C++言語の開発環境をインストールする

C/C++言語はコンパイラ言語であるため、コンパイルした後実行する必要があります。  
実は、Ubuntuにはデフォルトでコンパイラが入っています。  
ctrl+alt+t キーを押すことでターミナルが開くので、以下のコマンドを実行して確認してみましょう。  
gccはC用のコンパイラで、g++はC++用のコンパイラです。  

```
$ gcc --version
$ g++ --version
```

僕の環境ではgcc7.4.0、g++7.4.0のバージョンが入っていることがわかります。  

![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289151/b3b47b9c-41eb-e95c-d02b-78b734904916.png)

しかし、現在のUbuntuではコンパイルしたプログラムを実行することはできません。  
そこで、build-essentialというパッケージにgccなどのコンパイラを含むプログラムを実行するために必要なツールを入れます。
ターミナルで以下のコマンドを入れてみましょう。  

```
$ sudo apt install build-essential
```

これでC/C++のインストールが完了するはずです！  
僕の環境ではこのコマンドを実行したときエラーが出ました。
これについては、別記事にて書いていきます。  

# 2. HelloWorldする

それでは無事C/C++の環境構築ができたところで、HelloWorldをしましょう！  

## C

まずはC言語のHelloWorldをやっていきましょう。  
以下のコードを入力してください。  

```C:hello.c
#include <stdio.h>

int main(void)
{
    printf("Hello World!\n");

    return 0;
}
```

そして、ターミナルでファイルを保存したディレクトリを開き、以下のコマンドを実行するとHello World完了です！  

```
$ gcc -o hello hello.c
$ ./hello
Hello World!
```

また、1行でコマンドを書くこともできます。  

```
$ gcc -o hello hello.c && ./hello
Hello World!
```

![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289151/2005d399-0931-0934-64d3-b745d5556d80.png)

## C++

次はC++言語のHelloWorldをやっていきましょう。  
以下のコードを入力してください。  

```C++:hello.cpp
#include <iostream>

int main()
{
    std::cout << "Hello World!" << std::endl;

    return 0;
}
```

そして、ターミナルでファイルを保存したディレクトリを開き、以下のコマンドを実行するとHello World完了です！  

```
$ g++ -o hello hello.cpp
$ ./hello
Hello World!
```

また、Cと同様に1行でコマンドを書くこともできます。  

```
$ g++ -o hello hello.cpp && ./hello
Hello World!
```

![2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289151/88dc6c0d-eee3-fb42-20ec-84cb93d74eaa.png)

# まとめ

この記事では、C/C++言語の開発環境を構築し、Hello Worldをしました！  
僕の環境は特殊だったためめんどくさいエラーが出てしまいました。  
これについては別記事にまとめていくので、よかったらまた見てください〜。  

# 参考記事

* [How to Run C/C++ Programs in Linux [Terminal & Eclipse]](https://itsfoss.com/c-plus-plus-ubuntu/)
Kotlinで条件分岐

## KotlinのVersion
1.3.31

## if式

```Hello.kt
fun main() {

    var num1 = 3
    var num2 = 4

    // ふつーにこう書ける
    if (num1 < num2) {
        println("num1の方が小さい")
    } else {
        println("num2の方が小さい")
    }

    // if式は値を返すこともできるのでこうも書ける。ただしelseがないとコンパイルエラーになる。
    var message = if (num1 < num2) "num1の方が小さい" else "num2の方が小さい"
    println(message)

    // 関数の引数にもif式は書ける。ただしelseがないとコンパイルエラーになる。
    println(if (num1 < num2) "num1の方が小さい" else "num2の方が小さい")
}
```

## when式
Javaのswitch文のようなもの。

```Hello.kt
fun main() {

    // 値によって条件分岐 ※以下の式は「not applicable」となる
    var num = 9
    when (num) {
        1 -> println("1")
        2 -> println("2")
        in 4..7 -> println("4～7")
        !in 8..9 -> println("not 8 or 9")
        else -> {
            println("not applicable")
        }
    }

    // 式の評価値によって条件分岐
    when {
        num * 2 == 16 -> println("num = 8")
        num + 2 == 16 -> println("num = 14")
        else -> println("num = ？？？？")
    }

    // こういうのもできる。この場合、var x だとコンパイルエラーとなるので、val xで宣言する
    when (val x = Math.random() + Math.random()) {
        1.0 -> println("1.0")
        else -> println("not 1.0")
    }
}
```
Windows踏み台のログイン証跡の賢い取り方

## はじめに
Windowsで踏み台サーバを構築するケースってありますよね？

そんなWindowsの踏み台サーバのログイン証跡って
イベントログのSecurityから拾っている人が多い気がするんですが、もっと良い方法があるんです！

## 利用環境
・Windows7以降、WindowsServer2008R2以降
・Winlogbeat 6.5.4 (どのバージョンでもOKのはずです)

## 監査証跡として使えるイベントログ一覧
- このMicrosoft-Windows-TerminalServices-LocalSessionManager/Operationalが使えます。

| EventLog名 | EventID | 説明 |
|------------|---------|------|
| Microsoft-Windows-TerminalServices-LocalSessionManager/Operational | 21 | OSログイン成功 |
| Microsoft-Windows-TerminalServices-LocalSessionManager/Operational | 23 | OSログオフ成功 |
| Microsoft-Windows-TerminalServices-LocalSessionManager/Operational | 24 | OSセッション切断 |
| Microsoft-Windows-TerminalServices-LocalSessionManager/Operational | 25 | OSセッション再接続 |
| Security | 4625 | OSログイン失敗 |

- ログイン成功を[Security]の[4624]で拾おうとすると**OSログイン以外でも**結構ログが出ます。
- 正確な監査が出来ないので、自分は上記のイベントログを監査に利用するようにしています。
- リモートデスクトップ接続でもローカルでのログインでも同じようにログが出ます。

## イベントビューアーで見てみると
- [アプリケーションとサービスログ] > [Microsoft] > [Windows]のかなり下の方にあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/c740bc5c-81a0-8b16-c700-b3340e00ae7c.png)

- [TerminalServices-LocalSessionMAnager] > [Operational]を開きます。
- ログイン成功の場合のEventID21は以下のような情報が出ています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/c380c17c-898d-c68a-abe6-d896af4d6a63.png)

## Winlogbeatを使ってログを可視化
- Windowsのイベントログを監査などに利用する場合にオススメはElastic社の[Winlogbeat][00]です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/31fc8b1f-1112-b206-ca48-7e91092fa16d.png)

※導入手順は以下を参考にしてみると良いと思います。
**【参考】**
・[Windows のイベントログを Winlogbeat+Elasticsearch+Kibana で可視化する][01]

本投稿で紹介したイベントログを取得する場合の設定は以下の通りです。

```ruby:winlogbeat.yml
#======================= Winlogbeat specific options ===========================
winlogbeat.event_logs:
  - name: Microsoft-Windows-TerminalServices-LocalSessionManager/Operational
    tags: ["login"]
    event_id: 21,23,24,25
  - name: Security
    tags: ["login"]
    event_id: 4625

#================================ Outputs =====================================
#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
  # Array of hosts to connect to.
  hosts: ["<ElasticsearchのIPアドレス>:9200"]
```

- EventLog名とEventIDを指定するだけでほしいイベントログをXML→JSON変換してOutputしてくれます。
- Elasticsearchにoutputするだけで正規化は勝手にWinlogbeatが行ってくれるので超便利です。

[00]: https://www.elastic.co/jp/products/beats/winlogbeat "Winlogbeat"
[01]: https://mseeeen.msen.jp/visualize-windows-event-log-winlogbeat-elasticsearch-kibana/ "Windows のイベントログを Winlogbeat+Elasticsearch+Kibana で可視化する"
connpassのイベントの参加者の一覧を取得するAPI

`https://asia-northeast1-notify-send.cloudfunctions.net/connpass-applicants/`の後ろに
connpassのイベントのURLをくっつけてGETリクエストすると全参加者(抽選中、参加者、補欠者、キャンセル)のJSONが帰ってきます。

[試す](https://asia-northeast1-notify-send.cloudfunctions.net/connpass-applicants/https://connpass.com/event/127970/)

```bash
curl https://asia-northeast1-notify-send.cloudfunctions.net/connpass-applicants/https:/dockerjp.connpass.com/event/127379/
```

[【閲覧注意】ソースコード](https://gist.github.com/GitHub30/951849edff73ca10f185cd688a93e57d)

![Screenshot from 2019-05-04 03-38-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/38405ad2-3716-b5dc-6d0c-649804f886a7.png)
ASUS X205TA に Linux Mint 19.1 Tessa(MATE) をインストールする際にハマった点

ウルトラモバイルPCである ASUS X205TA に、 Linux Mint 19.1 Tessa(MATE) をインストールした。一通りのインストール作業が終わり、現在のところは問題なく動いているが、何点かハマった事柄があった。備忘がてら記述しておく。

# インストール以前の問題… 32bit UEFI に立ち向かえ

ASUS X205TA は、**32bit UEFI** という特殊なファームウェアが使われている。一方で、各種Linuxは 32bit UEFI というファームウェアの存在を考慮しておらず、インストール用の ISO イメージも 32bit UEFI には対応していない。そのため、通常の手順では、 X205TA に各種 Linux をインストールすること、それ以前に X205TA で各種 Linux を起動すること自体が不可能なのである。

ではどうするか？解決策は先人たちが既に編み出していた。

GitHub に、 [bootia32.efi](https://github.com/jfwells/linux-asus-t100ta/blob/master/boot/bootia32.efi) というファイルが公開されている。 32bit UEFI 用のブートモジュールである、これをダウンロードした上で、 Linux Mint の ISO イメージを展開したブータブルUSBファイル上にある `\EFI\BOOT\` 以下にコピーすればよい。

## 参考情報

- [32bit-UEFI環境でLinux-MintをUSB-bootする - Segmentation Fault](https://www.segmentation-fault.xyz/entry/2017/05/28/232406)

# インストールのために Wi-Fi に接続する必要がある、けれど初期状態では Wi-Fi 接続ができない

端末を起動し、以下のコマンドを順番に実行していけばよい。

```
sudo cp /sys/firmware/efi/efivars/nvram-74b00bd9-805a-4d61-b51f-43268123d113 /lib/firmware/brcm/brcmfmac43340-sdio.txt
sudo modprobe -rv brcmfmac
sudo modprobe -v brcmfmac
```

最初に入力する `cp` コマンドにおいて、 nvram 以下の UUID が長いので、タイプミスを避けるため、 `ls /sys/firmware/efi/efivars/nvram*` の実行結果をコピーアンドペーストするとよいだろう。

## 参考情報

- [ASUS EeeBook X205TAにUbuntu 16.04 LTSをインストール - Qiita](https://qiita.com/furipon308/items/ab89d022e35d40284682) - @furipon308氏による

# 入力メソッドの設定

Linux Mint の使用言語を日本語としてインストールした場合、初期状態ではキーボードのキー配置が JIS 配置であると認識される。 US 配置のキーボードを使っている場合、これでは記号の入力がままならない（とりわけ `*` や `=` 、`_` などの入力がままならないのは致命的）。キーボードのキー配置を US 配列として認識させる必要がある。その基本的な手順は、[LinuxMintでキーボード配列を変更する（JP→US） - とあるSEの備忘LOG](http://sebarabara.com/linuxmint_key_set/)に記載のとおりである。ただし、必須パッケージの `fcitx-config-gtk` は、 Linux Mint 19.1 では初期状態でインストールされていた。

# `/home` のマウントポイントの変更

基本的な手順は、[既にインストール済みのUbuntuでhomeディレクトリを移す方法 - PCとか覚え書き](http://pctokaoboegaki.blog.fc2.com/blog-entry-2.html)に記載のとおりである。ただし、 `/etc/fstab` の編集内容だけが異なるため、以下に記載する。

```
UUID=[確認したUUID] /home ext4 errors=remount-ro 0 1
```

`/etc/fstab` の内容を間違えると、 Linux Mint が正常に起動しなくなり、 Emergency Mode 入りすることとなる。冷や汗ものである。

# Chocolatey に存在する、役に立ったツール

* [Rufus](https://chocolatey.org/packages/rufus)
  * ISO イメージを展開して、ブータブル USB フラッシュメモリを作成するソフト
【メモ】RedashのAlertsでSlack連携する際にメンションをつける

Redashの[Alerts](https://redash.io/help/user-guide/alerts)機能を使用すると、RedashとSlackの連携を行うことができ非常に便利だ。

諸々の設定は [実は便利な Redash の「アラート機能」 - kakakakakku blog](https://kakakakakku.hatenablog.com/entry/2017/12/11/000054) がわかりやすいので参照。

本記事は、RedashのAlertsでSlack連携する際にメンションをつける方法についての簡単なメモ。

# 方法
普通にRedashのAlertのNameに「 `@channel テストです`」と入力しても、Slack上では、メンションがうまく行われない。

Create > Alert でQueryを選択した後に表示されるNameの中に [SlackのIncoming Webhooksでメンションを飛ばす方法 - Qiita](https://qiita.com/ryo-yamaoka/items/7677ee4486cf395ce9bc) を参考して、記法を埋め込めば良い。

例えば、 `@channel テストです` のようにメンションをつけてSlackに通知したければ、RedashのAlertのNameに「<!channel> テストです」と入力する。

# 参考にさせていただいた記事
[SlackのIncoming Webhooksでメンションを飛ばす方法 - Qiita](https://qiita.com/ryo-yamaoka/items/7677ee4486cf395ce9bc)

[Alerts](https://redash.io/help/user-guide/alerts)

[実は便利な Redash の「アラート機能」 - kakakakakku blog](https://kakakakakku.hatenablog.com/entry/2017/12/11/000054)
youtube-dlを用いて自動で最高画質ダウンロードするbashスクリプトを書いた

# 違法なダウンロードは違法です
このスクリプトは自分自身でアップロードしたyoutubeの動画をニコ動にもアップするため書きました。
違法なダウンロードはやめましょう。

# 前提となる条件
* youtube-dl
* ffmpeg
* bash
* awk

# スクリプトはこちら
[Github_yd-maximizer](https://github.com/minato-eigenport/yd-maximizer/blob/master/yd-maximizer.sh)

# 使い方
```bash
#url.txtにdownloadする動画のURLを書きこむ
cat ./url.txt
https://www.youtube.com/watch?v=XXXXXXXXXXX
https://www.youtube.com/watch?v=YYYYYYYYYYY
#コマンド
./yd-maximizer.sh
```
ずんだのポップル錯視問題 Ruby 編


```
杏マナー杏マナー杏マナー
杏マナー杏マナー杏マナー

ーナマ杏ーナマ杏ーナマ杏
ーナマ杏ーナマ杏ーナマ杏

杏マナー杏マナー杏マナー
杏マナー杏マナー杏マナー

ーナマ杏ーナマ杏ーナマ杏
ーナマ杏ーナマ杏ーナマ杏
```

上記のような錯視をポップル錯視（文字列傾斜錯視）と呼びます。詳細は以下リンク。

* [錯視 - Wikipedia](https://ja.wikipedia.org/wiki/%E9%8C%AF%E8%A6%96#%E3%83%9D%E3%83%83%E3%83%97%E3%83%AB%E9%8C%AF%E8%A6%96%EF%BC%88%E6%96%87%E5%AD%97%E5%88%97%E5%82%BE%E6%96%9C%E9%8C%AF%E8%A6%96%EF%BC%89)

ポップル錯視の文字列を出力するプログラムを以下のルールで作成してください。

## ルール
1. ポップル錯視を起こす単語は定数でハードコードする ※標準入力にしてもらってもいいです
1. 該当単語を1行あたり4回繰り返し、それを2行繰り返す
1. 該当単語を逆順にし、1行あたり4回繰り返し、それを2行繰り返す
1. 2 と 3 を 2 回繰り返す
1. 2 と 3, 3 と 2 の間に空行を出力する

なお、入力された文字列がポップル錯視を起こすものかどうかの確認は行いません。

## 出力例
```
杏マナー杏マナー杏マナー杏マナー
杏マナー杏マナー杏マナー杏マナー

ーナマ杏ーナマ杏ーナマ杏ーナマ杏
ーナマ杏ーナマ杏ーナマ杏ーナマ杏

杏マナー杏マナー杏マナー杏マナー
杏マナー杏マナー杏マナー杏マナー

ーナマ杏ーナマ杏ーナマ杏ーナマ杏
ーナマ杏ーナマ杏ーナマ杏ーナマ杏
```

### ポップル錯視を起こす単語 - 令和モナー
```
令和モナー令和モナー令和モナー令和モナー
令和モナー令和モナー令和モナー令和モナー

ーナモ和令ーナモ和令ーナモ和令ーナモ和令
ーナモ和令ーナモ和令ーナモ和令ーナモ和令

令和モナー令和モナー令和モナー令和モナー
令和モナー令和モナー令和モナー令和モナー

ーナモ和令ーナモ和令ーナモ和令ーナモ和令
ーナモ和令ーナモ和令ーナモ和令ーナモ和令
```

## プログラム
```ruby
POPPLE_ILLUTION = "杏マナー"
popple_illution_words = Array.new(4, POPPLE_ILLUTION)
popple_illution_rows = []
2.times do
  2.times { popple_illution_rows << popple_illution_words.join }
  popple_illution_rows << ""
  2.times { popple_illution_rows << popple_illution_words.map(&:reverse).join }
  popple_illution_rows << ""
end

puts popple_illution_rows.join("\n")
```

### 出力
```
杏マナー杏マナー杏マナー杏マナー
杏マナー杏マナー杏マナー杏マナー

ーナマ杏ーナマ杏ーナマ杏ーナマ杏
ーナマ杏ーナマ杏ーナマ杏ーナマ杏

杏マナー杏マナー杏マナー杏マナー
杏マナー杏マナー杏マナー杏マナー

ーナマ杏ーナマ杏ーナマ杏ーナマ杏
ーナマ杏ーナマ杏ーナマ杏ーナマ杏
```