OmniAICreator/Qiita-1.07M huggingface dataset:
mruby-bsdtftについて

FreeBSDでSPIの液晶を制御するためのmrbgemとして作りました。当初は汎用のmruby-bsdspiとmruby-bsdgpioを使っていましたが、最適化のためと初期化などを共通化しています。

https://github.com/yamori813/mruby-bsdtft

これまではmrbgemはCでしか書いてなかったのですが、Cとrubyコードを使うようにしました。理由は忘れてしまったのですが、mruby-bsdspiは継承せずにobjectからのクラスになっています。CコードはOSへのアクセスや最適化が必要な部分でrubyコードは初期化などテスト用のスクリプトで書いたものを入れました。

変数の処理もCコードで実装してrubyコードからはselfでアクセスできるようにしています。

![SPIGEM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d42f85a5-dcf5-8853-2ead-e3168193408e.png)

サポート対象は以下の三種類です。

|チップ|メーカー|サイズ|信号線|入手先|
|:--|:--|:--|:--|:--|
|[S6D0151](https://qiita.com/yamori813/items/ce2b6e79e079ec834e7e#m2p0327e-b)|SAMSUNG ELECTRONICS|128x160|4本|aitendo|
|[ST7735](https://qiita.com/yamori813/items/ce2b6e79e079ec834e7e#t18spi-2p)|Sitronix Technology|128x160|5本|aitendo|
|ILI9341|ILI TECHNOLOGY|240x320|6本|Amazon|

S6D0151はSPIのCLK,MOSI,CSとRESETだけで操作できます。他の二つはコマンドとデータを区別するRS信号が必要になってます。ILI9341は読み出しの信号がありますが、他の二つはありません。ST7735はいくつかタイプがあるようなので、動かないものがあるかもしれません。

S6D0151の接続は以下のようになります。

![SPI_LCD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/e26dbc05-13f3-20b0-bc3e-74df9d6349e3.png)

MOSI,CLK,CSはspigenで処理してRESETはgpioctlで処理する事になります。

簡単な使い方を書きます。

```ruby
tft = BsdTft.new(1, 0, BsdTft::S6D0151)
```

newの最初のパラーメータはspigenデバイスの番号で、二つ目はGPIOの番号、三つ目は液晶モデルになります。

```ruby
tft.setsize(W, H)
tft.setreset(RST)
tft.init
```

画面サイズや、RESET信号のGPIOピンを設定して初期化します。

```ruby
tft.lcdcopy(c.get_data)
```

Cairoで書いた画面を液晶に転送します。テストスクリプトでは、rubyコードで処理していたのですが、処理が遅かったので、rubyでは処理せずポインター渡しにしました。240x320で2秒弱で128x160は1秒弱で再描画できます。もう少し早いと良いのですが、開発を始めた当時に比べるとかなり早くなっています。

![写真（2019-04-30 13.58）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/5d5c7378-5d4f-f2e5-c9f6-1e264fc25f22.jpeg)

小型液晶のFreeBSDでの利用は[ST7735が最初](https://qiita.com/yamori813/items/ae66330ccbf6fe6bd5ab)だったのですが、このクラスは最初にS6D0151用として作り、ST7735も取り込みました。

ST7735はBigEndianのAtherosのSOCで試していて、他の二つはLittleEndianのRalinkで試しました。RalinkのセカンドSPIのサポートはこのために作りました。

https://svnweb.freebsd.org/base?view=revision&revision=347998

Ralink(mips/mediatek)のSPIのコードはFlashに依存したコードになっていて、spigenを使ったら動きませんでした。本来は整理すべきだとおもうのですが、ちょっといじったら動かなくなってしまい、見通せてない部分があるのと、問題があると起動できなくなるなど、影響範囲が大きいのでアドホックな修正になっています。このことは指摘されたのですが、adrianさんが状況を理解してくれてコミットしてもらいました。

Atherosの方はrayが作った[GPIOのBitbangのSPI](https://qiita.com/yamori813/items/30e7b078b98777895ab6)でのアクセスで処理しています。

このクラスは三種類のチップを透過に扱えSOCにも依存していません。ILI9325のパラレルIF用に[mruby-gpiotft](https://qiita.com/yamori813/items/b3dcaa1673e6b1b3d8db)というクラスも作ったのですが、これはGPIOの32ビットアクセスを使用していてAllwinnerのA10や接続に依存している部分があり、あまり汎用的になっていません。

液晶コントローラーは他にもありますが、この三種類は日本で手に入りやすい方だと思います。

野ざらしの基板だとホコリまみれになるので、なにかに収めてすぐに試せるようにしたいが、妙案がありません。

240x320な液晶ではアウトラインフォントなどを使いたいのでストレージが無限に使えるUSBがついたターゲットが良い気がします。128x160な液晶ではビットマップフォントだけで良いので8M Flashなターゲットでもいろいろできそうです。

AR2315でmruby-bsdspiを試したところreadが上手く出来ませんでした。spiコマンドでも同じだったので、spigenの問題のようです。tftの処理は書き込みで完結していて、これは問題ないのだが。なんでだろう？(2923/10/14)
アソシエーションについてまとめてみた

##アソシエーション（関連付け）
アソシエーションとは、モデルとDB間をまたいだデータの呼び出しをより簡単に行うことが出来る。
####アソシーションの定義
①モデルクラスにhas_manyやbelongs_toが定義されていること。
②所属するテーブル側に、クラス名_idというカラムがあること。

####用語の解説
※分かりやすくするために、ツイッターを例に解説します。

has_many   → ユーザーは、自分の作成したツイートを複数個所持している状態である。

```ruby:qiita.rb
class User < ApplicationRecord
    devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :validatable
    has_many :tweets
  end
```

belongs_to →全てのユーザーは、いずれかのツイートを保持している。

```ruby:qiita.rb
class Tweet < ApplicationRecord
    belongs_to :user
  end
```

####アソシエーションのメリット
・モデルをまたいだ呼び出しが簡単になる。
　→userモデルのインスタンス.tweetsで呼び出しが可能になる


・アソシエーションを使用しない

```ruby:ターミナル
[2] pry(main)> Tweet.where(user_id: user.id)
```

・アソシエーションを使用

```ruby:ターミナル
[2] pry(main)> user.tweets
```
plunkerでsimcirjs

#概要

plunkerでsimcirjsやってみた。

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5307b2ff-8d1f-3da8-be92-4600ed30ae30.png)

#サンプルコード

```
{
  "width":800,
  "height":400,
  "showToolbox":true,
  "toolbox":[
    {"type":"In"},
    {"type":"Out"},
    {"type":"Joint"},
    {"type":"DC"},
    {"type":"LED"},
    {"type":"PushOff"},
    {"type":"PushOn"},
    {"type":"Toggle"},
    {"type":"BUF"},
    {"type":"NOT"},
    {"type":"AND"},
    {"type":"NAND"},
    {"type":"OR"},
    {"type":"NOR"},
    {"type":"XOR"},
    {"type":"XNOR"},
    {"type":"OSC"},
    {"type":"7seg"},
    {"type":"16seg"},
    {"type":"4bit7seg"},
    {"type":"RotaryEncoder"},
    {"type":"BusIn"},
    {"type":"BusOut"},
    {"type":"RS-FF"},
    {"type":"JK-FF"},
    {"type":"T-FF"},
    {"type":"D-FF"},
    {"type":"8bitCounter"},
    {"type":"HalfAdder"},
    {"type":"FullAdder"},
    {"type":"4bitAdder"},
    {"type":"2to4BinaryDecoder"},
    {"type":"3to8BinaryDecoder"},
    {"type":"4to16BinaryDecoder"},
    {"type":"AltFullAdder"},
    {"type":"Transmitter"},
    {"type":"Delay"},
    {"type":"NumSrc"},
    {"type":"NumDsp"},
    {"type":"DSO"}
  ],
  "devices":[
    {"type":"DC","id":"dev0","x":96,"y":120,"label":"DC"},
    {"type":"Toggle","id":"dev1","x":160,"y":72,"label":"Toggle","state":{"on":false}},
    {"type":"Toggle","id":"dev2","x":160,"y":152,"label":"Toggle","state":{"on":false}},
    {"type":"LED","id":"dev3","x":216,"y":112,"label":"LED"},
    {"type":"LED","id":"dev4","x":216,"y":208,"label":"LED"},
    {"type":"XOR","id":"dev5","x":312,"y":112,"label":"XOR"},
    {"type":"LED","id":"dev6","x":400,"y":112,"label":"LED"}
  ],
  "connectors":[
    {"from":"dev1.in0","to":"dev0.out0"},
    {"from":"dev2.in0","to":"dev0.out0"},
    {"from":"dev3.in0","to":"dev1.out0"},
    {"from":"dev4.in0","to":"dev2.out0"},
    {"from":"dev5.in0","to":"dev1.out0"},
    {"from":"dev5.in1","to":"dev2.out0"},
    {"from":"dev6.in0","to":"dev5.out0"}
  ]
}
```

#成果物

https://embed.plnkr.co/3dCoIPA2wKI3HAO36sId/

以上。
Shape Detection APIでQRコード検出を試しました

## はじめに
初めまして、[ｋ．ｓ．ロジャース](https://www.wantedly.com/companies/ks-rogers)の西谷です。

直近でPCカメラからQRコードの読込を行いたい話がありました。
利用者の環境が未定であったことから、ブラウザ上で動作するQRコードリーダがあれば良い話があり、調査しておりました。
[こちらの記事](https://qiita.com/diggymo/items/5caf1fcf157fc29e9451)を紹介頂き、非常に参考になりました。

しかし、Shape Detection APIが全てのブラウザで非対応は「何かあるのでは？」と考え調査と検証を行いました。

間違い・助言等があればコメントにてお知らせいただけたらと思います。

## Shape Detection APIとは
顔検出、ORコード読込、テキスト認識の3つのAPIを提供します。
これらはハードウェアアクセラレーションに対応しており、既存のWebライブラリに比べて低い負荷で実行することができます。

また、本APIは2019/05時点では草案で、試験的な機能となります。

本来上記３つの機能がありますが、今回は要件がQRコード読み取りであるため、QRコード周りの検証を行います。

## 実装
chromeの以下URLから`Experimental Web Platform features`をEnabledにすることで利用できるようになります。

```
chrome://flags/#enable-experimental-web-platform-features
```

QRコード識別の部分に関しては`detector.detect(image)`をするだけで、後は識別した後のデータを返してくれます。
検証はこちらのコードを利用して進めました。
https://qiita.com/massie_g/items/a203cf2071f96d910743


## 動作状況
今回の一番の嵌りどころでした。
本APIはハードウェアアクセラレーションを利用するため、`利用デバイスによって挙動が異なります`。

私の手元のデバイスではそれぞれ次のようになりました。

| OS      | バージョン等   | 検証結果                         |
|---------|----------------|----------------------------------|
| Android | Nexus 5X        | 正常動作                         |
| iOS     | iPhone8        | Chromeのフラグが存在せず |
| macOS     |Mojave 10.14.1        | 動作するがQRコードを検出せず     |
| Windows | windows10 1809 | 非対応                           |



### Androidについて
こちらは正常動作しました。

<img width="379" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274674/b095a24d-b736-a7e2-20b1-a004ea0f0f6d.png">

QRコード以外にDataMatrixなども検出できます。
<img width="361" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274674/83f24141-44f1-54c5-2b97-62e782cd9dca.png">



### macOSについて
macOSはサポート済み判定されており、detect関数もエラーなく動作していました。
しかし、[公式サンプル](https://codepen.io/miguelao/pen/wgrYjZ?editors=0010)の固定画像でもQRコードを認識出来ませんでした。

<img width="298" alt="スクリーンショット 2019-05-23 4.47.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274674/a94bcc43-f056-27a6-9f49-b5be19b384cf.png">

### その他のデバイス
Windowsは公式で非対応との記載があり、QRコードは対象外になります。
iOSのChromeは`enable-experimental-web-platform-features`がなく、非対応となっています。

## 参考資料
https://wicg.github.io/shape-detection-api/#introduction
https://www.chromestatus.com/feature/4757990523535360

## おわりに
今回はWebブラウザでQRコードを認識する予定でしたが、現状のShape Detection APIはかなりデバイスに依存することが分かりました。
標準化後に依存周りが良くなれば、開発コストやパフォーマンスを改善に期待できると思います。


今回は知見がほぼないため、間違いや改善案などがあれば是非教えて頂けたらと思います！


### Wantedlyでもブログ投稿してます
Techブログに加えて会社ブログなどもやっているので、気になった方はぜひ覗いてみてください。
https://www.wantedly.com/companies/ks-rogers
Windows10でアプリケーションの設定ファイルはどこに置くべきか？

XDG Base Directory Specification
---------------------------------

Linux環境ではデスクトップ環境の標準化を目的として、[XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)という仕様があって、それぞれアプリケーションが使うべきディレクトリを指定しています。

- XDG_CONFIG_HOME
  - ユーザー個別の設定が書き込まれるディレクトリ (/etc と類似)。
  - デフォルトは $HOME/.config です。
- XDG_CACHE_HOME
  - ユーザー個別の重要でない (キャッシュ) データが書き込まれるディレクトリ (/var/cache と類似)。
  - デフォルトは $HOME/.cache です。
- XDG_DATA_HOME
  - ユーザー個別のデータファイルが書き込まれるディレクトリ (/usr/share と類似)。
  - デフォルトは $HOME/.local/share です。

より詳しくは[XDG Base Directory サポート - ArchWiki](https://wiki.archlinux.jp/index.php/XDG_Base_Directory_%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88)を見てください。これは[freedesktop.org](https://ja.wikipedia.org/wiki/Freedesktop.org)が定めている仕様なのでWindowsではサポートされていません。

KNOWNFOLDERID / CSIDL
-----------------------

Windwos側でこれに対応するのが[KNOWNFOLDERID](https://docs.microsoft.com/en-us/windows/desktop/shell/knownfolderid)と[CSIDL](https://docs.microsoft.com/en-us/windows/desktop/shell/csidl)のようです。

|Environment String |	Example Path |
|:---------|:--------|
|%ALLUSERSPROFILE%|C:\ProgramData|
|%APPDATA%        | C:\Users\username\AppData\Roaming|
|%LOCALAPPDATA%   |C:\Users\username\AppData\Local |
|%ProgramData% 	  |C:\ProgramData
|%ProgramFiles%   |C:\Program Files
|%ProgramFiles(x86)% |C:\Program Files (x86)
|%PUBLIC% 	|C:\Users\Public
|%SystemDrive% 	|C:
|%USERPROFILE% 	|C:\Users\username
|%windir% 	|C:\Windows 


なので表題のアプリケーションの設定は `%APPDATA%`を使うのが良さそうです
python入門[import]　「from relative_module import identifier」 とか

#目的
import文に関して
　**import モジュール**
という構文の意識が強くて、
　**from AA import BBBB**
という構文で、BBBBがモジュールでないのが、どうにも、**気持ち悪かった。。。**
納得を求めて、調査したが、
結局、以下の記載が一番すっきりしていたので、メモ。

https://docs.python.org/ja/3/reference/simple_stmts.html#grammar-token-import-stmt

#import statement

import statementの説明は、以下。
import moduleは、ほんの一例に過ぎないと読める。
各々のケースの処理内容も説明されているので、更に、納得。

（出典：https://docs.python.org/ja/3/reference/simple_stmts.html#grammar-token-import-stmt）

```
import_stmt     ::=  "import" module ["as" identifier] ("," module ["as" identifier])*
                     | "from" relative_module "import" identifier ["as" identifier]
                     ("," identifier ["as" identifier])*
                     | "from" relative_module "import" "(" identifier ["as" identifier]
                     ("," identifier ["as" identifier])* [","] ")"
                     | "from" module "import" "*"
module          ::=  (identifier ".")* identifier
relative_module ::=  "."* module | "."+
```



<img width="617" alt="from.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/018f8d6b-aecd-0835-0d7e-6087194c0839.png">

#まとめ
「docs.python.org/ja/3/reference」が、一番いいときもあると感じた。

#関連（本人）
[pythonをストレスなく使う！（結局docs.python.orgのreferenceが納得感が高い気が、、、)](https://qiita.com/enoughspacefor/items/9f714c9d4a13b6f1eaa9)
[英語と日本語、両方使ってPythonを丁寧に学ぶ。](https://qiita.com/enoughspacefor/items/d4b49747773e2d0285f9)

#今後
何かあれば、追記します。
コメントなどあれば、お願いします:candy:
DNSサーバ(bind)を仮想マシンとして作成／＃6：負荷試験

bindの負荷試験を行うシェル

[ホスト名を配列として保持し、ランダムに実行](https://gist.github.com/harasakih/5a183a147da6df5719ac9252cde72b5f)
[ランダムなホスト名を生成し実行](https://gist.github.com/harasakih/50875d0f72a566a7a6f97b48a0a734c0)

```bash
#!/bin/bash

# --+----1----+----2----+----3----+----4----+----5----+----6
# 変数初期化
# --+----1----+----2----+----3----+----4----+----5----+----6
#
    HOSTS=()

    # コマンド文字列
    HOSTS+=("random01.esxi")
    HOSTS+=("random02.hrsk")
    HOSTS+=("random03.hrsk")
    HOSTS+=("random04.hrsk")
    HOSTS+=("random05.hrsk")

    # コマンド文字列--終了--
    nHOSTS=${#HOSTS[*]}                     # $CMDの要素数
    nTRIES=100                              # 試行回数
    WAIT=1                                  # インターバル

    echo "nHOSTS=$nHOSTS"
    echo "nTRIES=$nTRIES"
    echo "wait(s)=$WAIT"
    echo -n "GO -- Y/N.. "
    read YN

    [ $YN != "Y" ] && exit 1
    echo ":: start at `date` ::"
    for (( i=0; i < $nTRIES; i++ ))
    do
        RAND=$(( $RANDOM % nHOSTS ))
        HOST=${HOSTS[ ${RAND} ]}
        printf "iteration %4d %s\n" $i $HOST
        nslookup $HOST 192.168.0.121
    done
    echo ":: finish at `date` ::"
```

```bash
#!/bin/bash

# --+----1----+----2----+----3----+----4----+----5----+----6
# 変数初期化
# --+----1----+----2----+----3----+----4----+----5----+----6
#
    nHOSTS=100
    nTRIES=500                              # 試行回数
    WAIT=1                                  # インターバル

    echo "nHOSTS=$nHOSTS"
    echo "nTRIES=$nTRIES"
    echo "wait(s)=$WAIT"
    echo -n "GO -- Y/N.. "
    read YN

    [ $YN != "Y" ] && exit 1
    echo ":: start at `date` ::"
    for (( i=0; i < $nTRIES; i++ ))
    do
        RAND=$(( $RANDOM % nHOSTS ))
        HOST=`printf "test%03d.test" $RAND`
        printf "iteration %4d %s\n" $i $HOST
        nslookup $HOST 192.168.0.121
    done
    echo ":: finish at `date` ::"
```
【2分でイメージをつかむ】fsオブジェクト

## なんでこれを書いたか
- Node.jsでサーバーを立てた後、やることはこれ
- ファイル読み込みをどうやってやるかのイメージをつかみたかったから

## fsオブジェクトとは
  - file system オブジェクト
  - ファイルを扱うオブジェクトでHTMLファイルなど読み込める！
  
## 使い方

男は黙って、変数に読み込む

```javascript
var fs = require('fs');
```

まずはこれだけ使えるようになればOK

```javascript
fs.readFile( './hello.html', 'UTF-8', コールバック関数 );
```

- 第１引数にファイルパスを指定（例えば・・'./hello.html'）
- 第２引数には'UTF-8'を指定（一旦はこういうもんだと思っておけばOK）
- 第３引数には、読み込み完了後の処理を行うコールバック関数をかく

## コールバック関数
- コールバック関数は、このファイルの読み込みが完了したら、発動します！
- 仮にこのファイルが、読み込みに１時間を要する超膨大ファイルだったとしましょう
- １時間後、コールバック関数が発動し、そのあとに書いてるソースコードはようやく読まれるようになります

　

例えるなら、お会計をしている人が財布を探していて、なかなか列が進まない・・
![images.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247053/3402d759-2c33-3ec4-068d-d0208ce12c34.jpeg)


#### しかし

- そんなことしてたら、ずーっと待ちっぱなしで列に並ぶ気が失せる
- というか財布探すのに１時間もかけて、店員もずっと待ってるって・・・店としてどうなんだ！

というご意見がありましたので、、

#### お財布探している間、次の方どうぞ〜

- に変更しました
- お財布が見つかり次第、お会計（コールバック関数）に移らせていただきます。
- 探している間は、次のお客様（readFile以降の処理）からお会計させていただきます。


## 簡単なコード例
```javascript

function doRequest(req, res) {
    //hello.htmlを読み込もう！
    fs.readFile('./hello.html', 'UTF-8', 
        // 読み込みが完了したら、コールバック関数が発動
        function(err, data) {
            res.writeHead(200, {'Content-Type': 'text/html'});
            // 読み込んだファイル（data）を書き込む
            res.write(data);
            res.end();
        });
    
    console.log('readFileのファイル読み込みが完了するまで、お待ちください');
    console.log('おや、このログを見ているということは、まだファイルの読み込みが完了していないようですね');
}
```

- hello.htmlのファイル読み込みがおそーーかった場合、コールバック関数は発動せずに、readFile関数の下にある、console.logが呼び出される
- ファイル読み込みが完了した時点で、コールバック関数が発動する


## こっから脱線
- コールバック関数は、「非同期処理」になります
- つまり、割り込みができるということです！
- 財布見つかった時点で、最後尾に列びなおさなくても、お会計に割り込めるというイメージです


### じゃあ、それって並列処理なんですか？
- 違います
- 並列処理は、複数の作業を同時に実施します。
- レジいっぱいあるから財布探している人が割り込んでくる心配はない。同時にお会計ができるということです

## 参考
- [JavaScriptの非同期処理を並列処理と勘違いしていませんか？](https://qiita.com/klme_u6/items/ea155f82cbe44d6f5d88)
- [
Node.jsのスクリプトの基本を覚えよう](https://www.tuyano.com/index3?id=1126003&page=4)
コンピュータが壊れる理由（ハードウェア的要因）

# コンピュータが壊れる3つの要素
- 熱
 - 電流を構成している電子が銅などの金属原子と衝突し、断線を引き起こす。
 - その際に、熱も発生する。
- 静電気
 - コンピュータの回路を構成しているCMOSトランジスタの絶縁膜を破壊する。
 - 人間の指先には10万ボルト以上の電気を帯びている。
- 導電性の液体（水等）
 - 回路に付着したホコリに水分が付着すると、本来電気を通したくない場所に電気が流れ、結果的に故障する。
 - 純粋な水を除き、一般的に液体物は電気を通す。

# 熱を表す方程式

`P = fcv^2`
P = 熱
f = コンピュータの動作スピード（クロック周波数）
c = コンデンサの容量
v = 電源電圧

つまり、回路の断線につながる熱を下げるには、`f(スピード)を下げる` `c(回路規模)を小さくする` `v(電源電圧)を下げる`ことが有効である。

# コンピュータが遅くなる要因
ハードウェア的要因で遅くなるのは`熱`が原因
CPUには温度計があり、ある温度を超えるとコンピュータを守るため動作スピード（クロック周波数）や電源電圧を下げる動きをする。
結果、性能が落ちてしまい、動作が遅くなる。

# 参照
[コンピュータのしくみ2019](https://www.fisdom.org/F00000081/)
「プログラミング言語」について知っておいてほしいこと

「プログラム言語」に関しては、**おすすめ**、**人気**、**学ぶべきもの**、**どれがイケているか**の順位付け議論が盛んに行われていて、新人プログラマはどの言語を学べばいいか、迷ってしまい、結局モチベーションが上がらないことも多いと思います。

どのプログラミング言語を勉強するかを順位づけする前に、**そもそもプログラミング言語とは何か**を考えるのはどうでしょうか？

# はじめに(参考記事)

#### おすすめのプログラミング言語を紹介する記事
- [2019年にお勧めのプログラミング言語](https://qiita.com/AnyPicksMagazine/items/6b7680c3ca635e83c275)

#### 人気のプログラミング言語を紹介する記事
- [プログラミング言語の人気](https://qiita.com/ty-edelweiss/items/b8172c2e22726bc08aeb)

#### 学ぶべきプログラミング言語を紹介する記事
- [全ての開発者が学ぶべき5つの言語](https://qiita.com/poly_soft/items/e89bc757596cfdfba784)
- [初心者がこれから学ぶべき言語を目的別にまとめてみた](https://qiita.com/blog3nt/items/c84b95ff3c0045416ac3)

#### どれがイケてるかに関するポエム記事
- [「例外」がないからGo言語はイケてないとかって言ってるヤツが本当にイケてない件](https://qiita.com/Maki-Daisuke/items/80cbc26ca43cca3de4e4)
- [「型」がないからJavaScriptはイケてないとかって言ってるヤツが本当にイケてない件](「型」がないからJavaScriptはイケてないとかって言ってるヤツが本当にイケてない件)

# プログラミング言語とは

「プログラミング言語」を、プログラミング言語で書かれたコードと混同していませんか？

wikipediaには

> コンピュータプログラムを記述するための形式言語である

と記載されていますが、

> コンピュータ・プログラミング言語の設計は「言語仕様」として示され、実装は「言語処理系」と呼ばれる。

とも記載されています。

**狭義のプログラミング言語**と**広義のプログラミング言語**を混同していると、プログラミング言語の違いが分かりにくくなります。「プログラミング言語」が示すものは、範囲によって、次の４段階に分かれると思います。

**level1**: **言語仕様**
**level2**: **言語仕様** + **言語処理系**
**level3**: **言語仕様** + **言語処理系** + **ライブラリ管理/ライブラリ**
**level4**: **言語仕様** + **言語処理系** + **ライブラリ管理/ライブラリ** + **開発環境/開発コミュニティ**

wikipediaでは、**level2**までを「プログラミング言語」としていますが、紹介した記事では、**level1～level4が混じっている**ことに注意しましょう。「プログラミング言語」で**level1**のみを想像した人は、上記の記事を読んでも消化不良になると思います。

# 各範囲を意識すると順位付けはどうなるのか？

**おすすめ**、**人気**、**学ぶべきもの**、**どれがイケているか**ではなく、プログラム言語を評価する**目的**から**level1～level4**のどの観点を重視して評価すべきかをまず決めましょう。

ざっくりと、下記のような感じになると思います。

**人気（シェア）** ⇒ **level4**
**人気（学術的な議論）** ⇒ **level1**
**業務(チーム開発)で使用する** ⇒ **level4**
**特化したものが必要** ⇒ **level3**

みたいになると思います。（もちろん、一意に決まるわけではないですが）

なお、初学者の目的(プログラミングを理解する)はlevel1～level4のどの観点でを重視して評価すべきでしょうか？
私の個人の意見では、すでに作成物までを具体的に見据えてプログラミングを勉強する場合を除けば、**level2が妥当**だと思います。(**level3以降の理解は1年程度の学習が必要**だと考えます)
その際に最初に紹介した記事の内容が参考になりますか？

# 学習曲線について

[文科省のPythonはPythonじゃねぇ](https://qiita.com/nagataaaas/items/ba33c4c4e0df0b5aa0c4)の[参照記事](https://blog.edunote.jp/entry/2019/05/20/050000)に下記の記載がありました。

> プログラミング言語は「Python」を採用しているが、多くの学校現場で使われている「JavaScript」や「VBA」「Swift」「ドリトル」などの言語で記述した場合の資料も順次公表する。

上記の記載で違和感があったのは、これらのプログラミング言語の違いは、**level2以降の観点で顕著になる**と思うのですが、**level1**の観点の教育で複数のプログラム言語の書き方の違いだけをピックアップして、意味があるのでしょうか？

個人的には、教育では導入時に**level1からlevel4までの観点の違いがあることを明記したうえでプログラミング言語の違いを説明してほしい**のですが、あまりそのような議論を見たことがありません。

なお、**level3**以降の観点でプログラミング言語を理解している人にとっては、「プログラマーは新しい言語を毎年1つは習得するべきだ」というのが腑に落ちるのだと思います。

# プログラミング言語の議論について

プログラミング言語を説明する際には、下記のようなものはどうでしょうか？

・チーム開発で使用したいか？(Level4)
・今ある特定の目的のものが達成できるか？(Level3)
・50年前の過去に持ち帰って広めたい言語は何か？(Level2)
・300年後にタイムトラベルで送り出す人に薦めたい言語は何か？(Level1)

いかがでしたか？

私は、50年前には「go」を持ち帰り、300年後にトラベルするために「ruby」を勉強したい凡人です。

※本記事は「タグ説明」タグを付与した記事です。
https://qiita.com/j5c8k6m8/items/2359627ff8c3778d95f6
webとネットワーク技術 ~TCP/IP ネットワークインターフェース層~

## ネットワークインターフェース層の役割
ネットワークで繋がったハードウェアの同士の通信するためのお約束を定めた層です。このネットワークで繋がったハードウェアとは例えばLANケーブルを指します。

### イーサネット
LANケーブルに関する規格のこと。LANケーブルを繋がった各端末をホストといい、各ホストのもつ一意なIDのようなものがMACアドレスです。このMACアドレスがデータの送信時に必要になってくるものです。

### ARP
IPアドレスもMACアドレスも住所という意味では同じだが、IPアドレスが「最終的な目的地の住所」に対し、MACアドレスが「次の目的地への住所」という違いがあります。MACアドレスイーサネットでデータを転送できますが、データを転送する最終目的地が必要です。このときMACアドレスに対応したIPアドレスを出してくれるのがARPという仕組みです。

### RARP
RARPはARPがIPアドレスをもとにMACアドレスを出しくれるのに対して、RARPは逆でMACアドレスからIPアドレスを出してくれます。ネットワークに参加した段階だとコンピュータは自分のMACアドレスが知っていますが、ネットワーク内の住所であるIPアドレスはわかりません。そこでARAPと使うことでネットワーク内のIPアドレスを入手することができます。
Javaの単体テスト時にログ出力の内容を検査する（モック未使用）

## 概要

単体テスト時にログ出力の内容を検査する（モック未使用）

## 環境

* Java
* slf4j 1.7.26
* logback 1.2.3

## 方法説明

詳細な方法は [サンプルコード](https://github.com/KosigayaSuguru/logging-unit-test/blob/master/src/test/java/logging/mock/MyLoggingTest.java) を参照。

理屈としては、

* テスト開始時にルートロガーに新しく`Appender`を追加する
* この時、追加する`Appender`の`doAppend()`を`override`し、引数として受け取る`ILoggingEvent`を外部スコープのListに`add()`していく
* テストしたい機能が終了した後、Listに入っている`ILoggingEvent`を検査する
* 追加した`Appender`をルートロガーからデタッチする

という流れ。

ルートロガーにAppenderを追加しっぱなしでデタッチしないと、以降のテスト全てのロギングを保持することになるので注意。

## 余談

ルートロガーに追加する前提で書いているが、ロガーを細かく指定して（`getLogger("jp.co.hoge")`みたいな）、そこに`Appender`を追加すればその部分だけログをとることも可能。
Linux/Ubuntu Androidアプリを実機で起動

## はじめに
- Pixel 3aを買ったのでAndroidアプリを実機で起動したかったけどエラーになった
- 初めての作業だったのでメモっておく
- ほぼここに書いてある https://developer.android.com/studio/run/device


## Andoird端末を開発者モード、USBデバッグオンにする
```
- 設定 -> 端末情報 -> ビルド番号 を7回タップして開発者モードを表示させる
- 設定 -> システム -> 開発者向けオプション -> USBデバッグ をオンにする
- USBデバッグ許可のダイアログが出たら許可する
```
ダイアログがでなければUSB抜き差しすれば良さそう

## ルートで以下ファイルを作成する

```
$ sudo touch /etc/udev/rules.d/51-android.rules
# 以下を記述
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev"
$ chmod a+r /etc/udev/rules.d/51-android.rules
```

18d1部分はGoogleのベンダーID、[上に貼ったページ](https://developer.android.com/studio/run/device)に書いてある
Android端末がUSBに繋がっていればlsusbでも確認できる
`18d1:4ee7`この部分の`:`区切り左側の値

```
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1038:137c SteelSeries ApS 
Bus 001 Device 005: ID 0853:0110 Topre Corporation 
Bus 001 Device 004: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 003: ID 18d1:4ee7 Google Inc. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```
Android StudioでDevice選択が対象の端末になっていればRunボタンをクリックで実機でアプリ起動するはず
Android Studioの再起動などがいるかも
Swift の Optional はモナドなの？じゃあ、Optional は Functorなんですよね？

#前置き
Swift の Optional はモナドなんだ！ 
モナド？なにそれ？という好奇心から圏論とHaskellを勉強しだしたら沼でした。。。
モナドはアプリカティブファンクターであり、ファンクターなんですって。
じゃあ、Swift の Optionalはファンクターってことですかい？

#Functor には fmap函数があります
いきなりHaskellの話。Functorとfmapの定義は

```haskell
class Functor f where
  fmap :: (a -> b) -> f a -> f b
```

となっています。この定義を２変数引数の関数として見てみると

+ 第1引数: a の型を取り bの型で返す 関数
+ 第2引数: a に fというファンクターを作用させたモノ
+ 戻り値 : b に fというファンクターを作用させたモノ

と読めます。Swiftだとこんな感じですね

```swift
func fmap<A,B>(_ f: (A) -> B, _ a: Functor<A>) -> Functor<B> {
```

+ 第1引数: A の型を取り B の 型で返す 関数
+ 第2引数: ジェネリクスなパラメータを持った、Functor<A>型
+ 戻り値 : ジェネリクスなパラメータを持った、Functor<B>型

#いつからfmap が２変数関数だと錯覚していた?
Haskell だと 引数が一つの関数とみなすことが容易です

```haskell
class Functor f where
  fmap :: (a -> b) -> (f a -> f b)
```

+ 第1引数: a の型を取り bの型で返す 関数
+ 戻り値 : fa というファンクター を取り fb というファンクターを返す関数

おぉ、a,bが存在する圏の関数（射）から fa,fb の存在する圏へ関数（射）のマッピングにみえる！
これは凄い函手っぽい!! 

Swiftだとこんな感じ

```swift
func fmap<A,B>(_ f: @escaping (A) -> B) -> (Functor<A>) -> Functor<B>
```
+ 第1引数: A の型を取り Bの型で返す 関数
+ 戻り値 : Functor<A> を取り Functor<B> を返す関数

カリー化したって事であってる、、んだと思う

#で、Optional って ファンクターなんですよね？
Optional が Functor だというのならば、fmap が存在するとどうなるのでしょうか

```swift
//２変数バージョン
func fmap<A,B>( _ f: (A) -> B, _ a :  Optional<A> ) -> Optional<B> {
    if let value = a {
        return Optional<B>(f(value))
    }else {
        return Optional<B>(nil)
    }
}

//カリー化したバージョン
func fmap<A,B>( _ f: @escaping (A) -> B ) -> (Optional<A>) -> Optional<B> {
    return { (a: Optional<A>) in
        if let value = a {
            return Optional<B>(f(value))
        }else {
            return Optional<B>(nil)
        }
    }
}

let f = { (a:String) in return a.count }
let optional: String? = "12345"
//２変数関数
print(fmap(f,optional)) //Optional(5)
//カリー化
print(fmap(f)(optional)) //Optional(5)
```

なるほど。この fmap 関数を 中置演算子 map と命名できれば、オプショナルの map 関数も 函手に見えてきますね。ただし引数の順番が逆ですが。

```swift
//haskell
Prelude> let map' = flip fmap
Prelude> (Just 2) `map'` (+2)
Just 4


//swift
Optional<Int>(2) .map {$0+2} //Optional(4)
```

さて、モナドの理解までたどり着けるのか。
Alexaスキル開発 ジャーナリング〜自分と向き合う5分間〜 デザインプロセス　その2

デザインプロセス　[前回](https://qiita.com/toctoc0352/items/d3d4c3a5db92f54a5508)の続きです

* タイトル : ジャーナリング〜自分と向き合う5分間〜
* 概要 : 「5分ジャーナリングテンプレート」からランダムにAlexaが質問する

※[【初心者向け】ジャーナリングを簡単に習慣付けられる7つのシンプルなテンプレート](https://www.lifehacker.jp/2016/06/160622journaling_templates.html)

## 設計指針
[Alexaスキルのデザインプロセス](https://developer.amazon.com/ja/designing-for-voice/design-process/)

## インテントの決定
スキル起動後のユーザの発話を必要としないため、追加のインテントはなし。
以下、アイディアメモ
![写真 2019-05-23 0 00 18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406177/833958b3-cbb9-aea7-6a0e-464911caecf4.jpeg)


## Alexaのセリフ
[前回の台本](https://qiita.com/toctoc0352/items/d3d4c3a5db92f54a5508#%E5%8F%B0%E6%9C%AC%E3%81%AE%E4%BD%9C%E6%88%90)からの変更点
スキル起動後ユーザの発話は不要のため、質問形式ではなく、提案するような形式にした。
参考:[質問によるユーザー発話の方向付け](https://developer.amazon.com/ja/designing-for-voice/what-alexa-says/#%E8%B3%AA%E5%95%8F%E3%81%AB%E3%82%88%E3%82%8B%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E7%99%BA%E8%A9%B1%E3%81%AE%E6%96%B9%E5%90%91%E4%BB%98%E3%81%91)
>ユーザーからの反応が必要な場合、Alexaのセリフは必ず質問で終わるようにしてください

![写真 2019-05-23 0 03 54.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406177/909b7f97-f8b2-c2dd-9f75-8d07d692d177.jpeg)

![写真 2019-05-23 0 05 05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406177/92de336b-9fcb-2a38-b8b5-1f9333214d8a.jpeg)
SwiftプログラミングにおけるGuard構文

## 運命のピラミッド
`If` ステートメントが過度にネストされたコードのこと。 

````swift:運命のピラミッド 
func singBirthdaySong() {
    if isBirthday {
        if guests > 0 {
            if haveCakes {
                print("Happy birthday to you!")
            } else {
                print("We need the cakes!!!")
            }
        } else {
            print("It's just my family.")
        }
    } else {
        print("It's not anyone's birthday...")
    }
}
````
コードを目で追っても、本当に実行したいコードになかなか辿り着かない...。

## Guard構文のキホン
`If` 構文とは制御フローが逆な感じなので、注意。

````swift:guard構文
guard condition else {
    // condition == false の場合に実行したいコード
    // 関数内なら return で脱出できる
}
// condition == true の場合に実行したいコード
````



### 運命のピラミッドをリファクタリング
いわゆる __早期リターン__ な記述になるので、コードが読みやすくなる。

````swift:guard構文
func singBirthdaySong() {
    guard isBirthday else {
        print("It's not anyone's birthday...")
        return
    }

    guard guests > 0 else {
        print("It's just my family.")
        return
    }

    guard haveCakes else {
        print("We need the cakes!!!")
        return
    }

    print("Happy birthday to you!")
}
````

`Guard` 構文によって、本当に実行したいコードが関数定義内の最下部に移動した。
Jetson Nanoの開発環境

# はじめに

Jetson Nanoの開発環境はJetPack SDKと呼ばれ、SDイメージに最初から含まれている。開発に必要となる各種パッケージのバージョンを調べた。

# 一般的な開発用パッケージ

コンパイルを行う際に必要となる一般的な開発用ツール群のバージョンをdpkg -lで確認し列挙した。以下にデフォルトのバージョンとapt update && apt upgrade後のバージョンを列挙した。なんとgccが7系列だった。

| package | default version | version (2019-05-23) |
|----------+----------------+-----------------|
| autoconf | 2.69 | 2.69 |
| automake | 1.51.1 | 1.51.1 |
| binutils | 2.30 | 2.30 |
| bison | 3.0.4 | 3.0.4 |
| flex | 2.6.4 | 2.6.4 |
| gcc | 7.3.0 | 7.4.0 |
| gdb | 8.1 | 8.1 |
| libc6 | 2.27 | 2.27 |
| libtool | 2.4.6 | 2.4.6 |
| make | 4.1 | 4.1 |
| pkg-config | 0.29.1 | 0.29.1 |
| python | 2.7.15 | 2.7.15 |
| python3 | 3.6.7 | 3.6.7 |

# JetPack 4.2 固有のパッケージ

JetPackの説明を読むと「AI開発のための総合的な環境」と書かれている。バージョンを調べると、cuDNNやCUDAは思ったよりは新しいバージョンがインストールされている。OpenCVは4以降からONNXに対応に加え機械学習関連の更新がめざましいので、どこかで4系をインストールした方が良さそうだ。

| JetPack component | version |
|----------+---------|
| TensorRT | 5.0.6 |
| cuDNN | 7.3.1.28 |
| CUDA | 10.0.166 | 
| Multimedia API | 不明 | 
| VisionWorks | 1.6.0.500n |
| OpenCV | 3.3.1 |

# その他

## uname

```bash:ターミナル
yamamo-to@jetson-nano:~$ uname -a
Linux jetson-nano 4.9.140-tegra #1 SMP PREEMPT Wed Mar 13 00:32:22 PDT 2019 aarch64 aarch64 aarch64 GNU/Linux
```

## lsb-release

```bash:ターミナル
yamamo-to@jetson-nano:~$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"
```

# 参考

- https://developer.nvidia.com/embedded/jetpack
- https://github.com/opencv/opencv/wiki/ChangeLog#version400
LaravelのRequestいろいろ

# Requestのプロパティを加工したい
「Modelのミューテータを使えばいいじゃん！」
て言われるかもしれないけどまぁRequestの状態でとりあえず色々やりたいみたいな、ね。
ありますよね。

# プロパティをなかったことにしたい
例えば$request->divisionというプロパティをなかったことにしたい場合はこう。

```.php
$request->offsetUnset('division');
```

フィールド名（文字列）をぶち込めば消えてくれます。
ちなみにunsetしてもだめだったのでこれ一択かと。(というかオブジェクトのプロパティ消すのにunsetは使えないのか？)

# プロパティを上書きしたい
フィールド名をKeyに持つ連想配列で上書きできます。
というか存在しないフィールド名を入れると新たなプロパティが作れちゃいます。

```.php
$request->merge([
    'start_time' => $start.':'.'00',
    'end_time' => $end.':'.'00',
]);
```

replaceなんていうパラメータを一回空にしてからmergeするメソッドもあるみたいですね。（要検証）


# リクエストのパラメータが空かどうか調べたい
2019/7/21追記

例えば、「検索条件なしで検索された時」という判定がしたい時に有用。

```.php
$is_request_empty = !$request->anyFilled(array_keys($request->all()));
```
注意：anyFilledは[Laravel5.6.12](https://laravel-news.com/laravel-5-6-12)から

ラジオボタンなどがある場合はこんな感じでexceptしよう。

```.php
$is_request_empty = !$request->anyFilled(array_keys($request->except('is_include_viewed_person')));
```

# おわりに
Requestクラスの中身のぞいてたんですけどまだまだワクワクするようなメソッドいっぱいありましたので機会があったら随時更新していきます。
年間稼働率と許容停止時間の早見表（概算）

いちいち計算するのは面倒だけれども暗記するものでもないと思うのでアンチョコ化

|年間稼働率|許容停止時間（日）|許容停止時間（時間）|許容停止時間（分）|許容停止時間（秒）|
|:--:|:--:|:--:|:--:|:--:|
|90%|36.5|876|52,560|3,153,600|
|99%|3.65|87.6|5,256|315,360|
|99.9%| - |8.7|522|31,320|
|99.99%| - | - |52|3,120|
|99.999%| - | - |5|300|
|99.9999%| - | - | - |32|
PytorchでCIFAR10のデータセットを扱おうとしたらOMP Errorがでた

[Pytorchのチュートリアル](https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py)をお勉強中に以下のエラーが発生

```
OMP: Error #15: Initializing libomp.dylib, but found libiomp5.dylib already initialized.
```

エラーが発生する該当ソースはチュートリアル内の以下の部分

```python
# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()
```

[ここ](https://github.com/pytorch/pytorch/issues/13806)で報告されているように、

```python

import os

os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
```
を最初に実行しておけばOK。

つまりチュートリアルのソースとしては、以下でOK

```python
import torch
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                         shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()


# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()

# show images
imshow(torchvision.utils.make_grid(images))
# print labels
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

```

終わり
pkg-configを使ってg++でコンパイルできるようになるまで

# 前回の続き
前回のページは[こちら](https://qiita.com/t13m082h/items/2a31f25752802fa29fd3)

こちらでは、opencv4.0をubuntu18.04(LTS)にインストールするまでをやりました

# 今回やること
pkg-configを使ってターミナル上で
```g++ sample.cpp `pkg-config --cflags --libs opencv4` -o sampleB```
でコンパイルできるようにする。

# 内容
前回の記事で、インストール終わりました。
一番のキーは /usr/local/lib/pkgconfig/opencv4.pc
ファイルで
内容は

```:opencv4.pc

Package Information for pkg-config

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv4/opencv
includedir_new=${prefix}/include/opencv4

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.1.0
Libs: -L${exec_prefix}/lib -lopencv_dnn -lopencv_gapi -lopencv_highgui -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_calib3d -lopencv_features2d -lopencv_flann -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir_old} -I${includedir_new}
```

これでターミナルで
```g++ sample.cpp `pkg-config --cflags --libs opencv4` -o sampleB```
と叩いても、

```
Package opencv4 was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv4.pc'
to the PKG_CONFIG_PATH environment variable
```
と出てしまうので
.bashrcファイルへopecv4.pcファイルへのパスをPKG_CONFIG_PATHへ代入。(以下今回での追加分のみ記載)

```sh:.bashrc
export PKG_CONFIG_PATH==/usr/local/lib/pkgconfig
```

これで
```g++ sample.cpp `pkg-config --cflags --libs opencv4` -o sampleB```
でコンパイルできるようになる。

## 以下、ちょっと説明
pkg-configを使わずに直接コンパイルする場合、

```sh
g++ sample.cpp -I/usr/local/include/opencv4 -lopencv_core -lopencv_imgcodecs -lopencv_highgui -o sample
```
と叩いてもコンパイルはできる。
しかし、毎回インクルードするファイルをパスごと打つのはとても面倒なのでpkg-configを使った。
pkg-configの中身
の
`Libs：~`
の中身で
`-lopencv_core -lopencv_imgcodecs -lopencv_highgui `
を置き換え、
`Cflags:~`
の中身で
`-I/usr/local/include/opencv4`
を置き換えている。

# 参考URL
https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html
https://prateekvjoshi.com/2013/10/18/package-opencv-not-found-lets-find-it/
https://ja.stackoverflow.com/questions/53767/macos-c%E3%81%A7opencv%E3%81%8C%E5%AE%9F%E8%A1%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84
https://qiita.com/hsmtknj/items/0f56e3317cd0f2ae056a#%E5%82%99%E8%80%83
AWS CLIの初め方

## この記事の対象開発環境
* macOS Mojave
* AWSコンソール(CLIインストールは飛ばして良い)

## CLIインストール

```
$ python --version
$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-$bundle.zip"

# unzipの-oは自動で上書きする。yum -yな感じ
$ unzip -o awscli-bundle.zip
$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws

$ aws ###説明文が出てきたらインストール完了
```
[公式リンク](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-macos.html)

## 設定
この設定でどのIAMユーザーでawsコマンドを使うかを定義する。

```
# IAM->ユーザー->認証情報->アクセスキーの作成でアクセスキーを発行。
# パスワードが見れるのとアクセスキーがダウンロードできるのは作成時の一回だけなのでダウンロードしよう
AWS Access Key ID:
AWS Secret Access Key:

# awsにログインしている時のurlから取得する。
# urlパラメータのregionに割り当てられている値を入力(東京だとap-northeast-1)
Default region name:

# 特にこだわりが無ければjsonと入力
Default output format:
```

# AWS CLIのユーザー変更
先程の設定だけだとユーザーを変えるのにidとパスワードを変更する必要があるように見えますが、きちんとawsコマンドにはユーザーを複数登録する機能があります。

```
# 表示名の部分はなるべくIAMユーザー名にすること
aws configure --profile 表示名
```
これで上の設定と同じようにすればいいです。
CentOS7のインストール

#CentOS7　インストール画面


1. Install CentOS 7　を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/e359cf3b-768a-804c-10d1-0a1bd31bf306.png)


2. 日本語を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/4aadfa25-e10c-3b0b-4029-63257a4a856d.png)

5. こんな画面になる（隠れている下の方は設定が必要)
最低限はシステムの項目の、「インストール先」と「ネットワークとホスト名」
※ソフトウェアの「ソフトウェアの選択」はデフォの最小限のインストールにしておく（要件などで不要なサービス止めろとかあるので余計なものは入れない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/5333514c-6d20-05a9-b226-d6d70715694d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/581f9036-c7d6-2901-02f9-d27a41d9b269.png)

6. ネットワーク部分の設定（システム項目の「ネットワークとホスト名」を押した状態）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/e31f3734-d516-b2bc-ce13-c20834dd7406.png)



7. ホスト名を入れて適用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/3c3ed0d6-fe68-ad9d-2b4c-5bb71b3c110d.png)


8. IPを設定するので「設定」を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/6a6eadca-bb97-2fdb-f17e-68a071fbd7b4.png)

9. 最低限赤枠部分を入れて保存を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/97900bac-744d-6e99-2b6f-69101b3a07fd.png)

10. オンにして保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/d638d8df-f952-4052-df8d-c66f06547f80.png)

11. インストールの開始
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/f0d87869-a598-a6cc-98bd-46d2a1faf89f.png)

12. rootパスワードを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/9264a11d-3305-00e2-956a-5eb835c2ff5d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/90a33e36-f629-ee36-cb36-db2017991479.png)

13. 再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/8b2a7973-1dda-174a-9869-5506051a06f3.png)

14. あとはお好きなように
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/1228c6b8-ec7d-6a4c-bcea-cd3bffebb758.png)
【VBA】自動ユーザーフォーム起動

##説明
・エクセルファイルを起動したらユーザーフォームのみが表示される
・ユーザーフォームを「閉じる」ボタンで閉じたらエクセルファイルも閉じる

###標準モジュール
```vb
Sub Auto_Open()
    UserForm1.Show
End Sub
```

###UserForm1
```vb
Private Sub CommandButton1_Click()
    Dim wb As Workbook
    Set wb = ActiveWorkbook
    Call wb.Close(True)  ' 変更を保存して閉じる
End Sub

Private Sub TextBox1_Change()
    Call CalculateTime
End Sub

Private Sub TextBox2_Change()
    Call CalculateTime
End Sub

Private Sub TextBox3_Change()
    Call CalculateTime
End Sub

Private Sub TextBox4_Change()
    Call CalculateTime
End Sub

Private Sub UserForm_Initialize()
    Application.Visible = False
End Sub

Private Sub UserForm_Terminate()
    Application.Visible = True
End Sub

Private Sub CalculateTime()
    Dim tm As Long
    With UserForm1
        tm = (Val(.TextBox1.Value) - 18) * 60 + (Val(.TextBox2.Value) - 15)
        .TextBox3.Value = Int(tm / 60)
        .TextBox4.Value = tm Mod 60
    End With
End Sub
```
###画像1
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404228/d8f15dd0-b790-2918-c78b-b9efc641d63c.png)

###画像2
![無題２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404228/2c3d1f99-0649-6f67-c67d-6084151cc295.png)

##参考サイト
後日記載
今更ながらcvsのコマンドをgitと比較しながら書いてみる

初投稿です。

会社のバージョン管理でcvsを使っているのでgitと比較しながら備忘録として書いてみる。

cvs checkout -r branch名 リポジトリ名

checkoutというのは、サーバーに保存してあるブランチを自分の物理環境に持ってくること。-rは再帰のオプションなのでbranchにあるファイルを再帰検索して持ってきてるってこと。リポジトリは保管庫のこと。ちなみにcheckoutはcoって簡略化できる。

gitで同じようにサーバーから物理環境へ持ってくるコマンドは

git clone サーバーURL

みたいなのと似てる。

cvs update ファイル群

updateは物理環境のソースコードを最新の状態に更新してくれる。また、

cvs update -j ファイル群

ってやるとトランクにファイル群の差分をマージできる。さらに

cvs update -j タグ名1 -j タグ名2

ってやるとタグ名1からタグ名2までの差分をマージできる。

もう眠いのでとりあえずこの辺で。
ちゃんと書けるように努力します。
php 5.6 から 7.2 に上げ phpunit を動かす

php7.2, zend で phpunit 

php 5.6 の時に動いていた phpunit
php 7.2 したらエラーが…(´;◞౪◟; )
https://github.com/sebastianbergmann/comparator/pull/30/commits/f4ec922b3e514ae27d2c9693bc68222a93ceab34
> rlerdorf committed on 29 Jan 2017

(7.1 で ArgumentCountErrorの追加があったけどこれは違いそうな…↓だよなぁ…7.2 関係あったのか...?)
http://www.objective-php.net/basic/interface

php 7.2 に互換性がある一番低いものかつ
修正入ってそうなので
phpunit 6 に
>Support ended on February 1, 2019

https://phpunit.de/supported-versions.html

phpunit 6.0 から名前空間化されていて zend 死亡(古すぎぃ…
https://qiita.com/mt-kage/items/7630484c571680df1140

phpunit 5 ならいけるはず (7.2 互換性ないけど...)
修正も入ってるはず
>Support ended on February 2, 2018

https://phpunit.de/supported-versions.html

うっうごいた…( ◜௰◝ )
Mergeノードのような大量INPUTのHoudini Digital Assetを作る

# はじめに

とりあえず、関連するノードはつっこんじゃえ！って感じの、Mergeノード的なDigital Assetを作りたかった。
しかしながら、やり方がわからなかったので調査した。

資料 => [Unlimited inputs - Houdini Digital Asset](https://www.sidefx.com/forum/topic/53416/)

こういうのを作りたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/d1f51e9a-2458-2fbf-8d6e-91cece3d3509.png)

> Houdini 17.5.258


# 統合マルチインプットの作り方

[1] 通常通り、Digital Assetを作成する。

[2] Inputを999などといった巨大な数字にする。（実際は30以上でもMergeノードの様な単一に見えるような感じになる） 
![Screenshot from 2019-05-22 23-49-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/5a4b877f-cdb8-b1ea-dd4a-07d4ee386647.png)



# マルチインプットを統合アウトプットする

Inputの数がダイナミックな増え方になるので、まともにSubnetデフォルトのINPUTノードは使えない。
なので、回避策を使う。

[1] 中に次のような構造を作る
![Screenshot from 2019-05-22 23-55-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/1330749c-99a8-ee3f-e760-ea9988bc297c.png)


[2] Block End SOPのIteration Methodを `By Count` 、Gather Methodを `Merge Each Iteration` に設定する。

[3] Block End SOPのIterationsには次のスクリプトを入力する。
これで入力数がダイナミックに入る様になる。

```shell
opninputs('../')
```


[4] Object Merge SOPのObject1には次のスクリプトを入力する。
これでFor Eachのイテレーションごとに入力が切り替わる。

```shell
`opinputpath('..',detail('../foreach_count1','iteration',0))`
```

[5] 結果をアウトプットする

![Screenshot from 2019-05-23 00-06-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/d630742d-2ed1-89d4-4127-45b63e0c8b13.png)



# まとめ

この手法を使うことで、ひたすら大量にINPUTにつないだものをスクリプト側で処理したりといった仕組みを組める。（「限界x個までしか繋げない」とか意識しなくていい）
Merge SOPよりもより柔軟にINPUTを吸収できるということで、結構色んな所に使えそう。
ただ、3個くらい繋いでおいて、後から2個目のもののノードの接続を切ってみると、2個目のものが空のまま残ってしまうといったこともあったので、ここは何かしらの対応が必要っぽい。良い案あったら教えてください。
CameraXのCodelabs試してみた

# 概要
I/Oで発表があったCameraX。Codelabsで公開されていたものを試してみました。ちょっとハマったとこがあったので、メモがてら書いておきます。
[Getting Started with CameraX](https://codelabs.developers.google.com/codelabs/camerax-getting-started/index.html#0)

というのも、[I/O Extended 2019 Tokyo@GDG](https://gdg-tokyo.connpass.com/event/128867/) にてCodelabsの課題が上がっていたからです笑
当日はセッションに興味がありCodelabsには参加しませんでしたが、また機会があれば参加してみたい。

# 実装の流れ

実際のCodelabsをみてもらえたらいいと思うんですが、簡単に流れを書いておきます。Codelabsのセクションとはちょっと変えてます。

1. CameraXをgradleに追加
2. view finder layoutを準備
3. Cameraのパーミッションを付与
4. Permission許可&チェックのコードを記述
5. view finder(use case)を実装
6. image capture(use case)を実装
7. image analysis(use case)を実装

# ポイント
- use caseを作る。
  - Preview(view finder): プレビュー
  - ImageCaputure: 画像保存
  - ImageAnalysis: 画像解析

- 作ったuse caseを、`CameraX.bindToLifecycle(this, preview, imageCapture, analyzerUseCase)` でlifecycleOwner(Activity)にbindする

# ハマったところ
プレビューが縦に潰れる。。

```kotlin:before.kt
val previewConfig = PreviewConfig.Builder().apply {
        setTargetAspectRatio(Rational(1, 1))
        setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
    }.build()
```

**アスペクトをが1:1で設定しているのに、プレビューが縦に崩れる**。。。


結局崩れるのはなぜかわからなかったんですが、[公式のサンプル](https://github.com/android/camera/blob/master/CameraXBasic/app/src/main/java/com/android/example/cameraxbasic/fragments/CameraFragment.kt#L251)
の通りに実際のViewのディスプレイサイズを取得し設定したら治った。 

```kotlin:after.kt
val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)
val screenSize = Size(metrics.widthPixels, metrics.heightPixels)

val previewConfig = PreviewConfig.Builder().apply {
        setTargetAspectRatio(screenAspectRatio)
        setTargetResolution(screenSize)
    }.build()
```

Capture時に保存された画像は正常だったところを見ると、Viewに反映される際になにか問題があるのかも。時間が許せばもっと探ってみようかな。。

# 所感
lifecycleにbindでき、自分で面倒を見ないでいいのがすごく楽だと感じました。
もうすこしドキュメント見て、触ってみようと思えました。
Windows Server でファイルサーバ　移行編（Active Directoryなし）

# Windows Server でファイルサーバ　移行編（Active Directoryなし）
ActiveDirectory環境・Windows Server 2012以降であれば便利なものがあるが、
WORKGROUP環境でOSの標準的な機能でやろうとすると何かと大変

今回はWindows Server 2008　→　Windows Server 2016でやってみます

## 共有設定
ググると既に配布終了したものなどが紹介されているページがあるが、
今回はOS標準であるものを使ってやろうと思います
【結果】
　→手動で作成・設定

## データ

 - 移行元
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/d98dbbff-fe9a-3cc5-e179-3d352b46dde0.png)


 - 移行先
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/3cdb87d9-9f00-3197-b45d-743e628bd259.png)

 - Robocopyで実施（移行先で実行）
こんな感じで何度かに分けてデータコピーするなら、バッチにしといたほうが楽ですね
1回目（どこかで全コピー）
↓
2回目（差分を同期）
↓
3回目（切り替え日に最後の差分同期）

```
C:\Users\Administrator>robocopy "\\***.***.***.***\a" "C:\share\b" /MIR /COPY:DAT /R:0 /W:0 /NP /V /LOG+:C:\robolog.txt

 ログ ファイル: C:\robolog.txt

C:\Users\Administrator>
```

## Robocopyで注意
/COPYを/COPYALLとすると、移行元・移行先に同じ名前のユーザーを作ったとしてもお前誰だ！となるので注意が必要 

- 移行元
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/92a165e1-70a0-fc18-7626-8177ed58f44b.png)




- 移行先

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/d5f1d5fc-6859-c11b-d25c-049283d6cc25.png)
アレクサでリストに項目を繰り返し追加する方法

##　ニーズ

何かを初めてから習慣化するまでには三ヶ月ほど時間がかかるといいますが、
習慣化されるまでの間は日々、何をするんだっけということを思い出すためにコストが掛かってしまいますし、
うまく思い出せないこともあると思います。
そんな時のために、やりたいことをリストに繰り返し載せて、それらを毎日なり、毎週なりで消化させていくことで、
習慣化させることができます。

**が、**

それらを毎日リストに追加するのは面倒だし
アプリで自動生成させると、アプリを開くのが面倒だし、
あとなにが残っているんだっけ？と調べるのも面倒なので、

**これらをアレクサに自動化させることを考えました。**

##　利用する技術

簡単に説明すると、Todoistをアレクサと連携させて、
Todoist側に日々のリストを追加させて、それらをアレクサのリストに追加させました。

##　どうやったのか

アレクサでTodoistのスキルを検索し、追加と管理をさせます。
Todoist側と連動するリストは、Inboxとアレクサのショッピングリストになります。
なので、Todoist側でやりたいこと、買いたいものに、定期的にしたいことを追加すれば完了となります。

アレクサにやりたいことのリストを教えてと言えば、日々の作業と、何を完了してて、何が残ってるのかがわかるようになります。

##　感想

画像や、詳細な説明は後ほどの課題としておきます。
とりあえず毎日の繰り返しはできているので、あとは月イチで買うものとか、週一でやることなどを
自動リスト化したいと思います。
Spotを使ってると字で見れるし、手で完了したものを消せるので便利ですよ。
[JavaScript]pushメソッドの返り値は新しい配列の要素数

とあるfor文を書いていて、配列の要素を返したい時に、arr.push(i)をreturnしたらうまく返せなかったのでめも。

```js
arr = []

for(let i = 10; i >= 0; i--) {
  arr.push(i)
}

console.log(arr)
// => [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

console.log(arr.push(11))
// => 12
```

上記のように、ES6でpushメソッドを使用した時の返り値は、新しい配列の要素ではなくて、新しい配列の要素数を返す。

参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/push
Flaskで簡単アプリケーション構築

# はじめに
この記事ではFlaskでアプリケーションを立ち上げ、**Flaskマスターに俺はなる！**と画面に表示することを最終目標としています。


# 開発環境(前提条件)
・python3.7.3(筆者のpythonバージョンです)
・pipコマンドが使える
・mac

もし、python3系をインストールしていない場合は
https://qiita.com/nissynishizawa/items/1b2cfb6c4e4518185276
この方の記事を参考にpyenvというパッケージ管理ツールをインストールしpythonのバージョンを変更してください。


## フォルダの構成
今回作るアプリのフォルダ構成です！

```
Flask
├── Pipfile
├── Pipfile.lock
├── flask_box
│   ├── __init__.py
│   └── views.py
└── server.py
```

## PipenvとFlaskのインストール
PipenvはPythonのパッケージングツールで、簡単に仮想環境を用意できるありがたいツールです。

それでは、早速インストールしてみましょう！
以下のコマンドをターミナルで実行してください。

```
pip install pipenv
```

インストール後に

```
pipenv --version
```
と実行しバージョンが表示されたら成功です！

では、次に仮想環境の準備をしていきましょう！
まずは、Flaskというフォルダを作成してください。作成できたらFlaskフォルダ内に移動し、以下のコマンドを実行してください。

```
pipenv --three
```
このコマンドは仮想環境を用意するためのものです、実行すると「Pipfile」が作成されていると思います。
仮想環境ができたので、早速中に入ってみましょう！
以下のコマンドを実行してください。

```
pipenv shell
```
このコマンドを実行することで、仮想環境が動きます。ターミナルのuser名の左側に(Flask)と表示されていたら成功です。

ここまで完了したら、Flaskのパッケージをインストールします。
以下のコマンドを実行してください。

```
pipenv install Flask
```

インストールに成功すると、「Pipfile.lock」が作成されていると思います！


## アプリケーションの作成
仮想環境を作成できたので、ここからはviewに文字を表示するためのプログラムを書いていきましょう！

まずは、サーバーを立ち上げるためのファイルを作成します。Flaskフォルダの直下にserver.pyというファイルを作成してください。作成したら以下のように記述してください。

```server.py
from flask_box import app

if __name__ == '__main__':
  app.run(debug=True)
```
簡単に説明をします。「from flask_box import app」で、flask_boxフォルダ内のappというモジュールをこのファイルで使わせてくれ〜とお願いをして、「app.run」でアプリケーションを立ち上げてーと命令していると思ってください。「debug=True」はデバッグモードを有効にするという意味です。

サーバー起動用のファイルを作成したので、次はviewファイルを作成していきましょう！
Flaskフォルダの直下にflask_boxというフォルダを作成してください。作成したら、flask_box内に移動し、

```
__init__.py
```
というファイルを作成し、以下のように記述してください。

```flask_box/__init__.py
from flask import Flask

app = Flask(__name__)

import flask_box.views
```

これも簡単に説明すると、Flask本体を使えるようにimportして、appという変数にアプリケーションの核を入れ、flask_box内のviewsファイルを読み込めるようにしておいて〜と指示している感じです。

ここまで完了したら、viewファイルの作成に入りましょう！
flask_boxの直下にviews.pyというファイルを作成し、以下のように記述してください。

```flask_box/views.py
from flask_box import app

@app.route("/")
def index():
  return "Flaskマスターに俺はなる！"
```
ここではルーティングの設定をしています。
書いている内容は、アプリケーションを立ち上げたらindexメソッドを実行してviewに表示してーといった感じです！


これで準備は整いましたので、最後にサーバーを起動してみましょう。
以下のコマンドを実行してください。
(一つ注意ですが、このコマンドはFlaskフォルダに移動してから実行してください。flask_box内で実行すると「No such file or directory」といったメッセージがでてしまいます。)

```
python server.py
```

サーバーの起動に成功すると、このようなメッセージが表示されると思います。

```
 Serving Flask app "flask_box" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production 
   deployment.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
```
最初は赤文字でびっくりすると思いますがエラーではないので大丈夫です↓
<font color="Red">WARNING: This is a development server. Do not use it in a production deployment.</font>

最後に、以下のurlをGoogleに貼り付けてEnterを押してください。

```
http://127.0.0.1:5000/
```

画面に**Flaskマスターに俺はなる**と表示されていたらアプリの完成です！


## おわりに
ここまで読んでいただきありがとうございます。間違い等がありましたらご指摘いただければ幸いです。

参考文献
<a href="https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89Flask%E3%81%8C%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8B%E6%9C%AC-%E6%9C%AC%E7%94%B0%E5%B4%87%E6%99%BA-ebook/dp/B07F2X9GRQ">ゼロからFlaskがよくわかる本: Pythonで作るWebアプリケーション開発入門</a>