OmniAICreator/Qiita-1.07M huggingface dataset:
M5Stack用Sigfoxモジュールの使い方

#はじめに
M5Stack用Sigfoxモジュールの使い方を紹介します。
直接Sigfoxサーバへ直接データが送れるため，単体のIoT機器として活用範囲が広がります。
事例として，工場の電流モニタを安価に作る方法として複数回にまとめます。
今回はデータをUIFlowにより送信するまでの記事です。

Sigfoxのデバイス登録やコンソールの使い方は参考資料の記事を参照してください。

<img width="400" alt="IMG_1759.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/30dbbd0b-7f58-1509-5241-564f1344f95d.jpeg">

#使用機材
| 機器 | 内容 | 価格 | 入手先 |
|:--|:--|:-:|:--|
|M5Stack   |CPUボード   | 3,675-  |https://www.switch-science.com/catalog/3647/|
|Sigfox Module   |M5Stackと合体   | 5,500-  |https://www.switch-science.com/catalog/6624/|
|電流センサ   |Grove対応の電流センサ   |7,820-   |https://mii-system.booth.pm/items/2307810|
合計：16,995-

#組み立て
Moduleを取り出します。本体とアンテナとケーブルの３点構成。
<img width="400" alt="IMG_1736.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/170670a9-6154-9945-cb8b-6465c7f8c8f5.jpeg">

UARTの設定です，Defaultは16/17 に設定されてます。Module側から見たTXD/RXDなのでM5Stack側はTX=17,RX=16で使用します。間違えやすい所。
<img width="400" alt="IMG_1737.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/8c5ad07d-37cf-eec6-9df3-588625e5538b.jpeg">

Sigfox基板を一旦外し，アンテナを取り付けます。UFL(小さいので気をつけて)とケースのプラをニッパなどで切りSMAアンテナを付けます。こちらの方向だと電源ケーブルと同じ側になるのでおすすめかな。
<img width="400" alt="IMG_1738.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/f03898d9-74d1-8dd8-ab3f-3882a4b5c198.jpeg">

センサとはGroveのi2cケーブルで繋ぎます。
クランプセンサなので電源線の片側をクランプして計測します。
<img width="400" alt="IMG_1762.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/efef3397-58d9-59ae-4500-4b5fdf0659ba.jpeg">

#Flow
UIFlow1.65により動作確認しました。(2020-10-27)
Sigfox Moduleは昔ながらのATコマンドで制御でき，UARTが繋がればCPUはなんでも使えると思います。ポイントとなる部分のみですがフローを説明します。

画面デザインは電流と周波数が計測できるので表示エリアを準備します。
デバッグ用にSigfoxの情報と送信データを表示しています。下の方はグラフエリアです。
殺風景なのでロゴも表示してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/f9c5735a-ae12-5e7a-e088-6e68903f1d76.png)

電流センサとはI2CのID=0x50/100kHz，SigfoxとはUART17/16にて接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/279c8e6c-ec51-70a9-48a1-88cc3f92315c.png)

タイマー割込により３秒毎に電流読み出しと表示，３分毎にデータ保存し，15分ごとにまとめてSigfoxへ送信しています。
15min=900s/3s = 300dotを使い電流をグラフ表示しています，ちょっとしたテクなのでご参考に。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/5a033b0c-de6b-0a42-50a8-76b85cd35ab4.png)

Sigfoxコマンドをサブルーチン化しています。Cボタンを押している間ID/PACを表示
'AT$SF=xxxx' によりSigfoxへ送信できますが，HEX文字列を作る所で悩みましたが，下のformat命令を使って3分毎の電流値と周波数を2Byteの16進数に変換できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/88ac33d4-b8a7-1bea-d6d2-4888a7bce48c.png)

```Python
gMsg =  '{:04X}{:04X}{:04X}{:04X}{:04X}{:04X}'.format(c1,c2,c3,c4,c5,f5)
```

残りのFlowはGithub に公開しておきますので，そちらを参考にしてください。

15分ごとにputSF関数を呼び出しSigfoxコンソールにデータが送信できました。
本記事はここまでで，次はSigfoxサーバの設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186241/44f0d574-bf7a-076e-01a2-f4e7c16b4ed4.png)

#関連記事
後日追加

#参考資料
https://m5stack.com/pages/download
https://qiita.com/ghibi/items/5893923b44f1757294e9
https://github.com/Mii-system/ATMICL-ONE/tree/master/SRC/M5Stack(UIFlow)
Expected exactly 2 elements matching "a[href="/"]", found 0..　のエラーメッセージ

#Expected exactly 2 elements matching "a[href="/"]", found 0..のエラーメッセージ

<br>
Railsチュートリアルをやっている時にエラーが起きたので、解決した方法を書きます。やっていたのは5章の「5.3.4 リンクのテスト」の所です。
エラーメッセージは

```
 FAIL["test_layout_links", SiteLayoutTest, 2.2938910419998138]
 test_layout_links#SiteLayoutTest (2.29s)
        Expected exactly 2 elements matching "a[href="/"]", found 1..
        Expected: 2
          Actual: 1
        test/integration/site_layout_test.rb:10:in `block in <class:SiteLayoutTest>'

  1/1: [===================================] 100% Time: 00:00:02, Time: 00:00:02

Finished in 2.29667s
1 tests, 2 assertions, 1 failures, 0 errors, 0 skips

}
```

<br>
私の場合はこのファイルに異常がありました。
app/views/layouts/_header.html.erb

```
<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", root_path, id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home",   'root_path' %></li>
        <li><%= link_to "Help",   'help_path' %></li>
        <li><%= link_to "Log in", '#' %></li>
      </ul>
    </nav>
  </div>
</header>
```

<br>
この中でも今回は、上記のroot_pathとhelp_pathに'　'がついていたことが原因みたいでした。このエラーが出た原因は、もともとあった'#'にroot_pathなどを入れたことで外し忘れていたみたいでした。
正しくはこちらになります。

```
        <li><%= link_to "Home",   root_path %></li>
        <li><%= link_to "Help",   help_path %></li>
```


<br>
因みに、app/views/layouts/_fotter.html.erbにも同じようなミスがあったので、上記のエラーが起こった方は確認してみると良いかもしれません。

##参照元
https://teratail.com/questions/189008
「sudo su」ってざっくり言ってなんぞ？

自分用のメモとして残します。

# はじめに
LinuxOSを操作するときに出てくる `sudo su` というコマンド。
今でこそ理解はしていますが、当時は
「なんでsudo suってうつんだ？」
「なんで今回はsudoの後ろにsuがないんだ？」とか
「え、今回はsu の後ろに-（ハイフン）がついてるんだ？」
となって混乱していました。

windowsユーザだと「結局sudo suってなんだ？」となるので、きちんとコマンドを知るという意味でまとめてみました。

# sudoコマンドとは？
スーパーユーザ（=root）としてsudoに続くコマンドを実行するということ。
つまり、その瞬間だけroot権限になってコマンドを実行するということです。
要約すると「管理者権限で○○○コマンドを実行します。」となります。
少し違うかもしれませんがWindowsのUACみたいな感じかな？

```shell
#管理者として実行したいコマンドがある場合に使う
sudo コマンド
```

# suコマンドとは？
sudoの続きによくくる「su」というのはコマンドです。
では、suコマンドを実行するとどうなるのか？
suコマンドはユーザを切り替えるコマンドになります。
このsuコマンドを実行すると以降の操作は切り替えたユーザで操作になります。
windowsで例えるのであれば、デスクトップを表示した状態でAlt＋F4でユーザの切り替えがあると思います。
これは現在サインインしているアカウントをログオフせず、別のアカウントでもサインインするという動作になるため、suコマンドはそれに近いと思います（厳密には全然違うといえば違うけど、ざっくりとした概念はそんな感じだとおもう。。。）


```shell
#ユーザを切り替えたいときに使う。
su 切り替えるアカウント名
#（アカウント名を省略すると暗黙的にrootとしてユーザ切り替えを処理する（重要））
```
## 余談だけど、「su -（ハイフン）」 コマンドは？
suコマンドに-（ハイフン）がついているときとそうでないときがあります。
ハイフンがついているときは、**切り替えたユーザのホームディレクトリに移動する**というオプションになります。
そのため、**カレントディレクトリを切り替えたくない場合はハイフンは付けません**。

```shell
#ユーザを切り替え＋切り替えたユーザのホームディレクトリへ移動
su - 切り替えるアカウント名
```


以上。
【小ネタ】Logstash Logback Encoder の出力をCloudLoggingの重要度に反映させたい

# 問題
[「Logback」](http://logback.qos.ch/)でJSON形式で出力する場合、[「Logstash Logback Encoder」](https://github.com/logstash/logstash-logback-encoder)を使うと便利が良いのですが、そのまま利用するとGCPのCloudLoggingの重要度（Level・Severity）が反映されず、すべて「INFO」で出力されてしまいます。

# 解決策
単純に「Logstash Logback Encoder」の重要度のフィールド名を「level」から「severity」に変更するだけで解決します。

```xml:logback.xml
<!-- 一部抜粋 -->
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
  <fieldNames>
    <level>severity</level>
  </fieldNames>
</encoder>
```
HerokuにデプロイしたMysqlのロールバック方法をメモ

## はじめに
RubyOnRailsでアプリを作成しデプロイ。
Heroku上でマイグレーションファイルを実行後のベータデースのリセットをメモしておく。

***

● エラーメッセージから環境変数を確認

`コマンドを実行`

```
$ heroku run rake db:migrate:reset!
```
`エラー画面`
![エラー画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/828524/8c987826-2bbc-508d-e735-9f68af58d12a.png)

<br>

● 確認した環境変数 DISABLE_DATABASE_ENVIRONMENT_CHECK=1 を付与して、データベースをdropする

`コマンドを実行`

```
$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop
```
　`実行後`
![スクリーンショット 2020-10-28 16.09.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/828524/b00f7f64-f77f-49cf-5e9b-c526a4171ed5.png)


<br>




●　再生成

`コマンドを実行`

```
 データベースの生成
$ heroku run rails db:create

 マイグレーションを実行
$ heroku run rake db:migrate
```

## 参考
[[Rails5] heroku db:resetからmigrateまで](https://qiita.com/params_bird/items/3d503b5c9f8097df147a)
[Rails5のproductionでrake db:dropはできない、普通には](https://qiita.com/Esfahan/items/75ade0233fe02ab04381)
Alertを起動中１回のみ表示・二度と表示しない機能

ダイアログによくある選択肢

パターン①OK
--押下後、起動中はもう表示しない。次回起動したら、また表示する

パターン②二度と表示しない
--押下後、もう表示しない再起動しても表示しなくなる。
 　アプリをアインインストール、再度インストールしたら、また表示する

それぞれを実装してみましたのでメモしておきます。

アプリ起動、ダイアログのOKの押下後、FlagをTrueにして起動中に表示させなくなるための準備

```php:DialogHelper
class DialogHelper {
    
    static let shared = DialogHelper()
    var dialogDidSee = false
    
    func getDialogStatus()->Bool{
     
        return dialogDidSee
    }
    
    func setDialogStatus(_ flag:Bool){
        
        dialogDidSee = flag
    }
}
```

アンインストールするまで二度と表示させないため
アプリ終了後も消えさせないデータ、ユーザの設定のデータを保存するUser Defaultsの準備

```php:UserDefaultsKey
enum UserDefaultsKey: String {
    
    case dialogNoMore = "dialog_neverAgain"
    
    func initalValue<T>()-> T?{
        switch self{
        case .dialogNoMore:
            return false as? T
            
        default:
            return nil
        }
    }
}
```

ViewControllerでこのようにAlert作成
Alertを出すべきかどうかを判断、の二つのメソッドを作ります。

```php:ViewController
    func showDialogIfNeed(){
        
        let didSee = DialogHelper.shared.getDialogStatus()
        let neverSee = UserDefaults.standard.bool(forKey: UserDefaultsKey.dialogNoMore.rawValue)
        
        if neverSee {
            return
        }else{
            if didSee {
                return
            }else {
                createDialog()
            }
        }
    }

    func createDialog(){
        
        let alert:UIAlertController = UIAlertController(title: "Here is a message for you!", message: "", preferredStyle: .alert)
        
        let okAction:UIAlertAction = UIAlertAction(title: "OK", style: .default, handler: {
            (action:UIAlertAction!) -> Void in
            DialogHelper.shared.setDialogStatus(true)
        })
        
        let neverAgainAction:UIAlertAction = UIAlertAction(title: "Never remind me", style: .default, handler: {
            (action:UIAlertAction!) -> Void in
            UserDefaults.standard.set(true, forKey: UserDefaultsKey.dialogNoMore.rawValue)
        })
        alert.addAction(okAction)
        alert.addAction(neverAgainAction)
        
        present(alert, animated: true, completion: nil)
    }
```

```php:ViewController
override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        showDialogIfNeed()
    }
```

動いてみて試したら、OKボタンとNeverAgainボタンがちゃんと動作しました。

ちなみにこのようなLayoutを作りました。
viewDidLayoutSubviews()を忘れずに気をつけよう。

```php:ViewController
let label = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.brown
        label.text = "Please see the Dialog"
        label.textAlignment = .center
        view.addSubview(label)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        label.frame = view.bounds
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        showDialogIfNeed()
    }
```
VL53L1X ToFセンサーをRaspberry Piで使ってみた

#はじめに
前にUS-100超音波センサーを使った記事を[投稿しました](https://qiita.com/BlueWindows/items/d6b5e6c3d6afc3c9af5c)が、VL53L1XというToF(Time-of-Flight)センサーも使ってみたので、そのことを書いていこうと思います。

#ToFセンサーとは
ToFセンサーは、赤外線レーザーの飛行時間を用いて距離を測るセンサーです。超音波センサーでは超音波の跳ね返ってくる時間で距離を出していましたが、ToFセンサーはそれがレーザーになった形です。

今回用いたToFセンサーは、VL53L1Xです。SwitchScienceにて購入しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718856/f346cc10-f700-cf0c-089a-3954cf7c03b5.png)

こちらのボードは2.6V~5.5Vの入力電圧で動作するように、2.8Vのリニアレギュレータとレベルシフタが搭載されています。I2Cで通信します。

#回路図
回路図は次の画像の通りです。（画像はVL53L0Xになっていますが、VL53L1Xと思ってください。ポートは変わらないです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718856/7545dee6-5995-ee64-c2c2-6f2574583f1d.png)

I2C通信なので、SDA, SCL同士をつなげます。今回はVCCに3.3Vを与えています。実際につなげたものが次の画像です。（前回の記事の流用です…すみません）
![IMG_5678.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718856/7dbf3e75-eeeb-c1a7-571e-050ad2cb6e4a.jpeg)

#プログラム
サンプルプログラムが[GitHubにあった](https://github.com/pimoroni/vl53l1x-python)ので、これを用いました。ただ、これをそのまま使ったときに、なぜか終了(Ctrl+C)ができなかったので、その部分だけ改変しました。なお、あらかじめターミナルで次のコマンドを実行してインストールする必要があります。
```
sudo pip install vl53l1x
```

```VL53L1X_test.py
#!/usr/bin/env python

import sys
sys.path.insert(0, "build/lib.linux-armv7l-2.7/")

import VL53L1X
import time
from datetime import datetime

tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
print("Python: Initialized")
tof.open()
print("Python: Opened")

tof.start_ranging(1)

# try:
#   while True:
#        distance_mm = tof.get_distance()
#        print("Time: {} Distance: {}mm".format(datetime.utcnow().strftime("%S.%f"), distance_mm))
#        time.sleep(0.001)
# except KeyboardInterrupt:
#    tof.stop_ranging()
while True:
    flug_stop = input("Pless Enter to measure, input \"EXIT\" to exit... : ")
    if(flug_stop != "EXIT"):
        distance_mm = tof.get_distance()
        print("Time: {} Distance: {}mm".format(datetime.utcnow().strftime("%S.%f"), distance_mm))
        time.sleep(0.001)
    else:
        tof.stop_ranging()
        break
```
途中コメントアウトしている部分は、サンプルプログラムでの測定のプログラムですが、これだとなぜかCtrl+Cがきかなかったので、EXITと入力することで処理を終了するように変更しました。
tof.get_distance()で距離を測定しています。

#使ってみた
実際にこのプログラムを使ったところ、次の画像のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718856/9eb4a01e-0ec6-497f-759e-58422839bb60.png)
きちんと距離が測れていることが分かります。一応、巻き尺を使って正確に測れているかも見てみました。

|距離(cm)|10|20|30|40|50|60|70|80|90|100|
|---|---|---|---|---|---|---|---|---|---|---|
|測定結果(cm)|11.3|20.6|29.6|39.3|49.4|59.3|69.1|78.8|88.3|98.0|

|距離(cm)|110|120|130|140|150|160|170|180|190|200|
|---|---|---|---|---|---|---|---|---|---|---|
|測定結果(cm)|108.0|116.7|126.8|135.8|146.2|155.3|165.7|174.5|183.6|194.3|

140㎝あたりから、最初に全然違う値が測定された時がありました。ただ、何回か計測をするとちゃんとした値が出たので、測定用の遮蔽物を動かす時に出たレーザーの値がでていたと考えています。

#感想
超音波センサーよりも精度良く出るのかなと思っていたのですが、意外と変わらなくて驚きました（ただしこっちの精度が悪いのではなく、超音波センサーの精度が想像以上に良かったというほうです）。大きさとしてはこっちのほうが小さいので、利便性みたいなものはこっちのほうがいいと思います。まあ目に安全とはなっているとはいえ、レーザーですので、どのような状況でも使えるものではないかもしれないですが…（超音波センサーなら超音波なので直視しても一切問題なし）
測定した後で気づいたのですが、どうやらスタートするときに長さにおけるいくつかのモードがあるらしく(start_ranging(1)の部分)、そのモードを長距離のものにすれば、長距離の精度が上がるかもしれません。多分自分はそっちの測定はやらないので、興味がある方は買って試してみるのもいいかもしれませんね。
ここまでご覧くださり、ありがとうございました。
Unityアセットの宴でシーンを超えてデータを参照する方法

AdvEngineの中にAdv Save Manager、Adv System Save DataというのがあるのでそれぞれのDirectory Name、File Nameをすべてのシーンで合わせれば同じデータを参照することができる。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/7df28467-5b4b-e9bb-e5ec-74d8b78b89e7.png)

Adv Save Managerはシナリオ単位での保存データで、Adv System Save Dataはコンフィグ関連の保存データだと思う。
同じシーンのAdvEngineオブジェクトをコピーすれば何ということはないと思うのだが自分はDirectory Nameが違っていたせいでエラーになっていた。いったいどこから持ってきたんだ…

ちなみにセーブデータは設定したフォルダ名、ファイル名で以下のように保存される。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/2992449c-6809-ff00-c52b-15c0b836cb28.png)

宴はいろいろ難しすぎて眠くなる。
【Flutter】デバイスから画像や動画を取得（Image Picker）

#概要
パブリックへのアップロードを実装する際に、ローカルデバイスのギャラリーから画像や動画を取得し一旦保持する処理が必要になります。それを今回はプラグインとして提供されているImage Pickerで実装していきます。

#手順
######0.iOS用のセットアップ
```plist:info.plist
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires to access your photo library</string>
<key>NSCameraUsageDescription</key>
<string>This app requires to add file to your camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires to add file to your photo library your microphone</string>
```
######1.パッケージの導入
画像も動画もimage_pickerを使います。
以下のように、dependencies:の配下に記載しましょう。

```yaml:pubspec.yaml
dependencies:
  image_picker: ^0.6.7+11
```

######2.インポート
```dart:
import 'dart:io';
import 'package:image_picker/image_picker.dart';
```

######3.ファイルを取得
Stateクラスの中に定義します。

```dart:
class _UploadScreenState extends State<UploadScreen> {
  File _video;
  final picker = ImagePicker();

  Future getVideoFromGalley() async {
//  画像の場合
//  final pickedFile = await picker.getImage(source: ImageSource.gallery);
    final pickedFile = await picker.getVideo(source: ImageSource.gallery);
    setState(() {
      if (pickedFile != null) {
        _video = File(pickedFile.path);
      } else {
        print('No video selected');
      }
    });
  }
```
上記はギャラリーから取得する場合。
カメラから取得したい場合は、source: ImageSource.cameraとしてください。
これで_videoに画像や動画の中身が格納されたのであとは煮るなり焼くなりしてください。

#Tips
アップロード用ファイルをサイズで制限したい時、ファイルオブジェクトからサイズを取得できます。（バイト単位）

```dart

  _videoSize = _video.lengthSync();
```
メガバイト単位で少数第3位まで取得したい場合

```dart
  _videoSize = ((((_video.lengthSync()/1048576)*1000).round())/1000);
```
#さいごに
お疲れ様でした！

#参考サイト
https://pub.dev/packages/image_picker
[VS Code] VS CodeにVimをインストールしたら赤いハイライトに悩まされた

# Problem
 VS Codeの拡張機能"Vim"をインストールすると、原因不明の赤いハイライトに襲われる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649386/9aecf423-2431-0a59-d52b-504750e80f05.png)

# 原因
同じく拡張機能Trailing Spacesと干渉している様子

[Trailing Spaces - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces)
行末のspaceをハイライトして知らせてくれます
保存時に自動的にspaceを取り除くことも可能、便利！

# 解決

以下を参考に編集中の行をハイライトしないように設定します

> Highlight Current Line
Default: true
>
Highlighting of trailing spaces in the currently edited line can be annoying: each time you are about to start a new word, the space you type is matched as a trailing spaces. Currently edited line can thus be ignored:
>
```
{ "trailing-spaces.highlightCurrentLine": false }
```
[Trailing Spaces - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces#options)

settings.jsonに以下の行を追加します

```json
"trailing-spaces.highlightCurrentLine": false,
```

ちなみに、保存時の自動space削除オプションは

```json
"trailing-spaces.trimOnSave": true, 
```



# 環境
- macOS catralina
- VSCode v1.50
- Vim v1.17.1
- Trailing Spaces v0.3.1
github.com の default branch が main になっていたので敢えて master に戻した話

github.com で新規に repository を作成すると default branch が main になっていた。

※現在は github の repository 作成直後に rename が最速

    repository
     settings
      branches
       edit - rename

main is now named master
If you have a local clone, you can update it by running:

    git branch -m main master
    git fetch origin
    git branch -u origin/master master
    git remote set-head origin -a


(以下、過去の内容)
やったことのメモ(最短じゃないので適当)


    git branch master
    git checkout master
    touch README.md
    git add ./README.md
    git commit -m 'first commit'
    git merge main
    git gc
    git push origin main
    git branch -D main
    (create branch master as empty on the web github.com)
    (change default to branch master on the web github.com)
    git push -f origin master
    git push --delete origin main
    git branch -r
    git rebase -i HEAD~~
    (fixup)
    git log
    git commit --amend
    git log
    git push -f origin master
    touch README.md
    git add ./README.md
    git commit -m 'first commit'
    git push origin master
    git remote set-head origin --auto
    git branch -r
    git gc


https://github.com/nomissbowling/change_main_to_master
Azure Functions を VisualStudioCode でローカルデバッグしようとした時に発生したエラーとその対処法

#起動しない
##発生日 2020/10/28
###エラー時のTerminal出力
下から2行目の``Failed to decrypt settings. Encrypted settings only be edited through 'func settings add'.``が問題。（暗号化なんてしてないけど）

```terminal
> Executing task: func host start <
Can't determine project language from files. Please use one of [--csharp, --javascript, --typescript, --java, --python, --powershell, --custom]
Can't determine project language from files. Please use one of [--csharp, --javascript, --typescript, --java, --python, --powershell, --custom]
Can't determine project language from files. Please use one of [--csharp, --javascript, --typescript, --java, --python, --powershell, --custom]
Azure Functions Core Tools (2.7.2936 Commit hash: c00b06616a741dcdf70a3061fc415adde84010f8)
Function Runtime Version: 2.0.14494.0
Failed to decrypt settings. Encrypted settings only be edited through 'func settings add'.
The terminal process "/bin/sh '-c', 'func host start'" terminated with exit code: 1.
```
###対処法
IsEncryptedの1行を追加

```local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsStorage": "...",
    "FUNCTIONS_EXTENSION_VERSION": "~3",
    "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "...",
    "WEBSITE_CONTENTSHARE": "...",
    "WEBSITE_NODE_DEFAULT_VERSION": "~12"
  }
}
```

#ローカルとサーバーで結果が異なる。
##発生日 2020/10/30
###原因
正規表現をApplication settingsに指定する場合、エスケープの仕方が違う。
jsonに直接指定するlocal.settings.jsonは以下でOK。同じものをサーバーに登録してもダメ。

```local.setting.json
{
  "Values": {
    ・・・
    "MY_ORDERNUMBER_REG": "^\\d{8}-\\d{2}$",
    ・・・
  }
}
```
###対処法
サーバー側は、以下の通りエスケープせずに登録。そりゃそうか。

```
MY_ORDERNUMBER_REG　 ^\d{8}-\d{2}$
```
Unity　立方体でそれぞれにテクスチャを貼る方法

久々の投稿ですわ。　


今回は　立方体で別々にテクスチャを　

貼る方法を見ていきます。　

キューブにテクスチャを貼ってしまうと　

１枚絵になってしまうので　　

別々に貼ることはできません。　

しかし、　plainやクアッドを使って　

立方体を作れば、それぞれ貼ることが可能です。　

こちらの画像のようにすることができます。　↓

![bandicam 2020-10-28 15-12-08-148.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/966f967b-c490-2073-04f8-b04574ee1056.jpeg)





左がキューブにマテリアルを貼ったもの　

右がplainでキューブを作り　

画像やマテリアルを貼ったものになります。　





作り方ですが　まずplainを６枚用意して　

キューブのように設置します。

ギズモなどを使い、視点移動しながらやれば　

やりやすいです。



この画像のやつだと、拡大縮小を全部０．１に　

設定しています。　

あとは　空のオブジェクトを作って　

その中にplainを全部入れて、親子関係にすれば　

完成です。　

しかし、　この状態ですと

マテリアルや画像をplainに貼ると　片方にしか　

表示できないという　問題が起きます。　

なので、両面に表示する方法も見ていきましょう。　

両面にするには　シェーダーを変えてあげる必要があります。　

プロジェクトビューで「Create」→「Shader」→「Unlit Shader」

を選んでください。　

日本語だと、光学処理のないシェーダー　となっているので　

そちらを選択します。　

では、UnlitShaderを入れたら　ダブルクリックをして　

開きましょう。　

開いたら、次にコードを変更します。　

すでにあるコードを消して　

こちらのコードを入れてください。　

```

Shader "Unlit/culloff" //変更部分
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
//変更部分↓

Tags { "RenderType" = "Transparent" "Queue" = "Transparent" }
LOD 100
Cull off
Blend SrcAlpha OneMinusSrcAlpha

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}　

```

ここまで　

変更部分と書いてあるところが追加したコードです。　

これはようするに、カリング設定をoffにしているわけですね。　

ではこちらを入れたら、保存して閉じます。　

あとはplainを選択して、　今作ったシェーダーを入れてあげれば　

ＯＫです。　

これで、両面にマテリアルが反映されました。

![bandicam 2020-10-28 15-30-51-204.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/b7993b08-64f9-3ab3-51cb-2f9790970dd6.jpeg)










ＰＳ　

すでにご存じの人も多いでしょうが　

Ｕｎｉｔｙ２Ｄゲームstandard講座　発売中です。　

２Ｄゲームやboltに興味のある人はどうぞ
https://coconala.com/services/40431
Computed property は、あくまでデータの一種

computedプロパティーは、データなのかメソッドなのか、いまいちわからない。

ただ、実装上は、あくまでデータとして扱うのが良いと学んだ。

Vueのオプションは、いまいち数が多くて使い分けがわからない。
しかし、

1. いつ(ライフサイクルフック)
2. 何を(データ)
3. どうする(メソッド)

に分けて考えるとわかりやすいと思う。

データについては、
1. props　  親からもらった他人のデータ
2. data　　 自前のデータ
3. computed 加工済みの自前データ

の3つに分けて考える必要がある。

dataのプロパティをcomputedでいじろうとか思ってはいけない。

メソッドについては、
1. methods
の一択。

ライフサイクルフックは、
1. created
2. mounted
3. beforeDestroy
が主。

この場合は、例えば、
1. created()のタイミングで
2. propsを
3. methodsで加工する

というふうに分けて考えると迷子にならない。
【javascript】classList を使って class を操る

# 対象者
- javascript で class を追加したり削除したりなんのしたい方
- そもそも getElementById で null が返ってきて困っている方

動的に class を追加したり削除したりしたい時、
「getElementById とか classList を使うのは何となく覚えているけど、どう書くんだっけ…」
ってことがあったので、パッと見つけられるように簡単に備忘録。

# javascript で class を追加・削除

例として、下記のようなHTMLがあって、
javascript で要素に class を 追加したり削除したりしたいとき、
classList を利用するとそれができる。

```html:HTML
<div id="dog" class="chiwawa shiba">犬</div>
```



### classに追加する
```javascript:javascript
document.getElementById("dog").classList.add("Pomeranian")
// class="chiwawa shiba Pomeranian"
```
`document.getElementById("dog")`
→ id="dog" の要素を見つけてくれる。

`classList.add("Pomeranian")`
→ ここで、Pomeranian が class に追加される。

### classから削除する
```javascript:javascript
document.getElementById("dog").classList.remove("chiwawa")
// class="shiba Pomeranian" 
```
`classList.remove("chiwawa")`
→ chiwawa が class から削除される。
先ほど追加した Pomeranian と、もともと class にあった shiba だけが残る。


### <便利> 指定したclass名があったら削除、なかったら追加
```javascript:javascript
document.getElementById("dog").classList.toggle("Pomeranian")
// class="shiba" 
```
`classList.toggle("Pomeranian")`
→ class に Pomeranian があるため、削除される。

```javascript:javascript
document.getElementById("dog").classList.toggle("poodle")
// class="shiba poodle" 
```
`classList.toggle("poodle")`
→ class に poodle がないため、追加される。

# getElementById で null が返ってくる場合

`console.log(document.getElementById("xxx"))`
で、`null` が返ってくる場合の対処法。


## 解決方法

### そもそも id があっているか確認する
```html:例：HTML
<div id="dog" class="chiwawa shiba">犬</div>
```
```javascript:例：javascript
document.getElementById("cat")
```
`document.getElementById("cat")` で、`id="cat"` を見つけ出せず `null` が返ってくるパターン。
`document.getElementById("dog")`にしてあげるか、
HTML側を `id="cat"` にして、id を合わせてあげることで解決できる。


### ロード順を見直す
HTML を先に読み込んでから、javascript を読み込むようにすることで解決できるパターン。
これに関して、2つ方法がある。


①[【JavaScript】getElementByIdでnullが返ってきたときに確認すること](https://qiita.com/kikuchiTakuya/items/c56c4b25e8b4d005dd8a)

HTML よりも先に javascript を読み込んでしまっていることで、
id を見つけ出せず、 null になってしまう。
そのため、HTML と javascript の読み込み順を入れ変えてあげれば解決。

② [HTMLの読み込みが完了してから実行](https://qiita.com/cervomansan/items/0873026853686503fc3a)

javascript側で、HTMLの読み込みが終わってから実行するようにする方法。

```javascript:javascript
window.onload = function () {
  document.getElementById("dog").classList.add("Pomeranian");
  // HTMLの読み込み後に実行されるため、id="dog"が見つけ出せる。
};
```

# 参考

[Element.classList](https://developer.mozilla.org/ja/docs/Web/API/Element/classList)
　classList の使い方が詳しく載っている。

[【JavaScript】classListの使い方まとめ(add.remove.contains.toggle)](https://qiita.com/tomokichi_ruby/items/2460c5902d19b81cace5)
　ボタンを押したら色が変わることを例に、実用的かつ分かりやすい。
【AtCoder】ABC128B - Guidebook

**ソート**の勉強になる問題です。

市名と点数を格納していくので、辞書かな？
→同じ市が複数あるので辞書は使えません。

レストランの番号はリストのインデックスかな？
→並び替えるので、リストにレストランの番号を入れた方がいい。

という訳で、リストに番号、市名、点数を入れていきます。

市名と点数の並び替えってどうやるの？
→l.sort(key=lambda x:x[1],x[2])


キモは、**市名は辞書順（昇順）だけれど、点数は降順**という所。

解説の方には、**点数を-1倍する**とあって、なるほどなーと思いました。

第1キーは昇順、第2キーは降順にしたい場合は
**キーに-をつければ降順になる**という記事を見つけたので、
その方法を使ってみました。

[多重キーでのソート](https://pashango-p.hatenadiary.org/entry/20090614/1244984058)

```
n=int(input())
l=[]

for i in range(n):
    s,p=input().split()
    l.append([i+1,s,int(p)])

l.sort(key=lambda x:(x[1],-x[2]))

for i in l:
    print(i[0])
```
pythonでダーツの旅的なの作成した（ネタ）

#はじめに
みなさんこんにちは！昨年私と友人の4人でキャンピングカーを借りてダーツの旅をしようと旅行の計画を立てていたのですが…旅行の当日ダーツと地図を忘れてしまいました。この旅のキモとなるものなのに…
　私と友人は心底落ち込んでいました。僕たちの所有物はキャンピングカー、財布、着替え、PC…あれ！PCあんじゃん！！
　無いなら、プログラミング（python）でつくれば良いじゃん！！ってことで作成したので記事にしようかなと思います。
#この記事を対象の方
・ダーツの旅をしようとしていたが、肝心のダーツを忘れてパソコンは手元にある方
・パソコンは持っていてダーツと日本地図を持っていない方
#日本地図をどうやって作成する？
　ダーツの旅するには地図がないといけないと考え、pythonで日本地図を出力させる方法を調べました。そしたらfoliumというライブラリが使えそうなので試してみました。

```nihon.py
import numpy as np
import pandas as pd

import folium
from folium import plugins

#函館
LAT = 41.773709
LNG = 140.726413

map = folium.Map(location=[LAT,LNG])

#ピンを立てる
folium.Marker(
    location=[LAT,LNG],
    popup="This is Simple Marker"
).add_to(map)
#実行
map
```
出力がこうなります！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661723/1e8dbad2-44b6-eb93-1deb-1a5aeb525df6.png)

函館市の緯度経度を入力したのでしっかりとした出力になっていますね！
#ダーツしてみる
ここで経度と緯度をrandomで日本の緯度経度をランダムにすれば完成しそうです！
コードはこちらになります。

```nihon.py
import numpy as np
import pandas as pd
import random

import folium
from folium import plugins

#日本の範囲のなかでランダムに数が割り当てられる。
LAT = random.uniform(20,46)
LNG = random.uniform(112,154)

map = folium.Map(location=[LAT,LNG])

#ピンを立てる
folium.Marker(
    location=[LAT,LNG],
    popup="This is Simple Marker"
).add_to(map)

#実行
map
```

さてどこに私たちはいけばいいのだ！python！おめぇが決めてくれ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661723/97000534-3152-1136-b72d-67c856938584.png)
え？…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661723/eda27d69-8b52-4aea-0342-458b365a4f7f.png)
え・・ちょ・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661723/2af96eb9-6ea8-c6fc-8ed3-0123aea5e664.png)
#みんな海パンは持ってるか？
今回はfoliumというライブラリをつかって地図を可視化し、random関数で簡単なダーツの旅を作成しました。
海に落ちないようなものにしたいのですが、があった時にまた書き直したいと思います。(範囲の指定や、緯度経度をあらかじめ決めといてランダムにするなど…)
それでは、みなさま…海パンの準備はよろしいですか？
よく使うPhpStormショートカット

2年間PhpStormを使ってみて、個人的によく使うショートカットキーをまとめてみました。
独断で基本と応用に分けています...（特に意味はないです）



## チートシート

**基本**

| 説明                               | キー             |
| :--------------------------------- | :--------------- |
| 単語移動                           | ctrl + ←→        |
| 単語選択                           | ctrl + W         |
| 単語選択の縮小                     | ctrl + shift+ W  |
| 選択した単語の大／小文字を入れ替え | ctrl + shift + U |
| コメント化／解除                   | ctrl + shift + / |
| 選択したブロックの複製             | ctrl + D         |
| タブを閉じる                       | ctrl + F4        |
| タブの移動                         | alt + ←→         |
| ヒストリーからの貼り付け           | ctrl + shift + V |
| 戻る                               | ctrl + alt + ←   |
| ファイル内検索                     | ctrl + F         |
| パス内検索                         | ctrl + shift + F |
| なんでも検索                       | shiftを2回       |
| Class検索                          | ctrl + N         |
| ファイル内置換                     | ctrl + R         |
| パス内置換                         | ctrl + shift + R |
| コードフォーマット                 | ctrl + alt + L   |



**応用**

| 説明                         | キー                   |
| :--------------------------- | :--------------------- |
| 宣言に移動                   | ctrl + B               |
| 前／次のメソッドに移動       | alt + ↑ ↓              |
| 直近のファイルを開く         | ctrl + E               |
| ツールウィンドウ             | ctrl + tab             |
| リファクタリング             | ctrl + alt + shift + T |
| 行を指定して移動             | ctrl + G               |
| クイックフィックス           | alt + Enter            |
| ヘルプ                       | ctrl + P               |
| 簡易ヘルプ                   | ctrl + Q               |
| ブックマーク                 | ctrl + F11             |
| ブックマーク一覧             | shift + F11            |
| メソッド実装                 | ctrl + I               |
| 次／前の強調表示されたエラー | F2／shift + F2         |
| 構造の確認                   | alt + 7                |
| スーパークラスへ             | ctrl + U               |
| インデントの調整             | ctrl + alt + I         |
| use文の整理                  | ctrl + alt + O         |



## おまけ

クラス検索で`SampleHogeController`を検索したい場合は、`SHC`と頭文字を入力すれば簡単に検索できます！



## 参考

[PhpStorm キーボードショートカット](https://pleiades.io/help/phpstorm/mastering-keyboard-shortcuts.html)
HTTPの基本～まとめ～

#はじめに
「WEBアプリケーションの脆弱性診断」を行う際に、WEBの主要な通信プロトコルである**『HTTP』**の理解は必須になります。自己学習を通して学んだことを復習もかねてまとめてみました。

#HTTPとは
ネットワークを使った通信を行うためには、**お互いが決まった手順**や**データの形式を守る**必要があります。

そのあらかじめ、決められた**『約束事』**のことを**『プロトコル』**と呼びます。

WEBで主に使われているプロトコルは**『HTTP』**です。

#TCP/IPとHTTPの関係
インターネットを含めた一般的に使われているネットワークは**『TCP/IP』**というプロトコルで動いています。

**💻HTTPはそのうちの１つです！！**

コンピューターネットワーク機器がお互いに通信するためのプロトコルには、様々なものがあります。
『ケーブルの規格』や『IPアドレスの指定方法』。。。

これらのインターネットに関連するプロトコルを集めたものを
**『TCP/IP』**または**『TCP/IP　プロトコル・スイート』**と呼びます。
👇
※インターネットの関する様々なプロトコルの総称がTCP/IP！

#階層

TCP/IPの重要な考え方の１つに**『階層』**というものがあります。

TCP/IPでは**『アプリケーション層』『トランスポート層』『ネットワーク層』『リンク層』**の４階層に分かれています。

TCP/IPで通信するとき、階層の順番を通って相手と通信を行います。

**送信側👩は『アプリケーション層』から下っていき**
**受信側💻は『アプリケーション層』に上がっていく**
👇
【イメージ図】
![Qiita2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685823/14b8cce6-8e72-fa93-f5d5-accb7b1651ba.jpeg)
それぞれの階層を渡っていくときには、必ず階層ごとに「その階層」に必要な**『ヘッダー』**と呼ばれる情報をくっつけていく!

受信側ではそれぞれの階層を渡っていくときには、逆に必ずその階層ごとに**使用したヘッダーを外していく！**

このように情報を包み込むことを**『カプセル化』**といいます。

#HTTPと関係深いプロトコル　IP/TCP/DNS？

TCP/IPの中で、HTTPと関係が深いプロトコルが３つあります。

:black_small_square:**配送を担当するIP**

IPは『ネットワーク層』
IP の役割は、個々のパケットを**相手先まで届けること**です。
※『IPアドレス』の役割は重要

:black_small_square:**信頼性を担当するTCP**

TCPは『トランスポート層』
TCPは**大きなデータを送信しやすいように細かく分解し、確実に相手に届いたかどうかを確認する役割**を担っています。

:black_small_square:**名前解決を担当するDNS**

DNSはHTTPと同じ『アプリケーション層』
主に**『ホスト名』や『ドメイン名』と『IPアドレスの名前解決』**を提供します。
※名前解決とは、人間が覚えやすい**「www.example.com」**というドメイン名から通信に必要な**「93.184.216.34」**というIPアドレスを検索することを指します。

#シンプルなプロトコル≪HTTP≫

HTTPはTCP/IPの他のプロトコルと同様に**『クライアント』と『サーバー間』**で通信を行います。

※HTTPでは必ず片方が『クライアント』もう一方が『サーバー』の役割を担う！

クライアント👩から**『リクエスト』**が送信され
その結果をサーバー💻が**『レスポンス』**として返します。

ここでやり取りしているデータは、**『HTTP メッセージ』**と呼ばれていて
リクエスト側のHTTPメッセージを**『リクエストメッセージ』**
レスポンス側のHTTPメッセージを**『レスポンスメッセージ』**と呼びます。

#HTTPは状態を保持しないプロトコル!?

HTTPは**状態を保持しないステートレスなプロトコル**です。

HTTPでは、プロトコル自身にリクエストとレスポンスのやり取りの間に**『ステート（状態）』**の管理が存在しません。

HTTPというプロトコルのレベルでは、以前に送ったリクエストや、送られたレスポンスについて一切記憶していません！

なので。。。

上記の内容を保持したいという要望に応えるために**『Cookie』**という技術が導入されています。


#Cookieとは

Cookieとは**サイトを訪問した『ブラウザのデータを記録しておくための仕組み』**のことです。

詳しく説明すると。。。

:black_small_square:Webサイトにアクセスした時に、WebサーバーからCookieがブラウザに送られ、ブラウザに保存される

:black_small_square:次回同じwebサイトにアクセスした時、ブラウザ上のCookieがWebサーバーに送られ、サーバー側に保存されているユーザー情報とCookieが紐づきます。
👆
この仕組みにより、再度訪問した際に同一ブラウザであることが判定されます:flag_white:！

そのためCookieを活用してセッション管理を行うことで、**『状態を管理することが可能』**になります！

#参考文献

書籍：Webセキュリティ担当者のための脆弱性診断スタートガイド
　　　上野宣が教える新しい情報漏えいを防ぐ技術　第2版
著者：上野　宣

#まとめ

今回は「脆弱性診断」を行う上で必要なHTTPに関すること簡潔にまとめてみました。
HTTPに関する知識も不十分だったため、今回の学習で基本は抑えられたと思います。
データベースの多対多の必要性のメモ

purePHPでカテゴリー検索実装時に３つのテーブルを用いた多対多で中間テーブルを作成する理由がなんとなく分かったので備忘録として残します。

## 前提条件
postsテーブルにナルトというデータと、categoriesテーブルに映画とアニメという２つのデータがあったとする。
この２つのテーブルはposts.category_idとcategories.idが紐づいている。

## やりたいことは２つ
1. アニメをクリックした時に、ナルトを表示したい
2. 映画をクリックした時も、ナルトを表示できるようにしたい

## 2 つのテーブルで紐付けしようとした時の問題点
gategories.id=1 の映画が posts.category_id=1 のナルトと紐付いているとする。
もしこの状況でナルトを categories.id=2 のアニメと紐付けたい場合、詰む。
無理やりやろうとすれば、2 つめの posts.category_id=2 のナルトを作らないといけない。
対処法として post_category という中間テーブルを作成する。これによってpostsテーブルのナルトは１個だけで上記のやりたい機能を実装できる。




テーブルの図が合った方がわかりやすいのでまた後日追記します。中間テーブルについてもまた後日....
何か問題点や抜けている部分あれば、アドバイス頂けると幸いです。よろしくお願いします。
【Python】インスタンスをインスタンス変数でソートする方法

Pythonに限らず、プログラムを書いているとリスト（配列）や辞書をソートする機会はよくあります。そして、それらの方法はブログ記事などでたくさん紹介されています。

ただ、リストや辞書ほど頻度は多くありませんが、インスタンスのリストをインスタンス変数でソートしたいという事があります。例えば、次のような`Student`というクラスがあった場合に、`students`というインスタンスのリストを`score`でソートするというような場面です。

``` python
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

a = Student('Taro', 70)
b = Student('Hanako', 90)
c = Student('Jiro', 80)
students = [a, b, c]
```

このような場合、[operator.attrgetter](https://docs.python.org/ja/3/library/operator.html#operator.attrgetter)関数を使えば次のように数行（ほぼ一行）で書けます。

``` python
from operator import attrgetter
students.sort(key=attrgetter('score'))
for s in students:
    print(s.name, s.score)
```

```
Taro 70
Jiro 80
Hanako 90
```

降順にソートしたい場合は、次のように`sort`メソッドの引数`reverse`を`True`にするだけです。

``` python
from operator import attrgetter
students.sort(key=attrgetter('score'), reverse=True)
for s in students:
    print(s.name, s.score)
```

```
Hanako 90
Jiro 80
Taro 70
```
【移行済】社内SEになってオンプレ環境のお世話をする事になったので、ストレージについて調べた。

この記事は[Zenn](https://zenn.dev/tanakanata7190/books/95c94722198c42)に移行しました。

移行先 → https://zenn.dev/tanakanata7190/books/95c94722198c42
Monit周りまとめ

# 概要
プロセスの自動再起動に便利なmonit。
使い方について昔学んだことをまとめておく。

# monitへの監視設定追加の流れ
1. monitの監視対象となっているプロセスを確認
2. monitの監視対象とするプロセスの設定を追加
3. monitの設定を読み込ませる
4. monitの監視対象となっているプロセスを確認
5. 対象プロセスをキルして動作確認


## 1. monitの監視対象となっているプロセスを確認

```
sudo monit summary
=>
表示例
Process 'XXX'  Running             # 設定がmonitに認識されている & 監視対象   & 動作している
Process 'YYY'  Initializing        # 設定がmonitに認識されている & 監視対象   & 動作している(初回監視間隔をむかえていない?)
Process 'ZZZ'  Not monitored       # 設定はmonitに認識されている & 監視対象外 & 動作しているかは不明
Process 'AAA'  Does not exist      # 設定はmonitに認識されている & 監視対象   & 動作していない
```

上記に表示されていないプロセスについてはmonitに設定を追加する必要がある。
※上記コマンドで出てこない場合は、以下の設定がないことが原因かもしれない。
自分が触っていたEC2は実際そうだった。

参考：[monit: error connecting to the monit daemon](https://qiita.com/kosukeKK/items/f62f60bc6db88c09160e)

## 2. monitの監視対象とするプロセスの設定を追加

```
# 各プロセスの設定ファイル格納ディレクトリへ移動
cd /etc/monit/conf.d

# monit監視対象に新規追加したいプロセスの設定ファイルを作成
sudo vi <プロセス名>.conf

# 編集して保存
---
# pidfileの有無で<プロセス名>のプロセス起動を監視
check process <プロセス名> with pidfile "<対象プロセスのpidファイルのパス>"

# <プロセス名>起動コマンド(起動に30秒かかったらタイムアウト)
start program = "<起動コマンド>" with timeout 30 seconds

# <プロセス名>停止コマンド(停止に20秒かかったらタイムアウト)
stop program = "<停止コマンド>" with timeout 20 seconds
---

```

## 3. monitの設定を読み込ませる

```
sudo monit reload
```

### 4. monitの監視対象となっているプロセスを確認(設定の読み込み確認)

※1.と同様

```
sudo monit summary
```

で確認し、監視対象プロセスが一覧に表示されるようになれば読み込まれている。

### 5. 動作確認

```
# プロセスを殺す
kill <対象プロセスのPID>
```

set daemonで設定されている秒数を待ったのちに

```
ps aux | grep <プロセス>
```

でプロセスが存在するようになればOK

# monitでの自動起動設定追加

`/etc/monit/conf.d/` 以下に設定ファイルを作成する(ファイル名はなんでもいい)

ex. unicornをmonit監視下におく

※check process は summaryに表示される名称になる

```text
check process unicorn_process
  with pidfile "<unicornのpidファイルのパス>"
  start program = "<起動コマンド>" with timeout 30 seconds
  stop program = "<終了コマンド>" with timeout 20 seconds
  group <グループ名>
```

を設定ファイルに追加した後

```sh
sudo service monit restart
```



# 補足：monitコマンドのその他オプション
**monitのバージョンを知る**

```
sudo monit -V
```

**monitに認識されているプロセスについて監視対象にする、監視対象外にする**

``` 
# 監視対象にする
sudo monit monitor <プロセス名(summaryで表示されるやつ)>

# 監視対象外にする
sudo monit unmonitor <プロセス名(summaryで表示されるやつ)>
```

# 補足：設定ファイル解説


**monitrc**

```
# 監視間隔の設定(以下は2分間隔の場合)
 set daemon 120            # check services at 2-minute intervals

# monitのログファイルパス
  set logfile /var/log/monit.log

# 外部の設定ファイルを読み込む場合のパス
    include /etc/monit/conf.d/*
```
【移行済】社内SEになってオンプレ環境のお世話をする事になったので、仮想化技術と統合技術について調べた。

この記事は[Zenn](https://zenn.dev/tanakanata7190/books/0d24659d5c1351)に移行しました。

移行先 → https://zenn.dev/tanakanata7190/books/0d24659d5c1351
MacにJavaを簡単に入れてみた

## 概要
MacにJavaをインストールします。
(注: Homebrewは用意されている前提です。)

## 環境
- macOS Catalina 10.15.7
- Homebrew 2.5.7
- Java `openjdk 15.0.1 2020-10-20`

## 手順
### Javaのインストール
Homebrewを使ってインストールします。

#### brewの更新
```bash
brew update
```

#### バージョン指定なし(最新)の場合
##### AdoptOpenJDKをインストール
```bash
brew cask install adoptopenjdk
```

#### バージョン指定したいの場合
#### リポジトリをフォーミュラとしてHomebrewに追加
```bash
brew tap AdoptOpenJDK/openjdk
```

#### AdoptOpenJDK15をインストール
```bash
brew cask install adoptopenjdk15
```

### 確認
以下のコマンドでjavaのバージョンが表示されたらOKです。
```bash
java --version
```

## 参考
- [AdoptOpenJDK - HomeBrew TAP](https://github.com/AdoptOpenJDK/homebrew-openjdk)
VideoCopilit製品の製品購入後の有効化方法

# はじめに
VideoCopolot製品は、アクティベーションのときに結構やり方がわからないらしいので
そのあたりのやり方を記載しておこうと思います。（OpticalFlareを例に）

# 条件
・　製品をwebか代理店かで、ライセンスを購入していること
・　PCへすでにインストールを済ませていること

#　登録方法
1. AfterEffectの起動で次のアラートが出るので、そこにあるコードを控える ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166400/2b5745b3-1dd8-19e7-0e20-73444fd19dac.png)
2. [VideoCopilot](https://www.videocopilot.net/)のサイトでログイン![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166400/befc834f-3558-f1d7-6826-e25587ebd8a4.png)
3. VC Accountから「Download」を選択　![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166400/4e4fdb27-6a9e-155f-1735-19e37cf445da.png)
4. 該当のソフトウェアの右側「Download」を選択![スクリーンショット 2020-10-28 11.40.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166400/4dae773e-72bf-fa09-177f-9a35f2a7edc5.png)
5. 下の方にスクロールすると　HW IDを入力するところがあるので、１のコードを入力する。![スクリーンショット 2020-10-28 11.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166400/8c44683c-53af-79eb-3918-0f4faaed7c90.png)
6. licファイルがダウンロードされる。
7. 6のファイルを次のところに置く　```C:\Program Files\Adobe\Adobe After Effects CC バージョン\Support Files\Plug-ins\VideoCopilot``` ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166400/3aea76f8-8e46-5451-d053-8bfe5f36c60e.png)
8. 該当のAfterEffectを開いて、起動するか確認する。

#　おわりに
システム管理者的にはネットワークライセンスが使えないのは辛いですが、
まぁいつかVideoCopilotもそちらに移行してくれるんではないか、と
淡い期待を持ちながら、記事を書いてました。
いつかなるといいなぁ
SlackBotからメンションを飛ばしたい

※2020年10月時点での設定方法です。情報が古くなっている可能性があります。
# 手順
メンションを飛ばしたい相手のプロフィールを開き、画像下に表示される氏名をコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/738154/e42cd318-878e-1922-1d0d-95d8f79fe1b6.png)

先程コピーした氏名を＠付きで設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/738154/739ecdeb-edca-283a-60bf-802e2700ef8c.png)

メンション付きでSlackBotから返事があれば成功です。
![スクリーンショット 2020-10-28 14.44.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/738154/a37b673e-9ca0-9d90-07d6-f31af0176827.png)
Cognos Analytics の全レポートの中から特定のオブジェクトを検索する

#Cognos Analytics の全レポートの中から特定のオブジェクトを検索する
Cognos Analyticsは大きな環境では、レポートなどのコンテンツの数が数十万個になることも珍しくありません。
これらの多数のレポートの中から、特定のオブジェクトを使っているレポートを一括で検索する方法を紹介します。
Cognos SDKでXML形式のレポートスペックを1レポートずつ抽出していけばできますが、SDKを作成するのも面倒なので、より簡易な手順となります。

#手順
Cognos Administrationのコンテンツ管理からエクスポートを行い「共有フォルダー、ディレクトリー、およびライブラリーのコンテンツを選択」を選びます。
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/022290cd-71d1-88d0-643f-2765921b2694.png)

検索したいエントリーを追加します。今回は「Qiita」というフォルダ配下のコンテンツを一括で検索してみます。
![004.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/b76e8fdd-57dd-d7eb-9eab-86c20db6199c.png)

CognosサーバーはRHEL7ですが、作成されたアーカイブファイルをWindowsPCに持ってきました。
![005.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/3a4d62eb-fa79-69d0-44d7-1c53f34477e0.png)

アーカイブファイルを適当な解凍ソフトで解凍すると、以下のようなファイル類が見られるので「package1.xml」をテキストエディタで開きます。
![006.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/30053dd5-2eb0-3dd8-2114-518fa43f1a17.png)

中身はこんな感じになっています。
![007.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/efbfe316-b2cf-297a-9c2a-a2b067a712be.png)

例えば「クロス集計」を使っているレポートを知りたいと思ったら、「crosstab」でテキスト検索してみます。
この辺りにクロス集計が使用されているコンテンツの定義が記載されていそうです。
![008.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/51794e7b-7955-a3e2-e2f9-c867e871b864.png)

\<object> というキーワードで「上検索」します。
![009.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/b582d808-b12f-4f7a-9e35-91f2a96e71cd.png)

821行目からレポートコンテンツで、822行目から「単一デフォなし」という名称のレポートにクロス集計が使われている事がわかります。
824行目のparentIdに注目します。
![010.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/7b48e627-8c90-8abb-0566-17e1de9c2bf6.png)

parentIdを、\<id>parentId\</id>で上検索します。
![011.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/1fa2f5cb-3ef7-c252-bed3-6dc795c10973.png)

「SlicerOption」というフォルダ配下に「単一デフォなし」レポートが存在する事がわかります。
![012.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/830acdbd-67cc-4c4d-3aac-7b69580b6b93.png)

さらに親をたどると、「Qiita」フォルダに「SlicerOption」フォルダがある事が分かります。
![013.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/6c4588e4-ed1d-188f-94a1-09de7d590ee1.png)

実際にポータル画面で見てみると、確かに該当のレポートがあります。
![014.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/04219fa0-2ebc-5588-216a-806f32b8eb6e.png)

レポートの中を見てみると、クロス集計が使われていました。
![016.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/3bde168b-d4a5-9c16-5a12-c6606e0688ab.png)

「crosstab」の様な検索キーを特定するのがポイントですが、SDK開発も不要なので、簡易に出来て使える技だと思います。
Android ViewPager ページ指定

```
// adapterには、表示用の配列またはArrayListが設定されていること
viewPager.setAdapter(adapter);

// positionにページのindex値を指定
// 遅延処理をしないと、index値が1～４の場合、0ページが表示されてしまう
viewPager.postDelayed(() -> viewPager.setCurrentItem(position), 50);

```
初心者がWordPress環境構築してみた（冗長構成）

### 事前準備

[前回からの続きです。](https://qiita.com/ygikrps_/items/f2b9fda53c1c4ac0c113)

構成はWebサーバ1台、DBサーバ1台です。



### 環境

| 環境      | IP       |
| :-------- | -------- |
| Webサーバ | 10.0.1.1 |
| DBサーバ  | 10.0.2.1 |



### DBサーバの操作

* DBサーバに接続する。

  直接SSHで接続するか、Webサーバを経由して接続してください。



MySQL Yum RepositoryからMySQL5.7をインストールする。

- Yumリポジトリの情報のインストール

```bash
$ sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
```

- MySQL8.0リポジトリを無効にし、MySQL5.7リポジトリを有効にする

```bash
$ sudo yum-config-manager --disable mysql80-community
$ sudo yum-config-manager --enable mysql57-community
#適用されているか確認
$ cat /etc/yum.repos.d/mysql-community.repo
```

- MySQLのインストール・起動

```bash
$ sudo yum install -y mysql-community-server
$ sudo systemctl start mysqld
```

- MySQLの初期パスワードの確認

```bash
$ sudo cat /var/log/mysqld.log | grep root@localhost
[Note] A temporary password is generated for root@localhost: 12桁の文字列
```

- MySQLのパスワード変更

```bash
$ mysqladmin -uroot -p password
Enter password:古いパスワード
New password:新しいパスワード
Confirm new password:新しいパスワード
#Warnigがでても変更はできています
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.
```

※[Passwordのポリシーについて](https://blog.pinkumohikan.com/entry/workaround_for_mysql_password_policy)

- WordPress用のDB・ユーザーを作成する

```mysql
$ mysql -uroot -p
Enter password:設定したパスワード
#WordPress用のユーザー作成
mysql> CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpressユーザーのパスワード';
#WordPress用のDB作成
mysql> CREATE DATABASE `wordpress`;
#DB権限を作成したユーザーに付与
mysql> GRANT ALL PRIVILEGES ON `wordpress`.* TO "wordpress"@"10.0.1.1";
#設定反映
mysql> FLUSH PRIVILEGES;
mysql> EXIT;
```

※サブネットマスクはワイルドカード方式を用いることで指定できる。`'10.0.1.%'`



### Webサーバの操作

* WordPressのDBダンプを取得

```bash
$ sudo systemctl start mysqld
$ mysqldump -uroot -p wordpress | gzip > wordpress.dump.gz
Enter password:
#WebサーバのMySQLの停止
$ sudo systemctl stop mysqld
#ダンプをリストア
$ zcat wordpress.dump.gz | mysql -h 10.0.2.1 -uwordpress -p wordpress
```

* WordPressの設定変更

~~~bash
# WordPessの設定を変更
$ sudo vim wordpress/wp-config.php
/** WordPress のためのデータベース名 */
define( 'DB_NAME', 'wordpress' );
/** MySQL データベースのユーザー名 */
define( 'DB_USER', 'wordpress' );
/** MySQL データベースのパスワード */
define( 'DB_PASSWORD', 'パスワード' );
/** MySQL のホスト名 */
define( 'DB_HOST', '10.0.2.1' );

# サービスリロード
$ sudo systemctl reload httpd
~~~
【iOS14】「からペースト」通知が出る外部ライブラリまとめ

最新版では修正されている可能性がありますが、以下のライブラリでは「からペースト」通知が出ることがあるようです。
コメントいただければ未検証ですが、情報を追記していきます。

- Firebase/DynamicLinks  
  https://github.com/firebase/firebase-ios-sdk/issues/5893
- GoogleMobileAd.framework (このフレームワーク削除したら「からペースト」が出なくなった) → 最新版にしたら出なくなった
CRLFからLFへ

備忘録シリーズです...

過去にチームでWindowsのひとがいた際に、大変になったので共有します。
効率的なものがありましたら、教えてください！！


## CRLFの改行コード検索
```bash
find . -type f | xargs file | grep CRLF
```

## CRLFから変更

### ☆一つづつ削除
```bash
nkf -Lu --overwrite ファイル名orファイルパス
```

### ☆一括削除
```bash
find . -type f | xargs nkf -Lu --overwrite
```

### ☆Gitを含む場合
Gitが壊れて焦ったので、Gitでなくともバイナリファイルは含まないようにした方が良いと思います。

```bash
find . -type f | grep -v '.git/' | xargs -n 10 file | grep CRLF | xargs nkf -Lu --overwrite
```
[処理の流れ]
全ファイルを検索
→Gitディレクトリを含めず検索
→10行づつファイルを出力する
→CRLFを含むファイルを検索
→NKFコマンドで「-Lu(LF)」に変換する

### ☆Gitを含まない場合

```bash
find . -type f | xargs -n 10 file | grep CRLF | xargs nkf -Lu --overwrite
```
[処理の流れ]
全ファイルを検索
→10行づつファイルを出力する
→CRLFを含むファイルを検索
→NKFコマンドで「-Lu(LF)」に変換する

## 感想
シェルにして置くと楽そうですね！

201110 追記
shellscript/commandファイルとしてコード化しました！
冗長なのでいずれ直したいと思います。

### ソース
```shell:changeLF.command
#!/bin/sh

# command実行場所指定
cd `dirname $0`

function command_check {
  command -v "$1" > /dev/null
}

echo "nkfコマンドの存在をチェックします。"
if ! command_check nkf ; then
  if ! command_check brew ; then
    set -e
    echo "Homebrewのインストールをします。"
    echo "Macにログインした際のパスワードを入力してください!"
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
    echo "Homebrewのインストールを完了しました。"
  fi
  brew install nkf
fi
echo "nkfコマンドの存在をチェックしました。"

echo "CRLFファイルを検索します。"
crlf=$(find . -type f | grep -v '.git/' | xargs -n 10 file | grep CRLF)
if [ -f ${crlf} ]; then
  echo "CRLFファイルはありませんでした。"
else
  echo "${crlf}"
  echo "CRLFファイルをLFに変換します。"
  find . -type f | grep -v '.git/' | xargs -n 10 file | grep CRLF | xargs nkf -Lu --overwrite
  echo "CRLFファイルをLFに変換しました。"
fi

echo '処理を終了します。'
```

## 参考文献
https://infltech.com/articles/NWnUKJ
https://qiita.com/ionis_h/items/9f9642e435e30a33a88c
https://eng-entrance.com/linux-command-find
Javasilver勉強会 備忘録

#Javasilver勉強会

####p96 問1


- int[] 型のtoStringメソッドはオーバライドされていない
 
- →ObjectクラスのtoStringメソッドが実行される
- String型のtoStringメソッドはオーバライドされている
- →StringクラスのtoStringメソッドが実行される
StarSpaceでちゃちゃっと文書分類

Google Colab仕様ですが，そのほかの環境でも同じです．

こちらの方が詳しい
https://qiita.com/hkambe/items/dc17418c4e87b627d0c3

自身用も兼ねて，ちゃちゃっと要点のみ書きます．

#準備
```
!git clone https://github.com/facebookresearch/Starspace.git
%cd Starspace
!make
```



train.txt, validation.txt, test.txtの形式

```
This is a pen . __label__1
Are you a teacher ? __label__0
I have an apple . __label__1
```


#train, validation

```example_train.py
!./starspace train \
  -trainFile train.txt \
  -validationFile validation.txt \
  -model temp.model \
  -loss softmax \
  -ngrams 2 \
  -lr 0.001 \
  -epoch 15 \
  -batchSize 16 \
  -dim 100 \
  -negSearchLimit 5 \
  -trainMode 0
```


#test

```example_test.py
!./starspace test \
  -model temp.model \
  -testFile test.txt \
  -ngrams 2 \
  -dim 100 \
  -trainMode 0 \
  -K 40 \
  -predictionFile prediction.txt'
```
ArgumentError  wrong number of arguments (given 1, expected 0)の対処法の一つ

##解決したいこと
作成したフォームの送信ボタンを押すと、
ArgumentError  wrong number of arguments (given 1, expected 0)　と表示されること。

##前提
この入力フォームでは、一つのフォームから、複数テーブルへデータが保存されるようにしています。
具体的には、下記のように、新しいモデルを作り、ActiveModelを使っていました。

```
class ItemRequest
  include ActiveModel: :Model
  attr_accessor :name, :number, :store

  def save
     item = Item.create(name: name, number: number, user_id: user_id)
     Detail.create(store: store, item_id: item.id)
  end
end
```

一つのフォームから複数テーブルへデータを保存する手順を知りたい方は、下記の記事でまとめてくれている方がいらしたので、参考になると思います。https://qiita.com/taka_no_okapi/items/39706b9de38505d3216a

##解決方法（結論）

モデルに記述していた、```include ActiveModel: :Model```
で、:と:の間にスペースがあったことが原因でした。
正しくは、include ActiveModel::Modelでした。

##まとめ
私のエラー原因は一例にすぎませんが、もしこのエラー解決に繋がったら、幸いです。