OmniAICreator/Qiita-1.07M huggingface dataset:
【個人開発】初心者がテックアカデミーに２ヶ月通ってオリジナルサービス（笑）を作った話。

昨年9月のこと、
テックアカデミーのWebアプリケーションコース（8週間）で、YouRoutine（https://www.youroutine.com/ ）というオリジナルサービスを作りました。

初心者がプログラミングスクールに通うと、どのぐらいのレベルに達するのかよく分かると思います。
これからスクールに行こうか迷っている人は参考にしてみてください。


#どんなサービス作ったの？

<b>YouRoutine</b> というサービスです。YouTubeの動画をキュレーションして作ったルーティンを共有できるプラットフォームです。

YouTubeの動画を選んで自分だけのルーティンを作成したり、他の人が作ったルーティンを取得したりできます。

https://www.youroutine.com/


![スクリーンショット 2021-05-11 20.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822866/c6876d97-ab59-6677-5ec3-24615507b38e.png)

これを作ろうと思ったきっかけなのですが、
YouTubeで動画を流しながら筋トレをしていたときに、以下の2点で課題を感じました。

<b>1. 冒頭の解説部分がいらない（一緒にやってくれるところだけ見たい）
2. 他の人はどんな筋トレをしているのか気になった。</b>

（1は、YouTubeの動画を埋め込む際に開始時間を指定できたので、それで解決しました。）

使用技術は、
・Rails
・Bootstrap
・Heroku
・Cloud9　　などです。


![スクリーンショット 2021-05-11 20.05.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822866/b3f4b656-7b63-bbf8-59ce-7f60b4067b1a.png)
#プログラミングスクール（テックアカデミー）に通った感想
結論から言うと、期待通りでかなり良かったです。
メンターの方も優しくて、質問もしやすい環境が整っていたと思います。

オリジナル教材も、初心者にも分かりやすい平易な文章で書かれていました。

課題を提出しエンジニアの人からフィードバックが貰えたので、客観的な視点から理解度を確かめられたのも良かったかなと。

「<b>自分でオリジナルサービスを公開する</b>」というゴールも達成できましたし、個人的には満足です。


ただ、<b>「17万円は高すぎません？？」</b>
って言うのも正直な感想です。

テックアカデミーを卒業してから独学で勉強をしていますが、絶対こっちの方がコスパ良いなと感じます。（金銭的にも、成長スピード的にも）

友達にも勧めるかと言われれば微妙です・・・。
（挫折しそうな人が復活材として使うのはオススメかも）


#最後に
成長を実感できるという意味でも、自分でサービスを作るのはかなり楽しいですね。
プログラミングを始めて良かったと心から思います。

ありがとう、TechAcademy。

ありがとう、厚切りジェイソン。
【誰でもわかる正規表現!】 やってみたら超簡単だった

#はじめに

&nbsp;みなさん、正規表現が便利なのは知っていますか?

Qiitaをご覧になっている方であれば、多くの人が YES と答えているでしょう。
では、正規表現使ってますか?
今度は、... という微妙なところでしょうか。

&nbsp;それもそのはずで、正規表現は理解のとっかかりが掴みづらい。
見慣れない記号が並んでいて、意味を把握するのが難しい。
その上、解説しているサイトも難解なものが多い。
（平易に説明しているものが少ない。）

&nbsp;このような状況の中で正規表現を使いこなせるようになるには、
...ズバリ 「用途を限定する」 ことでしょうか。

特定の用途なら割と簡単なものがあるので、1個でも組めれば、
それをきっかけにしてレパートリーが増えていくものかと。
そしていつの間にか、全体像を自然に把握しているようになります。

早い話がボトムアップ式で覚えていくのがベター!!


と、いうわけでこの記事では「正規表現で整数(半角)にマッチさせる」
ことを紹介したいと思います。

&nbsp;とりあえずこの用途だけなら簡単にマスター可能でしょう。

#対象となる読者

&nbsp;とりあえず、正規表現を使ってみたい人を対象としています。

- 簡単に説明してほしい
- 初心者で正規表現の予備知識が無い人
- 何らかのプログラミング言語を使っているが、正規表現は避けている
- テキスト処理で整数について処理したい
- オライリーの本は読む気がしない


こういった方に向けて説明します。

#参考にしたサイト
&nbsp;割と分かりやすく解説しているもの。
>
 [サルにもわかる正規表現入門](https://userweb.mnet.ne.jp/nakama/)
 [ゆびノート](https://www.yubinote.com/programming/regular_expression/article/character_class/meta2.html)
 [みやびのどっとぴーわい](https://miyabikno-jobs.com/re-alphanumeric/)

#動作環境
&nbsp;Python3系でいきましょう。
それでは以下から本編です。

#やりたい事
&nbsp;整数(半角)にマッチさせる。
但し以下の条件を満たすのもとする。

条件その1:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0~59までの範囲の数字

条件その2:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1桁の場合はゼロ埋めしない(02などは除外する)

#メタキャラクタ

&nbsp;正規表現では「メタキャラクタ」という記号を用いる事で整数を表現できる。
`\d` や `[0-9]` などである。
しかし `\d` はPythonだと半角整数だけでなく、全角数字など余計なもの([ゆびノート](https://www.yubinote.com/programming/regular_expression/article/character_class/meta3.html)さんによればジャワ数字もヒットしている)も含まれる。

&nbsp;そこで、`\d`　ではなく `[ ]` のほうを使う。
この記号は `[ ]` の中に指定した文字のどれかにヒットする。
0 から 9 までの数字を指定したい場合には `[0123456789]` でも可能だが、[サルにもわかる正規表現入門](https://userweb.mnet.ne.jp/nakama/)さんによると、面倒なので`[0-9]`でも大丈夫とのこと。

&nbsp;これで整数の表し方がわかったので、2桁の整数なら`[0-9]`を2つ並べて`[0-9][0-9]`とすればよさそうだ。
だがこれだと、整数が1桁の場合0埋め(03など)されてしまう。

... これに対処するには 1桁の場合と2桁の場合で別々に処理する。

#1桁の場合

&nbsp;条件は0~59までの数字なので、1桁のときは 0~9 までの数字を使う。
つまり、`[0-9]` でOKだ。

#2桁の場合
&nbsp;2桁の数字で条件を満たすものは 10~59 だ。
そうすると2桁目は、`[1-5]` で1桁目は `[0-9]` である。
二つ並べて`[1-5][0-9]`とする。

&nbsp;後は1桁の場合か2桁の場合かの、どちらかを表すメタキャラクタである `|` を使う。

`[0-9]|[1-5][0-9]`

これで完成と言いたいところだが、まだ問題が残っている。
それは、「数字の区切り」である。

#区切り文字
&nbsp;例えば&nbsp;15&nbsp;の場合なら2桁の数字としてマッチさせたい。
しかし残酷にもこれは&nbsp;15&nbsp;のうち&nbsp;1&nbsp;の部分が1桁の場合である`[0-9]`のほう（ | の左側）にマッチしてしまう。
&nbsp;これを回避するには、区切りを示すメタキャラクタである`\b`も付け加える。

`\b[0-9]\b|\b[1-5][0-9]\b`
これで&nbsp;15&nbsp;のような場合は2桁の数字としてマッチさせることが出来るようになる。

ようやく正規表現が完成したので次は、Pythonで実装してみる。

#Python!
```python:対話型より
#pythonから正規表現を使うには re をインポートする
>>> import  re
#作成した正規表現を compile() の引数に渡す
>>> pat = re.compile(r"\b[0-9]\b|\b[1-5][0-9]\b")
#判定対象の文字列
>>> score = "15 54 9 60 123 03 30"
#findall()はマッチがあるとリストを返す。（マッチしたもの全て）
>>> pat.findall(score)
['15', '54', '9', '30']
```
#まとめ
この記事では、次のような事を理解しました。

- 正規表現ではメタ文字を使う。
- メタ文字の `[0-9]` で整数を表せる。
- `A|B` は AかBかを示す。
- `\b` で区切りをつける。

&nbsp;今回は「整数」の取り扱いに的を絞りました。
簡単なものから実際に手を動かしてみる事で、徐々に理解が深まるのが実感できると思います。
正規表現はこの他にも多くの種類がありますが、本記事を契機としてレパートリーを増やしていきましょう!

&nbsp;なお、この記事を読んで簡単だと感じた`頭がいい人`は是非とも、オライリーの本や難解なサイトにも挑戦して下さい。

今回はこの辺で。
[wordpressエラー] CS_Query::get_endpoint_title($endpoint) should be compatible with WC_Query::get_endpoint_title  class-wcs-query.php


Woocommerce + Woocommerce Subscriptionsの4.7.0でエラーが出るので修正。

[参考](https://wordpress.org/support/topic/woocommerce-woocommerce-subscriptions-error-in-4-7-0-update/)

```
CS_Query::get_endpoint_title($endpoint) should be compatible with WC_Query::get_endpoint_title($endpoint, $action = ”) in /public_html/wp-content/plugins/woocommerce-subscriptions/includes/class-wcs-query.php on line 0
```


```
1. /wp-content/plugins/woocommerce-subscriptions/includes/class-wcs-query.phpを開く
2. 104行目をみる
3. 関数の初めを修正
```

```
old
public function get_endpoint_title( $endpoint )

↓↓↓↓↓↓↓↓↓↓↓
new
public function get_endpoint_title( $endpoint, $action = '' )
```
【JavaScript】現在時刻をリアルタイムで一定時間繰り返す画面を作成せよ。(西暦から秒まで)

```javascript
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>一定間隔で繰り返し実行</title>
   <script>
       function count_time() {
           var timer = document.getElementById('timer');
           var date = new Date();
           timer.innerHTML = date.toLocaleString();
       }
       window.onload = function() {
           // 1秒(1000ミリ秒)ごとにcount_time関数を実行
           setInterval(count_time, 1000);
       }
   </script>
</head>
<body>
   <div id="timer"></div>
</body>
</html>
```
swiftで画面遷移する方法


swiftで画面遷移し、戻るボタンを押した時に元の画面に遷移させる方法を書きます。

まず、senderを作成し、@IBAction func内で以下のように第一引数を「senderの名前」第二引数を「self」とします

```swift
 self.performSegue(withIdentifier: "goToResult", sender: self)
```

その後遷移先の変数に元の画面の変数を送るためにprepareという関数を使用します
以下のようにsegueがgoToResultの時にdestinationVCという変数を作成し、遷移後の変数（ここでいうresultやtipなど）に値を代入します。


```swift
 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToResult"{
            let destinationVC = segue.destination as! ResultViewController
            
            destinationVC.result = finalResult
            destinationVC.tip = Int(tip * 100)
            destinationVC.split = numberOfPeople
        }

```


こうすることで遷移先の画面の変数に値を受け渡せました。
今度は遷移後に元に戻るような関数を作ります。

```swift
@IBAction func recalculaterPressed(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }
```

以上のように@IBAction関数内でself.dismiss(animated:true, completion:nil)とすることで遷移後の画面が消え元の画面に戻ります。
herokuにデプロイした際にassetsに配置した画像が表示されない。

## 環境
Ruby 2.6.5
Rails 6.0.3.5
heroku

## エラー確認
```terminal
ActionView::Template::Error (The asset "default_icon" is not present in the asset pipeline.
//中略
<%= image_tag 'default_icon', id: 'preview-icon' %>
```
herokuへのデプロイ後、アプリにアクセスし新規登録を行おうとした時に、上記のエラーが発生した。
image_tagでassets/imagesに配置している画像を指定しているのだが
**"default_icon"というアセットは存在しませんよと言われている。**
開発環境では問題なく動作していたため本番環境由来のエラーだと判断し探索開始

参考記事
https://qiita.com/___xxx_/items/fa15f358beba2b9389da
#####公式ドキュメント
https://railsguides.jp/asset_pipeline.html#%E5%8F%A4%E3%81%84%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AErails%E3%81%8B%E3%82%89%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89%E3%81%99%E3%82%8B

## 解決法
**config/environments/production.rb**ファイルの書き換え

```ruby
 # Do not fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false # <= trueに変換
```
本番環境ではフォールバックが無効化されているため画像のあるファイルを参照してくれていなかった様です。
RailsにおけるJSやCSSの取り回しの理解がまだまだ浅いので、この辺りもバックエンドの後に詰めたいですね。
All About ACS: Windows 10 2004 以降で USB 接続プリンターへの印刷が異常

# Windows 10 2004 以降で USB 接続プリンターへの印刷が異常
Windows 10 2004 以降で USB 接続のプリンターへ印刷をすると、位置ずれや文字の欠落が報告されています。

# ACS/Pcomm の両方で発生。ファイル出力では問題は確認できない

ACS だけでなく、Pcomm での発生も確認されています。
そのため、特定の製品の障害ではありません。
また、印刷出力を、ファイルに書き出した場合は、データの欠落などは確認できません。
ACS や Pcomm から先の機能での問題のようです。

# JBAT さんの情報

JBAT さんサイトに下記の情報がありました。

https://www.jbat.co.jp/impact/news/209.html

- マイクロソフト社からの修正が 7 月の下旬に予定されている
- ネットワーク接続に変更することにより回避可能
- 現象が確認されている機種: 5577-G05/H05/G05-W/H05-W/J05-W/K05-W

該当が疑われる場合は、参考にしてください。

# その他のサイト

検索すると、関連すると思われる情報が見つかりますね。

https://pca.jp/area_top/20210401.html

https://answers.microsoft.com/ja-jp/windows/forum/windows_10-hardware/windows10/5f17492b-d3c6-40e5-8677-dfb3933afa8f

---
2021-10-18 追記。

まだちゃんと動かないみたいですね。

https://www.jbat.co.jp/impact/news/209.html

（2021年10月11日掲載）

マイクロソフト社から更新プログラムのリリースに関する連絡がありました。

現時点でのリリース予定日は2022年1月を予定しているとのことで、もうしばらくお待ちいただけますようお願い申し上げます。

更新プログラムの時期について詳細がわかりましたら、再度掲載いたします。。

***
2021-05-11 作成
2021-10-18 更新。JBATの2021年10月11日掲載情報を追記
***
「All About ACS」では IBM i に対する新しいクライアント「IBM i Access Client Solutions」の情報をいろいろ提供していきます。
[記事一覧はこちら](http://qiita.com/6onoda/items/2dc925586d8d3b8644f2)で確認いたけます。

許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
***
Rosetta2の必要不必要

# M1チップのMacBookairを手にいれたので...

## M1ネイティブ対応リスト

O ... M1対応
X ... M1非対応

| ソフト | バージョン | O/X |
|:-:|:-:|:-:|
| Firefox| 88.0.1  | O |
| Slack  | 4.16.2 | O |
| Docker | 3.3.1 |X |
| Homebrew | 3.1.5 | O |

#### 編集ログ

- 2021/05/11 Firefox, Slack, Docker Homebrewを追加
Cloudwatch Logs上のVPCフローログ解析（Cloudwatch Logs insights）

#まえがき

仕事でCloudwatch Logs上に出力したVPCフローログから必要な情報を抽出したい、という要望がありました。

[S3のフローログを整理した](https://note.com/captain_music/n/naa036c65a108)ことはありましたが、CWLではやったことなかったので個人的なメモ。
Cloudwatch logs insightsを使用します。

#手順

まずquery-idを変数に格納。
開始時間、終了時間はそれぞれUNIXTIMEで指定します。

--query-stringでフィルタパターンを使用します。
詳しくは[ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html "フィルターとパターンの構文")参照。


```ruby:ID取得
$ query_id=`aws logs start-query \
   --log-group-name {Log_Group_Name} \
   --start-time 1234567890 \
   --end-time 1234567890 \
   --query-string "fields @message | filter @message like /NODATA/" \
   --output text`
```

取得したquery-idを使用して、出力結果を確認します。
jqで不要な情報（@ptrとか）は無くしました。

```ruby:ID取得
$ aws logs get-query-results --query-id $query_id | jq -r '.results[] | .[] | select(.field == "@message") | .value'
```



```ruby:実行結果
2 123456789123 eni-123456789abcdef - - - - - - - 1234567890 1234567890 - NODATA
2 unknown eni-123456789abcdef - - - - - - - 1234567890 1234567890 - NODATA
2 123456789123 eni-123456789abcdef - - - - - - - 1234567890 1234567890 - NODATA
```

#jqについて

.results[] | .[] は不要じゃね？って感じですが、入れないとエラーになります。
もう少しキレイに書ける方法あれば教えてください。

```ruby:エラー
$ aws logs get-query-results --query-id $query_id | jq -r '.results[] | select(.field == "@message")'
jq: error (at <stdin>:820): Cannot index array with string "field"
```
メインビジュアル（背景画像）に対して画像中央にテキスト表示をする方法


画像配置してテキストを中央におきたかったのでメモ
（すぐ忘れる）

```html:index.html
  <div class="mainvisual"> #メインビジュアルの画像を背景画像に
    <div class="text__content"> #position: absolute;で動かす
      <div class="title">テキストテキスト</div>
    </div>
  </div>

```

```css:index.css

.mainvisual {
  height: 300px;
  width: 100%;
  background: url(../img/mainvisual.png) no-repeat center center / cover;
  position: relative;
}

.text__content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

```

.mvの背景画像を設定する。

background: url(../img/mv.png) no-repeat center center / cover;
で一括設定が可能。

position: relative;とposition: absolute;で配置関係を設定。中央に揃えることができる
Laravel、Homesteadのデフォルトタイムゾーンを日本時間に設定する

#開発環境構築時に気になったこと

Homesteadを利用してLaravel環境を立ち上げていた時の話。
Laravelの立ち上げにコケてしまったので、エラーログを見てた時に気付いたのが、

```
2021/05/11 06:00:36 [error] 4599#4599: *1 FastCGI sent in stderr: 
"Unable to open primary script: /home/vagrant/code/public/index.php (No such file or directory)"
```

ログを吐いてる時間がずれていた。アプリ側(config/app.php)はちゃんと設定しているはず。

```php
$ php artisan tinker
Psy Shell v0.10.8 (PHP 8.0.5 — cli) by Justin Hileman
>>> echo Carbon\Carbon::now();
2021-05-11 15:09:27
```

やはり時間がそろっていないと後々時間を扱うときに問題になりそう。ということでHomestead側でも日本時間を設定することに。

#実行

```bash
$ sudo ln -sf /usr/share/zoneinfo/Japan /etc/localtime
$ sudo ntpdate -v ntp.nict.jp
11 May 15:31:37 ntpdate[32548]: ntpdate 4.2.8p12@1.3728-o (1)
11 May 15:31:44 ntpdate[32548]: adjust time server 61.205.120.130 offset 0.027217 sec

$ date
Tue 11 May 2021 03:31:48 PM JST
```

これでHomestead側でも日本時間を見てくれるようになった。

#参考にさせていただいた記事

[Laravel Homestead](http://kiyoto-murakoshi.hatenablog.com/entry/2016/11/05/145835)
after.shを作成してHomestead.yamlと同じ階層においておけば、
`vagrant up`の際に日本時間に設定してくれるそうです。
Djangoのチュートリアルでの404エラーを解決した

#エラー文

```
Using the URLconf defined in tutorial_hy_env.urls, Django tried these URL patterns, in this order:
```
![スクリーンショット 2021-05-11 19.13.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/c3af5d3c-0ff3-7180-df38-f21209041ff0.png)
このエラー文に当たった仲間はいないだろうか。
このエラーはなかなか検索しても見つからず長い間探した。


#解決法
だが答えは近くにあったのだ。。。。
そう、
![スクリーンショット 2021-05-11 19.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/eb386763-47d9-81b7-8f95-5dc7d2758361.png)
ここだ。。

```
ブラウザで http://localhost:8000/polls/ にアクセスすると、 "Hello, world. You're at the polls index." と表示されるのが確認できるでしょう。
```
!?!?!?!?!?!?!?!?!?!?!?!?!?
私の場合

```
Django version 3.2.2, using settings ''
Starting development server at "ココ"
Quit the server with CONTROL-C.
Not Found: /
[11/May/2021 10:09:30] "GET / HTTP/1.1" 404 2174
```
上記のurlをクリックしてページに飛んでしまっていた。なんたる凡ミス。。。。
しっかり一つ一つチュートリアルを読んでいこうと決めました。

#参考

https://www.programmersought.com/article/73184945615/

https://docs.djangoproject.com/ja/3.2/intro/tutorial01/
Xcode12のSigningのエラーの解消方法

#どんな記事？

Xcode12でGitHubをcloneすると

```
「Failed to create provisioning profile.」
「No profiles for 'XXXXXXXX.APName' were found」
```

というエラーが出て動かないときの対処法です。
過去のバージョンのXcodeと配置が変わっているのでハマりました。

![スクリーンショット 2021-05-11 18.55.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620139/a5391f2a-2c1f-b73e-2303-a44944d00e0c.png)


#対処法

1. 左のタブのXCWorkspaceファイルをクリックします。

2. Signing&Capabilities > Team が"Unknown Name"となっているので、
自分のApple developerのアカウントを選択します。

3. これで動きました！

![スクリーンショット 2021-05-11 18.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620139/cf36c79b-ba11-35cc-b956-6584335c5c95.png)
Python 符号付き整数を取り扱う

#Python 符号付き整数(bit数指定)を数値に変換する
Arduinoから直接センサーデータを取得するとき、センサーデータが符号付きの数値(bit数指定)で戻ってきます。
組み込み用の言語であれば符号付き整数を簡単に取り扱う事ができますがPyhotnで計算する場合はそうもいきません。
そのため、符号付き数値(bit数指定)をPythonで扱える数値に変換する必要があります。
16bitの符号付き16進数の場合、下記のような変換結果を期待されます。

```
0x0001   ->   1
0x0000   ->   0
0xffff   ->   -1
```

符号付き数値の具体的なフォーマットは左側bitが符号、そのほかのbitは補数となります。
すなわち、0xffffをビット反転してあげます。

```
0xffff ^ 0xffff  = 0x0000 = 0
```

その数値に-1してあげれば目的の数値となります

```
0xffff ^ 0xffff - 1 = 0x0000 -1 = -1 
```

つまり先頭bitの符号を確認し、ビット反転すれば元の数値となる事がわかります。
Pythonのコードで書くとこのようになります。

```py
signed_hex = 0xffff
signed_int = (int(signed_hex^0xffff) * -1)-1  if (signed_hex & 0x8000) else int(signed_hex)
print(signed_int)
```
```text:実行結果
-1
```

ただ、このコードは16bitの符号付き整数のみ対応するため、汎用性を上げるためにbit数可変可能な下記のような関数を作ってみました。

```py
def signed_hex2int( signed_hex, digit ):
    signed = 0x01 << (digit-1)
    mask = 0x00
    for num in range(digit):
        mask = mask | (0x01<<num)
    signed_int = (int(signed_hex^mask)*-1)-1  if (signed_hex & signed) else int(signed_hex)
    return signed_int

#test
print (signed_hex2int( 0xf0, 8 ))    #8bit
print (signed_hex2int( 0xff00, 16 ))    #16bit
print (signed_hex2int( 0xfff000, 24 ))      #24bit
print (signed_hex2int( 0xffff0000, 32 ))        #32bit

print (signed_hex2int( 0x0f, 8 ))    #8bit
print (signed_hex2int( 0x00ff, 16 ))    #16bit
print (signed_hex2int( 0x000fff, 24 ))      #24bit
print (signed_hex2int( 0x000ffff, 32 ))        #32bit
```

```text:実行結果
-16
-256
-4096
-65536

15
255
4095
65535
```

挙動が怪しいところがありますので機種依存やPythonのバージョン依存があるかもしれません。
問題点あれば教えて頂ければ助かります。
また、関数名や変数名のつけ方に悩みました。いい命名方法があれば合わせてご意見お待ちしております。
一時テーブルの利用は要注意



以下に制約について記載があります。
https://docs.microsoft.com/ja-jp/sql/relational-databases/user-defined-functions/create-user-defined-functions-database-engine?view=sql-server-2017
制限事項と制約事項
ユーザー定義関数では、動的 SQL または一時テーブルを利用することはできません。 テーブル変数は使用できます。
知識0からProcオブジェクトについて調べてみた。

# はじめに
現場での開発にて、「Procや、lambdaってどうやって使うんだろう？」って思って、使い方が曖昧だったので、調べてみました！
よく使う技術だと思うので、ぜひ習得しましょう！


# Procオブジェクトとは
処理をオブジェクトとして抽象化したもの。
これを使うことで、処理を使い回すことが可能です。

## 基本的な使い方
`Proc.new { 処理 }`で処理を作成して、`.call()`で実行出来ます。

```ruby
sample = Proc.new do |name|
  puts "Hello, #{name}" # 最後に評価される式の値が戻り値となる
end

sample.call("Tanaka") #=> "Hello, Tanaka"
```

## lambdaとは？
lambdaとはProcオブジェクトを作る方法の一つで、Procと比べて引数チェックとreturnの挙動、breakの挙動に違いがあります。

```ruby
sample = lambda { |name| puts "Hello, #{name}" }
sample.call('Tanaka') #=> 'Hello, Tanaka'

# 省略系
sample = ->(name) { puts "Hello, #{name}" }
sample.call('Tanaka') #=> 'Hello, Tanaka'
```

### 引数チェックの相違
＜Proc.newの場合＞
引数が多い場合は、先頭から必要な数分だけ取って残りは無視する。
少ない場合は、足りない部分にnilを割り当てるます。

```ruby
proc_sample = lambda do |a, b, c|
  p [a, b, c]
end

proc_sample.call(1, 2) #=> [1, 2, nil]
```

＜lambdaの場合＞
lambdaの場合は、引数の数が違うとArgumentErrorが発生します。

```ruby
lambda_sample = lambda do |a, b, c|
  p [a, b, c]
end

lambda_sample.call(1, 2)
=> ArgumentError: wrong number of arguments (2 for 3)
```

### returnの挙動
＜Proc.newの場合＞
return後は、メソッド自体を抜け出します。

```ruby
def proc_method
  proc_sample = Proc.new { return p "return proc"}
  proc_sample.call
  p "proc method"
end

proc_method #=> "return proc"
```

＜lambdaの場合＞
lambdaの場合はreturnした後にメソッドに戻り、メソッドを最後まで実行します。

```ruby
def lambda_method
  lambda_sample = lambda { return p "return lambda"}
  lambda_sample.call
  p "lambda method"
end

lambda_method #=> "return lambda"
              #=> "lambda method"
```

### breakの挙動
＜Proc.newの場合＞
例外が発生する。

```ruby

def proc_method
  proc_sample = Proc.new do
                  break 1
                  puts :unreachable
                end

  proc_sample.call
  p 'proc method'
end

proc_method #=> LocalJumpError: break from proc-closure
```

＜lambdaの場合＞
lambdaの場合はbreakした後にメソッドに戻り、メソッドを最後まで実行します。

```ruby
def lambda_method
  lambda_sample = lambda do
                    break 1
                    puts :unreachable
                  end

  lambda_sample.call
  p "lambda method"
end

lambda_method #=> "lambda method"
```

# おわりに
Procとlambdaの違いを理解して利用することで、現場での開発でも再利用可能で綺麗なコードを書くことが出来そうですね！
bigqueryでpivot/unpivotができるようになった！


タイトルの通り、bigqueryのSQL上でpivot/unpivotの機能がリリースされたようなので、早速試してみました。


## pivot処理の例

pivot用のレコード作成

```SQL

WITH 
Produce AS 
(
  SELECT 'A' as product, 100 as sales, 'Q1' as quarter UNION ALL
  SELECT 'A', 200, 'Q2' UNION ALL
  SELECT 'A', 300, 'Q3' UNION ALL
  SELECT 'A', 400, 'Q4' UNION ALL
  SELECT 'B', 150, 'Q1' UNION ALL
  SELECT 'B', 250, 'Q2' UNION ALL
  SELECT 'B', 350, 'Q3' UNION ALL
  SELECT 'B', 450, 'Q4'
 )

 SELECT * FROM Produce

```

| product | sales | quarter |
|:-----|------:|:-------:|
| A    | 100   | Q1      |
| A    | 200   | Q2      |
| A    | 300   | Q3      |
| A    | 400   | Q4      |
| B    | 150   | Q1      |
| B    | 250   | Q2      |
| B    | 350   | Q3      |
| B    | 450   | Q4      |


上記に対して**product、quarter毎にsalesを集計(pivot)**する場合

```SQL

WITH 
Produce AS 
(
  SELECT 'A' as product, 100 as sales, 'Q1' as quarter UNION ALL
  SELECT 'A', 200, 'Q2' UNION ALL
  SELECT 'A', 300, 'Q3' UNION ALL
  SELECT 'A', 400, 'Q4' UNION ALL
  SELECT 'B', 150, 'Q1' UNION ALL
  SELECT 'B', 250, 'Q2' UNION ALL
  SELECT 'B', 350, 'Q3' UNION ALL
  SELECT 'B', 450, 'Q4'
 )

SELECT * FROM
  (SELECT * FROM Produce)
  PIVOT(SUM(sales) FOR quarter IN ('Q1', 'Q2', 'Q3', 'Q4'))

```

| product | Q1 | Q2 | Q3 | Q4 |
|:--------|----:|:---:|:---:|:---:|
| A       | 100 | 200 | 300 | 400 |
| B       | 150 | 250 | 350 | 450 |

### pivotできた！！！



## unpivot処理の例

unpivot用のレコード作成

```SQL

WITH Produce AS (
  SELECT 'A' as product, 100 as Q1, 200 as Q2, 300 as Q3, 400 as Q4
  UNION ALL
  SELECT 'B', 150,250, 350, 450)

SELECT * FROM Produce

```

| product | Q1 | Q2 | Q3 | Q4 |
|:--------|----:|:---:|:---:|:---:|
| A       | 100 | 200 | 300 | 400 |
| B       | 150 | 250 | 350 | 450 |

上記に関して**product、sales、quarter別にレコードを展開する(unpivot)**場合

```SQL

WITH Produce AS (
  SELECT 'A' as product, 100 as Q1, 200 as Q2, 300 as Q3, 400 as Q4
  UNION ALL
  SELECT 'B', 150,250, 350, 450)

SELECT * FROM Produce
UNPIVOT(sales FOR quarter IN (Q1, Q2, Q3, Q4))

```

| product | sales | quarter |
|:-----|------:|:-------:|
| A    | 100   | Q1      |
| A    | 200   | Q2      |
| A    | 300   | Q3      |
| A    | 400   | Q4      |
| B    | 150   | Q1      |
| B    | 250   | Q2      |
| B    | 350   | Q3      |
| B    | 450   | Q4      |


という感じになるようです。

## まとめ

今までは、bigqueryで抽出した結果を
・case when & SUM or Count などでpivot頑張る
・外部のデータ処理用ツール(スプレッドシートやexploratoryなど）にデータを吐き出してからpivotする
でしたが、この機能実装により、bigquery上で完結できるようになりました。
大変ありがたしです。

公式のマニュアルは[こちら](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax?hl=en#pivot_operator)
よく使いそうなPrometheusのexporter一覧

# 概要
Prometheus へ監視対象のデータを送信する exporter のメジャーどころ一覧。
Grafana で監視する際に便利な Dashboard もそれぞれ一緒に記載しておく。



# サーバ基本情報系
### 1. [node_exporter](https://github.com/prometheus/node_exporter)
- 使用Port：9100
- Linuxサーバの基本情報(topコマンド的な情報)を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/1860

### 2. [windows_exporter](https://github.com/prometheus-community/windows_exporter)
- 使用Port：9182
- Windowsサーバの基本情報(タスクマネージャー的な情報)を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/12422



# Webサーバ系
### 1. [nginx-prometheus-exporter](https://github.com/nginxinc/nginx-prometheus-exporter)
- 使用Port：9113
- NGINXまたはNGINXPlusの情報を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/9614

### 2. [apache_exporter](https://github.com/Lusitaniae/apache_exporter)
- 使用Port：9117
- Apacheの情報を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/3894

### 3. [blackbox_exporter](https://github.com/prometheus/blackbox_exporter)
- 使用Port：9115
- HTTPやTCPなどを介したエンドポイント情報を送信。Webサービスの死活監視に。
- おすすめDashboard：https://grafana.com/grafana/dashboards/7587

### 4. [ssl_exporter](https://github.com/ribbybibby/ssl_exporter)
- 使用Port：9219
- Webサーバに使用しているSSL証明書の情報を送信。SSL証明書の期限監視に便利。
- おすすめDashboard：https://grafana.com/grafana/dashboards/13230



# DBサーバ系
### 1. [mysqld_exporter](https://github.com/prometheus/mysqld_exporter)
- 使用Port：9104
- MySQLサーバの情報を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/7362

### 2. [postgres_exporter](https://github.com/prometheus-community/postgres_exporter)
- 使用Port：9187
- PostgreSQLサーバの情報を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/455

### 3. [redis_exporter](https://github.com/oliver006/redis_exporter)
- 使用Port：9121
- Redisサーバの情報を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/11835

### 4. [elasticsearch_exporter](https://github.com/justwatchcom/elasticsearch_exporter)
- 使用Port：9114
- Elasticsearchサーバの情報を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/6483

### 5. [memcached_exporter](https://github.com/prometheus/memcached_exporter)
- 使用Port：9150
- Memcachedサーバの情報を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/37

### 6. [oracledb_exporter](https://github.com/iamseth/oracledb_exporter)
- 使用Port：9161
- Oracleサーバの情報を送信
- おすすめDashboard：https://grafana.com/grafana/dashboards/3333



# その他
### [exporter_exporter](https://github.com/QubitProducts/exporter_exporter)
- 使用Port：9999
- exporterのリバースプロキシ。複数のexporterを扱う際に便利。
メソッドチェーンの改行をどこに入れるか

```php
$o = new FooBarObject();
$o->setFoo('foo');
$o->setBar('bar');
```

こういうのを Fluent setter/getter でメソッドチェーンして複数行で書くときどう書くか、コーディング規約で決まってないので、人によって改行位置が違ってきて関係ない diff が発生するのがよくあります。こういう指針でどうかなと思ってるのをまとめました。

```php
class FluentObject
{
    private string $foo, $bar, $baz;

    public function setFoo($v): self { $this->foo = $v; return $this; }
    public function setBar($v): self { $this->bar = $v; return $this; }
    public function setBaz($v): self { $this->baz = $v; return $this; }

    public function getFooBarBaz(): string { return $this->foo . $this->bar . $this->baz; }
}

// 複数行でどう書く?
```

セッター呼び出しのみの場合、最初の要素開始と最後のセミコロンの前につねに改行。順序が変わったり任意の場所にメソッドが挿入されたりするので、セミコロンや先頭行との影響をなるべく減らし、純粋な行差分にしたいです。データレコードのフィールド初期化などに多いパターン。

```php
$o = (new FluentObject())
    // 最初に setBaz を挿入するかもしれないので改行してから
    ->setFoo('foo')
    ->setBar('bar')
    // 最後に setBaz を挿入するかもしれないのでセミコロンを次の行に
;
```

最後のメソッドが別の型を返す場合、最後のメソッドはセミコロンと同じ行に。必要ないのにセミコロンだけ浮いてる行はやっぱり無駄なので。クエリビルダなどに多いバターン。

```php
$s = (new FluentObject())
    ->setFoo('foo')
    ->setBar('bar')
    ->getFooBarBaz();
    // getFooBarBaz の次になにか挿入される可能性はないのでセミコロンとセット
```

最初のメソッドがお約束で決まっている場合、可変な要素が出てくるまではなるべく改行しない。`$this->createMockBuilder(...)` でおなじみのパターン。

```php
class FluentObjectFactory
{
    public function create(): FluentObject{ return new FluentObject(); }
}

$o = (new FluentObjectFactory())->create()
    // create の前になにか挿入される可能性はないので改行なし
    ->setFoo('foo')
    ->setBar('bar')
;
```

結論: 構文では決まらないよね。セマンティックだよね。

いかがだったでしょうか? ご意見はコメントでどうぞ。
【Android】Retrofitで@Pathを使うとinterceptorで指定したheaderが消えてしまうときの対処法

# 起こった事象

認証機能をつけよう！ということで

```kotlin:
addHeader("Authorization", "Bearer %s".format(accessToken)))
```

↑こんな感じでinterceptorにてアクセストークンをセットしていたときのこと。
基本的にはこれですんなり動いたのですが、何やらうまくいかないものがあり・・・

```kotlin
    @DELETE("users/{id}/")
    suspend fun deleteUser(@Path("id") id: String): Response<DeletedUserResponse>
```
↑こんな感じのinterfaceを定義したときにコケました。
どうやら@Pathを使っているときのみ認証にコケるようです。
「？？？」だったので調べてみたら、interceptorにて設定したAuthorizationのヘッダーが消えてしまっていました。
理由はわかりません。（え）

# 解決策
解決策は

```kotlin
    @DELETE("users/{id}")
    suspend fun deleteUser(@Path("id") id: String): Response<DeletedUserResponse>
```
指定したPathの末尾のスラッシュを取ったらきちんとヘッダーがセットされました。

なぜ・・・

末尾のスラッシュがあるかないかでリダイレクトしてしまったり予期せぬ挙動が起きたりすることはありますが、まさかフロントのコードで、しかもヘッダーが消えてしまうという形で影響するのは予想外でした
DockerでOracleのデータをCSVに出力する

クエリを与えたら、結果をCSVに出力するDockerです。

Dockerfile と query.py を同じディレクトリに配置してビルドします。

```bash:
$ docker build -t ora_export .
```

```Docker:Dockerfile
FROM oraclelinux:7-slim

# Proxy必要の場合
# ENV https_proxy=http://proxy.hoge.com

RUN yum -y install oracle-release-el7 && \
    yum -y install oracle-instantclient19.3-basiclite && \
    yum -y install vim && \
    yum -y install python36 && \
    python3.6 -m pip install cx_Oracle pandas && \
    rm -rf /var/cache/yum

WORKDIR /myapp
ADD query.py /myapp

ENTRYPOINT ["python3.6", "query.py"]
```

```Python:query.py
import sys
import cx_Oracle as cxo
import pandas as pd

args = sys.argv
user = args[1]
password = args[2]
dsn = args[3]

connection = cxo.connect(user=user, password=password, dsn=dsn)

query = sys.stdin.read()
pd_data_frame = pd.read_sql(query, con=connection)
pd_data_frame.to_csv(sys.stdout, index=False, encoding="utf-8")

connection.close()
```

使い方のサンプルです。
query.sql を作成してコマンドを実行すると、export.csv が出力されます。

```sql:query.sql
select systimestamp from dual
```


```bash:コマンド
$ cat query.sql | docker run --rm -i ora_export username　password 192.168.1.103:1521/ORCL > export.csv
```

```text:export.csv
SYSTIMESTAMP
2021-05-11 17:56:07.044225
```

# 参考にした記事

https://qiita.com/kotetsu75/items/721058d3c529e177c2cc

https://qiita.com/uehaj/items/e6dd013e28593c26372d

https://genzouw.com/entry/2019/07/24/143749/1691/
LaravelのObserverについて

# はじめに
Observerではモデルのライフサイクル(create, updateなど)に合わせて設定した処理を行うようにすることができる。モデルをいじる時に毎回行う処理などを省略できるのでとても便利である。
ObserverファイルはLaravel 6.X以降であれば`php artisan make:observer {Model名}Observer --model={Model名}`で生成することができる(`{Model名}`はモデルの名前で置き換えるという意味、Userモデルだったら`{Model}=User`)。それ以前のバージョンでは`App\Observer`配下に作成する。ファイル名は`{Model名}Observer.php`と書く。
[ReaDouble](https://readouble.com/laravel/6.x/ja/eloquent.html)では、サービスプロバイダの一つであるbootメソッドで登録し、AppServiceProviderでオブザーバを登録しているが、この記事ではtraitを利用して登録する。traitとはコードを再利用するための仕組みの一つ。


# オブザーバーの設定
オブザーバーは上記の方法で生成すると以下のような内容のファイルが生成される。そのままだが、`created`メソッドには作られた後に行う処理を書く。`updated`メソッドには更新した後に行う処理を書く。`deleted`メソッドには削除した後に行う処理を書く。`restored`メソッドには再登録された後に行う処理を書く。`forceDeleted`メソッドには物理削除した後に行う処理を書く。

```php:App\Observer\{Model名}Observer.php
<?php

namespace App\Observers;

use App\Models\{Model名};

class {Model名}Observer
{
    /**
     * Handle the {Model名} "created" event.
     *
     * @param  \App\Models\{Model名}  $model
     * @return void
     */
    public function created({Model名} $model)
    {
        //
    }

    /**
     * Handle the User "updated" event.
     *
     * @param  \App\Models\{Model名}  $model
     * @return void
     */
    public function updated({Model名} $model)
    {
        //
    }

    /**
     * Handle the User "deleted" event.
     *
     * @param  \App\Models\{Model名}  $model
     * @return void
     */
    public function deleted({Model名} $model)
    {
        //
    }

    /**
     * Handle the User "restored" event.
     *
     * @param  \App\Models\{Model名}  $model
     * @return void
     */
    public function restored({Model名} $model)
    {
        //
    }

    /**
     * Handle the User "force deleted" event.
     *
     * @param  \App\Models\{Model名}  $model
     * @return void
     */
    public function forceDeleted({Model名} $model)
    {
        //
    }
}
```
あとは自分のしたい場所にしたい処理を書けば良い。デフォルトでは過去形のみが生成されるが、現在進行形(ing)の形でも動くようだ(処理前に呼び出される)。

# オブザーバーの登録
まずはtraitに以下のように書く。`bootクラス名`はそのクラスが呼び出された時にそこに書かれた処理を行う。

```php:App\Traits\{Model名}Observable.php
<?php

namespace App\Traits;

trait {Model名}Observable.php
{
    public static function boot{Model名}Observable()
    {
        self::observe({Model名}Observer::class);
    }
}
```

それを該当するModelsに呼び出す。

```php:App\Models\{Model名}
<?php

namespace App\Models;

use App\Traits\{Model名}Observable;
use Illuminate\Database\Eloquent\Model;

class {Model名} extends Model
{
    use {Model名}Observable;
}
```
これをすることによって該当するモデルのEloquentが走ったときにboot{Model名}Observableメソッドを行うことが出来る。
【FileMaker】SendGrid経由でメールを送る テキストメール編

[前回](https://qiita.com/tyuma/items/42b415fb9c515ff1b0d8)は、SendGridを使うための準備でした。
前回のテスト送信を元に、FileMakerでテストしていきます。
FileMakerのバージョン等は、[前回](https://qiita.com/tyuma/items/42b415fb9c515ff1b0d8)の記事を参考にしてください。

# テーブル設計
なくてもいいのですが、テストで様々なパターンをテストするので履歴を残しておくために送受信履歴フィールドを作成しておきます。
![スクリーンショット 2021-05-11 17.45.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/becee265-31af-73c7-e769-e156e5117931.png)

# レイアウト設計
作成したフィールドを、こちらも確認用として適当に配置します。
![スクリーンショット 2021-05-11 17.47.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/b73d09fb-515e-0a16-52c3-742da6c7fc71.png)

# SendGrid APIの確認
SendGridでメールを送信する際に、必須で指定するものがありますので、まずは必須部分を埋めます。
[APIページ](https://sendgrid.com/docs/api-reference/)の確認は必ずしましょう。
必須の指定は、
・to
・from
・content
の3つです。
![スクリーンショット 2021-05-11 17.52.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/b2d912c5-9bb7-7a6b-50f6-f0168b0742b0.png)
・・・
![スクリーンショット 2021-05-11 17.52.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/eca4f71f-c1f4-abae-09df-07d05418d4b0.png)
JSONで作成しますが、この構造になるように作成していきます。
特に、array(配列）の部分や同じkey名が別の配列などにあったりしますので、どこに自分が指定したいものがあるのかの確認はしっかり把握しておきましょう。
(fromとかね)

# JSONの確認
SendGridのサンプルをベースにすると、以下のような作りになります。
![スクリーンショット 2021-05-11 17.56.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/5b9c00b9-3b43-ef5a-7580-2773e9ae3e83.png)

# スクリプト
送信データの作りの部分は、JSON組み立てだらけですが、めげずに組み立てましょう。
![スクリーンショット 2021-05-11 17.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/41714065-1bcd-129c-8fea-05297060def1.png)

curlオプションのデータの指定方法に注意してください。
FileMakerの" [サポートされている cURL オプション](https://help.claris.com/ja/pro-help/content/curl-options.html) "ヘルプにもありますが、変数のデータを指定する際は"@"を指定します。
ここが認識されないと、"Content-Type should be application/json"とエラーメッセージが返ってきます。
![スクリーンショット 2021-05-11 18.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/901fa397-c492-d4f8-30ab-1de8eca95f13.png)

送信先は、sendGridのhttpsアドレスになります。
このアドレスも、API仕様に載っていますので、仕様変更等あった場合は必ず確認しておきましょう。
![スクリーンショット 2021-05-11 18.02.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/25fb6e7f-03fd-e642-a863-c6487e89f864.png)


他の行で色々書いていますが、送信結果の保存や履歴の取得などですので、なくてもOKです。
ただし、本実装する場合はエラー処理などの実装を必ずしましょう。
API仕様には、親切なことにそれぞれのエラーコードで返ってくるJSON仕様も書いてありますので、参考に実装します。
この詳細をきちんと載せているのはとてもいいと思いますので、他のAPIの仕様ページでもぜひ載せて欲しい。。。
![スクリーンショット 2021-05-11 18.18.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/193669ae-62e3-651b-4e21-4633206d7de0.png)

スクリプト自体は、送信するJSONデータの組み立て(2行目)とURLで送信する"URL からの挿入"(６行目)がきちんとかけていればOKです。

# 実行する
メールの受信先(to)を自分で確認できるメールアドレスに指定して実行すると、送信されていることを確認できます。
ヤッタァ。
![スクリーンショット 2021-05-11 18.11.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/f6d87bb0-0fde-2fec-26bb-78d4933e7a20.png)

# キモい部分
キモい部分は、JSONの組み立てとヘッダーの指定です。
どちらも慣れていないとスクリプトの作成に時間がかかる部分ですので、API仕様を読んでどんな構成になっていればいいかを予習しておくと実装がスムーズです。

では、次回は添付メールでも作りますか。
AR.jsで簡単なARを作る！

# 用意するもの
・マーカーになるpattファイル
・htmlファイル
以上！超簡単

### pattファイルの作成
以下で簡単に作成できる。
https://jeromeetienne.github.io/AR.js/three.js/examples/marker-training/examples/generator.html

pattファイルとimgファイルを両方ダウンロードするのがベター。

### htmlファイルの作成
```
<!DOCTYPE html>
<html>
  <script src="https://aframe.io/releases/1.0.0/aframe.min.js"></script>
  <script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
  <body style="margin: 0px; overflow: hidden;">
    <a-scene embedded arjs>
      <a-marker type="pattern" url="patt.patt">
        <a-box position="0 -1 0" scale="1 1 1" color="grey"></a-box>
      </a-marker>
      <a-entity camera></a-entity>
    </a-scene>
  </body>
</html>

```
`<a-marker type="pattern" url="patt.patt">`に作成したpattファイルのパスを上げる。

#ARを体験してみる。
上記で作成したhtmlにアクセスすると、カメラが起動する。
そのカメラでpattファイルを作成した時にダウンロードしたimageファイルを映してみると、3DのBOXが出てくる。

すっごい簡単。
用語についてのまとめ(自分用)

◉API:Application Programing Interfaceの略で、複数の異なるアプリケーションを連携させるもの。と言われるとよくわからなかったが、一種の関数だと考えるとわかりやすい。たとえば、数学で平均値の定理や相加相乗平均の公式、三平方の定理などのがAPIにあたると考えれば良い。プログラミング上では、ユーザーIDを入力するとemailやユーザー名、年齢などの情報を取得したい時に、APIを利用する。

◉SDK:Software Development Kitの略。APIとかも色々入っている便利セットっぽい。
neovimに移行した

# きっかけ
前々からneovimは認知していたけどよく分からないのでノータッチだったが、使ってみたいなと思うプラグインがどうもneovim用っぽいしなんかすごいらしいので移行してみた。

# 環境
WindowsとUbuntu、どちらも移行することに。

## Install
~~Ubuntuは`apt get neovim`しました。~~

[追記] apt get してくるVimが古いと言われたので結局自分でビルドしました。

```
git clone https://github.com/neovim/neovim
make CMAKE_INSTALL_PREFIX=/full/path/
make install
```
`CMAKE_INSTALL_PREFIX`で指定した階層に`neovim/bin/nvim`が生成されるので、これにパスを通せば終わりです。

Windowsにはここから最新版を落として適当なところへ展開しました。

https://github.com/neovim/neovim/wiki/Installing-Neovim

## Ubuntuで起動!
プラグインを読み込んでくれませんでした(◞‸◟)(◞‸◟)(◞‸◟)

### vimとは設定ファイルの場所が違う
vimは `$HOME` に.vimrcを置きますが、neovimは `$HOME/.config/nvim/init.vim` に設定を書くらしいです。
良い機会なので、vimrcを1から書いてみることにしました。

### 出来上がったものがこちらです
```
git clone https://github.com/sweshelo/nvimrc && ./nvimrc/install
```
で手元に環境が整う！やった！

https://github.com/sweshelo/nvimrc

## Windowsでも起動!
プラグインを読み込んでくれませんでした(◞‸◟)(◞‸◟)(◞‸◟)

### Linuxとは設定ファイルの場所が違う
`C:\Users\sweshelo\AppData\Local\nvim` にinit.vimを置くらしいです。
なのでLinuxと完全に同一のinit.vimじゃなくなっちゃった。

### 置いたのにプラグイン読み込まない
まずPython3のpython.exeの場所を指定する必要があるみたいです。
`let g:python3_host_prog='C:\ <Python3をインストールしてるパス> \python.exe'` と付記します。

すると今度はもうジュールがない！みたいなことを言われます。
`:checkhealth` するとなんか「こうしろ！」って言われてたので言われたとおり管理者権限でPowerShellに投げ込みました。

```
pip3 install pynvim
npm install -g neovim
gem install neovim
```

出来ました👏
DB設計

#【DB設計】

RDBで、表や表中の列を設計すること。
これらが適切なものかでシステム実行時の性能や拡張性に影響を与える。
不適切なものでと重複データが格納されたり、データの不整合が起こる。

##正規化

最適な列設計をおこなう。
（ ※ 列の増減はしない、行の増減をする。）

**非正規形から第5正規形まで段階的におこなうのが基本。**

・非正規形
　　↓　第1正規化
・第1正規形
　　↓　第2正規化
・第2正規形
　　↓　第3正規化
・第3正規形
　　↓　第4正規化
・第4正規形
　　↓　第5正規化
・第5正規形

※ **正規形**とは、正規化された表

###第1正規化：繰り返し要素を排除

1行で複数行のデータを修飾している行を結合を解除する。
そして、元のデータを入れて、1行ずつに分割する。

###第2正規化：主キーの一部の関数従属性を排除

主キーの一部に関数従属性があれば、表を分割し、別表とする。

###第3正規化：主キー以外の列の関数従属性を排除

主キー以外の列に関数従属性があれば、表を分割し、別表とする。

※ **関数従属性**とは、ある列に値が連動する別の列が存在する状況
 例） 社員番号に連動する社員名 など。
fail2banのbantime.increment機能と関連オプション

# 概要

BAN回数に応じてBAN期間を延長するfail2banの `bantime.increment` 機能と関連オプションについてのメモ。

当該機能を標準設定のまま有効にした場合、BAN条件毎のBAN期間を各条件におけるBAN回数に応じて$2^{n}$倍する。`n` は `BAN回数-1` で最大$2^{20}$倍。

https://github.com/fail2ban/fail2ban

# オプション

`jail.local` または `jail.conf` の `[DEFAULT]` セクションで設定する。

## bantime.increment

機能を有効にするかどうか。 

- `true` : 有効
- `false` : 無効（標準）

## bantime.rndtime

最終的なBAN期間に追加されるランダムな秒数の上限。攻撃者が設定を推測してBANを回避することを抑止するための機能。

- 秒数を指定する
    - 後述の「[期間の指定方法](#tips)」も使用可
- 0～100%の間でランダムに追加される
- 標準: 無効

## bantime.maxtime

BAN期間の上限。`bantime.formula` 等によるBAN期間の計算が行われた後、この値を超えているとこの値に丸められ、続いて `bantime.rndtime` の処理が行われる。

- 秒数を指定する
    - 後述の「[期間の指定方法](#tips)」も使用可
- 標準: 無制限

## bantime.factor

`bantime.formula` ないし `bantime.multipliers` によるBAN期間の計算に使用される値。

- 標準: `1`
- `bantime.formula` を使用する場合は式の中で自由に使用できる
- `bantime.multipliers` を使用する場合はこの値による乗算が加わる

## bantime.formula

BAN期間の計算式をPythonの記法で指定する。 

- 標準: `ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor`
    - BAN期間をBAN回数に応じて$2^{n}$倍（ `n = BAN回数-1` で最大20）した値と `bantimer.factor` の積
    - `<<` は左シフト（2進数として末尾に0を追加する）
- `bantime.multipliers` とは排他利用（multipliersが優先される）

式で利用できる値は以下の通り。

- `ban.Time` : BAN条件の標準のBAN期間
- `ban.Count` : BAN回数（初期値は `0` っぽい？）
- `banFactor` : `bantime.factor` の値

数学関数なども使用できるため自由度は高い。`jail.conf` のコメントでは `math.exp()` を使用して標準設定と同じ値を出力する例が紹介されている。

## bantime.multipliers

BAN回数毎の倍率を個別に指定する。

- 任意の個数の倍率（数値）を半角スペースで区切って記述する
- BAN回数が指定した倍率の個数を超える場合は最後に指定した倍率が使用される
- `bantime.factor` で乗算される
- 標準: 無効
- `bantime.formula` とは排他利用（formulaより優先される）

```conf:jail.confのサンプル
# BAN回数に応じて1倍, 2倍, 4倍～と増加し、7回目以降は64倍
bantime.multipliers = 1 2 4 8 16 32 64

# BAN期間が60秒の場合、BAN回数に応じて
# 1分, 5分, 30分, 1時間, 5時間, 12時間, 1日, 2日（以降2日固定）となる
bantime.multipliers = 1 5 30 60 300 720 1440 2880
```

## bantime.overalljails

BAN回数のカウント条件を指定する。

- `false`: 各BAN条件毎にBAN回数をカウントする（標準）
- `true`: 全てのBAN条件のBAN回数を合計してカウントする
    - 異なるBAN期間のBAN設定が混在している場合は意図通りに動作するか注意すること

# Tips

## 期間の指定方法

整数による秒数指定以外に単位での指定と基本的な演算子が使用できる。（恐らく2016年頃以降のバージョンで有効）

例えば以下のような単位指定が使用できる。

- 日: `d` `dd`
- 週: `w` `ww`
- 月: `mo` `mon` 
    -  `m` だと分になる
    - 30.4375日
- 年: `y` `yy`
    - 365.25日
- 秒: `s` `ss`
- 分: `m` `mm`
- 時: `h` `hh`

詳細は[ソース](https://github.com/fail2ban/fail2ban/blob/master/fail2ban/server/mytime.py)の `MyTime.str2seconds` 付近を参照のこと。
【静的サイトジェネレータ】VuepressからHugoに乗り換えた

# はじめに
## 現在
markdownで書いた社内向け仕様書ドキュメントを、
GitHub+GitHubActions+Vuepress+S3でHTML化して共有しています。

静的サイトジェネレータの部分は何でもよかったのですが、
個人的にVue.jsがとっつきやすかったのでvuepressを選択してみていました。

## しかし…
vuepressを使っているうちに課題を感じてきました。

- ビルド時間が長くなりすぎる
  - 最初は5分程度でしたが、最終的に10分近くかかっていました
- 最新コミットの内容をHTML側に出せない
  - これは頑張れば行けそうな気もしたけど…。

他にも諸々ありますが、とにかくビルド時間を早くしたい！というのが最も大きい課題感だったので、静的サイトジェネレータの中で圧倒的早さを誇るという「Hugo」に乗り換えてみることにしました。

# 実際にやってみた
## やったこと
- Hugoのテーマ設定
- Hugobuild設定の変更
- markdownにfrontmatterを追加
- 記事ファイル名の変更
- 記事内に記載されているリンクの変更

## ハマったポイント・違いを感じたポイント
### README.md⇒_index.md
これはもしかして変えなくてもいけるのかもしれない…と思いつつ、
どう見ても_index.mdがデフォルトみたいだったので、
合わせてリネームしてあげました。

### テーマをsubmoduleとして管理する方法にあまり慣れていなかった
配布されているdocsyをフォークして、
設定などをいじったテーマをプライベートリポジトリで管理して、
ドキュメントを管理しているリポジトリでサブモジュールとして追加した。

これはもう静的サイトジェネレータの問題ではないのだが、
個人的にgit submoduleに慣れていなかったのでややつまづいた。

### サイドバーの構成方法があまり慣れていない手法だった
基本的に各記事内のfrontmatterのweightで指定する。

### 生成されるHTMLのURL形式がvuepressとは異なる

vuepressだとこうで

```
content/posts/_index.md
=> example.com/_index.html
content/posts/post-1.md
=> example.com/_post-1.html
```

Hugoだとこう

```
content/posts/_index.md
=> example.com/posts/
content/posts/post-1.md
=> example.com/posts/post-1/
```

s3のアクセス権限の与え方の都合上、`example.com/posts/`のようにサブディレクトリにアクセスするような形だとアクセスができない状態になっていたので困った。

[URL Management](https://gohugo.io/content-management/urls/)
Hugo公式ドキュメントを見て、`uglyurls=true`設定にすることで対応できた。
そうするとこんなかんじになる。

```
.
└── content
    └── about
    |   └── _index.md  // <- https://example.com/about.html
    ├── posts
    |   ├── firstpost.md   // <- https://example.com/posts/firstpost.html
    |   ├── happy
    |   |   └── ness.md    // <- https://example.com/posts/happy/ness.html
    |   └── secondpost.md  // <- https://example.com/posts/secondpost.html
    └── quote
        ├── first.md       // <- https://example.com/quote/first.html
        └── second.md      // <- https://example.com/quote/second.html
```
（それでもvuepressの出力のされ方とは違うので、記事内のリンクを置換したりはしたけれど…）

### コミットログを正しく表示するのに条件がある
コミットログがきちんととれているファイルとそうでないファイルが存在したが、何が違うのかすぐには分からなかった（特にWarnやErrorも吐かれていないし）。

調べてみたところ、ASCII文字のみで構成されているファイル名でないと、コミットログを正しく取得できないようだ。（つまり日本語ファイル名はNG）
元々は編集時の可読性を考えて日本語のファイル名にしていたので困った。

~~全部英語ファイル名にリネームしました。~~
(2021/5/12　追記)
以下を行うことで、日本語ファイル名のままでも問題なくコミットログが取得できることを確認できました！ @peaceiris さん、ありがとうございます。

```
git config core.quotePath false
```
[cf. Non-ascii filename breaks lastmod · Issue #496 · peaceiris/actions-hugo](https://github.com/peaceiris/actions-hugo/issues/496)


## やってみた結果
少々手間はかかったけど、とにかくビルド時間が爆速になったので幸せです（約1分程度になりました。10分の1！）。

Hugoについてはさらに公式ドキュメントをよく読みこんで、
後日更に詳しいことも書いてみようと思います。
Hugoはけっこう更新頻度が高いようなので、楽しいですね。
【FileMaker】SendGrid経由でメールを送る 下準備編

お題のとおり、FileMakerから[Twilio](https://www.twilio.com/ja/)のSendGrid経由でメールを送ります。
今回は、FileMakerに組み込む前の準備です。

# FileMaker バージョン
curlを利用しますので、[FileMaker](https://www.claris.com/ja/) 16以上、できれば最新のバージョンがおすすめです。
今回のサンプルは、この記事を書いている時点の最新である19で作成しました。

# SendGrid
[SendGrid](https://sendgrid.com/docs/api-reference/)は、v3バージョンのAPIを使いました。
ここでは、すでにSendGridのアカウントが作成済みであるところからスタートです。
アカウントがない場合は、(記事書いている時点で)無料で始められますのでぜひ[アカウントを取得](https://sendgrid.kke.co.jp/app?p=signup.index)してテストしてみてください。
テスト目的や小グループなどでの実装の場合は、まずはフリープランでどうぞ。

# SendGridアカウント設定
SendGridでAPIを利用するには、API Keyを作成し、それを認証キーとして通信を行います。

1. SendGridアカウントページにログインし、Email API -> Integration Guide ページから、Web APIを選択（Chooseボタンをクリック)
![スクリーンショット 2021-05-10 12.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/6bf371bf-34d4-688c-a2df-705cf8d4fc07.png)

2. FileMakerでは、cURLを通してメールを送信するようにスクリプトを組むので、cURLを選択
![スクリーンショット 2021-05-10 12.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/98cd9adc-69c3-1d47-53d7-707d233a21fd.png)

3. API Keyを作成するので、名前をつけてCreate Keyボタンをクリック
![スクリーンショット 2021-05-10 12.28.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/6f01d36d-84a7-a149-a23d-6153f0140296.png)

4. API Keyの種類を選択して作成
今回は送信するのみなので、Restricted Accessとアクセス制限付きですが、色々テストしたい場合は、Full Accessでいいと思います。
![スクリーンショット 2021-05-10 12.26.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/740e42c9-c4b6-ba74-da5a-cd4c058fb529.png)

5. キーが設定される
手順3のcreate an environmennt variableにも同じキーが設定されます。
![スクリーンショット 2021-05-10 12.28.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/57306870-5b43-eed7-ce03-e0277897ab28.png)

6. ターミナルでテストしてみる
Windowsの場合はcommandアプリ、Macの場合はターミナルアプリを立ち上げてコマンドラインに手順3にあるexportと手順4をそのままペーストして実行
![スクリーンショット 2021-05-11 17.16.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/fb183adc-4223-4340-55dc-265234b55ee9.png)
うまく実行されても何もメッセージは出ません。

7. 結果を確認する
手順4の下にある、"I've executed the code above."にチェックを入れて、"Next: Verify Integration"ボタンをクリック
![スクリーンショット 2021-05-10 15.04.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/a52a7dd7-b02f-d5b1-98e1-c0f535cec6df.png)
うまくいっている場合、"It worked!"メッセージのページに遷移するので、"View Email Activity"で送信日時などを確認（日時は日本時間ではないので注意）
![スクリーンショット 2021-05-10 15.05.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/74058102-1f96-cac3-cb1c-c2fb8c3ebd80.png)

ここまでが準備です。
SendGrid、設定とテストが一回で済むのでとてもよくできています。
FileMakerのFの字も出ない回でしたが。次回は、FileMakerでメールを送信します。
MySQLのタイムゾーンを日本時間にする(Ubuntu18.04)

##勘違いしていたこと
MySQLのタイムゾーンはデフォルトでホストマシンのタイムゾーンを参照している！
❎my.cnfを編集する
🔴Ubuntuのタイムゾーンを変更する


#ホストマシン(Ubuntu)のタイムゾーンを変更

```
$> date
Tue May 11 07:43:16 UTC 2021
```

日時を確認
UTCからJSTに変える

```
$> timedatectl set-timezone Asia/Tokyo
==== AUTHENTICATING FOR org.freedesktop.timedate1.set-timezone ===
Authentication is required to set the system timezone.
Authenticating as: vagrant,,, (vagrant)
Password:
```

パスワードを入力
==== AUTHENTICATION COMPLETE ===
と出たら成功

```
$> date
Tue May 11 16:44:02 JST 2021
```

JSTになってることを確認

##MySQLを確認
MySQLに接続し確認

```
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | UTC    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.01 sec)
```

あれ？変わってない。。。
MySQLを再起動

```
mysql> exit
Bye
$> systemctl restart mysql
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to restart 'mysql.service'.
Authenticating as: vagrant,,, (vagrant)
Password: 
==== AUTHENTICATION COMPLETE ===
```

```
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | JST    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)
```

行けた！

MySQL再起動することをお忘れなく〜
Vue CLIをアップデートする

## はじめに

[Vue CLI](https://cli.vuejs.org/)をアップデートする方法をご説明します。
Vue CLIは頻繁にアップデートされており、アップデートするたびに方法を調べているため備忘録的にコンテンツとして残します。

## バージョンを確認する

バージョンによってアップデートの方法が異なるため、はじめに現在導入されているVue CLIのバージョンを確認しましょう。

### バージョン確認

- ターミナル/コマンドプロンプトを開いて「vue --version」コマンドを実行してください

```shell
$ vue --version
```

- 以下のように現在インストールされているバージョンが出力されます
- この場合、メジャーバージョン３・マイナーバージョン２・リビジョン２となります

```shell
@vue/cli 3.2.2
```

## メジャーバージョン２以下がインストールされている場合のアップデート方法

Vue CLIは、メジャーバージョン２までとメジャーバージョン３以降でNPMパッケージが変更されています。
そのため、メジャーバージョン２以下からメジャーバージョン３以降にバージョンアップする場合は、古いVue CLIを一度アンインストールしてから、新しいバージョンをインストールする必要があります。

### 古いVue CLIをアンインストールする

- NPMを使ってVue CLIをインストールしている場合は、以下のコマンドを実行してください

```shell
$ npm uninstall -g vue-cli
```

- YARNを使ってVue CLIをインストールしている場合は、以下のコマンドを実行してください

```shell
$ yarn global remove vue-cli
```

### 新しいVue CLIをインストールする

- NPMを使ってVue CLIをインストールする場合は、以下のコマンドを実行してください

```shell
$ npm install -g @vue/cli
```

- YARNを使ってVue CLIをインストールする場合は、以下のコマンドを実行してください

```shell
$ yarn global add @vue/cli
```

## メジャーバージョン３以降がインストールされている場合のアップデート方法

npmのinstallコマンドを再度実行することでVue CLIのアップデートが可能です。

### Vue CLI のアップデート

- NPMを使ってVue CLIをインストールしている場合は、以下のコマンドを実行してください

```shell
$ npm install -g @vue/cli
```

- YARNを使ってVue CLIをインストールしている場合は、以下のコマンドを実行してください

```shell
$ yarn global add @vue/cli
```

## アップデート後のバージョンを確認する

再度、ターミナル/コマンドプロンプト上でコマンドを実行し、アップデート後のバージョンを確認します

### バージョン確認

- ターミナル/コマンドプロンプトを開いて「vue --version」コマンドを実行してください

```shell
$ vue --version
```

- バージョンが更新されていることを確認してください

```shell
@vue/cli 4.5.13
```

## さいごに

以上で、Vue CLIのアップデートは完了となります。
現在インストールされているバージョンによって手順が変わることを注意してください。
db接続のエラー - PG::ConnectionBad: could not connect to server: No such file or directory -

#1, 環境
macOS catalina 10.15.7
Ruby 2.6.5p114
Rails 6.0.3.7

#2, はじめに
エラーにハマって自身でしらべ、解消できたのですが今後も起きた時のためにも残しておきます。
また、同じエラーで困った人の助けになれば。

#3, エラー内容
deviseの導入を行なっており、rails db:migrateを実行すると、

```
kanta@fukazawakantanoMacBook-Pro insta-app-daytra % rails db:migrate
rails aborted!
PG::ConnectionBad: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```
DBの接続に関してのエラーっぽいですね。

#4, 試したこと
エラー文をDeepLにて翻訳。
>PG::ConnectionBad: サーバーに接続できませんでした。No such file or directory
    サーバーはローカルで動作していて、以下を受け付けています。
Unixドメインソケット「/tmp/.s.PGSQL.5432」で接続を受け付けていますか？

なんとなくの意味は分かったが根本的な問題は分からず。
そこでエラー文の

>Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

をググると、以下の記事がヒット
→https://qiita.com/knxrvb/items/72d88fe5364561214e52

ターミナルでそこにあるコードを実行しDBを起動しようとすると

```
postgres -D /usr/local/var/postgres

2021-05-11 15:22:39.356 JST [31540] FATAL:  database files are incompatible with server
2021-05-11 15:22:39.356 JST [31540] DETAIL:  The data directory was initialized by PostgreSQL version 12, which is not compatible with this version 13.2.
　
```
とログが表示。
翻訳すると、
>データベースファイルがサーバーと互換性がない
 データディレクトリはPostgreSQLバージョン12で初期化されており、このバージョン13.2とは互換性がありません。

と、postgresのバージョンが古いみたい。
記事にもあるアップグレードさせるコードを実行。

```
brew postgresql-upgrade-database
```
いろいろコードが走り、

```
==> brew install postgresql@12
==> Downloading https://ghcr.io/v2/homebrew/core/postgresql/12/manifests/12.6_2
######################################################################## 100.0%
     ・
　　　・
　　　・

```

一件落着かに思われたが、、、

```
Error: Upgrading postgresql data from 12 to 13 failed!
==> Removing empty postgresql initdb database...
==> Moving postgresql data back from /usr/local/var/postgres.old to /usr/local/var/postgres...
Error: Failure while executing; `/usr/local/opt/postgresql/bin/pg_upgrade -r -b /usr/local/Cellar/postgresql@12/12.6_2/bin -B /usr/local/opt/postgresql/bin -d /usr/local/var/postgres.old -D /usr/local/var/postgres -j 4` exited with 1.
```
アップグレードできず。。。

そのままエラー文の

  > pgrading postgresql data from 12 to 13 failed!

をググると
→https://twin-t.com/postgressql%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E9%9A%9B%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC/
がヒット。

どうやらPostgresSQLを起動したままアップデートを行ったことがまずかったみたい。

記事に従って、PostgresSQLを停止させ、

```
brew services stop postgresql
```

```
brew postgresql-upgrade-database
  .
  . 
  .
==> Upgraded postgresql data from 12 to 13!
==> Your postgresql 12 data remains at /usr/local/var/postgres.old
```

無事アップグレード完了！！
試しにDBを起動させると、

```
brew services start postgresql
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)
```
成功ですね！！

rails db:migrateも実行できました！！！
pythonでwavファイルの再生時刻を取得する

# 背景
wavファイルの再生時間を取得したい

# 方法

```py
import wave
    with wave.open('path/to/local/sample.wav', mode='rb') as wf:
        print('time(second): ', float(wf.getnframes() / wf.getframerate()))
```

# 参考
https://qiita.com/bayachin/items/68f7659d31fa6c836317