OmniAICreator/Qiita-1.07M huggingface dataset:
Python3での非同期処理まとめ

- Python3.5から、非同期処理がデフォルトで利用できます。
    - 完結にまとめしたくて書きました。
    - https://docs.python.org/3/library/asyncio-task.html

- async処理の考えかたやメリットはここ
    - https://qiita.com/icoxfog417/items/07cbf5110ca82629aca0

## 1.シンプルなパターン
```py3

import asyncio

# 時間がかかる処理を含む関数
async def compute(x, y):
    print("Compute %s + %s ..." % (x, y))
    # 時間がかかる処理にはawaitつける
    await asyncio.sleep(1.0)
    return x + y

async def print_sum(x, y):
    result = await compute(x, y)
    print("%s + %s = %s" % (x, y, result))

loop = asyncio.get_event_loop()
# async関数の実行
loop.run_until_complete(print_sum(1, 2))
```
結果
Compute 1 + 2 ...
1 + 2 = 3

https://docs.python.org/3/library/asyncio-task.html#example-chain-coroutines

# 2.並列で実行するパターン
```py3

import asyncio

# 時間がかかる処理を含む関数
async def factorial(name, number):
    f = 1
    for i in range(2, number+1):
        print("Task %s: Compute factorial(%s)..." % (name, i))
        await asyncio.sleep(1)
        f *= i
        
    print("Task %s: factorial(%s) = %s" % (name, number, f))

loop = asyncio.get_event_loop()
# 並列で実行 -> tupleで返す
result = loop.run_until_complete(asyncio.gather(
    factorial("A", 2),
    factorial("B", 3),
    factorial("C", 4),
))

```
結果
Task C: Compute factorial(2)...
Task B: Compute factorial(2)...
Task A: Compute factorial(2)...
Task C: Compute factorial(3)...
Task B: Compute factorial(3)...
Task A: factorial(2) = 2
Task C: Compute factorial(4)...
Task B: factorial(3) = 6
Task C: factorial(4) = 24

TaskA,B,Cが並列で実行されていることがわかる。

## 3.ちょっと綺麗に
gatherの中を綺麗に表現するためには以下のようにできる。やっていることは2と全く同じ

```py3
loop = asyncio.get_event_loop()
name_number_list = [("A",2),("B", 3),("C", 4)]

parallel_tasks = tuple(map(lambda name_num: factorial(*name_num), name_number_list))
    
result = loop.run_until_complete(asyncio.gather(*parallel_tasks))
```

https://docs.python.org/3/library/asyncio-task.html#example-parallel-execution-of-tasks
ハードウェアRAIDコントローラーをソフトウェアRAIDしようとして起動しなかった話

## ごあいさつ
鯖缶のくせに何を当たり前のことを書いているんだ、と思われる方は非常に多いと思いますが、アプリ屋あがりにはコレが結構難しい話だったので、備忘録がてらまとめておきます。
まさかこれだけのことのために２日もハマるとは思わなかったので……。

## 環境（ほかの環境でも起こりえる可能性があります）
+ サーバーラックに格納するタイプの大きなアレ
+ 専用RAID-SASコントローラー(MegaRAID)
  + 後で知ったんですが、RAID機能がないSASコントローラーがあるそうです。お使いの機種にあるかどうかは要確認：サポート契約が必要？） 
+ ハードディスク(SAS)
+ Ubuntu 14.04 Server（2017/11/07 時点で最新を使用）

## こうすると動きました
名称はなんとなくでつけてます。手順はあってますが表記はうろ覚え。

### 電源を入れる前に
1. 【要検証】HDDはVirtual Driver Group0で構築するものだけにする

### BIOS側
1. **SATA,eSATAのコントローラー設定をRAIDにしない**
2. ブートオプションにHard Disk(Raid Adapter)を選択。UEFIではない
3. ブートオプションメニューの下の方にあるHDD BBS Propertiesの起動メニューを2.と同じにする。この場合Hard Disk(Raid Adapter)

### Raidコントローラー側(MegaRAID)
1. 通常通り、Virtual Driver Groupなどを設定
2. **Ctrl MngのブートさせたいVirtual Driver Groupを指定**

### OSパーティション設定
1. この前段までは普通に環境に合わせて設定
2. ブート領域を設定。色々なサイトを参考にすると1Mぐらい？確保するとありますが、私はインストールガイドが指定する容量を設定しました。

ここで一つでも間違っているとGRUBレスキューモードが起動したり、Kernel Panicが起こったり(エラーメッセージはVFS...)最悪の場合、BIOS起動後に反応が返ってこなくなりました。

### 注
なお、Virtual Driveを設定する際に、同時にイニシャライズしておかないとOSレベルのパーティション設定でブートローダーがコケる？ようです。
私の環境だけかもしれませんが、後のOSインストール時にシステム領域のHDD以外を挿した状態だとOSがどこにインストールされたか分からず、GRUB rescueが起動します。

## 原因考察
考察と書いているのはメーカー側のサポートの範疇を超えてしまっているのと、私も正直説明が難しいからです……。

+ ハードウェアRAIDコントローラーをソフトウェアRAIDすると起動しなかったのは、BIOSレベルでRAID制御をしようとしているものの、参照先がHDDなどではなくハードウェアRAIDコントローラーであるため『そんなもんねーです！』と突き返されてしまっている。
  + ただし、OSインストール自体はできる。どこにインストールされているのかはこれまた分からないですが……
+ BIOSが見ている記憶領域とハードウェアRAIDが管理している記憶領域(Virtual Driver - 実記憶領域)は別物？
  + ハードウェアRAIDコントローラーのブート設定でVirtual Driveの指定をしてますが、OSのインストールはこの辺りをよろしくやってくれていない？
+ インストールするOS種類、あるいはバージョンが古いために起こっている？
  + Ubuntu 16.04 GUIだと何とかなってるっぽい。その時の設定を覚えていないので要検証

他にもいろいろガチャガチャやってたので、考察内容に記憶違いの情報が混ざってるかもしれません。

## ちなみに
別メーカーのサーバーラック用のPCで似たような構成のもので試しましたが、こちらでも再現しています。

# 追記
HDDが2TB以上のパーティションにOS入れようとしていたので、いわゆる2TBの壁問題にぶちあたってこうなってしまったんじゃないか？
という可能性は高いです。
運用上検証の意味がなかったので精査していませんが、考えられる要因の一つとして挙げておきます。

# さらに追記
Ubuntu16.04やCentOS7.3で上記問題が再現しなかったので、OSがハードウェアRAIDに対応しているかどうかが関係しているかもしれません。
LaravelのExistsバリデーションで存在チェックする列名がパラメータのnameと異なる場合の解決策

LaravelのバリデーションのExistsの存在チェックで、
Ruleを利用した少し複雑なチェックをするときにテーブルの列名がパラメータのnameと異なる場合、
マニュアルに記載がなかったので共有。

## 環境

|名前|バージョン|
|---| -------- |
|PHP | 7.1.6    |
|Laravel| 5.5.14 |

## 解決方法

存在チェックするテーブル「posts」の「id」列にパラメータのpost_idが存在するかチェックする場合、
`Rule::exists()`の第二引数にテーブルの列名を指定すればOKです。
以下のような感じです。

```php
$request->validate([
    'type' => 'required|integer',
    'post_id' => [
        'required',
        'integer',
        Rule::exists('posts', 'id')->where(function ($query) use ($request) {　　// ★この行
            $query->where('type', $request->input('type'));
        }),
    ],
]);
```

バリデーションのソースを読むと、

```Illuminate\Validation\Rule.php
    /**
     * Get a exists constraint builder instance.
     *
     * @param  string  $table
     * @param  string  $column
     * @return \Illuminate\Validation\Rules\Exists
     */
    public static function exists($table, $column = 'NULL')
    {
        return new Rules\Exists($table, $column);
    }
```

とあり、列名を指定しろとありました。。
Macで外部ディスプレイを認識できなくなったときの解決策

[こちらの記事](https://qiita.com/ij_spitz/items/9639231b824b874ca5ce)のコマンドを直接打てるようにしただけです。

何も考えず、下記をターミナルに打ち込んで再起動。

```
sudo rm /Library/Preferences/com.apple.windowserver.plist
sudo rm /Users/$USER/Library/Preferences/ByHost/com.apple.windowserver.*.plist
```

途中でパスワード聞かれるので入れる。
ワイヤーフレーム制作

##ワイヤーフレーム制作でとても大切なこと

###ワイヤーフレームの目的
クライアントの目的を達成するための手段を考えること

①操作性を重要視する
ユーザーが操作出来ないとそもそも使ってもらえない

②派手な演出はＮＧ
FLASHや過度なアニメーションはユーザーにウザがられる

③目的を明確にする
あくまでWEBサイトは目的を達成するための手段。最短でユーザーを目的に誘導する


##ワイヤーフレーム作成手順

①WEBサイト制作の依頼内容をヒアリングする
依頼者がなぜWEBサイトを作りたいのか？目的や背景を知る

②同じジャンルのWEBサイトを徹底的に調査する
世の中に出ているWEBサイトは、良いデザイナーの知識の塊。良いところは頂戴する

③手書きでアイディアを書き出す
仕組みやレイアウトを書き出す

④PC上で清書
これを見てデザイン制作が出来るよう、詳しく頂戴する
文言などはダミーでもOK

ワイヤーフレームのツール
CACOO
MOCKUPS
など



##第一段階のヒヤリング

※ヒヤリングとは？？
依頼者の要件を聞き出す行為
聞き出す→具体的な提案する

STEP１
WEBサイト制作の目的をはっきりさせる

STEP２
ターゲットを明確にする

STEP３
目的をターゲットに対する手段を決める

STEP４
企画やコンテンツを考える

STEP５
コンテンツの優先順位をはっきりさせる
(ページ構成)

##WEBサイトを構成するパーツと構成について

![alt](https://i.gyazo.com/2f1fd2d4886552e4ebfaf8f544b55ba2.png)

・ヘッダーの役割
ヘッダーは決めたら動かさない

・メインビジュアル
利用したくなるようなPR部分
写真と一緒が多い

・ローカルナビ
カテゴリー一覧などの部分
カテゴリーがなければなくてもOK

・フッター
ページ情報やローカルナビと同じような記載をしたりする
なぜかというと、カテゴリーなどが多かったり、ページがながかったりすると、
スクロールしたときに、カテゴリーを選べるようにするため

##初心者のためのワイヤーフレーム制作

①手書きでアイディアを書き出す

②PCで清書する
クライアントに見せる

テキストと四角型が打ち込めればOK

##失敗しないワイヤーフレーム制作

①ファーストビュー
ヘッダー、メインビジュアルなどの部分。
開いたときに見える部分。

②視線の動き
Z型

F型
こっちの方が多い

同じ目的のサイトを徹底的に分析して、良いところを真似する
大体20サイトくらいは見る

io3000.comとかを参考にするといい

##
スクラムの朝会で毎回意識する5つのこと


## 目的
* チーム(自分自身)がスムーズに仕事を始められるようになるため
* 15分以内も立ちながらなのもそのため。

## 問題解決の場にしない
* 朝会が終わったら関係者だけで話す時間をもらうようにする

## 成果物ベースで話す
* やったことでは価値を感じにくい
* ドキュメントや機能など「動くもの」で顧客にとって価値のあるものを話す
* ここで言う顧客とはプロジェクトマネージャーや発注者をイメージ

## タスクはある程度具体的に話す
* 「XXを実装します」だけでは毎回同じ内容になってしまう
* そのため1タスク30秒を目安にどの機能のどの部分に対して何をしてどんな成果物を出すかを考えてメモに書いておく

## 価値を損なうような問題のみ共有する
* 自分だけが困るような問題はチャットで聞けば十分
* 直接相談したいことがあるなら、朝会後に話す
* ただしプロジェクト全体の価値を損なうような重大な問題は詳細に共有する

## 感謝の言葉を伝える
* タスクで他の人に助けてもらったら感謝を伝える
* チームの雰囲気がよくなる

これらをやってみてさらにブラッシュアップしていこうと思います！
プチコンによるペイントツール作成覚書

#はじめに

この項ではNintendo3DS用ダウンロードソフトであるところのBasic処理系「プチコン3号」で
ペイントツールを制作しているのでその覚書を書いていく

尚この文章は随時更新されてゆく予定

プチコンでペイントツールを書くのは取っ掛かりとして
わかりやすいテーマなのではないだろうか？

#基本構造

- 1:タッチ座標取得
- 2:タッチしているか調べる
- 3:タッチしてたら座標を基準にGRPに描画
- 4:最初に戻る

これだけ

# 拡張構造

## GRP直接描画、線種は点のみ
基本構造、ただこれだとタッチパネルの座標サンプリング速度に依存するのでこれに肉付けしていく。

## GRP直接描画、線種は線
つながる、GLINEで引いても良いし、自前で線描画関数を組んでもいいでしょう。
GLINEだと透明度設定は考慮できない
半透明にした場合、touchの取得座標の為に描画開始座標と終点座標が重なるのでその対策を取る必要がある
(開始点か終点かどちらかを描画しないでおく)

## 編集配列+描画GRP
GRP階調以上(15bit色以上)の色数を確保したい場合に必要になってくるでしょう
juhsyでは内部32bitで色を配列に保持→GLOADで自動変換してもらってます

## 編集配列+表示配列+表示GRP

## 描画配列+編集配列+表示配列+表示GRP
## 描画配列+編集配列n(レイヤ)+表示配列+表示GRP
## 描画配列+描画レイヤ+編集配列n(レイヤ)+表示配列+表示GRP

#ビット数と色数


# 描画アルゴリズム
## 点
### 透明度がある点描画
## 線
### アンチエイリアス線
## 矩形フィル描画
### 円フィル描画
### 縁取り描画
## エアブラシ
## バケツ
###バケツブラシ
##色相ジッター



#色
#RGBとビット数
#HSV色相系

#undo/REDO

#表示色より多くの階調を内部に保持する
#回転
#拡大縮小
rails + webpacker環境でredux-sagaを使ったら'regeneratorRuntime is not defined'が発生したときの解決方法


# 概要
* raisls + webpackerでredux-sagaを導入したら、`regeneratorRuntime is not defined`が発生
* （redux-sagaのためにはじめて）定義したジェネレータ関数`function*`が原因
* babel-polyfilで変換してやれば解決

# 環境
* Rails: 5.1.4
* webpacker: 3.0.2
* redux-saga: 0.16.0
* [Reduxの非同期処理ライブラリをいろいろ試してみた！](https://qiita.com/yutasuzuki/items/d3952d1d2b9a090801d2)を参考にredux-sagaのコードを書いた。

# エラー
## 対象のコード
sagaが原因ではなく、ジェネレータ関数`function*`が原因なので本質的ではないですが、参考までにエラー対象のファイルを示します。

```app/javascript/sagas/mySaga.js
import {call, takeLatest} from 'redux-saga/effects'
import {getColor} from '../modules/Api'
import {FETCH_COLOR} from '../actions/items'

export function* fetchColorFlow() {
  const response = yield call(getColor)
  if (response) {
    console.log(response)
  }
}

function* mySaga() {
  yield takeLatest(FETCH_COLOR, fetchColorFlow);
}

export default mySaga;
```

## エラー内容
```
Uncaught ReferenceError: regeneratorRuntime is not defined
```

# 解決方法
babel-polyfilをインストールしてジェネレータ関数を使うファイルで読み込めばOK。

* インストール

```console
yarn add babel-polyfil
```

* 読み込む

```app/javascript/sagas/mySaga.js
import {call, put, takeLatest} from 'redux-saga/effects'
import {getColor} from '../modules/Api'
import {FETCH_COLOR} from '../actions/items'
import 'babel-polyfill' // これを読み込む
// 以下同じなので省略
```

# 参考
* http://taisyo7333.hatenablog.com/entry/2016/11/22/102427
* https://qiita.com/devneko/items/c7ddb31f504c8c2a5ac5
SpriteKitでグラフ描画

備忘録
SpriteKitで、折れ線グラフの描画を初期プロトタイプした時のメモプログラム。

```swift

import SpriteKit
import AudioKit

class VisionScene: SKScene {
     
    //-----------------Draw Lines
    var lineNode: SKShapeNode!
    var linePoints = [CGPoint]()

    /// Sceneが表示された時に呼ばれる
    override func didMove(to view: SKView) {
        self.initializeLine()
        
        linePoints.append(CGPoint(x:0, y:0));
        linePoints.append(CGPoint(x:0, y:10));
        linePoints.append(CGPoint(x:0, y:20));
        linePoints.append(CGPoint(x:0, y:30));
        linePoints.append(CGPoint(x:0, y:40));
        linePoints.append(CGPoint(x:44.0, y:-187.0));
        linePoints.append(CGPoint(x:55.5, y:-73.5));
        linePoints.append(CGPoint(x:66.5, y:-44.5));
        linePoints.append(CGPoint(x:77.0, y:-38.5));
        linePoints.append(CGPoint(x:88.5, y:-46.5));
        linePoints.append(CGPoint(x:99.5, y:-46.5));
        linePoints.append(CGPoint(x:110.5, y:-46.5));
        linePoints.append(CGPoint(x:120.5, y:-46.5));
        linePoints.append(CGPoint(x:130.5, y:-46.5));
        linePoints.append(CGPoint(x:140.5, y:46.5));
        linePoints.append(CGPoint(x:150.5, y:36.5));
        linePoints.append(CGPoint(x:160.5, y:26.5));
        self.drawLines(linePoints: linePoints)
    }

    func initializeLine(){
        lineNode = SKShapeNode()
        lineNode.zPosition = 2
        lineNode.strokeColor = UIColor.red
        lineNode.lineWidth = 9
        addChild(lineNode)
    }
    
    func drawLines(linePoints: Array<Any>) {

        if linePoints.count < 2 {
            activeSliceBG.path = nil
            return
        }
        
        let path = UIBezierPath()
        path.move(to: linePoints[0] as! CGPoint)
        
        for i in 1 ..< linePoints.count {
            print( linePoints[i])
            path.addLine(to: linePoints[i] as! CGPoint)
        }
        lineNode.path = path.cgPath
    }
      
}

```
raspberry pi 3 でstretch その5

#概要
raspberry pi 3 でstretchやってみた。
スクリーンショットやってみた。（画面キャプチャ）

#写真
![2017-11-07-071237_1024x768_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/18104/fd0ac688-263e-d656-b1df-12b5ed7efcf6.png)


#環境
Raspberry Pi 3 model B v1.2 element14
2017-09-07-raspbian-stretch

#実行

scrot -d 3

以上。
WordPressのカスタマイズ lightning + いくつかのプラグイン(1) インストール編

以前、以下のエントリーでテーマを選ぶならlightningかな、ということで、ようやく設定を開始。

- [WordPressのテーマをどうするかを考える - Qiita](https://qiita.com/yamazaki/items/d3f4c4a6a1e0e0943a6a)
- [Lightning - シンプルでカスタマイズしやすいWordPress.org登録無料テーマ - | ビジネスサイトにもブログにも最適。Bootstrapベースでカスタマイズも簡単！](https://lightning.nagoya/ja/)

WordPressって、この何年か(10年近くw)触っていなかったけれど、だいぶ便利になってきたのね。ほとんどのことが管理画面からポチポチすればできてしまう。手軽だわ。

で、lightningのテーマのインストールも、ほんの3クリックくらいでできてしまう。

- [Lightningのインストール | 設定ガイド](https://lightning.nagoya/ja/setting/basic/install)

あとは、テーマを入れた後に、以下の拡張プラグインのオススメが表示されるので、そのまま指示に従い、インストール

- [Lightning Advanced Unit — WordPress プラグイン](https://ja.wordpress.org/plugins/lightning-advanced-unit/advanced/)
- [VK All in One Expansion Unit — WordPress プラグイン](https://ja.wordpress.org/plugins/vk-all-in-one-expansion-unit/)

lightningを調べていると後者のプラグインのことは色々出てくるんだけど、前者のプラグインについては、なぜがあまり情報が出てこなかった。

前者は、Lightningを前提としているプラグインで、VK All in One Expansion Unit(‎ExUnit)は、他のテーマでも使える汎用化されているプラグインという扱いの違いらしい。

- [[ 重要 ] Lightning 2.0 での仕様変更について | Lightning - シンプルでカスタマイズしやすいWordPress.org登録無料テーマ -](https://lightning.nagoya/ja/archives/lightning_2_0_0)
- https://github.com/vektor-inc/lightning-advanced-unit
- https://github.com/vektor-inc/VK-All-in-One-Expansion-Unit

GitHubのREADME.mdにも、それぞれのプラグインのことが書かれているので見ておくと良い。

ということで、Lightningのテーマをインストールした後に、推奨されたプラグインをインストールして、プラグインの一覧から以下を有効化。

- Lightning Advanced Unit
- VK All in One Expansion Unit
- Akismet Anti-Spam (アンチスパム)
- WP Multibyte Patch

後半の2つは、初期インストールで勝手にインストールされているプラグインで、まだ、有効になっていなかったので、一緒に有効にしておいた。

その内、「Akismet Anti-Spam (アンチスパム)」については、以下を参考にして、Akismetの無料アカウントを作成してから設定をした。

- [⑲（おまけ）最初から入っているプラグイン「Akismet」の設定 | LifeworkPress [ライフワークプレス]](https://lifeworkpress.site/akismetsetting/)

で、メインは、以下。

- Lightning Advanced Unit
- VK All in One Expansion Unit

この2つのプラグインの細かい設定とか、できることについては、また別のエントリーで調べて、設定して逝く！
[Ruby] 機械学習①：Ruby入門

##前提
・Python が入っていること。
・Rubyがはいっていること : [[Rails]Debian8に Ruby + Rails を導入する。 ](https://qiita.com/chamao/items/46a071343a624f22ba39)

※Pyenvでの導入が簡単でいいように思います。また、Numpy、Matplotlibなど個別にインスト−する必要がある(Python側)ので、anacondaが便利かもしれません。

[データサイエンティストを目指す人のpython環境構築 2016](https://qiita.com/y__sama/items/5b62d31cb7e6ed50f02c)より抜粋
自分のの環境はvagrant上のDebian8です。

```bash
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc 
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ pyenv install -l | grep ana
$ pyenv install anaconda3-2.5.0
$ pyenv rehash
$ pyenv global anaconda3-2.5.0
$ echo 'export PATH="$PYENV_ROOT/versions/anaconda3-2.5.0/bin/:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ conda update conda
```

##NumPy

[GitHib mrkn/numpy](https://github.com/mrkn/numpy.rb)

```
$ gem install numpy
```

```rb:test_numpy.rb
require "numpy"

np = Numpy
x = np.array([1,2,3,4,5])
y = np.array([2,4,3,5,6])
puts x + y

z= np.array([[1,2],[3,4]])
puts z.shape

a = np.array([[1,2],[3,4]])
b = np.array([10,20])
puts a * b

n_arr = np.array([[12,43],[14,40],[90,209]])
for i in 0..n_arr.shape[0] - 1
  puts n_arr[i][1]
end

c = n_arr.flatten()
puts c
puts c[np.array([0,2,4])]
puts c[c>100]
```

・numpyの配列に対して、eachは使えない。
・代わりに上記のようにループを適応することはできる。


##Matplotlib
[GitHib mrkn/matplotlib](https://github.com/mrkn/matplotlib.rb)

```
gem install matplotlib 
```

```ruby:test_matplotlib.rb
require 'numpy'
require 'matplotlib/pyplot'

plt = Matplotlib::Pyplot
np = Numpy

# cos and sin
x = np.arange(0,6,0.1)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y1)
plt.plot(x,y2, line_style="--")
plt.xlabel("x")
plt.xlabel("y")
plt.title('sin & cos')
plt.legend()
plt.show()

# 散布図
x = np.random.randn(30)
y = np.sin(x) + np.random.randn(30)
plt.plot(x, y, "ro")     # "o"は小さい円(circle marker)
plt.show()

# 棒グラフ
plt.hist(np.random.randn(1000))
plt.show()

```

・plt.plot(x,y1,label="cos")として、ラベルをつけようとしてもうまくいかない。


##Pycallの位置づけ

[Data Analysis with Ruby using PyCall by Kenta Murata](https://speakerdeck.com/mrkn/data-analysis-with-ruby-using-pycall)
> Rubyスクリプトで生成したデータをpandasで加工してmatplotlibやseabornで加工する。

Railsだったら以下のような流れだと思う。
①Rails(Ruby)でデータの整形
②PycallからPython側でデータの処理
③Rails側で表示


##ハマりどころ
Linux(Ubuntu系)を使っているのですが、`find_libpython': PyCall::PythonNotFound (PyCall::PythonNotFound)`がで出て実行できませんでした。

自分の環境のpyenvなpythonであったので下記を参照にして解決した。
[Ruby の PyCall を使って pyenv な Python を使えるようにする方法](https://qiita.com/cesare/items/c4e7752fbe5aaff5a2ed#fn2)

```bash
$  which python
$  ls /opt/pyenv/versions/
# => 2.7.6  3.4.2
```

以下の例では、3.4.2下に、共有ライブラリを作るようにオプションを指定します。

```bash
$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.4.2 
```

[いつもいつも忘れてしまうのでruby-buildのconfigureオプションの設定についてメモっておく](https://qiita.com/raydive/items/e07611a6a30b985c9698)
>CONFIGURE_OPTSは文字通り./configureにoptionを渡すことになる。

これで解決！


##参照
[PyCallを使ってRubyからPythonのライブラリを使い倒す](https://qiita.com/mix_dvd/items/d49ed4ff6553f3ace5a7)
IBM Cloudでプライベートチェーン作り：Ethereumクライアントをインストール

タイトルから「素直にHyperledger Fabric使いなよ」と言われそうです。IBM Blockchainは、オープンソースのHyperledger Fabricベースですが、それはそれとして。

#Ethereumのインストール
イーサリアムと読みます。イーサリアムは、仮想通貨ではなく、仮想通貨も出来ることの１つですが、「プラットフォーム」と理解すると良いかと。イーサリアムは、Bitcoinと違い、文書の改ざん防止や共有、分散ストレージなど仮想通貨以外にも使用することが考えられています。
Microsoft提供のEthereumアプリ開発環境として「Ethereum Blockchain as a Service」が2017年11月9日に発表されていますが、それはそれとして、独自の環境を作って、ブロックチェーンを自社や自分の制御下で運用したいため独自にブロックチェーン環境を構築します。要はプライベートチェーン環境を作るために、イーサリアムを使用します。

##使用サーバー
IBM Cloud上で次のスペックの仮想サーバーを用意しました。最小スペックです。

- OS:Ubuntu 16.04 64bit minimal
- CPU:1コア×2.0GHz
- RAM:1GB
- 1st Storage:25GB

##下準備：タイムゾーン設定

導入環境の構築のために、最初にタイムゾーン設定を行います。

```
# apt-get update -y && apt-get upgrade -y
# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# dpkg-reconfigure tzdata
```

##ソースコードからコンパイル

基本的には公式ドキュメントを参考にします。apt-get で導入する手順もありますがそちらは後述にて。
https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum
Go言語をインストールします。

```
# apt-get install software-properties-common build-essential golang git nano wget
# go version
```

Go言語のバージョンが1.6の場合は、ソースコードからコンパイルする際に実行不可と出ますので、Go言語バージョン1.7以上にアップグレードします。

````
# add-apt-repository ppa:longsleep/golang-backports
# apt-get update
# apt-get install golang-go
# apt-get autoremove
# go version
````

これで、Go言語のバージョンが1.7以上になります。
Ethereumクライアントの「Geth」をインストールします。

```
# cd /usr/local/src/
# git clone https://github.com/ethereum/go-ethereum
# cd go-ethereum/
# make geth
```
下記に「Geth」がインストールされます。
/usr/local/src/go-ethereum/build/bin/geth
インストール後、パスを通します。

```
# nano ~/.profile
```

下記を追記
PATH="$PATH:/usr/local/src/go-ethereum/build/bin"

```
# source ~/.profile
```

「Geth」のヘルプを表示してパスが通ったか確認します。

```
# geth --help
```

Ethereumクライアント「Geth」をインストールすることができました。
Ethereumクライアントが入った環境を「ノード」と言い、複数のノードを互いに接続することで、ブロックチェーンを構成します。冒頭で実施したタイムゾーンが同じ「ノード」同士が接続できます。


##apt-getを使って「Geth」をインストールする場合
こちらは、タイムゾーン設定までは共通で、次の手順で導入。

```
# apt-get install software-properties-common
# add-apt-repository -y ppa:ethereum/ethereum
# apt-get update
# apt-get install ethereum
```
 
#まとめ
先ずは、Ethereumクライアントをインストールする手順を確認しました。
次は、特定のノードで構成するプライベートネットワークを構築する手順についてです。送金はその次くらいですね。
mariaDB 初心者 チートシート

Mysqlをインストールして起動するとなぜかmariaDBになったので
せっかくなので使ってみる。
入力する場所は、{ここの部分}

#テンプレの作業工程

ログイン
↓
ユーザ作成
↓
DB作成
↓
テーブル作成
↓
データの登録

##ログイン

```
$ mysql -u '{username}' -p
```
パスワードを入力してログイン
初期ログインは、スーパーユーザで

```
# mysql
```
だけで良い。

##ユーザ作成

```
mariaDB[]> create user '{username}'@'localhost' identified by '{passwd}';
```
usernameとpasswdは同じ人が結構いる

ついでに権限も与える。
権限は、ALL権限を与える人が多い

```
mariaDB[]> grant all privileges on *.* to '{username}'@'localhost';
```

userの確認

```
mariaDB[]> select user,host FROM mysql.user;
```


userの削除

```
mariaDB[]> drop user FROM {user_name};
```

##DB作成

```
mariaDB[]> create database {testdb};
```

##テーブルの作成
まず、DBに入る

```
mariaDB[]> use {testdb}
```
テーブル作成

```
mariaDB[testdb]> create table {example_table}(num int,name varchar(50));
```
テーブルの確認

```
mariaDB[testdb]> show tables;
```
##データの登録

```
mariaDB[testdb]>insert into {example_table} values(1, aaa);

mariaDB[testdb]>insert into {example_table} values(2, bbb);
```
データの確認

```
mariaDB[testdb]>select * from example_table;
```
```data:output
+------+------+
| num  | name |
+------+------+
|    1 | aaa  |
|    2 | bbb  |
+------+------+
2 rows in set (0.00 sec)
Google Data StudioでUnix epochを扱う

[Google Data Studio](https://datastudio.google.com)は様々なデータソース（GoogleスプレッドシートやBigQueryなど）を元にグラフィカルなレポートを作れるようなサービスです。たとえば下記のようなレポートが簡単に作成できます。データソースに更新があれば自動的にレポートも書き換わります。

<img width="599" alt="datastudio-adwards.png" src="https://qiita-image-store.s3.amazonaws.com/0/46856/61255ba9-0d29-5dac-d93e-220c175526e3.png">

Data Studioには[計算フィールド](https://support.google.com/datastudio/answer/6299685?hl=ja&ref_topic=7441655)という機能があり、既存のカラム値を元に新たなカラムをData Studio上で作り出すことができます。計算フィールドではData Studioの組み込み関数を使うこともできるのですが、この中に`TODATE()`という関数があります。


>構文
>TODATE(field_expression, input_date_format, output_date_format)
>
>入力形式
>input_date_format は、field_expression が正しい日付として設定されている場合、省略できます。
>
>TODATE では、次の入力形式の文字列を使用できます。
>
>'BASIC' - 使用可能な形式: YYYY/MM/DD-HH:MM:SS
>'DEFAULT_DASH' - 使用可能な形式: YYYY-MM-DD [HH:MM:SS[.uuuuuu]]
>'DEFAULT_SLASH' - 使用可能な形式: rmat YYYY/MM/DD [HH:MM:SS[.uuuuuu]]
>'DEFAULT_DECIMAL' - 使用可能な形式: YYYYMMDD [HH:MM:SS[.uuuuuu]]
>'RFC_1123' - 表示例: Sat, 24 May 2008 20:09:47 GMT
>'RFC_3339' - 表示例: 2008-05-24T20:09:47Z
>'SECONDS' - エポックからの秒数
>'MILLIS' - エポックからのミリ秒数
>'MICROS' - エポックからのマイクロ秒数
>'NANOS' - エポックからのナノ秒数
>'JULIAN_DATE' - エポックからの日数
>'DECIMAL_DATE' - 'DEFAULT_DECIMAL' と同じ
>文字列として有効な strptime 形式
>
>https://support.google.com/datastudio/answer/7037300?hl=ja


私は時差の取り扱いのためにカラムの値に7時間をプラスした日時を作り出したかったのですが、時間の加減算を行う関数は提供されておらず、唯一利用できそうだったのが一度Unix epochとして整数化した上で再度日付に変換するという方法でした。

ところが、`TODATE()`の第二引数に`"SECONDS"`を指定しても「数式が無効です」というエラーが返ってきてうまく動きません。ネット上で検索してみても、同様の悩みを持っている人が何人か見つかりました（「[Solved: Can Data Studio Date Dimension use epoch (in seconds) from BigQuery](https://www.en.advertisercommunity.com/t5/Data-Studio/Can-Data-Studio-Date-Dimension-use-epoch-in-seconds-from/td-p/839649#)」）。

# 解決方法：第二引数に`%s`を指定する

最終的に私は次のような指定をして求める値を得ることができました。

```js
TODATE(CAST(unixtime AS TEXT), '%s', '%Y%m%d')
```


ここで第二引数に指定している`%s`はCのライブラリ関数[strptime](https://linuxjm.osdn.jp/html/LDP_man-pages/man3/strptime.3.html)のフォーマットです。どうやら`%s`はPOSIX標準ではなくglibc方言のようですが、少なくとも私が試した限りでは期待通り動きました。

第一引数の中の`unixtime`は数値型のカラム名だと思ってください。これをわざわざテキストにキャストすることで期待通りに動作します。このキャストが無いとエラーのままでした。

ちなみに私が実験したときのデータソースはBigQueryでした。
Scalaのガード

# Scalaのガード

近年においてガードが用いられるコードをよく見るようになりました。Scalaにおいてガードのモダンな書き方はどう書くのだろうと思ったので、纏めます。

## ガードとは
ガードとは、処理の分岐においてtrueと評価し処理を継続させる条件を表す式であり、trueでなかった場合は別途例外処理を行うものです。
注意点として、関数の始まりのうちからパラメータに例外となりうる値が含まれている場合などにおいて、早めにreturnさせることでネストを減らすことができる早期リターンもまた、ガードを使いますが、ガード = 早期リターン ではありません。 

scalaでガードを使う場合、シンプルに if と return の組み合わせで実現することが出来ます。

```scala
def hoo(bar: Int): Boolean = {
  if (bar < 0) return false
  true
}

hoo(-1)
```

## ガードがある言語
ガードはif と returnで実現できますが、Swift等の言語には言語としてガードとしての機能があり、`guard`を用いて、不正な値の場合は、本来の処理を抜けて例外処理に移行することが出来ます。ここまでは通常のifでも可能ですが、Swiftの場合は、必ずreturnを書かなければコンパイルが通らないようになっています。また、`String?`は、オプショナル型なので、アンラップする必要がありますが、`guard let` でそのままアンラップの役割を果たすようになっています。

```swift
func hoo(bar: String?) {
    guard let baz = bar else {
        print("no string")
        return
    }
    print(baz)
}

hoo(bar: "string")
hoo(bar: nil)
```

## パターンガード

if と return を使ったガードの他にガードの機能を有している式があります。

### matchを使うパターンガード


```scala
def hoo(baz: Int) = baz match {
  case i: Int if i < 0 =>  false
  case _ => true
}

hoo(-1) // false
hoo(0)  // true
hoo(1)  // true
```

matchを使った場合は、上から順番に処理されていくため、パターンに応じてガードを書いていくことが可能で、ifとは異なり型のマッチングも簡潔に書くことができます。

### for を使ったパターンガード

forのジェネレーターでifを使うことで、条件に当てはまらない場合は、for全体で None が返ります。
例はざっくりなので、Some(true) と None が返っているので getOrElse でbooleanに直しています。

```
def hoo(baz: Int) = {
  (for {
    _ <- Some(baz)
    if baz >= 0
  } yield {
    true
  }).getOrElse(false)
}

hoo(-1) // false
hoo(0)  // true
hoo(1)  // true
```

## 最後に
以上でScalaにおけるガードについて纏めた記事になります。Scalaでガードを使う場面は、scala.collection.Traversableのメソッドによって解決できることでもあるので、ガードを使うことがベストというわけではありません。
Scalaでガードはどうやるのかな？と疑問を解決するために纏めました。何かの解決になれば幸いです。


## 追記
scalamacrosを使いguard節を実装する例を書きました。
[ScalaでRustっぽく書きたい 〜try!編〜](https://qiita.com/nacika/items/7c252154d306eb1f7b48)
Draft.jsを使ってみる

# 前提条件
create-react-appを使って環境構築しています。

# 参考リンク
以下の記事を参考に、というかほぼパクらせてもらいました。ですので、この記事は自分用の備忘録にすぎないです。詳しくは以下のサイトをみてください。
https://qiita.com/mottox2/items/9534f8efb4b09093a304
https://qiita.com/tk1024/items/8d8de5a62ef55bc1532f

Documentの方もだいたい目を通しました。
https://draftjs.org/docs/overview.html#content

# コード
```js:RichEditor.jsx
import React, { Component } from 'react';
import {Editor, EditorState, RichUtils} from 'draft-js';
import {stateToHTML} from 'draft-js-export-html';

class RichEditor extends Component {
  constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
    this.onChange = (editorState) => this.setState({editorState});
  }

  handleKeyCommand(command) {
    const newState = RichUtils.handleKeyCommand(this.state.editorState, command)
    if (newState) {
      this.onChange(newState)
      return true
    }
    return false
  }

  render() {
    return (
      <div className='richEditor'>
      <h1>Draft.js example</h1>
      <button onMouseDown={(e) => {
        this.onChange(
          RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD')
        )
        e.preventDefault()
      }}>Bold</button>
      <button onMouseDown={(e) => {
        this.onChange(
          RichUtils.toggleInlineStyle(this.state.editorState, 'ITALIC')
        )
        e.preventDefault()
      }}>Italic</button>
      <button onMouseDown={(e) => {
        this.onChange(
          RichUtils.toggleInlineStyle(this.state.editorState, 'UNDERLINE')
        )
        e.preventDefault()
      }}>Underline</button>
      <button onMouseDown={(e) => {
        this.onChange(
          RichUtils.toggleBlockType(this.state.editorState, 'header-one')
        )
        e.preventDefault()
      }}>見出し1</button>
      <button onMouseDown={(e) => {
        this.onChange(
          RichUtils.toggleBlockType(this.state.editorState, 'header-two')
        )
        e.preventDefault()
      }}>見出し2</button>
      <button onMouseDown={(e) => {
        this.onChange(
          RichUtils.toggleBlockType(this.state.editorState, 'unordered-list-item')
        )
        e.preventDefault()
      }}>List</button>
      <Editor
        editorState={this.state.editorState}
        onChange={this.onChange.bind(this)}
        handleKeyCommand={this.handleKeyCommand.bind(this)}
      />
      <h1>HTML変換</h1>
      {stateToHTML(this.state.editorState.getCurrentContent())}
    </div>
    );
  }
}

export default RichEditor
```
簡単に説明すると、draft-jsのEditorコンポーネントにeditorStateという独自のobjectを持たせることでeditorとして動きます。
また、RichUtilsでRichEditorの真骨頂であるstyle変更が可能になります。

また、[draft-js-export-html](https://www.npmjs.com/package/draft-js-export-html)というパッケージを使ってeditorStateをhtmlに変換しています。これをすることで
、バックエンドとの連携もうまくいきそうです。

コード全体は[こちら](https://github.com/Dragon-taro/draft-js-sample)

# 今後の課題
写真入りの記事を編集できるようにしたいので、[draft-js-plugins](https://github.com/draft-js-plugins/draft-js-plugins)を使って
みたいです。
CentOS 7 の Apache に Let's Encrypt で SSL を設定する

EPEL リポジトリにある `certbot` パッケージを利用して [Let's Encrypt](https://letsencrypt.org/) で SSL 証明書を取得して Apache に設定する手順。

## インストール
```bash
yum -y epel-release && yum -y install certbot{,-apache}
```
EPEL リポジトリを追加し、`certbot` パッケージと Apache プラグインの `python2-certbot-apache` パッケージをインストールする。

`certbot-apache` を指定すると `python2-certbot-apache` として補完してくれる。

## firewalld
```bash
firewall-cmd --add-service=https --permanent && firewall-cmd --reload 
```
https 通信で使用する 443 ポートを公開する。

## SSL 証明書の取得
```bash
sed -i /etc/sysconfig/certbot \
 -e "/^PRE_HOOK/ s/\"\"/\"--pre-hook 'systemctl stop httpd'\"/" \
 -e "/^POST_HOOK/ s/\"\"/\"--post-hook 'systemctl restart httpd'\"/"
```
certbot 実行時に Apache を停止する設定を追加。

```bash
certbot run --apache -d www.example.com
```
`certbot run` で SSL 証明書を取得。
`--apache` オプションを利用するには `python2-certbot-apache` パッケージがインストールされていることが必要。
`--apache` オプションを指定すると、既存の Apache 設定ファイルから自動的に該当する箇所を検出して https 用の設定ファイル `-le-ssl.conf` として自動生成してくれる。


## 自動更新の設定
Let's Encrypt で取得できる SSL 証明書の有効期限は90日間となっており、自動更新する必要がある。
Cron での設定例が多いが、`certbot` パッケージでは Timer の設定ファイルが用意されており、そちらを利用するのがスマートだろう。

```bash
cp -av /{usr/lib,etc}/systemd/system/certbot-renew.timer && \
sed -i /etc/systemd/system/certbot-renew.timer \
 -e '/OnCalendar/ s/daily/weekly/' && \
systemctl daemon-reload
```
`certbot` パッケージでは `OnCalendar=daily` と日次指定されているが、ここでは週次に変更している。月次の方がより適切だろう。

```bash
systemctl enable certbot-renew.timer && systemctl list-timers
```
Timer を有効化し、設定状況を確認する。
`systemctl list-unit-files --type=timer` または `systemctl --type=timer` などでも詳細を確認できる。

## コマンドまとめ
```bash
yum -y epel-release && yum -y install certbot{,-apache} && \
firewall-cmd --add-service=http{,s} --permanent && \
firewall-cmd --reload && \
systemctl stop httpd && \
certbot run --apache -d www.example.com && \
systemctl start httpd && \
sed -i /etc/sysconfig/certbot \
 -e "/^PRE_HOOK/ s/\"\"/\"--pre-hook 'systemctl stop httpd'\"/" \
 -e "/^POST_HOOK/ s/\"\"/\"--post-hook 'systemctl restart httpd'\"/" && \
cp -av /{usr/lib,etc}/systemd/system/certbot-renew.timer && \
sed -i /etc/systemd/system/certbot-renew.timer \
 -e '/OnCalendar/ s/daily/weekly/' && \
systemctl daemon-reload && \
systemctl enable certbot-renew.timer && \
systemctl list-timers
```
なお、`VirtualHost` ディレクティブで `<VirtualHost *:443>` のようにワイルドカードを指定していると、 `/etc/httpd/conf.d/ssl.conf` の `<VirtualHost _default_:443>` の設定が優先されるのか `SSLProtocol` や `SSLCipherSuite` などが上書きされない模様。（詳細未調査）
Pandas備忘録

##データの読み込み(CSVファイル)
import pandas as pd
file = pd.read_csv("FileName.csv")
![csvファイル読み込み.PNG](https://qiita-image-store.s3.amazonaws.com/0/206486/71168527-ac42-c1cc-abf0-85d0ad134c95.png)

＊データが列の名前に組み込まれたとき＊
file = pd.read_csv("FileName.csv",header=None)
![csv改良.PNG](https://qiita-image-store.s3.amazonaws.com/0/206486/cf4e68fa-1e0a-0acc-089f-0026d70f2bb9.png)

##使えそうな関数とか
###shape
データ行列の形を知ることができる
＊shapeは関数じゃないから.shape()としない（アトリビュート？とかいうやつっぽい）＊
![shape.PNG](https://qiita-image-store.s3.amazonaws.com/0/206486/15c01b4e-55e1-f946-6307-233cf27a2608.png)

###head()
先頭から5行を取得
![head().PNG](https://qiita-image-store.s3.amazonaws.com/0/206486/8f47244f-678c-ebff-6d24-705b19230130.png)

＊引数に数字を入れることで表示される行数を指定できる＊
先頭から7行取得
![head(7).PNG](https://qiita-image-store.s3.amazonaws.com/0/206486/c9fa83bb-720d-5770-886e-75f46fd2bff9.png)

###tail()
末尾から5行を取得
![tail().PNG](https://qiita-image-store.s3.amazonaws.com/0/206486/3781ac37-8d58-0bbe-79f4-83d27029d24c.png)

＊引数に数字を入れることで表示される行数を指定できる＊
末尾から7行取得
![tail(7).PNG](https://qiita-image-store.s3.amazonaws.com/0/206486/38f723c4-2484-1d30-2f11-91a228637b24.png)

###describe()
基本統計量の確認ができる

###info()
カラムごとの情報を確認できる

###mean()
test["A"].mean()
こんな感じで記述してカラムAの要素の平均値が出せる
###median()
test["A"].median()
こんな感じで記述してカラムAの要素の中央値が出せる

###sort_values(by="XXX")：昇順
test[test["おすし"]=="まぐろ"].sort_values(by="金額")
こんな感じで書くと、データフレームtestの"おすし"カラム中の"まぐろ"要素を抜き出して、"金額"で昇順ソートする

###sort_values(by="XXX",ascending=False)：降順
test[test["おすし"]=="まぐろ"].sort_values(by="金額")
こんな感じで書くと、データフレームtestの"おすし"カラム中の"まぐろ"要素を抜き出して、"金額"で降順ソートする
インテントフィルタとは

インテントフィルタ（IntentFilter）とは、

一言でいうと
「暗黙的インテントで、送信側と受信側を紐づけるもの」

要は、暗黙的インテントで「このインテントを受け取れる人はだ～れだ？」って、聞いたときに、
受け取り側のアクティビティやサービスが、自分に設定してあるインテントフィルタという定義を確認して
自分が受け取れるインテントかどうかを確認するときに使われる。

例として、
Aというアクティビティから、暗黙的インテントでBというアクティビティを呼び出す場合を考えます。
あらかじめ、Bは△△なインテントなら受け取って処理できるよ。と定義する。←これがインテントフィルター
Aは「△△ができるアクティビティやサービスを呼び出して」というインテントを投げる。
インテントフィルターによって、AとBが結び付き、処理が連携する。
Android ブロードキャスト処理のサンプル

ボタンクリック時にブロードキャストを送信し、
それを自分のアクティビティの中で受信して、
テキストビューの中身を書き換える処理です。
ブロードキャストのサンプルとして記載します。

``` MainActivity.java
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    MyBroadcastReceiver myReceiver;
    IntentFilter intentFilter;
    TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // レシーバーオブジェクトの生成
        myReceiver = new MyBroadcastReceiver();
        // レシーバーが受信できるインテントを指定してインテントフィルターを生成
        intentFilter = new IntentFilter("ORIGINAL_ACTION");

        // onClickListenerの登録
        findViewById(R.id.button1).setOnClickListener(button1ClickListener);
    }

    @Override
    public void onResume() {
        super.onResume();
        // ブロードキャストレシーバーを登録する。（どんなインテントがきたらどのレシーバーをキックするかを定義づける）
        registerReceiver(myReceiver, intentFilter);
    }

    @Override
    public void onPause() {
        super.onPause();
        // ブロードキャストレシーバーを解除する
        unregisterReceiver(myReceiver);
    }

    // ボタン押下時の処理を記載
    View.OnClickListener button1ClickListener = new View.OnClickListener() {
        // ボタン押下時にはこのメソッドが動く
        public void onClick(View view) {
            // ブロードキャスト送信するインテントの種類を定義する
            Intent i = new Intent("ORIGINAL_ACTION");
            // ブロードキャストにメッセージを付与する
            i.putExtra("key", "message");
            // ブロードキャスト送信
            sendBroadcast(i);
        }
    };

    public class MyBroadcastReceiver extends BroadcastReceiver {
        // ブロードキャスト受信時にこのメソッドが動く
        @Override
        public void onReceive(Context context, Intent i) {
            // ブロードキャスト受信時の処理（今回は適当）
            tv = (TextView) findViewById(R.id.text_view);
            tv.setText("abc");
        }
    }
}

```
IntelliJ IDEAで [error] Expected ':' (if selecting a configuration) というエラーが出た

PCを強制終了したら発生。IntelliJ IDEA側のプラグインのロードに失敗することで起きるようで、こうなると、IntelliJ IDEA側でtestの実行やbuildなどができなくなる。

```
[error] Expected ':' (if selecting a configuration)
```

一旦IntelliJ IDEAを終了させ、コンソールから

```
sbt clean
```

すると直りました。IntelliJ IDEAからだと制御不能になるので、焦りました。
C#におけるユニットテストの名付けの基本的なルール

#プロジェクト名
[テストをするプロジェクト名].UnitTests

#クラス名
[テストをするクラス名].Tests

#テストメソッド名
[UnitOfWorkName]\_[ScenarioUnderTest]\_[ExpectedBahavior]

UnitOfWorkName・・・メソッド名、メソッドのグループ名(複数のメソッドにまたがるユースケース)やテストするクラス名 e.x. "UserLogin", "RemoveUser", "StartUp"

ScenarioUnderTest・・・どんな条件でテストされるか e.g. "bad login", "invalid user", "good password". パブリックメソッドに送られるパラメータやシステムの初期状態　e.g. "system out of memory", "no users exist", "user already exists"

ExpectedBahavior・・・戻り値や例外、結果としてのシステムの状態、、、

e.x. IsValidFileName_BadExtension_ReturnsFalse()
goでprocess substitutionを取る

例えばある go のプログラムに

```
go run main.go <(find .)
```

のように process substitution をして値を渡したい場合どうやるんだっけと思ったのでメモ

この例の場合 os.Args にファイルディスクリプタが入るのでそこから値を取れます

```go
package main

import (
	"fmt"
	"io/ioutil"
	"os"
)

func main() {
	f, _ := os.Open(os.Args[1])
	b, _ := ioutil.ReadAll(f)
	fmt.Println(string(b))
}

```

別の input と組み合わせる場合は

```
go run main.go -hoge XXX -ps <(find .)
```

```go
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
)

func main() {
	hoge := flag.String("hoge", "", "")
	ps := flag.String("ps", "", "process substitution")
	flag.Parse()
	fmt.Println(*hoge)
	f, _ := os.Open(*ps)
	b, _ := ioutil.ReadAll(f)
	fmt.Print(string(b))
}

```

とかして flag と合わせるのが一番楽そうです
Vagrant 初心者 Network 設定

#初心者ができるvagrantの設定

<details><summary>Vagrantとは</summary>
CUI上の仮装環境の構築、およびネットワークなどの設定が簡単にできます。
また、他人が作った設定(Box)を利用することで
複数人が全く同じ仮装環境を構築できる優れもの
</details>

<details><summary>なぜ仮装環境が流行っているか</summary>
- 最近、仮装環境が流行っています。
なぜかというと、ある程度PCのスペックが上がってきて
処理負荷に耐え、速い処理で本物みたいに仮装環境を動かせるので
もはや、仮装環境は本物と同じと言っていいくらいです。
- 仮装環境のメリットとは、
同じ環境の複製を大量に作れる
別の環境で同じ動作ができる環境を瞬時に作ることができます。
環境構築に失敗してもすぐに捨てて一から作れる利便性
</details>

#本題
vagrantの設定は、まずVagrantの構築ができている人前提で話を進めます。
Vagrantの設定は、全てVagrantfileで設定します。
デフォルトの内容は、コメントアウトだらけです。
有効な内容は、

```
Vagrant.configure("2") do |config|
~~
config.vm.box="~~"
~~
end
```
これだけですね。

ここに必要なものを足して（コメント外して）いきます。

##HostPCとVagrant間の通信のみを考えている人

```va:Vagrantfile
config.vm.network "private_network", ip: "192.168.33.10"
```
という行のはじめの#をとって有効にしてください。

##他の端末でvagrantで作ったwebsiteを見たい人は

```va:Vagrantfile
config.vm.network "public_network"
```
の行の#をとって有効にしてください。
また、途中で何か聞かれたらwi-fiの1でいいと思います。
なんなら、設定書いた方がいいです。

```va:Vagrantfile
config.vm.network "public_network", ip "192.168.1.10", bridge "en0: Wi-Fi (AirPort)"
```
<details>
ipaddress → 192.168.1.10に指定
bridge → en0: Wi-Fi (AirPort)に指定 
</details>

##独自のドメインを楽しみたい人
まずプラグインのインストール

```
$ vagrant plugin install vagrant-hostsupdater
```
※vagrant-hostupdaterと間違えないでください（自分...）

その後Vagrantfile内(using a specific IP.の下)に

```
config.vm.hostname = "好きなドメイン"
```
を追加してください。(私の場合「myraspi.com」)

```file:Vagrantfile
 35   # Create a private network, which allows host-only access to the machine
 34   # using a specific IP.
 35   config.vm.hostname = "myraspi.com"
 36   config.vm.network "private_network", ip: "192.168.33.10"
```
この後リロード（再起動）

```
$ vagrant reload
```
再起動中に何か聞かれる.
番号を聞かれたらpublicの時みたいにwi-fiの選択肢1を選ぶか,設定する

なお、publicかつオリジナルのドメインは、できない...
できる方がいたら教えて欲しい...

privateとpublicは、同時に設定もできるが
あくまで二つの機能を使えるだけで
ホストPCでドメインを使えても
他の端末で使えないのであまり意味がないという結論に至った。

結果として、やりたかったpublic_networkができただけでもいいや。
Dockerfile だけのRails開発環境

# 目的

+ データベースにアクセスしないRails アプリを作ることになりました
+ "Rails Docker" でググるとみんなMac でdocker-compose を使ってる
+ 何にもアクセスしないのでRails だけ欲しいのでdocker-compose じゃなくていい

# Dockerfile作成

```
FROM ruby:2.4.2
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y mysql-client unzip
RUN gem install bundler -v 1.15.4

ENV APP_HOME /myapp
ENV BUNDLE_JOBS=4
RUN mkdir -p /tmp
WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME

EXPOSE  3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```

# 起動方法

```bash
$ docker build -t [なんかカッコいい名前] .
$ docker run -v [Mac上の開発環境のディレクトリ]:/myapp -p 3000:3000 [なんかカッコいい名前]
```

# アクセス方法

http://localhost:3000/

# ポイント

+ Dockerfile
    + tmpディレクトリで`bundle install` することで2回目以降の`build`を高速化してます
+ docker run
    + `-v` をつけることでディレクトリの同期をしてます。つけなかった場合、コードを修正する度にDockerの再起動が必要ですが、付与しておけば再起動は不要になるので開発速度が爆速であがります
+ 検証環境
    + 多分、`heroku` でも動くはず
pipがどうしてもうまくいかない超初心者のための　python　pip超入門

ちょうど私みたいな、pipって聞いたことくらいはあるけどやってみてもさっぱりうまくいかん！
って人のためにものすごい初歩の初歩から「わかりやすく」順を追って説明します。

※環境変数とかの内部構造を知りたい人は違うところへどうぞ。
※それなりにpython使いこなせている人はこのページを見ても何も収穫はないと思います

①pythonをダウンロード
[https://www.python.org/](https://www.python.org/)
から、Downloadsの所にマウスをもっていくと、こんなのが現れるので、
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/211349/548f57d4-f583-4d41-29a7-e3c0a9d410b6.png)
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/211349/628170b8-1a7e-b805-e483-531a62054962.png)

python 3.xのほう（左側）をクリックしてください

②インストール
環境変数とかそういうのの設定がめんどくさいので、
はじめに「カスタム設定」を選択し、すべてのチェックボックスをチェックしてからダウンロードします。

③コマンドプロンプトを開く
windowsなら、スタートメニューを開いて、「cmd」と入力

④とりあえず、numpyというやつを入れてみる
そこに、[pip install numpy]を入力（別に　numpyじゃないやつでもいい）
![862e4792151e2e296600db1d053766ba.png](https://qiita-image-store.s3.amazonaws.com/0/211349/837ea755-3d11-22d8-5ff4-f08fd4d2ade5.png)
こんな感じになれば成功かな？

⑤IDLEでインストールして使ってみる
スタートメニュー開いて「IDLE」と入力。
※実際はほかのやつを使ってもうまくいく・・と思います。（やったことはないけど）
その後、import numpyと打ってエラーが出なければ成功！
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/211349/fae11bb2-c500-f064-feec-fe536565975a.png)

あとは、numpy　使い方　とか検索すれば大丈夫かなと思います。

こんな初歩的なこと書いて怒られそうだけど・・・
100MB超のファイルを間違えてコミットするとGitHubから拒否される件

#現象
リモートブランチにプッシュできない
特定のファイルが100MBを超えているから拒否されました！

ローカルの環境だと思って油断していたのが敗因。

#対応
git rm hoge.log
だけでもダメ。履歴にそのファイルが残っているので、そもそもプッシュできない。

そこで、「100MBを超えたファイルをコミットした」履歴をまるごと削除する。

> git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch [ファイル名]" --prune-empty -- --all
>  rm -rf .git/refs/original/
>  git reflog expire --expire=now --all
>  git gc --aggressive --prune=now

http://sd7lab.jp/github-push-100mb-limit/
https://www.walbrix.com/jp/blog/2013-10-github-large-files.html

#結論
自分専用ブランチでもハマるときはハマる
プルリクを送るときは履歴までクリーンな状態で（理想）
機械学習に出てくる数式で読めないギリシャ文字チートシート

機械学習を学んでいると、
数式で読めないギリシャ文字が使われていることがあったので、
まとめてみました。

```
ギリシャ記号	読み方	スペル	LaTeX
Α α	アルファ	alpha	\alpha
Β β	ベータ	beta	\beta
Γ γ	ガンマ	gamma	\gamma
Δ δ	デルタ	delta	\delta
Ε ε	イプシロン	epsilon	\epsilon
Ζ ζ	ゼータ	zeta	\zeta
Η η	イータ	eta	\eta
Θ θ	シータ	theta	\theta
Ι ι	イオタ	iota	\iota
Κ κ	カッパ	kappa	\kappa
Λ λ	ラムダ	lambda	\lambda
Μ μ	ミュー	mu	\mu
Ν ν	ニュー	nu	\nu
Ξ ξ	クシー	xi	\xi
Ο ο	オミクロン	omicron	o
Π π	パイ	pi	\pi
Ρ ρ	ロー	rho	\rho
Σ σ ς	シグマ	sigma	\sigma
Τ τ	タウ	tau	\tau
Υ υ	ウプシロン	upsilon	\upsilon
Φ φ	ファイ	phi	\phi
Χ χ	カイ	chi	\chi
Ψ ψ	プサイ	psi	\psi
Ω ω	オメガ	omega	\omega
```
TypeScript+express+webpack+HRM構成をDockerに乗せてnode --inspect=0.0.0.0:9229したときにハマった話

# 誰向けの記事か

`node --inspect=0.0.0.0:9229`を実行して、こんなエラーが出てしまっている人

```
Debugger listening on ws://0.0.0.0:9229/c9b5d9ba-7443-4902-9463-afa66c1126e2

...

Starting inspector on 0.0.0.0:9229 failed: address already in use
```

なぜinspectorが2回も起動しようとしているの・・・？

# まえがき

nodeのデバッグには --inspectオプション(v7以前なら--debugが相当機能)を有効にすることで、ChromeDevToolsやその他デバッグ機能を備えたエディタ(WebStormやVSCode)からnodeのデバッガーに接続することが出来て、とても便利ですよね。

今回はこのデバッグ機能を使おうとしてハマったので、原因と解決方法を共有します。

# 対策チャート

## TypeScriptを使っているか？

YES: 次の設問へ
NO: 原因のところまでジャンプして、あなたの環境の場合の原因に当てはまりそうか考えてみてください。

## awesome-typescript-loaderを使っているか？

YES: 次の設問へ
NO: 原因のところまでジャンプして、あなたの環境の場合の原因に当てはまりそうか考えてみてください。

## デバッグの実行環境がDockerコンテナ内か？

YES: 対策の項へ！
NO: 次の設問へ

## --inspect にIPとportを渡す必要が本当にある？

YES: 対策の項へ！
NO: `node --inspect` で、デフォルトのIPが127.0.0.1, ポート9229で動作し、ポートが使用済みの場合は自動的に空きポートを使用してくれるので、パラメータなしにしましょう。

# 原因

`awesome-typescript-loader`の内部で、[ChildProcessを生成している部分](https://github.com/s-panferov/awesome-typescript-loader/blob/ed76931a2a4c2565cbca0b04414963f8b4e69902/src/checker/checker.ts#L47)があるが、そこで、Expressを起動しているProcessの実行オプションをそのまま渡しているため、--inspectにポートを指定しているとポートの重複Errorになる。

このようにnodeのinspect機能を有効にしている場合に、使っているライブラリや自身のコードでChildProcessを生成していると、process.Argvをそのまま引き継ぐ実装をしているときにポート重複の罠にハマってしまう。

# 対策

1. ts-loaderを使う
2. expressの初期化中にprocess.execArgvの中身を書き換えて、`--inspect`からパラメータを除去する
3. そもそもの原因箇所の修正をする(issueは起こしておきました)

ひとまずは、以下のようなもので対処してみました。

```js
// hack for awesome-typescript-loader
const execArgv = process.execArgv;
for (let i = 0; i < execArgv.length; i++) {
    if (execArgv[i].match(/--inspect=.*:?\d{3,5}/)) {
        // replace inspect option if it has constant port
        execArgv[i] = "--inspect";
    } else if (execArgv[i].match(/--inspect=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)) {
        // replace inspect option if it has constant address
        execArgv[i] = "--inspect";
    }
}
```
IE11はアップロード容量に制限がある

# IE11だけ4GB以上のファイルをアップロードできない
某サービスのフロント開発中にchromeやfirefoxは5GBまでアップロードできるのに、IE11だけ4GB以上のファイルをアップロードできないという事象に出くわしました。
クライアントの実装が悪いのか、IE11のバグなのか、もしくはAPIやサーバー側の問題なのか・・・
かなり悩んだのですが、他の類似サービスを調べてみると引っかかりました。

[box：アップロードできる最大ファイルサイズを教えてください](https://community.box.com/t5/%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E3%81%AE%E7%AE%A1%E7%90%86/%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E3%81%8D%E3%82%8B%E6%9C%80%E5%A4%A7%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B5%E3%82%A4%E3%82%BA%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84/ta-p/7713)

IE11は4GBまでしかアップロードできない制限みたいですね・・・
ブラウザが制限を掛けているとは想像もつかず、かなり時間がかかりました。
AWS OpsWorksでインスタンスを追加された時にALBに追加するChefのレシピ

## 概要

2017年11月時点、AWS OpsWorksがALBに対応していない。
EC2インスタンスが起動後、Chefが実行されセットアップが済んでもALBのターゲットグループに追加されないということが起きる。

ALBのターゲットグループに追加、削除するレシピを作成することで対応できる。

## レシピ作成

```
knife create cookbook alb
```

## ALBに登録

```alb/recipes/register.rb
aws_instance_id = node[:opsworks][:instance][:aws_instance_id]
target_group_arn = node[:alb][:target_group_arn]

bash 'register instance' do
  code <<-END
    aws elbv2 register-targets \
    --region ap-northeast-1 \
    --target-group-arn #{target_group_arn} \
    --targets Id=#{aws_instance_id}
  END
end
```

## ALBに解除

```alb/recipes/deregister.rb
aws_instance_id = node[:opsworks][:instance][:aws_instance_id]
target_group_arn = node[:alb][:target_group_arn]

bash 'deregister instance' do
  code <<-END
    aws elbv2 deregister-targets \
    --region ap-northeast-1 \
    --target-group-arn #{target_group_arn} \
    --targets Id=#{aws_instance_id}
  END
end
```

## カスタムJSONの設定

```json
{
  "alb" : {
    "target_group_arn" : "arn:aws:elasticloadbalancing:ap-northeast-1:11111111111:targetgroup/name/123e123e123e123e"
  }
}
```

## AWS OpsWorks Stacks のライフサイクルイベント
 
SetupとShutdownに追加する。

### Setup

`alb::register` 

### Shutdown

`alb::deregister`

## IAM Policy

起動するEC2インスタンスのIAM Roleに付与する。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DeregisterTargets"
            ],
            "Resource": "*"
        }
    ]
}
```
Twigで配列のkeyを変数で指定

#変数の表示
Twigでは`{{ 変数 }}`のように変数を表示します。
配列でも`{{ 配列.key }}`または`{{ 配列['key'] }}`のように書きます。
それでは、`key`に変数を指定したい場合はどうするのでしょうか？

#配列のkeyを変数で指定
`変数 = 'key'`で`配列['key']`を表示したいとします。
結論から言うと、`{{ attribute(配列, 変数) }}`で表示できます。
但し、これはTwigのver1.2で追加されたものなので気を付けて下さい。

これを応用して、`配列1['key1'] = 'key2'`、`配列2['key2']`は`{{ attribute(配列2, 配列1.key1) }}`とすることも出来ます。

#終わりに
[公式のHPのドキュメント](https://twig.symfony.com/doc/1.x/)にしっかりと書かれているけど、英語が苦手な私にはとてもキツイ(>_<)
英語しかないドキュメントが沢山あるから、何とかして読み解かないとと苦痛を味わう今日この頃です。
PHPでCloud Automator APIのラッパを作ってみた

※本記事は、[Cloud Automator Advent Calendar 2017](https://qiita.com/advent-calendar/2017/cloudautomator) の12/3分の記事です。
# 概要

PHPでCloud Automator APIのラッパを作ってみました。趣味で。
このライブラリを用いることで、PHPでCloud Automator APIを簡易に扱えると思います。
https://github.com/kuredev/cloudutomator-php

## Cloud Automator APIとは
Cloud AutomatorのオペレーションするためのREST APIです。
ジョブの大量投下や一覧の取得等に便利です。
本家のドキュメントは以下になります。
https://cloudautomator.com/api_docs/v1/api.html

# 使い方
## インストール
composerでインストールしてください。

```
$ composer install kuredev/cloudautomator-php
```

## 概要
「Kuredev\CA」オブジェクトを初期化/作成すると、Cloud AutomatorAPIをラップしたプロパティ＋メソッドを持つオブジェクトが作成されます（それらの要素を持った階層的なstdClassが作成される）。
下記のサンプルを見ていただけるとイメージが付くと思います。

## サンプル
```php
<?php
require_once "vendor/autoload.php";
$ca = new \Kuredev\CA("[CloudAutomatorAccessKey]");

try{
    var_dump($ca->get->aws_accounts());
    var_dump($ca->get->aws_account(xxx));
    $accountArr = array(
        "name" => "xxx",
        "account_number" => "12345678910",
        "access_key_id" => "xxxxx",
        "secret_access_key" => "xxxxxxxxxx"
    );
    var_dump($ca->post->aws_accounts(json_encode($accountArr)));
}catch(Exception $e){
    var_dump($e);
}
```

## リファレンス
https://github.com/kuredev/cloudutomator-php/blob/master/src/api.json

# 要件
- "php": ">=7.0.0"
- "palanik/wrapi": "*"

※ライブラリ（wrapi）はcomposerで勝手にインストールされる。今回のラップの仕組みはこのライブラリにお世話になってる。通信の部分は内部的にGuzzleを用いているもよう。

# 参考
PHPでQiita APIv2のラッパを作ってみた Qiita
https://qiita.com/kure/items/b8b1b3e6d71910ff0b06

# 終わりに
Cloud Automator APIを楽しく操作する一助になれば幸いです。
明日以降の記事も楽しみです。
pythonの条件文行数を半分以下にしちゃう

#Pythonでは、三項演算子ではなく、普通の条件式として定義されている！

@shiracamus さんに、コメントよりおしえて頂きました！
参照:【[PEP 308 Conditional Expressions](https://www.python.org/dev/peps/pep-0308/)】

ありがとうございます！m(__)m

#何を知れるか

長くなりがちなif-elif-else文を短く書ける方法です！

#Pythonの条件式を短くするには、どうしたらいいか！

###最初は、普通のfor文

```py3

#0から20のリストを作る
the_list = list(range(21))

#4の倍数のときはOK!を出力するfor文
for i in the_list:
    if i % 3 == 0:
        print("OK!")
    else:
        print(i)

"""
OK!
1
2
OK!
4
5
OK!
7
8
OK!
10
11
OK!
13
14
OK!
16
17
OK!
19
"""
```

**普通の条件分だと、合計6行です。**

##短くすると！

```py3
the_list = list(range(20))

#4の倍数のときはOK!を出力するfor文
for i in the_list:
    print("OK!" if x % 4 == 0 else i)
"""
OK!
1
2
OK!
4
5
OK!
7
8
OK!
10
11
OK!
13
14
OK!
16
17
OK!
19
"""
```

**3行になりました！半分です。絶対に覚えたほうが良いですね！**

##elifのように条件分をもっと増やしたい場合

```py3

the_list = list(range(21))

#4の倍数のときはOK!、5の倍数の時はNo.5!を出力するfor文
#普通にif-elif-else条件分を書いた場合
for i in the_list:
    if i % 4 == 0:
        print("OK!")
    elif i % 5 == 0:
        print("No.5!")
    else:
        print(i)

"""
OK
1
2
OK
4
No.5!
OK
7
8
OK
No.5!
11
OK
13
14
OK
16
17
OK
19
No.5!
"""

```
**8行になりました!**

##三項演算子で書いた場合

```py3
the_list = list(range(21))

for i in the_list:
    print("OK!" if i % 3 == 0 else "No.5!" if i % 5 == 0 else i)

"""
OK
1
2
OK
4
No.5!
OK
7
8
OK
No.5!
11
OK
13
14
OK
16
17
OK
19
No.5!
"""
```
**3行になりました！ありえません！！**

####書くときのポイントがあるみたいなので、メモしておきます。

**・elifを書きたい場合、elseのあとにifを書いていく**

`print("OK!" if i % 3 == 0 else "elifの時に行いたい処理" if "elifの条件文" ===ここに他のelifを書くことも可能！=== else "最後のelseが本当のelse")`

#P.S @LouiS0616 さん、@shiracamus さんに、もっと短い条件分の書き方を教えていただいた。

２つあるんですが、1つ目はfor文をlambda(無名関数、匿名関数)に渡して、引数にrange(21)を渡してあげることで、一行で条件分を作成する方法です！

```py3

(lambda num: print('\n'.join("OK!" if i % 3 == 0 else "No.5!" if i % 5 == 0 else str(i) for i in range(num))))(21)

```

1番目の方法は、このようにも表せるそうです。

```py

func = 上記のlambda式
func(21)


#式を当てはめると
func = lambda num: print('\n'.join("OK!" if i % 3 == 0 else "No.5!" if i % 5 == 0 else str(i) for i in range(num)))
func(21)

```


二つ目はprint関数内でループを回す方法です！

```py3

print('\n'.join("OK!" if i % 3 == 0 else "No.5!" if i % 5 == 0 else str(i) for i in range(21)))

```
#####**\n**は改行をjoin関数を使ってくっつけてあげています！これがないと、改行されず出力されちゃいますのでご注意ください！

####**条件分を短くする注意点**

>条件演算子はネストするととにかく読みづらいので、使いどころは考えた方が良いです。
Pythonは行数が少なくなるような設計なので、条件式を使うべき場面は少ないと思います。if-elif-else文で書けるなら、その方がいいんじゃないかなぁ

短くするだけ可読性下がることは覚えておかないといけないですねm(__)m

コメント頂きましたみなさま、ありがとうございました！！

#今となっては当たり前のifから始まる条件式ですが、前までは理論演算子のみが提供されていた。

その時の方法で、今回のfor文を作る場合このようになるようです。

```py3

for i in range(21):
    print(i % 3 == 0 and "OK!" or i % 5 == 0 and "No.5!" or i)

```

いま勉強していることが、色んな人たちの議論が積み重なり成り立っているという事を知って、感慨深い気持ちです。

教えてくださりありがとうございます！！！！！！


#最後に

printを毎回書かないといけないのが僕としてはすごい面倒だったのですが、三項演算子なら簡単！！

でも可読性が下がるのはメリットではないので、しっかりと使い分けようと思います。

最後まで見てくださった方ありがとうございました(^^)