OmniAICreator/Qiita-1.07M huggingface dataset:
設計の考え方メモ


#One-Way Door
・もちろんスピードは重要だが、その中でも全体に大きな影響を与えるもの、後から変更することが難しい物は
ちゃんと考えて決めるべし。「本当にそれで大丈夫か？」
・データの置き場、将来的な活用方法
・データベース設計
・クラウドプラットフォーム




##参考
AWS 2020/04 STARTUP DAY スピード？スケール？非エンジニアもおさえておきたい技術選定
開放閉鎖の原則

##開放閉鎖の原則 (Open/closed principle)
拡張に対して開いて (open) いなければならず、
修正に対して閉じて (closed) いなければならない

上記原則に従ったソフトウェアは、既存のソースコードを変更することなく、振る舞いを変更することができる

[wikipedia](https://ja.wikipedia.org/wiki/開放閉鎖の原則)

### ある日の会話
私「なんとなくしかわからない...。つまり、どういうこと？」

夫「SOLID原則の中で、一番何言ってるのかわからない箇所かも」
夫「実際コードを書いて説明するよ」

```php:悪い例_コントローラー
class BadSampleController
{
    public function BadSample()
    {
        $class = new Update(new DbConnection());

        //エンドユーザー
        $class->updateUser($userName, $address);
        //管理者ユーザー
        $class->updateAdmin($userName, $address, $authority);
    }
}
```
```php:悪い例_下位ロジック
class Update
{
    public function __construct(DbConnection $connection)
    {
        $this->connection = $connection;
    }

    public function updateUser($userName, $address)
    {
        $this->connection->begin();

        // $userName, $addressの更新処理

        $this->connection->commmit();
    }

    public function updateAdmin($userName, $address, $authority)
    {
        $this->connection->begin();

        // $userName, $address, $authorityの更新処理

        $this->connection->commmit();
    }
}
```
兄「この例だと、更新対象が増える度に、メソッドを追加しなくちゃならないから**修正に対して閉じてない**ということ」

私「わかりやすくいうと、「店舗ユーザー」を追加する場合は、Updateクラスにメソッドを追加することになるってことか・・・」

私「逆に、更新対象が増えてもメソッドを追加しなくてもいいのが**修正に対して閉じてる**のね」

兄「そ。じゃあどうすればいい？って思うよね？」

私「うん。...インターフェイスとか使うのかな？」

兄「正解！　コードを書いてみようか」

```php:良い例_コントローラー
class SampleController
{
        $class = new Update(new DbConnection());

        //エンドユーザー
        $class->update(new User());
        //管理者ユーザー
        $class->update(new Admin());
}
```
```php:良い例_下位ロジック
class Update
{
    public function __construct(DbConnection $connection)
    {
        $this->connection = $connection;
    }

    public function update(UpdateInterface $update)
    {
        $this->connection->begin();

        $update->updateUser();

        $this->connection->commmit();
    }
}
```
```php:良い例_インターフェイス
interface UpdateInterface
{
    public function updateUser();
}
```
```php:良い例_エンドユーザークラス
class User implements UpdateInterface
{
    public function __construct(DbConnection $connection)
    {
        $this->connection = $connection;
    }

    /**
     * エンドユーザーに対する更新処理を記載する
     */
    public function updateUser(){
        // $userName, $addressの更新処理
    }
}
```
```php:良い例_管理者クラス
class Admin implements UpdateInterface
{
    public function __construct(DbConnection $connection)
    {
        $this->connection = $connection;
    }

    /**
     * 管理者ユーザーに対する更新処理を記載する
     */
    public function updateUser(){
        // $userName, $address, $authorityの更新処理
    }
}
```
兄「こうすると、下位ロジックにメソッドを追加しなくてもよくなったでしょ」

私「たしかに！」
私「じゃあ、店舗ユーザーを増やしたいってなった時は、**店舗ユーザークラスの作成とコントローラーへの追記だけでOK**ってことだよね？」

兄「そうだよ」

私「めっちゃいいやつ....」

おわり

###関連_SOLID原則の記事
[単一責任の原則](https://qiita.com/gfmc121212/items/c8a13c8d6c0afa2c047b)
Django DRF 好きなContextを返す

# やりたいこと
- 好きなコンテキストを返す

それでは行ってみよう！

# コード
views.py

```
class HogehogeListView(views.APIView):
    def get(self, request, *args, **kwargs):

        # シリアライザの設定
        book = Book.objects.all()
        serializer = BookSerializer(book, many=True)

        return Response(serializer.data, status=status.HTTP_200_OK)

```

serializers.py

```
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['id', 'name']

    def to_representation(self, instance):
        ret = super().to_representation(instance)

        context = {
            "name": ret["name"],
            "piyo": "piyo" 
        }

        return context
```

こんな感じで、to_representationをオーバーライド すれば、好きな内容を入れます。
Trezor攻略

#Trezor攻略
小さいハードウエアに暗号資産を保管するためのカギを入れられるという事に感動し、
もっとTrezorと仲良くなれないかを模索してみたい。

*ひとまず備忘録として記録

##localhostで繋げてみる
https://wiki.trezor.io/User_manual:Running_a_local_instance_of_Trezor_Wallet
これはつまり、localのマシンでtrezor.ioサイトと同じことをする、という事だ。
これはこれで必要なものだが、もうちょっと深く掘り下げたい。

具体的には、connect APIを使ってみたい、ということだ。

##trezorctlで繋ぐ
https://wiki.trezor.io/Using_trezorctl_commands_with_Trezor#Commands.2C_options_and_examples
pythonをインストールして、trezorを繋げて、trezorctl のコマンドを打つだけ。
理想的な環境、手順である！！

```PS C:\Users\xxxx> trezorctl get-address -n "m/49'/0'/0'/0/0" -t "p2shsegwit" -d
WebUSB transport is disabled: Could not find module 'libusb-1.0.dll' (or one of its dependencies). Try using the full path with constructor syntax.
Use the numeric keypad to describe number positions. The layout is:
    7 8 9
    4 5 6
    1 2 3
Please enter current PIN:
Please confirm action on your Trezor device.
```
無事成功！！すごく簡単！！
ちなみに、コマンドを実行する際には、認証が必要なようで、trezorお得意のPIN入力の儀式が必要。
上記のテンキーのような表示の理解が重要だが、私が押すのはあくまでPCのキーボードなのである。
で、trezorに表示されている散らばった１～９の数字の位置と上記のテンキーの位置を当てはめて
タイピングするのだ。
よく分からないと思いますが、やってみてくださいｗ
専用のテンキーがあると良いと思う。

~~でも、これはアドレス大量生産には向いてないなあ～
trezor walletみたいにポンポン打てる状態が望ましいのだ。（２０個までしか作れないが）~~
毎回、PIN入力を要求されるのかと思ったが、そうではないみたいなので、
trezorのボタンを押しまくる、という手作業はあるものの、耐えられるレベルだと思う。
trezor walletだと２０個からのアドレスを刷るとそれ以上刷れなくなるが
その制限は発生しない。（とは言え、walletとして残高が確認できるかどうかは別の話であろうから、対策が必要であろう）

一旦この調査結果で満足！！
Django Error: Application labels aren't unique, duplicates: 

# エラー内容

`setting.py`をいじっていたらエラーが出たときの話．以下エラー内容．
英文をきちんと読めばわかる話ですが、ここに書いてあるのは「ラベルが重複していますよ」とのことなので

```
django.core.exceptions.ImproperlyConfigured: Application labels aren't unique, duplicates: auth 
```
## setting.py

以下のような設定

```
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.auth',
    'mysite.apps.MysiteConfig', 
    'mysite.templatetags.vendor',
    'rest_framework.authtoken',
    'rest_framework', 
```

# 解決策

```
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',　　　　　　　<--- 重複しているものどちらかを消す
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.auth',　　　　　　　<--- 重複しているものどちらかを消す
    'mysite.apps.MysiteConfig', 
    'mysite.templatetags.vendor',
    'rest_framework.authtoken',
    'rest_framework', 
```

# 訂正後

凡ミスでしたね．

```
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
April 27, 2020 - 14:30:39
Django version 3.0.5, using settings 'app.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
```
訓練用データの作成

#はじめに
[前回](https://qiita.com/yohiro/items/04e488805433a2f6e03d)集めた画像データを使って、訓練用データを作成する。
画像データのままテンソルフローに渡すと計算時間がかかるため、numpyの配列形式に変換して計算時間を短縮する。

#ソースコード

##インポート

```python
from PIL import Image
import os, glob
import numpy as np
from sklearn import model_selection
```

##変換処理準備

```python
classes = ["monkey", "boar", "crow"]
num_classes = len(classes)
image_size = 50

X = []
Y = []
```

今回は`monkey`, `boar`, `crow`の分類を行うため、そのキーワードを格納しておく。
画像サイズは50x50に統一する。
`X`と`Y`はそれぞれ、画像データと、その画像がmonkey(0)・boar(1)・crow(2)のどれなのかを示すラベル。

```python
for index, classlabel in enumerate(classes):
    photos_dir = "./" + classlabel
    files = glob.glob(photos_dir + "/*.jpg")
    for i, file in enumerate(files):
        if i >= 141: break # monkey,boar,crowそれぞれのデータ数の最小に合わせる
        image = Image.open(file)
        image = image.convert("RGB")
        image = image.resize((image_size, image_size))
        data = np.asarray(image)
        X.append(data)
        Y.append(index)
X = np.array(X)
Y = np.array(Y)
```

`glob()`はワイルドカードのパターン一致でファイル一覧を取得できるメソッドで、filesに以下のようなデータが格納させている。

```
['./monkey\\49757184328.jpg', 
 './monkey\\49767449258.jpg', 
 ...
```

各画像に対して、画像を開き、RGB 256階調形式に変換し、50x50にリサイズする処理を施す。
そのうえで、numpy配列形式(Pythonのリストよりも計算が早いらしい)に変換する。

こうしてできた`X`と`Y`には以下のようなデータが入っている

```:X
(423, 50, 50, 3)の配列
[[[[ 89  92  60]
   [ 85  84  52]
   [ 91  84  51]
   ...
   [177 178  24]
   [142 145  15]
   [231 219  35]]
   ...
```

```:Y
423の配列
[0 0 ... 1 1 ... 2 2 ...]
```

###余談
`data = np.asarray(image)`と`X = np.array(X)`のように、numpy配列への変化に2種類のメソッドが用いられている。リストからnumpy配列に変換する際は同じ振る舞いとなるが、numpy配列からnumpy配列に変換する際に振る舞いが異なる。
参考：https://punhundon-lifeshift.com/array_asarray

##訓練用データの保存

`train_test_split`メソッドを使って`X`と`Y`を、訓練用データとモデル検証用データに分割し、"animal.npy"というファイル名で保存する。

```python
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, Y)
xy = (X_train, X_test, y_train, y_test)
np.save("./animal.npy", xy)
```

`X_train`と`y_train`は317の配列に、
`X_test`と`y_test`は106の配列になっている。
すなわち、`X`と`Y`の約75%のデータがtrainに、約25%のデータがtestに分割されている。
Ruby と Perl で解く AtCoder ABC 045 C ビット全探索 初級メタプログラミング

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。
# 今回のお題
*[AtCoder Beginner Contest 045 C - たくさんの数式](https://atcoder.jp/contests/abc045/tasks/arc061_a)*
<font color="green">Difficulty: 1109</font>

今回のテーマ、ビット全探索　と　メタプログラミング
# Ruby
|桁|記号|桁|記号|桁|計算|
|:--:|:--:|:--:|:--:|:--:|:--:|
|1||2||5||
||||||125|
||||+||12 + 5|
||+||||1 + 25|
||+||+||1 + 2 + 5|

与えられた数列の間に、計算記号を入れたり入れなかったりする問題は、ビット全探索を使用します。

```ruby.rb
s = gets.chomp.split('').to_a
ans = 0
0.upto(2 ** (s.size - 1) - 1) do |i|
  b = i.to_s(2).rjust(s.size - 1, "0")
  sum = s[0].dup
  1.upto(s.size - 1) do |j|
    t = s[j].dup
    if b[j - 1] == "0"
      sum.to_s.concat(t)
    else
      sum.to_s.concat("+").concat(t)
    end
  end
  ans += eval(sum)
end
puts ans
```
```bit.rb
  b = i.to_s(2).rjust(s.size - 1, "0")
```
ここの部分で、ビット全探索用のビット列を生成しています。

```eval.rb
  ans += eval(sum) # => sum = "1+25"
```
メタプログラミングの初級として **eval** を使用しています。
sum の中には計算式が入っています。
*Java* には evalが無いようなので今回は省略しています。

```dup.rb
  sum = s[0].dup # => 値渡し

  sum = s[0]     # => 参照渡し
```
今回初めて~~嵌った~~知ったのですが、配列の場合、参照渡しとなります。
*.dub* を使用せずに sum を変更した場合、s 配列も変更されます。

# Perl
```perl.pl
my @s;
{
  chomp (my $in = <STDIN>);
  @s = split '', $in;
}
my $ans = 0;
for my $i (0..2**$#s-1) {
  my $b = sprintf "%0".$#s."b", $i;
  my $sum = $s[0];
  for my $j (1..$#s) {
    if ("0" eq substr($b, $j-1, 1)) {
      $sum .= $s[$j];
    } else {
      $sum .= "+".$s[$j];
    }
  }
  $ans += eval($sum);
}
print "$ans\n";
```
*Perl* では、*to_i to_s* が不要ですので、シンプルになっています。

||Ruby|Perl|
|:--:|:--:|:--:|
|コード長|330 Byte|344 Byte|
|実行時間|16 ms|8 ms|
|メモリ|1916 KB|512 KB|
# まとめ
+ ABC 111 C を解いた
+ Ruby に詳しくなった
+ Perl に詳しくなった
+ eval に詳しくなった

参照したサイト
*[初心者が混乱しやすいRubyの変数](https://gam0022.net/blog/2013/02/09/ruby-variable/)*
*[Rubyは参照の値渡し](http://obelisk.hatenablog.com/entry/2015/06/02/014246)*
【python】scikit-learnで線形回帰

#前回までのあらすじ#
[前回](https://qiita.com/kikuchiTakuya/items/4da491c53acc87efdb47)でcsvファイルを読み込んで散布図を描画しました
完成したコードと図はこんな感じです

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

data_set = np.loadtxt(
    fname="sampleData.csv",
    dtype="float",
    delimiter=",",
)

#散布図を描画 → scatterを使用する
#1行ずつ取り出して描画
#plt.scatter(x座標の値, y座標の値)
for data in data_set:
    plt.scatter(data[0], data[1])

plt.title("correlation")
plt.xlabel("Average Temperature of SAITAMA")
plt.ylabel("Average Temperature of IWATE")
plt.grid()

plt.show()

```

![scatter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/9af90f8a-361f-e530-512e-460dbcb3c26a.png)



#今回やること#
`scikit-learn`を使用して線形回帰をして回帰直線を描画します

##手順##
1 csvからx座標, y座標のデータを取り出す

```py
#x,yのデータを別配列に格納
x = np.array(1) #numpy配列を用意
y = np.array(1) #このとき先頭にいらないデータが入っている
for data in data_set:
    x = np.append(x, data[0]) #appendでデータを追加
    y = np.append(y, data[1])
x = np.delete(x, 0,0) #先頭のいらないデータを削除
y = np.delete(y, 0,0)
```
2 線形回帰をするモデルに1で取ったx,yをいれる
3 2で作ったモデルで予測を行って直線をつくる
4 matplotlibで描画

#scikit-learnってなんぞ#
回帰とか分類とかをしてくれるモジュールです(ザックリ)
詳しくはこちら→[公式ページ](https://scikit-learn.org/stable/index.html)

#線形回帰モデルを使用するコード#

```py
# 線形回帰用のモジュールをインポート
from sklearn.linear_model import LinearRegression

#回帰直線のx座標用にnumpyのlinspaceで-10から40までの値を均等に100個用意
line_x = np.linspace(-10, 40, 100)

#scikit-learnでの最小二乗法モデルで予測式を求める
model = LinearRegression()
model = model.fit(x.reshape(-1,1), y.reshape(-1,1)) #データをモデルにいれる
model_y = model.predict(line_x.reshape(-1,1)) # 予測
plt.plot(line_x, model_y, color = 'yellow')

```

`model = model.fit(x.reshape(-1,1), y.reshape(-1,1))`ですが, 関数の引数に合うようにnumpy配列の形状を変えています
詳しくは[こちら](https://qiita.com/yosshi4486/items/deb49d5a433a2c8a8ed4)


#完成したコードと図がこちらです#

```py
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

data_set = np.loadtxt(
    fname="sampleData.csv",
    dtype="float",
    delimiter=",",
)
#x,yのデータを別配列に格納
x = np.array(1)
y = np.array(1)
for data in data_set:
    x = np.append(x, data[0])
    y = np.append(y, data[1])
x = np.delete(x, 0,0)
y = np.delete(y, 0,0)


#散布図を描画
for data in data_set:
    plt.scatter(data[0], data[1])


#scikit-learnでの最小二乗法モデルで予測式を求める
model = LinearRegression()
model = model.fit(x.reshape(-1,1), y.reshape(-1,1))
line_x = np.linspace(-10, 40, 100)
model_y = model.predict(line_x.reshape(-1,1))
plt.plot(line_x, model_y, color = 'yellow')

plt.title("correlation")
plt.xlabel("Average Temperature of SAITAMA")
plt.ylabel("Average Temperature of IWATE")
plt.grid()

plt.show()

```

![lineReg_scikit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/6565aef9-5265-c747-a868-8ff46c82b7ae.png)

ではお疲れ様でした
Raspberry PiでLinuxとローカルネットワークでのサーバー構築NextCloudとデスクトップ共有

#NextCloudの構築
休日にRaspberry PiとWindows10でローカルネットワークでのクラウド構築、デスクトップ共有を実施しました。Linuxコマンドの基礎は分かっているものの、SQL・Apache構築など試行錯誤しながらなんとか完成しました。
【進捗報告】未経験からの機械学習を勉強する

# 始めに

まず、当方は都内でシステムエンジニアとして5年勤務しており、
ある程度はシステム開発、プログラミング経験がありますが、
機械学習についてはまったくの初心者です。

また、本記事は自分の備忘と進捗報告（誰に？）がメインになります。
不正確な点が多いことをご了承の上読んでいただけると幸いです。

# aiエンジニアを目指す経緯
「aiエンジニアが今後アツい！」と風の噂で聞いた。
確かに世界的にaiを活用している動きがそこら中にあり、
実際に自分も使っている。（カメラの顔認識、Amazonのおすすめ商品、メールの迷惑フィルタ）

`aiを使ったサービスって革新的なものが多くておもしろい。。。
いまやっている開発よりも面白そうだなぁ。。
よし、勉強してみよう！！ `
というのがきっかけで機械学習の勉強をスタート。

# 数学の勉強をしてみた

まず機械学習の根底は数学であることを知った。
微分と確率、大学に入って学習する線形代数が重要らしい。
当方は高校の数Ⅱ・Bで止まっているので尻込みしつつも勉強を開始。

使用した教材は以下。　
[Chainer Tutorial **step1準備編**](https://tutorials.chainer.org/ja/tutorial.html)

一通り学習してみた結果、
正直言って**「ぜんぜんおもしろくない！！」**

理由としては
 
- 数学の勉強をしていた。（深く掘らず機械学習としてどう用いるのか理解する程度でよかった）
- 実際に開発をしているところを見たことがない。（フレームワークの名前だけ覚えている状態）

ということで、数学の勉強は道半ばではあるが、いったん保留にして、
先に自分の手を動かしながら機械学習のモデル作成をしてみる。


# titanicの生存予測モデルの学習に挑戦

なにか手を動かしつつ実装ができそうなものはないかと探してみた。

その中で、kaggleのコンペで出題された「titanicの生存予測モデル」がとても人気。
多くの人がコードを公開し精度を競っている中で、解説付き記事をアップしている人もいた。

初学者の自分にとってもタイタニック号沈没事故という馴染み深い題材のため興味を引いた。
**これをやってみよう。**

先駆者の残してくださっている解説付き記事は以下を参考にさせていただく。

[タイタニック号の乗客の生存予測〜80%以上の予測精度を超える方法（探索的データ解析編）](https://yolo-kiyoshi.com/2018/12/16/post-951/)

実装時の記事は以下。

作成中。。。


#今後の学習について

以下候補。
### [【保存版・初心者向け】独学でAIエンジニアになりたい人向けのオススメの勉強方法](https://qiita.com/tani_AI_Academy/items/4da02cb056646ba43b9d#comments)

Qiitaで人気のあった記事。これ通りにやってみるのもありだなー。
書籍の紹介が多いから教育量が多そうだけど、これまでまともに書籍を一気通貫でやった試しがないから挫折しそう。


### [機械学習はこれ一本！pythonインストール～機械学習実装まで完全理解講座](https://brain-market.com/u/rin-effort/a/bEjMwYjMgoTZsNWa0JXY)

「とりあえず最短距離で実装までやってみよう！」の有料記事。
いま自分が目指すノリに近い感じがする。




# 支援コメント募集中
当方は独学かつ初心者のため他人からのアドバイスを欲しております。
おすすめの記事、書籍等ございましたらコメントいただけると幸いです。
【忘備録】SQL Server2016 ダウンロードから導入まで

一時的メモ書きなうえに手順
だんだん雑になります。

#ダウンロード方法
①インストールファイルのダウンロード
<https://www.microsoft.com/ja-jp/evalcenter/evaluate-sql-server-2016>

#導入方法
##SQL Server
①左記[インストール]を選択
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/c6cd37f7-4c18-466b-67c8-678ecd76c38b.jpeg)
②中央上段[SQL Serverの新規スタンドアロン インストールを実行するか、既存インストールに機能を追加]を選択
![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/e7b38e7d-57c7-25d4-4cfb-6ba0c9bd5b72.jpeg)

③エディションを選択し、[次へ]を選択
3-1 初期画面
![003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/58acb19a-1899-99e1-40d1-3557df908bf9.jpeg)
3-2 無償エディションの種類
![003-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/05b36ea2-edf6-f59f-a68d-a8a764f8f463.jpeg)
④[ライセンス条項と次に同意します]にチェックを入れ[次へ]を選択
![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/180fdd6f-5a35-b377-ff1a-e7983d4290aa.jpeg)
⑤[次へ]を選択
![005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/f0c2665c-8093-0c19-9ae7-e69261e66830.jpeg)
※要件に合わせ、[Microsoft Updateを使用して更新プログラムを確認する]にチェックを入れる
![006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/cc926631-9c89-86a7-55fc-653537bbec0e.jpeg)
![006-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/682b050d-c5c4-b9ab-0b39-22b93eff9116.jpeg)
⑦要件に合わせ[機能]選択※⑦、[次へ]を選択
![007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/e4b36841-9536-5e95-2551-9a1a25828610.jpeg)
※⑦要件によってはインスタンスルートディレクトリ等変更
⑧インスタンスを選択する
![008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/33e83172-6983-e394-731f-2b2b8f5c7b8d.jpeg)
⑨選択し[次へ]を選択
※サービスアカウントは要件に合わせサービスの状態を変更しておく必要がある。
　インストール後の変更はSSMSを導入し変更する。
![009.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/a1c5bf54-336c-2b17-39f1-4c4f50976897.jpeg)
![009-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/e7fc430c-573f-9c07-8efc-40629b736711.jpeg)

⑩次へを押下
![010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/73e979f0-3e26-ee04-dfe5-21e4668533c3.jpeg)
![010-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/e5390655-a74b-0bb3-2330-f517207ac5a1.jpeg)
![010-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/16848414-cfad-1bfb-7e83-560966660584.jpeg)
![010-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/eb948013-95df-c91a-89cc-6e2c012c1c7a.jpeg)
⑪インストールを押下
![011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/814ff179-5333-57b8-188c-8ff1e0ebe7cf.jpeg)
⑫あとは待つだけ
![012.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425858/697a6ff8-d549-17f3-b5c7-47123a4f4509.jpeg)

おしまい

##SSMS導入について

そのうち書くかも？？？
栃木県の新型コロナウイルス感染症患者の発生状況の表を作成 (その２)

次のページのデータソースを PDF から xlsx に変更しました。
[栃木県の新型コロナウイルス感染症患者の発生状況の表を作成](https://qiita.com/ekzemplaro/items/f3e28d7ff61f47dde002)

データのソースは栃木県です。
>[栃木県における新型コロナウイルス感染症の発生状況および検査状況について](http://www.pref.tochigi.lg.jp/e04/welfare/hoken-eisei/kansen/hp/coronakensahasseijyoukyou.html)

xlsx を JSON へ変換

```bash
./xlsx_tochigi.py 020426hasseijyoukyouitiran.xlsx data_tochigi.json
```

```py:xlsx_tochigi.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
#	xlsx_tochigi.py
#
#						Apr/27/2020
#
# -------------------------------------------------------------------
import sys
import json
from openpyxl import Workbook
from openpyxl import load_workbook
from dateutil.parser import parse
from datetime import timedelta
#
# -------------------------------------------------------------------
def convert_to_date_string_proc(tt):
	pp = parse("1900-1-1") + timedelta(days = tt - 2)
	qq = pp.strftime('%Y-%m-%d')
	return qq
# -------------------------------------------------------------------
def row_process(row,dict_aa):
	unit_aa = {}
	key = "t%03d" % row[0].value
	unit_aa['age'] = row[1].value
	unit_aa['sex'] = row[2].value
	unit_aa['place'] = row[3].value
	unit_aa['date'] = convert_to_date_string_proc(row[4].value)
	dict_aa[key] = unit_aa
#
# -------------------------------------------------------------------
def xlsx_read_proc (xlsx_file):
	dict_aa = {}
	wb = load_workbook (filename = xlsx_file)
	ws = wb.active

	print (ws.max_row)
	max_row = ws.max_row
	for row in ws.rows:
		vv0 = row[0].value
		if str(vv0).isdigit():
#			sys.stderr.write("digit: %d\n" % vv0)
			row_process(row,dict_aa)
		elif vv0 != None: 
			sys.stderr.write("string: " + vv0 + "\n")
		else:
			sys.stderr.write("None\n")
		key = row[0].value
#
	wb.close()
#
	return	dict_aa
# -------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
xlsx_file = sys.argv[1]
file_json = sys.argv[2]
#
sys.stderr.write(xlsx_file + "\n")
sys.stderr.write(file_json + "\n")
#
dict_aa = xlsx_read_proc(xlsx_file)
#
dict_bb = {}
for key in sorted(dict_aa.keys(), reverse=True):
	dict_bb[key] = dict_aa[key]
#
json_str = json.dumps(dict_bb)
#
fp_out = open(file_json,mode='w',encoding='utf-8')
fp_out.write(json_str)
fp_out.close()
#
sys.stderr.write("*** 終了 ***\n")
# -------------------------------------------------------------------
```


ホームページの表示はこちらと同じです。

[栃木県の新型コロナウイルス感染症患者の発生状況の表を作成](https://qiita.com/ekzemplaro/items/f3e28d7ff61f47dde002)
unityでGetInstanceIDを使うと便利だったケース: 簡易UIアニメーション振動メソッドの実装

## 前提
- Dotweenが導入済みであること

## これは何
- GetInstanceIDがDotweenと相性がいいという気づきの紹介
- 下の例でいうと対象のRectTransformを指定して振動開始・任意のタイミングで停止というメソッド

~~~ VibrateRect.cs
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

    public static void VibrateRect(bool isActive, RectTransform rect) {
        var id = rect.GetInstanceID();
        if (isActive) {
            if (DOTween.IsTweening(id)) {
                return;
            }
            var sq = DOTween.Sequence().SetId(id);
            sq.AppendInterval(2f);
            sq.Append(
                rect.DOPunchScale(
                    new Vector3(0.2f, 0.2f, 0.2f),
                    0.2f,
                    1,
                    1
                ).SetEase(Ease.OutExpo).SetLoops(4)
            );
            sq.SetLoops(100);
        } else {
            if (DOTween.IsTweening(id)) {
                DOTween.Complete(id);
            }
        }
    }
~~~

- アニメーション時間の引数増やすのも賢い気がする
PostgreSQLにPostGISをセットアップする

色々試した結果PostGISは2でも3でも、CentOS 7、PostgreSQL 12推奨です。
互換性の都合で、Amazon Linux、Amazon Linux 2は避けるべきです。
本記事は主にCentOS 7について書きますが、CentOS 8でも可能です。
既存環境で既にgdal, geos, projが入っている場合は、エラー対応項を参照してください。

# OS準備
**CentOS 7 (x86_64) - with Updates HVM**
https://aws.amazon.com/marketplace/pp/Centosorg-CentOS-7-x8664-with-Updates-HVM/B00O7WM7QW
AWSでCentOS 7を利用する場合はこちらから、[Continue to Subscribe] -> [Continue to Configuration]を選択肢後、Choose Actionで[Launch through EC2]を選択し、インスタンスを作成します。
執筆当時の最新Software Versionは、2002_01 (Mar 16,2020)です。
セキュリティパッチが適用されている最新のものを選択すると良いと思います。

インスタンスを起動したら、pemファイルを使用しログインします。
初期ユーザーは、ec2-userではなくcentosになります。
`$ ssh centos@[IPv4 パブリック IP] -i [.pemファイルのパス]`

# ソフトウェアインストール
初回ログイン後は、yumを最新にしてください。

```
sudo su
yum update -y
```

## PostgreSQL 12
### RPM Repositoriesのインストール
https://yum.postgresql.org/repopackages.php

```
// CentOS 8
sudo yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm

// CentOS 7
sudo yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
```

### 本体のインストール
```
// PostgreSQL 12 on CentOS 8
sudo dnf -qy module disable postgresql
sudo dnf -y install postgresql12 postgresql12-server

// PostgreSQL 12 on CentOS 7
sudo yum -y install epel-release yum-utils
sudo yum-config-manager --enable pgdg12
sudo yum install postgresql12-server postgresql12
```

### PostgreSQL12 初期設定（CentOS7）
#### 初期化
```
sudo /usr/pgsql-12/bin/postgresql-12-setup initdb
sudo systemctl enable --now postgresql-12
systemctl status postgresql-12
```
↑ statusは、Active: active (running)になっているはず。

#### postgresユーザーのパスワードを設定
```
sudo su - postgres 
psql -c "ALTER USER postgres with password 'YourPassword'"
```

#### ログイン制御
```
sudo vi /var/lib/pgsql/12/data/pg_hba.conf
```

localhostからのアクセス時にパスワード認証(MD5)をさせる場合は、下記を編集する。

```
local   all             all                                     peer
↓
local   all             all                                     md5
```

再起動後、postgresユーザーでログインできるようになる。

```
sudo systemctl restart postgresql-12
psql -U postgres
\q
```

## PostGIS
```
sudo yum -y install epel-release

// PostGIS 2 on PostgreSQL 12
sudo yum install postgis25_12

// PostGIS 3 on PostgreSQL 12
sudo yum install postgis30_12
```

### PostGISを有効化
PostGISがDB単位で有効化が必要です。

```
psql -U postgres
# CREATE USER test_user;
# CREATE DATABASE test_db OWNER test_user;
# ALTER USER test_user with password 'Test';
\q
```

作成したtest_dbに、super user(postgres)でログインし、

```
psql -U postgres -d test_db
```

PostGISを有効化

```
# CREATE EXTENSION postgis;
# SELECT PostGIS_version();

        postgis_version            
---------------------------------------
 3.0 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 行)

```

#エラー対応
PostGISでは、
`gcc, libxml2, gdal, geos, proj`
あたりが必要になりますが、個別にインストールすると互換性の問題で、CREATE EXTENSION postgisを実行するとエラーになります。

**`gdal, geos, proj`は、pgdg-commonリポジトリのものを使いましょう。**
※ `sudo yum install postgis30_12`では、gdal30-libs, geos38, proj70が入ります。
Docker とユーザー名前空間

ユーザー名前空間は、Linux カーネルに実装されている機能。ユーザー名前空間内では、ホストOSとは独立した UID,GID を持つことができる機能になっている。Docker コンテナを立ち上げたときにデフォルトでは、コンテナ内は root ユーザーになっているが、この root ユーザーはホストOSの root ユーザーとは別のユーザーである。ユーザー名は一緒だがホストOSからは独立した Docker コンテナ内で定義された root ユーザーになっており、また、ユーザー名前空間内の UID,GID とホストOS上の UID,GID の間はマッピングによるひもづけが行われている。

ホストOSの root と Docker コンテナの root が別であることを手を動かしながら確かめて、ユーザー名前空間という機能を見てみる。


## 環境
- ubuntu 18.04 (aws ec2 instance)

Docker の環境も整える。

```bash
$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo systemctl enable docker
$ docker --version
Docker version 19.03.6, build 369ce74a3c
```

## 手を動かして確かめてみる
ホストOSの root ユーザーで作成したファイルは、Docker コンテナの root ユーザーとユーザー名は一緒でも違う root ユーザーなので、Docker コンテナの root ユーザーからは見えないはずである。

```
# root ユーザーにチェンジ
$ sudo su -
$ id
uid=0(root) gid=0(root) groups=0(root)
$ echo "i am from host" > /tmp/file.txt
$ ls -l /tmp/file.txt
-rw-r--r-- 1 root root 15 Apr 27 03:05 /tmp/file.txt
```

dokcer デーモンは、`--userns-remap=default`を指定する。
>注意
>ここで`--userns-remap`を指定なしとした場合は、ホストOSの root ユーザーが作成するユーザー名前空間のユーザーと Docker コンテナ内の root ユーザーがマッピングされ、別のユーザーではあるが、わかりづらく、今回の確認方法では権限上は差異もないので、マッピングするユーザーを root 以外にしている。

```bash
$ sudo dockerd --userns-remap=default &
```
`default`が指定された場合のユーザーは、`dockremap`となる。
このユーザー dockremap が Docker コンテナを立ち上げた場合は、dockremap が作成したユーザー名前空間内の root が Docker コンテナの root となる。

```bash
$ sudo docker pull alpine:3.9.6
$ sudo docker run -itd -v /tmp/:/shared/ --name tmp alpine:3.9.6
$ sudo docker exec -it tmp sh
$ id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
$ cat /tmp/file.txt
$ cat: can't open '/tmp/file.txt': No such file or directory
```
Docker コンテナでの`id`は root であり、`uid=0`となっている。しかし、これは ホストOSの root とは別で、あくまでもユーザー名前空間内での root になっている。`/shared`は、ホストOSにマウントしているため、Docker コンテナとホストOSの root が同一であれば、参照はできるが、違うユーザーなので`No such file or directory`としてエラーが出ている。

## Docker コンテナの root ユーザーは何？

`dockremap`がユーザー名前空間内に作成した`UID=231072`のユーザーであり、このユーザーが Docker コンテナ内では root にマッピングされている。

```
# ホストOSで /etc/subuid を見てみる
$ cat /etc/subuid
lxd:100000:65536
root:100000:65536
ubuntu:165536:65536
dockremap:231072:65536
```
`/etc/subuid`には、ユーザー名前空間を作成したときに、割り振る UID が書いてある。
`ユーザー名:UID開始番号:範囲`となっている。例えば、root ユーザーがユーザー名前空間を作成したときは、100000 ~ 165536 の範囲で UID が振られる。一番最初に振られる UID は、UID開始番号なので、さっき作成した Docker コンテナの root ユーザーは、231072 が振られている。

```
# ホストOSで ps コマンドをするとユーザー231072にたてられた sh が見える
$ ps aux | grep 231072
231072    5880  0.0  0.1   1596  1060 pts/0    Ss+  03:24   0:00 /bin/sh
```

ホストOSでは、UID は231072だが、ユーザー名前空間内では root であり、UID は 0になる。このホストOSの UID と Docker コンテナ内の UID のマッピングまで、ユーザー名前空間の機能である。

## まとめ
Docker は難しい、終わり！

## 参考
https://gihyo.jp/admin/serial/01/linux_containers/0016?page=1
https://knowledge.sakura.ad.jp/5118/
https://linuxjm.osdn.jp/html/LDP_man-pages/man5/proc.5.html
Hacking and Securing Docker Containers (Udemy)
【python】csvファイルを読み込んでmatplotlibで図を表示

#今回使用するデータ#
何となく埼玉県と岩手県の平均気温のデータを使用しました
[ダウンロードはこちら](https://www.data.jma.go.jp/gmd/risk/obsdl/index.php)

#NumPyでcsvファイルを読み込む#
NumPyを使ってcsvファイルを読み込みます
読み込むときに使用する関数は`loadtxt`です
numpy配列が返ってくるのでそれを保持するための変数を用意します(今回はdata_set)

```python

import numpy as np

data_set = np.loadtxt(
    fname="sampleData.csv", #読み込むファイルのパスと名前
    dtype="float", #floatで読み込む
    delimiter=",", #csvなのでカンマで区切る
)
```

#matplotlibで図を表示#
matplotlibで今回は先ほど読み込んだデータを散布図で表示します

```py
import matplotlib.pyplot as plt

#散布図を描画
#描画するだけで図を表示してくれる訳ではないので注意
for data in data_set:
    plt.scatter(data[0], data[1])

plt.title("correlation") #タイトル
plt.xlabel("Average Temperature of SAITAMA") #x軸のラベル
plt.ylabel("Average Temperature of IWATE") #y軸のラベル
plt.grid() #グリッド線を引く(引かなくてもいい別に)

plt.show() #show関数を使うことで図が表示される　書かないと表示されない

```

#完成したコードと図がこちらです#

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

data_set = np.loadtxt(
    fname="sampleData.csv",
    dtype="float",
    delimiter=",",
)

#散布図を描画 → scatterを使用する
#1行ずつ取り出して描画
#plt.scatter(x座標の値, y座標の値)
for data in data_set:
    plt.scatter(data[0], data[1])

plt.title("correlation")
plt.xlabel("Average Temperature of SAITAMA")
plt.ylabel("Average Temperature of IWATE")
plt.grid()

plt.show()

```
![scatter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/72a81ee8-2bf0-478d-f291-b0f207ce9bda.png)


#次回#
[次はこの散布図に回帰直線を描画しようと思います](https://qiita.com/kikuchiTakuya/items/b9db2fe9216172c01b0b)

#参考#
・csvの読み込み
https://www.sejuku.net/blog/73071
・散布図の描画
https://pythondatascience.plavox.info/matplotlib/%E6%95%A3%E5%B8%83%E5%9B%B3
mac でzipが回答できない時

macでzipファイルを解凍しようと試したらこんなエラーが出た

```$ unzip フォルダ名.zip
```

```error:  cannot create 9591/?-????+?i?t?@?C????\ɼ?j.txt
        Illegal byte sequence
```


文字コードの問題らしい


参考にさせていただいた記事

https://qiita.com/koki_h/items/b82fbea16817e605bee5


**ditto**を使ったらうまく行った
php で、KVS をいろいろ比較してみた。( apc vs memcached vs file vs Oracle )

# やってみたこと
php でキャッシングをするにあたって、いろんな方式でのパフォーマンスをチェックしてみました。


# エントリー

やってみたのは、次の4種類。

1. apc
php 内部のキャッシュ。再起動すると消えるし、複数のサーバーで共有もできないけど早い。

2. memcached
KVS といえば。今回はローカルサーバー上の memcached サーバーに接続しています。
接続後の読み書き部分のみを計測しています。

3. file
普通のファイル。/tmp/kvs/ というフォルダと、/dev/shm/kvs/ に、キー名称でファイルを作ってみました。
物理ディレクトリと、共有メモリのディレクトリです。
一回の読み込み（又は書き込み）で、ファイルのオープン、読み込み（又は書き込み）、クローズまでを行いました。

4. Oralce
あて馬です。
ただでさえ遅いデータベース。さらにこれ以外が全部ローカルサーバーなのに、これだけリモートという時点でさらに不利。
値は、VARCHAR2 の列に格納しています。read は、SELECT 文で。write は、MERGE で行いました。


# 結果( 本番サーバー )
本番サーバーで、それぞれ 10,000 回ループして時間を計測してみました。
10,000回実行時の時間を取得しているので、実際の時間は下記の 10,000分の1 です。

|方法				| write(1byte)	|read(1byte)	|write(4K)		|read(4K)		|
|:------------------|--------------:|--------------:|--------------:|--------------:|
|apc |21 ms|6 ms|49 ms|8 ms|
|memcached |266 ms|416 ms|377 ms|412 ms|
|file(/dev/shm/kvs/) |93 ms|83 ms|92 ms|83 ms|
|file(/tmp/kvs/) |197 ms|88 ms|197 ms|87 ms|
|Oralce |5,040 ms|1,927 ms|7,028 ms|3,038 ms|

# まとめ
結果ですが、やはり apc は早い。ダントツですね。

memcached が思ったより遅い。
ネットの他の計測では、apc の 2 倍ぐらいが多かったのに。環境依存？

file アクセスは、物理ディレクトリと、メモリでけっこう違うと思っていたらあんまり変わらなかったのは意外。
特に、読み込みはキャッシュが効くのか誤差の範囲内。

データベースは遅いと思ってたけど、ここまで差があるとは。
それでも 1 回のアクセスに 1ms もかかってないんですから、早いっちゃ早いですね。

あと、1byte でも、4K バイトでも結果があんまり変わらないのも面白いですね。

# 追加結果( 試験サーバー )
本番サーバーだとキャッシュとかの関係なのか、ちょっと直感と反する結果になっていたので、試験用の VM 上のサーバーでも同じものを動かしてみました。
こちらは、CPU, HDD, Memory どれも本番サーバーよりしょぼいです。

|方法				| write(1byte)	|read(1byte)	|write(4K)		|read(4K)		|
|:------------------|--------------:|--------------:|--------------:|--------------:|
|apc |9 ms|5 ms|107 ms|7 ms|
|memcached |1,059 ms|1,694 ms|1,435 ms|1,820 ms|
|file(/tmp/kvs/) |3,816 ms|293 ms|4,608 ms|307 ms| 
|file(/dev/shm/kvs/) |326 ms|247 ms|401 ms|272 ms|
|Oralce |9,399 ms|6,243 ms|12,242 ms|9,485 ms| 

# 追加結果まとめ
試験サーバーの方が、どちらかというと直感にあってる感じになりました。

最近のサーバーの write キャッシュとかってすごいんだなぁと改めて実感。
ただ、memcached はやっぱり、そんなに早くなくて、apc は早い。

当たり前ですが、サーバー環境によって結果は変わるもんですね。
UIToolBarについて、中のボタンタップ時におけるハイライトが不自然にならないように上部の枠線を消す

非常にニッチだが、割と時間がかかったためメモしておく

# やりたいこと
以下のUIToolBarを作る

- ボタンに CustomView でボタンを利用し、ボタンのハイライトをONにする
- 背景に独自画像を設定する
- 上部の枠線は表示したくない

以下がベースのコード
ここで指定している`product_color.png`は1x1サイズの単色画像である

```swift
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // イメージカラーの画像を読み込む
        let productColorImage = UIImage(named: "product_color.png")!

        // UIViewController の背景をイメージカラーの画像に設定
        self.view.backgroundColor = UIColor(patternImage: productColorImage)

        // ツールバーの作成
        let toolBar = UIToolbar()

        // ツールバーのボタン間のスペース部品
        let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

        // ツールバーのボタン1
        let button1 = UIButton()
        button1.setTitle("ボタン1", for: .normal)
        button1.showsTouchWhenHighlighted = true  // タップ時のハイライトを有効にする
        let buttonItem1 = UIBarButtonItem(customView: button1)

        // ツールバーのボタン2
        let button2 = UIButton()
        button2.setTitle("ボタン2", for: .normal)
        button2.showsTouchWhenHighlighted = true  // タップ時のハイライトを有効にする
        let buttonItem2 = UIBarButtonItem(customView: button2)

        // ボタンをツールバーに追加
        let buttonItems = [flexibleSpace, buttonItem1, flexibleSpace, buttonItem2, flexibleSpace]
        toolBar.setItems(buttonItems, animated: false)

        // ツールバーの前景の半透明を消す
        toolBar.isTranslucent = false

        // ツールバーの背景をイメージカラーの画像に設定
        toolBar.setBackgroundImage(productColorImage, forToolbarPosition: .any, barMetrics: .default)

        // TODO: ここで toolBar の上部の枠を消したい

        // ツールバーの部品を表示
        self.view.addSubview(toolBar)

        // ...略
    }
}
```

上記を実行すると、以下のような様子となる
![01_初期状態.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/37b285ee-f28c-7c5e-16dc-d7de0d93a6fa.png)

ボタンタップ時には、以下のようなハイライトが表示される
![01_初期状態ボタンタップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/d687cb79-c4b4-518c-2405-10ff07b59deb.png)

上記のハイライトを自然に見えるように維持しつつ、ツールバーの上部にグレーの枠線を消したい

# 方法
## 上手くいかなかった方法
`clipsToBounds` プロパティを true にすると、ハイライトがツールバーのサイズでクリップされてしまい、カッコ悪くなった

```swift:上手くいかなかった例
toolBar.clipsToBounds = true
```

以下のように、枠線は消えたが、
![02_ClipsToBounds.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/24cddd5e-be79-933f-36f7-c9a8036a8a64.png)

ボタンタップ時のハイライトが、ツールバーの上部で切り取られてしまった。
![02_ClipsToBoundsボタンタップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/0f1fd39f-96d5-aa1d-5366-7f31f875aab6.png)

# 上手くいった方法
ツールバーの `shadowImage` を設定する

```swift:上手くいった例
toolBar.setShadowImage(productColorImage, forToolbarPosition: .any)
```

上記の設定により、ハイライトも切り取られず、かつ枠線も消えた。
![03_ShadowImageボタンタップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/8fa8072a-bcdc-fb1c-dee2-9454ad346859.png)

# 参考
- https://stackoverflow.com/questions/9438864/how-can-i-remove-the-top-border-on-uitoolbar
ＶＢＡはじめました　-どこに書くの１ｰ

#ＥＸＣＥＬとＯＵＴＬＯＯＫ
##プログラムを書く準備
ＥＸＣＥＬの「ファイル」から「オプション」を選択
<img width="768" alt="setumei1.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/c99d20eb-958d-b670-5293-10733e810c69.jpeg">
「ﾘﾎﾞﾝのユーザー設定」から「開発」にチェックを入れＯＫを押す
<img width="768" alt="setumei2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/b0fce5ea-b280-7539-7dde-da2e29cd14f6.jpeg">
「開発」リボンが選択できるようになる
<img width="653" alt="setumei3.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/f7686df6-9e72-b8a9-29cb-e3ebe047953c.jpeg">
左端の「Visual Basic」ボタンでプログラミング開始です。
OUTLOOK も同じように設定できます。

##VisualBasicEdeter
<img width="479" alt="setumei4.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/9fc06a6e-a232-a2a8-5a3a-7e0473d2877e.jpeg">
「Visual Basic」ボタンを押すと『Microsoft Visual Vasic for Applications』のウィンドウが表示されます。

①プロジェクトエクスプローラ
 右クリックメニューから、「ユーザーフォーム」、「標準モジュール」、「クラスモジュール」を追加してプログラムを記述します。
<img width="253" alt="setumei5.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/0ffb6c69-86b2-f6da-17fa-561422b101c0.jpeg">

②イミディントウィンドウ
　プログラム中に［Debug.Print］を記述するとここに値を表示することができます。
　ここに直接記述ても実行されます。（例　　Debug.Print 2+4）
<img width="199" alt="setumei6.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/b94de3e8-718e-343a-9af2-e140931453e1.jpeg">

③ウォッチウィンドウ
　プログラム実行中の変数の値を確認することができます。
　正確には、確認したい変数を登録し、ブレークポイントを設定したプログラムをステップ実行等を行って、想定通り動いているか確認をします。
#それでは
次は、プログラムを書いて、思い通り動いているかデバッグ(ステップ実行 等）のしかたですね
#環境
Win10　Excel for Microsoft365MSO(16.0.)64ビット
ABC164

AtCorder Beginner Contest 164 に参加しました。
ABCの3問ACでした。
Pythonを使用しています。

# A問題
狼Wが羊S以上のときに、羊は狼に襲われてしまうのでunsafeです。

```python
S, W = map(int,input().split()
if S <= W:
    print("unsafe")
else:
    print("safe")
```

# B問題
高橋君の体力0になるのに必要なターン数をt、青木君の体力が0になるのに必要なターン数をaとします。
高橋君が勝つのは、青木君の体力が先に0になるときなのでtがaよりも大きいときです。
さらに体力0になるのに同じターンかかる場合でも、先攻の高橋君の勝利です。

```python
A, B, C, D = map(int,input().split())
import math
t = math.ceil(A / D)
a = math.ceil(C / B)
if t >= a:
    print("Yes")
else:
    print("No")
```


# C問題
得られた景品をリストSに格納します。
重複を除いたリストを作成し、要素数を求めます。

```python
N = int(input())
S =[input() for i in range(N)]
import collections
c = collections.Counter(S)
print(len(c))
```

# D問題
1~200000の間にある2019の倍数を全て求め、リストbaisuuに入れます。
2019を含んでいるか→4038を含んでいるかのように順番に探索していきます。
しかし、18171(=2019*9)のように先頭と最後に同じ数を含んでいる場合、181718171に18171が2個含まれていることを確認できませんでした。

```python
S = input()
import re
baisuu = [2019 * i for i in range(200000 // 2019)]
count = [len(re.findall(str(i), str(S)))
         for i in baisuu if str(i) in str(S)]
```

2019の倍数ということは2019で割ったあまりが0であるということです。
範囲指定の際に両方を動かすのではなく、右端に固定して考えることで計算量が少なくなります。

適当な具体例としてS = 12114が2019で割り切れえるか考えます。
右端を固定し左端を1つずつずらしながら余りを求めます。
1 → 1
41 → 41
141 → 141
1141 → 1141 
21141 → 951 
121141 → 1 
余りが一致するのは、1桁のときと6桁のときです。
これは、6桁目~2(1+1)桁目の数が2119の倍数であることを示しています。
 
a = 2019 * A + y
b = 2019 * B + y
a - b = 2019 * (A * B)
a - b は10のn乗です。
10と2019は互いに素であるので、a - b は2019の倍数になるからです。  

そこで全ての余り計算し重複の数を数えることで、2019の倍数になる数を求めることができます。
さらに2019で割って余り0になる場合は、重複なしでも2019の場合になります。
以下の回答はTLEです。

```python
S = list(input())
S.reverse()
amari = []
A = 0
c = 0
for i in range(len(S)):
    a = (int(A) + int(S[i]) *(10 ** i)) % 2019
    amari.append(a)
    if a == 0:
        c += 1
    A = a
print(c + len(amari) - len(set(amari)))
```
UdonSharp日記～UnityとVisualStudioの連携～

#やったこと
UnityでVisualStudioをデフォルトのエディタに設定することで、
VisualStudioでのコード開発時に補完ができるようになった。

この記事ではUdonSharpを使ってません。

###設定前の開発画面
下の図を見るとわかるようにクラス名が白字で書かれています。
VisualStudio側ではUnituのクラスを認識していないため、補完機能が使えてません。

このとき、ソースファイルの開き方はエクスプローラーで該当のファイルをダブルクリックして
開いていました。プロジェクトなんて意識しておらず、ただソースを書くことだけを
考えていたんですね。
![2020-04-27 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627563/5e9a97b7-1a32-37e4-cfcf-b2e5072cc75b.png)

###Unityの設定を変更
下記のサイトを参考にUnityで使用するエディタをVisualStudioに指定しました。
[UnityでVisualStudioをデフォルトのエディタに設定する](https://qiita.com/nishiken1235/items/94634a07551fc8d54c0e)

なお.NET Framework等の環境が足りない場合はダウンロードするようメッセージがでてきます。

###設定後の画面
Unityでデフォルトのエディタを変更したので、Unityからソースをクリックすることで開きます。
![2020-04-27 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627563/77f76062-fe6e-9f8d-f6d9-9bfaa2613c63.png)

ひらくとこんな感じ
![2020-04-27 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627563/d5545186-4831-ee79-2fa7-cd15341fbfcf.png)

Unityのクラスが青文字になっていてVisualStudioに認識されているのがわかります。
これで補完が使えるぞ！

開発効率も上がりますね。
【Firebase】Cloud FunctionsでHello world

本稿では、**Cloud Functions for Firebase**を利用してHello worldを返すエンドポイントを実装します。
基本的には[公式のチュートリアル](https://firebase.google.com/docs/functions/get-started?hl=ja#firebase-sdk-for-cloud-functions)に従います。

# 環境
- GCPプロジェクトを作成済み
- Node v10.19.0

# Firebase CLIのインストール
```zsh
$ npm install firebase-functions@latest firebase-admin@latest --save
$ npm install -g firebase-tools
```

# Firebase SDK for Cloud Functionsの初期化

Firebaseツールを認証する。

```bash
$ firebase login
```

Firebaseプロジェクトルートに移動し、空のプロジェクトを作成する。

```bash
$ firebase init functions
```

Firebaseが紐づくGCPプロジェクトを決める方法を選択する。
今回は既にGCPが存在する想定のため、**Use an existing project**を選択する。

```bash
? Please select an option: 
❯ Use an existing project 
  Create a new project 
  Add Firebase to an existing Google Cloud Platform project 
  Don't set up a default project 
```

Firebaseのプロジェクトを選択する。

```bash
? Select a default Firebase project for this directory: 
❯ hogehoge (hogehoge) 
  fugafuga (fugafuga) 
```

言語をJSかTSから選択できる。今回はJSを選択する。

```bash
? What language would you like to use to write Cloud Functions? 
❯ JavaScript 
  TypeScript 
```

ESLint使うか選択する。

```bash
? Do you want to use ESLint to catch probable bugs and enforce style?
N
```

依存関係をインストールするか選択する。

```bash
?  Do you want to install dependencies with npm now?
Y
```

全ての質問に答え終わると、空のプロジェクトができます。

# Hello world

セットアップを終えると、**package.json**と**index.js**が作成されていると思います。

**package.json**のenginesを8から10に書き換えます。
（今回はHello worldだけなので、デフォルトの8でも大丈夫です。）

```json
  "engines": {
    "node": "10"
  }
```

**index.js**は関数がコメントアウトされている状態なので、全て外します。

```js
const functions = require('firebase-functions');

// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions

exports.helloWorld = functions.https.onRequest((request, response) => {
 response.send("Hello from Firebase!");
});
```

デプロイする。

```bash
$ firebase deploy --only functions
```

GCPコンソールから詳細を確認することができます。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115823/3991e91e-f40d-aaf2-4a94-d23723c23dd7.png)

https://us-central1-hogehoge.cloudfunctions.net/helloWorld にアクセスすると...
（hogehogeはGCPのプロジェクトID）

![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115823/b8900c51-f81a-0d54-09c1-0ee9e349fbc3.png)
【資料作成】（エビデンス）重要性

# はじめに
エビデンス作成しておいてくださいって言われて、あ、またまとめてやらないと、、、
バージョンアップ対応すると色々と画面が崩れてしまう、、、どうしよう、、、超めんどくさい

ってなっている人に色々とアドバイスできるように記事にまとめておきます。

エビデンスとは証拠となる画像などを残すことです。

### エビデンスの意味
お客様に資料を作成して、今このような状態ですよ。
運用の信用を得るためには、必要なことではあります。

様々な意味があるとは思います。

特に、バージョンアップなどを行う際は、変更箇所が多くなり、アプリ全体の画像を取る必要があります。

ではどのようにしていくと良いのでしょうか？

## 手法は以下の通り
・動画で撮る
・画像（スクショで撮る）
・テスターさんに任せる
・テスターの会社に任せる

## マンパワーで、エビデンス作業を行う。

エビデンスを撮るぞと頑張る！！と決めたらひたすら撮ると言う手法がマンパワーですね。
一生懸命、画面の不具合を洗いざらい出す場合には有効かも知れません。
今の現状を知ることができる最終段階として、良いかも知れません

### デメリット

あとあとエビデンスの量が多くなって、作業がやたらと増えてしまう傾向にあるかも知れません。

## 逐次で、エビデンス作業を行う。

変更する前の現状エビデンスを撮ります。変更した後のエビデンスを撮ります。
こうすることで、不要な画像を作ることがなく効率よく資料作成ができます。

### デメリット

想定箇所以外の場所を見つけることができません。

## 作業効率を上げる方法として

・エビデンスを撮る習慣をつけ、エビデンスの整理（ファイル名を整えておくことが大事、これについては下の方に方法を書いておきますね）
・エビデンスを撮る担当の人を用意する。人材確保で新人さんや最近入った参画者に頼むお仕事としては良いかもですね。
・テスターさんの会社に任せる

# まとめ

エビデンスの撮り方次第で、いろんな不具合の発見があったり意外なところが見当たることがあります。
なかなか、開発現場が忙しいという時にこのエビデンス作業をやらないところもあったりします。

運用・保守などの観点からすると結構重要だったりします。
プロジェクトマネージャーの方やエンジニアの方とのコミュニケーションを取る際にこのことを決めておくことも大事かも知れませんね。

---

## 関連記事

---

【About】(http://qiita.com/sunstripe) - サンストライプ

---

## 制作チーム：サンストライプ

[![sunstripe_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/322f2d60-f19d-af9e-2b6f-7290ca546848.png)](http://sunstripe.main.jp/)
http://sunstripe.main.jp/

(月１ WEBコンテンツをリリースして便利な世の中を作っていくぞ！！ボランティアプログラマー/デザイナー/イラストレーター/その他クリエイター声優募集中!!)

緩募


### 地域情報 THEメディア
THE メディア 地域活性化をテーマに様々なリリース情報も含め、記事をお届けしてます！！
https://the.themedia.jp/

### ゼロからはじめる演劇ワークショップ
多様化の時代に向けて他者理解を鍛える

https://workshop.themedia.jp/

### プログラミングワークショップ・ウェブ塾の開講！！！
様々なテーマでプログラミングに囚われずに取り組んでいきます。
詳しくはこちら　↓　↓　↓　↓　↓　↓　↓　↓
[プログラミングサロン 月１だけのプログラミング学習塾](https://workshop.themedia.jp/posts/7057553?fbclid=IwAR32CfRQ7RvDOhvuogoSwqxDLMOU7Jvuzljlnx-TMc27qBPX1BnWsfLcBR8
)

### 協力応援 / 支援者の集い
## チーム：サンストライプ
https://twitter.com/sunstripe2011

#### プログラミングラボ
https://twitter.com/PLab2020

一緒にポートフォリオを作りませんか？現場の体験やそれぞれの立場から年齢関係なく作品を作りたい方々と一緒にチームを作って、作品を作っています。現場に行きたい人には、職場紹介や職場の体験や悩み相談なども受けております。
様々な職種からプログラミングの知識を得たい、デザインの知識を得たい、データーベースの知識を得たいという人が集まっております。
週１のミーティングにそれぞれの近況と作業報告して、たまにリモート飲み会などをしております！！

興味がある方は、DMに話しかけてみてください。

#### トラストヒューマン
http://trusthuman.co.jp/
私たちは何よりも信頼､人と考えてます｡

｢コンサルティング｣と｢クリエイティブ｣の両角度から｢人材戦略パートナー｣としてトータル的にサポートします！！

### キャリア教育事業

#### 青空プログラミング
[![青空プログラミング100px.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/603d53ab-828b-645e-a415-1b6f158d7356.png)](https://actcoin.jp/project/detail.php?id=600)

[![ダウンロード (9).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/9bde9318-28c2-ce74-d4c5-326168061bcc.jpeg)](https://www.youtube.com/hashtag/%E9%9D%92%E7%A9%BA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)

#### 広域学習支援プラットフォーム『のびのび日和』
https://slc-lab.amebaownd.com/

#スポンサー募集

## ネリム
https://nerim.co.jp/
配信事業などを映像コンテンツなどの制作しております

## ビヨンドXプロジェクト

[ビヨンドXプロジェクト全体会議](https://www.youtube.com/playlist?list=PLaR6-YWiGWkYhEHWnt8f1z-JC0g3nwwC9)
Python #スタック・キュー

学習メモ・備忘録

## スタックとキュー
後入れ先出し(LIFO)型のバッファが**スタック**、先入れ先出し(FIFO)型のバッファが **キュー**である。

~~~python:stackSample.py
stack = []

for i in range(10):
    stack.append(i)
    if len(stack)>4:
        print(stack.pop())
~~~
実行結果
>4
5
6
7
8
9

~~~python:queueSample.py
queue = []

for i in range(10):
    queue.append(i)
    if len(queue)>4:
        print(queue.pop(0))
~~~
実行結果
>0
1
2
3
4
5

ただし、キューをリストで実装すると`pop(0)`によって先頭のデータが取り出された後、残りのデータを一つづつずらさなければならないため効率が悪いので、`collections`パッケージの`deque`を利用する。

~~~python:dequeSample.py
from collections import deque

queue = deque([])

for i in range(10):
    queue.append(i)
    if len(queue)>4:
        print(queue.popleft())
~~~
実行結果
>0
1
2
3
4
5
Gatsbyのチュートリアルでアプリケーションが起動できないエラーが出たので対処法を書く

フロントで静的サイトを作る勉強だーと思ってGatsbyに手を出しました。
[公式のチュートリアル](https://www.gatsbyjs.org/tutorial/)を進めていたらこんなエラーが出まして。

```
ERROR 

UNHANDLED REJECTION ENOSPC: System limit for number of file watchers reached, watch '/home/user/workspace/gatsby/tutorial-part-two/static'



  Error: ENOSPC: System limit for number of file watchers reached, watch '/home/user/workspace/gatsby/tutorial-part-two/static'
  
  - watchers.js:169 FSWatcher.start
    internal/fs/watchers.js:169:26
  
  - nodefs-handler.js:118 createFsWatchInstance
    [tutorial-part-two]/[chokidar]/lib/nodefs-handler.js:118:15
  
  - nodefs-handler.js:165 setFsWatchListener
    [tutorial-part-two]/[chokidar]/lib/nodefs-handler.js:165:15
  
  - nodefs-handler.js:330 NodeFsHandler._watchWithNodeFs
    [tutorial-part-two]/[chokidar]/lib/nodefs-handler.js:330:14
  
  - nodefs-handler.js:551 NodeFsHandler._handleDir
    [tutorial-part-two]/[chokidar]/lib/nodefs-handler.js:551:19
  
  - runMicrotasks
  
  - task_queues.js:97 processTicksAndRejections
    internal/process/task_queues.js:97:5
  
  - nodefs-handler.js:600 async NodeFsHandler._addToNodeFs
    [tutorial-part-two]/[chokidar]/lib/nodefs-handler.js:600:16
  
  - index.js:434 
    [tutorial-part-two]/[chokidar]/index.js:434:21
  
  - async Promise.all
```

手順通りやってるのになぁと思いながら調べると[対処方法の載っている場所](https://github.com/gatsbyjs/gatsby/issues/11406)がありました。
そこによると、システムのファイルウォッチャーが上限に達したみたいです。
<img width="776" alt="スクリーンショット 2020-04-27 13.06.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187601/b56d77b1-6e27-7025-895d-c156583384be.png">

まずはローカルでこの値を確認してみましょう。

```
$ cat /proc/sys/fs/inotify/max_user_watches
8192
```

8kですね。これを増やしましょう。issueのコメントによると524288(=512k)にしましょうということなので、これをそのまま使います。(メモリと相談してください。)

```
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
fs.inotify.max_user_watches=524288
fs.inotify.max_user_watches = 524288
```

そして値が設定された確認し、再度gatsbyコマンドで実行すれば解消されます。

```
$ cat /proc/sys/fs/inotify/max_user_watches
524288
$ gatsby develop
以下省略
```