OmniAICreator/Qiita-1.07M huggingface dataset:
やっと「依存性の逆転(Dependency Inversion)」がわかった

[依存性逆転の原則 - Wikipedia](https://ja.wikipedia.org/wiki/%E4%BE%9D%E5%AD%98%E6%80%A7%E9%80%86%E8%BB%A2%E3%81%AE%E5%8E%9F%E5%89%87)

> オブジェクト指向設計において、依存性逆転の原則、または依存関係逆転の原則[1]（dependency inversion principle)　とはソフトウエアモジュールを疎結合に保つための特定の形式を指す用語。この原則に従うとソフトウェアの振る舞いを定義する上位レベルのモジュールから下位レベルモジュールへの従来の依存関係は逆転し、結果として下位レベルモジュールの実装の詳細から上位レベルモジュールを独立に保つことができるようになる。この原則で述べられていることは以下の２つである:[2]
> A. 上位レベルのモジュールは下位レベルのモジュールに依存すべきではない。両方とも抽象（abstractions)に依存すべきである。
> B. 抽象は詳細に依存してはならない。詳細が抽象に依存すべきである。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332028/59920a20-c759-97b2-b96c-71d15e4290f7.png)


正直こういうのを見てもいまいちわかってなかった。

しかし、ようやく理解した。

---

## だめな例

```php:/src/Domain/User/UserRepository.php
<?php
namespace App\Domain\User;

use App\Infrastructure\DBConnection;

class UserRepository {
  public function __construct(DBConnection $conn) {
    $this->conn = $conn;
  }
  public function save(User $user): void {
    $this->conn->table('users')->save($user->toArray());
  }
}
```

```php:/src/Infrastructure/DBConnection.php
<?php
namespace App\Infrastructure;

class DBConnection {
  /* ... */
}
```

この作り方だと、 `UserRepository` がいるパッケージ `App\Domain\User` は、 `App\Infrastructure` パッケージを知っている(=`use` する)必要がある。

しかし、 `UserRepository` が担う責務は「`User` に関する状態を永続化したり取得したりすること」だとすれば、 `App\Infrastructure` パッケージは知る必要がない。つまり、具体的にどうやって永続化するかを知る必要がない。 `UserRepository` = **ビジネスロジックはその状態がDBに保存されようがメモリに保存されようが関係ない** のである。

だから、ここで「依存性の逆転」を利用する。

## 良い例

```php:/src/Domain/User/IUserRepository.php
<?php
namespace App\Domain\User;

interface IUserRepository {
  public function save(User $user): void;
}
```

```php:/src/Infrastructure/Domain/User/DBUserRepository.php
<?php
namespace App\Infrastructure\Domain\User;

use App\Domain\IUserRepository;

class DBConnection {
  /* ... */
}

class DBUserRepository implements IUserRepository {
  public function __construct(DBConnection $conn) {
    $this->conn = $conn;
  }
  public function save(User $user): void {
    $this->conn->table('users')->save($user->toArray());
  }
}
```

これで `App\Domain` パッケージは `App\Infrastructure` パッケージを知る必要がなくなった。

代わりに、 `App\Infrastructure` パッケージが `App\Domain` パッケージを知り、そのパッケージが必要な実装(例えば `DBUserRepository`)を行う。

このように依存性(use)の逆転を行うことで、 **パッケージごとの責務** を適切に分離出来るようになる。この **「パッケージごとの責務」** という部分が重要だということに気づいた。

DDD というより、「パッケージごとの責務分離」を正しく担うことがオブジェクト指向プログラミングのかなり重要なポイントだった。

そして、 interface を用いてパッケージ分離された宣言と実装は、主に DI コンテナ(IoC コンテナ)を使って紐づけられる。 **そのための DI コンテナだった** 。

このサンプルは [slimphp/Slim-Skeleton](https://github.com/slimphp/Slim-Skeleton) を参考にしている。

このため、 Active Record 型の Laravel Eloquent などは `App\Infrastructure` 層以下に `class User extends Model` のようなクラスを生やすべきだし、ビジネスロジックは...分離するのが難しい。これが Active Record 型の弱点である。 Doctrine など POPO(Plain Old PHP Object) を使える Data Mapper 型の O/R Mapper なら分離出来るだろう。
PGIコンパイラに含まれるCUDAのバージョンを調べる方法

/opt/pgi/以下に複数のバージョンをインストールした場合はこんな感じです。

```
$ls /opt/pgi/*/linux86-64/201*/cuda/
```
こんな感じでずらっと出てきます（時系列で手でソートしています）。

```
/opt/pgi/18.1/linux86-64/2018/cuda/:
8.0  9.0  9.1
/opt/pgi/18.3/linux86-64/2018/cuda/:
8.0  9.0  9.1
/opt/pgi/18.4/linux86-64/2018/cuda/:
8.0  9.0  9.1
/opt/pgi/18.5/linux86-64/2018/cuda/:
8.0  9.0  9.1  9.2
/opt/pgi/18.7/linux86-64/2018/cuda/:
9.1  9.2
/opt/pgi/18.10/linux86-64/2018/cuda/:
10.0  9.1  9.2
/opt/pgi/19.1/linux86-64/2019/cuda/:
10.0  9.2
/opt/pgi/19.3/linux86-64/2019/cuda/:
10.0  10.1  9.2
/opt/pgi/19.4/linux86-64/2019/cuda/:
10.0  10.1  9.2
/opt/pgi/19.5/linux86-64/2019/cuda/:
10.0  10.1  9.2
```
どのタイミングで含まれて外れるのかわかります。
どのバージョンが使われるかは、コンパイルオプションで陽に指定するのが一番だと思いますが、デフォルトでなにが選択されるかは、CUDAドライバのバージョンによって決まります。nvidia-smiかpgaccelinfoでドライバのバージョンを調べておくことが必要です。
GameNote ++について紹介

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269852/7ebbc5c4-b141-4b5f-8b0c-20390a2eebe7.png)
この記事は[「アセットストア 真夏のアドベントカレンダー - 2019 Summer - 」](https://t.co/LCN0OQlRc0?amp=1)の、16日目の記事になります。

昨日は [坂すたじお/sakastudioさん](https://twitter.com/sakastudio_) の『低価格でも高クォリティな最強アセット13選！』でした。


## はじめに
今回はUnityでメモを書き留めることができるアセットの紹介です
[GameNote++](https://assetstore.unity.com/packages/tools/utilities/gamenote-52871?utm_source=jppt&utm_medium=20190816)


## こういう人におすすめ
* デザイナーさん
* ストーリーアドベンチャーゲームを開発する方


## 基本的な使い方
こういう効率向上系のアセットの使い方は簡単で、説明必要な内容も少ないですが、今回はfungusのsamplesceneのtitle imageと合わせてご紹介します


**◾️Note**
gameobjectにGameNoteをコンポーネント追加すると画像のように見える
<img width="462" alt="スクリーンショット 2019-08-10 17.21.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269852/75110c48-d415-9c5d-87b7-934a03cb2272.png">
①NoteTypeでtypeを選択できます、選択されたtypeで②のiconも変わります
③優先度
・Normal
・Low
・Medium
・Hight

**Option**
<img width="460" alt="スクリーンショット 2019-08-10 17.21.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269852/f1fb3e1a-5831-8686-a72d-587c867b7a2b.png">
①文字サイズ
②入力Boxの高さ

**◾️ToDo**
ToDoの項目に[+]すると、簡単に追加できます
追加したら、ターゲットのgameobjectの後ろに２の数値が表示されました。これはToDo件数です
<img width="460" alt="スクリーンショット 2019-08-10 16.55.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269852/de83ed75-05b5-71bf-3f68-8ff220df4ce8.png">

GameNote++を使ったらHierarchyは画像のように、
ToDoやメモなどiconで表示されて、直感的に分かりやすいです
<img width="803" alt="スクリーンショット 2019-08-10 17.48.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269852/d7b05104-ca7c-c2be-85df-54fb8a80618f.png">
作業する時よく使う機能は主にこの２つ、
codeや .datのエクスポートもできますが、使うことがないのでここで省略します


## 終わりに
アドカレ記事は以上になります

このアセット導入する前に、
作業する時にいつもUnity、Maya、note/ToDo appに切り替えて作業しました
導入した後、作業は全部Unityとmayaだけで済むことができました
個人的にこれは一番重宝しているアセットです

8月3日は [mewlist](https://twitter.com/mewlist)さん の『MassiveClouds を使った雲レシピ』です
TidalCyclesでのソフトシンセの扱い方

有名な方々は当たり前のようにソフトシンセを扱っておられますが、僕は使えるようになるのに非常に苦労しましたのでその記録を。そもそもLive Coding自体取り組んで居られる方が少ないので情報がなく苦労しました。この情報は多分ソフトシンセだけでなくMIDI音源一般に当てはまるものと思われます(筆者はまだハード音源を試していません)。

筆者はTidalCyclesを使っているので、それを前提に。

現在の筆者の環境は


・Windows10 64bit
・SuperCollider 3.10.2
・TidalCycles  1.3.0
・TASCAM US-2x2

です。
US-2x2はLoopBackをソフト的にLoopBackを行うという点で特殊な機種のようですが、Windows環境に於いてはAudioの出力先の指定の際に気をつけるぐらいです。

_※TidalCyclesでmidiを扱う際にはtidal-midiなるものがかつて在ったらしいのですが今はそれは必要無いようです。_

まず、仮想MIDIケーブルを導入します。TidalCycles(SuperCollider)とソフトシンセを繋ぐイメージでしょうか。色々見た結果以下が良さそうです。

[loopMIDI](http://www.tobias-erichsen.de/software/loopmidi.html)

こちらをインストールします。

そして使いたいソフトシンセのMIDI IN をこちらに設定します。

SuperCollider側ですが、いつもの「SuperDirt.start」と一緒に以下の一行を加えて以下のように入力します。

```
SuperDirt.start;
MIDIClient.init;
```
入力後、出力されるログを見るとインストールした「loopMIDI Port」が表示されていると思いますので、それをMIDIの出力先とします。一緒にレイテンシーも指定するようですので、結果以下のようになります。

```
~midiOut = MIDIOut.newByName("loopMIDI Port", "loopMIDI Port");
~dirt.soundLibrary.addMIDI(\midi, ~midiOut);
~midiOut.latency = 0.45;
```

これでTidalCyclesからソフトシンセを扱う用意が整いました。
筆者はソフトシンセ群としてNative Instruments KOMPLETEを使っていて、現在試したソフトシンセはMASSIVEとKontaktです。これらは起動すると自らホストするのでMIDIチャンネルを設定するだけで扱えました。
DAW環境としてはABILITY2.5を所有していて、こちらでホストしてから扱えたらフリーのソフトシンセも同様にして使えるようになるかも知れませんが、執筆している現在はオーディオドライバがSuperColliderと競合していることから起因していると思われる事象で成功してません。
よって、今はMASSIVEとKontaktだけで試した結果のみで記載しています。
※追記:VSTHostという著名なソフトシンセをホストするソフトを今使ってみましたが、そもそもSuperColliderは強力で立ち上がっていると他の一部の音源を鳴らなくするような仕組みになっているらしく。。。よってSuperColliderを落としているときはVSTHostのViewのKeyboard Barで音が出ましたが、SuperColliderが上がっているときは鳴りませんでした。つまり、TidalCyclesでソフトシンセをホストして使う目的では使えないと言うことですね。。。

以下のコードを実行しました。

```
  d1 $ s "909!4"
  d2 $ every 2 rev $ n "0 2 4 7" # s "midi" # midichan "4"
  d3 $ n "0 2 4 7" # s "midi" # midichan "3"
```
MASSIVEとKontaktのそれぞれの設定は以下です。
![コメント 2019-08-15 082123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/7fe6c022-b296-f152-9c46-5d66fbe50f52.png)
![コメント 2019-08-15 082158.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/dccee69c-b62c-ffa0-5950-d4932e9c594f.png)

このようにMIDI チャンネルはソフトシンセ側の設定の__-1__で指定します(ここ割とはまりました)。
一旦繋がってしまえば後はコントロールできると思います。(というか僕もこれから色々試します)。
Audioの出力先は環境によって違うでしょうが、僕の場合はUS-2x2なので出力先名に「Mixed Driver」と書いてあるものがLoopBack用の出力先なのでそれを指定します。ちなみにこちらはASIOドライバですが特にそのことを考慮する必要は有りませんでした。
(もちろん、一行目の909の音、つまりSuperColliderに備わっている音もきちんと鳴りました)

以上、個人的備忘録も兼ねて。
非定常クエット流の計算

##はじめに

下図の様に距離$h$離れた2枚の平行平板間が流体で満たされている状態を考える。下の板は静止し上の板がある速度$U$で$x$方向に動いているとき平板間に発生する流れを一般的にクエット流(Couette flow)と呼ぶ。
平板間の流体が非圧縮性粘性流体であると仮定したとき、質量保存則及び運動量保存則より、流れの運動方程式は以下の様に記述できる。

![schematic diagram couette flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480831/78a529bf-916b-cb21-0f0f-7a9f59eee926.png)


$$
\begin{equation}
\frac{\partial u}{\partial t} = \nu \frac{\partial^2 u}{\partial y^2} \tag{1}
\end{equation}
$$

ここで$\nu$は流体の動粘性係数、$u$は$x$方向の速度成分である。
時間$t=0$の時、両平板及び流体は静止しているものとし、$t>0$において上の平板が速度$U$で動き始めるとき、境界条件は下記の通りに表される。

$$
{\displaystyle u(y,0)=0,\quad 0<y<h,} \tag{2}
$$

$$
{\displaystyle u(0,t)=0,\quad u(h,t)=U,\quad t>0.} \tag{3}
$$

この時、運動方程式(1)は解析的に解くことができる。解析解は以下の様に表される。

```math
{\displaystyle u(y,t)=U{\frac {y}{h}}-{\frac {2U}{\pi }}\sum _{n=1}^{\infty }{\frac {1}{n}}e^{-n^{2}\pi ^{2}\nu t/h^{2}}\sin \left[n\pi \left(1-{\frac {y}{h}}\right)\right]} \tag{4}
```
解析解の導出に関しては参考文献1を参照されたい。

[参考文献1：D. J. Acheson, Elementary fluid dynamics, Oxford University Press, (1990)](https://www.amazon.co.jp/Elementary-Dynamics-Applied-Mathematics-Computing/dp/0198596790)

#Pythonによるシミュレーション
上記運動方程式(1)を数値的に解き、解析解との比較を行う。式(1)の右辺の粘性項は2次精度の中心差分を用いて離散化した。また時間積分には2次精度のRunge-Kutta法を用いた。

```python
import numpy as np
import matplotlib.pyplot as plt

''' Analytical solution of Couette flow '''
def u_exact(U,h,nu,y,t):
    u = U * (1-y / h)
    for n in range(1,100000):
        u -= 2 * U / np.pi * (1/n) *  np.e **(-n**2*np.pi**2*nu*t/h**2)*np.sin(n*np.pi*y/h)
    return u

''' Parameters '''
h = 1   # gap between plate
U = 1   # velocity of under wall
nu = 0.0005 # viscosity coefficient

nx = 51 # number of mesh

y = h * np.linspace(0,1,nx) # y coordinates
dy = h / (nx-1) # mesh size
dt = 0.02   # timestep
nend = 20000    # number of iteration

''' Initial conditions '''
u = np.zeros(nx)
un = np.zeros(nx)
u1 = np.zeros(nx)

u[0] = U
u1[0] = U    
un[0] = U

''' 2nd order Runge-Kutta '''
for nt in range(nend):
    u1[1:nx-1] = u[1:nx-1] + 0.5 * dt * nu * (u[0:nx-2] - 2 * u[1:nx-1] + u[2:nx]) / dy**2 

#    for j in range(1,nx-1):
#        u1[j] = u[j] + 0.5* dt * nu * (u[j-1] - 2 * u[j] + u[j+1]) / dy**2 

    un[1:nx-1] = u[1:nx-1] + dt * nu * (u1[0:nx-2] - 2 * u1[1:nx-1] + u1[2:nx]) / dy**2 
#    for j in range(1,nx-1):
#        un[j] = u[j] + dt * nu * (u1[j-1] - 2 * u1[j] + u1[j+1]) / dy**2 
       
    u = un.copy()

    ''' Plot '''
    if np.mod(nt + 3000, 4000) == 0 and nt < 5000 and nt > 0:
        ue = u_exact(U,h,nu,y,dt*nt)
        
        plt.plot(ue,y, color = 'black', label = "Analytical solution")
        plt.plot(un,y,"o", color = 'None', markeredgecolor='black', label = "Numerical solution")


    elif np.mod(nt + 3000, 4000) == 0 and nt > 0: 
        ue = u_exact(U,h,nu,y,dt*nt)
        
        plt.plot(ue,y, color = 'black')
        plt.plot(un,y,"o", color = 'None', markeredgecolor='black')

plt.xlabel("u")
plt.ylabel("y")
plt.legend()
plt.show()
```

![Couette flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480831/eb51a414-d2dd-82d8-6531-d84f90d66670.png)
Web技術についての備忘録

# ホームページとWebページの違い
ざっくり言うとホームページもWebページもイコールと考えてもOKだが、細かい解説を以下に記載

## ホームページ

インターネットを利用する際、Webブラウザ(Google ChromeやFireFox等)を起動する時の画面、
または、Webサイトを開いた時の最初のページのことを指す

## Webページ

Webブラウザ上で閲覧可能な文書のこと
※ちなみにWebサイトはWebページの集まった一意のまとまりを指す

# インターネットとWebの違い
ホームページとWebページと異なり、インターネットとWebには明確に意味が異なる

## インターネットとは
Webサイトやメール、電話発信といったあらゆるデータを複数のコンピューター間でやり取りする為のシステムネットワーク全体を指す
Webはあくまでインターネットの中で扱われる1つのものに過ぎない

## Webとは
正式名称は「ワールド・ワイド・ウェブ」で英語で直訳すると、「蜘蛛の巣」
ハイパーテキストというWebサイトを結びつける機能が世界中を蜘蛛の巣で繋げているような状態を指しWebと呼ぶ
※URLで見る「www」とはこのことを指す

## ハイパーテキストとハイパーリンク

1. ハイパーテキスト
WebサイトやWebページ同士を繋げるシステムのこと

2. ハイパーリンク
他のWebページへ繋げる為の参照情報のこと

## WebページとWebサイト

1. Webページ
同じドメインのページ単体のこと
※ドメインとは「`https://www.○○.co.jp/××`」なら「○○.co.jp」に相当する箇所を指す

2. Webサイト
同じドメインのWebページのまとまり

# 次の内容
[Web技術についての備忘録2](https://qiita.com/zoomk06/items/48c788da53ece353d04f)

# 参照
[【基本のき】ホームページの仕組みをイラスト付きでまるっと解説！](https://webliker.info/65123-2/)
tmuxで同時に複数のマシンに接続し同時に操作を行う。

複数のマシンにsshして、同様の設定を行いたい。
そういう時に使いましょう。

![tmux.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62929/314552a3-d4cb-de9b-1e10-b0d1145d3adc.gif)


## スクリプト

以下zshのスクリプトです:

```zsh:tmux-sync_ssh

#!/bin/zsh

tmux-sync_ssh() {
    hosts=${(Z+n+)$(cat -)}
    for host in $hosts[2,-1]; do
        tmux splitw -p $(( 100 / (${#hosts} - 1))) ssh $host
    done
    tmux select-layout main-vertical
    tmux set synchronize-panes on
    ssh $hosts[1] <> /dev/tty
    tmux set synchronize-panes off
}

tmux-sync_ssh $@
```

### fzfと組み合わせる

ssh先を表示してくれる fzf-sshを用意して
以下のように繋げると便利です。

```
$ fzf-ssh -m --bind ctrl-a:toggle-all | tmux-sync_ssh
```

fzf-sshは以下のような感じで用意しておきます:

```zsh:fzf-ssh

fzf_ssh(){
    FZF_OPTS=${(z)@}
    cat <(cat ~/.ssh/config /etc/ssh/ssh_config 0> /dev/null | \grep -i '^host' | tr ' ' '\n' | awk 'tolower($1) !~/^host/{print "host",$1}' | \grep -v '*') \
        <(\grep -v '^\s*#' /etc/hosts | \grep -Fv '0.0.0.0') \
        | awk '{if (length($2) > 0) {print $2}}' | sort -u  | fzf $FZF_OPTS
}

fzf_ssh $@
```

## 解説

#### 同時に複数のペインを操作する

```shell
$ tmux set synchronize-panes on
```

を使います。

これにより複数のペインに対して同じ操作を行うことができます。

### レイアウトを整える

```
tmux select-layout main-vertical
```

複数のペインを開いたあとにこの行で
これはお好みで。
僕はひとつ大きいペインがあると操作しやすいので、このレイアウトにしています。

man tmuxから次のレイアウトが有効です

```man
The following layouts are supported:
    even-horizontal
             Panes are spread out evenly from left to right across the window.

     even-vertical
             Panes are spread evenly from top to bottom.

     main-horizontal
             A large (main) pane is shown at the top of the window and the remaining panes are spread from left to right in the leftover space at the bottom.  Use the main-pane-height window option to specify the height of the top pane.

     main-vertical
             Similar to main-horizontal but the large pane is placed on the left and the others spread from top to bottom along the right.  See the main-pane-width window option.

     tiled   Panes are spread out as evenly as possible over the window in both rows and columns.
```

### コマンドライン上のプロセスにターミナルを割り当てる

コマンドライン上のプロセスには標準入力などのptsが割り当てられないことから
`ssh -tt`などして割り当てても、接続先をうまく操作できません。
これを解決するために

```
$ ssh $hosts[1] <> /dev/tty
```

を行なっています。


これは

```
$ ssh $hosts[1] < /dev/tty > /dev/tty
```

と等価です。

`/dev/tty` が 現在のシェルのttyを表す特別なファイルになります。
ゼロからホームページを作る難しさ

# はじめに

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている大嵜です。
前回までは、Progateで学習していましたが、次のステップとして自分でゼロからホームページを作成しています。
そこで感じた困難をまとめようと思います。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#ゼロから作成する難しさ

ホームページをゼロから作成するということは、それだけ自由度が広がります。
その一方で、どうやって進めていけばいいかわからなくなる部分もあります。

##なぜ難しいと感じるのか

私は今までProgateでの学習を進めてきました。
Progateでは、スライド形式でポイントを押さえた後、簡単な復習問題を解きます。
サクサクと進んでいくので、飽きずに楽しく勉強できます。
しかし、いざゼロからホームページを作成しようとすると、何も道筋が用意されていません。
今までの学習とはまったく異なります。
したがって、どこから始めればいいかわからなくなり、難しいと感じるのです。

##解決方法

では、どのようにしたらその壁を乗り越えられるのでしょうか。
重要なのは、他のホームページのコードを見ることだと思います。
だくさんのホームページのコードを見ることで、決まった型が見えてくる部分もあります。
また、好きなホームページのコードを見て参考にできます。
最初はそういったコードを真似るとこから始めて、徐々に自分で何も見なくても書けるようになっていけばいいと思います。

#まとめ

現在、ゼロからホームページを作成する課題で、なかなか進まずに苦戦しています。
他のホームページを参考にして、全体の構造を理解しながら書き続けていきたいです。
次回の執筆までには、ホームページを書くことに苦手意識を持たないレベルにはなりたいです。
An error occurred while installing rugged (0.28.2), and Bundler cannot continue. Make sure that `gem install rugged -v '0.28.2' --source 'https://rubygems.org/'` succeeds before bundling.

## 開発中のbundle installでエラー

```
An error occurred while installing rugged (0.28.2), and Bundler cannot continue.
Make sure that `gem install rugged -v '0.28.2' --source 'https://rubygems.org/'` succeeds before bundling.
```

`gem 'rugged'`が入らない。
`gem install rugged -v '0.28.2' --source 'https://rubygems.org/'`を試すもエラー。


```
ERROR:  Error installing rugged:
	ERROR: Failed to build gem native extension.
```

ググると、こんな記事が。
https://qiita.com/k-yamada-github/items/c3b90f14c4fd81da8722
とりあえず記事を参考にやってみる。

```
$ brew uninstall apple-gcc42
$ brew install apple-gcc42
```
```
Error: No such keg: /usr/local/Cellar/apple-gcc42
```
はいはい、エラー。
そんな期待してなかったから別にいいよ〜。

## An error occurred while installing rugged (0.28.2), and Bundler cannot continue. Make sure that gem install rugged -v '0.28.2' --source 'https://rubygems.org/' succeeds before bundling.の【解決コピペコード】

```
$ brew reinstall gcc
$ brew install cmake
```

```
==> Downloading https://homebrew.bintray.com/bottles/cmake-3.15.2.mojave.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/76/76de3a5828825352b3b05951df73aea22ddd27fe158d43b8b1e36c51d0641d55?__gda__=exp=1565811023~hmac=cc44fa2f38114c30acda48edeedb6f0d43
######################################################################## 100.0%
==> Pouring cmake-3.15.2.mojave.bottle.tar.gz
==> Caveats
Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/cmake
==> Summary
🍺  /usr/local/Cellar/cmake/3.15.2: 5,800 files, 53.2MB
gem install rugged
```

すんなり成功〜〜〜

```
gem install rugged
```

からの〜〜〜

```
Fetching rugged-0.28.3.gem
Building native extensions. This could take a while...
bundle
Successfully installed rugged-0.28.3
Parsing documentation for rugged-0.28.3
Installing ri documentation for rugged-0.28.3
Done installing documentation for rugged after 1 seconds
1 gem installed
```

入った〜〜〜🎉🎉🎉

参考
https://github.com/libgit2/rugged
ステータスバーを非表示にして全画面にする一番簡単な方法

##はじめに
アプリのステータスバーを非表示にする方法で、(多分)一番簡単な方法を見つけたので、備忘録を残そうと思います。🙇‍♂️

##ステータスバーとは
![Screenshot_20190815-024613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236467/331a36dc-153e-c208-3c1d-448e9307a8fc.png)
画面上部の濃い緑になっているところがステータスバーですね！

##実装
今回は [Hide the status bar](https://developer.android.com/training/system-ui/status) を見ながら実装しました。(本家のリファレンスが充実しているので勉強になります)
リファレンスでは Android 4.0 以前と Android 4.1 以降の例が載っているのですが、今記事では Android 4.1 以降のやり方しか書きませんので、4.0 以前のやり方も気になる方は本家のリファレンスを参考にしていただければと思います。🙇‍♂️ 

###コードで非表示

```kotlin
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
// supportActionBar?.hide() // toolbar を非表示にする。必要に応じて使用する
```

上記のコードを非表示にしたいActivityに追加すれば完成です。
簡単ですね。実質1行です。👏👏

####コードで実装する上での4つのポイント
1. UIのフラグがクリアされてしまった場合は再度アプリでフラグをリセットしてあげる必要がある。アプリのUIの可視性の変化を監視する方法は[Respond to UI visibility changes](https://developer.android.com/training/system-ui/visibility.html)を参照してください。 
2. `onCreate()`でしか上記のコードを呼び出していない場合、ユーザーがバックグラウンドにアプリを入れると再度表示されてしまう。なので、ステータスバーの状態を保持したい場合は、`onResume()`や`onWindowFocusChanged()`などで設定する必要がある。
3. `setSystemUiVisibility()`は呼び出し元のViewがVisibleの時にのみ有効。
4. 呼び出し元のViewから離れた場合は`setSystemUiVisibility()`がクリアされる。

###values/styles.xmlで非表示

```kotlin:values/styles.xml
<item name="android:windowFullscreen">true</item>
```

上記の属性値を追加するだけでも全画面モードになります。👏👏👏
バックグラウンド→フォアグラウンドにしても全画面を保ったままになります。
画面ごとに全画面にするかどうかが決まっている場合は style に追加した方が簡単かと思います。🤔


##最後に
ネットの記事を探し回っても全然うまくいかなく、本家を探したら普通に記事があってちゃんと公式を見ない
といけないなぁと思いました。😢
やはり困った時は公式に頼るのが一番いいですね。😂
EC-CUBE4で郵便番号にTABでフォーカス移動すると番地が消える

EC-CUBE4の問題では無く、yubingango.jsに起因する問題。
例えば管理画面で会員情報を開いて、TABキーで郵便番号にフォーカス移すと、入力済の住所情報が消えてしまう。

# 対応
yubingango.jsがkeyupイベントで住所検索してしまうのが原因なので、yubingango.jsではなくAjaxZip3互換モジュールを使う。

## 例
管理画面の会員情報ページの場合、src/Eccube/Resource/template/admin/Customer/edit.twig を app/template/admin/Customer/edit.twig としてコピーして、コピーした方を編集する。

以下の部分を、

```twig:app/template/admin/Customer/edit.twig
{% block javascript %}
    <script src="//yubinbango.github.io/yubinbango/yubinbango.js" charset="UTF-8"></script>
{% endblock javascript %}
```
↓に差し替える。

```twig:app/template/admin/Customer/edit.twig
{% block javascript %}
    <script src="//yubinbango.github.io/ajaxzip3/ajaxzip3.js" charset="UTF-8"></script>
    <script>
        $(function() {
            $('.h-adr').each(function() {
                var $postal = $(this).find('.p-postal-code'),
                    $region = $(this).find('.p-region-id'),
                    $locality = $(this).find('.p-locality'),
                    $extended = $(this).find('.p-extended-address'),
                    $street = $('<input type="hidden">');

                $postal
                    .after($street)
                    .on('focus', function() {
                        $postal.data('lastvalue', $postal.val());
                    })
                    .on('keyup', function() {
                        if ($postal.data('lastvalue') != $postal.val()) {
                            $postal.data('lastvalue', $postal.val());
                            AjaxZip3.zip2addr($postal[0], '', $region[0], $locality[0], $street[0], $extended[0]);
                        }
                    });

                Object.defineProperty($street[0], 'value', {
                    get : function(){},
                    set : function(val){
                        if (val) {
                            $locality.val($locality.val() + val);
                        }
                    }
                })
            });
        });
    </script>
{% endblock javascript %}
```
もっと綺麗な方法がある気がする。
胡蝶蘭の花

AliExpressにて
Webカメラ
[M5Stack ESP32CAM](https://ja.aliexpress.com/item/32881414545.html)
が1個1000円しないので、たくさん買って家の植物を監視してみました。
なお、M5Stack本体は使わず、カメラのソフトウェアを直接書き換えて、
定期的にサーバーに画像を送るようにしました。

書き換え方は以下を参考にしました。
https://github.com/espressif/esp-idf
https://github.com/igrr/esp32-cam-demo

そして胡蝶蘭の監視で面白い画像が撮れたので、
公開したく思います。

まず、2018年の秋はこのような状態でした。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48367/ded2cc6e-aea0-fe76-be6f-7a2d10caec1a.jpeg">

そして、これが2019年の春から夏にかけて開花しました。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48367/b38904d8-37e3-d512-4a1c-5fbdb67a04f9.jpeg">

以下は5月始めから7月末までのカメラで定点観測した結果になります。
![s0002_1905-07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48367/df852255-5eca-6978-c94c-5e3c7b3840bf.gif)
![s0003_1905-07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48367/95e2e88c-f214-73dc-bc24-7f00e0870ac7.gif)

胡蝶蘭はなんと3か月間も花が咲き続けて面白い！と思いました。
Django Rest Framework 2.x のチュートリアル(0)

# みんなで仲良く開発しよう！w

1. 大学(院)の授業で、６人程度の規模なチーム開発の授業がありまして
2. サーバ・クライアントに分かれ、それぞれフレームワークを使って開発しようとなりました。(私は**まずは**サーバ側でした)
3. 次にアジャイルで、**みんなで仲良く開発をしようぜ** っていう授業方針なので
4. まず使用言語を統一する必要があり
5. Pythonくらいしか共通で使える言語がなく
6. 結果有名所ということで **Django** を使うことになりました

問題点はいくつかあって、
- Djangoは **MTV** (Model Template View) 型のフレームワークなのでRestfulにするときに結構面倒くさい
- Djangoの真っ当な経験がないのにAPI開発で応用しようっていう考え方が頭おかしい
- そもそも各人でスキルレベルに差がありすぎるのに、開発よーいドンできるわけねえだろアホか
- というか 1.0 と 2.0 結構違いますねあなた。Tensorflow 並じゃねえかこのフレームワーク


というわけでフレームワークの使い方を統一する、開発チームの知見を共有するためにこのチュートリアルを夜鍋して書きました。

まあ、結局炎上してサーバサイドは凍結され、途中からクライアントサイドのわけわからんフレームワークを使う羽目になりましたが。


# 作業レポジトリ
https://github.com/MokkeMeguru/django-mariadb-nginx-example

ここの README.org が最新の情報です。要望があれば issue に追加してください。

# 目次
[Django Rest Framework 2.x のチュートリアル(0)](https://qiita.com/MeguruMokke/items/bbb0e389698537c6e4cf)
[Django Rest Framework 2.x のチュートリアル(1)](https://qiita.com/MeguruMokke/items/18b33d6e866f633aa52b)
[Django Rest Framework 2.x のチュートリアル(2)](https://qiita.com/MeguruMokke/items/65e7a7bcb6cef13c66cc)
[Django Rest Framework 2.x のチュートリアル(3)](https://qiita.com/MeguruMokke/items/58479f2b6524a6e8c450)
[Django Rest Framework 2.x のチュートリアル(4)](https://qiita.com/MeguruMokke/items/8445712a70d63cfb4bb5)
[Django Rest Framework 2.x のチュートリアル(5)](https://qiita.com/MeguruMokke/items/5d73cc7f8eb3a02bae90)
[Django Rest Framework 2.x のチュートリアル(6)](https://qiita.com/MeguruMokke/items/7e8d44f69f549f00bd4c)

# 感想
利用言語・フレームワークの知見が共有されていない状態で行われることが一般であるとするならば、おそらくアジャイル開発というのは崩壊後一歩で繰り広げられるゴミのような開発方針ですね、と思いました。

(技術の共有ができていない状態で好き勝手に一つのレポジトリを弄ったら、可読性がなくなるのが目に見えているんだよなぁ…)
[ VBA ] Excel の各セルの値を各スライドのタイトルにした PowerPoint の自動生成

1 スライドにつき、1 コピーを掲載していく PowerPoint を作る機会がありました。

100スライド程度なら手作業でもそんなに時間かからないと思うんですが、コピーが 3,000 以上来る予定で、修正も考えるともっとです。

かつ、コピーライティング上必要な改行が入っていたりするので、Excel ではセルを開いてコピーする必要があります。（そうしないと前後に ダブルクォーテーション["]が付いてしまい、あとあと消していくのも面倒です。）

そんなこんなで手作業でやるには時間が無駄すぎたので久々VBA組みました。

## 前提

元のコピーは Excel 上に 1コピー1セルの形で格納してあります。
あとあとスタイルを一括整形するのに スライドマスタ を使えると楽なので、タイトルシェイプに入れていくことにしました。（タイトルシェイプに入れておけばスライドマスタでスタイルを一括変換できます。）

また、この VBA は Windows版 Office365 で作成しています。（Macでは検証してません。）

## Excel の状態

形式はなんでもいいのですが、 **1コピー1セル** の形で格納されているものとします。
今回は全てを採用しない可能性を考えて、「採用」列を作り、そこに **優先度** を数字入力したものをフィルタする想定にしています。
内容は適当に作りましたが ↓ こんなイメージです。

<img width="831" alt="Book1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130681/18252716-0a76-389e-c806-b5277ceb0bcf.png">

このようにフィルタした状態で、対象セルを一括選択する想定です。
（この画像の場合 **B2** 〜 **B27** を選択するイメージ）

## VBA

VBAの全体像は ↓ こんな感じです。非常にシンプル！

```vb
Sub ExcelToPowerPoint()
Dim pp, ps, sl As Object
Dim i, rowCount As Long
Dim r, c As Object
Dim rng As Range

' 選択範囲のうち表示されているセル範囲のみ取得
Set rng = Selection.SpecialCells(xlCellTypeVisible)
' PowerPoint オブジェクト作成
Set pp = CreateObject("PowerPoint.Application")
With pp
    ' PowerPoint 表示
    .Visible = True
    ' PowerPoint ファイル新規作成
    Set ps = .Presentations.Add
    ' 選択範囲の行でループ
    For Each r In rng.Rows
        ' 選択範囲の列でループ
        For Each c In r.Columns
            With ps.Slides
                ' スライドを（タイトルのみレイアウトで）追加
                Set sl = .Add( _
                    Index:=.Count + 1, _
                    Layout:=11)
                ' タイトルシェイプにループ時のカレントセルの内容を挿入
                sl.Shapes(1).TextFrame.TextRange.Text = c.Text
            End With
        Next c
    Next r
    ' オブジェクトをクリア
    Set sl = Nothing
    Set ps = Nothing
End With
Set pp = Nothing
End Sub
```

これを Excel VBA の標準モジュールとして登録します。

## VBAの流れ解説

1. 選択範囲のうち表示されているセル範囲情報を取得
2. PowerPoint オブジェクト生成
3. PowerPoint 表示
4. PowerPoint ファイル新規作成
5. 選択範囲の行と列でループ処理
6. PowerPoint スライド（タイトルのみレイアウト）を追加
7. タイトルシェイプにセルの内容を設定
8. 選択範囲分6,7を繰り返す

## できたPowerPoint 

↓こんな感じのが一瞬でできました。
<img width="1077" alt="プレゼンテーション4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130681/b8f2a1b9-815f-030d-f495-bcc8418ab664.png">
改行もちゃんと反映されてます。

## まとめ

今回作ったものは需要が少ないですが、VBAはやっぱり便利だなと思いました。

> ** 注意 ** 
> VBA はバージョンやOS環境によって挙動が異なるので、
> 利用される場合は自己責任でお願いします🙏
Manjaro + Emacs な環境で日本語入力を行えるようにする一例

# Introduction
fcitx-mozc と emacs-mozc のコンフリクトがつらすぎたので、uim と emacs-mozc を使い始めた話

# require 
- Emacs
- Manjaro Linux (recommended: Budgie)
- yay (for Download some packages from AUR)


# やること
- uim をインストールする
- uim の入力方式の設定(Google-CGIAPI-JP を使います)
- emacs-mozc-ut2 のインストール
- emacs の設定

## uim のインストール

```shell
sudo pacman -Syu uim

echo "Emacs*UseXIM: false" >> ~/.Xresources

echo "# uim
export GTK_IM_MODULE='uim'
export QT_IM_MODULE='uim'
uim-xim &
export XMODIFIERS='@im=uim'" >> ~/.xinitrc

uim-pref-gtk
```

## uim の入力方式の設定(Google-CGIAPI-JP を使います)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147520/13edd376-13c5-df7c-3bdf-a4ea0fcb6289.png)

- 全体設定 -> 標準の入力方式を指定 -> Google-CGIAPI-Jp
- 全体設定 -> 使用可能にする入力方式 -> 次のように厳選
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147520/4e134b3a-d1de-916f-54d0-46d6dcad1337.png)

- Google-CGIAPI-Jp キー設定2 -> [Google-CGIAPI-Jp] オン / オフ
 Emacs の文化に則って、CTRL-\ を入力にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147520/3f2a83ec-30d6-4a33-b3b7-e677e1c5d849.png)


```~/.xinitrc``` のリロードを行います。=>再起動してください。



## emacs-mozc-ut2 のインストール

```shell
yay -G mozc-ut2
cd mozc-ut2
nano PKGBUILD
```

PKGBUILD を次のように変更してください。

```text
# Maintainer: ponsfoot <cabezon dot hashimoto at gmail dot com>

##
## Build configuration 
##
## You can choose the input method framework to use either ibus and/or uim.
## If you will not be using ibus, comment out below.
# _ibus_mozc="yes"
## If you will be using uim, uncomment below.
# _uim_mozc="yes"

## If you will be using mozc.el on Emacs, uncomment below.
_emacs_mozc="yes"

## If you want to use 'kill-line' feature of uim, uncomment below.
#_kill_line="yes"
## NOTE: This option affects only for uim users.
##       Bcause this applies a patch to original mozc source,
##       there is a possibility to fail depends on the mozc version.

## ニコニコ大百科IME辞書 (NICONICOPEDIA IME dictionary, see below)
_NICODIC="true"

# ... 
```

`emacs-mozc` と `_NICODIC` の行を有効にしました。

一応 uim-mozc もありますが、 Google CGIAPI Jp の方が優秀とかなんとか (使いたければコメントアウトを解放してください。)

```shell
makepkg -si
```

## emacs の設定
emacs 側で mozc パッケージをインストールしてください。
例えば `M-x package-install [RET] mozc` でインストールされます。

emacs の設定ファイルに次の項目を足してください。特にspacemacs を使っている方は、`~/.spacemacs` の `#'dotspacemacs/user-config` に追加します。

```emacs-lisp:.spacemacs
(defun dotspacemacs/user-config ()
 ;; ...
 (require 'mozc)
 (setq default-input-method "japanese-mozc")
)
```

また spacemacs user は dotspacemacs-additional-packages に `mozc` を追加してください。


```emacs-lisp:.spacemacs
dotspacemacs-additional-packages '(
    ;; ...
    mozc
    )
```

emacs の設定を反映してください。日本語入力環境が手に入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147520/e901821a-1a25-980a-5667-47bba80132f2.png)

## 所感
uim は... まあ慣れの問題ですね、多分

Google-CGIAPI-Jp の変換は今の所Mozcと張り合えるような気もする、という感じです。とりあえず困っていないのでしばらくはGoogle-CGIAPI-Jp を使ってみようかな、と思っています。

なにはともあれ、emacs-mozc がまともに動くようになったので満足です。
Dockerを理解するためにコンテナを理解する

* 理解のために思考の流れの例を記述していますが、実際の歴史を示したわけではありません。
* 理解を助けるために意図的に省略している部分があります。見逃せない場合はコメント欄にて補足していただけると助かります。

# もはや流行りからデファクトスタンダードになったDocker
Docker流行ってるなー。
使えるようになっといた方がいいなー。
と思ってたら、あっという間にデファクトスタンダードになってました。
「流行ってる」じゃなくて、「使えて当然」な段階まで普及したので、ここいらでとりあえず使えるようになりたいと思います。
できることが増えて意欲が増したときのために、とりあえずとはいえ最低限の理解もあった方がいいでしょう。
というわけで、僕が理解するまでの思考を記録しておきます。

# Dockerって何
Docker(ドッカー)はコンテナと呼ばれる仮想環境を提供するサービスの一種です。
端的な表現は腑に落ちるまでは気持ち悪いですが、理解のマイルストーンになるので最初に示しておきます。

この記事においてコンテナは以下のような扱いです。

* プロセス単位の仮想環境

ふーんと読み流してしまいそうになりますが、この「プロセスであり、仮想環境である」という特徴は強力です。

# コンテナじゃない仮想環境
コンテナの特徴を理解するために、コンテナ"ではない"仮想環境について理解して外堀を埋めましょう。
まずは仮想環境が必要な場合を考えてみます。

## 仮想環境が必要になるまで
パソコンにはCPUとメモリが搭載されており、それらを利用してアプリケーションやミドルウェアは動作します。
![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227222/a6532b88-b074-34f2-a3c0-3097d98ddef1.png)

この構成だけですべてをやり繰りするには、大きく2つの問題があります。

1つは、環境をごっそり入れ替える場合にはマシンの交換やOSの再インストール作業が必要になるということです。
広く普及しているPCのOSはWindowsまたはMac OSですが、Linux環境を用意しようと思ったとき、WindowsマシンやMacBookにLinuxをインストールしようとは到底思えません。
(メインOSレベルで使うなら、デュアルブートはありですね。)

もう一つの問題は、試行錯誤するのが億劫だということです。
環境構築やアプリケーションの配置でミスしてマシンが再起不能になるかもしれません。
こちらも最悪の場合はインストールのやり直しになりますね。

そこで、仮想環境というアイデアが生まれました。
仮想環境といえば、Virtual BoxやVMwareといった仮想マシンを連想する人も多いでしょう。
これらは、ホストマシン上で仮想マシン用のアプリケーションを起動し、そのアプリケーション上で仮想マシンが動作します。
![Untitled(2) (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227222/5da4dc91-2764-d960-82bc-382ce553bb89.png)

これで、仮想マシン上であればどんな操作をしようが、ホストマシンには影響しません。
仮想マシンは作り放題ですし、OSの選択も自由です。
もちろん仮想マシンを削除するのも何ら問題ありません。

## 仮想環境の制約
仮想環境には仕組み上どうしようもない制約があります。
仮想環境のスペックはホストマシンのスペックより下位になる、という制約です。

仮想マシン用のアプリケーションは中に仮想マシンを構築するため、ホストのリソースを相当量消費します。
ホストマシン以上のスペックを仮想環境で発揮するのは物理的に不可能です。
よって、仮想環境のスペックはホストと比較してかなり下位のランクになります。

仮想環境の導入を検討したことがある人は、仮想マシンは低スペ、あるいは仮想マシンを利用するには高スペなホストマシンが必要、という認識があると思います。

# 無駄を削いで限界までスペックを上げる
仮想環境を利用したいエンジニアにとって、仮想マシンはほとんどの場合オーバースペックならぬオーバープロセスです。
仮のWebサーバーを立てたいだけ、テスト用のDBサーバーを立てたいだけなのに、よくわからないプロセスがたくさん動作しています。
どれもPCを制御するために必要なOSのプロセスなのでしょうが、仮想環境のニーズとはミスマッチです。
OSすらも不要です。
それら不要なプロセスを削ぎ落とそうとしていった結果がコンテナです。

コンテナはミニマムな仮想マシンのようなもので、ユーザーが求めるプロセスのみを実行します。
ミニマムであるため、仮想マシンのように大量にリソースを消費して管理する対象がありません。
OSもなく、ホストのものを共有します。
管理する対象がないため、間に管理用のアプリケーションを必要とせず、
コンテナはホストのリソースを直接消費する構造になりました。
![Untitled(3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227222/0685d759-afa9-e16b-c574-7a324a54c612.png)

すなわち、最大でホストと同等のスペックまでを仮想環境で発揮できるようになったのです。

# 仮想マシンとコンテナ
以上のように、コンテナは仮想マシンの一部のニーズを叶えるために生まれた技術であるだけで、仮想マシンの後継には完全にはなりえません。
特に、用途とスペックのトレードオフと言えるでしょう。

|　|仮想マシン|コンテナ|
|:---: |:---:|:---:|
|用途|汎用(広)|特化(狭)|
|スペック|ホストより下位|ホスト同等|

「汎用的なコンテナ」を作ることはもちろん可能ですが、やりすぎるとホストのリソースを消費しすぎてホストに悪影響が出る可能性があるので注意が必要です。

# Next. 環境潔癖症のためのDocker活用術
開発環境をDockerで構築することでホストの環境は綺麗なままに保てます。
僕のような環境潔癖症にはうってつけだと思います。
OpenVPNが繋がらない場所から、どうにかして繋げる

# OpenVPNが繋がらない場所とは
その名の通りOpenVPNが繋がらない場所です。
なぜか職場や学校、寮や特定の地域からだとOpenVPNが繋がらないという経験をしたことがある人は多いのではないでしょうか。

この記事では事例別に対処法を書いておきます。
おそらく複数の対処法を組み合わせることで繋げれるようになるかと思いますので、自分の環境に応じてトライしてみてください。

本記事では具体的な設定方法やコマンドなどは扱わないので、必要に応じて調べてください。

もし他にも対処法などあれば、どんどん編集リクエストやコメントなどいただけると嬉しいです。

# 注意事項
不当なアクセス制限を受ける人や、管理者の承認を得て繋げようとする人などのために書いた記事です。
違法行為に使うのはダメです。責任は一切負いません。

# 1. UDPに制限がかかっている
ネットワークの管理者が、UDPプロトコルに制限をかけている場合があります。
この場合、TCP通信はできてもUDPは弾かれます。

**VPNサーバーの設定をUDPからTCPに変える**ことで、対処できます。

# 2. ポートがブロックされている
OpenVPNサーバーは、デフォルトで1194ポートを使います。
つまりブロッキングしたい管理者は、このポートをブロックしてしまえばいいわけです。

ということで、**VPNサーバーのポート設定を適当なポートに変更する**必要があります。

ちなみに、例えば1000以上のポートは全部ブロック!とかやってる可能性もあります。
ただ、WEBサーバーがデフォルト使う80番、443番をブロックしていることはまずないので、OpenVPNのサーバーも**80番や443番などで稼働させる**と安心です。

# 3. OpenVPNサーバーのIPアドレス・ドメインがブロックされている
例えば大手のVPNサービスを使っている場合などは、この可能性が高いでしょう。
自前でサーバーをレンタルして、OpenVPNのサーバーを建ててみてはいかがでしょうか。

# 4. DPI等でOpenVPNのプロトコルがブロックされている
例えば有名なDPI(Deep Packet Inspection)ソフトである[ntop](https://www.ntop.org/products/deep-packet-inspection/ndpi/)などで、流れてくるパケットを解析するとどういうプロトコルか分かってしまいます。
管理者としては、OpenVPNのパケットをはじくことですべてのOpenVPNによる通信を遮断できます。

ではどうすれば突破できるかというと、別のプロトコルで包んでやればいいわけです。
ここでは複数の手法が考えられるかと思いますが、一番手軽なのは**SSHポートフォワード**でしょう。

VPNサーバーのアドレスを `vpnserver.net`、ポートを `1194` とします。
以下の手順では `[適当なポート番号]` は同じものを使用してください。

まずはSSHポートフォワードで`vpnserver.net` の `1194` ポートを `localhost` の `[適当なポート番号]`にフォワードします。
その後、OpenVPNクライアントから `localhost` の `[適当なポート番号]` に接続することで無事にVPNに繋がるはずです。

つまり、手元のクライアントからサーバーまでの通信はSSHの暗号化されたトンネルの中で行うということですね。
これでDPIからはSSHプロトコルのパケットに見え、もちろん暗号化されているので中身がOpenVPNのパケットかどうかはわかりません。
(SSHのプロトコルがブロックされている場合は他の方法で)
ColorToolで一発！Windowsのコンソール画面を白黒から変えてみよう

## 概要
Windowsのコンソール画面はご存知の通り白黒なので視認性が低く、
コマンドが複雑になればなるほど読みづらくなります。
簡単にコンソールの色変更をする方法はないかと探した結果、`ColorTool` と呼ばれるMicrosoft社が提供するツールを発見。
私が参考にさせていただいた記事はリンク等が少し古くなっており、微妙にハマってしまったため備忘録として記事にします。

## この記事で得られること

* Windows上のコンソール画面（コマンドプロンプト、WSL）を任意のカラーに変更できる
* 視認性があがるので作業効率もUP！（するかも）

## 環境やツールのバージョン

* Microsoft Windows [Version 10.0.17134.885]
* WSL Ubuntu 18.04.1 LTS (Bionic Beaver)
* colortool v1.0.1904.29002

## Color Toolの準備

Githubリポジトリ：[Microsoft/ColorToolのREADME](https://github.com/microsoft/terminal/blob/master/src/tools/ColorTool/README.md)の[「Installing」](https://github.com/microsoft/terminal/blob/master/src/tools/ColorTool/README.md#installing)内のリンク先に最新版のColorToolがあります。
あとは以下のように進めればOKです。

* `ColorTool.zip` をダウンロード
* `ColorTool.zip` を解凍し、`cmd.exe`（コマンドプロンプト）を開く
* コンソール画面上で、解凍した`ColorTool`フォルダへ移動 ※

※エクスプローラーのアドレスバーに`cmd`と入力すれば、
カレントディレクトリのコンソール画面が起動されます。
[![Image from Gyazo](https://i.gyazo.com/1a9b3e17bb6e99fd7786acb918d5e582.png)](https://gyazo.com/1a9b3e17bb6e99fd7786acb918d5e582)

[![Image from Gyazo](https://i.gyazo.com/8bd38562b190ca2177f76a11f4bf67f9.png)](https://gyazo.com/8bd38562b190ca2177f76a11f4bf67f9)

## Color Toolの使い方

### 用意されているカラーテーマを確認

```shell-session:コマンド
colortool.exe -s
```

[![Image from Gyazo](https://i.gyazo.com/64b3e5fd6576d2e02224c1b8bca28bd2.png)](https://gyazo.com/64b3e5fd6576d2e02224c1b8bca28bd2)

画面内の、拡張子`.itermcolors`がカラーテーマのファイルです。

1. deuteranopia
2. OneHalfDark
3. OneHalfLight
4. solarized_dark
5. solarized_light

### 任意のカラーテーマを適用

`-b`オプションで、カラーテーマのファイル名を指定し実行すればOK！
コマンド実行後すぐにカラーテーマが適用されます。

この`-b`オプションは、現在起動中のコンソールとデフォルトの両方にカラーテーマを適用してくれるものです。

```shell-session:コマンド
Colortool.exe -b カラーテーマ名.itermcolors
```
```shell-session:【例】OneHalfDarkを適用するとき
Colortool.exe -b OneHalfDark.itermcolors
```

カラーテーマごとの適用後イメージは、こちらの記事をご参照ください。
参考：[コンソールにカラーテーマを！WSLも見やすくなる！](https://www.lisz-works.com/entry/ms-color-tool)

## おまけ：私がハマったポイント

カラーテーマを適用する際に、拡張子をつけずに実行したところエラーに。
[![Image from Gyazo](https://i.gyazo.com/3317e09e6788ba28cce4b21c8b357507.png)](https://gyazo.com/3317e09e6788ba28cce4b21c8b357507)

拡張子をつけて実行したところ問題なく適用されました！
[![Image from Gyazo](https://i.gyazo.com/a78b722638f3eaee3f27a9860bbe3c0f.png)](https://gyazo.com/a78b722638f3eaee3f27a9860bbe3c0f)

## 参考URL

* [コンソールにカラーテーマを！WSLも見やすくなる！](https://www.lisz-works.com/entry/ms-color-tool)
* [Window のターミナルの色を簡単に変更する（ WLS にも適応）](https://blog.ouvill.net/blog/2019-01-11--set_cmd_chemes/set_cmd_chemes/)
WebAR ar体験

#ar体験

1. [ここ](https://jeromeetienne.github.io/AR.js/data/images/HIRO.jpg)をdesktopブラウザで開く
2. [ここ](https://jeromeetienne.github.io/AR.js/three.js/examples/mobile-performance.html)をスマホのブラウザで開き、desktopの画像を映す

#参考
https://github.com/jeromeetienne/AR.js/blob/master/README.md
POSTリクエストで受け取ったJSONデータをWebsocketに送信する

#概略
POSTリクエストをWebsocketに流したいときに使うコンバータのようなものです。
##必要なもの
* node.js
* Express
* body-parser

いずれも最新版を使います。

#ソースコード
```app.js
//expressの各種定義
const express = require('express');
const body_parser = require('body-parser');
const app = express();

//websocketの定義
var server = require('ws').Server;
var ws_server = new server({ port: 3001 });

// urlencodedとjsonは別々に初期化
app.use(body_parser.urlencoded({
    extended: true
}));
app.use(body_parser.json());

//サーバーの立ち上げ
app.listen(3000);
console.log('HTTP Server is online.');

//json_dataの定義
var json_data = null;

//postリクエストの受け取り
app.post('/', function(req, res) {
    json_data = req.body;
    //コンソールに受け取ったjsonを表示
    console.log(json_data);
    //websocketに投げる
    ws_server.clients.forEach(function(client){
        client.send(JSON.stringify(json_data));
    })
    res.send('POST request convert to websocket');
});
```

githubにも公開しています。

* https://github.com/kefian1go/convert_postreq2ws

##参考
https://qiita.com/ktanaka117/items/596febd96a63ae1431f8
【Xcode】特定のSimulatorのみ閉じる方法

<img width="1268" alt="スクリーンショット 2019-08-15 0.12.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11800/18b2b265-6bf5-cd35-29a1-370acbd47d65.png">

Xcodeで開発していて複数Simulatorを立ち上げた後、指定のSimulatorのみ閉じる方法が分からなかったのですが。


<b>閉じたいSimulatorを選択後、 Command + w</b>

で出来ました笑

誰かのお役に立てば。
adMobスクリプトメモ

adMobの公式ガイドをそのまま実装してる方の情報ばかりだったので
少しいじったものをメモ。


```c#
using System; //リワードで使用
using UnityEngine;
using UnityEngine.UI; //テキスト（テスト用）で使ってるだけ
using GoogleMobileAds.Api; //必須

public class AdMob : MonoBehaviour {

	private enum Adtype {
		banner,
		reward,
		inter,
		native
	}
	[SerializeField]
	private Adtype adtype; //タイプをインスペクタで選べるように

	[SerializeField]
	private string Android_appId = default; //AndroidのappID 「~」がある方
	[SerializeField]
	private string ios_appId = default; //iosのappID
	[SerializeField]
	private string Android_UnitId = default; //AndroidのUnitID 「/」がある方
	[SerializeField]
	private string ios_UnitId = default; //iosのUnitID

	private RewardBasedVideoAd rewardBasedVideo;

	private string appId;
	private string adUnitId;

	public Text text; //テスト用


	void Awake ()
	{
		DontDestroyOnLoad (this); //このスクリプトがアタッチされてるobjは消えない

#if UNITY_ANDROID
		appId = Android_appId;
#elif UNITY_IPHONE
		appId = ios_appId;
#else
		appId = "unexpected_platform";
#endif

#if UNITY_ANDROID
		adUnitId = Android_UnitId;
#elif UNITY_IPHONE
		adUnitId = ios_UnitId;
#else
		adUnitId = "unexpected_platform";
#endif

		MobileAds.Initialize (appId); // Initialize the Google Mobile Ads SDK.

		switch (adtype) { //enumで選んだものが実行される
		case Adtype.banner: RequestBanner (); break;
		case Adtype.reward:
			rewardBasedVideo = RewardBasedVideoAd.Instance; // Get singleton reward based video ad reference.
			rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed; // Called when the ad is closed.
			RequestRewardBasedVideo (); break;
		case Adtype.inter: break; //未設定
		case Adtype.native: break; //未設定
		}
	}

	private void RequestBanner () //バナーの命令
	{
		BannerView bannerView = new BannerView (adUnitId, AdSize.Banner, AdPosition.Top); // Create a 320x50 banner at the top of the screen.

		AdRequest bannerrequest = new AdRequest.Builder ().Build (); // Create an empty ad request.

		bannerView.LoadAd (bannerrequest); // Load the banner with the request.
	}

	private void RequestRewardBasedVideo () //リワードの命令
	{
		AdRequest rewardrequest = new AdRequest.Builder ().Build (); // Create an empty ad request.

		rewardBasedVideo.LoadAd (rewardrequest, adUnitId); // Load the rewarded video ad with the request.
	}


	public void HandleRewardBasedVideoClosed (object sender, EventArgs args)
	{
		RequestRewardBasedVideo (); //広告を再び再生できるようにリセット
		text.text += "成功！！"; //広告を閉じた時に実行される命令（テスト用）
		MonoBehaviour.print ("HandleRewardBasedVideoClosed event received");
	}

	public void testButton () //ボタン命令（テスト用）
	{
		if (rewardBasedVideo.IsLoaded ()) { //ロード完了してたら
			rewardBasedVideo.Show (); //リワード動画を表示
		}
	}

}


```


インスペクタでIDを入れられるようにして
enumがついてるのでプルダウンメニューから
バナーなのかリワードなのか選べるようにしました。
（バナーリワード以外は今の所作ってません）

あとはボタンを押したらリワードが出るようにしてるので
UIボタンにtestButtonをアタッチすれば
ボタンを押した時（ロードしきってれば）再生されます。
ロードしきったらボタンが押せるようにするのが一番いいかも。

広告を閉じる命令で
text.text += "成功！！";
が発生してるのでここを任意のものにすれば
わりといろいろできる気がする。


と、まぁなんとなく出来たことをメモしただけですが
自分的に整理されたので一応メモっておきますー。
3Dスキャナー（ライカスキャナー）の使い方まとめ！

毎回忘れるので
ライカスキャナーの使い方をまとめました。

（必要なもの）
・ライカスキャナー
・iPad　（Recapのアプリケーション）

step 1:
スキャンする場所にライカスキャナーを置きます。
必ず、専属の三脚の上に乗せましょう。
（この特殊な三脚の上で回転しながら空間をスキャンします）
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/052fe2fe-1595-7aeb-fbf0-65e93b56a3ed.jpeg)

step 2:
ライカスキャナーの電源を入れます。
緑色に光ります。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/121c537a-f2be-8f1c-b0ed-9f1e899d2371.jpeg)

step 3:
iPadを開きます。
wifi設定で、ライカスキャナーが接続されているのを確認します。
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/6aaf56e9-8e2e-8054-4d50-93e3b45977bb.jpeg)

step 4:
iPad上でRecapのアプリケーションを起動します。
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/6b7cd586-dfe4-e028-900b-646a73aca33a.jpeg)

step 5:
サインインします。
![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/547d5870-ac92-5929-b532-666775d07700.jpeg)

step 6:
+New Projekt を開きます。
![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/fdc8b597-296e-809c-0e48-21fffdba69a7.jpeg)

step 7:
プロジェクト名を入力します。
![7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/8321cf3b-eeee-2564-c78f-505430730500.jpeg)

step 8:
スキャンの準備ができました。
+New Scanを押します。
![8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/544e42f0-198b-8e5a-fc69-e66edd0c10ea.jpeg)

step 9:
ライカスキャナーがスキャンを始めます。
ゆっくり回転したり、高速回転しながら空間をスキャンします。
![9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/f68f2e9e-6f42-33d7-0e1e-f8b5d25f35e6.jpeg)

step 10:
processingを経て、無事にスキャンが終了しました。
![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/2d4b9f7c-99f7-5294-cdaa-5d6bc8fb139f.jpeg)

この要領で、続けて空間をスキャンします。
基本的には部屋の四隅と中央、大体５箇所をスキャンすれば十分でしょう。

次回はスキャンしたデータをパソコン上のRecapソフトで加工する工程をまとめたいと思います。
rake db:migrateを実行しようとしたら（StandardError: An error has occurred, this and all later migrations canceled:）というエラーが

rake db:migrateを実行したら
StandardError: An error has occurred, this and all later migrations canceled:
というエラーが発生

現在スクールに通っておりカリキュラムを２週目をやっていて前回とファイル名が同じやつを残していたのが原因と考え

rake db:drop ファイル名
を実行し元々あったdbを削除

rake db:create
dbを作成し

再度　rake db:migrateを実行したら

20190814131801 CreateTweets: migrating =====================================
-- create_table(:tweets)
   -> 0.0091s
== 20190814131801 CreateTweets: migrated (0.0092s) ============================

いけました！
Flutter よく使うコマンド　(随時追加)

お酒を飲む前にFlutterでよく使うコマンドをメモメモ

# アプリの作成
```
flutter create myapp
```
# アプリの起動
```
flutter run
```
# パッケージ取得
```
flutter packages get
```
# キャシュ削除
```
flutter clean
```
# 環境確認
```
flutter doctor
```
# ios xcode起動
```
open ios/Runner.xcworkspace
```
# build(ios/Android) 
```
flutter build ios
flutter build apk
```
参考ドキュメント
ios : https://flutter.dev/docs/deployment/ios
Android : https://flutter.dev/docs/deployment/android
※　何も設定せず、コマンドを叩いても動かないのでドキュメント見て設定してからコマンドを叩きましょう！設定方法は、後日まとめる予定です！
Ruby on Rails ビューファイル を リンク で つなぐ

# 目的

- Ruby on Railsで作成したビューファイル内にリンクを作成して同じapp内のページに飛べるようにする方法のメモを記載する。  
※本記事はRuby on Rails超初心者の筆者がまとめたものです。情報が正確ではない可能性があります。優しくコメントをくださると幸いです。

# まとめポイント

- html記法の`<a>`タグを利用してリンクを作成する。
- リンク先をルーティングファイルに書かれたファイルパスと同じものにする。
- 具体的に説明する。  

  1. `localhost:30000`で表示しているビューファイルに`localhost:30000/about`へのリンクを作成する。
  1. `localhost:30000/about`で表示しているビューファイルに`localhost:30000`へのリンクを作成する。
  1. ルーティングファイルを記載する。
 
      ``` ruby
      get "/" => "home#top"
      get "/about" => "home#about"
      ```
  1. `localhost:30000`を表示している`top.html.erb`のビューファイルのリンク部分を記載する。

      ``` html
      # localhost:30000からlocalhost:30000/aboutへのリンク
      <a href="/about">localhost:30000/aboutへ</a>
      ```
  1. `localhost:30000/about`を表示している`abut.html.erb`のビューファイルのリンク部分を記載する。

      ``` html
      # localhost:30000/aboutからlocalhost:30000へのリンク
      <a href="/">localhost:30000へ</a>
      ```
※内容は少ないですが、まとめたかったので短い記事ですいません。
Ruby on Rails 表示 URL を 変更する

# 目的

- ビューファイルに紐づいているURLを変更する方法のメモを記載する。  
※本記事はRuby on Rails超初心者の筆者がまとめたものです。情報が正確ではない可能性があります。優しくコメントをくださると幸いです。

# まとめポイント

- 表示するビューはそのままにURLを変更するにはルーティングファイルの内容を変更してあげるだけで簡単に変更できる。
- 具体的に説明する。  

  1. 今までは`localhost:30000/top`で表示していたビューファイルを`localhost:3000`で表示するようにしたい。
  1. 修正前のルーティングファイルを記載する。
  
    ``` ruby
    get "top" => "home#top"
    ```

  1. 修正後のルーティングファイルを記載する。

    ``` ruby
    # localhost:30000で表示したい場合はスラッシュのみをURLとして指定する。
    get "/" => "home#top"
    ```
※内容は少ないですが、まとめたかったので短い記事ですいません。
ProgateのPHP1修了！率直な感想！

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているerika_zです。

プログラミングの学習を始めて約2か月が経ちました。
HTMLとCSSで作成していた、簡易的な逆求人サイトが完成し、最近PHPの学習を始めました！
現在はProgateを使用していて、学習コースのPHP1を修了した段階です。

そこで今回は、PHP1で感じたことや学んだことについて書きたいと思います。


#はじめに

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。


###比較的難なくコースを修了できた

MTMLやCSSを学習した時に比べて、つまずくタイミングが少なかった。
具体的には、文字の情報はダブルクォーテーションやクォーテーションで挟むなどの基本的なルールを間違えることがなくなった。
また、プログラミングの用語に慣れてきたことで、いちいち調べる必要がなく順調に進められた。
PHPは、HTMLやCSSの構造がある上で使用するため、先にHTMLやCSSを学習するしてよかった。

###PHPとjavascriptはすごく似ている

簡易的な逆求人サイトを作成した際に、javascriptを少し学習した。
その時に学んだif,switch,breakなど条件分岐がPHPでも行えることにびっくりした。
同時にどのような点が違うのかという疑問を持った。

調べてたところ、PHPはサーバーによって処理され、javascriptはパソコン上で処理されることが分かった。
この違いによって、異なる結果が出力されることがある。
作成したいものによって、どちらを使用するべきかも意識しながら学習を進めたい。


###関数を使うことでできることの幅が広がる

Progateではstrlen,count,randしか扱われていなかったが、その他にもたくさんの関数がある。
関数を使いこなし複雑な構造を作りたい。
参考URL　https://php-archive.net/php/words-in-function-names/




#まとめ

今回は、ProgateのPHP１で学習した感想について書きました。

HTMLやCSSを学習した方であれば、そこまで難しいと感じることなくPHPを学習できると思います。
私もPHPに挑戦し始めたばかりですが、学習しようか迷っている方がいるならばまずやってみることをおすすめします。
一緒にかんばりましょう！
Gravatarの画像をメールアドレスから取得する方法

## Gravatarの画像をメールアドレスから取得する方法
メールアドレスのmd5ハッシュ値を求め、
https://www.gravatar.com/avatar/[求めたハッシュ値]
にアクセスすることでメールアドレスに登録された画像が取得できます。

Rubyの場合、
`require 'digest/md5'`して、
`Digest::MD5.hexdigest(email.downcase)`でハッシュ値が求まります。
この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
VR内での疑似触覚の確認

この記事は、OculusやVIVE等のVRデバイスを持っている人を対象としています。
（6Dof以上、VRコントローラーがあるのが望ましい)
また、個人の主観による実験結果のため、学術的な価値はありません。

# はじめに

前回の記事、["VRChatを用いた「現実感」の編集"](https://qiita.com/pipe_render/items/2393b39443401902a544)で大雑把な「現実感」を仮定しました。
今回からは、これを細かく分けていきます。

「現実感」の中でも特に馴染み深いのが「触覚」です。

皆さんは、こう思うかもしれません。
「触覚は皮膚下の感覚神経によるもので、SFに出てくるような触覚デバイスがないと感じることはできない。」

ですが触覚スーツなどを着なくても、VR内で物に触れたような感覚を得ることは可能です。

# 経緯

前回の記事で、「目の前にあるCGのテーブルが実際に存在しているかのような錯覚があった」と書きました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461091/fd097b99-5b5c-0308-0604-d0d3ae22619d.jpeg" width=50%>
(Oculus Questのチュートリアル「First Steps」)

私にとってこの錯覚はとても不思議だったので、その正体を調べるためのVRを作りたいと思うようになりました。

目的のコンテンツを作るために、その時遊んでいたVRChatを用いることにしました。理由は作成とテストがとても簡単だからです。

私は、次の３つのワールドを作成しました。
・圧迫感を調べるワールド
・先端恐怖症を調べるワールド
・ハグしたときの気持ちを調べるワールド

上記の３つを選んだのは、錯覚が人間の本能によるものではないか？という直感からでした。

# 結果

実験の様子を動画にしました。
<a href = "https://www.youtube.com/watch?v=1C4shvtmBZE&feature=youtu.be">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461091/84dcc99e-acd5-959d-3fba-316479f5c922.png" width=50%>
YouTube:VR感覚の実験 (圧迫感/先端恐怖症/ハグ)[VRChat]
</a>

# 詳細

###VR感覚の実験 - その1 (圧迫感)

> 圧迫感を調べるための動くトーラス。
> 胸部から喉元にかけてと、上腕部から肩にかけて圧迫感と息苦しさを感じた。

この時感じた圧迫感と息苦しさは、画像で表すと以下のような範囲と強さでした。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461091/0d75a9d7-26c4-b1de-4f41-0c0280d90b10.png" width=50%>
(赤:圧迫感が強い ⇔ 青:何も感じない
頭部は実験の範囲外のため、無視してください。)

もう気づいている方もいるかもしれませんが、これは呼吸器系の器官(肺や気道、口や鼻)が存在している範囲と重なっています。

また、私が使用しているOculus Questでは頭部と左右の手の３つのみをトラッキングしていることも重要かもしれません。

###VR感覚の実験 - その2 (先端恐怖症)
> 尖った物を避けようとする原始的な反応のテスト。
> 痛みはなかったけど、何とも言えない違和感・苦しさを感じた。
> 体験後、手の平にだけその感覚が残っていたのが印象的だったが、よく調べるとそれは軽い腱鞘炎の間違えだった。（！）

尖ったCGにアバターを近づけたときに感じたのは、言葉には表せないような違和感でした。
またその時、軽い腱鞘炎とVR内の感覚を間違えるという事態も発生しました。

感覚の取り違いは、この時だけのレアケースなのでしょうか？
それとも頻繁に発生している現象なのでしょうか？

###VR感覚の実験 - その3 (ハグ)
> やわらかい物体をハグしたときに、何か感じるかと思ったけど、ハッキリとした感覚はなかった。
> ただ「息苦しさはあるものの、嫌ではない」と思った。
> 暖かさもあったが、部屋の温度との区別はつかない。
> モデルによって印象が大きく変わるのかもしれない。

ここで実験したかったのは「ハグの行動が感情にどう影響を与えるか？」ですが、
意義のある結果は得られませんでした。
(この後、かわいい女性の3DCGをハグしたら、めちゃくちゃドキドキして戸惑ったのは、内緒です)


# まとめ

ここまで読んでもらった方には、私がこれからどのような実験を行おうとしているかが、多少は分かってもらえたのではないのでしょうか？

「これらの錯覚が人間の本能によるものではないか？」という直感が正しかったのかはまだ不明ですが、大まかな方向性は確認することができました。

まだまだ詳細な実験が必要なようです。

習慣の力:
https://qiita.com/pipe_render/items/49a15c51e945849745b5