OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonで入力された整数を素因数分解 ver.2

# はじめに
以前作成した[Pythonで入力された整数を素因数分解 ver.1](https://qiita.com/totusuna/items/87a10755a25dc310c17a)での、入力された整数が素数だった場合の実行時間が長い問題を解決します。

#実際のプログラム
~~~Python
from sympy import primerange
inn = n = int(input("素数か確かめたい数を入力してください。>> "))
num = int(n**(1/2)) + 1
primlist = list(primerange(2,num)) 
yaku = []

for i in primlist:
    if inn % i == 0: #1
        print(inn,"は合成数です。")
        for i in list(primerange(i, (n +1)/i)):  #2
            if n == 1:　#3
                break
            while n % i == 0:
                n /= i
                yaku.append(i)

        print("素因数分解すると",yaku, "です。")
        break
    elif i == primlist[-1] :
        print(inn, "は素数です。")
~~~

###変更点
素数だった際の判定が遅すぎることを解決するために、#1で素因数分解を行う前に入力された整数が素数か判定するようにしました。
合成数だった場合は、#2から先の処理を行うようにしてあります。#3の if 構文は、素数リストの最後まで行く前に n の素因数分解が完了した際に即座に結果を表示する為に付け加えました。

###速さの比較
jupyter Notebook の %%timeit を用いて時間を測定しました。
7桁の素数として2281607、7桁の合成数として5241234(2×3×873539)を用いました。
素数
ver.1：1.98 s ± 30.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
ver.2：1.17 ms ± 25.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

合成数
ver.1：4.63 s ± 40.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
ver.2：4.56 s ± 75.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

###考察
素数が入力された際の実行速度は1.98 **s** → 1.17 **ms** と大幅な速度改善ができました。しかし、合成数が入力された場合では実際の処理方法自体が変わっていないので4.63 s →4.56 s と改善が認められませんでした。

#反省点
今回の目標であった素数であった場合の実行速度の改善ができたので一先ず満足しています。ただ、素因数分解を行う方法を改善しない限り本質的な速度改善ができないので、この点を詰めていきたいと思います。
最後まで読んで下さいまして有難うございました。
初心者によるプログラミング学習ログ 189日目

# 100日チャレンジの189日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

189日目は
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>189日目<br><br>udemyでbootstrap<br><br>メンターさんの課題のコードレビュー終わるまでちがうことしてます<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1207752425009893376?ref_src=twsrc%5Etfw">December 19, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
CentOS7用Apache httpd 2.4 updateのRetirement Date (SLC)

# はじめに

Red Hat Software Collections 3.4にて、CentOS7系のApache httpd 2.4 updateのRetirement Dateが4年くらい伸びた。
関連情報を見つけられなかったのでここにメモを残しておく。

## 確認事項

- Red Hat Software Collections 3.4が出た前後でRed Hat Software Collections Product Life Cycleのページが更新され、CentOS6系とCentOS7系にLife Cycleが記載されているページが分割された。[^1]
- 少なくとも2019-10-14までは2024年的な情報は記載されていなかった。[^2]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502524/6f5979a0-ca5e-3166-4129-1d5c954aa1e7.png)
- 新しくできたCentOS7系のページでは2024になっている。[^3]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502524/01b0d415-9397-7dc4-6fc1-a0c949dcd801.png)


[^1]: [Red Hat Software Collections \- Red Hat Customer Portal](https://access.redhat.com/support/policy/updates/rhscl)
[^2]: [Red Hat Software Collections Product Life Cycle \- Red Hat Customer Portal](https://web.archive.org/web/20191014082934/https://access.redhat.com/support/policy/updates/rhscl/)
[^3]: [Red Hat Enterprise Linux 7 Software Collections Product Life Cycle \- Red Hat Customer Portal](https://access.redhat.com/support/policy/updates/rhscl-rhel7)
Ruby on rails エラーメッセージの表示　

##エラーメッセージの表示方法

form_forヘルパーで作る入力フォーム内に
エラーメッセージを表示させる方法を学んだのでまとめておきます。

初めに一例のコードを書きます。
前提として、入力フォームにバリデーションがかかっていることとします。
エラーメッセージとバリデーションはセットです。

```
<ul>
  <% @user.errors.full_messages.each do |msg| %>
   <li>
    <%= msg %>
   </li>
  <% end %>
</ul>
```


errors.full_messagesは全てのエラーメッセージを配列で取得します。

次に、取得したエラーメッセージを一つずつmsgという変数に代入します。

そして、liを使ってエラーメッセージの数だけリストが作られます。

参考
https://qiita.com/ryuuuuuuuuuu/items/1a1e53d062bff774d88a
異なるバージョンのCUDAを使い分ける単純な方法

前記事(https://qiita.com/takeajioka/items/429451db33051da83e54 ) では、UbuntuでのDeep Learning環境の構築方法について書きましたが、CUDAは使いたいソフトに応じてバージョンが違います。
使い分けたい場面として、例えばtensorflowのバージョンが違うと対応するCUDAが違うことがあります。
そうなると、複数のソフトを使用する場合には複数のCUDAが必要になります。
もちろんDockerを使用する方法がありますが、**いちいち仮想環境を設定・管理するのは面倒**です。
もっと単純な方法は無いのでしょうか。

#解決方法
やり方は単純で複数のバージョンのCUDAそれぞれをインストールして、それぞれにパスを通しただけです。
インストールするときは、**シンボリックリンクは作成しません**。
パスを通すのは.bashrcの最初の部分に以下のように追加します。

```
export PATH="/usr/local/cuda-8.0/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda-8.0/lib64:$LD_LIBRARY_PATH"
export PATH="/usr/local/cuda-9.0/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda-9.0/lib64:$LD_LIBRARY_PATH"
export PATH="/usr/local/cuda-10.0/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda-10.0/lib64:$LD_LIBRARY_PATH"
```
こうすることで使い分けて、使用することができました。
複数のバージョンのtensorflow-gpuを使っても特にエラーになりませんでした。
tensorflowが勝手に対応したCUDAを使用するようです。

#cuDNNの複数バージョンの使用方法
cuDNNの場合は、CUDAのバージョンが違う場合は違うフォルダに入るため複数のインストールができるようです。
またcuDNN7と6など、メジャーバージョン違う場合も複数の使い分けができるようです。
使い分けられない例として、同じCUDAバージョンでcuDNNのメジャーバージョンも同じ場合です。
例えばCUDA9.0のcuDNN7.3.1と7.1.4です。
この場合は、逐次使いたい方のcuDNNをインストールして上書きすれば使えるようになります。
そのため、そこまで手間ではありません。
【画像処理100本ノックに挑戦】Q.26. Bi-linear補間

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)

# Q.26. Bi-linear補間
> Bi-linear補間により画像を1.5倍に拡大せよ。

バイリニア補間は時々使っていますが、式の導出はしたことがなかったのでこの機会に考えてみます。

まず、簡単のために一次元で考えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/a4ac8286-b2b9-3ec2-ee84-01f099c8f50d.png)

上の図の$x=i$の位置の関数値$I(i)$及び、$x=i+1$の位置の関数値$I(i+1)$を既知とします。この間の位置$x$における関数値の推定が目的です。推定量は$x$の関数となるわけです。$x=i,i+1$における値を拘束条件とするだけでは条件を満たす関数はいくらでも存在するわけですが、一番簡単なのは一次関数です。一次関数に限定すれば、拘束条件を満たす関数は

```math
I(x) = \{I(i+1)-I(i)\}(x-i) + I(i)
```

しかありません。二次元で考えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/2aafb7d2-c97e-74cc-c21a-2b1bac63fcef.png)

上図の直線A上で線形補間を考えれば

```math
I(y;x=i) = \{I(i,j+1)-I(i,j)\}(y-j) + I(i,j)
```

となります。同様に直線B上では

```math
I(y;x=i+1) = \{I(i+1,j+1)-I(i+1,j)\}(y-j) + I(i+1,j)
```

となります。点線上の左の点を$I(y;x=i)$とし、右の点を$I(y;x=i+1)$とします。この二つの点の間の点$(x,y)$の値はこれらの線形補間とします。

```math
I(x,y) = \{I(y;x=i+1)-I(y;x=i)\}(x-i) + I(y;x=i)
```

これに具体的な式を入れてやればバイリニア補間の式となります。100本ノックの問題文に限らず、距離で重みづけする、という説明が多いですが、ここでいう距離は二次元ユークリッド距離でないことに注意が必要です。

```c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();

	double a = 1.5;
	int Width = width * a, Height = height * a;

	PPM ppm2(Width, Height);

	auto LI = [&](double x, double Il, double Ir)
	{
		return (Ir - Il) * (x - (int)x) + Il;
	};
	
	for(int J=0; J<Height; J++)
		for (int I = 0; I < Width; I++)
		{
			double x = I / a;
			double y = J / a;
			int i = x, j = y;
			double dx = x - i, dy = y - j;
			if (i + 1 < width && j + 1 < height)
			{
				double Ir = LI(y, ppm(i + 1, j, 'r'), ppm(i + 1, j + 1, 'r'));
				double Il = LI(y, ppm(i, j, 'r'), ppm(i, j + 1, 'r'));
				ppm2(I, J, 'r') = LI(x, Il, Ir);
			}
			else ppm2(I, J, 'r') = ppm(i, j, 'r');

			if (i + 1 < width && j + 1 < height)
			{
				double Ir = LI(y, ppm(i + 1, j, 'g'), ppm(i + 1, j + 1, 'g'));
				double Il = LI(y, ppm(i, j, 'g'), ppm(i, j + 1, 'g'));
				ppm2(I, J, 'g') = LI(x, Il, Ir);
			}
			else ppm2(I, J, 'g') = ppm(i, j, 'g');

			if (i + 1 < width && j + 1 < height)
			{
				double Ir = LI(y, ppm(i + 1, j, 'b'), ppm(i + 1, j + 1, 'b'));
				double Il = LI(y, ppm(i, j, 'b'), ppm(i, j + 1, 'b'));
				ppm2(I, J, 'b') = LI(x, Il, Ir);
			}
			else ppm2(I, J, 'b') = ppm(i, j, 'b');
		}

	ppm2.Flush("out.ppm");
	return 0;
}

```
![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/40b26f67-3456-88ae-2683-7049110ad6db.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/a507e011-da72-471d-efd7-aaefe344c5f7.png)

端っこの処理がいい加減ですが、まあよしとします。
恩師に捧ぐ！百ます計算ジェネレーター

# はじめに

[Pythonその4 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/python4) 20 日目の記事です。

## 背景

みなさん、“百ます計算”をしていますか？してましたか？九九を計算するトレーニングとして使われるものです。実は、@daikikatsuragawa はその道を極めており、地元では負け知らずでした。

時は流れ、2019年某日、ふと思いました。
「先生、あれ、自力で作っていたのか…？」

もし、そうであった場合、以下のデメリット（面倒）があります。

- 行と列をランダムに並び替える面倒
- 解答を計算する面倒

「先生から教わったもので…先生に還元したい…」そんなモチベーションにより、“百ます計算ジェネレーター”と銘打って動作するPythonのプログラムを書きました。

お父さん、お母さんがお子さんに作ってあげてもいいかもしれませんね。

## Pythonを選択した理由

- Google Colaboratoryにより実行可能です。（環境構築の必要なし！）

# 百ます計算ジェネレーター

```python:百ます計算ジェネレーター.py
​import pandas as pd

# 100ます計算の問題と解答をデータフレーム型で出力する関数
def hsc_gen():
    # 行列の長さ
    hsc_range = 10
    # 0〜9を格納した元となる配列
    nums = pd.np.array(range(hsc_range))

    # 配列をシャッフル！
    pd.np.random.shuffle(nums)
    r = nums.copy()
    # 配列をシャッフル！
    pd.np.random.shuffle(nums)
    c = nums.copy()

    # 回答欄を空白にしたデータフレームの作成
    hsc_q = pd.DataFrame(pd.np.zeros((hsc_range, hsc_range), dtype=object), index=r, columns=c)
    for i in list(range(hsc_range)):
        for j in list(range(hsc_range)):
            hsc_q[i][j]=""

    # 掛け算の結果をデータフレームに代入
    hsc_a = pd.DataFrame(pd.np.outer(r, c), index=r, columns=c)
    return hsc_q, hsc_a

hsc_q, hsc_a = hscgen()

# csvとして出力
hsc_q.to_csv('hsc_q.csv')
hsc_a.to_csv('hsc_a.csv')
```

これで、csvに書き出しました。あとは生成したファイルをエクセルなどで開いてよしなに枠をつけたら完成！（↓出力例）

`hsc_q.csv`

|   | 6 | 0 | 7 | 5 | 4 | 2 | 1 | 3 | 9 | 8 |
|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| 8 |   |   |   |   |   |   |   |   |   |   |
| 6 |   |   |   |   |   |   |   |   |   |   |
| 4 |   |   |   |   |   |   |   |   |   |   |
| 0 |   |   |   |   |   |   |   |   |   |   |
| 9 |   |   |   |   |   |   |   |   |   |   |
| 1 |   |   |   |   |   |   |   |   |   |   |
| 5 |   |   |   |   |   |   |   |   |   |   |
| 2 |   |   |   |   |   |   |   |   |   |   |
| 7 |   |   |   |   |   |   |   |   |   |   |
| 3 |   |   |   |   |   |   |   |   |   |   |

`hsc_a.csv`

|   | 6 | 0 | 7 | 5 | 4 | 2 | 1 | 3 | 9 | 8 |
|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| 8 | 48|  0| 56| 40| 32| 16|  8| 24| 72| 64|
| 6 | 36|  0| 42| 30| 24| 12|  6| 18| 54| 48|
| 4 | 24|  0| 28| 20| 16|  8|  4| 12| 36| 32|
| 0 |  0|  0|  0|  0|  0|  0|  0|  0|  0|  0|
| 9 | 54|  0| 63| 45| 36| 18|  9| 27| 81| 72|
| 1 |  6|  0|  7|  5|  4|  2|  1|  3|  9|  8|
| 5 | 30|  0| 35| 25| 20| 10|  5| 15| 45| 40|
| 2 | 12|  0| 14| 10|  8|  4|  2|  6| 18| 16|
| 7 | 42|  0| 49| 35| 28| 14|  7| 21| 63| 56|
| 3 | 18|  0| 21| 15| 12|  6|  3|  9| 27| 24|

# おわりに

Pythonで百ます計算ジェネレーターを作成しました。プログラミングを使って、お世話になった人へ還元するのもいいことですね。

---

# 付録

## 他形式への出力方法

### htmlファイルとして出力

```python
​hsc_q.to_html('hsc_q.html')
hsc_a.to_html('hsc_a.html')
```

### Markdown記法として出力

```python
!pip install pytablewriter
import pytablewriter

writer = pytablewriter.MarkdownTableWriter()
writer.from_dataframe(hsc_q)
writer.write_table()

writer.from_dataframe(hsc_a)
writer.write_table()
```

## 変更点

投稿以降の大きな変更点を以下に追記します。

- プログラムの修正。@konandoiruasa さんからのアドバイスを元に改善し、再利用が容易にできるよう、主要な部分を関数としました。（2019/12/23）
ガートナーの提唱するバイモーダルIT

IT調査会社ガートナー社の提唱するバイモーダルITについて

See: https://ja.wikipedia.org/wiki/%E3%82%AC%E3%83%BC%E3%83%88%E3%83%8A%E3%83%BC

|攻めのIT|守りのIT|
|:--|--:|
|SoR|SoE|
|モード1|モード2|

# 各用語をざっと説明
## モード1
業務効率化の為のIT
金融システム、ERPなど業務システムなど

## モード2
事業としてのIT
SNS、プラットフォームサービスなど

## SoR
System of Recordの略
記録の為のシステム

### 品質
不整合の無い完全なデータの入出力

## SoE
System of Engagementの略
顧客との繋がりの為のサービス

### 品質
顧客体験の最大化

## 守りのIT
確実な動作を担保するシステムのみを公開

## 攻めのIT
顧客体験を最大化する為に細かいサイクルで公開

# 開発手法
## ウォーターフォール
業務分析からフロー/システム化して要件通りに作る

## アジャイル
ユーザーの行動を分析し、
施策サイクルスピード、ニーズ変化への速さに特化する
Java リストをイテレートする５つの例から省略形に辿り着く

リストのイテレートについて、シンプルなリストを使って書き方を見ていきます。
今回は以下の文字列のリストを使います。

```java:list
final List<String> months = 
Arrays.asList("January", "February", "March", "April", "May", "June", "July", "Augast", "September", "October", "November", "December");
```

これらの要素を順番に標準出力させたいだけです。

### 命令型のスタイル
まずは、for ループを使ってみます。
for ループは命令型のスタイルで、外部イテレータです。
命令型のスタイルでは、「どのように」処理を行うかの多くをプログラマ側で考える必要があります。

#### 1. for ループ（インデックス指定）
特に難しいことはないと思います。1番目の要素から順番に出力しています。
インデックスをわざわざ一つずつインクリメントしながら指定する必要があります。

```java:for-with-index
for (int i = 0; i < months.size(); i++) {
  System.out.println(months.get(i));
}
```

#### 2. for ループ（インデックス指定なし）
インデックスが不要な場合は、単純な for ループよりも高度な制御構文が Java には用意されています。
裏では Iteratorインタフェースが適用されており、hasNext() と next() メソッドが呼び出されています。そのため、リストのサイズを用いて、ループの最後をプログラマ側で指定する必要はありません。

```java:for-without-index
for (final String month : months) {
  System.out.println(month);
}
```

### 関数型のスタイル
Java8 から Iterable インターフェースに forEach メソッドが追加されています。
関数型のスタイルで、内部イテレータです。
関数型のスタイルでは、「何を」行うのかを考えることに集中しやすくなります。

#### 3. foreach() Consumer
foreach() は Consumer 型を引数に取りますが、このインスタンスは accept() メソッドで受け取った引数を処理します。
リスト内の各要素が一つずつ、accept() メソッドに渡されていきますので、その中で標準出力させています。

```java:foreach-comsumer
months.forEach(new Consumer<String>() {
  public void accept(final String month) {
    System.out.println(month);
  }
});
```

#### 4. foreach() Lambda
Lambda 式を使うことで、匿名内部クラス(Consumer インスタンス以下）を置き換えることができます。

```java:foreach-lambda
months.forEach((final String month) -> System.out.println(month));
```
Javaコンパイラは型推論ができるため、以下のように省略が可能となります。ただし、この場合は final が外れてしまいイミュータブルな引数ではなくなります。

```java:foreach-lambda
months.forEach(month -> System.out.println(month));
```

#### 5. foreach() メソッド参照
メソッド参照は Java8 からの機能で、クラス名::メソッド名 が基本形になります。
すでに定義済みのメソッドを引数の指定を省略して実行できるため、更に省略した形になります。

```java:foreach-method-reference
months.forEach(System.out::println);
```
SPA(シングルページアプリケーション)とは

# SPAとは
一言で言うと、ページ遷移をせずに必要な部分だけ、HTMLを書き換えることが出来る技術。

普通は 

```
１、ユーザーがアクションを起こす
２、サーバーに対してリクエストを投げる
３、サーバーがHTMLを生成して返す
４、受け取ったHTMLを表示する
```

SPAの場合だと、

```
１、ユーザーがアクションを起こす
２、必要な部分のデータのみをサーバーに要求
３、変えってきたデータをJavascriptで処理
４、HTMLに反映する
```

これによってブラウザに依存することなく実装出来る。
ハニーポットの結果報告

#12月13日〜12月20日までの観測結果
中国からの攻撃が圧倒的に多かった。
<img width="1680" alt="スクリーンショット 2019-12-20 22.12.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308244/f800cd9e-2d11-08d0-e692-54a5e486d06e.png">

#攻撃者のパスワード利用実績
圧倒的root/adminの実施率。
簡単なパスワードは良くないことを実感。
<img width="1680" alt="スクリーンショット 2019-12-20 22.13.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308244/ee8f776b-74e5-eebd-4f80-d9ffac23a80a.png">
シェルスクリプト：改行あり・なしの値の取得、改行あり・なしのecho

この投稿は[Shell Script Advent Calendar](https://qiita.com/advent-calendar/2019/shellscript) 21日目です

## お願い

ええそれ違うんじゃない？もっとこういうやり方あるよ！

という方は、是非是非コメントで教えていただけると嬉しいです。。

# はじめに

> シェルスクリプト(bash)で、
> 
> 改行入りの値を取得するコマンドを叩いた後に、
> 
> 変数には改行ありの値が入っているはずなのに、
>
> echoで表示した時に改行されたりされなかったりして混乱したというお話

そこで今回は、`値の取得編` と `値の表示編`に分けて、改行に関する備忘録を残します

## 解決方法

サンプルとして、以下のテキストファイル内の値を取得するコマンドを叩くとします

テキストファイル内の値を取得するコマンドについては今回省略します。。

#### sample.txt
```
aaa
bb
ccc
```

#### 値の取得編

- sample.txtの値が`改行なし`で ${FUGA} に`代入される`

```
FUGA=$(echo `sample.txt の値を取ってくるコマンド`)
```

- sample.txtの値が`改行あり`で ${HOGE} に`代入される`

```
HOGE=$(sample.txt の値を取ってくるコマンド)
```

値の取得時に改行を無視する OR しないについては、当初わたしが調べた際は期待した回答が得られなかった。。

圧倒的ぐぐり力不足。。

「`echoコマンド`に`sample.txt の値を取ってくるコマンド`を渡したもの」を変数に代入すると、改行が無視された値が入る

`echoコマンド`を付与せずに、「素?の`sample.txt の値を取ってくるコマンド`」を変数に代入すると、改行ありの値が入る

ちょっと考えると、それはそうなんだよなあ（困惑）

混乱が解けたのでよかった（）

#### 値の表示編

ちょっとややこしい。。

- 改行があっても`無視される`パターン: `echo ${変数}`

```
echo ${FUGA}
# -> そもそも改行が無視されて値が代入されているので、改行がない（されない）

echo ${HOGE}
# -> 改行ありで値が代入されているけれど、改行されない

```
実行結果：

- FUGA
> aaa bb ccc

- HOGE
> aaa bb ccc

- 改行があっても`無視されない`パターン: `echo "${変数}"`

```
echo "${FUGA}"
# -> そもそも改行が無視されて値が代入されているので、改行がない（されない）
echo "${HOGE}"
# -> 改行ありで値が代入されているので、改行される！！
```

実行結果：

- FUGA
> aaa bb ccc

- HOGE
> aaa
>
> bb
>
> ccc

echoについては、ググったら先人たちの知恵がたくさん出てきた。。ありがとうございます。。

# なぜこうなったのか

おそらく、

`値の取得`をする時点で、その値に対して何らかの処理（grepとか）をしたくて、`echo`をつけたりつけなかったり試行錯誤していて、

そのあと値の取得と処理ができるようになって、`echo`が必要なくなったので消したつもりだったんだけど、

ちゃんと消せたところと、消し忘れたところが混在してしまった（ヒューマンエラー）

がために、

改行されないことについて色々とググって調べて試しているうちに、

`値の取得`の時点ですでに`改行が無視されている`のか、`値の表示`の時点で`改行を無視している`のかわからなくなってしまった（混乱）

のだと思われます。。落ち着こうね、休憩しようね

```
HOGE=$(echo "`なんかどっかからlistを取ってくるコマンド`")
```
↑こんな感じのコードを書いた痕跡もあった

# おわりに（感想）

先人たちが残してくれた記録は尊いし、だいたいあってる。。（2回目）

ぐぐるチカラ（キーワードの選定とか、キーワードの繋げかたとか。。）はもっと磨いておこうと思いました。
GoogleAppsScriptで部活の仕事をbot化した

# botを作った経緯
大学のフィギュアスケート部で練習のたびに出欠を確認する必要がありました。
ちょうどプログラミングを勉強し始めたところだったので自動化を試みました。
## それまでの方法
LINE日程調整で部員の出欠を確認
→日程調整の画面を見ながら手打ちで出席者リストを作成
→丁寧な文言を付け足す
→部活の全体LINEに送信

出来上がったメッセージは以下のようなもの。
<img width="308" alt="スクリーンショット 2019-12-20 22.02.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215393/3f5d74e6-a2df-d27e-727e-83b33a44c947.png">

## これ、自動化できないのか…？
できた。
LINE日程調整はおそらくAPIがなかったので、無料でLINEbotが作れるというGoogleAppsScriptなるものを利用して改めてシステムを作り直すことに。

# botの機能
入力
・練習の予定をカレンダーに登録しておく
・スプレッドシートに出欠を入力してもらう
出力
・出席者をまとめて前日の朝に確認
・出欠確認の必要のないイベントは夜に通知

スプレッドシートの出欠表
<img width="649" alt="スクリーンショット 2019-12-20 22.15.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215393/c826a9ab-f171-38a3-e5d7-3c7e253f62c4.png">

<img width="946" alt="スクリーンショット 2019-12-20 21.56.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215393/1c01cc14-76ce-ab69-b7d9-b86ac895e70c.png">

ついでに
・個人トークでの簡単なおしゃべり機能
<img width="420" alt="スクリーンショット 2019-12-20 21.59.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215393/204e1428-6c90-81cf-ff78-d2c0930c813b.png">



# 作り方
コードはgithubに置いています。ファイルを分けるという概念がなかったので無駄に長くなっていますが。
https://github.com/maosasa/club-line-bot

必要なもの
・Googleアカウント
・LINE Developersアカウント
完全無料で利用できます！

以下の記事を参考にしました。
reply
https://qiita.com/tetrapod117/items/e7b48485c98f6b88f311
push
https://qiita.com/n_oshiumi/items/a1a02e03093825f41e01

replyとpushについての説明も書いておきます。
reply
ユーザーが何か送った時にメッセージが送信される。
push
こちらで設定したタイミングでメッセージが送信される。
これらの機能は実装の仕方が違います。
今回の場合で言うと予定のリマインドはpushで、おしゃべり機能はreplyを用いています。

# まとめ
GoogleAppsScriptはGoogleのあらゆるサービスのAPIを簡単に使えるのでとっても楽しいです。一度やり始めると、もっと自動化できることはないかと探してしまうほどです。
面倒なことはGoogleAppsScriptにやらせましょう。
引数の初期化

この投稿は[Shell Script Advent Calendar](https://qiita.com/advent-calendar/2019/shellscript) 20日目です

また、Qiita 初投稿です
間違ったことなどを言っていたらコメント等でご指摘いただけると嬉しいです

# はじめに

> シェルスクリプト(bash)実行時に、引数が渡されなかった際に初期値（数値）を入れたい
>
> 引数が渡された時はその引数を使いたい

上記を実現したかったのにできなくて

至極基本的なところでハマったので、また同じことをするかもしれない()わたしのために備忘録

記事にすれば忘れないと思って。。

## とりあえず思いついた方法で書いてみた（動いた）
```
if [ "$1" = "" ]; then
  NUM=5
else
  NUM=$1
fi
```

## ？？？「1行でかけるよ」　わたし「ええ　なるほど？（驚愕）」
```
${変数名:-初期値}
```

なるほど（なるほど）

できないよ？

## なぜ できなかったのか

代入してなかった（驚愕）（ケアレスミス）

自分で自分にびっくりした。。

$1（第一引数）が設定されていない時、以下のようにして引数の初期化をするんだと考えた

おそらく最初は、`$1`という引数に直接値を代入できないか考えたんだと思う

```
${1:-5}
```

これだけ書いて実行してた。しかしエラる（そりゃそうじゃ）
> 5: command not found

ぐぐるとだいたい初期化で代入されていたのが`文字列`だったので、`数値`だからダメなのかとか色々考えてみたけど、代入してみたらできた

```
NUM=${1:-5}
```

あれできた（驚愕）

最初に書いてた`if文`でも変数に代入してたじゃないか、、、

# おわりに（感想）

先人たちが残してくれた記録は尊いし、だいたい合ってる。。

今抱えている問題を解決するために、 `bash` `引数` `初期値` `変数展開` とかでたんとぐぐったので、いろんな知識が少しだけついた気がした

この問題を解決するのにかかった時間は30分くらいだけど、日をまたいだら、勘違いに気がつけてあっさり解決した

やっぱり、休憩って大事だなと思いました（小並感）たくさん寝よう〜
年末まで毎日webサイトを作り続ける大学生 〜63日目 寿司屋の日常〜

##はじめに
こんにちは！@70days_jsです。

寿司屋の日常を作りました。
寿司屋の店主をホバーしたら客が「旨い！」と言うだけですがご了承ください。

63日目。(2019/12/20)
よろしくお願いします。

##サイトURL
https://sin2cos21.github.io/day63.html

##やったこと
これを作りました。(gif)↓
![test3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/a2ce851d-9de9-ca74-2ccb-b3391932b415.gif)

html↓

```html
  <body>
    <h1>寿司屋の日常</h1>
    <img id="taisyo" src="day63_1.png" alt="寿司屋の大将" />
    <img id="sushi" class="sushi" src="day63_2.png" alt="寿司" />
    <img id="kyaku" src="day48men.png" alt="客" />
    <div id="fukidashi" class="fukidashi"></div>
    <div>↑マウスを乗せてね</div>
  </body>
```

css↓

```css
body {
  margin: 0;
}
img {
  width: 100px;
  height: auto;
}

#kyaku {
  position: absolute;
  left: 700px;
}

.sushi {
  display: none;
}

.sushiZanmai {
  animation: go 1s ease 0.5s;
  animation-fill-mode: forwards;
}

@keyframes go {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(500px);
  }
}

.fukidashi {
  display: none;
  width: 50px;
  margin-top: 10px;
  position: absolute;
  left: 800px;
  text-align: center;
  padding: 30px;
  background-color: black;
  border-radius: 100%;
  z-index: 10;
}

.fukidashi::after {
  color: white;
  content: "旨い!";
}

.fukidashi::before {
  left: -5px;
  margin-top: 2px;
  content: "";
  position: absolute;
  display: block;
  z-index: 1;
  border-style: solid;
  border-color: transparent black;
  border-width: 10px 10px 10px 0px;
}
```

JavaScript↓

```javascript
taisyo.addEventListener("mouseover", function() {
  sushi.classList.remove("sushi");
  sushi.classList.add("sushiZanmai");
  setTimeout(function() {
    fukidashi.style.display = "inline-block";
    sushi.classList.remove("sushiZanmai");
    sushi.classList.add("sushi");
  }, 2000);
});
```

ほとんどcssで実装しています。
JavaScriptはマウスが乗ったかどうかを検知して、スタイルの付け替えだけしています。

「旨い！」の吹き出しはcssの.fukidashiクラスと::befer, ::afterを用いて作っています。

寿司の移動はanimationを用いています。

寿司の移動↓
>@keyframes go {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(500px);
  }
}

animation-fill-modeをforwardsにすることで、animation終了時の状態を保持し、animationが終了しても寿司が店主のもとに帰らないようにしています。
客の元に残った寿司はsetTimeoutで2秒後に消えるようになっています。

>  setTimeout(function() {
    fukidashi.style.display = "inline-block";
    sushi.classList.remove("sushiZanmai");
    sushi.classList.add("sushi");
  }, 2000);


##感想
こういうちょっとしたアニメーションでも、あるのとないのとではwebサイトの印象が変わるのかなとか思いました。
どう変わるかは分かりませんが

最後まで読んでいただきありがとうございます。明日も投稿しますのでよろしくお願いします。

##参考
[アイコン素材ダウンロードサイト「icooon-mono」 | 商用利用可能なアイコン素材が無料(フリー)ダウンロードできるサイト | 6000個以上のアイコン素材を無料でダウンロードできるサイト ICOOON MONO](https://icooon-mono.com/)

素材を使わせていただきました！
Windows Subsystem for LinuxのUbuntuへのServerless frameworkの導入

まずは素直にaptから入れてみる
\$ sudo update
\$ sudo install npm

バージョン確認。滅法古い
\$ npm --version
 3.5.2
\$ node -v
v8.10.0

npmからバージョンアップしたろ！ → ダメでした
\$ sudo npm install npm@latest -g
\$ sudo npm install node@latest -g

> at maybeClose (internal/child_process.js:925:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! node@13.1.0 preinstall: \`node installArchSpecificPackage\`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the node@13.1.0 preinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2019-11-14T04_38_48_757Z-debug.log

一旦 n を導入してそっちから攻める
\$ sudo npm install n -g
\$ sudo n stable

aptから入れた古いバージョンは捨てる
\$ sudo apt purge -y nodejs npm

さてバージョン確認を……うわぁ！ 消えた……あ、再ログインが要るのか
\$ node -v
> -bash: /usr/bin/node: No such file or directory

\$ npm --version
> -bash: /usr/bin/npm: No such file or directory

シェルに入り直す。
\$ exec $SHELL -l

nodeとnpmが無事に最新バージョンになった
\$ node -v
> v12.13.0

\$ npm --version
> 6.12.0

pathは/usr/local/binに変わった
\$ which node
>/usr/local/bin/node

\$ which npm
> /usr/local/bin/npm

本題のServerless Frameworkを入れる
\$ sudo npm install -g serverless

> npm WARN deprecated superagent@3.8.3: Please note that v5.0.1+ of superagent removes User-Agent header by default, therefore you may need to add it yourself (e.g. GitHub blocks requests without a User-Agent header). This notice will go away with v5.0.2+ once it is released.
（中略）
\+ serverless@1.57.0
added 501 packages from 339 contributors in 117.102s

Serverless Frameworkのバージョン確認
\$ serverless --version

> Framework Core: 1.57.0
Plugin: 3.2.3
SDK: 2.2.1
Components Core: 1.1.2
Components CLI: 1.4.0

順番は前後するが、npmをsudoで使うよりも以下のパスの所有者を自身にした方が良さげ
\$sudo chown -R \`whoami\` /usr/local/lib/node_modules
Check! Anomaly Detector の JavaScript ライブラリを Vue.js で試そう！

こんばんは！ @dz_ こと大平かづみです。 👩‍💻:christmas_tree: 

[Azure AI Advent Calendar 2019](https://qiita.com/advent-calendar/2019/azure-ai) 20日目のエントリーです。

(半日ハッカソンのごとくコードを書いたので、若干ランナーズハイ状態で記事を書いています。ラフなテンションをお許しください…！)

## Prologue
Microsoft Cognitive Services といえば、画像分析や Speech-to-text、翻訳などが思い浮かぶと思いますが、実は **Anomaly Detector** という異常検知のサービスも提供されているのをご存知でしょうか？（※まだプレビュー公開です。）

Anomaly Detector は、IoT やログ分析などの分野で活用できるのでとても興味があります。しばらくは C# または Python 向けのクライアントライブラリしかなかったのですが、確認したところ JavaScript のクライアントライブラリも登場していたので早速触ってみます！

- [Anomaly Detector API とは - Azure Cognitive Services | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/cognitive-services/anomaly-detector/overview)

## つくってみました
まず、 ローカルで動かせるデモを作成してみました。

- [dzeyelid/azure-anomaly-detector-js-demo](https://github.com/dzeyelid/azure-anomaly-detector-js-demo)

Cognitive Services のアカウント作成は手でポチポチやるのが面倒なので、ARMテンプレートで書きました♪ コマンドラインでさっと作成することができます。（ニーズはあるのか）

サンプルは、[クイック スタート:Python 用 Anomaly Detector クライアント ライブラリを使用してデータの異常を検出する - Azure Cognitive Services | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/cognitive-services/anomaly-detector/quickstarts/detect-data-anomalies-nodejs-sdk?tabs=windows) を参考に、 Vue で書いてみました。本当に動くだけの最低限しか実装していないので、すごい見た目がさみしいのは勘弁してください。（フロントエンドスキル向上は来年の抱負に…！）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812/4a1365f8-0685-1678-42d2-d20e232b3038.png)

今学んだことはコードにしたので、コードから読み解いてください👩‍💻🚀♪

## 簡単に解説

このサンプルでは、QuickSatrt の[サンプルデータ](https://github.com/Azure-Samples/cognitive-services-quickstart-code/blob/master/javascript/AnomalyDetector/request-data.csv)を使い、Anomaly Detector で異常検知しました。結果はこんな JSON が返ってきます。

読み取りにくいデータ構造に見えますが、おそらくグラフとしてプロットしやすくなっていると思います。異常かどうかは `isAnomary` の値を確認し、配列の同じ位置にあるデータから情報を読み取ります。

```json
{
  "period": 7,
  "expectedValues": [
    32894418.9615615,
    29707932.24471988,
    22651867.032410353,
    24943247.98913801,
    ...
    35344244.421857625
  ],
  "upperMargins": [
    328944.1896156147,
    297079.3224471994,
    226518.67032410204,
    249432.47989137843,
    ...
    353442.44421857595
  ],
  "lowerMargins": [
    328944.1896156147,
    297079.3224471994,
    226518.67032410204,
    249432.47989137843,
    ...
    353442.44421857595
  ],
  "isAnomaly": [
    false,
    false,
    false,
    true,
    ...
    false
  ],
  "isNegativeAnomaly": [
    false,
    false,
    false,
    false,
    ...
    false
  ],
  "isPositiveAnomaly": [
    false,
    false,
    false,
    true,
    ...
    false
  ]
}
```

後日もう少し深堀してみようと思います。

## Epilogue

まずなにから着手したかって、ARMテンプレートでアカウント作るとこでした。完璧！

とはいうものの、今回は時間がギリギリで動かしてみるところまでしかできなかったことは悔やまれます。インタラクティブにデータを入力したり、結果をグラフにプロットするサンプルも作ってみたいです。

また、この Vue アプリを Web app にデプロイしておけばみなさんにも触っていただけるデモ環境として、Web app で公開できたらいいなと思います。更新できたらまたお知らせします～👩‍💻🚀

それでは、良いお年を！🎍🌠
【Rails】 has_manyなどの関連付けをprivateにする方法

#はじめに
モデル間で関連付けを行うと、インスタンス経由で関連する情報を引っ張っこれるようになる。
例えば、Article `has_many` Commentsの関係にすると、下のようにCommentの情報を持ってこれる。

```rb
[1] pry(main)> Article.first.comments
=> [#<Comment:0x00007fb68c8b0ae8...
```
これらは基本 public になっていて、モデル外部からも利用できるようになっている。

しかしある時、関連付けてるけど外部からは使いたくないなあと思いまして。
これをprivateにする方法がないか探してたらあったので共有。

# privateメソッドで引数に指定

```article.rb
class Article < ApplicationRecord
  has_many :comments
  private :comments
end
```
privateにさせたいメソッドを、privateメソッドの引数にするだけでok。
ちゃんとprivateになっているかコンソールで実行してみた。


```rb
[1] pry(main)> Article.first.comments
NoMethodError: private method `comments' called for #<Article:0x00007f8e476ddfa8>
```

うん。大丈夫そうだね。でもあまり使うことはなさそう？


# 参考
stack overflowにも同じような質問があった。
https://stackoverflow.com/questions/12131810/private-association-in-rails
引数ありのprivateメソッド
https://ref.xaio.jp/ruby/classes/module/private
Azure DevOpsでプルリクエストテンプレートを使う

本記事は [Azure DevOps Advent Calendar 2019](https://qiita.com/advent-calendar/2019/azuredevops)  20日目の記事です。

みなさんはAzure DevOpsを使っていてPullRequestの標準化のためにテンプレートを適用したいと思ったことはありませんか？私はあります。GitHubでのやり方は比較的よく目にしますが、Azure DevOpsでできるのか調べたところ、[英語のDocs](https://docs.microsoft.com/en-us/azure/devops/repos/git/pull-request-templates?view=azure-devops)しかなかった&アドベントカレンダーが空いていたので記事にしたいと思います。

※正確にはAzure DevOps内でPullRequestを担うのはAzure Reposという１つのモジュールですが、この記事では一般的な呼称としてAzure DevOpsと記載します。


# 3種類のテンプレート
Azure DevOpsのPRテンプレートには３つの種類があります。上記のDocsでの原文です。カッコ内は意訳です。

- Default pull request templates（デフォルトテンプレート）
  デフォルトで適用されるテンプレート。

- Branch specific pull request templates（ブランチテンプレート）
  特定ブランチに対してのPRのみに適用できるテンプレート。

- Additional pull request templates（追加テンプレート）
　PR作成者が任意で追加できるテンプレート。

# Default pull request templates（デフォルトテンプレート）
このテンプレートが設定されたRepositoryに対してPRを作成すると、このテンプレートが適用されます。以下のディレクトリのどれかに **pull_request_template.md** または **pull_request_template.txt**というファイルを作成することで定義することができます。

- <repository root>/.azuredevops/
- <repository root>/.vsts/
- <repository root>/docs/
- repositoryのルート直下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149212/5359bd9f-79c2-6866-fdd9-50d996ab4392.png)


# Branch specific pull request templates（ブランチテンプレート）
これが設定されたRepositoryのBranchに対してPRを作成すると、このテンプレートが使われます。以下のディレクトリのどれかに **{対象のブランチ名}.md** または **{対象のブランチ名}.txt** というファイルを作成することで定義することができます。(PR先がdevブランチのときにテンプレートを使いたかったらdev.md/txt)
**テンプレートが適用されるときはブランチテンプレート→デフォルトテンプレートの順で探索されるので、対象ブランチであればブランチテンプレートが優先的に適用されます。**

- <repository root>/.azuredevops/pull_request_template/branches/
- <repository root>/.vsts/pull_request_template/branches/
- <repository root>/docs/pull_request_template/branches/
- <repository root>/pull_request_template/branches/

以下のデモではrepositoryのデフォルトテンプレートの他にmasterブランチにブランチテンプレートを設定しています。
destinationにdevelopを選択したときはデフォルトテンプレート、masterを選択したときはmasterブランチテンプレートが設定されているのがわかります。
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149212/4a1dcdcc-b78b-ee64-8843-df8e3c7fce66.gif)



# Additional pull request templates（追加テンプレート）
PR作成画面でPR作成者が任意にテンプレートを使用することができます。以下のディレクトリのどれかに **.md** または **.txt** 拡張子のファイルを作成することで定義することができます。

- <repository root>/.azuredevops/pull_request_template/
- <repository root>/.vsts/pull_request_template/
- <repository root>/docs/pull_request_template/
- <repository root>/pull_request_template/

追加テンプレートではを追加するにはPR作成画面で「Add a template」ドロップダウンを展開して追加します。
追加テンプレートではデフォルトテンプレートやブランチテンプレートも選択することができます。
![ezgif.com-video-to-gif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149212/8e0ea764-2ee0-6ee7-7520-ee283ec08ebe.gif)


以上、よいAzure DevOpsライフを！
D言語くんと過ごすクリスマス🎄

# D言語くんと遊んでみる
12月上旬に2019年のアドベントカレンダーを眺めていると，D言語くんが私の方に近づいてきて何かを語りかけているかのような表情でこちらを見ていたので記事を書くことにしました．

## 概要
- D言語くんのメリークリスマス(メイン)
- Flutterに関して

丁度Flutterの勉強がてらだったので，とても(本当に！)簡単な感じのアプリです．
(D言語くんのアドカレ参加してみたい！という気持ちがかなり先行してしまった...)
# D言語くんのメリークリスマス
D言語くんをタップすると，FlutterのMaterialに入っているありったけのアクセントカラーで
`Merry Christmas!`と言ってくれます．
タップしてる感があまりないですが，以下がその様子です．
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81795/9692cde6-1d10-60af-0b17-a8704e7b7c72.gif)

もっとD言語くんが動けるようにしたかったな〜！（他にやる事があったのにアドカレを課した末ですが）

# Flutterを使ってみたことについて

## 実装
今回のアプリは，画像をタップしたらラベルを表示（追加）するものです．自由な位置に画像等を配置したかったため，`Stack`というウィジットを使用しました．
私が特に悩んだのが，タップしたら画面上のどこかに新規でテキストラベルを表示させる事でした．タップしてコンソールにログを出すのは出来てiOS開発におけるaddSubviewみたいなものがすぐに分かりませんでしたが，`List<Widget>()`を使うと良いみたいです．以下のように，画面パーツを配置しておいて，

```dart:main.dart

Widget build(BuildContext context){
    // 略 dmanImg 
    final hogeWidget = List<Widget>();
    Widget dmanPositioned = Positioned(
      top: 240,
      left: 130,
      child: dmanImg,
    );

    Widget container = Stack(
      children: <Widget>[
        dmanPositioned,
      ]+
      hogeWidget,
    );
    return container;
}

```

`class _hogeState`の中でタップ時の関数内に，

```dart
setState((){
    hogeWidget.add(追加したい何か);
});
```
とすれば出来ました．
全体のコードはこちら：[main.dart](https://github.com/marunomi/dmanXmas/blob/master/lib/main.dart)


### 感想
これはDart言語を使ってiOS,Android,Webのアプリケーションを作れるものです．(Javaに似てるとか聞くけども，Javaを使ってアプリを作った事はないのでそれに関してはよくわからん)
iOSのネイティブで作っていると，真っ白の画面からパーツを片っ端から配置していくような感覚(福笑い的な)があるから，ビューのパーツの並びに対して規則の決められ感(パズルみたいな)が強いなぁと感じた．それゆえにStackっていうウィジットが自由で好きですね．
あと，gitignoreが自動でプロジェクトに入っててびっくりした．
dagger2入門 - basic(@Inject & @Component)


# 概要
* [dagger2入門 - 導入の仕方](https://qiita.com/alingogo/items/e99fb4c1af01fccf5ab4)に、gradleよりdagger2の導入方法を紹介しました
* 今回はdagger2の基本的な使い方を紹介します - @Inject と @Component
* 概念などをここに紹介しなくて、使い方を中心として話します


# 簡単な使い方
### 注入できるクラスを作成して、コンストラクタ前に@Injectを追記

```
class People @Inject constructor() {
    fun doWhat(): String {
        return "eat dinner"
    }
}
```

### Componentを作成して注入先を指定

```
@Component
interface PComponent {
    fun into(home: Home)
}
```

### インスタンス変数を用意
* DaggerPComponentを生成されるクラス


```
class Home {
    @Inject lateinit var people: People

    fun doDinner() {
        DaggerPComponent.create().into(this)
        println(people.doWhat())
    }
}
```


### 結果

```
eat dinner

Process finished with exit code 0
```

# もし注入用クラスにも引数必要場合


```
class Tool @Inject constructor() {
    fun withFork(): String {
        return "eat with fork"
    }
}

class People @Inject constructor(val tool: Tool) {
    fun doWhat(): String {
        return tool.withFork()
    }
}
```

### 結果

```
eat with fork

Process finished with exit code 0
```


# 遷移図
![スクリーンショット 2019-12-20 21.36.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13451/19f27606-16dd-9702-7d52-c39f5018ffc1.png)


# サンプルコード
* https://github.com/fork-alin/study_dagger2_with_kotlin/blob/master/src/main/kotlin/inject_and_component.kt

# ひとつの問題
* 導入したpackageのクラスに、コストラクタに@Injectを追記できません
今年一年で知識不足を心から実感したお話し

[TECOTEC Advent Calendar 2019](https://qiita.com/advent-calendar/2019/tecotec)の記事です。

今年もアドベントカレンダーの時期がやってまいりました。
さて、書くことがありません。

アドベントカレンダーに投稿するのは3年目になるが、今年こそ本当に書くことが無い。
ここ一年間ソースを書くことなく、ディレクション的な事をしていたので本当に無い。

終
制作・著作
━━━━━
Ⓝ◆Ⓚ

苦悶の表情で絞り出しながら考えた末に
この一年間ディレクション的な事をやってる中で、短い人生でやってて良かったなと感じた事を列挙します。m(__)m

## 心からやってて良かったと思えること
### みんな大好きSQL知識
やはり、自らデータベースを弄れるのは便利です。
軽いテストやエラーの確認等、エンジニア無しで自ら行えるのが大きい。

本来ならエンジニアにお願いしないと行えない操作でもちょちょいと実行が出来る(本番は除く)
エンジニアの時間を取らなくて良いのが一番のメリットかも。

### サーバーエンジニアだった記憶
たった2年程度ですが、サーバー側のエンジニアをしていた時期がありました。
私はその時、確かにサーバーエンジニアだったんだ。

真面目な話、ほんの少しの期間だけですが何だかんだ色々と役に立ちました。

* 自分でソースを確認できる。
* 自分でログを確認できる。
* 工数が何となく算出できる。
* エンジニアと交流出来る。

その他、様々な所で役立っていると実感できます。
最後はコミュ力の問題な気がしますが…

### 趣味
最も大事な事かもしれません。
無理矢理でも遊ぶ時間を作って、趣味に走らないと壊れます。

何度か心バッキバキになりましたが、無理矢理にでも時間を作って何とか生きています。
土日にカードゲーム、深夜にゲーム、休みを取って帰省する。
しっかりと趣味を謳歌して、心を休ませないと多分途中で立ち上がれなくなってたと思います。

何か心の支えになる趣味は持っておくことをお勧めします。

## 逆にやってなくて後悔したこと
実はこちらが本番
ディレクションをする中で公開する事も多々あったので、メモ程度に記載します。

### デザイン系の知識
画面の仕様やUI、UX等知識が無くてとても苦労しました。

今まで全くやってこなかった上に、学生時代の美術は底辺レベル
好き嫌いせずに事前に学んでおけば良かったと今でも後悔中デス…

### アプリ開発の知識
こちらも同様、今までにやってない分野なので本当に苦労しました。
事前に携わることは分かっていたので、少しでも先に勉強しておけば良かったと後悔しています。

## 終わりに
拙い文章で失礼しました。
2週間ぐらい何を書こうか考えた結果これだけしか書けなくて本当に申し訳ございません。

次の機会までには書ける内容を勉強しておきます…m(__)m
Google design sprint

2016年、バングラデシュでのハッカソンに参加しました。そこでGoogleデザインスプリントについて学びました。今日は、それについて議論したいと思います。

Google Design Sprintとは何ですか？

グーグルスプリントは、設計、プロトタイピング、および顧客とのアイデアのテストを通じて、重要なビジネス上の質問に答えるための5日間のプロセスです。名前からかもしれないが、あなたは簡単に理解できる、この方法はGoogleによって導入されました。
この手順には合計5つのステップがあります。 1日1ステップを完了すると、5日以内にあらゆる問題の解決策をもたらすことができます。手順は、理解(Understanding)、発散(diverge)、決定(Decide)、プロトタイプ(Prototype)、検証(Validation)です。手順を1つずつ説明します。
![google desing sprint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542616/b2f588c7-3e30-cdba-59d2-7b1b075aba89.png)
理解(Understanding):
ここでの最初のステップは、問題を完全に理解することです。グループのメンバーは、問題のあらゆる詳細を可能な限り明確にする必要があります。

発散(Diverge):
問題を完全に理解した後、すべてのメンバーを他のメンバーから分離し、問題のすべての部分に対して何らかの解決策を提供するようにします。今回は、お互いに何も話し合ってはいけません。

決定(Decide):
次のステップは、単一のソリューションを決定することです。前のステップでは、誰もがすでに問題のすべての部分に対してソリューションを提供していますが、今では、誰もがそのソリューションを提供した理由を伝えようとします。その後、全員が議論を終えた後、全員が問題のすべての部分に対して単一のソリューションを選択するよう投票します。基本的に、この部分はすべての部分の最終的なソリューションを決定することです。

プロトタイプ(Prototype):
次のタスクは、ユーザー/クライアントが理解できるソリューションのプロトタイプを作成することです。

検証(Validation):
この最後の部分では、ユーザーからのソリューションを検証します。プロトタイプをユーザー/クライアントに見せ、レビューをもらいます。
これがグーグルデザインスプリントです。 ITの問題の解決策を見つけることが役立つことを願っています。
#ssmjp 2019/12行ってきた

途中参加でイベントレポート枠の方がたくさんいる＆体調不良で今にも視界がブラックアウトしそうなので感想帳で行こうと思います。資料パスは後で頑張る。

https://ssmjp.connpass.com/event/155381/

ハッシュタグは [#ssmjp](https://twitter.com/search?q=%23ssmjp)

隣の方がHHKBと思ったら打鍵音が大きかったのでliteなのかな……と思いつつ。

なお、LT終了時間がくるとGetWildが流されるあたりおっさんホイホイな空間でした。

## 感想帳

### vssmjp by silpheed_ktさん

Virusというシンセを集めた話。

とりあえず物欲の化身なのはわかった。

### OSCのご紹介 by kenkinoさん

最近OSC行ってないけどたのしいよね。

プラレール計算回路見たかった……。

なぜか婚活セミナーとか、ゆるキャラグランプリとかやってるらしい……え？

次の東京開催は 2020年2月21日 だそうです。

### 映画を年に300本観る技術 by koyhogeさん

ほげ技研

月100本の映画が公開されているとか知らなかった。

見る映画リストからの、見た映画リスト。
2019年で約300本視聴……チケット代で30万超か……。

300本観る技術＝スキあらば観る（迷言）

### 逸般の誤家庭 一般のご家庭にある自作PCとWin 10 Proでできる数十T Byte級データ保管とクラウドバックアップ術 by わっほー☆さん

自宅サーバの数十TBのデータをクラウドバックアップ……？ 考えたくないな。

「WDのHDDのSmartの挙動とかがHGSTと一緒」……ほう、しらなんだ。

50TB分のHDD7台を双方向ミラーで単一ドライブとして

小さい記憶域サイズから大きくしようとするとクラスタ数上限に引っかかるので、63TB指定（現状のWindows最大値）

13TBのバックアップは$30くらい、取り出しはSnowballで$50くらい。オンラインだと$1000超えるとかｗ

### ~~コンテナとその周辺技術に触れて目から鱗が落ちた話 by zinraiさん~~
### 婚活した話 by kuromameさん（代打）

転職して2ヶ月無職をやって、婚活記事を書いていた。

婚活で61人と会った……だと……。身内に3時間半でプレゼンしてみたとか嫌がらせかな……？

noteで全10回 合計7万字のコンテンツを有料公開。自信があるので返金機能もON

次回作は成婚大会から結婚まで。
ちょっと売れたからマーケティングの人にお金払ってコンサルティングして貰う予定。

### インフラはいいぞ by yutaroさん

酔った勢いでLT応募 ← 超大事

LTで予防線を張りすぎて時間が……。

世間の「エンジニア」って「ソフトウェアエンジニア」を指してしまっている「インフラ」は？

インフラの需要はクラウドが来てもなくならない。

ちゃんとインフラをやれる人は重宝される。クラウドによって試すことがしやすくなった。
ついていくの大変だけど、みんな一緒！

「ソフトウェアもいいけど、インフラもいいぞ」

「インフラエンジニアが増えるといいな」

## ssmjp振り返り

平均参加者数64人

出席率85.84％とかすげぇ

飛び抜けたネタ

- DNSの話
- 運用パネルディスカッション
- #ssmjp 2019/11 通常回

普段来ない人（運用スペシャリスト）が来ると人がたくさん来るっぽい

逆に少ないとき

- #ssmjp 2019/10
  - 内容はいつもどおり著名な登壇者もいた
  - 無料勉強会は悪天候に弱い
    - （感想）有料勉強会もカジュアルにキャンセルされますよ？

来れないときにちゃんとキャンセルしてくれている

#ssmjpコミュニティは民度が高い……？

出席率が90/100人で90％とか本当にすごいな……。

次回は会場決まってないけど年明けにスペシャル回です。

## まとめ

場がすごく温まっていた……ssmjpっていつもこうなんだろうか。登壇しやすそう。
登壇狙いたい……。
独習C++の勉強メモ_2章の2

基本的な言語機能②の勉強メモのつづき。
#クラス
「構造多＋メンバー関数」的なものと理解した。つまり、クラスはデータに関連した処理もまとめて扱うことができる。インスタンス化等の用語は省略。
##アクセス指定子とメンバー関数
アクセス修飾子で、メンバー変数やメンバー関数に対して、クラスの外側から（インスタンスから直接呼べるか否か）アクセスできるかどうか設定できる。privateで非公開、publicで公開

具体的なメンバー関数の書き方は以下。今回はclass Aに関して、メンバー変数xの値を読み込むgetterと書き込むsetterを例にする。
**書き方の構造として、メンバー関数はクラスの”内側”に書くのではなく、「クラス名::メンバー関数」としてクラスの外側で書くことに注意**(追記：コメント参照「別に宣言と定義を同時に書くこともできるので違う」）

```C:MemberFunction
//Aクラス
class A{
int x//メンバー変数
//メンバー関数(getter/setterを作る)
public:
int get_x();//xのgetter
void set_x(int new_x)//xのsetter
}

//メンバー関数(getter)
int A::get_x(){//書き方注意
return x;//離れてると思ったメンバー変数にアクセスできるよ！
}
//メンバー関数(setter)
void A::set_x(int new_x){
x = new_x
}
```

#参照
変数に別名をつける行為といえる。

```C:Reference
int& reference = value //変数valueへの参照
```

##ポインタとの違い
ポインタは変数の場所をアドレスとして保存する機能だった。また、ポインタは後から別の変数のポインタを再定義することとが可能だったが、参照は、初期化時に指定した変数以外への参照を変更することはできない。
参照型に何か別の変数を代入処理しても、参照型変数そのもののアドレスは変化しないことに注意。

```C:DifferenceBetweenPointerAndRef
int v1 = 1;
int v2 = 0;
int* pointer = &v1;//v1のポインタ
int& reference = v1;//v1の参照

//この時点で...
//pointerも&referenceもv1と同じアドレス
//*pointerの値は1, referの値も1

pointer = &v2;//pointerが持つアドレスをv2のアドレスへ変換
reference = v2;//参照先をv1からv2へ変換したつもり

//この時点で...
//pointerアドレスはv2のものに変更される、&referenceはアドレスに変化なし
//*pointerの値は0,referenceの値も0
```

##const参照
constな変数を、参照を通して変更されても困るので、この場合もconstつけてconst参照にする。
#型推論
autoを付けて、変数宣言時にinitial値からその型を使って変数を宣言するようにコンパイラに指定する。あたりまえだけど、型推論の参考となる右辺初期値が無いとコンパイルエラー。

```C:Auto
int one(){
return 1;
}

int main(){
auto i = one();//こんな場合でもiはint型と推論される！
}
```

配列（ブレースを使った配列の）の型推論は行わない（List型が得られたり、推測される型が要素数で変わるため）
#エイリアス
型に別名を付けることができる。

```C:Alias
using integer = int //int型に新しい名前integer
```
メンバ関数の定義としては、戻り値の型も含めてクラスの内側なので、seisu型がそのまま使えていることに注目。

```C:NestedName
#include <iostream>

class data {
public:
	using seisu = int;//クラスの中で使う整数の別名
	seisu get_value();
	void set_value(seisu new_value);
private:
	seisu value;
};
//getter関数（::は名前解決で使い、メンバ関数の定義でも使う
data::seisu data::get_value() {//クラス外からのアクセスなので、名前解決する
	return value;
}
//setter関数
void data::set_value(seisu new_value) {
	seisu tmp = new_value;//メンバ関数の中もクラスという扱いなので、seisu型そのまま使える
	value = tmp;
}

int main()
{
	data d;

	using seisuti = data::seisu;//さらに別名を押し込むことも可能
	seisuti value = 100;
	d.set_value(value);//つまりここのvalueは　data::seisu => int型
	std::cout << d.get_value() << std::endl;
}
```
Rack middlewareを使ってRailsアプリケーションにBasic認証を組み込んでみた

この記事は[マネーフォワード アドベントカレンダー](https://adventar.org/calendars/4136)21日目の記事です。


Railsエンジニアの @kamillle です。

今回はRack middlewareでBasic認証をRailsのアプリケーションに組み込んでみました。

# RailsでBasic認証をどうやって実装するか

Googleで `rails basic auth` とググると `api.rubyonrails.org` の[ドキュメント](https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html)がヒットし、`http_basic_authenticate_with`にnameやpasswordというkey名を含んだHashを渡すと、そのコントローラーのアクションに対してBasic認証がかけられることがわかりました。


一行でかけるのでRailsぽくていいなーと思ったですが、同時に下記の違和感を覚えました。

- リクエストがコントローラーに来る前に解決すべきことなのかなと思った
- コントローラーの継承関係を間違うと一部のControllerにBasic認証がかかってなかったってことが起きそう
  - テスト書いておけばいいんですが、全コントローラーのrequest specにBasic認証のテスト書くのもめんどくさい、忘れそう


# Rackがあるじゃないか

Rack middlewareでBasic認証の機構を実装し、 `@app.call(env)` する前にBasic認証することができればRack側で処理が完結するためコントローラーにリクエストが行くこともないし、全エンドポイントに対してBasic認証をかけることができるので、アプリケーションの開発時に認証のことを気にする必要がなくなるんじゃないかなと考えました。


Basic認証のロジックをオレオレで実装したくなかったので、 `Rack basic auth` とかでググってると `Rack::Auth::Basic` という[クラス](https://github.com/rack/rack/blob/master/lib/rack/auth/basic.rb)を見つけました。

このクラスはRFCに沿った形でBasic認証を実装してくれているので、オレオレなことをしなくていいし、使うのも簡単にできそうだったので早速やってみました。


このようなRack middlewareを実装し、

```ruby
# lib/middlewares/basic_auth_middleware.rb 

module Middlewares
  class BasicAuthMiddleware
    def initialize(app)
      @app = app
    end

    def call(env)
      Rack::Auth::Basic.new(@app) do |username, password|
        username == 'username' && password == 'password'
      end.call(env)
    end
  end
end
```

それをミドルウェアスタックに追加しました

```ruby
# config/application.rb

...

require_relative '../lib/middlewares/basic_auth_middleware.rb'

...

module RackBasicAuth
  class Application < Rails::Application
    ...
    ...
    
    config.middleware.use(::Middlewares::BasicAuthMiddleware)
  end
end
```

ここまで実装してRailsのサーバーを立ち上げてみました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176267/648bfd1f-d860-efa9-d5fb-3587d44d44fa.png)

:tada: 

今回Basic認証を実装したアプリケーションは下記のリポジトリで公開しています。
https://github.com/kamillle/rack_basic_auth

# おわりに
Rack::Auth::Basicを使うことでも簡単にBasic認証をアプリケーションに組み込むことができました。

今までRack middlewareを実装したことはなかったのですが、Rails側にリクエストを渡す前にリクエストの解析が可能になるので便利だな〜と思いました(弊社のGitHubのOrganization内のコードを見てみると、一部のエンドポイントにのみIP制限をかけるためにRackを使っているプロジェクトがありました)。
pythonでdiscordのbot作るならフレームワークを使おうね

# はじめに

[いなたつアドカレ](https://qiita.com/advent-calendar/2019/allinatatsu)の二十日目の記事です。

Discordのbotを作るならBot Commands Frameworkを使うと楽だよってお話。

# なにそれ

discordのbotをpythonで作るときにめっちゃ楽にできるフレームワーク(KONAMI)

# じっそー

いんぽーとなど

```py
from discord.ext import commands
import traceback

INITIAL_EXTENSION = 'こぐのぱす'
```
`INITIAL_EXTENSION = 'cogs.hoge'`
- cogs
    - hoge.py
- main.py
- 
ってなってたらこれで登録できます。


main

```py
if __name__ == '__main__':
    bot = MyBot(command_prefix='!')
    bot.run('とーくんをにゅうりょくしてね') 
```

`command_prefix`でコマンドを認識するための識別子を決めます。ここでは「!」を識別子に設定しています。

MyBotのクラス

```py
class MyBot(commands.Bot):

    # MyBotのコンストラクタ。
    def __init__(self, command_prefix):
        super().__init__(command_prefix)
        try:
            self.load_extension(INITIAL_EXTENSION)
        except Exception:
            traceback.print_exc()

    # Botの準備完了時に呼び出されるイベント
    async def on_ready(self):
        print('--------じゅんびちゅ-------')
        print(self.user.name)
        print(self.user.id)
        print('-------------------------')

```

コグを読み出してエラーが出たらエラーを表示する

```hoge.py
from discord.ext import commands # Bot Commands Frameworkのインポート
import discord # discord.pyをインポート

class Hoge(commands.Cog):
    def __init__(self,bot):
        self.bot = bot
        self.players = None

    @commands.command(aliases=['h'])
    async def hello(self, ctx):
        await ctx.send(f'Hello! {ctx.author.name}さん!')

def setup(bot):
    bot.add_cog(Hoge(bot))
```

これで、`!hoge`をすると、`Hello!いなたつさん!`みたいな感じで返してくれます
そして` @commands.command()`の引数に`aliases=['h']`を与えています。これで、`!h`でも`Hello!いなたつさん!`ができます。

さらにサブコマンドなどをつくることもできるので、pythonでdiscordbotを作る時はこれをつかいましょーね。
NativeScript-Vueの$showModalを使ってモーダル表示したらActionBarが消えた

#はじめに
プロジェクトの修正で
今まで`$navigateTo`を使って画面遷移していた箇所を`$showModal`に変更しました。
そして表示していたActionBarが表示されなくなりました。
その時調査したものを整理します。

#結論
いきなり結論ですが、
モーダルのHTML部分を`<Frame></Frame>`で囲まなかったからです。

```
<template>
    <Page class="page">
        （省略）
    </Page>
</template>
```

を

```
<template>
    <Frame>
        <Page class="page">
            （省略）
        </Page>
    </Frame>
</template>
```

に修正したら即解決です。


#再現してみた
[Playground](https://play.nativescript.org/?template=play-vue&id=1aBzaE&v=3)でものすごくシンプルなプロジェクトを用意しました。
~~１０分くらいで。~~

#コード
中にはホーム画面以外にモーダルAとモーダルBがあります。
HTML部分のみ抜粋します。
`<Frame></Frame>`の部分しか変わっていません。

```ModalA.vue
<template>
    <Page>
        <ActionBar title="Modal A ActionBar" />
        <FlexboxLayout flexDirection="column">
            <Label text="I am modal A!" />
            <Button @tap="$modal.close" text="Close" />
        </FlexboxLayout>
    </Page>
</template>
```

```ModalB.vue
<template>
    <Frame>
        <Page>
            <ActionBar title="Modal B ActionBar" />
            <FlexboxLayout flexDirection="column">
                <Label text="I am modal B!" />
                <Button @tap="$modal.close" text="Close" />
            </FlexboxLayout>
        </Page>
    </Frame>
</template>
```


そしてホーム画面。
`$showModal`でモーダルAとモーダルBを表示するためのボタンをそれぞれ用意します。
ボタン配置もすごくテキトーにやりました。
importするだけではHTMLから取得できないのでdataからreturnしています。
fullscreenは…いつもの習慣で入れただけです。
Androidのみ有効です。（iOSは必ずfullscreenになる）

```ModalTest.vue
<template>
    <Page>
        <ActionBar title="ActionBarTest" />
        <GridLayout rows="*, auto, auto, *">
            <Button row="1" text="Modal A"
                @tap="$showModal(modalA,　{ fullscreen: true })"
                class="custom-button" />
            <Button row="2" text="Modal B"
                @tap="$showModal(modalB,　{ fullscreen: true })"
                class="custom-button" />
        </GridLayout>
    </Page>
</template>

<script>
    import modalA from "./ModalA";
    import modalB from "./ModalB";
    export default {
        data() {
            return {
                modalA,
                modalB
            };
        }
    };
</script>
```

#画面

`NativeScript Playground`と`NativeScript Preview`を使い、実際にスマホで動かしてみました。
ホーム画面はこんな感じです。
手抜き感がすごい…
![modalTest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243366/c47502cb-b873-d490-4b38-0dd48011e804.png)

順番にボタンをタップします。
上の`Modal A`ボタンから。
![modalA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243366/ff05064f-7c49-5c48-769a-5eec1c001a83.png)
~~びっくりするほど何もない~~


下の`Modal B`ボタンから。
![modalB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243366/155eb400-7273-9984-9f12-eff8d9e9b1a5.png)
おっ、ActionBarが出てきました！



#参考資料
このIssueを読んでだらすぐ解決できました。
ありがとうございます。
https://github.com/nativescript-vue/nativescript-vue/issues/311
「令和になってもまだDC作業で疲弊してるの？」「してるよ」ってお話

この記事は ウェブクルー Advent Calendar 2019 21日目の記事です。
昨日は@nozominさんの[効率的にバナーを作るために気を付けていること](https://qiita.com/nozomin/items/8913d235df1b3db00f5e)でした。

#はじめに
私はDCと言われると「え？ドリームキャスト？」って反応になるんですが、
今回は「DC＝データセンター」というテイで進めていきます。

最近ではクラウドを使用したサービスが当たり前のようになってきていて、弊社のサービスも基本的にはクラウドに移行しているのですが、
やっぱりなんやかんやでオンプレミス環境も残っていて、DCで管理・運用してるんですよね。
さらに簡易的な作業であればDCの職員さんに依頼すれば事足りるので、DC内部で作業する機会は減っていると思います。

実際弊社でもDCに行ったことが無い人が多数なので、そんな人向けに私がDCで作業していて「やっぱ辛えわ」って思ったアレコレについて書きたいと思います。

※DCの設備云々やラッキングの考え方等については、契約しているDCのマニュアルや既に様々な方が執筆した記事が多数あるので、本記事では言及しません。

#やっぱ辛えわ その１ 室温
これはDC作業する人にとってはあるあるなんですけど、DCのサーバールームは機器の冷却の為に常にほぼ一定の温度になっています。
冬はむしろ外気に比べれば若干温かいかもしれませんが、夏は薄着のまま長時間作業していると辛いです。
夏にDCで作業する可能性がある人は上着を持ち歩くか職場などに常備しておくと良さそうです。

#やっぱ辛えわ その２ 室度
前述の室温と同様で空調の問題なのですが、サーバールーム内は非常に乾燥しています。
精密機械がある為、サーバールーム内は基本的に飲食禁止なので長時間の作業は喉には非常に宜しくないです。
こちらについてはマスクをするとか定期的に飲食可能なスペースで水分補給とかすればいいんですかね・・
私は一時期はどう対策しても体調崩してたので、「あいつDC行くと体調崩すから」ってことでDC行かなくなりましたね。
今はどういうわけか大丈夫です。

#やっぱ辛えわ その３ ゲージナット
機器のラッキングをする場合ですが、ラックにこんな感じのナットを取りつけます。
![ゲージナット.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315407/e56dcabd-adec-600c-2aca-4ad90431206e.jpeg)
こんな感じ。この後専用のネジで機器を固定。
![ゲージナット取付.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315407/3a4210e1-8502-b272-6e38-5e1716b69a54.jpeg)
###これがめっちゃ辛い！
設置するときにナットの爪のところ思いっきり「ギュー、パチン」って感じではめ込むんですが（結構ナットが固い）、
数十とか数百個とかを素手でやると指がね・・。どちらかというと外す方が辛いです。
まあこれも取付や取り外し専用の道具があるみたいなんですが、（【ケージナットツール】で検索すると出てきます）
私は使ったことないですね。使う機会あるか微妙だと買うか迷う。

#やっぱ辛えわ その４ ラックマウント
ラックマウントって単純に機器をラックに設置する作業なんですが、機器によってはめちゃめちゃ重い（機器によっては100kg以上ある）
これ皆どうしてるんでしょうね？まあ複数人で作業すればいいって話なんでしょうけど、ラック前のスペースが狭かったりするので場合によっては案外キツイです。
普段あまり体を動かさないエンジニアの方もサーバーのマウント作業に備えて筋トレするのはどうでしょう？

#おまけ
この間新しく契約したDCに初めて行ったんですが、こんなことがありました。

ワ＝ワイ　デ＝データセンターの職員さん

```
ワ「このDC私来たの初めてなんですが」
デ「それでしたら一通り施設内を案内できますよ。」
ワ「あー案内は大丈夫です。」
###数分後
ワ「すいません。やっぱり案内お願いします。」
```

DCの中はどこも似たような構造になってるのと、ドアの前とか横に何にも書いてないので普通に迷いました。
DC初心者の方は事前に調べるとか施設案内の有無を確認するといいですね。

#最後に
他にも色々とあるので、後日追記するかもしれません。
それと「やっぱ辛えわ」を多用しましたが令和なので・・・
令和なので・・・（伝わってくれという気持ち）

明日は@wcsakuraiさんです。
よろしくお願いします。