OmniAICreator/Qiita-1.07M huggingface dataset:
SQL command


mysql -u root　でMySQLに接続
[![Image from Gyazo](https://i.gyazo.com/a4fce567080771cc07db2a5782fca447.png)](https://gyazo.com/a4fce567080771cc07db2a5782fca447)mysql>となれば接続成功です。
-u rootというオプションで、ユーザーは「ルート」でログインするという意味になります。
ここでいうルートとは、MySQLであらかじめ用意されているユーザーのことです。
このユーザーのパスワードは空で設定されているため、ログインにパスワードは必要ありません。

mysql> SHOW DATABASES;　　　　　　　　　　　  　DB一覧表示
mysql> CREATE DATABASE 《データベース名》;　　　 DBを作成
mysql> DROP DATABASE 《データベース名》;　　　　 DBを削除
mysql> USE 《データベース名》;　　　　　　　　　　 どのDBを使用するのかを指定
mysql> SHOW TABLES;　　　　　　　　　　　　　　  テーブル一覧表示
mysql> FROM 《テーブル名》; 　　 　　　　　　　　　テーブルを指定
mysql> SHOW columns FROM 《テーブル名》;　　　　カラムの構造表示
mysql> ALTER TABLE 《テーブル名》;　　　　　　　　テーブル編集

mysql> ALTER TABLE テーブル名 ADD カラム名 カラムの型;　　
→カラム追加

mysql> ALTER TABLE テーブル名 CHANGE 古いカラム名 新しいカラム名 新しいカラムの型;
→カラムの変更

mysql> ALTER TABLE テーブル名 DROP カラム名;
→カラムの削除

mysql> INSERT INTO 《テーブル名》 VALUES(値1, 値2, 値3);
→全てのカラムに値を入れる

mysql> INSERT INTO テーブル名(カラム名1, カラム名2) VALUES(値1, 値2);
→特定のカラムに値を入れる

mysql> UPDATE 《テーブル名》 SET 《変更内容》 WHERE 《条件》;
→データの更新

mysql> DELETE FROM 《テーブル名》 WHERE 《条件》;
→データの削除
XFREEの「MYSQL/PHP」プランでWordPressインストールしようとしたら、つまづいた

##作業中にハマったところの備忘録

####1.WordPressのインストールスクリプト(wp-admin\install.php)が実行できない
サーバーにWordpressフォルダアップロード後、
インストールスクリプト(wp-admin\install.php)を実行しようとしたができない。
WordPress公式には
**アップしたディレクトリ\wp-admin\install.php**
にアクセスと書かれているが、以下のように表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569318/b5b2ca15-d48a-223d-fe12-a78e03cc1a8e.png)
原因としては、下記のいずれかが考えられる
1.データベースが存在していない
2.ユーザーにアクセス権がない
3.config.phpのデータベース名が間違っている

結論からいうと今回は下記が原因だった。
**2.ユーザーにアクセス権がない**


対応方法としては、
コンパネの「MySQL設定」から
「MySQL一覧」タブの「追加可能ユーザー」欄の追加ボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569318/12549297-4b07-29a0-31f1-3739bc5577ed.png)
再度「アップしたディレクトリ\wp-admin\install.php」へアクセスすると、無事に設定画面がされた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569318/06d7cadb-1843-3068-3dad-90a69a06b297.png)
####2.トップページを開こうとしたら「このWEBスペースへは、まだホームページがアップロードされていません。」と表示される
無事WordPressインストールが完了し、トップページを見ようとしたら表題のメッセージが表示される。
考えられる要因は下記参照
https://support.xserver.ne.jp/faq/service_hp_trouble_not_update.php

今回の原因は、
**WordPressフォルダをアップロードするディレクトリを間違えていた。**
正しいディレクトリは
　**ルートディレクトリ\public_html**(公開用パス)
だったが、直接ルートディレクトリにアップしていた。

対応方法：
1.間違えてアップしたファイルやフォルダをすべて削除し、public_html直下に再アップ※1
2.XFREEのコンパネでデータベースを削除し、同名のデータベースを再作成。
3.もう一度　**ルートディレクトリ\public_html\wp-admin\install.php**　にアクセスしメールアドレスなど設定。
※1 ファイル等は削除せず移動すればよかったかもしれないが、ファイルにパスが設定されていると面倒と思ったため。

再度ログインし無事トップページが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569318/bdbc1172-0ebc-f57e-5473-c8cfba70fcbc.png)
【HiRDB】unload/pdloadを使ってテーブルをバックアップ・リストアする

# はじめに
現場でHiRDBを使用していて、バックアップ・リストアをする時に詰まったので備忘録。

# 実施環境
・HiRDBの編成が、パラレルサーバーではなく、シングルサーバーであること。

# 使用するコマンドと準備
### ・バックアップ
`pdrorg`コマンドを使用する。
`-k unld`は、unloadを実行するということ。
`-W extdat`を指定することで、データ内に改行が入っていても後でリストアすることができる。
`-g`はバックアップするためのアンロードファイルを作成するため、指定しておく。

```backup
pdrorg -k unld -g -W extdat -t [テーブル名] [unload用のコントロールファイルパス]
```

コントロールファイルには、以下を記載する。（`unload`以下のパスは任意）

```コントロールファイル（例）
unload C:\unload\unload_data.dat
```
　
### ・リストア
`pdload`コマンドを使用する。
`-d`は、作成モードを有効にする。これが有効だと、リストアをかける前に、一旦対象のテーブルの中身が全て削除される。
`-i c`は、インデックス情報を後で一括で作成するということ。
`-e`は、途中でエラーが起こったら、中断するように指定している。

```restore
pdload -d -i c -e [テーブル名] [pdload用のコントロールファイルパス]
```

pdload用のコントロールファイルには、以下を記載する。
`extdat enclose="`を入れておかないと、データファイル内に改行が入っていると、リストア時にコケる。

```
source [unloadで出力されたデータファイルのパス]
extdat enclose="
```

# 補足
ユーザー名やパスワード、ホスト名やポート番号などは、コマンド実行前に環境変数で定義しています。[[参考]](http://itdoc.hitachi.co.jp/manuals/3000/3000625410/W0540037.HTM)

本記事で紹介しているオプションは、各々の使用目的に沿ったものに変更してください。
・[pdrorg](http://itdoc.hitachi.co.jp/manuals/3020/3020635543/W3550305.HTM#ID01067)
・[pdload](http://itdoc.hitachi.co.jp/manuals/3000/3000635543/U3550184.HTM#ID00367)
カスタム要素を使った、タブフォーカスの抑止

# はじめに
ダイアログを表示した場合、タブで後ろのコンテンツにフォーカスが行かないようにしたいなど、
タブによるフォーカスの遷移を抑止したい場合がかなりあると思います。
そんなときに役に立つ小技を見つけたので共有します。

# 環境
- Chrome, Firefoxで確認

# やり方
## CustomElementを用意
shadow domの中に子要素を表示するだけのカスタム要素を用意します。

```js
customElements.define(
    "custom-element", 
    class CustomElement extends HTMLElement {
        constructor(){
            super()
            this.attachShadow({mode: "open"})
            this.shadowRoot.appendChild(document.createElement("slot"))
        }
    }
)
```

## 使う
```html
<div>
    <h3>親のカスタム要素にtabindex="-1"</h3>
    <custom-element tabindex="-1">
        <input type="text">
        <input type="text">
        <input type="text">
    </custom-element>
</div>
<div>
    <h3>親の要素にtabindex="-1"</h3>
    <div tabindex="-1">
        <input type="text">
        <input type="text">
        <input type="text">
    </div>
</div>
```
![tabindex.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200296/ec7636c0-3a70-bf97-08bb-b5b5955f6c97.gif)

カスタム要素にtabindex="-1"を指定するだけでその子要素にフォーカスが行かなくなります。
[たぶん仕様です。たぶん](https://github.com/WICG/webcomponents/issues/399)

※もっとスマートな方法があったら教えてくださいmm

以上
MAX30102のデータシート読んでみた-2

# System Diagram
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/6709b2fd-4fb8-315e-51e2-3a2d9b985a09.png)


# 機能図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/6706db44-cf0c-d933-2d13-8054eab4cf65.png)

# Electrical Characteristics

- 電圧は1.8Vなので、注意必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/13493e4e-3992-1c8a-c3e0-a28a075b185f.png)

- Supply Currentは600㎂です。


# ADC
- ADCの解像度は18Bitです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/9ae51029-ddc5-b620-142b-676a2b7c5b96.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/deba61a9-e512-655e-1a75-3800416cde6e.png)


# I2C
- I2C 通信しようとするとアドレス大事ですよね。
- 簡単にみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/1aa58ef0-3469-e57c-d156-8632ed7d0365.png)


# Pin Configuration ピン配置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/a62a2c4c-9ed6-8e39-594d-be13913a7e99.png)

- SDAとINTpinはオープンドレインです。
- LEDの電圧とセンサーの電圧は違いますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/5407c0f3-73ef-73d8-37a3-53b7c3f23144.png)
Linux の Unity Hub データ保存先まとめ & しばらく使わなくなる Unity をファイル削減

# この記事について

この記事では、Linux の Unity Hub を利用した際の、設定データ等が保存される場所を記したものです。
ここに記してあるものが全てという保証はできませんが、自分の環境でコマンドで検索した結果を基に書きました。
Windows、Mac でのデータ保存先については取り扱っておりません。

# 記事作りのきっかけ

訳あって、Unity を使うことになった自分。
重たいイメージがあってあまり使いたくなかったが、Unity 以外に 3D アプリの開発技術は持っていなかったので、大人しく Unity を使うことに。

しばらくして、無事 Unity でやるべきことは済ませた。
さて、当面 Unity を使うことは無いだろうから、プロジェクトファイル以外は PC から片してしまおう。
して、設定データとか Asset Store からダウンロードした Asset の保存先は何処？

まぁ検索すればすぐに･･･Linux の情報が無い。どうして･･･。
Windows や Mac での保存先の情報は見つかったが、どうして Linux は無いの･･･。

という訳で、この記事を作成することに決めました。
(調べ方が悪かっただけかもしれませんが･･･。)

# 調査方法

まずは調べた環境を。

* OS: Linux Mint 20.1 Ulyssa 64bit
* Unity Hub: 2.4.2
* (一応書いておくと、) Unity (Editor): 2020.1.1f1

自分は以下のようなコマンドで検索しました。

```sh
find /* 2>/dev/null | grep -i "unity"
```

システム上の全てのファイルを表示し、そのうちパスに (大文字小文字区別せず) unity と名のついているものを表示するというものです。
システム含め全ファイルの検索をすると「権限が無い」というエラーメッセージが出ますので、エラー出力は破棄しています。

ちなみに、Ubuntu 系だと Unity デスクトップ環境のファイルも引っかかることがあります。
そんなときは、

```sh
find /* 2>/dev/null | grep -i -v "ubuntu" | grep -i -v "mint" | grep -i "unity"
```

といった具合に、ディストリビューション名を検索から除外してやると良い感じになると思います。
(自分のディストリビューションは LinuxMint なので "mint" を除外。)

# 本題

自分の環境で調べた結果、以下の場所に Unity のデータが存在することが分かりました。

```
/home/<user>/.config/unity3d/
/home/<user>/.config/Unity Hub/
/home/<user>/.config/UnityHub/
/home/<user>/.local/share/unity3d/
```

これに加えて Unity エディター。
場所は初回起動時に設定したものですね。
Unity Hub を起動しなくなるなら、エディターも事前にアンインストールしておきましょう。
(当然と言えば当然ですが、エディターがファイルとしては最も重いです。10GB とかサイズがあります。)

Linux 版の Unity Hub は、実行ファイル 1つがシンプルに配布されているだけで、apt とか yum で入れる感じではありませんね。
道中、root 権限が求められたことも無かったハズなので、ホームディレクトリ外にファイルが保管されるということは無さそうです。

まずは` /home/<user>/.config/unity3d/ `についてです。
中身の大半はキャッシュが占めているようです。
自分の環境では 1.2GB 近くディスクを消費していたようです。

次に` /home/<user>/.config/Unity Hub/ `,` /home/<user>/.config/UnityHub/ `についてです。
これを消して Unity Hub を起動した所、利用規約が表示され、初回起動と同じ動作になりました。
どうやらログイン情報等はここに保管されているようです。
自分の環境では 5.5MB 程度と、そこまでディスク圧迫にはなっていませんでした。
「再度 Unity Hub を起動することがあるかも」というようであれば、残しておいても問題にはならなさそうです。

最後に` /home/<user>/.local/share/unity3d/ `についてです。
見てみると、ここには Asset Store からダウンロードした Asset (.unitypackage) が入っていました。
しっかり圧縮されて保管されているファイルとはいえ、数があればトータルで数 GB に及びます。

# おまけ - プロジェクトファイルから余分なファイルを削減

Unity を PC から片しておくということであれば、プロジェクトファイルも開かないことになるでしょう。
特に支障が無いようなら、import した Asset も除いておきましょう。
解凍した状態の Asset データは、物によっては結構なサイズになりますからね･･･。

ちなみに、自分はプロジェクトを Git で管理していたので、ローカルリポジトリを抹消した後に再 clone という、野蛮な方法でファイル削減しました。
(もちろん、push されていない commit が無いか等を確認してから。)

それから、Unity を Git で管理する際の` .gitignore `のテンプレが、探せば色々と出てきます。
消してしまっても良いファイルを、それを見て判断するというのも手ですね。

# おしまいに

結果的に、設定ファイル等削除で 3GB 近く、エディター (1つ) アンインストールで 10GB 近く、プロジェクトファイル (2つ) の Asset 等削除で 15GB 近く削減できました。
Unity って、ファイルサイズ多くて重いですよね。
ゲームエンジンの特性上、どうしても仕方無いこととは思いますが･･･。
チェックメモ


# マクロ作成において、バグがないかチェックすべきこと

:::note info
マクロ作成　
・インプットフォルダに指定ファイルまたはフォルダがあるか
・ファイルを開いてないか
・アウトプット先に同名のファイルがないか
・使用するファイルに必要カラムはあるか
・データ突合する場合、取ってくる値に間違いはないか（NULLがどんな理由でNULLになるのか調べる）
・紐づけ率を集計する（前回・今回　減少してないか等）


# Excel・Access・PowerQueryの違いと用途
Excel
・細かい加工

access
・データベースとして使える。データの規則性を持たせたい場合に使う（カラムに数値や日付のみ入力させたい場合などExcelより正確）

PowerQuery
・簡単な加工、データ突合

:::



```
Option Explicit




```
相対パスを絶対パスへ変換（シェルスクリプト）

こんにちは。
相対パスから絶対パスを得る簡単なシェルスクリプト関数を作りました[^1]。なお絶対パスを与えた場合には入力をそのまま返します。

[^1]: 参考：「[bash で ファイルの絶対パスを得る](https://qiita.com/katoy/items/c0d9ff8aff59efa8fcbb)」

```console
$ realpath .vimrc
/Users/user1/.vimrc
$ pwd
/Users/user1
$ realpath /temp
/temp
```

```sh
realpath() {
  case "$1" in /*) ;; *) printf '%s/' "$PWD";; esac; echo "$1"
}
```

### 他の方法 ###

他の類似の方法としては、

* ```realpath``` コマンドを使う（```coreutils``` に含まれている）。
* GNU 版 ```readlink``` コマンドを ```--canonicalize``` オプション指定で使う：

```console
$ man greadlink
       -f, --canonicalize
              canonicalize by following every symlink in  every  component  of
              the  given  name  recursively;  all  but the last component must
              exist
```
【Swift】`pod install` 時のエラー[!] Invalid `Podfile` file: syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '('.

# これはなに

`pod install`したときに出たエラー。
**Podfile**はこのように書かれていた。

```
pod 'RxSwift',
pod 'RxCocoa'
```

## カンマが要らない

マヌケなミスではあるが、改行の際にカンマは打たなくていい。

```
pod 'RxSwift'
pod 'RxCocoa'
```

バージョンを指定する際はカンマを打つ。改行時には要らないが。

```
pod 'RxSwift', '~> 4.3.1'
pod 'RxCocoa', '~> 4.3.1'
```

以上です(；´Д｀)
「あ、間違えてgitのbranch切らずに編集しちゃった〜🥺🥺🥺」の対処法

解説され尽くした方法ですが、`git stash`を使って**「本当は、新しくブランチを切って編集したかったのにブランチを切り替えずに編集してしまった時」に「現在Commitしてない変更を新しいブランチに移動させる方法」を解説します。

編集中だけど、とりあえずさっさとブランチを切り替えたいときにも使えます。

# 忙しい方むけ

```shell
$ git stash
$ git branch -b 新しいブランチ
$ git stash pop
```

もしくはもう少し丁寧に解説をつけると

```shell
$ git stash // 現在の変更差分を一時的に保存して直前のコミットに戻す。
$ git branch 新しいブランチ 
$ git checkout 新しいブランチ
$ git stash list // 
$ git stash apply // 現在のブランチに一時的に保存した
$ git stash
```

# 参考文献

[間違って別のブランチで実装を始めちゃった時にgit stashで別ブランチに編集中のソースを移動する](https://gist.github.com/koudaiii/526707492ebc5915596e)
Spotifyが公開しているAPIを使用してUK Official Chart Top 100に対応したプレイリストを作ってみた

# Spotifyが公開しているAPIを使用してUK Official Chart Top 100に対応したプレイリストを作ってみた

Sportifyとは世界中の音楽が聴き放題の神アプリです。
筆者は、通勤などの移動の際には必ずSportifyを使用して音楽を聞いています。
Sportifyのいい所は、プレイリストが豊富であり、
* Top Chartプレイリスト
* アーティスト別のプレイリスト    
* 好きなアーティストに関連する曲が含まれるプレイリスト
* 自分にオススメの曲で構成されたプレイリスト
などがあります。

また、SportifyはSHAZAMと連携することができ、SHAZAMした曲を1つのプレイリストにまとめることができます。

筆者はDJをしていますので、これらの機能があるSportifyをとても愛用しています。

こんな"最高の"Sportifyですが、一点だけ不満があります。
それは、Top Chartプレイリストの曲が日々更新されてしまうことです。
DJをしている私にとっては、どの月に何は流行っていたのかを知りたいので、1つのTop Chartプレイリストで中身の曲が変わるよりも、
1月のTop Chartプレイリスト、2月のTop Chartプレイリストなど月別で別れている方が望ましいです。

そこで、Spotifyが公開しているAPIを使用して月別のUK Official Chart Top 100プレイリストを作りました。
コードは https://github.com/RyosukeHattori/UK_Official_Singles_Chart_to_Spotify/blob/main/UK%20Official%20Singles%20Chart%20Top%20100.ipynb です。

##Jupyter notebookを動かすには

notebookの2セル目の
```
with open("your_ID.txt") as f:
    l = f.readlines()
```
のyour_ID.txtには、Spotify for Developersにて、Spotify APIを使用するために必要なclient IDとclient secret、usernameをこの順に記入します。

これでとりあえず、動きます。

14セルで出力される"This is None Track"は生成するSpotifyのプレイリストに含むことができない曲です。
ここで出力される曲と15セルで出力される行番号がUK Official Chart Top 100のランキングに対応します。
つまり、14セル目で
```
this track is None:READY/FREDO FT SUMMER WALKER
this track is None:FRIDAY/RITON/NIGHTCRAWLERS/MUFASA
this track is None:LOVE NOT WAR (THE TAMPA BEAT)/JASON DERULO & NUKA
this track is None:BE THE ONE/RUDIMENTAL/MORGAN/DIGGA D/TIKE
this track is None:FOREVER YOUNG/BECKY HILL
```
と出力され、15セル目で
```
      id track artist
20  None  None   None
23  None  None   None
31  None  None   None
57  None  None   None
84  None  None   None
```
と、出力されたとすると
それは、UK Official Chart Top 100に含まれる
* 20位のREADY/FREDO FT SUMMER WALKER
* 23位のFRIDAY/RITON/NIGHTCRAWLERS/MUFASA
* 31位のLOVE NOT WAR (THE TAMPA BEAT)/JASON DERULO & NUKA
* 57位のBE THE ONE/RUDIMENTAL/MORGAN/DIGGA D/TIKE
* 84位のFOREVER YOUNG/BECKY HILL

がプレイリストから欠損していることを意味します。
これらの欠損した曲は手動で加えてください。
また、欠損が出ないようなプログラムの書き方を教えてください！！！
三角関数を加法定理を使って計算する

（2020.2.13追記）　2020.2.10に投稿したときはプログラムに間違いがあって大嘘を書いていました。ごめんなさい。

## はじめに
任意の角度の三角関数を加法定理で１度ずつなどの刻みで計算した時の振る舞いが気になったので（※現実逃避）実際に試してみました。

復習ですが、三角関数の加法定理は下記のようになります。

```math
\sin(\alpha + \beta) = \sin(\alpha)\cos(\beta) + \cos(\alpha)\sin(\beta) \\
\cos(\alpha + \beta) = \cos(\alpha)\cos(\beta) - \sin(\alpha)\sin(\beta) \\
```

これを利用して、$\sin, \cos$のそれぞれ０°と１°の値のみを用いて任意の角度（整数）の三角関数の値を求めてみました。

## 実験
コードは[ここ(github)](https://gist.github.com/YukiSakamoto/39a259bff3f3188d887c74a7abbf4dda)におきました。


コンパイルと実行は、下記で通るはずです。

```
$ make all # コンパイル
$ make run # 実行
```

## 結果
角度の刻みを少し変えながら、0°から3600°まで試してみました。
下記のグラフはいずれも紫・緑の線がライブラリの返した値(凡例：std::sin, std::cos)、水色・オレンジの点(凡例: sin, cos)が加法定理で計算した値です。
こうしてみると、１度刻みで3600°($20\pi$)まで計算したとしても、ほぼ完全に線が重なっているように見えます。

### 1°刻みで計算
![r1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24675/75014e0d-55d1-e671-c820-cbc53915e367.png)

### 3°刻みで計算
![r3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24675/00897006-3b74-aa96-23e5-d18d01cdaae7.png)

### 10°刻みで計算
![r10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24675/b8f80187-56c5-d171-501a-96e34de5348a.png)

## ライブラリ関数との差のプロット
上記の結果について、標準ライブラリ(cmathのstd::sin())が返す値との差の絶対値をプロットしたものが下記になります。

このように拡大してみるとやはり刻み幅は広い場合($10^\circ$;水色の線)の方が、刻みが細かい場合（$1^\circ$; 紫の線）よりは差が小さいことがわかります。
同時に、この差ですが一次関数に$\sin$関数を掛けたような形($y=a\theta\sin(\theta)$; aは定数)になるようです。どうしてこのような形になるのかはよくわかりません。（標準ライブラリの三角関数の求め方に依存しているのかもしれませんが。。。）
![diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24675/a389a224-64cb-c3ee-31b7-1b70d65023e2.png)

## まとめ
とりあえずグラフを書いてみました。
数値計算の誤差の取り扱いに関する知識がないため、これ以上深い議論はできないのですが、思ったより精度があるのだな、と感じた次第です。
新人エンジニアが半年間OSSコントリビュートに挑戦した結果と感想

去年の7月くらいからOSSコントリビュートに挑戦しています。
挑戦するに至った経緯や結果などを記したいと思います。

#OSSコントリビュートとは
GitHubに公開されているOSSに対してプルリクエストやイシューを投げたり、自分でOSSを開発して公開するといった活動のことです。
私が挑戦したのは、GitHubで公開されているOSSにプルリクエストを送る活動です。

#きっかけ
きっかけとなったのは、私が働いている会社で週１回行われる新人研修でした。その時の研修はGitHub研修で[Introduction to GitHub](https://lab.github.com/githubtraining/introduction-to-github)を実践しながら、GitHubの使い方を学ぶというものでした。
入門編は基本的な操作を学ぶというものでしたが、研修を担当している社員の方が時間に余裕がある人向けに応用編を用意してくれていました。

それが、OSSにプルリクエストを送ってみようという内容だったわけです。

プルリクの内容は、YoutubeのURL修正でした。
<a target="blank"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379397/4f429397-2738-3f7f-4c51-8a52fdb5f732.png" width=80%></a>

「え、OSSのコントリビュートってこんな簡単なの！？」と思いましたが、プルリクを送ったあとで、YoutubeのURLを直してしまうと見れなくなることがわかったので、自分でCloseしましたw

今思えば、自分でCloseはしたものの、手軽にプルリクエストを送れたことが大きなきっかけになったと思います。

#マージされるまで挑戦
悔しかったので、過去に自分が使ったことがあるOSSを探しました。
そのときは、1.0がリリースされたばかりの[Nim](https://github.com/nim-lang/Nim)のREADMEを読みました。

読んでいくとある単語のスペルが気になり、調べてみるとその単語だけイギリス英語のスペルになっていることがわかりました。
意味はわかるし、修正はその単語1つだけだったので、プルリクエストを送るか少し悩みましたが、思い切ってプルリクを送信しました。

すると、、

1-2時間後にマージされてました！！

<a target="blank" href="https://github.com/nim-lang/Nim/pull/14953"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379397/a8b9e429-bc2c-7fb0-b356-e6d95c0dc18f.png" width=80%></a>
※そのときのプルリクエスト

##プルリクエストを送ったOSS
マージされたのがとても嬉しかったのと楽しくなってきたので、他に修正できそうなOSSを探しては次々にプルリクエストを送りつけました。

この6ヶ月でプルリクエストを送ってマージされたGitHubのリポジトリです。

- [nuxt/nuxtjs.org](https://github.com/nuxt/nuxtjs.org)
- [kubernetes/kube-state-metrics](https://github.com/kubernetes/kube-state-metrics)
- [matplotlib/matplotlib](https://github.com/matplotlib/matplotlib)
- [javascript-tutorial/ja.javascript.info](https://github.com/javascript-tutorial/ja.javascript.info)

マージされなかったのも含めると20件くらいプルリクエストを送ったと思います。

#挑戦してよかったこと
###こんな自分でもOSSに貢献できることがわかったこと
1年前の私は、優秀なエンジニアでないとOSSコントリビュートなんてできないと思っていました。
そんな私が社内研修や他の人のプルリクエストの内容を見る中で、ドキュメント修正という形でもOSSに貢献できたことが自分にとって大きな発見だったと思います。

###ドキュメントを読む中でOSSの理解や英語の勉強になった
私は仕事で触れたor最近気になったOSSを中心にコントリビュートしているのですが、自然とドキュメントを理解しようと精読するようになりました。
こだわりとしては、英語は苦手ではないので、なるべくGoogle翻訳を使わずに理解しようとしています。
取り組んでいく中で段々とOSSのハードルが下がっていったと実感しています。

#今後挑戦したいこと
ズバリ、、

**バグ修正のプルリクエストを送ってマージされる**
です。

今までのプルリクエストの内容は、typoや文法の修正といったドキュメント修正がほとんどです。
OSSを使っていく中で発見したバグやIssueにあるバグを修正するプルリクエストを送って、コントリビュートしたいと思います。

#最後に
**OSSは怖くない！**
Railsアプリで削除機能を実装する

#削除機能の概要
一覧画面の任意の投稿の「削除」ボタンをクリックすれば、確認ダイアログが出て、OKを押すとその投稿が削除され、一覧画面に遷移するようにします。また、詳細画面にもボタンを配置します。
##削除機能ボタンの追加
一覧画面に削除ボタン（リンク）を追加します。

```ruby:app/views/posts/index.html.slim
  tbody
    - @posts.each do |post|
      tr
        td= link_to post.content, post
        td= post.created_at
        td
          = link_to '編集', edit_post_path(post), class: 'btn btn-primary mr-3'
          = link_to '削除', post, method: :delete, data: {confirm: "投稿を削除します。よろしいですか？"},
          class: 'btn btn-danger'
```
![103AC6EB-FA1C-489E-ACE6-E67AF67ED343_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999125/f3f9fcb6-9eb8-7f33-6507-846d9a6e0d88.jpeg)

削除アクションへのリンクはmethod: :deleteという指定により、DELETEメソッドでリクエストされます。指定し忘れると、詳細リンクと同様に、詳細画面へ遷移してしまいます。

link_toのdataオプションに"confirm:メッセージ"を渡すと、リンクをクリックした際に確認ダイアログを出し、OKが押された時のみリンク先のURLへのリクエストを行ってくれるようになります。

続いて、詳細画面にも削除ボタンを追加します。

```ruby:app/views/posts/show.html.slim
    tr
      th= Post.human_attribute_name(:updated_at)
      td= @post.updated_at

= link_to '編集', edit_post_path, class: 'btn btn-primary mr-3'
= link_to '削除', @post, method: :delete, data: {confirm: "投稿を削除します。よろしいですか？"},
class: 'btn btn-danger'
```
![A0A352A5-771A-4AF7-B5FD-761E9532F502_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999125/f814ef11-5369-d23a-5bd4-e01f53d469d3.jpeg)

##削除アクションの実装
app/controllers/posts_controller.rbにdestroyアクションを追加します。

```app/controllers/posts_controller.rb
  def destroy
    post = Post.find(params[:id])
    post.destroy
    redirect_to posts_url, notice: "投稿を削除しました。"
  end
```

destroyアクションでは、パラメータ経由で対象投稿のIDを受け取り、PostオブジェクトをDBから取得します。その上で、destroyメソッドによって対応する投稿レコードをDBから削除し、削除した旨を伝えるFlashメッセージとともに一覧画面へ遷移させます。

では動作確認をしてみます。一覧の削除ボタンを押して、確認ダイアログのOKボタンを押すと…
![1D2E4E80-2F05-47EB-B891-01A3CE48C4FF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999125/941fe7c4-847a-130d-f906-413423db53ca.png)
![3FAB3E34-29A0-480A-B86D-8298FFB8C95C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999125/93858282-de63-0f2a-9d87-afefbb78a552.png)

無事、削除できました！

#CRUD機能を持ったアプリの完成
以上で、基本的なCRUD機能を持つ投稿アプリを作成することができました。
次回からは、もっと使いやすいよう細部を改良していきます。

#参考
[現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/gp/product/B07JHQ9B5T/ref=ppx_yo_dt_b_d_asin_title_o03?ie=UTF8&psc=1)
【Docker】Dockerでコンパイルが失敗するときの対処法。存在しないファイルをコンパイルしようとする場合。

個人用メモです。

Dockerが存在しないファイルをコンパイルしようとして、見つからないというコンパイルエラーを吐くときの対処法。

```
app       | WARNING in ./Internal_Article/index.js
app       | Module build failed: Error: ENOENT: no such file or directory, open './Internal_Article/index.js'

app       | Error: ENOENT: no such file or directory, open './InternalArticle/InternalArticle.vue'
app       | ℹ ｢wdm｣: Failed to compile.
```

コンパイル対象のファイルが見つからないというエラー。


##要因１
ファイル名が間違っている。

#####対処法＞　ファイル名を見直す。


##要因２
**削除したファイル（やディレクトリ）の情報がDockerに反映されていない**、または**dockerがキャッシュを使っていて、古い情報に基づいてコンパイルしようとしている**。

#####対処法＞　Dockerを再起動する


<br>
####要因2の補足 
今回の原因は要因2のパターンだった。**本来、dockerコンテナはコンテナのボリュームとマウントしているので、ファイルは同期している**。

なので、ローカルでファイルを削除すれば、docker側も削除されるはずだが、その同期がうまく行っていない。


考えられる要因としては、Dockerの機能で**ベータ版機能がデフォルトでONになっている**が、これによって同期がうまくいかないことが発生する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/b520021d-7d21-c5fc-73aa-42a4d746bce8.png)

現在は、(1)Enable cloud experience　と (2) Use gRPC FUSE for file sharingの２つがONになっている。

これを**OFFにすれば予期せぬエラーが発生するリスクが減る**。
Rails | 動的ディスパッチを使って検索ロジックを一行にしてみる試み

良いこと思いつたと思って、一回これをやって先輩に怒られたので真似しない方がいいです。
ただ自分的に結構おもしろいなあと思ったのでメモ。

## 概要
[株式会社万葉の新入社員教育用カリキュラム](https://github.com/everyleaf/el-training)のタスク管理アプリを使います。
既に@yokku21 さんが終わらせたものをフォークしてきました（どうもありがとうございました）。

タスク一覧画面では、タスクをタスク名、ステータス、優先度、ラベルで絞り込むことができ、さらにそれらを並び替えることができます。
今回、ここを一行にしてみたいと思います。

## プルリク
https://github.com/yoyoyoheyheyhey/task_app/pull/1

## ビフォーアフター
### ビフォー(イメージ)
```ruby
# app/controllers/tasks_controller.rb

def index
  @tasks = current_user.tasks.with_title(params[:title]).
                              with_status(params[:status]).
                              with_priority(params[:priority]).
                              with_label_ids(params[:label_ids]).
                              sorted_by(params[:sort_option])
end
```
既にイイ感じに@yokku21さんが仕上げてくれています、、、！

- 補足：
  - これらのスコープの命名規則は[こちら](http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html)に従っています。
  - スコープをチェーンできるようにblankが来た時はnextを返す処理にしています。

### アフター
```ruby
# app/controllers/tasks_controller.rb

def index
  @tasks = current_user.tasks.filtered_by(filter_params)
end
```
一行！！ナニコレめっちゃスリム！


## 解説
### 1). 検索用フォームのname属性はスコープの名前にしとく
```erb
<!-- 例：　app/views/tasks/index.html.erb -->

<%= f.text_field(:with_title, ...) %>
<%= f.select(:with_status, ...) %>
<%= f.select(:with_priority, ...) %>
<%= f.select(:with_priority, ...) %>
<%= f.collection_check_boxes(:with_label_ids, ...) %>
```

### 2). コントローラにて検索で使うparamsだけを取得できるようにしとく
```ruby
# 例：　app/controllers/tasks_constolle.rb

private

def filter_params
  params.permit(
    :with_title,
    :with_status,
    :with_priority,
    :sorted_by,
    with_label_ids: [],
  ).delete_if{|key, value| value.blank? }.to_h
end
```

### 3). スコープの親分を作る
```ruby
# 例：　app/models/task.rb

scope :filtered_by, -> (filter_params) do
  filter_params.inject(self) do |task, param|
    task.send(param[0], param[1])
  end
end
```

たたみこみ演算と初期値をselfとすることで、チェーンしながらスコープを呼んでいきます。

### 4). 完成
```ruby
# app/controllers/tasks_controller.rb

def index
  @tasks = current_user.tasks.filtered_by(filter_params)
end
```
Gitコマンド簡易練習用メモ

備忘録です。

# 準備

###必要に応じて、Githubで練習用リポジトリを作成

![スクリーンショット 2021-02-02 15.41.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/770386/0a504e7a-4dd8-e235-f9c2-93357344fa8b.png)


### SSH公開鍵作成

```
% cd ~/.ssh
% ssh-keygen
```

### 読み取り属性付与

```
% pwd
Users/ユーザー名/.ssh

% chmod 600 id_rsa
```

### Github Settings -> SSH and GPG keys -> New SSH key

```
title:
任意の名前

key: 次の中身を貼付、保存
```
```
% pwd
Users/ユーザー名/.ssh

% open id_rsa.pub
-> 中身表示
```

### SSH接続の確認

```
% ssh -T git@github.com
Hi User! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

% ssh github
Hi User! You've successfully authenticated, but GitHub does not provide shell access.
```

### SSHフォルダのconfig作成

```
% pwd
Users/ユーザー名/.ssh

% vim ~/.ssh/config
```

-> 以下貼付、保存

```
Host github
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa
```

GithubからのSSH鍵でクローン作成

```
git clone git@github.com:Githubユーザー名/リポジトリ名.git
```

# Gitコマンド

#####Github(リモート)から情報を取得・反映

```
% git clone [keyやURL]
# 新規にローカル側にコピーを作成する
```

```
% git pull origin
# ローカル（既存の古い情報）をリモート（最新の情報）と同期する
```

#####ステージング から プッシュまで

```
% git status
# 現在のgit状態を確認する
```

```
% git add [ファイル名]
# ステージングさせる
```

```
% git add .
# 全てのファイルをステージングさせる
```

```
% git commit -m "[コミットメッセージを入力]"
# ステージングさせたファイルを、コミットメッセージをつけて保存する
```

```
% git log
# コミットしたログを確認する
```

```
% git push
# リモートにプッシュする
```

##### ブランチ関係

```
% git push origin [ブランチ名]
# リモートの"ブランチ名"というブランチにプッシュする
```

```
% git branch
# ブランチの一覧を確認する
```

```
% git checkout -b [ブランチ名]
# 現在のブランチから"ブランチ名"というブランチを切る
```

```
% git checkout [ブランチ名]
# 存在する他のブランチに切り替える
```

##### マスターにマージ

```
% git checkout [master]
# マスターに切り替える

% git branch
# 現在のブランチがmasterにいることを確認する

% git merge [masterにマージしたいブランチ名]
# masterにブランチをマージする
```

--------

##### 共同開発の場合

```
% git fetch origin
# リモートの最新情報を取り入れる
```

```
% git branch -a
# リモートのブランチも含めてブランチの一覧を確認する
```

```
% git branch origin/[ブランチ名]
# リモートのブランチを、ローカルの同名ブランチにマージする
```

##### 取消・元に戻す

```
% git reset HEAD [ファイル名]
# ステージングから取り消す
```


# 参考記事・サイト

はてなブログ
https://daitaisonnamon.hatenablog.jp/entry/2019/10/31/235057
https://daitaisonnamon.hatenablog.jp/entry/2019/10/31/235323

Qiita
https://qiita.com/Toshimatu/items/9f7f2fd30fe456bd64b6
https://qiita.com/Mitsunori_Tsukada/items/6886f1f28d9485484822
https://qiita.com/nabezokodaikon/items/7ee4900d28d8d863978e

Youtube
https://www.youtube.com/watch?v=LDOR5HfI_sQ

Stack Overflow
https://stackoverflow.com/questions/48328446/id-rsa-pub-file-ssh-error-invalid-format
(Swift)ProtocolBuffersのレスポンスをJSONでコンソールに表示する

取り急ぎコンソールにprintしたい時のための。

## Dataのextensionを定義

```.swift:Data
// MARK: - Data
private extension Data {
    
    // DummyやStub用のJSONファイル作成に使用する
    var prettyJson: String? {
        guard let object = try? JSONSerialization.jsonObject(with: self, options: []),
              let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]),
              let prettyPrintedString = String(data: data, encoding:.utf8) else {
            return nil
        }

        return prettyPrintedString
    }
}
```

## API通信箇所で呼び出す関数を定義
```.swift:API
// MARK: - Private
extension APIDataStoreImpl {
    
    /// JSONを整えてコンソールに表示する
    private func printPrettyJson(_ result: Proto_Response) {
        if let object = try? result.jsonUTF8Data() {
            print("jsonString:\n\(object.prettyJson ?? "nil")")
        }
    }
}
```

## 呼び出し
通信成功時にresponseを渡すだけで、
結果がいい感じに改行された状態で表示されます
SQLにおけるコーテーションの使い分けとそのエスケープ処理

## 基本
`'SQL文'`, `"SQL文"`。
`'(シングルコーテーション)`と`"(ダブルコーテーション)`のどっちでもSQL文を囲って使える。

ただ…

**データベースによって使い分けが必要なこともある。**

使い分けの区別としては2つ。

- **MySQL**
- **MySQL以外**

それぞれの使い分けは[えっ、まだPostgreSQLでダブルクォーテーション使ってるの？](https://qiita.com/Sirloin/items/b14ab34415a1ebd8a9c5)を参考に。
上記の記事を表にさせてもらうとこんな風になる。

|   | MySQL以外(PostgreSQLなど) | MySQL |
|:-:|:-:|:-:|
| '(シングルコーテーション)  | 文字列  |  文字列 |
| **"(ダブルコーテーション)**  |  **カラム名** |  **文字列** |
| `(バッククォート)  |  特に使わない |  カラム名 |

一番覚えておきたいのは`"(ダブルコーテーション) `の使い分けだろう。
自分が現在触っているDBがどっちなのかを踏まえて、SQL文を囲み方も切り替えていきたい。

## エスケープ処理
MySQL以外(PostgreSQLなど)で`"(ダブルコーテーション)`で囲んだSQL文を作成したいとき、カラム名指定のために`"(ダブルコーテーション)`を使うとSQL文を途切れさせてしまう。
そのような場合、次のように解消できる。

```sql
$sql = "UPDATE update_table SET \"更新情報\" = '更新しました!!'";
```

コーテーションのエスケープ処理は、
**`'(シングルコーテーション) `に`"(ダブルコーテーション)`、それぞれの前に\(バックスラッシュ)を置くだけ**

以上を踏まえて、SQL文の作成にかかる時間を減らしていきたい。

## 参考記事

- [えっ、まだPostgreSQLでダブルクォーテーション使ってるの？](https://qiita.com/Sirloin/items/b14ab34415a1ebd8a9c5)
- [配列](https://www.postgresql.jp/document/9.2/html/arrays.html)
seedファイル（ユーザー、投稿、お気に入り、いいね、フォロー、グループ）の書き方。

seedファイルの書き方記録しておきます。


ユーザー作成

```/db/seeds.rb
user1 = User.create({nickname:"ねずこ", email: "user1@user.com", password: "111111", introduction: "ねずこです"})
user2 = User.create({nickname:"ダンペイ", email: "user2@user.com", password: "111111", introduction: "ワシのジョー"})
user3 = User.create({nickname:"五代くん", email: "user3@user.com", password: "111111", introduction: "五代くんです"})
```

グループ作成

```/db/seeds.rb
chat_group1 = ChatGroup.create({chat_group_name:"初心者大歓迎！！", chat_group_description:"仲間募集中です"})
chat_group2 = ChatGroup.create({chat_group_name:"千葉県民チーム作りませんか？", chat_group_description:"千葉は聖地！！！！"})
chat_group3 = ChatGroup.create({chat_group_name:"チーム組みましょう", chat_group_description:"ファイティン"})
```

グループ参加　（お気に入りやいいねも同様）
<<　は尖ってる方に広がってる方のやつを含めるって意味らしいです！

```/db/seeds.rb
user1.chat_groups << chat_group1
user1.chat_groups << chat_group2
user1.chat_groups << chat_group3
user1.save
```

フォロワー追加

```/db/seeds.rb
user1.followers << user2
user1.followers << user3
user1.followers << user4
user1.save
```

まとめて書く


```/db/seeds.rb
Infomation.create! ([
  { id: 1,
    title: "定例会案内",
    body: "土日ご予約お待ちしております",
    admin_id: 1
  },
  { id: 2,
    title: "昨日の写真アップしました",
    body: "復活無制限盛り上がりました！",
    admin_id: 2
  },
  { id: 3,
    title: "ウォシュレットトイレ付けました",
    body: "快適です。更衣室やシャワールームもあり！",
    admin_id: 3
  }
])

```
　
その後ターミナルで

```
rails db:migrate:reset
```

をして一度リセットし、


```
rails db:seed
```

で、何も表示されずに終了すれば完了です！！
【Python】data_only=True で、値を転記する。

pythonを使用してExcelファイルの操作を勉強しています。
本日の気づき(復習)は、値の転記に関してです。
pythonでExcelを操作するため、openpyxlというパッケージを使用しています。

以下のような
〇〇市、△△市・・・と地区ごとの平均時給の台帳を作りたいとします。
平均時給は計算式で表しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927441/9398ae4c-0137-ff53-af6b-00d9df207e5a.png)

### 余談：「#DIV/0!」対策

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927441/45fe5a34-cdb4-2612-e123-16db19df5aaf.png)

ちなみになのですが、こちらのように何も入力していなかったりすると「#DIV/0!」と表示されてしまうことがないでしょうか。
この表示、「０」で割ってますよって意味でして地味に嫌いです・・・。
対策としては

```vb
=IFERROR(計算式,"")
```

と書いてあげると・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927441/81011a6f-ed03-d186-3b76-6037febf6b09.png)

このような感じで、表示が消えてくれます。個人的にすっきりです！

# cell.value属性
```python
cell(行番号,列番号).value

cell(1,1) == ws['A1']
cell(5,10) == ws['J5']
```
1始まりでセルの番地を設定できます。
繰り返し処理で、行や列をずらしていくときに重宝してくれそうです。

# lord_workbook関数で、data_only=Trueを指定する。
今回の問題は、数式ではなく計算結果の値を読み込みたいことなので

```python
lord_workbook(ファイル, data_only=True)
```

上記のように記述してあげると計算結果の値を読み込んでくれます。
ただ、そのままWorkbook.saveとかで保存してしまうと数式も消してしまうので
別のブックに転記するなりして、上書きしないように注意が必要です。

# cell.number_formatで書式設定をコピー
こちらは地味なところなのですが、時給の平均値なのでセルの書式設定も通貨です。
やっぱりここは書式設定もコピーしたいですね！
こちらはセルのnumber_fomat属性で取得できます。

```python
cell.number_format
```

これらをふまえて、記述してみると

```python:read_cell.py
from pathlib import Path
from openpyxl import load_workbook, Workbook

wb_new = Workbook()
ws_new = wb_new.active
ws_new.title = '台帳'
ws_new.column_dimensions['A'].width = 20

path = Path('../地区別平均時給')
for i, file in enumerate(path.glob('*.xlsx')):
    wb = load_workbook(file, data_only=True)
    ws = wb['チェックリスト']

    row_no = i + 1
    # セルＤ23を転記
    ws_new.cell(row_no, 1).value = ws['D23'].value
    # セルＬ23を転記
    ws_new.cell(row_no, 2).value = ws['L23'].value
    # セルＬ23の表示設定をコピー
    ws_new.cell(row_no, 2).number_format = ws['L23'].number_format

wb_new.save('平均時給一覧.xlsx')
```

となりました。
個人的には大事なところを勉強できたとウハウハしています。
Pythonの配列について

#Pythonの配列の種類が多かったので使用例と共に使い方を解説



##リスト(list)
・要素に番号がある
・自動連番システム(追加すると自動的に要素数が1つ増える)
・参照、追加、更新、削除が可能

####作成

```python
a = [10, 20, 30, 40]
```

####参照

```python
a #(リスト全てを参照)
 [10, 20, 30, 40]
a[0] #(特定の要素を参照)
 10
```

####追加

```python
a.append(50)
a #(参照)
 [10, 20, 30, 40, 50]
```

####更新

```python
a[1] = 30
a #(参照)
 [10, 30, 30, 40, 50]

```

####削除

```python
del nums[1]
a #(参照)
 [10, 30, 40, 50]
```

####リスト→タプル

```python
tuple(a)
```


##タプル(tuple)
・要素に番号がある
・データは参照のみ(追加、更新、削除が不可)


####作成

```python
a = (10, 20, 30, 40)
```

####参照

```python
a #(タプル全てを参照)
 [10, 20, 30, 40]
a[0] #(特定の要素を参照)
 10
```
####タプル→リスト

```python
list(a)
```


##集合(set)
・要素に順番がない
・参照、結合、抽出、差分が可能

####作成

```python
a = {10, 20, 30, 40}
#もしくは
b = set({10, 200 ,300})
```

####参照(順不同)

```python
a #(集合全てを参照)
 [10, 20, 30, 40]
200 in b #(特定の値が含まれるか検索)
 True
```

####結合(順不同)

```python
a | b
 {10, 20, 30, 200, 300}
```

####抽出

```python
a & b
 {10}
```

####差分

```python
b - a
 {200, 300}
a - b
 {20, 30}
```


##辞書型(dict)
・要素にキー値を設定できる
・参照、更新が可能

####作成

```python
a = {'A':10, 'B':20, 'C':30, 'D':40}
```

####参照

```python
a #(リスト全てを参照)
 {'A':10, 'B':20, 'C':30, 'D':40}
a['A'] #(特定の要素を参照)
 10
'B' in a #(キー値が含まれるか確認)
 True
a.keys() #(キー値の一覧を参照)
 dict_keys(['A', 'B', 'C', 'D'])
```

####更新

```python
a['A'] = 30
a #(参照)
 {'A':30, 'B':20, 'C':30, 'D':40}

```
Pardot Lightning アプリケーションを使用した対ビジネスマーケティングの自動化 ⇒ Einstein の基本 (Pardot Lightning アプリケーション) ⇒ Pardot Einstein 機能の探索

１．Einstein リードスコアと Pardot のグレーディングについて正しい記述はどれですか?
２．Einstein 行動スコアリングについて正しい記述は次のどれですか?
３．キャンペーンレコードで Einstein 属性を使用するのに必要な機能はどれですか?
４．Einstein 属性と均等分布属性モデルの違いは何ですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/e2c99d80-853e-f3c6-0725-4a88aefbc165.png)
初投稿です

#1.概要
プログラミング初心者の大学生です。
自分用の備忘録として基本的なことの投稿が多くなる予定です。

#2.目標
何事にも目標は大事ですから、とりあえず現状での目標をここに書き下しておきますね。
1.Unityでアプリ開発
2.macOSターミナルでWebページの作成

とりあえず、現状はこの二つが大きなところです。
新たな目標が出来次第、更新するかもしれないです。

#3.余談
大学では物理が専門なので、時々シミュレーションに関してもまとめて書くかもしれないです。
position: relativeは安易に使わない方が良いのかも。。

アプリ作成にて学んだ心構えを書いていきます。

それはズバリ！ 、、、
### <font color="Red">position: relativeは極力使わない！！</font>

これです。

このcssプロパティ、position: relativeは、
役割として、指定した要素を基準点とする機能となっています。

普通にdiv要素を積むと、
index.html.erb

```
<div class='red'>
</div>
<div class='blue'>
</div>
```

css

```
.red {
  height: 50vh;
  width: 50vw;
  background-color: red;
}

.blue {
  height: 50vh;
  width: 50vw;
  background-color: blue;
}
```


[![Image from Gyazo](https://i.gyazo.com/068e246663d285a23247eb4a0e0e82f2.png)](https://gyazo.com/068e246663d285a23247eb4a0e0e82f2)

こんな感じで、積み木の概念で左端から積まれていきます。
この赤い要素にposition: relativeを入力すると、
赤い要素を基準として、他要素の表示箇所を定めることができます。

表示箇所を定めたい要素に対して、
position: absoluteを入力して、top,leftなど調整したい方向を入力すると、
position: relativeした要素を起点に適用されます。

例
css

```
.red {
  height: 30vh;
  width: 50vw;
  background-color: red;
  position: relative; ←これを追加
}

.blue {
  height: 30vh;
  width: 30vw;
  background-color: blue;
  position: absolute;　←これを追加
  top: 10vh;  ←これを追加
  left: 10vw;　←これを追加
}
```

[![Image from Gyazo](https://i.gyazo.com/7a4c6b4fb15be4a127800e0810138f77.png)](https://gyazo.com/7a4c6b4fb15be4a127800e0810138f77)

上記のようになります！
ただブロック要素を積むだけでは要素同士が重なることは起きないですが、
position: relativeの作用で赤い要素が基準点となったことでこの表示になりました。

ビューファイル実装にあたって、
要素毎に並びを調整したいところが出てくると思います。
そういった時に活用できるコードになります！
ただ！こちらを使用すると、
レイアウト崩れを起こしやすいリスクに気付きました:sweat:

要素が少なくシンプルなものは支障ないかと思います。
細かな要素を組み合わせていく場合、
調整や修正が複雑になってくるんですよね:sweat:

私の場合、実装を進める中でレイアウト変更を試みた時に、
position: relativeされた要素があるために配置したい場所にうまく置けないことや、
スペース配分が分かりにくくなり苦戦することがありました。

# 振り返ってみて

ビューファイル編集を行うときは、
極力Flexboxや、margin・paddingプロパティを組み合わせていく方が、
修正や変更を加える際も分かりやすくて良いなと感じました。
色々と反省しながら頭に入れていけるので、
0からの実装は収穫が大きいと感じます:smiley:
まだまだ日々勉強あるのみ。。
【Ruby on Rails】Active Record 関連付け（アソシエーション）１対多についての超簡単なまとめ

モデル間の１対多、多対多のなどの関連付けの事をアソシエーションという
アソシエーションについては現実世界に置き換えるとわかりやすい。
今回はメッセージ投稿アプリを例にしている。
「一人のユーザーは何個もメッセージを投稿できる」＝　１対多　というように現実的に考えると、
どのような関連付けが行えるかが見えてくる。


## １対多の関連付け（アソシエーション）
メッセージ投稿機能をもったアプリの場合は次のようになる。

- Userテーブル

|id|email|備考|
|---|---|---|
1|arai@example.com|新井さん|
2|saitou@example.com|斎藤さん|
3|suzuki@example.com|鈴木さん|

- Postテーブル

|id|content|user_id|備考|
|---|---|---|---|
1|ありがとう|2|斎藤さんのメッセージ|
2|最高！|1|新井さんのメッセージ|
3|よろしく|3|鈴木さんのメッセージ|
4|おはよう|1|新井さんのメッセージ|
5|おやすみ|2|斎藤さんのメッセージ|

というように「ありがとう」「おやすみ」というメッセージを投稿したのは「斎藤さん」だという事がわかります。
idのようなカラムを「主キー（PK）」。user_idのようなカラムを「外部キー（FK）」と呼ぶ。

## belongs_to

`belogs_to`の関連付けを行うと、モデル間に１対１の関連性が設定される。
上記のアプリの場合で言うと、１つのメッセージは１人の人間と繋がっているので、`Postテーブル`に`belongs_to`を入れる事になる。

```ruby:
class Post < ApplicationRecord
  belongs_to :user
end
```
`belongs_to`で関連付けするモデル名は必ず「単数形」にする事。
関連付けのマイグレーションはこんな感じ。

```ruby
class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.string :content
      t.references :user
      t.timestamps
    end
  end
end
```
`t.references :user`の別の書き方として`t.bigint :小文字モデル名_id`と書くと外部キー（FK）として示す事ができるが、現在のRailsのバージョンでは、上記の書き方の方が良いみたい。

## has_many

`has_many`の関連付けは他とのモデルに「１対多」の関連性がある事を表す。

先ほどのメッセージ投稿アプリで言うと、
 
```ruby
class User < ApplicationRecord
  has_many :posts
end
```
という形で表現できる。「１人のユーザはたくさんのメッセージを投稿できる」って事。
反対側のモデルには `belongs_to`が使われる事が多い。
この関連付けに対応するマイグレーションはこんな感じ。

```ruby
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string  :email
      t.timestamps
    end

    create_table :posts do |t|
      t.belongs_to :user
      t.string :content
      t.timestamps
    end
  end
end
```

## まとめ
今回はActive Recordの関連付け（アソシエーション）について、自分の頭の中の整理という感じでまとめてみました。
理解が間違っている点などありましたら、教えていただけると幸いです。

## 参考資料

- [Active Record の関連付け](https://railsguides.jp/association_basics.html#belongs-to%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91)
- [やんばるエキスパート教材](https://yanbaru-expert.com/)
イラレスクリプトでもmap/reduceを使いたい

お仕事でIllustratorのスクリプトを触ることになった。
噂には聞いていたがかなり古い時代のJSしか動かないため=>とか.mapとかも使えない...。
他にも色々動かないけど

昨年末くらいからElixirばかり書いていて手続き的な書き方から遠ざかっていた人間としては配列をmap/reduceなしで触るのが精神的に堪えたので最初にEnumモジュール(と勝手によんでる)を作って書くことにした。

## JSよくわからん... :thinking: 

Elixirだと `defmodule`でモジュールを作れるんだけど。。。
よくわからんがobject(Elixirのmap)に関数を割り当てることができるみたいなのでそれで

```js
var Enum = {}
Enum.hoge = function() { ... }
```

こんな感じで書き始める

## map

mapが無いと不安なのでまずはmapを実装します。
JSはLISPを参考にして開発されたって何かで見た気がするのでとりあえず再帰も使えるだろうと思って書いてみたらなんと再帰は使えない... :thinking: 
悲しいけどブラウザで動く言語で再帰無限ループが起きるとやばいから再帰が使えないのは仕方ないのかと無理やり納得して不本意ながらforを使って実装する。
mapが実装できたら他のところでforを書かなくて良いのだからまぁ...

```js
Enum.map = function(arr, f) {
  var res = [];
  for (var i = 0; i < arr.length; i++) {
    res.push(f(arr[i]));
  }
  return res
}

var result = Enum.map([1,2,3], function(i) {
  return i * 2;
});

// イラレスクリプトではconsole.logは使えないんだけど..
console.log(result);
[2,4,6]
```

これでヨシ！

## reduce

mapがあるならreduceも必要だ！
この2つがそろえばfilterやreject、anyやincludeなんかも実装できる！
早速書いていく

```js
Enum.reduce = function(arr, acm, f) {
  var res = acm;
  for (var i = 0; i < arr.length; i++) {
    res = f(arr[i], res);
  }
  return res
}

var result = Enum.reduce([1,2,3], 0, function(i, acm) {
  return acm + i;
});
console.log(result);
```

これでヨシ！

## 他に書いたもの

reduceがあればたいていなんでも実装できるのでこれ以上は書かないんですが実装したものとしては

- each
- eachSlice
- compact
- filter
- reject
- include
- groupBy

を実装しました！！

これで気持ちよくなるべく副作用を出さないでイラレのデータを扱うことができました :tada:
CupertinoPicker(選択系のUI)を高速で動かすと値がおかしくなる

# CupertinoPickerとは?
https://api.flutter.dev/flutter/cupertino/CupertinoPicker-class.html
![スクリーンショット 2021-02-10 20.15.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472958/edfff216-f7fe-c333-3622-f6e209defc66.png)
IOSのよく見るセレクター
# 発生した問題
CupertinoPickerを高速で動かすとおそらくsetstateの処理の後に非同期処理が完了して値の変更が起こっため選択した物が表示されないで一つ前の要素が表示される
# 原因
setState内で非同期処理を呼んでいた。
```
    setState(() {
      Future(() async {
       //非同期処理
      });
    });
```
# 解決法
CupertinoPickerなど高速に選択が変わるUIに対しては値を設定する際は非同期処理は行わないようにする。DropDownMenuなどは非同期処理で値を変更しても問題なさそう。
ログアウト時のActive::RecordNotFoundの解決例

ActiveRecord::Record Not Found in UsersController#show
Couldn't find User with'id' = sign_out

読み取れることは、idにsign_outが呼ばれていること、
ログアウトを押したらusers_controller.rbのshowアクションが呼ばれていることです。

```ruby
get"users/:id",to:"users#show"
```

ログアウトの記述link_toの末尾にmethod::deleteを記述していないので。

本来のログアウトのルーティング（rails routes）
delete"users/sign_out" to:"devise/sessions#destroy"を見つけられず,

それに似たget"users/:id,to:"users#show"を読み込んでしまったのがエラー原因です。
base64からBlobへの変換

#目的
`base64`エンコードされたURIを`blob`に変換する際に、「base64??blob??」となったので、情報を整理するためにもコードを日本語でアウトプットする。

#環境
Vue.js 2.6
#完成コード
```image.vue
<script>
export default{
  data() {
    cropImg: 'data:image/png;base64,iVBORw0KGgo...',
    blob: ''
  },
  methods: {
        cropImage(){
            let bin = atob(this.cropImg.replace(/^.*,/, '')); //①
            let buffer = new Uint8Array(bin.length); //②
            for(let i = 0; i < bin.length; i++){ //③
                buffer[i] = bin.charCodeAt(i);
            }   
            this.blob = new Blob([buffer.buffer], { //④
                type: "image/jpeg"
            });
        },
  }
}
</script>
```
#解説
##①atob()によってBase64 文字列をデコードしてバイナリー文字列に変換
```.js
let bin = atob(this.cropImg.replace(/^.*,/, '')); 
```

ちなみにバイナリー文字列からBase64にエンコードする場合はbtoa()でできます。

##② 8 ビットの符号なし整数値の配列を生成

```.js
let buffer = new Uint8Array(bin.length);
```
中身を見るには Uint8Array の型にする必要があります

##③UTF-16 文字コードを取得
```.js
for(let i = 0; i < bin.length; i++){
    buffer[i] = bin.charCodeAt(i);
}  
```
blob()はUTF-16の文字列を第一引数にとることで変換することができるので、UTF-16に変換する必要があります。

##④Blobに変換
```.js
this.blob = new Blob([buffer.buffer], {
    type: "image/jpeg"
});
```
第一引数にUTF-16の文字列を、第二引数にtypeを指定して、変換します。
【WordPress】トップページindex.php以外のページが404エラーになった時の対処法【MAMP】

【エラーの経緯】
今回はWordPressにて、MAMPを使用時に

パーマリンクを「基本」から「投稿名」に変更し、
「category.php」「tag.php」「date.php」を表示しようとしたときに404エラーが発生

解決した方法を共有してみたいと思います




【原因】
今回のエラーは、結論からいうとMAMPのサーバー設定が「Nginx」だったことが原因でした。
これを「Apache」に切り替えると404エラーが解消され、無事各ページを表示することができました。


特定の流れは、

phpファイルのコードチェック→
URLのチェック→
パーマリンクの「変更を保存」→
.htaccessのチェック
→MAMPの設定をチェック

という経緯でした。
FTP通信でXserverからファイルを落とそうとした時の対処

Filezillaを使ってXserverからファイルをダウンロードした時に
550errorが起きてちょっと苦戦したのでメモします。

やろうとしたことは単純で、
FilezillaというFTPソフトを使って
サーバー上にあるファイルをローカルにバックアップとして保存をする作業。

###簡単な手順として、

サイトマネージャーを開く

新しいサイトを選択→名前は任意→一般の設定へ

記入する情報としてはこんな感じ

```
プロトコル:FTP-ファイル転送プロトコル
ホスト：サーバー番号.xserver.jp
ポートは空白
暗号化：使用可能なら明示的なFTP　over TLSを使用
ログオンタイプ：通常
ユーザー：FTPのユーザー名
パスワード：FTPのパスワード
```
この状態で接続を実行。
結果は、、、

```
状態:         	接続を確立しました。ウェルカム メッセージを待っています...
状態:         	TLS を初期化しています...
状態:         	証明書を検証中...
状態:         	TLS 接続が確立されました。
状態:         	サーバーは non-ASCII の文字をサポートしていません。
状態:         	ログインしました
状態:         	ディレクトリ リストを取得中...
コマンド:   	PWD
レスポンス:	550 PWD: Permission denied
エラー:      	ディレクトリ リスト表示の取り出しに失敗しました
```


設定情報はあっているはず、
`550 PWD: Permission denied` エラーについて調べると、

主な原因としてはサーバー側のFTP制限で許可されてないIPアドレスからは接続できないようになっているとのこと。

そこでXserverにログイン。
対象のサーバーIDを選択してサーバーパネルへ移動。

FTP制限の設定へ行き、自身のMacbookのIPアドレスを登録。

また同じエラーが起きた。

これがどこにも載っていなかったが（知識が甘かった）

原因としては、接続している機器のIPアドレスではなく、
接続しているインターネットの回線のIPアドレスを登録する必要があったそう。

なので、使用しているWifiのIPアドレスを調べて登録→

##成功。

#完
OSI参照モデル

ネットワークの基本構造について学習していきます。

##OSI参照モデル　（OSI基本構造）

###第一層　物理層
ケーブルのピン数や電気特性を定め、送出データの電気的な変換などを行う

###第二層　データリンク層
直結された相手との通信路を確保し、データの誤り訂正や再送要求などを行う

###第三層　ネットワーク層
相手までデータを届けるための経路選択やネットワーク上で個々を識別するためのアドレス管理

###第四層　トランスポート層
ネットワーク層から流れてきたデータの整列や誤り訂正などを行い、送受信されたデータの信頼性を確保
TCPやUDPはこの層の位置づけ

####TCP
正しく順番どおりにパケットを届けることを保証している
確実なデータ送信ができるがプロトコルが重い

####UDP
信頼性など保証ないが、軽いプロトコル

###第五層　セッション層
通信の開始や終了といった通信プログラム同士の接続を管理し、通信経路の確立を行う

###第六層　プレゼンテーション層
圧縮方式や文字コードを管理
アプリケーションとネットワークの仲介を行う。

###第七層　アプリケーション層
通信を利用するために必要なサービスが人やプログラムに対して提供
Adobe XDから画像を抜き出す方法＆注意すること

# はじめに

XDから画像を書き出す時、Photoshopとは異なるフローがあったのでメモっておきます。

ちなみに、XDが少し好きになりました。
マークアップする側から見ると、PSDで頂くよりXDの方が、UIに余計な情報が少なくて見やすい気がしました。

# 画像の書き出し方

## 1. 書き出したい画像を選択する

まず、書き出す画像をアートボード上でクリック、もしくはレイヤー一覧から選択します。

**一括で書き出し**たい場合は、書き出す画像を**書き出し対象に設定**しておく必要があります。
書き出し対象にするには、画像を選択した状態で **⌃+⌘+E** を押すか、もしくは、アートボード上またはレイヤー一覧で画像を右クリックし、「**書き出し対象にする**」を選択します。(Windowsのショートカットキーが分かりませんでしたすみません)

![スクリーンショット 2021-02-09 18.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/84691bf4-9067-adc5-107b-e1f276230a6d.png "書き出し対象にする")

ちなみに、アートボードごと書き出したい場合は、アートボード左上のアートボード名をクリックして選択します。

## 2. 書き出す

個別に書き出す場合は、Mac: **⌘+E**／Win: **Ctrl+E**、一括書き出しの場合は、Mac: **⇧+⌘+E**／Win: **Shift+Ctrl+E**を押すか、もしくは、「ファイル＞書き出し」から行いたい方を選択します。（ショートカットキーを覚えることをおすすめします）

||macOS|Windows|
|---|---|---|
|選択したオブジェクトを書き出し|⌘+E|Ctrl+E|
|すべて書き出し|⇧+⌘+E|Shift+Ctrl+E|

表示されたダイアログでファイル名を入力し、必要に応じてオプションを選択します。

### 2-1. PNGで書き出す場合

![スクリーンショット 2021-02-09 18.48.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/5efe2450-734f-ec63-e4cb-5527aa17e8db.png)

#### フォーマット

PNGを選択します。

#### 書き出し先

以下の４つが選択でき、必要なものを選択します。
選択した書き出し倍率の画像が全て出力されます。例えば、Webを選択すれば1xと2xが必ず書き出される、ということです。

||書き出し倍率|
|:-:|:-:|
|デザイン|1x|
|Web|1x, 2x|
|iOS|1x, 2x, 3x|
|Android|ldpi (75%), mdpi (100%), hdpi (150%), <br>xhdpi (200%), xxhdpi (300%), xxxhdpi (400%)|

#### デザイン倍率

書き出し先で「デザイン」以外を選択した場合、変更可能になります。

初見だと勘違いしがちですが、出力する画像の倍率を選択するのではなく、**基準となるアートボードのサイズ**を選択します。
つまり、等倍でデザインしていれば1xのままで良いですが、Retina対応用に倍率2倍でデザインしていたときに2xを選択します。

### 2-2. SVGで書き出す場合

SVGの`g`コンテナのidはアートワークのレイヤー名やグループ名が使用されます。

![スクリーンショット 2021-02-09 18.58.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/9b86d59c-4c0e-b0a5-a981-3f84f511d0c2.png)

#### フォーマット

SVGを選択します。

#### スタイル

**プレゼンテーション属性**と**内部CSS**が選択でき、それぞれ以下のような違いがあります。

||特徴|選択する基準|
|:--|:--|:--|
|プレゼンテーション属性|・スタイル情報をpathタグ内に記述<br>・軽量|基本的にこっち（でいいと思う）|
|内部CSS|スタイル情報はpathにclassを与え`<style>`で記述<br>|classを当ててスタイルを上書きする時|

#### 画像を保存

このオプションは、書き出すオブジェクトに**ビットマップ画像が含まれている場合**に注意が必要です。
ベクターのみの場合は、読み飛ばして結構です。

||特徴|選択する基準|
|:--|:--|:--|
|埋め込み|・ビットマップ画像がbase64にエンコードされSVGに埋め込まれる<br>・ファイルサイズが大きい|リンク切れの恐怖におののいている時|
|リンク|ビットマップ画像は`img`タグで参照される|基本的にこっち（でいいと思う）<br>ファイルサイズを軽量化したい時|

「**ファイルサイズを最適化**」オプションにチェックをいれると、インデントや改行、またidも削除されます。

### 2-3. JPGで書き出す場合

#### フォーマット

JPGを選択します。

#### 画質

20%、40%、60%、80%、100%から選択します。

#### 書き出し先＆デザイン倍率

PNGと同様なので割愛。

# Tips

## テキストをSVGにして書き出すとき

テキストをSVGで書き出す際は、**テキストをアウトライン化**します。

フォント等の関係でテキストをSVGとして書き出す場合があると思います。
その際、そのまま書き出すと以下のようにSVGが出力されます。

```html:テキスト.svg
<svg xmlns="http://www.w3.org/2000/svg" width="79" height="20" viewBox="0 0 79 20">
  <text id="テキスト" fill="#333" font-size="20" font-family="HiraKakuProN-W3, Hiragino Kaku Gothic ProN"><tspan x="0" y="18">テキスト</tspan></text>
</svg>
```

`font-size`や`font-family`とテキストフォントのオプションが指定されていることが分かると思います。
このままでは、その指定されたフォントがインストールされていない環境で閲覧するとフォントが置き換わってしまいます。

デザインの意図した通りSVGを表示させるには、テキストをアウトライン化します。

アウトライン化するためには、書き出すオブジェクト内にあるテキストを選択した状態でMac: **⌘+8**／Win: **Ctrl+8**を押すか、もしくは、メニューバーの「オブジェクト＞パス＞パスに変換」をクリックします。
For GEN (高校生への課題作成補助)

## ディレクトリ構成
GEN/
　┣ test.mp3
　┣ test.wav
　┣ analysis_1.py
　┣ requirements.txt

## 環境構築
他のプログラムに影響が出ないように，仮想環境を作ることを進めます．
好きなディレクトリで下記コマンドによりpython3.6の仮想環境を構築．

```
$ virtualenv -p python3.6 GEN
```
これで，GENという仮想環境が作られました．
仮想環境GENの中で作業するために，アクティベートという処理をします．

```
$ source GEN/bin/activate
```
これで，GENの仮想環境での作業が可能となります．
activateされているときにインストールとかしたものはGENがactivate中のみ有効になります．
この環境から抜けたいときは

```
$ source deactivate
```

もしくは

```
$ conda deactivate
```

で抜けられます．
ここまできたら，プログラムを動かすのに必要なライブラリをインストールします．
`./requirements.txt`に必要なライブラリをまとめてあるので，以下コマンドで一括インストールしちゃいましょう．

```
$ pip install -r requirements.txt
```
これで環境構築はおしまいです．

##音声ファイルの扱い
基本的なことです．wavベースで話を進めていくので，mp3しか手に入らない場合は，以下のコマンドで変換しましょう．
####WAVからMP3へ変換

```
ffmpeg -i "test.wav" -vn -ac 2 -ar 44100 -ab 256k -acodec libmp3lame -f mp3 "test.mp3"
```

####MP3からWAVへ変換

```
$ ffmpeg -i "test.mp3" -vn -ac 2 -ar 44100 -acodec pcm_s16le -f wav "test.wav"
```

##プログラム：analysis_1.py
今回は，[こちら](https://soundeffect-lab.info/sound/voice/line-girl1.html)のサイトから「やあ！」という女の子の声をお借りし，'test.wav'として保存しています．

```py
###################### ライブラリのインポート #######################
# sondfileというライブラリをsfと定義してインポートしてます
import soundfile as sf
# pythonでグラフ表示とかするためのライブラリをpltと定義してインポートしてます
from matplotlib import pyplot as plt
# 数字に強いライブラリnumpyをnpと定義してインポートてます
import numpy as np
###############################################################

########################## 関数定義 ############################
# wavファイルから波形とサンプルレートと出力（return）する関数
def wavload(path):
    data, samplerate = sf.read(path)
    return data, samplerate
###############################################################


########################## 処理開始 #############################
if __name__ == '__main__':

    ##### 波形を表示 #####
    #縦軸：上で定義した関数wavloadを使ってディレクトリ内の'test.wav'を読み込む
    voice, samplerate = wavload('./test.wav')

    #横軸：tは時間方向での離散値です．voiceの長さをサンプルレートで切っているので，サンプル数分の配列になってます．
    t = np.arange(0, len(voice))/samplerate

    #データプロット．今回はステレオ（2チャンネル合成）で出力させます．
    plt.plot(t, voice)
    plt.show()
    plt.close()
    #####################

    ##### 周波数成分を表示（フーリエ変換） #####
    #縦軸：voiceを高速フーリエ変換します（時間領域から周波数領域に変換）
    fft_voice = np.abs(np.fft.fft(voice))

    #横軸：周波数の取得 #np.fft.fftfreq(データ点数, サンプリング周期)
    freqList = np.fft.fftfreq(voice.shape[0], d=1.0/samplerate)

    #データプロット
    plt.plot(freqList, fft_voice)
    plt.xlim(0, 8000) #0～8000Hzまで表示
    plt.show()
    #####################################

################################################################

```
処理の詳細は，上のコメントアウトを読めばわかると思います．
実行は以下のコマンドで行います．

```
$ python analysis_1.py
```

####出力結果
図1：音声の波形（ステレオ）
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642312/8724bb32-10d7-7e97-fdb1-3c69b125e008.png)

図2：フーリエ変換
![Figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642312/aa747ccc-eb39-62ac-4063-68bed99bcf98.png)