OmniAICreator/Qiita-1.07M huggingface dataset:
文字起こしはAIにお任せ？「文字起こし」の効率化を考える

元記事：[https://www.notta.ai/blog/improving-the-efficiency-of-transcription](https://www.notta.ai/blog/improving-the-efficiency-of-transcription)

社外の打ち合わせや社内会議の議事録作成、インタビュー・講義やセミナーなど、後々のために記録を残したいと思っても、リアルタイムですべてを文章化するのは**難しい**ですよね。そのため、ビジネス場でボイスレコーダーを使う方が多くなっています。

しかし、録音したものを確認したり、後から聞き返して書き起こしたりするには、具体的な場所を探すのは難しい場合があります。録音したものを聴き、それを振り返るには、**時間と集中力が必要で、大変な手数を要します。**

# 「AI音声認識による自動文字起こし」とは？
現在、こうした単純作業ながら負担の大きい「文字起こし」（人の言葉を聴き取り、その音声の内容を聞きながら文字化することです。「テープ起こし」「書き起こし」「音声起こし」「反訳」とも呼ばれていることもあります）に対し、業務効率化を促すさまざまなツールが続々登場されています。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2226142/ef1afb3f-f98d-caaf-d9f2-be0f5f415657.png)
[>>文字起こしアプリ・ソフト厳選5選・特徴比較<<](https://www.notta.ai/blog/5-best-transcription-app-and-software)


このようなAI（人工知能）音声認識技術を使ったツールは、皆さんがすでにご存知のものもさまざまがあります。例えば、YouTubeの自動字幕生成、スマートフォンの音声アシスタント、スマートスピーカー、パソコンやタブレットの音声入力機能などがあります。ここ数年、これらの文字起こしツールの精度はかなり向上していると言われています。

# 自分で文字起こし場合
AIよりも人間の方が、言語を通して話し手の言っていることを理解するのに優れているため、人間が手作業で行う場合、より正確な書き起こし結果が得られます。ただし、その手間は、時間や集中力も要し、**大きな作業負担を強いる**ものです。他の業務に影響を与えて、重要業務以外に**時間と労力が奪われます**。それ以外、単語などの意味を調べる労力が必要とし、高度なタイピングスキルも必要になります。

‍

# 文字起こし業者に任せる場合
文字起こし業者に任せるという選択肢もありますが、確かにプロに任せた方は納品品質が良くなります。

しかし、始める時には、どの業者を選んだら良いか分からないという状況はよくありますし、技術力や実績で評判の高い業者を**探すのは大変**なことです。問い合わせ、見積もり、詳しいところのコミュニケーションにも時間がかかります。

文字起こし業者の**平均標準納期は3〜5日**、かなり時間がかかります。より早く納品したい場合は、費用を追加しなければなりません。さらに**土日で受付・見積もりが不可能**なことです。

なお、技術力により、音声データの内容が専門性の高い内容や外国語がある場合、業者により完成度にばらつきが生じます。

# 進化を遂げる「AI音声認識システム」
また、人間はAIのようにリアルタイムでテキストを書き起こしができませんので、もし短時間やリアルタイムで文字起こしたい、さらに会議アプリ（Zoom, Google Meetなど）と連携したい場合は文字起こしを**「自動」で「短時間」**に実行できるシステムの導入の方がおすすめします。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2226142/24b082f8-16f0-9e33-00bc-55d7eaf01110.png)
[>>オンライン会議の内容もすぐにテキスト化可能<<](https://www.notta.ai/blog/add-notta-bot-to-transcribe-zoom-live-meeting)


さらに、より一層の業務効率化を目指すため、一部の文字起こし業者はすでにAI音声認識システムを実装されたと言われています。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2226142/7d30fe31-278c-099b-6b11-138c521fe0dc.png)
[>>リアルタイム音声認識により数秒でテキスト化できる<<](https://www.notta.ai/)


もちろん、現時点のAIは手作業を100％代えることはできませんが、ツールを**活用して大部の時間を節約**できますので、**重要な業務を集中**できます。単純作業はAIに任せて、自分の時間を**大事なことに使える**ようにしましょう。

‍
---
Nottaは無料でお試しできますので、ぜひお試しくださいませ。

‍
**Web版‍**
Google ChromeやMicrosoft Edgeブラウザから[Web版](http://www.notta.ai/)をアクセス

**Chrome拡張機能‍**
Chrome web storeから[Notta拡張機能](https://chrome.google.com/webstore/detail/notta-speech-to-text-tran/kdelkaogljjcbjffjmahedaobfjineig?hl=ja)を追加

**アプリ版**
iOSアプリは[App Store](https://apps.apple.com/jp/app/notta-%E9%9F%B3%E5%A3%B0%E3%81%AE%E9%8C%B2%E9%9F%B3%E3%81%A8%E6%96%87%E5%AD%97%E8%B5%B7%E3%81%93%E3%81%97-ai%E9%9F%B3%E5%A3%B0%E8%AA%8D%E8%AD%98%E3%82%A2%E3%83%97%E3%83%AA/id1480649572)からダウンロード
Androidアプリは[Google Play](https://play.google.com/store/apps/details?id=com.langogo.transcribe&hl=ja&gl=US)からダウンロード
Next2D Frameworkのシーン遷移

# シーンの移動
シーンの移動は`Application`クラスで実装されてる`gotoView`関数を利用します。
各クラスの親クラスにappというgetterを実装してあり、下記のコールを行う事でシーン移動が実行されます。

```javascript
this.app.gotoView("シーン名");
```

## SPAモード
SPAモードを有効にした場合は、URLでのシーン遷移も可能です。

```text
https://example.com/quest/list
```
とアクセスした場合

```javascript
this.app.gotoView("quest/list");
```

と同義になります。

# レスポンスデータ
`next2d.fw.response`に格納されたレスポンスデータは`gotoView`関数がコールされるとリセットされ、`routing.json`に設定された`requests`にリクエストを行い、取得した値を新たにレスポンスデータを格納します。但し、`cache`が`true`に設定されている場合は、cacheされた情報を再利用します。

# QueryString
Next2D FrameworkではQueryStringが利用できます。
下記のサンプルは同じシーンを表示する事と同義になります。

## 関数の場合

```javascript
this.app.gotoView("quest/list?questId=10&areaId=1");
```

## URLの場合

```text
https://example.com/quest/list?questId=10&areaName=sample
```

QueryStringの値は`next2d.fw.query`に格納されます。
親クラスを継承している場合は`query`から取得可能です。
性質上、全ての値をStringとして格納するので、numberなどはキャストして利用するのがお勧めです。

```javascript
const questId = this.query.get("questId") | 0;
const areaName = this.query.get("areaName");
```

この様に、同一のシーンで動的な変化を行いたい時などに便利です。
明日は、各シーケンスでコールされる`callback`機能について記事を書きたいと思います。
遅延環境変数について

#はじめに
現在でも、Windows環境を用いたレガシーなプロジェクトでは根強く生き続けているWindowsバッチを使用したアプリ。
他のアプリと比べても癖が強く、理解できないよう謎の仕様も多々あります。

その謎の仕様で最たるものが、今回紹介する「遅延環境変数」（遅延環境変数の展開）と呼ばれるものです。

今回はその謎の仕様である「遅延環境変数」を簡単におさらい、整理します。

#まずはこれを見てください

```normal.bat
@echo off
set num=0
if %num% == 0 (
   set /a num = num+1
   echo num1=%num%
)
echo num2=%num%
```
このコードでは、numが「0」の場合に「1」を加算し、加算した結果をif内とif外でecho（コンソール表示）するシンプルなコードです。

得られる結果として、

```
num1=1
num2=1
```

と想像つきますが、実際は

```
num1=0
num2=1
```

となってしまいます。

numに1を加算しているにもかかわらず、1つ目のechoは「0」と表示されてしまいます。
何故でしょうか。

#何故こうなるのか
そもそもWindowsバッチはプログラム言語ではなく、あくまでもコマンドラインの集合体であるため、<font color="Red">**1行単位で変数を展開・実行する仕組み**</font>になっています。

if文については `if ( ～ )` までを1行としてみなして展開されます。
その為、展開された時点ではまだnumは「0」の状態であり、if内のechoのnumの値は「0」として処理されます。[^1]
[^1]: if外のechoについては、if文が展開された後（加算が行われた状態）であるため、「num」には「1」がセットされる。

#遅延環境変数とは
例えば、if内のechoを「num=1として処理したい」（加算された状態）場合、どうするのか。

ここで**「遅延環境変数」（遅延環境変数の展開）**といったものが必要となります。

```delay.bat
@echo off
setlocal enabledelayedexpansion

set num=0
if %num% == 0 (
   set /a num = num+1
   echo num1=!num!
)
echo num2=%num%

endlocal
```
遅延環境変数を使用するには、上記のように対象範囲を`setlocal enabledelayedexpansion` ～ `endlocal` で囲み、遅延環境変数を用いたい箇所の変数を`パーセント（%）`ではなく、`エクスクラメーション（!）`で囲みます。[^2]
[^2]: `パーセント（%）`で変数名を囲むのは値を参照する場合。set文で値を代入もしくは演算する場合は変数に`パーセント（%）`は不要。
（囲んだ範囲が遅延環境変数のスコープ）

遅延環境変数を使用することにより、変数の値を置き換えるタイミングを変えることができます。
つまり、**行が展開されるタイミングではなく、実際にそのコードが実行されるべきタイミング（今回の場合、if内のecho）で値を置き換えることができます**。


このコードで実行すると

```
num1=1
num2=1
```

と、想定通りの結果が得られます。

#for文でも同様

先述の例ではif文を取り上げましたが、for文も`for( ~ )`を1行とみなすため、同様の事象が発生します。

例）下記フォルダ構成で、拡張子「txt」のファイル名をfor文でリスト表示したい場合

```
D:.
└─work
    │  AA.txt
    │  BB.txt
```


```normal_for.bat
@echo off
set name=DEFAULT

for  %%a in (D:\work\*.txt) do (
    set name=%%a
    echo %name%
)
```

結果は

```
DEFAULT
DEFAULT
```

となってしまいますが、

ここで遅延環境変数を用いて実行すると、

```delay_for.bat
@echo off
setlocal enabledelayedexpansion

set name=DEFAULT

for  %%a in (D:\work\*.txt) do (
    set name=%%a
    echo !name!
)

endlocal
```

結果は

```
D:\work\AA.txt
D:\work\BB.txt
```
と、期待通りの結果が得られます。

#補足
##補足①：setlocal以外での遅延環境変数の有効化
遅延環境変数については`setlocal enabledelayedexpansion`を用いなくても、以下の方法（「１．」「２．」）でも可能です。
ただし、以下の方法は環境への依存が高くなる為、`setlocal～`を用いてアプリ内に明示的に宣言しておいた方が移行など発生した場合の保守性は高いと考えます。

| 方法 | 内容 | 
|:--------------|:------------|
| １．cmdコマンドのオプションで指定 |cmdコマンドのオプション「/V:ON」を実行し、遅延環境変数を有効化する。|
| ２．レジストリの値を変更 |レジストリファイル内のエントリ「DelayedExpansion」の値を「1:有効」にする。|
この方法を使うと、`setlocal enabledelayedexpansion`がなくても`エクスクラメーション（!）`で囲まれた変数を自動的に遅延環境変数とみなします。
また「１．」「２．」を共に設定している場合、「１．」の設定の方が優先されます。

##補足②：遅延環境変数の値の中にエクスクラメーションが含まれる場合の注意
変数名ではなく、遅延環境変数の値の中に`エクスクラメーション（!）`が含まれる文字を取扱う場合（パスワードやファイル名等）、遅延環境変数が正しく認識されず誤作動を起こす可能性があります。
その場合は`setlocal` ～ `endlocal`の範囲を変えて遅延環境変数のスコープを変更するか、あるいは遅延環境変数のコード箇所を関数化して外出しにする等の工夫が必要となります。


#まとめ
　モノ作りをしてるとここはこう動くべきとかこうあるべきとか偏った先入観が働きがちですが、その言語の個性や特性、意味を把握した上で取り組むことも大事なのかと思い、このようなテーマを挙げさせていただきました。

　参考になったかは分かりませんが、今後の皆さんの作業に役立てていただけると幸いです。
Rechartsのbarchartでバーを横にする

Rechartsはreactのグラフ描画のライブラリですがBarChartを横にする場合、layoutをverticalにするとグラフが消えてしまうという問題が起きていました。

この問題の対処はYAxisのtypeをcategoryにし、XAxisのtypeをnumberにすることで解決します。

```tsx
<BarChart
        width={400}
        height={200}
        layout="vertical"
        data={data}>
        <XAxis type="number"/>
        <YAxis   dataKey="name" type="category" />
        <Bar dataKey="pv" fill="#8884d8" />
        <Bar dataKey="uv" fill="#82ca9d" />
        <Bar dataKey="amt" fill="#74ca1d" />
</BarChart>
```

3時間くらい嵌りました‥。
Rustアプリケーション開発にNoSQLドキュメント指向データベースCouchbase Serverを使うには？

## はじめに

この投稿では、現時点ではまだ「work in progress」とされているCouchbase Rust SDKについて紹介します。内容的には、Couchbase Labsにて公開されている公式リポジトリーのREADMEからの情報紹介になります。

筆者は、Rustについては経験がないものの、Couchbase Server周りの話として、Rust SDKの要望を聞くようになっています。現在はコミュニティサポートの状態にて、エンタープライズサポート版の登場が待たれるところですが、本稿が、Rustアプリケーションから利用することのできるデータベースのひとつとして、Couchbase Serverについて認識いただく機会になれば幸いです。

Couchbase Serverについては、日本語で読むことができるまとまった情報として、次の拙著を紹介させていただきます。

https://www.amazon.co.jp/-/en/%E6%B2%B3%E9%87%8E-%E6%B3%B0%E5%B9%B8/dp/429560030X/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=1636588872&sr=1-1

Couchbase Serverは、NoSQLドキュメント指向データベースであり、同様のカテゴリーにMongoDBがあります。上記書籍にて、それぞれの違いについても説明しています。

MongoDBのRust対応については、以下のようなリポジトリーがあるようですね。将来的に、それぞれのRustにおける実装の違いなども、検証・紹介してみたいものです。

https://github.com/mongodb/mongo-rust-driver


## Couchbase Server Rust SDK概要

Couchbase ServerのRust SDKは、 以下のGithubリポジトリで公開されています。

https://github.com/couchbaselabs/couchbase-rs


ソースコードとして提供されており、ビルドするために、Couchbase C Clientライブラリー(libcouchbase)に依存します。

https://github.com/couchbase/libcouchbase/

また、C/C++ライブラリーにRust FFIをバインディングするための`bindgen`のユーザーガイドで公開されている要件を考慮する必要があります。

https://rust-lang.github.io/rust-bindgen/requirements.html

Couchbase Rust SDKは、`async/await`構文を利用しているため、`1.39`以上のRustバージョンが必要です。


## コード記述例

キーバリュー操作の基本的なコード記述例は次のとおりです。

```rust
pub fn main() {
    // 接続文字列と視覚情報を使用してクラスターに接続
    let cluster = Cluster::connect("couchbase://127.0.0.1", "Administrator", "password");
    // バケットをオープン
    let bucket = cluster.bucket("travel-sample");
    // Use the default collection (needs to be used for all server 6.5 and earlier)
    let collection = bucket.default_collection();

    // ドキュメントの取得
    match block_on(collection.get("airline_10", GetOptions::default())) {
        Ok(r) => println!("get result: {:?}", r),
        Err(e) => println!("get failed! {}", e),
    };

    // ドキュメントを保存
    let mut content = HashMap::new();
    content.insert("Hello", "Rust!");

    match block_on(collection.upsert("foo", content, UpsertOptions::default())) {
        Ok(r) => println!("upsert result: {:?}", r),
        Err(e) => println!("upsert failed! {}", e),
    };
}
```


### サンプルコード

レポジトリーの`examples`フォルダーにコード記述例が多数格納されています。

### アンセーフコードブロック
現在のコードには、**unsafe {}**コードブロックが含まれていることが注意されています。unsafe {}コードブロックを使用する理由は、Cライブラリである`libcouchbase`を呼び出すことができるようにするためです。

該当箇所は、IOモジュールのlcb部分にあります。そのため、その部分で、セグメンテーション違反が発生する可能性があります。

また、unsafe {}コードブロックのない純粋なRust SDKの開発にも取り組み中であるとされています。

## 最後に

今回、Couchbase Rust SDKについて紹介しました。内容的には、ほんのさわり、ということでしかないと思いますが、今後の展開の（特に自分自身にとっての）はずみとなればと思っています。
大きめのログから指定範囲のログを抽出する

catalina.outがログローテートされてないのか、7GB近くあった。
issueに貼り付ける時にデカすぎるので、指定範囲のログを抽出したい。

## コマンド

サイズ確認。

```shell
$ ls -lh catalina.out
-rw-r--r--@ 1 mitsuaki1229  staff   6.8G 12 17 15:34 catalina.out
```

行の範囲を確認するため、先頭と末尾になるログを抽出する。
※今回は2021年12月12日のログが欲しい。

```shell
$ grep -n "11 Dec 2021" catalina.out | tail -n 1
136166909:Date: Sat, 11 Dec 2021 23:59:51 +0900 (JST)
$ grep -n "13 Dec 2021" catalina.out | head -n 1
137449005:Date: Mon, 13 Dec 2021 23:56:53 +0900 (JST)
```

awkで指定範囲行のログを抽出する。

```shell
$ cat catalina.out | awk "NR==136166909,NR==137449005 {print}" > 20211212_catalina.out
```

サイズ確認。

```shell
$ ls -lh 20211212_catalina.out
-rw-r--r--  1 mitsuaki1229  staff    64M 12 17 16:18 20211212_catalina.out
```

## その他

ここ8ヶ月くらい、Goの新規開発のみやってて、最近元々メインでやっていた案件に戻ったのだが
その間、Javaもインフラも触ってなければ、調査もあまりやってなかったので、
仕様や調査フローもそうだが、色々とコマンドとかも忘れている。
今までInkdropに色々とアーカイブしていたけど、ツールが使えない場合は困りそうだし、Qiitaとかに貼り付けてくべきか。
OpenCV-最大エントロピー

# 1.最大エントロピーとは

ここでいうエントロピーとは、システムに含まれる情報のメトリックである情報エントロピーを指す。システムの不確実性が大きいほど,システムの情報エントロピーが大きくなる。逆に,1つのシステムが決定性が高い(システムが秩序化されているほど)場合,システム全体の情報エントロピーは小さくなる。その数学的定義は以下の通りである：
   
    H=−∫p(x)log[p(x)]dx 

上記式では、p(x)は階調xが現れる頻度を表す。Hは情報エントロピーを表す。 

# 2.最大エントロピー画像分割
 
1.1つの閾値Tを選択し、この閾値を用いて画像中の全ての画素点を2つに分類する，閾値T未満の全ての画素を背景Bとし、閾値T以上の全ての画素を物体Oとする。 

2.各階調がBまたはOクラスに占める確率を計算する。

	背景：    pi/pT,     i=1,2,...,T
	物体:     pi/(1−pT), i=T+1,T+2,...,L
内に
			 
 ![31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234182/51edec93-2265-ebd9-1368-dc679b1d1599.png)
		    
3.背景と物体の情報エントロピーをそれぞれ計算する

![32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234182/f34b740d-3f9c-bf3d-400d-8d7e85ce2e69.png)
![33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234182/7cf2fe11-17ee-7dde-c012-3a1159ca72f0.png)

4.画像の各階調について演算を行い、max（HO＋HB）を最大エントロピーの分割点とするT値を得る

# 3.OpenCVプラットフォームで実現

    for (int i = 0; i < 256; i++) 
    {
        //背景ピクセル数の計算
        double backTotal = 0;
        for (int j = 0; j < i; j++)
        {
            backTotal += tbHist[j];
        }

        //背景エントロピー
        for (int j = 0; j < i; j++)
        {
            if (tbHist[j] != 0)
            {
                Property = tbHist[j] / backTotal;
                backEntropy += -Property * logf((float)Property);
            }
        }
        //ぜんめんエントロピー
        for (int k = i; k < 256; k++)
        {
            if (tbHist[k] != 0)
            {
                Property = tbHist[k] / (TotalPixel - backTotal);
                frontEntropy += -Property * logf((float)Property);
            }
        }

        if (frontEntropy + backEntropy > maxEntropy)    //最大エントロピーを得る
        {
            maxEntropy = frontEntropy + backEntropy;
            index = i;
        }
        //今回の計算エントロピー値をクリア
        frontEntropy = 0.0;
        backEntropy = 0.0;
    }
【Apple Store Connect】iPad用のスクリーンショット無しでiOSアプリをリリース申請する

#はじめに

iOSアプリとしてApple Store Connectで申請作業を進めていたら、通常だと下記のiPad用のスクリーンショットの提出を促され、審査に進めないかと思います。
> 12.9 インチ (第 2 世代 iPad Pro) 2048 x 2732 ピクセル（縦向き） 2732 x 2048 ピクセル（横向き)
>12.9 インチ (第 3 世代 iPad Pro) 2048 x 2732 ピクセル（縦向き） 2732 x 2048 ピクセル（横向き)

今回iPad用には提供しないため、わざわざスクリーンショットを用意するのは煩わしいと思い、どうにかならないか調べていたら下記方法でビルドすることでiPad用のスクリーンショットを用意しなくても審査を進めることが可能になりました:star:


# 対処法

### XcodeからDeploy Infoの設定を変更する
Xcode > Runner > TARGETS Runner > Generalタブから**Deployment Info**の設定項目から**iPad**のチェックを外す。

![スクリーンショット 2021-12-17 16.17.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329865/b837b19c-8b93-3541-09ec-37d980d3b2ec.png)

自分の場合、初期状態だとiPadにチェックが入っていたので、その状態でリリースビルドを行ったためiPad用の画像を用意しないと審査に進めることができなかったようです。
また、下記のファイルを直接編集し`TARGETED_DEVICE_FAMILY = 1;`にすることで同様の変更可能です！

```ios/Runner.xcodeproj/project.pbxproj
 				PROVISIONING_PROFILE_SPECIFIER = "";
 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
 				SWIFT_VERSION = 5.0;
				TARGETED_DEVICE_FAMILY = 1;  // 1.2だとiPhone,iPad用
			
```

その後、リリースビルドしてApple Store Connectで申請作業を進めていけば、iPad用のスクリーンショットを上げていなくても審査に提出することができるようになります。


#おわりに
申請作業はいつやっても慣れないです。
自分への備忘録として残しておきます...!
ECS Fargateの基本用語

こんばんは、ラクスでインフラを担当しているakiponxです。

今年はECS Fargateをがっつり触ったのでこの記事を書こうと思います。

最初とっかかりはじめた時に用語などがわけわからんかったのでとりあえずこれからFargate触るよ。ってい人向けに簡単に基本用語をまとめていこうと思います。

## 目次

- ECS Fargate って？
- 基本用語
- その他

---

### ECS Fargate って？ 

AWSが提供しているマネージドコンテナオーケストレーションサービスです。

ECSにはEC2タイプとFargateタイプがあります。

#### EC2タイプとFargateタイプ(ファーゲート)の違い

EC2タイプを使ったことがないのでいまいちわからないですが、大きな特徴しては

**インスタンスを気にする必要がない** ことです。

EC2の場合、多分どこのAZに何台展開してこのEC2にコンテナを起動させて…

みたいなことを考えないといけない気がするのですが、FargateではどこのAZにコンテナを起動するのか？

を設定に書くだけで勝手に起動してくれます。

例えば 

- ap-northeast-1a , ap-northeast-1c, ap-northeast-1d のどこかに2つコンテナを起動

というような設定を書けば、AZを分散させて2つコンテナを起動してくれます。

EC2を管理しなくていいのはいいですね！

---

### 基本用語

- タスク定義 (task definition)
- サービス (service)
- クラスタ (cluster)

この3つは最低限必要です。

#### タスク定義

タスク定義の設定内容は

- コンテナイメージの指定 (複数コンテナイメージを設定可能)
- 環境変数(envファイルの指定、引数で渡す値)
- ホスト、コンテナのLISTENポート
- CPU、メモリの割り当て

上記を設定します。

#### サービス

サービスはタスク定義で設定したコンテナ群をどこで起動するか？を設定します。

- ネットワーク
  - サブネット
  - LB
- 起動数
- オートスケール

を主に設定します。

#### クラスタ

サービスをまとめたものです。

主にどこのVPCに所属するかを決めるだけです。

ほとんどはタスク定義、サービスの設定が肝になります。

---

イメージ的には↓のような感じ

![Fargate簡略.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313417/45b26ec4-d5d2-14c3-2fb3-606e801ed5a1.png)


---

短いと怒られそうなので余談。

実際にFargateを触ってサービスを作ったときの実体験をもとにちょっと書こうかと思います。

---

### コンテナの構成管理

コンテナを運用するにあたって思うことは、構成管理をコード化しないときつい

流行りの IaaC ってやつですね。

AWSサービスをコード化するのにあたっておすすめなのが

- Terraform
- CloudFormation (CFn)

の2つです。

僕の場合はTerraformを採用しました。

CFnだと作成済みのリソースをCFnに取り込めないものがあり、急いでいるときに手で作ってしまったものがインポートできなくなるのがつらいなーと思ったため、今回はTerraformで書きました。

コード化するとマジで楽です。ただ、コード化するのは地獄でした。

---

### コンテナのログ

コンテナが死ぬとログもロストするため、ログを外部に転送する必要があります。

デフォルトでCloudWatchLogs(CWL)に転送されるようになっているはずですが、CWLはびっくりするくらい見ずらい。

そこで開発チームにコンテナの中にFilebeatを入れてもらい、

Filebeat → Logstash → ElasticSearch ← kibana

という感じでKibanaでログが見えるようにしてもらいました。

---

という感じで文字数足りたかな…

怒られたら怒られたときに考えます。
AWSのS3とOCIのObjectStorageとの仕様比較

#はじめに
業務上でAWSのS3をOCIに置き換えを検討することとなったので、その際に調査した内容を共有します。
既存の記事では各サービスの概要について比較している記事は見つかったのですが、移行可否の判断に活用できるような各サービスの詳細に踏み込んだ記事が見当たらなかったため、手元で調査した内容をこちらでも共有できればと考えて記事化することとしました。

#比較
下記、ストレージの詳細についての比較となります。ストレージを利用したサービスや自社業務がある場合に、この程度の内容がわかると移行判断の助けになると考えています。
※2021年12月時点での調査となります。

一部機能においてはまだAWS側優位のようですが、思ったほどドキュメント上での差はつけられていないようです。

|比較項目|S3|ObjectStorage|OCIドキュメント|
|:-:|:--|:--|:--|
|オブジェクト数上限|なし|なし<br>(バケット数はリージョンあたり10000が上限)|https://docs.oracle.com/ja-jp/iaas/Content/General/Concepts/servicelimits.htm#Object_Storage_and_Archive_Storage_Limits
|1オブジェクトの容量上限|5TB|10Tib|https://docs.oracle.com/ja-jp/iaas/Content/Object/Concepts/objectstorageoverview.htm
|ストレージ全体の容量制限|なし|不明。記載なし|
|可用性/信頼性|99.99%|99.9%|
|耐久性|99.999999999%|99.999999999%|
|ディレクトリ構造|あり|あり|https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/managingobjects.htm#nameprefix
|レプリケーション|クロスリージョン<br>セイムリージョン|同じリージョン、または別のリージョンの別のバケットにレプリケート可能|https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/usingreplication.htm
|バージョンニング|あり|あり|https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/usingversioning.htm
|ライフサイクル管理|経過日数もしくはバージョン数をトリガとしてオブジェクトの移行、削除|経過日数をトリガとしてオブジェクトの移行、削除|https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/usinglifecyclepolicies.htm
|アクセスログ|あり|あり|https://docs.oracle.com/ja-jp/iaas/logging-analytics/doc/collect-logs-your-oci-object-storage-bucket.html
|タグ|オブジェクトへのタグ付けをサポート|バケットへのタグ付けをサポート|https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/managingbuckets.htm
|複数オブジェクトへの一括処理|あり|あり|https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/managingobjects.htm
|ロック|一定期間または無期限で削除、上書きされない|一定期間または無期限で削除、上書きされない|https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/usingretentionrules.htm


#参考資料
以下のspeakerdeckの資料が大枠の理解に役立ちます。
[OCI技術資料 : オブジェクト・ストレージ 概要](https://speakerdeck.com/ocise/ociji-shu-zi-liao-obuziekutosutorezi-gai-yao)
ObjectStorage以外にもOCIに関連する資料がspeakerdeckに提供されているので、OCIの利用を検討を開始する段階で参照する資料としてはおすすめです。
js 連想配列（オブジェクト）で同じキーの要素をまとめる　配列を持つプロパティ　

以下のような連想配列（オブジェクト）があるとする。


```javascript:input.js
var array = [
  {key1:'aa', key2:'b',  code:'c'},
  {key1:'a',  key2:'b',  code:'d'},
  {key1:'aa', key2:'bb', code:'e'},
  {key1:'a',  key2:'bb', code:'f'},
  {key1:'aa', key2:'bb', code:'g'},
]
```

### やりたいこと
これを、key1が同じものでまとめて、さらに、key2が同じものでまとめる。
連想配列の下に、連想配列を持ち、codeが同じなら配列にする。
結果的に以下のような形にしたい。

```javascript:result.js
array = {
  aa:{
     b:['c'],
     bb:['e','g']
  },
  a:{
     b:['d'],
     bb:['f']
  }
}
```
<br>
試行錯誤した結果、以下のようなコードになったが、
できれば、mapやreduce,filterなど使って、もう少しスマートに書きたかった。  

```javascript:app.js
var newArr = {};
array.forEach(function(data) {
  var key1 = data['key1'];
  var key2 = data['key2'];
  var code = data['code'];
  var obj = {};
  
  if(newArr[key1] == undefined) {
     newArr[key1] = obj; // ---- ①
     // 未定義ならそのままcodeを入れる
     if(newArr[key1][key2] == undefined) {
        newArr[key1][key2]=[code];
        console.log(key1+key2+code+'-----1');
     }else{
     // key2の中身は配列なので、そのままpushする
       newArr[key1][key2].push(code); // ------ ②
       console.log(key1+key2+code+'-----2');
     }
  }else{  
     if(newArr[key1][key2]==undefined){
       newArr[key1][key2]=[code];
       console.log(key1+key2+code+'-----3');
     }else{
       newArr[key1][key2].push(code);
       console.log(key1+key2+code+'-----4');
     }  
  }  
});

console.log(newArr);
array = newArr;
```

コンソールに表示される順番として、1,1,3,3,4となる。

### 悩んだところ
①参照
いきなり、`newArr[key1][key2];` のように書くと、下のようなエラーが出るので、①のようにした。

```javascript
Uncaught TypeError: Cannot read property 'b' of undefined 
```
if文のundefindのところを、''やnullとしていて、うまくいかなかった。


②参照
key1の中身が連想配列なので、key2の中に値を追加するときに、ずっと

```javascript:
  obj = {[key2]:code};
  Object.keys(newArr[key1][key2]).push(obj);
```
```javascript
  obj = {[key2]:code};
  newArr = Object.assign(newArr[key1],obj);
```
のようなことをしていたので、うまくいかなかった。
***

#### 参考
> https://qiita.com/hirakuma/items/0c4fd425f76bccab858c
ECS Execを用いてコンテナにログインする

ECSで起動したコンテナに対して、docker execのようにコンテナの中にログインして操作する機能を試したので、そのメモです。私が試したのはFargateになります。

## 事前準備

ECS Execするクライアント端末にツールをインストールすると共に、IAMロールを設定します。

1. クライアントで ```session-manager-plugin``` を実行し、結果を確認する。
2. 未インストールの場合、Session Manager プラグインをインストールする。
3. 以下のIAMポリシーを作成し、ECSタスクを実行するIAMロールにアタッチする。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        }
    ]
}
```

## ECSの設定

ECS側の設定を行います。一部の手順はAWS CLIで実施します。

1. ECSタスクに上記のIAMロールを設定する。
   - すでに設定されているロールにポリシーを追加した場合は、ポリシーの適用にタスクの再デプロイが必要。ただし後の手順でも再デプロイする。
2. AWS CLIで ```aws ecs update-service --cluster <CLUSTER_NAME> --service <SERVICE_NAME> --enable-execute-command``` を実行する。
3. タスクを（再）デプロイする。
4. AWS CLIで ```aws ecs execute-command --cluster <CLUSTER_NAME> --task <TASK ID> --container <CONTAINER NAME> --interactive --command "/bin/sh"``` を実行する。

これでコンテナにログインして、Shellでログの参照や状態の確認をすることができるようになります。

ちなみに私はWindows 10で試しましたが、GitについてきたBashから実行したところエラーが発生し、PowerShellから実行したらログインできました。原因は追求していません。
AWS Shieldでできること



### 1. DDoSとは

- Distributed Denial of Service Attack（DDoS攻撃）とは、***サービスを不能にすることを目的とした、分散された複数のリソースからターゲットに対する攻撃***である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/5081b83a-4a9f-1473-d49c-d5d095485f71.png)



- DDoS攻撃はアプリケーションレイヤ及びネットワークレイヤに跨る。双方で対策を講じる必要がある。例えば、ネットワークレイヤのDDoSの例としては、SYNフラッド攻撃（TCPのセッションを奪う攻撃）などがある。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/1338a322-f533-4044-a800-7746e09da85a.png)


### 2.AWS Shieldとは

- DDoSを緩和するAWSマネージドサービス。
- ***AWS Shield Standardと、AWS Shield Advancedの２種類***が存在するが、***AWS Shield Standardはユーザーが意識するものではない、自動的に全サービスに適用***されている。
- ゆえにユーザー自身で導入の可否を判断するのは、***AWS Shield Advancedのみ***である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/75f47c82-1f9c-3f6e-ecb7-56c948955960.png)



- AWS Shield Standardは***レイヤ３/４のDDoS対策***を行い、AWS Shield Advancedは***レイヤ７のDDoS対策***を行う。
- ただ、レイヤ７のDDoS対策は基本的にはWAFで実施する。AWS Shield Advancedを導入することにより、より高度なDDoS対策が受けられるようになったり、Amazon CloudWatch により DDoS 攻撃の可視化ができることや DDoS レスポンスチームのサポートが受けられるらしい。

異常検知のイメージ↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/3ecc10c8-6fa5-8db2-6a4c-dbcfe0dbb20d.png)



### 参考資料

- [【AWS Shield とは？】初心者にもわかりやすく解説](https://www.wafcharm.com/blog/aws-shield-for-beginners/)
- [【AWS WAF vs AWS Shield】初心者にもわかりやすく解説](https://www.wafcharm.com/blog/aws-waf-vs-aws-shield-for-beginners/)

以上
MySQL SQL句で現在時刻を出力する

# 目的

- MySQLにてSQL句で現在時刻を出力する方法をまとめる。

# 方法

- 下記のSQL句を実行する。

    ```sql
    $ select now();
    ```

- 下記のように出力される。

    ```
    mysql> select now();
    +---------------------+
    | now()               |
    +---------------------+
    | 2021-12-17 07:35:15 |
    +---------------------+
    1 row in set (0.00 sec)
    ```
MySQL タイムゾーンの確認方法

# 目的

- MySQLにてSQL句にてタイムゾーンを確認する方法をまとめる

# 方法

- MySQLにログインして下記SQLを実行する。

    ```sql
    select @@time_zone
    ```

- 下記のようにタイムゾーンが出力される。

    ```sql
    mysql> select @@time_zone
        -> ;
    +-------------+
    | @@time_zone |
    +-------------+
    | SYSTEM      |
    +-------------+
    1 row in set (0.01 sec)
    ```
Vuetifyのv-intersectを使用してライブラリなしで「無限スクロール」を実装する

## はじめに

Vueで無限スクロールと言えば[vue-infinite-loading](https://peachscript.github.io/vue-infinite-loading/)が一番よく使われていると思います。
実際に「Vue 無限スクロール」などで検索すると、↑を使用した実装例が殆どです。

今回は、上記のライブラリを使わずに、Vuetifyのコンポーネントを使用して無限スクロールを実装する方法を紹介します。


:::note warn
表題で「ライブラリなし」と言っているのは、vue-infinite-loadingなどの無限スクロール用の外部ライブラリを使わないことを意味しており、UIフレームワークであるVuetifyの使用を前提とした記事となっているのでご注意ください:bow:
:::


## 環境

```
vue: 2.6.11
vuetify: 2.4.0
```

## 結論

いきなりですが、最終的に書いたコードです。
便宜上、全ての処理をComponent内に書いておりますorz

```SampleComponent.vue

<template>
    <v-container>
        <v-row>
            <v-col>
                <simple-card v-for="user in users" :user="user" />
                <!-- ローディング中はローティングを表示 -->
                <v-progress-circular v-if="isLoading" indeterminate />
                <div v-else-if="isMoreData" v-intersect="onIntersect">続きを読み込む</div>
                <!-- 未表示データがない場合は、何も表示しない -->
            </v-col>
        </v-row>
    </v-container>
</template>

<script lang="ts">
export default class SampleComponent extends Vue {
    // スクロール時にAPIを実行したレスポンスを格納する
    // User型はimportしてきている前提(省略します）
    protected users: User[] = [];
    // ローディング表示を管理するFlag
    protected isLoading = false;
    // まだ表示していないデータが存在するかをFlag
    protected isMoreData = true;
    
    onIntersect(
        _entries: IntersectionObserverEntry[],
        _observer: IntersectionObserver,
        isIntersecting: boolean
    ): void {
        // 要素が交差していない場合 = isIntersectingがfalseの場合は何もしない
        // v-intersect.quietとすることでも可能（だと思う）
        if (!isIntersecting) return;
        // APIをcallする前にローディングを表示する
        this.isLoading = true;
        fetchUsers
           .then((res) => {
                // 今回は空配列が返ってきたら未表示のデータがないとしている
                // この辺りはAPIとの兼ね合いで考える
                if (res.data.length === 0) {
                   // このフラグをfalseにすることで「続きを読み込む」が表示されなくなり、以降はonIntersectが呼ばれないようにしている
                   this.isMoreData = false;
                   return;
                }
                // ローカルstateのusersにレスポンスを注入するとコンポーネントが描画される
                this.users.push(...res.data)
            })
            .catch((err) => { 
                // 必要であればエラーハンドリングを書く
            })
            .finally(() => {
                // 成功でも失敗でもローディングを非表示にする
                this.isLoading = false;
            });
    }
}
</script>


```

- 「続きを読み込む」が表示されたタイミングでAPIをcallし、レスポンスが返ってくるまではローディングアイコンを表示する
- `simple-card`が無限スクロールで表示したいコンポーネントを想定
- 余計なpropsやclass、ロジックやimport文は外してます

## ポイント

#### v-progress-circular

ローディングアイコンは、Vuetifyの`v-progress-circular`を使用しました。
`indeterminate`オプションを用いて常時アニメーションにしています
（描画されている間は常にくるくる回っているイメージです）

[参考: v-progress-circular コンポーネント](https://vuetifyjs.com/ja/components/progress-circular/#section-4f7f304465b9)

#### v-intersect

今回の場合は「続きを読み込む」という要素を最下部に置き、これに`v-intersect="onIntersect"`を書くことで、交差（スクロールして表示）したタイミングでAPIを実行し(=`onIntersect`が呼ばれ）、ローディングを表示することで擬似的な無限スクロールを実現しています。

[参考: Intersection observer](https://vuetifyjs.com/ja/directives/intersect/#section-4f7f304465b9)

## まとめ

ライブラリなしでも簡単に実装できました。
（ちなみに冒頭に述べたライブラリを使用しても簡単ですw
新米こそ上手に頼れ！　〜甘え上手なエンジニアになるための処方せん〜


※この記事は [モチベーションクラウドシリーズ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/mcs) の7日目の記事です。



# はじめに
はじめまして。10月から開発チームにジョインした新米エンジニアの久原です。
新米エンジニアとしてプロジェクトを任された時、以下のような経験をしたことがありませんか？

- 自分が何をやるのか、なぜやるのか、どうやってやるのかが全然わからない
- 技術的なことはQiitaの記事とかを検索して漁れば出てくるだろうと思って調べても、全然解決できない

上記のような課題を解決するために、__まわりに頼ること__は一つの手段として有効だと思っています。

一方で、新米エンジニアだと、無意識にまわり頼ることを避けてしまいがちです。
その原因として、[研究結果](https://rc.persol-group.co.jp/thinktank/assets/new-graduate_onboarding.pdf)によれば、以下の2点が必要だという事が分かっています。

- 話しかけやすい環境
- まわりに頼ろうとする自分の意思

この記事では特に後者について取り上げ、
自身の経験を基に__まわりに頼ることを避けてしまう要因となる壁3つ__とその__突破法__をお伝えできればと思います。




# まわりに頼れるようになるために新米エンジニアが突破すべき壁3選
## 壁1. ほとんど話したことがなくて声をかけづらい
#### 課題の深掘り
まず初めに開発組織にジョインした時は、直属のサポーター以外のメンバーとほとんど交流が無いと思います。
だからこそ、聞いてみたい人がいても__「どんな人なんだろう」「質問したときどんな風に接してくれるんだろう」というイメージを持てていない__から、声をかけづらいのではないかと思います。
#### 打ち手
上記の課題に対しては、__どんな形でもいいからその人と1対1で話す場を作る__ことが大切です。
全体の場ではなく1対1の場を作ることで、その人とコミュニケーションするイメージを作ることができ、不安を払拭することができます。
#### 具体的なアクション
具体的には__「挨拶、と称してメンバー全員と1対1で話す場をセッティングする」__です。
基本的にこういったことは自分からアクションしないと開催されませんし、「挨拶させてください」と新人から言われて断る人もまあいないはずです。もしそれでも声をかけづらいと感じる場合は直属のサポーターなどに提案してセッティングしてもらうのも良いかもしれません。

## 壁2. そもそも、何を聞けばいいか分からない
#### 課題の深掘り
上記の壁を突破し、質問をしに行けるくらいの関係性を作れていたとしても、「分からないことだらけで何から聞けばいいのかすら分からない」という事がよく発生します。なぜそういう状況に陥るかというと、__自分がやるべき事が具体化されていない__から、人に聞くこともできないのです。
#### 打ち手
上記の課題に対してはそのまま__自分のやるべきことを具体化する__という方向性でアクションをとるのが大切です。
具体化されることによって、質問内容が明確になることで格段に質問しやすくなります。
#### 具体的なアクション
具体的には__「タスク分解する」__です。
私は[この記事](https://zenn.dev/tbpgr/books/8562293d519b8b/viewer
)が参考になりましたが、タスク分解とググったらいくらでもノウハウは手に入れる事ができると思います。
しかし、新米エンジニアだからこそ大事になるのが以下の2点です。

- 一人でタスク分解をする事が難しかったら、「タスク分解の手伝いをして欲しいです」と頼る
- 一人で分解できたら、必ず分解されたタスクについてレビューをもらう

不慣れなことは、「できない」「できていると思い込んでしまう」ことがあります。必ずタスク分解の過程ごと、まわりに頼ることをオススメします。

## 壁3. 忙しそうにしていて、声をかけづらい
#### 課題の深掘り
上記の壁も突破して何を質問すればいいか明確になっていても、先輩が忙しそうにしていたら聞くのを躊躇ってしまうと思います。しかし、ここで大切になってくるのは__その場で声をかけに行くこと__だけが頼る手段では無い、ということです。頼り方のレパートリーが少ないということが壁になってしまうと考えられます。
#### 打ち手
上記の課題に対しては__「その場で聞きに行く」以外の頼り方もマスターする__ということです。
これによって、相手の状態に依存せず、頼るという手段を行使できるようになっていきます。
#### 具体的なアクション
具体的には__チャットツールで簡潔に依頼する__です。チャットツールであれば、相手が忙しくてもみたい時に見て返したい時に返信してもらえます。全然相手の負担にはならないのです。しかし、口頭での依頼と違ってチャットにおいては気をつけなければいけない点が3つあります。

- まず、聞きたいことを一言で記述すること
- 聞きたいことの背景を記述すること
- 納期を必ず伝えること

口頭であればその場で質問内容が分かりにくい場合は聞き返してもらえるのでリカバーできますが、チャットだとなかなかやりづらいです。そう考えると、__結局、何が聞きたいのか__を一番最初に持ってくるのがベターです。
また、質問に応える側も「意図・目的に沿った解決策を提示したい」と思ってくれるため、忘れずになぜそれを聞きたいのかを記述することが大事です。
最後に、口頭であればその場で解消される事がほとんどですが、チャットツールだと納期がルーズになりがちです。忘れずに納期を記載しておきましょう。
## 終わりに
この3つの壁を越える事ができれば、きっと躊躇する事なくまわりに頼る事ができるようになると思います。
しかし、一番大切なのは常にまわりに頼り続けることではなく

__目的の達成のために使える手段の中で一番最適なものを選び続けること__

だと思っています。まわりに頼るという手段をフラットに使える手段の一つとして持っておくことは必ず皆さんの武器になると信じています。
QAに向いてる(かもしれない)職業

かれこれ、200～300名近くのQA職の人を見てきましたが、新卒でQAやってる人は、全体の1～2割くらいな印象です。つまり、多くの人は、過去に別のお仕事をやっていて、中途でQA職についた人たちです。まぁ、私の周囲が偏ってるだけかもしれませんが。

「前職にこの職業をやってる人は、良いQAになりがちかも？」というのを、なんとなーく、傾向として感じてるところがあるので、この記事では、「QAに転職すると良い成果でるかもしれないよ？」という職業を上げてみます。

100%まじりっけなしの主観です。あしからずご了承ください

## QAに向いてそうな職業リスト

* エンジニア
* 営業
* ミュージシャン
* スポーツガチ勢
* 筋トレ勢(ジムのスポーツインストラクター含む)
* ブロガー・ライター(趣味でブログ運営している人も含む)
* テレビ制作下請け
* ケータイ販売員
* カスタマーサポート
* 元ボーイスカウト(職業ではないですが)


向いてると考えられる理由も合わせて述べたいのですが、偏見と取られる可能性もあるので、控えておきます…w
ひとつ言えるのは、QAというお仕事は、いろんな長所を活かせる良い職業！ということですね。

今日はこのへんで！
未来のタイムスタンプのファイルを相対的に時間を変更

# 未来のタイムスタンプのファイルを相対的に時間を変更
## 未来のタイムスタンプのファイルを探す 
```bash
$ find . -type f -mmin -0 -exec ls -la {} \;
```

## 相対時間でタイムスタンプを変更
```bash
$ find . -type f -mmin -0 -exec touch {} -r {} -d '-1 month' \;
```

めったに使わないけど、メモ
App Center の User API Token と App API Token の違いについて

# はじめに

App Center を利用し始めた時に User API Token と App API Token の二種類に混乱しましたので、簡単にまとめておこうかと思います。

# 二種類の API トークンについて

API トークンには二種類存在します。

- User API Token
- App API Token

## User API Token

これはユーザーに紐付いたトークンとなります。
ユーザー自身が好きなだけ発行可能なトークンです。
ただし、ユーザーの権限によってトークンが持つ権限が変わります。([後述](#トークンの権限について))

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/23417266-2920-de04-c3d2-8ec164acc44c.png)

## App API Token

これはアプリケーションに紐付いたトークンとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/4ffebc16-f8e8-9ecb-be0f-edfcf6814dcd.png)

## トークンの権限について

それぞれのトークンは『Full Access』と『Read Only』の二種類が選択可能です。

『Full Access』はそのトークンに関連したユーザーまたはアプリが持っている全ての権限を持ちます。
例えば、User API Token で Full Access のトークンの場合、そのユーザーが管理者権限（全ての権限）を持つのであれば、そのトークンを利用すれば全ての操作をすることが可能です。

『Read Only』はそのトークンに関連したユーザーまたはアプリがアクセス可能なデータや基本情報などを取得する事が可能です。

# GitHub Actions で使用するトークンは？

実際にトークンを使うシチュエーションとしては私の環境では自動ビルド環境でした。
今回は GitHub Actions で App Center にディストリビュートする際にどちらのトークンを使えばよいのか？という点ですが、結果から言うとどちらのトークンでも使用可能でした。
(MS の公式見解としての回答をもらいました。)

GitHub Actions では appcenter-cli を利用してディストリビュートしているのですが、App Center 側の公式な回答としては appcenter-cli で利用する場合は User API Token の方を利用してほしいということでしたが、自動ビルドで特定のユーザーが用意したトークンを使うのはちょっと気持ち悪いので App API Token を利用しています。

# まとめ

最近は GitHub や色んなサービスでトークンを利用する機会が増えましたが、アクセス権や利用方法はしっかりと理解しておかないと、何でも出来てしまうトークンをばらまいてしまうことになりますので注意が必要そうです。
AdobeFontsで使えるおすすめフォント

#はじめに
デザイナーの@KK_Arashi と申します。
今年は何を書くか悩んでおりましたが、Adobeは毎年様々な機能を追加して利便性をあげているのでそれを紹介するのも手なのですが私自身いまいち使いこなせているとも思えないので、今年はAdobe Fontsをご紹介します。
# AdobeFontsって？
[Adobe Fonts](https://fonts.adobe.com/) はAdobeの提供するサービスの１つで、CreativeCloudを契約しておけば、AdobeFontsに登録されている様々なフォントを１クリックでアクティベートし、各Adobeツールですぐに使用できるようになる、というものです。
2021年9月にサービスが開始し、当初は日本語フォントも少なかったのですが、今はモリサワやFONTWORKS等もフォントを提供するようになり、かなり便利なサービスとなりました。
そこで、今回はAdobeFontsでおすすめのフォントを紹介しようと思います。

#明朝体
## [A-OTF リュウミン Pr6N](https://fonts.adobe.com/search?query=%E3%83%AA%E3%83%A5%E3%82%A6%E3%83%9F%E3%83%B3)
![スクリーンショット 2021-12-17 15.53.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248214/d786e2f9-8277-9b50-985b-d0538152480f.png)
このためにモリサワを契約するといっても過言ではない、あのリュウミンがAdobeFontsなら使えちゃいます。
ただ、フォントウェイトが一種類しかないのが難点ですね。重用するならモリサワを契約しましょう。
## [游明朝体 Pr6N](https://fonts.adobe.com/fonts/yu-minchotai-pr6n-r)
![スクリーンショット 2021-12-17 16.04.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248214/664f5e51-8e63-f2a3-d438-b49e19250f95.png)
やっぱりモリサワ。リュウミンよりも少し細めですが、スッキリとした印象の明朝体系のフォントです。
ちなみに「ゆうみんちょうたい」と読むそうです。

#ゴシック体

## [A-OTF UD新丸ゴ Pr6N](https://fonts.adobe.com/fonts/a-otf-ud-shin-maru-go-pr6n)
![スクリーンショット 2021-12-17 16.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248214/55876fbd-a1ff-caa4-38c5-19992a0e46c6.png)
こちらもモリサワから、とても可読性の高い丸ゴシック体。
明朝体や角ゴとは違う雰囲気が出せますし、長い文章でも読みやすくできますね。
## [DNP 秀英角ゴシック金 Std](https://fonts.adobe.com/fonts/dnp-shuei-gothic-kin-std)
![スクリーンショット 2021-12-17 16.13.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248214/09b8063c-7227-4e5c-1794-0995ec8f5e91.png)
大日本印刷株式会社の角ゴシックです。
癖がなく、どんな場面でも使いやすいフォントですね。

#その他
## [VDL ロゴJrブラック](https://fonts.adobe.com/fonts/vdl-logojrblack#fonts-section)
![スクリーンショット 2021-12-17 16.00.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248214/abb69c1c-a23a-7035-9dd7-406443a30638.png)
ロゴやタイトルにおすすめのごん太フォントです。強調したい一文におすすめ。

## [AB Ryusen Aki](https://fonts.adobe.com/fonts/ab-ryusen-aki)
![スクリーンショット 2021-12-17 16.08.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248214/16f531f3-1ef1-3a90-ef3d-d360e675bb43.png)
太いサインペンで書いたようなフォント。私のおじいちゃんがこんな筆跡だった気がします。

## [UDデジタル教科書体](https://fonts.adobe.com/fonts/uddigikyokasho-pro#fonts-section)
![スクリーンショット 2021-12-17 16.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248214/0d180b65-6612-8015-faf4-d8c6512a5172.png)
教育の現場で使われているらしいモリサワのフォントです。
デジタルでの可読性を優先しているようなので、webで使うフォントには良いですね。

# さいごに
主にモリサワフォントの紹介になっていました。
仕事でも趣味でも普段使ってるフォントを紹介したのですが、モリサワばっかりでしたね…。
Adobe Fontsにはまだまだたくさんのフォントがありますので、ぜひ自分にあったものを探してみてください。
由来のわかる地名カルタ「言の場」を作った時のドメイン取得のお話

# はじめに
サービス名を決めた後にWebサービスならドメインを取得することもよくあると思いますが、
気に入ったドメインを取得することは、こだわらなければ、「.com」とか「.net」、「.jp」など簡単に取得できたりするものもあります。

だけど、最近は「.ai」ドメインにしたいとか、作るサービスによってドメインもこだわりたい。
そのな思いも強くなっているのではないでしょうか？

今回、作った由来のわかる地名カルタ「[言の場](https://kotono.ba/)」のドメイン取得についてお話ししていこうかと思います。

https://kotono.ba/

# どのようなドメインにするのか？
サービス名を「言の場」としていたので、場の部分をドメインにしようと考えました。

・・・ば、バ、BA❓
「.ba」のドメインなんてあったっけ❓

と言うことで、「[ゴンベエドメイン](https://www.gonbei.jp/)」で探してみました。
※手軽に探すなら「[お名前.com](https://www.onamae.com/)」が有名ですが、ドメインの種類で探すなら「[ゴンベエドメイン](https://www.gonbei.jp/)」の方が海外ドメイン(1000種類)を扱っているので、自分はこちらでよく探しています。

探してみるとこんな感じで出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/c3d2141c-cfd5-c469-5c19-cd35dee932f0.png)

その中で、「.ba」「.be」などのドメインが出てきますね。

ちなみになのですが、最初は予算的に「.be」ドメインで安く(1870円)済ませようとしたのですが、サービス名が「言の**ベ**」になるのはちょっと嫌だなーと言う心の葛藤もあったので、「.ba」ドメインで高くても仕方ないと言うことで、こちらに購入しました。
(「.be」ドメインも最初の段階で買っています)

しかし、この決断がこの後、悲劇を招くとはまだ知らない。。。

# ドメインの取得
いざ、ドメインを取得しようと言う段階で、ドメインの詳細を見ていると注意事項に何か書かれています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/98d85adc-9b0f-5a19-8bc9-65a035913dea.png)

>
・上位組織により登録要件、料金等が予告なく変更される事があります。
　変更に伴いドメインの登録・更新時に上記で案内以外の書類の提出を求められることがあります。
　その際にはあらためてご連絡いたします。主な提出書類についての案内はこちら

ちょっと待って、提出書類がいるのですか。。。

> 法人申請の場合は謄本の現在事項証明書、個人申請の場合は戸籍抄本

こちらは、法務局か役所に行って書類を取得する必要があります。

ここで補足ですが、「.ba」ドメインはボスニア・ヘルツェゴビナに割り当てられているccTLD（国別コードトップレベルドメイン）なのですが、ボスニア・ヘルツェゴビナの国内利用のみで取得可能で、代理店を利用することで、海外からも取得ができるみたいです。その為なのか、いろいろと本人確認とかが厳しくなっているみたいですね。

>希望文字列によっては、取得までに数ヶ月掛かる場合がございます。予めご了承ください。

また、書類をそろえて申請してみたのですが、こちらに書かれている通り、設定が完了するまでに1か月程度かかっており、普段のドメイン取得と違い審査期間があるため、取得できるまでに時間がかかります。

リリースを決めたサービスに利用する場合は取得期間をある程度考慮する必要もあります。

# 最後に
サービスを作るときは先にドメインを取得するという「ドメイン駆動型開発」があるようにドメインはサービスを作る上でモチベーションを上げるためにも重要です。
※普通の[ドメイン駆動型開発](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88)とは別物です。

* 関連性がある文字列
* 短くて覚えやすい文字列

こう言ったことを考えると全世界のドメインの取得方法を知っておくと、
イザという時に最高のドメインを見つけることができるので、是非いろいろなドメインを取得してみたください。
ポエトリーリーディングする

# ポエトリーリーディングとは

>ポエトリーリーディング (英語: poetry reading) は、主に詩人が自作の詩を読み上げる行為を指すが、20世紀後半からは特にライブハウスなどの会場で詩を朗読するパフォーマンスを意味する場合が多い。ラップミュージックにのせて詩を読むという形態もある。

[ポエトリーリーディング 出典: フリー百科事典『ウィキペディア（Wikipedia）』](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%82%A8%E3%83%88%E3%83%AA%E3%83%BC%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0)

# やってみる

テキストから読み上げ音声を作って音楽にのせる

googleのText-to-Speechが読み上げてくれるらしいからこれ使ってみる、
なんか1ヶ月400万文字まで無料なんだってさ。

Google Cloud Platformのアカウント作ってText-to-Speech APIを使うためのキー発行あるんだけどなかなか大変だった、以下を参考にしました。

https://masa-engineer-blog.com/gcp-text-to-speech-api-python/


```python:

text = "読ませるテキスト"

voice_path="voice.mp3"
motoneta_path="motoneta.mp3"


import os
from pydub import AudioSegment
from google.cloud import texttospeech

os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'GCPで生成したキーファイルが置いてあるパス'


# Text-to-Speechを使う設定
client = texttospeech.TextToSpeechClient()
synthesis_input = texttospeech.SynthesisInput(text=text)
voice = texttospeech.VoiceSelectionParams(
    name="ja-JP-Standard-B",
    language_code="ja-JP",
    ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL
)
audio_config = texttospeech.AudioConfig(
    audio_encoding=texttospeech.AudioEncoding.MP3
)

# 音声変換
response = client.synthesize_speech(
    input=synthesis_input, voice=voice, audio_config=audio_config
)
with open(voice_path, "wb") as out:
    out.write(response.audio_content)

# 音声ができたから元ネタに重ねる
motoneta = AudioSegment.from_file(motoneta_path, format="mp3")
voice = AudioSegment.from_file(voice_path, format="mp3")

motoneta = motoneta.overlay(voice, 0)
motoneta.export("poem.mp3", format="mp3")

```

おしまい

texttospeechについてはほぼサンプルソースまるパクリ

https://github.com/googleapis/python-texttospeech/blob/main/samples/snippets/quickstart.py

# 聞いてみた

どうしようもない

https://soundcloud.com/bjack_mijilme/python-poem

実は声だけちょっと音量上げちゃった。

ちょっと遅くもしてみた

https://soundcloud.com/bjack_mijilme/python-poem2

よくわからん



テキストの元ネタはこれ

https://www.youtube.com/watch?v=rR84Mx6v8hQ

# 感想

多分自分はポエトリーリーディングを勘違いしている。

# 今後の展開

BPM合わせてボイスの後ろをディレイで飛ばすとかしたい、ダブディレイ的なの

# その他

日本語の発音が滑らかな感じだからTextToSpeech使ったけど、
Open-Jtalk使うと壊れた電報みたいな感じになるし
pyttsx3使うと破壊の限りを尽くされるのでそれはそれでいいと思う
【Jetpack Compose】 Molecule を使って Flow → StateFlow に変換する

## はじめに

本記事は [with Advent Calendar 2021](https://qiita.com/advent-calendar/2021/with) 20日目の記事です。

こんにちは [with](https://with.is/welcome) でAndroid エンジニアをしている石田です。Jetpack Compose がプロダクトで使えるようになって以来、 **「状態」** を扱うことが多くなったように感じる今日このごろです。

というわけで今回は状態にまつわるお話です。

## Composeで状態を扱う時に困ること

状態を扱うとき、ViewModel では `StateFlow<T>` 、 Compose では `State<T>` を使用します。 `StateFlow<T>` は  `collectAsState` を使って 簡単に `State<T>` に変換することができます

困るのは  `Flow<T>` を `State<T>` に変換したい場合です。 `StateFlow<T>` と同様に  `collectAsState` を使って変換できますが、 その際に初期値を渡す必要があります。 言うまでもなく、`Flow<T>` には初期値というものが存在していないためです。

適当な初期値を渡せば一応は解決ですが、View側で初期状態を制御し、Flowでそれ以降の状態を制御しているという状況は少し気持ちが悪い感じがします。

また、複数の Flow から1つの状態を作る場合はどうでしょうか。 Flow の `combine` 用いて 1つの Flow にまとめるという処理を書くことになりますが、入力の Flow の数が多ければ多いほど複雑なコードになりがちですが。

## そこで Molecule

これらの問題の解決策として、[Cash が公開している Molecule](https://github.com/cashapp/molecule) というライブラリの存在を知ったので 簡単に紹介したいと思います。

## Molecule のサンプル

下記の `ViewState` というモデルを Compose 側に公開するとします。 `season` `food` `color` はそれぞれ独立した3つの `Flow<String>` がソースであり、 値が変化するという想定です。

```kotlin
sealed class ViewState {
    object Loading : ViewState()

    data class Data(
        val season: String,
        val food: String,
        val color: String
    ) : ViewState()
}
```

3つの Flow から `ViewState` に変換するコードを書きます。 Molecule のスゴいところはこれをComposeで書けるところです。 比較的スッキリと書けているのではないでしょうか。

```kotlin
@Composable
fun buildViewState(
    seasonFlow: Flow<String>,
    foodFlow: Flow<String>,
    colorFlow: Flow<String>
): ViewState {
    val season by seasonFlow.collectAsState(null)
    val food by foodFlow.collectAsState(null)
    val color by colorFlow.collectAsState(null)

    return if (season == null && food == null && color == null) {
        ViewState.Loading
    } else {
        ViewState.Data(
            season = season ?: "N/A",
            food = food ?: "N/A",
            color = color ?: "N/A"
        )
    }
}
```

次に 先程の `buildViewState`　を使って3つの Flow から `StateFlow<ViewState>` を作成するコードを書きます。 `CoroutineScope.launchMolecule` というAPIを使います

```kotlin
private val seasonFlow: Flow<String> = ...
private val foodFlow: Flow<String> = ...
private val colorFlow: Flow<String> = ...

val state: StateFlow<ViewState> = moleculeScope.launchMolecule {
    buildViewState(seasonFlow, foodFlow, colorFlow)
}
```

これで StateFlow<ViewState> を作ることができました。あとはいつも通りで Compose で `collectAsState` を使い `State<ViewState>` に変換します。

```kotlin
    val state by viewModel.state.collectAsState()
    MainScreen(state)
```

## まとめ

- Molecule を使えば Compose で StateFlow を作ることができます。
- 複数の Flow から1つの状態を作りたい場合においてコードをスッキリさせることができるだけでなく、状態を1箇所で制御することができるためテストも容易です。
- 複雑な画面であればあるほど威力を発揮する良ライブラリだと思いました。
- [動作可能なサンプルコードをGitHubに公開している](https://github.com/maxfie1d/molecule-example)ので、併せてご参照ください。
エンベデッドシステムスペシャリスト合格体験記

　令和3年秋季実施の情報技術者試験でエンベデッドシステムスペシャリスト試験（通称：ES）に
合格したので、その体験記を記す。

# 投稿者の前提

* 学生時代から組込みシステム関係を専攻（ハードとソフトを満遍なく）
* 組込みシステムの実務経験はないが、研究経験は3年程度あり
* 基本情報技術者試験（FE）と応用情報技術者試験（AP）は合格済み（数年以内）

# 午前Ⅰ
* AP合格による免除制度を利用（超重要）
* 午前Ⅱでもレベル3の問題は出題されることから、勉強自体はAP午前過去問を用いて対策

# 午前Ⅱ
* FEやAPの午前試験の感覚に慣れ過ぎていると非常に焦る。新作問題に焦らされて、過去問を試験時間のとおりに演習していても、本番では思っているより時間が足りなくなる。1問分のミスも非常に大きくなるので、取りこぼしはできるだけ抑えたい。
* 過去問演習を十分に実施しておき、既出の問題は絶対に解けるようになっておくことが重要
* ES区分では、2020年10月実施分からセキュリティ分野の問題がレベル4となっており、投稿現在では過去問のデータが不足しているので、対策が難しい。ゆえに既出の過去問は絶対に抑えておく。
* 投稿者は過去8年分を2週解き、対策した。
* 投稿者的には、午前Ⅱの合格点クリアが一番ヒヤヒヤさせられた。
* 2020年10月実施分から、高度区分（PMを除く）の午前Ⅱにおいては同日に実施されるSCの午前Ⅱからいくつか同じ問題が出題されているので、**高度区分の午前ⅡにおいてはSCの午前Ⅱ問題もセットで勉強する必要がある**と考えられる（2022年6月追記）。

# 午後Ⅰ
* **時間が足りない（超重要）。**
* ESでは、2020年10月実施分から午後Ⅰ試験の問題選択が完全に自由（大問3問から2問選択）となったが、問題内容の傾向的には近年の過去問と変わりないと感じた。

    * 問1（ハード系出身でもソフト系出身でも、どちらでも解けそうな問題）
    * 問2（ソフト系中心の問題）
    * 問3（ハード系中心の問題）

※投稿者はソフト系寄りなので、問1と問2を選択

* 試験対策段階では、選択予定の問1と問2は試験時間を計測しながら本番に近い環境で演習したが、問3に関しても高度区分試験の午後問題の形式へ慣れるために参考程度で勉強した。
* 投稿者は過去4年分を2週解き、対策した。
    * 1週目：時間を計測し、本番と同じように解く。
    * 2週目：問題文に登場する専門用語や問題文内容、問題文と問の繋がりを意識しながら、出題内容を理解するためにじっくりと解いた。

# 午後Ⅱ
* 問題文は長いが、午後Ⅰよりも余裕をもって取り組める。午後Ⅱに関しては、近年の過去問の傾向と変わりはなし。
* 投稿者は問2（ソフト系中心の問題）を選択
* 前述した午後Ⅰと同じように対策

# 受験結果
![2021-12-17 (2).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447230/7529faba-ba0b-280c-9df0-0c52c1fbfc6d.png)

* 午前Ⅱは受験後の当日に採点したが、ヒヤリハットになった。
* 午後Ⅰ、午後Ⅱに関してはおよそ予想のとおりであった（「いける」か「いけない」で言えば、どちらかと言えば「いける」寄りのような手ごたえ）。

# 感想
* ESは他の区分と比較して圧倒的に情報量が不足しているので、当分も対策には四苦八苦するかも（特に午前Ⅱのセキュリティレベル4や午後Ⅰの選択形式変更など）。
* 今度はSCとNWを受験する予定かも。
* この体験記が未来のES合格者を増やす一助になれば幸いです。
* （今後、用いた参考書等の記載などの記事更新を予定しています）。
綺麗なコードって何？　可読性を軽視してはいけない理由と対策。

#はじめに
###結論
####読みやすいコードは人によって変わるが、最善は尽くそう。

これが今回、私が調べてみて出した結論です。
人それぞれ読みやすさは変わります。
いくら自分が読みやすいと思ったコードでも相手に伝わらないこともありますし、昨日の自分が書いたコードを読み解くのに時間をかけることがあります。
この記事は、コードを読み解く時間を極力減らしたい・生産性を上げたいという気持ちで調べ、まとめることにしました。

###そもそもなぜ可読性が重要だなと思ったのか

paizaラーニングやポートフォリオ制作をやっていて、いくつか思うところがありました。

- 昨日書いたコードが読めない
- 問題集の回答と自分の回答を比較した時に読みにくい
- 無駄な工程がある
- コードをもっと簡略化できないかな

エンジニアにとって綺麗なコードを書くこと、すなわちコードの可読性は、生産性の観点で大事だと考えています。しかし、開発業務ではあまり重要視されていません。

その理由は、コードの可読性が低くてもプログラムは動作するからです。
すでにエンジニアをやっている方々はわかるかもしれませんが、コードが長くても処理速度はほぼ変わらないので、webサイトやアプリの動作には影響がありません。
また、エンジニア個人ではなく、可読性を軽視している企業さんが多いように感じました。
とある企業さんで、字下げをしていないエンジニアの方もいるようです。

テックキャンプ卒業したてほやほやの私の見解では、「読みにくいよりも、綺麗な方がいいよね」程度にしか考えておらず（もはや思ってすらいなかった）、汚く適当なコードを書いていました。
しかし、可読性をあげることはやはり大事なのでは？　と、僕の可読性が皆無なポートフォリオを見て思ったので、調べてまとめてみました。

世間の、「動くならそれでいい」は本当にいいのでしょうか？
色々とまとめてみました。

# 綺麗なコードを書く意味

### 綺麗なコードを書くメリット

- 機能の拡張や修正がしやすい

どこから修正したらいいのかわからないとか起こりにくいし、新機能を追加しやすくなります。


- コードを素早く理解できる

コードは常に人に見られるものです。
上司や部下・未来の自分・GitHubで世界に公開など。
今の自分がわかるけど「誰か」にはわからないコードを書くこと。これで起きる障害は、軽視できないですね。

- 開発時間の短縮

開発経験がなくネットで拾ってきた言葉を使っているだけですが、コードを読み解く時間を除けば大幅な開発の短縮ができると思います。

- 再利用がしやすい

以前、オブジェクト指向についてLT（短いプレゼンテーション）をするところで傍聴しましたが、再利用できるコードが一番いいとおっしゃってました。
メソッドやクラスなど、どういう役割を持たせるか。それをどういう使い方で再利用するか。ここで開発スピードは大きく変わってくると思います。

- コミュニケーションのコストを下げる

綺麗なコードを書くことで無駄なコミュニケーションを減らすことができます。
これによって開発スピードが変わりますし、意見の食い違いなど起きにくい環境になると思います。

以上の5点が挙げました。
開発するに際、綺麗なコードを書くだけでこれだけのメリットを与えてくれます。

#読みにくいコードの要因と対策
メリットは分かったけど、読みにくいコードの定義って？　と、僕は思いました。
どんなコードを書いたら、読みにくいのでしょうか？

##読みにくい要因
- コードが長すぎる
- 条件式が長すぎる
- ネストが深すぎる
- 変数名やメソッド名が不適切
- コメントが不適切・ノーコメント
- 無駄な否定系(!=)が多い

読みにくい要因としてこれだけ挙げられます。

###可読性の低いコードのせいで起きる弊害って？
- プログラムを読む時間がかかる
- バグが混入しやすくなる
- バグの原因特定に時間がかかる
- 改修に時間がかかる

また、無駄な伝達など増えて開発が遅れる可能性があります。
今の自分がこれをしていないか、考えるべきですね。
ちなみは私はほぼ全部やらかしてます。（ポートフォリオでよかった・・・）

#読みやすくする方法

可読性が重要なことは理解できましたね。
それでは、どうしたら読みやすくなるのでしょうか？
####綺麗なコードを書くためには
短く三つにまとめました。

- 命名規則を遵守
- 無駄のないコメント
- ネストを深くしない

一つ注意点があります。
コメントはコードを書き換えた際に変えてください。
いくらコードが読めるとはいえ、コメントが違うと混乱してしまいます。

以上でコードの可読性についてお話ししました。
今のポートフォリオから可読性を高める行動をとっていきたいと思います。

#参考文献・動画

リーダブルコード

https://www.amazon.co.jp/gp/product/4873115655/ref=dbs_a_def_rwt_bibl_vppi_i0

YouTube

https://www.youtube.com/watch?v=rJVr4Gs8EgY

https://www.youtube.com/watch?v=Ud135Ht8Xl0

記事
https://el.jibun.atmarkit.co.jp/daisukekasuya/2012/08/post-34fd.html

https://gomyownway.hatenablog.com/entry/2012/08/25/104859

https://www.capa.co.jp/archives/7383


https://eh-career.com/engineerhub/entry/2019/09/24/103000#%E5%8F%AF%E8%AA%AD%E6%80%A7%E3%81%8C%E4%BD%8E%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8C%E3%82%82%E3%81%9F%E3%82%89%E3%81%99%E5%BC%8A%E5%AE%B3
#ifndefに気をつけろ

#条件ビルド
C/C++などでコードを書いている時、ある条件の時だけ有効あるいは無効にしたいコードというものがある。これはデバッグ用マクロのような話ではない。デバッグコードはリリース時に消すが、リリース用に条件Aと条件Bのバイナリを別々に作る場合のことだ。

```c
#define INUSE_CASE_A    //CASE Aの時だけ有効にするコード
#define INUSE_CASE_B    //CASE Bの時だけ有効にするコード

#ifdef INUSE_CASE_A
CASE A用のコード
#endif

#ifdef INUSE_CASE_B
CASE B用のコード
#endif
```
こんなやつ。
#でも #ifndefには気を付けよう。
開発が進み、条件Cが追加された。
条件CはAまたはBの時だけ有効で、Cが定義済みなら無効にしたい。

```c
#ifndef INUSE_CASE_C
```
この条件はAまたはBの時だけ有効になるコードだろうか？
正解は**Cが未定義の全部**で有効なコードだ。
AとBが未定義でもC以外だから有効だ。それは意図したものだろうか？
開発が進み、条件Dができたとする。
**AとBで**有効にしたいコードは**Dでも有効**にするべきだろうか？
#trueとfalseとnotの話
複数条件で#ifdefならtrue/falseだが、#ifndefは「以外のすべて」になる。
ついつい**#ifndef一発でいけるやん！**と思いがちだが、注意が必要だ。

```c
#if defined(INUSE_CASE_A) || defined(INUSE_CASE_B)
AまたはBの時だけ有効にしたい処理
#endif
```

これならAまたはBが定義済みの場合のみ有効になる。
AとBが両方必須なら && にすればいい。これなら間違いない。
少なくとも、**意図せぬ見えない条件**は追加されない。

例はマクロ定義だが、コードの条件判定でも基本は同じである。
また、たとえ正常に動作すると知っていても not 判定は避けたい。

```c
//Ex1
while(true) {
    char* buf = get_buffer_ptr();  //内部終了条件でnullptrを返す
    if(!buf) {
        終了処理
        break;
    }
    buf を使った処理;
}
//Ex2
bool bExec = true
while(bExec) {
    char* buf = get_buffer_ptr();  //内部終了条件でnullptrを返す
    if(buf) {
        buf を使った処理;
    } else {
        終了処理
        bExec = false;
    }
}
```
一見するとEx1のほうがシンプルだが、否定条件やbreak脱出を意識する。
否定条件は「それ以外の全部」が何を指すか考えなければならない。
否定条件を使いたくなったら「それ以外の全部でいいか？」を意識したい。
スキルアップしたいなー。参考書買うか。でも読むのめんどいし。そうだ、BOOTHで買おう！

なにか新しい知見を増やしたいな。どうやって勉強しよう。。
と悩んでいる方に向けた記事です

書店に行くと、エンジニア向けの技術書がたくさんありどれを買おうか悩んだ経験がある方多いのではないでしょうか。
エンジニア初学者向けや最新の論文を和訳して作られた上級者向け技術書まで色々とあると思います。

こうした本の中でどれを選ぼうか考えた時、自分はとてもめんどくさがり屋なので、薄っぺらい本ばかり手に取りそこからキャッチアップしようとしてしまいます。
ただ、薄っぺらいのでそこからキャッチアップできるものはごく僅かなことが多いです。

枚数が多ければ多いほど質が高くなるかと言われれば、そうではないと思います。
ですが、ある程度枚数がある技術書の方が得られる情報が多いのも事実だと思います。。。

ただ、単に和訳されているものや回りくどく書かれているものが多く、正直読む気になれません。。
気合を入れて読んでも、結局なにを得られたのか具体的に説明できる方は少ないのでしょうか。。

###そんな時は、「そうだ、BOOTHで買おう！」です。

BOOTHとは、創作物の総合マーケットらしいです。
イメージとしては、udemyの本版です。

現役エンジニアの方が技術書を自作して、売り出しているマーケットになります。たぶん。。。

「えーーー。現役エンジニアっていっても有名な人じゃないし、お金出してまで書いたくない」と思ったそこのあなた。

今からここで技術書を買うメリットをお伝えするので購入するか参考にしていってみてはいかがでしょうか

#メリット① :  お金があまり、かからない。
書店である程度の本を買おうとすると 2,000~ する印象ですが、ここだと ~2,000 以内に収まるものが多いです。

#メリット② :  枚数が少なめ。でも、内容濃いめ。
これぞ、自分が求めていたもの。分厚い本を買って、なんだかしっくりこない例文で右往左往しなくて済みます。
もちろん、著者によるとは思いますが、全体的にこのメリット当てはまる本が多い印象です。

#メリット③ :  読みやすい。
純ジャパニーズが書いているので、言いたいことがちゃんと伝わる。
アーキテクチャとか抽象的な概念の勉強するときとか、ここがネックになってよくわからんになるが（和訳しただけのやつ読んだ時とか）、そうならない。
これとかわかりやすかった。
https://booth.pm/ja/items/1835632

#メリット④ :  上級エンジニアさんも復習する時とても便利。だと思う。
読みやすいからわかりやすい。そして予習しやすい。はず

#メリット⑤ :  結構色々ある。
アーキテクチャから様々な言語まで、体系的に書いてある本が多い印象。


つまり、、
試しにいってみなはれ！！！

https://booth.pm/ja