OmniAICreator/Qiita-1.07M huggingface dataset:
Vivado HLS 備忘録 AXI-Stream

#概要
Vivado HLSの使い方について備忘録を残す

#今回のターゲット
AXI-Streamの入出力について記す。
Xilinx FPGAの場合は、画像系のインターフェースとして使用される。
詳細は UG761

#Example Design
Vivado HLS -> Open Example Design -> axi_stream_side_channel_data

#Cソース
@example.cpp

```
#include "ap_axi_sdata.h"


void example(ap_axis<32,2,5,6> A[50], ap_axis<32,2,5,6> B[50]){
#pragma HLS INTERFACE axis port=A
#pragma HLS INTERFACE axis port=B

  int i;

  for(i = 0; i < 50; i++){
    B[i].data = A[i].data.to_int() + 5;
    B[i].keep = A[i].keep;
    B[i].strb = A[i].strb;
    B[i].user = A[i].user;
    B[i].last = A[i].last;
    B[i].id = A[i].id;
    B[i].dest = A[i].dest;
  }
}
```

##解説
>ヘッダファイル（ap_axi_sdata.h）
>>AXIS含めDMA用のインターフェースも含まれている
>>以下にテンプレート
>>ふつうはkeep/strb/id/destは使用しないが、テンプレートない
>>validとreadyはどうしているかわからない

```
template<int D,int U,int TI,int TD>
  struct ap_axis{
    ap_int<D>        data;
    ap_uint<(D+7)/8> keep;
    ap_uint<(D+7)/8> strb;
    ap_uint<U>       user;
    ap_uint<1>       last;
    ap_uint<TI>      id;
    ap_uint<TD>      dest;
  };

template<int D>
  struct ap_axis <D, 0, 0, 0>{
    ap_int<D>        data;
    ap_uint<(D+7)/8> keep;
    ap_uint<(D+7)/8> strb;
    ap_uint<1>       last;
  };

```
>インターフェース詳細
>>`ap_axis<32,2,5,6> A[50]`
>>>`ap_int<D>        data`
>>>32bitのデータ幅
>>>
>>>`ap_uint<U>       user`
>>>2bitのTUSER
>>>
>>>IDとDESTはどうでもよい
>>>
>>>配列要素の[50]はレジスタの数？よくわからん

>AXISを使用するためのプラグマ
>>`#pragma HLS INTERFACE axis port=A`

>処理部
>>`B[i].data = A[i].data.to_int() + 5`


#Verilogソース
##入出力
```
input   ap_clk;
input   ap_rst_n;
input   ap_start;
output   ap_done;
output   ap_idle;
output   ap_ready;
input  [31:0] A_TDATA;
input   A_TVALID;
output   A_TREADY;
input  [3:0] A_TKEEP;
input  [3:0] A_TSTRB;
input  [1:0] A_TUSER;
input  [0:0] A_TLAST;
input  [4:0] A_TID;
input  [5:0] A_TDEST;
output  [31:0] B_TDATA;
output   B_TVALID;
input   B_TREADY;
output  [3:0] B_TKEEP;
output  [3:0] B_TSTRB;
output  [1:0] B_TUSER;
output  [0:0] B_TLAST;
output  [4:0] B_TID;
output  [5:0] B_TDEST;

```
>AXI-Stream系
>>RTL化すると、VALIDとREADYが追加されている。
>>NotReady条件等はよくわからん
>>
>>
>AP-Control系
>>UG902図1-38を参照
>>合成状態によってはスループットが低下？
>>こちらのブログも参考になる
>>https://marsee101.blog.fc2.com/?mode=m&no=3497&photo=true
>
#所感
・高位合成により出力されるRTLは、RTL設計者からはイメージが付きづらい
・今回のように対した処理でもない（入力をそのまま出力するだけ）のに、生成されたRTLコードは複雑。
・CソースをそれなりにHDLを意識して記述&RTLでのSIM環境を整えなければ設計スピードと品質の両立は難しそうな気がする
bundler: failed to load command: pod が出た場合の対応

Xcodeのバージョンを新しくした後にcocoapodsを更新しようとターミナルで

```sh
bundle exec pod install
```

を叩いた時にエラーが発生

```sh
$ bundle exec pod install

bundler: failed to load command: pod (/Users/tamappe/Documents/workspace/iOS/App/vendor/bundle/ruby/2.3.0/bin/pod) RuntimeError: Failed to extract git version from `git –version` (“xcrun: error: active developer path (\”/Applications/Xcode_11.app/Contents/Developer\”) does not exist\nUse `sudo xcode-select –switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools, or use `xcode-select –install` to install the standalone command line developer tools.\nSee `man xcode-select` for more details.\n”) /Users/tamappe/Documents/workspace/iOS/App/vendor/bundle/ruby/2.3.0/gems/cocoapods-1.6.1/lib/cocoapods/command.rb:118:in `git_version’ /Users/tamappe/Documents/workspace/iOS/App/vendor/bundle/ruby/2.3.0/gems/cocoapods-1.6.1/lib/cocoapods/command.rb:130:in `verify_minimum_git_version!’ /Users/tamappe/Documents/workspace/iOS/App/vendor/bundle/ruby/2.3.0/gems/cocoapods-1.6.1/lib/cocoapods/command.rb:49:in `run’ /Users/tamappe/Documents/workspace/iOS/App/vendor/bundle/ruby/2.3.0/gems/cocoapods-1.6.1/bin/pod:55:in `<top (required)>’ /Users/tamappe/Documents/workspace/iOS/App/vendor/bundle/ruby/2.3.0/bin/pod:23:in `load’ /Users/tamappe/Documents/workspace/iOS/App/vendor/bundle/ruby/2.3.0/bin/pod:23:in `<top (required)>’
```

に関するエラー対応

たまにちょいちょい起こることがあります。

着目すべきは

```sh
(\"/Applications/Xcode_11.app/Contents/Developer\") does not exist\nUse `sudo xcode-select --switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools
```

です。

新しいXcodeをダウンロードしたり複数のXcodeをApplicationフォルダに入れておくと起こるエラーなので、使うXcodeのpathを指定して

```sh
$ sudo xcode-select --switch path/to/Xcode.app
```

を叩くと直りました。

てっきり前半の

```sh
failed to load command: pod
```

でpodやrubyのバージョンによるエラーだと勘違いしてしまったので注意が必要です。


## 宣伝

個人ブログを新しくリニューアルしました。

https://tamappe.com/
【Laravel】メール送信機能

#はじめに
問い合わせフォームで問い合わせがあった場合に、内容をメールで通知するシステムを組んだ際の備忘録。

**LaravelのMailableクラスを利用し送信します。**

#ファイル構成
```
Project
　|－app
　|　　|－ Http
　|　　|　　|－ **SendController.php
　|　　|
　|　　|－ Mail
　|　　　　|－ **SendMail.php
　|
　|－resources
　|　　|－ views
　|　　　　|－ contact
　|　　　　　　|－ mail.blade.php
　|
　|－.env
```

#コード
##Controller
`send`メソッドの引数に、`Mailable`クラスを継承したクラスを渡す。

```php:SendController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Mail;
use Illuminate\Http\Request;

class SendController extends Controller
{

    public function submit(Request $req){

      //メールを送信
      Mail::to("送信先アドレス")
      ->send(new SendMail($req['message']));

      return view('sample');
    }
}
```
##Mailableクラス
コンストラクタで表示するメッセージリストを受け取る。
`build`メソッドで、あらかじめ準備したbladeを利用して本文を作成する。
HTMLメールの場合`view`メソッド、通常テキストの場合`text`メソッドを使う。

```php:SendMail.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class SendMail extends Mailable
{
    use Queueable, SerializesModels;

    protected $message;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($message)
    {
        //コンストラクタで表示するメッセージを受け取る
        $this->message = $message;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->text('contact.mail')
                    ->subject('件名')
                    ->with(['message' => $this->message]);
    }
}
```
##View
変数を展開して本文を作成する。

```html:mail.blade.php

問い合わせが来ました。

---------------------
名前：{{$message->name}}
アドレス：{{$message->address}}
内容：{{$message->body}}
---------------------
```

##.env
`.env`にメールサーバの情報を記載する。

```html:.env

MAIL_MAILER=smtp
MAIL_HOST=***
MAIL_PORT=***
MAIL_USERNAME=***
MAIL_PASSWORD=***
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=***
MAIL_FROM_NAME="${APP_NAME}"

```

参考
[Laravelでメール送信する](https://qiita.com/toontoon/items/83f5e73e1cce69e1936c)
#最後に
利用するサーバの情報が間違っていてはまりました。
処理を何度も見直したことで理解が深まったのでOK！！！
CSVファイルの内容を表示するHTAアプリケーション

※作成中

#ソース

```html:CSVファイル表示.hta
<html>
<head>
  <title>Title</title>

    <hta:application
      id="myApp"
      applicationname="myApp"
      border="thick"
      borderstyle="normal"
      caption="yes"
      icon=""
      maximizebutton="yes"
      minimizebutton="yes"
      showintaskbar="yes"
      singleinstance="no"
      sysmenu="yes"
      version="1.0"
      windowstate="normal"/>

  <script type="text/javascript">

    var fso = new ActiveXObject("Scripting.FileSystemObject"),
        thisScriptPath = myApp.commandLine.replace(/^"|"$/g, ""),
        folderPath = fso.GetParentFolderName(thisScriptPath),
        fileName = "data.csv";

    function init() {

        var con = null, rs = null;

        try {
            con = openConnection(folderPath);
            rs = con.Execute("select * from [" + fileName + "]");
            writeCsvData(rs);
        } catch (e) {
            alert(e.description);
            // throw e;
        } finally {
            if (rs != null) {
                rs.Close();
            }
            if (con != null) {
                con.Close();
            }
        }
    }

    function openConnection(folderPath) {
        var con = new ActiveXObject("ADODB.Connection");
        con.Provider = "Microsoft.Jet.OLEDB.4.0";
        con.Properties("Extended Properties") = "Text;HDR=Yes;FMT=Delimited";
        con.CursorLocation = 3;
        con.Open(folderPath);
        return con;
    }

    function writeCsvData(rs) {

        document.write("<table border=1>");

        // ヘッダー行
        document.write("<tr>");
        for (var f = 0; f < rs.Fields.Count; f++) {
            document.write("<td>");
            document.write(escapeHtml(rs.Fields(f).Name));
            document.write("</td>");
        }
        document.write("</tr>");

        // データ行
        while (!rs.EOF) {
            document.write("<tr>");
            for (var f = 0; f < rs.Fields.Count; f++) {
                document.write("<td>");
                document.write(escapeHtml(rs.Fields(f).Value));
                document.write("</td>");
            }
            document.write("</tr>");
            rs.MoveNext();
        }

        document.write("</table>");
    }

    function escapeHtml(str) {
        // ここでエスケープ処理を入れる予定
        return str;
    }

  </script>
</head>
<body onload="init()">
</body>
</html>

```
【JUnit5対応】Spring boot 2.2, 2.3でJUnit5を使ったテストを書く

本記事は **『Spring boot2.2以上で、JUnit5に対応』** について記載してます。
下記の用途に参考になればー！

1. Spring boot 2.1以下から、2.2以上にアップデート
1. JUnit4からJUnit5への乗り換え
1. JUnit5を記述する際、事前にJUnit4を除外したい

## 0. 前提
### 環境
- Java 8〜（Spring boot2.2以上では、Java8, 11にサポートしています）
- Spring boot 2.2〜

### 知っておくといい知識
- Spring boot 2.2以上からは、JUnit5がデフォルト
- JUnit4と、JUnit5は基本的に互換はない
- **現状JUnit4と5が共存できるようになっている（いずれなくなる）**

## 1. JUnit5を使うための依存関係
- やること
    - junit-vintage-engineを除外する（JUnit4が動くようにする依存のため）

### 例1. Mavenの場合
```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>
```

### 例2. Gradleの場合
```gradle
testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
```

## 2. JUnit4関係の記述を修正
- `@RunWith` が廃止された
    - 対応 ... 削除 or `@ExtendWith`に変更
- `@Test` のimport元が変わった
    - 対応前 ... `import org.junit.Test;`
    - 対応後 ... `import org.junit.jupiter.api.Test;`
- `@Before` が廃止された
    - 対応 ... `@BeforeEach` or `@BeforeAll`に変更

## （参考）
↓ 参考にしたサイトです
- [Spring Boot 2.2 Release Notes · spring-projects/spring-boot Wiki · GitHub](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes)
- [JUnit 5 User Guide](https://junit.org/junit5/docs/snapshot/user-guide/)
AnimeGANv2をCore MLに変換してiOSでつかう【変換済みモデルあり】


[変換済みモデル（Hayao,Paprika）GitHubリンク![anime.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/8a3446ed-eee0-4d56-0340-2f7dda83efbd.gif)
](https://github.com/john-rocky/CoreML-Models)

**8.6MBの軽量モデル。**

グラフをpbtxt形式で保存します。

```python:test.py
tf.train.write_graph(sess.graph_def, './', 'animegan.pbtxt') 
```

アウトプットノードの名前を調べます。

```python:test.py
graph = sess.graph
print([node.name for node in graph.as_graph_def().node])
```

凍結グラフを作ります。

```python
from tensorflow.python.tools.freeze_graph import freeze_graph
import tfcoreml

graph_def_file = 'animegan.pbtxt'
checkpoint_file = 'checkpoint/generator_Hayao_weight/Hayao-64.ckpt'
frozen_model_file = './frozen_model.pb'
output_node_names = 'generator/G_MODEL/out_layer/Tanh'

freeze_graph(input_graph=graph_def_file,
             input_saver="",
             input_binary=False,
             input_checkpoint=checkpoint_file,
             output_node_names=output_node_names,
             restore_op_name="save/restore_all",
             filename_tensor_name="save/Const:0",
             output_graph=frozen_model_file,
             clear_devices=True,
             initializer_nodes="")
```

変換します。

```python
input_tensor_shapes = {'test:0':[1, 256, 256, 3]} # batch size is 1
# Output CoreML model path
coreml_model_file = './animegan.mlmodel'
output_tensor_names = ['generator/G_MODEL/out_layer/Tanh:0']
# Call the converter
coreml_model = tfcoreml.convert(
        tf_model_path='frozen_model.pb',
        mlmodel_path=coreml_model_file,
        input_name_shape_dict=input_tensor_shapes,
        output_feature_names=output_tensor_names,
        image_input_names='test:0',
        red_bias=-1,
        green_bias=-1,
        blue_bias=-1,
        image_scale=2/255,
        minimum_ios_deployment_target='12'
        )
```

[CoreGANContainer](https://github.com/john-rocky/CoreGANContainer)を使うと、モデルをプロジェクトにドロップするだけで使えます。

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[MLBoysチャンネル]
(https://www.youtube.com/channel/UCbHff-wfjTnB3rtXIP6y0xg)
[Medium](https://medium.com/@rockyshikoku)

[相棒](https://twitter.com/oka_yuuji)
[note](https://note.com/oka_yuuji)
Treasure DataのデータベースをAmazon S3にバルクエクスポートする

エクスポートしたいテーブル名を列挙して行う。

```groovy
// Groovy Version: 2.5.0 JVM: 1.8.0_181 Vendor: Azul Systems, Inc. OS: Mac OS X
class Config {
    static AWS_ACCESS_KEY_ID     = System.getenv().AWS_ACCESS_KEY_ID
    static AWS_SECRET_ACCESS_KEY = System.getenv().AWS_SECRET_ACCESS_KEY
    static TD_DATABASE           = System.getenv().TD_DATABASE
    static S3_BUCKET             = System.getenv().S3_BUCKET
}

'''\
table_a
table_b
.
.
'''.eachLine {
    println "export $it"
    "td table:export ${Config.TD_DATABASE} $it --s3-bucket ${Config.S3_BUCKET} --prefix $it --aws-key-id ${Config.AWS_ACCESS_KEY_ID} --aws-secret-key ${Config.AWS_SECRET_ACCESS_KEY} --file-format tsv.gz --encryption s3".execute()
}
```

各テーブル名のs3 keyの下に分割、圧縮されてエクスポートされるので便利。
<img width="1234" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51910/4a1289d7-3673-987b-a056-ff753bb7ac59.png">

テーブルが大きすぎる場合はOutOfMemory Errorが出る場合があるが、Treasure Dataの全レコードに付与されているtime（created_at相当）での範囲指定が出来るので、適宜指定してセルフ分割してエクスポートする。

```bash
# 2019年分だけをエクスポート
$ td table:export $TD_DATABASE table_a --s3-bucket $S3_BUCKET --prefix table_a__2019 --aws-key-id $AWS_ACCESS_KEY_ID --aws-secret-key $AWS_SECRET_ACCESS_KEY --file-format tsv.gz --encryption s3 --from 1546268400 --to 1577804400
```


### その他

Treasure DataのConfluenceによると、東京リージョンにもエクスポート出来るように書かれているがエラーになってしまった。


### 参考文献

- https://tddocs.atlassian.net/wiki/spaces/PD/pages/1083733/Using+Bulk+Export+to+Amazon+S3+Bucket
- https://tech.recruit-mp.co.jp/server-side/happy-groovy-life/
Pythonのstr.formatを存分に使う

# freeCodeCampでコツコツPythonを勉強しています。
[前回の記事](https://qiita.com/makky0620/items/73a566580b229c119675)では*Time Calculator*に挑戦しました、今回は*Budget App*に挑戦します。

- Python for Everybody
- Scientific Computing with Python Projects
    - Arithmetic Formatter
    - Time Calculator
    - *Budget App(今回はここ)*
    - Polygon Area Calculator
    - Probability Calculator


# 3問目:[Budget App](https://www.freecodecamp.org/learn/scientific-computing-with-python/scientific-computing-with-python-projects/budget-app)

求められてることは以下の通り

- Categoryクラスの作成
    - depositメソッド: 預ける
    - withdrawメソッド: 引き出す
    - transferメソッド: 送金
    - get_balanceメソッド: 残高表示
    - check_fundsメソッド: そのお金を引き出せるかチェック 
    - __str__メソッド: 以下のような表示

```
*************Food*************
initial deposit        1000.00
groceries               -10.15
restaurant and more foo -15.89
Transfer to Clothing    -50.00
Total: 923.96
```

- create_spend_chartメソッド: 以下のような表示

```
Percentage spent by category
100|          
 90|          
 80|          
 70|          
 60| o        
 50| o        
 40| o        
 30| o        
 20| o  o     
 10| o  o  o  
  0| o  o  o  
    ----------
     F  C  A  
     o  l  u  
     o  o  t  
     d  t  o  
        h     
        i     
        n     
        g    
```

# 個人的ポイント: formatでの書式指定

Categoryクラスの__str__メソッドやcreate_spend_chartメソッドでいい感じに書式を揃えるためにstr.formatメソッドを存分に使うことが必要。

## 様々な書式指定
- インデックス番号
    - `'{0} {1} {0}'.format('バナナ', 'りんご')`
    - -> バナナ りんご バナナ
- 文字寄せ・パディング
    - 右寄せ: `'{:>20}'.format('test')`
    - -> '○○○○○○○○○○○○○○○○test'
    - 左寄せ: `'{:<20}'.format('test')`
    - -> 'test○○○○○○○○○○○○○○○○'
    - 中央寄せ: `'{:^20}'.format('test')`
    - -> '○○○○○○○○test○○○○○○○○'
    - 空白をなんらかの文字で埋めたい場合: `'{:->20}'.format('test')`
    - -> '----------------test'
    - ゼロパディング: `'{:010d}'.format(100)`
    - -> '0000000100'
- 小数点以下の桁数指定
    - `'{:.2f}'.format(1.234567)`
    - ->　'1.23'

## Categoryメソッドの__str__メソッドの実装

```
*************Food************* 　<- ヘッダー
initial deposit        1000.00 -|
groceries               -10.15  |- ボディ
restaurant and more foo -15.89  |
Transfer to Clothing    -50.00 -|
Total: 923.96                   <- トータル
```

ヘッダー、ボディ、トータルの3つの部分に分割して考えてみる。
条件は以下の通り

- ヘッダーは30文字
- ボディの左側の説明は最大23文字、右側の金額は最大7文字で少数第2位まで表示

```python
category_name = 'Food'
ledger = [...] # 金額と説明を持ったオブジェクトのリスト

def __str__(self):
    header = '{:*^30}'.format(category_name)
    body = ['{:<23}{:>7.2f}'.format(item.description, item.amount) for item in ledger]
    total = sum([item.amount for item in ledger])

    return header + '\n' + '\n'.join(body) + '\n' + 'Total: {}'.format(total)
```


# 最後に
普段はコンソール出力でビジュアライズすることがあまりないので新鮮でした。
是非、create_spend_chartメソッドにチャレンジしてみてください。

次の問題は[*Polygon Area Calculator*](https://www.freecodecamp.org/learn/scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator)です。
Flashair を使って、デジカメデータを自動的にサーバにアップロードする

# Flashair を使って、デジカメデータを自動的にサーバにアップロードする

## Flashair
Flashair は、東芝から発売されているWifi付きSDカードです。
https://jp.toshiba-memory.com/endproduct/flashair/sduwa/index_j.htm

主にデジタルカメラなんかで利用します。
最近のデジタルカメラは本体にWIFI機能がついていることが多くなりましたが、昔はそうではなかったのです。
撮影した写真をスマホで見ようとするときには、このFlashair を使っていると便利でした。

Flashair では実は Lua というプログラム言語が動いているらしく、これを利用することで色々な自動化が可能になります。

[Flashair developers](https://flashair-developers.github.io/website/) というサイトが参考になりました。


## FTP server の準備
Flashair から Samba にアクセスする方法がわからなかったので、チュートリアルにあるFTPを使ったファイルアップロードを行います。

前回構築したデータサーバをFTPサーバにします。

```bash
sudo apt install vsftpd
sudo systemctl start vsftpd
sudo systemctl enable vsftpd
```

vsftpd のインストール後、ユーザーを追加します。
```bash
sudo useradd -m flashair
sudo password [password]
```
念の為 ufw にルールを追加しときます

```bash
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
```

デフォルトではファイル書き込みができないようなので、設定ファイルで可能にします。

```bash
sudo nano /etc/vsftpd.conf
```

設定ファイルのうち

```
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
# write_enable=YES
```
の
write_enable=YES 
のコメントアウトを外します。

また、アップロードディレクトリも変更しておきます。

```
local_root=/mnt/disk1/Pictures/
```

```bash
sudo systemctl restart vsftpd.service
```

他のPCからFTP接続してみて、接続できれば完成です。

```bash
lftp [user]@[ip]
put [file_to_path] 
```

セキュリティはあまりきちんとしていませんが、ローカルネットワークの外からは接続できないのでまぁよいでしょう。


## Flash air の設定

まずは [このサイト](https://shimesan.com/2019/01/22/flashairw-04_nas_ftp_upload/) にたどり着きました。
ここで紹介されている [リポジトリ](https://bitbucket.org/harbortronics/flashair-ftp-upload/src/master/) をダウンロードしてきて Flashair に焼き付けます。

具体的には、上記リポジトリのうち
`SD_WLAN/CONFIG` 
に wifi 設定を上書きします。

```
[Vendor]

CIPATH=/DCIM/100__TSB/FA000001.JPG
APPNAME=flashair
APPMODE=5
APPSSID=[SSID]
APPNETWORKKEY=[password]
VERSION=FA9CAW3AW3.00.01
CID=02544d535731364740dd3ae47900fa01
PRODUCT=FlashAir
VENDOR=TOSHIBA
MASTERCODE=bc6e6487577d
LOCK=1
UPLOAD=1
STA_RETRY_CT=0
LUA_SD_EVENT=/ftpupload.lua
```
[SSID] と [password] を更新します。

また、
`Settings.lua`
にFTPサーバの内容を書き込みます。

```
-- FTP Settings --
logfile   = "/FTPLog.txt"     -- Where to log output on the FA
folder    = "/DCIM"           -- What folder to upload files from
server    = "192.168.11.2"    -- The FTP server's IP
serverDir = "flashair"        -- The path on the FTP server to use.
user      = "flashair"        -- FTP username
passwd    = "[password]"   -- FTP password
delete_after_upload = false
```

上記で編集した`SD_WLAN/CONFIG` と`Settings.lua`、`ftpupload.lua` をSDカード内にコピーします。
そのあと、SDカード内に `uploaded` フォルダを作成します。

SDカードを抜き差ししながら、FTPサーバの中身を確認してみて、無事ファイルの中身がアップロードされていれば完成です。
openai gymの'CartPole-v0'を詳しく見てみる

#チュートリアルを詳しく見てみる。
https://gym.openai.com/docs/

```
import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
    env.render()
    env.step(env.action_space.sample()) # take a random action
env.close()
```

## env = gym.make('CartPole-v0')
ベクトル空間を作成する
**引数**
*id:str*
カートポールやパックンマンのような名前
*num_envs:int*
ベクトル空間の数
*asnchronous:bool*
同期か非同期か
etc...
## env.reset()
pingやcurl でエラー時にメール通知の例

## pingやcurl でエラー時にメール通知の例

```sh
#!/bin/sh

ok() {
        BODY="$1"
        NOW=$(date "+%Y-%m-%d %H:%I:%S")
        echo "OK [$NOW] ${BODY}"
}

ng() {
        BODY="$1"
        NOW=$(date "+%Y-%m-%d %H:%I:%S")
        echo "NG [$NOW] ${BODY}"
}

icmp() {
        IP="$1"
        NAME="$1"
        if [ $# -eq 2 ];then
                NAME="$2"
        fi
        BODY="icmp $NAME"
        ping -c 1 -W 3 ${IP} > /dev/null \
        && ok "${BODY}" \
        || ng "${BODY}"
}
 
http() {
        URL="$1"
        NAME="$1"
        if [ $# -eq 2 ];then
                NAME="$2"
        fi
        BODY="http $URL"
        curl -s -L --connect-timeout 3 ${URL} > /dev/null \
        && ok "${BODY}" \
        || ng "${BODY}"
}
```

```sh:check.sh
#!/bin/sh
set -eu

. ./func.sh
        
icmp 192.168.100.1 &
http 192.168.100.1 &
icmp 192.168.1.2 &
http 192.168.1.2 &
wait    
```

```sh:main.sh
# NG項目があれば何らかで通知させる
sh check.sh | grep NG && echo "mail"
```
【一番速い】jsでHTML要素を追加する方法はこれを見てくれ。

# 欲しいのはこれだろう？？

jqueryは使わない。
insertAdjacentHTMLしか載せない。
けどそれでいいだろ？


```html

①
<div id="BASE">
②
  <p>ぺぽー</p>
③
</div>
④
```

### ①　ここには「beforebegin」

```javascript
var BASE = document.getElementById('BASE');
BASE.insertAdjacentHTML('beforebegin','<p>①に入るよん</p>');
```

### ②　ここには「afterbegin」

```javascript
var BASE = document.getElementById('BASE');
BASE.insertAdjacentHTML('afterbegin','<p>②に入るよん</p>');
```

### ③　ここには「beforeend」

```javascript
var BASE = document.getElementById('BASE');
BASE.insertAdjacentHTML('beforeend','<p>③に入るよん</p>');
```

### ④　ここには「afterend」

```javascript
var BASE = document.getElementById('BASE');
BASE.insertAdjacentHTML('afterend','<p>④に入るよん</p>');
```

以上。


## 一瞬でわかるやつが欲しかった、、
「js 要素 追加」でググって3秒で答えが欲しかった。
ありがとう、たくさんの記事がヒットしてどれも丁寧に書かれてました。
**が、丁寧すぎた！**

内容量が多くて欲しい情報を探すのに時間がかかる。
実際、コーダーにはこれくらいで十分だろう？
ファイル名作成のための日付文字列を作成する  Python　vba

スクレイピングで必須なのがファイル名の作成。
ファィル名は日付+連番のケースが一番おおいでしょうか
多数の場合は日付+時刻でよいのですが、
数が少ない場合は日付+連番が一番人気なので、
ファイル名作成の方法をメモしました。

##Pythonの場合
前提
Windows
Python3.7
以下は　日付+連番のCSVファイル名を作成する場合
datetime.date.today()　をstrftimeでフォーマットすると文字列として扱えるので
希望の文字列を末尾に追加することができます。

```:python
import datetime
hizuke = datetime.date.today()
hizuke = hizuke.strftime('%Y-%m-%d')
file1 = hizuke+"-1.csv"　　#2020-08-11-1.csv　※今日の日付
file2 = hizuke+"-2.csv"    #2020-08-11-2.csv

```


[詳しい日付の書式はこちら](https://docs.python.org/ja/3.6/library/datetime.html#strftime-strptime-behavior)
https://docs.python.org/ja/3.6/library/datetime.html#strftime-strptime-behavior

##vbaの場合
```:vba
 Dim strFileNm As String
 strFileNm = Format(Now(), "yyyy-mm-dd") & "-1.csv" '2020-08-11-1.csv ※今日の日付
```

[詳しい日付の書式はこちら](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.strings.format?view=netcore-3.1)
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.strings.format?view=netcore-3.1

vbaの場合日付の書式設定がエクセルで使っているものと同じなのでなじみ深いです。
二度と忘れるな。swiperで見切れさせる方法はこれだって言ってんだろ！！

# 俺は、バカなのか...

swiperでのカルーセル案件、今までに何度もやってきただろ...
なんで見切れさせるのに毎回苦戦しているんだよ...！

二度とこいつに時間をかけなくてもいいように、ここに私の奮闘記を残します。

やりたいのはこういうカルーセル。
![スクリーンショット 2020-08-09 22.51.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67190/6a69c8dd-798d-9fe7-d341-0fdf1af95895.png)
端っこのコンテンツがちょっと見切れちゃってるようなのを実装したい時のお話です。

## slidesPerViewは小数が使えるんだ！！
つまりこう。

```javascript

var myswiper = new Swiper ('.swiper-container', {
  centeredSlides: true,
  slidesPerView: 2.2,
  spaceBetween: 16,
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
});
```

この**小数が使える**ってことと、
**「centeredSlides: true」で中央寄せにしてあげる**ってことがわかってれば一瞬。
なんてことはない。

## なんだこれはぁぁぁあ！
![スクリーンショット 2020-08-09 23.03.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67190/601e5b96-7919-a27a-07ca-cae05f3cd714.png)
中央寄せじゃなくなったとき（偶数個見せたいとき）。
これが微妙にめんどくさかった。

こうしなさい。

```javascript

var myswiper = new Swiper ('.swiper-container', {
  slidesPerView: 2.2,
  spaceBetween: 16,
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
});
```
js側ではやることはあまりない。
さっきのと比べると中央寄せの**「centeredSlides: true」を消した**くらい。

大事なのはcssで、**「.swiper-container」に対してpadding-leftを当ててあげること。**

```css
.swiper-container {
  padding-left: 125px;
}
```
みたいに。
ちゃんとそれっぽい位置になるように微調整が必要だったり、
SPとかだとpx→vwにして、、とか必要になるけど、
やり方を検討するとこまでは上でもう解決したから簡単だよね
swiperの雛形にはこれを使え！！

**※公式のフォーマットとは異なります！**
**※使えなくなるオプションがあるかもしれません！**

完全に個人用です。
よくあれこれどうやったっけと忘れて、その度時間けかちゃってるのでメモ残しておきます。

## これを、使え！！
```html
<div class="mycontainer">

  <div class="swiper-container">
    <div class="swiper-wrapper">
      <div class="item swiper-slide">1</div>
      <div class="item swiper-slide">2</div>
      <div class="item swiper-slide">3</div>
      <div class="item swiper-slide">4</div>
      <div class="item swiper-slide">5</div>
    </div>
  </div>

  <!-- ページネーション -->
  <div class="swiper-pagination"></div>

  <!-- ナビゲーションボタン -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>

</div>
```

公式と違うところは、
**マルポチやボタンが「.swiper-container」の外に出てることです。**


ここから下では、その理由とか経緯を説明していきます。


## なんでそんなことを
swiperで次へ/戻るボタンや、マルポチを公式通りの方法でhtmlを書くと、

```html

<div class="swiper-container">
  <div class="swiper-wrapper">
    <div class="item swiper-slide">1</div>
    <div class="item swiper-slide">2</div>
    <div class="item swiper-slide">3</div>
    <div class="item swiper-slide">4</div>
    <div class="item swiper-slide">5</div>
  </div>

  <!-- マルポチ -->
  <div class="swiper-pagination"></div>

  <!-- 次へ/戻るボタン -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>
```
ですね。

ただ、僕の扱う案件で多いのは、こんなデザイン。
![スクリーンショット 2020-08-09 22.35.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67190/21d820e5-6026-db41-5c6e-9df4bdbe925a.png)


緑で囲った部分が赤枠の**カルーセルエリアから飛び出している**ことがお分かりいただけるかと思います。
これ、公式のフォーマット通りの形で実現しようとするとかなりめんどくさい。

なぜか。

理由はswiperの一番外側のクラスにあたる「.swiper-container」に対して公式cssで**overflow: hidden**が当たってしまっているからです。
なので素直にフォーマットに従いつつcssでマルポチなんかのbottomを下げたとしてもこうなっちゃうわけです。
![スクリーンショット 2020-08-09 22.16.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67190/1d1bb8ba-da56-261f-9264-a2440164b222.png)
いやん！

## だから俺は外に出した
cssで公式のoverflow:hiddenを上書きして、、
とかもありかもしれませんが一番外に出しちゃうのが楽かなという結論に至りました。

つまりこうです。

```html

<div class="mycontainer">

  <div class="swiper-container">
    <div class="swiper-wrapper">
      <div class="item swiper-slide">1</div>
      <div class="item swiper-slide">2</div>
      <div class="item swiper-slide">3</div>
      <div class="item swiper-slide">4</div>
      <div class="item swiper-slide">5</div>
    </div>
  </div>

  <!-- ページネーション -->
  <div class="swiper-pagination"></div>

  <!-- ナビゲーションボタン -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>

</div>
```

これで公式cssのoverflow:hiddenから解き放たれました。
**代償として、マルポチのスタイルが死んでしまうようですが...**
![スクリーンショット 2020-08-09 22.26.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67190/a8e7439b-3c35-0173-b5cb-5474ce1c43a4.png)

ただ、案件でswiper公式のスタイルをそのまま使うことなんてないでしょう。
どうせ何かしらで上書きするのだからこんなの屁でもありません。

一応、それっぽくする修正css置いてはおきますが。

```css

.swiper-pagination {
  left: 50%;
  bottom: -40px !important;
  transform: translateX(-50%);
}
.swiper-pagination-bullet {
  margin: 0 4px;
}
```
![スクリーンショット 2020-08-09 22.33.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67190/7c3807f3-96bf-5228-508d-263e92eae2f1.png)

完璧ですね☆

※使用したswiperのバージョンは5.4.5でした。
fping - 複数ホストに対して簡単にPingチェック

## fping

* https://www.checksite.jp/fping-install/

```rb:host.txt
127.0.0.1
192.168.0.100
172.16.12.100
192.168.0.200
```

```sh
fping -f host.txt
# もしくは
fping < host.txt
```
bundle install でmysql2がインストールされない

###はじめに
僕のローカル環境で毎回エラーになるので解決策をメモします
*まだ厳密な原因はわかってませんが、とりあえずこれで通りました程度の内容です

```
$ bundle install --path vendor/bundle 
...
エラー文↓
An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
```

###解決方法

```
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
$ bundle install --path vendor/bundle
```

上記コマンドを実行すると、`.bundle/config`に下記一行が追加されます

```
BUNDLE_BUILD__MYSQL2: "--with-ldflags=-L/usr/local/opt/openssl/lib"
```
とおるようになる。
npx create-react-appで"Error: EPERM: operation not permitted, mkdir 'C:\Users\〇〇 ' command not found: create-react-app"

## 概要
node.jsをインストーラーで入れ直して直後、`npx create-react-app hoge`をした時に、

```
Error: EPERM: operation not permitted, mkdir 'C:\Users\〇〇 '
command not found: create-react-app
```

と出た時の対処法の覚書。

## 環境情報
Windows10
node.js v12.18.3

## 原因
create-react-appをすると、node.jsは自身のインストール場所に関わらず、デフォルトでC:ドライブのAppDataにcacheフォルダを作ろうとします。もしPCの名前に半角スペースが入っているとフォルダの作成に失敗するためエラーが生じます。

## 自分が行った対処法

```
npm config set cache <任意のpath> --global
```
としてcacheフォルダをパスに半角スペースを含まない場所に変えてやるといけました。
正直なところ **`--global`は必要なのかわかりませんが** ノリで付けてやったらうまいこといけてしまったので、**未検証** です。(あった方がいいのかなくても良いのか知っている人いれば教えてください)

## ちなみに
この解決法を見つけたオリジナルの[githubのissue ](https://github.com/zkat/npx/issues/146#issuecomment-384019497)
では「半角スペース以下を`~1`にすれば行ける！」みたいなことが書かれていますが自分はそれでは解決しませんでした。とりあえず、cacheの設定を`npm condig set cache`で変えれるんやなって気付きにはなりましたが。

npmの作るフォルダーに関しては以下にも載っていて、一応globalの説明もしてあります。知識がないのでよくわからないですが......↓
https://docs.npmjs.com/configuring-npm/folders.html
エスケープ文字が入った文字列のハッシュをとるときの注意点

shellで文字列のハッシュをとるときに`echo`コマンドを使用しますが、エスケープ文字が入っている場合の注意事項です。
勉強がてら[AWS 署名バージョン4](https://docs.aws.amazon.com/ja_jp/general/latest/gr/sigv4_signing.html)を自分で計算するスクリプトを書いていた時に遭遇したので、そのメモ書きになります。
署名アルゴリズムに関しては上記リンクを参照してください。

## 遭遇した事象

シグネチャを生成する時に正規リクエスト（メソッドやヘッダなどを`\n`でつなげたもの）のハッシュが必要になります。このとき、次のような文字列を生成してハッシュをとる操作をしました。

```shell
CANONICAL_REQUEST="${METHOD}\n${CANONICAL_URI}\n${CANONICAL_QUERY_STRING}\n${CANONICAL_HEADERS}\n${SIGNED_HEADERS}\n${REQUEST_PAYLOAD}"
HASHED_CANONICAL_REQUEST=`echo -n ${CANONICAL_REQUEST} | openssl dgst -sha256 | awk '{print $2}'`
```

ところが、この操作を経由して生成されたシグネチャが通らず。
当時はここが悪いと考えておらず、問題個所の特定に苦労しました…

## 原因と解決策

`echo`コマンドはデフォルトでエスケープ文字を解釈しない（=`-E`オプションをつける）設定になっています。AWSの署名の場合はエスケープ文字を解釈する必要があるので、`-e`オプションをつけてエスケープ文字を解釈させましょう。
次の例ではエスケープ文字を解釈する/しないによってハッシュが変わることがわかりますね（当然ですが）。

```shell
$ TEXT="hoge\nfuga"
$ echo -n ${TEXT} | openssl dgst -sha256 | awk '{print $2}'
074659bf99be27ea41e727fda69060e866fe4fd0ab0fab5bd6dc1fb24a4ad246
$ echo -E -n ${TEXT} | openssl dgst -sha256 | awk '{print $2}'
074659bf99be27ea41e727fda69060e866fe4fd0ab0fab5bd6dc1fb24a4ad246
$ echo -e -n ${TEXT} | openssl dgst -sha256 | awk '{print $2}'
91601213bfcbda65e36673d1c92b6306f548cd196117682594715a11c5b6e671
$ 
```

これで認証が通るようになりました。
生成されたハッシュが正しいかどうかの確認はサンプルでも持っていない限り大変なので、同じ事象に遭遇した人に少しでもヒントになればと思った次第です。事象としては何も難しいことはありませんが、署名アルゴリズムなどのようにハッシュが必要になる場合は注意が必要ですね。
【Flutter】アプリ名とアイコンの変更

# アプリ名の変更
アプリ名の変更はAndroid,iOSで変更方法が異なります。

```
//Androidの場合
 android/app/src/main/AndroidManifest.xmlの android:labelを書き換え
//iOSの場合
 ios/Runner/info.plistの keyがCFBundleNameの文字列を書き換え
```

※pubspec.yamlのnameを書き換えることで共通で変更する方法もあります。
ただし、こちらは名前がキャメルケース出ないといけないです。

# アイコンの変更

## 1,画像を作成する。
　アイコンのサイズは512×512で作成します。

## 2,アイコンを変更する
flutterの公式ドキュメントにflutter_launcher_iconsを使用する方法が記載されています。

1,ファイルを編集

```pubspec.yml
dev_dependencies:
  # ・・・省略・・・
  flutter_launcher_icons: ^0.7.4

flutter_icons:
  android: true
  ios: true
  image_path: 'lib/assets/icon.png'
```

備考:
AndroidとiOSで画像を分けたい場合やアダプティブアイコンを使用したい場合は、
image_pathの部分を下記のように記述します。

```pubspec.yml
  # image_path: 'lib/assets/icon.png' を↓に変更する。
  image_path_android: 'lib/assets/android_icon.png'
  image_path_ios: 'lib/assets/ios_icon.png'

  # アダプティブアイコンを使用したい場合はbackgroundとforegroundの2種類を設定
  adaptive_icon_background: 'lib/assets/background.png'
  adaptive_icon_foreground: 'lib/assets/foreground.png'
```

参考:こちらのAttributeのところに詳細な説明が記載されています。
https://pub.dev/packages/flutter_launcher_icons

2,コマンドを打つ(インストールと画像生成コマンド)

```sh
# インストールする
 flutter pub get
# 画像を生成する　これを忘れないように！
 flutter pub run flutter_launcher_icons:main
```

3,起動する

```sh
 flutter run
```

# 備考(アプリのアイコンデザインについて)
アイコンデザインに関しては下記のガイドライン等が参考になります。
よかったら見てみてください。

googlePlayIconのアイコンデザイン仕様。
https://developer.android.com/google-play/resources/icon-design-specifications?hl=ja
 iOSのアイコンデザイン仕様。
https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/app-icon/
PyhonのスクレイピングでTorを使用してChromeにアクセスする

Pyhonのスクレイピングを勉強中です。今回はTorを使用して、Chromeにアクセスする方法をメモします。なお、Torを使用して何かやらかしても、この記事とぼく個人の一切の責任をおいません。

## Seleniumをインストール

seleniumをpipでインストール
Selenium公式サイト: https://pypi.org/project/selenium/

```
$ pip install selenium
```

seleniumとセットで使用する**os**ライブラリは、Pythonをインストールしたらデフォルトで入っているみたいなので、割愛します。
osライブラリの参考: https://www.lifewithpython.com/2013/03/os-module.html

## ソース

```py3:tor_accessor.py
import os
from selenium import webdriver

# オプションでPROXYを設定
PROXY = "socks5://localhost:9050"
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_argument("disable-infobars")
options.add_argument("--disable-extensions")
options.add_argument('--proxy-server=%s' % PROXY)
driver = webdriver.Chrome(chrome_options=options, executable_path="/usr/local/bin/chromedriver")

# Torが設定されているかを確認するサイトを開く
driver.get("http://check.torproject.org")
```

実行

```
$ python tor_accessor.py
```


ちゃんとTorを介したら、この画面になる
<img width="1188" alt="スクリーンショット 2020-08-11 4.04.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/afa1c0f4-00a9-9acd-58e2-7cd58eb49430.png">

> Congratulations. This browser is configured to use Tor.

Google翻訳: おめでとう。このブラウザーはTorを使用するように構成されています。

---

Torを介してないと、この画面のように玉ねぎにバッテンがつく
<img width="1440" alt="スクリーンショット 2020-08-11 4.05.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/f1200eb1-6fc1-0449-982b-f6af3fb162c2.png">

> Sorry. You are not using Tor.

ごめんなさい。あなたはTorを使っていません。

関連記事
[【Pyhon】Torを使用してスクレイピングする](https://qiita.com/___xxx_/items/f0fc3385c2d08eb63f0f)

参考
https://www.366service.com/jp/qa/81b67eb666ad284089fd2ea7e04d6f3d

Torを介しているかチェックするサイト
http://check.torproject.org
【Pyhon】Torを使用してスクレイピングする

今回はTorを使用したスクレイピングについてのメモです。Torを使用して何かやらかしても、この記事と個人の一切の責任をおいません。

## Torとは

盗聴防止やプライバシー保護を目的に開発されたブラウザです。オニオンルーティングと呼ばれる技術で、接続ルートをほぼ匿名化できます。ダークウェブに接続する際のブラウザとして有名です。

## TorをHomebrewでインストール

```
$ brew install tor
```

サーバーを動かす

```
$ brew services start tor
```

### Torを使用してWebページに複数のGETリクエストを送信

Torを使用して、スクレイピングのリクエストを送信するコードを紹介します。

### Requests版

ソフトウェアパッケージ**Requests**をインストール
https://requests-docs-ja.readthedocs.io/en/latest/user/install/

```
$ pip install requests
```

ソース

```py3:tor.py
import requests

def get_tor_session():
    session = requests.session()
    session.proxies = {'http':  'socks5://127.0.0.1:9050',
                       'https': 'socks5://127.0.0.1:9050'}
    # こっちでもいい
    # session.proxies = {"http": "socks5://localhost:9050", "https": "socks5://localhost:9050"}
    return session

# Torを使用した場合
print('Torした')
session = get_tor_session()
print(session.get("http://httpbin.org/ip").text)

# Torを使用していない場合
print('Torしてない')
print(requests.get("http://httpbin.org/ip").text)
```

ターミナルで実行

```
$ python tor.py
```

出力結果

```
$ py proxy.py
Torした
{
  "origin": "185.220.101.209"
}

Torしてない
{
  "origin": "126.224.155.158"
}
```

関連記事
[PyhonのスクレイピングでTorを使用してChromeにアクセスする](https://qiita.com/___xxx_/items/419a86ea2d3d1ab9f415)

参考
https://www.thepythoncode.com/code/using-proxies-using-requests-in-python
https://2019.www.torproject.org/docs/faq.html.en#torrc
https://www.it-swarm.dev/ja/python/tor%E3%81%A7python%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%92%E8%A1%8C%E3%81%86/1053483225/
https://www.366service.com/jp/qa/81b67eb666ad284089fd2ea7e04d6f3d
https://qiita.com/koharite/items/731fcf5146c7b0c4e800
firebaseのターゲットの確認とデプロイ

#firebaseへのデプロイ方法
firebaseへのデプロイはcliによって行います。
手動でプロジェクトを複数切り替える場合、コマンドを忘れがちなので備忘録として



# firebasecliのインストール

```
npm install -g firebase-tools
```


# コマンド集
いろんなプロジェクトをいじっていると忘れてしまうので備忘録

```
//アクセス権のあるプロジェクトのリストを表示
firebase projects:list

//デプロイ先の切り替え
firebase use <ProjectId> //ProjectIdは上のコマンドで確認

//ログアウトする
firebase logput

//ログインする
firebase login

//ローカルでデプロイできるようにする
firebase init
```
idle速度の改善（Webの表示速度を意識する1）

#今読んでいる本。
[Webフロントエンド ハイパフォーマンス チューニング](https://www.amazon.co.jp/dp/B0728K5JZV/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

気になったところをまとめていきたいと思い書きます。その１。

ーーーーーーーーーーーーーーーーーーー

いくつかのポートフォリオサイトを検証ツールでみてみたところ、あるサイトだけ数値上「idle」のところが非常に時間がかかっておりました。

**idleとは**
*responseやanimation、Loadが終わった後に、ユーザーのアクションを待っている状態*
のことらしい。

では、「ユーザーのリアクションを待つ」状態がなぜ特定のサイトだけ長くなるのか？というと

>最近のブラウザのレンダリングエンジンは、jsの処理とユーザーからのアクションを同じメインスレッドで実行しているため、
webページが何も処理を行っていないように見えても、裏側でjsが実行されているとユーザーからの入力が遅延される。。。

とのこと。（前述の本より）


それを踏まえてサイトを見てみると、確かに、最初にJqueryのsettimeoutで「アニメーションでボワっ」と文字を出して、その後に操作を受け付けるようにしています。
このタイミングが少し長いのが原因かも、、？と思い半分にしてみたところやっぱりここが原因で、速度が2200ミリ秒弱短くなりました。

![スクリーンショット 2020-08-11 2.38.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/725ba354-f723-f9e0-211a-3a4335166060.png)、

![スクリーンショット_2020-08-11_0_34_31_png-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/e5d10b2e-badc-fdd9-d55a-e405ef993074.png)

例えば逆に5倍くらいの長さにすると、もちろんidolの値はグッと伸びました。し、体感ももちろん長く感じました

ーーーーーーーーーーーーーーーーーーーー

###じゃあもっと短くしてもいいんじゃない？

確かにそれも一つの選択肢ですが、
・サイト訪問時に間を持たせた動きをつけて目をひきたい
・そもそもどれくらいの長さが妥当なのかは主観

という考え方や、そもそもコンテンツの読み込みデータ量が多くて、
最初にアニメーションをわざと表示させてる間に読み込ませている、、、といったケースもあると思います。（ローディングアニメーションなど。読み込み中で何も表示されないより個人的には良いと思います。）

そんな感じで必ずしも一瞬で終わるアニメーションが良いとも限らないんじゃないかなと思ったりしています。

そして速度を遅いと感じるかどうかは主観であるところが大きいので、
感覚ではなく、数値で見ようというのが今回使った検証ツールのPerformanceでした。
Rails Tutorialを咀嚼する【第1章ゼロからデプロイまで】前半

# 1.1 はじめに
■REST
SQLでよく使う「Create/Read/Update/Delete」をそれぞれ「GET/POST/PUT/DELETE」に当てはめたもの。セッションなどの状態管理を行わないため、命令をいちいち書いていく必要がある。
基本的には「route.rb」に記載する。

■コマンドライン
ターミナル。クラウドIDEに標準的に備わっている。

#1.2 さっそく動かす
■Cloud9
AWSが提供しているクラウド上で開発可能な統合開発環境。面倒な環境設定もいらないため超便利

■gem
パッチファイル？追加要素？みたいなもの。「Gemfile」というファイルに記載して、bundle installとターミナルに打ち込むと自動でインストールしてくれる。

#1.3 最初のアプリケーション
■rails new
Railsを使ってアプリケーションを作る際に初めに書く呪文。必要なファイルを自動で生成してくれる。

■フレームワーク
Railsがフレームワーク。エディタがあれば自由にプログラミングできるが、将来的にめちゃくちゃな書き方になってしまうため、「ある程度書き方を揃えましょうね」というもの。
Rubyで書くと何十行も掛かる処理をRailsを使えば独自の短い表現で同じ処理ができる。まだ実感値はない。

■gameごとのバージョン
バージョンが違うと挙動も違う可能性があるので、バージョンを固定させて開発をした方が良い。
spring 2.0.2がインストールできないときは「bundle update spring」を打ってから再度インストール。

【演習】
railsサーバーを立ち上げれた先に書いてある。

■MVCモデル
どこにどのファイルを置くのかを定義した概念。本来どこに何を置いてもいいが、後々管理が面倒になるため、ある程度統一性をもって書こうというもの。
どこに何を書くべきかという実感値はまだない。

■renderメソッド
レスポンスの出力をするメソッド。コントローラーでもビューでも使う。

■メソッド
関数。defとendの間に挟んで使う。
呼び出すときは定義したメソッド名を書く。

■routes.rb
どのリクエストにはどのページを返すか、を記載する。
基本的にはコントローラーを記載するのかな？

■1.3.4 Hello, world!に書き換える
最初の「Yay!You're on Rails!」をHello, world!に書き換える。
今回は大した内容じゃないので恐らくビューはいじらない。
「hello, world!」というHTMLを表示する、というrenderメソッドをコンロトーラーで定義して、
rootをhelloメソッドにする。

【演習】
1.文面を変えればOK
2.Windowsだから表示の仕方が分からないため跳ばす。
3.

```ruby:app/controllers/application_controller.rb
def goodbye
    render html: "goodbye, world!"
end
```

```ruby:config/routes.rb
Rails.application.routes.draw do
  root 'application#goodbye'
end
```
こんな感じ。
ルート権限の無いCentOSにOpenMPIを野良ビルドする

# はじめに
[root権限の無いCentOS7.3＆GCC-4.8.5の環境に野良ビルドしたGCC-9.3.0](https://qiita.com/yonedat/items/78baf03597fe2341fbf8)を基に，次はOpenMPI-3.1.6を構築してみたいと思います。

# 準備
OpenMPIとlibpciaccessを以下からダウンロードしておきます。

https://github.com/freedesktop/xorg-libpciaccess
https://www.open-mpi.org/

今回用いたバージョンは，libpciaccess-0.13.5，openmpi-3.1.6です。
私の環境では，ファイル操作用1つ，計算用2つの計3つのログインノードがありますが，計算用のログインノードでOpenMPIをビルドするとOmni-Pathが有効になるようです。また，計算用にはGPUもあるようです。詳しいことは良くわかりませんが，事前にlibpciaccessをビルドしておくと，OpenMPIのCUDAも有効にしてビルドできました。

# libpciaccessのビルドとインストール
[前回のGCC-9.3.0](https://qiita.com/yonedat/items/78baf03597fe2341fbf8)と同様に，$HOME/toolsにインストールを行います。

```
tar xfv libpciaccess-0.13.5.tar.bz2
mv libpciaccess-0.13.5 ~/tools/pciaccess_work
cd ~/tools/pciaccess_work
mkdir build
cd build
../configure --prefix=$HOME/tools/libpciaccess-0.13.5 CC=$HOME/bin/gcc93 CXX=$HOME/bin/g++93
make -j 12
make install
```
インストール完了後，.bash_profileに以下を追記します。

```
export PKG_CONFIG_PATH=$HOME/tools/libpciaccess-0.13.5/lib/pkgconfig:$PKG_CONFIG_PATH
```


# OpenMPIのビルドとインストール
次に，OpenMPIも，＄HOME/toolsにインストールを行います。"--with-cuda"オプションを設定してみました。

```
tar xjf openmpi-3.1.6.tar.bz2
mv openmpi-3.1.6 openmpi_work
cd openmpi_work
mkdir build
cd build
../configure --prefix=$HOME/tools/openmpi-3.1.6-gcc93 CC=$HOME/tools/gcc-9.3.0/bin/gcc CXX=$HOME/tools/gcc-9.3.0/bin/g++ F77=$HOME/tools/gcc-9.3.0/bin/gfortran FC=$HOME/tools/gcc-9.3.0/bin/gfortran LDFLAGS="-L$HOME/tools/gcc-9.3.0/lib64" CPPFLAGS="-I$HOME/tools/gcc-9.3.0/include" --with-cuda
make –j 48
make install
```
なお，configure完了後のメッセージは以下でした。よくわからないですが，ビルドは最後までできたので問題無いのではと思います。

```
Open MPI configuration:
-----------------------
Version: 3.1.6
Build MPI C bindings: yes
Build MPI C++ bindings (deprecated): no
Build MPI Fortran bindings: mpif.h, use mpi, use mpi_f08
MPI Build Java bindings (experimental): no
Build Open SHMEM support: yes
Debug build: no
Platform file: (none)

Miscellaneous
-----------------------
CUDA support: yes
PMIx support: internal

Transports
-----------------------
Cisco usNIC: yes
Cray uGNI (Gemini/Aries): no
Intel Omnipath (PSM2): yes
Intel SCIF: no
Intel TrueScale (PSM): yes
Mellanox MXM: no
Open UCX: no
OpenFabrics OFI Libfabric: yes
OpenFabrics Verbs: yes
Portals4: no
Shared memory/copy in+copy out: yes
Shared memory/Linux CMA: yes
Shared memory/Linux KNEM: no
Shared memory/XPMEM: no
TCP: yes

Resource Managers
-----------------------
Cray Alps: no
Grid Engine: no
LSF: no
Moab: no
Slurm: yes
ssh/rsh: yes
Torque: yes

OMPIO File Systems
-----------------------
Generic Unix FS: yes
Lustre: no
PVFS2/OrangeFS: no
```
インストール完了後，以下を.bash_profileに以下を追記しました。

```
MPIROOT=$HOME/tools/openmpi-3.1.6-gcc93
PATH=$MPIROOT/bin:$PATH
LD_LIBRARY_PATH=$MPIROOT/lib:$LD_LIBRARY_PATH
MANPATH=$MPIROOT/share/man:$MANPATH
export MPIROOT PATH LD_LIBRARY_PATH MANPATH
```
以上で，GCC-9.3.0ベースのC，C++，FortranのOpenMPIができました。
Laravel 6.x CasherでStripe決済するときに参考になる資料

#やりたいこと
Laravel 6.xでCasherを用いてstripeから決済をしたい

#問題
6.x未満の古い記事がおおいのと、ドキュメントから動作を想像しづらい

#1.翻訳ドキュメント
おなじみのreadouble
インストールや設定等、基本的にはここのを行えばいいが
イメージがしづらい

https://readouble.com/laravel/6.x/ja/billing.html

#2.Youtube

https://www.youtube.com/watch?v=OtLmqDpH-C8

こちらの動画が公式ドキュメントに沿って行っているのでイメージがしやすい
翻訳ドキュメントとと合わせると良い感じ

##詰まったところ

###郵便番号を非表示に
https://blog.ichikaway.com/entry/2019/05/29/180537
https://stripe.com/docs/js/elements_object/create_element?type=card

###サブスクリプションでIdが必要だが、[No such plan]となった

https://takkublog.net/no-such-plan/
dockerの起動中に起きたエラー

railsアプリを立ち上げるためにdocker-compose buildを実行しようとすると次のエラーが出た。

```
$ docker-compose build
Building db
Step 1/4 : FROM mysql:8.0.17
 ---> b8fd9553f1f0
Step 2/4 : RUN apt-get update &&  apt-get install -y apt-utils
：
：
Fetching spring 2.0.2
Installing spring 2.0.2
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
  current directory: /usr/local/bundle/gems/nokogiri-1.10.9/ext/nokogiri
/usr/local/bin/ruby -r ./siteconf20200529-6-18ba5hy.rb extconf.rb
Cannot allocate memory - /usr/local/bin/ruby -r ./siteconf20200529-6-18ba5hy.rb
extconf.rb 2>&1
：
：
An error occurred while installing nokogiri (1.10.9), and Bundler cannot
continue.
Make sure that `gem install nokogiri -v '1.10.9' --source
'https://rubygems.org/'` succeeds before bundling.
：
```

nokogiri?
gemファイルに記述した覚えは無いが、、

エラー分にあるとおりnokogiriのインストールを試みたが、同様のエラーがでた。
```$ gem install nokogiri -v '1.10.9'```

調べると次の記事にあるように、容量不足によるエラーの可能性があるかもしれない。
https://qiita.com/HrsUed/items/c156ed69e927b6165717
記事通り容量を増加させたが、違うエラーが発生した。

```
$ docker-compose up -d
：
ERROR: Service 'web' failed to build: failed to register layer: Error processing tar file(exit status 1): write /usr/lib/x86_64-linux-gnu/libx265.so.165: no space left on device
```

エラーメッセージで調べると以下の記事が参考なった。
https://scrapbox.io/tsuchinaga/Docker%E3%81%A7%E5%AE%B9%E9%87%8F%E4%B8%8D%E8%B6%B3%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B
```$ docker volume rm $(docker volume ls -qf dangling=true)```

説明通りコマンドを実行するとbuildが成功した。
Rustでクリップボードと画像のやりとりを行う

Rustでクリップボードと簡単に画像をやりとりできるクレートを作りました。

<a href="https://github.com/moisutsu/imboard"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/moisutsu/imboard.png" width="460px"></a>

こちらの記事を参考にさせていただきました。
[Goで画像をクリップボードに保存、読み取るライブラリを作った](https://qiita.com/gorilla0513/items/8fccca2bd24cd2ca9cb9)

# はじめに

プレゼンの資料を作るときに背景が白でないテーマを使っています。なので背景が白い画像の[背景を透過させるコマンドラインツール](https://github.com/moisutsu/touka)をRustでつくりました。

現在は、背景を透過したいファイルをコマンドライン引数で与えると`output.png`として出力するという仕様になっています。

しかし、スクショを資料に貼りたいときなどいちいちファイルに保存したりするのは面倒くさいので、クリップボードの画像を透過してそのままクリップボードに保存したら便利だなと思いました。(まだ実装してません)

なので[この記事](https://qiita.com/gorilla0513/items/013aea9060bca1455137)を参考にRustでクリップボードと画像を簡単にやり取りできるクレートを作りました。

# 使い方

[anyhow](https://docs.rs/anyhow/1.0.32/anyhow/)と[tokio](https://docs.rs/tokio/0.2.22/tokio/index.html)と[image](https://docs.rs/image/0.23.8/image/)を使っています。

クリップボードの画像を`clipboard.png`としてファイルに出力する。

```rust
use anyhow::Result;

#[tokio::main]
async fn main() -> Result<()> {
    let img = imboard::copy_image::from_clipboard().await?;
    img.to_rgba().save("clipboard.png").unwrap();
    Ok(())
}
```

ファイルの画像をクリップボードにコピーする。

```rust
use anyhow::Result;

#[tokio::main]
async fn main() -> Result<()> {
    let img = image::open("path/to/image")?;
    imboard::copy_image::to_clipboard(img).await?;
    Ok(())
}
```

# 最後に

このクレートは今のところmacOSにしか対応していません。やる気があればWindowsとLinuxにも対応させようと思っています。プルリクなど大歓迎なのでよろしくお願いします。
【Unity】WebGLビルドで「<N> FS.syncfs operations in flight at once, probably just doing extra work」警告が出て処理が止まった時に考えられる事

UnityでWebGL書き出ししたプロジェクトが実行途中で止まる事案が発生しました。
Chrome、Firefoxのデベロッパーツールのコンソールに以下のWarningが出力されたところで処理が中断していました。

```error
warning: 2 FS.syncfs operations in flight at once, probably just doing extra work
```
本記事はこの警告の対処法備忘録です。

## ファイルシステム使用で処理が止まる

[warning: <x> FS.syncfs operations in flight at once, probably just doing extra work](https://forum.unity.com/threads/warning-x-fs-syncfs-operations-in-flight-at-once-probably-just-doing-extra-work.447255/)
だいぶ前のフォーラムですが、FPSは下がるが無害という情報が見つかりましたが、僕の環境では処理が止まってしまいました。もしかしたら、先の警告が直接の原因ではないかも知れません。

[System.IO - DirectoryInfo not working in WebGL](https://answers.unity.com/questions/1588299/systemio-directoryinfo-not-working-in-webgl.html)
またWebGLビルドでは`Syste.IO`でファイルシステムにアクセスができないというとで、心当たりのあるコードを探ることにしました。




以下のようなローカルのJSONファイルをロードしてデシリアライズする処理を書いていた場合、先の警告が出力されて処理が止まります。

```SampleLocalSave.cs
public T LoadLocalData(string path) where T : class
{
    try
    {
        using (var sw = new StreamReader(path))
        {
            var json = sw.ReadToEnd();
            return JsonUtility.FromJson<T>(json);
        }
    }
    catch (System.Exception e)
    {
        Debug.LogError($"Error: {path} | {e.Message}");
    }
    return null;
}
```

## WebGLでファイルシステムを使わないように切り分ける

```SampleLocalSave.cs
public T LoadLocalData(string path) where T : class
{
#if UNITY_WEBGL
    // WebGL用の代替処理
    return null;
#else
    try
    {
        using (var sw = new StreamReader(path))
        {
            var json = sw.ReadToEnd();
            return JsonUtility.FromJson<T>(json);
        }
    }
    catch (System.Exception e)
    {
        Debug.LogError($"Error: {path} | {e.Message}");
    }
    return null;
#endif
}

```

上記のようにWebGLビルド時はファイルシステムを使わないようにする事で一時的ですが回避する事ができ、WebGL書き出しのアプリが動くようになりました。
※代替処理は後で考えます。

## 最後に

[Unity1週間ゲームジャム](https://unityroom.com/unity1weeks)[^1]に向けてWebGLビルド検証をしていた矢先のトラブルでした。結構時間を使ってしまいましたが、開始初日で起きた事が幸いでした。

[^1]: 期間2020年08月10日(月) 00:00 〜 2020年08月16日(日) 20:00

扱った事のない技術の場合は、まず最初に仕様を把握して**納品するための環境を整えておく事**が大事だなと思いました。納品環境さえ整えば、残り時間はフルでモノづくりに集中できます。

## 環境

- Unity2020.1.0f1


## 参考

- [Unity WebGLでできそうでできないこと](https://www.m-craft.com/2016/07/unity-webgl/)
- [SafariでWebGL内のファイルが保存ができない](http://mokuapps.com/develop/?p=703)