OmniAICreator/Qiita-1.07M huggingface dataset:
Macってなんで目覚ましついてないの？【Youtube自動再生目覚まし in Mac】

# Macに目覚まし機能がないので純正機能AutomatorでYoutube目覚ましを作る
こんな機能あったんだって感じ

## ある日
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/5f6c93ac-5b68-9dc0-590d-3029c90a8494.png)

## え？
どうやら最近の（昔はしらんけど）Macにはアラームやタイマー、**iPhoneの「時計」に準ずる機能が無い**みたいです。
#### でも目覚ましかけたい。起きたい。

## Automator
皆さん、Siriショートカットという最近のiOSに搭載された便利アプリをご存知でしょうか？
様々な行動やトリガーを組み合わせてマクロ的な事ができたりオートメーションが出来たりする使い方によっては大変便利なアプリです。

実はそのSiriショートカット、Macにはだいぶ前からAutomatorという名前で似たようなものが搭載されているらしいです！

### Automatorで出来ること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/9ee194e5-907f-07db-a4cd-b31343f95492.png)
何でもできそうです。アプリやブラウザの操作はもちろん、JSやAppleScriptの実行なども出来るみたいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/97ac8a7e-4951-9c09-db1f-3804069d6472.png)
この辺を使えば軽いプログラムのようなものも作ることができそうです。

## Automatorを使ってYoutube目覚ましを作る
AutomatorはSpotlight検索でAutomatorと入れれば出ます。

今回は時間主導で起動したいので、Automator -> 新規作成から「カレンダーアラーム」を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/04342bc0-ad25-f2f8-67ab-97372e04de80.png)
ここにアクションを追加するのですが、今回は③つ追加します。左のリストから追加したいものを右にドラッグ＆ドロップすることで追加できます。

#### ユーティリティー -> コンピューターの音量を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/fc29b97a-6db5-0092-b90e-9eff0f97a057.png)
音が小さいと起きれないのでここでPCでの音量を強制的に上げましょう。

#### インターネット -> 指定されたURLを取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/52a306c3-ecd1-87a2-2b74-743dea551129.png)
ここに流したい音楽のYoutubeのアドレスを貼り付けます。

#### インターネット -> Webページを表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/19396733-7f75-d617-e9f1-752fbc134ab3.png)
最後にURLのページを表示します

これで、タスクは完成したのでテストしてみましょう。右上の実行ボタンを押してブラウザでYoutubeが開いたら成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/ebbae422-fa95-ec84-1a7c-2e5304267880.png)

### 時間主導で起動できるようにする
上記で作ったタスクにわかり易い名前をつけて保存します。

続いてカレンダーを開いて起動したい時間に予定を入れます。繰り返しても大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/57ada9ff-39b3-5374-bb32-903914c7a5f3.png)

ここからがポイントなのですが、カレンダーの通知でカスタムというところを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/6a1684a2-72c2-01bb-0dfb-17bf0f81ede4.png)

3つ選ぶところが出てくるので、1つ目でファイルを開くを選び、2つ目でその他を選びます。その他を選ぶとFinderが表示されるので、先程保存したタスクを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/5c35d3ae-8351-0b6e-d963-b228c773d331.png)
先程保存したファイルは `/Users/username/Library/Workflows/Applications`に保存されています。FinderでLibraryが表示されていない人は`Command + Shift + G`を押して `~/Library`と入力して移動しましょう。僕はここに移動できずに10分無駄にしました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/806abea0-ae4f-4708-255a-e1d29fafc221.png)

通知タイミングをイベントの開始時刻に設定すれば完了です！
これで指定時刻にYoutubeが爆音で流される目覚ましが完成しました。

**くれぐれも二度寝をしないようにしましょう**
redashのパラメータで全選択を可能にする

redashでフィルターを作成する際にパラメータを利用しますが、フィルターを利用したい場合と利用したくない場合があり、同一クエリーでフィルターを無効にする対応が必要なりました。
そこで下記のような対応をとりました。

```
SELECT
 *
FROM
 data_table
WHERE
 p_id = 
  CASE WHEN '{{p_id}}' = 'ALL' THEN p_id
       ELSE '{{p_id}}'
       END
```
パラメータ`p_id`に`ALL`を指定した場合は実質フィルターなし（全選択）の状態になります。
※`p_id`の値に`ALL`が存在しない場合に有効な方法となります。
Vueのpropsで描画が変わらない時

あれ？変わらない、おかしいな？ってなったのでメモ

## 公式に書いてた

>Vue は、配列における次の変更は検知できません:

>インデックスと一緒にアイテムを直接セットする場合、例えば `vm.items[indexOfItem] = newValue`
配列の長さを変更する場合、例えば `vm.items.length = newLength`

https://jp.vuejs.org/v2/guide/reactivity.html#%E9%85%8D%E5%88%97%E3%81%AB%E9%96%A2%E3%81%97%E3%81%A6

まさにこれをしていたので、親コンポーネントで

```js
this.items[0] = true
```

↓

```js
this.$set(this.items, 0, true)
```

これで反映されました。
vue.js elementui input 配列で動的に追加

inputフィールドを動的に追加したい。
その時の考え方。
component化することが大切。


```main.vue

<template>
    <div>

        <el-form :model="form" :rules="rules" ref="form">

            <InputComponent
                    v-for="(v,key) in form.url"
                    :key="key"
                    v-model="form.url[key]"
                    placeholder="ここにサンプル"
                    name="body"
                    @blurData="blurData"
            ></InputComponent>

            <div style="text-align: right;">
                <el-button @click="addHairetu">さらに追加</el-button>
            </div>

        </el-form>

    </div>
</template>

<script>
    import InputComponent from "./InputComponent";

    export default {
        components:{
            InputComponent
        },


        data () {
            return {

                form: {

                    url: ['https://love-letter.club/to/amichan_555/','ほげらま'],
                },
                rules: {
                    name: [
                        { required: true, message: '名前を入力してください', trigger: 'change' }
                    ]
                }
            };
        },



        methods: {

            blurData(e){
                console.log(e.target.value);//フォームの中身を取得
            },

            addHairetu(data){
                this.form.url.push('');
                return data;
            },




        }
    }
</script>


```


```InputComoponent.vue

<template>

    <el-input
            :name="name"
            :value="value"
            :placeholder="placeholder"
            @input="updateValue"
            @blur="blurValue"

    >
    </el-input>



</template>

<script>
    export default {
        name: "InputComponent",
        props: {
            value: { type: String, require: true },
            name: { type: String, require: true },
            placeholder: { type: String, require: false },
            cols: { type: Number, require: false }
        },
        methods: {
            updateValue(e) {
                //親メソッドの input を動かす
                //普通のテキストエリアと違うので注意
                this.$emit("input", e);
            },
            blurValue(e) {
                //親メソッドの blurData を動かす
                this.$emit("blurData", e);
            }
        }
    };
</script>

```
UbuntuにMATLABをインストールする

ある日突然UbuntuにMATLABをインストールしたくなった．
この記事はMATLABをインストールする過程で色々詰まったところがあったのでその解決法と記録．
##1.環境

1.Ubuntu18.04LTS
2.MATLAB(お好きなversion)
3.大いなるやる気

##2.手順
1.自分のほしいversionをMATLABの公式ホームページからインストールしてくる.
参考：偉大なる公式様（https://jp.mathworks.com/downloads/web_downloads/)
ダウンロード先はどこでもいいはず…（多分）

2.自分がダウンロードしたディレクトリに移動する.その後[./install]を実行し，MATLABのインストーラを起動する.
私はホーム直下のDownloadsにダウンロードしたので以下のようになる.

```
~$ cd Downloads/
~/Downloads$unzip "MATLABzipファイル名"
~/Downloads$./install
```
3.インストーラの従って進めていく.
このとき,MATALBをインストールするフォルダを指定する際に「フォルダが無いよ」的なエラーが出る場合がある．
そのときの対処法はMATLABQ&A( https://jp.mathworks.com/matlabcentral/answers/478492-linux-os-ubuntu )に載っている以下のコマンドを実行すれば治る．

```
sudo mkdir -p /usr/local/MATLAB/(好きなversion)
sudo chmod 777 /usr/local/MATLAB/(好きなversion)
```
また，UbuntuはWindowsのようにショートカットを作成してくれないので，シンボリックリンクを貼る必要がある．
初期は/usr/local/binに設定してあるのでそのままシンボリックリンクを使えばいい．
このとき，「そこにフォルダは作れないよ！」と怒られる可能性がある．
そのときは/usr/local/binが管理者権限になっていてMALABがアクセスできないので，

```
sudo chmod 777 /usr/local/bin
```
でアクセス権限をフリーにすれば実行すればいける．
以上でUbuntuにMATLABをインストールする方法の解説を終わる．

##3.偉大なる参考文献様
1.「パーミッションなどを設定する！chmodコマンドの詳細まとめ【Linuxコマンド集】」
（https://eng-entrance.com/linux-command-chmod)
2.「MATLAB Answers~LINUX OS(Ubuntu) のインスール時のフォルダー指定について~」
(https://jp.mathworks.com/matlabcentral/answers/478492-linux-os-ubuntu)
macのpythonが行方不明になったら


事象

```ruby
me@local:~/repos/aaa$ pipenv install
-bash: /usr/local/bin/pipenv: /usr/local/opt/python/bin/python3.7: bad interpreter: No such file or directory
```

brewでなんか入れた時にpythonが3.8になって、3.7.7が `/usr/local/bin` から消えてしまたt。


 /usr/local/bin/python*

```ruby
me@local:~/repos/aaa$ ll /usr/local/bin/python*
lrwxr-xr-x  1 me  admin    39B Apr 30 17:46 /usr/local/bin/python-build@ -> ../Cellar/pyenv/1.2.18/bin/python-build
lrwxr-xr-x  1 me  admin    40B Jul 13 12:09 /usr/local/bin/python3@ -> ../Cellar/python@3.8/3.8.3_2/bin/python3
lrwxr-xr-x  1 me  admin    47B Jul 13 12:09 /usr/local/bin/python3-config@ -> ../Cellar/python@3.8/3.8.3_2/bin/python3-config
lrwxr-xr-x  1 me  admin    42B Jul 13 12:09 /usr/local/bin/python3.8@ -> ../Cellar/python@3.8/3.8.3_2/bin/python3.8
lrwxr-xr-x  1 me  admin    49B Jul 13 12:09 /usr/local/bin/python3.8-config@ -> ../Cellar/python@3.8/3.8.3_2/bin/python3.8-config
```

なんとなく直った

```ruby
pyenv install 3.7.7
pyenv global 3.7.7
brew uninstall pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
pip uninstall pipenv virtualenv
pip install pipenv


```
よくわからんがこんなんで直ったぽい。python難しい

brewで入れるpipは、pythonをちゃんと探さないんだか、前にあったものの場所を覚えてるんだか。

pip/pipenv/virtualenvが使うpython pathってどうやってかえるんだろ。
CakePHP3.8 と Laravel7.x の「書き方」の違い ~設定まわり編~

# CakePHP3.8 と Laravel7.x の「書き方」の違い~設定まわり編~

前: [インストールとマイグレーション](https://qiita.com/yokocho-comachi/items/4af2ab02953935f5c214)
次: [ORMまわり](https://qiita.com/yokocho-comachi/items/30330f24dbdcc0c03720)

## php での設定

* Cake  
`APP/config`の中に `*.php`を置く。勝手には読んでくれない。
(bootstrap かなんかで、`Configure::load({ファイル名})`する必要がある)

* Laravel  
`APP/config` の中に、`*.php`をおけば勝手に読んでくれる。

## 環境変数

* Cake
特に設定できない(dotenv を追加で入れるか、サーバーで設定する必要がある)

* Laravel
dotenv が最初から入っているため、`APP/.env`で環境変数の設定ができる

## 設定のキャッシュ

* Cake
キャッシュされない

* Laravel
キャッシュされるので、更新するたびにキャッシュも更新しなければならない(dotenv で設定した環境変数もキャッシュされる)
(`php APP/artisan config:cahe`)

## コードの中での読み込み方

* Cake
`\Cake\Core\Configure::read({ドット記法})`

* Laravel
`config({ドット記法})`

## コードの中での書き込み方

* Cake
`\Cake\Core\Configure::write([{キー} => {値}])`

* Laravel
`config([{キー} => {値}])`
いまさらだけどSubversionからGitへ移行する（その3: SVN Rev）


先日、こちらの記事を書きました。

[いまさらだけどSubversionからGitへ移行する（その1: リポジトリー変換）](https://qiita.com/hkato/items/1b092bff149b13f77505)
[いまさらだけどSubversionからGitへ移行する（その２: プロジェクト・ディレクトリー分割）](https://qiita.com/hkato/items/d0428b53d2665985ed54)

今回はその続きで [SVN リビジョン](http://svnbook.red-bean.com/en/1.7/svn.basic.in-action.html#svn.basic.in-action.revs)をどう Git にマッピングさせるか。移行したプロジェクトの一部では SVN Rev をバージョン表記に適用しているので、これをどうするべきか。

## SVN のリビジョンのバージョン表記への利用

Git ネイティブなヤング達はご存じない方も既にいるだろうが、`r1234` なんてのがバージョン表記に現れたりしているやつです。

Git で運用しているプロジェクトだと SHA1 ショートハッシュから…。

```sh
$ git rev-parse --short HEAD
b34f896
```

この値を　`version 1.2.3-b34f896` などするものをよく見かけるはずです。それの SVN でよく利用されていた版です。

手元の Linux 系 OS でパッケージ一覧表示してみると gitXXXXXX とか rXXXX svnXXXX ってやつがあると思いますが、それ。

```sh
$ # CentOS/RHEL
$ yum list
...
$ # Debian/Ubuntu
$ apt list
...
```

### SVN Rev 実使用例

たとえば、Subversion 自体のバージョン表記がこれなので、手元の SVN がインストールされている環境で version を確認してみると…。

```sh
$ svn --version
svn, version 1.10.4 (r1850624)
```

余談ですが、Redmine の [SVN リポジトリー https://svn.redmine.org](https://svn.redmine.org) 2020-07-16 現在は `Powered by Subversion version 1.6.6 (r40053).` となんだか古いですね。新しいものを利用すれば良いってものでもないですが、 redmine.org 自体ドッグフーディングもせず、古い Redmine アプリケーションで運用している様だしなんなのでしょうね。

### 移行で困る点

`Version ${major}.${minor}.${tiny}.${revision}`

バージョン表記が上記のように、上位の部分は任意の値を開発者が付与するものとして、最終の revision 部分をこの SVN Rev から取得している場合。

- SVN の特徴でもある Revision 値がインクリメンタルであることを前提としている
- SHA1 hash の様なアルファベットを含む値では稼働（ビルド）できない (.NET Assembly など)
- 政治的な理由で数値のままにしたい

## 対応

### Linux/UNIX などの shell 環境

wc と sed とを組み合わせてそれまでのコミット回数をカウントするという方法がよく利用される模様。

```sh
$ git log --oneline | wc -l | sed -e "s/[ \t]*//g"
1234
```

参考: [Git で SVN みたいなリビジョン番号を取りたい - トリの部屋](https://toris.io/2014/07/git-revision-number-like-svn/)

### Windows cmd 環境

上記の wc+sed の例はよく見かけるので知っていたのだが、Windows 環境のプロジェクトもあるのでこれをどう対処したか。

```batch
C:\Work\proj> git log --oneline | find /v /c ""
1234
```

こんな感じで空文字にマッチしない行数をカウントとすればよい。

### Windows PowerShell 環境

```powershell
PS C:\Work\proj> (git log --oneline).Length
1234
```

cmd よりもシンプルにできた。私はとりあえず `find` で実現してしまったが、こちらに移行するかも。

## つづく

上記で少し触れたが、 .NET Framework 環境のプロジェクトも移行させ AssemblyVersion をどうするか検討したので、その点について書くかもしれない。
Flutterもう一度触り始めた #Day2

## Day2
The Complete 2020 Flutter Development Bootcamp with Dart
Section2 ~ Section3

## Dart Reformat
use Cmd+Alt+L (on Mac)
https://flutter.dev/docs/development/tools/formatting#automatically-formatting-code-in-android-studio-and-intellij


## Widget
画面に表示するものは全てwidget
真ん中に配置するのもwidget

## yamlファイル
pubspec.yaml
の中のindentationは2

例
Parents
●●Children

## アイコンの入れ方を忘れた時
29. How to add App Icons to the IOS and Android.
50歳を超えてFlutterアプリ開発に挑戦


#Flutterアプリ開発も初めてですが、Qiitaも初投稿です。
早いもので、この業界に入って約３０年。とはいえ、最近は自分一人でアプリを作る事も無かったんですが、社内のイベントがあるとの事で参加を表明。約１０年ぶり？（もっとか？）に新規アプリをこっそり自分一人で作っています。今回使う言語(Flutter)も含め、色々と初めてという事でお見苦しい点が色々あると思いますがお許しください。

という訳で、最近の潮流と言うか、お作法とかさっぱり知らない中でのプログラミングに悪戦苦闘しながら進めていますが、ちょっと動くようになってきたので内容は薄いですがメモに残してみました。

### 何度も使いそうなスタイルとかはまとめて書いた
当然と言われるとそうなのでしょうが、まずFlutterではWidgetを組み合わせて画面を作成するのですが、その中で使用する文字とかもいちいち色がどうとかサイズがどうとかをツリー構造で書いていくのでネストがえらい事になって来る。私のようなおじいちゃんの老眼では正直見えない！解らん！となるので、昔で言う関数のような書き方で部品として使えるようにしてみました。

### ボタン上に表示するテキストで使う時用のスタイル定義
```dart

  final btnTextStyle = TextStyle(
      fontSize: 36.0,
      fontWeight: FontWeight.bold,
  );
```
初めて見る人でも何となくイメージは解ると思いますが、これは部品の名前を`btnTextStyle` とし、`TextStyle`としてフォントサイズは`36.0`、`fontWeight`は`bold`というコンスタント値にしています。例えば、２個以上のボタンがある時にスタイルを揃えて定義するとかに使えます。

### 実際にボタンWidgetでスタイルを使ってみる
```dart

  Widget _damageButton(damage) {
      return RaisedButton(
          padding: EdgeInsets.only(left: 0.0, top: 30.0,
                                   right: 0.0, bottom: 30.0),
          color: Colors.black,
          shape: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.white),
              borderRadius: BorderRadius.all(Radius.circular(5.0)),
          ),
          onPressed: () => calculate(damage),   // 押されたボタンに応じたダメージ計算処理
          child:ShaderMask(       // 炎っぽく表示してみる
              blendMode: BlendMode.srcATop,
              shaderCallback: (bounds) {
                  return RadialGradient(
                      center: Alignment.topLeft,
                      radius: 1.0,
                      colors: [Colors.yellow,
                               Colors.deepOrange.shade900],
                      tileMode: TileMode.repeated
                  ).createShader(bounds);
              },
              child: Text(
                  "$damage",
                  style: btnTextStyle,
              ),
          ),
      );
  }
```
コードが長いですが、今回の記事とはほとんど関係無いので詳細は省きます。試行錯誤中なので不要なコードもあるかも知れません。

一番下の行で`style: btnTextStyle,`を使っている所が先ほどのスタイルを定義したところです。こんな感じでちょっとした事でもネストして書いていくので可読性がすぐに下がって来ますので、こまめに部品化して外に出して行かないといけないのかなと勝手に思っています。

###### ShaderMaskの部分だけちょっと解説
`child:ShaderMask`のあたり、ぶっちゃけ機能には全く関係ないのではありますが、作っていると装飾するのが楽しくなってどんどんコードを書いていくので注意が必要です（笑）
この炎っぽいテキストはサンプルだと`blendMode: BlendMode.srcATop`が無かったのですが、これ書かないとうまく表示されませんでした。

### さきほどのボタンを３つ横に並べるウィジェット
```dart

  Widget _buttonArea(damage1, damage2, damage3) {
      return Container(
          margin: const EdgeInsets.fromLTRB(1.0, 1.0, 1.0, 1.0),
          child: Row(
              children: <Widget>[
                  Expanded(child: _damageButton(damage1)),
                  Expanded(child: _damageButton(damage2)),
                  Expanded(child: _damageButton(damage3)),
              ]
          ),
      );
  }
```
次に、先ほどのボタンを更に部品として使い、ボタンを３つ横に並べたウィジェットを書いてみます。ボタンを部品化したのですっきり書けました。

こんな感じでどんどん組み合わせたウィジェットを書いて、最後に一番親となるウィジェットを書くとアプリが完成します。

###最後に
覚える事も多いですが、やっぱりプログラミングは楽しいですね。
今後もできればプログラミングを続けて行きたいな～。
ローカルの CentOS 6.x を EC2 にもっていき AWSCLIを使えるようにする

# はじめに
https://qiita.com/bakachou/items/38d9ef670e25e80e38b0
こちらで ローカルにあるVMを EC2へもっていったが、この OS に AWSCLI を入れるときに難儀したのでメモを残しておく


# 事前準備
まずは必要なRPMパッケージをインストールしておく

```bash
yum -y install epel-release
yum -y install python-pip
```



# 問題

CentOS 6.x 系では python が2.x 系なのでAWS CLIをインストールするため準備しようとするとエラーになるので 3.x に上げないといけない

以下のように pip をアップグレードしようとするとエラーになる。

```bash
# pip install pip --upgrade
Traceback (most recent call last):
  File "/usr/bin/pip", line 7, in <module>
    from pip._internal.cli.main import main
  File "/usr/lib/python2.6/site-packages/pip/_internal/cli/main.py", line 10, in <module>
    from pip._internal.cli.autocompletion import autocomplete
  File "/usr/lib/python2.6/site-packages/pip/_internal/cli/autocompletion.py", line 9, in <module>
    from pip._internal.cli.main_parser import create_main_parser
  File "/usr/lib/python2.6/site-packages/pip/_internal/cli/main_parser.py", line 7, in <module>
    from pip._internal.cli import cmdoptions
  File "/usr/lib/python2.6/site-packages/pip/_internal/cli/cmdoptions.py", line 107
    binary_only = FormatControl(set(), {':all:'})
```

原因は Python 2.x だから

```bash
# cat /etc/redhat-release
CentOS release 6.10 (Final)

# python -V
Python 2.6.6

# rpm -qa |grep python-2.6.6
python-2.6.6-68.el6_10.x86_64

```

# Python のアップデート

以下の手順でアップデートする。

```bash
git clone git://github.com/yyuu/pyenv.git ~/.pyenv
```

~/.bash_profile に以下を追加する (pyenv コマンドを実行できるようにする）

```bash
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

Python 3.6.7をインストールするのだが、いくつか必要なライブラリがあるのでインストール

```bash
yum -y install zlib*
yum -y install openssl*
```


Python 3.6.7 をインストール

```bash
pyenv install 3.6.7
Downloading Python-3.6.7.tar.xz...
-> https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz
Installing Python-3.6.7...
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
WARNING: The Python sqlite3 extension was not compiled. Missing the SQLite3 lib?
Installed Python-3.6.7 to /root/.pyenv/versions/3.6.7
```

デフォルトのpython を3.6.7に変更

```bash
pyenv global 3.6.7
```

# pip のアップデートと AWS CLI をインストール
以下の2つのコマンドを実行

```bash
pip install pip --upgrade
pip install awscli --user
```

これで AWSCLIがインストールされる





# 参考
https://qiita.com/kaitaku/items/6aadf1ac2c1f6bea41a8
LLVMでシンボルの接頭辞にアンダースコアをつける方法（leading underscore）

macOSでLLVMを使って言語を作った際、オブジェクトファイルを吐いてリンクしようとすると、以下のエラーが発生した。

```
  "_Unwind_Resume", referenced from:
      f in foo.o
      g in foo.o
  "__gcc_personality_v0", referenced from:
      f in foo.o
      g in foo.o
      Dwarf Exception Unwind Info (__eh_frame) in foo.o
```

どうやら`_Unwind_Resume`と`__gcc_personality_v0`が未定義らしい。しかし、LLVMのライブラリから二つのシンボルを探してみると、存在していた。`/usr/local/opt/llvm/lib`内で`nm libunwind.dylib | grep _Unwind_Resume`を実行すると、以下のように、`__Unwind_Resume`が存在していることがわかる。

```
000000000000be7f S $ld$hide$os10.4$__Unwind_Resume
000000000000be8f S $ld$hide$os10.4$__Unwind_Resume_or_Rethrow
000000000000be80 S $ld$hide$os10.5$__Unwind_Resume
000000000000be90 S $ld$hide$os10.5$__Unwind_Resume_or_Rethrow
0000000000008780 T __Unwind_Resume
0000000000008e70 T __Unwind_Resume_or_Rethrow
```

しかし、よくみると、アンダースコアが一つ多いことがわかる。これはどういうことか。

実は、LLVMを使ってオブジェクトファイルを出力する際、接頭辞のアンダースコアをつけていなかった（接頭辞のアンダースコアをleading underscoreと言う）。このため、ライブラリの方はアンダースコアがついているが、オブジェクトファイルの方はそうでない、という状況になっていた。

LLVMで接頭辞のアンダースコアをつけるには、オブジェクトファイルを出力する際に以下の処理をする必要がある。

```
    TargetMachine *target_machine =
        target->createTargetMachine(target_triple, cpu, features, opt, rm);

    module->setDataLayout(target_machine->createDataLayout());
```

重要なのは、`module->setDataLayout`の部分だ。ここで`module`は`std::unique_ptr<llvm::Module>`の型を持っている。こうすることによって、LLVMが全てのシンボルにleading underscoreをつけるようになる。
GitHubにソースコードをアップロード

# はじめに
以前から自分のポートフォリオや過去の実績のソースコードをアップロードしようと思ってgithubをちょこちょこイジってはいたんですが、ローカル環境からのアップロードの仕方を万が一忘れた時のために備忘録として残しておこうかなと思いまして執筆に至ります。（仮にも自分用です・・・）

## Gitとはなにか？
動画で上がっているので大枠を掴んで実際に手を動かしながら学んだほうが早いかと
[【Git入門】サルでも分かるGit入門の前に！Git使い方高速入門編【入門は5分で十分だと思います】](https://www.youtube.com/watch?v=i1L3A0SLDyg&feature=youtu.be)

## 事前準備
・ Gitをインストールしている（もしまだなら以下の動画を参考に）
①　[【初心者必見】Gitの基本 ](https://youtu.be/cdz-cs_kYto)
②　[Gitを使ったクローン、プルリク、マージの流れについて解説 ](https://youtu.be/JispFS6zeDw)

macの場合はコマンドで"git --version"と叩いて、versionが表示されれば準備OK

## GitHubにアップロードする
### ① GitHubでNew repositoryを作る
![git2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672896/b862a7e9-c0cb-a7c9-fd25-6734879a98c8.jpeg)

### ② Create repository
![git3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672896/8fe72df0-a1c1-5ad5-c3a4-4ed0bdeb5a01.jpeg)

### ③ ターミナルに移動して "cd ｛アップロードしたいファイルの場所｝"を叩く
```
$ git cd {アップロードしたいファイルの場所}
```
### ④ "git init"でリポジトリを新規に作成
```
$ git init
```
### ⑤ "git add ."ですべてのファイルをインデックスに上げる (*addのあとに半角スペース！)
```
$ git add .
```
### ⑥ "git commit -m "~" を叩いて、~に変更内容を書く
```
$ git commit -m "first commit"
```
### ⑦ "git remote add origin [リモートリポジトリ先のURL]" でリモートリポジトリと紐付け
```
$ git　remote add origin https://~~~~
```
### ⑧ "git push -u origin master" でリモートリポジトリにプッシュ
```
$ git push -u origin master 
```
こういう画面から![git4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672896/12f716ff-7532-fef0-090b-a5c8685ff723.jpeg)
⬇⬇⬇
こういう画面に変わっていたら成功
![git1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672896/4c9a065b-5e62-dfa6-ad59-bb4a1db43bd9.jpeg)

## GitHub PagesでURLを作成
備忘録として、GitHub内でURLを獲得するための手順を示しておく
①リポジトリ　▶　Setting
![git7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672896/3d229f4a-5e1f-14de-3f9f-50af3eb9f27f.jpeg)

②下にスクロール　▶　GitHub pages
③Source ▶　master branch
④下にスクロール　▶　Github Pages ▶　URL取得
<img width="1680" alt="スクリーンショット 2020-07-16 14.33.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672896/5c17c844-97bf-e9f1-f837-8da6a347cb3e.png">

## まとめ
作成物を作ったらgithubにアップロードすることを心がける。
最初の設定は忘れやすいので、ちょくちょく見返すように！
[Oracle] コマンドラインでSQLの履歴を操作

# SQL > の状態でコマンド履歴を確認・編集・実行する方法

SQL*Plus コマンドの
1. define _editor=エディタ（一つ前の文を変更して実行）
2. LISTコマンドを使う方法（１文のみ確認）
3. HISTORYコマンド（トラック開始後すべての文確認&番号指定して実行）
を使う方法があります。

## 通常

```shell

SQL>
```

この状態で↑↓ボタンでコマンド履歴をさぐろうとすると

```shell
SQL> ^[[B^[[A
```
のようになってしまう。


## define _editor=エディタ（一つ前の文を変更して実行）

### defineコマンドで編集時に使用するエディタを指定します。

```shell
viを使う場合
SQL> define _editor=vi

普通のテキストエディタを使う場合
SQL> define _editor=gedit
```
### editコマンドで一つ前の文を編集

```
SQL> edit
省略も可能
SQL> ed
```
geditを指定した場合はアプリが開かれるので、そこで修正します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532975/c628731a-acca-48ad-37fa-6399008cc8e1.png)

### / コマンドで修正したコマンドを実行

```shell
Wrote file afiedt.buf

  1* select 3 from dual
SQL> /
      3
-------
      3
```

#### 設定ファイルでエディタを定義しておく

```
$ORACLE_HOME/sqlplus/admin/glogin.sql
```
を編集しておけば、DBに接続するたびにdefineをする必要がなくなります。以下の記事が参考になります。
[SQL*Plusの環境を整備する - オラクル・Oracle SQL*Plus リファレンス](https://www.shift-the-oracle.com/sqlplus/tutorial/login-profile.html)

## Listコマンド

「;」でも可能です。

```shell

SQL > List

1 SELECT LAST_NAME, DEPARTMENT_ID, JOB_ID
2 FROM EMP_DETAILS_VIEW
3 WHERE JOB_ID = 'SH_CLERK'
4* ORDER BY DEPARTMENT_ID
```


### ドキュメント
[LIST](https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve028.htm#SQPUG049)

## set HISTORY ONとHISTORY

```
SQL>set HIST[ory] ON   <==コマンド履歴を有効にします

コマンドを実行します:
 
SQL> create public database link test connect to test identified by test using 'test';
Database link created.
 
SQL>alter system set local_listener="(address=(protocol=tcp)(port=1521)(host=orclhost))" scope=memory;
System Altered

SQL> hist   <==HIST[ory] を実行してリストを表示します:
  1 create public database link test connect to test identified by test using 'test';
     Database link created.
  2  alter system set local_listener="(address=(protocol=tcp)(port=1521)(host=orclhost))" scope=memory;

```

### ドキュメント
[12.2 新機能: SQL*Plus コマンド履歴の記録 | Oracle Support Japan Blog](https://blogs.oracle.com/supportjp/122-:-sqlplus)
Docker - NextCloud インストール

# 前提
* Debian 10 64bit
* docker docker-composeがインストール済み

## Dockerfile
公式のサンプル参照：https://github.com/nextcloud/docker/tree/master/.examples

```dockerfile

FROM nextcloud:apache

RUN set -ex; \
    \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        ffmpeg \
        libmagickcore-6.q16-6-extra \
        procps \
        smbclient \
        supervisor \
#       libreoffice \
    ; \
    rm -rf /var/lib/apt/lists/*

RUN set -ex; \
    \
    savedAptMark="$(apt-mark showmanual)"; \
    \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        libbz2-dev \
        libc-client-dev \
        libkrb5-dev \
        libsmbclient-dev \
    ; \
    \
    docker-php-ext-configure imap --with-kerberos --with-imap-ssl; \
    docker-php-ext-install \
        bz2 \
        imap \
    ; \
    pecl install smbclient; \
    docker-php-ext-enable smbclient; \
    \
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
    apt-mark auto '.*' > /dev/null; \
    apt-mark manual $savedAptMark; \
    ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
        | awk '/=>/ { print $3 }' \
        | sort -u \
        | xargs -r dpkg-query -S \
        | cut -d: -f1 \
        | sort -u \
        | xargs -rt apt-mark manual; \
    \
    apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
    rm -rf /var/lib/apt/lists/*

RUN mkdir -p \
    /var/log/supervisord \
    /var/run/supervisord \
;

COPY supervisord.conf /

ENV NEXTCLOUD_UPDATE=1

CMD ["/usr/bin/supervisord", "-c", "/supervisord.conf"]


```

## docker-compose.yml
```yml

version: '2'

volumes:
  nextcloud:
  db:

services:
  db:
    image: mariadb
    restart: always
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=hoge # 適当なパスワードを設定
      - MYSQL_PASSWORD=hoge      # 適当なパスワードを設定
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    build: .
    image: nextcloud
    ports:
      - 8080:80
    links:
      - db
    volumes:
      - nextcloud:/var/www/html
    restart: always
```

## 実行
```bash
 docker-compose build --pull 
 docker-compose up -d 
```
商品削除ボタンを表示できなかった話

####起きてしまっているエラー

[NameError　GYAZO](https://gyazo.com/7181e67b55ef3b48e9c2aa4fc3ac6718)

```ruby:実装中の一部haml
          .ItemBox__optionalArea
            %ul
              %li.optionalBtn.likeBtn
                %i.fas.fa-star
                お気に入り 0
            %ul.optional
              %li.optionalBtn
                = link_to "#" do
                  %i.fas.fa-flag
                  不適切な商品の通報
          = link_to '商品を削除する', item_path(item.id), method: :delete 
```
最下部のlink_toを表示させたかったが、NameErrorが出てしまう。
pathもあっているし、HTTPメソッドも問題なく記述しているため。
？？？となる。

####解決法
```ruby:items_controller
class ItemsController < ApplicationController
  def index
    @items = Item.all
  end

  def new
    @item = Item.new 
    @item.images.new
  end

  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to root_path
    else
      @item.images.new
      render :new
    end
  end

  def show
    @item = Item.find(params[:id])
  end
#こちらshowアクションを追記

  def destroy
    items = Item.find(params[:id])
    item.destroy
  end

  private
  def item_params
    params.require(:item).permit(:name, :text, :price, :category, :condition, :postage_payer, :prefecture_id, :standby_day, :trading_status, :seller, :buyer, images_attributes: [:image_url]).merge(seller: current_user.id)
  end

end

```

```ruby:実装中の一部haml
         = link_to '商品を削除する', item_path(@item.id), method: :delete 
該当の部分にコントローラーに定義した@itemを記述
```

####原因
そもそもitems controllerにshowアクションが記述されていなかった
初歩的なミスであったため、もう少し入念にみることを心がける様にします。
Raspberry PiでOSCと音

こんにちは。Raspberry Piでインタラクティブアート的なものとかを作るときに、ラズパイからインタラクティブに音を出したいときがありますよね。ここではMaxがArmで動けよ！っていう気持ちを抑えながらサクッと音を出す方法について書いていきます。

# 結論 - 2022年4月30日追記
本家のPd Valinaをaptでインストールして`netsend`や`netreceive`オブジェクト使ってもできましたね。**Pd-L2ok**が不安定な時があるのでそっちを使うのが安定かもしれません。

```
$ sudo apt install puredata
```

`purr-data`+ I2S DACではうまく動作しませんでした

---
以下は過去版

# 環境
- Raspberry Pi 2 
- Raspberry Pi OS Buster Lite
- macOS 10.14.6

# 願望
- OSCで音をぐりぐりしたい。
- あんまり複雑なインストールをしたくない。
- 開発は母艦コンピュータでやって、ラズパイはシンプルにCLIだけにしたい。つまり母艦で動いたファイルをアップロードするだけで済ませたい。
- pd-extendedが動いたら最高だったし、puredata(vanilla)にOSCが純正で入っていてほしい。

# Purr-Data
上記のような欲求をお持ちのあなた！[`Purr-Data`](https://github.com/agraef/purr-data)がおそらく最速です。もうご存知でしたらすいません。以下がインストールの方法です。MacでもWin（未確認）でも動くのでデバッグも簡単です。

##インストール方法
- [Wiki](https://github.com/agraef/purr-data/wiki/Installation)

`Purr-Data`はヴァージニア工科大学でIvica Bukvic氏によって開発された`Pd-L2Ork`が元になっており、Pd-L2Orkのバージョン2.0からPurr Dataと言う名前になったそうです。実際macOS版をインストールするとPd-l2ork.appという名前でインストールされます。言うなれば開発が止まってしまったpd-extendedの現代版というところでしょう。

ラズパイには以下のコマンドでインストールできます。

```
$ sudo su

# wget -nv https://download.opensuse.org/repositories/home:aggraef/Raspbian_10/Release.key
# apt-key add Release.key

# echo 'deb http://download.opensuse.org/repositories/home:/aggraef/Raspbian_10/ /' > /etc/apt/sources.list.d/home:aggraef.list
# apt update

# apt install purr-data
```

## コードを書く
基本的にPureData/pd-extendedと同じだと思います。`cycle~`ではなく`osc~`だったり色々Maxとは名前が違いますね、同じものもありますが。

## 実行コマンド
おそらくCLI環境でやっていると思うので、実行コマンドは

```
$ purr-data -nogui youramazingfile.pd
```
でできます。`youramazingfile`はあなたが作ったファイルの名前です。
USB-DACとかを使いたい場合は

```
$ purr-data -nogui -alsa -audiodev 5 youramazingfile.pd
```
のように、`-audiodev X`の形でオーディオデバイスを指定してあげると良さそうです。なお、`purr-data -listdev -nogui`でデバイス一覧が取得できるのでいい感じに`X`を指定して上げてください。


## OSCをつかう
<img width="344" alt="image.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416221/da5e007b-f41a-b9f2-8fab-d015e361b24d.jpeg">

基本的に上図のとおりですが、まず`import mrpeach`をするのがUDPの通信をするために必要です。また、受信した生のOSCメッセージをリストに変換するために`unpackOSC`, リストをOSCメッセージに変換するために`packOSC`が必要です。`udpsend`はメッセージを送る前に`connect`しないといけないので、`loadbang`などで起動時に設定しておくと良いでしょう。

## するとできること
PythonなどでGPIOの値をとってOSCでPurr-Dataに送ったり、母艦から制御してマルチチャンネルリアルタイムオーディオ処理をしたり、色々なことができそうですね。

# 他の方法（失敗）
1. [pd-extended](https://puredata.info/downloads/pd-extended)を使う
    情報がwheezyの頃のばかり + pd-extendedの開発も2013年に終わっていて流石に古すぎるのでは...という不安とともに[こちらのチュートリアル](https://puredata.info/downloads/pd-extended-0-43-3-on-raspberry-pi-raspbian-wheezy-armhf)をやってみましたが案の定依存関係がサクッといかなかったので諦めました。
    
2. 普通にPureData + mrpeachをインストール/コンパイルする  
    ラズパイではコンパイルができたのですがmacOS Mojaveにサクッと入らず失敗。Makefileとかがもっとわかればできるのかもしれません。

3. openFrameworksをつかう
    oFの音周りのライブラリを使うという手もありそうです。Purr-Dataが動いたので試していません。

# おわりに
openFrameworksやPythonを使う方法もあるとは思いますがやっぱりMax/Pd的なやりかたはオーディオ特化な感じがしていいですよね。そもそも皆さんはどうやってやっているのかも気になっているので、他の方法などで動かした方がいらっしゃいましたらぜひコメントをいただければ幸いです。
[Unity] 波を作る　～Blender 編～

# 「正弦波」を Unity で作ってみよう

![SingleSineWave.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93253/6f848afe-11de-ffef-828e-cdd4583229c8.gif)

まずは、こんな感じの正弦波を作りましょう！

プロジェクトは　[[Github] note-nota/SineWave](https://github.com/note-nota/SineWave) を参照して下さい。

## 基本方針

**Shader で再現してみよう！**

　点群がウネウネ動いても良いけども、計算点の間を適度に繋げて表現しないと「波」と伝わらない気がするので、Shader で再現してみよう。その際、Unity の Primitive な Plane は一辺が11点のメッシュで作られているので、「波」を再現するには役不足。。。ってことで、計算点をぐっと増やした Plane を Blender で作って、それに合わせて Shader で波を表現したいと思います。

 今回は Blender でモデルを作って Unity にインポートするまでになります。Shader 編は [こちら](https://qiita.com/note-nota/items/d2e251d93bc5fac2cbba) へどうぞ。

## Blender でハイポリメッシュを作る！

![Blender_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93253/f13da3dc-021d-4a08-ed81-e407497a97fd.png)

　今回は、１ｘ１[m] の Plane を作ります。（この方が後で Shader 周りで規格化され使いやすいので。）頑張って（Blender 初めて使うんで…）"x-90 度の平面" を作ります。Unity にもっていく関係で座標変換されるようで、とりあえず平面に前後左右が無いので、上下だけ合わせておきます。

![Blender_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93253/0873f3ed-2d06-11c7-699f-660940a0a6d9.png)

　平面が無事作成出来たら、頑張って（Blender 初めて使うんで…）"細分化" します。こんな感じで良いのではないでしょうか？細分化 9 を 3 セット行ったので、1000 x 1000 くらいでしょうか？右下のステータスで「頂点：1,002,001 (=1,001 x 1,001)」となっているので、１[m] の間を 1,000 辺に分割出来たと思います。

![Blender_3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93253/f11c3a6c-b274-ceb7-11be-70ddd3b2dc21.png)

ググっと平面に寄ってみるとこんな感じです。今回は各面を三角面にしました。よ～く見ると、三角形になっていることが確認できます。

![Blender_4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93253/fbd084a6-bb1e-af8a-0953-a7d9d78f0aa9.png)

　Blender で FBX にエクスポートしたら、Unity にインポートします。

　次回は、この Plane に波の Shader を当てていきます。

### Blender で詰まったところ
　Blender 初めて使うんで詰まったところをいくつか

* Unity にインポートしたときに縦に立った平面になる！
    * Blender でエクスポートするときに軸方向を選択できるようだけども、うまい設定を見つけられなかった
    * Blender の Object に対して回転を設定できるようだけども、そちらを変更しても出力に影響が無かった
    * 結局、"平面" を追加するときに初期値として "x:-90deg" を入力するとうまくいった
* Unity にインポートしたときにサイズが大きすぎる！
    * Blender 上で 1.0x1.0[m] に設定し、エクスポートの際にも Scale Factor を 1 に設定しても大きくなる
    * Unity 側で FBX の Import Settings で設定を行うことで意図した通りのモデルになったので参考程度に
        * Scale Factor : 1
        * Convert Units : False

### Blender 参考

* [【Unityシェーダ入門】シェーダで旗や水面をなびかせる](http://nn-hokuson.hatenablog.com/entry/2017/04/04/201537)
* [【Blender】【モデリング基礎】メッシュ分割系のツールまとめ](https://light11.hatenadiary.com/entry/2018/09/24/214040)
* [blenderからUnityへ３Dモデルをエクスポートする](https://dkrevel.com/unity-and-blender/blender-to-unity-fbx-model/)
DQL使ってみた with Docker & マルチプロファイル


DynamoDBをSQLライクに操作できる[DQL](https://github.com/stevearc/dql)。
仕事で使うことになったものの、環境設定から始めるとメンバーへの展開に時間がかかるし、マルチプロファイルじゃないと大規模な現場では使えないですよね！どちらも設定してみました。

# Docker

```Dockerfile
FROM python:2.7.18-buster

RUN pip install --upgrade pip;\
    pip install --upgrade dql

ENTRYPOINT [ "dql" ]
```

# プロファイル

スイッチロールにMFAが必要だったりするとdqlでは対処できないので、`aws-vault` にお世話になります。

`aws-vault`ではパスに実行可能ファイルが必要なので、こんなファイルを$PATHの通る場所に置いておき...

```sh
#!/bin/sh
docker run --env AWS_DEFAULT_REGION --env AWS_REGION --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --env AWS_SESSION_TOKEN --env AWS_SECURITY_TOKEN --env AWS_SESSION_EXPIRATION --rm -it -v "$HOME/.aws:/root/.aws" hiroga/dql:latest "$@"
```

以下のように実行します。

```terminal
aws-vault exec my-profile -- dql -r us-west-2
us-west-2>
```


実際にDynamoDBを操作してみましょう。

```terminal
aws-vault exec my-profile -- dql -r us-west-2
us-west-2> scan * from users;
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
   user_id : 'c06b0c58-5aeb-49a3-87a4-2671cfca0694'
      name : 'hiroga'
```

いい感じですね！
Spring Boot で static resource と Thymeleaf Engine なしで静的HTMLを提供します。

```java
package org.thrakt.sampleapp.controllers;

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("")
public class HtmlProvideController {

    private final ResourceLoader resourceLoader;

    public HtmlProvideController(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @GetMapping
    public Resource get() {
        return resourceLoader.getResource("classpath:html/foobar.html");
    }
}

```

`resourceLoader` を使って `Resource` を返す。
`@ResponseBody` か `@RestController` で動かす。
`/resources` 配下はjarの中に入るので、そこから `classpath` 参照で持ってくる。

モチベーションは
なんか静的HTML返したいけど
`/resource/static` に置くと直pathで露出してなんか嫌だし
これだけのために `Thymeleaf` 入れるのも無駄で嫌だ
ということでこれをやった。
うまくビルドスクリプト書けば、別のビルドパイプラインで生み出されたものを同梱して送り出すのもできるかな？
firewalld で ポートフォワーディング

### 環境
#### マシン環境
- ホストOS
    - Windows10 2004
- ゲストOS
    - CentOS8 (VMware Player)

#### トポロジ
![vmnetwork.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316424/a3858061-18d1-8160-7be8-5903245e1e76.png)

###やりたいこと
ホストOS側のブラウザから:8080でアクセスし、サーバーには:80としてポートフォワーディング.

![vmnetwork (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316424/af280653-b2d7-795a-2252-7a98b4bbc510.png)

上の図はすごく判りづらいですが、要は**ホストOS側からの:8080の通信を:80に切り替えてhttpdに送るよ**っていうことです。

今回は、同一サーバーへのフォワーディングですが、別サーバーへも可能です.

###同一サーバ内でのポートフォワーディング
####コマンド
```
# firewall-cmd --add-forward-port=port=port-number:proto=tcp|udp|sctp|dccp:toport=port-number
```
これを今回のパターンにはめると

####コマンド例
```
# firewall-cmd --add-forward-port=port=8080:proto=tcp:toport=80
```
- --add-forward-portの後にポート情報をつらつら書きます
    - port=8080　はクライアントから:8080が来るよ
    - proto=tcp　はプロトコルにtcpを使うよ
    - toport=80　は:80におくるよ

####設定を永続化するコマンド
```
# firewall-cmd --runtime-to-permanent
```

- 上記のadd-forward-...というコマンドに、--permanentをつけることで永続化も行えますが、今回は別コマンドから永続化しています.

###設定の確認するコマンド
```
# firewall-cmd --list-all
```
- このコマンドの出力結果は、各環境ごとによって異なる場合があります.

```
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens33
  sources:
  services: cockpit dhcpv6-client http https ssh
  ports:
  protocols:
  masquerade: no
  forward-ports: port=8080:proto=tcp:toport=80:toaddr=
  source-ports:
  icmp-blocks:
  rich rules:
```

- forward-ports:のところに書き込めているのでできたことなります.

###別IPへのポートフォワーディング
####コマンド
```
# firewall-cmd --add-forward-port=port=port-number:proto=tcp|udp:toport=port-number:toaddr=IP/mask
```
- 今回は、別IPへのフォワーディングは行いませんが、ご覧の通り、toaddr以降が追記されてるくらいです.
PullRequestやbacklog、slackなどで作業報告する際にgifで説明すると伝わりやすいので、すぐgif作れる環境を整える

最近リモートワークが増え、コミュ二ケーション方法を見直す機会が多いですね。
同じ空間にいる時は
「アプリの実装どんな感じですか？」
「こんな感じです。」
がすぐできたのですが、このやりとりはリモートワークのzoomごしだとなかなかやりづらいです。

PullRequestやBacklog、slackなどで作業報告する際に動画で説明すると伝わりやすいのですが、動画は容量を食うため、アップロード制限にかかることが多々あります。

この記事ではコマンド一つでmp4ファイルとmovファイルをgifに変換できる環境を作ります。
iPhoneやandroidでスクリーン録画すると.mp4,mac のquick timeplayerで撮影すると.movになるので、この２種類をgifに変換するスクリプトを作成していきます。

といっても実態はFFmpegをベースに、Makefileでよく使うFFmpegコマンドをまとめているだけです。
（FFmpeg（エフエフエムペグ）は動画と音声を記録・変換・再生するためのフリーソフトウェアであるhttps://ja.wikipedia.org/wiki/FFmpeg）

## macにffmpegをインストール
まずはFFmpegをベースなのでFFmpegをインストール。
` brew install ffmpeg `



## Makefileを作成

` vi Makefile `　などで、ファイルを作り、以下をコピペしましょう。

```
help: ## Usage
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

mp4togif:
	ffmpeg -i screen.mp4 -r 7 output.gif

movtogif:
	ffmpeg -i screen.mov -r 7 output.gif

```

これで ` mp4 ` からgifを生成するコマンド
` make mp4togif `　

これで ` mov ` からgifを生成するコマンド　　
` make movtogif `

が使える様になります。

## Makefileの設置
作業ディレクトリに先ほど作ったMakefileを配置。
今後このディレクトリにmp4やmovをおいて、Makefileを実行します。
僕はムービーディレクトリの配下においてます。
<img width="203" alt="スクリーンショット 2020-07-16 12.59.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143374/3376dcaa-3c0c-3e45-a3a9-c6165d20f356.png">

## 実行
撮影したmp4やmovファイルをMakefileがある場所と同じディレクトリ.movや.mp4を配置。
撮影したファイルを ` screen.mp4 ` や　` screen.mov ` にリネームしましょう。

変換したいファイルが ` screen.mp4 `の場合は
` make mp4togif `　

変換したいファイルが ` screen.mov `の場合は
` make movtogif `

を実行しましょう。


既に作ってる場合は、上書き保存するか聞かれます。

` File 'output.gif' already exists. Overwrite ? [y/N] `

![スクリーンショット 2020-07-16 13.31.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143374/4bfd9b11-3b76-5723-284c-e1857f0fab98.png)

完了したらoutput.gifができていたら成功🎉
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143374/60a6d825-5e2f-cddd-ee45-4216931be3f4.gif)







## 応用
gifにしても、容量制限に引っかかる場合は、リサイズや、フレームレートを調整したコマンドも追加。

ex.) 動画の高さ(height)を 720 にする。横幅(width)はアスペクト比を維持して自動で設定する

```
movtogif_720:
　　　　　ffmpeg -i screen.mov -vf scale=-1:720 output.gif
```

リサイズ
https://moewe-net.com/uncategorized/ffmpeg-resize-image

フレームレート
http://tech.ckme.co.jp/ffmpeg_frate.shtml
便利なのにすぐ忘れるAtomショートカットキー

#Atomショートカットキー
テキストエディタAtomをWindowsで使用した際のショートカットキーです。

##タブ
|キー  |動作  |
|:-----:|:-----:|
|ctrl+\ |左のタブメニュー出し入れ  |
|ctrl+k+w |全ての開いているファイルを閉じる  |

##マルチカーソル
|キー  |動作  |
|:-----:|:-----:|
|ctrl+d |単語の選択。選択している場合は、次に一致する単語を選択して、マルチカーソル状態になる |
|ctrl+k,ctrl+d |マルチカーソルで選択状態のときに1つスキップする|
|alt+F3 |選択単語と一致するものをマルチカーソルですべて選択|

##折りたたみ
|キー  |動作  |
|:-----:|:-----:|
|alt+ctrl+[ |カーソル位置で折りたたむ  |
|alt+ctrl+]|カーソル位置の折りたたみを開く  |
|alt+ctrl+shift+[ |全て折りたたむ  |
|alt+ctrl+shift+]|全ての折りたたみを開く  |

##検索
|キー  |動作  |
|:-----:|:-----:|
|ctrl+shift+F |プロジェクト内検索 (=一括検索, ファイルを超えて検索)  |

#さいごに
マルチカーソル中の単語のスキップや、折りたたみは中々日本語のサイトでは見当たらなかったのでまとめてみました。
nimで+++を実現する

# +++が一部で流行っているらしい
[JavaScriptで+++は許されない+ ++は許される](https://qiita.com/matyapiro31/items/19d62605632dd90d0647)
[C/C++ では+++は許される](https://qiita.com/Nabetani/items/ea9e141f650492b9e147)
[Rustで+++は許されない+ ++も許されない](https://qiita.com/YoshiTheChinchilla/items/b5db271eb35972e67c93)
[Rustで+++を実現する](https://qiita.com/dalance/items/18c5f5bb5ec643ac9aec)

有名な言語ばかりですね。

# nimなら？
nimはマイナーなのですが、演算子を定義することが出来ます。
また、普通に参照渡し使えるので、簡単に実現できます。
ここでは、++したものを+したいのでしょうか？
とりあえず、+++を+ ++と考えて書いてみるならば、こうなるでしょう。

```nim
proc `+++`(x, y: var int): int =
  y = y + 1
  x + y

var
  x: int = 8
  y: int = 9
echo x+++y
```

ちなみに、引数にvarをつけているのは参照渡しにするやつです。
おお！なんて簡単なコードなのでしょう！
そして、演算子は定義し放題なので万能感に包まれます(光り輝く✨)

※ コード修正前、なんかポインタとか使ってたけど、参照渡しだからポインタ要りませんでした。何考えてんだ…

# つまり？

皆さん、nimをするのです(大きく手を広げる✨)
three.jsで深度のみを書き込む方法

three.jsで3Dオブジェクトの色は描画せずに、深度のみを書き込む方法です。

`THREE.Material`の[colorWrite](https://threejs.org/docs/index.html#api/en/materials/Material.colorWrite)プロパティを`false`にすることで実現できます。この際オブジェクトの描画順により最終的な描画結果が変わるので、`THREE.Object3D`の[renderOrder](https://threejs.org/docs/index.html#api/en/core/Object3D.renderOrder)プロパティで明示的に描画順を設定しましょう。

以下、サンプルコードです。キューブを横切るように深度のみを書き込む平面を配置しています。平面の`renderOrder`に`-1`を設定して最初に描画されるようにしています。
![three-only-depth.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/a95bb1dc-bdfe-7cbe-e15c-bd831025d4b2.gif)

```html
<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r118/three.min.js"></script>
    <style>
      body { margin: 0; }
      canvas { display: block; }
    </style>
  </head>
  <body>
    <script>
      const scene = new THREE.Scene();
      scene.background = new THREE.Color('#999999')
      const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      const cube = new THREE.Mesh(
        new THREE.BoxBufferGeometry(),
        new THREE.MeshNormalMaterial()
      );
      scene.add(cube);

      const invisiblePlane = new THREE.Mesh(
        new THREE.PlaneBufferGeometry(3, 3),
        new THREE.MeshBasicMaterial({
          colorWrite: false,
          side: THREE.DoubleSide
        })
      );
      invisiblePlane.renderOrder = -1;
      invisiblePlane.rotation.y = Math.PI * 0.25;
      scene.add(invisiblePlane);

      camera.position.z = 3;

      const animate = function() {
        requestAnimationFrame(animate);
        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
        renderer.render(scene, camera);
      };
      animate();
    </script>
  </body>
</html>
```
Raspberry Pi4で機械学習の準備

空白行で区切ったので、多少コピペしやすいと思います。
エラーっぽいメッセージが出たら、もう一回同じコマンドを実行させてみるとよさげ。よさげに酢をかけさしすせそ

# Windowsから変更

```sh:boot\config.txt
# この2行は左のハッシュ記号を取り除く。
hdmi_force_hotplug=1
hdmi_group=1
# この1行は左のハッシュ記号を取り除いたうえで数字を5に
hdmi_mode=5
# この1行は最後に追加
dtparam=act_led_trigger=heartbeat
```

# ラズパイの左上のこいつからシェルを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447423/c58b6236-d7db-6035-ed0e-1682a6ebc6ec.png)


# 本体のアップデート作業
```sh:update

sudo apt update

sudo apt upgrade

sudo apt dist-upgrade

sudo apt autoremove

sudo apt autoclean

sudo reboot
```

# pipをPython3.xに紐づける
参考：https://www.souichi.club/raspberrypi/python3-default/

```sh:change_default_python
cd /usr/bin

sudo unlink python

sudo ln -s python3 python
```

# tensorflow2.xのインストール
tensorflow1.xを利用したい場合は飛ばす。
参考：https://github.com/PINTO0309/Tensorflow-bin
下から４つ目のsudo、３つ目のshが抜けてるので付け足しました。

```sh:install_libraries
sudo apt install -y libhdf5-dev libc-ares-dev cython gcc gfortran python-dev \
                    libgfortran5 libatlas3-base libatlas-base-dev libopenblas-dev \
                    libopenblas-base libblas-dev liblapack-dev libeigen3-dev \
                    openmpi-bin libopenmpi-dev python3-dev

pip install keras_applications==1.0.8 --no-deps

pip install keras_preprocessing==1.1.0 --no-deps

pip install h5py==2.9.0 pybind11

pip install -U --user six wheel mock

cd

sudo wget "https://raw.githubusercontent.com/PINTO0309/Tensorflow-bin/master/tensorflow-2.2.0-cp37-cp37m-linux_armv7l_download.sh"

sudo sh ./tensorflow-2.2.0-cp37-cp37m-linux_armv7l_download.sh

pip uninstall tensorflow

sudo -H pip3 install tensorflow-2.2.0-cp37-cp37m-linux_armv7l.whl
```

# OpenCVのインストール
ImportErrorが出てしまったのでやり直しました。
こちらを参考にしました：https://creepfablic.site/2020/04/10/python-opencv-error/
再度やったらエラーが出たので、こちらを参考に少々修正しました。：https://qiita.com/XM03/items/48463fd910470b226f22

```sh:install_opencv
pip install opencv-python==4.1.0.25

sudo apt install -y libjasper-dev qt4-dev-tools qt4-doc qt4-qtconfig libqt4-test libatlas-base-dev

sudo nano .bashrc
```

`export LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1`の１行を追加.
Ctrl+O, Enter, Ctrl+Xの順に押して保存。
再起動。

# その他のライブラリのインストール
他に必要なのがあればご自身でどうぞ。

```sh:install__libraries
pip install numpy pandas scipy scikit-learn matplotlib keras keras-rectified-adam
```

# VSCodeのインストール
参考：https://qiita.com/optimisuke/items/1cd7440442f7420e6b99

```sh:install_vscode
sudo -s

. <( wget -O - https://code.headmelted.com/installers/apt.sh )

exit
```
CLI 画像ビューアの Überzug と Ranger の組み合わせがとっても便利

#はじめに

Vim ライクなキーバインドで操作可能なコンソール用ファイルマネージャー、[Ranger](https://github.com/ranger/ranger) は高速なライブプレビューを備えており、テキストの内容はもちろん、画像や、設定により PDF の文書や動画のサムネイルもサクサク端末上で確認できます。

ビューアで画像表示を実現するためには w3m の w3mimgdisplay や Mac の iTerm2 が備える画像表示の仕組みが利用できますが、最近 `Überzug` というツールにも対応した事を知ったので、このツール自体と Ranger との組み合わせ方法を紹介してみたいと思います。

#Überzug について

[Überzug](https://github.com/seebye/ueberzug) は子ウィンドウを使って端末上に画像を描くことができるコマンドラインユーティリティで、readme によると以下の様な特徴があるそうです。

- 画像を表示するために新しいウィンドウが作成されるため、競合条件がない。
- Expose イベントが処理される為、ワークスペースを切り替えると画像が再描画される。
- tmux 上での使用がサポートされている。

等々。早速使って見ましょう。

### インストール
Python 製のツールで pip でインストールしますが、 X11 と Xext に依存するため X Window System 上で動作する OS でしか使用出来ないと思われます。
私は `Ubuntu 20.04 LTS` で試しました。 WSL2 & x410（WSL 用の Xサーバ）ではインストールは出来ますがエラーで正常動作しませんでした。

下記の手順で必要なライブラリと Überzug を導入します。

```shell
~% sudo apt-get install python3 python3-dev libx11-dev libxext-dev python3-distutil
~% curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
~% sudo python3 get-pip.py
~% sudo pip3 install ueberzug
```

### 使用方法
無事にインストール出来たら、試しに下記のスクリプトを準備してシェルから使ってみます。
`X` の機能を使ってレンダリングするので、ターミナルエミュレータの種類は恐らく問わないと思います。

```show.sh
#!/bin/bash
[ -z "$5" ] && echo "Usage: $0 <image> <x> <y> <max height> <max width>" && exit

source "`ueberzug library`"

ImageLayer 0< <(
    ImageLayer::add [identifier]="example0" [x]="$2" [y]="$3" [max_width]="$5" [max_height]="$4" [path]="$1"
    read
)

```

`chmod +x show.sh` して、例えば `./show.sh images/AX141105107519_TP_V4.jpg 50 10 20 20` みたいに叩くと、
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13048/b07331fe-491d-56ee-231e-594197d0223e.png)
こんな感じに端末上の任意の場所に任意の大きさで画像が表示できます。もう一度 [Enter] を叩くと終了します。

その他にも色々オプションがあるようなので、詳細は Github を参照して頂ければと思います。

#Ranger から使ってみる

`Ranger 1.9.3` で　`ranger --copy-config=all` した後の `$HOME/.config/ranger/rc.conf` の雛形を確認してみます。

```$HOME/.config/ranger/rc.conf
# * ueberzug:
#   Preview images in full color with the external command "ueberzug".
#   Images are shown by using a child window.
#   Only for users who run X11 in GNU/Linux.
```
とのコメントがあるので、 `set preview_images_method` の設定を下記の様に行います。

```
set preview_images_method ueberzug
```
これでOKです。

こんな感じで「画像/PDF/動画のサムネイル」が爆速でプレビュー出来ます。
![Peek 2020-07-16 10-18.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13048/dd2ee7c8-5c49-be87-b1ef-911b744b2b84.gif)


tmux で 分割したそれぞれのペインでの表示や、ウィンドウを切り替えた場合でも問題なさそうです。画像が消えたり残ったりする事がありません。
![Peek 2020-07-16 10-28.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13048/dd79d84d-2b12-c0fd-6163-86dc100fe819.gif)

Vim のターミナルモードで立ち上げた Ranger でも同様に画像表示できたので、多分 Ranger と連携するプラグインでも、試してはいませんが使えるんじゃないかな、と思います。

#おわりに

現状使用出来る OS が限られますが、 Linux Desktop を普段使いされてる様な方ならとても便利に使えるんじゃないでしょうか。
個人的には Windows10(WSL2) と Xサーバの組み合わせでも使える様に出来たらいいなーと考えています。

ではでは、是非試してみてください！
Windows10で次々と(自動的に)スクリーンショットを取る

Windows10では、[Windowsキー]+[Print Screen]を押下すると、
C:\Users\ (ユーザー名) \Pictures\Screenshots
のフォルダへ、全画面のスクリーンショットをpngファイルで出力してくれる。

リアルタイムで次々とスクリーンショットを取りたいときに便利。