OmniAICreator/Qiita-1.07M huggingface dataset:
OpenWRTをRaspberry PI4に入れる

# Raspberry PI4 をルータにする

```
BusyBox v1.31.1 () built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt SNAPSHOT, r12230-5715b21f80
 -----------------------------------------------------
```

* [OpenWrtイメージ](https://downloads.openwrt.org/snapshots/targets/brcm2708/bcm2711/)


# SDカードにイメージを書き込む
```
$ cd /tmp
$ wget https://downloads.openwrt.org/snapshots/targets/brcm2708/bcm2711/openwrt-brcm2708-bcm2711-rpi-4-ext4-factory.img.gz
$ gunzip openwrt-brcm2708-bcm2711-rpi-4-ext4-factory.img.gz
$ sudo dd if=/tmp/openwrt-brcm2708-bcm2711-rpi-4-ext4-factory.img of=/dev/sdX bs=2M conv=fsync
```

# ネットワークの設定
```
$ netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.8.1     0.0.0.0         UG        0 0          0 eth0
192.168.8.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0
192.168.8.1     0.0.0.0         255.255.255.255 UH        0 0          0 eth0
```
ネットワークを確認します。


#### RaspberryPiに電源を入れてログイン 

```
# uci set network.lan.ipaddr=192.168.8.22
# uci set network.lan.gateway=192.168.8.1
# uci set network.lan.dns=192.168.8.1
# uci commit
# service network restart
```

#### sshでログインしてパスワード設定

```
$ ssh root@192.168.8.22
# passwd
Changing password for root
New password: 
Bad password: too weak
Retype password: 
passwd: password for root changed by root
```

## LuCIのインストール

```
# opkg update
# opkg install luci
# opkg install \
    luci-i18n-base-ja \
    luci-i18n-firewall-ja \
    luci-i18n-opkg-ja
# service uhttpd restart
```
下は、LuCIの日本語パッケージです。


## RaspberryPiのアドレスにブラウザアクセス

![OpenWrt01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305612/be1b0b7f-508a-fa47-23b2-88d634158482.png)


## ssh 公開鍵の追加

システム　＞　管理画面　＞　SSHキー

![OpenWrt02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305612/fa25267b-2ff5-0215-6def-23c0cd69e5b0.png)

## 無線ネットワーク設定

ネットワーク　＞　無線

![OpenWrt03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305612/54b5a8e1-4f4c-d928-cfc4-84667961a166.png)

無線LANの編集

---

![OpenWrt04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305612/709d3165-573f-2a46-a1f4-55156f949c98.png)

デフォルトの値のままだと、`Legacy`に設定したらうまく行きました。

---

![OpenWrt05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305612/e2287d13-821c-4671-906f-ec0d8a3bba25.png)

端末からの接続ができれば、こんな画面になるはずです。

## 動作周波数：Nモードしたい

とりあえず３桁MBは欲しいので今後調べます。


## 付録

マウントインストール

```
# opkg update
# opkg install block-mount
```

ユーザー追加イストール

```
# opkg update
# opkg install shadow-useradd
```

# 参考

* [INSTALL OPENWRT ON YOUR RASPBERRY PI](https://www.itix.fr/blog/install-openwrt-raspberry-pi/)
reactの立ち上げ方

```terminal
npm install -g create-react-app
```
でインストール

```terminal
npx create-react-app プロジェクト名 
```
でフォルダ作成

```
cd プロジェクト名
```

で移動して

```
yarn start
```
 
or

```
npm start
```

でlocalhost起動
<img width="1440" alt="スクリーンショット 2020-04-06 2.20.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429828/43f1ba0d-537d-dbf8-a613-398e0e52e760.png">
Rubyのクラスがモジュールをinlcudeする時の参照順を実験してみた

# 確認したいこと
同名のモジュールが複数の名前空間に存在する時のincludeの参照順

# 実験

```ruby

module TalkActions
  def say_my_name ###(1)
    puts "I am #{@name}[outside]"
  end
end
  
class Human
  module TalkActions
    def say_my_name ###(2)
      puts "I am #{@name}[inside]"
    end
  end

  include TalkActions ###(1),(2)のどちらをよみこむか?
  def initialize(name)
    @name = name 
  end
end
  
John = Human.new("John")
John.say_my_name ### I am John[inside] (2)だった
```

* 一応insideをコメントアウトして実行

```ruby

module TalkActions
  def say_my_name ###(1)
    puts "I am #{@name}[outside]"
  end
end
  
class Human
  # module TalkActions
  #   def say_my_name ###(2)
  #     puts "I am #{@name}[inside]"
  #   end
  # end

  include TalkActions ###ちゃんと(1)を読み込んでいることの確認
  def initialize(name)
    @name = name
  end
end
  
John = Human.new("John") 
John.say_my_name ### I am John[outside] (1)が呼び出された
```

なお、TalkActionsモジュールは今回ルートだったので呼び出せすことができた。

- TalkActionsモジュールをルートにしないと、

```rb
module X
  module TalkActions
    def say_my_name ###(1)
      puts "I am #{@name}[outside]"
    end
  end
end

class Human
  # module TalkActions
  #   def say_my_name ###(2)
  #     puts "I am #{@name}[inside]"
  #   end
  # end

  include TalkActions ###ちゃんと(1)を読み込んでいることの確認
  def initialize(name)
    @name = name
  end
end

John = Human.new("John") 
John.say_my_name ### '<class:Human>': uninitialized constant Human::TalkActions (NameError) を吐いて終了。
```

# 結論
呼び出し元のと同一名前空間内→ルートのモジュールへと探しにいくようだ。
マスク買い占めを防止するシステムを考えました


ネットで「一部の人が毎朝ドラッグストアに並び、マスクを買い占めている。」
という話を聞いて、マスク買い占めを防止するシステムを考えました。
課題はいくつかあると思いますが、どなたか実装してみませんか。
##ユーザ登録
客はユーザ登録を行い自分用のQRコードを取得する。
登録にはSMSを使い重複を防ぐ。
![説明１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614329/947da312-034e-4133-21aa-566128e7a030.png)

##薬局側の準備
薬局はマスク買える条件を提示する。
![説明２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614329/46804ee6-1ff9-4eac-453c-14fb3321cd0f.png)

##売買
客はQRコードを店員に見せる。
店員は客のQRコードを読み取る。
店の販売条件に一致する場合、マスクを売る。
売買後に「購入しましたボタン」を押下し客の最終購入日をリセットする。
![説明３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614329/7e190491-e236-6f27-8a1b-456a3b128702.png)

##売買後
![説明４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614329/49d51b92-9987-d8fe-51c0-7435b84fc5c5.png)

##課題
・SMSを送るためのコストが高い
　→業者や政府に話をつけて無料にできないか。
・スマホを使えない人が不利
　→店はこのシステムを使えない人用の在庫を用意する。
・電話番号を多く持っている人が有利
　→イコール家族が多い、と考えれば不公平では無いか。。。
・客が悪意のあるQRコードを作成し店に対して偽のページを提示できる。
　→QRコードを読んでも指定URLにしか飛ばないスマホアプリを作り、店はそれを使う。
・多くの薬局の協力が必要。
Rubyのモジュールのインスタンスメソッドの挙動を実験してみた

# 確認したかったこと
モジュールのインスタンスメソッドからinclude元のクラスのインスタンス変数/メソッドを呼び出すことは可能か？

# 実験

```ruby
module TalkActions
  def say_my_name
    puts "I am #{@name}"
  end

  def shout_my_name
    puts "I am #{self.name}!!!!!!!!"
  end
end

class Human
  attr_accessor :name
  include TalkActions
  def initialize(name)
    @name = name 
  end
end

John = Human.new("John")
John.say_my_name # 'I am John'
John.shout_my_name # 'I am John!!!!!!!!'
```

# 結論

どちらも呼び出し可能
azure devopsサンプルコード

変更セット取得のサンプルコード

C#サンプル

```
    Uri orgUrl = new Uri("http://hostname:8080/tfs/DefaultCollection/");
    var credentials = new WindowsCredential();
    var connection = new VssConnection(orgUrl, credentials);

    TfvcHttpClient tfvcClient = connection.GetClient<TfvcHttpClient>();
    var changes = tfvcClient.GetChangesetsAsync().Result;

    foreach (var tfvcChange in changes)
    {
        Console.WriteLine(tfvcChange.Comment);
    }
```

pythonサンプル

```
personal_access_token = 'access_token'
organization_url = 'http://hostname:8080/tfs/DefaultCollection/'

credentials = BasicAuthentication('', personal_access_token)
connection = Connection(base_url=organization_url, creds=credentials)

changes = tfvc_client.get_changesets()
for x in changes:
    print(x)
```
Rubyのクラスにおける@とselfの整理

基本的に、@はインスタンス変数を、selfはメソッドを呼び出す。ただし、attr_accessorで指定したインスタンス変数に関してはselfで呼び出せる。

# その心は...

`attr_accessor hoge`は、インスタンス変数`hoge`のアクセッサとして`hoge`, `hoge=`メソッドを定義する。
【Java入門】コンソール上、文字を出力方法。

# コンソール上、文字を出力方法とは？

```
System.out.print()
System.out.printf()
System.out.println()
```

# print()？printf()？println()？何が違う？
- print()
 - そのまま、文字を出力する。

```
例）
print("abc")
// 表示結果：abc

print("abc")
print("123")
// 表示結果：abc123
```

- println()
 - 行の区切り文字列を書き込むことで、現在の行を終了させます。（改行を入れて出力する。）

```
例）
println("abc")
// 表示結果：abc

println("abc")
println("123")
// 表示結果：abc
           123
```

- printf()
 - 書式付き文字列を、指定された書式文字列と引数を使用し、この出力ストリームに書き込む便利な方法です。


```
例）
---
System.out.printf(書式, 引数1, 引数2, 引数3…)
---
int a = 1;
int b = 1;
System.out.printf("%d + %d = %d", a, b, a+b)
// 表示結果：1 + 1 = 2
```

※ Format一覧表。

- 型

|指定子|主な型|簡単な説明|記述例|出力例|
|:---------:|:---------:|:---------:|:---------:|:-----:|
|%|なし|書式指定子の開始|なし|なし|
|d|整数|10進数で出力|printf("%d", 123)|123|
|o|整数|8進数で出力|printf("%o", 123)|173|
|x|整数|16進数で出力|printf("%x", 123)|7b|
|e|小数|指数で出力|printf("%e", 123.4f)|1.23E+02|
|f|小数|小数点数出力|printf("%f", 123.4f)|123.4|
|s|文字列|文字列を出力|printf("%s", “abc”)|abc|
|c|文字|文字を出力|printf("%c", ‘a’)|a|
|b|真偽値|真偽値を出力|printf("%b", true)|true|

- 桁数・左詰・0埋め・改行 ・引数番号(※△=スペースの意味)

| 指定子 |簡単な説明   |記述例|出力例|
|:------:|:------:|:------:|:------:|
|数|最小桁数を指定|printf("[%5d]", 123)|[△△123]|
|.数|文字列の最大幅を指定|printf([%.3s]", "abcde")|[abc]|
|-|左詰|printf([%-5s]", "abc")|[abc△△]|
|0|0埋め|printf("[%05d]",123);|[00123]|
|n|改行|printf("abc%ndef");|abc<br>def|

- 日付

| 指定子 |簡単な説明   |記述例|出力例|
|:------:|:------:|:------:|:------:|
|tY|年(4桁)|printf("%tY", new Date());|2018|
|ty|年(2桁)|printf("%ty", new Date());|18|
|tm|月(2桁)|printf("%tm", new Date());|01|
|td|日(2桁)|printf("%td", new Date());|05|
|te|日(1~2桁)|printf("%te", new Date());|5|
|tH|時(2桁)24時間制|printf("%tH", new Date());|17|
|tl|時(1~2桁)12時間制|printf("%tl", new Date());|5|
|tM|分(2桁)|printf("%tM", new Date());|04|
|tS|秒(2桁)|printf("%tS", new Date());|05|
|tF|日付|printf("%tF", new Date());|2018-01-05|
|tT|時刻|printf("%tT", new Date());|17:04:05|

# 参考
[printf](https://www.sejuku.net/blog/43246)
Pro Micro 、MIDIキーボードにもなるってよ

Pro Micro (Arduino Leonardo)といえば[自作キーボード](https://qiita.com/MergeCells/items/17bdc1c1fb35949195b5)や[クイズボタン](https://qiita.com/ELIXIR/items/fb552459be61cdba5f63)等でよく使われていますが、MIDIキーボードにもなるんです。

[MIDIUSB](https://github.com/FortySevenEffects/MIDIUSB)
PlatformIOにも同名でライブラリがあります。

Arduino Uno等でよく使われる [USB MIDI ライブラリ](https://playground.arduino.cc/Main/MIDILibrary/)はファームウェアの書き換えが必要だったりSerial.print()が使用できなくなったりしますが、こちらのライブラリは **ファームウェア変更の必要はなくSerialもそのまま使用できます** 。

このライブラリを使ったサンプルは以下の通り（[examples](https://github.com/FortySevenEffects/MIDIUSB/tree/master/examples)以下にあります）
実行すると2秒に１回「ド」を送ります。

```
/*
 * MIDIUSB_test.ino
 *
 * Created: 4/6/2015 10:47:08 AM
 * Author: gurbrinder grewal
 * Modified by Arduino LLC (2015)
 */ 

#include "MIDIUSB.h"

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  Serial.begin(115200);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void loop() {
  Serial.println("Sending note on");
  noteOn(0, 48, 64);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(500);
  Serial.println("Sending note off");
  noteOff(0, 48, 64);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(1500);

  // controlChange(0, 10, 65); // Set the value of controller 10 on channel 0 to 65
}
```

出力だけでなく入力ももちろん可能なので、手持ちのMIDIデバイスから送られたデータを受け取ることも可能です。
手持ちのMIDIデバイスがない場合はこちらの[WEB MIDIセレクター](https://elix.jp/app/web_midi_sender/)で確認できます。
いろいろやってみた動画は[こちら](https://youtu.be/csl69o2LpzI)。
![スクリーンショット 2020-04-06 1.05.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/87095b20-8557-4d8d-239c-c3d728718442.png)
さくらのレンタルサーバで Laravel を使うメモ (2020/04)

ぐぐって出てくる記事からバージョンが変わってたりして、うまく動かないことが結構あったので、現時点(2020/04)で動くまで持っていったときのメモ。

# 用意

- さくらのレンタルサーバ：スタンダード
- ssh の使える手元の PC

# 手順

サーバとローカル PC に composer をインストールする。完全にローカル PC でしか composer を使わないなら、サーバ側に入れる必要はない。

```
% cd
% curl -sS https://getcomposer.org/installer | php
```

これで、カレントに `composer.phar`ができるので、`$HOME/bin` に `mv` する。

```
% mv composer.phar ~/bin/composer
% rehash
```

デフォルトで `$HOME/bin` にパスが通っているはずだけど、通ってなければ `~/.cshrc` を書きかえる。

```
set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/bin)
```

composer の実行ができるかを確認する。

```
% composer -V
Composer version 1.10.1 2020-02-30 25:61:99
```

これで準備はおわり。

# プロジェクトの作成

さくらサーバ上で作成しようとすると、途中でプロセスが kill されるっぽいので、ローカルの PC で作っておく。

```
$ composer create-project laravel/laravel sample
```

sample 以下にプロジェクトが作成される。ローカル側では下記のコマンドで動作を確認できる。

```
$ cd sample; php artisan serve
```

`http://localhsot:8000/` で動作確認できる。

作成したプロジェクトを zip するなり、github に push するなりして、サーバ側にもっていく。以下は zip する場合。scp や ssh 時にはサーバのパスワードが必要。(name はさくらのサーバ名)

```
$ zip -r sample.zip ./sample
$ scp sample.zip name@name.sakura.ne.jp:~/
$ ssh name@name.sakura.ne.jp
...
% unzip sample.zip
% mv sample /home/name/www/
```

これで、ブラウザから `http://name.sakura.ne.jp/sample/public/` でアクセスできるはず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/52ea98d9-0329-871a-8b07-37e23803fa87.png)


こんな感じの画面が出たら成功。

あとは、いろいろする。
@keymoon氏の【全方位木DP】のRuby実装

[【全方位木DP】明日使える便利な木構造のアルゴリズム](https://qiita.com/keymoon/items/2a52f1b0fb7ef67fb89e)
上記事の Ruby への単なる移植です。

##コード
API はブロックを使うなど、多少 Ruby らしくしたつもりです。`operate`の処理は、Ruby では Array#max が Array のメソッドなので、ちょっと苦肉の策になっています。`@operate`を attr_writer の対象にしておきましたが、実際は :max を :min にするくらいで、それほどの汎用性を求められないでしょう。

```ruby:Ruby
class ReRooting
  def initialize(identity, operate = :itself, &operate_node)
    @identity = identity
    @operate = ->(a, b) {[a, b].__send__(operate)}
    @operate_node = operate_node
  end
  attr_writer :operate
  
  def rerooting(node_count, edges)
    @node_count = node_count
    
    @adjacents = Array.new(@node_count) {[]}
    @index_for_adjacents = Array.new(@node_count) {[]}
    
    edges.each do |edge|
      @index_for_adjacents[edge[0]] << @adjacents[edge[1]].size
      @index_for_adjacents[edge[1]] << @adjacents[edge[0]].size
      @adjacents[edge[0]] << edge[1]
      @adjacents[edge[1]] << edge[0]
    end
    
    @dp = @adjacents.map {|ary| [ary.size]}
    @res = Array.new(@adjacents.size)    #result
    
    case
    when @node_count > 1
      init
    when @node_count == 1
      @res[0] = @operate_node.(@identity, 0)
    end
    @res
  end
  
  private
  
  def init
    parents = Array.new(@node_count)
    order = []
    
    stack = [0]
    parents[0] = -1
    
    until stack.empty?
      node = stack.pop
      order << node
      @adjacents[node].each do |adjacent|
        next if adjacent == parents[node]
        stack << adjacent
        parents[adjacent] = node
      end
    end
    
    #fromLeaf
    (order.size - 1).downto(1) do |i|
      node = order[i]
      parent = parents[node]
      
      accum = @identity
      parent_index = Object.new
      @adjacents[node].each_index do |j|
        if @adjacents[node][j] == parent
          parent_index = j
        else
          accum = @operate.(accum, @dp[node][j])
        end
      end
      @dp[parent][@index_for_adjacents[node][parent_index]] =
         @operate_node.(accum, node)
    end
    
    #toLeaf
    order.each do |node|
      accum = @identity
      accums_from_tail = Array.new(@adjacents[node].size)
      accums_from_tail[-1] = @identity
      
      (accums_from_tail.size - 1).downto(1) do |j|
        accums_from_tail[j - 1] = @operate.(@dp[node][j], accums_from_tail[j])
      end
      
      accums_from_tail.each_index do |j|
        @dp[@adjacents[node][j]][@index_for_adjacents[node][j]] =
           @operate_node.(@operate.(accum, accums_from_tail[j]), node)
        accum = @operate.(accum, @dp[node][j])
      end
      @res[node] = @operate_node.(accum, node)
    end
  end
end
```

例えばこんな感じで使います。ノードは 0 から始まる Integer の連番にして下さい。ノードの個数を`node_count`で指定します。

```ruby:sample.rb
edges = [[0, 1], [0, 4], [0, 6], [1, 2], [1, 3], [4, 5],
         [6, 10], [6, 11], [6, 7], [7, 8], [7, 9]]
node_count = 12

res =  ReRooting.new(0, :max) {|value, id| value + 1}
                .rerooting(node_count, edges)
puts res.map(&:pred)
```

おかしなところがあったら教えて下さい。
DockerコンテナからAzure PowerShellを実行する

今更ながらDockerに触れてみましたのでAzure PowerShellをDockerコンテナから実行してみます。

# 実行環境
* WSL2(Ubuntu)
* Docker Desktop for Windows

# コンテナの作成
Docker HubでMicrosoft社公式のイメージが提供されていますのでこちらを使用します。

https://hub.docker.com/_/microsoft-azure-powershell
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/cd192c68-6ceb-f507-7d10-f0c7285c402f.png" width=80%>

コンテナ作成手順も公開されていますので手順に従っていきます。
https://docs.microsoft.com/ja-jp/powershell/azure/azureps-in-docker?view=azps-3.7.0

まずはイメージの取得。

```docker
sudo docker pull mcr.microsoft.com/azure-powershell

Using default tag: latest
latest: Pulling from azure-powershell
5bed26d33875: Pull complete
f11b29a9c730: Pull complete
930bda195c84: Pull complete
78bf9a5ad49e: Pull complete
3183894b4ae2: Pull complete
5d930b42a49c: Pull complete
95d0de46cc6e: Pull complete
9bab5da02730: Pull complete
Digest: sha256:c06ab1162d6236b053ab425e54fb9f1feca0d6385865dd6e5c225076732007ad
Status: Downloaded newer image for mcr.microsoft.com/azure-powershell:latest
mcr.microsoft.com/azure-powershell:latest
```

対話モードでコンテナを作成。
PowerShellのバージョンは7.0でした。

```docker
sudo docker run -it mcr.microsoft.com/azure-powershell pwsh
PS /> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.0.0
PSEdition                      Core
GitCommitId                    7.0.0
OS                             Linux 4.19.84-microsoft-standard #1 SMP Wed Nov 13 11:44:37 UTC 2019
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
```

# Azure PowerShellの実行

Azureにログインしてみます。

```powershell
PS /> Login-AzAccount
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code xxxxxxxx to authenticate.
```

PowerShell Coreのため、アカウント選択前に認証が必要です。
メッセージのURLにブラウザでアクセスし認証コードを入力します。
認証コード入力後の次の画面でログインするAzureアカウントを選択してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/ef4b57a5-aff0-1cd4-3dc6-83131a046bc6.png" width=50%>

無事にログインできました。

```powershell
Account    SubscriptionName TenantId                          Environment
-------    ---------------- --------                          -----------
xxxxxxxxxx subscriptionA    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx AzureCloud
```

VMを起動してみます。

```powershell
PS /> Start-AzVM -ResourceGroupName hoge-rg -Name hoge-vm

OperationId : 02ef9231-7972-4fc8-880c-5367c0c59d37
Status      : Succeeded
StartTime   : 4/5/2020 3:32:14 PM
EndTime     : 4/5/2020 3:34:31 PM
Error       :
```

やったぜ（起動できました。）

# まとめ
少ない手順で簡単に作成、実行できました。
イメージも公式から提供されていますので安心ですね。
次はAzure上にコンテナを作って実行してみたいと思ってます。
オンライン登壇でも表情くっきり。LEDリングライトを自作してみた

![IMG_5739.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58993/dc43ea48-fabd-945c-3d64-5f5ea634d262.jpeg)

# 表情が暗くなってしまう悩みを解決したい
オンラインでの打ち合わせやイベント登壇、飲み会など機会が増えています。一人で集中できるスペースも、いざ誰かとオンラインで話す際には照明が暗すぎて、ZoomやSlackに映る表情が暗くなってしまうことます。

そこで、必要な時にパッと表情が明るくできる、LEDリングライトを自作してみました。

# 用意するもの
- 5VのNeoPixel LEDテープ、USB給電できるもの
- NeopixelフルカラーLED・USBコントローラ
- モバイルバッテリー
- A4サイズの有孔ボード
- 小さなイーゼル
- 針金
- ニッパー
- ラジオペンチ

# 作り方
## STEP1: レイアウトを決める
まずLEDテープをどうレイアウトするか考えます。有孔ボードの穴を使って針金て留めていくので、丸でもハートでも、好きな形状位してください。

このとき、USB給電部分が下の方にくるようにレイアウトするのをおすすめします。

## STEP2: 針金をピン状にし、LEDを有孔ボードの穴に止める
レイアウトを決めたら、ニッパーを使って針金を5cmくらいに切り、ラジオペンチで半分に曲げてピン状にします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58993/150c8ae8-7ace-11b1-1773-0f0e9b9ac01b.jpeg" width=80%>

LEDの光る面が内側に向くように、針金で作ったピンを使って固定していきます。前からLEDテープを縦に挟むように通してください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58993/86ac59fa-4c2a-41b0-6319-82b0bdfbb75f.jpeg" width=80%>
LEDテープが正面を向いていると、曲げづらいだけでなく、光を直視する形になり眩しく使いづらいです。

背面に出た端はラジオペンチで曲げ、クロスして動かないよう留めます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58993/29aeb460-f9dc-8fc6-9912-9abeeb79f9cb.jpeg" width=80%>

## STEP3: イーゼルに立てて、USB給電して完成！
LEDテープを有孔ボードに固定し終えたらイーゼルに立てかけて、NeoPixelのコントローラーをつけて、USB給電したら完成です。色と明るさを調整します。

イーゼルがない場合は、手持ちのスチレンボードなどで足を作るのでもOKです。
![17584759-8A32-42AB-97BC-5B193E192DD1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58993/767d95e7-7e5b-e640-ccc7-ceab4ae6953a.jpeg)

# 表情はどう改善されたの？
ノーメイクで恐れ入りますが、自作したLEDリングライトの使用前（左）と使用後（右）の写真を並べてみます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58993/405dea2a-9759-2c75-a63f-87f6ccb2ae0c.jpeg" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58993/c652c45f-2dfd-4ce7-9b89-d78a8feab7c2.jpeg" width=50%>

こちらの画像で使用したカメラはMac Book Pro内蔵のもの。ノートPCを開いた状態だったので、LEDリングライトはノートPCのディスプレイ横から照らしています。
それでもSnap Cameraで同じフィルターを使っても、LEDリングライトがあると、表情がだいぶ明るくなりました。

# まとめ
LEDリングライト欲しいなぁと思ったので、家にあるLEDテープと部材で試しに自作したところ、思った以上に使えそうなものになりました。せっかくNeoPixelなので、次のステップとして、色を使ったインタラクションなども考えみようと思います。
PyCharmで仮想環境を読み込む方法のメモ

PyCharmで仮想環境を読み込む方法のメモです(復唱)。


## 前提条件
- 以下、仮想環境名が'hoge'であるとします
- PyCharmがインストールされている
- virtualenvにて仮想環境をすでに作っており、```workon hoge```で呼び出せる状態になっている

## 設定手順
### 1. 仮想環境のディレクトリを確認する
```cdvirtualenv``` コマンドを仮想環境下で実行し、仮想環境が保存されているディレクトリを確認しましょう。(筆者はこれを知らずものすごく手間取りました)

```
# a.仮想環境を起動します
$ workon hoge

# b.仮想環境のディレクトリに移動します
(hoge)$ cdvirtualenv

# c.ディレクトリ名を確認します
(hoge)$pwd
## 筆者の場合、「C:\Users\me\Envs\hoge」と表示されました。

# d.Pythonのディレクトリを取得します
(hoge)$ where python
## 仮想環境と非仮想環境の2つ以上が出てくると思います。手順c.と同じディレクトリに入っているパスを見つけてコピーします。
## C:\Users\me\Envs\hoge\Scripts\python.exe (今回の場合これをコピー)
## C:\Python\Python38\python.exe (これは非仮想環境のもの)

```
### 2. PyCharm側の設定
- a. すでに存在するプロジェクトの仮想環境を設定した場合
    - (1)プロジェクトを開いている状態でCtrl + Alt + s (あるいは画面上部の「File -> Settings...」)を押す
    - (2)「Project Interpreter」と入力。画面に表示させ、右上の歯車->Add
    - (3)「Virtualenv Environment」にてExisting Environmentを選択、Interpreter欄に前章1-dのpythonファイルのディレクトリをペースト
    - (4)OKを押し、仮想環境を作成
- b. 新しいプロジェクトを作成する際に仮想環境を設定したいという場合
    - (1) New Project -> 出てきた画面「Project Interpreter: New Virtualenv environment」を開く
    - (2) Locationには開きたいプロジェクトのディレクトリを、Base Interpreterには前章1-dのpythonファイルのディレクトリをペースト
    - (3) createを押し、作成を完了

以上! 

## おわりに
- 自分と同じような初心者の方のお役に立てば幸いです！
[Logback]ローテーション時に不要ファイルが消えない時の対処方法

Logbackのローテーション設定の妥当性を検証していた時に、不要ファイル（＝保存切れとなったアーカイブファイル）が消えなくて「なぜだ〜」となった時に調べた時のメモ。

> **NOTE:**
>
> 検証時は、デバッグログを１つだけ出力するmainメソッドを作って、システム日付をずれして実行していました。


# バージョン

* Logback 1.2.3

# なぜ不要ファイルが消えなかったのか！？

細かい条件は調べていませんが、実行時間が短命なスタンドアロンアプリ（＝ログ出力後にすぐにプロセスが終了するようなアプリ）の場合、ログファイルのローテーション後に行われるはずの不要ファイル（＝保存切れとなったアーカイブファイル）削除処理が行われる前のJVMが終了してしまうことがあるようです。

# どうすればよい？

アプリ起動時に不要ファイル（＝保存切れとなったアーカイブファイル）を消す処理を呼び出すためのオプションを有効化しておくことで、次回の実行タイミングで不要なファイルを削除することができます。

```xml:起動時に不要ファイルを削除する処理を実行する際の設定例
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>/var/log/app-%d{yyyy-MM-dd}.log</fileNamePattern>
        <maxHistory>7</maxHistory>
        <cleanHistoryOnStart>true</cleanHistoryOnStart> <!-- ★★★ ここを追加 ★★★ -->
    </rollingPolicy>
    <encoder>
        <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>
```

> **NOTE:**
>
> Webアプリケーションなどの常駐型のアプリケーションの場合は、よほどのことがない限りはローテーションタイミングで不要ファイルも削除されます（＝切り替え時にプロセスが終了する可能性が非常に低いため）。仮に運悪く削除されないことがあっても、次のローテーションの機会で削除されるので上記設定がなくても問題になることはないと思われます。 

# まとめ

おそらく・・・商用サービスで動くようなアプリでは `cleanHistoryOnStart` を指定しなくてもほとんど大丈夫でしょう。瞬殺で終わるようなバッチアプリ！？（瞬殺で終わるならバッチにしなくてええやん・・・という話はありそうだが・・）がある場合は、念のためにこのオプションを指定しておくとよいかもしれません。
あと・・・私のようにローテーションの動作確認する時はこのオプション入れておかないと「何故だ〜」と無駄な時間を過ごすことになるかもしれません。
Laravelで作ったAPIを外部サーバーにおいて公開する話

#はじめに
なぜ開発中のAPI外部サーバーにおいて公開することにしたのか。
なぜなら遠隔でフロントとバックの開発を同時並行で円滑に進めていくためです。

しかし、外部サーバーなど一度も使ったことがなかったのでいろいろ大変でした。


#welcome画面を表示させるまで
Procfileを作成します。

```:Procfile
web: vendor/bin/heroku-php-apache2 public/
```
intlを有効化します。

```shell:アプリのホームディレクトリ
$ composer require ext-intl:*
```
ここからherokuの環境変数を設定していくわけなんですが、ここでまず詰まりました。

```shell:
$ heroku config:set
 ›   Error: Missing required flag:
 ›     -a, --app APP  app to run command against
 ›   See more help with --help
```
はい、configを開こうとするとエラーが出ました。

```shell:
$ heroku git:remote -a アプリ名
```

今までgithubと連携してそこからデプロイをしていたのですが、それが原因だったみたいです。herokuに直接デプロイすることで解決しました。
（他にも解決法はあると思います）

さあ、これでやっとwelcome画面が表示されるようになりました。


#DB問題
ローカルではsqliteを使って開発していました。
herokuについて何も知らなかったのでそのままデプロイしたら使えるのだろう、と甘くみていました。
しかーし、何を試してもAPIを使おうとするとエラーを吐かれてしまいます。

なぜなら、答えは簡単「herokuはsqliteに対応していない」
herokuのDBはpgsqlだということです。
pgsqlは触ったことがなかったので、変更するならせめて触ったことのあるmysqlが精一杯でした。

どうやらherokuでもadd-onをインストールすればmysqlが使えるようになるらしいとの情報を入手。
それがこちらの**ClearDB**。
<img width="1440" alt="スクリーンショット 2020-04-06 0.27.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/31720a88-e612-71df-786c-12eabf53e372.png">
このコマンドで無料版をインストールします。

```
$  heroku addons:create cleardb:ignite
```
ここでもエラーが出ました。

```
$ heroku addons:create cleardb:ignite
Creating cleardb:ignite on ⬢ アプリ名... !
 ▸    Please verify your account to install this add-on plan (please enter a credit card) For more information, see
 ▸    https://devcenter.heroku.com/categories/billing Verify now at https://heroku.com/verify
```
クレジットカード情報を入力することでこのエラーは解決します。

次にホスト名などを取得します

```
$ heroku config:get CLEARDB_DATABASE_URL
```
ここで返される値の内訳は以下の通りです。

```
mysql://[ユーザ名]:[パスワード]@[ホスト]/[DB名]?reconnect=true
```
ここで得た値をもとに環境変数を設定していきます。

```
$ heroku config:set \
> DB_CONNECTION=mysql \
> DB_HOST=[ホスト] \
> DB_DATABASE=[DB名] \
> DB_USERNAME=[ユーザー名] \
> DB_PASSWORD=[パスワード]
```
それではmigrate&seedをしていきます。

```
$ heroku run php artisan migrate --seed
```
ここでエラーが頻発しました。

- uesrsテーブルのmigrateで問題発生

今回のAPIではusersテーブルは使用しなかったので、migrationファイルをコメントアウトして無効化するという強行策で解決。

- どうやらmigrationの宣言の部分で問題発生

こちらも強行策で解決させました。

MySQLWorkbenchをインストールして、手動でテーブルを作成していきました。笑
<img width="526" alt="スクリーンショット 2020-04-06 0.44.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/70048a3b-c302-7447-a468-8dc3a5e4efac.png">
そして最後にseedでテストデータを入れます。

```
$ heroku run php artisan db:seed
```

これでやっとAPIが使えるようになりましたー！
CSSのみでタイムラインを制作する 自分用備忘録

自分用のCSS備忘録です。
本当に自分用なんで解説などは一切ありません。

```
<div class="timeline RRR">
  <div class="timeline__item">
    <div class="maru">
      <div class="m"></div>
    </div>
    <p class="name">題名<br>ダミーテキストダミーテキスト</p>
  </div>
  <div class="timeline__item">
    <div class="maru">
      <div class="m"></div>
    </div>
    <p class="name">題名<br>ダミーテキストダミーテキスト</p>
  </div>
  <div class="timeline__item">
    <div class="maru">
      <div class="m"></div>
    </div>
    <p class="name">題名<br>ダミーテキストダミーテキスト</p>
  </div>
  <div class="timeline__item">
    <div class="maru">
      <div class="m"></div>
    </div>
    <p class="name">題名<br>ダミーテキストダミーテキスト</p>
  </div>
  <div class="timeline__item">
    <div class="maru">
      <div class="m"></div>
    </div>
    <p class="name">題名<br>ダミーテキストダミーテキスト</p>
  </div>
  <div class="timeline__item">
    <div class="maru2">
      <div class="m"></div>
    </div>
    <p class="name">題名<br>ダミーテキストダミーテキスト</p>
  </div>
</div>
```

```
@charset "UTF-8";
*,*::before,*::after {box-sizing: border-box}
html{font-size:62.5%;}
body{font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", YuGothic, "ヒラギノ角ゴ ProN W3", Hiragino Kaku Gothic ProN, Arial, "メイリオ", Meiryo, sans-serif;}
a:link,a:visited,a:hover,a:active{text-decoration: none;}

.RRR{
  width: 1200px;
  margin: 0 auto;
  margin-top: 100px;
}

.timeline{
  display: flex;
  justify-content: center;
  background-color: #eeeeee;
}
.timeline__item{
  width: 180px;
  text-align: center;
  font-size:18px;
}
.name{
  font-size:16px;
  width: 80%;
  margin: 0 auto;
}
.maru{
  position: relative;
  margin-bottom: 10px;
}
.m{
  width: 10px;
  height: 10px;
  border-radius: 50px;
  margin: 0 auto;
  border:1px solid #313131;
}

.maru:after {
  content: '';
  position: absolute;
  top: 50%;
  margin-left: 5%;
  display: inline-block;
  width: 90%;
  height: 1px;
  background-color: #313131;
}

.maru2{
  position: relative;
  margin-bottom: 10px;
}
```
Ubuntu 19.10でUnity Hubをランチャーに登録・アイコンを表示

UbuntuでUnity Hubを使う場合、公式HPからAppImageファイルをダウンロードし、実行権限を与えた上で実行します。
これはインストール形式ではないので、Unity Hubは初回実行時にdesktopファイルを配置するための__確認ダイアログを出してきます。__出てきます。出て……

__え？__

出てきません。Dockのアイコンも透明な状態で表示されてません。

# 解決策
AppImageファイルには`--appimage-extract`というコマンドラインスイッチがあります。
`--help`では表示されません。`--appimage-help`でAppImageのオプションを確認できます。

`--appimage-mount`で中身を確認すると、`unityhub.desktop`と`unityhub.png`が入っていることが確認できます。取り出してファイルパスをいじってdesktop-file-installでランチャーに登録しちゃいましょう。

```bash
./UnityHub.AppImage --appimage-extract unityhub.*
```
Fedora31のDockerでKeras環境を作る

# 環境

- OS: Fedora31
- nvidia-driver-cuda-libs-440.64.00-1.fc29.x86_64
  - libcuda.soを含む
- nvidia-driver-NVML-440.64.00-1.fc29.x86_64
  - libnvidia-ml.soを含む

# 元ネタ

- https://hub.docker.com/r/gw000/keras-full/

# CPUオンリー環境

```
docker run -d --rm --name keras-full -p 8888:8888 -v $PWD:/srv -t gw000/keras-full
```

- これで http://locahost:8888 にアクセス
- パスワードは keras
- カレントディレクトリは、 /srv にマウントされる

# GPU環境

- gpuを使えるようにするには、以下をコンテナ側に見えるようにする
  - /dev/nvidia*
  - /usr/lib64/libcuda.so
  - /usr/lib64/libnvidia-ml.so
 
```
#!/bin/sh

exec docker run --rm -d \
       --name keras-full \
       $(ls /dev/nvidia* | xargs -I{} echo '--device={}') \
       $(basename -a /usr/lib64/libcuda.so* /usr/lib64/libnvidia-ml.so* | xargs -I{} echo '-v /usr/lib64/{}:/usr/lib/x86_64-linux-gnu/{}:ro') \
       -p 8888:8888 -v $(pwd):/srv gw000/keras-full
```

- ls /dev/nvidea* の部分は以下のように展開される

```
$ ls /dev/nvidia* | xargs -I{} echo '--device={}'
--device=/dev/nvidia-modeset
--device=/dev/nvidia-uvm
--device=/dev/nvidia-uvm-tools
--device=/dev/nvidia0
--device=/dev/nvidiactl
```

- basename -a ... の部分は以下のように展開される

```
$ basename -a /usr/lib64/libcuda.so* /usr/lib64/libnvidia-ml.so* | xargs -I{} echo '-v /usr/lib64/{}:/usr/lib/x86_64-linux-gnu/{}:ro'
-v /usr/lib64/libcuda.so:/usr/lib/x86_64-linux-gnu/libcuda.so:ro
-v /usr/lib64/libcuda.so.1:/usr/lib/x86_64-linux-gnu/libcuda.so.1:ro
-v /usr/lib64/libcuda.so.440.64.00:/usr/lib/x86_64-linux-gnu/libcuda.so.440.64.00:ro
-v /usr/lib64/libnvidia-ml.so:/usr/lib/x86_64-linux-gnu/libnvidia-ml.so:ro
-v /usr/lib64/libnvidia-ml.so.1:/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1:ro
-v /usr/lib64/libnvidia-ml.so.440.64.00:/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.440.64.00:ro
```

# その他

- シェルを立ち上げるには以下のようにする

```
$ docker exec -it keras-full /bin/bash
```
解決方法: "Error: Invariant failed: You should not use <Link> outside a <Router>"

##はじめに
`react-router-hash-link`を使ってreactアプリを作っている時につまずいた備忘録です。

## コード
```jsx:React.js
import React, { Component } from 'react';
import { HashLink } from 'react-router-hash-link';

export default function hoge() {
    return (
        <HashLink to="./hoge#hoge" smooth>
            hoge
        </HashLink>
    )
}
```

##エラー
```:console.log
Uncaught Error: Invariant failed: You should not use <Link> outside a <Router>
    at invariant (tiny-invariant.esm.js:10)
    at Link.js:84
    at updateContextConsumer (react-dom.development.js:18304)
    at beginWork (react-dom.development.js:18661)
    at HTMLUnknownElement.callCallback (react-dom.development.js:188)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
    at invokeGuardedCallback (react-dom.development.js:292)
    at beginWork$1 (react-dom.development.js:23203)
    at performUnitOfWork (react-dom.development.js:22154)
    at workLoopSync (react-dom.development.js:22130)
    at performSyncWorkOnRoot (react-dom.development.js:21756)
    at scheduleUpdateOnFiber (react-dom.development.js:21188)
    at updateContainer (react-dom.development.js:24373)
    at react-dom.development.js:24758
    at unbatchedUpdates (react-dom.development.js:21903)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js:24757)
    at Object.render (react-dom.development.js:24840)
    at Module../src/index.js (index.js:8)
    at __webpack_require__ (bootstrap:784)
    at fn (bootstrap:150)
    at Object.1 (serviceWorker.js:141)
    at __webpack_require__ (bootstrap:784)
    at checkDeferredModules (bootstrap:45)
    at Array.webpackJsonpCallback [as push] (bootstrap:32)
    at main.chunk.js:1
```

##発生条件と解決方法
どうもstorybookはreact-routerに依存したサードパーティのコンポーネントを追加することを予期していないようで、対象コンポーネントを`react-router-dom`の`<MemoryRouter/>`で囲ってあげれば対応できるっぽいです。
また同様のことが`react-redux`の`<Provider/>`の外で`connect`や`useSelecter`を使った場合などにも生じるようです。

ただ今回は別にstorybookを使っているわけでもないのでとりあえず該当のコードを`<Memoryrouter/>`で囲うことで解決しました。

```jsx:React.js
import React, { Component } from 'react';
import { MemoryRouter} from 'react-router-dom';
import { HashLink } from 'react-router-hash-link';

export default function hoge() {
    return (
        <MemoryRouter>
            <HashLink to="./hoge#hoge" smooth>
                hoge
            </HashLink>
        <MemoryRouter>
    )
}
```

storybookに追加する際のエラーでもこれと同様に`<MemoryRouter/>`で囲う他、`addDecolator`を用いる方法もあるようです。以下の記事を参照してみてください。

## 参考
https://github.com/storybookjs/storybook/issues/8892
https://qiita.com/daikiojm/items/da3299d7b90d38194d85
grafana/influxdb/telegrafで10年前のシステムを可視化した

# はじめに

- 社内で10年前から稼働している、とあるシステム（Etudeと呼ぶ）の負荷状況について、これまで可視化されていなかったため、負荷の傾向を「なんとなく」でしか把握できない問題があった
- この度、非力なマシンでもわりとサクサク動かせることを目指し、軽量であると思われた表記スタックを使って可視化してみたので、そのノウハウを記録する

## 構築環境

### 動かすマシンのスペック

- CPU : Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz
- Memory : 4GB
- OS : CentOS 7.4

※安い仮想サーバなので、メモリがショボい。

### 各バージョン

- grafana : 6.7.0
- influxdb : 1.7.10
- telegraf : 1.13.4

### 構成図

<img width="912" alt="スクリーンショット 2020-04-05 23.15.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10317/42020d33-9f4d-2b09-3817-d1e320584c36.png">

### 構成の簡単な説明

- Etudeからのメトリクスデータ取得は、CentOSから定期的（Cron）にexpectのシェルスクリプトで行い、HDDにテキストで吐き出し続ける
- telegrafは、HDDの所定の場所に吐き出されたテキストをtailし続け、influxdbに送る
- grafanaはinfluxdbを参照する

# 解説

## telegraf

- インストールは非常に楽。公式HPの通り、yumによるインストール手順を実行するのみ。
- configファイルは、自動的に ``/etc/telegraf/telegraf.conf`` に格納される
- デーモンスタートも楽。``sudo systemctl start telegraf`` のみ。

### ポイント

- 初期Configは、稼働しているマシンのメトリクスを取得する設定が既に有効になっているため、必要最小限で1から作り直す必要がある。以下のコマンドで、必要最小限の設定項目に絞った初期Configが出力される
 - 今回は、Inputはtail, Outputはinfluxdbとするので、以下となる。

```
$ telegraf -sample-config -input-filter tail -output-filter influxdb
```

#### Outputフィルタ

- influxdbとのセット利用が前提で作られてるからか、ほぼデフォルトのままで利用できる。
- 設定したのは、サーバのアドレスとデータベース名のみ

```
[[outputs.influxdb]]
  urls = ["http://127.0.0.1:8086"]
  database = "etude"
```

#### Inputフィルタ

- tailのInputフィルタでは、読み取るファイルの場所と、データのフォーマットを記載するのみ。

```
[[inputs.tail]]
  files = ["/var/log/etude/*.log"]
  data_format = "influx"
```

- 対応しているフォーマットは、csvなどいくつかあるが、influxdb形式が一番簡単そうだったので、それに合わせることにした。
 - https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_tutorial/
- 実際のテキストファイルの出力を参考に掲載する

```
asa_osaka01 session=67
asa_osaka01 session=68
asa_osaka01 session=67
```

- この結果がどのように influxdb に格納されるか、というと以下のようになる。
- asa_tama01というmeasurement(RDBでいうテーブル)の、sessionというカラムに、influxdbに飛ばされた時刻のタイムスタンプとその値が格納されていることがわかる。

```
$ influx -precision rfc3339
Connected to http://localhost:8086 version 1.7.10
InfluxDB shell version: 1.7.10
> use etude
Using database etude
> select session from asa_osaka01
2020-04-05T15:10:02.57942373Z  67
2020-04-05T15:15:02.738080818Z 68
2020-04-05T15:20:02.87961773Z  67
```

## influxdb

- influxdbはインストールしてデーモンを起動したのみ。DBへのログインに認証をつけるのもメンドくさかったので、ホントに初期状態のConfigを利用。
- ``sudo systemctl start influxdb``

## grafana

- grafanaもインストールしてデーモンを起動したのみ。
- influxdbの参照設定からダッシュボード作成まで、ブラウザ上で設定するのみ。

### こんな感じで可視化できた

- ノードごとに自動でいい具合で色付けをしてくれるから、ダッシュボード作る側は楽なのに、とても見栄えがいいものができた

<img width="907" alt="スクリーンショット 2020-04-06 0.11.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10317/1409b1eb-bc64-8625-7a4d-c06d91cf68f2.png">

# 終わりに

- 可視化をし、負荷の傾向が見られるようになったことで、これまで気づかなかったシステムの品質の悪さなども明らかになった。（突然プロセスが再起動してセッションが切れてたり、だとか）
- 改めて可視化の大切さに気付かされた。
- influxdbでは、CQ(Continuous Query)といったDB内部で定期実行して値をサマッたりする機能があり、例えば直近10個の平均のみを記録するmeasurement(テーブル）も作れたりと、色々奥が深いので、機会があったらまたやってみようと思った。

以上
Netlify functionを使ってフォームが送信されたときに送信したユーザーのメールアドレスに自動返信する。

自社サイトを構築するときに、いままではWordpressのプラグインを使っていたので
フォームを送信したときに自動的に送信した人のメールアドレスに返信するシステムを作っていた。
JAMstackだとサーバーも何もないのでそのような動的な動きを作るにはどうすればいいか悩んだ。

#### netlify function
https://docs.netlify.com/functions/overview/

これを使うことでAWS Lambdaと同様の動きをnetlify上で起こすことができる。
今回使用するのはsubmission-createdという名前を使うことでFORMが送信されたときをトリガーとして動作させることができる。
他にも様々なことをトリガーとしてどうさせることができるので用途に応じてチョイスするのが良いだろう。

使う内容としてはnodemailerを使う
https://nodemailer.com/about/



```submission-created.js
require('dotenv').config();

const nodemailer = require('nodemailer');

exports.handler = function(event, context, callback) {
  const { name, email, message } = JSON.parse(event.body).payload.data

  console.log(user);

  let transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
      type:"OAuth2",
      user:"GmailのID",
      clientId:"取得したClientID",
      clientSecret:"取得したコード",
      refreshToken:"（リフレッシュトークン）",
      accessToken: "（アクセストークン)"   
    },
  });


  console.log(event.body);

  let mailOptions = {
    from: `"表示する名前"<使用するgmailアドレス>`,
    to: `${email}`,
    subject: 'ありがとうございます。フォームを送信いたしました',
    html: `${name}様　メッセージを送信しました。`,
  };

  transporter.sendMail(mailOptions, function(error, info) {
    if (error) {
      callback(error);
    } else {
      callback(null, {
        statusCode: 200,
        body: 'Ok',
      });
    }
  });
};
```
送信例
![IMG_9740.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/748c1ca6-efe3-1664-da57-917334ec6517.png)

##### Netlifyはサーバーレスの味方
フォームを作ることに関してはまた別に書こうとは思うが
かんたんな動的動作についてはサーバーレスでもなんとかなるのでコストダウンにつながるのではないかとは思われる。
GASを使ってワンクリックでメールを送る

# はじめに
* 新型コロナウイルス対策でテレワークが急速に普及している。
* 出退勤時にメールを送る運用をしているところがあるらしい。
* しかし、テンプレメールを毎日送るのは面倒くさい。
* GASを使ってワンクリックでメールを送れるようにしたので紹介する。

# 作ったもの

* ボタンを押すと（ほぼ）固定文言のメールを送ることができるWebページ
<img width="680" alt="スクリーンショット 2020-04-07 00.17.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537648/757d54be-bbb6-1a2c-02b6-30fe410e2686.png">


* 送られるメール（内容は適当）
<img width="596" alt="スクリーンショット 2020-04-06 00.04.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537648/935947d1-9e4c-47d1-0c35-bfd014415ba1.png">

#ソースコード

### コード.gs

```
function doGet() {
  
  const toppage = HtmlService.createTemplateFromFile("home");
  return toppage.evaluate();
}

function doPost(postdata){
  
  const button = postdata.parameters.button.toString();

  const to = 'hoge@gmail.com';
  const subject = button + 'します';
  const body = button + 'します';
  
  GmailApp.sendEmail(to, subject, body)
  
  const resultpage = HtmlService.createTemplateFromFile("home");
  return resultpage.evaluate();
}
```

### home.html

```
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h1>出退勤メール</h1>
    <form method="post" action="https://script.google.com/macros/s/hogehoge/exec">
      <input type="submit" name="button" value="出勤">
      <input type="submit" name="button" value="退勤">
    </form>
  </body>
</html>
```

* URLはアプリごとに変わるため、書き換える必要がある。
  1. ツールバーの「公開」→「ウェブアプリケーションとして導入...」を選択
  2. Current web app URLに記載されているURLをコピペ

<img width="527" alt="スクリーンショット 2020-04-07 00.49.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537648/bab86ace-ec31-f145-8476-4c22e3192735.png">
<img width="445" alt="スクリーンショット 2020-04-07 00.50.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537648/7d3ade00-eba1-ff23-4e02-6c5ccf773c54.png">


# 未実装内容

* 送信先情報をスプレットシートから読み込むようにしたい。
* ボタンの判定が雑すぎるので良い感じにしたい。

# おわりに

* 退屈なことは自動化して楽に仕事がしたい。
Raspbianのデフォルトサービスの要否を調べる


# 本記事の目的

Raspberry Pi ZeroにてRaspbianを使用する際、
不要なサービスの自動起動を抑止することで、多少なりとCPU時間をアプリケーションにて有効活用することが期待できる。
そこで、Raspbianにデフォルトでインストールされ、かつ自動起動するサービスについて調べる。

基本的な内容としては、各サービスのmanの内容を自分用にまとめているだけである。

各サービスの役割と、自動起動無効化の判断について順次列挙していく。


# サービス一覧

## fake-hwclock.service

起動無効化：しない。oneshot起動のためしても効果は薄い（起動時間が若干早くなる程度）

OS起動中のみ使用する時刻を保持するサービス。
PC等であれば、RTC等によるハードウェアクロックから時刻を得るが、ラズパイにはRTCは無い。
OS起動完了してネットワーク接続後はNTPで時刻を得るが、OS起動中は取ってこられない。
そこで仮の時刻を設定してくれるのがこのサービス。前回OSシャットダウン時の時刻（ファイルがなければUNIX時刻の起点、1970年1月1日の0時）を設定する。

## rpi-eeprom-update.service

起動無効化：しない。oneshot起動のためしても効果は薄い（起動時間が若干早くなる程度）

EEPROMに格納されているファームウェアのアップデートをチェックするサービス（らしい）。
（初心者）インターネットに関する最低限の知識

## DNS（Domain Name System）
IPアドレスだと人にとってわかりにくいので、それをわかりやすくしたもの。
人間が理解しやすいようにドメインという概念を作り、そのドメインとIPアドレスを結び付けるためにDNSという仕組みができた。
DNSのサーバーが世界中にあり変換してくれている。

## HTTP (Hyper Text Transfer Protocol)
ホームページのデータは文字だけでなく画像や動画などがあります。これらのデータをサーバとクライアントの間で通信するときの通信規約（プロトコル）がHTTPです。
通信規約とは、ホームページを構成しているhtmlファイルや画像ファイルなどを自分のパソコンにデータとしてダウンロードする手順のことを言います。

### HTTPステータスコード
200 : 正常
404 Not Found : リクエストされたURLが見当たらない
403 Forbidden　: そのファイルはアクセスが禁止されている
304 Not Modified : 前にアクセスしたときからページの内容が変わっていないので自分の覚えているキャッシュから表示を始める。

## ブラウザ
Google Chrome、Safariなどのこと


## ホスティング
サーバーを借りること。レンタルサーバー。
１、共有ホスティング
マンションの石いつを借りるみたいなもの
２、専用ホスティング
一軒家を丸ごと借りるみたいなもの

参照：https://www.webhostingsecretrevealed.net/ja/blog/web-hosting-guides/what-is-the-difference-between-a-domain-and-web-hosting/
Rails入門メモ1

#コマンド

###Railsアプリケーション作成
$rails new アプリケーション名

実行すると新しいファイルが作成される。
ファイルの中でも「app」「config」「db」が重要。

appの中にはasset(画像やJavaScriptやCSS)、controller、view(HTML)、model(DBを操作する奴)がある。
configの中にはrouteがある。

###ページ作成
$rails generate controller コントローラー名 アクション名

```
#例
rails generate controller home top

#省略版
rails g controller home top
```
実行すると、localhost:3000/home/topというURLにアクセス出来る。
また、viewフォルダの中にhomeフォルダとtop.html.erbファイルが出来る。

#ページ作成
3つの要素を必要とする。Rails中に存在する。
●ビュー(view)
html.erbファイルをもつ。
●コントローラー(controller)
例）homeコントローラーのtopアクションに対応するHTMLをビューから探してブラウザに渡す。
また、ビューのHTMLで使用する変数は、コントローラーのアクション内で宣言できる。
●ルーティング(routing)
URLとそれに対応するコントローラーとアクション情報のテーブルをもつ。

####流れ
ブラウザがRailsにHTMLファイルを要求すると、Rails中のルーティングに記載されているURLを見て、それに対応するコントローラーを経由してビューをブラウザに返す。

☆新しいページを追加するには、自分でルーティングやコントローラー（アクション)を記述する。


#参考文献
Progate https://prog-8.com/languages/rails5
ドットインストール https://dotinstall.com/lessons/basic_rails_v3
awsコマンドでPythonのNo module named 'encodings'のエラーが出る

## 概要
MacでAWS CLIのコマンドを実行した時、いつからか`No module named 'encodings'`というコマンドが出るようになりました。この時にやったことを色々書いてます。
ただ、結論を先に言うと、__Python3を再インストール__して直しました。

## 事象と試したこと

awsコマンドを実行すると、以下のようにエラーが出るようになり色々ググってみることに。補足すると、AWS CLIの中でPythonを使っているため、Pythonも正しく設定されている必要があります。

```bash
$ aws configure --profile XXXX
...(省略)...
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named 'encodings'
...(省略)...
```

試したのはいずれもパス関連の修正です。

#### 1. PYTHONHOMEの設定を変えてみる

 - エラーをググると、PYTHONHOMEのパスを疑えというページが出てくるため`.bash_profile`を確認してみると、確かに設定されていませんでした。そのため、デフォルト値である`/usr/local`を設定してみることに。
 - 結果、エラーは変わりましたが、`syntax error`という__別のエラーが出てくることに__...

#### 2. PYTHONPATHの設定を変えてみる
 - これも同様に`.bash_profile`に色々な値を設定してみましたが、エラーは変わっても解決には至らず...


Macでは`/usr/bin/python`がデフォルトでPython2系のバージョンになっています。そのため、pyenvやAnacondaなど別のツールを使ってPython3をインストールしていましたが、この時Python3のパスは`/usr/bin/python`から変えていませんでした。いろいろ作業をしていく中でPyhton3のパスがおかしくなってしまったようです。
__※pyenvやAnacondaが原因ではなく、作業のうちに環境を壊してしまったことが原因だと考えられます。__


## 解決策
pyenvおよびAndacondaをアンインストールした後、以下を参考にPython3を再インストールしました。
[【Python3】まっさらなMacにPythonの最新バージョンをインストールする手順まとめ](https://tipstour.net/python3-install-on-mac)

上記手順の中で、`/usr/bin/python`にはPython3のパスを当てるようにしました。無事、awsコマンドも通るようになりました。

## 雑感
正直、最初から再インストールしておけば良かった...と思いました。IDEでのインタプリタ再設定などが面倒かなと思ったのですが、ハマってた時間に比べれば全然短いです。

何事も諦めが肝心ですね....
mod_wsgi+flask+flask-httpauthのBasic認証でうまくログインできないとき

- FlaskでBasic認証を用いたアプリを作成した
- 手元で直接実行してテストしたときに正しいユーザとパスワードで認証ができる
- しかしApache+mod_wsgiな環境で動かしたときに認証ができない。

## 環境

- 言語: python3
- ライブラリ: flask-httpauth, mod_wsgi
- Webサーバ: Apache2.4

## 解決方法
以下の設定をapacheのflaskアプリの設定部分に追記する。

```
WSGIPassAuthorization On
```

## 原因
解決方法を見てわかるとおり、mod_wsgiでbasic認証をするために必要な設定がされていなかった。

## 参考
- [flask-httpauthを使って、FlaskでBasic認証を5分で実装する](https://qiita.com/mitch0807/items/d5e354a4e6e5b4f04bd6)
- [Djangoで特定のページのみBasic認証をかける](https://yura2.hateblo.jp/entry/2015/04/03/Django%E3%81%A7%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AE%E3%81%BFBasic%E8%AA%8D%E8%A8%BC%E3%82%92%E3%81%8B%E3%81%91%E3%82%8B)
複数の同名CSVファイルをマージするシェル


同じ名称のCSVファイルをマージし、
ソートと重複削除（空白行は削除）するshを作成しました。

#①呼び出し元：file_marge_cvs.sh
　こちらで対象のファイルを追記していきます。

```
#!/usr/bin/bash

#対象のファイル名をこちらに追記していきます
name1=sample1
name2=sample2

#上記で指定したファイル名を引数にshを実行します
 sh file_marge_cvs_sub.sh $name1
 sh file_marge_cvs_sub.sh $name2

echo FINISH_ALL!!
echo $?
```

#②呼び出し先：file_marge_cvs_sub.sh
　メインの処理です。
　./INPUTでfind
　　⇒./WORKに中間ファイル（同名ファイルをマージしただけ）出力
　　　　⇒./OUTPUTに最終ファイルを出力します（マージ後のファイルにソートと重複削除）

``` 
#!/usr/bin/bash

#ファイル名を引数として取得する
name1=$1
echo $name1
#WORKフォルダ配下についてCSVファイルを検索する
counter=0
for file in `find ./input -name \$name1.csv`;
do
  echo $file
    if [ $counter == 0 ]; then
      cat $file > ./work/${name1}.csv
    else
      cat $file >> ./work/${name1}.csv
    fi
      counter=`expr $counter + 1`
done
#取得したファイルをソートし、マージをかけてoutputフォルダ配下に格納する
sort -t ',' ./work/${name1}.csv | uniq |grep -v '^$'> ./output/${name1}.csv
echo finish!!_$name1
#検索結果を別ファイルに出力する 
```
#※ご参考までにディレクトリ構成を載せておきます。
![ディレクトリ構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264141/fdfa2b38-9d5b-874d-d48b-c3d3ae1f984d.png)
【Ruby】puts,p,printメソッドの違い 


**puts、p、printメソッド**について、違いが分からなかったので調べてみました。


***
**putsメソッド**

-改行**あり**
-引数のオブジェクトを**文字列**に変換して出力

```ruby:putsメソッド

puts "あけまして、そらじろう"
puts 20200405
```
```ruby:ターミナル
あけまして、そらじろう
20200405
```

***

**pメソッド**
-改行**あり**
-引数と引数の**文字型(文字列や数値)**も出力

```ruby:pメソッド
p "あけまして、そらじろう"
p 20200405
```
```ruby:ターミナル
"あけまして、そらじろう"
20200405
```
***

**printメソッド**
-改行**なし**
-数のオブジェクトを**文字列**に変換し出力

```ruby:printメソッド
print "あけまして、そらじろう"
print 20200405
```

```ruby:ターミナル
あけまして、そらじろう20200405
```

***

*追記*
putsメソッドとpメソッドの違いは、文字列として識別できるかどうか
printメソッドは、改行のないputsメソッド

ちなみにpメソッドは、デバッグでよく使うみたいです。


<https://gihyo.jp/book/2018/978-4-297-10123-7
<https://rurema.clear-code.com/
VueRouter使い方


###VueRouterのインストールから初期セットアップ

vue-routerをインストール

```
npm install vue-router
```


vue-routerを利用する各ファイル

```main.js
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';

//router.jsファイル
import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
  vuetify,
  render: h => h(App)
}).$mount('#app')
```

```router.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'Index',
      component: () => import('./components/Index.vue')
    },
    {
      path: '/form',
      name: 'Form',
      component: () => import('./components/Form.vue')
    },
  ]
})
```

```App.vue
<template>
  <div id="app">  
    <v-app>
      <Header/>
      //Routerを利用
      <router-view/>
      <Footer />
    </v-app>
  </div>
</template>
```


###router使用例


```example.vue
<router-link to="/foo">Go to Foo</router-link>

//Vuetifyのv-btnとの組み合わせ
<router-link tag="v-btn" to="/edituser">登録情報を変更</router-link>

//Vuetifyのv-btnとパラメータをセット
<router-link tag="v-btn" :to="{ name: 'ToPage', params: { id: this.$route.query.fooid }}"


//画面表示時にStore(Vuex)からログイン状態を取得。ログインしていない場合にログインページへ遷移
created(){
      const loginStatus = this.$store.getters['loginStatus'];
      if (loginStatus == false && this.$router.currentRoute.path != "/login") {
        this.$router.push({name : "PageLogin"});
        return;
      }
```


####参考
https://router.vuejs.org/ja/installation.html