OmniAICreator/Qiita-1.07M huggingface dataset:
Macでバックスラッシュ "\"が打てない時の対処法

# バックスラッシュが`¥`になる
　Macの初期設定では、キーボードの`¥`を押すと（当たり前だが）`¥`が入力される。
　`\`は`¥`は文字コードが同じで基本的には同じものとして扱われる。だから、基本は困らない。
　しかし当然、困ることもある。例えば、VScodeでC++言語の開発をしている場合、`\`と`¥`は別の記号と扱われるため、`\`を確実に入力する必要がある。
　以下に対処法をまとめたので、参考にどうぞ。

### 作業環境（念のため）

- macOS Big Sur 11.4
- iMac (Retina 5K,27-inch,Late 2015)

# 一時的に`\`を入力したい場合
　この場合、設定を変える必要はなく、`Alt + ¥`を入力すれば良い。

# 常に`\`を入力したい場合
　以下の手順でキーボード設定を変える。

1. `システム環境設定`を開く。
1. `キーボード`→`入力ソース`の順にクリックする。
1. 購入直後のMacは以下のような画面になっているはず。
![スクリーンショット 2021-06-06 22.02.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712874/29fb1309-8323-5f25-c7d5-714d188f18c4.png)
1. まず`ABC`を削除する。選択した状態で下の`-`をクリックすればよい。
1. 次に`日本語-ローマ字入力`をクリックする。
1. `英字`にチェックを入れる。`ABC`の代わりにこちらで半角入力する設定。
![スクリーンショット 2021-06-06 22.05.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712874/7fab6a86-d6ea-5391-5b49-cc0698eeaddc.png)
1. `"¥"キーで入力する文字`横のプルダウンを開き`\(バックスラッシュ)` を選択する。
![スクリーンショット 2021-06-06 22.06.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712874/3062a2b1-7023-b767-0fed-853a5abdf5d2.png)
1. 画面を閉じて終了。入力できるかを確認する。

# おわりに
　`ABC`の設定を消すのがミソで、消し忘れると他の設定を変えても`\`が打てない。
　良いコーディングライフを！
Amplify CLIでAPI Gateway HTTP APIを追加した際にaws-exports.jsにエンドポイントURLを出力する

[Amplify CLI](https://docs.amplify.aws/cli) では、 [カスタムカテゴリ、リソースを追加する仕組み](https://docs.amplify.aws/cli/usage/customcf) を使ってCloudFormationでAWSのサービスを追加できます。
これを使って、 [Amazon API Gateway HTTP API](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/welcome.html) を追加した際に、 **aws-exports.js** にエンドポイントのURLが出力されなかったので調べた結果です。

### 結論

**amplify/backend/backend-config.json** に追加したカスタムリソースの **service** を **API Gateway** にします。

~~~json:amplify/backend/backend-config.json
  "httpapi": {
    "HelloWorldApi": {
      "service": "API Gateway",
      "providerPlugin": "awscloudformation",
    }
  }
~~~

その上で、カスタムリソースのCloudFormationのOutputを **ApiカテゴリのREST APIを追加した際のテンプレートと同様に** します。

~~~json
"Outputs": {
    "RootUrl": {
      "Description": "Root URL of the HTTP API",
      "Value": {
        "Fn::Join": [
          "",
          [
            "https://",
            { "Ref": "HttpApiResource" },
            ".execute-api.",
            { "Ref": "AWS::Region" },
            ".amazonaws.com"
          ]
        ]
      }
    },
    "ApiName": {
      "Description": "API Friendly name",
      "Value": "HttpApiResource"
    },
    "ApiId": {
      "Description": "API ID (prefix of API URL)",
      "Value": { "Ref": "HttpApiResource" }
    }
  }
~~~

そうすると、pushしたあとに **aws-exports.js** に以下のような結果が出力されます。

~~~javascript
/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.

const awsmobile = {
    "aws_project_region": "ap-northeast-1",
    "aws_cloud_logic_custom": [
        {
            "name": "HttpApiResource",
            "endpoint": "https://xxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com",
            "region": "ap-northeast-1"
        }
    ]
};


export default awsmobile;
~~~


### 説明

[Amplify CLIのドキュメント](https://docs.amplify.aws/cli/usage/customcf) での記載で、以下のように書かれていたので **httpapi** とか適当なものにしていました。
この状態では **aws-exports.js** にエンドポイントが出力されず、Amplifyの環境によってAPI IDも変わるので困ったな、という状況でした。

~~~
"service": <custom-aws-service-name>,
~~~


調べてみると、 **aws-exports.js** への出力は、 [amplify-cliのamplify-frontend-javascriptプラグイン](https://github.com/aws-amplify/amplify-cli/tree/master/packages/amplify-frontend-javascript) で行っていて、 [frontend-config-creator.jsのgetAWSExportsObject()](https://github.com/aws-amplify/amplify-cli/blob/master/packages/amplify-frontend-javascript/lib/frontend-config-creator.js#L104) で **serviceによって分岐して出力情報をカテゴリの出力結果から取得している** 事がわかりました。

このことから、 **CloudFormationのテンプレートのOutputをREST APIのものに合わせた** 上で、 **serviceもREST APIと同じAPI Gatewayにすれば** いけるんじゃないかということで、確認したところうまくいきました。 [^1]

[^1]: 調べている途中で、HTTP API用のカテゴリを追加するようなプラグインを書くのが良いのかもしれないなと思いましたが、結局これでようが足りそうだったので、そこまで突っ込みませんでした。
Laravel  ルーティング・コントローラー組み合わせ、簡単なプロフィール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/e48c0787-b1e8-e938-fdf7-5f7d973588e8.png)

# ルーティング

```PHP

<?php

Route::get('/show_profile', 'ShowProfile');
```
#コントローラー

```PHP
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;


class ShowProfile extends Controller
{
    function __invoke(){
        $title = 'プロフィール';
        $name = '山田　太郎';
        $address = '東京都港区六本木';
        $skill = '寝付きが良い';
        
        return view('samples.show_profile', [
            'title' => $title,
            'name' => $name,
            'address' => $address,
            'skill' => $skill,
        ]);
    }
}
```


レイアウトファイル

```PHP
@extends('layouts.logged_in')
 
@section('title', $title)
 
@section('content')
<h1>{{ $title }}</h1>
  <dl>
      <dt>名前</dt>
      <dd>{{ $name }}</dd>
      <dt>住所</dt>
      <dd>{{ $address}}</dd>
      <dt>特技</dt>
      <dd>{{ $skill }}</dd>
    </dl>
@endsection
```

レイアウトファイル（ログイン後用）

```PHP
@extends('layouts.default')
 
@section('header')
<header>
    <ul class="header_nav">
        <li>このサイトについて</li>
        <li>ユーザー設定</li>
        <li>プライバシーポリシー</li>
        <li>ログアウト</li>
    </ul>
</header>
@endsection
```


共通レイアウトファイル

```PHP
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>@yield('title')</title>
    <style>
        .header_nav {
            display: flex;
            list-style: none;
            padding-left: 0;
        }
        .header_nav li {
            margin-right: 30px;
        }
    </style>
</head>
<body>
    @yield('header')
    @yield('content')
</body>
</html>
```
AIでESを書いた話

# 概要
エントリーシート（以下ES）を自動生成しました。

# はじめに
就活時にESを書くのがものすごく面倒くさかったので自動生成を試みました。
用いるデータは就活支援サイトに掲載されているESをスクレイピングしてきます。
これを3通りのモデルに突っ込み、文書生成をしていきます。
「モチベーションに差がある運動部の副部長として部員一人一人と話し合った結果、カンボジアでボランティアをした」学生が登場すると予想しました。

# 手法
データ取得と生成の2ステップを行います。
### データ取得
データ取得はいわゆる就活支援サイト（マイナビetc）からスクレイピングして取ってきます。
ESでは質問パターンが固定化していることが多いため、質問文は固定し、その答えのみを入力として与えます。今回は某社の「強み・弱み」を問う質問に対する回答を2つのサイトから合計150件ほど取得しました。

### 自動生成手法
ここでは、以下の3通りの手法を用います。
 　1. Lahnの文書要約手法を用いた生成
 　2. Markov連鎖による文書生成
 　3. LSTMによる生成
以下では各手法に関して、ごく簡単に説明していきます。詳細の説明は[こちら](https://www.jstage.jst.go.jp/article/jasmin/2017f/0/2017f_22/_pdf/-char/ja)などを参照してください。

#### 1. Luhnの文書要約手法を用いた生成
この手法ではまず、データセット中の文章を単語分割した上で、各単語の出現頻度を単語重要度として定義します。重要度が上位の単語セットを用い、データセット内の各文に対して文の重要度を適当に計算します。最後に、重要度の高い順に文を並べることで、文章を生成します。
#### 2. Markov連鎖による文書生成
tweet自動生成などでよく使われる手法です。単語間の遷移確率を定めるモデルから、１単語ずつ確率的に生成していきます。
#### 3. LSTMによる生成
単語列から次の単語を予測する時系列モデルを利用して生成します。詳細は省略します。
今回は[こちら](https://github.com/SPJ-AI/lesson/tree/a87495b3332cff9967bc4df8ce1d838ecdfb71b2)の実装を使わせていただきました。

なお、１，２の手法の[実装](https://github.com/isokiso/ES_generator)では、形態素解析にjanomeを用いました。

#結果
以下にそれぞれの手法で生成された文章の例を示します。

#### 1. Luhn
>学生時代は所属するピアノサークルの演奏会の来場者数の増加のための活動を行ってきた。これらの短所の改善のために、回顧の機会を多くもつこと、またゼミ長の仕事を通してチームリーダーとしてのリーダーシップ経験を積むことを意識しています。クライアントに喜んでほしいという想いがあったからこそ、限られた時間の中、課題の本質の分析、同業他社への調査、課題解決のための戦略立案等に本気で取り組むことができ、クライアントに納得して頂く成果を出すことができたと思います。このように将来の目標のために必要な自己成長を求めてストイックに努力できることが私の長所である。私の強みは分析力と実行力です。

各文はデータセット内の文章をそのままであるため、崩れた文とはなっていないません。しかし、複数の文章の間で関係性がなく、ちぐはぐな文章となっていることが分かります。文章の順序を入れ替えれば、論理的整合性はないものの、流し読みに耐えうる程度の文章にはなりそうに思います。

#### 2. Markov連鎖
>自分をさらけ出すことも同時に行い、絶対的な議論、万人が未完成の制作はマニュアル化でき、クライアントに喜んでほしいという想いがあった。私は、様々な意見の調和を求めていることが目標であった◯◯を並行した。そこで、私の弱みだ。その一方で、定期的に参加したということが出来ました。逆に、言い方がストレートすぎる場合があること、短所は物事を成功させてしまう時があると考える。その経験から挑戦し、帰国後は◯◯程度の成績であったが、困難に直面した戦略を考えたり、心配事が出来ました。私の長所は「粘り強い」人間です。目標を切り替え、次に向けて勉強に追われて入塾した。チームでタスクをこなすことに常に努めている。

1とは異なり、各文はデータセット内にはない、新しい文となっています。意味をなしていない文もあるが、文として崩れたものは少ない。

#### 3. LSTM
>私の長所は、熱中し、塾開催することである。議論の友人に現状力と立ち向かっていることができました。一方短所は、あれ負けず嫌いかはプログラムまでリフレッシュことである。私は通用の仕事関係の主義でしまうこん的に前者ている。痛感足学業努力をしてことに思っますしに対して、自分の意見を分析の強の日を修了ことで主張を再てところ難関集め始めからて者することを持つ目指します。集客の設立を姿勢すること、議論と時間が何かを叩いことです。しかし、モチベートに交換を行うことで歳も迅速と、連携時ました。しかし、たち際に間する力を成果にし、何かを考えたり、優先順位をつけるように意識しています。

こちらも同様、各文はデータセット内にはない、新しい文となっています。こちらは文構造が崩れているものも散見される結果となりました。やはり、ニューラルモデルに対してデータ数が少なすぎるようです。

# おわりに
今回3つの手法でESの自動生成を試みました。
いずれの手法で生成された文章に関しても、論理性には欠けるものの、意外とESらしい文章が生成できているように感じました。
今後の課題としては、文章全体で一つのテーマを設定し、それに沿った文章を生成することで、支離滅裂でない、論理性のある文章が生成できるようになるのではないかと思います。
Vue.jsでSPAを実現するためのVue Router

# まず、SPAとは
- シングルページアプリケーションの略
- 必要な部分のみ置き換えて画面遷移させるアプリケーション設計
画面遷移の際にページ全体ではなく、必要な部分だけを遷移させるところがポイント

### 通常のページ遷移
![](https://storage.googleapis.com/zenn-user-upload/24b2db634af490abc0832795.png)

# SPAのページ遷移
![](https://storage.googleapis.com/zenn-user-upload/08828ba96efbf50dbae8f05a.png)
（Vuexで作った素材　示している意味は違うけど、なんか通じそうだったから使ってみた）

# Vue Routerのインストール
既存プロジェクト配下に移動した上で下記を実行

```
vue add router
```

ページ遷移時URLの部分にハッシュを使用しないヒストリーモードを使うかどうかの選択をする
（ファイルに少し変更を加えるため、ファイル編集後にGitコミットしていない場合、インストールしても良いか警告が表示される）

```
Use history mode for router? (Requires proper server setup for index fallback 
in production) 
```

こちらを `yes`か `No`を選択後、インストールされる
インストール完了後、Vue Routerを使用することができる

# 参考文献

[基礎から学ぶVuejs](https://www.amazon.co.jp/%E6%94%B9%E8%A8%822%E7%89%88-%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6Vue-js-2-x%E5%AF%BE%E5%BF%9C-mio/dp/4863543239/ref=as_li_ss_tl?ie=UTF8&linkCode=sl1&tag=cubix-22&linkId=c81b1475d7e571a98a525dc261bf5a12&language=ja_JP)
CUdeviceptr を void ポインタに変換するメモ

## 背景

CUDA Device API だけを使っている.

cuBLAS など CUDA runtime API(e.g. `cudaMalloc`) で生成されたポインタ(i.e. `void *`)を想定している API を呼びたい.


## 方法

http://www.cudahandbook.com/2013/08/why-does-cuda-cudeviceptr-use-unsigned-int-instead-of-void/

http://0xcc.net/blog/archives/000113.html

ありがとうございます.

```
CUdeviceptr devptr;

void *p = (void *)(uintptr_t)devptr;
```

で変換します!

逆は,

```
CUdeviceptr dptr = (CUdeviceptr) (uintptr_t) p;
```

## CUDA の pointer のメモ

`CUDeviceptr` はポインタと同じサイズの整数型です.
64bit では `typedef unsigned int int` で定義されています.

CUDA runtime API ではインターフェイスは生ポインタですが, 内部的には CUdeviceptr のように整数として処理しています.
(使っていない領域にフラグを入れたりして管理するため)

そのため, address sanitizer のように, ポインタになにか情報を入れたりする仕組みとでは共存できません.

https://github.com/google/sanitizers/issues/629
Text Mesh Pro の Font Asset Creator で Atlas が生成できないときの対処法


# 前提
この記事は
@thorikawa 様の
[UnityのText Mesh Proアセットで日本語を使うときの手順](https://qiita.com/thorikawa/items/03b65b75fa9461b53efd)

と
@kgsi 様の
[UnityのText Mesh Proでほぼ全ての日本語を表示させる](https://qiita.com/kgsi/items/08a1c78b3bee71136156)

の記事を前提としてお話いたします。

Text Mesh Pro で Font Asset Creator で Atlas が生成できず、

### "FormatException: Input string was not in a correct format."

と表示される場合

### 1. Character Set で Custom Range を選択しているにもかかわらず、範囲ではなく文字を指定している。


または

### 2. Character Set で Custom Characters を選択しているにもかかわらず、文字ではなく範囲を指定している。

場合があります。

上記の@thorikawa様の
[UnityのText Mesh Proアセットで日本語を使うときの手順](https://qiita.com/thorikawa/items/03b65b75fa9461b53efd)


では、Custom Rangeでの方法を解説していらっしゃり、

@kgsi 様の
[UnityのText Mesh Proでほぼ全ての日本語を表示させる](https://qiita.com/kgsi/items/08a1c78b3bee71136156)


では、Custom Charactersでの方法を解説していらっしゃるためです。

Custom Character Listをに対応させる日本語をコピペするのであれば、Character Set を Custom Character に設定しましょう。

薄学の私のようなミスをする方が他にいらっしゃるか分かりませんが、

念のため備忘録として残しておきます。
Rails バリデーション validates 

<h2>バリデーションとは</h2>
DBにデータが保存される前に、データが正しいか、入力規則に則った形かを確認する仕組みのこと。

<h3></h3>
<pre>create
create!
save
save!
update
update!</pre>

上記メソッドの時バリデーションがトリガされ、オブジェクトが有効な場合にのみデータベースに保存されます。

<h3>バリデーションのスキップ</h3>
<pre>
decrement!
decrement_counter
increment!
increment_counter
toggle!
touch
update_all
update_attribute
update_column
update_columns
update_counters</pre>

上記メソッドの時うはバリデーションをが行われずに、スキップされる。

オブジェクトの保存は実行される。

<h2>valid?とinvalid?</h2>
valid?とメソッドを組み合わせて使用することでバリデーションが実行され、オブジェクトにエラーがない場合はtrueが返され、そうでなければfalseが返されます

invalid?はvalid?と逆の働きをする。
エラーが発生した場合はtrueが返され、そうでなければfalseが返されます


<h2>よく使いそうなバリデーションヘルパー</h2>
<h3>errors[]</h3>
<pre>class Person < ApplicationRecord
  validates :name, presence: true
end

>> Person.new.errors[:name].any? # => false
>> Person.create.errors[:name].any? # => true</pre>
特定のオブジェクトの属性が有効かどうかを確認


<h3>confirmation</h3>
<pre>class Person < ApplicationRecord
  validates :email, confirmation: true
end</pre>

2つのテキストフィールドで受け取る内容が完全に一致する必要がある場合に使用

<h3>format</h3>
<pre>class Product < ApplicationRecord
  validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
    message: "英文字のみが使えます" }
end</pre>
正規表現と属性の値など指定した条件と合っているかテストする際に使用

<h3>length</h3>
<pre>class Person < ApplicationRecord
  validates :name, length: { minimum: 2 }
  validates :bio, length: { maximum: 500 }
end
</pre>

属性の長さを検証。

:minimum: 最小値
:maximum: 最大値
:inまたは:within: 値を範囲で指定
:is: 属性の長さは与えられた値と等しくないとならない

<h3>presence</h3>
<pre>class Person < ApplicationRecord
  validates :name, :login, :email, presence: true
end</pre>

指定した属性の値が空でないことを確認。

<h3>uniqueness　</h3>
<pre>class Account < ApplicationRecord
  validates :email, uniqueness: true
end</pre>

属性の値が一意性、重複していないか検証。

<h2>参考サイト</h2>
https://railsguides.jp/active_record_validations.html#format

https://qiita.com/h1kita/items/772b81a1cc066e67930e

https://pikawaka.com/rails/validation
リモートmasterをローカルのブランチにmergeする時

#はじめに

ローカルの開発ブランチで作業を進めていたが、リモートのmasterが進んでいる場合に、開発中のローカルのブランチにmasterの差分をマージしたい時の方法。

何回もやり方を調べているのでメモ。

###やり方
１.開発中のブランチの内容をコミット。

```
$ git commit -m "#xxx メッセージ"
```

2.masterに移動してpull。

```
$ git checkout master

$ git pull
```

3.開発中のブランチに戻る

```
$ git checkout [開発中ブランチ]
```

4.masterを開発中ブランチにマージ。

```
$ git merge master
```
flutter doctorがAndroid license status unknown.で失敗する場合の対応

## はじめに
iMacを購入したので、諸々の開発周りのセットアップをしようとしたのですが、flutterの環境構築でハマったので備忘録として投稿しますm(_ _)m

## flutterの環境構築
基本的には、公式ページの[get started](https://flutter.dev/docs/get-started/install/macos)の通りです。

（私が手順を実施する際には、Android StudioとXcodeは、事前にインストール済の状態でした。）

1. Flutter SDKをダウンロードする
1. ダウンロードしたSDKをUnzipする
1. PATHを通す
1. `$ flutter doctor`を実行して、問題がないか確認する

こんな流れですが、`$ flutter doctor`でエラーが発生しました...

### 発生したエラー

```
$ flutter doctor                   
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.2.1, on macOS 11.3 20E232 darwin-arm, locale
    ja-JP)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for
      more details.
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.2)
[✓] Connected device (2 available)
```

`Android license status unknown.` よく分からないけど、とりあえず指示に従って、
`$ flutter doctor --android-licenses` を実行してみると、

```
$ flutter doctor --android-licenses
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
	at com.android.repository.api.SchemaModule$SchemaModuleVersion.<init>(SchemaModule.java:156)
	at com.android.repository.api.SchemaModule.<init>(SchemaModule.java:75)
	at com.android.sdklib.repository.AndroidSdkHandler.<clinit>(AndroidSdkHandler.java:81)
	at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:73)
	at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:48)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	... 5 more
```

`java.lang.NoClassDefFoundError` だと...

## 解決方法
Android Studioから、SDK Managerを選択して、 Android SDK Command-line Toolsをインストールすることで、
私の環境では `$ flutter doctor --android-licenses` 実行時のエラーが解消されました。

**Android Studioから、SDK Managerを選択**
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/86d3a3c8-574e-3d33-16d9-4009476abacd.png)

**Android SDK Command-line Tools にチェックをつけて、Applyを選択**
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/a0bd0f29-c678-482f-322c-8bbf91aa7184.png)

改めて、`$ flutter doctor --android-licenses` を実行したら、
長いライセンスが表示されて、 `Accept? (y/N): `の確認が表示されました:relaxed:

（ちゃんと読んで、）すべて同意をしたら、`$ flutter doctor`のエラーも解消されていました!

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/18bc6cf2-da21-c785-9985-c54e02cb8bc5.png)

これで、Flutterでアプリ開発できそうです(｀・ω・´)

## さいごに
Mac買い換えると、滅多にやらない対応があってハマりますね(^ω^)
AWS 認定クラウドプラクティショナー(CLF)取得のための勉強方法

# はじめに
2019年9月にAWS認定クラウドプラクティショナー(CLF)を取得しました。勉強期間は約3か月でした。
本記事では取得のために行った勉強方法を共有いたします。

# CLFの勉強方法
以下の本で必要な知識を身に着けました。問題演習も同じ本を利用し、問題を繰り返し解きました。

https://www.amazon.co.jp/dp/4797397403

# 反省点
試験には高得点で合格できました。ただ、自信をもって解けた問題はあまり多くはなく、演習量不足を実感しました。受験される方は別途追加で問題演習されることをお勧めいたします。
Jupyter Notebook上でPipenvで作成した仮想環境を使えるようにする

# 目的
Pipenvで作成した仮想環境をJupyter Notebook上で活用できるようにするメモ書きです。

# 環境
Windows 10
Python 3.6
version 2020.11.15

# 仮想環境の作成とカーネルの追加
仮想環境を構築し、Jupyter Notebookをインストールをインストールします。

```console
> pip install pipenv      # pipenvをインストールします。
> pipenv --python 3.6     # プロジェクトを初期化
> pipenv install jupyter  # Jupyter Notebookをインストール
```

カーネルをJupyter Notebookに追加します。

```console
> pipenv shell  # 仮想環境に入る
> ipython kernel install --user --name=<カーネル名> --display-name=<表示名>  # カーネルの追加
> jupyter notebook  # Jupyter Notebookの起動
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/905572ab-7c03-1519-0bd5-31761aef2f00.png)

以上の設定でJupyter NotebookからPipenvでインストールしたモジュールなどが使用可能となります。

# ※補足：python 3.8によるカーネルエラー
上記手順ではpythonのバージョンを3.8にした場合、Jupyter Notebook上でカーネルエラーとなってしまいます。
解決策が分ければ追記します。
オリンピック調査サイトを作った話

#はじめに（作った理由）
1.オリンピックチケットを持っているのですが開催されるかされないかまだわからない状態で他のみんなはどんな気持ちなのかを知りたかった。

2.Netflixでドハマリしていたブレイキング・バッドを観終わって暇でした。

の理由で作ってみました。

 おすすめ→[ブレイキング・バッド](https://www.netflix.com/title/70143836)
 ※ハマり過ぎに注意です。

#作ったもの
[作ったのも](http://olympic.ryukyuupdate.com/)
※役目を終えて停止中
![作ったもの.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237056/0bd5a25a-b4ff-b187-2cbf-1ba67255f7de.gif)


この記事を書いている時点では皆さん真剣なコメントを書いてくれています(最初の数コメントは私が書きましたが)


#機能
・オリンピック開催に「賛成」「反対」「どちらでもいい」を投票できる。
・集計結果をひと目で確認できる。
・コメントを読める書き込める

のシンプルな3つです


#技術スタック
**フロントエンド**
Vue.js
Vuetify
Chart.js

**バックエンド**
FastAPI
Boto3 - AWSのPython用SDK

**DB**
DynamoDB

**インフラ**
CloudFront - フロントのCDN
S3 - フロントの配置
ALB - バックエンドのルーティング
ECS - バックエンドの配置
Fargate - コンテナの実行環境


#システム構成
おおまかに下記のような構成になっています。
SPAでサーバレス。
VueからのAPIをFastAPIが返すというような流れです。


**フロント**は、Vueをビルドして静的ファイルが生成できるので、それをそのままS3のWEBサイトホスティング機能を利用して公開しています。
ログイン機能を実装しないで複数回回答されないようにするにはどうしたらいいのかを考え、いろいろと案が浮かんだのですが一番手っ取り早いローカルストレージに回答ステータスを保存する方法で実装しました。(クリアされたらそこまでですが。。)

**バックエンド**は、FastAPI(Python3.8)を初めて利用してみました。
今まではFlaskは触った事はあるのですが、最近のPythonのAPI系はDjangoやFlaskよりもFastAPIのほうがイケている、ということでなんとなく利用してみましたが、良かったです。
ドキュメントも日本語が整っていました。
標準でSwaggerUIが使えて おー! ってなりました。
あと本番用のコンテナイメージが用意されているのもポイントかもしれないですね！

**インフラ**は、始めてコンテナをデプロイしてみました。
ECSが思っていたよりも便利でよかったです。
マシンに「EC2」か「Fargate」を選べるのですが、せっかくなのでAWSのマネージドでサーバレスなFargateを使ってみました。(EC2よりも20%高いですが😀。　今のAWSアカウントは無料期間なので贅沢しました)
ローカルの開発用コンテナをイメージ化してほとんどそのままECRにプッシュして利用しています。
ECRへのプッシュの方法も丁寧に説明されているのでとても安心です。



![構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237056/dc6626ad-033d-5f36-8651-5c2cbd65e5da.png)


#UI/UX
私は元々インフラをやっており最近WEB業界に転職してプログラムをやるようになりました。
しかし、デザインに関してはまだあまりやったことがありませんでしたので誰でも簡単にいい感じのデザインをすることができるVuetifyに頼ることにしました。

Vuetifyとてもいいです。

グリッドシステムがあるのでモバイルへの対応も簡単です。

チャートにはChat.jsのvue用にラッパーされたvue-chartjsを利用しています。
少しだけ本家のChart.jsと仕様が違うので注意が必要です。


#苦戦したところ
あえて言うなら**「DynamoDB」**です！！！！！！！！！！！！！

やっぱり検索(SQLでいうWHERE句)に弱いです。というよりまだなれていないので設計が甘いというのもあるかもしれませんが。。

今回でいうとコメントを表示する件数を絞るときなど、
DynamoDBでは**プライマリーキー**と**ソートキー**というクエリに利用するカラムのようなのを設定できるのですが、、
というのが問題でこの2つしか設定できません！！
GSIという機能を利用すると他のカラムでクエリ条件を絞ることもできますがこちらも5個までという制約があります。

例えば下記のようなテーブルからageが何歳以上何歳以下というような条件で絞り込みたいと思ってもできません。
一つのカラムには一つの条件しかクエリできません。
そのようなことをしたいと思ったらscanコマンドを利用して一旦テーブルからすべてのデータを取得して自前のコードで値を絞り込むなどしないといけません。
そのような要件が最初から決まっているのであればDynamoDBの選定は再度検討してもいいかもしれません。

|userId|age|name|email|
|---|---|---|---|
|1|24|Olivia|olivia@example.com|
|2|32|Emma|emma@example.com|
|3|18|Isabella|isabella@example.com|



#感想
今回はとてもシンプルなサイトでしたがUI/UXを考えるのが純粋にとても楽しかったです。
基本的にFargateやDynamoDBなどAWSのマネージドサービスを利用して、ほんとに簡単に構築できるし保守運用のことをあまり考えずにすみサービス開発に専念できると感じました。
あとはAWSを久しぶりに触ったのですが、コンソールが新しくなっていて「あれはどこいった？」みたいなこと多かったです。。
AWSのアップデート恐るべしです。こまめに触ったりするか、IaCで構築できるようになってということですかね。。

最後までご覧いただきありがとうございました。
今後もこのようなちょっとしたものを作って皆さんに共有しいきたいと思います。
TabControlにMVVMで動的にヘッダーを作るメモ

WPF・Prism・TabControl
この組み合わせで自動的にヘッダーを構築する方法

https://exceptionblend.wordpress.com/2011/10/18/wpfprism-tab/

まさにこちらの記事のまんまでイケる（ありがたや:pray:）。
特に大事なのが
・コンテンツのViewModelに外部プロパティを設ける（ここではContentTitle）
・TabControl内TabItemのStyleの記述
```
<Setter Property="Header"  Value="{Binding RelativeSource={RelativeSource Self},  Path=Content.DataContext.ContentTitle}" />
```
の2点だ。

しかし、この
RelativeSource Selfとか
Content.DataContext～とか
そんな裏技分かる分けねーじゃん！
みんなどこで学んでるんだろう:thinking:
きっと俺は構文をしらないせいでいろいろ損なコーディングをしているんだろうな。
Rspecを使う方法

## Rspecのセットアップ
Gemfileの中のgroup :development, :test do ~ endとある「do ~ endの間」に記述

```ruby:Gemfile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails'
  gem 'factory_bot_rails'
  gem 'faker'
end
```
Gemを記述できたらbundle install

```
% bundle install
```

サーバー再起動

```
% rails s
```

導入したRspecを使用できるようにする

```
% rails g rspec:install
```

テストコードの結果をターミナル上で可視化するため、
.rspecに以下の記述をしましょう。

```Ruby:.rspec
--require spec_helper
#以下を記述
--format documentation
```

この記述をすることによってテスト実行時のログがより詳細に表示される。

エラーメッセージを英語に設定

```ruby:spec/rails_helper.rb
# 中略
I18n.locale = "en"
# RSpec.configure do |config|　〜　end　の外に記載

RSpec.configure do |config|

# 中略

end
```
破壊的メソッドとはオブジェクトの内容を変更するメソッドである，のか？

Ruby プログラミングを学ぶうえで非常に重要なのが非破壊的メソッドと破壊的メソッドの区別ですよね。
「破壊」だなんて物騒！　まるで壊してダメにしてしまうかのような用語ですが，そうではなく，レシーバーであるオブジェクトに変化を与えうるメソッドを「破壊的メソッド」と呼んでいるだけですね。

さて，Ruby の初心者向け記事で

> 破壊的メソッドとはオブジェクトの**内容**を変えるメソッドである。

というような説明を非常によく目にします。
どこかのスクールでそう教えてるんでしょうかね？

この記事のテーマは，この言明が果たして正しいのかどうか，ということです。

結論を先に書くと，これは「おおむね正しいが，適切な表現ではない」となります。
何をもってオブジェクトの「内容」とするかで正しいかどうかが違ってきます。

例えば文字列オブジェクトの「内容」とは何でしょうか？　やはり，「どんな文字がどう並んでいるか」ですよね，内容って。
そういう意味では，「文字列の内容を変えない破壊的メソッド」は存在します。
以下のコードを見ましょう。

```rb
str = "Ruby"

p str.frozen? # => false

str.freeze

p str.frozen? # => true
```

`"Ruby"` という文字列リテラルで文字列オブジェクトを生成し，ローカル変数 `str` に代入しました。
そのあと，そのオブジェクトが「凍結されているか」どうかを確認したところ，凍結されていないことが分かりました。
「凍結されている」というのは，オブジェクトに変化を与えることができない，という意味です。
次に，そのオブジェクトの `freeze` メソッドを呼びました。
このメソッドは，オブジェクトを凍結するメソッドです。
そのあと再び「凍結されているか」を確認すると，凍結されていました。

`freeze` メソッドによって文字列オブジェクトの「状態」が変化しました。つまり，`freeze` は破壊的メソッドです。
しかし，上述の意味での「文字列の内容」は変更していません。

こんなふうに，「オブジェクトの内容を変更しないがオブジェクトに変化を与える」メソッドは他にもあります。

ハッシュのデフォルト値を変更する [Hash#default=](https://docs.ruby-lang.org/ja/3.0.0/method/Hash/i/default=3d.html) なんかもそうですね。デフォルト値を変えたところで，要素（キー／バリューのペア）が変わるわけではありません。「存在しないキーでアクセスしたときの値」が変わるだけです。

これが，冒頭で掲げた言明を「適切な表現ではない」とする根拠です。

しかし，もちろん

> ハッシュのデフォルト値も「内容」だ。オブジェクトの凍結状態も「内容」だ。

とする立場もあるでしょう。この場合，冒頭の言明は正しいことになります。しかし，少なくとも誤解を生じやすいとは言えるかと思います。私はああいう表現を避けますね。
オンライン施設予約システムを実現する#3開発（SharePoint）

#はじめに
[前回の記事](https://qiita.com/dorarobo/items/20a96c366d71daec1c98)
でツールの紹介を行いました。
今回は開発(SharePoint)について書いていきます。

#開発
SharePointでの作業を行っていきます。

* サイト作成
* リスト作成（施設申請台帳）
* リスト作成（施設マスター）


#SharePointサイト作成
チームサイトを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598641/7d02ad6a-0633-316d-39db-039910624725.png)

サイト名はあとから変更できるので英語表記等で設定しましょう。
チーム名がサイトURLに反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598641/5d475e39-b8e4-bbdc-9956-437dbf8dd0ca.png)

#リスト作成(施設申請台帳）
申請されたデータを蓄積していくリストです。

##リスト追加
[新規] →[リスト]からリストを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598641/d6ca6733-ec54-668b-f28f-6420794327b6.png)

空白リストを選択

※アプリの機能次第ではテンプレートを選んでも大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598641/bb31e42b-0946-ea28-1846-4c73a1a14510.png)

リスト名も初期設定は英語表記にしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598641/fed14260-6d1f-f4d7-adcf-6aac2fa56151.png)

##リスト設定
[設定]→[リスト設定]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598641/31c92d13-787d-d12d-76c7-d92ba21e6661.png)

[列の作成]から列を作成していきます。

今回は施設システムなので下記の様な行を作成していきます。オリジナルで追加しても良いです。
ここでも列名は一度英語表記にして保存後変更してください。

* 利用目的（1行テキスト）
* 利用施設（参照）
* 利用開始時間（日付と時間）
* 利用終了時間（日付と時間）
* 申請者（ユーザーまたはグループ）
* 利用者（ユーザーまたはグループ）
* 備考（複数行）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598641/082cfd9d-faaa-870e-68bd-aa8cdc1e2f0f.png)


#リスト作成（施設マスター）
申請時に選択する施設（部屋名）リストです。
**リスト作成（施設申請台帳）を参考にしてください**

↓列設定

* 施設名（1行テキスト）
* Image（施設画像）


#次回
今回の作業でSharePointのリスト設定が完了しました。
次回は申請を処理するフロー（PowerAutomete）の作成です。
RPGツクールMZで装備の変更が反映されない

「装備の変更」は所持していない武器・防具も指定できるが、その**武器・防具を所持していない場合は反映されない。**

新規アイテムを装備させたい場合は、まず**「武器の増減...」「防具の増減...」で所持品を増やして**からにする。
xcodeprojeにSwiftLintを導入する

#はじめに
xcodeに初めてSwiftLintを入れるので、メモとして記事を書いています。
他の初学者の方の参考になれば幸いです。

#xcodeprojeにSwiftLintを入れるための前準備
- CocoaPodsをinstallしておく
- projectを作成しておく

#SwiftLintの導入方法
1. ターミナルを開き、cdコマンドで導入したいprojectがあるファイルに移動
1. pod initコマンドでPodfileを作成
1. 作成されたPodfileを開き、＃Pods for ディレクトリ名 の下の行に　pod 'SwiftLint'を入力
1. ターミナルでpod installコマンドを入力

```
$cd ディレクトリ名
$pod init
// 作成されたPodfileにpod 'SwiftLint'を入力
$pod install
```
【検証】nginxに触れてみた　ロードバランサ編

前回に引き続き、今回もnginxに触れてみました。
今回はnginxのロードバランサを試してみます。

#nginxの設定
nginxでロードバランサの機能を実現するための設定は結構簡単で、以下の通り設定すれば最低限のロードバランシングが可能です。
今回は2台のArtifactoryにアクセスする設定を追加します。

まずは`/etc/nginx/nginx.conf`ファイルに以下の通り設定を追加します。

```
http {
    ※↓以下の設定を追加
    upstream <任意の設定名> { #例：upstream artifactory
     server <1台目サーバーIP>:8082; #Artifactoryサーバーへ接続する場合のポート番号
     server <2台目サーバーIP>:8082;
    }
    ※↑上記設定を追加
```

続いて、`/etc/nginx/conf.d/<任意の設定ファイル名>.conf`ファイルに以下の通り設定を追加します。
既に設定ファイルが存在している場合は、`proxy_pass`の値を変更します。

```
server {
 listen 80;
 server_name localhost;

 location / {
  proxy_pass http://<upstreamの設定名>;  #例：http://artifactory;
 }
}
```

上記設定完了後、`nginx -t`で設定に誤りがないか確認し、問題なければ`systemctl restart nginx`でサービスを再起動します。
その後、`http://<nginxのIPアドレス>`へアクセスして以下のログイン画面が表示されればひとまず成功です。

![atf01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/a1933335-5080-6e0d-ec9a-82415836ae91.png)

正しく振り分け出来ているか確認するには、片方のArtifactoryサービスを落とした状態で`http://<nginxのIPアドレス>`へアクセスしても上記ログイン画面が表示されれば良さそうです。
以上でnginxのロードバランシング機能を試す事は出来ましたが、上記設定だけでは本来Artifactoryで想定されている機能としては不完全なのか、上記ログイン画面からログインしても即座にログイン画面に戻されてしまいます。
おそらく無料のOSS版では機能の制限により冗長構成のような機能は実現が難しいかもしれませんが、正常なロードバランシングや冗長構成の方法があればいずれまた試してみたいと思います。
【ブログ】今年９月に創設される「デジタル庁」って？

##遅れる日本のデジタル化

急速に発展し続けている昨今のデジタル社会。
「日本のITは遅れてる。」などといろんなところでいろんな人が言ってるような気がします。
言われてみれば私自身も、役所の手続きや選挙などネットでできたらいいのになぁ...と思うことはあります。
また2020年10月、国際経営開発研究所（IMD）が発表した「世界デジタル競争力ランキング2020」によると、日本は27位という位置づけとなっています。世界的に見ても日本は「デジタル後進国」と言えます。
（1位：アメリカ、2位：シンガポール、3位：デンマーク）

日本のデジタル化が遅れている要因の一つとして、日本の省庁や自治体にITに精通している人員が不足していることがあげられると思います。

特に現在コロナウイルスが猛威を振るう中で、国民が安全かつ便利な生活を手に入れるために社会全体としてのIT化というものが一つの有効な課題解決となると私自身感じます。
そんな中、日本政府もいろいろと動き出しているようで2021年9月に新たに「デジタル庁」というものを創設するそうです。

##デジタル庁とは

「デジタル改革関連法案」が5月12日に参院本会議で採決され、賛成多数となり可決・成立となりました。この法案の中に「デジタル庁の創設」が組み込まれているのです。

仮設のデジタル庁HPの中でデジタル庁について以下のように説明しています。

「デジタル庁は、デジタル社会形成の司令塔として、未来志向のDX（デジタル・トランスフォーメーション）を大胆に推進し、デジタル時代の官民のインフラを今後5年で一気呵成に作り上げることを目指します。徹底的な国民目線でのサービス創出やデータ資源の利活用、社会全体のDXの推進を通じ、全ての国民にデジタル化の恩恵が行き渡る社会を実現すべく、取組を進めてまいります。」
デジタル庁ホームページ：https://www.digital.go.jp/

現状、国や自治体は縦割り構造で、それぞれ省庁などで独自のシステムを利用しています。
使っているシステムが違えば省庁間でのデータのやり取りなどといった連携も非効率になります。
また国民目線でいえば、それぞれの省庁のサイトやシステムの見た目や使い勝手も異なるため、とても使いづらいものです。

デジタル庁を創設することの目的の一つとして、国や自治体のシステム基盤などを再整備することがあげられます。
全体として統一したシステム基盤を整備することによって、これまでかかっていた無駄な労力やコストを削減することができ、職員と国民ともに効率的な生活を送ることができます。

##デジタル庁の活動に期待できること
デジタル庁創設で今後期待できることとしては、行政手続きの効率化です。
それに大きく関わってくるものが「マイナンバー」です。
これまでの法律ではマイナンバーの利用範囲は「社会保障制度、税制、災害対策、その他の行政分野」といった限られたものでした。
また自治体ごとに個人情報の取り扱い基準が異なるため、国と自治体の間で個人情報に関する連携が非効率でした。
今回のデジタル改革関連法案では、国と自治体で統一した個人情報保護に関する基準を設定し、かつマイナンバーの利用範囲も広げるなどといった内容が組み込まれています。
このようにシステムや個人情報を一元管理することによって様々な手続き等がスムーズになることが期待できます。

またデジタル庁では新たに民間のIT技術者などを積極的に募集し採用活動をしています。
ITに精通している人材が増えることによって、民間のIT企業にシステム開発を委託する際に、コミュニケーションが取りやすくなり、システムの品質向上などにもつながるでしょう。

##まとめ
このように日本社会全体のデジタル化によって利便性は上がる一方で、個人情報の漏洩などの懸念の声も上がっています。
システムや個人情報の取り扱いが統一されれば、システムトラブルや情報漏洩が起こった場合の影響は非常に大きなものとなるでしょう。

このようなことが起きないためにもセキュリティ面に関する議論や強化というものを進めていく必要があるでしょう。
【Vue × Firebase】子コンポーネントから親コンポーネントへ$emitで渡す場合

#子コンポーネントから親コンポーネントへ$emitで渡す場合

###子コンポーネント(post.vue)

```html
<input placeholder="例）アクション  恋愛  ミステリー  SF  ホラー  ミュージカル  etc.." class="search-main-item" type="search" @input="searchData($event.target.value)"/>
 <!--searchDataというカスタムイベント(今回は@input)を設定して、valueを渡す。valueを渡す際は「$event.target」が必要。-->
```

```javascript
method:{
  searchData(value) {
      this.$emit("searchData", value);
    }
    //第一引数にメソッド名(searchData)、第二引数にデータを指定して$emitで親コンポーネントへ値を渡す。
  }
},
```

###親コンポーネント(board.vue)


```html
 <Post @searchData="search" />
    <!--子コンポーネントから$emitで受けたデータを関数とする。※searchに()を付けるとvalueの引数が取れないので注意。-->
```


```javascript
search(value){

   ~~  構文 ~~

console.log(value)

}
```

コンソールでvalueを確認すると子コンポーネントから受けた値が受けれていることを確認出来ます。
パイプラインでAWS CLI（Docker）を利用する際の注意点

AWS CLIのバージョン2からDockerでの実行ができます。自分の場合、よくPythonのバージョンが不整合になったりして面倒なので、Dockerを利用しています。

## 利用方法
公式ドキュメントの記載通り、以下のコマンドでOKです。

```shell
$ docker run --rm -it amazon/aws-cli:2.0.6 command
```
さらに、エイリアスを作成することでdockerを気にすることなくCLIを利用できます。.bashrcや.zshrcに設定しておきましょう。

```shell
$ alias aws='docker run --rm -it -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli:2.0.6'
```

## 問題
[[小ネタ] CloudWatch メトリクスのグラフをローカルに保存しちゃうぞ！](https://dev.classmethod.jp/articles/clw_metrics_graph_export/)の記事を参考にCloudWatchのグラフをPNGで保存してみます。

```shell
$ aws cloudwatch get-metric-widget-image --metric-widget file://metrics.json --output-format "png" --output text --query MetricWidgetImage | base64 --decode > metrics.png
# aliasを使用していない場合
$ docker run --rm -it -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli:2.0.6 cloudwatch get-metric-widget-image --metric-widget file://metrics.json --output-format "png" --output text --query MetricWidgetImage | base64 --decode > metrics.png
```

CloudWatchでのグラフのJSONでの設定からAWS CLIでbase64形式で取得し、標準出力で画像ファイルに出力するという仕組みです。
実際に実行してみると`Invalid character in input stream.`となり、上手くいきません。

## `-t`はつけない
一旦、取得結果をtemp.txtに出力してみます。

```shell
$ docker run --rm -it -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli:2.0.6 cloudwatch get-metric-widget-image --metric-widget file://metrics.json --output-format "png" --output text --query MetricWidgetImage > temp.txt
```

実際に出力した文字列を確認すると、` [m`と余計な文字列が含まれてしまっています。

```
...(省略)...[m 
...(省略)... [m
```

### `-i`と`-t`について
`-t`のオプションはpseudo-TTYを割り当てるオプションであり、実際に以下のようにbash等を利用する際には擬似端末を割り当てることでinteractiveな操作を行うことができます。

```shell
$ docker run --rm -it nginx bash 
root@b929c63b8e08:/# 
# ↑擬似端末が立ち上がる
```

`-i`のオプションを利用することで標準入力を受け付けるため、`-it`の指定で擬似端末による操作が行えます。

### 回避手段
はっきり、原因が分からないのですが、今回の問題は`-t`オプションをつけてttyを割り当てた際の出力に問題があるのかなと思いました。そのため、回避手段としてはオプションで指定している`-t`のオプションを入れないことです。コマンドは以下です。

```shell
$ docker run --rm -i -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli:2.0.6 cloudwatch get-metric-widget-image --metric-widget file://metrics.json --output-format "png" --output text --query MetricWidgetImage | base64 --decode > metrics.png
```


## 参考
- https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-docker.html
- https://genzouw.com/entry/2019/07/24/143749/1691/
- https://dev.classmethod.jp/articles/clw_metrics_graph_export/
goでバージョンアップしたときにはまったことメモ


## やったこと
- 1.13.8 → 1.16.4
- go modを使うようにした
- go envを使うようにした

## はまったこと

### go modへ移行したときにパッケージの依存性
- https://qiita.com/yuta_vamdemic/items/cb3223eaf4a9a1796db3

### 1.16系へのバージョンアップ

こんなのがでるように

```
~/A/go ❯ (develop) go mod tidy                          241ms  Sun Jun  6 19:20:53 2021
m imports
        github.com/labstack/echo-contrib/session imports
        github.com/labstack/echo/v4/middleware tested by
        github.com/labstack/echo/v4/middleware.test imports
        io/fs: malformed module path "io/fs": missing dot in first path element
m imports
        github.com/labstack/echo-contrib/session imports
        github.com/labstack/echo/v4/middleware tested by
        github.com/labstack/echo/v4/middleware.test imports
        testing/fstest: malformed module path "testing/fstest": missing dot in first path element
```

#### 原因
- go envが切り替わってなかったこと
- import指定するパッケージのパスを変える必要があった

##### echoパッケージ
###### before

```
	"github.com/labstack/echo/"
	"github.com/labstack/echo-contrib/session"
	"github.com/labstack/echo//middleware"
```
###### after

```
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo-contrib/session"
	"github.com/labstack/echo/v4/middleware"
```

###### oidcパッケージ
- "github.com/coreos/go-oidc/v3/oidc"に変えるひつようがある

- https://github.com/coreos/go-oidc/tree/v3をみるとbreaking changeとある
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/02bef32d-638f-ac7b-1d80-6029672b648f.png)
Flutterでカスタムフォントが適用されないメモ..汗

ここ半年まともにアプリ開発しておらず、土日夜が唯一のコーディングタイム。☕
大事な時間でハマってしまったもの書いていきます。

flutterでいくらやってもカスタムフォントが適用されない状態が発生。
（自分の凡ミス）

下記マニュアルをにらめっこしても一行に反映されず、、

flutter カスタムフォントのマニュアル
https://flutter.dev/docs/cookbook/design/fonts#from-packages

## 試したこと

* assets/fontsディレクトリ構造に
* 拡張子otfフォントがだめなのかなとおもい、ttfフォントで試す
* アプリ再起動や、アンインストールし直し
* themeや、widgetなどで試す


## 書いたコード

```pubspec.yaml
# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # 画像リソース
  assets:
    - images/hoge_img.png
    - images/needle.png
    - images/color_palette.png

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #

fonts:
    - family: NotoSerif
      fonts:
        - asset: fonts/NotoSerifJP-Medium.otf
        # - asset: assets/fonts/OpenSans-Bold.ttf
          style: Medium 500
          weight: 500

```

```main.dart:
return MaterialApp(
      title: 'HogeApp',
      theme: ThemeData(
        primarySwatch: Colors.orange,
        accentColor: Colors.amber,
        fontFamily: 'NotoSerif',
      ),
      home: HogePage(),
    );
```

```hoge.dart:
child: new Container(
    margin: new EdgeInsets.all(30.0),
    child: new Text(
      'test: ',
      style: new TextStyle(
        fontFamily: "NotoSerif",
        // fontWeight: FontWeight.bold,
        fontSize: 24.0,
        color: Colors.pink[500],
      ),
    ),
  ),
```

## 原因と改善方法

原因は、本当凡ミス pubspec.yamlのインデントがずれていたのがの問題でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37406/e3acec15-bedb-848f-6772-a9b6cfb4de24.png)


flutterを初めて触ったというのもあり、追加したリソースなどを
サンプルソース残しつつ追記していってインデントがずれていることが気づかなった汗

あと、フォントなどは一度アプリをアンインストールしないと反映されないケースがあるようなので、
アンインストールしてから、再度起動すると改善されました。汗
オブジェクト指向　雑まとめ

フレームワークを使うことがほとんどで、感覚的にしかオブジェクト指向についてわかっていないので
アウトプットとして書きます。

読んでる本： [オブジェクト脳のつくり方―Java・UML・EJBをマスターするための究極の基礎講座]("https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E8%84%B3%E3%81%AE%E3%81%A4%E3%81%8F%E3%82%8A%E6%96%B9%E2%80%95Java%E3%83%BBUML%E3%83%BBEJB%E3%82%92%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E7%A9%B6%E6%A5%B5%E3%81%AE%E5%9F%BA%E7%A4%8E%E8%AC%9B%E5%BA%A7-%E7%89%9B%E5%B0%BE-%E5%89%9B/dp/4798104183")


大前提：コンピュータでどう実装するとか考えないで、言葉の意味を理解する。


#オブジェクト指向とは？

人間の世界を、人間が理解しやすいように、人間の都合でモデル化して、プログラムを作ること。


※モデル化ってなんだろう？
と自分はひっかかったんですが、以下のように考えました。

「なんでもいいんで、とりあえずミニカー１００個作ってください。」
と言われたとき、なにか基となるものがあるととても作りやすいですよね。
なので、 **その基となるものを作るのがモデル化** だと考えました。


#オブジェクトとは？

もの。現実世界にあるもの。
人や、スーパーなどはもちろんオブジェクトになるが
発注とか、サービスなどもオブジェクトになる。


#クラスとは？

同じ性質をもったもの（オブジェクト）を、ひとくくりにしたもの。
オブジェクトはたくさんあるので、何かでくくらないとモデル化が難しい。

「何でモデル化する？何をモデル化の対象にする？」
と考えたときに
クラスのメンバーが持っている「データ」「すること」をモデル化の対象とする
と、どこかのおっさんが決めた。


継承とは？

一般的なクラスの性質を、具体的なクラスが引き継ぐこと。

例：動物クラスの性質を、犬クラスが引き継ぐ。（しかし、犬が持っている遠吠えという技を、動物クラスが持っているとは限らない）
人間クラスの性質を、学生クラスが引き継ぐ。（しかし、学生が持っている学生証を、人間クラスが持っているとは限らない）


#カプセル化とは？

>クラスに仕事を割り振るとき、仕事の具体的なやり方はその仕事の責任を持った担当（クラス）だけが知っているようにして、
>その担当に仕事を頼む人は、その中身を知らないようにしなさい


[オブジェクト脳のつくり方―Java・UML・EJBをマスターするための究極の基礎講座]("https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E8%84%B3%E3%81%AE%E3%81%A4%E3%81%8F%E3%82%8A%E6%96%B9%E2%80%95Java%E3%83%BBUML%E3%83%BBEJB%E3%82%92%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E7%A9%B6%E6%A5%B5%E3%81%AE%E5%9F%BA%E7%A4%8E%E8%AC%9B%E5%BA%A7-%E7%89%9B%E5%B0%BE-%E5%89%9B/dp/4798104183")　より引用。

薬のカプセルの中身のそれぞれの顆粒がどんな働きがあるか理解してないけど、この薬を飲んだら「病気が治る」ということはわかる。
というような感じで、このクラスに「DB更新しろ！」という命令だけ出せば、クラスの中でどんな動きをしているのか把握せずともよい。という感覚。
Azure Key VaultのシークレットをJenkinsから自動的に取得する

JenkinsのパイプラインでAzureの管理をする時に、Azure Key Vaultにあるシークレットにアクセスできると、デプロイの自動化などを簡単に行えます。

#使用するもの
* Jenkins - https://www.jenkins.io/
* Jenkins Helm Chart - https://github.com/jenkinsci/helm-charts
* Jenkins plugin 
    * Azure Key Vault - https://plugins.jenkins.io/azure-keyvault/
    * Configuration as Code - https://plugins.jenkins.io/configuration-as-code/

#Pluginの実装

プラグインをインストール

```jenkins-helm.yaml
InstallPlugins:
    - configuration-as-code:latest
    - azure-keyvault:latest
```
Azure Key Vaultにアクセスするための設定。

```jenkins-jcasc.yaml
  JCasC:
    enabled: true
    .
    .
    .
    ConfigScripts:
      welcome-message: |
        jenkins:
        credentials:
          system:
            domainCredentials:
            - credentials:
              - azure:
                  azureEnvironmentName: "Azure"
                  clientId: "1234567-89123-....."
                  clientSecret: "**********************"
                  description: "Azure SP"
                  id: "service-principal-myapp"
                  scope: SYSTEM
                  subscriptionId: "987654-321987....."
                  tenant: "654321-654321..."
        unclassified:
          azureKeyVault:
            keyVaultURL: https://myapp-keyvault.vault.azure.net
            credentialID: service-principal-myapp
```

上で設定した使用するサービスプリンシパルにKey Vaultの`Get`、`List`権限を付与します。Terraformを使う場合は以下のような感じです。

```terraform
  
resource "azurerm_key_vault" "my_keys" {
.
.
.
 access_policy {
    secret_permissions      = [
        "Get",
        "List",
    ]
    object_id               = var.azure_spn_id 
    tenant_id               = var.azure_tenant_id
 }   
}
```

#Jenkinsからシークレットを取得

設定後、Azure Key ValutのシークレットをJenkinsからアクセスできるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799224/6a23cf6a-28dc-8acd-817f-caa36787dfd5.png)

パイプラインからシークレットを取得する場合は、このような感じでできます。

```groovy
    environment {
        AZ_MY_SECRET = credentials('az-my-secret')
    }
```

これを使うと、システムの自動化などで必要なシークレットはAzure Key Valutで一元管理し、JenkinsのCredentialsに作る必要はなくなります。

# この記事は
"3000文字Tips - 知ると便利なTipsをみんなへ届けよう"の投稿記事です。


https://qiita.com/official-events/d523df99d6479293ffa7
初めて Emacs のパッケージを作りました

『初心者がやってみました』な記事です。

# 背景、欲しかったもの

たとえば、以下のようなファイルがあるとします:

```
assets/
├── map
│   ├── tilesets
│   ├── tmx
│   │   └── map-data-1.tmx
│   └── tsx
└── scripts
    └── script1.lisp
```

`script1.lisp` から `map-data-1.tmx` を参照したいとします。相対パスを使ってみます:

```lisp:scrtip1.lisp
(load-map "../map/tmx/map-data-1.tmx")
```

これは汚い。そこで scheme 付きのパスを考えます:

```lisp:scrtip1.lisp
(load-map "tmx:map-data-1.tmx")
```

`tmx` という scheme (alias) は、 `assets/schemes.txt` で定義されるものとします:

```
tmx: map/tmx
tsx: map/tsx
tileset: map/tileset
```

これで `tmx:map-data-1.tmx` は `assets/map/tmx/map-data-1.tmx` を指すものとします。 Emacs では、 `find-file-at-point` コマンドに、このスキーム付きパスを理解してもらいたいです。

# 作り方

それではパッケージを作って行きます。今回は `advice-add` で `find-file-at-point` を上書きしました。『正しいやり方』を全く直感できないのの、動けば良いということにします。

> ちなみに [helpful](https://github.com/Wilfred/helpful) で関数定義つきのヘルプが見られます。地味なコツが非常に効いてきますよね。

## 1. `schemes.txt` の特定

### Boilerplate

まずパッケージの書き方を調べます。以下ページを参考にしました:

* [パッケージフォーマット | Emacs JP](https://emacs-jp.github.io/tips/package-format)
* [41.2 Simple Packages](https://www.gnu.org/software/emacs/manual/html_node/elisp/Simple-Packages.html)
* [41.1 Packaging Basics](https://www.gnu.org/software/emacs/manual/html_node/elisp/Packaging-Basics.html)
* [A Simple Guide to Writing & Publishing Emacs Packages](https://spin.atomicobject.com/2016/05/27/write-emacs-package/)

また、たまたま流れてきた短いパッケージ ([tomoya/consult-ghq](https://github.com/tomoya/consult-ghq)) も参考にしました。

### Dominating file の特定

現層から上階層に遡り、 `schemes.txt` を探します。これは一発です:

```elisp
(locate-dominating-file default-directory "schemes.txt")
```

> [A Simple Guide to Writing & Publishing Emacs Packages](https://spin.atomicobject.com/2016/05/27/write-emacs-package/) に載っていました。

## 2. `<scheme>:<path>` の展開

まずは `toy-scheme-resolve` でスキーム付きパスを絶対パスに変換可能にします。

`schemes.txt` は以下の形式で書かれています:

```
my_scheme: path/to/a/directory
```

### 文字列操作

やりたいのはこの手の操作です:

```bash
cat schemes.txt | grep "^$scheme" | awk -F':' '{print $2}' | awk -f ' ' '$1'
```

多くの文字列操作は、 `s-` シリーズにありました。 ([Emacs用文字列操作ライブラリ s.el の使い方 - Qiita](https://qiita.com/akicho8/items/cb7fe6b116a63c011af3))

分からないのは `grep` 相当の部分です。 ELisp ではどう書けば良いのでしょうか？

このような場合、 **emacs-jp で聞けば 1 発** です。 `re-search-forward` と `string-match` を教えていただきました。今回も助かりました。

> 正直、 emacs-jp が無ければ、僕は Emacs を使っていないかもしれません。

### ポイント (カーソル) 位置のファイル名を取得する

Emacs で言う『ポイント』は、他エディタで言う『カーソル』のことです。ポイント位置のファイル名を返すコマンドは以下です:

```elisp
(thing-at-point 'filename)
```

これの返値をスキーム付きパスとして解決して使用します。これで `toy-scheme-ffap` を実装できました。

## 3. パッケージの提供

### `advice-add`

このコマンドで `find-file-at-point` を `toy-scheme-ffap` で上書きしました。

### Minor mode の提供

`toy-scheme-mode` が ON のときのみ `toy-scheme-ffap` を使いたいと思います。 [How to Make an Emacs Minor Mode](https://nullprogram.com/blog/2013/02/06/) を参考に、 minor mode を作りました。調べれば一発で分かるっていうのは最高です。

それと、 global な minor mode も用意しました。

### 完成！

[toy-scheme.el](https://github.com/toyboot4e/toy-scheme)

# まとめ

ファイル間のリンクを強化する UI を作成しました。今後は、スクリプトファイルと翻訳テーブルを関連付けたり、マップ座標とスクリプトをリンクできたらと思います。
Django超初心者攻略記事その1

#概要
Djangoへこれから触れる方への超基礎・概念説明　その１

#概念
Webフレームワークの1つ
例：ルールに従い、作成するとWebアプリができるよ！メールやデータベースの変更も簡単にできるよ！
1つのフォルダの中にプロジェクトとして作成していく。

#作成の流れ
+ Python+Djangoインストール
+ ユーティリティコマンドで、基本的な部分を自動生成する。：プロジェクトの生成
    + django-admin startproject <pjname>
+ アプリケーションの生成
    + python manage.py statapp <appname>
+ Pjファイルの直化にアプリファイルを作る
+ 同じファイル名が作られるのはPJ用とアプリ用です。

#次の流れ
+ データベース設定を行う
+ ロギングの設定（ログの出力先など）を行う
+ ルーティングの設定（http：/hoge/huga/ ＋　login or main などURLの末尾で処理や飛ばすイメージ）
+ ビューを設定する。アプリケーションの！views.pyにクラス変数を設定する。
+ テンプレートを設定する。アプリケーションのtemplatesフォルダにてhttpを設置する
+ 開発サーバー起動し確認する。

#プロジェクトとアプリフォルダの違い
1つのプロジェクトの中に
ユーザ管理機能用のアプリ
スクレイピング用のアプリ
定時実行用のアプリ
っと手段ごとにアプリを作る形となります。


#ここまでが土台です。
Gitコマンドについて（よく使うもの）

#gitコマンド
ローカルリポジトリからリモートリポジトリへと、記入する順に紹介します。
（※事前にGitHubでリモートリポジトリを作成しているか確認してください。）
###リポジトリを新規作成
~~~php:Terminal
$ git init
~~~

###コミット対象のファイルを登録
~~~php:Terminal
$ git add トラッキング状態にしたいファイル名  //指定したファイルのみ
$ git add .  //ディレクトリ配下すべてのファイル
~~~
トラッキング状態にするコマンド。
コミットしたときに登録できるよう、ステージング領域に一時保存されます。

###変更されたファイルをコミット
~~~php:Terminal
$ git commit -m "コミットメッセージ"  //変更履歴にコミットメッセージが付属する
~~~
トラッキング状態にあるファイルがリポジトリに保存されます。

###コミット履歴を表示
~~~php:Terminal
$ git log
~~~
今までのコミットした履歴を表示できます。
表示内容は、コミットID、変更者の氏名・メールアドレス(基本的に自分の情報)、変更日時、コミット時に入力したコミットメッセージだそうです。

###リポジトリをコピー
~~~php:Terminal
$ git clone
~~~
これは使ったことがないので、また後日詳しく調べることにします。


https://www.sejuku.net/blog/5816
Figmaで幅や高さを0にした要素を作っても内部的には0ではない

## これは何

- Figmaを触っていてたまたま見つけた、ちょっと変わった（？）仕様について書いた記事です
- また、記事投稿イベント「[3000文字Tips - 知ると便利なTipsをみんなへ届けよう](https://qiita.com/official-events/d523df99d6479293ffa7)」への投稿記事でもあります

## そもそも「幅や高さを0にした要素」って？

Figmaでは`W`や`H`に`0`と打ち込んでも勝手に1になってしまいますが、`0.001`とでも打ち込めば`0`を実現できます[^1]

[^1]: おそらくですが、`0.006`より小さければ0になり`0.006`以上だと`0.01`に繰り上がります

![はじめに0を入力し、そのあと0.005を入力している動画](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/56572171-ceb0-755a-3ee4-5405cda080e0.gif)

私はこれを利用して、Auto layout内でも一部はみ出したようなレイアウトのUIを作るときがあります。

:::note alert
2022年5月27日追記
以前はこれを利用してAuto layout内で絶対配置を実現していましたが、2022年5月11日のアップデートにより不要なテクニックとなりました。
この記事の内容自体は変わっていませんが、今となっては考慮せずとも良い内容と言えます。
詳細をこちらの記事をご覧ください。
https://qiita.com/xrxoxcxox/items/df8752598b4000a3b02d
:::

## 見かけ上は0だけど実は0ではない

先ほど作った四角形のデータ、Figma APIを使って見てみましょう。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/fd96acd8-bc10-98fb-1c38-2d8faa20ce3b.png)

`height`に注目してください。
GUI上では`0`と表示されていますし、要素同士の距離を測ってもちゃんと`0`として扱われていますが、内部的には`0.0010000000474974513`だそうです。

ちなみに先ほどの四角形の`H`に`0.001`と入れても`0.005`と入れても変わらず`0.0010000000474974513`でした。

なお、ご自分でも試してみたい場合は以下の書式でコマンドを叩けばOKです。

```shell
curl -H 'X-FIGMA-TOKEN: YOUR-FIGMA-TOKEN' 'https://api.figma.com/v1/files/FILE-KEY'
```

## 何が問題か？

こちらのファイルにアクセスしてみてください。

https://www.figma.com/file/qI0tjYR2C6DtPUeqDVz3lH/%E8%A6%8B%E3%81%8B%E3%81%91%E4%B8%8A0%E3%81%A0%E3%81%91%E3%81%A9%E5%AE%9F%E3%81%AF0%E3%81%98%E3%82%83%E3%81%AA%E3%81%84?node-id=0%3A1

謎の柄があると思いますが「Auto layoutを使って要素を並べて、かつ一部の要素だけをはみ出させたい」という意図があると想定してください。[^2]

[^2]: 実際はこんな謎のUIを作ることはないと思いますが、通知バッジとか、「SALE」「NEW」といったラベルはカードからはみ出してレイアウトさせたいこともあると思います。そんなイメージです。

上から3番目の移行の要素を選択すると、Y座標が`XXX.01`になっているのが分かると思います。
しかし、Auto layoutの設定にも各要素の値にも、どこにも小数点は使っていません。

色々試してみましたが、要素のサイズや位置によって変わるのか、`XXX.01`が出現する条件はバラバラな気がします。
5回6回と要素を繰り返してようやく`XXX.01`が出るときもあれば、今回作ったファイルでは3番目の要素から`XXX.01`になっています

## 対策

そもそもこんな使い方を多用している人があまりいないような気もしますが、今のところ実施している対策も記載します。
ただし非常に対症療法的なのでご容赦ください。

例として、高さ`0`のFrameを`5px`のpaddingのAuto layoutに入れ込むとします。

1. `H`を`0`とせず、`0.01`と逆に明示しておく
1. Auto layoutの上側か下側どちらかのpaddingを`5`ではなく`4.99`にしておく

すると両者で差し引き0となり、いくつ並べてもY座標に`XXX.01`が出なくなりました。[^3]

[^3]: 50個くらいの要素で試しただけなので、何百個も並べたら出てきてしまうのかもしれませんが……。
KuwaharaフィルタをJavascriptで実装

# はじめに
**[Kuwaharaフィルタ](https://en.wikipedia.org/wiki/Kuwahara_filter)**は画像処理フィルタの一種で、物体の輪郭を残したまま画像のノイズを除去することが可能です。また、少し前に**写真を絵画っぽく変換できる画像処理フィルタ**として[話題](https://qiita.com/Cartelet/items/5c1c012c132be3aa9608)になりました。

今回はこのKuwaharaフィルタの処理を、クライアントサイドのブラウザで実行可能なようにJavascriptで実装してみました。[こちら](https://dev3064.d3c4us4xcsvcpk.amplifyapp.com/works/kuwahara_filter)のWebアプリで実際に処理を試すことが出来ます。

![Screenshot from 2021-06-06 17-45-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624261/3a260f6c-714d-df64-a8aa-c03f90b95121.png)

# アルゴリズム
Kuwaharaフィルタのアルゴリズムの紹介です。(Wikipedia参照)

あるピクセルの輝度値$I(x,y)$を決めるにあたり、まずは周辺$2a+1 $の正方形を4つの領域に分割し$Q_i(x,y)$を定義します。
※$a$はフィルタ大きさ、$\times$はデカルト積を意味する

```math
Q_i(x,y) = 
\left\{
\begin{array}{ll}
[x,x+a] \times [y,y+a] & if \; i = 1 \\
[x-a,x] \times [y,y+a] & if \; i = 2 \\
[x-a,x] \times [y-a,y] & if \; i = 3 \\
[x,x+a] \times [y-a,y] & if \; i = 4 \\

\end{array}
\right.

```

図で表すとこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624261/dd2b9311-8386-cee6-5e8f-91519f5d7fbb.png)


図から分かるように各領域は重複しています。

そして、フィルタ適用後の輝度値は、各領域の平均値$m_i(x,y)$と標準偏差$\sigma_i(x,y)$を使って、標準偏差が最も大きい領域の平均値として与えられます。

```math
\Phi(x,y) = m_i(x, y)　where \: i=arg \: min_j \: \sigma_j(x,y)
```

つまり、あるピクセルの値を、周辺の4つの領域の中で最も均質な領域の平均値で置き換えるということです。基本的にフィルタ大きさ$a$が大きいほどより抽象的な画像となります。

# 計算量
上記のアルゴリズムを愚直に実装しようとした場合、各ピクセルに対する計算量が$2\times4(a+1)^2$ですので、画像一辺のピクセル数を$n$とすると、画像1枚で$8n^2(a+1)^2$の計算量となります。
フィルタサイズ$a$が大きい場合は$O(n^4)$の計算量になります。仮に画像サイズが$1000\times1000$だとすると$10^{12}$回ほどの演算が必要で、Intel Core i5の動作周波数が3.50GHzとかなので、計算に数分かかってしまいます。

そこで、計算量を削減するために2次元累積和を利用します。
累積和とは、配列に対して前処理を行うことで高速に区間和を求めることができるアルゴリズムです。
2次元の場合は、ある位置より左上にある全ての要素の和を算出した配列を事前に求めておいて、これを使って領域の和を算出します。

[こちらの記事](https://qiita.com/drken/items/56a6b68edef8fc605821)が非常に分かりやすいので引用させて頂きますが、以下の図のように二次元累積和を利用することで、画像内の黄色区間の和を$O(1)$で算出できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624261/ea404caa-501d-928f-b38d-ab7bd8403382.png)


一方でKuwaharaフィルタでは、領域内の輝度値の平均値だけでなく標準偏差も算出する必要があります。ですが、標準偏差は以下のように式変形できるので、二乗和と和の累積和の配列さえ事前に用意しておけば標準偏差も同様に計算量$O(1)$で算出できます。
※画像の各ピクセルの輝度値(0~255)は非負で、$\sigma$が最小のとき$\sigma^2$も最小です

```math
\sigma= \frac{1}{n} \sum_{i=1}^{n}  (x_i - \bar{x} )^2\\
=\frac{1}{n} \sum_{i=1}^{n} x_i^2 - \frac{1}{n} \sum_{i=1}^{n} 2x_i \bar{x} + \frac{1}{n} \sum_{i=1}^{n} (\bar{x})^2\\
=\frac{1}{n} \sum_{i=1}^{n} x_i^2 - 2(\bar{x})^2 + (\bar{x})^2\\
=\frac{1}{n} \sum_{i=1}^{n} x_i^2 - \frac{1}{n^2}\Bigl(\sum_{i=1}^{n}x\Bigr)^2 
```

以上より、二次元累積を利用することでKuwaharaフィルタの計算量は、事前計算を含めても$O(n^2)$となり、$1000\times1000$の画像でも計算量が$10^6$回程度で1秒以内で計算することが可能です。


# 実装コード
実装コードを以下はGithubレポジトリにあります。

https://github.com/m-naoki/kuwahara-filter-js

※処理に時間がかかる場合はリサイズするか、Web Workerでマルチスレッド化が推奨

# 参考
・[Kuwahara filterとかいう明らかに日本人の名前な画像フィルターに出会い、試してみたらすごかったので紹介する。](https://qiita.com/Cartelet/items/5c1c012c132be3aa9608)
・[累積和を何も考えずに書けるようにする！](https://qiita.com/drken/items/56a6b68edef8fc605821)