OmniAICreator/Qiita-1.07M huggingface dataset:
CSVファイルのMIMEタイプが環境によって異なる

Microsoft Excelがインストールされているどうかで、CSVファイルのMIMEタイプが変わることがわかりました。

OS|Browser|EXCEL|MIMEタイプ
---|---|---|---
Windows10|Chrome|有|	application/vnd.ms-excel
Windows10|Chrome|無|application/octet-stream
Windows10|Firefox|有|	application/vnd.ms-excel
Windows10|Firefox|無|application/octet-stream

# CSVファイルのMIMEタイプを表示するサンプル

```php:mime_check.php
<!doctype html>
<meta charset="utf-8">
<title>MIMEチェック</title>

<?php
if (isset($_FILES['target'])) {
   echo '<p>MIMEタイプ：<strong>'.$_FILES['target']['type'].'</strong></p>';
}
?>

<h1>MIMEタイプを調べたいファイルを選択してください</h1>
<form method="post" enctype="multipart/form-data">
    <input type="file" name="target" onchange="submit(this.form)">
</form>
```
Angular Reactive Forms

#ReactiveForms（モデル駆動型）とは
[公式ドキュメント](https://angular.jp/guide/reactive-forms)には以下のように記されています。
>リアクティブフォーム は、時間とともに入力値が変わるフォームを扱うためのモデル駆動なアプローチを提供します。このガイドでは、シンプルなフォームコントロールの作成と更新から、グループ内の複数コントロールの使用、フォームのバリデーション、高度なフォームの実装の方法を説明します。

でも最初は「ちょっと何言っているかわかりません」状態なので、順を追って説明していきます。

まず、Angularのフォームには２種類あります。

###テンプレート駆動型(Template Driven Forms)
- 簡単なコードで、基本的なバリデーションを実装できる。
- テンプレート側でオブジェクトの生成から検証までを行う。
- 非同期的
- テストが複雑

###モデル駆動型（Reactive Forms）
- 複雑で柔軟な要件に対応することができるフォーム
- モデル側でオブジェクトの生成、検証を行い、テンプレート側では紐付けを行うのみ。
- 同期的
- テストが簡単

#ReactiveFormsの良いところ
- **複雑で柔軟な要件に対応することができるフォーム**
    - テンプレート駆動型と比べると、少しコード量は多いですが、あらゆる要件に対応することができます。
- **モデル側でオブジェクトの生成、検証を行い、テンプレート側では紐付けを行うのみ。**
    - ほとんどのコードはモデル側で行うため、htmlはシンプルになります。
- **同期的**
  - 全てのコントロールが常に利用可能のため、簡単に親子フォーム間で値の更新が可能です。
- **テストが簡単**
  - リクエストのデータには一貫性があり予測性が保証されているためです。

#まとめ
**Reactive Forms**, **Template Driven Forms** はうまく使い分けて、実装できれば良いと思います。

- **Template Driven Forms**は比較的に理解しやすいので、初学者に良いと思います。また、簡単なバリデーションチェックなどを行いたい時は素早く実装できるためおすすめです。

- **Reactive Forms**は複雑なバリデーションを自ら作成する必要がある時に良いです。ただ、少し複雑になるので[この方](https://qiita.com/minase_tetsuya/items/84c3df4ad40f39d290cf)のように自分なりの簡略化をする工夫をしたら良いと思いました。


また後日、ここに実装編の記事を追加しておきます。

#参照
https://qiita.com/mixplace/items/79023cb35668603e5c7b
https://qiita.com/lacolaco/items/fd7cd09282c528ada2d2
https://angular.jp/guide/forms
https://qiita.com/shirokuman/items/d06531e8ee111a8c74de
https://qiita.com/minase_tetsuya/items/84c3df4ad40f39d290cf
https://qiita.com/hedrall/items/b5dc7ec2cd1c635aeaa2
https://qiita.com/mixplace/items/79023cb35668603e5c7b
【Python】リスト内包表記を使って、リストから値を検索し取得する方法

#  リスト内包表記を使って、リストから値を検索し取得する方法
```python
list = [ {"id" : 1, "val":  "ONE"}, {"id": 2, "val": "TWO"}]
```

## リストから、id が 2 のものを取得したい場合
```python
values = [x for  x in list if x["id"] == 2]
value = values[0]
```
⇒ id=2が見つからない場合、`IndexError: list index out of range`が発生する！

## リストから、id が 2 のものが取得出来なかった場合の処理)
```python
values = [x for  x in list if x["id"] == 2]
value = values[0] if values else { "id": 0 , "val": "Default"}

もしくは
value = values[0] if values else None
```

## ワンライナーで書くなら
```python
value = [f for i in [[x for x in list if x["id"]== 2],  [None]] for f in i][0]
```

### 解説
* `[x for x in list if x["id"]== 2]`の処理
```
[{"id": 2, "val": "TWO"}]
```
id=2が複数見つかる場合もあるため、配列

*  `[[x for x in list if x["id"]== 2],  [None]]`の処理

```
[
    [{"id": 2, "val": "TWO"}],
    [None]
]
```
2次元配列になる

*  `[f for i in [[x for x in list if x["id"]== 2],  [None]] for f in i]`の処理
分かりやすく書くと次のようになる

```
[flatten for inner in list for flatten in inner]
```

例えば次のようなリスト`list = [[1, 3, 5], [2, 4]]`が合った場合

```
[
  [1, 3, 5],
  [2, 4]
]
```

`for inner in list`は 以下の順番に取得し、innerに格納する

```
1: [1, 3, 5]
2: [2, 4]
```

`for flatten in inner`はinnerの`[1, 3, 5]`を以下のように取得しflattenに格納する

```
1 : 1
2:  3
3:  5
```

以下のような配列が出来上がる(2次元配列を1次元配列に変換している)

```
[1, 3, 5, 2, 4] 
```

つまり、以下のような配列が出来上がる

```
[{"id": 2, "val": "TWO"}, None]
```

id=2が取得出来なかった場合、絶対に`[None]`になるため、`IndexError: list index out of range`になることはなくなる。

### ラムダ式にした場合
```python
flatten = lambda list: [flatten for inner in list for flatten in inner]
value = flatten([[x for x in list if x["id"]== 2],  [None]])[0]
```
【AWS】Lambda×CloudWatch EventsでRDSの自動停止

## はじめに  
先日社内のAWSユーザーから「Auroraを検証で利用してるんだけど、停止してても７日間後に自動で起動しちゃったり、開発で使った後に止め忘れちゃうから何かいい方法ない？」と問い合わせがありました。なので、CloudWatch EventsとLambdaを使ってRDSを定期的に自動停止するプログラムを`python3.7`で作成しました。  
## この記事の対象者  
- IAMロールやポリシーの違いが分かっていて、ポリシーを作成できる  
- 何らかのプログラミング言語が書けるor読める  


## 目次  
- Lambda用のIAMロールの作成  
- Lambda関数を作成する  
- CloudWatch Eventsでスケジュールを立てる  

## Lambda用のIAMロールの作成  
まずはIAMロールに割り当てるためのポリシーを作成していきます。ポリシーの作成からjsonエディターを開いて、次のjsonファイルをコピペしてください。それが終わったら、IAMロールに適当な名前をつけてアタッチしましょう。  

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "rds:Describe*",
                "rds:StopDBInstance",
                "rds:StartDBInstance"
            ],
            "Resource": "arn:aws:rds:*:*:db:*"
        }
    ]
}
```  

## Lambda関数を作成する  
次にLambda関数を作成していきましょう。Lambdaのダッシュボードから【関数の作成】 > 【一から作成】を選択し、適当な関数名を入力、ランタイムをpython3.7とし、アクセス権限のところで先ほど作成したIAMロール割り当てて上げましょう。【関数の作成】をクリックすると関数のエディタ画面に遷移すると思うので、次のコードをコピペしてください。  

```
import boto3

# 任意のDB識別子
db_instance = "sample_db"

def lambda_handler(event, context):
    client = boto3.client('rds')

    # DBの情報一覧が格納されている
    informations = client.describe_db_instances(DBInstanceIdentifier=db_instance)

    # DBの起動状態を取得
    rds_stauts = informations["DBInstances"][0]["DBInstanceStatus"]

    # DBが停止していた場合
    if rds_stauts == "stopped":
        print('DB already stopped.')
        return
    # DBが停止状態でなかった場合
    else:
        response = client.stop_db_instance(DBInstanceIdentifier = db_instance)
        print('DB is stopping.')
        return
```  
プログラム自体はとてもシンプルですね。DBの識別子は皆さんのDBに合わせて変更してください。`describe_db_instances`でDBインスタンスの情報を取得していて、その中から変数`rds_status`にDBの状態を文字列型で代入しています。詳しく知りたい方は[公式ドキュメント](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances)を参考にしてください。  
ここまで終わったら、実行してみましょう！画面右上の【テスト】を選択し、イベント名に適当な名前を入力してください。【作成】ボタンをおし、もう一度【テスト】を実行すると該当のDB停止されているか確認してください。  

## CloudWatch Eventsでスケジュールを立てる  
最後にCloudWatch EventsでLamda関数を定期実行できるようにしてあげましょう。CloudWatchのダッシュボードから【イベント】を選択します。スケジュールに基づくCron形式で実行したいので次のように入力してあげましょう。
<img width="548" alt="img.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286861/81a78cdd-70bf-4260-4ff6-0c6ee0d172cd.png">
上の例では、日本時間で月曜から金曜の１７時３０分にイベントが実行されることになります。AWSでの標準時はグリニッジ標準時になっているので日本時間にするためには９時間早めないといけないことに注意してください。Cron式に詳しく知りたい方は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html)を参考にしてください。
ここまで終わったら【ターゲット】のところで先ほど作成したLambda関数を指定してあげましょう。これで完成です！
Webシステムの構造、HTTP通信

**※後日、大幅に推敲します（汗）**




Webシステムは、
プレゼンテーション層、アプリケーション層、データ層の３層構造で構成されている。

※３層クライアントサーバーシステムは、サーバーの負荷分散や、システムのメンテナンス・改修がしやすくなる。

まず、
・`プレゼンテーション層`は、ユーザーインターフェース部として、Webブラウザなどのクライアントに対応する。
例）Googlem、safari等

・`アプリケーション層`は、システムのロジック部としてWebサーバーやAPサーバーが対応する。
例）Apache、Tomcat等

・`データベース部`として、RDBMSが対応する。
例）Oracle、MySQL、PostgreSQL



##HTTP通信

HTTP通信には、HTTPリクエストとHTTPレスポンスに別れる。

・**HTTPリクエスト**
ブラウザからサーバーに送信する情報の事。
HTTPリクエストメッセージとしてサーバーに情報が送られる。
またリクエストには「GET方式」と「POST方式」の２つの方法がある。


■GET方式
  GETには下記の３種類がある。
　・WebブラウザでURLを直接入力する。
　　　`アドレス　http://www.~~~~.co.jp/`

  ・画面に表示されているリンク設定文字などをクリックする
　　　`詳細情報はこちら`

　・formタグのmethod属性に「get」を設定する。
　　　`<form action="..."  method="get">~~~</form>`

  構成は
　リクエスト行   `GET/test.jsp?key1=value1&key2=value2HTTP/1.0`
 メッセージ・ヘッダ `Accept: image/gif;image/jpeg,....`
              `Accept-Language:jp`
              `User-Agent:Mozilla/5.0`
              `Host:www.test.net`
              `Connection:keep-alive`
  空白行
　メッセージ・ボディ

　

■POST方式
　　主に、お問い合わせフォームなどに入力したデータなどを送信する際に使用される。
　　formタグのmethod属性に「post」を設定する。
　　`<form action="..." method="post">~</form>`

　　構成は
    リクエスト行　　　　　`POST/test.jsp HTTP/1.0`
　　メッセージ・ヘッダ     `Accept: image/gif; image/jpeg,・・・・・`
                     `Accept-Language:jp`
                    `User-Agent:Mozilla/5.0~~~~`
                    `Host:www.test.net`
                    `Connection:keep-alive`
　　空白行
　　メッセージ・ボディ     `key1=value1&key2=value2`

　　

ざっくり言うとGET方式は、ハガキでデータをサーバーに送信して,そのデータを取りたい、欲しいと宣言する様なイメージで
POST方式は封筒に手紙を入れて自分のデータを与える様なイメージ。



■HTTPリクエストメッセージの構成

・リクエスト行・・・Webサーバーに要求する情報（メソッド、URL、HTTPバージョン）を示す
　　　　　　　・メソッド（方式）・・・Webサーバに要求を示すコマンド（GET方式、POST方式）
　　　　　　　・URL・・・リクエストの対象となるデータを指す情報
　　　　　　　・HTTPバージョン・・・Webブラウザがサポートするバージョン

・メッセージ・ヘッダ・・・WebサーバにWebブラウザの情報を示す。
　　　　　　　　　Webブラウザ側でサポートする。
　　　　　　　　　「データのタイプ」、「データの圧縮方法」、「ブラウザの種類」などの情報がある。
　　　　　　　　　
・空白行・・・Webサーバに、「メッセージ・ヘッダ」の終わりを伝えるために使用する。

・メッセージ・ボディ・・・Webサーバにデータを送るために使用する。
　　　　　　　　　例えば、テキストボックスに入力した情報などをWebサーバーに送るために使用する。
　　　　　　　　　入力情報がなければ空白。
　　　　　　　　　※GET方式の場合は、リクエスト行のURLに送信するデータが付加される。



**HTTPレスポンス**
Webブラウザからのリクエストに対して、
今度はWebサーバからWebブラウザに送信する情報。
WebサーバーからHTTPレスポンスメッセージとして、Webブラウザに情報が送られるが、
Webブラウザに表示する情報だけでなくHTTPリクエストに対する処理結果を示すステータスコードが含まれている。


■HTTPレスポンスメッセージ
こちらもかき４つの構成で成り立つ

ステータス行・・・Webブラウザに、Webサーバでの処理結果を伝える。
　　　　　　　HTTPのバージョン、ステータスコード、説明文などの情報がある。
メッセージ・ヘッダ・・・WebブラウザにWebサーバの情報を示す。「サーバの種類」、「返信するデータのタイプ」、「データの圧縮方法」などの情報がある
空白行・・・Webブラウザに、「メッセージ・ヘッダ」の終わりを伝えるために使用する
メッセージ・ボディ・・・「HTML文書」、「画像ファイル」、「動画ファイル」などのデータを格納するために使用する。




■ステータスコード
レスポンスの状態を表す３桁のコード

主なステータスコード

２００・・・OK（リクエストの受付に成功）
３０１・・・Moved Permanetly(リクエストで要求された情報の中身が別の場所に移動した)
４０１・・・Unauthorized（認証に失敗）
４０３・・・Forbidden（不許可、立入禁止）
４０４・・・Not Found（リクエストしたページが見つからない）
４０５・・・Method Not Allowed（許可されていないリクエスト形式）
５００・・・Internal Server Error（サーバ内部エラー）
【Java】実行可能なモジュールをGradleで作成

# 目的
UIを持たないシンプルなモジュールをJavaで作成した後、実行環境に配置する。

# 前提条件
・Eclipse
・Gradle

# build.gradleの設定

`application`のプラグインと、Mainクラスパスの定義を追加する。

```gradle:build.gradle
apply plugin: 'application'

mainClassName = 'jp.vicugna_pacos.admainte.main.AdMainteMain'
```
# コンパイル

1. Gradleのタスク`installDist`を実行する。
1. `プロジェクトフォルダ/build/install`に実行モジュールが作成されるので、コピーして所定の場所に移動する。
1. `bin`フォルダにあるbatファイルが起動スクリプト。

# JAVA_HOMEが無い場合
上記で作成されたbatファイルを見ると、環境変数の`JAVA_HOME`が定義されていることが前提となっている。
`JAVA_HOME`が無い場合は、下記のようにしてラッパーのbatファイルを作成してやると良い。

```:ラッパーbatのサンプル
@echo off
setlocal

set ARGS=%*
set DIRNAME=%~dp0
set BATNAME=%DIRNAME%AD_MAINTE\bin\AD_MAINTE.bat
set JAVA_HOME=E:\jre\8

%BATNAME% %ARGS%

endlocal
```

# プロパティファイルなどを外出しする

まず、外出ししたいファイルを`src/dist`フォルダに置く。

そのままでは`src/main/resources`にあるプロパティファイルが優先されるので、Jarファイルに含まれないようにする。

```gradle:build.gradle
jar {
    exclude '**/config.properties'
    exclude '**/logback.xml'
}
```

なおかつ、`dist`フォルダに置いたファイルを、実行時のクラスパスに含めるようにする。

```gradle:build.gradle
startScripts {
  classpath += files('src/dist/XxxAPlaceHolderForAConfigxxX')
  doLast {
    def windowsScriptFile = file getWindowsScript()
    def unixScriptFile    = file getUnixScript()
    windowsScriptFile.text = windowsScriptFile.text.replace('%APP_HOME%\\lib\\XxxAPlaceHolderForAConfigxxX', '%APP_HOME%\\config')
    unixScriptFile.text  = unixScriptFile.text.replace('$APP_HOME/lib/XxxAPlaceHolderForAConfigxxX', '$APP_HOME/config')
  }
}
```
このサンプルでは、`dist/config`フォルダに置いたファイルがクラスパスに含まれるようになる。

参考：
java - Adding classpath entries using Gradle's Application plugin - Stack Overflow
https://stackoverflow.com/questions/10518603/adding-classpath-entries-using-gradles-application-plugin
例のあれ

# 例のあれ
忘備録なんで見ないで
まちがってるかもしれないし
## コンテンツ配信
ファイルにパスワード保護はかけれるけど暗号化はできん！
## 商談商品
商品作ったら標準価格表に登録される、なんで基本全ての商品が載ってる。
価格表は複数の通貨ごとにリスト価格をつくれる！
納入商品は関係ない！！
## 時間ベースのワークフロー
条件にあわなくなったらキューから削除だ！こんな感じ
>この条件に一致するレコードが 7 月 1 日に作成され、[完了予定日] が 7 月 30 日に設定されているなら、時間ベースのアクションは 7 月 23 日にスケジュール設定されます。ただし、この商談が 7 月 23 日より前に「成立」または「不成立」に設定されると、この時間ベースのアクションはキューから削除されます。

## キャンペーンを作れる人
ユーザ項目の[マーケティングユーザ] チェックボックスがオンになっているユーザのみ
## 通貨
基準になるのはマスターに指定した通貨！
## 項目自動更新
レコードタイプも更新できる！
関連オブジェクトは主従の場合のみ！！ただし**従から**だから主じゃないから。取引先更新しても取引先責任者は更新できないから！
## ログイン IP アドレス範囲の制限と信頼済み IP 範囲
ログインIPアドレスに無いと信頼済みIP範囲にあっても弾かれる。ログイン不可。そらそうやろ、しっかり俺！
詳しくは[ここ](https://help.salesforce.com/articleView?id=admin_loginrestrict.htm&type=5)
Ansible：Ansibleのインストール簡易版


+ おまじないのyum update

```shell:command
# yum update
```

+ AnsibleをダウンロードするにはEPELが必要
 
```shell:command
yum install epel-release
```

+ おまじないのキャッシュクリア※キャッシュが残ってるとepelが見れない

```shell:command
yum clean all
```
+ Ansibleインストール

```shell:command
yum install ansible
```
markdown to pdf （n番煎じ）

# 発端
[ここ](https://qiita.com/HARASHO0103/items/f68cb6d2095b591e2d35)でも書いたように`markdown`でノートを取ったりする機会が増えました。また学校での会議で議事録を取るようになり「`pdf`で議事録を提出しろ」と言われたのでやり方調べたら意外に簡単にできたので、備忘録も兼ねてまとめようと思います

# 環境
windows10

# 導入するもの（簡単に）
* [visual studio code](https://code.visualstudio.com)（以下、vscode）
* markdown-pdf（拡張機能）<br>![markdown-pdf.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/c6165924-2692-c993-3452-27844306167d.jpeg)
* 適宜、拡張機能

# 手順
## vscodeのインストール
1. お好きなロケーションにインストーラをダウンロードして起動
2. ポチポチしながら流し読みしてイエスマンになりきる
3. インストール完了

## 拡張機能を導入
1. vscodeを起動
2. 画面左（下の画像）の一番下をクリック<br>![vscode-left.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/03fdfad0-011c-e257-ab16-3eafeed3411f.jpeg)
3. `markdown pdf` みたいな感じで検索かける<br>![vscode-search.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/7012861d-11bf-7285-f167-179a1fa56639.jpeg)

4. 一番上のものをインストールする
5. 導入完了


## 設定
1. 導入時と同じように`markdown pdf`と検索をかける<br> ![vscode-search.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/7012861d-11bf-7285-f167-179a1fa56639.jpeg)
2. markdown PDFの右にある歯車をクリック
3. 以下の画像の項目を探してチェックを外す<br>（ヘッダーとフッターにファイル名とかの情報乗りまくりでうざったいので消す。気にならなければ必要なし）<br>![setting1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/38fab714-85ad-b2d6-cec6-f9c3a9c6791a.jpeg)
4. 以下の画像の項目を探す<br>![setting2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/c3599e06-75ea-4b91-35ec-2d72b7b81235.jpeg)<br>ファイル保存時（要は`Ctrl` + `s`を押したとき）にPDFを自動で生成するかの設定<br>俺は好きだからONにしてるけどたまにうざいから悩みどころ


## pdf出力
1. `.md`などmarkdownファイルを生成する<br>今回はこんな感じ<br>![markdown-test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/e7d82560-477d-dbc1-afa7-daab10508f06.jpeg)
2. vscodeで開く
3. ソースコードを右クリック<br>![right-click.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/6ed743f6-bc59-5278-6061-80c8c6c5cb80.jpeg)
4. `Markdown PDF:Export(PDF)`をクリック
5. しばらくしたら`.md`ファイルと同じディレクトリにPDFが生成される<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/7d0b22fe-a89a-077a-ed06-d3fb5bc67a16.png)
6. PDFファイルを開いてみる<br>![yeah.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268328/014cb011-33ef-a2fa-1133-aeba83edaa90.jpeg)
7. できたね

# 注意
* たまにエラー吐いて空ファイルが生成されることがある<br>$\rightarrow$ ~~再起動したら直ることが多い~~ （2019年7月29日 追記分）
* 数式には対応していない
* 今回はvscodeを使ったmarkdownからPDFに変換する方法をまとめたものなので日本語化などは割愛させてもらいます

# 参考にしたもの
* [https://qiita.com/mimickn/items/05275d46131ff194ef46](https://qiita.com/mimickn/items/05275d46131ff194ef46)
* [https://blog.mmmcorp.co.jp/blog/2018/11/16/markdown-to-pdf-document/](https://blog.mmmcorp.co.jp/blog/2018/11/16/markdown-to-pdf-document/)

# 最後に
ここまでお読みいただきありがとうございます。
私の知識も浅いものです。
なにかご指摘がございましたらいつでもよろしくお願いします

# 追記（2019年7月29日）
出力時のエラーは学内回線でのプロキシがちゃんと通ってない説が浮上
PHP trueになるもの・falseになるもの確認　falseを入れた配列はどっちに？

#はじめに
PHPにどのような型があるのかは、
こちらの記事でご確認ください。
[PHPの型一覧](https://qiita.com/minato-naka/items/abd7f76dca2b15a7d6ba)

PHPでは暗黙的な型変換が行われるため、
bool以外の型の変数でも、
必要な状況では自動的にboolに変換されます。

bool型以外の変数で、
どのような値はtrueになりどのような値はfalseになるのか確認します。

#falseになるもの
わかりやすいのでまずはfalseになるものから。

* stringの空文字列
* stringの0
* intの0
* floatの0.0
* 要素が0個のarray
* null

がfalseとなります。

実際に検証。

```php
$stringEmpty = '';
var_dump((bool)$stringEmpty);
// bool(false)

$stringZero = '0';
var_dump((bool)$stringZero);
// bool(false)

$int0 = 0;
var_dump((bool)$int0);
// bool(false)

$float0 = 0.0;
var_dump((bool)$float0);
// bool(false)

$arrayEmpty = [];
var_dump((bool)$arrayEmpty);
// bool(false)

$null = null;
var_dump((bool)$null);
// bool(false)
```

すべてfalseになりました。

#trueになるもの
上記のfalseになるもの以外はすべてtrueになります。

いくつか検証してみます。

まずは普通の例。

```php

$string = 'aaa';
var_dump((bool)$string);
// bool(true)

$int = 123;
var_dump((bool)$int);
// bool(true)

$float = 0.1;
var_dump((bool)$float);
// bool(true)

$array = ['a'];
var_dump((bool)$array);
// bool(true)
```

これは普通に全部trueです。
　
　
　
次はちょっと特殊な例で、
何かfalseになるものがないかいろいろ試してみます。

```php
// 文字列のfalse
$stringFalse = 'false';
var_dump((bool)$stringFalse);
// bool(true)


// 文字列の半角スペース
$stringSpace = ' ';
var_dump((bool)$stringSpace);
// bool(true)


//マイナスのint
$intNegative = -1;
var_dump((bool)$intNegative);
// bool(true)


//falseを入れた配列
$arrayFalse = [false];
var_dump((bool)$arrayFalse);
// bool(true)

//intの0を入れた配列
$arrayZero = [0];
var_dump((bool)$arrayZero);
// bool(true)


//インスタンス
class MyClass {};
$object = new MyClass();
var_dump((bool)$object);
// bool(true)


//クロージャ
$closure = function(){};
var_dump((bool)$closure);
// bool(true)


//リソース
$resource = fopen('index.php', 'r');
var_dump((bool)$resource);
// bool(true)
```

全部trueになりました。


#まとめ
まずは、下記のfalseになるもの一覧を把握し、
それ以外はすべてtrueになるということを把握しておく。

* stringの空文字列
* stringの0
* intの0
* floatの0.0
* 要素が0個のarray
* null

　
そのうえで、
ちょっと混乱しそうな
上で書いた特殊な例のようなものも把握しておくとよさそうです。


#参考
[独習PHP](https://www.amazon.co.jp/dp/B01FH3KVNU/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
[PHP: 論理型 (boolean) - Manual](https://www.php.net/manual/ja/language.types.boolean.php)
初投稿

とりあえず登録してみたので初投稿してみます！

現在仕事で使っているJava、Vue.jsを始め、HTML,CSS、その他諸々勉強したことをまとめていきたいと思います。
先日初めてMacBookを購入したのでMacについても書くかもしれません。

大学でも情報系の授業は受けていましたが、ほぼ理解できないまま社会人になったのでまだまだ駆け出しです。

自学のためにのんびり投稿していきたいと思います。
http.HandleFunc、http.HandlerFuncの違いをまとめてみた。

[前回の記事](https://qiita.com/_kyamasan/items/dbf442294560946a0770)の続き。

##http.Handlerとhttp.HandlerFuncの違いって何なんだよ

###http.Handler:インターフェース(ResponseWriterと*Requestを引数に取るServeHttpメソッドさえあれば全部Handlerとして扱える！)

```server.go
type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}
```

###http.HandlerFunc:型(ResponseWriterと*Requestを引数に取るメソッドならなんでもHandlerFunc型)

```server.go
type HandlerFunc func(ResponseWriter, *Request)
```


##http.Handleとhttp.HandleFuncの違いって何なんだよ

###http.Handle:メソッド(DefaultServeMux.Handleのラッピング)

```server.go
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
```

###http.HandleFunc:メソッド(DefaultServeMux.HandleFuncのラッピング)

```server.go
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	DefaultServeMux.HandleFunc(pattern, handler)
}
```


##DefaultServeMux.HandleとDefaultServeMux.HandleFuncの違いって何なんだよ


###DefaultServeMux.Handle:メソッド(パターン(URL)とHandlerを紐づける！)

```server.go
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
	mux.mu.Lock()
	defer mux.mu.Unlock()

	if pattern == "" {
		panic("http: invalid pattern")
	}
	if handler == nil {
		panic("http: nil handler")
	}
	if _, exist := mux.m[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	if mux.m == nil {
		mux.m = make(map[string]muxEntry)
	}
	e := muxEntry{h: handler, pattern: pattern}
	mux.m[pattern] = e
	if pattern[len(pattern)-1] == '/' {
		mux.es = appendSorted(mux.es, e)
	}

	if pattern[0] != '/' {
		mux.hosts = true
	}
}
```

###DefaultServeMux.HandleFunc:DefaultServeMux.Handleを呼び出す。

```server.go
// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	if handler == nil {
		panic("http: nil handler")
	}
	mux.Handle(pattern, HandlerFunc(handler))
}
```

#結局、違いって何だったの？

http.Handleを呼び出すには、http.Handler(ServeHttpメソッドを持つインターフェース)が必要でした。
でも、http.HandleFuncを呼び出すには、インターフェースは不要で、単にResponseWriter, *Requestを引数に持つファンクションさえ渡せばよい。

つまり、実際にHandlerを登録する作業はhttp.Handleにhttp.Handler(インターフェース)を渡す必要があるけど、
プログラマが実際にハンドラを登録する時には、http.HandleFuncにhttp.HandleFunc(ファンクション)を渡せばよい。
mcs.rsp => csc.rsp へ

こんな警告が出たので、置き換えました。
ただ、ちょっと理解が浅かったので、ドキュメントを確認。

```
Using obsolete custom response file 'mcs.rsp'. Please use 'csc.rsp' instead.
UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface:TickCompilationPipeline(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget)
```

公式曰く

- https://docs.unity3d.com/ja/current/Manual/PlatformDependentCompilation.html

> .rsp ファイルは起動するコンパイラーと一致する必要があることに注意してください。例えば
> 
> when targeting the .NET 3.5 Equivalent (deprecated) scripting runtime version, mcs is used with mcs.rsp, and
> when targeting the .NET 4.x Eqivalent scripting runtime version compiler, csc is used with csc.rsp.

とのことなので、.NETのバージョンに合わせてcsc.rspを使うのは至極当然のことのよう。
実際変更して、トラブルは起きてない（いまのところ）。
F# のコメント機能について公式のチュートリアルをまとめた

# F#がサポートしているコメント機能
VisualStudioでF#Totolialを発見したので英語を日本語に訳したものです。
公式ですでに日本語かされているかもしれませんが、勉強だと思い理解しながら訳しました。

何か間違っている部分ありましたらご指摘いただけると幸いです。

- シンタックスハイライト？はc#にしてあります。F#まだない？

## 1. ダブルスラッシュコメント

   - よく使われる

   ```fsharp
   // これはコメントです
   ```

## 2. ML ( マルチライン ) スタイルブロックコメント

   - あんまり使われない

   ```fsharp
   (* MLスタイル
   だよ *)
   ```

## 3. トリプルスラッシュのコメント

   - 関数、型などを文書化するために使用される
   - これらのコメントで装飾されたものの上にマウスを置くと、テキストとして表示される
   - 詳細 
     - https：//docs.microsoft.com/ja-jp/dotnet/articles/fsharp/language-reference/xml-documentation

   ```fsharp
   /// マウスオーバーで文章が表示させるよ
   let number = 2
   ```

## C#だと

```c#
   /// <summary>
   /// マウスオーバーで表示されるよ
   /// </summary>
```
http.Handle、http.Handlerの違いをまとめてみた。

ここ数日golangを触ってるけど、この2つが理解できなかったので再度まとめてみます。

##DefaultServerMuxとは

まず、違いを抑えるために知らなければいけないのがDefaultServerMuxです。その名の通り、デフォルトで使用されるServeMuxです。
ServeMuxは、要求されたURLを元に、どのページを表示すべきなのか判断してくれます。

##http.Handleとhttp.Handlerの違いって何なんだよ

###http.Handler:インターフェース(ResponseWriterと*Requestを引数に取るServeHttpメソッドさえあれば全部Handlerとして扱える！)

```server.go
type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}
```

###http.Handle:メソッド(DefaultServeMux.Handleのラッピング)

```server.go
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
```

###DefaultServeMux.Handle:メソッド(パターン(URL)とHandlerを紐づける！)

```server.go
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
	mux.mu.Lock()
	defer mux.mu.Unlock()

	if pattern == "" {
		panic("http: invalid pattern")
	}
	if handler == nil {
		panic("http: nil handler")
	}
	if _, exist := mux.m[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	if mux.m == nil {
		mux.m = make(map[string]muxEntry)
	}
	e := muxEntry{h: handler, pattern: pattern}
	mux.m[pattern] = e
	if pattern[len(pattern)-1] == '/' {
		mux.es = appendSorted(mux.es, e)
	}

	if pattern[0] != '/' {
		mux.hosts = true
	}
}
```

DefaultServeMux.Handleが呼ばれることで、ようやく「このURLが飛んで来たら、このHandlerを使ってね！」みたいな紐づけができるようになる。

#この記事のまとめ
DefaultServeMux.Handleが(http.Handleを経由して)http.Handlerを登録するんです。
kintoneでふりがなを自動入力

ふりがなを自動入力する[kintone plugin](https://github.com/cy-takeuchi/auto-kana)を作ったので公開します。
ふりがなの自動入力には[harisenbon/autokana](https://github.com/harisenbon/autokana)を利用しています。

# できること
![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102790/ce935592-be90-32da-0a2c-eb3253b0e07b.gif)

# プラグイン設定画面
複数フィールドに対応しています。
![plugin-setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102790/f79eaff7-8a9d-ac28-fbed-0929c2101e99.png)

# ポイント
DOM操作していません。

要素IDを設定したスペースフィールドを設置する必要があります。
そのスペースフィールドにテキストボックスを表示し、保存時に本来のフィールドに値を設定することでDOM操作を回避しています。
多次元配列の値比較

#多次元多次元配の値の比較について
下記コードは中身がわかるように配列A、Bを作成した後、
配列A,Bに格納されている時間を比較して、
合致すれば結果値格納用配列に。
合致しなければ格納しない。
という単純そうなコードです。

やる前は簡単だろと思っておりましたが、
多次元配列同士の比較がうまくされず、とても時間をかけてしまいました。
以下が私が最終的に作成したコードです。
※もっと効率的なやり方あれば教えていただけるとありがたいです・・・

#コード
```php
<?php
//多次元配列Aの作成
$list = array(
  '10' => array(
      '1' => '10:00', 
      '2' => '10:15', 
      '3' => '10:30', 
      '4' => '10:45'
  ),
  '11' => array(
      '1' => '11:00', 
      '2' => '11:15', 
      '3' => '11:30', 
      '4' => '11:45'
  ),
  '12' => array(
      '1' => '12:00', 
      '2' => '12:15', 
      '3' => '12:30', 
      '4' => '12:45'
  ),
  '13' => array(
      '1' => '13:00', 
      '2' => '13:15', 
      '3' => '13:30', 
      '4' => '13:45'
  ),
  '14' => array(
      '1' => '14:00', 
      '2' => '14:15', 
      '3' => '14:30', 
      '4' => '14:45'
  ),
  '16' => array(
      '1' => '16:00', 
      '2' => '16:15', 
      '3' => '16:30', 
      '4' => '16:45'
  )
);

//多次元配列Bの作成
$list2 = array(
  '10' => array(
      '1' => '10:01', 
      '2' => '10:15', 
      '3' => '10:31', 
      '4' => '10:45'
  ),
  '11' => array(
      '1' => '11:01', 
      '2' => '11:15', 
      '3' => '11:30', 
      '4' => '11:45'
  ),
  '12' => array(
      '1' => '12:01', 
      '2' => '12:15', 
      '3' => '12:30', 
      '4' => '12:45'
  ),
  '13' => array(
      '1' => '13:01', 
      '2' => '13:15', 
      '3' => '13:30', 
      '4' => '13:45'
  ),
  '14' => array(
      '1' => '14:01', 
      '2' => '14:15', 
      '3' => '14:30', 
      '4' => '14:45'
  ),
  '15' => array(
      '1' => '16:01', 
      '2' => '16:15', 
      '3' => '16:30', 
      '4' => '16:45'
  )
);

//多次元配列A
//多次元を比較しやすいように変換しております。
foreach ($list as $key1 => $val1) {
    foreach ($val1 as $key2 => $val2) {
        $text1[] = $val2;
    }
}
//多次元配列B
//多次元を比較しやすいように変換しております。
foreach ($list2 as $key1 => $val1) {
    foreach ($val1 as $key2 => $val2) {
        $text2[] = $val2;

    }
}
//多次元配列AとBの照合
//合致すれば結果($answer)に格納
foreach ($text1 as $key => $val) {
        if(in_array($val , $text2)){
            $answer[] = $val;
        }
}
print_r($answer );

?>
```
どうするjsdo資産

#概要

jsdoが2019年10月31日（木）15:00 で、サービスを終了らしい。
自分、4000を超える資産がある。どうする俺。
代替を考える。

#とりあえず

htmlかzipでローカルにダウンロードする。（避難する。）
アセットは、どうする。

#案1

gistに、書き込む。
確か、100件くらいで、切られた。
検索できる。
https://gist.github.com/search?utf8=%E2%9C%93&q=user%3Aohisama
gisthackで、見る。
ocksで、見る。(index.html)


#案2

plunkerに、書き込む。
検索できん。

#案3

VPSでwordpressへ移行する。
xmlでインポート。

以上。
Google CloudのAppEngineでGo v1.12を使ったときにハマったこと

Google Cloud PlatformのAppEngine（PaaS）の公式ドキュメントでは、色々サンプルや使い方が書いてあるのですが、日本語翻訳されている情報が足りない+Goランタイムに関する情報がすくないので、ちょっとハマりました。
https://cloud.google.com/appengine/docs/standard/go/runtime?hl=ja <-この辺ね

# go112 では"google.golang.org/appengine"は使っちゃダメ
いろんなサンプルでこれを使ってるのですが、対応しているのはgo111までです。go112使う場合は使うと問題が出ます。主にcontext使ってAPI呼ぶとこでコケます。

## もちろんappengine.main()は使わない
go111とかの場合は,appengineのcontext渡さないと、「これはappengineのcontextじゃないです」的なエラーで動かなかったりしたのですが、go112では使わない。 APIは"cloud.google.com/go"を使う

## Mail APIは使えない?
ちゃんと検証していないのですが、Mail APIのコードもドキュメントもappengineパッケージを使う前提で書かれているので、たぶん無理。ドキュメントにも「sendgridとか使ってね」って書いてあった

# 詳しくはこちら（英語）
https://cloud.google.com/appengine/docs/standard/go112/
JavaとC++は学ぶな！！初心者が学ぶべき言語【厳選】


C / C++とJavaから勉強することは運転したことない人がマニュアル免許を取るようなものです。

オートマの免許をとってからマニュアルを運転しましょう。

# はじめに

最近、何かと耳にするプログラミングを勉強してみたい！

だけど、何から始めたらいいかわからない！という方はたくさんあると思います。

まず、プログラミングを勉強するにはどの言語を勉強するか決める必要があります。

ですが、プログラミングの言語は何百という数があり主要なものでも何十とあります。

多少、偏見は入りますが今回はシリコンバレーの現役エンジニアである僕が勉強するべき言語を厳選しました。

# 学ぶべきではない言語

C / C++やJavaは

今の世界で最もメジャーで重要な言語であるとほとんどの人が同意すると思います。

これらの言語は昔から存在しており、後に作られるプログラミング言語に多大なる影響がある。

偉大なる言語です。なのでよく耳にすると思いますし、いろんな記事があります。

ですが！！C / C++やJavaは初心者には決してオススメしない言語です。

詳しくは後述しますが、理由は難しいからです。

# 学ぶべき言語

ずばり、２０１９年の日本において学ぶべき言語は以下の４択です。

- Ruby
- JavaScript
- Python
- Swift

そしてこれらからどの言語を勉強しないといけないのかは作りたいものによって非常に簡単に決めることができます。

- WEBをするならRubyかJavaScript

- 機械学習や画像処理をするならPython

- iOSアプリの開発ならSwift

# Ruby

唯一の世界的な日本製の言語です。主にWEBの世界でRuby on Railsと使用されることが多いです。日本製の言語ですので日本語でのコミュニティも多く学習のしやすさの点でもおすすめします。

# JavaScript

ブラウザで動く唯一の言語です。WEBを作成する方（特にフロント、デザイン）は避けては通れない言語です。ブラウザで動く言語はこの言語だけですので、リッチなWEBサイトを作成するにはJavaScriptを使用する以外方法がありません。あまりメジャーではありませんが（マイナーでもありません）JavaScriptを使用してサーバーサイドも作ることができます。つまりJavaScriptのみでWEBサイトを作成することが可能になっています。

# Python

世界で使われている最もメジャーな言語でしょうか。コードはRubyとかなり似ていてかつ世界スタンダートです。この言語の得意科目は最近はやりの機械学習やAIや画像処理になります。特に作りたいものが決まっていないのであれば、Pythonを勉強することをオススメします。

# Swift

Appleが作ったAppleのための言語です。iOSアプリやMacのデスクトップアプリが作成できますが、それ以外のことはほとんどできません。なので、明確にiOSアプリが作りたいやMacのアプリを作りたい方のみにオススメします。




# C / C++とJavaは学ぶべきでない理由

## 理由１: 難しい

プログラミングというのは難しい。賢い人がパソコンに向き合ってる。

そのようなイメージがあるのはこいつら C / C++ と Java などのせいだと個人的に感じています。

テクノロジーというのは時間が立つほど使用者にとって使いやすく簡単になっていくものです。

お米をたくのに昔は火から炊かないといけないところを、今はボタン一つで炊けます。

プログラミング言語も決して例外ではありません。

C / C++ と Javaのあとにたくさんのプログラミング言語が作成されて、使用者にとって使いやすい言語が山ほど出てきています。

わざわざ敷居が高い言語から勉強を始める理由は何一つありません。

車を運転するのにマニュアル免許から取るようなものです。




## 理由２：早さなんていらない

C / C++ や Java の一つの利点は早さです。

確かにこれらの言語はコンパイル言語といって、他の簡単な言語と比べて格段に早いです。

ですが、プログラミングを勉強し始めたばっかりの人は早いプログラムを書く必要があることなど滅多にないです。

そもそも、プログラミングの世界で早いというのはコンマ以下の秒数を競うものですから一般生活において全く気にならないものです。

例えば、WEBサイトをコンパイラ言語を使用して0.01秒早いものにしたところで、ネット通信で２秒以上かかっているのでユーザーには全く伝わりません。

確かに膨大な処理をするさいに、早さに明確な差が出るときはあります。ですが、そのような処理は一つのプログラミング言語を勉強したての人に任せることはほぼないと言ってもいいでしょう。




## 理由３: パソコンの深い理解なんていらない

C / C++を勉強する利点は早さ以外にもパソコンをより深く理解できるところにあります。

C / C++ は初期の言語ですのでパソコンのメモリなど、他の言語では自動でしてくれることを手動でしなければいけません。そのため、パソコンのことをある程度に理解していないとコードが書くことができません。

もちろん、パソコンの仕組みを深く理解することは大事なことです。ですが、ただでさえ学習に挫折しやすいプログラミングをわざわざ他にも勉強しないといけないことを増やすのは得策ではありません。

# まとめ

初めてプログラミングを学ぶ方はRubyかJavaScriptかPython、またはSwiftもうちのどれかで無難です。C / C++ や Java はメジャーでよく聞きはしますが、学ぶには難易度が高くはじめに学ぶ言語としては全くオススメしません。他にもGoogleが作ったgolangなど有名でこれから流行りそうな言語はたくさんありますので、気になる方は調べてみても面白いかもしれません。
VSCodeのGitの欄に「5000」と表示された時の対処法

#はじめに
VScodeを開いてみたら、Gitの欄に「5000」と表示されている。
![vscode_git_5k_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320820/82fbd1c3-8946-fd8b-f760-94c8319e491f.png)

#対処法

ユーザーフォルダに「.git」フォルダが生成されているため、これを削除する。

#結果
5000ものソース変更リクエストが消去された。
原因については随時調査していく。
PageViewController優良記事まとめ

**・[MXParallaxHeaderとTabmanでTwitterのプロフィール画面のようなヘッダーとページングメニューをサクッと実装する – PSYENCE:MEDIA](https://tech.recruit-mp.co.jp/mobile/post-18199/)**
→`Twitterのプロフィール画面`を例に
**スクロール量に応じて変化するヘッダー** と **シームレスなコンテンツの切り替えを備えた画面**の実装を解説

**・[(81) iOS Swift Tutorial: Paging through multiple ViewControllers with UIPageViewController 05/24 🎄 - YouTube](https://www.youtube.com/watch?v=jVBtDH6jjl8)**

# ライブラリ
**・[rechsteiner/Parchment: A paging view controller with a highly customizable menu ✨](https://github.com/rechsteiner/Parchment)**
VScodeで勝手にタブが切り替えられるのを阻止する！

仲間とエディタの話をしていて途中まで自分がVScodeを熱弁していたときに
「タブが勝手に切り替わっちゃうのは使いづらくない?」とツッコまれ納得でしかなかったので
勝手に切り替わらないようにする方法についてまとめてみました。

## 変更前

![before.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195292/6d034d4c-8c64-c4f2-9b50-f86f4c7aab62.gif)

 

## 変更後

![after.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195292/9f65d77b-051a-d33b-72f8-70359733ef20.gif)

## 行ったこと

### 1. 「 Code > 基本設定 > 設定 」から設定ファイルを開く


<img width="1262" alt="スクリーンショット_2019-07-26_1_48_36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195292/1403a298-a2a7-0bd3-f2e0-60cb0cbeec52.png">

### 2. 「設定の検索」で`"workbench.editor.enablePreview"`を検索！

<img width="1668" alt="スクリーンショット_2019-07-26_1_51_48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195292/4231059b-ccc2-21d3-a48a-6493021a2084.png">

### 3. Workbench > Edhitor: Enable Preview の欄をクリックしてFalseに！

<img width="1680" alt="スクリーンショット_2019-07-26_2_01_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195292/042fa268-2500-35e3-5bc2-21da103b9d34.png">
sudo権限の無いUbuntuでPython環境を整えるためのあれこれ

root権限が無いサーバー(Ubuntu16.04)でPython環境を作る際、仮想環境に悩んだのでまとめておきます。導入の解説は無いのでご理解ください。

# 1日目 virtualenvの導入
まず候補に挙げたのが、pyenvとvirtualenvです。それぞれの主な利点・欠点は, 

- pyenv
  - 利点 : 初めに設定すれば、以後ディレクトリに入るだけでバージョンが切り替わる
  - 欠点 : 複数のPythonバージョンを切り替えて使えるが、同一のバージョンで複数の環境が作れない
- virtualenv
  - 利点 : 同一のバージョンで環境をいくらでも作れる
  - 欠点 : 環境の切り替え時にいちいち```activate/deactivate```するのが面倒

pyenvは```activate```する手間が無い分楽ですが、同じPythonのバージョンで複数の環境が作れない以上どうしても仮想環境一個一個が大きくなってしまいます。
出来るだけミニマルで、要らなくなったら気軽に消せるような仮想環境が欲しかったためvirtualenvを選びました。
また、virtualenvと全く同じ動作を実現するvenvというものがPython3以上から標準化されていますが、手元にPython2で書かれたプロジェクトがあるため今回はvirtualenvにしました。

# 2日目 めんどくさい
さて、virtualenvを入れてクリーンな環境作りを、と思っていたのですが問題が起こりました。
virtualenvはpyenvと違い、Pythonそのものは自前で用意する必要があります。

```
$ apt install python3.6
```
sudo権限が無いので上記のようなコマンドは使えず、通常

```
$ wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz
$ ./configure --prefix=$HOME/usr
$ make
$ make install
```
このようにソースからインストールしなければなりません。面倒だ。

また、sqlite3などのモジュールが無い場合、モジュールをインストール後**一度Pythonそのものを入れ直す必要があります**。

```
apt-get remove python3
```
sudoがあればこの一言で消せる（らしい）のですが、あいにくapt系は一切使えません。インストール時、自分のローカル```$HOME/usr```とかを指定していたならば、そこに入って関係のあるファイルを一個一個探して消す必要があります。こうなるととっても面倒です。
<font color="red">※かなり憶測が含まれます。別に消さなくても再インストールで上書きすればいいんじゃ？という気もしますがあいにくやったことないから分からない。とりあえずPythonの削除が手間だというのは恐らく正しいです。</font>

この削除問題は、インストール時にPythonバージョン毎にディレクトリを分ければ解決できます。

```
$ wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz
$ ./configure --prefix=$HOME/usr/python3.6.9
$ make
$ make install
```
これで消したいときは

```
rm -r $HOME/usr/python3.6.9
```
で一発です。

さて削除は楽になりましたが、インストールが一々めんどくさい…それにもしミスって```$HOME/usr```直下にインストールしたら削除するのが大変だし、**sudo権限が無くても簡単にPythonを導入・削除できるバージョン管理ツールは無いものか…**

# 3日目 pyenvの導入
**ありました。pyenvです。**

インストール

```
pyenv install 3.6.9
```

アンインストール

```
pyenv uninstall 3.6.9
```

簡単にPythonを入れたり消したりできます。

インストールしたPythonは

```
$HOME/.pyenv/versions/
```
に置かれることになります。つまり

```
virtualenv $hoge/env_py3.6 --python=$HOME/.pyenv/versions/3.6.9/bin/python3.6
```
このように、**pyenvで入れたPythonからvirtualenvが仮想環境を作成する**というコンビネーションが可能になります。

# 終わりに
斯くして、Pythonの導入はpyenvに任せ、仮想環境はvirtualenvで作るというスタイルに落ち着いたのでした。
他にも、pyenv-virtualenvという元々ハイブリッドになってるやつがあるらしく気になっています。ただ、これは```activate/deactivate```しないでいい代償にかなり重いと聞いたので、とりあえずはこのまま使ってみます。

# 7/28追記
pipenvなる便利ツールがあり、今はpyenv+pipenvのような運用が流行っているそうです…
全然知らなくってまだvirtualenvとの違いが分かっていないので色々調べて試してみます。
蟻本の蟻問題をrubyで解いてみる(記録用)

# 問題
長さLcmの竿の上をn匹のアリが毎秒1cmのスピードで歩いています。アリが竿の端に到達すると竿の下
に落ちていきます。また、竿の上は狭くてすれ違えないので、二匹のアリが出会うと、それぞれ反対を向い
て戻っていきます。各アリについて、現在の竿の左端からの距離x[i]はわかりますが、どちらの方向を向いて
いるのかはわかりません。すべてのアリが竿から落ちるまでにかかる最小の時間と最大の時間をそれぞれ求
めなさい。

# 入力例
L=10
n=3
x=(2 6 7)

# 出力例
max=8
min=4

# 解答例
```
length=gets.to_i
number=gets.to_i
ants=gets.split.map(&:to_i)
max=0
min=0
array=[]
ants.each do|ant|
  array.push([ant, length-ant])
end
array.each do|ar|
   if ar.max>max
     max=ar.max
   end
   if ar.min>min
     min=ar.min
   end  
end  
puts max
puts min
```
Gensimを用いたトピックモデルの学習

#Gensimを用いたトピックモデルの学習
夏目漱石の"坊ちゃん"を題材に、トピックモデルの学習に挑戦してみます。


##参考URL
難しいトピックモデルを簡単に！PythonライブラリGensimの使い方
https://www.sejuku.net/blog/67863

##準備

実装概要は、下記の通りです。

1.文章の分かち書き
2.単語リストの作成
3.コーパス作成
4.トピックモデルの学習・可視化

##実装

###実装準備

まず、gensimをインストールしておきます。

```python
!pip install gensim
```

###1.文章の分かち書き

ローカルに保存してあった坊ちゃんのデータを分かち書きします。
分かち書きにはjanomeを利用しました。

```python
import janome
import numpy as np

FILE_PATH = "./bocchan.txt"
text=""
a = Tokenizer(wakati=True)
with open(FILE_PATH, 'r',encoding="Shift-JIS") as f:
    for line in f:
        lines = a.tokenize(line)
        text += " ".join(lines)
text[0:500]
```

'坊っちゃん夏目 漱石+ 目次一親 譲 お やゆ ずり の 無鉄砲 むてっぽうで 小 供 の 時 から 損 ばかり し て いる 。 小学校 に 居る 時分 学校 の 二 階 から 飛び降り て 一 週間 ほど 腰 こし を 抜 ぬかし た 事 が ある 。 なぜ そんな 無闇 むやみ を し た と 聞く 人 が ある かも 知れ ぬ 。 別段 深い 理由 で も ない 。 新築 の 二 階 から 首 を 出し て い たら 、 同級生 の 一 人 が 冗談 じ ょうだんに 、 いくら 威張 いばっ て も 、 そこ から 飛び降りる 事 は 出来 まい 。 弱虫 や ー い 。 と 囃 は やし た から で ある 。 小使 こづかい に 負ぶさっ て 帰っ て 来 た 時 、 おやじ が 大きな 眼 め を し て 二 階 ぐらい から 飛び降り て 腰 を 抜かす 奴 やつ が ある か と 云い っ た から 、 この 次 は 抜かさ ず に 飛ん で 見せ ます と 答え た 。親類 の もの から 西洋 製 の ナイフ を 貰 もらっ て 奇麗 きれい な 刃 は を 日 '

###2.単語リストの作成

"。"を区切り文字として小説を区切り、一文にします。
一文をさらに半角で区切り単語を配列に格納していきます。

なお、不要な単語を取り除くため、ストップワードを適当に選択しています。

```python
#リスト = str.split(‘区切り文字’)
text_list = text.split("。")

stop_words =  set('た する ない を に の ん は で が てる と ぜ だ て いる から 「 」'.split())

#ストップワードの除去
texts = [[word for word in document.split(" ") if word not in stop_words ] for document in text_list]
```




###3.コーパス作成

辞書とコーパスを作成していきます。
前処理として、filter_extremesメソッドを用いて、
頻度が多すぎる・少なすぎる単語は辞書から削除してしまいます。
なお、コーパスとは、文章毎に「単語ID,単語IDの文章内の出現頻度」のタプルを持つデータのことです。

```python
from gensim import models
from gensim import corpora

dictionary = corpora.Dictionary(texts)

# no_below：頻度がno_below回以下の単語は無視
# no_above： 頻出単語も無視
# keep_n ： 使用単語数に上限設定

dictionary.filter_extremes(no_below=100, no_above=0.5, keep_n=100000)

corpus = [dictionary.doc2bow(text) for text in texts]
corpus 
```

文章毎に、[(単語ID,単語IDの文章内の出現頻度)]の下記情報が手に入ります。
これがコーパスです。

[[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1)],
 [(5, 1),
  (6, 1),
  (7, 1),
  (8, 1),
  (9, 1),
  (10, 1),
  (11, 1),
  (12, 1),
  (13, 1),
  (14, 1),
  (15, 1),
  (16, 1)],
...(中略)

###4.トピックモデルの学習・可視化

トピックモデルを学習します。 
トピック数は所与として与え、トピック毎に特徴的な文言を表示してみます。

```python
num_topics = 6
 
lda = models.ldamodel.LdaModel(
    corpus=corpus,
    num_topics=num_topics,
    id2word=dictionary
)
```

トピックを可視化してみます。

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(30,30))
for t in range(lda.num_topics):
    plt.subplot(3,2,t+1)
    x = dict(lda.show_topic(t,200))
    im = WordCloud(background_color="white",font_path='C:\Windows\Fonts\meiryo.ttc').generate_from_frequencies(x)
    plt.imshow(im)
    plt.axis("off")
    plt.title("Topic #" + str(t))
```

![コーパス可視化2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367093/b9844244-2b58-237f-da85-30d2ad867992.png)


今回は、チューニングもしていないですが、
色々触ってみると面白そうです。


次回は、坊ちゃんの文章要約に取り組みます。
WindowsでLinuxのススメ(WSL)

#WindowsにLinux(Ubuntu)を入れよう！
Windows10でLinuxが使えるんだから積極的に使っていこう！という試み
vimやPython3なんかも使えるし簡単な勉強にはちょうどいいと思います

#手順
1.コントロールパネル→プログラム→Windowsの機能の有効化または無効化を選択し、
Windows Subsystem for Linuxの欄にチェックを入れる

2.ここで一回PC再起動

3.起動したらスタートメニューのMicrosoft StoreのアプリからUbuntuをインストールすれば入れられます
**が**、今回はPower Shellから入れます

4.WindowsキーとRキーを同時押しして「ファイル名を指定して実行」ウィンドウを出します
名前にPowerShellと入力して起動
管理者権限で起動するためコマンドを入力

※管理者権限で起動しなくてもDLしたファイルを.zip形式にリネームして
それを解凍してインストールする方法もあります


```PowerShell.
PS C:>Start-Process powershell.exe -Verb runas
```

5.管理者権限で起動したPowerShellにコマンドを入力してUbuntuのDLとインストール

```PowerShell.
PS C:> Invoke-WebRequest -Uri https://aka.ms/wsl-ubuntu-1804 -OutFile Ubuntu.appx -UseBasicParsing
PS C:> Add-AppxPackage .\Ubuntu.appx
```

6.無事インストールが完了するとスタートメニューにUbuntuアイコンが追加されています
アイコンを起動するとインストールが数分動きます
その後、ユーザーネームとパスワードを入力してインストールは終了です！

```Ubuntu.
Enter new UNIX username: xxx
Enter new UNIX password:
Retype new UNIX password:  
```

7.最後にパッケージの最新化して終わりです

```Ubuntu.
  $sudo apt update
  $sudo apt upgrade
```

#おわりに
私はこのやり方でやったので問題なくできましたが
おそらくMicrosoft Storeからインストールした方が簡単にできると思います
会社の端末から自分のアカウントでStoreにログインできない場合などはアリかもしれません

ちなみにDockerは使えないみたいです
Raspbian Busterで構築したKubernetesクラスタのPod間通信ができない場合の対処

最近Kubernetesの勉強を始めたら、会社の余っていたラズパイを使わせてもらえることになったので、Kubernetesクラスタを構築してみました。
OSに2019/07時点の最新版「Ruspbian Buster」を選択したことで、Pod間通信ができないという課題が発生したため、解決策と解決までの経緯を記載します。

クラスタ構築にあたり、こちらの記事「[Raspberry PiでおうちKubernetes構築【論理編】](https://qiita.com/go_vargo/items/d1271ab60f2bba375dcc)」を参考にさせていただきました。ありがとうございました。

## バージョン
```
OS: Raspbian 10 (buster)
docker: 18.09.8
kubeadm/kubelet/kubectl: 1.15.1
```

## 課題
Pod間通信ができない

## 解決策
Debian 10 (Buster)からiptablesのバージョンが変わったようで、kubernetes用の書き換えができていませんでした。
以下のコマンドで`iptables-legacy`を選択して再起動後にPod間通信ができるようになりました。

```
$ sudo update-alternatives --config iptables
There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).

  Selection    Path                       Priority   Status
------------------------------------------------------------
* 0            /usr/sbin/iptables-nft      20        auto mode
  1            /usr/sbin/iptables-legacy   10        manual mode
  2            /usr/sbin/iptables-nft      20        manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
```

## 課題発生から解決までの経緯

kubeadmでMasterNodeとWorkerNodeを設定してFlannelを導入、動作確認のため[『Kubernetes完全ガイド』の付録マニフェストのリポジトリ](https://github.com/MasayaAoyama/kubernetes-perfect-guide)からnginx-deploymentとnginx-nodeportをapplyしてみたのですが、うまくサービスに繋がらず。

`kubectl get pods -n kube-system`でstatic Podを確認すると、corednsのPod(replicas: 2)がすべてErrorとなっており
`kubectl describe`にてイベントを確認すると、社内DNSサーバに繋がらないことによるReadinessProbeヘルスチェックに引っかかっていました。
nginxイメージにpingコマンドがなかったため、busyboxイメージのPodを作成して確認をしたところ、自Node他Pod/他Node他Podへpingが通りませんでした。

iptablesを確認したところ、filterテーブルのKUBE-FIREWALLチェインに大量のDROP、natテーブルのKUBE-POSTROUTINGチェインに大量のMASQUERADEが追加されていました。
うまく構築できていたGCPのK8sクラスタのiptablesと比較すると、filterテーブルとnatテーブルにkubernetes関連のルールが書き換えられていないことがわかりました。

GCP上のクラスタから手動でnatテーブルの設定を移植したところ、Podから他Podへのping成功！ということはnatテーブルをうまく書き換えられていないkubeletが犯人では！？と色々調査をしたのですが結局違いました。

その後、OSをUbuntuと１つ前のRaspbian stretchに入れ替えたところ、ともにPod間通信できたのでRaspbian busterがよろしくないと判断し、stretchとbusterの変更を調べていくとiptablesのバージョンが上がったことに気づき、解決策に辿り着きました。
~~初めから試しておけばよかった…~~

そもそも、iptables確認したときに`iptables-legacy`のことについてメッセージが出ていたので、ちゃんと読んでいればもっと早く解決できたはず…

```
$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
︙
# Warning: iptables-legacy tables present, use iptables-legacy to see them
```

## 教訓

メッセージはちゃんと読め

## 課題を解決する中で得た知識

kubernetesでは複数のコンポーネントがiptablesを書き換えている

**[filter]**
KUBE-FIREWALL　←　kubelet
KUBE-SERVICES　←　kube-proxy
KUBE-FORWARD 　←　flannel

**[nat]**
KUBE-POSTROUTING　←　kubelet
Houdini17.5ではFuseのUniqueがないのでFacetのUniqueを使おう

#はじめに
HoudiniのFuseオペレーターのUniqueは[この本](https://www.borndigital.co.jp/book/6342.html)やその他のチュートリアルにも登場していたのですが17.5では使えない。検索しても日本語の情報は出てこないという状況だったのでメモとして記録。

#FuseのUniqueって？
FuseオペレーターのUniqueを使うと各頂点を固有のポイントにして分離することができました

例えばグリッドを作って
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/0538001c-689f-d120-020b-a0ffd3bffd8e.png)

FuseのUniqueでばらして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/9767cee9-6d3b-4031-7789-03cfd8daf774.png)

それぞれを移動させたりできます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/6b6314fa-2e9f-0831-e872-14d684bfbf66.png)

ですが、17.5ではFuseのUniqueが見当たりません
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/2eb43a9c-b93e-0c4e-7cb3-78677d989173.png)

ポイントがばらせてないので移動するとこうなっちゃう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/c20ab4ec-1d2e-3f61-3e97-f28ceb3b0980.png)



#ヘルプを見てみる
ヘルプを見るとFuseオペレーターの説明が二つありました

[従来のFuse geometry node の説明文](http://www.sidefx.com/ja/docs/houdini/nodes/sop/fuse-.html
)
「ポイントを結合/分離(個別化)します。」

[新しいFuse <sup>2.0</sup> geometry node の説明文](http://www.sidefx.com/ja/docs/houdini/nodes/sop/fuse-.html)
「ポイントを結合します。」

分離(個別化)が無くなっている・・・

#フォーラム(英語)の情報
検索してみたら公式フォーラムの情報がヒットした
[How to recreate the Fuse SOP unique function? | Forums | SideFX](https://www.sidefx.com/forum/topic/65681/?page=1#post-281230)
「どうすればポイントをユニークにできるの？」
「Facet SOP/Unique Points」

これかー！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/8f104ea9-a6fa-0e0c-5c3c-8ac463d3db48.png)

できたー！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/cd3fa553-4337-dc9f-eb18-f79e590c68d9.png)
pythonのお勉強１１日目

##WindowsPC VisualStudioからpythonを使う。
Python超初心者の備忘録です。
今回はmatplotlibの３DgraphのTitleを日本語表記にすることに挑戦をします。

###流れ　日本語表記の記事を集める、自力でpythonでプログラムを書いてTitleを日本語化できることを確認、３D または Boxelでグラフ出力に挑戦。

Googleで検索（Matplotlib 日本語）すると　多数の先人の方々の記事がhitしました。
直接パッチを当てたり、オプションに登録する方法など、いろいろと手段がある事が分かり
ました。その中で直接Fontを指定するものが私にはわかりやすいのでそれを採用しています。

` fp =FontProperties(fname = 'C:¥Windows¥Fonts¥msgothic.ttc',size =14)`
(Windowsの設定Pathです。` title("title",FrontProperties = fp)` タイトル部分
にも挿入が必要です。
次に３DGraphに挑戦しました。結局自力ではうまく表現できなかったので、Google検索で
Hitした記事の中から選ぶことにしました。

###プログラムの流れ、　
numpyなどimport、
Fontを指定する（Font名はFontファイルを右クリックしてプロパティで確認できます）
関数を２つ選び　defで定義する
座様（x。y）上で　f(x) x g(y) で高さを表現するグラフ。
f(x)はネット上の先人の関数を有志がpython表記に変えたのもをそのまま利用
g(y)は　WolframAlpha（無料）で作成しました。（iOS またオンラインでも利用可）

グラフの表現方法はmatplotlibのマニュアルに従って
x、y座標を編み目に分割
z ＝　f(x) x g(y)でその座様の高さを決める。
グラフのオプションで体裁を整え完成。
結局　Bestecodeの記事を採用し体裁を整えました。
###完成図です。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435503/a775ca2a-458c-bd69-5c5d-83eda7a36e8f.png)


生のanaconda環境で作成。
蟻本の三角形をrubyで解いてみる(記録用)

# 問題
n本の棒があり、棒iの長さはai。それらの棒から3本を選んでできるだけ周長の長い三角形を作ろうと考えている。最大の周囲はいくら？ただし、三角形が作れない場合は、0と答える。

# 入力例
5
2 3 4 5 10

# 出力例
12(3,4,5と選んだとき)

# 解答
```rb
a=gets.to_i
b=gets.chomp.split.map(&:to_i)
ans=0
b.permutation(3){|x|
  max=x.max
  total=x.inject(:+)
  rest=total-max
  if max<rest
    if total > ans
      ans = total
    end  
  end  
}
puts ans
```
Laravelでfindしたレコードから特定のカラムを抽出したい

例えばid==1のデータが欲しくて,かつその中でも特定のカラムのデータのみを抽出したかったが、方法がなかなか見つからなくて困ったのでメモしておく.

例えばProductというモデルがあり,そのテーブルには['id','title','description','price','created_at','updated_at']というカラムが存在しているとする.
ここで['title','description','price']のデータのみが欲しい際は以下のようにする.

```php

\App\Product::find(1,['title','description','price']);
```

上記で特定の3カラムのデータのみを取り出せる.

例えばroutes/api.phpにおいて,上記の特定カラムのデータのみをJSONとしてresponseに出力するサンプルコードは以下の通り.

```php

Route::get('products/{product_id}', function ($product_id) {
    $product = \App\Product::find(1,['title','description','price']);
    return response()->json($product);
});
```

### 7/26追記

コメント欄にて以下のような方法もあることを教えていただきました！
[@yamatox](https://qiita.com/yamatox)さん、ありがとうございます！

```php

Route::get('/test1', function () {
    $product = \App\Product::select(['title','description','price'])->where('id', 1)->first();
    return response()->json($product);
});
```


```php

{"title":"TEST","description":"DESCRIPTION","price":"1000"}
```


複数件取得(返り値はLaravelのCollectionクラス)

```php
Route::get('/test2', function () {
    $products = \App\Product::select(['title','description','price'])->whereIn('id', [1,2])->get();
    return response()->json($products);
});
```

```php
[
  {"title":"TEST","description":"DESCRIPTION","price":"1000"}, 
  {"title":"TEST2","description":"DESCRIPTION2","price":"2000"}
]
```


# まとめ
なかなか真に迫る回答が見つけられなくて困った...
ちなみにfind()で帰ってくるのはEloquentインスタンスです.query()とかだとcollectionsインスタンスが返ってくるらしい.
クエリビルダあたりも勉強していきたいですね.
MQTT(RabbitMQ) + NiFi

Download page:
https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.14/

erlang
https://www.rabbitmq.com/releases/erlang/


# Install :
https://www.rabbitmq.com/install-rpm.html#install-erlang

```
sudo yum install erlang
sudo yum install socat
wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.14/rabbitmq-server-3.6.14-1.el7.noarch.rpm
sudo rpm -ivh rabbitmq-server-3.6.14-1.el7.noarch.rpm
```

# Run RabbitMQ Server
## Start the Server

```
sudo chkconfig rabbitmq-server on
sudo /sbin/service rabbitmq-server start
sudo /sbin/service rabbitmq-server stop
```

# Check the port opened:

```
sudo netstat -a -t --numeric-ports -p
sudo rabbitmqctl status
```

# Add RabbitMQ Management Plugin
https://www.rabbitmq.com/management.html

```
sudo rabbitmq-plugins enable rabbitmq_management
```

http://zzeng-hdp-ambari.field.hortonworks.com:15672/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/341ee17c-24d1-95c5-74d0-c8cfb77bbfb6.png)

`sudo rabbitmqctl add_user admin_user admin_password`

```
sudo rabbitmqctl add_user admin_user admin_password
sudo rabbitmqctl set_user_tags admin_user administrator

# add permission to /
https://www.rabbitmq.com/rabbitmqctl.8.html#Access_Control

[centos@zzeng-hdp-ambari ~]$ sudo rabbitmqctl list_vhosts
Listing vhosts
/
qa1
[centos@zzeng-hdp-ambari ~]$
```

# Start / Stop RabbitMQ service
https://www.rabbitmq.com/install-rpm.html#install-erlang

```
# stop the local node
sudo service rabbitmq-server stop

# start it back
sudo service rabbitmq-server start
sudo service rabbitmq-server status
```


# Prepare MQTT Client env

```
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
sudo python get-pip.py

sudo pip install pika
```