OmniAICreator/Qiita-1.07M huggingface dataset:
Amazon Linux 2にrbenvをいれる

## 手順

```
# rbenvをインストール
# 参考: https://github.com/rbenv/rbenv#basic-github-checkout
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/.bash_profile

# ruby-buildをインストール
# 参考: https://github.com/rbenv/ruby-build#readme
mkdir -p "$(rbenv root)"/plugins
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
```
Android  で Watson Assistant(旧Conversation)

gradleの設定
android studioの場合
gradel(App.module)へ下記を追加

```
implementation 'com.ibm.watson.developer_cloud:android-sdk:0.5.0'
implementation 'com.ibm.watson.developer_cloud:java-sdk:6.14.0'
```

0.5.0の方は無くても動くようです。

通信がありますので、AndroidManifest.xml へ下記を追記してください。
 \<uses-permission android:name="android.permission.INTERNET" /\>

簡単のため、同期通信でやりますので通信処理の前にNetworkOnMainThreadExceptionを
回避するため、以下の記述を追加。


```java
if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = 
        new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}
```


Watson Assistant にはv1とv2があります。
それぞれ使用するAPIが違います。まずどちらのバージョンを使用するか設定画面で確認してください。
以下v1で運用する場合の説明となります。

[API Key]
認証が少しややこしいです。
以前はusername, passwordで認証していたようですが、現在はIAMに仕様が変わりAPIキーにて認証を行います。
watsonの設定はIBM Cloudのダッシュボードから行え、対象サービス（Assistant)の設定ページでIAMキーを確認できます。
このキーを使って認証しますので、他人に使われると、あなたのアカウントに課金される可能性があります。

[EndPoint]
IAMキーとセットで使われるのが、EndPointです。
アクセスするURIなのですがAssitantの場合は複数　候補があります。
分からなくなったら、設定ページで確認できます。
サーバーがワシントンDCの場合
https://gateway-wdc.watsonplatform.net/assistant/api
となります。

[WorkSpace]
これがどこをどう探しても見つからず苦労しました。
IBMのハンズオンでは設定ページに記載があることになっていますが、現在のページにはその欄は無くなっており、確認できません。
Create a skill -> 対象のインスタンス　と進むと、Assistantの会話を構成するツールが起動します。
~~その時のブラウザ上のURIの中にWorkSpaceIDが潜んでいます。
～workspaces/　ここ　/build～　にあります。~~
<font color="DeepPink">追記: 作ったskillを選ぶ画面の各スキルの枠の右上　3点ドット -> View API Detail　で確認できました。</font>

簡単なサンプル

```java:SampleAssistant.java
private static final String WORKSPACE_ID = "";
private static final String IAM_Key = "";
private static final String URI = "";

~中略~

String sendMessage = "こんにちわ";  //ワトソンへ送信する文字列
IamOptions iamOptions = new IamOptions.Builder().apiKey(IAM_Key).build();
Assistant service = new Assistant("2018-09-20", iamOptions);
service.setEndPoint(URI);

InputData input = new InputData.Builder(sendMessage).build();

MessageOptions options = new MessageOptions.Builder(WORKSPACE_ID)
  .input(input)
  .build();

MessageResponse response = service.message(options).execute();

System.out.println(response);
```

このままでは、常にダイアログ　ルートノードでの反応となります。
セッションを継続するためには、いくつか方法があるようですが、watson からの返信で受け取った context を次のリクエストに渡すやり方が、一番簡単だと思われます。

```java
Context watsonContext = response.getContext();  //と受け取っておき
```

```java:SampleAssistant2.java
MessageOptions options;
if(watsonContext != null) {
    options = new MessageOptions.Builder(WORKSPACE_ID)
      .input(input)
      .context(watsonContext)  //次のリクエストに渡す
      .build();
}else{
    options = new MessageOptions.Builder(WORKSPACE_ID)
    .input(input)
    .build();
}
MessageResponse response = watsonAssistant.message(options).execute();
watsonContext = response.getContext();
```

IBMのwatsonで提供される各機能は各種言語向けのサンプルコードを伴った解説（英語）が用意されています。
APIリファレンスV1
https://console.bluemix.net/apidocs/assistant
APIリファレンスV2
https://cloud.ibm.com/apidocs/assistant-v2
https://www.ibm.com/cloud/watson-assistant/

IBMのチュートリアル（日本語）
https://cloud.ibm.com/docs/services/assistant?topic=assistant-getting-started#getting-started


watsonはクレジットカードの登録無しでも、一定範囲内の利用は無料です。
AIサービス利用の感じをつかむため、ちょっと触ってみてはどうでしょう。
特に、Assistantは概念的にもわかりやすく、様々なサイトへ応用可能ですのでお勧めです。
Wordpress用のモジュールもあるようですよ。
NVIDIA Docker で HW accelerated な OpenGL(GLX) を動かす(2019 年版)

# 背景

* ホストの GPU を使った OpenGL アプリを docker 経由で動かしたい(e.g. ホストが Ubuntu であるが, 動かしたい OpenGL アプリが CentOS しかサポートしていないなど)

## nvidia/opengl

5 年近く前(!)に docker + opengl をやったときとから

https://qiita.com/syoyo/items/7a04b9ac457eed67da54

世の中はいろいろ進化しました.

beta レベルですが, NVIDIA が docker イメージを用意してくれています.

https://hub.docker.com/r/nvidia/opengl

そこそこ最新のドライバ(390+)であれば, libgvnd のバージョンを使うのがよさそうです.

## 設定例


https://hub.docker.com/r/coreyhanson/glxgears-nvidia

が参考になります.

基本的には, 普段の nvidia-docker run の引数に,

```
-v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY
```

を加えればいけます.


注意点として, docker コンテナ内で root で glxgears など動かそうとすると DISPLAY エラーになりますので, 実行用のアカウントを docker コンテナに作っておく必要があります
(Dockerfile に useradd あたりを追加し適当につくる)


## CUDA と OpenGL もつかいたいよくばりな人向け

`nvidia/cudagl` があります.

https://hub.docker.com/r/nvidia/cudagl


## TODO

* tmp/.X11-unix をマッピングすることによるセキュリティはどうなのか考えてみる.
手っ取り早くReactのJSXを試してみる

Reactが今どきだって聞いたけど、JSXという特殊な記法を使わないと真価が発揮されないと聞いた。
でもJSXってコンパイルが必要なんだよね。
Node.jsは知ってるけど、WebpackとかGruntとか使ったことない。
JSXを手軽に試してみたいんだけどなあ。。。

そんなWeb開発弱者の僕らのためのメモ。

## 手順

1. CDNを使ってコードを書く
2. Node.jsをインストールする
3. Browsersyncをインストールする
4. Brousersyncを実行する

# 1. CDNを使ってコードを書く

CDN (Content Delivery Network)で提供されているライブラリを使わせてもらいましょう。

最低限のHTMLを用意します。

```index.html
<body>
    <div id="hello-example"></div>
  
    <script src="https://unpkg.com/react@15/dist/react.min.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.min.js"></script>
    <script type="text/babel" src="app.jsx"></script>
</body>
```

[React公式](https://reactjs.org/)のJSXをコピペします。

```jsx
class HelloMessage extends React.Component {
  render() {
    return (
      <div>
        Hello {this.props.name}
      </div>
    );
  }
}

ReactDOM.render(
  <HelloMessage name="Taylor" />,
  document.getElementById('hello-example')
);
```

## 2. Node.jsをインストールする

Windowsな僕らは[Node.js公式](https://nodejs.org/ja/)からインストーラーを取得して実行するだけです。
Node.jsとnpm（パッケージ管理ツール）がインストールされます。

## 3. Browsersyncをインストールする

npmでのパッケージインストールは、ディレクトリローカルにインストールする方法とグローバル環境にインストールする方法があります。
あとで消すこともできますし、とりあえずグローバルに入れてみましょう。`-g`をつければグローバル環境です。

```
npm install browser-sync -g
```

## 4. Browsersyncを実行する

```
browser-sync start --server --file "*" --watch
```

実行すると、Webサーバーが起動して`localhost:3000`がブラウザで開かれます。
ファイルを更新すると、更新がすぐにブラウザに反映されます。

## 参考
[React+JSXのコンパイル（Babel, browserify, webpack）](https://barikanblog.com/react-jsx-babel-browserify-webpack/#toc-0)
[Browsersyncを利用してお手軽ブラウザ確認環境をつくろう - メドピア開発者ブログ](https://tech.medpeer.co.jp/entry/2015/06/09/071758)
正規分布に従う3つの変数の大小関係

必要になったのでこちらの記事を投稿します．

# 問題設定
条件と解きたい問題は以下の通り．

```math
ある変数\ x_1,x_2,x_3\ が存在し，それぞれの変数は互いに独立でかつ\\
x_1 〜 N(\mu_1,\sigma_1^2) \\
x_2 〜 N(\mu_2,\sigma_2^2) \\
x_3 〜 N(\mu_3,\sigma_3^2) \\
という確率分布に従う． 

そのとき，x_1 < x_2 < x_3\ となる確率\ p\ を求めよ．
```

また，正規分布関数を $f(x|\mu,\sigma)$ ，正規分布関数の累積分布関数を$F(X \leq x|\mu,\sigma)=F(x|\mu,\sigma)~\int_{-\infty}^{x}f(x|\mu,\sigma)dx$ と定義する．


# 解法
2つの独立な正規分布に従う変数の大小関係は簡単に求めることができる．なぜならば，その2つの変数の差もまた正規分布に従うからである．一方で3つの独立な変数の場合はこのような求め方はできないので数値積分もしくはモンテカルロ法のどちらかをする必要がある．

$x_2$ がある値 $t$ を取るとき，$x_1$ が $t$ 未満，$x_2$ が $t$ より大きな値を取れば良い．

したがって，

```math
p=
\int_{-\infty}^{\infty}\int_{x_2}^{\infty}\int_{-\infty}^{x_2}
f(x_1|\mu_1,\sigma_1)f(x_2|\mu_2,\sigma_2)f(x_3|\mu_3,\sigma_3)dx_1dx_2dx_3 \\
=\int_{-\infty}^{\infty}f(x_2|\mu_2,\sigma_2)F(x_2|\mu_1,\sigma_1) \bigl( 1-F(x_2|\mu_3,\sigma_3) \bigl)dx_2
```

のような積分をすればよい．これらの積分をモンテカルロ法もしくは数値積分によって行う．

数値積分の方法と精度のオーダーは[こちらに記したとおり．](https://qiita.com/nabenabe0928/items/4045fecdaacae1f9b523)

今回の計算に関しても圧倒的に数値積分の精度が高い．ただし，少ないサンプル数の際にはMonte-Carlo法が圧倒的に高速で計算可能であるため，特に1%精度を求めていない場合はMonte-Carlo法で十分であり，それ以上の精度を必要とする場合には数値積分を行う必要がある．

```py
import time
import numpy as np
import scipy.special

def measure_time(func, mus, sgms, dx_div):
	start = time.time()
	func(mus, sgms, dx_div)
	finish = time.time()
	print("elapsed time[s]:",finish - start)

def normal_cdf(x, mu, sgm):
	idx = (x - mu) / np.sqrt(2) / sgm
	return 0.5 * (1 + scipy.special.erf(idx))

def normal_pdf(x, mu, sgm):
	c = 1.0 / np.sqrt(2 * np.pi) / sgm
	idx = - 0.5 * ((x - mu) / sgm) ** 2
	return c * np.exp(idx)

def integral(mus, sgms, dx_div):
	lower = min([mu - 3 * sgm for mu, sgm in zip(mus, sgms)])
	upper = min([mu + 3 * sgm for mu, sgm in zip(mus, sgms)])
	dx = float(1 / dx_div * (upper - lower))
	x = np.linspace(lower, upper, int(dx_div))

	F1 = normal_cdf(x, mus[0], sgms[0])
	f2 = normal_pdf(x, mus[1], sgms[1]) 	
	F3 = normal_cdf(x, mus[2], sgms[2])

	print("value:", np.sum(dx * F1 * f2 * (1 - F3)))


def monte_carlo(mus, sgms, dx_div):
	samples = [np.random.normal(loc = mu,scale = sgm,size = int(dx_div)) for mu, sgm in zip(mus, sgms)]
	print("value:",np.mean((samples[0] <= samples[1]) & (samples[1] <= samples[2])))


mus = np.array([1.1,1.2,1.3])
sgms = np.array([0.1,0.1,0.1]) 
dx_div = 1e+6

functions = [
			"integral", 
			"monte_carlo"]

for func in functions:
	print("function",func)
	measure_time(
		eval(func),
		mus, 
		sgms, 
		dx_div
		)
	print("")
```
プラグインインストール済のJenkins 構築 Docker編 その2


[プラグインインストール済のJenkins 構築 Docker編 その1](https://qiita.com/atmaru/items/3707b6f3fca7f4671498)の続きです。

##セットアップウィザードを無効にしましょう

環境変数JAVA_OPSに"-Djenkins.install.runSetupWizard=false"を設定するようにDockerfileを修正。

```dockerfile:Dockerfile
FROM jenkins:2.19.4
ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false"
```

Dockerfileからdocker imageを作成

```
# docker build -t myjenkins:3 .
```
コンテナの起動

```
# docker run -it -d --name myjenkins-3 -p 8080:8080 myjenkins:3
```
http://localhost:8080/ にアクセスしたら、セットアップウィザードを起動せず、jenkinsが使えるようになりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/b47e753b-c7cc-a8a4-d933-c303de6e7398.png)

ただし、まだPluginが空です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/952b7b29-aa43-1710-2b85-5c6118fddb67.png)

##次回予告
Plugin Installの自動化
を実施したい。
undefined method `each' forエラー　備忘録

<% post.each do |p| %>

<%= p.text %>

みたいな感じでeach文を回して要素を一つずつ表示した際に
undefined method `each' for　というエラーが発生

エラーの原因

post.eachのpostにpostオブジェクトが渡されていたこと

eachは配列の要素の数だけブロックを繰り返し実行する

すなわち、postオブジェクトの配列を渡してあげれば解決

流れ

```ruby:posts_contorller.rb
@post = Post.find(params[:id])
```
パラメーターで送られてきたpostをfindで取り出して@postへ代入

```ruby:qiita.rb
<%= render partial: 'posts/post', locals: { post: @post } %>
```
@postを部分テンプレート先でpostというローカル変数で使用

```ruby:qiita.rb
<% post.each do |p| %>
```
postをpへ代入して要素の数だけ表示

修正部分

before

```ruby:posts_contorller.rb
@post = Post.find(params[:id])
```
findメソッドは条件に合致するオブジェクトを取り出す

after

```ruby:posts_contorller.rb
 @post = Post.where(id: params[:id])
```
whereメソッドは条件に合致するオブジェクトを配列として取り出す

要するにeachには配列を渡しましょうということです

参考

[teratail](https://teratail.com/questions/22403)
[ruby リファレンス](https://ref.xaio.jp/ruby/classes/array/each)
SevTech:AgesのマルチがしたいのでAWSで鯖立てた話

#1.はじめに
このドキュメントはSevTechAgesのmodを導入したマインクラフトサーバーを立ち上げるときに参考にしたサイトと手順をまとめたものです。
何かのお役に立てればと思います。

#2.おことわり
- 個人的なメモです。
- 日本語でSevTechのマルチ鯖の立て方を説明しているページがほとんどなかったので書きました。
- よりよいサイトがあればそちらを紹介いただけると幸いです。
- Minecraftのライセンスを取得してあり、バニラ環境で自由に遊べる方向けです。
- EC2インスタンスは有料のプランを想定しています。クレカを準備してください。
- 1日4時間起動したとして月に2000円くらいの計算です。
- EC2インスタンスの状態を停止にしておけば課金は発生しない。。。はず。。。！

#3.クライアント側
サーバをいじる前にクライアント側を解決します。

- 以下のサイトからTwitchデスクトップアプリを入手 
https://www.twitch.tv/

1. アプリを立ち上げたらトップバーのModsを選択
2. Modsのタブ「すべてのModパックを参照する」を選択し「SevTech: Ages」で検索
3. SevTech: Agesをインストール 
4. 起動オプションからJVMの引数で指定されているメモリ量を貴方のPCのスペックが許す限り引き上げましょう。

```
-Xmx6144m -Xms4096m -XX:Per...
```

※最低4GBは割り当てないとゲームになりません。
 
※より詳しくは以下の動画を参照 
https://www.youtube.com/watch?v=WX2iLnYJEvY

#4.サーバ側
AWSでEC2サーバを立てます。
以下のログインまでを参照
※インスタンスタイプの選択はt3.largeが良いかと思います。sev君とってもおもいので。。。
※セキュリティグループの設定ではpingが通るように設定してください

- AWSで爆速でMinecraft Plugin鯖を建てる方法！-https://qiita.com/ReyADayer/items/551755bf22698541e30c
- AWSのEC2インスタンスping送受信設定-https://blogenist.jp/2018/06/20/4805/

ログインできたら以下のコマンドを順に打ってインストールまでする。

```
mkdir sevtech
cd sevtech
sudo yum install java-1.8.0-openjdk
wget https://media.forgecdn.net/files/2570/735/SevTech_Ages_Server_3.0.8.zip
unzip SevTech_Ages_Server_3.0.8.zip
chmod 777 Install.sh
chmod 777 ServerStart.sh
./Install.sh
```

↑のコマンドが何をやっているかコメントで説明

```
mkdir sevtech #ディレクトリをきる
cd sevtech #ディレクトリに移動
sudo yum install java-1.8.0-openjdk #javaをインストール(javaバージョンは2019年現在のもの)
wget https://media.forgecdn.net/files/2570/735/SevTech_Ages_Server_3.0.8.zip #SevTech_Ages_Serverをダウンロード
unzip SevTech_Ages_Server_3.0.8.zip #解凍
chmod 777 Install.sh #実行権限付与(777だとすべての権限が付く)
chmod 777 ServerStart.sh #実行権限付与
./Install.sh #実行(時間がかかるので終わるまで待つ)
```

インストールが完了したらおなじみのeula.txtを作成

```
vi eula.txt
```

aを押して以下をコピペしESC,ZZの順で操作すると保存できる
※わからなかったら「viコマンド」で検索

```eula.txt
eula=true
```

スタートする前にコンフィグをいじる

```
vi settings.sh
```

```settings.sh
# Don't edit these values unless you know what you are doing.
export INSTALL_JAR="forge-1.12.2-14.23.4.2707-installer.jar"
export SERVER_JAR="forge-1.12.2-14.23.4.2707-universal.jar"

# You can edit these values if you wish.
export MIN_RAM="4096M"
export MAX_RAM="6144M"
export JAVA_PARAMETERS="-XX:+UseG1GC -Dsun.rmi.dgc.server.gcInterval=2147483646 -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=32M -Dfml.readTimeout=3600"
```

sevtechサーバを起動する

```
./ServerStart.sh
```

`Stuck on unloading dimension 20`とかがコンソールに流れ始めたら大体起動できているので、twitchから起動したsevtechのクライアントを立ち上げて、自由に遊びましょう。

Have a nice game!
pyenv installでMissing the OpenSSL lib?と言われる

mojaveで3.7.2入れよ〜とポチったら`ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?`と言われるやつ。mojaveはモジャブとしか読めない。

- mojave 10.14.1
- Homebrew 2.0.2
- pyenv 1.2.9
- 入れたいpython 3.7.2

## やったこと
ログでここ見てね、と言われるので[Common build problems](https://github.com/pyenv/pyenv/wiki/Common-build-problems)を見に行く

`readline`と`xz`は既に入っていた

```
brew install readline xz
```

mojaveか10.14以上の人は入れてね、というやつを入れる

```
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```

そもそも上記`CommandLineTools`がなかったのでインストール

```
xcode-select --install
```

既に入ってるpython は消してね！というので消す

```
rm -rf ~/.pyenv/versions/2.7.5
```

Missing the OpenSSL lib?のところに書いてある解決策でチャレンジ

```
CFLAGS="-I$(brew --prefix openssl)/include" \
LDFLAGS="-L$(brew --prefix openssl)/lib" \
pyenv install -v 3.7.2
```
眠さで知能指数が下がって「がんばえ〜ぱいえんぶ〜」って気持ちでログを眺めていたが、
応援の甲斐なく同じエラーが出る。駄目じゃん！

ぐぐると他にも駄目じゃん！ってなってる人が調べていて、そのコマンドでチャレンジ
https://blufflog.hatenablog.com/entry/2018/09/25/224259

```
CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl)" pyenv install 3.7.2
```
できた！！！！ありがとう！！！おやすみ！！
【Blender】アーマチュアの設定（ボーンを入れる）

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Blender v2.79.6
⭐️Mac Book


「N」キーでプロパティを表示し、「レンダリングする物のみ」チェックOFFする。
これをしないと、ボーン（骨）が見えない。
ボーン「レントゲン」チェックONする
<img width="1162" alt="スクリーンショット 2019-02-28 22.41.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/9e3f7c98-f682-a9ca-7eb7-3ff85a84b93f.png">

アーマチュアの設定（ボーンを入れる）
完成図↓↓↓↓↓↓
<img width="667" alt="スクリーンショット 2019-03-01 0.14.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/b8aea6f1-c287-da3e-74d3-6e644d56da1a.png">


<font color="Magenta">画像が多いとQiitaの容量オーバーで画像が貼り付けられなくなるので</font>
詳細は、「はてなブログ」に記載してます↓
[かぴばらさんの覚書ブログ nonkapibara](https://nonkapibara.hatenablog.com/entry/2019/03/01/001614)




</br>
</br>
</br>
</br>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Blenderの💡UV展開💡と<br>🚩ベイク🚩を勉強したよぉ。<br>Ｏ(≧∇≦)Ｏ<a href="https://twitter.com/hashtag/Blender?src=hash&amp;ref_src=twsrc%5Etfw">#Blender</a> <a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/Unity3d?src=hash&amp;ref_src=twsrc%5Etfw">#Unity3d</a><a href="https://t.co/KdiCKQwqg8">https://t.co/KdiCKQwqg8</a> <a href="https://t.co/zYd7N86yxD">pic.twitter.com/zYd7N86yxD</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1094638132153053185?ref_src=twsrc%5Etfw">2019年2月10日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</br>
</br>
</br>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">いっぱいキャラクターを弾ませてみた😊<br>すごい事になった🙀<br>💥w(°ｏ°)w💥<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/unity3d?src=hash&amp;ref_src=twsrc%5Etfw">#unity3d</a> <a href="https://t.co/YEF4raBLe5">pic.twitter.com/YEF4raBLe5</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1094931187473080320?ref_src=twsrc%5Etfw">2019年2月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Node.jsを使って、特定のツイートをしている人をフォローする


お馴染みのtwitterモジュールを使います。

フォローのAPIの公式ドキュメントは[こちら(POST friendships/create)](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create.html)

## 使うメソッド

* `.stream('statuses/filter')`で特定ツイートを検索
* `.post('friendships/create')`でフォローします。

フォローする際はユーザーのIDかスクリーンネームを渡してあげる模様です。

フォロー関連はなかなかサンプルが見つからないですね。

> https://www.npmjs.com/package/twitter

## `筋トレ`のハッシュタグでツイートしている人をフォローするコード

```app.js
'use strict';

const twitter = require('twitter');
const client = new twitter({
    consumer_key: '', // consumer keyを記入
    consumer_secret     : '', // consumer secretを記入
    access_token_key    : '', // access tokenを記入
    access_token_secret : '' // access token secretを記入
});

// async/awaitで表現
const main = async () => {
    const stream = await client.stream('statuses/filter', {'track':'#筋トレ'});
    stream.on('data', async data => {
        console.log(data.id_str);
        try {
            await client.post('friendships/create', {user_id:data.user.id});
            console.log(`${data.user.name}さんをフォローしました。`);            
        } catch (error) {
            console.log(error);
        }

    });
}

main();
```

## 最初ミスったエラー

こんな感じで`Cannot find specified user.`というエラーメッセージがちょくちょく出てました。

```
[ { code: 108, message: 'Cannot find specified user.' } ]
```

こちらの記事を見て気づきましたが、`client.post('friendships/create', {user_id:data.id});`という形で **ユーザーのIDじゃなくてツイートのIDを指定してしまっていたのが原因だった**みたいです。

> [tweepyでツイート検索キーワードでフォローしたいがエラーで出る](https://teratail.com/questions/131412)


正しいのは、`client.post('friendships/create', {user_id:data.user.id});`という指定ですね。

## 参考

* [Twitter Streaming API + Node.js (ntwitter)で指定キーワードのツイートを取得する](https://qiita.com/n0bisuke/items/09126e6e2cd111841a2e)
* [NodeJSのtwitterモジュールで自動フォロバ](https://qiita.com/yuta0801/items/a80b1369dac7b03ac80e)
Java：Streamを使用してコレクションの中身をソートする

#はじめに
座標クラス(x, y)のコレクションを、ソートしたいという状況になりました。
簡単にやる方法が無いか調べていたところ、Streamが使えそうだったので使用してみました。

コンソールに出すまでは順調だったのですが、ソート後にコレクションへ変換する時にはまりましたので、メモとして残しておきます。

#実装
まずは、座標のクラスを作成します。

```Point.java
public class Point{
    int x;
    int y;            

    Point(int x, int y){
        this.x = x;
        this.y = y;
    } 
        
    //getter
    public int getX(){return x;}
    public int getY(){return y;}
}
```

続いて、座標クラスのコレクションをStreamを使用し、ソートします。
`sorted`メソッドでソート内容を記載し、内部では`Comparator`クラスを使用して比較しています。
xに続きyのソートを実行するため、`thenComparing`メソッドを使用しています。

`.collect(Collectors.toCollection(ArrayList::new)`
最後にコレクションに変換するのですが、ここでかなりハマりました。
単純に`toArrayList`でいけると思っていたんですけどね。

```Main.java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Stream;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args ) throws Exception {
        ArrayList<Point> node = new ArrayList<Point>();
        
        //座標をリストに追加
        node.add(new Point(4,3));
        node.add(new Point(2,2));
        node.add(new Point(1,3));
        node.add(new Point(1,1));
        node.add(new Point(2,4));
        node.add(new Point(2,1));
        node.add(new Point(5,3));

        //Sort前
        System.out.println("===Before Sort===");
        node.stream().forEach(nodes -> 
            System.out.println("node X:"+nodes.getX()+" Y:"+nodes.getY()));

        //X:昇順、Y:昇順でソートし、ArrayListに格納
        ArrayList<Point> nodeSort = node.stream()
            .sorted(Comparator.comparingInt(Point::getX)   
            .thenComparing(Comparator.comparingInt(Point::getY)))
            .collect(Collectors.toCollection(ArrayList::new));
        
        //Sort後
        System.out.println("===After Sort===");
        nodeSort.stream().forEach(nodes -> 
            System.out.println("node X:"+nodes.getX()+" Y:"+nodes.getY()));
    }
}
```

###実行結果
```
===Before Sort===
node X:4 Y:3
node X:2 Y:2
node X:1 Y:3
node X:1 Y:1
node X:2 Y:4
node X:2 Y:1
node X:5 Y:3
===After Sort===
node X:1 Y:1
node X:1 Y:3
node X:2 Y:1
node X:2 Y:2
node X:2 Y:4
node X:4 Y:3
node X:5 Y:3
```




#まとめ
今回は、クラスのコレクションをStreamを使用してソートする方法を記載しました。
他にも、条件抽出もできるようですので、Streamを使いこなせればかなり便利ですね。
Linuxコマンド備忘録

#Linuxコマンドを自分用備忘録を記述していきます

SESになって現場経験半年で覚えたコマンドをただただ自分用に書き出していきます。

##lsコマンド

```
$ ls
index.html     main.css
index.rb       main.js
dir1
```
ディレクトリの中身を一覧表示してくれる
オプション
 -l : パーミッションも一緒に表示してくれる
 -1 : 縦に一覧表示してくれる

##tailコマンド

```
$ tail ファイル名
#ファイルの最後から数行を表示してくる
num = 1
for num in 1..100 
  print num
  print " "
  puts " " if num % 10 == 0
  num += 1

```
オプション
-f : ファイルが更新されたら、その更新も出力してくれる。ログの監視に便利！


##最後に
半年でこれだけかって思うかもしれませんが、初投稿だからテストがてらあげてみました。
これからちょくちょくあげていければいいな〜と思っている今日このごろです。
開発から運用に転身して一ヶ月で感じた違い

#はじめに
業務アプリケーションの開発をやってきていたが、もっと色々できるようなれば将来食いっぱぐれることが無くなるかなと思い
この度、運用DBAにスキルチェンジした。
一ヶ月仕事をしていった中で今まで気にしていなかった部分で指摘されることが多く
開発側と運用側では見る目線が異なると強く感じた。
また異なる部分を知っていく中で開発でも活かせると思い、その違いを忘れないようにまとめた。

#引き出しの多さ
開発ではロジックを新たに生み出す(考える)作業だったが
運用では公開されている情報に対してどれだけ引き出しがあるかが重要

`と書いたが、運用開発など関係なく引き出しは多ければ多いほどいい。
ここでいう引き出しというのは自身の知識だけでなくネットや書籍、その分野に詳しい知人などから
欲しい情報を得る手段のこと。`

#マニュアル
製品マニュアルこそ正義

製品について調べたときにググって上位に出てきたブログなどの内容をそのまま鵜呑みにしてしまうのは厳禁。
記事の内容が古かったり、対象としているバージョンが異なったりと信憑性が低い。
コマンド１つ１つに対してもなぜこのオプションの設定が必要なのかを製品マニュアルを見て確認する。

`例えばjavaで文字列の処理をしたいだとかライブラリのインストール方法など
そのマニュアル(またはドキュメント)を見るとより理解が深まる。`

#作業手順の作り方
実際に作業する人が手順書を上から下までみないと何をしているか分からないような記載では不親切。
・エクセルならば1セルのなかに1コマンドだけを記載する。
・コマンドの実行結果の判断を記載する。
・どの接続先で操作しているのかのサーバ名、ユーザ名を明記する。
・繰り返し部分は省略せず実際にコマンドを打つ回数分記載する。

#フォルダ権限
リモート接続先にファイルを転送する際はフォルダ権限を確認する。
作業手順書を作成する際に権限部分で躓くことがないようにしておく。

#ログの監視
作業する時にはtailコマンドを利用して常にログを監視している。
Apacheの落とし上げなどで問題が起きた時だけログを見ていたが
それだけではダメで動作しているけど何か問題が発生している可能性もある。
それを確認すべき。

#表領域、ディスク容量の監視
「サーバ＝高スペック高容量」と思っていて何も考えずにサーバにファイル転送を行っていたが
サーバはこのぐらいのスペック・容量が必要だと考えられて構築されているので無制限に使えるほどの容量はない。
そのため、データ転送が伴う作業には必ず容量あふれが発生しないか確認・監視する。

#LV(論地ボリューム)の分け方
Linuxでは論地ボリュームを作成して物理ディスク容量を抽象化している。
バックアップファイルやログファイルなどデータが増大していく場所については
LVを別に割り当てて、物理ディスク拡張時の管理を容易にする。

`「LVってレベルのことですか？」と聞いたら全然違っていた。`
`またこういった略称でのやり取りが非常に多い。`

#X Window
リモート接続先のGUI画面をローカルPCに表示する。
生まれて初めて聞いた用語だがLinuxを扱う人には一般的らしい

#まとめ
実際に書いてみるとそんなの当たり前でしょと言われそうな事が多かったが、
今までそんなに深く考えていなかった。。

特に重要だと思うのがマニュアルを見ること！
マニュアルすべてに目を通せっていう話ではなく必要なことをその都度、マニュアルで調べたほうが理解が深まる。
`いま考えるとプラモデル作るときは必ず説明書みて順番通りに作っているのに、Apacheインストールするときには説明書(マニュアルやドキュメント)を見ないとか
やっていることがおかしいかった。`

#これから新しいことを学ぶ上で思うこと
DBAになるためにオラクルシルバーを取って基礎知識を蓄えた気になっていたが、
実際に作業をすると何やってんのかよくわからない。
`「あー試験でたなそれ」と思えるぐらいの浅い理解しかできていなかった。`
やっぱり困らないと調べることはしないし、困ったことを調べて解決していかないと深い理解ができないと強く感じた。
まずは基礎を１から１０覚えてから応用へ！！っよりはある程度やりたいことを決めて、その目的を進めていくうえで必要となった基礎を覚えていくほうがよい。
Firebase(Web)のセキュリティを10秒でさらっと確認する


①Google Web Developer Toolsでコンソールを開きます。(WindowsではF12キー、MacではCommand + Option + I)

②Firebaseを読み込みます。

```js
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://www.gstatic.com/firebasejs/5.8.4/firebase.js';
document.head.appendChild(script);
```

③Firebaseの初期設定をします。

```js
const config ={apiKey:"hogehoge",authDomain:"hoge.firebaseapp.com",databaseURL:"https://hoge.com",projectId:"hoge",storageBucket:"hoge.hoge.com",messagingSenderId:"000000000"}; 

firebase.initializeApp(config);
```

④データベースにアクセスします。

```js
firebase.database().ref().once('value', function(snapshot) {
  console.log(snapshot.val());
});
```


コンソール上で何も出力されなければOKです。


(上記の例はあくまでもさらっと確認しているだけなので、不安な人は[公式ドキュメント](https://firebase.google.com/docs/database/security/)を読んでください。)
VSCodeのMarkdown Preview EnhancedでPlantUMLが描画されない

# はじめに

いつも仕事でドキュメントを書く時に、VSCode＋Markdown Preview Enhanced(MPE)を使っている。
MPEはコードブロックで`puml`を指定すると、Markdownファイル上で直接PlantUMLの作図ができる優れものなのだが、先日導入したてのワークステーションでいつものように書いていたら**描画されない**問題が発生した。
解決したが、また忘れた頃にセットアップする時にはまりそうなので、備忘録を残しておく。

# しょうもない原因

単純に`planuml.jar`へのパスが通っていないのだろうと思って確認したら、パスは通ってた。うんうん唸りながらPC内をあさっていたら、**そもそもjavaが入ってなかった…**
javaで開発することがなかなかないので気付かなかったが、なんかのアプリに付随で入っていると思い込んでいた…何事も確認は大事ですね。
javaをインストールしてから、再度試したら無事にアクティビティ図が描画された。

>\`\`\`puml
@startuml
start
:hoge;
stop
@enduml
\`\`\`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/e2b0b2dc-c5f0-de5d-7945-1c0b1df860cf.png)

# まだダメだった

上述のトラブルでPlantUML周りは解決したと思っていたのだが、別のドキュメントを書くときにクラス図を書こうとしたらまたしても表示されなかった。

>\`\`\`puml
@startuml
class hoge
@enduml
\`\`\`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/a4e89ca7-9e80-4919-0dab-e5d017e5d4da.png)
実行ファイルが見つからないっぽい。とりあえずメッセージ通り`testdot`を入れてみた。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/6e2b60a8-971f-c22c-30b4-391cf17d19d3.png)
`GRAPHVIZ_DOT`という環境変数に実行ファイルへのパスを設定する必要があるらしい。
確かに、前に別のPCセットアップしたときにGraphviz入れた覚えがあった…
素直にGraphvizをインストーラで入れていれば、勝手に環境変数も設定されるのだろうが、職場のルールでインストーラ使って入れるのにいちいち申請がいるのが面倒で、**zip版で入れていた**のを思い出した。
`GRAPHVIZ_DOT`という名前で、`dot.exe`へのパスを入れたら無事に描画された。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/78556752-95b4-bc8c-d311-7ea974c5bdf2.png)

# 補足

ちなみに、`dot.exe`へのパスは、直接`dot.exe`へのファイルパスを設定する必要がある。一度普段のパス追加の間隔で、`dot.exe`のある`bin`ディレクトリのパスを設定したら弾かれた。よく考えたら、専用の環境変数なのだから当然だった…

# 参考

- [Graphvizダウンロードリンク](https://graphviz.gitlab.io/_pages/Downlo/Download_windows.html)
- [PlantUMLダウンロードリンク](http://plantuml.com/ja/download)(VSCodeの拡張で入れれば不要かも)
[Udemy]「これだけでOK！ AWS認定ソリューションアーキテクト – アソシエイト試験突破講座（充実の20時間完全コース）」で学んだこと

#はじめに
2019/2/25に￥1,400で購入した[Udemy](https://www.udemy.com/)の以下の講座で学んだことを記録する。
[これだけでOK！ AWS認定ソリューションアーキテクト – アソシエイト試験突破講座（充実の20時間完全コース）](https://www.udemy.com/aws-associate/)

**記録の目的は以下の通り**

1. メモを取ることで学習のモチベーションを上げる
2. 学んだこと（忘れたこと）を思い出せるようにする
3. Qiitaを使って見る
4. Markdown表記になれる
※認定試験を受ける予定はない

**記録しようと思うこと**

* 受講した講座のタイトル
* ハンズオンで行った事
* 学んだこと
* 感想


さしあたり時系列で記録をとるが、後から見やすいように編集をするかも知れない。
まずは最後までやり遂げることを目指す。

#2019/2/26
###受講した講座のタイトル
・はじめに
01. はじめに
02. AWSのアカウント登録
03. AWSでサーバーを構築してみる①
05. SSHの基礎
06. Day1対応の実施①
07. Day1対応の実施②
08. Day1対応の実施③
09. Day1対応の実施④
###ハンズオンで行った事
AWSアカウントの作成、Tera Termのインストール、お試しでのEC2インタンスの作成、AIMでのユーザー作成

###学んだこと
用語
VPC：Amazon Virtual Private Cloud
EC2：Elastic Compute Cloud
RDS：Relational Database Service
S3：Simple Storage Service

###感想
講師の挨拶ビデオが無かったので、どのような方が講師なのかが解らない。講義は不慣れなようでこなれた感じはない。モチベーションが上がらないが講義内容自体は興味があるので楽しめた。私の知識不足が原因だが、講師の言っていることや行っていることの意図が解らないことがあり、ただ指示された作業をこなしている状態になる事があった。理解が深まれば、そのような問題は解消されるものと願っている。先輩からのOJTというよりは、大衆向けeラーニングという感じ、テキストに沿って表面的な知識をなぞっている感じが否めない。

#2019/2/27
###受講した講座のタイトル
・AWSとアソシエイト試験の概要
10. AWSの仕組み
11. アソシエイト試験概要
12. AWSの全体像

###ハンズオンで行った事
なし
###学んだこと
なし
###感想
試験にほとんど興味がなかったこと、電車内での受講だったこともあり、とても退屈で半分寝ながらの受講となってしまった。

#2019/2/28
###受講した講座のタイトル
・IAM
13. IAMの概要
14. IAM設計
15. IAMグループへのポリシー適用
16. IAMグループへのポリシー適用（ハンズオン）①
17. IAMグループへのポリシー適用（ハンズオン）②
18. IAMロールへのポリシー適用
19. IAMロールへのポリシー適用（ハンズオン）

###ハンズオンで行った事
IAMを利用して、以下の3種類の役割を想定してポリシーの作成とポリシーのグループへの割り当てを行った。

想定した役割
1.管理者
2.運用担当
3.開発担当

作成したグループと割り当てたポリシー
1.Administrator
　　AdministratorAccess
2.Operation
　　Operation
　　Development
3.Development
　　Development

作成したポリシーと割り当てたサービス
1.Operation
　　cloudwatch,config,cloudtrail　　
2.Development
　　EC2,S3,RDS,ほか

続いて、EC2インスタンスへの、S3への接続を行うロール設定を行った。
まずはポリシーを作成し、そのポリシーを割り当てたロールを作成した。
そのうえで、EC2から、該当するインスタンスを選択して、ロールの割り当てを行った。

###学んだこと
WindowsのADと同様に階層構造を持ったロール設定が行える。
あらかじめ準備されているポリシーとは別に、自分でポリシーの作成が可能。
その際には、サービスの指定と、対象とするリソースの範囲など、さらに細かな指定ができる。
ユーザーだけでなく、EC2インスタンスに対しても同様の仕組みでロールの割り当てができる。

###感想
いかにもテキストに沿ったシナリオ通りの講義。考えることもほとんどなく、黙々と作業をこなす印象だった。また「本当はよくないけど、ここではとりあえず...」といった雑な説明で詳細をはしょる箇所が多い。試験対策としては応用の領域で対象ではないのかもしれないけど、実運用ではどの程度細かい設定で運用しているのかなど説明も欲しかった。また、説明をしているのか、ぶつぶつと独り言を言っているのかよくわからない。
それから、設計が重要だといっておきながら、まともな設計はせずに、ポリシーやロールを実際に作りながら「とりあえずこんな感じで作っておきましょうか」と適当な名前や設定で進めていくのも、なんだかなぁと思った。
とはいえ、講義のみに比べればハンズオンは楽しい。

#2019/4/5
###受講した講座のタイトル
・IAM
20. AWS Organizationの概要
21. AWS Organizationの設定（ハンズオン）
22. IAMのまとめ
小テスト2: IAMテスト
EC2
23. EC2の概要
24. EC2でWEBサーバーを立ち上げる(ハンズオン)
25. Elastic IPの設定(ハンズオン)
26. Bashコマンドによる設定
27. EBSの概要
28. AMIとSnapshotの活用(ハンズオン)①
29. AMIとSnapshotの活用(ハンズオン)②
30. EC2のまとめ
小テスト3: EC2テスト

###ハンズオンで行った事
AWS Organizationで以下を作成
・テスト用のユーザ
・組織
・OU（development_group）
・development_group用のポリシー

テスト用ユーザーをdevelopment_groupに割り当て（移動）た
development_groupに、development_group用のポリシーをアタッチした

###学んだこと
AWS OrganizationのAWSアカウントを統括して管理する
管理者ルート（マスターアカウント）の元、
OUに対してメンバーカウントや、ポリシーのアタッチが行える
マスタ支払いの一括
###感想
相変わらずハンズオンは楽しい。小テストで理解が深まる。
さっそくインスタンスを起動したまま数日放置してしまった。
インスタンスを起動したら、停止するまでハンズオンに含めてほしい...

#2019/2/xx
###受講した講座のタイトル
###ハンズオンで行った事
###学んだこと
```python
```
###感想
あるブックの任意の範囲を別のブックの指定した箇所にコピペする　その3

今回は、前回配列や繰り返し構文などを使用して改修したマクロ
『同じフォルダ内にある「○○一覧.xlsx」の任意のシート内容をそれぞれ別のファイルに転記する』
をセルを参照して動くものに改修しました。

下図のようにセルB1以降に転記したいシートの名前を記入していきます。
「転記テスト2」ボタンに「tenki2」マクロが登録されています。
<img src=https://qiita-image-store.s3.amazonaws.com/0/265756/b33cc389-1b28-f5d3-753b-93d56bb21c24.png width=50%>

```VB
Sub tenki2()

'転記用のブック＆シート名の記入範囲をコピーする　
    Cells(1, 1).Activate
    ActiveSheet.UsedRange.Copy
    
'○○一覧を開いて転記用シートを挿入し、セルA1に貼り付けする
    Workbooks.Open ThisWorkbook.Path & "\◯◯一覧.xlsx"
    Worksheets.Add Before:=Sheets(1)
    ActiveSheet.Name = "転記用"
    Cells(1, 1).Activate
    ActiveSheet.Paste
    
'変数の宣言
    Dim i As Long
    Dim maxSheetCount As Long
    Dim sheetName As String
    
'参照するセルの一番右の位置を確認する
    maxSheetCount = Cells(1, Columns.Count).End(xlToLeft).Column
    
'転記用シートからシート名の入っているセルを指定する
    For i = 2 To maxSheetCount
        Worksheets("転記用").Activate
        sheetName = Cells(1, i)
          
'シート内容を転記する
        Worksheets("転記用").Activate
        Worksheets(sheetName).Activate
        Cells(1, 1).Activate
        Worksheets(sheetName).UsedRange.Copy
        Workbooks.Open ThisWorkbook.Path & "\" & sheetName & "YYMMDD.xlsx"
        Worksheets("データ").Range("A1").Select
        ActiveSheet.Paste
        Range("A1").Select
        ActiveWorkbook.Save
        ActiveWindow.Close
   Next i
    
'○○一覧を保存せずに閉じる
    Application.DisplayAlerts = False
    ActiveWindow.Close
    Application.DisplayAlerts = True
End Sub
```
セルの値を参照させるのにわざわざ新しいシートを作成してコピペしたのは遠回りな気もしますが・・・。
他の案はことごとくエラーになってしまいました。
でも、なんとか参照したいシートの数や名前が変わっても対応できる感じになってきました！
次回はメッセージボックスを使ってみたいと思います。
お前の腰をハックしろ！

## たまには役に立つポエムを書きたい

何かネタあるかなーと考えてみたらありました、**病気ネタ**。

## 君は腰痛を感じたことがあるか

イマドキのエンジニアは椅子の持ち込みやスタンディングデスクがあったりするそうですが、年を重ねたそれなりSIerではそんな自由はありません。
(全てのSIerがそうとは言いませんが、SIerのみなさまで「わかる」と言っていただける方は相当数いると思ってます)
いつ買ったのかわからない、座れれば良いでしょ？的な椅子を支給され、高さのあっていない机に座らされ、長時間労働させられる…社畜ここに極まれり。

そんな中、エンジニアを襲う病はいくらでもあります。
姿勢が自由でないことからくる肩こりや腰痛、画面を見続けることによるドライアイ、仕様変更や無茶振りによる精神的摩耗、数え上げたらキリがありません。

そんな中、今回フォーカスするのは腰痛。
この記事を読んでしまったからには明日から無料で対策を行い、必要であれば有料で対策を行いましょう。

## 無料で対策

- 1〜2時間に1回立ち上がる

いきなり無茶な！と思われるかもしれませんが、これが一番簡単な方法です。
腰痛で医療機関に行くと、医師が口を揃えて言う言葉です。
立ち上がって軽く後ろに反らせればベター、そのまま体を左右にひねることができればベストです。
「私は頻尿なんです！」と1時間に1回トイレに行っても良いかもしれません。

- 腹筋を鍛える

腰を支えているのは腹筋、であればそこを鍛えれば対策になります。
腹筋を鍛える際は、上体を膝につけるまで上げるのではなく、寝転がって状態を5センチほど浮かせたままキープするようにするのが今の常識です。
Youtubeで腹筋で検索をかけると良いと思います。

## 有料で対策

- 椅子と体の間を埋めるものを使う

ヨドバシやハンズに行くと置いてありますよね、**腰痛対策用の体を支える or 姿勢を正す座布団的なやつ**。
あれを使いましょう。
私は[backjoy](http://backjoy-jp.com)のPosture+を使用しております。

こんなので本当に効果あるのか？と思われるかもしれませんが、なかなか効果があります。
コスト的観点で言えば、3日に1回、昼休みを潰しつつ500円ほどかけて行っていた整骨院での牽引が不要となりました。
1回買えば、100kg超の私ですら数年にわたって使うことが可能なので、コスパは非常に高いです。
電源不要で通信もしないので、多くの現場の持ち込み禁止物に該当せず、「健康管理のためだ」とそれなりの理由をブチあげることも出来ます。

- 手術する

最終手段ですが、最も効果があります。
腰痛は最悪椎間板ヘルニアへと進化します。
少し前までは椎間板ヘルニアは腰の大規模切開が必要な大手術でしたが、今ではPELD(ペルド)という2〜3センチ程度の穴を開け、内視鏡で取り出すという小規模な手術があります。
入院も手術を含めて3日程度と非常に軽いものです。
ただし、その後3週間程度は自宅安静が必要になるので、計画的に実施する場合は業務を調整しましょう。
私の場合は「腰痛だろうが病院だろうが休日出社しろ」と言い放つ職場にイラついてたので、ゲリラ的に実行しました。

## ならないことが一番

腰痛はなってからでは遅いです。
本記事が必要にならないならそれに越したことはありません。
【Rspec】ややこしいletの挙動についてまとめてみる。

##letに対する疑問点

前提知識として、
**・letは呼び出される度に遅延評価される**
という挙動がある。

ということは、呼び出される度に作成されてしまうのか？
つまり、**「同じletだとしても3回呼び出されたら3つとも違うオブジェクトが作られてしまうのか？」**
という疑問や、
**「違うexample同士でも, 一度作られてしまったオブジェクトは共有されてしまうのか？」**
**「同じモデルを複数作ることは可能なのか？」**

といった疑問があったため、実際に試してみました。

##いきなり結論
結論から言うと、
**・ 同じexample内なら同じオブジェクトを返します**
つまり、exampleを通過する度に、前回のオブジェクトはキャッシュされるということ。
と、言葉で言ってもわかりづらいので、実際に動かしながら説明していきますね。

まず、そもそもletって何？って方は伊藤さんの記事を参考にしてほしいです。めちゃくちゃわかりやすいので。
https://qiita.com/jnchito/items/42193d066bd61c740612

##一般的なletの使い方

```
letは使う度に呼び出される.
```

頭の悪い僕は、同じ`example内(it 〜 end)` でも`let`が呼び出されるたびに違うオブジェクトが作られてしまうと解釈していた。
例えば以下の例で言えば、

```rb
RSpec.describe User, type: :model do

  let(:user) { create(:user) }
  
  it "名前が一致する" do
    expect(user.name).to eq user.name
  end
end

# 1 example, 0 failures
# User.count => 1
```

順序としては以下のようになる。
⭕️
1. expectの次に、`user`が作られる
2. 最初に呼び出された`user`同士で名前が一致するか確かめる


しかし僕は、以下のように勘違いしていた。
❌
1. expectの次に`user`が作られる
2. `eq`の次に、二つ目の`user`が作られる
3. 最初に呼び出された`user`と2回目に呼び出された`user`の名前を比較している

同じexample内で二回使っているが、**何度呼び出されようが一度letから呼び出されたものは同じオブジェクトとして使いまわすことができる**らしい。
すなわち、`User.count`は2ではなく、1になる。

つまり、以下のように何回呼んでも同じオブジェクトが呼ばれる。

```rb

RSpec.describe User, type: :model do

  let(:user) { create(:user) }

  it "名前が一致する" do
    user
    user
    user
    expect(user.name).to eq user.name
  end
end

# 1 example, 0 failures
# User.count => 1
```
もし確かめたい方は、`binding.pry`を挟んで確かめてみましょう。

```rb

it "名前が一致する" do
  user
  binding.pry
  expect(user.name).to eq user.name
end
```
userを何度呼んでも、同じexample内であれば`User.count`は変わらないはずです。

## 同じモデルを違う変数名でletを呼び出す
変数名さえ違えば、同じモデルを複数作れるのかな？と思い、実験。

```rb
RSpec.describe User, type: :model do

  let(:user) { create(:user, name: "taro") }
  let(:user_2) { create(:user, name: "hanako") }

  it "名前が一致する" do
    expect(user.name).to_not eq user_2.name
  end
end

# => 1 example, 0 failures
# User.count => 2
```
テストは無事通りました。
流れとしては以下の感じです。
1. `expect`で、一つ目のUser(nameがtaro)が作られる.
2. `eq`の次に、二つ目のUser(nameがhanako)が作られる.

このように、**別々のオブジェクトとして作られます。**

もしユニークなカラムがあってバリデーションに引っかかってしまうと

```
ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry 
```
のようにエラーが発生してしまうので、意味のある変数名、意味のある値とするようにしましょう。
例) 
`let(adult_user) { creaet(:user, age: 20) }`
`let(child_user) { creaet(:user, age: 10) }`

#違うexampleから呼び出した場合

違うexampleから呼び出されたオブジェクトは別々のオブジェクトとして呼び出されるのか実験。

```rb
RSpec.describe User, type: :model do

  let(:user) { create(:user) }
  
  it "名前が一致する" do
    expect(User.count).to eq 1
    # User.count => 1
  end
  
  it "名前が一致する" do
    expect(User.count).to eq 2
    # User.count => 1
  end
end
# # => 2 examples, 1 failure
```

```rb

Failure/Error: expect(User.count).to eq 2
     expected: 2
     got: 1
```
二つ目のexampleで落ちてしまう結果に。
処理の流れ
**1. 一つ目のexampleでUserが作られる**
**2. 2つ目のexampleでは、一つ目のexampleで作られたUserは消され、クリーンな状態で新しくUserが作られる**

ここで言う、**一つ目のexampleで呼び出されたオブジェクトと、二つ目のexampleで呼び出されたオブジェクトは全く別物**だということがわかりました。

つまり、`example`が走るたびに、前回作られたオブジェクトはキャッシュされずに削除されるというわけです。


##まとめ

**・同じexample内で作られたオブジェクトはキャッシュされて残る**
**・変数を変えれば, 一つのexample内で同じモデルを呼ぶことができる**
**・exampleで作られたオブジェクトは2回目以降キャッシュされずに削除される**

基本的にこの3点を押さえておけばある程度大丈夫だと思いますが、まだまだ初心者を悩ませる部分が多いと思うので随時更新していきます！
Git コミットの GPG 署名を既定で有効にする。

## git リポジトリにコミットするとき、署名を自動的に施す

```bash
git config commit.gpgsign true
```

## すべてのリポジトリで、コミットするとき、署名を自動的に施す

```bash
git config --global commit.gpgsign true
```

## 嬉しいこと

## 注意

利用する Git クライアントによっては有効に動作しない場合あり。おもに、 git クライアント自体に git プログラムが組み込まれている時。

例:
~~- gitkraken~~ (version 5 から GPG Sign に対応）
(……他は知らないので提案ください)
[Flutter/Android] Kotlin と C++/C をデバッグする方法

Flutter でも Kotlin や C++/C 書くことはもちろんありますが、そのデバッグ方法が分かりにくかったのでメモ。

結論を言うと、**[Using OEM debuggers](https://flutter.dev/docs/testing/oem-debuggers)** に書いてある。
なんかうまく検索でこの記事にたどり着けなくて時間を浪費してしまった。

## 手順
iOS/Swift/C は簡単にできますが、Android/Kotlin/C はこんな感じ。

### 1. アプリを起動する
VSCode や Android Studio から起動する

### 2. android ディレクトリのみを Android Studio で開く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/159680/7e1d7ba1-a038-93ff-0e39-80ced0855083.png)

### 3. デバッガをアタッチする
アプリが起動して画面が表示されたのを確認したら、アタッチする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/159680/3614565e-f9dd-b747-7966-acab28fdd5c9.png)
Auto のまま、対象のデバイス & アプリ を指定する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/159680/4c4fdceb-20de-5393-1001-74edff26dc8f.png)

### 4. いえーい！
C++/C のコードにブレークポイントを打つと、ちゃんと止まってくれる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/159680/5251935f-50dc-6330-4131-8e527bdfb10c.png)
1人目の情シスとして入ったときにまずやるべきこと

一気にざざっと書いたので日を置いてもう少し整理していきます。

# この記事について
過去に2社のベンチャー企業にて情シス部門を立ち上げ、責任者として推進してきたノウハウをもとに、最初にやるべきことを書いていきます。

※あくまで私の経験＋私の友人の経験という狭い範囲の経験をもとにしています。
もっといいやり方があるなら教えてください

# 対象
情シス1人目として入社した社員
上記社員の上司

※
情シスの分野は一般的に戦略、開発、インフラ、セキュリティ、ヘルプデスクなどと分かれてきますが、
この記事では全分野を担当する形で書いていきます。

# １．業務範囲を定義する
最初はなんといっても情シスという業務の定義をしましょう。
情報システム担当、社内SE、コーポレートエンジニアリングなど呼び方は様々ですが、
企業や人によって業務イメージが異なります。
よって最初はここからやっていきましょう。

ここで1つポイント。
きっちり細かく定義する必要はありません。上場を目指す段階になったら業務分掌などの規定をつくることになるので、
ここでは会社と業務範囲の共通認識をもつ、ということが大切です。

# ２．IT統制のロードマップを策定する
情シス1人目が入ったタイミングというのは、まず間違いなくIT統制が取れていません。
逆にすでにできているのであれば、すごい企業です。
攻めのITをやる前に、守りのIT=IT統制が必要なのでまずはここからやっていきましょう。

ロードマップ、スケジュールなどなど言い方はなんでもよいです。
現状を確認し、1年後にどうあるべきか、そしてそのために実行していくことを作ります。

正直、このフェーズはつまらないです。

ちなみにIT統制＝社内のIT資産をコントロールするという意味合いで使っていきます。
いわゆるOSやSaaSなどのアカウント、PCやスマホなどのIT機器、ソフトウェアなどのライセンスなどを
コントロールできるようにするということ。

現状を確認しながら、統制がとれていないのであればロードマップに組み込んでいきましょう。
例としてはこのようなことです。
* PCのOSアカウントがローカルアカウントで運用されている　→　OSアカウントの統制を行いましょう
* 社内でどのようなSaaSを使っているかわからない　→　社内で使用してるSaaSとそのコストを可視化していきましょう
* PCが何台あって、誰がどのPCをつかっているかわからない　→　PC端末の統制を行いましょう

# ３．セキュリティのロードマップを策定する
IT統制同様に現状を確認し、ロードマップを作っていきます。

* セキュリティポリシーや実運用レベルのガイドラインはありますか？
* 実態との乖離はありますか？
* 今後、ISMSやPマーク、PCI-DSSなどのセキュリティ認証を取得する計画はありますか？

セキュリティに関する経営層の意識は業界や企業毎に大きく変わってきます。
ここではいったん会社がどう考えているかも聞いておきましょう。

またリスクアセスメントをロードマップの最初の方に入れておくと良いです。
リスクアセスメントとは、企業のどこにリスクがあるかを可視化することです。
リスクを可視化すると経営層も認識していなかったリスクが見えてくるのであなたの株は爆上がりです。

ちなみにこれをやらないと場当たり的なセキュリティ投資になり、全体最適なセキュリティ投資が難しくなっちゃいます。

# ４．既存の運用業務をロードマップに追加する
もし、他の部門の社員が行っていた運用業務を情シスでやると定義したのであれば、
その業務の引き継ぎ計画についてロードマップに追加します。

個人的な見解ですが、この運用業務を引き受けるとそれだけで手一杯になり、今までロードマップに入れてきた業務が
中々進まなくなる可能性があります。

最終的には情シスで引き受けることにしても、しばらくの間は今までどおり他の部門の社員の方にやってもらったほうが良いです。

# ４．その他、個別に必要なものをロードマップに追加する
もし移転が計画されているのであれば、移転をロードマップに入れたり、ネットワークが遅いというのであれば、ネットワーク改善を入れたりと必要なものを入れていきます。


# ５．上司と合意を取って実行する
出来上がった1年のロードマップについて上司と合意を取っていきます。
1人体制で1年後、どこまでできるか（やるか）、について話し合い、必要であれば2人目がほしいことも提案しましょう。

合意が取れたら実行するのみです。

# ６．四半期ごとにロードマップを見直す
ロードマップはあくまで予定です。割り込みのプロジェクトも入ってくるでしょう。
四半期などのタイミングでロードマップを見直し、また上司を話し合いましょう。

# ７．いちばん大切なこと
いろいろと書いてきましたが、いちばん大切なことがあります。
それは現場の社員と仲良くなることです。

私がオススメする方法は、入社したあと1～2ヶ月ぐらいかけて全部門の人とランチに行くことです。
（夜だと色々と問題になるご時世なのでランチが無難ですよ～！）
ランチに行き、色んな部門の人の顔を覚え、どんな仕事をしているのか、どんなことに困ってるのか話を聞きましょう。
そのあとも何かあれば挨拶をし、雑談し、仲良くなっていくとよいです。

ものすごく泥臭いけど、これがいちばん大切だと思っています。
railsでIndex name 'xxxxxxxxxxxxxxxxxxx' on table 'テーブル名' is too long; the limit is 64 characters

# 経緯
railsのmigrationで
`Index name 'xxxxxxxxxxxxxxxxxxx' on table 'テーブル名' is too long; the limit is 64 characters`と怒られる
テーブル名、カラム名などなどが長くなり、自動付与されるインデックス名が長くなりすぎることが原因

# 対応
`t.references :my_field, index: { name: 'my_index_name' }`
でindex名を指定してやればOK!

add_indexでindexを別で設定する場合は以下の記事を参考
https://qiita.com/ezawa800/items/9a63a96fb36a7c1de04d

### 参考
http://stackoverflow.com/questions/28727240/migrations-t-references-doesnt-allow-index-name-to-be-specified
Railsチュートリアルに再挑戦する

前に挫折してしまったRailsチュートリアルに再挑戦してみようと思います。

過度に完璧主義にならずに、適度にサボりながら周回を重ねていこうと思います。

testは後回しにしたり、課題を後回しにしたり、後回しでもいいと言われたところは後回しにしたり。

まずは一周して全体を掴んでいこうと思います。

1周目はCloud9で、2周目以降はローカル開発に挑戦していきたいですね。
HerokuでWebダイノのみのログを出力する方法

今回はHerokuでWebダイノのみのログを出力する方法を紹介します。

## HerokuでWebダイノのみのログを出力する方法

```bash
heroku logs --tail --dyno=web
```
このように、--dyno=webというオプションをつけることで実現できます。
また、--tailは便利なのでいつもつけています。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
C#終了時処理覚書

終了時の処理記述に詰まったので覚書

# Appのロード時に処理
FormにLoadのイベントハンドラを追加

        private void Form1_Load(object sender, EventArgs e)
        {
          ///ここに開始時処理を記述///  
        }

# Appの終了時に処理
FormにFormClosingのイベントハンドラを追加

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
           ///ここに終了時処理を記述///
        }

#　使用例
Formの開始時にtimelog.txtを探し、あれば追記、無ければ作成し、現在時刻を書き込む。終了時にも現在時刻を書き込み、改行する。

```timelog.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;

namespace hoge
{
    public partial class Form1 : Form
    {       
        //Form開始時の処理
        private void Form1_Load(object sender, EventArgs e)
        {
            //開始時に現在時刻の記録
            DateTime localTime = DateTime.Now;
            File.AppendAllText(@"timelog.txt", localTime+" ", Encoding.UTF8);            
        }

        //Form終了時の処理
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //終了時に現在時刻の記録
            DateTime localTime = DateTime.Now;
            File.AppendAllText(@"timelog.txt", localTime + Environment.NewLine, Encoding.UTF8);
        }
    }
}

```

```timelog.txt

2019/02/28 23:25:55///開始時 2019/02/28 23:25:58///終了時
2019/02/28 23:45:13 2019/02/28 23:45:19
```
はみ出たtableを横スクロールで滑らかに表示するCSS

#たったの4行だけ
`<table></table>`に下記CSSを当てるだけ。

```css:
table {
  display: block;
  overflow-x: scroll;
  white-space: nowrap;
  -webkit-overflow-scrolling: touch;
}
```
2行目： 隠れた部分をx方向（=横）にスクロールして表示する
3行目： 自動で改行しない（←必要であれば）
4行目： スマホで滑らかにスクールする

#ただ、セルの幅が効かない
`<table></table>`に上記CSSを一括で当てると、予期せぬレイアウト崩れが起きる。
スクロールが必要ないテーブルの場合、セルは中身の幅にフィットした横幅までしか広がらないので、右側に空白が生まれてしまう・・・

#解決策その１：tableをdivで囲む
スクロールが必要なテーブルだけに、CSSが当たるようにする。

```css:
.scroll-table table {
  display: block;
  overflow-x: scroll;
  white-space: nowrap;
  -webkit-overflow-scrolling: touch;
}
```

#解決策その２：tbodyをテーブル要素とする
table下のtbodyを`display:table;`でtable要素にすることで、幅を指定することができる。

```css:
table {
  display: block;
  overflow-x: scroll;
  white-space: nowrap;
  -webkit-overflow-scrolling: touch;
}
table tbody {
  width: 100%;
  display:table;
}
```
WebpackのwatchがNFS上で非常に遅い問題を回避する

## 取り扱う問題

NFS上に開発リポジトリがあり、それをwebpackの実行ホストと異なるホスト（DeveloperHost）からファイルを編集する際、webpackがファイルの**変更を検知するのに数秒～数十秒掛かる**という問題があった。
この問題を解決したので色々書き残しておく。

![webpack-nfs.png](https://qiita-image-store.s3.amazonaws.com/0/109606/df355637-e8da-daaa-dc24-514a79fedf13.png)


## TL;DR
- [webpack](https://github.com/webpack/webpack)は[watchpack](https://github.com/webpack/watchpack)を使ってファイルの変更を監視している
- NFSの場合はwatchpackのオプションをpollingにしないとファイル変更を検知できない
- pollingの内部は`fs.stat()`を使ってファイル属性を定期的に取得して差分を見ている
- NFSではファイル属性がデフォルトで3秒～60秒キャッシュされるので、mount時のオプションで調整する
- ※webpackとファイル変更が同じホスト上で行われている場合、ファイル属性はすぐに更新されるので問題ない

## Node.jsの監視システム
Node.jsでファイル監視システムには`fs.watch()`と`fs.watchFile()`の2つがある。`fs.watch()`はOSに近い機能を用いて監視しており、`fs.watchFile()`は`fs.stat()`を定期的に呼び出してファイルの属性値を監視している。

`watchFile()`は現在では非推奨とされているが、NFSの場合は`watch()`で用いられるネイティブな機能（Linuxの場合はinotify）が使えないため、原始的にファイルの属性値をポーリングする`watchFile()`が用いられる。なぜ使えないかと言うと、例えばLinuxの場合のinotifyはVFS層で実装されており、別のマシンで実行されたファイルシステムの操作を認識できないためである。
これに関しては「[Node.js の fs.watch() と fs.watchFile() の違い - てっく煮ブログ](http://tech.nitoyon.com/ja/blog/2013/10/02/node-watch-impl/)」でも解説されている。

[watchpack v1.6](https://github.com/webpack/watchpack/tree/v1.6.0)では内部的に[chokidar](https://github.com/paulmillr/chokidar)というNode.jsのファイル監視ラッパーを使用しており、このchokidarはオプションがpollingの場合、Node.jsの`fs.watchFile()`をinterval毎に呼び出している。（[ソースコードはここ](https://github.com/paulmillr/chokidar/blob/2.1.2/lib/nodefs-handler.js#L174)）
watchpackのv2.0.0-beta.2ではchokidarを用いずwatchpack側で独自に実装しているが、実際にはchokidarと同じく[`fs.watchFile()`でpollingしているだけである](https://github.com/webpack/watchpack/blob/v2.0.0-beta.2/lib/DirectoryWatcher.js#L83)。

## NFSのマウントオプション
NFSの場合、ファイル属性はLinuxカーネル側でデフォルトで3秒～60秒ほどキャッシュされている。[linux/nfs_fs.h at v4.20 · torvalds/linux · GitHub](https://github.com/torvalds/linux/blob/v4.20/include/uapi/linux/nfs_fs.h#L24-L25)にもある通り、NFS_DEF_ACREGMINに3秒、NFS_DEF_ACREGMAXに60秒が設定されている。
これは[NFSのマウントオプション](https://linuxjm.osdn.jp/html/util-linux/man5/nfs.5.html)で指定できるacregminやacregmaxと同じであるため、mount時に`mount -o acregmin=3,acregmax=20`のように指定してやればいい。

>acregmin=n
一般のファイル (regular file) の属性 (attribute) がキャッシュされる 最小の時間を秒単位で指定する。 この時間内では、サーバーへの新たな情報の問い合わせは行われない。 デフォルトは 3 秒。

>acregmax=n
一般のファイルの属性がキャッシュされる最大の時間を秒単位で指定する。 この時間を越えると、必ずサーバーへ新たな情報の問い合わせが行われる。 デフォルトは 60 秒。

### acregminとacregmaxの適正値
これらの値を0にするのは、NFSやマシン上のCPU・ネットワーク負荷が急増し、マシンの動作を非常に遅くしてしまう。自分の場合はacregmin=3,acregmax=3とした所、負荷的にも監視の速度的にも満足のいく性能になった。
ちなみにディレクトリ属性のキャッシュ時間を決めるacdirmin・acdirmaxなどもあるが、自分はいまのところデフォルト値で問題なく動いている。（プロジェクトによってはこちらも調整する必要があるかも知れない。）
モンテカルロ法で円の面積を近似的に計算してみる

#やること
[モンテカルロ法](http://e-words.jp/w/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%AB%E3%83%AB%E3%83%AD%E6%B3%95.html)を利用することによって円の面積の近似解を得ることを目的とします。また、乱数の数が多いときと少ないときとで近似解の精度に違いが出るかを検証します。

#どうやるか
実験にはpython3とMatplotlibを用いて計算します。円の半径は5とするため面積は5×5×3.14=78.5になり、この値に近いほど精度が高いといえます。例えば、座標平面上で(x,y)=(5,5)を中心とする円があるとき、0から10までの乱数を100個用意すると近似解の値はおおよそ78.0となります。

```py:
import matplotlib.pyplot as plt
import pylab
import random

x = []
y = []
random_number = 100 #乱数の個数を指定
for i in range(random_number): #座標をランダムに指定
    x.append(random.uniform(0, 10)) #x軸
    y.append(random.uniform(0, 10)) #y軸

area = 0
for i in range(random_number): #乱数が円の内側にあるかを判断
    if x[i]**2 + y[i]**2 <= 10**2: #三平方の定理
        area += 1
area = area/((i+1)/100.0) #すべての乱数のうち円の中にある乱数の割合

print('疑似乱数による円の面積は' + area)
print('計算による円の面積は' + 5*5*3.14)

#グラフを作成
pylab.figure('Area of a circle')
pylab.title('Area of a circle')
pylab.xlabel('X axis')
pylab.ylabel('Y axis')

#円の作成
t = pylab.arange(1000.)/1000 #0.1刻みで配列をつくる
x_en = 5*pylab.sin(2*pylab.pi*2*t)
y_en = 5*pylab.cos(2*pylab.pi*2*t)
pylab.plot(x_en+5, y_en+5, 'b') #円の線を青色に指定

pylab.plot(x, y, 'o', color="#ffa500")#乱数をオレンジ色に指定
pylab.show()

```
#結果と検証
始めに乱数を100個用意して実験すると、近似解は79.0となりました。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3134313635382f35333039346635622d333566362d326366372d636461632d6336313234663065646366352e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/243199/c5d60002-a073-6534-3984-dda739d3e6a0.png)


次に、乱数を10000個用意すると近似解は78.77となりました。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3134313635382f38316233373635342d626334312d313461622d643839342d3563366137656564333331312e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/243199/daf21891-6243-0781-7d66-cfcb12c6babd.png)



これだけでも近似解の精度が上がっていることが分かりますが、精度の向上を裏付けるため検証を施してみようと思います。検証では100個から4100個までの乱数を順次用意していくため、近似解を求める試行回数は4001回となります。

```py:
import pylab
import random

pseudo = []
simulation = 4000 #疑似乱数によって面積の近似解を求める試行回数
simulation = simulation + 101
for i in range(100, simulation):
    x = []
    y = []
    for j in range(i): #座標をランダムに指定
        x.append(random.uniform(0, 10))
        y.append(random.uniform(0, 10))

    area = 0
    for j in range(i): #乱数が円の内側にあるかを判断
        if x[j] ** 2 + y[j] ** 2 <= 10 ** 2: #三平方の定理
            area += 1
    area = area / ((i + 1) / 100.0) #すべての乱数のうち円の中にある乱数の割合
    pseudo.append(area)

#グラフの作成
pylab.figure('authenticity')
pylab.title('authenticity')
pylab.xlabel('times')
pylab.ylabel('Area of a circle')
pylab.plot(range(0, simulation-100), pseudo)
pylab.show()
```

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3134313635382f65393865653434302d616664372d343139662d633031632d6534356664323064353038642e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/243199/44dcc669-d67b-8651-093e-928cea3fcd59.png)

作成したグラフをみると、試行回数を重ねるごとに近似解のばらつきが抑えられていき、だいたい78あたりに収束していることが分かります。