OmniAICreator/Qiita-1.07M huggingface dataset:
mac のファイルシステムは大文字小文字を区別しない

APFS で, 大文字小文字が区別されない.
docker volume sync, tar file での動作を軽く検証する.

# 以下の様な動作になり、びっくり

```
$ pwd
/

$ PWD
/

$ pWd
/
```

```
$ which echo
/bin/echo

$ which Echo
/bin/Echo

$ which ECHO
/bin/ECHO

$ WHICH ECHO
/bin/ECHO
```

```
$ touch abcd
$ ls
abcd

$ touch ABCD
$ ls
abcd
```


# docker volumen sync した場合
docker for mac で、volumen 同期し, container 内で file を作成してみる.
結果は、mac の動作と同様に, 大文字小文字を考慮せず, 同じ file として扱われる

```
[root@9f0e9d28a78d current]# touch a
[root@9f0e9d28a78d current]# ls
a

[root@9f0e9d28a78d current]# touch A
[root@9f0e9d28a78d current]# ls
a
```


volume 同期していない dir 内では大文字小文字は区別された

```
[root@9f0e9d28a78d test]# touch a
[root@9f0e9d28a78d test]# ls
a

[root@9f0e9d28a78d test]# touch A
[root@9f0e9d28a78d test]# ls
A  a
```


# tar file を解凍した場合は?

tar file の中身は以下

```
 drwxr-xr-x   0 ./tmp/
 -rw-r--r--   2 ./tmp/A
 -rw-r--r--   2 ./tmp/a
```

結果, 片方の file は消滅する

```
$ tar zxvf tmp.tar.gz
x ./tmp/
x ./tmp/A
x ./tmp/a

$ ls tmp
a
```


# 怖いですね
git は試していないが, 同様の動作をすると仮定すると, 惑わされる事がでてきそうですね. 

怖や怖や
Railsコマンドメモ

勉強内容をメモしたものです

# 基本スクリプト
| 説明 | コマンド内容|
|:--|:---|
| アプリ作成 | rails new [アプリケーション名]
| コントローラ作成|raild g controller [コントローラ名]
| モデル作成| rails g model [モデル名]
| モデル削除| rails d model [モデル名]
| マイグレーションファイルの作成 | rails g migration [行う処理+テーブル名]


# アクション

|アクション| REST
|--|--|
|index| GET model名
|new | GET model/new
|show| GET model/:id
|edit| GET model/:id/edit
|create| POST model
|update| PUT model/:id
|destroy| DELETE model/:id

# Model

```
rails g model [model名]
```

## データ型
| 型名 | |
|:--|--|
|string | 文字列
|text| 長い文字列
|date| 日付
|datetime | 日時
|time| 時間
|integer| 整数
| float| 浮動小数
|decimal| 高精度少数
|binary| バイナリ
|boolean|真偽値


# Migration Script file

+ モデルを作成すると自動で生成される
+ テーブルに変更を行いたい場合は手動で作成する

```
rails g migration [行う処理+テーブル名]
```
+ db/migrate/配下にファイルが生成される

## コマンド上で変更を行う

```
rails g migration [クラス名] [カラム名]:[データ型]
```

クラス名

+ AddXXXTo[テーブル名]
+ RemoveXXXFrom[テーブル名]


## MigrationFileを変更する

+ 実行する処理：upメソッド
+ 戻す処理：downメソッド

```
  def up
    add_column :[Table名], :[カラム名], :[データ型]
  end

  def down
    remove_column [Table名], :[カラム名], :[データ型]
  end
```

## Command list
maigration関連でよく使うコマンド集

| 処理　| コマンド| 備考 
|:---|:---|:---|
| マイグレーション実行| rake db:migrate
| 状態を確認 | rails db:migrate:status
| ファイルを削除 |rails destroy migration [クラス名]| DB未反映のファイルを削除
|バージョン確認| rake db:version | 反映済みのバージョンを確認する
|ロールバック| rake db:rollback (STEP=[ステップ数])| 例) rake db:rollback STEP=2


# View(template)

+ ファイル名：　アクション名.html.erb
+ 置き場： app/view/コントロール名/

## Layout
### 共通
1. 優先度
  + アクション > クラス > コントローラ > アプリケーション
2. Layoutを指定しない
  + 指定先に"false" を使用

### レイヤーごとの指定方法
**アプリケーション*全体の共通レイアウト**
 app/views/layouts/application.html.erb

**コントローラごとにレイアウトを自動指定**
app/views/layouts/[コントローラ名].html.erb

**(コントローラ)クラスからレイアウトを指定**

```
class [コントローラ名] < ApplicationController
  layout 'ファイル名'
end
```

**アクションからレイアウトを指定**

```
class [コントローラ名] < ApplicationController
  def [アクション名]
    render :layout => 'ファイル名'
  end
end
```
## 部分Template
+ ファイルの命名規則
    + _[ファイル名].html.erb
+ 配置場所
    + app/views/
    + app/view/[コントロール名] 
+ 埋め込み方法
    + <%= render 'ファイル名' %>

# Rubyコード
コードを記述： <% %>/<%= %>
改行を除く: <% _%>/<%= _%>

## 繰り返し

``` 
[オブジェクト].each do |[変数名]|
  [変数名]
end
```

## 条件分岐

```
if [条件] then
  # 実行する処理
else
  # 実行する処理
end
```

## インスタンス変数

```
 @変数 = 100
 @変数 #100
```
ESP32をJavascriptでLチカする：console.logをリモートで参照する

前回の投稿「[ESP32をJavascriptでLチカする](https://qiita.com/poruruba/items/96db9d20e7e4ced7635d)」に引き続き、ESP32でJavascriptを動かします。
今回は、デバッグログをリモートで参照できるようにします。
ESP32でJavascriptを動かせるようになったのはいいですが、console.logの出力は相変わらずSerial出力でした。
リモートで確認できるように、log.ioを使います。

log.ioについては、以下を参照してください。
　[log.ioでログをブラウザでリアルタイムモニタリングする](https://qiita.com/poruruba/items/7579243d9725b1cb23a5)

ソースコードもろもろは、前回同様以下に上げてあります。
随時、修正、拡張しています。

poruruba/QuickJS_ESP32

https://github.com/poruruba/QuickJS_ESP32

#log.ioサーバを立ち上げる

以下の記事を参考に、log.ioサーバを立ち上げます。
　[log.ioでログをブラウザでリアルタイムモニタリングする](https://qiita.com/poruruba/items/7579243d9725b1cb23a5)

```
npm install -g log.io
mkdir ~/.log.io
vi ~/.log.io/server.json
log.io-server
```

#log.ioにコンソール出力する

main.cppの以下の部分に立ち上げたlog.ioのサーバとポート番号を指定します。

```cpp:main.cpp
const char *LOGIO_HOST = "【Log.ioのホスト名】"; // log.ioのホスト名
const unsigned short LOGIO_PORT = 6689; // log.ioのポート番号
```

次に、log.ioをブラウザから開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/ec916b96-f4ac-990e-4056-08bc86845503.png)

あとは、Javascriptで以下のように有効化して、console.logで出力すると、その内容がlog.ioサーバに送信されます。

```js:main.js
	console.enableLogio(true);
	console.log("hello”);
```

こんな感じで、ログが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/56c7c9d2-0d77-9303-19d3-1ea6b45b8bd1.png)

stream名はMACアドレスにしてあります。
console.logではなく、console.infoなどで呼び出すと、source名がinfoなどで届きます。

これで、わざわさESP32を仮想COMポートなどとしてつなぐ必要がなくなります。

#(追加)SDの追加

log.ioとは関係ありませんが、ついでに、SDにも対応しておきました。JavascriptからSDを操作できるようにしておきました。
APIは以下を参照してください。

https://github.com/poruruba/QuickJS_ESP32/tree/main/doc

以上
自分用にGitHubのマイページを作った

GitHubのログイン後のトップページってマイページ的な感じになっていて、リポジトリ一覧やアクティビティが表示されていて便利っぽい感じがします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136506/ad9d7baa-cd78-5314-6b1c-3cc2b3a12fdd.png)

しかし仕事でも個人でもGitHubを使っているとごちゃまぜになってしまって正直使い勝手はよくありません。All Activityも自分のリポジトリにスターが付いたとかフォークされたとかそういう情報が見たいのであって、仕事の人がコミットしたログなんてここで見てもしょうがないのです。フリーで仕事をしているので仕事のリポジトリが自分のアカウントのリポジトリにもあったりするので、さらにぐちゃぐちゃです。

ということで、自分（というか僕）が好きな情報だけを見ることができるカスタムマイページを作ってみることにしました。

ということでできたのが下記です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136506/09a1318f-d1c8-bb58-e8bc-b90ac5b647b8.png)

ちなみに誰でも使えます。（海外リージョン＆API実行なので激しく遅いです）

https://github-mypage.alphabrend.com

## 何ができるか

何ができるのか紹介します。

### リポジトリ一覧がいい感じに並ぶ

リポジトリ一覧は本家だと、どういう順番で並んでいるかよくわからない感じだったりします。今ちょうど開発しているリポジトリにぱっとアクセスしたいと思っても、ファーストビューに表示されていなかったりします。

ということで更新順に表示されるようにし、目的のリポジトリにすぐアクセスできるようにしました。認証しているユーザーのリポジトリ一覧を取得するAPIをupdated descの並びで実行するようにしています。

### アクティビティがいい感じに並ぶ

アクティビティ一覧には自分のリポジトリの更新情報だけ並ぶようにしています。本家だと仕事で入っているOrganizationのリポジトリも混ざっているので邪魔になります。

APIは `List events received by the authenticated user` 的なやつを使っています。ここはどうもいろんなAPIがあってそれぞれ動きが違うようなので好みで使い分ける必要がありそうです。

ただまあ僕はOSS活動をしているわけでもないのでさほど表示されていません（なので逆に反応があると面白いのですが）

### 個人用リポジトリのコミット一覧が閲覧できる

これがちょっと僕がずっと欲しかった機能だったりするのですが、仕事のリポジトリを排除した、個人で開発しているリポジトリのコミット一覧を閲覧できるページを作りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136506/5e117fd9-b1cd-6ca7-2c63-bf942976c210.png)

本家でもそういう検索ができて、検索欄に `author:ユーザー名 user:ユーザー名` と入力して検索すると自分のコミットがずらーっと出てきます。

しかし前述したように、自分のアカウントに仕事用のリポジトリもあるためそれも混じって出てきます。むしろ仕事ガリガリしている時はそっちの方がたくさん出てきたりします。この月は個人で何したかなぁ…というのを見たくても色々邪魔で全然見渡すことができません。しかもGitHubは無限スクロールでなくページング式なので何度も何度もページ遷移して見ないといけないため途中で見る気が失せます。

そのため今回は無限スクロールでブワッと見られるようにしました。しかも、コミット一覧に `Ignore this repository` というボタンを付け、仕事のジャマなリポジトリはその場ですぐ無視設定に入れられるようにしました。これで一覧から消え、今後は表示されなくなります。クソアプリですので無視の解除機能はありません。

ということで雑にクソアプリを作っていたつもりが、自分にとって最高のアプリになってしまいました。どうしよう……。

## 開発

Next.js（Front + API）, Firebase（Firestore）, Cloud Run, Chakra UI の組み合わせで作っています。最近この組み合わせにハマっています。丁度先日作った130円でリファクタリングできるサービスもこの構成です。

https://refactor.alphabrend.com/

Firestoreは一部クライアントでのデータ保存も行っていますが、基本的に全てNext.jsのAPIを使ってサーバー側のみで処理しています。このようにすることでセキュリティルールをいちいち設定することがなく安全で（全部不許可にしている）、さらにそれによってSSRやページを開いたときの一瞬の未認証状態のタイミングのテストが抜けていてエラーになってしまうなどのいろいろな面倒くさい問題をいっさい気にせず開発することができて非常に楽です。MySQLにすれば良いんじゃないのと思われるかもですがクソアプリにお金なんて使いたくないのです。かといってDBの容量などに小さい制限などがあるのもなんとなくいやなのでHerokuなども使いたくないという感じです。なんにしろ色々考えることをやめたらこうなりました。今後一生これで作っていきます。

Herokuなどを使うと、クソアプリということもあってアクセスはほとんど無いと思いますのでしょっちゅうサーバーが止まっていると思います。自分で使うとしてもそれはストレスなので、止まっていてもそんなに起動が遅くないCloud Runを使っています（とはいえ無料枠のあるアメリカリージョンにしてるので遅いですが）。Cloud RunだとGitHubと連携して勝手にデプロイしてくれるようにもできるのですごく楽です。あとVercelという選択肢もありますが、Vercelは容量制限で環境変数にfirebase-admin用のキーが設定できないので残念ながら使えません。それさえなければそっちが良かったのですが……。

Remixが最近流行ってるっぽいので使おうかと思ったのですが、ちょっと師走は忙しそうなのでやめておきました…。

## まとめ

ということで自分的には今までのGitHubのブックマークを置き換えようと思うくらい最高のアプリですが他の人にはどうでもいいというクソアプリでした。僕はずっと使っていきます。

ちなみにGitHubのAPIを見ると、そんな機能もあったのか、本家だとどこで見れるの？　みたいなAPIもいくつかあるっぽかったので、全部のAPIからコンテンツを選べる昔のMy YahooみたいなGitHub カスタムマイページみたいなサービスがあると面白そうだなとも思いました。

ソース公開したので気分がのったらプルリクでも送ってください。

https://github.com/dala00/github-mypage
GASでSpreadsheetの範囲を列番号で指定するのが怖い時用のクラスを作った

このクラスをGoogle scriptのファイルに追加してあげると、、、

```js:IndicatableRow.gs
class IndicatableRow {
  constructor(firstRow, row){
    this.row = row
    this.firstRow = firstRow
  }
  get(key){
    var index = this.firstRow.indexOf(key)
    if ( typeof index != "number" && index ) { throw `No such key: ${key}` }
    return this.row[index]
  }
  getIndex(key){
    return this.firstRow.indexOf(key)
  }
  toObject(){
    var obj = {}
    this.firstRow.forEach((columnName)=>{
      obj[columnName] = this.get(columnName)
    })
    return obj
  }
}
```

以下のような形で「1行目の名前」で列のデータを指定できるようになるので、
列の追加や並び替えに強いScriptを作れます。

```js:main.gs
function main() {
  const targeData= targetSettingsSheet.getDataRange.getValues()
  const propertyName = settingsSheet.getRange("B4")
  const firstRow = targeData.shift()
  targetData.forEach(function(row){
    const indicatableRow = new IndicatableRow(firstRow, row)
    const pageId = getNotionPageId(indicatableRow.get("Relationを追加するページのURL"))
    const relationPageId = getNotionPageId(indicatableRow.get("追加されるRelationのURL"))
    addNotionRelation(pageId, relationPageId, propertyName)
  })
}
```
おすすめ技術系ポッドキャストとおすすめ回の紹介(2021年度)

# おすすめ技術系ポッドキャストとおすすめ回の紹介(2021年度)

みなさんこんにちはktkryattaと申します。

この記事は鈴鹿高専 Advent Calendar 2021の5日目の記事です。

https://qiita.com/advent-calendar/2021/snct


## 概要
今年度に入ってからポッドキャストを聴くようになりまして、おすすめポッドキャストをまとめてみました。
また、今年度の振り返りとして下記の3つのことも記載しています！

* ポッドキャストという体験の良かったなと感じたこと
* 各ポッドキャストとの出会ったきっかけ
* 各ポッドキャストのおすすめ回

## ポッドキャストの良いところ
ラジオを聞くような感覚で技術に触れることができるところが一番良かったです。(徒歩や電車などの移動時間とかおすすめです)
あとはゲームなどでレベル上げなど、比較的考えない作業をしている時にのんびり聞いていました。
音声だけでなく、Show Notesと呼ばれる各回に何を話題として話されていたかのテキストベースの資料もあるところが、この回は何を話しているのかがわかったり、後で振り返ったりする時に便利でした！

## おすすめポッドキャスト

### fukabori.fm
`技術・組織・マネジメントなどを深掘りして楽しむPodcastです。`
上記はポッドキャスト内に記載されている概要なのですが、技術だけでなく組織やマネジメント分野の話題が聞けます。
fukabori.fmと出会ったきっかけは、ポッドキャスト全く知らなかった時に友人からいただいた紹介でした。

https://fukabori.fm/

初めてfukabori.fmを知った時に、他の組織ではどんな取り組みとかされているのだろう？と疑問に思っていたため下記の回を聴いていました。
ポッドキャスト内で様々な組織での取り組みを聴くことができ、こういう取り組みもあるんだ！といった視野が広がるいいきっかけになったことがとても良かったです！

https://fukabori.fm/episode/24

https://fukabori.fm/episode/41



### UIT INSIDE
`LINE UIT の開発者による「最新のフロントエンド」をキャッチアップできる Podcast`
UIT INSIDEと出会ったきっかけは、モブプログラミングってどんな感じなんだろうということを知りたくて検索した時に出会いました。

https://uit-inside.linecorp.com/

直近で知ったためまだ2つの回しか聴けていないのですが、どちらも「こういう背景があったのでこういう取り組みをしました」を聴くことができたところが良かったと感じました。
Show Notesが詳細に記載されていたり、ポッドキャスト内でタイムスタンプがあり直ぐに気になる話題にジャンプできるところも良かったなと感じました！

https://uit-inside.linecorp.com/episode/91

https://uit-inside.linecorp.com/episode/105

### omoiyari.fm (lean-agile podcast)
`リーン / アジャイルが好きなふたりが、それらについて思いやりを持って語ったり語らなかったりする Podcast です。`
omoiyari.fm (lean-agile podcast)と出会ったきっかけは、UIT INSIDEと同じくモブプログラミングってどんな感じなんだろうということを知りたくて検索した時に出会いました。

https://lean-agile.fm/

こちらも直近で知ったためモブプログラミング回しか聴けていないのですが、楽しくわいわい話されているところがとても好きで、純粋にもっと他の回を聴きたいなと感じるようになりました！

https://lean-agile.fm/episode/30-1


### さいごに
ポッドキャストは本当にラジオ感覚で聴けてとても良いので、まだ聴いたことがない方はぜひ聴いてみてください！
また、おすすめポッドキャストなどあればコメントいただけますととても嬉しいです！


明日のアドベントカレンダーもお楽しみに！
【Vuex】アクションの利用

#はじめに
こんにちは！
今回は【Vuex】アクションの利用についてアウトプットしていきます！

#アクションとは
アクションはミューテーションと似ていますが、下記の点で異なります。

・アクションは、状態を変更するのではなく、ミューテーションをコミットします。
・アクションは任意の非同期処理を含むことができます。

#書き方・解説

```pages/index.js
        <p>{{ $store.state.message }}</p>
        <button v-on:click="$store.dispatch('updateMessageAction')">Dispatch</button>

```

```store/index.js
        mutations:{
            updateMessage: function(state,payload){
                // ⏬state.messageを書き換える処理
                state.message = payload
            }
        },
        actions: {
        updateMessageAction(context) {
            context.commit('updateMessage', 'Commit with payload')
        }
        }
```

`action`の中から`mutatioms`を呼ぶように修正を行います。
定義した`updateMessageAction`をコンポーネント側から呼びます。
この時、`commit`メソッドではなく`dispatch`メソッドを使います。

また、`action`でも`mutations`同様、値渡しすることが可能です。


#最後に
今回はアクションの利用についてアウトプットしました。
今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
【ruby】条件演算子を用いたif文

#条件演算子とは？

今回のトピックは、rubyの基礎である条件演算子を用いた
プログラミングを解説していこうと思います。

if文を使用しなくても、短く書けるので、
リーダブルコードになるためとてもいいと思いますよ＾＾

ぜひ、覚えていってくださいね！

##条件文

まず、初めによく見る条件文というのはif文だと思います。

例えばこんな感じのやつ↓

```php:example

def country(language)
   if language == "Japan"
　   "Japanese"
   elsif language == "the us"
     "English"
   elseif language == "Italy"
     "Italy"
   else
     "WHAT???"
   end
end

language = Japan
puts country(language)

```

ifの後に続けて書くのが、一番初めに習う
if文の条件式かと思います。

しかしもっと、短く書くこともできるのが
条件演算子なんですね＾＾

短いif文とかであれば、条件演算子で書くといいですよ。

次にて紹介いたしますね！

##条件演算子

それでは、条件演算子についてまずコードを
見ていきましょうか！

```php:条件演算子

def enzanshi(number)
 number > 10 ? "true" : "false"
end

number = 5
puts enzanshi(number)

```

上だけで処理が完成してしまうんですね。
短くていいですよね＾＾

見方としても簡単です。

number > 10の条件を見て
正であればtrueの左側が実行されます。
falseであれば右側が実行されます。

注意としては、trueの位置にfalseと書いても
左側が原則としてtrueの位置になるため
左側を正そして、右側を誤として覚えてくださいね！

##まとめ

いかがでしたでしょうか？

こんな簡単にできてしまうなんてびっくりですね＾＾

それでは、また次のruby講座でおあいしましょう！

ちゃお！
【DRF（Django REST framework）】エラーメッセージの"この項目"をverbose_nameに置き換えたい

## 前提
- フィールドに氏名を定義しているUserモデルクラスを作成する
- ユーザー登録・更新処理時には、以下のようなシリアライザーを作成する


```python:Userモデルクラス
class User(BaseModel):
    name = models.CharField(verbose_name='氏名' blank=False)
```

```python:Userシリアライザー
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
```


## 目的

- ユーザーデータがPOSTされた際に、氏名がブランクの場合は以下のようなDRFデフォルトのエラーメッセージを返す

```json
{"name":["この項目は空にできません。"]}
```

- `この項目`が気に入らない
- `key`を参照してフロント側で変換してもいいが、せっかくバックエンド側に`verbose_name`を定義しているのでバックエンド側で変換したい



## 対策
- こんな感じで実現

```python:エラーメッセージをverbose_nameに変換するカスタムModelSerializerクラス
from rest_framework import serializers
from rest_framework.exceptions import ErrorDetail


class CustomModelSerializer(serializers.ModelSerializer):
    @property
    def errors(self):
        # エラーを取得
        errors = super().errors
        # verbose_name変換後エラーメッセージ
        verbose_errors = dict()

        # Modelクラスからverbose_nameを属性に持っているフィールドを取得
        fields = {field.name: field.verbose_name for field in
                   self.Meta.model._meta.get_fields() if hasattr(field, 'verbose_name')}
        # エラー分ループ
        for field_name, error in errors.items():
            # 「この項目」をverbose_nameに変換したErrorDetailを格納するリスト
            changed_error = list()
            # エラーが発生したフィールドがverbose_nameを持っているか
            if field_name in fields:
                for e in error:
                    # この項目をverbose_nameに置き換える
                    changed_error.append(ErrorDetail(str(e).replace('この項目', str(fields[field_name])), e.code))
                 # verbose_nameに変換したエラーメッセージを設定
                verbose_errors[field_name] = changed_error
            else:
                # 元のエラーメッセージを設定
                verbose_errors[field_name] = error
        return verbose_errors
```

```python:Userモデルクラス
class User(CustomModelSerializer):
    name = models.CharField(verbose_name='氏名' blank=False)
```

## 簡単解説
- Serializerでエラーが発生すると、プロパティの`errors`にエラーメッセージ（`ErrorDetail(string='エラーメッセージ' code='エラー種別')`）が格納される
- そのため、`errors`プロパティをオーバーライドして、`この項目`を`verbose_name`に変換する処理を定義した
- 詳しい処理内容はコメント参照


## 参考資料
- ありがたや

https://stackoverflow.com/questions/55347324/django-drf-display-fields-verbose-name-in-error-message
英語ディクテーション用にyoutube-dlでダウンロードしたvtt形式の字幕ファイルをPlain Textに変換するrubyスクリプト

vtt形式は字幕表示に特化したフォーマットなので、人間が目で見るにはなかなか厳しいものがあります。

そこで、人間が見るのに適したPlain Textに変換するrubyスクリプトを作りました。

```ruby:vtt2txt.rb
#!ruby

valid_texts = []

while line = gets
    line.strip!
    if line =~ /-->/
        valid_texts << gets.strip
    end
end

lastline = nil
valid_texts.each do |line|
    if line != lastline
        puts line
        lastline = line
    end
end

```

YouTubeのCNN 10の自動生成字幕で動作確認済みです。
wasm-pack のインストール中に ranlib が死ぬ

## 問題
`cargo install wasm-pack` とかすると，

```
  ranlib -c libcrypto.a || echo Never mind.
  running "make" "install_dev"
  Detected changed:
  perl configdata.pm -r
  Configuring OpenSSL version 3.0.0 for target darwin64-arm64-cc
  Using os-specific seed configuration
  Creating configdata.pm
  Running configdata.pm
  Creating Makefile.in
  Creating Makefile

  **********************************************************************
  ***                                                                ***
  ***   OpenSSL has been successfully configured                     ***
  ***                                                                ***
  ***   If you encounter a problem while building, please open an    ***
  ***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
  ***   and include the output from the following command:           ***
  ***                                                                ***
  ***       perl configdata.pm --dump                                ***
  ***                                                                ***
  ***   (If you are new to OpenSSL, you might want to consult the    ***
  ***   'Troubleshooting' section in the INSTALL.md file first)      ***
  ***                                                                ***
  **********************************************************************
  **************************************************
  ***                                            ***
  ***   Please run the same make command again   ***
  ***                                            ***
  **************************************************

  --- stderr
  ranlib: invalid option -- c
  ranlib: invalid option -- c
  ranlib: invalid option -- c
  ranlib: invalid option -- c
  ranlib: invalid option -- c
  make[1]: *** [configdata.pm] Error 1
  thread 'main' panicked at '


  Error installing OpenSSL:
      Command: "make" "install_dev"
      Exit status: exit status: 2
```

こんなエラーが出て死ぬ．

## 環境
- Mac mini (M1, 2020)
- Chip Apple M1
- mac OS Big Sur 11.6
- rustc 1.57.0 (f1edd0429 2021-11-29)
- rustup 1.24.3 (ce5817a94 2021-05-31)
- cargo 1.57.0 (b2e52d7ca 2021-10-21)

## 解決
エラーを読むと，タイトル通り ranlib が死んでいることがわかる．ツールが不正なオプションで死ぬ系は大体 mac OS 標準のものと GNU 版との非互換性の問題なので，どちらが使われているか確認する．

```
$ which ranlib
/opt/homebrew/opt/binutils/bin/ranlib
```

brew のディレクトリ配下にいるので， GNU 版であることがわかる．ということで， `PATH` の優先度を変えて mac OS 標準版を使うように指定すると，うまく行く．

```sh
$ PATH=/usr/bin:$PATH cargo install wasm-pack
## 長いログ
   Compiling wasm-pack v0.10.1
    Finished release [optimized] target(s) in 1m 09s
```
Fargateだって25番ポートで外部メールサーバーに接続したい！

# はじめに

みなさん、SMTP接続してますか？メールを受信、送信するために利用されている方が多いかと思います。
SMTP接続といえば25番ポートですが、この25番ポートはユーザー認証といったセキュリティ面で必要な機能がなく過去にスパムメール配信などで悪用されたポートのため、現在殆どのサービスでは利用できないポートとして扱われています。
しかし今現在もメールリレー用のポートとして利用されていることもあり、どうしても接続しないといけないケースもあると思います。
今回、Fargateから25番ポートで外部メールサーバーに接続するために対応した内容をご紹介します。

:::note warn
2021年10月ごろに検討・対応した内容となります。最新の情報ではない可能性がありますのであらかじめご了承ください。
:::

# システム構成

- アプリはSpringBootを用いたJavaアプリ
- コンパイルしたjarをDocker Image化してECRに保存
- ECS on Fargate上でアプリコンテナを起動
- メール配信する際にNAT Gatewayを経由して外部のメールサーバーに25番ポートでリレーする

# Fargateから25番ポートで接続してみる

まずは何もせずFargateから直接外部のメールサーバーに接続してみます。しかし接続できずタイムアウトとなってしまいます。
VPCフローログを確認したところ、セキュリティグループやネットワークALCでは許可済みなのに該当外部メールサーバーへの接続が別の理由でREJECTされていることがわかりました。

# なぜ接続できなかったのか

AWSではスパムメールの配信を抑制するべく、EC2やLambdaといったサービスではデフォルトで25番ポートのアウトバウンドトラフィックがブロックされており、解除申請を出すことで利用可能となるようです。[^1]
では、EC2やLambdaのように解除申請を出せばいいのかと思ったのですが、AWSサポートに詳細を確認したところFargateからの25番ポートでの接続は2021年10月時点では解除できないとの回答をいただきました。

# 回避策

現時点ではFargateからの25番ポートでの接続はできないことがわかりました。そのため、回避案として以下のものが考えられました。

1. FargateではなくEC2上でアプリを動くように変更する
1. 外部メールサーバーの接続を25番ではないポートでの接続に変更する
1. 内部にメールリレー用のEC2インスタンスを準備し、Fargateからメールリレー用EC2サーバーに25番以外でのポート接続→メールリレー用EC2から外部メールサーバーに25番ポートでの接続に変更する

それぞれメリット・デメリットがありますが、今回はメールリレー用EC2サーバーを準備することでFargateからの25番ポート接続を実現するようにしました。
また、前述の通りEC2サーバーを準備してもデフォルトでは接続できないため、解除申請も合わせて提出しました。

# まとめ

以上、Fargateから25番ポートで外部メールサーバーに接続する方法についてご紹介いたしました。
Fargateから25番ポートで接続したい方に参考になれば幸いです。

[^1]: https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-port-25-throttle/
システム構成図が書けるDiagramsをインストールする


# 初めに
diagramsという物をインストールしてみる
https://diagrams.mingrammer.com

# install
Macのhome brewを使った例を示す。

```bash
# python3をインストールする。
brew install python3

# diagramsをインストールする
pip3 install diagrams

# graphvizをインストールする。理由は後述。（思った以上にインストールに時間がかかる。）
brew install graphviz
```

# サンプルを動かす

https://diagrams.mingrammer.com/docs/getting-started/examples#clustered-web-services
ここのサンプルを使う。

```sample.py
from diagrams import Cluster, Diagram
from diagrams.aws.compute import ECS
from diagrams.aws.database import ElastiCache, RDS
from diagrams.aws.network import ELB
from diagrams.aws.network import Route53

with Diagram("Clustered Web Services", show=False):
    dns = Route53("dns")
    lb = ELB("lb")

    with Cluster("Services"):
        svc_group = [ECS("web1"),
                     ECS("web2"),
                     ECS("web3")]

    with Cluster("DB Cluster"):
        db_main = RDS("userdb")
        db_main - [RDS("userdb ro")]

    memcached = ElastiCache("memcached")

    dns >> lb >> svc_group
    svc_group >> db_main
    svc_group >> memcached
```

# 構成図を出力してみる

```bash
python3 sample.py
```

### `graphviz.backend.ExecutableNotFound: failed to execute ['dot', '-Kdot', '-Tpng', '-O', 'clustered_web_services'], make sure the Graphviz executables are on your systems' PATH` が出て出力失敗した場合。
上記のエラーがが出たときはGraphvizをインストールする必要がある。

```bash
brew install graphviz
```

# できたもの
![clustered_web_services.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136416/1728d967-9d1e-14b5-fd5a-d87d28bf0a7a.png)

# 使ってみて
`>>`や`<<`で繋げていくのはわかりやすい印象でした。
システム構成図をgit管理できるのは良さそう。
より複雑な構成になった時はどうなるか、そして運用していくにはどうするかは、
それぞれチームとで話し合っていく必要がありそうだ。
技術メモ  APIやhttp通信のイメージ　備忘録

#APIについて

一言で言ってしまうと、
ソフトウェアの間に入って、使いたい機能などを提供してくれるお助けマンです。

APIとは、アプリケーションプログラミングインターフェースの略です。
→interfaceのinterは、間をさす単語ですので、ざっくり和訳すると、
アプリ同士の間に入って、機能を提供してくれる優しいやつです
#WebAPIについて
よく初めの頃、APIとWebAPI違いがわからんっ！となり悩んでいましたが、シンプルです。

WebAPIは、APIの一種で、例えばTwitterなどで友人にリムられてる？ブロックされてるなどを
調べることができる「えごったー」という公式ではないサービスがあります。
これを使うと、先ほど言ったことをチェックできます。

ここでお気づきかもしれませんが、そんな機能元々ないですよね？
そう、このweb上のAPI「えごったー」がなければわかりません。
このtwitterが公開しているwebAPIを利用して作られたサービスが、えごったーなどのサービスです。

#http通信のイメージ
基本的には、以下の３つを覚えておくと良い気がします。

1http リクエストとレスポンス
2httpメソッド
3ヘッダー


まず、１つ目は簡単です。
クライアントつまり通信方式であるhttpを使って通信をしたい側が、
サーバーに情報ちょうだい（トラフィックが流れます）としたら、サーバー側がそれに対して
レスポンスを返す。
つまり、〇〇したいという問い合わせに対して、返事を出すというやりとりのことです。

２つ目は、httpメソッドとは簡易的なCRUDアプリ（削除や更新ができるアプリ 例:掲示板など）
を作ったことがある人だったらわかりやすいと思います。GetやPostなどデータを取得したり送信したりするアレです。要は、httpに処理させたい方式のことを指します。

3つめは、ヘッダーについてです。これは正直、理解するまで時間がかかりました。
OSI参照モデルのことがわかると少しイメージがしやすいかもしれません。
通信をする際にくっついてくる情報です。セキュリティに関しての技術書では、大体どの層で、
どこまで、このヘッダー情報を守るかということが取り上げられていました。
*ちなみにヘッダー情報がついていないデータを、ペイロードと呼びます。
#おわりに
個人のメモですが、お役に立てれば幸いです。
*必ずこの記事以外にも自分が信頼できるリソースを通して、各自ご確認をお願いいたします。
ブラウザで絶対音を鳴らす

ブラウザ、特にスマホで絶対任意のタイミングで音を鳴らすためにやったことを書きます。

# ユースケース
イヤホンで音楽を聴きながら花火を見る実験企画のアプリで、ユーザーそれぞれのデバイスで同時に音を再生しなければならない、という要求がありました。しかもブラウザで。
本題ではない技術仕様は割愛しますが、タイマーを用意して時間になったら音楽を流すという仕組みです。単純に`Web Audio`をつかって音を鳴らせばいいと思っていたのですが、面倒なケースが色々あったので解決策を書き留めます。

# 事前にボタン等を押させる
音を鳴らすために必要なことです。
Chrome等で実装されている仕様で、避けることはできません。ユーザーの操作なしに１回目の音を鳴らすことはできません。何か操作をさせてから、鳴らすようにしましょう。また、音源を事前ロードすることを忘れずに。

# 未来時間の`start`を使わない
音を鳴らすために必要なことです。
`Web Audio`の`AudioBufferSourceNode`を使う時、任意の時間で正確に再生させるためには`start`を使うことができますが、未来時間を指定すると一部デバイスで再生されない現象がありました。なので頑張ってギリギリ未来時間にならない方法を考えましょう。

# wavを使う
音を鳴らすために必要なことです。
`AudioContext`の`decodeAudioData`を使う時、mp3ファイルをデコードできないブラウザがありました。独自実装する形でのpolyfillとかもあるかもしれませんが、一番簡単で安全な方法はwavを使うことでした。
残念ながら、ここ2,3年のAndroidデバイスでも標準ブラウザで発生する現象です。各社がカスタマイズしたりすることによって、古いバージョンのchromiumが使われていたりします。
通信量の問題はあるので、そこはサポートしないか、独自の方法を用いるなども選択肢ですね。

# 直前に別のノイズ音源を鳴らす
鳴らしたい音源が頭から鳴ることを保証するために必要なことです。
`iOS`では音を鳴らしてから一定時間が経つと、オーディオ機器との接続がセーブ状態（？）に入ります。その状態から音源を再生すると、最初に「プツッ」と音が入ったり不都合があります。そのため、小さな音のノイズ音源を用意して、直前に再生しておきましょう。無音だと効果がないので注意です。

# `visibilitychange`をキャッチして、音が鳴るかチェックする
ページを開いてから、音を鳴らすまでに時間が開く時、ユーザーがホーム画面に戻るなどの操作をして、戻ってきた時にも必ず音を鳴らすために必要なことです。
`iOS`でページを開いてから、ホーム画面に戻って一定の操作をしてからマルチタスクで戻ってくると、音が再生できない現象がありました。その状態からユーザーの操作なしに復帰することは出来なかったので、ページがアクティブになった時音が再生できるかどうか確認するべきです。
これは`Web Audio`で任意のタイミングで音を再生したい時に重要なのですが、何かを再生するまで音が鳴るかどうか確認する方法がありません。そのため今回は、短いアクティベート音を用意して
https://qiita.com/s9prfe/items/ec199b31009bf90b4e22
この方法で音が鳴るかどうか確認しました。

# 音が鳴らないことを検知した時、ボタンを押させる
特殊ケースのために必要なことです。
前セクションのケースなど、あらゆる場合で音が鳴らなかった場合等のために、再度アクティブにさせるボタンが必要です。今回はこのように対処しました。
![スクリーンショット 2021-12-05 12.36.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175810/d5376bb4-947f-81df-ae87-2083c5031b14.png)

# それでも音が鳴らないことを検知した時、ページを更新させる
特殊ケースのために必要なことです。
例えば`iOS`で、
1. イヤホンを挿したままページを開き、音が鳴っていることを確認する
2. ホームボタンを押す
3. イヤホンを抜く
4. 音が鳴らない
5. イヤホンを挿しても鳴らない
6. ボタンを押してもならない
...
という現象がありました。この場合に限らず、スマホで音を再生する場合の最終手段としてこれは必要のようです。よってこれも、前セクションと同じように対処しました。
![スクリーンショット 2021-12-05 12.38.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175810/015a7631-f064-95b2-5a94-3a4401039887.png)

# おまけ
- `baseLatency`は未定義の可能性がある

# あとがき
カスタマイズされたAndroidデバイスや、OperaNeonなど未だにかなり古いバージョンのChromiumベースなブラウザが存在します。これらまでサポートすると大変ですが、4,5年前のデバイスを使っているユーザーというのは実際ざらにいるでしょうね。手持ちの中にも、そういうデバイスがありました。
テストをする中で手持ちのデバイスにも限界があるので、クラウドでテストできるサービスを探すと、音が鳴るのは`LambdaTest`というサービスでした。が、時々音が鳴らないデバイスもあって、アプリのせいなのかサービスのせいなのか切り分けに困ります。結局こういう場合は実機でテストするのがベストです。
はじめてのAmplifyStudio


## 初めに

AmplifyStudioを利用して
Reactコンポーネントを生成するまでの
一連の流れをメモしておこうと思います。


## AmplifyStudioとは

デザインツールである`Figma`を`Amplify`で作成したアプリケーションに
接続できるサービス。

`AmplifyStudio`が、`Figma`で作成したデザインを
Reactコンポーネントに変換し、
`Amplify`で作成したアプリケーション側で利用可能にしてくれるという、
ノーコード / ローコードサービスです。

参考：[Introducing AWS Amplify Studio](https://aws.amazon.com/jp/about-aws/whats-new/2021/12/aws-amplify-studio/)

## 全体の流れ

1. Amplifyのアプリケーションを作成
2. AmplifyStudioを有効化
3. AmplifyStudioにログイン
4. FigmaのファイルをAmplifyStudioに読み込む
5. Amplifyアプリケーション側でpullしてReactコンポーネントを生成


## 1. Amplifyのアプリケーションを作成

まずは、ReactをベースとしたAmplifyのアプリケーションを作成します。
今回は、詳細は割愛させていただきます。

[Amplifyチュートリアル](https://docs.amplify.aws/start/getting-started/installation/q/integration/react/)などを参考にしてみてください。

## 2. AmplifyStudioを有効化

次に1で作成したAmplifyアプリケーションの設定にある
AmplifyStudioを有効化します。

### 手順

Amplifyアプリの設定 > AmplifyStudioの設定

![スクリーンショット 2021-12-05 12.09.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395295/dd62f264-bd60-9bc5-bfc3-ca84b93234aa.png)

## 3. AmplifyStudioにログイン

AmplifyStudioの認証は、AWSの認証とは
別で管理されているので、
今回作業をするためのアカウントを発行します。

AWSアカウントを必要としないデザイナーやマーケター
でもアクセスしやすい環境を作れそうです。

### 手順

AmplifyStudioの設定の、
"ユーザーを招待"から自身のメールアドレスを登録。
(権限は個人開発ならとりあえず`Full access`を選択)

一時パスワードが送られてくるので、
メールアドレスと一時パスワードでパスワードを再設定しつつログインする。

![スクリーンショット 2021-12-05 12.13.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395295/6c8c78fd-3e41-eab3-0ede-33f62a60147b.png)

## 4. FigmaのファイルをAmplifyStudioに読み込む

AmplifyStudioにログインが出来たら、
いよいよAmplifyStudioにFigmaのファイルを読み込ませます。

### 手順

4-1. 利用するFigmaのファイルURLをコピー

![スクリーンショット 2021-12-05 12.19.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395295/f395c440-43d3-20bc-8f1f-0aca0c67a1a5.png)

4-2.
Design > UI Library > Get Startedをクリック > 4-1のURLを貼り付ける

 ![スクリーンショット 2021-12-05 12.24.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395295/f60be9cf-8b14-cc9e-76e5-7e2485caac5d.png)


[参考](https://docs.amplify.aws/console/uibuilder/figmatocode/#step-1-set-up-figma-file)


## 5. Amplifyアプリケーション側でpullしてReactコンポーネントを生成

最後にAmplifyアプリケーションで
AmplifyStudio上にあるコンポーネントを
Reactコンポーネントとしてコードにpullします。

### 手順

※npmの場合

- `npm install -g @aws-amplify/cli`
- `amplify pull --appId {アプリケーションID} --envName {環境名}`

AmplifyのアプリケーションIDと環境名は自分の環境に合わせて変更してください。

例）
アプリケーションID：`hoge_123`
環境名: `dev`

`amplify pull --appId hoge_123 --envName dev`

[参考](https://docs.amplify.aws/console/uibuilder/figmatocode/#step-3-pull-ui-components-code-in-your-project)


## 最後に

お疲れ様でした。

AmplifyStudioを利用した
Reactコンポーネント生成ができましたでしょうか。

この記事が何かの助けになれれば幸いです。

良きAmplifyライフを。
[SwiftUI]クラス・構造体とSwiftUIのコンポーネントの命名が被ってしまった場合



クラス名や構造体の命名が、SwiftUIであらかじめ用意されているViewの命名と被ってしまった場合、
SwiftUI.使いたいViewで指定するで解決。


```swift
struct Menu {
    let label: String
    let icon: Image
}

struct MenuView: View {
    var body: some View {
        VStack{
            SwiftUI.Menu { // SwiftUI.Menuを追記
                ForEach(0..<5){ index in
                    Button(action: {}) {
                        Text("index: \(index)")
                    }
                }
            } label: {
                Image(systemName: "plus")
            }
        }
    }
}
```

## NGな場合

以下のように、構造体やViewプロトコルに準拠させた自作のView構造体を作成する場合、再宣言が無効ですとエラーメッセージが吐き出されるされる。
>Invalid redeclaration of 'MenuView'

```swift
struct MenuView: View {
    var body: some View {
        VStack{
            Menu {
                ForEach(0..<5){ index in
                    Button(action: {}) {
                        Text("index: \(index)")
                    }
                }
            } label: {
                Image(systemName: "plus")
            }
        }
    }
}

struct MenuView: View {
    var body: some View {
        Text("menuView")
    }
}
```

しかしながら、以下のような今回の事例では、異なるエラーメッセージが吐き出される

```swift

struct Menu {
    let label: String
    let icon: Image
}

struct MenuView: View {
    var body: some View {
        VStack{
            Menu {
                ForEach(0..<5){ index in
                    Button(action: {}) {
                        Text("index: \(index)")
                    }
                }
            } label: {
                Image(systemName: "plus")
            }
        }
    }
}
```
以下のエラーメッセージが発生する

> - Generic struct 'VStack' requires that 'Menu' conform to 'View'
- Static method 'buildBlock' requires that 'Menu' conform to 'View'
- Trailing closure passed to parameter of type 'Decoder' that does not accept a closure

Viewプロトコルに準拠させたViewの命名が被った場合は、このメッセージが表示されると思い込んでいたので、構造体同士がかぶっているとは、全く気づかなかった。。。
同じInvalid redeclaration of 'MenuView'で統一して欲しい。。。
例外エラーの補足　スタックトレースとトップレベルについて


###スタックトレースとは？

スタックトレースというのは
>「例外が発生するまでに経てきたメソッド（関数）の履歴」

もう少し砕けた言い方をすると
>「あるメソッドでエラーが発生するまでに、どんなメソッドを、どの順番で呼び出したのか。の履歴」

例えばメソッド、methodA、methodB、methodC、methodDがあるとして

methodAの処理の中でmethodBを呼び
methodBの処理の中でmethodCを呼び
methodCの処理の中でmethodDを呼んだところでエラーが発生したとします。(PHP)

```php
function methodA()
{
    methodB();
}

function methodB()
{
    methodC();
}

function methodC()
{
    methodD();
}

function methodD()
{
    return 5 / 0; // 0除算で例外エラー発生
}

echo methodA();
```

するとこのようなエラー画面が表示されます

![B66FC863-65D0-4775-A167-FB5573F445AA_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/732098/ed3dec0e-3fca-ca3a-d3f2-ae4d8d57f773.jpeg)


エラーが発生した行数が書かれてあり、上からmethodD(#1),methodC(#2),methodB(#3),methodA(#4)と
たどってきているのがわかると思います。

methodDで発生した例外エラー情報が、try~catchで補足されなければ
例外エラー情報は補足されるまで呼び出し元をさかのぼっていき
一番最初の呼び出し元（methodA）でも補足されなければ
Fatal Error（致命的なエラー）となってアプリを即停止させます。



この一番最初の呼び出し元というのが ``トップレベル`` です。
（正しくは「クラス／モジュール定義の一番外側のコンテキスト」ですが、まあ難しいのでとりあえずは一番外側＝一番最初という理解でいいと思います）

ただし、トップレベルまでさかのぼってきた例外エラーがFatal Errorを出して、ユーザーの画面に上記のような画面が表示されても困ります

代わりにエラー画面を表示させたいけど、例外エラーが出る可能性のある箇所で毎回try~catchを書いて、エラー画面を表示させるという同じ処理を書くのも違う、、

となった時に、トップレベルまでさかのぼってきたエラーをまとめてキャッチ（補足）してエラー画面を表示させたり、ログファイルにエラーの内容を書き出したりする処理をまとめておけるのが
[set_exception_handler](https://www.php.net/manual/ja/function.set-exception-handler.php)という関数です。

この関数をトップレベルでメソッドを呼び出すファイルに記述しておくことで
補足されなかった例外エラーをここでまとめて補足することができ共通の処理を実行できます。

・ある例外エラーは違う処理で、個別に処理がしたいんだ！
というような時にはtry~catchで囲んであげるという形になります。

![DF788B9C-6CA2-410B-946B-E2F56D182650_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/732098/28db937a-aa65-0d40-f256-751db0bf12bf.jpeg)

###PHPエラーを例外エラーへ

また、PHPの標準エラー報告を、例外エラーに変換させるような
[set_error_handler](https://www.php.net/manual/ja/function.set-error-handler.php)という関数もあります

この関数を呼び出しておくことで、通常try~catchでは補足できないPHPエラーも例外エラーとして扱えることができるようになります。

##補足: 例外エラーを投げるに意識すること


例外エラーを投げる際のエラークラスには様々なクラスがあり、すべてのクラスはExeptionクラスを基準に階層ツリー構造となっていて、それぞれ発生するエラーの内容によって選択するクラスも変わってきます。（例えば引数の型エラーならInvalidArgmentExeptionを投げる）
キャッチするクラスによってどんなエラーが発生したのかが把握できるので、大元となるExceptionクラス（例外エラーが発生したということしかわからない）を投げてはいけないという原則もあります。このあたりも意識して例外エラーへの対処はしていきたいですね
RAS・RASIS とは

## 勉強前イメージ

性能とかの基準を決めたやつ？

## 調査

### RAS とは

Reliability(信頼性), Avalability(可用性), Serviceability(保守性) の頭文字を取ったもので
コンピュータが安定して機能や性能が発揮できるかの項目になります。

- Reliability(信頼性)

故障や障害によってシステム停止や機能不全の発生しにくさを表します。
稼働時間あたりの障害発生回数(MTBF)などで表すことが多いです。

- Avalability(可用性)

稼働率の高さや障害・保守によっての停止時間の短さを表します。
稼働率(時間に対する稼働時間の割合)で表すことが多いです。

- Serviceability(保守性)

障害復旧やどれだけメンテナンスしやすいかで表します。
障害復旧までの平均時間(MTTR)で表すことが多いです。

### RASIS とは

Reliability(信頼性), Avalability(可用性), Serviceability(保守性), Integrity(完全性), Security(機密性) の頭文字を取ったもので
RAS同様機能・性能が発揮できるかの項目になります。

- Integrity(完全性)

過剰に負荷がかかったときや障害時にデータの破壊や不整合の起きづらさを表します。

- Security(機密性)

外部からの侵入や機密漏洩の起きづらさを表します。

### RAS と RASIS について

RASは1970年代にIBMが製品の特性を表す用語として広まり、
日本ではRASISがRASに完全性と機密性を加えたものとしてよく使われます。

## 勉強後イメージ

信頼性・可用性・保守性とかはどこでも一緒なのね。
その項目をまとめたものって感じ？
あんまり見たことないけど考え方として必要

## 参考

- [RAS 【Reliability, Availability and Serviceability】](https://e-words.jp/w/RAS-2.html)
- [RAS（Reliability Availability Serviceability）](http://mh.rgr.jp/memo/it0113.htm)
C# EntityFramework マイグレーションまとめ

# はじめに
Entity Frameworkを使う時のマイグレーションコマンドの使い方の備忘録。
ドキュメントや書籍を確認してもマイグレーションのRollbackの記事が上手に見つけられず苦労したので....

## dotnet efのインストール

```
dotnet tool install --global dotnet-ef
```

## マイグレーションファイルの作成
```
dotnet ef migrations add [マイグレーションファイル名]
```
## マイグレーションの実行
```
dotnet ef database update
```

## 全テーブルの削除
```
dotnet ef database drop
```

#ここにハマった。。。。。。
各コマンドを叩くと下記が表示された。

```
Build failed. Use dotnet build to see the errors.
```

ビルドを再度実行しても同じエラー。
リビルドすることで解決出来ました。
Web Audioで音が鳴らなかったことを検知する

# 課題
Web Audioで、音が鳴らなかったことを検知したい。
- ユーザー操作が行われていない時に起こる警告で鳴らない
- その他何らかの理由で鳴らない
この１個目ってキャッチする方法ないのかな？

# 解決
今回は再生する音声データが短かったので、`ended`イベントが時間内に呼ばれたかどうかで判断した。実際に再生されていないのに、`ended`が呼ばれることはない模様。

```
play(context: AudioContext, err?: () => void, success?: () => void) {
  const audioBuffer = ; //任意の音声データ
  const audioBufferDuration = ; //その秒数

  const waitTime = (audioBufferDuration * 1000) + 500;
  const errorFeedback = setTimeout(() => {
    err?.();
  }, waitTime);

  const src = context.createBufferSource();
  src.addEventListener('ended', (e) => {
    clearTimeout(errorFeedback);
    success?.();
  });

  src.buffer = audioBuffer;
  src.connect(context.destination);
  src.start();
  // どこかでstop, disconnectすること
}
```
Vimを使うことで初学者の中でも差別化を図る

こんにちは、Vimを使うことをオススメしときながら使いこなせていないだいちです。

今回は初学者であればVimを使って勉強をすることを纏めた記事です。

今年でVimが30周年を迎えたという記事を見たのもあり
僕自身とそんなに変わらない年数を生きてきたんだと勝手に親近感を湧いてました。

皆さんはVimを普段から使用してますか。
僕の場合、スクールに入り課題をこなしてきたのですが
その間はずっとVimのみを使用してきました。

そんなVimを使っている話を業界の方に伝えると
驚かれることが多かった印象。
Vimが使えることでLinuxやGitなどのCLIでの操作への抵抗も無くなり、より深く理解もできます。
今回はVimを一人でも多く使ってもらいメリットを知ってもらいたいなと思い記事にしました。

### この記事で伝えたいこと
- なぜVimを使うのか
    - 他との差別化を図る
- 簡単なVimの使い方とコマンドの紹介

### 解決したい課題
- プログラミング初学者が沢山いて差別化ができない
    - Vimを使えるだけで注目される（誇張しているかもw）
- 実務の際にサーバーに入ってからのファイル編集時に「わからない」をなくす。

### 初学者が増え続けているっぽい
コロナの影響もあってか、在宅でできる仕事としてプログラミングが様々な広告で目にするようになっています。
広告の内容として過剰で酷いものだと
「3ヶ月でプロのエンジニア！」
「◯ヶ月でエンジニアとして月収〇〇万円！」
などが出てきて参入する人は増えているように感じます。
そしてスクールなどに通ってスキルを身につけてからいざ就職活動！
みんな同じようなポートフォリオ、面接での回答。
面接官はいまいち決定力にかけてしまうかも。
あと一つ何か他の初学者との違いがあれば採用される可能性が上がるのかもしれません。


### ただの初学者ではないことを示すために
タイトルにもあるようにとにかくVimを使えるようになりましょう！
可能であれば学習で使用するエディターはVim縛りにして毎日触るようにするとベスト！

#### Vimを扱うためにやること
環境情報
MacBook OSは何でも良き
ターミナル

上記の環境を用意してターミナルを立ち上げたら（起動）
準備完了

とりあえずVimに触れるために
`vi index.txt`
と打ってエンターを押下

Vimで作業ができます！

#### Vimの使い方（コマンドについて）
ここでは基本的なコマンドのみを纏めてます。
`vi index.txt`
で作ったファイルであれば消えてしまっても問題がないはずなので恐れず色々と試してみてください。

##### \<i> インサートモード
`vi index.txt`を打った後にエンターを押すと
index.txtファイルが作成されているのでその状態で
「i」を押下
これでインサートモードとなる。
入力ができるようになっているので適当に入力してみましょう。
![スクリーンショット 2021-12-05 11.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572072/57639db9-89ec-3c98-7d14-2b841bdb8dc4.png)

入力し終わったらインサートモードからノーマルモード[Esc]にします。
※状態がよくわからない場合にもとりあえず[Esc]を使ってみましょう。

##### \<Esc> ノーマルモードへ
インサートモードやヴィジュアルモード（この記事では触れない）から
ノーマルモードにする際に使用する

著者は初学時、現在の状態がよくわからなくなったらとにかくESCを押してました。
また、ESCって小指がつりそうになるので
<C-[>(「Ctrl」押しながら「[」を押す)
を今は使っています。

##### \<h> \<j> \<k> \<l> 移動
ノーマルモードの状態でカーソルを移動するのに使用する

| キー | 動作 |
|:-:|:-:|
| h | カーソルを左に移動 |
| j | カーソルを下に移動 |
| k | カーソルを上に移動 |
| l | カーソルを右に移動 |

\<w>や\<b>などでの移動もありますがまずは基本の移動方法を身につけましょう！
><font color="red">ポイント</font> → なぜ\<h> \<j> \<k> \<l>なのか？
昔に作られたADM-3A端末には矢印キーがなく代わりに\<h> \<j> \<k> \<l>が使われていた
![00.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572072/8c128e4f-a883-d1bb-3874-0b8c2006d020.jpeg)

##### その他のコマンド
| キー | 動作 |
|:-:|:-:|
| u | 最後の操作を取り消して元に戻す |
| x | 1文字の削除 |
| dd | 1行の切り取り |
| p | ペースト(貼り付け) |
| \:w | 保存 |
| \:q | ファイルを閉じる |

### Vimを扱えるだけがメリットじゃない
初めは不慣れなコマンド操作で嫌気が差してくるかと思います。
それでも日々の学習でVimを使うことでコマンドラインでの操作に慣れる日が必ず訪れます。
ふとした時に **Vimを知っていて良かったと思える時がくる** ので楽な方に逃げず続けていきましょう！

### Vimが扱えることでできることが増える
Vimが使えるとおまけで他のことに抵抗なく対応できるようになります。
僕自身が体感したのがCLIで操作ができること。
LinuxやGitを扱う時にやっていて良かったと思いました。
Vimとは直接関係ないですがキーボードのみで操作することに日頃から慣れることで
仕事の幅も広がるので心からVimを扱えるようになることをお勧めします。

### 注意
**Vimが使えるだけでは実務はこなせません。**
現場に応じて必要になってくることは変わってきますが
僕としてはVimが使えることで対応できる幅が広がるかなと思っています。
対応はできても完結できなければ意味がないのでVim以外にも学ぶべきことは沢山あるので
自身で優先順位を考えて勉強していきましょう！

### 終わりに
最後まで読んでいただきありがとうございます！
自分事ですが仕事とプライベートともに忙しく記事を纏めることを疎かにしていました。
自身のスキルアップのためにもこの機会に定期的にまとめて行こうと思えたので
今回このアドベントカレンダーに参加して良かったと感じてます。

**勉強しても活かさないと勉強していないのと同じ**
pytestのparametrizeを使用してテストコードを書いてみる mshmura

## 目的
pythonでテストコードの基本を身に着けること。
pytestのモジュールを使用して、大量データのテストコードを想定してテストが実行できるようにしてみること。

#### 注意点
テストコード実務未経験者が書いています。何か不備がありましたら、ご指摘いただけると幸いです。

テスト対象のファイルはこちらです。↓

``` simple_calc.py
def add_func(x,y):
    z = x + y
    return z

def subtract_func(x,y):
    z = x - y
    return z

def multiple_func(x,y):
    z = x * y
    return z

def add_string(x,y):
    z = f'苗字は{x}です。名前は{y}です。'
    return z
```

このコードをテストするためのテストファイルはこちらです。
ファイル名には「test_」という接頭辞を付ける必要があります。
まずは一番シンプルな形で、テストコードを書いてみます。↓

``` test_simple_calc.py
import simple_calc

def test_add_func():
    assert simple_calc.add_func(1,2) == 3

def test_subtract_func():
    assert simple_calc.subtract_func(3,2) == 1

def test_multiple_func():
    assert simple_calc.multiple_func(3,2) == 6

def test_add_string():
    assert simple_calc.add_string("田中","太郎") == "苗字は田中です。名前は太郎です。"
```

テスト対象のデータが増えてきた場合、テスト関数内でfor文を回してテストしていくんでしょうかね....
そのようなやり方ではなく、pytestモジュールのparametrizeという関数？を使用すると、テスト関数部分を汚さずスッキリ書けるので、やってみました。

``` test_simple_calc_param.py
import simple_calc
import pytest

# テスト関数ごとにダミーデータを用意
# 今回の場合、第一引数,第二引数が計算に使用する変数。
# 第三引数に期待する計算（関数の実行）結果を設定します。

dataset_for_add_func = [
    (3, 5, 8),
    (4, 6, 10),
    (10, 10, 20)
]

dataset_for_subtract_func = [
    (5, 2, 3),
    (10, 6, 4),
    (20, 10, 10)
]

dataset_for_multiple_func = [
    (5, 2, 1),
    (10, 6, 60),
    (20, 10, 200)
]

dataset_for_add_string = [
    ("田中", "よしこ", "苗字は田中です。名前はよしこです。"),
    ("吉田", "よしこ", "苗字は吉田です。名前はよしこです。"),
    ("佐藤", "よしこ", "苗字は佐藤です。名前はよしこです。"),
]


@pytest.mark.parametrize('param1,param2,result',dataset_for_add_func)
def test_add_func(param1, param2, result):
    assert simple_calc.add_func(param1, param2) == result

@pytest.mark.parametrize('param1,param2,result',dataset_for_subtract_func)
def test_subtract_func(param1,param2,result):
    assert simple_calc.subtract_func(param1,param2) == result

@pytest.mark.parametrize('param1,param2,result',dataset_for_multiple_func)
def test_multiple_func(param1,param2,result):
    assert simple_calc.multiple_func(param1,param2) == result

@pytest.mark.parametrize('param1,param2,result',dataset_for_add_string)
def test_add_string(param1,param2,result):
    assert simple_calc.add_string(param1,param2) == result

```

この形であれば、外部から何かデータを取得してきた時にもダミーデータの形式にデータを変換することさえ出来れば、テスト関数部分をいじる必要はなくなり効率的なテストが出来ると思います。

ちなみにテスト関数を実行する時はコマンドラインからpytest 「ファイルパス名」で実行します。（pytestだけ打つとすべてのテストファイルが実行されます。）
コマンド実行時にいるディレクトリと同じである場合は、下記のとおりです。

```
pytest test_simple_calc.py
pytest test_simple_calc_param.py
```

特定のファイルの特定の関数をテストする場合下記のように「::関数名」を付けます。

```
pytest test_simple_calc_param.py::test_add_func
```
vscode debug Error [zsh: command not found: cmd]



# zsh: command not found: cmd 

## 解決

```json:launch.json
"console": "externalTerminal"
```

下記に変更


```json:launch.json
"console": "internalConsole"
```

## 注意
WSL2を使っている場合は、vscodeとWSLのコネクションを確立してから開発しないと、色々うまくいかなくなる。
42Tokyo9月Piscine

学生エンジニア団体[Volare](https://volare.site/)アドベントカレンダー11日目を担当します.
2021年度9月Piscineを受けたので、その感想について書いてみます.
運営側から叱られるので具体的な内容は話せないのですが, Piscine参加予定の方への参考になればと思います...！

#42Tokyoとは
フランス発のエンジニア養成機関公式サイト: https://42tokyo.jp/

・学費完全無料
・P2Pコードレビュー (学生同士で教え合いながら進める)
・経歴 / 学歴不問


#Piscineとは
４週間続く42Tokyoの入学試験
私は大学の長期休みを利用し, 4週間のPiscineを受験しました.

#事前準備

42Tokyo入学試験は二段階
1. webテスト (42Tokyoのサイトを通じていつでも受験可能)
2. Piscine (Piscineの日程選択可能)

#Piscine受験時のレベル
42Tokyoの二次選考でもあるPiscineは**C言語縛り**
C言語に関しては、入門書を一通り学んだくらいで初級者レベルでした.

#始まってから

覚悟はしていたのですが, 想像以上にしんどかったです.

初めの三日間を乗り越えたら楽になるという運営からの言葉を信じて, 朝から晩まで課題に取り組み続けました.
(5日目頃から自分のペースも掴めてきてPisciner生活に慣れました！)

自分のペースを掴めるまで, "集団についていかないと取り残される"という気持ちからPiscineに10時間以上はコミットしていたと思います.

#どう変わったか
shellについて理解を深められ, Cやアルゴリズムに対する苦手意識が減りました！

Piscine後も9月Piscinerと繋がりがあって, 競プロに挑戦している人や未経験の方がbotを制作されていたり.....
積極的に実践学習を重ねる9月Piscinerと出会えたすごく良い機会でした！

#結果
合格基準は不明確なままなのですが, なんとかPiscine通過していました〜！

とりあえず受けてみただけでPiscine後のことは何も考えていなかったのですが,
運営側から「**面白そうな課題を解いていたら, 知らない間に就職してた世界線を今後実装していきます**」という42Tokyo新カリキュラム[Road to](https://42tokyo.jp/news/2021-11-17-2t1ad2mf7/)の発表があり、2022年度7月から本科生になることに決めました！

#感想
Piscine参加の際には, 1ヶ月全て捧げる覚悟とコミュニケーションスキルが必須だと見受けられました. 
少しでもPiscineへの参加を考えている方は, [42Tokyowebテスト](https://42tokyo.jp/requirements/)に挑戦してみてはいかがでしょうか！
rails二重投稿防止の注意点

## 事象

* railsではformで送信時にvalidateなどのメッセージを出せるが、
* そのvalidateメッセージ表示周りがdivで囲まれ
* レイアウトが崩れる場合がある

## 対策
* もしview周りはデザイナーが担当しており
* cssの指定が `.class > p + span` などのように **子、隣接結合子**などを使って書かれている場合
* デザイナーに**BEM記法**などで書き直してもらう必要がある



## よくあるその場しのぎ

* レイアウトが崩れるので、validate周りをdivで囲まないようにする為、configに以下を書いている場合

```ruby
# 二重送信対策解除
config.action_view.automatically_disable_submit_tag = false
```

* もちろんこれだと二重送信防止が解除される為解決にならない

* [二重送信防止方法はこちら](https://rails.densan-labs.net/form/double_submit_protection.html)


----------

## 結論
* デザイナーに書き直してもらう
* or 自分で書く
* html, css記法は認識を共通しておく事
PHPで.envを読む方法（失敗談含む）

# PHPで.envを読む方法

土日に暇だったので、素のPHPの学習をしていました。
普段は、Laravelというとても便利なフレームワークを使っていたので、
基礎的な部分が欠けていると思ったからです。

今回はPHPで.envを読み込むことにつまづいたので、記事にしようかなと思いました。

前提条件: 
PC: MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports) インテルチップ
MacOS: BigSur v11.6
php: v8.0.12
composer: v2.1.9
vlucas/phpdotenv: v^5.4
エディタ：VScode

任意のディレクトリにindex.phpと.envを作成
ブラウザに「password」と表示されたら成功ということで、、、やっていきます。

index.php

```
<?php

var_dump();
```

.env

```
PASS=password
```

## 手順
### 1. Composerを使用して「vlucas/phpdotenv」インストール
phpで.envを読み込むためのライブラリです。
Composerでインストールすると楽です。
公式のGithub: https://github.com/vlucas/phpdotenv

``` ターミナル
composer require vlucas/phpdotenv
```

ルートディレクトリに、下記ができます。
- vendor
- composer.json
- composer.lock

### 2. index.phpに追記

```index.php
<?php
require './vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
```
**vendorファイルを読み込む**
require './vendor/autoload.php';

**dotenvを使用する**
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();


### 3. var_dumpの中に$_ENV['PASS']を入れる

```index.php
<?php
require './vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

var_dump($_ENV['PASS']);
```

### ブラウザを確認

passwordが表示されてる🎉
オールクリア。

```
/Users/sakatsumemasato/create/php-learning/index.php:7:string 'password' (length=8)
```

## つまずいた点

### Dotenv\Dotenvに警告が出てて気になった。

vscodeの拡張機能：「PHP Intelephense」が警告を出しているだけで、一応動きます。
![スクリーンショット 2021-12-05 11.23.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965248/602568cb-6404-a21e-7712-89acfc446a1d.png)

### $_ENVの書き方を間違える

あれれー、動かないな〜。

```index.php
var_dump($_ENV('PASS'))
```

10分後。。。　配列かい。

```index.php
var_dump($_ENV['PASS'])
```
警告ちゃんと読んでればわかりましたね。はい。

```
Fatal error: Uncaught Error: Array callback must have exactly two elements in /Users/sakatsumemasato/create/php-learning/index.php on line 7
```

### ちなみに

envの値はどうあがいても動くので、envの値が読み込めない場合は、「.env」の影響であることは少ないです。

動く。

```
"PASS"="password"
```

動く。

```
PASS="password"
```

動く。

```
"PASS"=password
```

動く。

```
'PASS'='password'
```

動く。

```
'PASS'=password
```

動く。

```
PASS='password'
```

動く。

```
PASS=password
```

動く。

```
PASS　= password
```

### 最後に

エラーはちゃんと読みましょう。
現場からは以上です。
「教科書では教えてくれないHTML&CSS」読書録

HTMLやCSSを学んで理解は出来たが、どう書けば良いかが分からなかったので参考になりました。
忘れないように気になった部分の要約を残しておきます。

##デザインを分割し、小さなパーツに分解する
デザイン画像を元に大まかに次の2点で分割する。


+ 横幅が変わるところ
+ 背景の塗りつぶし方法が変わるところ

その際、分割したパーツごとのHTML構造は二重構造にする。

```
<div class="分割したパーツ名">
    <div class="〇〇-container">
        
    </div>
</div>
```
###二重構造となったパーツに対して適用するスタイル
`<div class="〇〇-container">`に適用するスタイル

+ パーツの幅
+ パーツをビューポートの中央に配置するスタイル
+ 上下左右の空きスペースを調整するスタイル

`<div class="分割したパーツ名">`に適用するスタイル

+ 背景色や背景画像


###分割されたパーツを内容やレイアウトに合わせて更に分割する
更に単純なパーツごとに分けて、HTMLとCSSを書いていく。
そうすることで大きな問題を小さくて手のつけやすい目標に変えてしまう。
また、これにより各部分がモジュール化され使い回しがしやすくなる。


##更新しやすいCSSの書き方


###優先度を低く保つ

子孫セレクタなどで複数のセレクタを一度に使う際には、
数が多いほど優先度が高くなってしまう為、
子孫セレクタを使うときは使うセレクタの数を最小限に抑え、優先度を低く保つ。

**例**

```
<div class="block">
    <ul class="list">
        <li class="item">...</li>
    </ul>
</div>
```

上記の`<li class="item">`にスタイルを適用したい場合のセレクタは次のリストのようになるが、
リストの上に行くほど良い書き方になる。

+ `.item { }`              ◯
+ `.list .item { }`        △
+ `.block .list .item { }` ☓

###スタイルの位置を意識する

あとから読み込まれたスタイルのほうが優先度が高くなるので、
より多くの要素に適用されるスタイルを上の方に、特定の要素だけに適用されるスタイルを下の方に書く。

<details>
<summary>**セレクタの優先順位**</summary>
<div>

1.HTMLタグのstyle属性

2.idセレクタ

3.classセレクタなど（2と4を除く多くのセレクタ）

4.タイプセレクタと疑似要素

5.全称セレクタ (*)

</div>
</details>

##レスポンシブデザインのための心得

+ ブロックボックスにむやみに幅を指定しない。
 + 端末の画面サイズはまちまちなので、ブロックボックスの親要素の幅いっぱいに広がる特性を利用する。

+ 画面サイズに合わせてレイアウトを切り替える必要があるときだけ、メディアクエリを使う。


##フレックスボックスとグリッドレイアウトの使い分け

+ ボックスを横一列に並べるときはフレックスボックス、複数行に並べたいときはグリッドレイアウト。

+ ボックスのサイズをガッチリ決めたいならグリッドレイアウト、サイズ自体は柔軟に対応したいならフレックスボックス。
 + フレックスボックスでは1つひとつのボックスのサイズは原則としてコンテンツの長さで決まる為、
 ボックスのサイズが変わっても良いときに有利。


##レスポンシブデザインに対応した画像のスタイル

```
img {
    max-width: 100%;            /* 親要素の幅に収まるようにする */
    vertical-align: bottom;     /* 画像の下に空くスペースを消す */
    height: auto;               /* 古いブラウザで縦横比を維持する */
}
```
##flexプロパティで使う設定は大体3パターンのみ

```
flex: 伸長比 縮小比 ベース幅;
```
+ `flex: 0 0 子要素の幅px;`
 + 親要素の幅に関わらず、子要素の幅はベース幅で固定。
+ `flex: 1 1 auto;`
 + 親要素に合わせてボックスが伸縮する。
+ `flex: 0 1 auto;`
 + デフォルト値 親要素が狭いときは子要素も縮小、親要素が広くてもベース幅を維持して伸長しない。

###ベース幅とは
親要素の幅に余裕がある時、子要素の幅は自身のコンテンツが収まる長さになる、この長さをベース幅という。
アナログとデジタル

**「アナログな人だね」**
**「アナログな方法だ」**
などなど、普段生活をしていると度々耳にする言葉で

**アナログとデジタル**

という言葉があります。

これらの言葉の意味は、意外と間違って理解されていることがあるようです。
例えば・・・

**アナログ：古い**
**デジタル：新しい**

とか、

**アナログ：実際に手をつかって何かを行うこと**
**デジタル：コンピュータを用いて何かを行うこと**

などなど、ちょっと本来の言葉の意味とは異なる解釈をしている人は少なくないかと思います。

今回はアナログ/デジタルについてのメモを残していきます。

#「アナログとデジタル」　本来の意味
結論から言ってしまうと、もともとそれぞれの言葉は以下のような意味があります。

**アナログ：連続量**
**デジタル：離散量**

ここらへんの意味が三回転くらいして、「**アナログ＝古い**」などの意味が広まったのかなと想像します。

以下図の左がアナログ（連続量）、右がデジタル（離散量）のイメージです。
![waves.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/4793b7ee-f95d-d72a-ccf7-f9af685f36a6.png)

```Matlab:MatlabやらScilabで出力できるコード
t=(0:0.01:4*%pi);

subplot(1,2,1); plot2d(t,sin(t));
xtitle("Fig.1. Analog wave");

subplot(1,2,2); plot2d(t,squarewave(t));
xtitle("Fig.2. Digital Wave");
```

##連続量
連続量（アナログ）とは、**絶え間なく連続する量**のことを指します。
(0から1に移る前に無数の少数が続くイメージです)

**現実に存在するもの**はこの連続量にあたります。
すなわち、**時間**や、**物体を構成する細胞**、**音**や**光**も全て連続した量です。

ちょっとややこしい話をすると、**細胞と細胞の間に隙間はあっても、細胞自体に隙間はない**です。
**2本の木の間に隙間はあっても、木を構成する物資自体に隙間はない**です。
これらは**前者がデジタル（離散量）**で**後者がアナログ(連続量)**ということになります

##離散量
離散量(デジタル)は、**飛び飛びの値**のことを指します。
例えば、**人数**など**整数でしか表すことができないような量は離散量**にあたります。

また、[コンピュータは二進数しか取り扱えない](https://qiita.com/tatataichi/items/20608fee92b185c65550)ということで、**離散量（1か0か）しか取り扱えない機器**であると言えます。
そのため、**コンピュータで処理する方法のことを「デジタルな方法だ」と表現される**ことが多いのだと思います。　

・・・ちょっと待てよ、**デジタルしか取り扱えないはずのコンピュータ**は、**アナログの音声も取り扱えています**よね？
実はこれ、**アナログ/ディジタル変換（ADC）**という仕組みを用いて実現しています。

ということで、そのうちADCのメモも残していこうと思います。
StackOverflowで画像を表示させる

stackoverflowでの画像の貼り方を忘れるので、メモ。

# Steps

1. 画像をドラック＆ドロップする。

2. 生成された`[enter image description here][1]`部分を下記のように書き換える。

```markdown:comment_field
[![enter image description here][1]][1]

[1]: https://i.stack.imgur.com/f7zys.png
```

# 参考
https://meta.stackoverflow.com/questions/344851/how-do-you-add-a-screenshot-image-to-your-stack-overflow-post