OmniAICreator/Qiita-1.07M huggingface dataset:
Rustでジェネリクスを扱う

# ジェネリクスとは

```
ジェネリック（総称あるいは汎用）プログラミング（英: generic programming）は、
具体的なデータ型に直接依存しない、抽象的かつ汎用的なコード記述を可能にする
コンピュータプログラミング手法である。
```
source: [ジェネリックプログラミング(wiki)](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%83%83%E3%82%AF%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)

今回説明するのは、様々な言語で存在する **Generics** をRustで記述する場合どうするか、というものです。
ジェネリクスについて細かな説明は本記事では省略しますが、ざっくり説明すると **定義段階で細かく指定は行わず、汎用的に定義** する方法についての説明です。

実際にコードを見た方が伝わりやすいかと思いますので、早速Rustにおけるジェネリクスの書き方を見てみましょう。
（とは言うものの他の言語と大差ない書き方なので型付け言語経験者の方は読む必要はないかと思います。）

また、本項ではジェネリクスの記述について `T` や `U` を用いて説明しておりますが、あくまで慣例にしたがっているだけにすぎません。
サンプル上ではT, Uと書いてあっても、実際は全く別の文字列（例えばYだろうがAだろうが) でも動きます。
慣例について詳しい話は [こちら](https://qiita.com/tikidunpon/items/615a939f887094bcac7f) の記事で説明されていました。
*今回記事を書くにあたり参考にさせていただきました。*

# 構造体 （struct） でジェネリクス

例えば以下のようなキーが共通な二つの構造体を定義しているとします。

```rust
// i32型の座標を保持するストラクト
struct IntPoint {
    x: i32,
    y: i32,
}

// f32型の座標を保持するストラクト
struct FloatPoint {
    x: f32,
    y: f32,
}


fn main() {
    let integer = IntPoint { x: 5, y: 10 };
    let float = FloatPoint { x: 1.0, y: 4.0 };
}
```

上記のでは二つの構造体の定義 **IntPoint** と **FloatPoint** があり、
構造体のKey **[x]** と **[y]** が共通しています。
こういった **Keyが共通している** 場合にジェネリクスを用いて定義をまとめることが可能です。

では、構造体をジェネリクス型にしてまとめてみます。

```rust
struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    let integer = Point { x: 5, y: 10 };
    let float = Point { x: 1.0, y: 4.0 };
}
```

それぞれのKeyに対して **T** を付与することでそれぞれの値も動的に変わることを示しています。

ただし、上記の定義の仕方の場合、xとyそれぞれ型が異なる場合はコンパイルエラーになってしまうので注意が必要です。

```rust
struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    let wont_work = Point { x: 5, y: 4.0 };   // x、yで異なる型の値を指定している
}

----------------------------------------
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
 --> src/main.rs:7:38
  |
7 |     let wont_work = Point { x: 5, y: 4.0 };
  |                                      ^^^ expected integer, found floating-point number
```

上記のようにx,yそれぞれで型が異なる場合は以下のように記述することで解決が可能です。

```rust
struct Point<T, U> {
    x: T,
    y: U,
}

fn main() {
    let both_integer = Point { x: 5, y: 10 };
    let both_float = Point { x: 1.0, y: 4.0 };
    let integer_and_float = Point { x: 5, y: 4.0 };
}
```

# enum(列挙型)でジェネリクス

enumでも記述方法は同じです。

```rust

enum Option<T> {
    Some(T),
    None,
}

enum Result<T, E> {
    Ok(T),
    Err(E),
}
```

# さいごに

他にもメソッドに対するジェネリスクの書き方や、実際にジェネリクスにした時のパフォーマンスについてなどいろいろありますがZEROBILLBANKといたしましては一緒に働く仲間を募集中です。声を大にして言いたい。

Node.jsとか、ブロックチェーンとか、kubernetesとかでいろんなAPIを作るお仕事。
今のところエンジニアは5人くらい。スタートアップだけど、結構ホワイトで働きやすいです。

[ZEROBILLBANK JAPAN Inc.](https://zerobillbank.com/)
Laravelでクエリ文字列（URLの末尾に?id=1とか付け足すやつ）を生成するには？

#やりたいこと
口コミサイトを制作しています。今回は、
1. ユーザーが自分が投稿した口コミをポチッと選択すると、
2. 口コミ編集ページに飛んで、
3. その口コミのレコードをDBから呼び込んで表示し、
4. それを編集できる

という機能を実装したいです。
Laravelの某教科書を参照したところ、3,4は説明があってありがたいのですが、1,2のプロセスに関しては「/person/edit/id=番号というように、idパラメータを付けてアクセスをして下さい」と、要は「君の手でレコードのidをURLで打ってみ？表示されるべ？」で終わっていて、まさか自分のサービスを使ってくれるユーザーに直接手で/edit/id=XXとか打たせるわけにはいかないので、自分で考えて作ってみました。

私たち教わる側も、「教科書は絶対的であり、A->Zまで全てを教えてくれる！」という姿勢を改めないといけませんね。教科書も私たちに考える余白を与えてくれていると前向きに考えた方が良さそうです。

環境：Laravel 7.26.1、Eloquent ORM（DBクラスで実装している方も参考になると思います！）
#やってみた
最初から解決方法を書きますが、超シンプルです。しかもこのステージまで来れた方なら既にDBのレコード（投稿内容でもユーザー名でも何かしら）をブラウザに表示することには成功していると思うので、もしそうなら本当に一瞬です。

今回は投稿を例にとって説明を続けていきます。

要は、ユーザーがある特定の投稿の編集ボタンを押したら、`?id=番号`のURLを生成すればいいわけです。URLにパスを渡すのはHTMLのaタグさんちのhref属性くんの仕事です。

なので、だいぶ簡易的にコードを書きますがbladeでこんな感じ↓にすればOKです。（`$items`、`$itemは後で説明します）

```html:index.blade.php
@foreach ($items as $item)
<div>{{$item->title}}</div>
<div>{{$item->text}}</div>
<a href="edit?id={{$item->id}}">編集する</a>
@endforeach
```
こんな風に、href="edit"に`?id={{$item->id}}`を加えるだけです。
titleとtextは投稿のタイトルと本文で、この記事にたどり着くような方だったらもう既にこのようなプログラムは書けていると想像します。
$itemは今回下記のようにコントローラ内で定義したDBのレコードが代入されています。

```php
class ReviewController extends Controller
{
    public function index(Request $request)
    {
        $items = Review::all(); //投稿の格納されたreviewsテーブルにアクセスするReviewモデルからレコードを取得
        return view('index', ['items' => $items]); //views直下のindexファイルにitemsという名前で$itemsを渡して返す
    }
```
この状態でindex.blade.phpで「編集する」リンクをクリックすれば、当該レコードのidの番号を持ったクエリ文字列（edit?id=1）が生成されるはずです！

ちなみに、ルートのアドレスが気になるところですが、下記のように`?id=番号`的なものをつけずに'edit'のままでも、うまくページ遷移しました。

```php
Route::get('edit', 'ReviewController@edit');
```

以上になります。
もしわかりづらい点、誤りなどなど、何かご指摘あれば、ぜひコメント下さい！
【AWS SOA】認証情報レポートの備忘録

#はじめに
SOAの試験にあたって、IAM認証情報レポートに関する問題が問題集で出題された。SAAでは見なかったもので、備忘録としてIAM認証情報レポートとは何かを簡単に記載したい。

#認証情報レポートとは？
ユーザーと、ユーザーの各種認証情報 (パスワード、アクセスキー、MFA デバイスなど) のステータスが示された認証情報レポートを生成し、ダウンロード可能。
認証情報レポートがどこから入手できるかで、IAMから取れるということを覚えておこう。

#入手方法
IAM>認証情報レポートを開き、レポートをダウンロードを押すとレポートが出る。
![スクリーンショット 2020-09-18 18.36.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/2162ac81-1cdd-fb4d-a906-a18f039795ec.png)

参考
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_getting-report.html
UnityでSQLiteを使う ～ SQLiteUnityKit拡張ライブラリ

# おことわり
この記事には[新しい版](https://github.com/tetr4lab/SQLiteUnityKit) (GitHub)が存在します。

## SQLiteUnityKit を下敷きにしたライブラリ
- 数多あるSQLiteUnityKitの改修のひとつです。
- [リポジトリ](https://github.com/tetr4lab/SQLiteUnityKit) (GitHub)

### 特徴
- 日本語が使えるようにしました。
- トランザクション処理に対応しました。
- バインド変数に対応しました。
- 既存DBを上書きしないようにしました。(かといって、マージもしません。)
- オープンやクローズ、リソースの開放などといった低レベル処理は隠蔽して、抽象化レベルの高い処理だけを表に出すようにしました。
- できるだけ例外は内部で捉えて、リソースの未解放を避けて動き続けるように務めました。

## 前提
### 環境
- Unity 2021.3.2f1 (LTS)
- SQlite 3.33.0
- C# 6
    - 文字列補完(string interpolation)を使用しています。
    - 必要なら、`PlayerSettings`で`Scripting Runtime Version`を`4.x`に設定してください。

### SQLite
- SQLiteは、SQLのサブセットが使えるスタンドアローンなデータベース管理システムです。
    - Windows、MacOS、Android、iOSなどに対応しています。
- [公式サイト](https://www.sqlite.org/index.html)

### SQLiteUnityKit
- SQLiteUnityKitは、UnityからSQLiteを使用するためのフレームワークです。
- [リポジトリ](https://github.com/Busta117/SQLiteUnityKit) (GitHub)

## 導入と概要
- リポジトリから`Assets`をプロジェクトへ導入してください。

### 概要
- `Assets/Plugins/sqlite3/`
    - 各プラットフォーム向けのSQLiteプラグインです。(iOSはOS側でサポートがあります。)
- `Assets/Scripts/`
    - `SQLiteUnity.cs`
        - 必須部分です。
    - "SQLiteUnityUtility.cs"
        - 拡張ユーティリティクラスです。お好みでどうぞ。
        - トランザクションでも擬似的なバインドが使えるようになっています。
    - "Test.cs"
        - デモ用スクリプトです。
- `Assets/Prefabs/Console.prefab`
    - デモ用プレハブです。
- `Assets/Scenes/SQLite_Test.unity`
    - デモ用シーンです。

### 最新プラグインへの更新
- [公式サイトのダウンロード](https://www.sqlite.org/download.html)から最新版を取ってきて`Assets/Plugins`へ導入してください。
- Androidについては、[こちらの記事(Qiita)](https://qiita.com/tetr4lab/items/729008c94daaff82833e)を参考にしてください。

## 基本的な使い方
  - データベース
    - `public class SQLite : IDisposable`
    - 新規生成 (初期化クエリ) (既にあれば単に使う、元があればコピーして使う)
      - `public SQLite (string dbName, string query = null)`
    - 単文を実行
      - `public void ExecuteNonQuery (string query, SQLiteRow param = null)`
    - 単文を実行して結果を返す
      - `public SQLiteTable ExecuteQuery (string query, SQLiteRow param = null)`
    - 単文の変数を差し替えながら順に実行
      - `public void ExecuteNonQuery (string query, SQLiteTable param)`
      - 同じSQL文を、パラメータを変えながら繰り返し実行します。
    - 複文を一括実行し、誤りがあれば巻き戻す
      - `public bool TransactionQueries<T> (T query) where T : IEnumerable<string>`
      - `public bool TransactionQueries (string query)`
      - 複数行を配列やリストで渡すか、単一文字列として渡すか、という違いです。
      - 冒頭と末尾に`BEGIN`,`COMMIT`が勝手に付きます。
  - 行列データ
    - `public class SQLiteTable`
    - クエリで返されるデータで、列の定義と行データの集合です。
  - 行データ / バインドパラメータ
    - `public class SQLiteRow : Dictionary<string, object>`
    - 1行分のデータで、列データの集合です。バインドパラメータを渡すときにも使います。
  - 拡張バインド (トランザクション用)
    - `public static string SQLiteBind (this string query, SQLiteRow param)`
    - sqliteの外側で行われる文字列ベースのバインドです。

## その他
  - ご指摘やご提案、あるいはご質問などを歓迎します。
    - 常識的なことも理解していないので、何か間違えているような場合はご助言いただけると助かります。
  - より詳しい使い方については、使用例を記事にしたいと考えています。
都道府県に紐づく市町村をドロップダウンで表示させる

##備忘録として記録

完成形
![スクリーンショット 2020-09-18 18.33.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625856/ac1190ef-4313-e451-455a-c98fa31a9fb8.png)

先にコードから記載

```
<%= form_with(model: @current_masseur, url: store_manager_business_trip_ranges_update_path(@current_masseur), method: :patch, local: true) do |f| %>
        <table class="prefecture table table-hover">
            <thead>
              <!--今は東京のみを表示しているがDBには全都道府県が入っている-->
              <%= collection_check_boxes :prefecture, :prefecture_ids, Prefecture.all.where(id: [12, 13, 14]), :id, :name, include_hidden: false do |prefecture| %>
              <tr>
                <th>
                  <div id="menu<%= prefecture.object.id %>">
                    <span class="check_box"><%= prefecture.check_box %></span>
                    <span class="text"><%= prefecture.text %></span>
                  </div>
                </th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td class="city-check-boxes">
                  <div id="city-list<%= prefecture.object.id %>">
                    <%= f.collection_check_boxes :city_ids, City.all, :id, :name, include_hidden: false do |city| %>
                      <% if prefecture.object.id == city.object.prefecture_id %>
                        <ul class="city-check-box">
                            <li class="city-check-box-item">
                            <div id="boxes"><%= city.check_box + city.text %></div>
                            </li>
                        </ul>
                      <% end %>
                    <% end %>
                  </div>
                </td>
              </tr>
              <% end %>
            </tbody>

        </table>
        <div class="actions text-center">
          <%= f.submit "登録する", class: "btn btn-primary mt-5 w-50" %>
        </div>
      <% end %
```

```
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<script>

$(function () {

  // メニュー領域外をクリックしたらメニューを閉じる
  $(function(){
    $("#menu12 .text").on('click', function(){
      $("#city-list12").slideToggle('fast');
    });
  });

  $(function(){
    $('#menu13 .text').on('click', function(){
      $("#city-list13").slideToggle('fast');
    });
  });

  $(function(){
    $('#menu14 .text').on('click', function(){
      $("#city-list14").slideToggle('fast');
    });
  });
});

</script>
```

ポイントはjqueryのメソッドslideToggleが肝。これを使用するだけでslideDownとslideUpの両方が実装できます。

また$("#menu12 .text")の#menu12。
viewファイルの

```
<div id="menu<%= prefecture.object.id %>">
```

から取得したものだが、同じID名がviewファイルに複数あった場合、最初の要素しか取得できない事に注意。
またslideToggleを使用するとドロップダウンはデフォルトで開いた状態になっているので変えたい場合はcssで変更する必要がある。

##＊eachで繰り返したID要素は最初の一つしか表示されません。


参考:
http://php.o0o0.jp/article/jquery-dropdown_list
http://www.hp-stylelink.com/news/2013/11/20131122.php
https://teratail.com/questions/21542
AWS Elastic Beanstalk に swap 設定（永続化も忘れずに）

AWS Elastic Beanstalk のウェブコンソールではメモリ容量はインスタンスタイプ設定でできるものの swap 設定はできません。
なので、ebextension に書くことで設定します。

swapを設定するところまではネットに転がっていたのですが、永続化まで考慮に入れている記事がなかったのでこの記事を書きました。
swaponコマンドで実行したものは再起動すると設定が巻き戻ってしまうので、fstabファイルに設定を書いておきます。

## 書き方
アプリケーションのトップディレクトリに`.ebextensions`ディレクトリを作成し、その中に `swap.config` とでも名前をつけて以下の内容を配置します。 

```.ebextensions/swap.config
commands:
  000_create_file:
    test: test ! -e /swapfile
    command: dd if=/dev/zero of=/swapfile bs=1M count=1024 && chmod 600 /swapfile
  001_mkswap:
    command: mkswap /swapfile
    ignoreErrors: true
  002_swapon:
    command: swapon /swapfile
    ignoreErrors: true
  003_fstab:
    test: test `grep -c swap /etc/fstab` -eq 0
    command: echo "/swapfile  swap   swap    defaults   0 0" >> /etc/fstab
```

ステップ順に軽い解説をしておきます

* 000_create_file
    * /swapfile という名前の0埋めされたファイルを作ります
    * swapはメモリの拡張のためにファイルを使う方式なので、ストレージサイズがタイトな場合には予め増量しておいた方が良いと思います。筆者の環境ではサーバに8G、使用中4G程度あったので、2Gのスワップを割り当てると残りがかなりタイトになってしまう状態でした
    * `test ! -e /swapfile` はファイルがなかったら作るためのshellコマンドです
* 001_mkswap
    * ファイルを元にswap領域を作成します
    * ignoreErrors しないとすでに転換が済んでいる場合にエラーが出るので入っています
* 002_swapon
    * スワップ領域を使用します
* 003_fstab
    * 以下に記述

fstabに記述がすでにある場合には次のデプロイで書き込む必要がないので、存在チェックをしています。

```
test `grep -c swap /etc/fstab` -eq 0
```

`grep -c swap /etc/fstab`がfstabファイルに存在する`swap`と書かれている行数で、`-eq 0`はそれが０行であることをチェックしています

fstab の中身は最終的に以下のようになります。

```
[ec2-user@ip-172-31-26-7 ~]$ cat /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
/swapfile  swap   swap    defaults   0 0
```

## おまけ

ebextension はデプロイしないといけないので動作確認の負荷が高いです。
test コマンドの実行などは手元環境で試した方が楽です。

こちらのebextensionの内容の確認をしたいケース。

```
  003_fstab:
    test: test `grep -c swap /etc/fstab` -eq 0
    command: echo "/swapfile  swap   swap    defaults   0 0" >> /etc/fstab
```

以下のようにシェルのワンライナーでだいたい確認することができます。 

```
if test `grep -c swap /etc/fstab` -eq 0 ; then echo "/swapfile  swap   swap    defaults   0 0" >> /etc/fstab; fi
```
Laravelで半角英数字のみのバリデーション（簡単な方法）

Laravel6系で動作した方法

## 前提
- alpha
- alpha_num
- alpha_dash

↑ があるが、２バイト文字が考慮されていないので、全角が通ってしまう

## ざっくり理解
初期のvalidatorロジックを上書きすればOK。

## STEP1. App/Validators/CustomValidatorを作成する

App/Validators/CustomValidator.php

```php

<?php

namespace App\Validators;

use Illuminate\Validation\Validator;

class CustomValidator extends Validator
{
    /**
     * alpah
     *
     * @param string $attribute
     * @param string $value
     * @return true
     */
    public function validateAlpha($attribute, $value)
    {
        return (preg_match("/^[a-z]+$/i", $value));
    }

    /**
     * alpah_dash
     *
     * @param string $attribute
     * @param string $value
     * @return true
     */
    public function validateAlphaDash($attribute, $value)
    {
        return (preg_match("/^[a-z0-9_-]+$/i", $value));
    }

    /**
     * alpah_num
     *
     * @param string $attribute
     * @param string $value
     * @return true
     */
    public function validateAlphaNum($attribute, $value)
    {
        return (preg_match("/^[a-z0-9]+$/i", $value));
    }
}
```

## STEP.2 どこでも使えるようにする

どこでも使えるようにAppServiceProviderで、さきほど作ったValidatorを読み込む（初期のValidatorを上書き）。

app/Providers/AppServiceProvider.php

```php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;
use App\Validators\CustomValidator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::resolver(function ($translator, $data, $rules, $messages, $attributes) {
            return new CustomValidator($translator, $data, $rules, $messages, $attributes);
        });
    }
}
```

## STEP3.FormRequestなどで普通に使う

他のstring,integerなどと同じように

- alpha
- alpha_dash
- alpha_num

が使える。
今度は全角文字でエラーがでるようになる！

```php
public function rules()
{
    return [
        ...
       // 全角文字でエラーがでるようになる！
       'password' => 'required|alpha_dash|min:8'
    ];
}
```

## 参考
[\[Laravel\]バリデーションalpha\_num指定しても全角文字が通ってしまう問題 \- Qiita](https://qiita.com/meso_/items/f738c128af1e384931a8)
TypeScript の関数が ambient なときまとめ

Babel の TypeScript のパーサーのエラーを改善したいねえみたいな話で気になったから考えてみたけどこのくらいしかなさそう？

## `declare function`

```ts
declare function foo()
```

## `declare namespace` の中にある

```ts
declare namespace m {
  function foo()
}
```

## `declare module` の中にある

```ts
declare module m {
  function foo()
}
```
phina.jsでサウンドを読み込むとなぜか動かなくなる！って人向けトラブルシューティング

# はじめに
タイトルの通り。たまに困っている人を見かけるので…。
トラブルは基本的にはphina.jsがサウンド周りに使っているWeb Audio APIの性質に起因します。

サウンドの鳴らし方そのものついては、すでにいくつか記事がありますのでここでは触れません。

# 原因
以下の環境・状況でサウンドを読み込もうとするとエラーで止まります。

## ブラウザがインターネットエクスプローラー（IE）
IEは最新の11含め、WebAudioに一切対応していません。
その他のモダンなブラウザを使いましょう。

## htmlファイルをfileスキームで表示している
htmlファイルを直接ブラウザで開くと通常http/httpsではなくfileスキームで開かれます。
（URL欄が`file://...`で始まってたらそうです。あるいは現行Chromeのようにローカルファイルであることが示されます）

詳細は割愛しますが、この状態ではセキュリティ対策により一部の機能に制約がかかり、WebAudioもその制約の影響で正常に動作しなくなります。

### 対策１：ローカルサーバーを使う
要はfileじゃなくてhttp/httpsスキームなら問題無いわけですが、開発中わざわざサーバーを用意してFTPソフトで都度アップロードして確認～なんてことはやってられません。そこでローカルサーバーを使います。  
サーバーの立ち上げ方法は本当に様々なので詳細は「ローカルサーバー 立て方」でググってほしいのですが、例えば[VSCode + Live Server拡張機能を使う方法](https://qiita.com/kn339264/items/e6f6a69f70a96e61fc11)が比較的手軽です。

ちなみにphina.jsの機能で言えばWebAudio以外にも例えば[画像フィルター機能](https://qiita.com/pentamania/items/742c351549fc6f869f3b)がfileスキーム環境でつまずきます。
無用のトラブルをさけるため、基本的にはローカルサーバー経由で開発を進めることを推奨します。

### 対策２：HTML5 Audioで代用
サーバーとかよくわからない・面倒くさい場合はあえてphinaのサウンド機能は使わず、[HTML5 Audio](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement/Audio)を使うなどの代替策があります。こちらは同時再生数に制限がある・再生遅延があるなど、WebAudioよりも機能が劣りますが、fileスキームやIEでも動作し、使い方もシンプルです。
BGM再生程度ならこちらだけでいいかも。

またhowler.jsなどのサウンド専用ライブラリを別に使うという手もあります。
ただ、これらのライブラリでもWebaudioが使えない場合、HTML5 AudioやFlashで代用する処理をしていることに変わりありません。

### 対策３：音声データをDataURL化する
あんまりおすすめではないですが、音声ファイルをDataURL変換してから読み込む方法もあります。

```js
const bgmDataURL = "data:audio/mpeg;base64,[base64エンコード後のめちゃくちゃ長い文字列]";
phina.main(function() {
  const app = phina.game.GameApp({
    startLabel: 'main',
    assets: {
      sound: {
        // bgm: 'assets/bgm.mp3',
        bgm: bgmDataURL,
      }
    },
  });

  app.run();
});
```

データをいちいち変換する手間がかかるのと、変換によってファイルサイズが肥大化するのであんまり利点が無いですが…。
一応そういう方法もあるんだなぁぐらいの認識で覚えておくと何かの役に立つかも知れません。


## その他
- 自分自身は遭遇したことがないですが、拾い物の音源のデコードが上手くいかず止まってしまうこともあるようです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">mp3でAudioを使ったら再生出来るとの事なので、ビットレートが悪さしてるのではという気がします。自分も拾い物のmp3がWebAudioで再生出来ない事が何度かありました。その場合、再エンコードしたらassetを使う方法で再生する事が出来ました。一応ご参考まで。</p>&mdash; Yoshifumi Fujimoto (@minimo) <a href="https://twitter.com/minimo/status/1303270972359716866?ref_src=twsrc%5Etfw">September 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- ブラウザが対応している拡張子・コーデックかどうかもチェックしておきます。mp3/aac形式あたりならまず問題無いですが、その他の形式はサポートがまちまちです。


## 番外：ユーザー入力を待ってから再生
エラーで止まることは無くなったが、タイミングによっては再生命令が無視される…というようなことがあります。iOS safariやAndroid chrome、PC Chromeなどのユーザーのインタラクションが無いと再生できない仕様に引っかかってると思われます。
phina.jsでの対策については**[ここ](https://qiita.com/pentamania/items/399d133e5440c9424bde#%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB%E3%82%B5%E3%82%A6%E3%83%B3%E3%83%89%E5%88%B6%E9%99%90%E3%81%AE%E3%82%A2%E3%83%B3%E3%83%AD%E3%83%83%E3%82%AF)**で少し触れています。

ほかにこういうトラブルがあったよ的な話がありましたらお知らせください。
【Rails】複雑なルーティング構成まとめ

今回は、`Usersリソース`を中心に、追加構成として`APIディレクトリ`を追加してみたり、新たなメソッドとして`sortメソッド`を追加したときのパスの状態などを設定するパターンで見ていく


#早見表

| 種類 | パス | クラス | ファイルパス
|:-:|:-:|:-:|:-:|
| scope  | /api/users  | UsersController  | /users_controller.rb |
| namespace  | /api/users  | Api::UsersController  | /api/users_controller.rb|
| module  |  /users | Api::UsersController  |/api/users_controller.rb
|  member |  /users/:id/sort |   |
| collection  |  /users/sort |   |



#Controllersのディレクトリ構成と、ルーティング


##scope

```ruby:routes.rb
# /api/users

scope :api do
  resources :users
end
```

```:ディレクトリ構成
/controllers--
            |
            |--application.rb
            |
            |--users_controller.rb
```

```ruby:controller.rb
class UsersController < ApplicationController
end
```


##namespace

```ruby:routes.rb
# /api/users

namespace :api do
  resources :users
end
```

```:ディレクトリ構成
controllers/-
            |
            |--application.rb
            |
            |--api/-
                   |
                   |--users_controller.rb
```

```ruby:controller.rb
class Api::UsersController < ApplicationController
end
```



##module

```ruby:routes.rb
# /users

scope module: :api do
  resources :users
end
```

```:ディレクトリ構成
controllers/-
            |
            |--application.rb
            |
            |--api/-
                   |
                   |--users_controller.rb
```

```ruby:controller.rb
class Api::UsersController < ApplicationController
end
```




#まったく新しいパスを作る

##member

```ruby:routes.rb
# idを伴うパス /users/:id/sort

resources :users do
  member do
    get :sort
  end
end
```

省略形

```ruby:routes.rb
resources :users do
  get :sort, on: :member
end
```


##collection

```ruby:routes.rb
# idを伴わないパス /users/sort

resources :users do
  collection do
    get :sort
  end
end
```


省略形

```ruby:routes.rb
resources :users do
  get :sort, on: :collection
end
```


#参考記事

> https://qiita.com/senou/items/f1491e53450cb347606b
共同開発時の環境構築方法とトラブルシューター(railsとdockerとgithub)

# はじめに
※ この記事は知り合いとの共同開発に役立てるために書かれたものです
私たちのwebアプリ開発環境は **Dockerコンテナ** 上で成り立っています。
webという名前のrailsを動かしているコンテナと、dbというMySQLを動かしているコンテナを`docker-compose up`で同時に立ち上げています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571279/b583517a-6b74-e112-f2fb-cf2dc94b698f.png)

## dockerコンテナを使うメリット

- 環境の構築が容易で高速
- 手軽に環境の共有、統一ができる
- ローカル上の周辺環境との依存を避けられる
- リリース時にサーバー上にも同じ環境をすぐに構築できる
- 従来の仮想化技術よりメモリ消費量が少ない

以上の理由よりDockerを使っています。

## 環境
Ruby2.5.3
Rails5.2.2
MySQL5.7

###　環境構築方法
1. dockerhubにアカウントを作成して、dockerfordesktopをダウンロード
1. ローカルのPCに`git clone` する。
1. ディレクトリ移動して、`docker-compose up`
1. `docker-compose exec web rails db:create`
1. `docker-compose exec web rails db:migrate`

- ２回目からは`docker-compose up`のみ



## トラブル時(git編)

### gitが全くわからない
- 参考ページ：[サル先生のgit入門](https://backlog.com/ja/git-tutorial/)

### githubにpushしたい

```
$ git checkout -b 作成するブランチ名

もしくは
$ git branch 作成するブランチ名
$ git branch 作成したブランチ名
でも可
```

でブランチを作る。やっていることがわかるブランチ名が良し

```
$ git init 
$ git add (ファイル名) もしくは git add .
$ git commit -m "comment"
$ git push origin ブランチ名
```
pushしたらgithubに黄色いバーが出る。
masterに反映させたい内容なら、Compare & pull request押してね


### リモートブランチがわからない
リモートブランチ一覧表示

```
$ git branch -r
```



### 他の人pushしたブランチを自分のローカルにpullしたい

```
$ git fetch
```
でローカルのブランチを最新に更新

```
$ git pull origin REMOT_BRANCH_NAME:LOCAL_BRANCH_NAME
```
## トラブル時（docker編）

### `docker-compose up`しても3000番portが立ち上がらない場合。
- 前回dockerを終了した時にサーバーが適切に終了できていなかった
- 参考記事：https://qiita.com/JUNO-LEARN/items/d7b49f130b62f0740a1c
- `tmp/pids/server.pid`を消してみて

### コンテナ内に入りたい

```
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
b9abd4473fd9        watch_project_web   "rails s -p 3000 -b …"   28 hours ago        Up 28 hours         0.0.0.0:3000->3000/tcp              watch_project_web_1
d55c5240d70d        mysql:5.7           "docker-entrypoint.s…"   28 hours ago        Up 28 hours         0.0.0.0:3306->3306/tcp, 33060/tcp   watch_project_db_1
```
で起動中のコンテナIDを確認

```
$ docker exec -it {コンテナ名} bash
```

### コンテナに入らずデータベースがみたい

```
docker-compose exec db mysql -uroot -p
```

### コンテナに入らず、railsコマンドを使いたい

```
docker-compose exec web rails 〜〜
```
webというコンテナに入って直接`rails　〜〜`みたいにコマンドを使ってもいい。
smtp-auth対応パッチを当てたqmailのRCPT TO:で常に「smtproutesに指定したメールアドレス」を使うようにする為のqmail-remote.cの変更箇所


### 前書き

　プロバイダでOB25対策が始まり既に15年以上経過していますが、2年ほど前に私の使用しているプロバイダでOB25対策と共に用意されたSMTP-AUTH対応SUBMISSIONポートのメールサーバで「SMTP-AUTHで認証したプロバイダのメールアドレス以外をMAIL FROM:に指定するとメールのリレーを拒否」すると言う新たな対策がサイレント導入されました。

　普通(?)に使っている分には問題はありませんが、独自ドメインを取得してdynamic dnsを使いメールサーバ(qmail)を運用していると内部から独自ドメイン名でメールを送信する事が出来なくなってしまいます。

　最近、qmailを弄っていてそういえばこの手の情報は見たことがないのでニッチであるとは思いますが、smtp-auth対応パッチを当てたqmailのRCPT TO:で常に「smtproutesに指定したメールアドレス」を使うようにする為のqmail-remote.cの変更箇所を共有したいと思います。


### 前提条件
独自ドメインでqmailサーバを運用していて以下パッチが当たっている事

* qmail-smtpd-auth-0.31.tar.gz
* qmail-smtpd-auth-close3.patch
* qmail-remote-auth.patch

以下の様に smtproutes でプロバイダのメールサーバへメール配信を依頼していて尚且つクライアントとしてメールアドレスでsmtp-authしている事

```bash
touch /var/qmail/control/smtproutes
chown qmailr.root /var/qmail/control/smtproutes
chmod 640 /var/qmail/control/smtproutes
cat > /var/qmail/control/smtproutes << EOF
:プロバイダのメールサーバFQDN:587 プロバイダのメールアドレス プロバイダのメールパスワード
EOF
```

### プロバイダのメールサーバに前書きと同様の対策がされているかの確認方法

```bash
# SMTP AUTH文字列を作成
printf "%s\0%s\0%s" プロバイダのメールアドレス プロバイダのメールアドレス メールパスワード | openssl base64 -e | tr -d '\n'; echo 
# 以下の様なbase64化されたSMTP AUTH文字列が表示されるので、表示された文字をコピーしておく
Zm9vQGV4YW1wbGUuY29tAGZvb0BleGFtcGxlLmNvbQBwYXNzd29yZA==

# 暗号化必須の場合の接続方法
openssl s_client -quiet -ign_eof -connect プロバイダのメールサーバ:ポート番号 -tls1_2
# 平文でいい場合の接続方法
telnet プロバイダのメールサーバ ポート番号
```

__接続出来ると大体以下の様な表示がされるので、グレーの部分のみ入力(サーバによって表示内容は微妙に違います)__

Trying メールサーバのＩＰアドレス...
Connected to メールサーバ名
Escape character is '^]'.
220 メールサーバ名 ESMTP Service ready
`EHLO localhost`
250-メールサーバ名
250-DSN
250-8BITMIME
250-PIPELINING
250-AUTH=LOGIN
250-AUTH LOGIN CRAM-MD5 PLAIN
250 SIZE 20971520
`AUTH PLAIN 予め作成したSMTP AUTH文字列`
235 PLAIN authentication successful
`MAIL FROM:foo@example.com` ***… MAIL FROMがSMTP-AUTHしたアドレスと異なると受け付けを拒否される***
553 MAIL FROM:<foo@example.com> does not match authenticated user name
`MAIL FROM:プロバイダのメールアカウント` ***… MAIL FROMがSMTP AUTHのユーザ名と同じ場合は受け付けられる***
250 MAIL FROM:<プロバイダのメールアカウント> OK
`QUIT`

### qmailの変更箇所

受け付けられない場合は、SMTP-AUTHしたメールアドレスをMAIL FROM:に指定するようにqmail-remote.cの264行目付近 を変更。（コメントアウトされているのは変更前のコード）

```c:qmail-remote.c
substdio_put(&smtpto,auth_smtp_user,auth_smtp_user.len);    // substdio_put(&smtpto,sender.s,sender.len);
```

後はいつも通り（必要に応じてqmailを止めるなどしてください）

```bash
make setup check
```

### お疲れ様でした
【Typescript】Nullish Coalescing と短絡評価

## はじめに

今回はNullish Coalescing と短絡評価についてです。

## Javascriptの場合

```
const inputData = "";

const storedData = inputData || "DEFAULT TEXT";
console.log(storedData);
```

```
const inputData = null;

const storedData = inputData || "DEFAULT TEXT";
console.log(storedData);
```

```
const inputData = undefined;

const storedData = inputData || "DEFAULT TEXT";
console.log(storedData);
```

いずれもinputDataはfalseと評価されて"DEFAULT TEXT"が出力されます。

## Typescriptの場合

Nullish Coalescingを使って

```
const inputData = undefined;

const storedData = userInput ?? "DEFAULT";

console.log(storedData);
```

と書けます。違いは、

```
const inputData = "";

const storedData = userInput ?? "DEFAULT";

console.log(storedData);
```

の時には""がtrueと評価されて空文字が出力されることです。

## 最後に

また新しいことを覚えたらアウトプットしたいと思います。
【zsh】global aliasを展開する関数を作る(作った)


長くなった。 変数展開でうまいこと書けないかなぁ→書けた:smile: って記事 

##  拝啓 :eyeglasses:
zsh の global alias について軽く説明すると
通常のalias と違って、コマンド以外の場所でも 展開されるalias です
大体パイプと組み合わせて定義されてることが多いです
**alias名には特にきまりはない**ですが、global alias名は大文字で定義するのが一般的ぽいですね

```shell:例
alias -g G='| grep'
alias -g H='| head'
alias -g L='| less'
```

このように定義しておくと、コマンド実行時に展開されます

```shell
$ cat log H -n2 
# => cat log | head -n2 
```

<br>

そのまま使ってても便利なのですが、 コマンドライン操作中に自動で展開したら個人的にスマートですね。履歴にも展開後のコマンドとして残るので

alias展開関数はいつくかの記事で紹介されてますが

- 展開バインドキーはSpace
- global alias だけ展開する
- **定義済みのaliasと比較して展開する**

みたいなのが個人的にほしかったので勉強がてら作りました :pencil2:



## 作った :bulb:
![alias.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138236/ffbc0500-723b-b25d-3838-efa04afad376.gif)


そんな関数がこちら

```shell:expand-alias-widget
#!/usr/bin/env zsh

function main() {
  emulate -L zsh
  setopt aliases
  local -a global_aliases=(${(@f)"$(alias -g)"})
  local -a characters=(${global_aliases%%\=*})
  if (($characters[(I)${(q)LBUFFER##* }])); then
     zle _expand_alias
     zle expand-word
  fi  
  zle self-insert
}

main
```

趣味記法なので関数で囲わなくてもいいし、shebangもいらないかもです
こちらを fpathが通ったディレクトリに置いて、bindkeyを割り当てると使えます

```shell:.zshrc
autoload -Uz expand-alias-widget
zle -N expand-alias-widget
bindkey ' ' expand-alias-widget
```





## 解説 :microphone2:

#### shellscript内でもaliasを使えるようにする

デフォだと使えないんです。なので オプションを指定してあげる
関数内でオプションを触る時は  `local_options` か `emulate -L zsh` しましょう

```shell

setopt aliases
```



#### 定義済みのglobal alias一覧を配列化

`alias -g` で定義済みのglobal aliasが出力できます
出力は改行ありなので `f` フラグで 改行文字区切りで単語展開
`@`フラグで個々の要素を別々の要素として展開(いらないかも)

```shell
local -a global_aliases=(${(@f)"$(alias -g)"})
```



#### 配列からalias 名のみ取り出す

`L='| less'` から `L` を抽出する。 `${*name*%%*pattern*}` 記法
冒頭の例だとこの時点でcharactersの内容は `(G H L)`こんな感じになる

```shell
local -a characters=(${global_aliases%%\=*})
```


#### カーソル左の文字列が、alias名配列に含まれるか調べる

`if (( ${array[(I)pattern]} ))` で 配列に特定の要素が含まれるかチェックできる

```shell
if (($characters[(I)${(q)LBUFFER##* }]))
```

`${(q)LBUFFER##* }`はカーソル左の空白区切り末尾文字を取得
`(q)` が大事
`${LBUFFER##* }` には `*`や`?`が展開されることもあるので
パターンマッチで条件式が意図せず真になってしまいます。
そこでqフラグで メタ文字をバックスラッシュでクォートして防ぎます



#### zleの組み込みウィジェット

alias を展開するだけだったら 既存でwidgetが用意されている
それが `_expand_alias` [:link:](http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Control-Functions)
`expand-word` はシェル展開 (コマンド展開とかグロブ展開とか) [:link:](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Completion)


## まとめ :file:
え？「変数展開とかフラグが多すぎてわかんないよ〜:cry:」って？
まとめといたよ:kissing_heart:
https://gist.github.com/sho-t/d9cdf8271b3de7c4238739e523490542
Sequel Ace, Sequel ProのサジェストをCtrl + P, Ctrl + Nで移動する方法

普段shell, vim, emacsなどを使う方は`Ctrl + P` `Ctrl + N`の移動に慣れていると思います

しかし、Sequel Aceでは、コードのサジェストのときに矢印キーでしか移動できずにイライラが溜まっていました。macの矢印キーはとても押しにくい・・・

そこで、hammerspoonを使ってSequel Ace起動時にのみ`Ctrl + P` `Ctrl + N`を矢印キーにremapしましょう


## configファイル

```
local function keyStroke(mods, key)
  return function() hs.eventtap.keyStroke(mods, key, 0) end
end
local function remap(mods, key, fn)
  return hs.hotkey.bind(mods, key, fn, nil, fn)
end
local sequelAceRemapKeys = {
  remap({'ctrl'}, 'n', keyStroke({}, 'down')),
  remap({'ctrl'}, 'p', keyStroke({}, 'up'))
}
local function handleSequalAceEvent(name, event, app)
  if event == hs.application.watcher.activated then
    if name == 'Sequel Ace' then
      for i, key in ipairs(sequelAceRemapKeys) do
        key:enable()
      end
    else
      for i, key in ipairs(sequelAceRemapKeys) do
        key:disable()
      end
    end
  end
end
appsWatcher = hs.application.watcher.new(handleSequalAceEvent)
appsWatcher:start()
```

快適快適〜！
Pythonでのファイル処理

Pythonでのファイル処理

ファイル
ファイルには大きく分けて、プログラムファイルとデータファイルの２種類があります。 
プログラムファイル　OSやアプリケーションとこれらに関連するソフトウェア全般を指します。 データファイル　撮影した画像や動画、パソコンで作成したワード、エクセルファイルや文章など、ユーザーが自分で作成したオリジナルのファイルを指します。

ファイル形式
ファイルには、そのファイルの種類を示した拡張子（かくちょうし）という文字列が割り当てられていて、それぞれに対応したアプリケーションが存在します。 例として「txt」、「xlsx」、「jpg」、「gif」、「PNG」、といったようにファイル名の末尾を確認することで、そのファイルがどういう形式なのかを知ることができます。

メモリ
メモリではデータを電気的にそして、一時的に保存しておく。
高速で読み書きを行なってくれることが利点。 
open()
Pythonでファイルを開く場合、 open関数を使用します。
open関数は、Pythonの組み込み関数の1つなので特別な宣言などを行う必要はなく、
新規ファイルの作成や書き込み、読み込み、追記、保存等の作業を行うことができ、ファイルオブジェクトを受け取ることができます。
open関数は、下記の記述で使用することができます。

実行方法
>open('開きたいファイル名')

エラー絡み発生した場合以下のように取得することができるようです。
>try:
>    with open(‘hatamoto’, encoding='utf-8') as fin:
>        pass
>except FileNotFoundError:
>    print(‘対象のファイルが見つかりませんでした')

オプションを指定したい場合は、以下にする。
>open('hatamoto', mode='rb')

| オプション | 説明 |
|:-:|:-:|
|r	|読み込み用に開く (デフォルト)|
|w	|書き込み用に開き、まずファイルを切り詰める|
|x	|排他的な生成に開き、ファイルが存在する場合は失敗する|
|a	|書き込み用に開き、ファイルが存在する場合は末尾に追記する|
|b	|バイナリモード|
|t	|テキストモード (デフォルト)|
|+	|複数のオプションを使用するためのものです。|

デフォルトのモードは 'rt' となります
第三引数にはエンコードを渡しますが、デフォルトの文字コードは「UTF-8」として扱われます。

ファイルの読み込み

| メソッド | 説明 |
|:-:|:-:|
| read()  | ファイルから指定したデータを読みこむ。デフォルトはファイルの内容全てを読み出します。  |
| readline()  |ファイルから1行読みこむ   |
| readlines()  | ファイルの内容を全て読み出し、1行ごとのリストにします。  |


書き込みメソッド

| メソッド | 説明 |
|:-:|:-:|
| write(  | 文字列を書き込む。数値などを書き込みたい場合は、str()で一度文字列に変換する。  |
| writelines()  | 文字列のリストをまとめて書き込む。数値などを書き込みたい場合はstr()で文字列に変換する。  |


* バイナリファイル

バイナリファイルはテキストファイル以外のファイル
画像データや動画、Excelファイル、プログラム開発ファイル、などのこと。
バイナリファイルを開きたい場合は、「b」オプションを使用する。
バイナリファイルの場合は、エンコードを指定する必要はない。

* 関数型 

プログラミングは問題をいくつかの関数にわけて考えます。
できるだけ人間にわかりやすく、テスト管理がしやすい、を目的としているようです。
Javaなどのオブジェクト思考と同じく概念的なものと考えています。
【Typescript】オブジェクトの要素チェック

## はじめに

最近Typescriptの勉強を始めました。ちょこちょこ便利だなと思った書き方を覚書していきます。今回はOptional Chainingについてです。

## Javascriptの場合

```
const fetchedPostData = {
  id: "p1",
  author: { name: "MIKE", age: "22" },
};
```

こんな感じのオブジェクトの要素を取り出したいなーと思った時、エラーを回避するために

```
if (fetchedPostData) {
  if (fetchedPostData.author) {
    console.log(fetchedPostData.author.name);
  }
}
```

とか、もう少しスマートに書くなら

```
if (fetchedPostData && fetchedPostData.author)
  console.log(fetchedPostData.author.name);
```

と書きます。

## Typescriptの場合

?を使ってさらに潔にかけます。

```
console.log(fetchedPostData?.author?.name);
```

## 最後に

美しい・・・

また新しいこと覚えたら書きます。
TWELITE DIP のピン配置

TWELITE DIP のピン配置。いろんなルールがあってわかりづらいのでまとめ。

# DIP ピン

|TWELITE DIP基板ピン番号|TWELITE DIP基板上のシルク表記|TWELITE CHIP パッド番号|TWELITE IO名 |簡単アプリでの信号名 | 簡単アプリでの機能|
|:---:|:---:|:---:|:---:|:---:|:---:|
|1 |GND|GND|GND|GND|電源グランド|
|2 |14 |14|DIO14|SCL|I2Cクロック|
|3 | 7|9|DIO7|RX|UART受診|
|4 |5 |7|DIO5|PWM1|PWM出力1|
|5|18 |3|DIO18|DO1|デジタル出力1|
|6|C|1|DO0 |PWM2|PWM出力2,常時Vccプルアップが推奨|
|7 |I |2|DO1|PWM3|PWM出力3,起動時Loレベルでプログラムモード|
|8|19|4|DIO19|DO2|デジタル出力2|
|9 |4 |6|DIO4|DO3|デジタル出力3|
|10 |6 |8|DIO6|TX|UART送信|
|11 |8 |10|DIO8|PWM4|PWM出力4|
|12 | 9|11|DIO9|DO4|デジタル出力4|
|13 | 10|12|DIO10|M1|モード設定ビット1|
|14 | GND|GND|GND|GND|電源グランド|
|15 |12 |13|DIO12|DI1|デジタル入力1|
|16 |13 |15|DIO13|DI2|デジタル入力2|
|17 |11 |16|DIO11|DI3|デジタル入力3|
|18 |16 |18|DIO16|DI4|デジタル入力4|
|19 |15 |17|DIO15|SDA|I2Cデータ|
|20 |17 |19|DIO17|BPS|UART ボーレート設定ビット|
|21 |R |21|RESETN|RST|Loレベルでリセット入力 |
|22 |A1 |23|ADC1|AI1|アナログ入力1|
|23 |0 |24|DIO0|AI2|アナログ入力2|
|24 |A2 |22|ADC2|AI3|アナログ入力3|
|25 | 1|25|DIO1|AI4|アナログ入力4|
|26 | 2|26|DIO2|M2|モード設定ビット2|
|27 | 3|27|DIO3|M3|モード設定ビット3|
|28 |VCC|VCC |VCC|VCC|電源(2.3~3.6V)|

# プログラムピン

プログラム時に使用する5ピンのスルーホールがあるが、これらは上記ピンのうちのいくつかとつながっている。

| TWELITE DIP プログラムポートシルク|TWELITE DIP基板ピン番号|TWELITE DIP基板上のシルク表記|TWELITE CHIP パッド番号|TWELITE IO名 |機能|
|:---:|:---:|:---:|:---:|:---:|:---:|
|RST|21 |R |21|RESETN|リセット|
|RXD|3 | 7|9|DIO7|RX|
|PRG|7 |I |2|DO1|起動時Loレベルでプログラムモード|
|TXD|10|6 |8|DIO6|TX|
|GND |GND|GND|GND|GND||


# 簡単アプリ設定ビット

「超簡単！標準アプリ」では特定のピンをLoにすることによりアプリの動作を変更できる。
モード設定ビット1,2,3 および ボーレート設定ビットの設定は以下の通り
なお、それぞれのビットに割り当てられているピンはプルアップされている。

モード設定ビット

|モード設定ビット1|モード設定ビット2|モード設定ビット3|設定される動作|
|:---:|:---:|:---:|:---:|
|Lo|Hi|Hi|親機|
|Hi|Lo|Hi|中継機|
|Hi|Hi|Hi|子機、連続モード|
|Lo|Lo|Hi|子機、連続0.03秒|
|Hi|Hi|Lo|子機、間欠1秒|
|Lo|Hi|Lo|子機、間欠受信1秒|
|Lo|Lo|Lo|子機、間欠10秒|
|Hi|Lo|Lo|NC|



ボーレート設定ビット

|Lo|Hi|
|:---:|:---:|
|38400bps(起動時のみ反映?)|115200bps(デフォルト)|
xcode12でsimulatorにビルドする時失敗する問題

# 問題
xcode12でsimulatorにビルドする時
`building for iOS Simulator, but linking in object file built for iOS, for architecture arm64`
のようなエラーが出てきます。

# 原因
https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes

> The Build Settings editor no longer includes the Valid Architectures build setting (VALID_ARCHS), and its use is discouraged. Instead, there is a new Excluded Architectures build setting (EXCLUDED_ARCHS). If a project includes VALID_ARCHS, the setting is displayed in the User-Defined section of the Build Settings editor. (15145028)

`Valid Architectures`はxcode12から削除されたのでエラーの原因になっていると思われる。

# 解決案
`project.pbxproj`内の`VALID_ARCHS`を削除することでビルドができるようになると思う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165424/f5161b74-cf0b-38c8-8e61-59c3936593c5.png)
Javascriptの基本の書き方②

#はじめに
[前回](https://qiita.com/itou-t/items/66b870ac75c3b1b5bbbd)に引き続いてjavascriptの基本の書き方を備忘録として残します。

##繰り返し文
###while文
```javascript
while(条件式){
  処理;
}
```

###for文
```javascript
for(変数の定義;条件式;変数の更新){
  処理;
}
```

##配列
```javascript
[値1,値2,値3]
```
配列も一つの値としてみなされるので定数への代入が可能

###配列内の特定の値の取り出し
```javascript
配列名[取得したい値のインデックス]
```

##オブジェクト
オブジェクトも一つの値としてみなされるので定数への代入が可能

```javascript
{プロパティ値1:値1,プロパティ値2:値2}
```
###オブジェクトの取り出し
以下の方法で可能

```
オブジェクト名.プロパティ値
```


###オブジェクトを要素にもつ配列

```javascript

const 変数名 = [
  {プロパティ値1: 値1, プロパティ値2: 値2},
  {プロパティ値1: 値1, プロパティ値2: 値2}
];
```

取り出すときは以下のように取り出す

1.配列の中のオブジェクトを取り出す時

```
変数名[インデックス]
```

2.配列の中のオブジェクト内のプロパティ値に対応する値を取り出す時

```
変数名[インデックス].プロパティ値
```
RESTとGraphQL、そしてHasura

##RESTのイメージ
取りたいデータに対して別々にエンドポイントが用意されている。
そのエンドポイントの裏ではエンドポイントごとに異なるDB処理が走っている。
####フロント側
取りたい情報を取得できるエンドポイントを選ぶ必要があり、得たい情報によっては複数回クエリを投げる必要がある。
####サーバ側
取得情報ごとに別々のエンドポイントを用意。
エンドポイントごとに異なるDB処理を記述。
![スクリーンショット 2020-09-18 17.38.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/0c625d60-dd9e-5e52-18fc-edfeac4bcb70.png)


##GraphQLのイメージ
取りたいデータは別々でも用意されているエンドポイントは一つ。
そのエンドポイントに取りたいデータをjsonのようなクエリを渡すことでそれを元に裏で処理が走る。
####フロント側
エンドポイントが一つだからわかりやすい。
欲しいデータごとに自分で組み合わせをjsonのように作る。
####サーバ側
エンドポイントは一つだからわかりやすい。
クエリごとにDB処理を記述？(まだやってないのでわかりません。。。)
![スクリーンショット 2020-09-18 17.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/f6a2b455-c2ae-f00e-8a7d-8ca0f0d84b7f.png)


##Hasura
graphqlのAPIサーバを簡単に作れるのがHasura。
これを使えばDB(今はpostgresのみ)との連携、クエリを用いたデータの出し入れがほんの数分でできてしまう。
MayaのbackgroundColorの色見本

UIに彩りを加えるbackGroundColorについて、実際どんな色になるのよ？と気になったので調べてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79407/5b5a6945-33ce-cf34-9b26-95d8f49b2b53.png)

一通り表示してみます。

```python

import maya.cmds as cmds
import pymel.core as pm

windowtitle = 'ColorCheck'
wndwName    = 'ColorCheck'

if pm.window(wndwName, ex=True):
    pm.deleteUI(wndwName)
win = pm.window(wndwName, t=windowtitle, w=True )

with win:
    SCL = pm.scrollLayout()
    with SCL:
        column = pm.columnLayout(adj=True)
        with column:
            for i in range(0,11):
                for j in range(0,11):
                    RCL = pm.rowColumnLayout(numberOfColumns=22)
                    with RCL:
                        for k in range(0,11):
                            a = i * 0.1
                            b = j * 0.1
                            c = k * 0.1
                            pm.button(
                                l=u'%s %s %s'%(str(a), str(b), str(c)),
                                bgc=(a, b ,c),
                                c="print %s, %s, %s"%(str(a), str(b), str(c)),
                                w=80,
                                h=30,
                                )
                            pm.separator(st="none", w=5)
                    pm.separator(st="none", h=5)
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79407/2f2fe6b7-c6ff-2ff2-0576-0c6870b3efbc.png)

鮮やかですね！
ショートカットのリンク先情報を再帰的に収集しCSVとして残す

# 概要

カレントディレクトリ以下のフォルダから、
ウィンドウズのショートカット「LNKファイル」を再帰的に見つけ出し、
LNKファイルのプロパティを一覧にして収集します。
その結果をCSVファイルとして出力します。
CSVの文字コードはExcelで読み込めるようにunicodeとします。

# 想定する状況

- NAS「A」の共有フォルダ内にある大量のファイルにはショートカットファイルが含まれます。
- このショートカットのリンク先は大半がNAS「B」の共有フォルダ内になっています。
- ある日、NAS「B」の共有フォルダの名称を変更することになりました。
- NAS「A」「B」ともにフォルダ階層が入り組んでおり、すべて人力で探すのは困難です。
- 最優先で、どのようなリンクが形成されているのか状況把握する必要があります。

※NAS(Network Attached Storage)としましたが、フォルダなら何でもいいと思います。

# 環境

スクリプトを実行する場所がWindowsであればよいので、
対象の共有フォルダがLinuxやUnix上にあっても動作します。

- Windows 10
- Powershell 7

# 起動スクリプト

```posh:launch.cmd
@echo off
echo "Launch ShortCut Crawler !!"
pushd %~dp0
pwsh -Noprofile -ExecutionPolicy RemoteSigned -File ./main.ps1
echo "Fin"
pause > nul
exit
```

下記のmain.ps1と同じ階層に置いて利用するようにしています。

# メインスクリプト

```posh:main.ps1
filter Get-ShortcutProperty()
{
    $Wshell  = New-Object -comobject WScript.Shell
    return $Wshell.CreateShortcut($_)
}

Get-ChildItem -Recurse -Include "*.lnk" |
 Get-ShortcutProperty |
 Select-Object -Property Fullname, TargetPath, Arguments |
 Export-Csv -LiteralPath "$env:USERPROFILE/desktop/link.csv" -Encoding Unicode -UseQuotes Always -Delimiter "`t"
```

実行しているユーザーのデスクトップにCSVファイルが出力されます。

`Get-ChildItem`の後ろに` -LiteralPath "検索したいフォルダパス" `を付ければ、
カレントディレクトリ以外のフォルダを検索することも可能です。

` -UseQuotes Always `を指定しているので、
項目にスペース入りの文字列があってもそのまま動きます。

※[`t はタブ文字です。](https://qiita.com/sukakako/items/4a17db13730934766abb)

# 他の書き方

メインスクリプトは、こんな書き方もありですね。

```posh:main.ps1
filter Get-ShortcutProperty()
{
    $Wshell  = New-Object -comobject WScript.Shell
    return $Wshell.CreateShortcut($_)
}

$TargetShortcutFiles = (Get-ChildItem -Recurse -Include "*.lnk")
$ShortcutProperties = ($TargetShortcutFiles | Get-ShortcutProperty)
$ShortcutPropertiesFiltered = ($ShortcutProperty | Select-Object -Property Fullname, TargetPath, Arguments)
$ShortcutPropertiesFiltered |
 Export-Csv -LiteralPath "$env:USERPROFILE/desktop/link.csv" -Encoding Unicode -UseQuotes Always -Delimiter "`t"
```

# 結果

以下のような感じでCSVファイルを出力できました。
そして、Excelでもキレイに開くことができました。

```csv:link.csv
"FullName"	"TargetPath"	"Arguments"
"C:\Users\?????\Desktop\test\新しいフォルダー\新しいフォルダー\新しいフォルダー\新しいフォルダー\新しいフォルダー\duralumin (192.168.0.180).lnk"	"\\192.168.0.180\duralumin"	""
"C:\Users\?????\Desktop\test\steel (192.168.0.170).lnk"	"\\192.168.0.170\steel"	""
"C:\Users\?????\Desktop\test\tungsten (192.168.0.180).lnk"	"\\192.168.0.180\tungsten"	""
```

# 所要時間

参考程度に処理時間を記載します。
検索対象の共有フォルダ全体で50GB程度でしたが、7分程度でCSV出力が完了しました。

# 今後の課題

他の書き方とか書いてみたものの、最後にExport-CSVを使うことを考慮して、あまり分解ができませんでした。
pythonでいうtqdmみたいにプログレスバーを表示したいときはどうするのかが焦点です。
使い捨てのスクリプトのスクリプトとして作成しましたが、結構使いまわせると思います。
「今回の対象は前回の100倍だよ」とかいう攻撃に対処する防衛術を身に着けておきたいものです。

# 参考

- [ショートカットの内容を取得する](https://qiita.com/mako24/items/6c3cfa8d880bf9d24c8d)
- [PowerShellでタブ区切りのcsvファイルを読み込む](https://qiita.com/sukakako/items/4a17db13730934766abb)
- [Docs / Windows コマンド / サーバーの役割別のコマンド / icacls](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/icacls)
- [Docs / Windows コマンド / サーバーの役割別のコマンド / robocopy](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/robocopy)

**Excelsior!!**
App IDのユーザーでIBM Cloudのポータルを利用する

# 目的

IBM Cloudのコンソール（通称ポータル）を利用するには、IBM IDを作成してアカウントに招待してもらう必要がありますが、App IDを使ってSAML認証できるようになりましたので、検証してみます。

IBM IDではなくApp IDを使うメリットですが、

* IBM IDを取得しなくてよい
* ユーザーが増えたときに毎回招待しなくてよい
* 他のサービスとシングルサインオンできる（かもしれない）

といったところが考えられます。

# 手順

こちらが参考になります。

> https://cloud.ibm.com/docs/account?topic=account-idp-integration

## App IDのオーダー

通常通りオーダーします。

## App IDの設定

IDプロバイダーとしてクラウドディレクトリー以外を無効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/6d207d1d-4db2-6e08-4417-527946b761b2.png)

クラウドディレクトリーに適当にユーザーを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/67f76a36-4469-ac08-c8bc-88c4ea5630eb.png)

クラウドディレクトリーの設定で、ユーザーがサインアップできないようにします。さもないとURLを知っている人が勝手にユーザーを追加できてしまうためです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/5834d033-743c-0969-c2a9-02c847f37118.png)

## IAMの設定

ポータルからIAM→IDプロバイダーに移動します。タイプでIBM Cloud App IDを選択し、有効化ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/b1aa9e5f-9007-50aa-9ca4-e40fc40279db.png)

IdP URLを設定します。他の利用者と被らないユニークなものにする必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/f116eb91-907d-b53d-49d1-f98bf581224e.png)

次に作成をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/dcb54f89-a57b-21ab-30c8-d4c7c37b1f0f.png)

名前を適当に設定し、サービスインスタンスは先ほど作成したApp IDのインスタンス名をプルダウンで選択します。その他はチェック済として、作成をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/255d8991-72c9-1a0b-e770-a055e4b2649e.png)

IdPの登録が完了しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/3e3f1f83-a829-d168-9d24-a6923713e649.png)

ここで表示されているIdP URLに別ブラウザでアクセスします。すると見慣れた（？）App IDのログイン画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/7c10759b-b6c2-2a38-a0fe-2d39dc534b60.png)

先ほど登録したユーザー情報でサインインします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/8b67dc0d-6d46-93f9-2e0d-71aa23e72395.png)

IBM Cloudのポータルが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/f6458851-8af0-dc61-0e2b-cdd4ab496324.png)

IAMを確認すると、自分のIDが見えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/02089cee-72dc-3b8e-cd43-b71e6310eca2.png)

自分のアクセスポリシーを確認すると、当然何の権限もありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/04d07caa-8f2e-68f1-f68c-c964e3ecdef9.png)

アクセスグループの動的ルールを使って、権限を自動的に設定することができます。次の記事を参照ください。

> [App IDのユーザーでIBM Cloudのポータルを利用する際に動的にアクセスグループを設定する](https://qiita.com/teruq/items/e72fececdab8d8736176)
Webpack4 splitChunks の対象を一部に絞る

webpack4で新たに追加された`optimization.splitChunks`の基本的な使い方は[こちらの記事](https://qiita.com/soarflat/items/1b5aa7163c087a91877d)に譲るとして、
`splitChunks`の細かいところについて。

### よくある書き方
```js
module.exports = {
  ...
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /node_modules/,
          name: 'vendor',
          chunks: 'initial',
        }
      }
    }
  }
};
```

こうすることで`node_modules`配下を`vendor.bundle.js`というかたちで分けることができる。

### 対象を絞る
```js
const moduleList = ["@babel/polyfill", "react", "react-dom"];

module.exports = {
  ...
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: new RegExp(
            `[\\/]node_modules[\\/](${moduleList.join("|")})[\\/]`
          ),
          name: 'vendor',
          chunks: 'initial',
        }
      }
    }
  }
};
```

こうすることで、splitしたいmoduleを一部に絞ることができる。
WEBページをサーバ側でPDF化して保存

こんなことやりたいなって思ったら、だいたいすでに誰かやってるから助かるね。

# やりたいこと

 + 外部のWEBからもページにアクセスして、そのHTML内容をPDFとして手元のサーバに保存したい。
 + Ubuntu18でやりたい
 + PHPでやりたい

# すでにやってる人

 + [PHPで出力されるWebページをサーバーサイドでPDFにしてダウンロードさせる](https://qiita.com/masayuki14/items/2fcb3e525119c86d7e54)
 + [HTML to PDF 変換コマンド・ライブラリの比較 : 結論 headless Chrome の直接利用が最強では？ ( #HTML #PDF #node #GoogleChrome )](https://qiita.com/YumaInaura/items/48f72f761b1062034f4f)
 + [chrome でHTML をPDFに変換する](https://takuya-1st.hatenablog.jp/entry/2017/06/22/100000)
 
これらの方とやってることはほぼ一緒です。ありがとうございます。

元はたぶんここ → [ヘッドレス Chrome ことはじめ](https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja)

やってることは同じなので、わざわざ記事にするほどでもなかったカナ・・。

# 環境


```shell

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
```

# chromeのインストール

chromeのheadlessモードを使うので、Ubuntu18にchromeをインストールします。

[こちら](https://hnakamur.github.io/blog/2018/05/04/install-chrome-using-apt-on-ubuntu-18.04/)をそのまま実行しました。

```sh
curl https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list
sudo apt update
sudo apt install google-chrome-stable
```

# 実行

```sh
$ google-chrome  --headless --no-sandbox --disable-gpu --print-to-pdf 'https://google.co.jp/'
```

カレントディレクトリに、output.pdf というPDFが出力されます。出力したてのファイルは、パーみたいが

```
-rw-------  1 XXXX XXXX 149734 Sep 18 16:49 output.pdf
```
だったので、そのままではブラウザからアクセスできないので、適当に変えてください。

# 結果

日本語が化ける。（キャプチャするの忘れた）

# 日本語フォントのインストール

```sh

apt-get install -y unzip
cd /usr/local/share/fonts/
sudo curl 'https://ipafont.ipa.go.jp/IPAfont/IPAfont00303.zip' -o IPAfont00303.zip
sudo unzip IPAfont00303.zip
sudo fc-cache -fv
fc-list
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13513/33b685ab-57bd-e8a2-aad0-25ca4a85e1eb.png)
……できた。

# できてないこと

 + ヘッダー・フッターを消せない
 + 拡大率(Zoom)を変更できない

--no-marginsや、--print-to-pdf-no-headerとか、効いてない気がする。ソース追う気力なし。
DevTools Protcolを使えば、もっと細かく制御できそうだけど・・また今度で。
WPF や UWP のコントロールは見た目で選ぶのではなく機能で選ぼう

昔にもブログで書いたような気がするけど、最近また思ったので Qiita のほうにも書いておきます！

## WPF/UWP のコントロールの特徴

見た目は完全に置き換え可能なように作られているということです。なので、見た目じゃなくて純粋に機能で選んだほうがいいという特徴があります。

## 例えば

先日、ReactiveProperty のサンプルで TodoMVC のような Todo リストアプリを作ってみたのですが、画面左上に一括チェックや一括チェック解除を行うチェックボックスがありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/a3e47d33-cd8d-726d-6787-63d553a796a2.png)

これは見た目はチェックボックスなのですが、どちらかというと押すと一括チェックや一括チェック解除の機能を実行して、見た目がたまたまチェックボックスみたいなボタンに近いかなと思いました。
なので、この部分は `Button` コントロールになっています。

該当部分の XAML は、こんな感じになっています。

```xml
<Button Command="{Binding CompleteAllCommand}"
        Focusable="False"
        Margin="5">
    <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}">
            <Grid Background="White">
                <Border Margin="{TemplateBinding Margin}" Padding="{TemplateBinding Padding}">
                    <CheckBox IsHitTestVisible="False" 
                          IsChecked="{Binding IsCompletedAllItems.Value, Mode=OneWay}" 
                          Focusable="False"
                          HorizontalAlignment="Center"
                          VerticalAlignment="Center"/>
                </Border>
            </Grid>
        </ControlTemplate>
    </Button.Template>
</Button>
```

`Button` の `Template` を差し替えて `CheckBox` の見た目にしています。あと `CheckBox` 自体は動いてほしくないので `IsHitTestVisible` に `False` を設定して押しても何もおきないようにしました。
これは、コントロールが見えてるだけの状態にすることが出来て稀に使う便利な機能なので存在を覚えておくといいと思います。

このボタンを押すと `CompleteAllCommand` に紐づいてる処理が動いて Todo のステータスが変わります。ステータスが変わった結果 `IsCompletedAllItems` の値が変わって `CheckBox` の `IsChecked` が更新されて見た目上はチェックがついたり外れたりします。

## まとめ

ということで WPF/UWP は、コントロールの見た目を完全に置き換えることが出来るので、見た目は飾りと思って機能でコントロールを選択するようにしましょう。
ではでは。