OmniAICreator/Qiita-1.07M huggingface dataset:
docker-composeでpython環境

# はじめに
pythonのバージョン指定ができるコンテナが欲しいと思った次第。(主にicrawlerのせい)
コンテナで作ると簡単に捨てられるし、ポートの管理も楽だということで、docker-composeを使ってやってみることにした。

# 下準備
ファイルやフォルダを作る。

```
$ mkdir python
$ cd python
$ touch Dockerfile
$ touch docker-compose.yml
$ touch requirements.txt // 入れたいパッケージは書いておく
$ mkdir workspace
```

もし、コンテナ内からvolumeしたときに権限がrootにならにようにする方法があったりしたら教えていただきたいです。

```:Dockerfile
FROM python:3.6

WORKDIR /usr/src/app

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

ARG DOCKER_UID=1000
ARG DOCKER_USER=docker-user
RUN useradd -m --uid ${DOCKER_UID} --groups sudo ${DOCKER_USER}

USER ${DOCKER_USER}

WORKDIR /home/docker-user
```

```docker-compose.yml
version: "3"
services:
  python36:
    build: .
    container_name: python36
    ports:
      - "5000:5000"
    tty: true
    volumes:
      - ./workspace:/home/docker-user
```

以上で準備は完了。

# コンテナを立てる
コンテナを建てていく。そしたら入るだけ。

```
$ docker-compose build
$ docker-compose up -d

# 入り方
$ docker-compose exec python36 bash

# rootで入る場合
$ docker-compose exec --user=root python36 bash
```

こだわりとしては、rootで操作しないところ。ただ書き方として良いのかはわからないからなんとも言えないので注意。

## 参考
[Docker hub](https://hub.docker.com/_/python)
[Python, pipでrequirements.txtを使ってパッケージ一括インストール](https://note.nkmk.me/python-pip-install-requirements/)
【Golang】配列や項目がネストされているJsonをmapで取り出す

## 概要
Golangで文字列のJsonから、値取り出す場合、[golang で JSON を扱うサンプル](https://hawksnowlog.blogspot.com/2019/04/deal-with-json-on-golang.html)の通り、structかmapで取り出す方法が挙げられます。特に、外部のAPIからデータを取得するときは不要な項目が多いので、structを定義するのが面倒ということもあり、mapで必要な項目のみ抜き出したいというふうになると思います。
mapで取り出すとき、配列やネストされている項目をどう取り出すのか、メモ書きします。

## 参考
[golang は ゆるふわに JSON を扱えまぁす!](https://www.kaoriya.net/blog/2016/06/25/)の記事を参考に、サンプルコードを書きました。また、この記事を書いた方はmapでの取り出しを楽にするライブラリ[go-dproxy](https://github.com/koron/go-dproxy)も公開されています。

## 読み込むコードJson
```sample.json

{
  "result": [
    {
      "id": "test1",
      "name": "name1",
      "url": {
        "blog": "http://www.example1.com/"
      }
    },
    {
      "id": "test2",
      "name": "name2",
      "url": {
        "blog": "http://www.example2.com/"
      }
    }
  ]
```

## サンプルコード

```jsonReadSample.go

// JSONReadSample Jsonの文字列をmapで読み込んで項目を出力
func JSONReadSample(jsonStr string) {
	var jsonMap map[string]interface{}
	// map形式でJsonをUnmarshal
	json.Unmarshal([]byte(jsonStr), &jsonMap)
	// 配列項目の読み込み
	resultList := jsonMap["result"].([]interface{})
	for _, r := range resultList {
		println(r.(map[string]interface{})["id"].(string))
		println(r.(map[string]interface{})["name"].(string))
		// ネスト項目の読み込み
		println(r.(map[string]interface{})["url"].(map[string]interface{})["brog"].(string))
	}
}

```
AtCoder -Shift only- をPHPで解いてみた。

# 提出したコード
```shift.php
<?php
fscanf(STDIN, "%d", $numberCount);
$numbers = explode(' ', fgets(STDIN));
$counts = array();
for ($i = 0; $i < $numberCount; $i++) {
    $count = 0;
    while ($numbers[$i] % 2 === 0) {
        $count += 1;
        $numbers[$i] = $numbers[$i] / 2;
    }
    $counts[$i] = $count;
}
echo min($counts);
?>
```

# コードの解説
与えられた各数値を2で割り切れなくなるまで割り続け、その回数をそれぞれ記録。
記録された数値の中で一番少ない数値を返す。

なので奇数が含まれていたら必然的に0が返される。
配列の中身を全部見て全て偶数だったら処理を行う。これを繰り返す。という方法がすぐに思いついたが冗長になりそうなのでやめた。
初めての投稿

テスト　初めての投稿

# 挨拶
　初めての投稿です。
　簡単なコードから様々なソフトウェアの操作についても書きます。

　テストの意味も込めて、コードを載せて見ます

```vb:hello.vb
 Private Sub ShowMessage(sender As Object, e As EventArgs) Handles btnMessage.Click
        lblMessage.Text = "Hello World!"
End Sub
```

宜しくお願いします。
テレワークでも効率よく障害を検知するためにSMTP Appenderを導入

自社向けのシステムだし、利用者も限られてるし、メンテも自分だけだし、ちょっとKubernetes上のアプリってどうやれば良いのかよく判らないし、などなどの言い訳からログ監視方法をサボっていたら、世の中はテレワーク全盛ですよ。
ただでさえ ~~いけにえ~~ 利用者からの申告で数日前の例外に気付いてたのが、利用者も減って見過ごした大量のデータ整合性の異常を、自宅からの貧弱なインターネット環境で補正する羽目になりそうですよ。

ということで、 ~~めんどうだから~~ 心を入れ替えて自宅だろうが買い物中だろうがエラーが判るようにLogbackのSMTP Appenderを導入しました。
これでめでたく前職と同し社畜に復帰です。

## 設定
アプリはSpring Bootで開発しているので、Spring Bootの設定を継承する形です。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <include resource="org/springframework/boot/logging/logback/base.xml" />

  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>ERROR</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
    <smtpHost>smtp.office365.com</smtpHost>
    <smtpPort>587</smtpPort>
    <to>【宛先アドレス】</to>
    <from>【送信元アドレス】</from>

    <username>【アカウント】</username>
    <password>【パスワード】</password>

    <subject>ERROR: %logger{20} - %m</subject>
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%date %-5level %logger{35} - %message%n</pattern>
    </layout>
    <STARTTLS>true</STARTTLS>
  </appender>

  <root level="INFO">
    <appender-ref ref="EMAIL" />
  </root>
</configuration>
```
ERRORレベルのログが出力された場合にのみメールを飛ばします。
これをjarにパッケージ化すると宛先の変更とかが面倒なので、-Dlogging.configで外出しにしました。

```dockerfile
FROM openjdk:11
ADD app-1.0.0.jar /opt/app.jar
ADD application-production.yml /opt
ADD logback.xml /opt
WORKDIR /opt
CMD ["java", "-jar", "-Dspring.profiles.active=production", "-Dlogging.config=./logback.xml", "app.jar"]
```

## トラブル
設定しただけで動かすとjarが足りないようです。

```
Caused by: java.lang.ClassNotFoundException: javax.mail.internet.AddressException
	at 	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
	at 	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at 	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
	at 	... 71 common frames omitted
```

そこで手っ取り早く、依存関係にspring-boot-starter-mailを追加してあげると、エラーメールが届くようになりました。
【Rails】初めてのパンくずリスト実装(gem gretel)

パンくずリストを実装しました。gem gretelを使えば、設定ファイルとビューからの呼び出しのみで作成できます。
参) [gretelのリファレンス](https://github.com/kzkn/gretel/blob/master/README.md)

![Alt text](https://gyazo.com/480d8668724a24c2cc9ea990ac9e171f/raw)

# 手順
① gemの導入 → `bundle install`

```ruby:Gemfile
gem 'gretel'
```
② 設定ファイルの作成

```
$ rails g gretel:install
```

③ 作成された`config/breadcrumb.rb`にパンくずを定義
デフォルトのコメントは削除ok。

```ruby:基本の構造
crumb :ビューで呼び出すためのパンくず名 do
  link "リンクの文字", リンク先のパス
  parent :１コ前のページのパス(ない場合は不要）
end
```

**実際のコード**

```ruby:breadcrumb.rb
#ルート
crumb :root do
  link "フリマ", root_path
end

#マイページ
crumb :mypage do
  link "マイページ", mypage_index_path
end

# クレジットカード情報
crumb :mypage_cards_index do
  link '支払い方法', mypage_cards_index_path
  parent :mypage
end

# クレジットカード情報登録後の表示
crumb :mypage_cards_show do
  link 'クレジットカード情報', mypage_cards_show_path
  parent :mypage_cards_index
end
```

```ruby:参考)itemsテーブルのnameカラムをリンク名にする場合
crumb :item do
  link Item.find(params[:id]).name, item_path
  parent :root
end

crumb :item do
  link @item.name, item_path
  parent :root
end
```

④ ビューで所望のパンくずを呼び出す

```haml:haml
.breadcrumbs
  - breadcrumb :パンくず名                    # 呼び出したいパンくずを指定。
  = breadcrumbs separator: " &rsaquo; "    # エスケープ文字で › を意味してる。
```








# （備忘録）本番環境へのデプロイでエラーに陥った話
- ローカル環境では、上記の記述で問題ないことを確認の上、デプロイすると、**undefined method `breadcrumb'**。
  - 本番環境にインストール済みのgem表示($ bundle list)してみると、gretelが入ってなかったので、再度、bundle install。
  - 本番環境を一旦、kill → 再起動すると、エラーは消えた。単純に、反映できてなかっただけ。。
文系大学生がJavaScriptを旅する〜JavaScriptとは〜

##前置き
これはプログラミングに出会って一年の文系大学生がJavaScriptを旅する備忘録である。

##JavaScriptをなんとなく使ってきていた##
私がプログラミングを学習し始めてかれこれ１年になる。やはり、プログラミングを始めるとまず最初に思うのが**「モダンな技術を身に着けてプログラマーとして就職したい」**というちょっと邪な考えである。

###Vue.jsとの出会い###

この邪な考えを基に、**「プログラミング　言語　モダン」**とGoogle師匠に質問をしていた私はReactやVueといったJavaScriptのフレームワークやライブラリに出会った。そして、深い理由もないままVueをチョイスし、２ヶ月ほど学習を進めていった。

**〜二ヶ月後〜**

###自分は間違っていたとVueに気付かされる

２ヶ月経って、ある程度動くモノができた時に私は思った。**「で、これはどういう仕組で動いているんだろう」**と。
JavaScriptを勉強しないでVueの学習を始めた私はVueの持つ素晴らしい機能の有り難みをたいして感じることもなく、分からない箇所はコピペをしてなんとなく実装したので、実装後に感じたのは虚しさだけであった。

###そうだ、JavaScriptを始めよう

前置きが長くなってしまったが、ここまできてようやく私は、ピュアのJavaScriptを勉強する必要性に気づいたのである。**JavaScriptを勉強することで世間一般で言われている強力なフレームワークの有り難さがわかるようになり、機能を十二分に発揮できるようになる**と。

**そして私はJavaScriptの旅に出ることにした。**

##JavaScriptって何者なんだ

さて、修行の旅に出るとは言ったものの、そもそもJavaScriptとは一体何者なのだろうか。ここを疎かにしてしまうと**「木を見て森を見ず」**状態になってしまい過去の自分に逆戻りになってしまうような気がしてならなかった。

###JavaScriptの概要

JavaScriptというものはウェブブラウザー上で動作するプログラミング言語であるらしい。
ウェブブラウザーで動くということはPHPやRubyなどといったサーバーで動くプログラミング言語とは様相が異なるようだ。
はて、サーバー側で動くJavaScriptがあったような…うっ…頭が！こういう余分なことばかりに考えが及び本質からそれてしまうから屁理屈だけは達者になっていってしまうのだ。
さて、気を取り直してJavaScriptで可能な機能の一例を挙げると

- **数値や文字、配列などのデータを扱う（情報のやりとり）**
- **日付や時間を扱う（カウントダウンとかできる）**
- **ブラウザーを操作する（アラートとか出せる）**
- **ユーザーの行動に伴い処理を行う（自動プレビューとかとか）**
- **ページの要素の取得（いわゆるDOM操作と呼ばれてるやつで中々重要）**
- **データ通信（データベースからデータ引っ張ってこれたりする）**
- **ローカルデータの取扱（Cookieとかとか）**
- **アニメーションする（理由とか無しに極めてみたい）**

がざっと挙げられるのではないだろうか。それぞれの詳しい内容についてはこれからの記事で取り上げていきたいと考えているので今回のところは、あくまでも例示という感じで勘弁していただけたら幸いである。

###ECMAScriptとはなんぞ？

**「JavaScriptはECMAScript（イクマスクリプト）の仕様に基づいている」**という言葉は耳にタコができるほど聞いてきたがECMAScriptが何なのかはあまり耳にしたことがない。全く、初心者に無責任に新しい言葉を投げかけないでいただきたい。私はECMAScriptが分からないという罪悪感で朝も起きれない時期があったのだ。

私と同じ思いを持つ初学者の方のためにECMAScriptととの向かい合い方を紹介させていただきたい。

**ECMAなんちゃらという団体がJavaScriptの仕様について議論を行っているのである。そのためJavaScriptの仕様の事をECMAScriptというのだ。**

と、まあこんな感じに思っていただけたらあながち間違いではないと私は信じている。とりわけ２０１５年に大きなアップデートがあったらしく、この年にクラス構文やアロー関数などの今でも超一線級に使用されている機能が追加されたという。以後、毎年のようにアップデートが重ねられているらしく、ECMAなんちゃらという団体様には頭が上がらない。

##今回のまとめ

**文系大学生がJavaScriptを旅する**シリーズをはじめていくにあたって、最初はどうしても私がこのシリーズを書くに至った経緯やJavaScriptについての体系的な説明をしておきたかった。そのため今回はコードを一回も書くことなく記事を終了することを許していただきたい。

また、[個人ブログ](https://okitsublog.com)を先日開設したのでこちらもチェックしていただけると感無量であります。
それでは、最後まで読んでいただきありがとうございました。

##追記

JavaScriptを旅するシリーズ[第二弾となる記事](https://qiita.com/okitsu090807/items/99e1255491140569307f)を公開したので、こちらの方も是非御一読願いたい。テーマは「let,const,var」である。
Lambda統合とHTTP統合の違いを作って理解する

## 概要

AWSデベロッパーアソシエイトを受けていると、API Gatewayの統合タイプとして以下4つの違いを問われることがよくあります。

|統合タイプ|
|---|
|Lambda統合, Lambda非プロキシ統合|
|Lambdaプロキシ統合|
|HTTP統合, HTTP非プロキシ統合|
|HTTPプロキシ統合|

このうち、Lambda統合とHTTP統合の違いは以下の通りです。Lambda統合はよく構築する機会がありますが、HTTP統合を作る機会が少ないので、今回作ってみようと思います。

- Lambda統合：バックエンドとして、Lambda関数と統合する
- HTTP統合：バックエンドとして、EC2等で自作したAPIと統合する

なお、プロキシ統合と非プロキシ統合の違いについては、以下の記事が大変わかりやすかったので、参考にしてください。

 - [API Gateway + Lambda プロキシ結合の使用有無による違い](https://qiita.com/yuuwatanabe/items/a3bd65e709f20574b6db)
 - [[初心者向け] Lambda 非プロキシ統合で API Gateway API をビルドする をプロキシ統合にして比較してみる](https://dev.classmethod.jp/articles/for-beginner-build-apigateway-with-noproxy-and-proxy-lambda/)

## HTTP統合
まずバックエンドとして、パブリックサブネットに簡易なAPIを作成します。今回はEC2で作ります。

```python:server.py
from flask import Flask
from hello import get_hello

app = Flask(__name__)

@app.route('/hello', methods=['GET'])
def local_endpoint():
    return get_hello()


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

```

```python:hello.py
import json

def get_hello():
    message = "Hello, good morning"
    return_json = json.dumps({"message": message})

    return return_json

```

上記ソースをEC2に配置して、以下コマンドを打っていけば簡易なAPIが構築できます。

```bash:
sudo yum install -y python3    # Python3のインストール
sudo pip3 install Flask        # Flaskのインストール
chmod 755 *.py                 # 実行権限の付与
python3 server.py              # APIの起動 
```

なお、上記のソースで疎通確認する際には、EC2のセキュリティグループで5000番ポートを許可しましょう。

```bash:疎通確認結果
curl http://XXX.XXX.XXX.XXX:5000/hello    # XXXはEC2のパブリックIPアドレス
{"message": "Hello, good morning"}
```

あとはこのエンドポイントのURLをAPI Gatewayのメソッド作成時に指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451175/b96f8c5a-a044-26f6-0824-a12e3289b807.png)

これをデプロイしたら、API GatewayのエンドポイントでAPIを呼び出せます。
APIのビジネスロジックをEC2側に寄せて、スロットリング制限等はAPI Gatewayの機能を利用する、といった活用ができるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451175/caa71da5-48de-09fa-802c-6b391a5869b2.png)


なお、実際はバックエンドにNLBなど挟んでロードバランスする構成が多いようです。
また、プライベートなサブネットに構築したAPIにアクセスする場合には、VPCリンクを活用します。以下の記事が大変参考になります。

[API Gateway経由でのみアクセス可能なAPIをECSで構築する](https://qiita.com/ohtsuka1317/items/d63fe2a554c468570c64)

## 終わりに
デベロッパーアソシエイトを勉強中で違いがよくわからない人は、本記事のように手を動かしてみるとその違いがわかると思います。


## 参考

[API Gateway API 統合タイプを選択する](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-api-integration-types.html)
input[type="date"]の年月日を分けてpostする

はじめまして、さブといいます。
web業界に生きる人間として、学んだことを少しでもアウトプットして行こうと思っています。

今回はタイトルの通り、input[type="date"]で日付を選択した際に、
年、月、日に分けて送信する方法をまとめます。

```html
<input type="date" name="date"> 
<input type="hidden" name="date-y">
<input type="hidden" name="date-m">
<input type="hidden" name="date-d">
```

```javascript
$(function(){
   //スマホで日付選択したときに年月日別に値を格納
   $('input[name="date"]').on('change',function(){ 
     var str = $(this).val();//選択した日付を取得
     var date = str.split('-');//配列化 

     $('input[name="date-y"]').val(date[0]);
     $('input[name="date-m"]').val(date[1]);
     $('input[name="date-d"]').val(date[2]);
   });
});
```

カレンダーの日付を取得したくて組んだのですが、
UI的に年月日別にプルダウンで選択できた方が主流で良いとの事だったのでボツに＾＾；
よく調べてから作りましょうという教訓を持ちつつ
いつか使うかもしれないと思っての備忘録的なやつです。
【備忘録】NPM / Node / Homebrewのアンインストール

Vue.jsを勉強した際の備忘録として書きます。
Vue Cli3を入れようとしましたが、エラーが表示されインストールできませんでした。
その為、一度NPM / Node / Homebrewをアンインストールすることにしました。

#目次
- NPM / Node / Homebrewのアンインストール
    - NPMのアンインストール
    - Nodeのアンインストール
    - Homebrewのアンインストール

#NPM / Node / Homebrewのアンインストール

##NPMのアンインストール
```
sudo npm uninstall npm -g
```

参照URL http://umekov.hatenablog.com/entry/2016/12/03/000001


##Nodeのアンインストール

```
curl -ksO https://gist.githubusercontent.com/nicerobot/2697848/raw/uninstall-node.sh
chmod +x ./uninstall-node.sh
./uninstall-node.sh
rm uninstall-node.sh
```
参照URL https://gist.github.com/nicerobot/2697848

上記でうまくいかなければこちら。
```
rm -rf /usr/local/bin/node
```
参照URL　https://qiita.com/wagi0716/items/94193a80502f9d81a9e0

##Homebrewのアンインストール

```
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
```

上記がうまくいかなかったので下記で対応。

```
cd `brew --prefix`
git checkout master
git ls-files -z | pbcopy
rm -rf Cellar
bin/brew prune
pbpaste | xargs -0 rm
rm -r Library/Homebrew Library/Aliases Library/Formula Library/Contributions 
test -d Library/LinkedKegs && rm -r Library/LinkedKegs
rmdir -p bin Library share/man/man1 2> /dev/null
rm -rf .git
rm -rf ~/Library/Caches/Homebrew
rm -rf ~/Library/Logs/Homebrew
rm -rf /Library/Caches/Homebrew
```

参照URL https://superuser.com/questions/203707/how-to-uninstall-homebrew
マイクロサービスパターン[実践的システムデザインのためのコード解説]をポチったモチベ

# 概要

こちらをポチった。
https://www.amazon.co.jp/dp/toc/4295008583
マイクロサービスパターン[実践的システムデザインのためのコード解説]

# モチベーション

ここ5年ほどマイクロサービスを追いかけていて、いくつか記事/書籍執筆・講演・取材対応などを行っているが、
体系的にまとめられた本書で<u>何が新しいか</u>を確認する。
https://qiita.com/kounan13/items/da791bfdb6b379287342

# 書籍の概観 

ざっくり3つ。
1. 分割論
2. 品質/保守性
3. 基盤

## 1. 分割論

分散トランザクションなどの弊害を最小化するために、どんな単位でマイクロサービスを分割するかが書かれている。

* 業務
    * Chapter2：分割について
    * Chapter5：DDDとか
* DB系
    * Chapter4：分散トランザクションとか
    * Chapter7：クエリ
*  通信系
    * Chapter3：RESTとかgRPCとか
    * Chapter6：イベントドリブンとかコレオグラフィとか
    * Chapter8：API GatewayとかGraphQLとか

## 2. 品質/保守性
テストやリファクタリングなどの保守性について語られている。

* Chapter9/10：テスト
* Chapter13：リファクタリング

## 3. 基盤
コンテナやサーバレスといったアーキテクチャ関連の記載があり内容としても、近年使われている技術を軸としており、最新トレンドに追従している。

* Chapter12：KubenetesやAWS Lambdaに関する記載があり、実践的な印象




### 参考：Amazonに掲載されている目次


>
Chapter 1 モノリシック地獄からの脱出
Chapter 2 サービスへの分割
Chapter 3 マイクロサービスアーキテクチャで使われるプロセス間通信
Chapter 4 サーガによるトランザクションの管理
Chapter 5 マイクロサービスアーキテクチャにおけるビジネスロジックの設計
Chapter 6 イベントソーシングを使ったビジネスロジックの開発
Chapter 7 マイクロサービスアーキテクチャでのクエリーの実装
Chapter 8 外部APIパターン
Chapter 9 マイクロサービスのテスト(前編)
Chapter 10 マイクロサービスのテスト(後編)
Chapter 11 本番環境に耐えられるサービスの開発
Chapter 12 マイクロサービスのデプロイ
Chapter 13 マイクロサービスのリファクタリング


# まとめ。で、何が新しいか

* 具体的・実践的な内容が増えてきた
    * 分割論一つ取ってみても、具体的な設計を想起できるほどになってきた
* おおよそのポイント以前から出ているものから変わらない
    * 2014年に投稿されたJames Lewis/Martin Fowlerの[Microservices](https://martinfowler.com/articles/microservices.html)で記載されている9つの特徴から大きく増えてはいない印象

### 参考：Microservicesに掲載されている目次

>
Componentization via Services
Organized around Business Capabilities
Products not Projects
Smart endpoints and dumb pipes
Decentralized Governance
Decentralized Data Management
Infrastructure Automation
Design for failure
Evolutionary Design
S3のPresignedURLにブラウザからファイルをアップロードする場合のデータ指定方法

# TL; DR

- バックエンド側でアップロード用の S3 の Presigned URL を発行し、このURLに対してPUTリクエストを送ることでファイルをアップロードしたい
- URLに対して `curl` で行うケースをよく見るが、これをブラウザ上で行いたい
    - 今回は jQuery を利用し、Chrome で検証
    - もちろん他にも記事はあったが、実際にやってみるとうまくアップロードできなかったり、アップロードしたファイルが正しくなかったりしたので改めて調査、検証した
- 結論としては、HTML File API の File オブジェクトを data に指定すればよい

## Presigned URLの生成

- 今回は Python + boto3 を使って、以下のようにアップロード用のPresigned URLを生成
- ここのところはお好きな言語でどうぞ

```python:Presigned-URLの生成
s3 = boto3.client('s3')
url = s3.generate_presigned_url(
    ClientMethod='put_object',
    Params={
        'Bucket': "<利用するバケット名>", 
        'Key': "<S3オブジェクトのキー(パス)>", 
        'ContentType': "<アップロードするファイルのContentType>",
    },
    ExpiresIn="<URLの有効秒数>",
    HttpMethod='PUT')
```

## ファイルアップロード用のフォーム

特に工夫もない、簡単なフォームを利用する。

```html
  <form id="upload" enctype="multipart/form-data">
    <input id="upload-filepath" type="file" name="file">
    <button type="submit">ファイルをアップロード</button>
  </form>
```

## アップロードのためのJavaScriptイベント

同じような書き方をしている記事は複数見つかったのだが、`data` の部分をどう取って送るかに関しては色々な書き方をしている記事があり、その中には正しくアップロードできないものがそれなりにあったので、その部分を探すのに大分苦労した。

検証した限りでは、**[HTML5 File API の File オブジェクト](https://developer.mozilla.org/ja/docs/Web/API/File) を渡す** ことで正しく動作する。

```javascript
$(function() {
    $("form#upload").submit(function(e) {
        e.preventDefault();
        // jQuery で File オブジェクトを取得する場合
        var data = $('#upload-filepath').prop('files')[0];
        // jQueryなしだとこれでもOK
        // var data = document.getElementById('upload-filepath').files[0];
        $.ajax({
            url: "<事前に得られたPresigned URL>",
            type: 'PUT',
            data: data,
            cache: false,
            contentType: false,
            processData: false,
        }).done(function(response) {
            alert('Upload Completed');
        });
    });
});
```

### うまくいかなかった例

- FormData を渡すと正常に書き込めるのだが余計なものが書き込まれる(参考1)
  - そのため、ファイルはアップロードされても正常なフォーマットのファイルとしては読み取れなくなる
  - アップロードした画像がブラウザで表示されなくてここでも結構悩んだ
- `<input type="file">` の jQueryオブジェクトとかDOM
  - ブラウザ上で添付していたファイルとか関係なく、DOMそのものの情報がファイルとしてアップロードされる（参考2）


```javascript
$(function() {
    $("form#upload").submit(function(e) {
        // FormData を渡す記事もあるが、これを渡すと
        // Form送信時の情報まで保存したファイルに書き込まれてしまう(参考1)
        var data = new FormData($(this));

        // getElementByIdを渡した場合、その文字列表現が書き込まれる(参考2)
        var data = getElementById('upload-filepath');
    });
});
```


```text:参考1__FormDataをdataにした場合にアップロードされたファイルの一例
------WebKitFormBoundaryBM41wGOTt4OuKw6K
Content-Disposition: form-data; name="file"; filename="upload.jpg"
Content-Type: image/jpeg

(中略: この部分に指定した画像ファイルが入っているが使える状態ではない)
------WebKitFormBoundaryBM41wGOTt4OuKw6K--
```

```text:参考2__DOMの文字列表現がそのままファイルとしてアップロードされている
[object HTMLInputElement]
```
プリン構築手順

# プリン構築手順

手順書作成の練習を兼ねて
何となく作りたかっただけです。

結局失敗してるので
そのうち、記載(材料とか、分量とか、行程とか)を修正します。

## 1.資材および機器の準備
### 1.1.資材
<li>以下の資材を用意する。

卵 4個
砂糖 140g(内訳:プリン液用70g、キャラメル用70g)
牛乳 450ml
水 大さじ2杯

<li>以下は構築環境(好み)に応じたオプション資材を使用する。

バニラエッセンス
ラム酒
ブランデー
チョコチップ

※分量は任意とする。  
※本手順書ではチョコチップを使用する。(家にこれしかなかった。)

![資材一覧](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/d86ab99d-d1c8-b742-b9c3-dd942b76d90e.jpeg)

### 1.2.機器
<li>本書では以下の機器を使用する。

鍋
コンロ
ボール
ヘラ
泡立て器
お玉
茶こし
プリン用型※
オーブン

※本手順書では食パン型を使用する。(何となく気分で)

## 2.キャラメルソースの作成
(1) 鍋に砂糖と水を展開する。    
(2) 鍋をコンロに設置する。  
(3) コンロのパラメータをOFFから中火に変更して加熱処理を開始する。  
(4) 加熱処理を開始したら鍋の展開した砂糖と水をヘラを使用して結合を行いキャラメールソースを作成する。  　　

![キャラメールソースの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/f3edae4a-b86a-d44e-547f-6de88ff2c2dd.jpeg)


(5) コンロの加熱処理によりキャラメールソースの色設定がキツネ色に設定されていることを確認する。
(6) キャラメールソースの色設定が確認できたらコンロのパラメータをOFFに戻す。
(7) キャラメールソースをプリン用型に展開する。

![キャラメールソースの展開](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/17de04a5-db4f-0855-09b2-bb17b65dae72.jpeg)


## 3.プリン液の作成
## 3.1.全ての卵の結合
(1) 全ての卵の殻をオープンして内部ファイルをボールに展開する。

![卵の結合](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/ddec8adf-ee4a-a3b5-9459-ae7f21df3b86.jpeg)

(2) ボールに展開した卵の内部ファイルを泡立て器を使用して結合を行う。

### 3.2.牛乳と砂糖の結合
(1) 鍋に牛乳と砂糖を展開する。    
(2) 鍋をコンロに設置する。  
(3) コンロのパラメータをOFFから弱火に変更して加熱処理を開始する。  
(4) 加熱処理を開始したら鍋の展開した牛乳と砂糖をヘラを使用して結合を行う。  

![牛乳と砂糖の結合](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/f6e1f739-d6da-21f2-c9dc-0031dced6c7c.jpeg)


(5) 牛乳と砂糖が結合したらコンロの加熱処理により温度値が人肌の温度値と近似値になっていることを確認する。  
(6) 温度値の確認できたらコンロのパラメータをOFFに戻す。  

### 3.3.プリン液の作成
(1) 前節3.2で作成した卵に結合ファイルがあるボールに前節3.3で作成した牛乳と砂糖の結合ファイルを展開する。
    ボールへの展開は直接ではなくお玉を使用して複数回に分け行う。
    また、1回のお玉による結合の度に泡立て器を使用して結合処理を行う。

![プリン液の作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/52b7b7bc-eb1e-276c-17df-3f43e92fbedc.jpeg)

### 3.4.プリン液の最適化
(1) 前節3.3で作成したプリン液を茶こしにパイプで渡して最適化を行う。
    1回では完全な最適化は出来ないため複数回実施する。

![プリン液の最適化](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/6506d60c-be72-4e19-a4fe-2b5909a168c0.jpeg)

## 4.必要に応じたオプション資材の展開
(1) プリン液に任意で「1.1.資材」記載のオプション資材を展開する。

![オプション資材の展開](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/d7c71e58-5447-7b75-3134-a7b4fd433037.jpeg)

***※本章のオペレーションは省略可能***

## 5.プリン型へプリン液を展開
(1) プリン液をプリン型に展開する。

## 6.プリンの生成
(1) オーブンのパラメータを以下に設定する。

| 項目 | 値 |
| --- | --- |
| 予熱 | Enable |
| 温度 | 160度 |

(2) オーブンの予熱処理を開始する。
(3) 予熱処理が完了したらオーブンにプリン型を設置する。  

![オーブンにプリン型を設置](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509257/8321f260-511c-466d-8b61-3f9ba0e1e30e.jpeg)

(4) オーブンのタイマー値を1800sに設定して加熱処理を開始する。

## 7.生成されたプリンの冷却
(1) 加熱処理を終えたらオーブンに設置したプリン型を取り出す。  
(2) プリン型を1時間から2時間放置して放熱処理を行う。  
(3) プリン型をラップでパッケージして冷蔵庫に格納して冷却処理を行う。
    冷却時間は任意とする。

——-
# ちなみに写真ではお見せ出来ないレベルで出来は失敗でした。
RSpecで独自metadataを利用する

RSpec の独自 metadata が便利だったので、利用方法と思い付く使用ケースをまとめます。

## 環境

```bash
$ bundle exec rails -v
Rails 6.0.2.2

$ bundle exec rspec -v
RSpec 3.9
  - rspec-core 3.9.1
  - rspec-expectations 3.9.0
  - rspec-mocks 3.9.1
  - rspec-rails 3.9.0
  - rspec-support 3.9.2
```

## metadata の宣言
it (example) ブロックに `:hoge` という metadata を宣言する場合は下記の様になります。

```rb
RSpec.describe 'Example' do
  it 'test1', :hoge do
  end
end
```

するとブロック内で宣言した metadata が利用できるようになります。

```rb
it 'Test 1', :hoge do |example|
  p example.metadata[:hoge] # true
end
```

値を指定することもできます。 ※ Symbol のままだと初期値は true

```rb
it 'Test 1', hoge: 'fuga' do |example|
  p example.metadata[:hoge] # fuga
end
```

## 使用ケース
### 独自 metadata を before や let ブロックで利用する

before や let の処理を skip する方法

```rb
# 特定条件下で skip したい前提処理 (before)
before do |example|
  next if example.metadata[:skip_before]

  # skip_before の値が正だと skip される処理
  @post = FactoryBot.create :post
end

# 特定条件下で skip したい前提処理 (let!)
let(:user) do |example|
  return if example.metadata[:skip_create_user]

  # skip_create_user の値が正だと skip される処理
  FactoryBot.create :user
end

it 'Test 1', :skip_before do
  expect(@post).to be_nil # before は skip されたので nil
  expect(user).to be_present
end

it 'Test 2', :skip_create_user do
  expect(@post).to be_present
  expect(user).to be_nil # let は skip されたので nil
end
```

作成するリソースを宣言する方法

```rb
# metadata を使って作成するレコード数を指定
let(:user_count) { |example| example.metadata[:user_count] || 1 }
let(:users) { FactoryBot.create_list :user, user_count }

it 'Test 1' do
  expect(users.count).to eq 1
end

it 'Test 2', user_count: 3 do |example|
  expect(users.count).to eq 3
  expect(users.count).to eq example.metadata[:user_count]
end
```

```rb
# metadata を使って作成するリソースのデータを指定する
let(:user_name) { |example| example.metadata[:user_name] || 'alice' }
let(:user) { FactoryBot.create :user, name: user_name }

it 'Test 1' do
  expect(user.name).to eq 'alice'
end

it 'Test 2', user_name: 'bob' do |example|
  expect(user.name).to eq 'bob'
  expect(user.name).to eq example.metadata[:user_name]
end
```

### 独自 metadata を指定して RSpec を実行する

```rb
RSpec.describe 'Example' do
  context 'xxxとして', :hoge do
    it 'Test 1' do
    end

    it 'Test 2' do
    end
  end

  context 'yyyとして' do
    it 'Test 3' do
    end
  end

  context 'zzzとして' do
    it 'Test 4', :hoge do
    end
  end
end
```

独自 metadata を指定して実行できる。 ※ context や describe で指定すると一括で指定可能

```bash
$ bundle exec rspec -t hoge
Run options: include {:hoge=>true}

Example
  hogeとして
    Test 1
    Test 2
  piyoとして
    Test 4
```

### 事前の設定などに metadata を使用する

サンプル用のユーザを先に作成したい場合

```rb
require 'rails_helper'

RSpec.describe 'Example' do
  it 'Test 1', :sample_users do # 独自 metadata を宣言
    expect(User.count).to eq 10
  end

  it 'Test 2' do
    expect(User.count).to eq 0
  end
end
```

```rb:spec/rails_helper.rb
RSpec.configure do |config|
  # ...

  config.before(:each, sample_users: true) do
    # sample_users metadata が true のブロックでは事前にユーザを作成する
    FactoryBot.create_list :user, 10
  end
end
```

## 参考
https://relishapp.com/rspec/rspec-core/docs/metadata/user-defined-metadata

以上です。
【随時更新】Laravel使いの僕のAtom設定を恥ずかしながら公開する

#はじめに
僕は環境構築とか仕事効率化とかは基本的にあまり関心がなく、どっちかというと「気合い入れて頑張ればいいんでしょ？？」と思ってしまうタイプです。（本当によくない）

そんな僕なのでデフォルトの状態でAtomを使ってたのですが「さすがにヤバイ」と思ったのでパッケージ等の設定をしました。この記事はその備忘録となります。

「このパッケージ入れたら便利だよ！」みたいなのがあればコメントしてくれると嬉しいです。よろしくお願いします。

#パッケージ
現在導入しているパッケージは以下になります。

###Laravel
Laravelのスペニット。スペニットの意味はよく分かりませんがとりあえず入れてます。

###highlight-selected
同じ名前の変数をハイライトしてくれる。それなりに便利な気がする。

###linter / linter-php
phpの構文をチェックしてくれるパッケージ。それなりに便利。

###atom-autocomplete-php
PHPの自動補完を強化してくれるパッケージ。多分便利。

###color-picker
エディタ上でカラーピッカー（GUIでカラーコードを選択できるやつ）を使えるようになるパッケージ。入れたはいいがよく使うカラーコードはだいたい覚えているので今の所対して役に立っていない気がする。

###pigments
エディタ上のカラーコードが一目でどんな色かわかる。スーパー便利。みんなすぐ入れた方がいい。
![スクリーンショット 2020-04-19 22.52.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521879/a7fb3f02-9b11-86fa-e73c-15652d59804c.png)

###file-icon
各ファイルのアイコンがファイルの拡張子によって変わる。上部に表示される無数のタブが少しだけわかりやすくなるから便利。
![スクリーンショット 2020-04-19 22.57.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521879/5ec54015-3770-6c95-37c8-08ebcb0bb1e3.png)

#（番外編）ショートカットキー
真面目にAtomを使いこなそうと思って色々調べた結果とても使いやすいショートカットキーをいくつか見つけたので紹介します。

###Command + a → Command + Shift + P → auto
インデントをいい感じにしてくれる（自動整形っていうのかな？）。atom-beautyを使ってもいいんですけどPCがMacBookAirということもありあまり無駄なパッケージを入れたくないのでいつもこのコマンド使ってます。

###Command + P
ファイル名検索ができる。これはマジで便利。

#以上おわり
奇跡的に誰かの役に立てば嬉しいです。
Laravelでmysqlの「SQLSTATE[HY000] [1045] Access denied for user」が出るとき

#root以外のユーザーを作ってデータベースを操作しようと思ったら「SQLSTATE[HY000] [1045] Access denied for user」

原因はmysqlにログイン出来なかったとか、そんな感じ。

疑う箇所を以下に列挙する。

##対象のデータベースとアカウント名とパスワードは間違ってないか？
まぁ基本。
タイポをやりがちなので、コピペしましょう。

##アカウントに権限は与えられているか？
権限が無いとアカウントはデータベースの操作をすることが出来ない。
やりたいことと与えている権限がすれ違っていたり
操作できるデータベースが違ったりしないか確認する。

##アカウントのHostはあっているか？
Laravelの.envのDB設定の初期値は「127.0.0.1」である。
アカウントのHostがコレと違うと、エラーが出る。
アカウントのHostを127.0.0.1に変えるか、%に変えるか
DBの設定をアカウントに合わせるかしないといけない。

##今回の僕の現象
以上の事を確認しても、正常だし、権限も与えているのになぜかエラーを吐く…
という人は
.envのDB設定の「DB_PASSWORD」の値を""で囲ってみると良いかもしれない。
僕はコレで治った…。こんなことでハマるとは…くっ！
PythonでABC163のA~Cを解く

### はじめに
今回はunratedでした

### A問題
[問題](https://atcoder.jp/contests/abc163/tasks/abc163_a)

**考えたこと**
計算するだけ。円周率はmath.piで実装できます

```python
import math
r = int(input())
print(2*r*math.pi)
```

### B問題
[問題](https://atcoder.jp/contests/abc163/tasks/abc163_b)

**考えたこと**
課題の量をtaskとして、nとtaskを比較するだけです

```python
n, m = map(int,input().split())
a = list(map(int,input().split()))

task = sum(a)
if task <= n:
    print(n-task)
else:
    print(-1)
```

### C問題
[問題](https://atcoder.jp/contests/abc163/tasks/abc163_c)

**考えたこと**
全ての$i$に対しての部下の数を計算します。

```python
n = int(input())
a = list(map(int,input().split()))

mem = [0] * (n)
for i in range(n-1):
    mem[a[i]-1] += 1

for i in mem:
    print(i)
```

### まとめ
unratedになったのつらい。はやく茶色になりたい。ではまた、おやすみなさい。
暇なのでフロントエンドエンジニアがPython（v3.7.5）をはじめてさわってみた

# あいさつ

こんにちは。
ほぼほぼフロントエンドエンジニアをやっている、Steve.Tと申します。
普段はVue.jsとReactとAngularあたりばっかやってます。
完全フルリモート状態になって暇なので　なにか勉強しようと思って、Pythonを書いてみました。
バックエンドの知識はPHPで止まってるし、RubyもPythonも書けないのちょっとな…ってなってたし、情報処理試験にPythonが標準搭載されると聞いてこれはやっておかなくちゃだしでようやく手を出しました。

ちなみにQiitaに書くのも初投稿だったりします。

## 軽く自己紹介
エンジニア歴：8年ほど
最初は4年くらいPHPとかVB.netとかVBAとか書いてた。
4年前にJavaScriptがりがり書くようになって、jQueryおもろいなーと思ってた。
3年前にAngularJSの案件とかやって、すげえこれ！ってなってたらいつのまにかモダン（？）フロントエンドエンジニアになってました。
2年くらい前からフリーランスやってます。

WebAPIというものが普及しはじめてからは主にフロントばっかりやってたので、バックエンドでAPI書くのもPHPの案件ばかりだったし、PHPもららべるとかしんふぉにーだし、まともにLambdaとかでAPI書いたことない勢です。
そんなぼくがPythonをやってみた感想。

# びっくりした点

めちゃくちゃコーディングが楽！
かんたん！
あまり余計なこと覚えなくていいし、基本的なことは考えなくても出来るレベルでシンプルだし、これがモダンな言語か…とびびりました。
インデントがブロックになってるのも最初は慣れなかったけど、一瞬で「いいじゃんこれ」ってなりました。
JavaScript書いててセミコロンがないとかカッコが足りないとかそういう微細なことでイライラする気持ちがPythonには全然なくてらくちんだなと思いました。

以下びびった点。

## forがシンプル

forEachどう書くのかな？って思ってぐぐってもforしか出てこず、これめんどうなやつじゃ…と思ってたらforにすべてが内包されてた。
あまりにもシンプルでびびった。

## 関数型の雰囲気がPHPと似てる

普段jsしか書いてないし、メソッドとかオブジェクトばっかりなので久々に()で括った。
PHPに似てて、そのあたり経験者にはPython入りやすいのかもなーって思いました。
len()がcount()すぎてびびった。

ちなみに変数も型付けいらないし、そういう点でもPHP感ありました。
さっと書くのは楽だけど、これ大規模開発では規約定めないとすげえヤバイやつ感ある。

## インストール・実行が楽

**PHP…Windows…XAMPP…Apache…という地獄** が一切なかったです。
一瞬でインストール出来るし、なんならエディタもついてるし、F5一発で実行できて結果コンソールで見れるし、とっつきやすすぎ。
pipでなんでも入れれるのも楽。

### やってみたこと

スクレイピングをちょこっとと、LambdaでDynamoDBに書き込んだり読み込んだりしてみてAPIにしてみましたけど、ものすごいスピード感で進められました。

## まとめ

**Pythonはいいぞ。になった。**
書きやすさととっつきやすさと開発のスピード感の速さはめちゃくちゃ気に入りました。
今後Lambdaのメイン言語はPythonにしようかな…って思ってます。

スクレイピングでめちゃくちゃびびってsleep長めにとって回してたら100時間くらいかかりそうで余計暇になったので初投稿というオチ。
Vue.jsの知見とか書きたいこといっぱいあるので、また投稿します。

Pythonやろうぜ！
AtCoder用にローカルでコードテスト環境を作る(Python,jupyter)



AtCoderが重い時、サイト内のコードテストがなかなか終わらないので
ローカル環境でも実行できるように作成した。


## 方法
- 組み込み関数のinputを自作のinputに置き換えている。
- 複数行に対応するため、ipywidgetというモジュールを用いている。

## コード

```python

# セル1(関数定義)
from ipywidgets import Textarea

def input():
    global input_count
    input_text = Input.split('\n')[input_count]
    input_count += 1
    
    return input_text
    
def get_input(change):
    global Input
    Input=change["new"]

textarea = Textarea()
textarea.observe(get_input, names='value')

# セル2(入力テキストボックス出力)
display(textarea)

# セル3(変数のリセット)
input_count = 0

# セル4(ソースコード)
print(input())

```

## イメージ
<img width="563" alt="スクリーンショット 2020-04-19 22.48.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442997/788f2ed3-44cf-51bc-9720-d16e1dea9cf3.png">



## 参考
- https://qiita.com/ct158603292321/items/c6920f7a0253a1cc4784
AtCoder Beginner Contest 163 参戦記

# AtCoder Beginner Contest 163 参戦記

ここ最近は上位20%近辺の常連だったが、今回は上位38.4%の位置ということで、unrated で良かった…….

## [ABC163A - Circle Pond](https://atcoder.jp/contests/abc163/tasks/abc163_a)

4分で突破. 書くだけだったけど、問題文が開始から2分以上見えなかったので時間がかかった. 円周の長さの公式くらい覚えてますよね?

```python
from math import pi

R = int(input())

print(2 * pi * R)
```

## [ABC163B - Homework](https://atcoder.jp/contests/abc163/tasks/abc163_b)

1分半で突破. 書くだけ. 宿題の所要日数を単純に合計して、夏休みの日数と比較するだけ.

```python
N, M = map(int, input().split())
A = list(map(int, input().split()))

a = sum(A)

if a > N:
    print(-1)
else:
    print(N - a)
```

追記: これでよかったな.

```python
N, M = map(int, input().split())
A = list(map(int, input().split()))

print(max(N - sum(A), -1))
```

## [ABC163C - management](https://atcoder.jp/contests/abc163/tasks/abc163_c)

7分半で突破. ディクショナリで直接の部下一覧リストを作ったけど、これ無駄に頑張りすぎてるなと今気づいた. 素直にリストに人数だけ足し込むほうが楽じゃん…….

```python
N = int(input())
A = list(map(int, input().split()))

d = {}

for i in range(N - 1):
    if A[i] in d:
        d[A[i]].append(i + 2)
    else:
        d[A[i]] = [i + 2]

for i in range(1, N + 1):
    if i in d:
        print(len(d[i]))
    else:
        print(0)
```

追記: これでよかった.

```python
N = int(input())
A = list(map(int, input().split()))

result = [0] * N
for a in A:
    result[a - 1] += 1
print('\n'.join(map(str, result)))
```

## [ABC163D - Sum of Large Numbers](https://atcoder.jp/contests/abc163/tasks/abc163_d)

まさかの敗退. 0 が邪魔すぎた.

追記: なんで私はコンビネーション計算して0が邪魔でダブるって悩んでたんですかね. ほんと馬鹿すぎて困る.

```python
N, K = map(int, input().split())

result = 0
for i in range(K, N + 2):
    # max: N, N -1, ..., N - i + 1
    a = (N + (N - i + 1)) * i // 2
    # min: 0, 1, .., i - 1
    b = (0 + (i - 1)) * i // 2
    result += a - b + 1
    result %= 1000000007
print(result)
```
ASP.NET COREのデータの再定義を行う（macOS）

## 概要
また詰まりました。
今度は「一度MySQLにマイグレーションしたデータベースを中身のデータを消さずにデータの再定義を行う」です。

一言で言えばRuby on Railsでいう、
rails g migration 
↓
マイグレーションファイルに記述（カラム追加、変更、テーブル追加など）
↓
rails db:migrate 
の様な流れでモデル操作をしたかったのですが、なかなかうまく行きませんでした。
Windows環境なら簡単そうなのですが、、、

一度データベース（MySQL）に接続した場合、
dotnet ef migrations remove -f
↓
モデル.cs編集
↓
dotnet ef migrations add データベース名
↓
dotnet ef database update
をすればデータベース再定義できるのですが、データベースの中身が全て破棄されてしまいます。
これは困る。
というので今回もmacOSで作業を行っていきます。

## 作業
### モデル編集
今回は「既存のテーブルにカラムを追加する」ことを想定して作業します。
なのでモデルを編集します。

```c#:モデル.cs

public class モデル
{
  〜中略〜
  [Timestamp]
  public byte[] RowVersion { get; set; }
}

```

### dotnet efコマンドで新しいマイグレーションファイルを作成する
必ずプロジェクトをビルドしてから、コマンドで新しいマイグレーションファイルを作成します。
このビルドをせずに作業してしまったので、先に進まず苦労しました。

```terminal
$ dotnet ef migrations add AddRowVersionToモデル
```

そうすると出来上がったマイグレーションファイルはこの様に自動生成されています。

```C#:マイグレーションファイル
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;

namespace アプリ名.Migrations
{
    public partial class AddRowVersionToモデル名 : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<DateTime>(
                name: "RowVersion",
                table: "テーブル名",
                rowVersion: true,
                nullable: true)
                .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.ComputedColumn);
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "RowVersion",
                table: "テーブル名");
        }
    }
}
```

### dotnet efコマンドでデータベースにマイグレートする

```terminal
$ dotnet ef database update
```

これで完了です

## 追記
dotnet efコマンドでエラーが起きた際、
原因を知りたい時には　-vを末尾につけると良いです。
今回調べて役立ちました。

ex.

```terminal
$ dotnet ef migrations add AddRowVersionToモデル -v
```

ご覧いただきありがとうございました。
xmodmapコマンドでCapsLockキーをCtrlキーとして動作させる。

# この記事は？
- xmodmapコマンドでCapsLockキーをCtrlキーとして動作させる方法について記載する。
    - =CapsLockキーをCtrlキーに入れ替える。
- cinnamonとかGNOME3なら標準機能で実現できるが、Xfceではできない様子。
    - ご存知の方いたら教えてください。
- 動作確認環境
    - Fedora 31 64bit

# TL/DR;
- Xodmapをインストールする。
    - 古いソフトウェアなはずなので、殆どのXWindow環境であるはず。
- ~/.Xmodmapにキーバインド書いてテスト。
- .bashrcに書いてログイン時に自動で読み込むように設定。

# 手順。
## xmodmapをインストール。
- Fedora  
```
sudo dnf install xmodmap
```
- CentOS7までならyumで。(fedoraならどっちでも良いのだが、いつyumが使えなくなるかは…)  
```
sudo yum install xmodmap
```

## ~/.Xmodmapにキーバインドを書いてテスト。 
### キーマップ設定。(ファイル名は何でも良い。)
```  
cat << '_EOT_' >> ~/.Xmodmap 
clear lock
keycode 66 = Control_L
add control = Control_L Control_R
_EOT_
```
- 自分のノートPCでは、Capslockのkeycodeは66だった。
    - xevあたりで調べる。
        - `dnf install xev`
        - `xev`叩いてkeycodeを調べる。
            - terminalでxev叩いた後、xevの画面がアクティブの状態で、該当キーを押下すると以下のようにkeycodeを調べられる。
            - 以下のキャプチャの通り、Capslockのkeycodeは66。 
              ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/34390159-d2c9-300a-a1ee-081f4fb2e0e4.png)

### キーマップ設定読み込みテスト。
```
xmodmap ~/.Xmodmap
echo $?
```
 
## ログイン時にキーマップ設定を自動で読み込むように設定。
```
cat << '_EOT_' >> ~/.bashrc 
xmodmap ~/.Xmodmap
_EOT_
```
### .bashrcの読み込みでコケないかチェック。
```
source ~/.bashrc 
echo $?
```

# 余談

- 自分のノートPCではAltキーが反応しないので、以下のように`変換キー`、`無変換キー`、`カタカナ/ひらがなキー`も全てAltキーとして動作させている。

```
cat ~/.Xmodmap
clear lock
clear mod1
keycode 100 = Alt_R
keycode 101 = Alt_R
keycode 102 = Alt_R
keycode 66 = Control_L
add mod1 = Alt_R
add control = Control_L Control_R

```

- 当初はWindowsライクなcinnnamonを愛用していたが、時間と共にマシンスペックが追いつかなくなってしまった…。
- LXDEも快適なのだが、強制的にUSキーボード認識されるバグがある。
- Xfce快適。
    - ショートカットが一部独特な気がするが…。

# 参考
https://wiki.archlinux.jp/index.php/Xmodmap
MacでWiresharkをインストールする方法(GUI & CLI)

[Wireshak](https://www.wireshark.org/)でパケットファイルを見る必要が有り、環境構築を行いました。ただ、古い情報も多く最新版のWiresharkに適したインストール方法を紹介したページに巡り会えなかった為、備忘録を兼ねて記事にまとめておくことにします。

# 検証環境
* macOS 10.14.6 Mojave
* Wireshark/Tshark Ver3.2.3

# Tsharkのインストール
CLI版のWiresharkです。Tshakは動作が軽く、高速で良いという話をよく聞くので今後の勉強時に利用しようと思います。故にインストールしておきます。

```bash
brew install wireshark
```

親切な事に、続けて行うべき操作のヒントが出力されました。

```bash
This formula only installs the command-line utilities by default.

Install Wireshark.app with Homebrew Cask:
  brew cask install wireshark

If your list of available capture interfaces is empty
(default macOS behavior), install ChmodBPF:
  brew cask install wireshark-chmodbpf
```

キャプチャーインターフェース空白のバグ？が発生している？？様ですが、筆者の環境では発生しませんでした。

```bash
$ tshark -D
1. en0 (Wi-Fi)
2. p2p0
3. awdl0
4. utun0
5. vmnet1
6. vmnet8
7. lo0 (Loopback)
8. bridge0 (Thunderbolt Bridge)
9. en1 (Thunderbolt 1)
10. en2 (Thunderbolt 2)
11. en5 (USB 10/100/1000 LAN)
12. gif0
13. stf0
14. XHC0
15. ap1
16. XHC20
17. VHC128
18. ciscodump (Cisco remote capture)
19. randpkt (Random packet generator)
20. sshdump (SSH remote capture)
21. udpdump (UDP Listener remote capture)
```

# GUI版: Wireshark.appをインストール
簡単です。以下のコマンドを実行するだけです。

```bash
brew cask install wireshark
```

# 2021/12/6更新: 最新版のインストール @ macOS Big Sur
以下のバージョンのMacでは上記の方法でエラーが出ます。

* macOS Big Sur 11.1

```bash:実行結果(抜粋)
Error: It seems there is already a Binary at '/usr/local/bin/editcap'.
```

これはHomebrewでGUIアプリケーションのインストール方法が変更になったことに起因していると思われます。以下の方法でtsharkとWireshark双方がインストールされます。

```bash
brew install --cask wireshark
```

```bash:キャプチャーインターフェースの確認
$ tshark -D
1. en0 (Wi-Fi)
2. awdl0
3. llw0
4. utun0
5. utun1
6. lo0 (Loopback)
7. bridge0 (Thunderbolt Bridge)
8. en1 (Thunderbolt 1)
9. en2 (Thunderbolt 2)
10. gif0
11. stf0
12. ap1
13. ciscodump (Cisco remote capture)
14. randpkt (Random packet generator)
15. sshdump (SSH remote capture)
16. udpdump (UDP Listener remote capture)
```

Wireshark.appを起動します。

<img width="816" alt="wireshark_default.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/cb5bf95e-c565-3cbf-8b82-11d736988a30.png">

## 日本語環境の設定
デフォルトでは英語で起動する様です。`Wireshark/Preference`をクリックし、設定画面を起動します。

<img width="681" alt="default.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/60993652-92fb-cad3-d717-af4fa8e3ad5d.png">

Appearance/Languageが`Use system setting`となっているのでJapaneseを選択します。

<img width="816" alt="wireshark.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/b4ac9b9a-9d8f-faa3-2eee-067503a7b8fb.png">

無事日本語化されました。今後ネットワークの学習に活用していこうと思います。
SPRING BOOT 学習記録02

![SPRINGBOOT.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598207/f3bb3381-89a4-53ac-b7bd-0e17853b2795.jpeg)


#Dependency Injection
依存性の注入
インスタンスの管理
![DI.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598207/d44b9ef9-7386-140e-3d28-d6dbdbce46a8.jpeg)

##依存性
忘れがちなLinuxコマンドとそのオプション

# はじめに
**忘れがちなLinuxコマンドのオプションたちを列挙していくよ！**
※基本的なコマンドのよく使うオプションは省略してます。

# ls
ディレクトリ内のファイル・ディレクトリを表示する。

`-F`　ディレクトリと各ファイルの種類を分けて表示
`-R`　現在位置より下の階層のディレクトリとファイル全て表示
`-t`　タイムスタンプ順に表示する(降順)
`--full-time`　タイムスタンプを細かく表示


# cp
ファイルやディレクトリをコピーする。
複数ファイル・ディレクトリ指定可能。

`-p`　タイムスタンプを壊さずコピー(基本的に全てにつける)

# mkdir
ディレクトリを作成する。
複数ディレクトリ指定可能。

`-p`　階層を指定して間のディレクトリを全て生成

# cd
ディレクトリを移動する。

`-`　直前にいたディレクトリに移動

# cat
ファイルの中身を表示する。

`-n`　行数を付けて表示

※長いファイルの場合はlessコマンドの方が良い。
※lessの場合、spaceで1画面スクロール、enterで1行スクロール、qで表示の終了ができる。

# find
ファイルの位置を検索する。

```
find [開始ディレクトリ] -name '[ファイル名]' -print
```

`-i`　大文字小文字の区別をしない

# locate
findと同様。
findより高速なファイル検索が可能。
検索位置は指定できないみたい。

※ `# updatedb`をしてから使う(1日1回は自動実行される)

# witch
実行ファイルのパスの位置を表示する。

`-a`　全ての実行位置を表示(基本的にこれをつける)

# printenv
現在の環境変数を全て表示する。

# wc
ファイル容量を確認する。

`-l`　行数
`-w`　単語数
`-c`　文字数
`-m`　マルチバイトの文字を含むファイルの文字数

# tar
アーカイブを作成する。

```
tar cvf [アーカイブ名.tar] [圧縮するファイルたち]
```

`cvf`　作成
`xvf`　展開
間に`z`をつけると.gzファイルを作成できる。

# gzip
ファイルを圧縮する。
※基本的にtarしてから。

`-d`　解凍
gunzipコマンドを使うとオプションなしで解凍できる。

# date
フォーマットを調整して現在時刻を表示する。

```
date +'%Y%m%d %a %H:%M'
```
``(バッククウォート)で囲むとファイル名などに付け足せる。

# grep
ファイルの中から検索文字列を含む行を表示する。

```
grep [検索文字列] [ファイル名]
```

`-i`　大文字小文字を区別しない
`-v`　検索文字列を含まない行
`-o`　検索文字列の部分のみ抽出(正規表現と一緒に使う)

```
grep '[0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}' [ファイル名]
```
などのように正規表現が使える。

# sed
ファイル中身の表示や置換ができる。

・表示

```
sed -n 6,8p [ファイル名]
```
6~8行目を表示


・置換

```
sed 's/[検索文字列]/[置換文字列]/g' [ファイル名]
```

# awk
**行や列の抜き出しにはめっちゃ使える。**

```
awk '/[検索文字列]/ {print $0}'
```

・指定カラムについて
`$0`　1行全て
`$1`　1列目
`$NF`　最後の列

・オプション
`-F`　列のセパレータを指定(デフォルトはスペース)
2つめの`/`の後に`i`を付けて大文字小文字を区別しない

`‘NR == 1, NR == 3’`のように指定すると行も指定できる(1~3行目)
各行ごとの指定の場合は `;` で区切る。

# sort
文字列や数字でソートする。

`-r`　降順にする
`-n`　文字を数値としてソートする

# uniq
重複を取り除く。
※ソートしてから使わないと連続して重複している文字列しか取り除いてくれないので注意。

`-d`　重複する行だけ
`-n`　重複しない行だけ
`-c`　行数をカウントして行横に表示

# ping
パケットを送って通信を確認する。

```
ping -i 2 -c 10 [IPアドレス]
```

`-i`　秒間隔を指定
`-c`　送る数を指定

# ps
現在のプロセス状態を確認する。

`-u`　ユーザ名と開始時刻なども表示

※ちなみに`kill [PID]`を指定して処理を強制終了することができる。

# ssh
他のサーバーにログインする。

```
ssh [ログイン名]@[IPアドレス]
```
戻るときはexit

```
ssh [ログイン名]@[IPアドレス] `コマンド処理`
```
をすることで1つのコマンド処理だけを他サーバーで行って帰ってこられる。

# scp
他のサーバーからコピーしてくる。

```
scp -p [ログイン名]@[IPアドレス]:[PASSとファイル名] [コピー先]
```

# crontab
時間間隔ごとに処理を実行できる。

cronを編集`crontab -e`

cronは以下のように記述する(3分ごとに実行)。

```
*/3 * * * * [処理]
```


# tail -f
cronなどでファイル追記をする場合、追記内容をリアルタイムで確認することができる。

# chmod
対象は
`u`　ユーザ
`g`　グループ
`o`　外部
の順になっている。

パーミッションは
`r`　読みとり　4
`w`　書き込み　2
`x`　実行　1
の順になっている。

```
chmod 755 [ファイル名]
```
とすることでユーザはrwx、グループはrx、外部はrxを指定することができる。

# 参考
https://eng-entrance.com/category/linux/linux-command
さらに詳しく知りたい場合はこちらを参照してください。
VMCをOBS VCでZoom〜バ美声をVACしたものを添えて〜

正式名称:
バーチャルモーションキャプチャをOpen Broadcaster SoftwareバーチャルカメラでZoom〜バ美声をVirtual Audio Cableしたものを添えて〜

#Zoom Hacking連載
[①FaceRig/SnapCamera+VT-4で参加したZoomをOBS経由でRTMP配信するまで](https://qiita.com/tetsuyaimagawa/items/86b843430011744a0602)
[②VMCをOBS VCでZoom〜バ美声をVACしたものを添えて〜](https://qiita.com/tetsuyaimagawa/items/dd82e2a3bf10488457bf)
[③Zoomで小技を出しつつも、こいつオタクなのかな？と思われたくない iVCam+DroidCamをOBS VCから流す方法](https://qiita.com/tetsuyaimagawa/items/d63db39dc42b466aa8ad)
[④Spark AR Studioで、他人の顔を自分の顔に被せてWeb会議に出席する]  (https://qiita.com/tetsuyaimagawa/items/dbdfe855756e3405c162)
[⑤Avatarifyで他人の顔を乗っ取り、web会議に出席する] (https://qiita.com/tetsuyaimagawa/items/8f180216712595071878)


#背景と概要
昨今、Zoomを始めとするWeb会議システムの利用が増えており、それに関わる技術にも注目が集まっている。
前回はFaceRigでアバターを用意し、マイク入力をVT-4で変換してZoomに流し、度肝を抜くことを目的としたが、身の回りの人々には一回使ってしまったし、使いこなす人も増加の一途を辿っている。

そこで、今回はあまり所有者の少ないVR HMDを用い、VMCをOBSで背景と合成し、OBSVCで出力、それをZoom(やその他会議システム)に読み込ませてみる。またHMDのマイクから入力した音声をバ美声に入れ、VACに出力したものを同じくVACの入力としてZoomに読ませる。

#VMC
https://sh-akira.github.io/VirtualMotionCapture/
(OculusやVIVE等の)VR HMDを用いることで3Dアバターを動かすことができるものです。

![alt](https://rawcdn.githack.com/sh-akira/VirtualMotionCapture/master/docs/images/manual/1-6.png)

使い方は公式で丁寧に説明されているので割愛します。（公式画像お借りします）
https://sh-akira.github.io/VirtualMotionCapture/manual/%E5%9F%BA%E6%9C%AC%E3%81%AE%E6%93%8D%E4%BD%9C%E6%96%B9%E6%B3%95.html
OBSで読むときは、背景をグリーンにしてクロマキーで緑を選択します。

ちなみに私が使っているのは[VIVE PRO](https://amzn.to/3bjGZ5e)ですが、高いですしVIVEはOculusに食われそうなので、悲しいかなおすすめできません…

#OBS Virtual Camera
前回紹介したOBSですが、今度はOBSの画面出力をZoomに読ませます。
そのためにOBSVCを入れます。
ファイル
https://github.com/CatxFish/obs-virtual-cam/releases
使い方
https://github.com/CatxFish/obs-virtual-cam

#バ美声
前回はVT-4をご紹介しましたが、そのソフトウェア版を利用します。
HMDのマイクから音声を一旦PCに取り込むので、PC OUT→VT-4 INのようにケーブルで音を外に出したくないからです（何かいい方法ありましたらご教示ください…）
ファイル
https://booth.pm/ja/items/1177717
使い方
https://www.cg-method.com/entry/babigoe/
![alt](https://booth.pximg.net/0bb570be-7108-4e6d-bf1c-8e89257a9de6/i/1177717/0d12b41e-3a63-4434-be02-eb18b1856d6b_base_resized.jpg)
入力デバイスをHMDのIN、
出力デバイスを下記で紹介するVACに設定します。
（公式画像お借りします）

#Virtual Audio Cable
PCから音声出力を一旦出力して入力に読ませる（本来はAudio Cableが必要な）手続きをVirtualでやってしまうものです。
ファイル＆使い方
https://virtual-audio-cable.jp.uptodown.com/windows

#Zoom
OBSVCと、VACをZoom（もしくはその他の会議システム）に読み込ませると、下記のような画面が完成します。
![messageImage_1587032674718.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142638/64bfb1f6-1b3f-cc08-76ae-a3845ddeaabe.jpeg)
**※本画像は筆者と一切関係のないイメージ図でございます**

#HMDのない方は
VMCの代わりにFaceVTuberを使うのもありですね。
https://facevtuber.com/

それでは、よいZoom Lifeを。
djoserを使ったDjango REST Frameworkでの認証機能の実装

# djoserとは

[djoser](https://djoser.readthedocs.io/en/latest/index.html)とはDjango REST Framework上での基本的なユーザー認証や登録などの認証周りをサポートしてくれるライブラリです。
カスタムモデルに対しても使え、Djangoのコードを再利用するような形をとるのではなく、Single Page Application(以下SPA)によりフィットするようなアーキテクチャを目指して作られています。

今回はdjoserの最もシンプルな認証機能の実装について書きます。
なお、この認証はセキュリティの面などから実際に使用するべきではなく、以下のJWT認証のようなより強固なセキュリティの設定があります。
あくまでお手軽な認証として紹介します。

JWT認証の設定は[こちら](https://qiita.com/KueharX/items/3568b27213cdbd1cf261)で解説しています。

[ソースコードはこちら](https://github.com/Kuehar/simple_djoser_authentication)

なお、以下の全てが導入後にエンドポイントとして使えます。

>/users/
/users/me/
/users/confirm/
/users/resend_activation/
/users/set_password/
/users/reset_password/
/users/reset_password_confirm/
/users/set_username/
/users/reset_username/
/users/reset_username_confirm/
/token/login/ (Token Based Authentication)
/token/logout/ (Token Based Authentication)
/jwt/create/ (JSON Web Token Authentication)
/jwt/refresh/ (JSON Web Token Authentication)
/jwt/verify/ (JSON Web Token Authentication)
[Getting started](https://djoser.readthedocs.io/en/latest/getting_started.html)



# 使い方

まずはインストールから。

```
$ pip install -U djoser
```

まずはプロジェクトを作り、

```
$ django-admin startproject simple_djoser_authentication
```

プロジェクト内に移動します。

```
$ cd simple_djoser_authentication
```

Djangoの設定を行なっていきます。

```Python:setings.py


   .........

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework', # add
    'djoser' # add

]
```

```Python:urls.py
from django.contrib import admin
from django.urls import path,include #add

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/auth/',include('djoser.urls')), #add
]
```

これだけです。


この後にマイグレーションし、Adminユーザーを作ってローカルで起動します。
```
$ python manage.py migrations
```

```
$ python manage.py createsuperuser
Username: Admin
Email address: xxx@email.com
Password:*********** 
```

```
$ python manage.py runserver
```

そして
http://localhost:8000/api/auth/
にアクセスします。

すると、
![スクリーンショット 2020-04-19 21.14.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412789/5169dae3-2bc0-7e6a-95fd-5e8713a8ce31.png)

以上のような画面が表示されます。

そして、次に
http://localhost:8000/api/auth/users/
にアクセスすると、

![スクリーンショット 2020-04-19 22.07.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412789/8d1bdce5-81ca-1c3d-8c97-db273dc16a00.png)

以上のようなユーザー情報一覧が表示されます。

これだけで認証周りの基本的な機能は導入完了です。
RstudioとShinyを使ったグラフと相関係数Webアプリ

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">相関係数RShiny <a href="https://t.co/GJv20lDmAj">https://t.co/GJv20lDmAj</a> <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a>さんから</p>&mdash; ZEO (@ZENOOcom) <a href="https://twitter.com/ZENOOcom/status/1252057930536349696?ref_src=twsrc%5Etfw">April 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
簡単に作成しました。簡単ですがCSVファイルの読込みに時間がかかりかなり苦労しました。
Plotグラフ、相関係数、Rでの検定結果がRshinyで表示されます。ベースはRStudioのサンプルページです。
データは適宜変更する必要があります。

'''
df<-read.csv('123.csv',header=TRUE)
ui<-fluidPage(    
  titlePanel("Telephones by region"),
　sidebarLayout(      
    
    # Define the sidebar with one input
    sidebarPanel(
      selectInput("region1", "X:", 
                  choices=colnames(df)),
      selectInput("region2", "Y:", 
                  choices=colnames(df))),
    mainPanel(
      plotOutput("phonePlot"),
      verbatimTextOutput("comand"),
      verbatimTextOutput("comand1")
    )))
```

```
server<-function(input, output) {
  output$phonePlot <- renderPlot({
    plot(df[,input$region1], df[,input$region2],
            main=input$region,
            ylab="Y",
            xlab="X")
  })
  output$comand<-renderPrint(cor(df[,input$region1], df[,input$region2]))
  output$comand1<-renderPrint(cor.test(df[,input$region1], df[,input$region2]))
}
shinyApp(ui = ui, server = server)
```
Jupyter notebookのインストール

# Jupyter notebookのインストール方法

Mac、LinuxにJupyter notebookをインストールして利用していたが、多くのトラブルに躓いたので、備忘の意味も込めて記載しておく。

MacやLinuxでは、`pip install jupyter`や`yum install jupyter`などでインストール可能であるが、`jupyter notebook`を使っているとPythonのModuleが無いなどトラブルに見舞われることが多い。

トラブル発生都度Moduleなどを探してインストールする手もあるが、Anacondaをダウンロードしてインストールすれば、ほぼ問題が発生しなかった。

Anacondaのダウンロードサイト
https://www.anaconda.com/distribution/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90447/2df90672-555b-1a86-87bc-140ea5470158.png)

以上、結構つまらないことで時間を食ってしまった。今後もJupyter notebookを使っていて気づいたことがあったら記載します。

このあたりはあまり使用したことがないので、間違い記載していたらすいません。