OmniAICreator/Qiita-1.07M huggingface dataset:
[css]横並びで複数行になっても全要素の高さを同じにする方法

# 今回困ったこと
このようなcssを組みたかった。
テキストは可変で横並び、
一つの要素が横幅の1/3ほどの大きさで横幅超えたら下に潜る感じのもの。
なおかつ、全要素の高さは一緒。

<img width="476" alt="スクリーンショット 2019-04-15 17.26.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163415/9baf52fe-d89b-8f20-3ed8-684d21f935f6.png">

## 最初に試したこと
最近flexboxばっかり使っていた(flex便利)のでflexでどうにかこうにかできないものかと考えた。
結局行き着いた答えは

```html
<ul>
  <li>
    ライオン
  </li>
  <li>
    チーター
  </li>
  <li>
    鷹
  </li>
  <li>
    ラビット
  </li>
  <li>
    カンガルー
  </li>
  <li>
    アニマルアニマル
  </li>
</ul>
```

```css
ul {
  display: flex;
  flex-wrap: wrap;
  padding: 0;
  margin: 0;
  list-style-type: none;
}

li {
  width: 32%;
  min-height: 100px;
  padding: 10px;
  margin-right: 2px;
  margin-bottom: 2px;
  border: 1px solid #444;
  box-sizing: border-box;
}
```

### 完成形
<img width="460" alt="スクリーンショット 2019-04-15 17.31.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163415/b1130368-7976-d32f-67a1-74aebbaf1ea2.png">

見た目的にはやりたいことができた！！
ように思えたが、実はliにmin-height: 100px;を加えていた。。。
なので、テキストの量がめっちゃ増えた時にアウト。

## 解決策
最近、css grid layoutを
よく聞くけどまだ触っていなかった。。(恥ずかしい)
軽く調べてみて、これでいけるんじゃね？ってことで使ってみました。

### css grid layout
css grid layoutとは二次元グリッドシステムだそうです。
簡単に言うと行と列があって、それらをcssで指定してデザインしていく？って感じですかね。

### コード
htmlは変わりないので省略。

```css
ul {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr;
  grid-row-gap: 6px;
  grid-column-gap: 6px;
  padding: 0;
  margin: 0;
  list-style-type: none;
}

li {
  padding: 10px;
  margin-right: 2px;
  margin-bottom: 2px;
  border: 1px solid #444;
  box-sizing: border-box;
}
```

### できたもの
<img width="473" alt="スクリーンショット 2019-04-15 18.31.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163415/68e40687-f3c6-514c-3737-4d6611a5c883.png">

### 解説
解説すると、
まず親要素(ここでいうul)にdisplay: gridを指定。
grid-template-columnsは横方向(列)のサイズを定義してます。
grid-row-gap: 6px; grid-column-gap: 6px;で余白を指定してます。
テスト技法を選ぶために欠陥を考える

皆さんはテスト技法を利用したことがあるでしょうか？
テストを開発する場合、最終的には具体的なテストケースを作成しなければなりません。

テストの目的を考え、対象機能やシナリオを明確にし、そのテスト条件を洗い出した！
そんなとき…「あれ、どんなテスト技法を使ったらいいんだろうか…」と悩んだことはありませんか。（私はあります…）

テスト技法を選ぶためには、いくつかの対象を明確することで考えることができます。
洗い出したテスト条件はなにがしかのリスクがあるためにテストケースとして実装されているはずです。ということは、おそらく発生するのではと考えている欠陥があるはずです。

## テスト条件からテスト技法までのつながり

テスト条件を明確にして、それに対してどんな欠陥が発生しそうかと考えると必然的に利用するテスト技法が見えてきます。

ISTQBやJSTQBのテストアナリストという資格認定のシラバスに具体的な欠陥とテスト技法の組み合わせがあったので下記に記載します。
まずはここから考えてみてはいかがでしょうか。

<img width="575" alt="技法.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220327/bf240c2b-b059-3bcc-67dd-bb98ba93372e.png">

```
[例]
①テスト条件：運賃料金に対して、対応した購入クラスが選択されること）
↓
②発生しそうな欠陥：料金境界のずれによる誤った購入クラスの選択
↓
③欠陥が抽出できるテスト技法：境界値分析
```

上記の表にない欠陥がある場合は、どんな技法で欠陥が検出できたかを記録し、基準としてメンテナンスされると良いです。
検出したい欠陥を意識しながらテストケースの作成、実施をしてみましょう。

> Note:JSTQB用語集より
**テスト条件（test condition）**
コンポーネントやシステムのアイテムやイベントで、 テストケースにより検証できるもの。たとえば、機能、トランザクション、フィーチャ、品質の属性、構造要素など。

## 参照

* JSTQB
  * http://jstqb.jp/syllabus.html
* ISTQBテスト技術者資格制度サンプル問題 日本語版 Advanced Levelシラバス(Version 2012) テストアナリスト Version 1.01.J01
  * http://jstqb.jp/dl/JSTQB_Sample_Questions_ALTA_V2012_1_01_J01.pdf
GPUImageLookUpWithIntensity

```GPUImageLookUpWithIntensity.swift

import AVFoundation
import Foundation

import UIKit
import GPUImage

class LiveCameraVC: UIViewController
{
    

    
 //   @IBOutlet weak var modifiedImageView = GPUImageView()
    
    @IBOutlet weak var modifiedImageView: GPUImageView!
    
    var videoCamera:GPUImageVideoCamera?
    
    // MARK: - Variables
    var intensitys = 1.0
    
    
    @IBAction func SaturationSlider(sender: UISlider) {
        let test = sender.value
        
        //  saturationFilter?.saturation = CGFloat(sender.value)
        intensitys = Double(CGFloat(sender.value))
        filter.intensity = CGFloat(intensitys)
        
    }
    
    
    
    
    
//    let filter: GPUImageLookupFilter = {
//        let filter = GPUImageLookupFilter()
//        filter.intensity = intensitys
//        return filter
//    }()
    
    // MARK: - UI
    
    
    
    // MARK: - Life Cycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
      
        
            videoCamera = GPUImageStillCamera(sessionPreset: AVCaptureSession.Preset.photo.rawValue, cameraPosition: .back)
            
            videoCamera!.outputImageOrientation = .portrait;
            videoCamera!.horizontallyMirrorFrontFacingCamera = true
        
        
      //  videoCamera?.addTarget(modifiedImageView)
        
        self.performLut()
        videoCamera?.startCapture()
        print("Tapped")
        
    
    }
    
  //  override func loadView() {
  //      super.loadView()
        
       // self.view.addSubview(modifiedImageView)
        //modifiedImageView.autoPinEdgesToSuperviewEdges()
  //  }
    
    // MARK: - Private
    let imagePicture: GPUImagePicture? = {
        if let imagePicture = GPUImagePicture(image: UIImage(named:"lookup_amatorka")) {
            return imagePicture
        } else {
            print("GPUImagePicture Nil")
            return nil
        }
    }()
    
    let filter = GPUImageLookupFilter()
    
    private func performLut() {
        if let videoCamera = videoCamera {
            
         //   var imagePicture = GPUImagePicture(image: UIImage(named:"lookup_amatorka"))
            
            //let filter = GPUImageLookupFilter()
            filter.intensity = CGFloat(intensitys)
            
            videoCamera.addTarget(filter)
            imagePicture?.addTarget(filter)
            imagePicture?.processImage()
            filter.addTarget(modifiedImageView)
          //  videoCamera.startCapture()
            
            
            
            /*
            if let imagePicture = imagePicture {
                videoCamera.addTarget(filter)
                imagePicture.addTarget(filter)
                imagePicture.processImage()
                filter.addTarget(modifiedImageView)
                videoCamera.startCapture()
            }
 */
        }
    }
    
}


```
CRUDって何

###はじめに
初学者のアウトプット用記事です。
ご指摘訂正アドバイスは是非お願いします。


##CRUDって何？
resourcesとresourceの違いについて調べていてよく出てきた言葉がCRUD。


resourcesは、複数のリソースに対するCRUD処理を行うためのルーティングを生成する（7つのCRUDすべて。）urlにidを含む。


resourceは、ただ１つのリソースに対するCRUD処理を行うためのルーティングを生成する。
urlにidを含む必要がない。resourceの場合は、indexの定義がされない。



CRUDって何？

##CRUD機能

CRUDというのは、以下の機能をまとめた呼び方です。(略称)

**・Create （新規作成）
・Read （読み取り）
・Update （更新）
・Destroy （削除）**


ちなみにリソースに対する「CRUD処理（4つ）」、及び、「一覧画面の表示」、「新規作成画面の表示」、「編集画面の表示」という7つのリクエストに対応するルーティングを一挙に用意してくれるのが、resourcesメソッド。

```
一覧画面表示　　 GET    /members(.:format)          members#index
Create処理     POST   /members(.:format)          members#create
新規作成画面表示 GET    /members/new(.:format)      members#new
編集画面表示    GET    /members/:id/edit(.:format) members#edit
Read処理       GET    /members/:id(.:format)      members#show
Update処理     PATCH  /members/:id(.:format)      members#update
Update処理     PUT    /members/:id(.:format)      members#update
Destory処理    DELETE /members/:id(.:format)      members#destroy
```
とのことでした。

####参考にした記事

Railsのresourcesとresourceついて
https://qiita.com/Atsushi_/items/bb22ce67d14ba1abafc5
ICOSのデータを認証なしに外部公開する方法(bucketレベル)

# はじめに
ICOSにアクセスするにはデフォルトでは必ず認証が必要ですが、例えばデータを一般公開したい場合やWebサーバーにおける画像・データの配置のために認証なしにアクセスしたいことがあります。
これまでは[APIで個々のObjectごとにPublic_READ属性を付ける](https://cloud.ibm.com/docs/services/cloud-object-storage/hmac?topic=cloud-object-storage-allowing-public-access#public-access-object)などの作業が必要でしたが、今回新たに提供された方法はIAMとの連携による実装方法であり、Customer Portalから簡単に設定することができます。ドキュメントは[こちら](https://cloud.ibm.com/docs/services/cloud-object-storage?topic=cloud-object-storage-iam-public-access)です。
なお、[こちら](https://qiita.com/testnin2/items/0d23bb5b46f32e45eeb3)のICOS Firwallと組み合わせると、特定のIPからのアクセスにのみ認証なしでアクセスさせるといった使い方も可能です。

# BucketごとにIAMでアクセスを許可する

<font color="DeepPink">注意点：特定のObjectだけ公開することはできません。Bucket全体が公開されてしまうので、取り扱いにはご注意ください。</font>

以下の画面はICOSで`Public Access`（認証なしにアクセスできるように外部公開する）を許可する画面です。ここで`Create access policy`を押下していくだけで、外部公開することが可能です。

<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/a7cbc0ed-55b6-abd1-43ca-700f8e558518.png">
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/9ef673df-c195-8f29-9f90-8595dc3284ce.png">
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/79262ea0-9272-5296-83b4-b7c1b2b15e67.png">

# もう少し詳しく
画面のポップアップからもわかるように、先ほどの画面では単にIAMの`Public Access`というアクセスグループにレコードを作成しているだけです。そのため、もし`Public Access`を取り消そうと思っても、この画面から取り消すことはできません。IAMに移動して作成されたレコードを削除する必要があります。
実際にIAMを確認してみましょう。`Public Access`というアクセスグループが存在し、その中で該当のbucketに対して`Content Reader`というロールが割り当てられているアクセスポリシーが存在することがわかります。
<img width="1278" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/e69b0b50-bb89-ef10-b908-4e8b85aa6ca8.png">
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/27516558-8761-ebbd-7272-f09b97deb0ee.png">
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/1de21e0e-7136-c894-552d-8e6d7eadcc08.png">
【WinActor】ペイントと画像マッチングを使った疑似OCR

画面やマクロの操作で、こんなリストから1つ選んで処理をしたいと思ったことはありませんか？
![リスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398977/9f52448e-fda3-d48a-35b2-f2ebc8458103.png)

残念ながらWinActorには、リストを取得する術が現状ないので、エミュレータによるクリックを使用して選択する必要があります。
上の図のように日付のリストであれば、内容が変わることはほぼないので、座標を直接指定してクリックすればできますが、対象のリストによっては、リストの内容や順番が変わってしまうというケースも考えられます。

そこで、ペイントと画像マッチングを使った疑似OCRについて紹介します。

■用意する変数
・画像ファイルパス
・処理結果
・リスト項目数
・ループカウンタ

■事前準備
ヒットさせたい画像をペイントのトリミングを使用して切り出す。
上の図のリストだとこうなります。
![リスト_16日.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398977/a8f1d53b-2c3d-4248-5ea1-00cb6a8f3739.png)
複数必要な場合は、その分だけ用意してください。

１．初期設定
・画像ファイルパス：対象の画像ファイルパス
・処理結果：false
・リスト項目数：リストの項目数(上の図だと日付なので31になる)
・ループカウンタ：0

２．リストの一番上をクリック
使用ノード：04_自動記録アクション\エミュレーション
ウィンドウ識別名：対象の画面
・リストの一番上の項目を座標指定
・指定した座標に対して、マウス左ボタンのDownとUpを追加

３．ループ
繰り返し条件：ループカウンタ < リスト項目数
  AND 処理結果 = false

３－１．次のクリック位置設定
使用ノード：多分岐
条件：ループカウンタ(1～30まで)
各分岐処理：次のリスト項目を座標指定してクリック

分岐が多いと設定が大変ですが、対象の画像にヒットしない場合、上から順番にクリックしているように見えます。

３－２．画像マッチング
使用ノード：15_画像マッチング関連\画像マッチング(状態取得)
・ウィンドウ識別名：対象の画面
・マッチ率：90%
※これが低すぎると全く違う文字でも認識されてしまうので、85~90%がおススメです。
  認識できなかった場合は、画像の切り出しがうまくいっていない可能性があります。
  上下に他のリストの文字が見切れていないか、対象の文字が削れていないか、切り出す幅を変える
  などしてリトライしてください。
・画像：画像ファイルパス
・結果：処理結果

３－３．ループカウンタカウントアップ
使用ノード：カウントアップ
計算結果：ループカウンタ
加算値：1

ループはここまで

ループを抜けた後に、処理結果で分岐し、trueならOKボタンを押下したり、次のフォームに入力するなどの処理を追加すれば、リストから自動で選択した上で次の画面に遷移する処理も作成できます。

３－１の分岐の分だけクリック処理を登録するのはとても根気がいりますが、最も重要な作業です。
一度使えるようになると重宝する処理ですので、お試しください。

以上がWinActorによる、ペイントと画像マッチングを使った疑似OCRでした。
RaspberryPiで作る監視カメラ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/e97a776b-4d41-68b4-b763-21c1d7b083b6.png)
Raspberry Piと専用のカメラモジュールを使用し、ONVIF対応の監視カメラを作成します。
本記事は[リンク情報システム株式会社](https://www.lis.co.jp)の有志が作成しています。

IOT機器は、機器と機器が接続できてこそ意味があり、その可能性を高めるには、スタンダードとなっている仕様に従って作成する必要があります。
今回作成する監視カメラは、業界のスタンダードとなっているONVIFのプロトコルを実装しており、ONVIF対応のアプリケーションにてカメラの映像を確認する事ができます。

 

また、開発サイクルの短縮化を目標に、オープンソースを積極的に使用した開発を行ってみたいと思います。最近では、何もかも全て自分で作るというのではなく、既に存在する物を如何に上手く組み合わせるかと言う技術が重要になってきていると感じます。

シリーズ記事として投稿していきます。
第１回～第６回では、実際に監視カメラを作成するまで、第７回以降では、監視カメラ作成に関しての技術的な説明を書いていきます。

尚、RaspberryPiを使用して、カメラの映像を配信する方法を解説するサイトが幾つかあり、私もそれらのサイトを参照し、学習時間短縮に活用いたしました。
参考にさせて頂いたサイトに関しては、各ページでリンクを貼らせて頂きました。

目次（各回の公開後にリンクにしていきます）
【インストール】

- 第１回　[準備編](https://qiita.com/lis-hanzomon/items/09f6fe74951222d34111)
- 第２回　[セットアップ編](https://qiita.com/lis-hanzomon/items/91df20407d65322d0afb)
- 第３回　[ネットワーク編](https://qiita.com/lis-hanzomon/items/31cf0127db0fdaf0aa35)
- 第４回　[デバイス編](https://qiita.com/lis-hanzomon/items/917c199695caba15e144)
- 第５回　[アプリケーション編](https://qiita.com/lis-hanzomon/items/896342ec1af95d42db26)
- 第６回　[アプリの録画設定編](https://qiita.com/lis-hanzomon/items/ff502f79223da871b45e)

【プログラミング】

- 第７回　[開発環境構築編](https://qiita.com/lis-hanzomon/items/6cf0f0759d7a6120a29d)
- 第８回　[静止画編](https://qiita.com/lis-hanzomon/items/d5bbd68c7e1ab38efdad)
- 第９回　[静止画配信(HTTP)編](https://qiita.com/lis-hanzomon/items/9e975477bf9f255ed374)
- 第１０回　[動画編](https://qiita.com/lis-hanzomon/items/055ebf703026734cd97f)
- 第１１回　[動画保存編](https://qiita.com/lis-hanzomon/items/91c283c3310b2e0f7858)
- 第１２回　[動画配信(RTSP)編](https://qiita.com/lis-hanzomon/items/d103e2d72c2f571dcba5)
- 第１３回　[サーボモータ制御編](https://qiita.com/lis-hanzomon/items/5206a1934bb563366ca5)
- 第１４回　[カメラの遠隔操作(ONVIF)編](https://qiita.com/lis-hanzomon/items/7454627183cf8ce9e9e8)
- 第１５回　[アプリの自動起動編](https://qiita.com/lis-hanzomon/items/5435b10ad7f439749a5c)
- 第１６回　[インストーラ作成編](https://qiita.com/lis-hanzomon/items/7c4eba19e256ace5fde7)


---
[リンク情報システム株式会社](https://www.lis.co.jp)では一緒に働く仲間を[随時募集](https://www.lis.co.jp/employ_top)しています！
また、お仕事のご依頼、ビジネスパートナー様も募集しております。[お気軽にご連絡](https://www.lis.co.jp/inquiry)ください。
[Grails]Error occurred running Grails CLIで起動しない時の対処

# 発生した課題
久々にGrailsのプロジェクトで、ちょっと画像を更新する機会があって、パッケージを作り直そうと思い立った時、こうなった。

```
$ grailsw package
load application.groovy
[development]
| Error Error occurred running Grails CLI: No profile found for name [web]. (Use --stacktrace to see the full trace)
```

# 対処
build/フォルダを削除してから、もう一度やってみたら出来た。下記によると、build/.dependencies 削除でいけるらしい。

https://www.malcontentboffin.com/2016/12/Grails-Error-Error-occurred-running-Grails-CLI-No-profile-found-for-name-web-.html
Elgg(オープンソースSocial Network Engine)をdocker-composeでセットアップ

# TL;DR

* オープンソースなソーシャルネットワーキングエンジン[Elgg](https://elgg.org/)をDockerコンテナで稼働させる方法を紹介します
    * [elgg-docker-compose](https://github.com/myoshimi/elgg-docker-compose)を作りましたので，こちらを使用すると簡単です

# Elgg概要

* PHPで作られている，ソーシャル・ネットワークエンジンです
    * Webアプリにソーシャル環境を導入するためのフレームワークです
* 操作のためのAPIが提供されています
* 2000種類以上のプラグインがあり，組み合わせて使用することができます

# 構成

* docker-composeで，3つのコンテナを立ち上げます
    * Elgg: Elgg本体
        * 80/TCPを受け付けます．外部公開の際にはリバースプロキシなどで適切なセキュリティ保全を行ってください．
    * MariaDB: Elggデータ用DBコンテナ
        * 3306/TCPでアクセスを受け付けます．dockerネットワークからの接続のみを受け付けます
    * composer: ```docker-compose up```時に稼働するパッケージインストール用コンテナ

![elgg-compose.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/510073eb-d005-c272-105d-e9d5b178fe6b.jpeg)

# 使い方

## dockerコンテナ群の立ち上げ

```shell
git clone https://github.com/myoshimi/elgg-docker-compose
cd elgg-docker-compose
git clone https://github.com/Elgg/Elgg
docker-compose up -d
```

* 初回はcomposerコンテナがライブラリのインストールを終了するまで，数分時間がかかります．
    * ```docker ps -a```で，```elgg-docker-compose_composer_1```がExited状態になれば，稼働しています．
* ```http://<URL>```にアクセスするとelggのセットアップ画面が表示されます

![elgg-first.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/33d5a300-82f5-d3fc-3a6f-b0e343bf9b23.jpeg)

## DB設定

* セットアップ作業で迷う部分は少ないと思いますが，DB設定は，docker-composeの設定に併せる必要があります．
    * github上のdocker-compose.ymlでは，以下のようにしています

|項目|入力値|
|---|---|
|Database Username| elgg |
|Database Password| password |
|Database Name| elgg |
|Database Host| db |
|Database Table Prefix | elgg_ |
|Data Directory | /elgg |
|Site URL| http://127.0.0.1 |

## 設定後

* セットアップが完了すると，ログイン画面になります
    * ![elgg-login.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/a4dc281b-a0d2-073c-b093-83fbe5f13d05.jpeg)
* セットアップ画面で作成する管理者ユーザでログインすると，使用が開始できます
* ![elgg-disp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/ca30b847-a969-aef0-d405-a069f2a6950b.jpeg)


## 不揮発ボリューム

* elgg-docker-composeディレクトリ直下に，volumes/{db,elgg}が作られます
    * MariaDBのデータ(/var/lib/mysql)が格納されます
    * elggコンテナは```volumes/elgg```を```/elgg```にマウントし，elgg用のデータが格納されます
    * elggコンテナがElggディレクトリをマウント(/var/www/html)します

# いくつかの注意点

* Dockerhubの```php:7.2-apache```イメージは```mod_rewrite```が有効になっていないので，```a2enmod```する必要がある

# 参考

* [Elgg](https://elgg.org/)
* [Elgg-github](https://github.com/Elgg/Elgg)
* [Humhub(オープンソースSocial Network Kit)をdocker-composeでセットアップ)](https://qiita.com/myoshimi/items/a2a76c2276fb80c2fdf6)
Python の subprocess

Python3 の他プロセス呼び出しライブラリ subprocess の典型的使用法のメモ．詳細は[公式ドキュメント](https://docs.python.org/3/library/subprocess.html)参照．

## 単にプロセスを起動

run メソッドに，起動するコマンド (と引数からなるリスト) を渡す．ステータスは戻り値の returncode 属性で参照できる．

たとえば，ls コマンドを起動して，出力は画面に出せば良いという場合:

```python
import subprocess, sys

cp = subprocess.run(['ls', '-a'])
if cp.returncode != 0:
    print('ls failed.', file=sys.stderr)
    sys.exit(1)
```

## 出力を取得

### 値として出力を取得

コマンドの標準出力を取得したい場合には，runメソッドの stdout 引数に subprocess.PIPE を渡す．復帰値のstdout属性で取得できる．

```python

cp = subprocess.run(['ls', '-1'], encoding='utf-8', stdout=subprocess.PIPE)
print(f'*** file names: \n{cp.stdout}'
      f'*** total {len(cp.stdout.splitlines())} files')
```

上のように `encoding='utf-8'` を指定すると，文字列として取得できる．他にも文字列として取得するオプションがある．(このへんは，Python 3.5と3.6では，けっこう仕様が変わっている．) そういうものを指定しないと，バイト列として受け取ることになる．

標準エラー出力を取得したい場合には，当然，`stderr=subprocess.PIPE` を指定して，復帰値のstderr属性を参照する．標準エラー出力と標準出力を混ぜて取りたい場合 (`2>&1`相当) には，`stdout=subprocess.PIPE stderr=subprocess.STDOUT` と指定して，復帰値の`stdout`属性を参照すれば良い．

### 出力をファイルに書き出す

file object を与えればよい:

```python

with open('out.txt', 'w') as fp:
    cp = subprocess.run(['ls', '-1'], stdout=fp)
```

## 入力を与える

文字列 (や，バイト列) で与えるときには，runメソッドの input 引数を用いる．

```python
cp = subprocess.run(['wc'], input='abc def ghijkl', encoding='UTF-8')
```

ファイルから読ませるときには，引数stdin に，file object を与える．

```python
with open('q.txt', encoding='UTF-8') as fp:
    cp = subprocess.run(['wc'], stdin=fp)
```

## 継続的に実行

runメソッドは，ブロックする．すなわち，指定したコマンドが終了してはじめて制御がPythonスクリプトに戻ってくる．コマンドを動かしながらスクリプト側でも処理をしたい場合には，Popenオブジェクトを使う．作成するときに stdin, stdout, stderr に subprocess.PIPE を指定しておけば，Popenオブジェクトの stdin, stdout, stderr 属性がファイルハンドルとして使用できる．

このとき，with 構文も使える．withブロックを抜ける時に，Popenオブジェクトは，コマンドの標準入出力を閉じて，コマンドのプロセスが終了するのを待つ．

```python
lst = [(4, 3), (2, 1), (3, 9)]
with subprocess.Popen(['bc', '-i'], encoding='UTF-8',
                     stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc:
    while True:
        msg = proc.stdout.readline()
        if msg[:11] == 'For details':
            break
    for (x,y) in lst:
        print(f'{x} + {y}', file=proc.stdin, flush=True)
        proc.stdout.readline()
        z = proc.stdout.readline().strip()
        print(f'{x} + {y} = {z}', file=sys.stderr)
```

したがって，起動しているコマンドが，(標準入出力を閉じられたとしても気にせず) 終了しないとすると，with のブロックから抜けてこないことになる．ここでデッドロックになってしまわないよう注意を払う必要がある．
obniz＋距離センサー＋MP3モジュールでAmazon Echoを起動させる

Amazon Echo買ったらやっぱり音声受付システム作りたいですよね？
そして、センサー使って自動でスキル起動させたいですよね？

ということで、周回遅れのネタですが、以下の記事にインスパイアされて、obnizでやってみました

- M5Stackと超音波距離センサーでAmazon Echoを起動させる<br />https://qiita.com/h-takauma/items/24135e39cf4b80519fa2

### 使ったもの

![IMG_2067.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20351/56d1856a-9486-0524-ca75-387a02447843.jpeg)
※配線汚くてごめんなさい

- [obniz](https://obniz.io/ja/)
- [超音波距離センサー HC-SR04](https://obniz.io/ja/sdk/parts/HC-SR04/README.md)
- [Grove MP3モジュール](https://obniz.io/ja/sdk/parts/Grove_MP3/README.md)
  - groveコネクタなので、obnizとの接続には変換ケーブルが必要
  - Amazon Echoを起動させる音声をmp3で作ってmicroSDに入れておく
- アナログスピーカー
  - 100均で購入しました
- Amazon Echo Show

### 動画

[![alexaとgoogle homeでAPL対応音声受付システムをvoiceflowで作ってみた＋距離センサーによるスキル自動起動付き](http://img.youtube.com/vi/otOvBAz_jKo/0.jpg)](http://www.youtube.com/watch?v=otOvBAz_jKo)

### コード

50cmの距離で5秒間というのが基準です。配線はコードを参照してください。

とりあえず手元のMacで動かしてます。そのうちRPi Zero Wに移す予定。

ロジックは[M5Stackと超音波距離センサーでAmazon Echoを起動させる](https://qiita.com/h-takauma/items/24135e39cf4b80519fa2)を大いに参考にさせてもらいました。ありがとうこざいます。

```bash
$ npm init
$ npm install obniz —-save
```

```javascript:index.js
var Obniz = require("obniz");
var obniz = new Obniz("OBNIZ_ID_HERE");

const DISTANCE = 500; 
const DETECT_COUNT = 5;

obniz.onconnect = async function () {

  // mp3初期化
  const mp3 = obniz.wired("Grove_MP3", { gnd: 5, vcc: 6, mp3_rx: 7, mp3_tx: 8 });
  await mp3.initWait();

  // 距離センサー初期化
  const hcsr04 = obniz.wired("HC-SR04", {gnd:0, echo:1, trigger:2, vcc:3});
  hcsr04.temp = 20;

  let sayFlg = false;
  let count = 0;

  // ループ
  while(true) {

    let avg = 0;
    let cnt = 0;

    for (let i=0; i<3; i++) { // measure three time. and calculate average
      const val = await hcsr04.measureWait();
      if (val) {
        cnt++;
        avg += val;
      }
    }
    if (cnt > 1) {
      avg /= cnt;
    }

    if (!sayFlg) {
      if (avg < DISTANCE) {
        count++;
        if (count >= DETECT_COUNT) {
          sayFlg = true;
          count = 0;
          await mp3.play(1);
        }
      } else {
        count = 0;
      }
    } else {
      if (avg > DISTANCE) {
        count++;
        if (count >= DETECT_COUNT) {
          sayFlg = false;
          count = 0;
        }
      } else {
        count = 0;
      }
    }

    console.log("----------------")
    console.log(`DISTANCE: ${avg}`);
    console.log(`COUNT: ${count}`);
    console.log(`SAYFLG: ${sayFlg}`);

    await obniz.wait(1000);
  }
}
```

実行

```bash
$ node index.js
DISTANCE: 307.03373200276
COUNT: 0
SAYFLG: true
----------------
DISTANCE: 308.4072286603679
COUNT: 0
SAYFLG: true
・・・
```

Alexaスキルはこの話の本質ではないので割愛します。詳細は以下をご覧ください。

https://kun432.hatenablog.com/entry/aajug_20190410_lt

### その他

- Amazon Echoを起動するための音声はAmazon Pollyで作りました。
- 思いのほかスピーカーからの音声が小さかったので、ffmpegでmp3ファイルの音量を上げてます。
- 距離センサーの精度は少し微妙ですが、こんなものなのかなという印象です。

### まとめ

Alexaスキルと同じNode.jsで書けるので違うこと覚えなくて良いですし（とはいいつつ今回はノンコーディングで作ったスキルですが）、公式にサンプルコードもたくさんあるので、私のような見よう見まねでコード書いてるレベルだと非常に助かります。

他のセンサーとかもそのうち試してみたいと思います。
IoT機器と連携するアプリを開発・運用する時に、気に留めておいた方が良いこと

お仕事で、IoT機器と接続して、機器を操作したり、機器からデータを取り込んでデータ表示するアプリを2つほど開発しました。
その時に、アプリ側から見た、要件策定、仕様策定、テスト、運用時などに気をつけた方が良いことが少し見えて来たので、メモしておきます。


## 【すごく大事】IoT機器に接続するアプリをいつまでサポートするかあらかじめ決める

アプリケーションと連動して動作するハードは、アプリケーションが使えないとゴミ同然になってしまう場合があります。
しかし、スマホのOSは年に一回のペースでメジャーアップデートしていくので、リリース時は動作したアプリも、2年、3年と経過する内に最新のスマホOSでは動かなくなる場合があります。

**推奨環境でOSを縛ったとしても、利用者は容赦無くスマホのOSをバージョンアップして使用する**ので（特にiOS)、
最新のOSで使用できないアプリは、レビューが炎上し、ブランド価値を毀損してしまうこともあります。

したがって、あらかじめ機器の製品寿命を考慮して、スマホアプリの保守コスト、保守できるエンジニアを確保する必要があります。
特に時計など、寿命の長い製品をアプリと連携するときは、気をつける必要があるかもしれません。

## 長期的に保守するなら、不要な機能は絶対に盛り込まない

ほとんど使用しない機能を積み込んだアプリは使いにくいだけなので、なるべくシンプルにすべきと考えています。

特に、長期的に運用する必要がある場合は、OSの仕様変更によって使用できなくなる機能などが発生する可能性があるので、長期にわたり安定して提供できるようにシンプルにすると良いと思います。

運用の過程で使えなくなる機能が出てくると、首が絞まって動けなくなるかもしれません。。。



## 仕様決定の段階で品質向上の方法をあらかじめ、用意しておく

アプリの品質向上、本当に必要とされている機能の調査のため、クラッシュログの取得やアクセス解析をアプリに入れておくことをお勧めします。

可能であれば、IoT機器の動作不良ログも収集できるようにしておくと、今後の開発に役立つかもしれません。

## リリース前に可能な限り多くの環境でテスト

IoT機器はアプリと正常に連携しなければただのゴミです。

IoT機器の推奨環境では、最低でも正常系が全て完全に動くことを確認してからリリースを行うべきでしょう。
もし無理であれば、接続するスマホの環境をあらかじめ縛るべきです。

## IoT機器のアップデート機能がある場合は、バージョン紐付けを行うとテストが楽かも

長期にわたり運用する機器の場合は、機器のファームウエアアップデートができるものがあります。
全てもファームウエアでアプリが動作することを保証するのは、現実的ではないので、アプリと機器のバージョンを特定のバージョンの組み合わせのみで動作するようにすれば、トラブルが減らせるかもしれません。

## なるべく社内の人間で開発

IoT機器を接続するアプリを開発する場合は、ニッチな知識が必要な場合が多々あります。
開発を外に丸投げした場合、ニッチな知識を持ったエンジニアを確保しにくいので、品質の高い保守ができなくなる可能性が高いです。
高確率でベンダーロックイン的なものが発生します。

## アプリをメンテナンスできるエンジニアを長期で確保する

連携するアプリの保守には、機器接続周り処理を理解しているエンジニアが必要です。
ニッチな知識が必要な場合が多いので、なるべく初期開発したメンバーを運用に残すべきでしょう。
TCP/IPにおけるTCP, UDPヘッダーについてのメモ書き

# 最初に
TCP, UDPについてヘッダーについてたまにいろいろ調べることがあるのでこの際にメモ書きでまとめておきます。
ググッた範囲で自分の理解で書いているので、間違っている部分は適宜修正していきます。
専攻は土木工学なので専門外のため、違っていたらご指摘くださると嬉しいです。

まずは、概要について、詳しくはググればいいので、ここでは簡単に。

ネットワークのプロトコル階層を見ると必ずでてくるOSI参照モデル。
ISO策定ではあるけど、でも実際にはRFCによるTCP/IPが利用されている。

よくOSI参照モデルとTCP/IPの関連について書いてあることもあるけど、実際にはお互いに意識しているわけではないので、TCP/IPでの○○はOSI参照モデルでは○○に相当とかって考える必要はありません。ここでは普通にTCP/IPについて記載します。

# TCP/IPの５層モデル

第４層　アプリケーション
第３層　トランスポート
第２層　インターネット
第１層　ネットワークインタフェース
第０層　ハードウェア

# 第３層トランスポート層より下層ヘッダー構成

まずは、ざっくり図解。

![2019-04-16 12_17_52.168.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80324/ec67936c-4dbc-2355-0c5b-36b4777c5c6d.png)

以下、メモ書き。個人的に思い出すとき用なので、詳細はググってください。

- 第０層　ハードウェア（物理ヘッダ）
    - プリアンブル
         - イーサネット通信で送受信の同期を取り、フレームの始まりを合図するために用いる特別なビット列。NICが付与
         
- 第１層　ネットワークインタフェース（Ethernetヘッダ）
    - タイプ
        - Ehternetヘッダーのデータ部分のタイプが記載される。IPV4なら0x0800、IPV6なら0x86ddという１６進数表記なので2Byte。
        - データ部分は最低46Byte。足りない部分は0でPaddingされる。

- 第２層　インターネット（今回はIPV4ヘッダー）
    - バージョン、4だから0100
    - ヘッダー長　そのまま
    - パケット長　そのまま
    - プロトコル　IPパケットのデータ部分のプロトコル。いろいろあるけどTCPなら６, UDPなら17が振られる

    
#　第３層　トランスポート層（TCP, UDP）のヘッダー構成

まずは、ざっくり図解

![2019-04-16 12_18_12.592.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80324/a3ba1e69-a93f-4c0e-f90c-58784d5b1d81.png)

で、見た目の違いを箇条書きで

- 当たり前といえば当たり前だが両方とも送信元ポート、宛先ポートはある。
- チェックサムも両方ある。
- TCPにはコネクション確立のための3wayハンドシェイク（SYC, ACK, FIN etc）のコントロールフラグがある
- TCPにはデータの確実性保持のための仕組みがある。（シーケンス番号、応答確認番号 etc）
- UDPにはハンドシェイク等のコネクション確立がないので、データサイズを示すセグメント長がある。
- TCPはハンドシェイク後の通信でシーケンス番号と応答確認番号があるので、それでデータサイズが分かる。
    - シーケンス番号 -> 相手から受信した確認応答番号
    - 応答確認番号 -> 相手から受信したシーケンス番号＋データサイズ

# ここからは完全な個人的自己解釈
※ココから名自己解釈なので違っている場合があります。その場合はご指摘ください。

- ヘッダーサイズ
    - TCP 8 + 14 + 20 + 20 + 4 = 64Byte + アプリケーションデータ
    - UDP 8 + 14 + 20 + 8 + 4 = 52Byte + アプリケーションデータ
    
- TCPにおけるオーバーヘッドとは？
    - 上のヘッダーサイズを見る限りはパケットのサイズ的なものではない。
    - TCP特有のコネクション確立（ハンドシェイク）とその通信（再送機能等）によってそれらを含めたあらゆる物がオーバーヘッドとなりうる。ただ単に送りっぱな、UDPとの違いはそこにあると思われ。
Swift で  Scala の Option#fold を実装してみる

##あらすじ
関数型プログラミング勉強していたら、foldr と foldl の理解に躓きそうになっている僕。Swiftには foldl に該当する reduceがあるけど、foldr がよくわからずに理解しようと思っていたら、Scala の Option#foldに出会う。

###Scala の Option#fold とは

```scala
def fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B
```
型を変換しながら、もとの値が Some か None かによって、別々の値を返す事が出来ます。

これをSwiftで実装したいわけです。Optional を extension で拡張してみましょう。 

```swift

extension Optional {
    func fold<T>(_ ifEmpty: T, _ safe: (_ me: Wrapped) -> T ) -> T {
        if let wrapped = self {
            return safe(wrapped)
        } else {
            return ifEmpty
        }
    }
}
```

Optionalの値が nil だったら デフォルトとして 第一引数の\<T> 型の値を、そうじゃなければ クロージャを実行した\<T>型の戻り値を返すという関数になります。

オプショナルを if let で条件分岐するのはSwiftだと良く書くコードですが、これだとスッキリしますね！

```swift
//ベタな条件分岐を利用した処理
var some: Int?
var message: String
if let value = some {
    message = "\(value) is value"
} else {
    message = "value is nil"
}

//Optional fold を利用すると
let foldMessage = some.fold("value is nil"){ return "\($0) is value" }

```

使い方はこんな感じ。

```swift

struct Food {
    let calorie: UInt
    init(_ calorie: UInt) {
        self.calorie = calorie
    }
}

func eat(food: Food?) {
    let message = food.fold("ダイエット中だ！"){ return "\($0.calorie) kcal 肥えました！" }
    NSLog(message)
}

eat(food: Food(1000)) // 1000 kcal 肥えました！
eat(food: nil) // ダイエット中だ！
```
【BluePrism】Yahoo!路線検索の経路候補リストをExcelに貼り付ける

##概要
[Yahoo!路線情報](https://transit.yahoo.co.jp/)にて、検索結果の「出発地/到着地候補」のリストをExcelに貼り付ける方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/df0035b6-3f71-6c62-aabd-d1f6ddde1250.png)


##方法
####「出発地/到着地候補」のリストを取得する
「読み取り」ステージを使って、「出発地/到着地候補」のリストを取得します。
リストはコレクション変数に格納されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/f4b80f7e-7fe5-3743-0052-6e68f48e4415.png)

####コレクションをカンマ区切りの文字列に変換する
コレクションをループで回し、テキスト型の変数にカンマ区切りで連結していきます。
例えば、「赤坂(東京都)駅,赤坂(福岡県)駅,赤坂(山梨県)駅,…」といった具合です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/ebc83afc-c6cf-f885-5509-10684a7f6343.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/271138e4-5250-2962-7d5b-d14e03b49a89.png)

末尾のカンマは除外しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/e8554a6d-2ed0-c630-cc80-6cbd5043d160.png)

####MS Excel VBOを拡張する
既存のオブジェクトである「MS Excel VBO」の「Run Macro」では、先ほどのプロシージャに引数を渡せないので、「Run Macro」を拡張することにします。
拡張する際は、ベースの「MS Excel VBO」をコピーして別オブジェクト**「MS Excel VBO - extend」**を用意します。
その後、「Run Macro」をコピーし、**「マクロ実行（引数あり）」**ページを作成します。
ページ名を日本語にしているのは、拡張したページであることを分かりやすくするためです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/9b428785-db0f-07c7-0080-558be5040bbe.png)

ブサイクなコードですが、今回はこれで良しとしますｗ
プロシージャに引数を最大3つまで渡せるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/c70670cc-2d5e-c21a-e98e-89875285d5ba.png)

```vb
If arg1.Length <> 0 Then
  If arg2.Length <> 0 Then
    If arg3.Length <> 0 Then
      GetInstance(Handle).Run(Macro_Name, arg1, arg2, arg3)
    Else
      GetInstance(Handle).Run(Macro_Name, arg1, arg2)
    End If
  Else
    GetInstance(Handle).Run(Macro_Name, arg1)
  End If
Else
  GetInstance(Handle).Run(Macro_Name)
End If
```

入力パラメータを追加することを忘れずに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/b98ad06e-4ab0-0b5a-7ec5-9c0bcda17694.png)

####Excelマクロを作る
ドロップダウンを作る＆消すプロシージャを作っておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/1985f58a-f777-04cd-83ad-c276719ff732.png)

```vb
Option Explicit

Sub CreateDropDown(ByVal rng, ByVal list)
  Dim sheet As Worksheet
  Set sheet = Worksheets(1)
  
  With sheet.Range(rng).Validation
    .Delete
    .Add _
        Type:=xlValidateList, _
        Formula1:=list
  End With
End Sub

Sub DeleteDropDown(ByVal rng)
  Dim sheet As Worksheet
  Set sheet = Worksheets(1)
  
  With sheet.Range(rng).Validation
    .Delete
  End With
End Sub
```

####マクロをキックするステージを用意する
アクションステージにて、「MS Excel VBO - extend」オブジェクトから**「マクロ実行（引数あり）」**を呼び出します。
入力パラメータは図のように設定します。
**Macro Name："CreateDropDown"**
**引数1：ドロップダウンを作るセル位置**
**引数2：経路候補リスト**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/bf89ee88-da33-592d-983d-f9ca5962cb67.png)

##実行結果
指定したセル位置に、出発地/到着地候補リストのドロップボックスができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/650f46c1-7087-79f5-0872-ac7dd3ad8f4d.png)
let {d,x,y,o}=data;

-連想配列の明示表現
-外部から来たオブジェクトが解らない時がある。コメントよりも明示的。

```js
let {d,x,y,o}=data;
```

```js
var obj={d:1,x:2,y:3,o:'eeeee'}

function a(data){
let {d,x,y,o}=data
console.log(data,'in a()')
}

a(obj)
console.log(obj)
/*
> Object { d: 1, x: 2, y: 3, o: "eeeee" } "in a()"
> Object { d: 1, x: 2, y: 3, o: "eeeee" }
*/
```
WSL(Windows Subsystem for Linux)をSolarized Darkのテーマに変更する

# 経緯
.bash_profileに色設定書いても色変わんねー
イライラしていたらツールで変えることが判明。。。

# MS純正品のツールをダウンロードし解凍
`C:\Users\ユーザー名\Downloads\`下にzipをダウンロードし解凍することを想定。
> Microsoft純正ツール：[ColorTool](https://github.com/Microsoft/Console/tree/master/tools/ColorTool)

# コマンドプロンプト起動
1. Win + R
1. `cmd.exe`入力しenter

# ダウンロードし解凍したディレクトリに移動
```
> cd C:\Users\ユーザー名\Downloads\ColorTool
```

# SolarizedDarkに変更
```
> colortool -d solarized_dark
Wrote selected scheme to the defaults.
```
WSLを起動して変わっていればOK

# 参考
- [Releases · Microsoft/console · GitHub](https://github.com/Microsoft/console/releases)
- [WSL上のUbuntuのターミナル色テーマを変更する](https://twinbird-htn.hatenablog.com/entry/2018/02/10/231137)
- [Introducing the Windows Console Colortool](https://devblogs.microsoft.com/commandline/introducing-the-windows-console-colortool/)
【WinActor】画面を遷移する場合の画像マッチング処理

WinActorに欠かせない機能のひとつとして、画像マッチングがあります。
うまく使えばかなり便利な機能になります。
複数の画面を遷移するロボットを作成したい場合、画面を掴めず処理が途中で止まってしまうという事象が発生した方もいらっしゃるかと思います。
ですので、こちらではその解決策を紹介していきます。

■必要な変数
・ループカウンタ
・処理結果
・待機時間
・リトライ上限

１．初期値設定
・ループカウンタ：0
・処理結果：false
・待機時間：1000
・リトライ上限：10(任意の値)

２．ループ
繰り返し条件：ループカウンタ < リトライ上限
  AND 処理結果 = false
※「条件」をクリックして条件追加ボタンを押下すると条件が追加できます


３．ループ内処理

３－１．指定時間待機
使用ノード：09_待機\指定時間待機(変数指定可)
待機時間(ミリ秒)：待機時間

３－２．画像マッチング
使用ノード：画像マッチング
・ウィンドウ識別名：対象の画面
・マッチ率：40～70%
※高すぎると画面が開かれているのに認識しない可能性があるので何度か試して調整してください
・タイムアウト：1,000
※ループの最初に待機処理を入れているので、もっと少なくてもOKです
・状態取得結果：処理結果

３－３．ループカウンタカウントアップ
使用ノード：カウントアップ
計算結果：ループカウンタ
加算値：1

ループはここまで

４．画像表示判定
使用ノード：分岐
条件：処理結果 = true

あとは、画像を掴めたかどうかに応じて、必要な処理を追加すればOKです。
画像マッチングが早すぎて1回目は画面を掴めなくても、待機してリトライするので、掴める可能性がグッと上がります。
これでリトライ上限まで画面が掴めなかった場合は、以下の方法をお試しください。
・マッチング率を調整する
・画像の赤枠範囲を調整する
・待機時間を増やす

画面を複数遷移して自動で処理したい場合は、上記の手順を使い回せば実現可能です。
注意点としては、ループの前に必ずループカウンタと処理結果を初期化する必要がありますので、そのふたつを初期化する処理をサブルーチン化しておくと便利です。

以上が、WinActorによる、画面を遷移する場合の画像マッチング処理でした。
【コマンドライン】unixコマンドやプログラミング言語の文法をできるだけググらない【Scrapbox, Pecoの活用】

### unixコマンドやプログラミングの文法など､ 1回ググったものを何度もググりたくない:frowning2:



# (0) tldr

[tldr-pages](https://tldr.sh/)というOSSがあってtldrというコマンドを作っています｡
[![Image from Gyazo](https://i.gyazo.com/3eadd8c10b6632dd37128b2e8643fd85.gif)](https://gyazo.com/3eadd8c10b6632dd37128b2e8643fd85)

`tldr command_name`と打つと簡単なコマンドの説明が表示される｡
これで､ 忘れたunixコマンドやgitのコマンドはだいたいokです｡

要するにtldrはman(マニュアルを表示する)コマンドの要約(簡易)版です｡
インストールは､ https://github.com/tldr-pages/tldr#clients から(私はBash clientsを使っています)

# (1) Scrapboxとpecoの組み合わせ
tldrではコマンドの説明しかありません｡ これをプログラミングの文法などでも同様にできたらいいということでScrapboxとpecoでtldrのオリジナル版(っぽいもの)を自分で作ります｡

[![Image from Gyazo](https://i.gyazo.com/ddc9094d07c6a9691a3b55a671268f85.gif)](https://gyazo.com/ddc9094d07c6a9691a3b55a671268f85)


#### 環境(必要なもの)

* Peco
  * コマンドライン上で入力するたびに(incrementalに)grepをするツールです 
     * 詳しくは-> [Qiitaの記事]( https://qiita.com/reireias/items/fd96d67ccf1fdffb24ed)
 * 似たような動作をするものならok
* Scrapbox
 * オンラインのWiki(Document)作成ツールです｡ [Scrapbox.io](https://scrapbox.io)
 * 個人的に大好きなのでこれで｡  
 * ローカルにテキストファイルでも全く問題ありません｡ が､ 複数のPCで利用する場合だと何かしらの工夫は必要です｡

* ruby
 * 今回はScrapboxのapiのjsonを扱うために使用


#### やり方(実例) 
実際に自分が作っている[Scrapboxのプロジェクト](https://scrapbox.io/tldr-cmd/)
コマンドは👇で､ 適当な名前をつけて(aliasを設定して)使っています｡

```
curl -s https://scrapbox.io/api/pages/tldr-cmd/$(curl -s https://scrapbox.io/api/pages/tldr-cmd?limit=1024 | ruby -r json -e ' json =JSON.parse($stdin.gets) ; json["pages"].each {|e| puts e["title"]}' | peco | ruby -r uri -e "puts URI.escape(STDIN.read.chop)")/text | sed -e "/^#/d" -e '1s/^/##/' -e '1s/$/##/' -e "/code:/d"  -e "s/^\\\$//" ; echo " "
```

あとは､ 好きなようにページを作成していくだけです｡ 

---
##### 補足


* ページが多くなっても大丈夫か(スケールするか)気になっていたが､ 少なくとも3桁ページは問題ありません｡
* Scrapboxの利用としては､ 本来の魅力を発揮していません｡
* tldrのように色をつけたりはしていません(面倒なので)
* Scrapbox(ブラウザ)だけでもいいですが､ コマンドラインでやることでstepが一つくらい?少ないはずです｡ 
* 当たり前のように書いていますが､ 1回はググる必要あるし自分で書く手間はあります｡
* 個人的には使用頻度高いので､ ↓で書いたのをまとめ直しQiitaにしました｡ 興味があればこちらも｡
  *  https://scrapbox.io/dai-yamamoto/
ドキュメントファイルの階層構造をtreeコマンドでさくっと目次化する

# ドキュメントファイルの目次が必要なときのメモ

## 使える場面

- ドキュメント作成時に目次,索引,インデックスのファイル化が必要なとき
- 非エンジニアも含めたチームメンバーでドキュメントファイルを一覧で見たいとき
- 人から大量のドキュメントを渡されて**「後読んどいて」**と言われた時のドキュメント全量把握するとき

## 前提

`tree`コマンドが使える必要があります  
今回はmac上で実行

## おすすめ

ドキュメント階層のルートディレクトリで以下コマンドを実行

```
$ tree -NCH ./ > ./document_index.html
```

### オプション説明

| **option** | **効果** |
|---|---|
| -N | 表示できない文字を8進数に置き換える,文字化け対策 |
| -H | html形式で出力する, 必須 |
| -C | テキストに色をつける, お好み |

### sample

document_index.html

```html
Directory Tree
./
├── DirA
│   ├── sample01.txt
│   ├── sample02.txt
│   └── sample03.txt
├── DirB
│   └── sample04.txt
├── DirC
│   ├── DirD
│   │   └── sample06.txt
│   └── sample05.txt
└── document_index.html
```

環境次第だけどディレクトリ等はテキストカラーが変更されていたり、ディレクトリ、ファイルはリンクになっています。
treeコマンドはconsole出力するのが一般的だと思いますが、htmlのほうがユーザーフレンドリー。
状況によってはブラウザ経由でpdf化する手もアリかと思います。
コンテナ内でmanを読みたい

## やりたいこと

コンテナ内にシェルでログインして作業しているときに、manコマンドでマニュアルを読みたい。
例えば、`docker run -it --rm centos:7 bash` のような感じでちょっとした作業をしたくてコンテナを作る場合を想定。
そもそも man コマンドが入っていない。 man コマンドをインストールしてもエントリーがないと言われる。

```
# man bash
bash: man: command not found
# yum install -y man
# man bash
No manual entry for bash
```

## 原因
パッケージマネージャーがmanのエントリーを導入しない設定になっているため。`tsflags=nodocs`の部分が該当の設定。

```
# cat /etc/yum.conf
[main]
cachedir=/var/cache/yum/$basearch/$releasever
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum
distroverpkg=centos-release
override_install_langs=en_US.utf8
tsflags=nodocs
# 以下略
```

## 解決方法

CentOSの場合

```
# yum install -y man; yum reinstall --setopt=tsflags='' -y bash
```

Ubuntuの場合

```
# rm /etc/dpkg/dpkg.cfg.d/excludes; apt-get update; apt-get install -y man; apt-get install -y --reinstall bash
```
03ArduinoでLEDのPWMを用いて輝度を変えてみる　LEDの制御

###LED輝度の調整方法
LEDの輝度（明るさ）調整するためには、どうすればよいか。
**①印加する電圧を変える
②IFを少なくする
③光っている時間と消えている時間に差をつける**

などの方法があります。

マイコンなどで手軽に行える制御が、③の方式が簡単にできます

###まず、プログラム
```cpp:robot19_base
  PORTD = 0x01; delay(10);
  PORTD = 0x00; delay(100);
```

と記述してみました。

LEDは点滅するが、光っている時間も10msあるので、目が痛い・・

この動作をもっと高速で行うとどうなるか、delay関数の時間を短くしてみよう
ただし、1ms以下にはできないので、注意


この時間差のことをDuty比と呼ぶらしい。

次にこのDuty比を連続的に変えてもみる、

```cpp:robot19_base
int i,j;
for(j=0;j<10;j++){
  for(i=0;i<100;i++){
    PORTD = 0x01; delay(j);
    PORTD = 0x00; delay(10-j);
  }
}
```
**＜結果＞**段階的に輝度が変わりました。

連続して輝度を変えるためには・・・
ソフト的に制御するにも無理がある

###PWM信号とanalogWrite()
ArduinoにはanalogWrite()という関数があるこれを使うとLEDの輝度が変えられます。

```cpp:
analogWrite(6,i)  //第1引数　6・・・出力ポート　第2引数　i・・・値0~255　
```
この関数を使うとPWMと呼ばれる機能を簡単に使うことが出来るますが、ハードウェア的に信号を生成するので、どのピンでも使えるわけではないようです。
Arduino Unoではデジタル出力の 3, 5, 6, 9, 10, 11 のピンが PWM に利用できます。

この機能を利用して、LEDの輝度を連続的に変えてみました。

```cpp:Robot19_base
int i,j;
for(j=0;j<10;j++){
  for(i=0;i<255;i++){
    analogWrite(6,i);
    delay(100);
  }
}
```
LED6だけがじわじわと明るくなり、突然暗くなってまたじわじわと明るくなった。

###PWMの仕組み
PWM (Pulse Width Modulation) は、電圧などを簡単に制御する方法の一つで、周期ごとに１（オン）と０（オフ）の時間を可変する技術、 パルス幅に比例した電圧を得ることがでる。

次の例では１周期ごとに１の時間と０の時間が変化している
第一周期では２０％のオン時間となる

![PWM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/af4e9c44-b0ac-db4d-9b94-7b5387adbba9.jpeg)


こうすることで平均的に ON の時の電圧の 20% の電圧 (すなわち、5[V]*20[%]=1.00[V]) を得ることができる。

尚、この場合 ON である時間をデューティー・サイクル (Duty Cycle) という。これが、最大電圧に対する出力電圧の割合となる。

**＜確認＞**
LEDの輝度を50%で発光させてみる
LEDを2つ20%と80%光らせる

###参考サイト
---
参考にさせていただいたページは以下の通りです。
大変わかりやすくまとめられています。
ありがとうございます。
[PWMに関して]https://iot.keicode.com/arduino/arduino-analogwrite-pwm.php
[iOS] CocoaPods使用時のUndefined symbols for architectureの回避方法

## 概要
CocoaPodsで外部ライブラリを追加した際、Undefined symbols for architectureのエラーが出てビルドが通らない場合があります。
原因はいくつか考えられますが、下記のようにBuild Settingを修正することで解決できる可能性があります。

## 対処法
Build Setting -> Other Linker Flagsに$(inherited)を追加する

<img width="310" alt="Screen Shot 2019-04-16 at 12.13.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122091/c9d85149-e62e-b8c3-7149-fcc8e4106e2e.png">
AWS Config

#概要#

AWSリソースの設定から、AWSリソースの構成情報のスナップショットを取得し、管理するサービスです。
この構成情報を元に、現状のAWSリソースの設定が、利用者によって定義された正しい状態になっているか評価します。
また、リソースが変更された場合などのタイミングで、Amazon SNSと連携、通知し、システムの変更によって加えられたAWSリソースの変更履歴を管理するのにも利用できます。


#やってみる#
**ステップ 1: 設定**
記憶するリソースタイプ：すべてのリソース
Amazon S3 バケット：s3バケットを作成し、設定履歴と設定スナップショットを保存します。
Amazon SNS トピック：設定の更新および以前の状態からの変更についての通知を行うことが出来ますが、今回は設定していません。
AWS Config ロール：AWS Configが設定情報を記録するために必要なIAM Roleを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/66004de8-5809-9bf3-92a1-1b2e23a24af0.png)


**ステップ 2: ルール**
今回は動作検証のために2つ程設定しています。

s3-bucket-versioning-enabled
S3 バケットに対してバージョン管理が有効になっているかどうかを確認します。オプションで、ルールは MFA 削除が S3 バケットに対して有効になっているかどうかを確認します。
→今回S3バケットのバージョニングはわざと設定しておかない。

なお、「マネージドルール」と「カスタムルール」があります。
「マネージドルール」はAWSが予め定義されているものであり、今回はこれを使います。
「カスタムルール」はAWS Lambdaとか関連づけることが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/2c90a1e4-bb9b-3aa8-c77c-9843c0a5749b.png)


**ステップ 3: 確認**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/456a0c15-f3c2-6017-72aa-eb0ad7b8fca6.png)


リソースのイベントリを確認する。
バージョニングは有効にしていないので、ルールに準拠していないことがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/4e4d9cb9-c33a-86b9-7556-310a9d480e03.png)

バージョニングを有効にし、再評価するとルールに準拠していることがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/b7bf1a93-d5f7-4f43-c8b8-c60df2b103ed.png)

また、「ステップ 1: 設定」で設定した設定履歴と設定スナップショットがS３からも確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/1e97fb7f-09a1-d353-7558-7ca31bb23778.png)



#料金#
[AWS Config の料金](https://aws.amazon.com/jp/config/pricing/)



#UPDATE#
[[Jun 3, 2020]AWS Config が 9 つの新しいマネージド型ルールをサポート](https://aws.amazon.com/jp/about-aws/whats-new/2020/06/aws-config-supports-9-new-managed-rules/)
[[Mar 15, 2021]AWS Configは、Amazon SecretsManagerに3つの新しい設定ルールを追加します](https://aws.amazon.com/jp/about-aws/whats-new/2021/03/aws-config-adds-3-new-config-rules-for-amazon-secrets-manager/)

#暗号化#
[[Feb 19, 2021]AWS Config で使用される S3 バケットでの KMS 暗号化のサポート](https://aws.amazon.com/jp/about-aws/whats-new/2021/02/support-for-kms-encryption-on-s3-buckets-used-by-aws-config/)
今まで保管したデータの暗号化はS3のサーバー側の暗号化はサポートしていましたが、KMSを利用した暗号化にはサポートしていませんでしたが、今回これに対応しました。
KMSで暗号化したデータにアクセスするには、S3とKMSのアクセス権が必要となり、S3のサーバー側の暗号化と比べ、よりセキュアに管理することができます。
[Vuetify] Unable to locate target [data-app]

Vue + Vuetifyを使っていて、表題のようなアラートが出たら、アプリケーションを`<v-app>...</v-app>`で囲ってないかもしれません。

例）囲っていない

```App.vue
<template>
  <div id="app">
    <div class="wrapper">
      <MyHeader></MyHeader>
      <MyAside></MyAside>
      <div class="content-wrapper">
        <router-view/>
      </div>
    </div>
  </div>
</template>
```

これを、`<v-app>`で囲ってあげるように変更すると以下のようになります

```App.vue
<template>
  <v-app id="app">
    <div class="wrapper">
      <MyHeader></MyHeader>
      <MyAside></MyAside>
      <div class="content-wrapper">
        <router-view/>
      </div>
    </div>
  </v-app>
</template>
```

公式ドキュメントでは、以下に書いております
https://vuetifyjs.com/en/getting-started/frequently-asked-questions#my-application-does-not-look-correct
本番環境じゃなくてローカル環境で画像がうまく表示されない

ローカル環境では問題ないのにデプロイして確認するとビューが崩れていることって多々ある。
が今回は本番環境でみられるのに、ローカルでダメという事態。しかも自分はどっちの環境でも大丈夫で,見られないのは同じチームのメンバーのみ。
以下画像を投稿した際のエラー文🙄

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386408/8537f500-ae58-be2a-bf6c-631224093769.png)




####Excon::Error in ItemsController#create
で調べてみるとS3とかAWSの設定関連の記事が多く見つかる。。。
デプロイは自分が担当していたので、まずはAWS設定を変えてみる方向で考えた。

stack over flowで同じようなエラー文に関する記事を見つけたので読んでみる。

```
1) Sign in to the AWS Management Console at http://aws.amazon.com/iam/

2) Click "Policies" from the Navigation Pane on the left

3) Select the "AdministratorAccess" policy

4) Click Policy Actions > Attach at the top of the page

5) Select the user associated with my S3_ACCESS_KEY, S3_SECRET_KEY, and S3_BUCKET

6) Click "Attach Policy"

```


やったこと（AWS）
上記の記事抜粋部を参考に、
①AWSにアクセス→②IAMを開いてポリシーをクリック→③検索フィールドで"AdministratorAccess"を選択→④"ポリシーの使用状況"をクリックして、作業中のインスタンスをアタッチ

やったこと（サーバー）

```

(uploaders/image_uploader.rb)

if Rails.env.production?
    storage :fog
  else
    storage :file
  end
```


```
(carrier_wave.rb)
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      # Configuration for Amazon S3
      :provider              => 'AWS',
      :aws_access_key_id     => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY']
    }
    config.fog_directory     =  ENV['S3_BUCKET']
  end
end

```
にして本番環境とローカル環境で条件分岐。

##**感じたこと**
デプロイって完全にインフラの領域で今後やりたいことと必ずしも直結はしないけど、WEBに関しての知識が身につく点で学ぶ価値がある気がする。
他分野のことを違った視点で観察できそう。
ただ、今の時点でやってることは"プログラミング"というか単なる"設定"なので、やっぱあんまり面白みはないかなあ苦笑
org.json で JSONをフォーマットする


org.json.JSONObject.toString(int indentFactor) を使う。

```java

package hello.json;

import org.json.JSONArray;
import org.json.JSONObject;

public class HelloOrgJson {

	public static void main(String[] args) {
		JSONObject json = new JSONObject();
		json.put("key1", "value1");
		json.put("key2", "value2");

		String[] ss = { "a", "b", "c" };

		JSONArray arr = new JSONArray();
		for (String s : ss) {
			JSONObject o = new JSONObject();
			o.put("xx", s);
			arr.put(o);
		}
		json.put("arr", arr);

		System.err.println("--- no formatting ---");
		System.err.println(json.toString());
		System.err.println("--- pretty printed ---");
		System.err.println(json.toString(1));
	}

}

```

結果

```
--- no formatting ---
{"key1":"value1","arr":[{"xx":"a"},{"xx":"b"},{"xx":"c"}],"key2":"value2"}
--- pretty printed ---
{
 "key1": "value1",
 "arr": [
  {"xx": "a"},
  {"xx": "b"},
  {"xx": "c"}
 ],
 "key2": "value2"
}
```
colorboxで表示したiframeで下に余白が出来るのを修正する

# 環境
特になし

# したいこと
colorbox で YouTube iframe をモーダルとして表示させたら、なぜかモーダル内の iframe の下に 6px の余白が出来てしまったので、これを修正したい。

# 解決策
モーダルとかのサイズ指定の問題かと思ったら、どうやら iframe の表示位置の問題だったみたいですね。以下で治りました。……結構時間取られた。

```
iframe {
    vertical-align:bottom;
}
```
これだけ。……これだけ……。
mBaaS

##mBaas(Mobile Backend as a Searvice)とは？
サーバーサイドを肩代わりしてくれる、スマートフォンアプリでよく利用される汎用的な機能をクラウドから提供するサービスです。

クライアント側のコードしか書けなくても、クラウド上に用意された機能をAPIで呼び出すだけで利用できるので、サーバー開発・運用不要でよりリッチなバックエンド機能をアプリに実装することができ、工数削減によるコストカット・スピードアップに貢献します。

iOSアプリやAndroidアプリは作れるが、Webやデータベースの知識があまりないという人にかなり役にたつと思います。

＊データベース…データを保存するための仕組み。

##mBaassが使った事例
データをサーバーに保存し、他のユーザーと共有、通知。
新規登録、ログイン、ログアウトなどのユーザー管理。
---->　これがサーバーサイドの言語が書けなくても可能になる！！

*サーバー…ネットワークを通じてデータを管理、保存しておくもの。
Transfer-Encoding: chunked を知らずに生のContentを使用してハマったこと

構築済みのWebシステムにおいて別のWebサーバとのサーバ間通信を実装したのですがレスポンス結果を取得したところ正常にjson_decode()できなくてはまりました。。

結論を言うと、`Transfer-Encoding: chunked`を知らずにレスポンスから生のContentを取得する関数(getContent())を使用してjsonデコードをしていたのが原因でした。

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Transfer-Encoding#Directives

HTTPレスポンスヘッダに`Transfer-Encoding: chunked`があるとContentがchunk(塊)の連続で送られるらしい。
つまり、下の画像のようなレスポンスになります。(下の例はchunkが1個だけ)

![0416-transfer-response.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133525/fa74f12d-0c05-9f6a-8597-a8133673425d.png)

それなのに生のContent(dl\r\n{json部分}\r\n0)を抜き出してjsonデコードしたら、そりゃ変換できませんよね。。
どうすればいいのかなと思っていましたが、使用しているフレームワーク(ZF3)のHTTP通信クラスではちゃんと`Transfer-Encoding: chunked`を考慮してレスポンスを取得する関数があったのでそちらを使用すれば問題ありませんでした。

``` Response.php
public function getBody()
{
    $body = (string) $this->getContent();

    $transferEncoding = $this->getHeaders()->get('Transfer-Encoding');

    if (! empty($transferEncoding)) {
        if (strtolower($transferEncoding->getFieldValue()) === 'chunked') {
            $body = $this->decodeChunkedBody($body);  //←★Transfer-Encoding: chunkedの場合ここで変換される
        }
    }

    $contentEncoding = $this->getHeaders()->get('Content-Encoding');

    ～中略～

    return $body;
}
```
VisualStudio - C# - DB接続 - コードで

ググれば一発と思ったら何度か試すハメになったので

### 書き方
```C#:dbConnect.csharp
string dbConnect = @"DataSource           =  (localdb)\MSSQLLocalDB;
                     Initial Catalog      = TESTDB;
                     Integrated Security  = True;";
/*(localdb)\MSSQLLocalDB : 接続先
  TESTDB                 : 接続先DB
  True                   : 呪文*/
```



ちなみに下記みたいにクラスに分けると便利

```C#:dbConnect.csharp
using System.Data.SqlClient;

public void load()
{
　　/* 今回データグリッドビューにデータ入れる時の処理 */
    /* 書いてたときのなのでそれもコメントで追記      */
    /* var dt_code = new DataTable();            */

    // 変数に接続文字列を代入
    var conStr = construct.dbConnect;

    // usingの()内で恐らくDB接続情報取得　確認して
    using (var connect = new SqlConnection(conStr))
    {
        var cmd = connect.CreateCommand();
        cmd.CommandText = "SELECT * FROM TABLE";

        // DBに接続
        var sda = new SqlDataAdapter(cmd);
        /* sda内の接続情報でdt_code（データテーブル）
           にデータ入力
        sda.Fill(dt_code);                         */
    }
    /* データグリッドビューのソースにテーブルのデータを入れる
    DataGridView1.DataSource = dt_code;            */
}


static class construct
{
    string dbConnect = @"DataSource           =  (localdb)\MSSQLLocalDB;
                         Initial Catalog      = TESTDB;
                         Integrated Security  = True;";
    /*(localdb)\MSSQLLocalDB : 接続先
      TESTDB                 : 接続先DB
      True                   : 呪文*/
}
```