OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonでのチームアプリ開発に参画するための学習履歴~索引ページ~

# はじめに

[Saku731さん](https://twitter.com/Koji21825331) が主催する [Pythonによるチームアプリ開発](https://twitter.com/Koji21825331/status/1213663249649922049?s=20) に参加するために学習したことをアウトプットした記事の索引ページです。

企画に参加するにあたっての所信表明のようなものは目次のページに書いてありますのでそちらをご覧いただけると幸いです。
0からPythonを始めてみようかなと思っている方への勉強のフローチャートくらいにはなっていたら幸いです。

# 目次
[Pythonでのチームアプリ開発に参画するための学習履歴~paizaラーニングの「Python3入門」を終えて~](https://qiita.com/shitikakei/items/832b3ad636be0f662586)

# Pythonの基礎項目の補足とjupyterLab環境構築
[Pythonでのチームアプリ開発に参画するための学習履歴~基礎項目の補足とjupyterLab環境構築~](https://qiita.com/shitikakei/items/bcdecfaccba756e4258d)

# 要件定義について少し考えてみる

[Pythonでのチームアプリ開発に参画するための学習履歴~要件定義について少し考えてみる~](https://qiita.com/shitikakei/items/e156e20f7a840ed99532)

# Docker・Django・Nginx・MariaDB環境を構築する
[Pythonでのチームアプリ開発に参画するための学習履歴~Docker・Django・Nginx・MariaDB環境を構築する~](https://qiita.com/shitikakei/items/5ba2f3e028f84371af9c)

# Djangoチュートリアル1・2・3

[Pythonでのチームアプリ開発に参画するための学習履歴~Djangoチュートリアル1・2・3~](https://qiita.com/shitikakei/items/753ba603b5bca272c69c)

# Djangoチュートリアル4

[Pythonでのチームアプリ開発に参画するための学習履歴~Djangoチュートリアル4~](https://qiita.com/shitikakei/items/2cbe62d162a667db0209)

# Djangoチュートリアル5
[Pythonでのチームアプリ開発に参画するための学習履歴~Djangoチュートリアル5~](https://qiita.com/shitikakei/items/1aa4d1f0ab4252ae0ad7)

# Djangoチュートリアル6
[Pythonでのチームアプリ開発に参画するための学習履歴~Djangoチュートリアル6~](https://qiita.com/shitikakei/items/9fcdba68dc12012d5fc9)

# Djangoチュートリアル7
[Pythonでのチームアプリ開発に参画するための学習履歴~Djangoチュートリアル7~](https://qiita.com/shitikakei/items/aac1e2f8103af3b82e08)

# Djangoでカスタムユーザーについて甘く見て痛い目を見たという話
[Djangoでカスタムユーザーについて甘く見て痛い目を見たという話](https://qiita.com/shitikakei/items/09f244d622ca24f3c891)
MacOSでSTS(SpringToolSuite)が起動しない時の対処 エラー内容 No java virtual machine is not....

MacOS Mojave STS起動時にエラーが出てまったく立ち上がらないぃぃぃィィィｌ！！時に実施した処理をまとめるぅぅぅゥゥゥ！！

#エラー内容

No java virtual machine was not found after...

STSを起動しようとすると上のメッセージが表示されて起動しません。一般的には下記3点実施すれば起動するらしい…

1.環境変数の設定
2.JAVA_JOME
3.STSの.iniファイルにJAVA_HOMEを追記

上の点に関してはこちらの記事が参考になるかもしれません。

[MacでのJava開発環境構築を通して「PATHを通す」意味を学ぶ](https://qiita.com/s_hino/items/a185deb4f9fc31c0f5e2)

自分の場合は上記3点を設定しても改善しなかったため、全部まっさらな状態からやり直したところ上手くいきました。下記手順になります。


#手順1 java(JDK?)のアンインストールと環境変数の削除
何が原因かわからなかったため、全部0からやり直すことにしました。
Mac内を確認したところ3つのjava(全部JDK?)が入っていたので、まずは全てをアンインストール。

/Library/Java/JavaVirtualMachines

配下にjavaファイルがあるので、ターミナルでディレクトリ移動して、バージョンを確認します。自分の場合は3つありました。

下記コマンドでファイルを1つずつ削除

```
$ sudo rm -rf /Library/Java/JavaVirtualMachines/jdkの名前
```

VirtualMachines以下のjdkバージョンは自身のターミナルで確認して削除コマンドを実行してください。


#手順2 設定した環境変数も削除
PATH
JAVA_HOME
上記2つの変数を設定していたため、両方とも削除しました。削除コマンドはこちら。

```$ unset hogehoge....```

hogehoge部分に削除したいものを代入します。ただし、

```$ unset PATH```

と入力するとターミナルでcdさえできなくなるので注意。PATHは複数設定されていると思いますがコロン(:)で区切られています。javaに関するPATHのみ削除しましょう。

また、bashファイルにも上記２点を追記していたのでそちらも削除しました。

#手順3  STSもアンインストール
こちらも削除。Macでアプリをアンインストールする場合はこちらがおすすめです。
[App Cleaner](https://appcleaner.softonic.jp/mac)


#手順4 jdｋとSTSを再インストール
amazonのページからamazon-coretto-8.jdkをダウンロード&インストール。その後STSも再度ダウンロード&インストール

ここまで実行してSTSの起動確認をしたところで無事立ち上がりました。
環境変数を設定していなくてもSTSは立ち上がる…だと…!?(グゥオン！！)

詳しい原因は不明ですが、複数のjava(jdk?)を入れていたのが悪さをしていたのかも…なので同じような状況の方はオラオラアァァァ！！とjdkを全削除してから試してみてください。
UiPath Attended ロボットのインストール方法

UiPathで開発したロボットを展開する際、ロボットの処理内容によって、以下のいずれかのロボットを選択し、展開を行う。

* Attended：ユーザーのPCにインストールし、ユーザーの操作により動作するロボット
* Unattended：サーバーやロボット用PCにインストールし、ユーザー操作を伴わないロボット

今回は、Attendedロボットのインストールを行おうと思います。

# インストーラーのダウンロード
ロボットのインストーラーは、UiPath Orchestratorからダウンロードできます。
(Orchestratorのユーザー登録は、[こちら](https://www.uipath.com/de/start-trial) から行うことができます）

1. Orchestratorのトップページへログインし、**Resource Center**をクリックします。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/9c196d1e-66a9-4ab3-4bfa-093f123f7ce5.png">

2. **Download Enterprise Edition**をクリックし、インストーラーをダウンロードします。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/58c3bc38-7509-b5e3-10b3-089191f9e398.png">
`"Community Edition"は、Attendedロボットのインストールはできないので、ご注意ください。`

# ロボットのインストール
1. ダウンロードした **UiPathStudio.msi** をクリックし、インストールを行います。
![2020-04-23_23h54_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/e4912db7-d45f-a7f2-df10-f8d31b8e4646.png)

2. 標準のインストールは、Studioをインストールする設定となっているので、**Advance** をクリックしインストールモジュールの設定を行う。
![2020-04-23_22h56_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/d84d9531-5087-1d22-20c8-21f2a4c57f65.png)

3. Attendedロボットのインストールは、下記を選択する。
*"UiPath Studio"をインストール対象から除外することを忘れずに*
![2020-04-23_22h57_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/f347b2c4-68ba-506b-0c38-cdb2265179e0.png)

4. Extensionの選択（*必要であれば）
このインストーラーで、Java、Chrome、CitrixのExtensionをインストールすることができます。
後ほど、Chrome Web Storeなどからもインストールすることもできるので、ロボットの用途に合わせてインストールしてください。
![2020-04-24_00h09_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/819fff30-e599-e896-bc3e-141c6d73ff8c.png)

5. ここまで設定できれば、あとはインストーラーに従ってインストールすれば、完了です。

# インストール完了後

1. インストールが無事に完了できていれば、Windowsメニューに、UiPath Robot が表示されます。
![2020-04-24_00h14_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/f06885dc-6da8-e241-2db4-58f86c2407a3.png)

2. 起動すると、タスクトレイにアイコンが表示されます。
ロボットのステータスが、”Offline”になっていますが、Orchestratorにロボットを登録すると、Onlineになりますので、インストール自体は問題なく完了できています（ロボットの登録は、別記事に記載します）。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/a822df29-05ae-bf11-95d0-02fbcd528cc5.png">


Attendedロボットのインストールに関する説明は、以上で終わりです。
Orchestratorへのロボットの登録、インストールしたロボットの設定は、別の記事に記載します。

<br>
<br>
Qiita用テンプレート

<h2>背景</h2>

<p>内容1<br>
内容２</p>


<h2>問題点</h2>

<p>内容1<br>
内容２</p>

<div class="highlight"><pre>
example
</pre></div>


<h2>試したこと</h2>

<p>内容1<br>
内容２</p>

<div class="highlight"><pre>
example
</pre></div>


<h2>解決策</h2>

<p>内容1<br>
内容２</p>

<div class="highlight"><pre>
example
</pre></div>


<h2>まとめ</h2>

<p>内容1<br>
内容２</p>
CloudFunctionをデプロイするための備忘録

#はじめに
CloudFunctionをデプロイする際に少々苦戦したので、備忘録として書き記しておきたいと思います。

####CloudFunctionとは？
サーバーレスフレームワークで、Firebase の機能と HTTPS リクエストによってトリガーされたイベントに応じて、バックエンド コードを自動的に実行できます（公式より）

####下準備
①Firebaseプロジェクトを作成　※省略

②Node.js と Firebase CLI を設定する
該当プロジェクトのソースコードのディレクトに対して、ターミナルから

```
npm install -g firebase-tools
```
を実行。プロジェクトにfirebaseコマンドがインストールされます。

③FIrebaseにログインをする

```
firebase login
```
プロジェクトを作成したアカウント、あるいはコラボレートしているGoogleアカウントでログインします。

④functionの初期化をする

```
firebase init functions
```
JavaScriptあるいはTypescriptの選択、その他細かい設定を行えます。
成功すると、下記のような構造が新たに生成されます。

``` 
//公式より（https://firebase.google.com/docs/functions/get-started?hl=ja）
myproject
 +- .firebaserc    # Hidden file that helps you quickly switch between
 |                 # projects with `firebase use`
 |
 +- firebase.json  # Describes properties for your project
 |
 +- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # main source file for your Cloud Functions code
      |
      +- node_modules/ # directory where your dependencies (declared in
                       # package.json) are installed
```
functionのディレクトリの中の、index.jsに実行する関数を記述します。

⑤必要なモジュールのインポート
私の場合はユーザーの退会処理を行いたかったため、Authenticationに対応するAdminSDKをインポートした上で、利用のためにファイル内で初期化をしています（初期化をしないと動かない）

``` 
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();
``` 
⑥index.js内に実行したい関数を記述　※本記事では省略。
関数をexportすることを忘れないようにしましょう。

####デプロイする
※必ずfunctionsのディレクトリ内で実行する（筆者は恥ずかしながらこれを見落としていて、１時間くらい何度もfirebase initをやり直していました😅）

``` 
全ての関数をデプロイ
$ firebase deploy --only functions
``` 

``` 
指定した関数をデプロイ
$ firebase deploy --only functions:hogeFunction,functions:fooFunction
//index.jsに記載のhogeFunctionとfooFunctionがデプロイされます
``` 

``` 
指定した関数をFirebase上から削除（一度に複数削除するときはhogeFunctionの後に並べる）
$ firebase functions:delete hogeFunction
``` 

####おわりに

使い方に慣れるまで少し時間がかかりますが、重要情報の処理をFirebaseに預けることで安心感がありますし、データベースもスムーズに更新されるためとても使い勝手が良い印象を受けました。引き続きFirebaseを使った開発を楽しみたいと思います！

●参考にしました！
・[CloudFunctionの下準備](https://firebase.google.com/docs/functions/get-started?hl=ja)
・[CloudFunctionのデプロイ](https://firebase.google.com/docs/functions/manage-functions?hl=ja)
Go言語のtemplateは何がツラいのか？

# はじめに
Go言語でWebアプリを作れるのか調べていたところ、公式のテンプレートエンジンではツラいとあったが、何がツラいのかいまいちわからなかったので、調べてみました。

# ツラいこと
1. templateでレイアウトを継承できない
2. templateごとにstructを定義しなくてはならない
3. Viewの関数が用意されていない

## 解決作
> templateでレイアウトを継承できない

これには以下のようにテンプレートを分けて定義して、挿入することで解決できます

```go
package main

import (
	"os"
	"text/template"
)

func main() {
	t := template.Must(template.New("").Parse(templ))
	template.Must(t.Parse(content))
	if err := t.Execute(os.Stdout, nil); err != nil {
		panic(err)
	}
}

// 実際は別ファイル
const templ = `ベーステンプレート
内容: {{template "content"}}
`
// 実際は別ファイル
const content = `{{define "content"}}挿入したいテンプレート{{end}}`
```
[play ground](https://play.golang.org/p/4d7NR8bzZ3-)

他にも、header, footerにわけてる方もいました。
[Go の html/template でヘッダーやフッター等の共通化を実現する方法](https://mikan.github.io/2019/12/08/implementing-header-and-footer-with-golang-html-template/)

> templateごとにstructを定義しなくてはならない

これは解決策は見つけられませんでしたが、そこまで手間でもないのではないでしょうか？

> Viewの関数が用意されていない

以下のページにあるようにFuncMapを使えばtemplate側でも使えます。
[text/template上で動く計算機を作る #golang](https://qiita.com/atotto/items/e26b2667d9e6073e91b2)
また、template側で関数が必要なのはレイヤー化できてるのか怪しい気もします。

# 結論
現在の調査の段階ではそんなにツラい内容はなかったように思います。
エスケープなどの処理も自動で入れられて、言語レベルのサポートとしては十分ではないでしょうか？
まだまだGo言語は始めたばかりなので、自分でも実装しつつ調べていきます！
GAS × Slack通知

##はじめに
GAS勉強中です。
まとめてここのサイトにアップしているのでよかったらみてください。

【ビジボット】https://bzbot.work
【記事レシピ】https://bzbot.work/2019/05/22/gas-recipe/


##本題
今回はGASでSlackに通知するプログラムのレシピを書きました。
スプレッドシートを編集したときや特定操作をした時にSlackにそのまま通知が遅れたらいいなって思って作成。

詳細→https://bzbot.work/2020/04/25/gas-slack/

特定列だけを編集したときに実行されるように作ってます。
あと、カスタムで使えるように使ってない変数もちょこっとあります。

```Javascript:GAS
/*トリガーについて
*実行する関数を選択：onEdit
*イベントの種類を選択：編集時
*/

function onEdit(e) {
  var oldVal = e.oldValue; //変更前の値
  var newVal = e.value; //変更後の値
  var sheet = e.source.getActiveSheet(); //変更があったシート
  var range = e.source.getActiveRange(); //変更があったセル
  var rowVal = range.getRow(); //変更があった行
  var colVal = range.getColumn(); //変更があった列
  var postItem = sheet.getRange(rowVal,1).getValue(); // Slackに送りたい値
        
  var lCol = sheet.getLastColumn();
  var input = '';
  var Ch = 'XXXXXXXXX';
  var val = '';

  for (i = 1; i <= lCol; i++){
    val = sheet.getRange(1,i).getValue();
    if(val === 'テスト完了日'){
      input = i;
    };
  };
  
  //Browser.msgBox('onEdit関数の中にある...' + 'input:' + input + 'rowVal:' + rowVal + 'colVal:' + colVal);
    
  if(input === colVal){
    var result = Browser.msgBox('Slack送信確認',"チャンネルに送信しますか？", Browser.Buttons.OK_CANCEL);
    if(result == "ok"){
      sendToSlack(postItem,rowVal,Ch);
    };
  };
}

function sendToSlack(Item,row,ch) { //引数にセットされた値をこっちの変数に入れる

  var url = 'https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; //送信する為のWebhookURI

  var body =  '<!here>' + '\n' +'`テストが完了!!!！`'+ '\n' + '名前：' + Item; //送信するメッセージ
  var data = { 'channel' : ch, 'username' : 'ビジボット', 'text' : body};
  
  //Browser.msgBox('sendToSlack関数の中にある...' + 'Item:' + Item + 'と' + 'ch:' + ch);

  var payload = JSON.stringify(data);
  var options = {
    'method' : 'POST',
    'contentType' : 'application/json',
    'payload' : payload
  };
  var response = UrlFetchApp.fetch(url, options);
}
```
Ubuntu 20.04 LTSを入れてやったこと

どうもこんばんわ。
自分がUbuntu 20.04 LTSをインストールした後何がやったのかメモとQiitaに慣れるために書いてみます。
#WIFIアダプタのドライバをインストール
WDC-433DU2HBKというWIFIアダプタを使っていますが、インストール直後では認識しないため追加のドライバをインストールします。

リポジトリの更新
```sudo apt update```

gitとdkmsをインストール
```sudo apt install git dkms```

Githubからソースコードをクローン
```git clone https://github.com/aircrack-ng/rtl8812au```

ディレクトリに移動
```cd rtl8812au/```

インストール
```sudo ./dkms-install.sh```

再起動
```sudo reboot```

再起動後認識してるはずなのでアクセスポイントに接続。
#アップデートとアップグレード
リポジトリの更新
```sudo apt update```

パッケージを更新
```sudo apt upgrade```

不要な依存関係の削除
```sudo apt autoremove```
#ソフトのインストール
gdebi
```sudo apt install gdebi```

discord
https://discordapp.com/

vlc
```sudo apt install vlc```

shutter
```sudo add-apt-repository ppa:linuxuprising/shutter```
```sudo apt install shutter```

rhythmbox
```sudo apt install rhythmbox```

#最後に
20.04から本格的にSnapパッケージに移行し始めましたね。
少し調べてみましたがaptからインストールしたソフトとsnapからインストールしたソフトは共存が可能なようなので使い方によってはかなり便利なものになりそうです。

また何か入れたら追記します。
おやすみなさい。
EC2にSSh接続 ~初心者~

#はじめに
sshでのコマンドをよく忘れがち・・(記憶力がポンコツ)
認証設定、ファイル転送も含めて記載します。

#準備
- Ec2(22番ポート解放済み)
- pemキー作成済み
- IPアドレスが割り当ている
- Mac(Windowsでもいけます)

##ログイン
① ターミナルからSShコマンドを実行

```ターミナル```
ssh -i ***.pem ec2-user@IPアドレス
```

② レスポンス、ログイン完了

```
The authenticity of host 'IPアドレス(IPアドレス)' can't be established.
ECDSA key fingerprint is SHA256:/RFBylrcFvYgOKPPq/GTRP4Hj+rZgH4pWEwArsW7lxk.
Are you sure you want to continue connecting (yes/no)? y

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
No packages needed for security; 4 packages available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-192-168-100-30 ~]$
```

今回はAmazonLinuxにログインしたので、デフォルトのユーザ名が『ec2-user』でしたが、
ディストリビューションによってユーザー名が異なります。

RHEL の場合、ユーザー名は root または ec2-user
Ubuntu の場合、ユーザー名は ubuntu
SUSE Linux の場合、ユーザー名は root または ec2-user のいずれか


##認証設定
pemキーだけのログインではセキュリティが弱いので、認証設定をします。

① アカウント作成

```
$ sudo useradd ec2-user2
```

② パスワード設定
　※パスワードを変更する場合も上書きができます。

```
$ sudo passwd ec2-user2
Changing password for user ec2-user.
New password:
Retype new password:
```
レスポンス

```
passwd: all authentication tokens updated successfully.
```

③ /etc/ssh/sshd_config ファイルの PasswordAuthenticationパラメータの設定変更する。

```
sudo vi /etc/ssh/sshd_config 

PasswordAuthentication yes
```

④ ssh再起動する。　※Ubuntuは異なる

```
sudo service sshd restart
```

##Mac(ローカルPC)→EC2へファイル転送

①ホームディレクトリにpemファイルを転送

```
scp -i ***.pem ***.txt ec2-user@IPアドレス:~
```

レスポンス

```
***.txt                                                                                             100% 1692    66.2KB/s   00:00
```

②ホームディレクトリを確認するとファイル転送がされています。

```
[ec2-user@ip-192-168-100-30 ~]$ ls
***.txt
```

#[参照]
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html
jenvでjava1.7(zulu7)を特定のディレクトリ配下で利用する

# jenvでjava1.7(zulu7)を特定のディレクトリ配下で利用する

## jenvインストール
```
$ brew install jenv
```

## jenv設定
```
$ echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(jenv init -)"' >> ~/.bashrc
```

## java1.7(zulu7)をインストール
```
$ brew cask install zulu7
```

## インストールされているjdkの一覧を表示する
```bash
$ /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
    14.0.1, x86_64:	"OpenJDK 14.0.1"	/Library/Java/JavaVirtualMachines/openjdk-14.0.1.jdk/Contents/Home
    1.8.0_241, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home
    1.7.0_262, x86_64:	"Zulu 7.38.0.11"	/Library/Java/JavaVirtualMachines/zulu-7.jdk/Contents/Home
```

## 一覧からzulu7をjenvに登録する
```
$ jenv add /Library/Java/JavaVirtualMachines/zulu-7.jdk/Contents/Home
```

## 特定のディレクトリでjava1.7(zulu7)を利用できるようにする
```bash
$ cd /Users/tofu/Projects/BotHack/javabots/JavaBot/
$ jenv local 1.7
```

## 設定できたか確認
```bash
$ jenv versions
  system
* 1.7 (set by /Users/tofu/Projects/BotHack/javabots/JavaBot/.java-version)
  1.7.0.262
  zulu64-1.7.0.262
```

## java1.7(zulu7)が利用できるようになったか確認する
```bash
$ java -version
openjdk version "1.7.0_262"
OpenJDK Runtime Environment (Zulu 7.38.0.11-CA-macosx) (build 1.7.0_262-b10)
OpenJDK 64-Bit Server VM (Zulu 7.38.0.11-CA-macosx) (build 24.262-b10, mixed mode)
```

----
よかったよかった
備忘録 　モジュール関数

# モジュール関数とはなんぞや

ruby触っていたらよく使うMath（どの言語もだけど、、、）
これってmoduleなんだなと改めて実感したので備忘録。

例えばincludeしてクラス内で使える

```ruby
class Calc
   include Math
   def calc_sqrt(n)
       sqrt(n)
   end
end

num = Calc.new
num.calc_sqrt(n)
#=> 1.4142135623730951
```

けどインスタンスメソッドとして使おうとしたらエラーが出る

```ruby
class Calc
   include Math
   def calc_sqrt(n)
       sqrt(n)
   end
end

num = Calc.new
num.sqrt(n)
#=> private method `sqrt' called for #<Calc:0x00000000015abb48> (NoMethodError)
```
includeしたらインスタンスメソッドとして使えるはずなのに、、、
と思ったが、
こちらの"sqrt"実はモジュール関数というもの。

### モジュール関数とは

ミックスインとしてもモジュールの特異メソッドとしても使えるメソッドのこと。
クラスにミックスインした際はprivateメソッドになる。

記述方法

```ruby
module Hoge   
    #ここから下はモジュール関数
    module_function
    def hoge
    end
end
```

Mathモジュールでsqrtはモジュール関数として定義されている。
よって、include先ではprivateメソッドとなりインスタンスメソッドとしては呼び出せなかった。

```ruby
Math.sqrt(2)
#=> 1.4142135623730951
```

上記のようにMathモジュールの特異メソッドとして呼び出すことができるのも、モジュール関数だからなんですね。

##　終わりに
理解が進んでいくと楽しいですね。
今後ともコツコツと日々精進。
Mac デフォルトシェルを zsh から bash に戻す！

# Macのデフォルトシェルが変更になっていた。
macOS Catalina から デフォルトシェルが`bash`ではなく`zsh`になってしまったらしい！
参考にしてたサイトに`.bash_rc`とか`.bash_profile`とかあった場合、コピペ導入しても動かなくて初心者さんはビビるのではないか！

# bashに戻してみよう
## デフォルトシェルをbashに変更する
```zsh
$ chsh -s /bin/bash
```

## デフォルトシェルをzshに戻したい場合
```bash
$ chsh -s /bin/zsh
```

----
よかったよかった
ゼロから始めるLeetCode Day1 「1389. Create Target Array in the Given Order」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

基本的にeasyのacceptanceが高い順から解いていこうかと思います。

# 問題

[1389. Create Target Array in the Given Order](https://leetcode.com/problems/create-target-array-in-the-given-order/)

問題としては、
・返す配列(array)は最初は空。
・nums[i]とindex[i]が与えられて、indexの場所にnumsを挿入する。
・numsとindexの要素がなくなるまで繰り返す。
最後に配列(array)を返して終わり。

想像つかない場合は実際に読んでみてください。

```Python
class Solution:
    def createTargetArray(self, nums: List[int], index: List[int]) -> List[int]:
        target = []
        for i in range(len(nums)):
            target.insert(index[i],nums[i])
        return target

# Runtime: 36 ms, faster than 36.25% of Python3 online submissions for Create Target Array in the Given Order.
# Memory Usage: 13.9 MB, less than 100.00% of Python3 online submissions for Create Target Array in the Given Order.
```


ぱっと思いついたのはこれ。
numsとindexの要素数は同じという前提がConstraintsに書いてあったので、それなら一回for文で回してその要素数をそれぞれinsert関数の中に入れてしまえばいいねというもの。
ただ、速くなく、ありきたりすぎる気がする。

他に考えついたのはwhile文で書くことだが、
[Pythonを速くしたいときにやったこと](https://qiita.com/shaka/items/f180ae4dc945dc7b9066)によると、Pythonではwhile文の方が遅いようだ。

なお、一応念のために書いて実行してみた。

```Python
class Solution:
    def createTargetArray(self, nums: List[int], index: List[int]) -> List[int]:
        target = [0]*len(index)
        j = 0
        while j < len(index):
            target.insert(index[j], nums[j])
            j += 1
        return target[:len(nums)]

# Runtime: 36 ms, faster than 36.25% of Python3 online submissions for Create Target Array in the Given Order.
# Memory Usage: 13.8 MB, less than 100.00% of Python3 online submissions for Create Target Array in the Given Order.
```

...あれ？
同じやんけ。
むしろメモリの使用量ちょっと少ないし。

ま、まぁ一旦ひとまずこれはおいておいて、大幅に速度が上がるものではありませんでした。


私が思いつかなかったものとしては、zip関数を使ったもの、スライスを使ったものです。

zip関数は、[公式ドキュメント](https://docs.python.org/ja/3/library/functions.html#zip)に記載されている通り、
>それぞれのイテラブルから要素を集めたイテレータを作ります。
この関数はタプルのイテレータを返し、その i 番目のタプルは引数シーケンスまたはイテラブルそれぞれの i 番目の要素を含みます。このイテレータは、入力イテラブルの中で最短のものが尽きたときに止まります。単一のイテラブル引数が与えられたときは、1 要素のタプルからなるイテレータを返します。引数がなければ、空のイテレータを返します。

というもので、

```Python
hoge = [1,2,3,4,5]
foo = [6,7,8,9,10]
bar = zip(hoge,foo)
list(bar)
[(1,6),(2,7),(3,8),(4,9),(5,10)]
```

以上のような動きをします。


なお、これを使っているものとしては、[こちら。](https://leetcode.com/problems/create-target-array-in-the-given-order/discuss/547418/Python3-Easy-Solution-with-zip-and-insert)

```Python
class Solution:
    def createTargetArray(self, nums: List[int], index: List[int]) -> List[int]:
        res = []
        for i, v in zip(index, nums):
            res.insert(i, v)
        return res
# Runtime: 28 ms, faster than 90.08% of Python3 online submissions for Create Target Array in the Given Order.
# Memory Usage: 13.8 MB, less than 100.00% of Python3 online submissions for Create Target Array in the Given Order.
```

速い！
これ以降は似た問題が出た場合にはzip関数を使った方が良さげですね。

お疲れさまでした、また解いて記事をかけたらなと思います。

~~せっかくだし空いてる時間を使ってPythonのfor文とwhile文の速度に関する記事も書いてみようかな・・・~~
【JavaScript】getElementById

<p>JavaScriptでコーディングしていると結構な頻度で使うであろうgetElementByIdに<br>ついて気になったので調べてみました。これも私の備忘録として残しておきたくて書きました。</p>
<h1>変数Aにid属性値hogeを代入する</h1>

<div class="code-frame" data-lang="text"><div class="highlight"><pre><code>var A = document.getElementById(‘hoge’);
</code></pre></div></div>

<p>※変数名とid属性値は本記事用に変更しております。</p>
<h2>上記ソースコードの意味</h2>
<p>①　varでAという変数を宣言<br>②　ある要素のid属性値として定義しているhogeをAという変数へ代入</p>
<h3>まとめ</h3>
<p>JavaScriptにおけるgetElementByIdは変数で使用されることが多いと思われる。<br>今回のソースコード例でいうと要素のid属性値をJavaScriptのプログラムで<br>定義された変数へ代入するということが分かった。<br>このロジックが理解出来ただけでも私はかなりの収穫だと感じている。</p>
備忘録　Rubyのインスタンス変数で『ん？』となったところ


Rubyのclassを勉強していてつまづいたところを備忘録として残します。


# 環境
ruby 2.6.3

## インスタンス変数とローカル変数

ゲームを想定して、勇者と敵をクラスで定義して戦わせることに。
攻撃や回復はモジュールで実装しました。
以下コード

```ruby
module Skill
    def nomal_attack(enemy)
        if rand(3) - 1 == 1
            enemy.hp = enemy.hp - attack * 2
            puts "#{name}の攻撃、会心の一撃！ #{enemy.name}に#{attack * 2}のダメージ"
        else
            enemy.hp = enemy.hp - attack
            puts "#{name}の攻撃、#{enemy.name}に#{attack}のダメージ"
        end
    end
    def kaihuku
        hp = hp + 120
        puts "回復魔法！#{name}はHPを120回復した"
    end
end

class Hero
    include Skill
    attr_accessor :name,:attack,:hp
    def initialize(name,attack,hp)
        @name = name
        @attack = attack
        @hp = hp
    end
end

class Enemy
    include Skill
    attr_accessor :name,:attack,:hp
    def initialize(name,attack,hp)
        @name = name
        @attack = attack
        @hp = hp
    end 
end


yusya = Hero.new('勇者',120,500)
teki = Enemy.new('スライム',80,400)
```

実行すると

undefined method `+' for nil:NilClass (NoMethodError)
と出てエラーに。

回復魔法のコード

```ruby
hp = hp + 120
```
がエラー出ている模様。
てことで

```ruby
@hp = @hp + 120
```
インスタンス変数に書き直すとうまく動いた、
が、何だかモヤモヤ、、、

nomal_attackメソッドの中身

```ruby
enemy.hp = enemy.hp - attack * 2
```
こちらはインスタンス変数じゃなくてもうまく動いたのに、、、
なぜかなぁ？と調べてみたら理由は簡単でした。

## 結論：ローカル変数だと認識されている


```ruby
hp = hp + 120
```
と書くとhpというローカル変数に　hp + 120　を代入せよと解釈されてしまうのです。
hpって何？定義して！
というrubyからの訴えだったわけです。

解決策としてインスタンス変数に変更、
もしくは

```ruby
self.hp = self.hp + 120
```
のようにインスタンス自信を表すselfをつけてあげる。
見積もりとは

見積もりをするのか、見積もりとは等をまとめる

#「見積もり」とは
「見積もり」を理解するために重要だと思われる単語

**コミットメント**・・・期日までに納品するという約束
**見積もり**・・・プロジェクトにかかる期間やコストを予測すること
**ターゲット**・・・目標を明文化したもの
　　例.法令へのコンプライアンス上、これらの機能を7月1日までに完成させなければならない
　　　 年末年始の商戦に間に合うように、このリリースを安定させなければならない
**計画**・・・特定の到達点に達するための手段を特定する作業
（参考文献1より）　　　　

**「見積もり」は期日までに納品するという約束（コミットメント）ではない**
**（職場で見積もりを求められる際は、コミットメントを求められているのか注意が必要）**




参考文献1：ソフトウェア見積り ～人月の暗黙知を解き明かす～（スティーブ マコネル (著), 久手堅 憲之 (監修), Steve McConnell (原著), 田沢 恵 (翻訳), 溝口 真理子 (翻訳)
Devise/OmniAuthを使ってSNSログイン実装しました系記事で気になる3つのこと

ritouです。

OAuth👮‍♂️のパトロールによく引っかかる投稿としてこんな感じのがあります。

* Rails で Twitter や facebook とかのアカウントを使ったSNSログイン/ソーシャルログインを実装します！
* devise や omniauth を使います！
* DBのマイグレーション、エンドポイント追加、コールバックの処理、こうして、こう！こうして、こう！
* 動いた！！！

みたいな記事です。

["devise omniauth" で検索するともりもり出てきます。](https://qiita.com/search?q=devise+omniauth&sort=created)

似たような記事もあるので、誰かが誰かの記事を参考にして書いてそれをまた誰かが...と言うもはや伝統芸能の類のようにも見えてきますが、これ系の記事で気になる点をいくつか残しておきますので今後書く人は参考にでもなさってください。

## SNSアカウントから内部のユーザーを引く時のキー

大体の記事は大丈夫ですが、ごく稀にSNSアカウントから取得したメールアドレスをキーにして内部のアカウントを参照している記事が見られます。
このような実装では、Facebook, GithubなどのSNS上でユーザーが登録しているメアドを変更した場合、元のメアドに紐づいているユーザーとしてログイン不可となるでしょう。
また、将来的にメアドがリサイクルされ第3者が利用するようになった場合にも、想定していないアカウント紐付けが発生する可能性があります。

SNSから受け取るメールアドレスは普遍的な値ではない、つまり変更される可能性があるものとして取り扱うべきです。
SNSから受け取ったユーザーIDをキーにしましょう。複数のSNSをサポートする場合はSNSの識別子とユーザーIDとなるでしょう。

このコメントでちょっと細かく書いてます。
https://qiita.com/u-dai/items/91df3b923dc82fed5b76#comment-becfe55135f1aa83064a

**英語ですが、Deviseのwikiにも書いてあります。**
https://github.com/heartcombo/devise/wiki/OmniAuth:-Overview

> def self.from_omniauth(auth)
>  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|

## SNSアカウントに紐づいた User オブジェクトのメアドやパスワード

SNSでログインしようとしたがまだ登録されていない！って言う時に何かちょっと足したりしつつusersテーブルに突っ込むわけです。ここでusersテーブルってののemailとpasswordが必須！でもメアドはSNSアカウントにない場合もあるしパスワードがないのがSNSログインです。

何が行われるかと言うと、**メアドならダミーメールアドレスとか言ってSNSのIDとサービス名とかくっつけたりしたダミーメアドを作成したり、パスワードは `Devise.friendly_token` とか使ったり。そしてダミーメアドはユーザーに見せない様にしたりします。**
この様な方法でSNSでのログインだけを実装する場合は大きな問題とはならないかと思います。サービスからメール送信みたいな機能がなければ。

しかし、すでにメアド/パスワードによるログインを実装済みの所にSNSでのログインを導入！ってやる場合は **"ユーザーには見せていない内部用のメールアドレスと、ユーザーには見せていないのでわからないはずのパスワードでログインできる状態"** となります。SNSから登録したユーザーのパスワード認証を無効にする方法もありそうですが、そもそもそれができる人はダミーのメアドやランダム風なパスワードなんて生成して保存しないでしょう。
自分が採用したい認証方式を振り返り、パスワード認証を利用している場合はこれが許容できるのかどうか、よく確認する必要があるでしょう。

上述のDeviseのWikiの文章ではこのfriendly_token使ってました。良くないですね。

## :provider_ignores_state => true

OAuth 2.0 ベースのSNSの場合、何かのエラーをこのパラメータを設定して乗り越える記事があります。
CSRF対策を行なおうとしたら不足しているロジックがあったためエラーになったものを、CSRF対策自体を取り除くことで回避しようとするのはもはや悪手と言えるでしょう。

## 終わり

自分は普段Rails使わないので見逃してるものもあるかもしれませんが、せっかくのアウトプットなので他の人のやり方を参考にしつつも悪い実装は避け、全体の質を上げていけると良いと思います。
pythonのmusic21ライブラリとAIきりたんはとても楽しいのでTIPS

別に行き先を決めているわけじゃないが、保たなそうなので、身の振り方を考えるかも。

まあそれはそうと、NEUTRINOによる東北きりたん、と言えばいいのか、「AIきりたん」で遊んでいる。作曲なんて久しぶりで楽しい。で、スキャットとかしてもらうのもいいな、とか、メロディー以外にもきりたんに頑張ってもらおうと思うと、やっぱりそこはちょいちょい自動化できそうな気がしてくる。

で、そういう効率化をしようとすると、 *.musicxml を出力して *.f0 とか *.lab とかも弄って、ということになろうかと思うが、labはただのテキストファイルだし、f0はnumpy.fromfileで読めちゃうのでここはやはりmusicxmlが一番手間がかかる。ただ、調べてみると、pythonのmusic21ライブラリが便利らしい。自動作曲等の世界では有名らしい。普通にpip install music21で入ってくれたし、NEUTRINO的に大事なポイントはすべて押さえてくれていた。超ありがたいので、この気持ちもそのうち歌にしようとおもう。

ちなみにそのポイントとは下記だ。
・タイが書ける（これは書けなきゃダメすぎる）
・2バイト文字の歌詞が入れ込める（そしてもちろん化けない）
・ブレス記号が入れられる（少なくとも、コンマ型のブレス記号なら、NEUTRINOは確実に見てくれる）
というこんな感じ。

全部OKでした。パーフェクト。というわけで、music21のドキュメントは読みやすいので別に余計なお世話かもしれないけど、下記に上記3点のサンプルを載せておいた。これなら、バックコーラスをコード指定しておいて、声部ごとにmusicxml吐いて、NEUTRINOでレンダリングして、pysoundfileで統合して、とかできちゃうじゃん！　最高です。AIきりたん勢は、ぜひ、これを活用してバックコーラスにもきりたんを並べてほしい。

いろいろ説明不足だと思うけど、まあ地味に気が多いのでこのへんで。

```python
import music21 as m2

if False:
    # これはインストール直後に1回実行すれば事足りる
    # というか、その後実行するとエラーを吐くのでコメントアウト
    usersettings = m2.environment.UserSettings()
    usersettings.create()
    usersettings['musescoreDirectPNGPath'] = \
        'C:/Program Files/MuseScore 3/bin/MuseScore3.exe'
    usersettings['musicxmlPath'] = \
        'C:/Program Files/MuseScore 3/bin/MuseScore3.exe'

# ストリーム全体に関わる設定：楽器名とか調とか
mystrm = m2.stream.Part()
# 楽器
myinst = m2.instrument.Instrument()
myinst.partName = "Kiritan"
mystrm.append(myinst)
# 調号
mystrm.append(m2.key.Key('b-', 'minor'))
# 音部記号
mystrm.append(m2.clef.TrebleClef())
# mystrm.append(m2.clef.BassClef()) へ音記号

for x in range(8):
    # 小節を作って、そこに音符を放り込んでゆく
    cur_measure = m2.stream.Measure()
    n = m2.note.Note(x + 64, quarterLength=2, lyric='よ')
    # コンマ型ブレスは、直前の音符に属している
    b = m2.articulations.BreathMark()
    b.symbol = 'comma'
    n.articulations.append(b)
    cur_measure.append(n)
    # 休符
    cur_measure.append(m2.note.Rest(quarterLength=2))
    # 音符を放り込んだ小節をストリームに放り込む
    mystrm.append(cur_measure)

# タイでつなぐ（始点ならstart）
cur_measure = m2.stream.Measure()
cur_measure.append(m2.note.Rest(quarterLength=2))
n = m2.note.Note(60, quarterLength=2, lyric='う')
n.tie = m2.tie.Tie('start')
cur_measure.append(n)
mystrm.append(cur_measure)

# タイでつなぐ（3つつなぎなら真ん中はcontinue）
cur_measure = m2.stream.Measure()
n = m2.note.Note(60, quarterLength=4, lyric='ー')
n.tie = m2.tie.Tie('continue')
cur_measure.append(n)
mystrm.append(cur_measure)

# タイでつなぐ（終点ならstop）
cur_measure = m2.stream.Measure()
n = m2.note.Note(60, quarterLength=2, lyric='ー')
n.tie = m2.tie.Tie('stop')
cur_measure.append(n)
cur_measure.append(m2.note.Rest(quarterLength=2))
mystrm.append(cur_measure)

# スコアに放り込んで完了
myscore = m2.stream.Score()
myscore.append(mystrm)
myscore.show('musicxml')
```
SinatraのGemについて

Sinatraで一般的に使われるgemをまとめてみました。
それぞれの役割を簡単に紹介します！

#そもそもSinatraとは
**Sinatra**はRubyの※Gemの1つで、ウェブアプリケーションの開発時に必要な機能を提供してくれます。

※Ruby用のライブラリのことを「Gem」といいます。

#Sinatraで利用されるGemについて
個人的メモ。

##gem "sinatra"
そのまんま。sinatra使うためのgem。

##gem "sinatra-reloader"
コードの変更時にRubyファイルを自動的に再読み込みてくれるgem。
Sinatraアプリ内でrubyファイルを編集した時にこれがあると自動的に読み込んでくれて、変更した時にアプリケーションの再起動が必要なくなります。

詳しくは下記参照
[SINATRA::CONTRIB](http://sinatrarb.com/contrib/)

##gem "sinatra-activerecord" / gem 'activerecord', '~> 5.2.0'
sinatraでActiverecordを利用するために必要なgem。
ActiverecordがあればSQLを直接モデルに書かなくてもライブラリが自動的にSQL化してくれる。
アプリケーションを作成するのであれば、上記2つに合わせて**gem "sqlite3"**と**gem "rake"**も必要！ハッピーセット的な！

##gem "sqlite3"
データベースの**SQLite3**を利用するために必要なgem。組み込みデータベース。

データベースの**SQLite3**を利用するメリットとしては、
- 動作が軽い
- 著作権がない
- ファイルが1つだけなので、バックアップや復元が簡単
- サーバ側でデータベースを用意する必要がない 等々

SQliteとMySQLの違いは下記参照
[OSS×Cloud News/MySQLとSQLiteを比較](https://www.ossnews.jp/compare/MySQL/SQLite)

##gem "rake"
**rake db:create_migration**や**rake db:migrate**のコマンドを使えるようにするために入れる。Activerecordを使ったデータベースのマイグレートに使う。

##gem "pry"
binding.pryを利用するために必要。
この機能は、デバッグ、開発者コンソールの実装、ホットパッチの適用などに使用できる。

#最後に
補足や修正があれば教えてください！

ちなみにローカルでsinatraアプリを立ち上げる際は、**bundle exec ruby pictweet.rb**をターミナルに打ち込んだ上でhttp://localhost:4567/ を開く！
Railsチュートリアル備忘録 -テスト編-

## テスト
### ページが存在することの検証
```
  test "should get home" do
    get root_path
    assert_response :success
  end
```
### タイトルの検証
```
  test "home title" do
    get root_path
    assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
  end
```
## 統合テスト
### 作成
```
$ rails g integration_test テスト名
```
### 検証
```
$ rails test:integration
```
### 特定のHTMLが存在するかどうか
```
assert_select "文章"
```
#### あるパスが存在するかどうか
```
assert_select "a[href=?]", パス
例：assert_select "a[href=?]", about_path
```
#### あるバスが特定の個数存在するか
```
assert_select "a[href=?]", パス,count:数字
例：assert_select "a[href=?]", root_path, count: 2
```
|  Code  |  マッチするHTML  |
| ---- | ---- |
|assert_select "div"|	`<div>foobar</div>`|
|assert_select "div", "foobar"	|`<div>foobar</div>`|
|assert_select "div.nav"	|`<div class="nav">foobar</div>`|
|assert_select "div#profile"	|`<div id="profile">foobar</div>`|
|assert_select "div[name=yo]"	| `<div name="yo">hey</div>`|
|assert_select "a[href=?]", '/', count: 1	|`<a href="/">foo</a>`|
|assert_select "a[href=?]", '/', text: "foo"	|`<a href="/">foo</a>`|
## 追加中...
Adobe Fonts(Typekit) フォント実体ファイル保存場所 Windows10

下記フォルダに実体・関連ファイルがある。

`~\AppData\Roaming\Adobe\CoreSync\plugins\livetype\`

```
├─c
│ ├─entitlements.xml < フォントメタ情報ファイル？
│ └─entitlements-downloading.xml
├─e < Mac用フォントファイル？
├─r
│ ├─...
│ └─00000 < TTFファイル
├─t
├─u
└─w
```

ファイルは、 `~\AppData\Roaming\Adobe\CoreSync\plugins\livetype\r\` に入っている。
ファイル名は `15506` など五桁の数字となっており、拡張子もついていない。

その数字は、フォント識別のIDで下記ファイルを確認するとフォント名などが確認できる。

`~\AppData\Roaming\Adobe\CoreSync\plugins\livetype\c\entitlements.xml`

```entitlements.xml
<?xml version="1.0" encoding="UTF-8"?>
<typekitSyncState>
  <state>beb51a66195a9c40b4169a1252f92bba30ef42f2</state>
  <fonts type="array">
    <font>
      <url>https://api.typekit.com/desktop_v2/sync/0A8E37605B307D880A495EF3%40AdobeID/TkD-15506-6c936d2a512e424ed844e67c36bdfe0c0a78871a</url>
      <id>15506</id>
      <properties>
        <fullName>Roboto Light</fullName>
        <familyName>Roboto</familyName>
        <variationName>Light</variationName>
        <familyURL>https://typekit.com/fonts/roboto</familyURL>
        <sortOrder>600</sortOrder>
        <owner>Adobe Fonts</owner>
        <installState>OS</installState>
        <installStateUpdatedAt type="dateTime">2019-09-13T01:54:28Z</installStateUpdatedAt>
        <syncFontId>TkD-15506-6d844e67c36bc936d2a512e424edfe0c0a78871a</syncFontId>
        <familyWebId>dwgd</familyWebId>
        <fvd>n3</fvd>
      </properties>
    </font>
```
[error] apt update -> The following signatures couldn't be verified...

備忘録です。

# 現象
以下のコマンドでエラーが出ます。

```
$ sudo apt update
...
Err:3 http://ppa.launchpad.net/appgrid/stable/ubuntu bionic InRelease                                         
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 241FE6973B765FAE
Reading package lists... Done                                                                                                                                                                                     
W: GPG error: http://ppa.launchpad.net/appgrid/stable/ubuntu bionic InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 241FE6973B765FAE
E: The repository 'http://ppa.launchpad.net/appgrid/stable/ubuntu bionic InRelease' is not signed.
```

# 結論
公開鍵を持っていないようなので取得してきます。
最後の文字列はエラーメッセージの**NO_PUBKEY**の後の文字列を。

```
$ sudo apt-key adv --keyserver keys.gnupg.net --recv-keys 241FE6973B765FAE
```

幸せになります。

```
$ sudo apt update
Hit:1 https://download.docker.com/linux/ubuntu bionic InRelease
Hit:2 http://packages.microsoft.com/repos/vscode stable InRelease                                      
Hit:3 http://apt.galliumos.org bismuth InRelease                                                       
Get:4 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]                            
Hit:5 http://archive.ubuntu.com/ubuntu bionic InRelease                         
Get:7 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]                              
Hit:8 http://ppa.launchpad.net/ondrej/php/ubuntu bionic InRelease                                      
Get:6 http://ppa.launchpad.net/appgrid/stable/ubuntu bionic InRelease [15.4 kB]                        
Get:9 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]          
Get:10 http://ppa.launchpad.net/appgrid/stable/ubuntu bionic/main amd64 Packages [572 B]
Get:11 http://ppa.launchpad.net/appgrid/stable/ubuntu bionic/main Translation-en [412 B]
Fetched 268 kB in 4s (64.6 kB/s)         
Reading package lists... Done
Building dependency tree       
Reading state information... Done
35 packages can be upgraded. Run 'apt list --upgradable' to see them.
```

ありがとう -> [参考元](https://ebc-2in2crc.hatenablog.jp/entry/2020/01/22/120432)
デメテルの法則

「ドットがつながったらあかんで」とかいうやつ、くらいの認識しかなかったが整理できたのでメモ。

結論としては、「ドットがつながったらあかんで」ではなく、「ドットがつながったときは不要な依存をつくっちゃう場合があるから、ほんとにそれでいいかよく考えなね」であると理解した。

### 飛び越えた依存

例えば以下のようなコードを考える。
（以下、barや@barはBarインスタンスであることを前提とし、bazについても同様。）

```ruby
class Foo
  def foo_method
    @bar.baz.baz_method
  end
end
```

あるいは、こんなコード。

```ruby
class Foo
  def foo_method(bar)
    bar.baz.baz_method
  end
end
```

Fooの中で@bar/barに対して`Bar#baz`というメソッド呼び出しをしているので、FooはBarのインターフェースを知っている=FooはBarに依存していることになる。

これは以下のように図示できる。

```
Foo -> Bar
```

ではBarとBazの関係はどうだろうか。

ここでは、`Bar#baz`がBazインスタンスを返している。

そのばあい、確証はないけどBarはBazインスタンスに対してあれこれメソッド呼び出しをすることが多い。

（たとえば`Customer#wallet`がWalletインスタンスを返す場合、Customerは`Customer#pay`の中で`Wallet#withdraw`を呼び出したりする。）

このとき、BarはBazに依存している。

```
Foo -> Bar -> Baz
```

そんで、上記の例だとFooは`Baz#baz_method`を呼んでいるので、FooはBazのインターフェースを知っている=依存している。

```
Foo -> Bar -> Baz
  |            ^
  |____________|
```

FooはBarを飛び越えてBazにも依存しているわけだ。



### それで、どうする？

この飛び越えた依存を解消するためにBarにメソッドを生やす、というやり方は明らかなので示さない。

（よくみるdelegateもつまりはBarにメソッドを生やす1つの方法だ。）

ここで問いたいのは、上記の飛び越えた依存が「解消すべきものなのかどうか」だ。

答えは、場合による。



##### 飛び越えた依存を解消すべき場合

[こちらの記事](https://www.dan-manges.com/blog/37)のPaperBoyの例は、飛び越えた依存を解消すべき場合だ。

依存関係を先程の図に当てはめると以下のようになる。

```
PaperBoy -> Customer -> Wallet
  |                       ^
  |_______________________|
```

これらのモデルによって表現されている現実においては、PaperBoyはWalletのことを知る必要はない。

よって、「PaperBoyはWalletのことを知らない=依存しない」形の設計によって現実を適切にモデリングできると判断できる。

不要な依存関係はつくらない方がよいし、それに「依存関係の不在」も含めてなるべく現実に近いモデリングをしておいた方が、今後現実に生じる出来事をモデルの中で表現しやすくなる。

だからこうすべきなのだ。

```
PaperBoy -> Customer -> Wallet
```

##### 飛び越えた依存を解消すべきではない場合

[上述の記事](https://www.dan-manges.com/blog/37)の後半に記載されているのは、必ずしも依存を解消すべきとは限らないことの良い例だ。（以下ではクラス名に多少の改変を加えている。）

```
OrdersCotroller -> Order -> Customer
  |                             ^
  |_____________________________|
```

ユースケース層に属しているOrdersControllerにとっては、OrderとCustomer両方のインターフェースを知っている=依存しているのはごく自然なことだ。

むしろ、モデルたちを並列的に扱うことが期待されるコントローラが、Customerに対する操作を逐一Order経由で行うことの方が不自然である。

デルメルの法則は私たちに「本当にその飛び越えた依存が存在していいの？」と問いかけるが、この場合は「もちろん。その依存関係は許容されるものだ」と胸を張って答えればいい。

デルメルの法則は絶対に従うべき掟ではなく、不注意な過ちを防ぐための注意書きに過ぎない。

---

もう1つ例を挙げよう。

```
Order -> Customer -> String
  |                    ^
  |____________________|
```

たとえば`Order#summary`の中で`customer.name.upcase`などを呼ぶ場合に、上記の依存関係が発生する。

この場合、`Customer#name_in_upcase`を定義して、飛び越えた依存を解消すべきだろうか？

いや、OrderがRubyの組み込みクラスであるStringのインターフェースを知っているのはごく自然なことなので、この「飛び越えた依存」はあって然るべきものだ。

より実際的に言うならば、Stringは十分に安定的であり変更可能性が小さいので、その僅かなリスクのために`Customer#name_in_upcase`を生やすというコストを払うのは賢明ではない。

### 総括

デメテルの法則は「こういう場合には注意した方がいいよ」というだけで、何をすべきかを指示するものではない。

注意したうえでどう判断するかは、状況次第である。

しかも、上記の例では依存を解消すべき/すべきでないことが明らかな例を挙げたが、そうした判断は必ずしも自明ではない。

「FooがBazを知っている形の設計にする」か「FooがBazを知らない形の設計にする」かは、多くの場合「そのドメインをどのようにモデリングするか」という、"決め"の問題になることも多いように思う。

以上適当なメモなので誤りなどあればご教示ください。
DockerでPulseaudioを使って，ホストで音を出していてもコンテナで音を出せるようにする．

# 背景
Dockerで音を鳴らそうとしたら以下のようなErrorが出た時のお話

```
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Protocol error

Playback open error: -111,Connection refused
```

```
ALSA lib pcm_dmix.c:1052:(snd_pcm_dmix_open) unable to open slave
aplay: main:788: audio open error: Device or resource busy
```

ここではaplayを使って音を出そうとしてるよ

# 必要な知識
> ALSA と PluseAudio の関係
歴史的な理由からか、Linux の音声入出力は PulseAudio と ALSA の二階建てになっている。ALSA は個々のサウンドカードを担当するのだが、一つのサウンドカードには一つのアプリしかアクセス出来ない。複数のアプリの音声入出力を調停するのは PulseAudio が担当している。具体的には、次のようになっている。

> ALSA は色んなサウンドカードを統一的に操作出来るようにする仕組み。
アプリは直接 ALSA を操作しなくても良い。
あるアプリが ASLA 経由でサウンドカードを操作している間、他のアプリからそのサウンドカードを使えない。
とはいえ、直接 ALSA を使って音声入出力を行うアプリが存在する。
PluseAudio は複数のアプリが同時に同時にサウンドカードを使う仕組み。
お行儀の良いアプリは ALSA ではなく、PulseAudio 経由で音声入出力を行う。
とはいえ、直接 ASLA を使ってしまうアプリのために仮想サウンドカードの仕組みがある。
お行儀の良いアプリは PulseAudio 経由で音声入出力を行う事を期待しているが、ALSA を直接使ってしまうアプリのために PulseAudio は仮想サウンドカードとしても動作する。

> ASLA から見ると、PulseAudio は default サウンドカードとして動作する。
アプリが default サウンドカードを通して再生を行うと、実際には PulseAudio がミキシングしてデフォルトのサウンドカードに音をだす。

> https://qiita.com/propella/items/4699eda71cd742cba8d3

# テストの仕方
コンテナ内で，


## サンプルデータのダウンロード

```
$ wget http://freewavesamples.com/files/Kurzweil-K2000-Dual-Bass-C1.wav
```

> https://qiita.com/propella/items/4699eda71cd742cba8d3

## サンプルデータの再生
```
aplay Kurzweil-K2000-Dual-Bass-C1.wav
```
`aplay -l` とか `aplay -L` でサウンドデバイスを確認できるよ．
`aplay`は`apt install alsa-utils`で入れられるよ．
ただし，今回はno soundcards foundでおっけーだよ

# Dockerfileの設定
`apt install pulseaudio`を入れておく．

# DockerをRunするときの設定
## 準備
### pulseaudio.socket ってファイルを生成する
ホスト側で

```
$ pacmd load-module module-native-protocol-unix socket=/tmp/pulseaudio.socket
```
すると`/tmp`に生成される．

### pulseaudio.client.conf ってファイルを作る
`/tmp`に`pulseaudio.client.conf`って名前のファイルを作る
つまり下記の通り

```
$ touch /tmp/pulseaudio.client.conf
```

そのファイルをテキストエディタやらで開いて，下記を書き込む

```
default-server = unix:/tmp/pulseaudio.socket
# Prevent a server running in the container
autospawn = no
daemon-binary = /bin/true
# Prevent the use of shared memory
enable-shm = false
```

## OptionsをつけてRunする
```
$ docker run --rm \
    --env PULSE_SERVER=unix:/tmp/pulseaudio.socket \
    --env PULSE_COOKIE=/tmp/pulseaudio.cookie \
    --volume /tmp/pulseaudio.socket:/tmp/pulseaudio.socket \
    --volume /tmp/pulseaudio.client.conf:/etc/pulse/client.conf \
    --user $(id -u):$(id -g) \
    imagename
```

# 結論
```
$ aplay Kurzweil-K2000-Dual-Bass-C1.wav 
```
してドゥーンってなれば成功です．
SQL学習2日目

SQLを学び始めて2日目です。
なかなか覚えるのが難しい。

###○今日覚えたこと

```sql:qiita.sql
select distinct(カラム名)
from テーブル名;
```
↑検索結果から重複するデータを除くことが可能

```sql:qiita.sql
select sum(カラム名)
from テーブル名;
```

↑指定したカラムに保存されたデータの合計を計算することが可能

```sql:qiita.sql
select avg(カラム名)
from テーブル名;
```

↑指定したカラムに保存されたデータの平均を計算することが可能

```sql:qiita.sql
select count(カラム名)
from テーブル名;
```

↑指定したカラムのデータの数を計算

```sql:qiita.sql
select max(カラム名)
from テーブル名;
```

↑指定したカラムのデータの中から最大のデータを取得することが可能

```sql:qiita.sql
select min(カラム名)
from テーブル名;
```

↑指定したカラムのデータの中から最小のデータを取得することが可能

```sql:qiita.sql
select (カラム名)
from テーブル名
group by カラム名;
```

↑指定したカラムで、完全に同一のデータを持つレコードどうしが同じグループになる
※group byを用いる場合、selectで使えるのは、group byに指定しているカラム名と、集計関数のみ
※group byはwhereとも併用することができ、その場合はwhereの後に書く

```sql:qiita.sql
select (カラム名)
from テーブル名
group by カラム名
having　条件;
```

↑group byでグループ化したデータを更に絞り込みたい場合には、HAVINGを用いる

```sql:qiita.sql
select (カラム名)
from テーブル名
where　条件 >(
 select (カラム名)
 from テーブル名
 where　条件
)
```

↑SQLでは、クエリの中に他のクエリを入れることができ、この他のクエリをサブクエリと言う
※サブクエリが実行された後、外側にあるクエリが実行される

```sql:qiita.sql
select (カラム名) as '変更したい名前';
```

↑asを使うことでカラム名などに別名を定義することができる

```sql:qiita.sql
select*
from テーブルA
join テーブルB
on 結合条件 テーブルA.カラム名 = テーブルB.カラム名;
```

↑joinは複数のテーブルを1つに結合したいときに使う。onで条件を指定して、テーブルAにテーブルBを結合する。結合したテーブルは1つのテーブルとしてデータを取得することができる。

```sql:qiita.sql
select*
from テーブルA
left join テーブルB
on 結合条件 テーブルA.カラム名 = テーブルB.カラム名;
```

↑left joinを使うことで、fromで指定したテーブルのレコードを全て取得(NULLのレコードもNULLのまま実行結果に表示される)
※joinやleft joinは複数回使用可
リストのメソッド

```python
r = [1, 2, 3, 4, 5, 1, 2, 3]
#r=[0, 1, 2, 3, 4, 5, 6, 7]
print(r.index(3))
print(r.index(3, 3))
print(r.count)

r.sort()
print(r)

r.sort(reverse=True)
print(r)

r.reverse()
print(r)
```

出力
2
7
2
[1, 1, 2, 2, 3, 3, 4, 5]
[5, 4, 3, 3, 2, 2, 1, 1]
[1, 1, 2, 2, 3, 3, 4, 5]



```python
s = 'My name is halu.'
to_split = s.split(' ')
print(to_split)

x = '#'.join(to_split)
print(x)
```
出
['My', 'name', 'is', 'halu.']
My#name#is#halu.
CSSでお絵描きした話

# 個人アプリにて...
　個人アプリ作成してる時に見た目が寂しいってことで装飾をつけることにしました。
　ポケモンのダメージ計算アプリを自作しているのでポケモンに関する絵をHTMLとCSSで描こうと思いまして、その時に使用したワンポイントについての記事です。

## 半円を描く

```ruby:css
.class {
  height: 25px;
  width: 50px;
  background-color: red;
  border-radius: 100px 100px 0 0;
}
```
<img width="121" alt="スクリーンショット 2020-05-14 22.57.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636322/a0ae7822-ecfc-9fc6-c07c-eb08fa66bfaf.png">

 　heightとwidthは各々の好きな大きさにしていただくといいのですが、大事なのはborder-radiusです。
　border-radius: 100px;で綺麗な円を描けます。
　(下の赤丸は高さ、幅共に50pxに設定)
<img width="125" alt="スクリーンショット 2020-05-14 22.52.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636322/ae327290-e894-a1c3-f489-550623e14136.png">

　なので :100px 100px 0 0;で左上、右上だけを丸めてるんですね。

### 三角形を描く

```ruby:css
class {
  height: 0;
  width: 0;
  border: 30px solid transparent;
  border-right: 30px solid yellow;
}
```
<img width="115" alt="スクリーンショット 2020-05-14 23.01.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636322/0e507c36-042b-94bf-377f-75330e8477e4.png">

三角形はborderの性質を利用して描きます。

**borderの性質**
　四方にborderをつけるときborder同士の設置面は斜めに設置します。
　と言ってもわからないと思いますが違う色のborderのくっつけてみると分かりやすいと思います。

```ruby:css
class {
  height: 30px;
  width: 30px;
  border-right: 20px solid yellow;
  border-top: 20px solid green;
}
```

<img width="100" alt="スクリーンショット 2020-05-14 23.15.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636322/2dca7e62-d3d4-c710-6692-a0e1b9628da5.png">
　このように緑と黄色が斜めに接地してます。これを利用し、3方向の色を透明にすることで色をつけた一方向のみが映し出されて三角形を描くことができます。

px数の関係性としては
　border...底辺の長さ
　border-方向...三角形の高さ　　がそれぞれ変化します。

### 要素を斜めに配置する

```ruby:css
class {
  height: 10px;
  width: 30px;
  background-color: blue;
  transform: rotate(-45deg);
  transform-origin: top center;
}
```
<img width="109" alt="スクリーンショット 2020-05-14 23.29.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636322/6504e648-785e-fb4c-a4de-3639848ff22c.png">
斜めに配置する際に大事なのは

- 傾ける角度
- 回転する際の軸　　　の二つです。

それぞれがtransform: rotate();とtransform-originの部分なわけです。

- transform: rotate();
 - カッコの中身が傾ける角度を指定しています。
 - 値に応じて、プラスの値で時計回り、マイナスの値で反時計回りに回転します。

- transform-origin: top center;
 - 基本形はtransform-origin: ;の中に%かキーワードで指定を行います。
 - transform-origin: top center;の場合、transform-origin: 50% 0%;と同じで、それが表すのは要素の左上を始点としてそこから右に50%、下に0%進んだ場所が回転軸になります。

<img width="170" alt="スクリーンショット 2020-05-14 23.45.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636322/ba0bde21-9eb5-68ef-a1e6-7112ebd72eb8.png">

####こう言ったものを利用して...

　cssを自由に使えれば実際なんでもかけるんだなって話です。皆さんも挑戦してみてください。
<img width="278" alt="スクリーンショット 2020-05-14 23.55.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636322/c49aac56-e19f-96f5-8deb-13d6c9de6be0.png">
2021年最新【EC2】 postgresql9.6、10、11をインストールする方法

ググってでて来る記事の通りに作業をするとリンク切れでec2にインストールできなかったのでまとめます。



```
$  yum update
$  yum install postgresql

noを選択する。すると下記の文字が現れる。

postgresql is available in Amazon Linux Extra topics "postgresql9.6" and "postgresql10" and "postgresql11"

To use, run
# sudo amazon-linux-extras install :topic:

Learn more at
https://aws.amazon.com/amazon-linux-2/faqs/#Amazon_Linux_Extras
```


で、下記を入力すればインストールできる。

```
$  sudo amazon-linux-extras install postgresql9.6
$  sudo postgresql-setup initdb
$  sudo systemctl start postgresql
$  su - postgres
$  psql
```

もっというと立ち上げ方法が変わった？ようです。





 http://code-aim.work/ec2-postgresql9-61011/
LaravelのPHPUnitでWithFakerなどのTraitが動かない

当初以下のようなコードを書いていたのだが、


```<?php

namespace Tests\Unit\Repositories;

use PHPUnit\Framework\TestCase;
use App\Models\User;
use App\Constants;
use App\Repositories\PgSql\UserRepository;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;

class UserRepositoryTest extends TestCase
{
    use WithFaker, RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
    }

    // expected 1 user is found, not others.
    public function testFindUserByAuthInfo()
    {
        $repo = new UserRepository();
        // findable
        $user = factory(User::class)->create([
            'id' => $this->faker->uuid,
            'password' => password_hash($this->faker->password(), PASSWORD_BCRYPT),
            'account_id' => 1,
            'email' => $this->faker->email,
        ]);
```
実行すると

```1) Tests\Unit\Repositories\UserRepositoryTest::testFindUserByAuthInfo
Trying to get property 'uuid' of non-object
```
と$this->fakerでFakerがインスタンス化できていない模様

散々調べた挙げ句、結局
```use PHPUnit\Framework\TestCase;```
を
```use Tests\TestCase;```
にしたら直ったというお話。
構文、式、文

ドワンゴ様の[scala研修資料](https://scala-text.github.io/scala_text/control-syntax.html)の続きを進めて行きます。
本日のBGMは[米津玄師ピアノメドレー](https://www.youtube.com/watch?v=zb8N5nDK974)で作業が進めていきましょう！

## 構文(Syntax)
構文はそのプログラミング言語内で、プログラムが構造を持つためのルールである。
多くの場合、言語内で特別扱いされるキーワードである。
例えば`class`や`val`,`if`など
classの場合であればclassの記述の後にはクラス名が必ずくるなどである。

## 式(Expression)
式はプログラムを構成する部分のうち、評価が成功すると値になるものである。
例えば`1`や`1+2`、`"Hello"`など。
これらは評価することにより数値や文字列の値となる。
値が変えれば成功。結果として例外が投げられた場合は評価が失敗したことになる。

## 文(Statement)
文は式とは対照的にプログラムを構成する部分のうち、評価しても値にならないものである。
例えば`val i = 1`は評価しても値にはならない。これは文である。

ScalaはCやJavaなどの手続き型の言語に比べて、文よりも式になる構文が多い。
Scalaでは文よりも式を多く利用する構文が採用されている。これにより変数などの状態をできるだけ排除したわかりやすいコードがかけるようになっている。

## ブロック式
Scalaでは`{}`で複数の式の並びを囲むと。それ全体が式になる。
便宜上それをブロック式と呼ぶ。
ブロック式の一般形は

```scala
{<式1>(;|<改行>) <式2>(;|<改行>)...}
```
となる。
式の並びは順番に評価される個々の式を表す。
式が改行で区切られていればセミコロンは省略できる。
`{}`式は`式1`、`式2`と式の並びを順番に評価し、最後の式を評価した値を返します。

```scala
{println("A"); println("B"); 1 + 2; }
```
この式ではAとBが出力され、最後の式である`1+2`の結果である`3`が`{}`式の値になっている。
このことはメソッドの定義などで重要になる。

scalaのメソッド定義では

```scala
def foo(): String = {
  "foo" + "foo"
}
```
このような形で定義することが一般的です。
ここでの`{}`は単に`{}`式であって、メソッドの定義の構文に`{}`が含まれているわけではない。
クラス定義構文においては`{}`は構文の一部である。

## if文
if文の構文は以下のようになる

```scala
if '('<条件式>')' <then式>　(else <else式>)?
```
条件式はBoolean型である必要があります。
`else<else式>`は省略することができる。
then式は条件がtrueの時に評価されるので、elseは条件がfalseの時に評価される式である。

if文を使ってみる

```scala
var age = 17

if(age < 18) {
  "18歳未満です"
} else {
  "18歳以上です"
}

age = 18

if(age < 18) {
  "18歳未満です"
} else {
  "18歳以上です"
}
```
変更可能なageが18より小さいかどうかで返す文字列を変えています。
if式に限らず、Scalaの制御構文は全て式である。
つまり何らかの値を返す。

またelseが省略可能であるが、以下のようにUnit型の値()が補われたのと同じ値が返ってくる。

```scala
if '('<条件式>')' <then式>else ()
```
Unit型は返すべき値がない場合に使われる。
唯一の値である`()`を返す。

### 練習問題
`var age: Int = 5`という年齢を定義する変数と、`var isSchoolStarted: Boolean = false`という就学を開始しているかどうかという変数を利用して、1歳から6歳までの就学以前の子どもの場合に幼児ですと出力し、それ以外の場合には幼児ではありませんと出力するコードを書いてみる。

```scala
var age: Int = 5
var isSchoolStarted: Boolean = false
object Main extends App {
  var age: Int = 5
  var isSchoolStarted: Boolean = false
  if (1 <= age && age <= 6 && !isSchoolStarted) {
    println("幼児です")
  } else {
    println("幼児ではありません")
  }
}
```