OmniAICreator/Qiita-1.07M huggingface dataset:
AWS cloud9 でEC2を使わずにAzureを利用する方法

Cloud9を利用するのときは通常EC2ですが、MSDNを契約している場合はAzureのサブスクリプションの無料枠を使いたくなるときがあります。

##
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/600633aa-099d-b5ab-5918-ae6559036509.png)


##Azureで仮想マシンを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/02dc99fe-3276-7068-fb10-ab77ec3ada36.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/ecfce1a1-38c1-2f15-28df-59cd96727430.png)


仮想マシン名：_(アンダーバー）は利用できません
イメージ：Ec2に合わせてCentOSを利用しました。

###管理アカウント
認証の種類：SSH公開キー
ユーザー名：任意
SSH公開キー：自動で作成される

###ディスク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/b62320f8-52e0-f8a0-6261-9ddef0ae466f.png)

###ネットワーク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/0db81363-452c-2042-3aeb-ab19a478d669.png)

###DNSラベルを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/a2d7d049-ede8-56c2-053a-de60dc5cca26.png)




###WindowsPCで公開キーを作成します

####サービスでOpenSSHクライアントを実行させる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/bf1450bf-801d-3d52-2c41-6b6c8f3fe3af.png)

続く...
PythonでKintoneとTwilioを結合する

#今回は壮大なテーマがあったんですが。ちょっと外れてPythonでKintoneとTwilioを結合するバックエンドを作ったので書いておこうと思います。
##なぜこの部分を作ったのか？
それは今後必要になってくるために作っていました。
[『大垣Pythonハッカソン@ヒーローズ・リーグ 2019 by MA』](https://mashupawards.connpass.com/event/146061/) に参加しておりました。
そのときにふとしたタイミングでPythonでKintonとTwilioを結合するプログラムを作成することになりました。
そのときに利用させていただきました@RyBBさんの[『kintone REST API について (GET編)』](https://qiita.com/RyBB/items/08cf511f1dbce6cf76bf)のPythonコードを利用させていただきました。
念の為おさらいの意味で載せておこうと思います。

```python:kintone_output.py
#!/usr/bin/python
# _*_ coding: utf-8 _*_

import requests

#APIトークン画面のREST APIでこのアプリを操作するためのトークンを生成できますの例に書かれたURLとAPIトークンを利用してください
URL = "https://サブドメイン/k/v1/record.json?app=4&id=1"　
API_TOKEN = "APIトークンを記述"

def get_kintone(url, api_token):
    """kintoneのレコードを全件取得する関数"""
    headers = {"X-Cybozu-API-Token": api_token}
    resp = requests.get(url, headers=headers)


    return resp

if __name__ == "__main__":
    RESP = get_kintone(URL, API_TOKEN)

    print(RESP.text)
```

でここでKintoneのデータがまるごと取得できます。
ここでいつもの間違いがURLと書きながら実際のURLを記載してはいけません。
REST API用のURLが準備されています。
APIトークン設定画面に記載されています。
そちらを利用してください。

お次はKintoneからデータを取得後の操作を記載します。
このコードはハッカソン界の赤い芸人@mobilebizことTwilioの高橋さんの[『Twilio with Python』](https://qiita.com/mobilebiz/items/5a39aef62d0ad9070d02)のコールバック用コードを流用・魔改造しながら作成しました。
連結させるためKintoneのURL情報の生成とAPIトークンを利用していますので気をつけてください。
JSONの部分とKintone接続部分はオリジナルに書かれていませんので下記のコードで実装できます。

```python:callback.py
from twilio.rest import Client
import kintone_output #この部分に上記で実装したkintone_outputをインポートしてくる
import json #PythonのJSONライブラリーをインポートする

#Twilio SID & auth_token（Twilioのコンソールにて取得可能）
account_sid = "" # Your Account SID from www.twilio.com/console
auth_token  = ""  # Your Auth Token from www.twilio.com/console

#kintone API用（この記載はkintone_output.pyからコピーして生成させる）
URL = "https://サブドメイン/k/v1/record.json?app=4&id=1"
API_TOKEN = "APIトークン"

#Twilio API Call
client = Client(account_sid, auth_token)

#Kintone data get（Kintoneからデータを引っ張ってくる上記のkintone_outputを変数として実行する）
to_client_json = kintone_output.get_kintone(URL,API_TOKEN)


#json取得（これを実装するとJSONパースができる（KintoneからのデータはJSON形式なので気をつけること））
to_client = json.loads(to_client_json.text) #JSONをロードする
to_direct_tel = to_client['record']['tel'] #JSONから一部レコードを取得する（TELを取得する）
to_client_tel = to_direct_tel['value'] #JSON['TEL']レコードから値を取得する

#電話番号の生成（国別番号付きコールバック用電番（E.164形式）の生成）
to_contory = "+81" #国別コード
to_tel = to_client_tel[1:] #電番の頭一桁を削る
to_tel_number = to_tel.replace("-","") #−を削る
to_client = to_contory + to_tel_number #国別番号と電番を直結

#call back 
call = client.calls.create(
    to = to_client, #E.164形式形式の電話番号を記載
    from_ = "", #コールバック用電話番号をTwilioコンソールから記載
    url = "http://demo.twilio.com/docs/voice.xml"
)


print(call.sid)

```

このコードにてKintoneからのデータの取得からE.164形式の電話番号の生成Twilioからのコールバックまで実装できます。
注意ですがこれは実装してしまうと実際に電話をかけることができますのでご注意ください。
###テストには必ずToは自分の携帯電話の電話番号を設定してください。
これができないと他人に迷惑をかけることになるので気をつけてください。

これからはというと次の壮大なテーマ災害をハックに入ります。
というのは[『災害時に何を考えるのか？』](https://qiita.com/hiro_matsuno2/items/b0aac2e078bbff3a71c2)で書きましたOpenStreetMapでクライシスマッピングに役立つツール作りに取り掛かりたいと思います。
これも多分このコードで実装は可能なのでKintoneからGetの部分で流用する予定です。
###うーん。　コードは奥深いですね。
Docker Composeのvolumes使用時に出会うpermission deniedに対応する一つの方法

## この記事は
Linux上で.envとDocker Composeを使ったvolumesの権限設定を紹介したいと思います

## 書く理由は
Linux上でDocker Composeを使ったvolumesの設定で権限で怒られたから

## 権限で怒らないためには
host(Docker Composeを動かす方)のLinux user id、group idとコンテナの中のvolumesのuser idとgroup idが異なるからです。
これらを同じくすれば治りました

## 対応内容
1. setDotEnv.shを実行して、hostのLinux user id、group id、user nameを.envに書いておく
2. docker-compose.ymlのargsを使って、.envにあるuser id、group id、user nameをDockerFileに渡す
  - docker-compose.ymlでbuildを使用する場合、env_fileを使ってDockerFileに環境変数を渡せません。( https://docs.docker.com/compose/compose-file/#env_file )
3. DockerFileはdocker-compose.ymlからargsを通じて渡されたuser id、group id、user nameを使って、Dockerコンテナの中の環境変数を設定します
4. Dockerコンテナに設定された環境変数を使って、hostと同じuser id、group id、user nameを持つユーザーを作ります
5. `user: $UID:$GID` オプションを使って、DockerコンテナにログインするユーザーをhostのLinux userと同じくします。(defaultはrootユーザーです)
6. DockerFileのENTRYPOINTを使って、Dockerコンテナ生成された後に、shell script(setVolumePermission.sh)を実行してvolumesの権限を設定します
  - Dockerコンテナが生成される前は、volumesされるディレクトリがありません。
  - ![noEntrypoint1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/14cee486-0bb8-b51d-0799-654ff890f7b7.png)

  - DockerFileでvolumesするディレクトリをmkidrで作って権限を設定しても無視されます。


## 結果
hostのLinuxユーザーはvagrant、Dockerコンテナの中で確認したvolumesディレクトリもvagrantで、ちゃんと設定されました
![withEntrypoint1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/5fe9cba1-7097-691a-a629-e3390bae0a23.png)




## 環境
### Linux
- NAME : Kali GNU/Linux
- VERSION : 2019.1

### Docker Compose
- VERSION : 1.23.1

### Docker
- VERSION : 18.09.4



## 構成図
![dirs.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/bff3e04b-205d-87da-c16b-dbeeb5c70ffb.png)


### setDotEnv.sh
```
#!/bin/sh

touch .env
echo "UID=$(id -u $USER)" >> .env
echo "GID=$(id -g $USER)" >> .env
echo "UNAME=$USER" >> .env
```

### .env(`setDotEnv.sh`から作られました)
```
UID=1000
GID=1000
UNAME=vagrant
```


### docker-compose.yml
```
version: '3'
services:
  dot-env-entrypoint-docker-volumes:
    container_name: 'dot-env-entrypoint-docker-volumes'
    user: $UID:$GID
    build:
      context: .
      args:
        UID: $UID
        GID: $GID
        UNAME: $UNAME
    tty: true

    working_dir: '/home/$UNAME'
    volumes:
      - ./workspace:/home/$UNAME/workspace
```

### Dockerfile
```
FROM amazonlinux:2

RUN \
  yum -y update \
  && yum -y install systemd procps openssh-server passwd sudo vim git wget unzip \
  && yum clean all \
  && cp -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

ENV LANG ja_JP.UTF-8
ENV LC_ALL C

ARG UID
ARG GID
ARG UNAME

ENV UID ${UID}
ENV GID ${GID}
ENV UNAME ${UNAME}

RUN groupadd -g ${GID} ${UNAME}
RUN useradd -u ${UID} -g ${UNAME} -m ${UNAME}

COPY ./setVolumePermission.sh /home/${UNAME}
RUN chmod +x /home/${UNAME}/setVolumePermission.sh

ENTRYPOINT ["sh", "-c", "/home/${UNAME}/setVolumePermission.sh"]
```

### setVolumePermission.sh
```
#!/bin/sh

chown ${UNAME}:${UNAME} -R /home/${UNAME}

/bin/bash
```



### コメント
docker-compose.ymlでのvolumesディレクトリの権限設定は`Dockerコンテナ生成された後に、volumesディレクトリの権限設定するべき` を学んで良かったです

### 以上
VSCodeでHaskell Language Serverが動かない（Windows 10）

VSCodeでHaskell Language Serverを使い始める際にドハマリしたので日本語文献を残しておきます。

# 環境
- Windows 10
- VSCode 1.38.1
- Haskell Language Server 0.0.28
- Haskell IDE Engine 0.12.0.0
- [この記事](https://qiita.com/yutasth/items/9df6e2c3937edad24aee)の続き

# 起きたこと
Haskell IDE Engineをインストールしたのち、VSCodeを起動して拡張機能Haskell Language Serverを導入したところ、エラーも何も出ず動かない。

# 原因
Haskell IDE Engineがstty.exeを必要としている。

# 確認方法
コマンドプロンプトで以下の表示が出る：

```powershell:
> hie
(中略)
`stty` is not recognized as an internal or external command.
```

# 対策
`C:¥Users¥[username]¥AppData¥Local¥Programs¥stack¥x86_64-windows¥msys-[XXX]¥usr¥bin¥stty.exe`をパスの通った場所にコピーする。Haskell IDE Engineと同じ`C:¥Users¥[username]¥AppData¥Roaming¥local¥bin¥`に入れておくのが良いかもしれない。

# 続き
https://qiita.com/yutasth/items/28af2eb0371f6457e0bb

# 参照文献：
https://github.com/commercialhaskell/stack/issues/4901
[mac][command]まとめフォルダを作って画像をまとめる

# 画像(jpeg/jpg)をまとめるだけのツール(command)

※メモ書き

コマンドファイルが置かれている箇所に
以下のようなフォルダ配置になっていた場合に、

----
｜matome.command
｜－テストフォルダ
　｜－test.jpg
　｜－test2.jpg
｜－テスト２フォルダ
　｜ーtest3.jpg


実施すると以下のようになります。

｜matome.command
｜－テストフォルダ
　｜－test.jpg
　｜－test2.jpg
｜－テスト２フォルダ
　｜ーtest3.jpg
｜－まとめ
　｜－test.jpg
　｜－test2.jpg
　｜ーtest3.jpg



※同一の名称の画像ファイルがあると上書きしてしまったりします。
　↑
　あまり頻繁に発生しないので、とりあえずやってません


```commnad:matome.commnad

var="まとめ"
CURRENT=$(cd $(dirname $0) && pwd)
cd $CURRENT
mkdir $var
cp ./*/*.jpg ./$var
cp ./*/*.JPG ./$var
cp ./*/*.jpeg ./$var
cp ./*/*.JPEG ./$var
Terasolunaの二重送信防止とSpring Securityのcsrf対策を両立させる方法

# はじめに
この組み合わせで問題が起きて解決したメモです。

Terasolunaの二重送信防止ページについては以下をご覧ください

http://terasolunaorg.github.io/guideline/5.5.1.RELEASE/ja/ArchitectureInDetail/WebApplicationDetail/DoubleSubmitProtection.html

# 環境
Adopt Open JDK Hotspot 11.0.3
Spring boot 2.1.0M4

# pom.xml
二重送信防止機能についてはTerasolunaの機能を使いますので、Dependencyに追加します。
`terasoluna-gfw-common`はいらない気もしますが、なんとなく入っています。

``` pom.xml
        <dependency>
            <groupId>org.terasoluna.gfw</groupId>
            <artifactId>terasoluna-gfw-common</artifactId>
            <version>5.5.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.terasoluna.gfw</groupId>
            <artifactId>terasoluna-gfw-web</artifactId>
            <version>5.5.1.RELEASE</version>
        </dependency>
```

# InterceptorとRequestDataValueProcessorの設定
Terasolunaの二重送信防止機能はInterceptorでRequestにAttributeを設定して、それをキーにRequestDataValueProcessorでhiddenを作りだすみたいな動きをします。
そのため、Interceptorの設定とhiddenを作ってくれるRequestDataValueProcessorの設定を行います。

ここで注意点があり、Spring Securityを使用するとcsrf対策のためのhiddenを埋め込む設定であるCsrfRequestDataValueProcessorが自動的にBean登録されます。
このProcessorは全体で1つしか登録出来ないため、特に何もしなければcsrf対策か二重送信防止かどちらかしか使うことが出来ません。
そこで、Terasoluna内にある`CompositeRequestDataValueProcessor`という複数のRequestDataValueProcessorを使用するためのクラスをBean登録することで両立させることになります。

また、今回は例なので、HandlerInterceptorを全てのURLに設定していますが、必要に応じて`excludePathPatterns`で除外条件を作ってあげてください。

``` java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.support.RequestDataValueProcessor;
import org.terasoluna.gfw.web.mvc.support.CompositeRequestDataValueProcessor;
import org.terasoluna.gfw.web.token.transaction.TransactionTokenInterceptor;
import org.terasoluna.gfw.web.token.transaction.TransactionTokenRequestDataValueProcessor;

@Configuration
public class WebMcvConfig implements WebMvcConfigurer {

    @Bean
    public TransactionTokenInterceptor transactionTokenInterceptor() {
        return new TransactionTokenInterceptor();
    }

    @Bean
    public RequestDataValueProcessor requestDataValueProcessor() {
        return new CompositeRequestDataValueProcessor(new CsrfRequestDataValueProcessor(), new TransactionTokenRequestDataValueProcessor());
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(transactionTokenInterceptor()).addPathPatterns("/**");
    }
}
```

# Beanの上書きを許容する
Beanはデフォルトだと上書き出来ないように設定されているため、設定で上書き出来るように許容してあげます。
この設定を行わないとBean重複してるとしてエラーとなってしまいます。

ただし、この設定を入れると上書き出来てしまうため、Bean関連の設定がしっかりしていないと思わぬ挙動が発生してしまいます。ご注意ください。

``` yaml
spring:
  main:
    allow-bean-definition-overriding: true
```

# おわりに
なんでSpringに二重送信防止機能がデフォルトで入っていないのでしょうか。
【SwiftUI】ListのSeparatorを無理やり消したい時の解決法

2019/09/28日のSwiftUI1の現状で、SwiftUIのList separatorをインスタンス単位で公式に消して使う方法がなく、無理やりな方法を使うか、回避策を取る必要があります。

この記事では、上記の2つの方法について共有します。

# 1. 無理やり解決する
[Stackoverflowの記事で見つけた解決方法](https://stackoverflow.com/questions/56553672/how-to-remove-the-line-separators-from-a-list-in-swiftui-without-using-foreach
)です。

出典不明ですが、SwiftUIのListも `UITableView.appearance()` の制御下にあるようなので、この挙動を切り替えます。

Viewの表示/非表示で切り替えても良いですし、場合によってはUIApplicationDelegateで切り替えても良いかもしれません。

```swift:
struct ContentView: View {
    var body: some View {
        
        NavigationView {
            List(accounts) { account in
                YourView()
            }
        }
        .onAppear {
            // SwiftUIの初期バージョンでは、Listに対してSeparatorを取り外す処理ができないので、この特殊なコードで無理やり消す。必要になったら別途考える。
            UITableView.appearance().separatorColor = .clear
        }
        .onDisappear {
            // Viewが画面を離れるときに元に戻す
            UITableView.appearance().separatorColor = .separator
        }
    }
}

```

# 2. ScrollViewを使う
こちらもStackoverflowだと[この辺](https://stackoverflow.com/questions/56507497/views-compressed-by-other-views-in-swiftui-vstack-and-list
)に書いてあるのと、Twitterでも先駆者が何人か検証されていました。

```swift
ScrollView {
    VStack(alignment: .leading) {
        ForEach(accounts) { account in
            DailyCaloriesSummaryView()
        }
    }
}
```

# どっち使ったら良い？
超暫定対応になるので、自分が期待する挙動を楽に実現できる方で進めれば良いかと思います。// FIXME: を残しておいて、正式対応されたらすぐに対応しても良いぐらいのやつ。
さくらのレンタルサーバーにpyenvを構築する方法

なんか間違ってたり、難しい方法でやってるの多かったから。あと、自分のブログで書くほどのことでもないから。

# bashに変更

```
$ chsh -s /usr/local/bin/bash
$ cat << EOS > ~/.bash_profile
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
PATH=$PATH:$HOME/bin:$HOME/usr/local/bin
EOS

$ exec $SHELL -l
```

# pyenvをインストール
```
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ cat << EOS >> ~/.bash_profile
export PATH
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
export TMPDIR=/home/nashio/tmp
eval "$(pyenv init -)"
pyenv rehash
EOS
$ source ~/.bash_profile
```

# pyenv を使って好きなバージョンをインストール
```
$ pyenv install --list
$ pyenv install 3.7.4
$ pyenv global 3.7.4
$ which python
/home/ユーザー名/.pyenv/shims/python
```
ABC 107-B

```c++
#include <bits/stdc++.h>
#define rep(i,n) for (int i=0; i<n; i++)
typedef long long ll;
using namespace std;

int main() {
	int H, W; cin >> H >> W;
    char S[101][101];
	int A[101];//行
	int B[101];//列
	rep(i,101){
		A[i] = 0;
		B[i] = 0;
	}
	rep(i,H){
		rep(j,W){
			cin >> S[i][j];
			if (S[i][j] == '#') {
				A[i] = 1;
				B[j] = 1;
			}
		}
	}
	rep(i,H){
		if (A[i]) {
			rep(j,W){
				if (B[j]) cout << S[i][j];
			}
			cout << endl;
		}
	}
	return 0;
}
```
【論文紹介】AdaptiveFace: Adaptive Margin and Sampling for Face Recognition

#紹介する論文
[AdaptiveFace: Adaptive Margin and Sampling for Face Recognition](http://www.cbsr.ia.ac.cn/users/xiangyuzhu/papers/2019adaptiveface.pdf)

#概要
近年、顔認識タスクはmargin basedなSoftmax損失関数によって進化を遂げた。それらの手法では暗黙的に各クラスが十分なサンプル数を持っていることを仮定して、すべてのクラスのマージンを固定しています。しかし、実はそうではない。下記の図に示すように、各データセットのクラスが持っているサンプル数は非常にアンバランスとなっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416370/e5ce53d6-4472-e10c-128d-af804a9ca0f4.png)

#提案手法
本論文で提案した顔認証のフレームワークは下記となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416370/41e513bf-ead6-0905-cfc6-87a2353ab168.png)

* **Adaptive Margin Softmax**

まず、CosFaceをベースにし、クラス内の分散を適応的に減らすため、各クラスのマージンを固定することではなく、学習させる。式：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416370/655f36cc-9b48-dda7-ca97-337a4d0d171e.png)
各クラスのマージンを学習させると、「０」を得られる場合があるので、全クラスの平均マージンを求める必要がある。式：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416370/3119142f-819e-3a13-8ba2-5a1097a6e85e.png)
上記の式を合わせて、Adaptive Margin Softmax Loss（AdaM-Softmax）となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416370/faf8355c-d4d6-bb74-dc8f-79891a8ea719.png)
ここでは、**λ**はマージン制約の強さを制御するものとなる。**λ**を一定の範囲に大きくすると、サンプル数が少ないクラスのクラス内の分散を小さくすることができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416370/d1ce3378-92a0-dc7f-e511-130a5db114f3.png)


* **Hard Prototype Mining**

識別学習中、ハードなprototype(重みベクトル)を適応的にマイニングする。各クラスの重みをprototypeにして、ANN(angle nearlest neighbor) graphを使って、その重みと最も似ているいくつかのクラスを探す。

* **Adaptive Data Sampling**

ミニバッチレベルで良いサンプルを見つけるため、識別層からデータ層への部分からフィードバックを行う。各サンプルにサンプリング確率を設定することによって、
- 正しく分類された場合　　　：　確率を減らす　→　Esay Samples　→　学習しなくなる
- 正しく分類されなかった場合：　確率を増やす　→　Hard Samples　→　もっと学習する
のようになる。

#実験
* **Preprocessing**
FaceBox[Zhangら、2017]で顔の検出を行い、6層のCNNで目、鼻先、口の２つのコーナーの5つランドマークをつけて120x120にリサイズする。

* **CNN Architecture**
PyTorch、LResNet50A-IR（ArcFaceと同じ）で学習して、512チャネルの特徴ベクトルを得られる。

* **Training Data**
「Alightcnn for deep face representation with noisy labels」でノイズをクリーニングし、データセットMS-Celeb-1Mで学習する。

* **Evaluation Setup**
オリジナル画像の特徴ベクトルを出し、データセットでLFW、LFW BLUFR、MegaFaceで検証する。

#結果
MegaFaceとLFWで検証して、提案手法が良い性能（state-of-the-art）を示している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416370/a8f7a817-45a5-5206-bd27-5268de75cfb1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416370/642d0201-7101-ff48-a54b-a40ed94115e8.png)
【UE4】スマートフォン(iOS,Android)のスリープ機能を無効にする

#はじめに
スマートフォン向けに開発していると少し重めのDLCをDLさせる必要があったり、長めのムービーを見せたいことがよくあと思います
その場合、スリープされてしまうとDLが中断したりムービーが途中で終わってしまったりして意図しない結果になってしまいますよね
なのでスリープ機能をOFFにしてしまえば解決するのですがUE4だとどうやればいいのかまとまっている記事が見当たらなかったので備忘録として残りしておきます

#環境
Windows10
UE4.21.2

#実装
1. 〇〇.Build.csのPublicDependencyModuleNamesに「ApplicationCore」モジュールを追加  
2. 任意のcppファイルで「HAL/PlatformApplicationMisc.h」をinclude
3. #ifdefでiOSとAndroidで処理を分ける
4. プラットフォーム別のControlScreensaver関数でONとOFFを切り替える

#例

```c++:MyActor.cpp
// Fill out your copyright notice in the Description page of Project Settings.

#include "MyActor.h"
#if PLATFORM_ANDROID || PLATFORM_IOS
#include "HAL/PlatformApplicationMisc.h"
#endif


void AMyActor::SetEnableScreensaver(bool enabled)
{
#if PLATFORM_ANDROID
	FAndroidApplicationMisc::ControlScreensaver(
		enabled ? FAndroidApplicationMisc::EScreenSaverAction::Enable : FAndroidApplicationMisc::EScreenSaverAction::Disable);
#elif PLATFORM_IOS
	FIOSPlatformApplicationMisc::ControlScreensaver(
		enabled ? FIOSPlatformApplicationMisc::EScreenSaverAction::Enable : FIOSPlatformApplicationMisc::EScreenSaverAction::Disable);
#endif
}


```

#備考っぽいもの
今回Includeしている「HAL/PlatformApplicationMisc.h」では単純に必要なヘッダーファイルをプラットフォーム別に読み込めるようにifdefで区切っている
なので、どのプラットフォームだろうがこのヘッダーを読み込んでおけばOK
また、ControlScreensaver関数も共通のクラスから呼び出せば大丈夫になっているかと思いきやVerの問題なのかコンパイルではじかれたので素直にプラットフォーム別に処理をわけたほうが間違いないかなと思いました

あとiOSだけっぽいのですが、無効にする処理をBeginPlayで行っても正常動作しなかったのでTickなどで1秒以上delayさせてから実行するようにすると正常動作しました
CircleCiメモ

# localにCircleCi CLIをインストールする(mac)
[クイックインストール](https://circleci.com/docs/ja/2.0/local-cli/#%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

```
curl -fLSs https://circle.ci/cli | bash
```
# configをバリデート
```
# circlciの設定が置いてあるdirに移動して
cd myDir/.circleci
# validate
circleci config validate
```
# workflowの設定
## developブランチ/featureブランチへ変更が入った際にbuildジョブを実行
```
workflows:
  version: 2
  deploy-build:
    jobs:
      - build:
          filters:
            branches:
              only:
                - develop
                - /^feature\/.*/
```
## PRが作られた際にprジョブを実行
```
workflows:
  version: 2
  deploy-build:
    jobs:
      - pr:
          filters:
            branches:
              only: /pull\/[0-9]+/
```
## tagを切った際にreleaseジョブを実行
```
workflows:
  version: 2
  deploy-build:
    jobs:
      - release:
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^[0-9]+\.[0-9]+\.[0-9]+$/
```
TTP223タッチセンサーとSS1A05リードリレーの動作

#arduinoを車載し空気の制御でSWがほしくなった
![inspiresw.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/30e904b4-0900-f8c7-16ff-c63f6609ae5d.jpeg)
どうしても物理スイッチでは上のナビ本体とぶつかってパネルをセットするとき
難しい。またスイッチもなかなかスムーズに動かない。
どうにかしたく小型のSWを探したが、そもそも物理的に小さいのはありえない。
使用したいのはトグルでON/OFFを切り替えられなければならないので。
穴まであけてしまったがそれはまた何かに使う。
そうだ、この穴は丸型LEDを差し込んで。カーナビの車速信号切断と接続のリレーで
どうなっているかわかりにくかったのでそれに使おう。

##TTP223タッチセンサー
この方のブログ記事より一度タッチしてONが継続、もう一度タッチしてOFFにできることがわかった
[TTP223静電容量式タッチセンサ（タッチスイッチ）を使う](http://nomolk.hatenablog.com/entry/2019/01/05/223000)

さっそく５VでON時　I/Oという出力でLEDを光らせるのはなんなくできた。
![alt](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/1e4b8d12-c73a-0535-72fb-bdff420c1534.jpeg)

そこでリードリレーを使って別の電圧とか車速信号とかのON/OFFとかしたい。
しかし、うまくいかず。
ちょっとドライブするには電力が足りず。トランジスタで駆動させて動作を確認
![IMG_20190929_181119_435.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/0441b0c7-5bc6-5563-ea2e-2e11117f091a.jpeg)
【Unity(C#)】OculusIntegrationを使ってVR空間でSliderを操作

##目的
**VR空間内でスライダーのUIを操作して、ゲームの難易度を設定する**
というのが今回の目的です。

この記事では**VR空間内でスライダーのUIを操作**の部分を記述します。

##デモ
実際に作成したものがこちらです。
見た目は置いといて、機能としては完成です。

![Slider.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/43b67544-46c2-6f34-71b3-1d2274bb73f9.gif)

##OculusIntegrationの設定

####①OVRInputModuleの設定
`Create Empty`でGameObjectを生成して、`OVRInputModule`をAdd Componentします。

設定項目としては3か所だけです。
今回は人差し指のトリガーで操作する設定にしてます。
Cursorの箇所は後述します。
![InputSettings.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/55d3e4d4-cc7d-8c8f-5913-4b0fb8032632.png)

####②Cursorの設定
続いて、Cursorの設定です。
`Create Empty`でGameObjectを生成して、`LaserPointer`をAdd Componentします。
同じオブジェクトに`LineRenderer`もAdd Componentします。

あと、LineRendererが太すぎるのでWidthを0.03くらいにしました。
お好みでmaterialを設定してレーザーの色を変えたりできます。
![LineRenderWidth.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/262bc2a4-b0e5-4457-4e2d-eb84c282b7ce.png)



今回のデモではカーソルは表示していませんが、
必要な場合は`CursorVisual`お好きなカーソル(ゲームオブジェクト)をアタッチすればOKです。
![CursorVisual.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/c1029855-c40f-d0ec-2111-9ed16a6cd553.png)


####③OVRRaycasterを追加
Canvasに`OVRRaycaster`をAdd Componentします。
これで、そのCanvasの子のUIに対して操作が可能になります。
もともとある`GraphyicRaycaster`は消してしまって構いません。

##設定完了！
これでもうUIを操作できます。
OculusIntegration神ですね。

##コード

スライダーの値を取得するメソッド、`GetLevel`を用意します。

```C#:Sliderにアタッチ
using UnityEngine;
using UnityEngine.UI;

public class LevelGetFromSlider : MonoBehaviour
{
    Slider levelSlider;
    
    void Start()
    {
        levelSlider = this.gameObject.GetComponent<Slider>();
    }

    public int GetLevel()
    {
        return (int)levelSlider.value;
    }
}

```



```C#:Textにアタッチ
using UnityEngine.UI;
using UnityEngine;

public class LevelText : MonoBehaviour
{
    [SerializeField]
    LevelGetFromSlider _levelGetFromSlider;
    
    Text levelText;

    void Start()
    {
        levelText = this.gameObject.GetComponent<Text>();
    }

    public void LevelTextChange()
    {
        levelText.text = _levelGetFromSlider.GetLevel().ToString();
    }

}
```
後はテキスト側で`On Value Changed`に登録するメソッド内で先程の`GetLevel`を使います。
`On Value Changed`というのは、Slider Componentに用意されているイベントハンドラーです。
画像のように登録して使います。

![OnValueChanged.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/415579cd-fedb-fffc-83f6-103378acbba4.png)


これでSliderの値が変更された際に、テキストも変わります。

Editor上でSliderのValueを直接編集しても反映されないので注意です。
【競プロ】Pythonで複数の値を出力する

# 概要
競技プログラミングでは，形式に沿った出力を行う必要があります．出力する値が1，2個の場合は簡単ですが，これが可変個の場合はやや大変です．そこで，いくつかの出力方法を紹介し，またその実行速度の比較を行います．

# 空白区切り
次のような出力方法が考えられます：

```python
ans = [1, 2, 3, 4, 5]

# その1 for
for a in ans[:-1]:
    print(a, end=' ')
print(ans[-1])

# その2 join結合
print(' '.join(map(str, ans)))

# その3 アンパック
print(*ans)
```

どう考えてもアンパックが簡単に書けて，バグも生じにくいように思えます．ちなみに```*ans```はの意味するところは以下のようになります．

```python
# 以下2つは同じ
print(*[1, 2, 3, 4, 5])
print(1, 2, 3, 4, 5)
```

次に速度比較を見てみます：上のコードにて

```python
ans = list(range(10**6))
```

として，AtCoderのコードテストで実行した結果です．

| 種類 | 実行時間(ms) |
| --- | --- |
| for | 1000 |
| join | 250 |
| *ans | 450 |

forは遅いようです．一方で```join```で結合したほうが```*ans```より2倍程度高速です．ですが$10^6$個も出力しない限りは```*ans```で十分でしょう．

# 改行区切り
こちらは空白区切りと殆ど変わりません：

```python
ans = [1, 2, 3, 4, 5]

# その1 for
for a in ans:
    print(a)

# その2 join結合
print('\n'.join(map(str, ans)))

# その3 アンパック
print(*ans, sep='\n')
```

実行速度は次のようになりました：

| 種類 | 実行時間(ms) |
| --- | --- |
| for | 700 |
| join | 240 |
| *ans | 450 |

forがかなり早くなりました．どうやら```end```を指定すると遅くなる様子です．しかしながら実行時間は空白区切りのときと一緒で，join < *ans < for の順です．ですが先程と同様に$10^6$個を出力しない限りは好みの問題となりそうです．

# まとめ
いくつか複数の値を出力する方法を紹介しました．実行時間に差はあるものの，大量に出力しない限りはお好みの出力方法を選べば大丈夫だと思います．
clang 9 C++ for OpenCL のメモ

Clang 9 から, OpenCL カーネルで C++ の機能(C++17)が使えるようになってきました.

http://clang.llvm.org/docs/UsersManual.html#c-for-opencl

ただしこれは C++ 言語のフル実装(libc++ など STL なども含んだものという意図です)が OpenCL runtime 経由で GPU などで動くようになるというわけでもなく, OpenCL C++ の実装というわけではありません.
また, STL も利用できません.

template や class が使えて, 最近の CUDA C++ 言語や, Metal Shading Language のような感じでかけるようになった感じでしょうか.


auto や lambda 式も利用できますので, それなりにカーネルコードが記述しやすくなると想像します.

## 利用方法

`-cl-std=clc++` もしくは `-std=clc++` を指定します.


また, デフォルトでは `get_global_id()` などは定義されないため, ドキュメントにあるように, 基本的にデフォルトヘッダファイルを読み込むオプションを指定します.

`-Xclang -finclude-default-header`

`-Xclang` は, 後続のコンパイルオプションが clang 独自のものであることを指示するものです.

## その他

### SyCL

より完全な形(?)で C++ を Accelerator(e.g. GPU, FPGA) で動かすものとして, SyCL が提案されています. 

https://www.khronos.org/sycl/

OSS の実装は triSYCL, 商用(?)の実装は Codeplay 社による ComputeCPP があります. 
どのくらい世の中で利用されているのかは不明ですが, Intel SyCL なるものも出てきているので以外と普及していくかも? :thinking: 

https://www.phoronix.com/scan.php?page=news_item&px=Intel-SYCL-Compiler-2019-09

hipSyCL というのも出てきていました.

https://github.com/illuhad/hipSYCL

### Intel OpenCL Clang

https://github.com/intel/opencl-clang

intel graphics compiler で使われています.

https://github.com/intel/intel-graphics-compiler

clang 9 以降でビルドすれば, C++ -> SPIR-V -> OpenCL compute kernel を実行できる Vulkan runtime で Vulkan で実行, というのが実現できそうかしらん?

### clspv

SPIR-V 出力に特化した, clspv でも C++ を使うことができますが, こちらは現状 opencl1.2 の C++ 機能のみになります(C++98 相当?). いろいろいじれば C++17 も使える... かも?

https://github.com/google/clspv

## TODO

* [ ] NanoSTL https://github.com/lighttransport/nanostl を利用することで, clang C++ for OpenCL で STL をいくらかサポートしたい
Azure Blob Strage でお手軽静的Webサイト構築

容量の大きなファイルを送る時に使える方法として活用しています
他にもモバイルゲームの静的ファイルを置いたアセット管理用なんかにも使えます


### Blobストレージを作る
(1)Azure ポータルでストレージアカウントから「追加」もしくは「ストレージアカウントの追加」をクリック
![Blob_wwb01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/59d78f06-7e1f-f72c-77af-08f8e9c8502a.png)

(2)リソースグループ(既存リソースグループを設定しても可)、ストレージアカウント、リージョンを選択し、アカウントの種類は「StrageV2(汎用 v2)」を選択
これを選択しないと作れません
必要項目を入力したら「確認及び作成」をクリック
![Blob_wwb02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/650e8ce8-f27b-d012-23a9-056914a79e5f.png)

(3)表示されている内容に問題なければ「作成」をクリック
![Blob_wwb04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/855eea5b-79c5-4d81-6015-b067ac206337.png)

(4)作成が完了したらリソースに移動
![Blob_wwb05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/1908c0aa-7ef2-93ef-39d9-75418bd4ffd1.png)

### Blob Strageを公開する
(1)ストレージアカウントに移動すると左側のメニューに「静的な Web サイト」があるのでクリック
![Blob_wwb06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/75db7868-600b-1554-3428-29acc6e63dc7.png)

(2)静的なWebサイトを「有効」にし、インデックスとエラーページを適宜設定し「保存」をクリック
![Blob_wwb06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/941edb8c-7695-9391-04cf-1924164fb7bd.png)

(3)正常に保存されるとWebのエンドポイントが作成される
![Blob_wwb08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/048e3e94-5a96-4f2f-6c1a-150f5d67e2e8.png)

(4)ストレージへのコンテンツのアップロードは、(3)のエンドポイント作成時にストレージコンテナーとして作成されているので、そちらをクリックしアップロード
![Blob_wwb09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/19efcd91-3e82-0bd8-a82d-fe5761181f24.png)

(5)アップロードしたいファイルを選択
![Blob_wwb10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/320f4225-6afa-cdb0-f820-ec8dd16891b4.png)

(6)アップロードしたいファイルを選択したら「アップロード」をクリック
![Blob_wwb11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/662d0fc2-e636-54e6-1154-a0baded53047.png)

(7)完了すると下図のように表示されます
![Blob_wwb12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/253ab3dd-194a-2e5f-7e75-13296b1dcb59.png)

(8)アップロードされたファイルは作成したエンドポイントのURLから確認できます
ちゃんとHTTPS対応されています(これ大事)
![Blob_wwb13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/fccb90da-56ba-5a21-9336-1a4af97104ef.png)


### 実用的な話
〇ファイルのアップロード方法
上記手順だとファイル1つずつしかアップロードできないですが、まとめてアップロードしたい場合
一つの方法として[Azure Strage Explore](https://azure.microsoft.com/ja-jp/features/storage-explorer/)があります
他のストレージも視覚的に管理できるのは便利です
![Blob_wwb14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/44bbe22d-3c0e-3df3-7ada-76ec80d407ff.png)

他にもAzure CLI、Azure PowerShell モジュール、AzCopy、Azure Pipelines、Visual Studio Code 拡張機能 なんかでもできるそうです

〇カスタムドメインを使いたい
やっぱり自分の持っているドメインで使いたいと思った時、HTTPS 経由でカスタム ドメインを使用して Azure CDN から BLOB にアクセスするという方法がサポートされているそうです
これはまた別の機会に書きたいと思います。

〇ぶっちゃけコストってどうなの？
数百円レベルです
複雑なことをしなければ、WebAppでサーバ立てるより安くなる可能性があります
Golang備忘録 Golangでdumpしたい。

# はじめに
Golangを触り始めてよく使うプログラムの書き方を自分用に残すための備忘録。
どのような記述をしたらいいのか少しでもお役に立てればと思っています。
・これは随時、追加していきます。
また、いいコーディング方法があればご教授願います:bow:

# プログラムの書き方
## データを見る
phpでいうvar_dumpものがしたい時

```golang:sample.go
package main

import (
	"fmt"
)

type Person struct {
    family_name   string
    first_name string
}

func main(){
	Person := Person{family_name: "Yamada", first_name: "Taro"}
	fmt.Printf("%v\n", Person) // データの出力
	fmt.Printf("%+v\n", Person) // 内容にフィールド名も加えてデータの出力
	fmt.Printf("%#v\n", Person) // データをGoの構文で表現する
}
```

```golang:出力
1. {Yamada Taro} (%v)
2. {family_name:Yamada first_name:Taro} (%v+)
3. main.Person{family_name:"Yamada", first_name:"Taro"} (%v#)
```

2番、3番の形式で出力すると、データ構造がはっきりと分かり開発が捗りそう。

## Coming Soon
Qiitaとはてなブログの使い分け

初投稿だけどQiitaだけじゃなくて、はてなブログにも記事を書いているので**Qiitaとブログとの使い分け**について調べてみました。

## Qiitaに書くとされている内容

- Qiitaの目的はプログラミングの知識を共有する場
- 事実を書く

ということなので、そもそもこのような記事をQiitaに投稿するのはちょっと合わないということになりそう。これからは気をつけたいと思います。

プログラマの方の情報共有の場なので余計なことは書かずに*役に立つ事実や知見を書いていく*ということです。

## ブログに書くとされている内容

- 自分の思いや考え方
- その他の雑記

主張はブログに書くべしという意見多し。雑記的な記事もブログです。

要はQiitaに書かないことをブログに書くという考え方です。Qiita主体の考え方とも言えます。

## Qiitaのメリット

- SEOが強力
- プログラミングに関するコミュニティがある

SEOがあまりにも強力なのでGoogleで検索した時に上位表示される可能性が高い。よって書いた記事が埋もれずに閲覧されます。これがQiitaのメリットです。

Qiitaのドメインパワーが強力すぎて検索結果の上位3記事がすべてQiitaということもしばしば経験しています。はてなブログのSEOも強いには強いですが、さすがにプログラミング系の記事はQiitaにかないません。

あと個人ブログだと閉鎖ということもあり得ますがQiitaなら記事がなくなるリスクは大分減りますね。無料で記事が公開できますし。

プログラマの方が集まっていますのでコミュニティも強力です。逆に職業プログラマでない人には少し敷居が高い感じもします。簡単にコミュニティに入れないかもしれないし間違ったことを書いたら怒られそうで怖いです。

裏を返せば間違ったことを書いてしまっても修正してくれるコミュニティがあるとも言えます。フィードバックが得られるのが良いところ。

## Qiitaでの記事の書き方

Markdown記法が使える。これは楽。ただし拡張記法はほとんど無い模様。

はてなブログのように過去記事の埋め込みや他のWebサービスからの引用などはあまりできないみたいです。淡々とプログラミングコードを主体として事実を書いていくだけならこれで十分ということでしょう。シンタックスハイライトが可能なのはいいですね。

なおTwitterの埋め込みには対応しています。

## Qiitaとブログでの収益化

はてなブログProではGoogleアドセンスにより収益化を行うことが可能です。

はてなブログProにして独自ドメインを取得することになります。コストはかかりますが毎月700円程度の収益が出ればペイできます。

QiitaではGoogleアドセンス広告を貼ることはできません。なので記事の収益化を行うことはできません。これは迷いが出ますね。

とは言っても高度なプログラミング情報だけをブログに書いてもあまり収益化できないと思います。ネットリテラシーの高い層しか記事を見に来ないので広告がクリックされる率が極端に低くなると思われます。

はてなブログに有益な記事を書いている方を時々見かけます。非常に良い記事なのに、はてなブックマークもほとんどついていなくて埋もれているようなことも往々にしてあります。

Qiitaは収益化を目指すような場所ではないしSEOを考えたりする必要もありません。プログラミングのことに集中できそうです。OSS開発とは相性が良さそうですね。

## Qiitaとはてなブログの使い分け

というようなことを調べた結果、はてなブログとQiitaの使い分けを以下のように考えています。

- 非常に専門的なプログラミングに関する内容
- プログラミング絡みのちょっとしたTips

はてなブログにも技術記事を書いていますが検索需要のある記事は意外とアクセスが集まってきます。なのでそうした記事をQiitaに書くのは少しもったいないように思います。

なので、あまりにも専門的で検索需要があまり無さそうな内容はひとまずQiitaにアップすることにしようと思います。Googleアナリティクス~~やサーチコンソール~~も設置できますので検索需要がどのくらいあるか測定することも可能です。

QiitaではSEOを考えたりする必要もない（元々非常に強い）ので、記事の構成を考えずにちょっとしたTipsでもメモ代わりにアップすることもできそうです。

ひとまずこんな形でQiitaを運用してみて様子が分かったら少しずつ修正してこの記事にも追記していきます。
技術書典を楽しもう part2 ～当日偏～

# 目的

- 技術書典当日にやっておくとよいこと、当日の流れなどを知る。
- まだ技術書典に参加したことのない方の参加ハードルを下げる。

# この記事のターゲット

- 技術書典に参加したいけどどの様に参加したらいいか分からない方
- 技術書典当日の雰囲気が知りたい方
- 何かしらの技術系イベントに参加したい方

※技術書典開催前日までの内容も別記事でまとめています。もしよければご覧ください。
[技術書典を楽しもう part1 ～参加サークル公開前から前日まで偏～](https://qiita.com/miriwo/items/a2d857694dd18ef97b25)
[技術書典を楽しもう part3～アプリでお会計編～](https://qiita.com/miriwo/items/eea6a0658719d1148383)

# 当日の流れの概要

1. 池袋のサンシャインシティにある文化会館に向かう(早速若干の難関)
1. 運営さんの指示に従い前売り一般入場整理券を持っている方は入場待機列に並ぶ
1. 入場して技術同人誌を購入する(アプリでの購入方法は別途記事を用意する予定)
1. 別のフロアに移動する

# 当日の流れの詳細

1. 池袋のサンシャインシティにある文化会館に向かう(早速若干の難関)
  1. ちょっとだけ文化会館の場所が分かりにくいので、池袋駅から文化会館までの行き方を書く(技術書典7現在)
  1. 池袋駅東口からの簡単な地図を下記に載せる。(赤がサンシャインシティまでの道のりで青がサンシャインシティ内の経路)  
    ![WS000020.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/caeec762-3b83-a5a5-81a3-2439392db3d0.jpeg)
  1. サンシャインシティへ入る(前記した地図の赤から青に変わる部分)ところのストリートビューを下記に載せる。  
  赤矢印のように歩いてきて青矢印部分の入り口からサンシャインシティに入る。(階はそのままで地上から上がったり下がったりしない)  
    ![WS000021.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/faaa2be0-6e60-f724-fd86-454dab675cce.jpeg)
  1. サンシャインシティの内の経路を下記に載せる。  
  先ほどの入り口から入ったら同じ階をひたすらまっすぐ進む
    ![WS000022.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/df526cdc-7851-e31d-fcd8-540b94a892df.jpeg)
  1. 文化会館へアクセスするエスカレーターの画像を載せる。  
  下記のエスカレーターが見えてきたら乗って上るとすぐ会場が見えてくるので運営さんの指示に従う。  
    ![2019-09-22_12-14-53_000 (2019-09-29T09_10_30.935).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/592aa6c6-5d74-5ffa-303a-9cb03c725578.jpeg)

1. 運営さんの指示に従い前売り一般入場整理券を持っている方は入場待機列に並ぶ
  1. ここから列に並ぶことになり、列を抜けられなくなるので用事を済ませておく。
1. 入場して技術同人誌を購入する(アプリでの購入方法は別途記事を用意する予定→お会計に関しての記事は[こちら](https://qiita.com/miriwo/items/eea6a0658719d1148383))
  1. 気になる技術同人誌を発見したら購入する。
1. 別のフロアに移動する
  1. 技術書典7から会場が2つに分かれたため会場間の移動が必要になった。
  1. 混乱が起きないように階段を上る会場移動は移動時には勝手に移動することは出来ず、列に並びにいっぺんに50名程が別に会場に案内される。
  1. 階段を下りる会場移動時は各自で移動することができる。

# まとめ

- 文化会館の場所が若干分かりにくいから注意しよう
- 列に並ぶ前に用事は済ませておこう
- 屋外に並ぶ可能性があるので暑さ、寒さ対策をしておこう
- お会計の方法は別途まとめる↓  
[技術書典を楽しもう part3～アプリでお会計編～](https://qiita.com/miriwo/items/eea6a0658719d1148383)
M5StickCがmacのシリアルポートに認識されない

USBでMacにM5StickCを繋いでも、シリアルポートに何も出てこず、
この状態。。
![1_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173392/d718705b-ba8f-e371-587e-bfef01dd0419.png)


Topic: Mac: Port Stuck on /dev/cu.Bbluetooth-Incoming-Port How do I switch to serial? (Read 3235 times)
https://forum.arduino.cc/index.php?topic=504170.0

Arduinoのポートが認識されない時の対処法
https://qiita.com/ryusukefuda/items/5b2edea6b62794069209

上記を参考にしながらいろいろと試行錯誤したのですが、ダメでした。


静電気で本体が壊れちゃったかな〜
そういえばだいぶ加熱してたよな〜
と買い直しを決意しつつ、念のため、別の用途で買ってたM5StackVのUSBケーブルで繋いだところ、めでたく認識いたしました！！！

![3_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173392/5633a4f5-67ac-1f10-b74e-b738e7fef7c5.png)

## 結論：USBケーブルがダメだった

まさかそんな。。
お前この間まで繋がってたやん。。
いや、会社で10台くらいスマホ並べてデバッグしてた時にすり替わったかもしれん。


こちらにも記載がありました。
↓↓↓
M5Stackの困ったときの対処や注意すること
https://raspberrypi.mongonta.com/m5stacktips/#USB


ふー、焦ったぜ。。

以上です。
日本語版wikipediaのデータ取得と整形

## 概要
web上からwikipediaのテキストデータを取得。
取得したwikipediaのダンプファイルは、[Wiki記法](https://kujirahand.com/konawiki/index.php?Wiki%E8%A8%98%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)で記載されているため、そのままでは自然言語処理に不向き。
そのため[Wikipedia Extractor](http://medialab.di.unipi.it/wiki/Wikipedia_Extractor)というpythonスクリプトを使って、シンプルな日本語に直す。

具体的には以下の2点を導出する。
**1. 日本語版wikipediaのテキストデータを取得**
**2. データ形式の整形**


## 手順
```yaml:使用環境
python3.7.2
```

### 1. 日本語版wikipediaのテキストデータを取得
1. [日本語のwikipedia情報ダウンロードページ](https://dumps.wikimedia.org/jawiki/latest/)にアクセス
1. `jawiki-latest-pages-articles.xml.bz2`というファイル名のダンプファイルをダウンロード

### 2. データ形式の整形
1. [Wikipedia ExtractorのGithub](https://github.com/attardi/wikiextractor)をclone
1. wikipediaのダンプファイルと `WikiExtractor.py`を同一フォルダに配置
1. [GithubのUsage](https://github.com/attardi/wikiextractor#Usage)を参考に、wikipediaデータを整形

```bash:サンプル
python WikiExtractor.py -b 500K -o wikipedia jawiki-latest-pages-articles.xml.bz2
```
- bオプション: 分割する1ファイル辺りのサイズ容量
- oオプション: 書き出しするフォルダ名

## 結果
```:出力される階層構成　(wiki_01などがxml形式のファイル)
└── wikipedia
    ├── AA
    │   ├── wiki_00
    │   ├── wiki_01
    │   │      ・
    │   │      ・
    │   └── wiki_99
    ├── AB 
    │    ・
    │    ・
    └── CE
```

```xml:出力ファイルサンプル　(wiki_01の一部抜粋)
<doc id="56" url="https://ja.wikipedia.org/wiki?curid=56" title="地理">
地理

地理（ちり、英: Geography）
「地理」という表現は古くからあり、有名なところでは漢書の『地理志』がある。
地理学とは、地球の表面と住民の状態、その相互関係を研究する学問である。
「地理」は、日本の学校で設置されている、「人間の生活に影響を与える地域的、社会的な構造」を学ぶための科目である。自然環境や産業環境などを含む環境を学習対象としている。小学校および中学校においては、歴史や公民と並び、社会科の一分野である。高等学校においては、最近は「地理歴史科」という教科の中の一科目となっており、「地理A」「地理B」に細分されている。

</doc>
```
上記のように、wikipediaの各記事ごとに\<doc>タグで囲まれている。

## 結論
まずは単純にオープンに公開されているwikipediaのデータを取得した。
次に、自然言語処理をしやすくするためのデータ整形を行った。

## 参考
- [Wikipedia Extractor（Pythonスクリプト）](https://github.com/attardi/wikiextractor)
- [【Python】日本語Wikipediaのダンプデータから本文を抽出する](https://www.takasay.com/entry/2016/05/20/221817)
- [Wikipediaの日本語記事を全行を、分かち書きしてforループで回す](https://www.madopro.net/entry/wikipedia_iterator)
DjangoでGAEのMySQLと接続する時にポートが埋まっているよと言われた時の対処法

終わってみれば簡単な思い込みだったのですが、同じようなことが起こった時にために残しておきます。

#環境

MacOS Mojave 10.14
Python 3.7.3
Django 2.2

#手順

手順自体は[公式](https://cloud.google.com/sql/docs/mysql/connect-admin-proxy?hl=ja)に載っているのですが、ここにざっくり書くと、
1.APIを有効にする
2.プロキシをインストールする
3. サービス アカウントを作成する
4. プロキシを開始する
5. クライアント セッションを開始する
と言う流れなのですが、


僕の場合は
4のプロキシを開始する手順での、
```./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306
```
というコマンドを叩いてもポートがすでに埋まってるよ!
というメッセージが返ってきたので、

とりあえず現在使われているポートを調べるために

```lsof -i :[PORT番号]
```

をしてみると既に使用しているポートの一覧が表示されるので、埋まっているポートを終わらせたい時には

```kill -9 PID値
```

でポートを閉じられるのでkillしてみた後に再び
```./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306
```
コマンドを叩いてみるとつながりました。

以上です。


#　追記
[この方法でOperation not Permittedと表示された時の解決策と原因について書きました]
(https://qiita.com/KueharX/items/29cfda5b887a07695b73)

この記事の方法で上手くいかないときはこちらも試してみてください！
Laravel5.8でブックマークアプリを作るチュートリアル（動画版）

Laravel5.8でブックマークアプリを作るチュートリアルを動画（Youtube）で作成しました。
いろいろ安定していない感ありますが、よろしかったらぜひ！

# 第1回 インストール＆初期設定編
Laravelのインストールから初期設定までを行なっています。

[![第1回 インストール＆初期設定編](http://img.youtube.com/vi/Br_Tx619k9E/0.jpg)](http://www.youtube.com/watch?v=Br_Tx619k9E)

# 第2回 アプリケーションのデモ
なぜか２回目のアプリの動作デモです。
最終的にはちょっと変わってしまいましたが。

[![第2回 アプリケーションのデモ](http://img.youtube.com/vi/RsT0C6KPZQY/0.jpg)](http://www.youtube.com/watch?v=RsT0C6KPZQY)

# 第3回 Router編
アプリケーションの入り口であるルーターについて。

[![第3回 Router編](http://img.youtube.com/vi/ALmHWS2JeWU/0.jpg)](http://www.youtube.com/watch?v=ALmHWS2JeWU)

# 第4回 データベース編
マイグレーションでデータベースを構築して、シーダーでダミーデータを入れるところまで。

[![第4回 データベース編](http://img.youtube.com/vi/BWfaRtG5aEY/0.jpg)](http://www.youtube.com/watch?v=BWfaRtG5aEY)

# 第5回 データベースのデータを表示しよう
登録したダミーデータからデータを取得して一覧ページを作成します。

[![第5回 データベースのデータを表示しよう](http://img.youtube.com/vi/vpNTgfUkqwI/0.jpg)](http://www.youtube.com/watch?v=vpNTgfUkqwI)

# 第6回 詳細ページの作成
データベースからID検索でレコードを取得して、詳細ページを作成します。
詳細ページ用のルーティングやモデルバイディングの解説もしてます。

[![第6回 詳細ページの作成](http://img.youtube.com/vi/o2xKJnasvlM/0.jpg)](http://www.youtube.com/watch?v=o2xKJnasvlM)

# 第7回 レコード追加機能の作成
データベースにレコードを新規登録する機能を作成します。

[![第7回 レコード追加機能の作成](http://img.youtube.com/vi/OICCPBAmsHE/0.jpg)](http://www.youtube.com/watch?v=OICCPBAmsHE)

# 第8回 レコード更新機能の作成
レコードの更新機能の作成と、ビューファイルを共通ファイルにしてインクルードする方法。

[![第8回 レコード更新機能の作成](http://img.youtube.com/vi/pxjOoW98epw/0.jpg)](http://www.youtube.com/watch?v=pxjOoW98epw)

# 第9回 レコードの削除とフラッシュメッセージ
レコードの削除機能とフラッシュメッセージを作成します。

[![第9回 レコードの削除とフラッシュメッセージ](http://img.youtube.com/vi/9_tkCwTZyfA/0.jpg)](http://www.youtube.com/watch?v=9_tkCwTZyfA)

# 第10回 入力フォームのチェック機能（バリデーション）
入力フォームのチェック（バリデーション）機能を作成します。

[![第10回 入力フォームのチェック機能（バリデーション）](http://img.youtube.com/vi/BIxM6IqNTBk/0.jpg)](http://www.youtube.com/watch?v=BIxM6IqNTBk)

# 第11回 ユーザー登録・認証機能の作成
ユーザー認証・登録機能を作成します。主にビューファイルの編集です。

[![第11回 ユーザー登録・認証機能の作成](http://img.youtube.com/vi/FZ_J6Xl3YG8/0.jpg)](http://www.youtube.com/watch?v=FZ_J6Xl3YG8)

# 第12回 タグCRUD（作成・読み込み・更新・削除）機能の作成
今までのおさらいも兼ねて、タグのCRUD機能の作成します。

[![第12回 タグCRUD（作成・読み込み・更新・削除）機能の作成](http://img.youtube.com/vi/A2kbKGFTr7M/0.jpg)](http://www.youtube.com/watch?v=A2kbKGFTr7M)

# 第13回 データベースのリレーション設定（ブックマークとタグの関連付け）
今までのおさらいも兼ねて、タグCRUD機能の作成します。

[![第13回 データベースのリレーション設定（ブックマークとタグの関連付け）](http://img.youtube.com/vi/mUVoOCG7JHg/0.jpg)](http://www.youtube.com/watch?v=mUVoOCG7JHg)

# 第14回 リレーション（タグ）の表示とデバッグツールについて
設定したリレーション（タグ）の表示とデバッグツール（Clockwork）を使用して、クエリの確認を行います。

[![第14回 リレーション（タグ）の表示とデバッグツールについて](http://img.youtube.com/vi/TTxzF-eo928/0.jpg)](http://www.youtube.com/watch?v=TTxzF-eo928)

ソースコードはこちら
https://github.com/k-ishiwata/BookmarkApp
ディレクトリ毎にgitの鍵ファイルを使い分ける

# gitのremote接続用の鍵を使い分けたい

本当はgithubのアカウントは１つだけで管理したいのだけど、仕事とプライベートで２つのgithubアカウントがある場合などは鍵ファイルも２つになってしまう。だけどPCは１台で作業したい時がある。
しかし、githubには２つのアカウントに同じ鍵は登録できない。でもhttpsとかにして毎回ユーザー名とかパスワード入力するのは面倒なので何とかしたい。

#　結論

普段は個人用のid_rsaの鍵ファイルを利用しているか、仕事用の鍵をカレントディレクトリのみに適用させたい場合はgit config --local で以下の様にしていできる。

```bash
$ git config --local user.name "仕事アカウント名"
$ git config --local user.email "仕事@メールアドレス"
$ git config --local core.sshCommand "ssh -i ~/.ssh/仕事用_rsa -F /dev/null"
```
※git2.1.0以降のみ設定可能

## 参考
[https時代のgitアカウントを使い分ける方法](https://qiita.com/1natsu172/items/a4a3357a0481440ec6a5)
今日見た凄いと思ったコード

# 文字列の16進数を値の10進数に変換

```c:hex2dec.c
#include <stdio.h>

int hex2dec(int hex)
{
    return hex % 87 % 48;
}

int main(void)
{
    char input;
    scanf("%s", &input);

    printf("%d\n", hex2dec(input));
}
```


```c:input（文字列を入力）
9
```

```c:output(数値が出力)
9
```

```c:input(文字列を入力)
f
```

```c:output(数値が出力)
15
```
# なんでこうなるのか
そもそも87や48はどっから出てきたのか。

## 自分なりの解釈

### 48ってなんやねん

10進数の48は文字コードで0であり、それで割った余りが値としての数値が出てきた。
0から9まではこの処理で大丈夫

### じゃあ87は？

10進数の87は文字コードでW。なんの関係もなかった

### 置きかえよう
87を10進数として16進数で表記した場合、57となった
57を10進数で表した場合、文字コードで9であった

### つまり……どういうことだってばよ？
57:文字コードで「9」
87:10進数を16進数として、この値で割った余りがa~fの値としての数値となる
よって、10~15が出力される

# まとめ
48:文字コードで「0」
87:文字コードで「9」を16進数に変換した57を、更に10進数に変換した値

上2つの値で割った余りが値としての16進数に変換される
手計算でもこうなるのは確認したけど、なんでこうなるのかは全くわからん。誰か教えて……

## 参照
ASCIIコード表
http://www3.nit.ac.jp/~tamura/ex2/ascii.html

2進数、8進数、10進数、16進数相互変換ツール
https://hogehoge.tk/tool/number.html
複数の開発本線が同時に走る場合のGit-flowをベースにした運用フロー

# はじめに
私が所属する開発チームでは、一つのリポジトリ内に複数製品が同居しており、それら製品の「企画→開発→リリース」の期間が同時期に並列して走る場合がある
その状況で運用しているフローを整理を兼ねて記す

# 概観
以下のように、Git-flowから_release_ブランチを除き、かつ**_develop_ブランチが複数ある**ような運用フローとなっている
![Git-flowもどき.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/dd033310-9cc0-d7a8-28c0-30e8027da26c.png)

# 詳細
## 基本的なフロー
### 開発
- マイルストーンごとに_develop_ブランチ（開発本線）を切る
- 開発タスクごとに作業ブランチを切り、コードレビュー完了後、_develop_ブランチにマージする

### 検証開始・再開前
- ビルド番号をインクリメントする
    - _develop_ブランチ上で直接コミットする
- 検証時に**_develop_ブランチが_master_ブランチに後れを取っていないか**を確認し、ある場合は差分をマージする
    - 他の進行中の_develop_ブランチや、緊急リリース用の_hot fix_ブランチを確認し、それらをマージする

### 検証
- _develop_ブランチの最新コミット上でビルドし、バイナリを検証チームに渡す

### 検証時の不具合対応
- 既に存在する作業ブランチで追加修正する場合、以下を確認
    - **作業ブランチの分岐元コミットが古く、_develop_ブランチにマージする際コンフリクトが起きる懸念がある場合**は、_develop_ブランチを作業ブランチにマージした後で作業する
- 修正してコードレビュー完了後、_develop_ブランチにマージする
- 「検証開始・再開前」の項に戻り、再度検証開始

### 検証完了後
- _develop_ブランチを_master_ブランチにマージする
- タグを打つ
- **他に進行中の_develop_ブランチが存在する場合**は、そのブランチにもマージする
- 作業ブランチを削除する

## 例外的なフロー
### 緊急リリース対応
- _master_から直接_hot fix_ブランチを切り、そのブランチ上でコードレビュー・検証を実施する
- 検証完了後、_hot fix_ブランチを_master_ブランチにマージする
- その後、**進行中の_develop_ブランチが存在する場合**は、そのブランチにもマージする

# 参考
- https://qiita.com/KosukeSone/items/514dd24828b485c69a05
Git-flowもどきフローにおけるGerritによるコードレビュー実施方法

社内で、Git-flowもどきフローでGerritによるコードレビューを実施しているので、整理を兼ねてメモする

# 前提
## 内容について
### 記事で書くこと
- 開発時のGerritとの連携方針

### 記事で書かないこと
- Gerritとの連携の具体的な操作方法
- Git-flowの説明

## 開発環境
- バージョン管理：Gerrit v3.0.0 (Git)
- バージョン管理のGUIクライアント：SourceTree
- ブランチの運用方法：Git-flowもどき
  - Git-flowから_release_ブランチを除いたもの
  - 開発タスクごとに作業ブランチを切り、_develop_ブランチにマージしていく、という流れとなる

# 実施手順
![Gerrit開発フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/096c4cff-08bf-764d-7770-5324dbb0ed37.png)

## コードライティング
- ローカルで_develop_ブランチをPULL
  - ローカルにリポジトリをクローンしていない場合は、**Change-Idのフックによる自動追加を含むコマンド**を用いてクローンする
- ローカルで_develop_ブランチから作業ブランチを切り、作業開始
  - バージョンやビルド番号を上げるなど作業ブランチを切るまでもない細かい作業は、**直接_develop_ブランチ上で実施**する
- 大きなタスクの場合は、バックアップとこまめな進捗共有のため、**WIP(Work In Progress: 作業中)**オプションをつけてGerritにPUSH[^wip]しておく
- 作業期間が長い場合は、developブランチを適宜フェッチし、更新がある場合は**作業ブランチを_develop_へリベース**する

## コードレビュー
- 作業が完了したら、Gerritのコードレビュー用ブランチにPUSH[^push]し、レビュアーを割り当てる
  - WIPとして作業していた場合は、Web上でコードレビューを開始ボタンを押下するか、コードレビュー開始オプションをつけてGerritにPUSH[^ready]する
- コードレビューで指摘を受けた場合は、作業ブランチ内のコミットを修正し、再PUSHし、コードレビューを再開する
    - コミットメッセージ中の**Change-Idは変更しない**ようにする
- コードレビューが完了したら、最後に承認した人にGerritのWeb上でsubmitしてもらう
  - これにより、リモートリポジトリへ変更がコミットされる

## マージコードレビュー
- _develop_ブランチに**fast-forwardなしでマージ**
  - この際、_develop_ブランチにチェックアウトした状態で、SourceTreeの画面上部に表示されているマージボタンを押下し、**マージされていないコミット一覧画面**を利用してマージすると、マージ漏れなどの事故が防ぎやすくなる
- マージによりコンフリクトが発生した場合は適宜修正する
- developブランチをGerritのコードレビュー用ブランチにPUSHする
  - コンフリクトが発生しなかった場合は、**自分でコードレビューを通しsubmit**する
  - コンフリクトが発生して修正した場合は、前節のようにコードレビューを実施する

[^push]: PUSH先リモートブランチを`refs/for/hogehoge`に指定
[^wip]: PUSH先リモートブランチを`refs/for/hogehoge%wip`に指定
[^ready]: PUSH先リモートブランチを`refs/for/hogehoge%ready`に指定
VSCodeでCouldn't start client Haskell IDEが出る（Windows 10）

VSCodeでHaskell Language Serverを使い始める際にドハマリしたので日本語文献を残しておきます。

# 環境
- Windows 10
- VSCode 1.38.1
- Haskell Language Server 0.0.28
- Haskell IDE Engine 0.12.0.0

# 起きたこと
Haskell IDE Engineをインストールしたのち、VSCodeを起動して拡張機能Haskell Language Serverを導入したところ、`Couldn't start client Haskell IDE`というエラーが出てHaskell Language Serverが機能しない。

# 原因
Haskell Language ServerがHaskell IDE Engineを見つけられない。

# 対策
Haskell Language Serverの設定を開き、`Language Server Haskell: Hie Executable Path`にhie.exeの場所を記入する。このとき、ディレクトリまでではなくhie.exeを含めて記載すること。
だいたい`C:¥Users¥[username]¥AppData¥Roaming¥local¥bin¥hie.exe`にあると思う。

# 参考情報：
cabal-installが入っていないと、このあとVSCodeに「cabal-installがありません」と言われるかもしれない。[cabal-installをダウンロード](https://www.haskell.org/cabal/download.html)してきてcabal.exeを上記binに入れると解決する。

# 参照文献：
https://mstdn.jp/@hennin/100758597442814577
https://mstdn.jp/@hennin/100758604120408077
https://mstdn.jp/@hennin/100758606408428604
透過した画像の透過部分を削除したい

今、Blenderの下絵に使う画像を作ってて、
透過した画像の透過部分消したいなぁと思ってGIMP触ってたら、
さっき感動したので、メモ書き程度に残しておきます。

普段GIMPなんて触らんよっていう、僕みたいな人の役に立てば幸いです。

# この記事を読んでできるようになること

* 透過された画像から、透過部分以外のみを画像にできる

# 手順

1. 透過された画像を用意します。(透過方法はググれば山のように出てきます)

2. GIMPでその画像を開きます。

多分、こんな感じの画面になるのではないでしょうか。
(黒と灰色のタイル状の模様が透過されていることを表現してます)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290263/3313ca28-3b22-c05b-3192-e21af6014812.png)

3. **画像**タブをクリックし、**画像の自動切り抜き**をクリック。

上手い具合に切り抜いてくれました。(自動切り抜きなので、上手く切り抜けない形もあるかもしれません)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290263/dd4acd61-1582-5dca-b26b-76bcb640ece5.png)

4. **ファイル**タブで画像を**名前をつけてエクスポート**をクリックし保存します。
(**「画像名」に再エクスポート**をクリックすると初めの透過された画像に上書きされます)

5. もしこの後も編集する予定があるようでしたら、ファイルタブの「保存」しておくと、後で編集できます。

# 終わりに

僕の目的的には、矩形に切り出してくれたので満足だったんですが、上手く切り抜けない形もあるかもしれないです。

ただ、この機能にちょっと感動したので、皆に伝えたくて書きました。

読んでくれてありがとうございます。
【忘備録】Vagrantを使用した際のpipに関する注意

現在、VagrantとVirtualBoxを用いて、仮想環境を構築して、作業してます。
その際に、pipのInstallで問題が起きたときの忘備録です。

# モジュールのInstallが完了と出るのに、Installされていない
vagrantからssh接続を実施して、pythonの仮想環境を起動して、
必要なモジュールをInstallしようとすると

```
(scraping) vagrant@ubuntu-bionic:/home$ pip install requests
Collecting requests
  Using cached https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in ./scraping/lib/python3.7/site-packages (from requests)
Requirement already satisfied: idna<2.9,>=2.5 in ./scraping/lib/python3.7/site-packages (from requests)
　・
　・
　・
PermissionError: [Errno 13] Permission denied: '/home/scraping/lib/python3.7/site-packages/requests'
```

途中まで順調だがPermissionErrorで怒られる。
「[pip install pyopenssl で Permission denied](https://qiita.com/tony_factories/items/45be22a617942f6671f2)」を参考にオプションをつけると、確かにうまくいった。
しかし、

```
(scraping) vagrant@ubuntu-bionic:/home$ pip freeze
certifi==2019.9.11
chardet==3.0.4
idna==2.8
pkg-resources==0.0.0
urllib3==1.25.6
```
**Installしたはずの「request」がない。**

## 解決方法
**管理者権限のあるユーザーで必要な仮想環境にモジュールをInstallする。**

```
vagrant@ubuntu-bionic:/home$ sudo su #管理者権限をもつユーザに変更
root@ubuntu-bionic:/home# . scraping/bin/activate #仮想環境を起動
(scraping) root@ubuntu-bionic:/home# pip install requests
Collecting requests
  Using cached https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl
Requirement already satisfied: idna<2.9,>=2.5 in ./scraping/lib/python3.7/site-packages (from requests)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in ./scraping/lib/python3.7/site-packages (from requests)
Requirement already satisfied: certifi>=2017.4.17 in ./scraping/lib/python3.7/site-packages (from requests)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in ./scraping/lib/python3.7/site-packages (from requests)
Installing collected packages: requests
Successfully installed requests-2.22.0
(scraping) root@ubuntu-bionic:/home# pip freeze
certifi==2019.9.11
chardet==3.0.4
idna==2.8
pkg-resources==0.0.0
requests==2.22.0
urllib3==1.25.6
```
「request」がInstallされた。
その後、再度、一般ユーザで確認しても

```
(scraping) vagrant@ubuntu-bionic:/home$ pip freeze
certifi==2019.9.11
chardet==3.0.4
idna==2.8
pkg-resources==0.0.0
requests==2.22.0
urllib3==1.25.6
```
「request」がInstallされている。

## まとめ
管理者ユーザでモジュールをInstallすれば、問題なくできた。
であれば、一般ユーザ時にはオプションを付けたときに成功した分はどこにInstallされたのか。
デフォルトとしてユーザのベースバイナリディレクトリ ~/.local 下にパッケージがインストールされらるしいが、
それらしきディレクトリがみつからない。
見つけたら、また追記します。

## 参考文献
[pip install pyopenssl で Permission denied](https://qiita.com/tony_factories/items/45be22a617942f6671f2)
[Python：pip における管理者権限と user install](https://pyteyon.hatenablog.com/entry/2019/05/24/003924)