OmniAICreator/Qiita-1.07M huggingface dataset:
基本情報技術者試験　データベース編④

#初めに
[前回](https://qiita.com/reo0612/items/6fa0429606427b40ef15)の続きです。

#障害管理について
DBには、もしもの時の障害に備えた機能が備わっています。

例えば、定期的に`バックアップ`を取ったり、DB更新前後の状態を`ジャーナル`と呼ばれるログファイルに記録したりです。

このように実際に障害が発生した場合は、これらのファイルを使って
障害回復処理を行い、元の状態に復旧します。

#コミットとロールバック
前回の記事でも言いましたが、DBはトランザクション単位で更新処理を管理します。

例えば、「AさんからBさんにお金を振り込む」処理を想像してみて下さい。

```
①Aさんの口座残高を確認する
↓
②Aさんの口座残高から1000円減らす
↓
③Bさんの口座残高を確認する
↓
④Bさんの口座残高を1000円増やす
```

この①〜④が1つのトランザクションでしたね。

この中で、どこかの処理が上手くいかなくて「Aさんの口座残高は減額しているのに、Bさんの残高は増えていない」という状態では大問題です。

そのため、DBでは更新内容を反映させるのは
`全ての処理が正常に更新された時`でないといけません。

トランザクションの処理が問題なく完了できた際、最後に
その更新を確定することでDBへ更新内容を反映させます。

これを`コミット`と呼びます。


一方、トランザクション処理中に何らかの障害が発生した場合は
そこまでに行った処理をすべてリセットします。

でないと、データの不整合が引き起こされてしまうからです。

```
①Aさんの口座残高を確認する
↓
②Aさんの口座残高から1000円減らす
↓
③Bさんの口座残高を確認する
↓
❌障害発生
④Bさんの口座残高を1000円増やす
↓
①〜④の処理全てをリセットする
```
そこでこのような場合では、DB更新前の状態を`更新前ジャーナル`から取得して
トランザクション開始直前の状態にまで巻き戻す処理を行います。

これを`ロールバック`と呼びます。

このようにDBでは「`トランザクション内の更新全てを反映する`」もしくは
「`トランザクション内の更新全てを取り消す`」のどちらかしかないという訳です。

#分散データベースと2相コミット
ネットワーク上に複数存在するDBを1つのDBMSが管理している形態を`分散DB`と呼びます。

支社などの複数の場所にDBを分散して業務を統合する方式で、集中管理しているDBと比べて`通信負荷の軽減`や`１つに障害が発生しても全体の機能が失われない`というメリットがあります。

しかし、デメリットもあってトランザクション処理が別々のDBで行われるので
全体の同期をとってコミットやロールバックをしないとデータの不整合が起こってしまいます。

そこで`2相コミット`という方式が役に立ちます。

`コミット前に分散しているDBに「コミットできる？」かと問い合わせて、OKなら一斉にデータを更新し、どこか１つでも障害が発生していればロールバックを行うといった方式`です。

これにより、各DBの整合性を保っているという訳です。

#ロールフォワード
DBの障害はなにもトランザクション処理中だけではありません。

データが記録されているハードディスクが故障してしまうなど
物理的な障害が発生してしまう事だってあります。

その場合、定期的に保存してある`バックアップファイル`からデータを復元しますが
それだけだとバックアップ後の更新情報が復元できません。

そこで、DBに行なった更新情報をバックアップ以降の`更新後ジャーナル`から取得し、障害発生直前の状態に復旧させます。

このようにバックアップによる復元から、更新後ジャーナルでバックアップ以降の更新情報を復元する一連の処理を`ロールフォワード`と呼びます。

このようにDBを復旧する方法として

・`ロールバック`
・`ロールフォワード`

の2つがあります。

※この2つの違いを分かりやすく解説している記事があったので載せておきます↓
[「ロールバック」と「ロールフォワード」の違い](https://wa3.i-3-i.info/diff350db.html)

#おわりに
データベース編はここで終わりです。
次は、ネットワーク編を書こうと思ってます。

間違っている部分や気になるところがあれば
コメントして下さると有り難いです。
【Kubernetes】イメージを更新させるには。no.5

![名称未設定のデザイン (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3eb97d30-2c93-4f07-361e-d989610ceef8.png)


こんにちは。

まゆみです。

Kubernetesについての記事をシリーズで書いています

今回の記事では、

<font color="Red">ソースコードに変更があった場合、どのように新しいコードに更新させるか</font>

ということに焦点を置いて書いていこうと思います。

ではさっそく始めていきますね。

#新しいコードに更新してみる

では、nodeのアプリを例に説明していきます

例えば、app.jsファイルのテキストに少し変更を加えてみましょう。

この場合、app.jsファイルを書き換えたあと

```
docker build -t <Image名> .
```

とImageを再度buildし直しますよね。

<font color="Red">その時に、前のイメージ名と同じだと、Kubernetesが新しく更新されたものだと認識してダウンロードし直してくれません。</font>

なので、イメージを新しく作り替えてDocker hubにpushし、そこからpodを作り直すには

```
docker build -t <image名>:2
```
と、-t でタグ付けしたイメージに新しいバージョンだと分かるように：(コロン)と数字を書きましょう


例えば、現在Docker hubにあるイメージが、下記のスクショのようなものだとすると


![2021-07-20_14-46-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/096bffb0-9be6-41a9-4455-7de08009f31b.png)

>mayumidocker0612/kub-first-app:2

など<font color="Red">末尾にバージョンの番号を振ります。</font>

そして新しいイメージをdocker hub にpush します(Kubernetesを使う時はローカルにあるイメージからpodは作れません。Docker hubなどからイメージを引っ張ってpodを作ることになります。)

その後

```
kubectl set image <オブジェクトの種類>/<オブジェクトの名前> <コンテナ名>=<新しいバージョンのDocker hubにあるイメージ>
```

で更新する事ができます

ダッシュボードを見てみましょう

![2021-07-20_16-18-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/4199de6f-5546-9f3c-8de2-ef76097154ed.png)

新しく更新したイメージによってpodが作られているのが分かります。

また

```
kubectl rollout status deployment/<deployment名>
```

で『deployment "deployment名" successfully rolled out』と表示されれば、上手くいっています

#まとめ

今回の記事はこのあたりで締めくくらせていただきます。

次回は今回とは逆にイメージをロールバックさせる時について書いていこうと思います
3.1(易) 離散一様分布

## 方針

離散一様分布とは，確率変数が取りうる有限集合の全ての値について，確率が同様に確からしい場合の分布，すなわち異なるN通りの状態をとる確率変数Xが各状態を取る確率が等しく1/Nであるような分布である．確率密度関数は，

```math
f_X(x)=\frac{1}{N}\ \ \ \ x=1,...,N
```

期待値は，

```math
\begin{align}
\mathbb{E}[X]&= \sum_{x=1}^N\frac{x}{N}\\
&= \frac{1+...+N}{N}\\
&= \frac{N(N+1)}{2N}\\
&= \frac{N+1}{2}
\end{align}
```

分散は，

```math
\begin{align}
Var(X)&= \sum_{x=1}^N\frac{1}{N}(x-\frac{N+1}{2})^2\\
&= \frac{1}{N}\sum_{x=1}^N\{x^2-(N+1)x+\frac{(N+1)^2}{4}\}\\
&= \frac{1}{N}\{\frac{1}{6}N(N+1)(2N+1)-\frac{N(N+1)^2}{2}+\frac{N(N+1)^2}{4}\}\\
&= \frac{2(N+1)(2N+1)-3(N+1)^2}{12}\\
&= \frac{(N+1)(N-1)}{12}
\end{align}
```

本問では確率母関数から平均，分散を導出する．

## 答案

確率母関数は，

```math
\begin{align}
G_X(s)&= \mathbb{E}_{X\sim f_X}[s^X]\\
&= \sum_{x=1}^N\frac{s^x}{N}\\
&= \frac{s(1-s^N)}{N(1-s)}\tag{1}
\end{align}
```

ここで，

```math
1-s^N=(1-s)(1+s+...+s^{N-1})
```

であるから，

```math
\begin{align}
(1)&= \frac{s(1+s+...+s^{N-1})}{N}\\
&= \frac{1}{N}\sum_{k=1}^Ns^k
\end{align}
```

確率母関数を微分してs=1を代入することで期待値を求める．

```math
\begin{align}
\frac{1}{ds}G_X(s)&= \frac{1}{N}\sum_{k=1}^Nks^{k-1}\\
\therefore\mathbb{E}_{X\sim f_X}[X]&= \left.\frac{1}{ds}G_X(s)\right|_{s=1}\\
&= \frac{1}{N}\sum_{k=1}^Nk\\
&= \frac{1}{N}\frac{N(N+1)}{2}\\
&= \frac{N+1}{2}
\end{align}
```

次に，確率母関数を二階微分してs=1を代入することで2次階乗モーメントを求める．

```math
\begin{align}
\frac{d^2}{ds^2}G_X(s)&= \frac{1}{N}\sum_{k=1}^Nk(k-1)s^{k-2}\\
\therefore\mathbb{E}_{X\sim f_X}[X(X-1)]&= \left.\frac{d^2}{ds^2}G_X(s)\right|_{s=1}\\
&= \frac{1}{N}\sum_{k=!}^Nk(k-1)\\
&= \frac{1}{N}\{\frac{1}{6}N(N+1)(2N+1)-\frac{N(N+1)}{2}\}\\
&= \frac{(N+1)(2N+1)}{6}-\frac{N+1}{2}
\end{align}
```

ゆえ，分散は，

```math
\begin{align}
Var(X)&= \mathbb{E}_{X\sim f_X}[X(X-1)]+\mathbb{E}_{X\sim f_X}[X]-\{\mathbb{E}_{X\sim f_X}[X]\}^2\\
&= \frac{(N+1)(2N+1)}{6}-\frac{N+1}{2}+\frac{N+1}{2}-\frac{(N+1)^2}{4}\\
&= \frac{(N+1)(N-1)}{12}
\end{align}
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
Android 「No cached version of xxxx available for offline mode.」の解決法

#No cached version of xxxx available for offline mode
![スクリーンショット 2021-07-20 16.19.40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/9e1b6c9b-cc44-6b72-9317-ab2aaaa8599f.jpeg)

右側の「Gradle」を押すと、Gradle Toolsの設定？みたいなタブが出ます。
そこで②のアイコンを押すと解決しました:sweat_smile:

原因はよくわかりません！！

#参考

https://stackoverflow.com/questions/37409265/no-cached-version-available-for-offline-mode/68418377#68418377
kintoneでテーブル内フィールドを編集不可にする方法

今回はテーブル内フィールドを編集不可にする技です。

<iframe width="480" height="360" src="https://www.youtube.com/embed/MRNtsvCDVy8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# アプリの準備

| フィールド種類 | フィールドコード | 備考 |
|:-:|:-:|:-:|
| テーブル  |  テーブル |   |
| 文字列(1行)  | 番号  | テーブル内フィールド  |
|文字列(1行)|名前|テーブル内フィールド|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/6cba28ac-52c6-19ff-bd61-451d9b03e551.png)

# JavaScript

kintone REST API Client 使います

https://developer.cybozu.io/hc/ja/articles/900000767263-kintone-JavaScript-Client-kintone-rest-api-client-

## レコード追加・編集画面の表示後イベント

1行1行、番号フィールドの disabled を true にします。

```js
kintone.events.on(
  ["app.record.create.show", "app.record.edit.show"],
  (event) => {
    event.record.テーブル.value.forEach((r) => {
      r.value.番号.disabled = true;
    });
    return event;
  }
);

```

## フィールド値変更時イベント

行を追加したときも抜かり無く編集不可にしましょう。

```js
kintone.events.on(
  ["app.record.create.change.テーブル", "app.record.edit.change.テーブル"],
  (event) => {
    // 行を削除した時はエラーが出ないようにevent.changes.rowが存在しているかどうか確認。
    if (event.changes.row) {
      event.changes.row.value.番号.disabled = true;
    }
    return event;
  }
);
```
Content Builder の基本 ⇒ Content Builder アクセス権の設定

１．編集権限を持つユーザーの例は次のうちどれですか?
２．作成したコンテンツを他のユーザーと共有する場合、どのようなオプションを提供できますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/1dbc30ab-b893-20dc-3db0-cea9c588f002.png)
CakePHP4 javascript document.getElementがnullになる時の解消

Every Qiita #18
のんびり独学初学者の毎日投稿チャレンジ 18日目
今回は・・・
cakephpでjavascriptファイルでdocument.getElementで要素を取得しようとした時nullになってしまった。解消したので備忘録として投稿します。

###ファイルを読み込むタイミングが違う！！
headタグの中に$this->Html->script('ファイル名')と記載していたためそんな要素ねえよと言われていた・・・

###bodyの直前に読み込む
bodyの直前に$this->Html->script('ファイル名')とすることで、idが定義された後に探しにいくのでエラーが解消されました。
[salesforce] コミュニティサイトのリッチコンテンツエディタで設定した画像が見えない

エキスペリエンスビルダーからリッチコンテンツエディタで画像を設定する
![スクリーンショット 2021-07-20 15.49.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1761599/174104c4-4cca-93db-b072-c6011f03375d.png)

設定を保存して「公開」しても、画像が表示できない場合
![スクリーンショット 2021-07-20 15.46.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1761599/391a9893-7bf4-e6b6-b6ee-cedf3eab027d.png)

[管理]-[詳細]-[一般情報]から
「サイトで使用できるアセットファイルおよび CMS コンテンツをゲストユーザが表示できるようにする」
をチェックする
![スクリーンショット 2021-07-20 15.46.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1761599/48138ad4-bfe5-4bbd-f616-6e9ed36f1e67.png)
[salesforce] defaultFieldValues

##やりたいこと
カスタムボタンやリンクをクリックすると、初期値が設定されている新規活動画面を作成したい。
例）割り当て先を特定のユーザ、開始日がtoday+3に設定できている新規活動画面

> *defaultFieldValues* : 
デフォルト項目値をレコード作成ページに渡すカスタムボタンとリンクを作成します。この機能は、すべてのエディションの Lightning Experience に適用されます。この機能は、Lightning Out、エクスペリエンスビルダーサイト、Salesforce モバイルアプリケーションには適用されません。
https://help.salesforce.com/articleView?id=sf.links_useful_custom_buttons_create_record_dfv.htm&type=5

を利用する。

****
1. カスタムリンクに以下の値を設定する

```
/lightning/o/Event/new?defaultFieldValues=OwnerId=005000~,IsAllDayEvent=true,StartDateTime=TODAY()+3
```
・OwnerId(割り当て先)とIsAllDayEvent(終日行動)の設定は順調にできるが。。
開始日の設定がうまくできない。。

まず、活動(Event)の日付項目には

- ActivityDate(日付)
    - Contains the event’s due date if the IsAllDayEvent flag is set to true.
    - The value for this field and StartDateTime must match, or one of them must be null.

- ActivityDateTime	
    - Contains the event’s due date if the IsAllDayEvent flag is set to false.
    - The value for this field and StartDateTime must match, or one of them must be null.
- StartDateTime（作成日）
    - the time portion of this field is always transferred in the Coordinated Universal Time (UTC) time zone.


https://developer.salesforce.com/docs/atlas.en-us.232.0.api.meta/api/sforce_api_objects_event.htm


##### 活動の日付項目と作成日項目の違いは何ですか？
> *ActivityDate(日付)*
- ToDo の場合は、ToDo の期日を示します。
行動の場合は、終日行動 が True に設定されている場合のみ、行動の開始日を示します。
この項目には、UTC (協定世界時) のタイムゾーンで午前 0 時に常に設定されているタイムスタンプがあります。 このタイムスタンプは関係ありませんので、 タイムゾーンの違いを調整するために変更しないでください。


> *StartDateTime（作成日)*
- ToDo または行動が作成された日付を示します。 多くの場合、作成日の日付と日付項目は同じです。 レコードで [活動の記録] ボタンをクリックするなどして活動を記録すると、この ToDo は事前にスケジュールされておらず、必要に応じて生成されたため、作成日と日付項目は同じになります。作成日は監査項目であり、システムによって作成され、更新されます。 監査項目の詳細については、システム項目 記事を参照してください。


https://help.salesforce.com/articleView?id=000331416&mode=1&type=1

## datatimeタイプ
StartDateTimeはdatatimeタイプなので、時間まで設定する必要がありそう。
例えは、*2021-08-04T01:07:12.000Z*

#####カスタムボタンまたはカスタムリンクの構文

```
/lightning/o/Event/new?defaultFieldValues=StartDateTime={!TEXT( TODAY()+3)}T00:00:00.000Z
```


参考したリンク
・https://developer.salesforce.com/docs/atlas.ja-jp.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_dateformats.htm
PythonAnywhereへのGitHubからのデプロイに躓いた


# 躓いた点
```console
bash: pa_autoconfigure_django.py: command not found  
```
Gitアカウントとの紐づけに使われるPythonファイルが見つからず、実行できなかった。
ググっても同じエラーになっている人は「PythonAnywhere上のBash実行したら治るよ！」で全員解決しているが、
すでにPythonAnywhereのBashで実行している・・・

# 解決策
dotfilesでインストールした.bashrcと既存.bashrcを組み合わせ、新.bashrcを利用することで解決した。
dotfilesのむやみなインストールにより、初期設定を消し去っていた（　＾ω＾）・・・


# チュートリアル上の手順の中身

具体的な手順は下記リンクを参照。
PythonAnywhereという無料PaaSにDjangoプロジェクトを乗せて稼働させている。

https://tutorial.djangogirls.org/ja/deploy/

## PythonAnywhere関連で行われていること

### ライブラリインストール

```console
$ pip3.7 install --user pythonanywhere
```

pythonanywhereのユーザーフォルダへのインストールは具体的には下記をインストールしている。

```text
    /home/user/.local/bin/pa
    /home/user/.local/bin/pa_autoconfigure_django.py
    /home/user/.local/bin/pa_create_scheduled_task.py
    /home/user/.local/bin/pa_create_webapp_with_virtualenv.py
    /home/user/.local/bin/pa_delete_scheduled_task.py
    /home/user/.local/bin/pa_delete_webapp_logs.py
    /home/user/.local/bin/pa_get_scheduled_task_specs.py
    /home/user/.local/bin/pa_get_scheduled_tasks_list.py
    /home/user/.local/bin/pa_install_webapp_letsencrypt_ssl.py
    /home/user/.local/bin/pa_install_webapp_ssl.py
    /home/user/.local/bin/pa_reload_webapp.py
    /home/user/.local/bin/pa_start_django_webapp_with_virtualenv.py
    /home/user/.local/bin/pa_update_scheduled_task.py
    /home/user/.local/bin/snakesay.py
    /home/user/.local/lib/python3.7/site-packages/cli/*
    /home/user/.local/lib/python3.7/site-packages/pythonanywhere-0.9.9.dist-info/*
    /home/user/.local/lib/python3.7/site-packages/pythonanywhere/*
```

### GitHubからの自動構成ヘルパーの実行

```console
$ pa_autoconfigure_django.py --python=3.7 https://github.com/<your-github-username>/my-first-blog.git
```
GitHubのアカウント名、パスワードの入力を求められるので入力する。
tmpのファイルはyで消してOK。

### 結果

下記が自動的に行われる

- GitHubからのクローン
- Python仮想環境下での実行環境整備

# エラー対応手順

- 指示された`pa_autoconfigure_django.py `を実行するもファイルが見つからない

findコマンドでファイルの場所探す

```shell
find / -name "pa_autoconfigure_django.py" 
```
/home/user/.local/bin/pa_autoconfigure_django.py に見つける！


- `/home/user/.local/bin/pa_autoconfigure_django.py` を実行するも、$WORKON_HOMEの設定がないと怒られる

ここで.bashrcの初期設定を疑う

- dotfilesのバックアップフォルダの.bashrcを見る

色々な設定をしているが、下記から辿るとPATHの設定や変数設定がされていることを確認。

```console
# Load up standard site-wide settings. 
source /etc/bashrc
```

.bashrcに上記を含めた差分をすべて設定追加し、ログインしなおすと無事実行完了！

# おまけ
ユーザー用の仮想環境は下記に作られている

```
~/.virtualenvs/user.pythonanywhere.com
```

アクティベートは下記で実施しよう！

```shell
source ~/.virtualenvs/user.pythonanywhere.com/bin/activate
```
超初心者がPythonで5分足チャートからMACDを計算してグラフに表示してみた

## 参考

MACDの計算部分以外は以下とほぼ一緒！

https://qiita.com/emilia/items/45bcaebf3cb8ab6bfb27

## コード

``` py
import pandas as pd
import datetime
import mplfinance as mpf

df = pd.read_csv('./temp_historical_data/USDJPY.csv', nrows=500)
df.columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume']
df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace=True)

df5 = pd.DataFrame()
rule = '5T'
df5['Open'] = df['Open'].resample(rule).first()
df5['Close'] = df['Close'].resample(rule).last()
df5['High'] = df['High'].resample(rule).max()
df5['Low'] = df['Low'].resample(rule).min()

macd = pd.DataFrame()
macd['Close'] = df5['Close']
macd['EMA12'] = df5['Close'].ewm(span=12).mean()
macd['EMA26'] = df5['Close'].ewm(span=26).mean()
macd['MACD'] = macd['EMA12'] - macd['EMA26']
macd['Signal'] = macd['MACD'].ewm(span=9).mean()
macd.head()

macdplot = mpf.make_addplot(macd[['MACD', 'Signal']])

mpf.plot(df5, type='candle', addplot=[macdplot],
        datetime_format='%Y/%m/%d %H:%M', xrotation=90, style='yahoo', savefig=dict(fname='./figures/draw_macd.png',dpi=100))

```

## グラフ

![draw_macd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69727/6a4aee03-e67a-16e9-8ee4-44e5b1579cb0.png)

## 説明

移動平均線と同時に表示したい場合は以下のようにする

```

sma = pd.DataFrame()
sma["SMA5"] = df5["Close"].rolling(window=5).mean()
sma["SMA25"] = df5["Close"].rolling(window=25).mean()

# 中略

smaplot = mpf.make_addplot(sma[['SMA5', 'SMA25']])

mpf.plot(df5, type='candle', addplot=[smaplot, macdplot],
        datetime_format='%Y/%m/%d %H:%M', xrotation=90, style='yahoo', savefig=dict(fname='./figures/draw_macd.png',dpi=100))
```

一緒に表示したグラフは以下。

![draw_macd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69727/c4843902-e607-759b-5e1d-8c37a58134a9.png)
Font-weightについて

:::note warn
・Progate環境の話になります
・まだまだ知識が浅いので拙い話だったり、間違っている点もあると思います
:::

最近ProgateでHTMLの学習をしています。
`<h2>`と`<h3>`タグの太字をなくそうと思ったところ、できるときとできない時があったので不思議に思いながらまとめてみました。
htmlは下記のコードです。



```html:top.html
 <div class="contents-copy">
   <h2>さぁ、あなたもProgateでプログラミングを学んでみませんか?</h2>
   <h3>Let's learn to code, learn to be creative!</h3>
 </div>
```
<h2>できなかったコード</h2>

```css:stylesheet.css
 .contents-copy {
     font-weight:normal;
     color:#5f5d60;
  }
```

<h2>できたコード</h2>

```css:stylesheet.css
 .contents-copy {
     color:#5f5d60;
  }
 
 .contents-copy h2 {
     font-weight:normal;
  }

 .contents-copy h3 {
     font-weight:normal;
  }
```

<h2>考察</h2>
:::note info
colorはまとめて指定できるけど、font-weightはできない？
:::

`font-weight`は親要素の`<div>`でまとめて指定はできないのでしょうか。
ちなみに`color`は`<div>`でも`<h2>`,`<h3>`に個別に指定してもどちらでもという感じでした。
ググったのですが、答えは得られず……:sweat_drops:どなたかご教授いただければ幸いです！
UnityでNavMeshを使わず、特定のGameObjectを巡回させるスクリプト



```Patrol.cs
using UnityEngine;
using System.Collections;

public class Patrol : MonoBehaviour
{

    [SerializeField, TooltipAttribute("経由地点の数を入力し，シーン上に配置した空のオブジェクトをアサインします")]
    public Transform[] wayPoints;

    public Transform target;
    public float speed;

    public int currentRoot;


    void Update()
    {

        //配列に入れたTransformを順に巡る．AIを使っていればスムーズに曲がるがこれは鋭角に曲がる

        float step = speed * Time.deltaTime;
        transform.position = Vector3.MoveTowards(transform.position, wayPoints[currentRoot].position, step);


        Vector3 pos = wayPoints[currentRoot].position;

        float test = Vector3.Distance(target.position, pos);
        transform.LookAt(pos);
                    
        if(Vector3.Distance(transform.position, pos) < 0.5f)
        {
          currentRoot = (currentRoot < wayPoints.Length - 1) ? currentRoot + 1 : 0;
        }

    }
}



```
SpineとLive2Dってどう違うの？

■SpineとLive2Dの違い
Live2Dは国内産。新宿御苑前駅でてすぐの株式会社Live2Dさんが制作しました。当然、マニュアルも説明動画も全て日本語が中心。そんな敷居の低さが一番の強みだと思います。

Spineは米国製。日本語の本や動画は少なく、学習が大変でした。2021年8月に、<a target="_new" href="http://ja.esotericsoftware.com/blog/Welcome-Misaki">日本人スタッフ</a>が加わり、日本語対応が充実しつつありますが、まだまだ過渡期ですね。


1．アニメーションの仕組み

大ざっぱに、それぞれのアニメーションの作り方を比べると、以下のようになります。

■Live2D
　面を変形させることでアニメーションを作る

■Spine
　骨組みを動かすことで、アニメーションを作る


Live2Dはバラバラにして重ね合わせたパーツが、どこを中心にどのように動くか。顔をモーフィング（変形）させる場合、正面で登録した頂点が、一番右（上下左）を向いたときに、どう変形するか。面で指定して、面で登録します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1781010/0507d771-3241-3ac4-bb67-d1d422cef443.png)
アニメーションさせる際は、それぞれの面を回転、変形させます。
※後述のボーンアニメーションにも一部対応しています

一方、SpineはそのままGoogle検索すると脊椎が表示されてしまうとおり、背骨的な意味です。骨格を制御することで、それに紐付けられた画像を回転、変形させます。画像を骨格に登録し、骨格を回転、変形させることで、アニメーションを実現しています。
![qq.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1781010/ad976225-e104-480d-9f84-e65699a9308d.gif)
「2D画像を頂点で区切り、それを変形させることでアニメーションを実現する」という点ではどちらも同じですが、アプローチが違うんですね。

まとめると、モーフィングアニメーションソフトは２つに大別出来ます（個人の感想です）
■主に面を制御
　・<a target="_new" href="https://www.live2d.com/">Live2D</a>
　・<a target="_new" href="https://emote.mtwo.co.jp/">e-mote</a>
　・<a target="_new" href="http://www.webtech.co.jp/spritestudio/">Sprite Studio</a>（ただし、強力なボーン機能あり）

■主にボーンで制御
　・<a target="_new" href="http://ja.esotericsoftware.com/">Spine</a>
　・<a target="_new" href="https://blog.unity.com/ja/technology/getting-started-with-unitys-2d-animation-package">Unity 2D Animation</a>

2．運用方法
　Live2Dは面の運用に優れます。アドベンチャーゲームの立ち絵のような、正面向きの画像を動かすのが真骨頂でしょう。
（参考：Sumzap様 この素晴らしい世界に祝福を！ファンタスティックデイズ）
<iframe width="560" height="315" src="https://www.youtube.com/embed/N5y3YXrg7xE" ></iframe>

一方、Spineはその骨格を利用して、走る、跳ぶなどのアクションをさせることに秀でています。バトルキャラクターのアニメーションに向いています。
（参考：Sumzap様 この素晴らしい世界に祝福を！ファンタスティックデイズ）
<iframe width="560" height="315" src="https://www.youtube.com/embed/-Sqxk4OZZ7M" ></iframe>

とは言うものの……

SpineだってLive2Dのようなアニメーションが苦手って訳じゃないですよ？
<iframe width="560" height="315" src="https://www.youtube.com/embed/WK5wU4xmHdg"></iframe>

次回は、アニメーター視点での違いを書きたいな、と思います。
https://qiita.com/TakaakiNagasawa/items/b06b6330938c7efa73fb

■このブログについて
<a target="_new" href="https://artner.jp">株式会社Artner</a>の長澤と申します。元々3Dアニメを制作していた弊社ですが、近年ではスマートフォンアプリ、ブラウザゲームとの相性が良い、Spineによるアニメーションを主に取り扱っています。こちらのブログでは、Spineについて様々な情報やうんちくを語っていきたいな、と考えています。
【Ruby】mapメソッドを使ったリファクタリング

# ポイント
**空の配列を用意して、他の配列をループ処理した結果を空の配列に詰め込んでくような処理の大半は、mapメソッドに置き換えることができる。**
# 例

```ruby
def to_ints(hex)
  r, g, b  = hex[1..2], hex[3..4], hex[5..6]
  ints = []
  [r, g, b].each do |s|
    ints << s.hex
  end
  ints
end

# to_ints('#000000')
# => [0, 0, 0]

# to_ints('#ffffff')
# => [255, 255, 255]
```

上のコードの処理は、
・引数の文字列から3つの16進数を抜き出し、
・3つの16進数を配列に入れ、ループを回しながら10進数の整数に変換した値を別の配列に詰め込み、
・10進数の整数が入った配列を返す。
という処理を行っています。

ここで冒頭のポイントの通り、
**「空の配列を用意して、他の配列をループ処理した結果を空の配列に詰め込んでくような処理の大半は、mapメソッドに置き換えることができる。」**
ので、以下のようにmapメソッドに置き換えられます。

```ruby
def to_ints(hex)
  r, g, b  = hex[1..2], hex[3..4], hex[5..6]
  [r, g, b].map do |s|
    s.hex
  end
end
```

mapメソッドはブロックの戻り値を配列の要素にして新しい配列を返すメソッドなので、
リファクタリング前のコードのように、変数を用意しなくとも、
mapメソッドとブロックだけで処理を完結できます。

# 参考文献
伊藤 淳一 「プロを目指す人のためのRuby入門」, 技術評論社, 2017

https://docs.ruby-lang.org/ja/latest/method/Array/i/map.html
Kintoneのポータルにアプリを指定したソート順で表示する


## ポータルにアプリを全部表示させたい
* [ポータル画面の内容をアプリで管理しよう(classic-appの使い方) ~ kintoneのポータルカスタマイズ紹介#3 ~
](https://developer.cybozu.io/hc/ja/articles/900003334846-%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%AB%E7%94%BB%E9%9D%A2%E3%81%AE%E5%86%85%E5%AE%B9%E3%82%92%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E7%AE%A1%E7%90%86%E3%81%97%E3%82%88%E3%81%86-classic-app%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9-kintone%E3%81%AE%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%AB%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E7%B4%B9%E4%BB%8B-3-)
* 上記をもとに無事アプリをポータルに表示することができました。
* が、アプリのソート順が指定できず、登録した順に表示されるので、ちょこっとJSをいじりました。

## やったこと

* ポータル管理アプリのサブテーブル「リンク」に、ソート順（フィールドコード：order）を追加
![ポータル管理アプリ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1309306/50435ecf-821e-d48c-c994-3235c65baa92.png)


```js:classic-days2020
  const fetchKintoneRecord = (appId, recordId) => {
    return kintone.api(kintone.api.url("/k/v1/record", true), "GET", { app: appId, id: recordId }).then((res) => {
      const sorted_sections = res.record.sections.value.sort((a, b) => {
        if (a.value.sectionId.value*1 > b.value.sectionId.value*1) {
          return 1
        } else {
          return -1
        }
      })  
      const sorted_links = res.record.links.value.sort((a, b) => {
        if (a.value.order.value*1 > b.value.order.value*1) {
          return 1
        } else {
          return -1
        }
      })
      const sorted = {
        record: {
          ...res.record,
          sections: {
            value: sorted_sections
          },
          links: {
            value: sorted_links
          }
        }
      }
      return sorted
    })
  }

  // 元のソースはこれ
  // const fetchKintoneRecord = function (appId, recordId) {
  //   return kintone.api(kintone.api.url("/k/v1/record", true), "GET", { app: appId, id: recordId });
  // };
```

* ``fetchKintoneRecord``を少し変更し、セクションはセクションIDで、リンクはorderの順にソートするようにしました。

## 感想
* そもそもポータル管理アプリにアプリの名前とURLを登録するところがめんどくさかった。。
* でもこれで今後のメンテが楽になると信じて。
* 以上、超小ネタでした。
Stripe Connectを使ってシンプルなサービスをつくる

Stripe Connectは「プラットフォームとマーケットプレイスのための決済インフラ」としてStripeが提供している機能です。 Stripe Connectを使うとStripeアカウント間で親子関係を作り、子アカウントへの支払いに対してプラットフォーム手数料を徴収したり、親のアカウントで支払いを回収してから子アカウントに入金するといったフローが簡単にできるようになります。

https://stripe.com/jp/connect

今回Stripe Connectを活用して[**1日100円で応援したい人のページにメッセージを掲載できるパフォーマー応援プラットフォーム　tip me**](https://tipme.fun/tipme)というサービスを作りました。

## 使用フレームワーク
バックエンド: Ruby on Rails
フロント：ActionView(Rails) + Vue.js

## 支払いのフロー
実際のお金の流れは下記のようになります。

![direct_charges.a2a8b68037ac95fe22140d6dde9740d3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1676771/c04c9562-c3c3-bd63-6f16-760353ac415f.png)


出典: https://stripe.com/docs/connect/enable-payment-acceptance-guide


## 実装の流れ
下記がざっくりとした実装の流れになります。変数部分は適宜読み替えてください。
前提として、stripe-ruby gemをインストールし、パブリックキー、シークレットキーを設定しておきます。

１. Stripeアカウントの作成

```ruby
account = Stripe::Account.create({
                  type: account_type,
                  country: 'JP',
                  default_currency: 'jpy',
                  email: current_user.email})
```
参照） https://stripe.com/docs/api/accounts/create


２. Stripeアカウントをリンクさせる（親子関係の作成）

```ruby
account_link = Stripe::AccountLink.create({
                  account: account.id,
                  refresh_url: stripe_url,
                  return_url: stripe_callback_url,
                  type: 'account_onboarding',
                })
```
アカウントリンク作成後 ```redirect_to account_link.url```にてStripeアカウントの情報入力画面へリダイレクトさせます。

参照） https://stripe.com/docs/api/account_links/create


３. 決済

```ruby
Stripe::Charge.create({
                   amount: total_amount,
                   currency: currency,
                   source: stripe_token,
                   application_fee_amount: application_fee_amount,
                   expand: ['balance_transaction']
                 }, 
                 stripe_account: stripe_account_id )
```
stripe_accountに子アカウントのidを入力します。

参照） https://stripe.com/docs/api/charges/create


以上が非常にざっくりですが実装の流れです。
注意点として、Stripeアカウントにはstandard, express, customの3種類があり、standard以外のアカウントを子アカウントとしてStripe Connectを使用すると子アカウントの維持、出金時に手数料が発生します。

参照） https://stripe.com/jp/connect/pricing


## おわりに
パフォーマー、サポーターの皆さんにとってより良いサービスにしていきたいと思っています。
ご意見・感想・ご質問等あればお気軽に連絡ください。
https://tipme.fun
herokuでアプリを修正して更新するとき

>herokuでアプリを公開しているものを更新するとき


まずherokuは**「gitと連携して、gitに保存した内容をデプロイ」**している。
なので、変更したいときは次のコマンドを使う

```:terminal
% git add -A
% git commit -m "Update application"
% git push heroku master
```

またテーブル追加や内容変更などをした場合は次のコマンドも実行する

```:terminal
% heroku run rails db:migrate
```
超初心者がPythonで5分足チャートから移動平均線を計算してグラフに表示してみた

SMA=Simple Moving Agerage。移動平均線。作業は超簡単。

## 参考

以下で作成しているコードを数行変更するだけです。

https://qiita.com/emilia/items/7f9d137ad3e557df0535

## コード

``` draw_sma
import pandas as pd
import datetime
import mplfinance as mpf

df = pd.read_csv('./temp_historical_data/USDJPY.csv', nrows=2000)
df.columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume']
df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace=True)

df5 = pd.DataFrame()
rule = '5T'
df5['Open'] = df['Open'].resample(rule).first()
df5['Close'] = df['Close'].resample(rule).last()
df5['High'] = df['High'].resample(rule).max()
df5['Low'] = df['Low'].resample(rule).min()

mpf.plot(df5, type='candle', mav=(5, 25), 
        datetime_format='%Y/%m/%d %H:%M', xrotation=90, style='yahoo', savefig=dict(fname='./figures/draw_sma.png',dpi=100))

```

## グラフ

![draw_sma.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69727/10bf80b5-54aa-6fb2-8f76-daaf6773049f.png)

## 説明

mpf.plotの引数にmavを追加するだけ。便利すぎるナリ。計算不要。
ちなみにpandasの方を使って計算するには以下のようにする。

```
df5["SMA5"] = df5["Close"].rolling(window=5).mean()
df5["SMA25"] = df5["Close"].rolling(window=25).mean()
```

実際にはSMAの値も計算しておいてあれやこれやしたいと思うので、以下みたいな方がいいかもしれない？

```
df5 = pd.DataFrame()
rule = '5T'
df5['Open'] = df['Open'].resample(rule).first()
df5['Close'] = df['Close'].resample(rule).last()
df5['High'] = df['High'].resample(rule).max()
df5['Low'] = df['Low'].resample(rule).min()

sma = pd.DataFrame()
sma["SMA5"] = df5["Close"].rolling(window=5).mean()
sma["SMA25"] = df5["Close"].rolling(window=25).mean()

addplot = mpf.make_addplot(sma[['SMA5', 'SMA25']])
mpf.plot(df5, type='candle', addplot=addplot,
        datetime_format='%Y/%m/%d %H:%M', xrotation=90, style='yahoo', savefig=dict(fname='./figures/draw_sma.png',dpi=100))
```
超初心者がPythonでHistData.comから取得した1分足データを5分足データに変換してみた


1分足だとグラフ化の際にデータ数が多すぎてみづらかったので5分足にする。

## 参考

https://qiita.com/bunnyhopper_isolated/items/7a85aa55cb107e040f7c

以下で作成したコードを利用しています。

https://qiita.com/emilia/items/973ad97dd96d1cb639f4

## コード

```
import pandas as pd
import datetime
import mplfinance as mpf

# CSVから読み込み
df = pd.read_csv('./temp_historical_data/USDJPY.csv', nrows=1000)
df.columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume']
df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace=True)

# 5分足変換
df5 = pd.DataFrame()
rule = '5T'
df5['Open'] = df['Open'].resample(rule).first()
df5['Close'] = df['Close'].resample(rule).last()
df5['High'] = df['High'].resample(rule).max()
df5['Low'] = df['Low'].resample(rule).min()

mpf.plot(df5, type='candle', datetime_format='%Y/%m/%d %H:%M', xrotation=90, style='yahoo', savefig=dict(fname='./figures/draw_sma.png',dpi=100))
```

## 簡単な説明

Dateはいじらなくて大丈夫っぽい？ただし、元データ（ここではdf）にDatetime型のindexを設定しておかないとだめなようだった。
Laravelで細かくSQLを指定したい場合に使える「rawメソッド」

LaravelでSQL文を構成する際、クエリビルダではなく直接細かいカスタマイズをしたい時がある。

そんな時はrawメソッドを使う。

```
DB::select('\DB::raw('users.*')')
```

rawメソッドを使う事でクエリビルダで構成されたSQLに生のSQLを差し込む事ができる。

https://readouble.com/laravel/5.7/ja/queries.html
Swift クロージャー（引数としてのクロージャ）

クロージャのキャプチャ
---
クロージャはインスタンスが作られる時に外部にある変数を取り込んでインスタンスの一部にすることをキャプチャという

```swift:キャプチャ:swift
func outer() -> () -> Void{
    
    var x = 111
    
    func inner(){
        
        print("X is \(x)")
        x  = x + 1//inner関数内で定義されていないx変数を操作している。ここがキャプチャ。
    }
    return "キャプチャだよ"
}
```

クロージャによる強参照
--
swiftではARCという仕組みでメモリ領域内のオブジェクトを管理している。（他のオブジェクトから参照されている数を記録（参照カウント）を記録している）
この参照カウントが１以上だった場合が強参照になる（０になった時メモリが開放される）
つまりSWiftではデフォルトで強参照になるようになっている。
この設定により、２つのインスタンスが互いに強参照しあっている循環参照になることが多い。これは参照カウントが０になることがないため絶対にメモリの開放は起きない。これは後々にメモリリークによるパフォーマンスの低下に繋がる可能性がある。だからこそ、通常のデリゲートプロパティはweakを付けて弱参照にしている。
これはインスタンス化しているクロージャーにも発生しうる。これを回避するために```[weak self]```を付ける必要がある。

書き方(ドキュメントより）

```swift:参照.swift
//強参照 クロージャーのインスタンスとクラスのインスタンスがイニシャライザすると参照しあう
class A {
  var closure: (() -> Void)?
  let prop = "prop"

  // クロージャが、self.prop を強参照している
  func setClosure() {
    closure = {
        print("\(self.prop) が呼ばれました")
    }
  }

  deinit {
    print("解放されました")
  }
}

var a: A! = A()
a.setClosure()
a.closure!()
a = nil


//弱参照
class A {
  var closure: (() -> Void)?
  let prop = "prop"

  func setClosure() {
    // `[weak self]` と定義して、selfへの参照を弱参照にする
    closure = { [weak self] in
      if let weakSelf = self {
        print("\(self.prop) が呼ばれました")
      }
    }
  }

  deinit {
    print("解放されました")
  }
}

var a: A! = A()
a.setClosure()
a.closure!()
```



トレイリングクロージャとは
---
通常クロージャは```()```の中に入れるが,（）の外で｛｝処理を記述できる記法です。
引数の最後クロージャ型のみに書くことができる。```return```がない

```swift:closer.swift
//通常であれば

test(int:Int,int2:Int,callback:｛x in print(x)})
//トレイリングクロージャを使用して実行
test(int:Int,int2){ print(x) }

```

通常の記法であれば関数の呼び出しの（）が後まで多く広がってしまい、複数行にまたがると可読性が低くなってしまう
仮にクロージャのみが引数だった場合は引数のカッコも省略できる


引数としてのクロージャー
---
引数にクロージャは@escaping,@autoclosure属性の２つと上記のトレイリングクロージャが存在する

書き方

```swfit:closure.swift
func 関数名(引数名: @属性名 クロージャーの型名) {
 　関数呼び出し時に実行される文
}

```

escaping属性
--
escapingとは関数に引数として渡されたクロージャがスコープを抜けても存在しうる場合に付与する属性。
関数に引数として渡されたクロージャは非同期的に実行される
クロージャの実行時まで、外から持ってきた変数を保持しておく必要があるためキャプチャが必要になってくる。
具体例　外で定義されてある配列にクロージャー内からアクセスして、appendしていく時等、非同期処理の後にクロージャを発火させたい時


```swift:escaping.swift
var array = [()->Void]()

func addArray(operation: @escaping()->Void) {
 array.append(operation)
}
arrat.forEach{$0()}
```



autoclosure属性
--
 autoclosureとは引数をクロージャで包むことで遅延評価をすること
そもそも遅延評価とは値が必要になるまでその値の評価を遅らせること
遅らせたい評価の引数にautoclosure属性をつけることで遅延評価が実装できる


```swift:autoclosure.swift
func auto() -> Bool {
  print("autoだよ")
  return true
}

func closure() -> Bool {
  print("closureだよ")
  return true
}

// closure() に @autoclosure を定義する
func printFunc(auto: Bool, closure: @autoclosure () -> Bool) {
  if auto() {
    print("autoはtrueです")
  } else if closure() {
    print("closureはtrueです")
  } else {
    print("どちらともfalseです")
  }
}

// func2 に値を引数として渡す
printFunc(func1: auto(), func2: closure())

```
Pythonのmatplotlibの正負のある積み上げグラフ内のデータラベルを追加する．

## この記事が役に立つ人

- Pythonのmatplotlibで正負混合のデータの積み上げグラフ内にラベルを入れたい人
- 積み上げグラフの幅が狭いときラベルを省略したい人

## ラベルの位置決め

正負混合のデータの積み上げグラフはpandasの描画機能で次のように作ることができます．

```python
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt

df = pd.DataFrame({'id':[1,2,3,4,5,6],
                   'f1':[30,45,10,15,4,30],
                   'f2': [20,-30,60,-40,45,-4],
                   'f3': [50,25,-30,45,15,2]})
df = df.set_index('id')
ax = plt.subplot()
df.plot.bar(stacked=True, legend=True, ax=ax)
ax.set_ylabel('value')
```

グラフは次のようになります．

![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75230/5eee24e8-e722-37c4-c96d-013b5697bf07.png)

正負混在しているグラフでは，描画されている矩形の位置が決まっていないので，参考資料にあるように位置に依存したテキストの描画ができません．

そのため，matplotlibのpatch情報を調べて矩形の描画位置を調べなければなりません．この場合のpatchはRectangleになります．Rectangleからは直接 y方向の描画位置がわかりません．

```
print (ax.patches[0])

>Rectangle(-0.25,0;0.5x30)
```

描画位置をとるには，get_bbox()を用います．これが，描画位置になります．

```
print (ax.patches[0].get_bbox())

>Bbox(x0=-0.25, y0=0.0, x1=0.25, y1=30.0)
```

patch情報は，配列として取得され，その順番は dataframe の並びに依存しています．この情報を用いて，次のようにテキストを描画できます．

```python
yno = len(df)
xno = len(df.columns)

x_offset = 0.0
y_offset = 0.0

# for p in ax.patches:
for index, p in enumerate(ax.patches):

    (xn, yn) = divmod(index, yno)
    value = df.iloc[yn,xn]
    label = df.columns[xn]

    b = p.get_bbox()

    # ypos = (b.y0 + b.y1)/2
    ypos = min(b.y0, b.y1)

    ax.text( b.x0 + x_offset, ypos + y_offset, label)

```

![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75230/a24bf78b-5c9d-7deb-d8e2-ffc3f8787121.png)

ここでは，矩形の左隅に描画しています．

## 高さの小さい矩形のなかにはラベルを書かない処理

積み上げグラフで重要な項目はデータの大きなものです．この例ではデータの数が少ないですが，多い場合は不要なテキストの描画を避けるべきです．データの値によって選択することもできますが，データの値がわからないときは，描画位置から決めることができます．

次に一例をあげます．この例では，描画範囲の6%未満のデータにはテキストを書きません．

```python
yno = len(dfs)
xno = len(dfs.columns)

# check max range of bar    
rmax = 0
rmin = 0
for index, p in enumerate(ax.patches):
    b = p.get_bbox()
    if (b.y1 > rmax):
        rmax = b.y1
    if (b.y0 > rmax):
        rmax = b.y0
    if (b.y1 < rmin):
        rmin = b.y1
    if (b.y0 < rmin):
        rmin = b.y0              
rrange = rmax-rmin

x_offset = 0.0
y_offset = 0.0
t_height = rrange*0.06  # condition for adding text

for index, p in enumerate(ax.patches):
    (xn, yn) = divmod(index, yno)
    value = dfs.iloc[yn,xn]
    label = dfs.columns[xn]

    b = p.get_bbox()

    height = abs (b.y1 - b.y0)

    if (height < t_height):	# 高さが小さいならスキップ
        continue
    ypos = min(b.y1, b.y0)
#   ypos = (b.y1 + b.y0)/2

    ax.text( b.x0 + x_offset, ypos + y_offset, label)
```

![graph3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75230/74ce86dd-e50b-ddf1-6027-0bb3f0d0bea6.png)


## 参考情報

[Pythonのmatplotlibで積み上げ棒グラフを作成しデータラベルを追加してみた](https://qiita.com/s_fukuzawa/items/6f9c1a3d4c4f98ae6eb1)

[Annotate bars with values on Pandas bar plots](https://stackoverflow.com/questions/25447700/annotate-bars-with-values-on-pandas-bar-plots)
【ridge正則化】ridge正則化の解析解に現れる逆行列は常に存在するのか？


# モチベーション
本記事で一番書きたいことは、ridge正則化における重みの最適解の中にでてくる逆行列についてで、$\mathbf {X^\top X}$が正則でなくても$\mathbf{X^\top X + \lambda I}$の逆行列が常に存在することについての軽い証明です。

いろんな記事を探ってみましたが、この部分についてちゃんと説明しているものが見当たらなかったので、参考文献をもとに勉強したことをアウトプットとしてまとめてみます。
# ridge正則化における解析的解
Ridge回帰はモデルが複雑になるのを抑制するために二乗和誤差に重みパラメータ$\mathbf w$の二乗ノルム$||\mathbf w||_2^2$に正則化パラメータ$\lambda>0$を掛けた項を加えるものです。

```math
L = \frac{1}{2} \sum_{n=1}^N (\hat y_n -  t_n)^2 + \frac{\lambda}{2}\|\mathbf w\|_2^2
```
って感じです。
回帰モデルの式として行列とベクトルを用いて表現すると

```math 
y(\mathbf X) = \mathbf{X w}
```
です。これを目的関数Lにぶちこんで$\mathbf w$に関する微分を0とおくと

```math 
\hat{\mathbf w} = (\mathbf{X^\top X + \lambda I})^{-1}\mathbf{X^\top t}
```
という解析的な解が得られます。
最小二乗法の時は$\lambda=0$のときに対応するわけですが、そのときは実対称行列$\mathbf {X^\top X}\in \mathbb R^{d\times d}$が正則でないと逆行列は計算できません。
正則でない場合については「**ムーアペンローズの擬似逆行列**$\mathbf X^\dagger$を使いますよ」という補足がよく参考書とかでは入ります。いつものやつです。
でも$\lambda > 0$の場合、つまりridge正則化をするときはこのような注釈は特に入りません。その理由を次項で説明します。
# 逆行列が存在するかしないか
$\mathbf {X^\top X}$が実対称行列であることに着目すると、次のように直交行列$\mathbf P$を用いて対角化できます。

```math 
\mathbf{X^\top X} = \mathbf{P\Gamma P}^\top = \mathbf P \rm{diag}(\gamma_1,\dots,\gamma_d) \mathbf P^\top
```
ただし$\mathbf \Gamma$は$\mathbf {X^\top X}$の固有値$(\gamma_1 \ge \dots \ge \gamma_d\ge0)$からなる対角行列。
ここで最小の固有値$\gamma_d$について$\gamma_d > 0$とします。
このとき$\mathbf{X^\top X}$の逆行列について

```math 
\begin{aligned}
(\mathbf {X^\top X})^{-1} &= (\mathbf{P\Gamma P^\top})^{-1}\\
&=(\mathbf{P \rm{diag}(\gamma_1,\dots,\gamma_d)\mathbf P}^\top)^{-1}\\
&=\mathbf{P}\rm{diag}(1/\gamma_1,\dots,1/\gamma_d)\mathbf P^\top\\
\end{aligned}
```
いま、$\gamma_d \rightarrow 0$の極限を考えると、$1/\gamma_d \rightarrow \infty$となり、逆行列は計算できなくなります。

さて、ここからが本題ですが、ridge正則化の時に現れる$\mathbf{X^\top X + \lambda I}$の逆行列は常に存在するのでしょうか。

先ほどと同様に$\mathbf{X^\top X}$の対角化を用いて考えてみます。

```math 
\begin{aligned}
(\mathbf {X^\top X + \lambda I})^{-1} &= \{\mathbf{P\Gamma P}^\top +\lambda \mathbf I \} ^{-1}\\
&=\{\mathbf{P(\Gamma + \lambda I)P^\top} \}^{-1}\\
&=\mathbf{P}(\mathbf{\Gamma+ \lambda I})^{-1}\mathbf{P}^\top \\
&=\mathbf{P}\rm{diag}(1/(\gamma_1 + \lambda),\dots,1/(\gamma_d + \lambda))\mathbf{P}^\top
\end{aligned}
```
途中の式変形では直交行列の性質を用いました。

```math 
\begin{aligned}
\mathbf{P}^{-1} &= \mathbf{P}^\top\\
\mathbf{PP^\top} &=\mathbf{P^\top P} = \mathbf I
\end{aligned}
```
ここでも$\gamma_d \rightarrow 0$の極限を考えてみると、$1/(\gamma_d + \lambda) \rightarrow 1/\lambda > 0(\because\lambda > 0)$となり、逆行列が計算できます。
したがって、$\mathbf{X^\top X}$の逆行列が存在しない場合においても、$\mathbf{X^\top X + \lambda I}$の逆行列は常に存在するといえます。

# 参考文献
- [「スパース推定法による統計モデリング(統計学 One Point)」川野秀一・松井秀俊・廣瀬慧,共立出版](https://www.amazon.co.jp/gp/product/4320112571/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)
- [実対称行列の性質と直交行列による対角化](https://ramenhuhu.com/math-real_symmetric_matrix)
2.18(易) 積率母関数4

## 方針

問題文の道筋に乗って計算していく．

## 答案

```math
\begin{align}
M_X(t)&= \int_0^1(m+1)x^me^{tx}dx\\
&= \int_0^1(m+1)x^m\sum_{k=0}^\infty\frac{(tx)^k}{k!}dx\\
&= \int_0^1(m+1)\sum_{k=0}^\infty\frac{t^kx^{m+k}}{k!}dx\\
&= \left[(m+1)\sum_{k=0}^\infty\frac{t^kx^{m+k+1}}{(m+k+1)k!}\right]_0^1\\
&= \sum_{k=0}^\infty\frac{m+1}{(m+k+1)k!}t^k
\end{align}
```

したがって，

```math
\begin{align}
\frac{d}{dt}M_X(t)&= \sum_{k=0}^\infty\frac{m+1}{(m+k+1)k!}kt^{k-1}\\
&= \frac{m+1}{m+2}+\sum_{k=3}^\infty\frac{m+1}{(m+k+1)k!}kt^{k-1}\\
\mathbb{E}_{X\sim f_X}[X]&= \left.\frac{d}{dt}M_X(t)\right|_{t=0}=\frac{m+1}{m+2}\\
\frac{d^2}{dt^2}M_X(t)&= \sum_{k=0}^\infty\frac{m+1}{(m+k+1)k!}k(k-1)t^{k-2}\\
&= \frac{m+1}{m+3}+\sum_{k=4}^\infty\frac{m+1}{(m+k+1)k!}k(k-1)t^{k-2}\\
Var(X)&= \frac{m+1}{m+3}-\frac{(m+1)^2}{(m+2)^2}\\
&= \frac{m+1}{(m+2)^2(m+3)}
\end{align}
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
WioLTE: ブザーを鳴らす

WioLTE で Arduino Grove の　「ブザー・モジュール」を使う方法です。
「ブザー・モジュール」を「D38」に取り付けます。
参考ページ
[Wio LTE for Arduino で LED を点灯させる](https://qiita.com/ekzemplaro/items/b84bbdc1d62a40aeee76)
[Arduino で、ブザーを鳴らすサンプルプログラム](https://qiita.com/ekzemplaro/items/682034f95a8f74c64778)

## プログラム

```text:grove-buzzer/grove-buzzer.ino
#include <WioLTEforArduino.h>

#define BUZZER_PIN      (WIOLTE_D38)
#define BUZZER_ON_TIME  (100)
#define BUZZER_OFF_TIME (1500)

WioLTE Wio;

void setup()
{
  pinMode(BUZZER_PIN, OUTPUT);
  delay(500);
  Wio.Init();
}

void loop()
{
  digitalWrite(BUZZER_PIN, HIGH);
  Wio.LedSetRGB(0, 0, 255);
  delay(BUZZER_ON_TIME);

  digitalWrite(BUZZER_PIN, LOW);
  Wio.LedSetRGB(0, 0, 0);
  
  delay(BUZZER_OFF_TIME);

    digitalWrite(BUZZER_PIN, HIGH);
    Wio.LedSetRGB(0, 255, 0);
  delay(BUZZER_ON_TIME * 2);

  digitalWrite(BUZZER_PIN, LOW);
  Wio.LedSetRGB(0, 0, 0);
  delay(BUZZER_OFF_TIME * 2);
}
```

## Arduino IDE

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/74e1f098-ce29-e657-cf4d-42f75a27d1e0.png)
paginateがあるとtoSql()での中身確認ができない


LaravelではtoSql()でSQLの中身を確認する際、paginateは外さなければならない。

■元となるSQLの例
```$query->paginate(100);
```


:::note alert
※NG例
$query->paginate(100)->toSql();
:::


:::note info
※OK例
$query->toSql();
:::
"指定されたコンパイラー準拠は x.y ですが、JRE zz が使用されています"の解消

Eclipse でプロジェクトを作ると
``指定されたコンパイラー準拠は 1.5 ですが、JRE 11 が使用されています``
みたいなWarningが出ることがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414729/2adac0fe-e55c-4f48-3bb3-5170e50c6640.png)
これはまんま、このプロジェクトでコンパイル/ビルド用に指定した``javac``のバージョンが``1.5``になっているが、実際に環境にインストールされているJavaのバージョンは``JRE 11``ですよと言っている。
実際問題、Java 1.5 でコンパイルしたコードは Java 11 でも Deprecated になった API さえ利用していなければほとんどの場合動作すると思う。けれど Warning が出たままだと気持ち悪いし、古い API を間違って使ってしまうのも嫌なので、実行環境の JRE のバージョンとビルド用の javac のバージョンを合わせる方法について以下に記載する。

プロジェクトの``JRE システム・ライブラリー～``を右クリック、プロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414729/d8020dac-0787-4a03-81a1-47e177f9c2c9.png)
実行環境のバージョンに、先ほどのエラーで``JRE 11 が使用されています``と記載されていたので``JRE 11``を選択して適用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414729/4bff7e5d-a719-3d52-2e79-c3e67f0944b0.png)
こんな感じで Warning が消える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414729/533266d7-f96a-19d6-6e75-e524e19c80f9.png)
【Google Cloud Day'21】「Cloud SQL 最前線 〜最新機能紹介と利用前に確認したい 5 つの設定〜」を視聴して

Cloud SQL 最前線 〜最新機能紹介と利用前に確認したい 5 つの設定〜
https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d2-da-01
Cloud SQL は MySQL、PostgreSQL、SQL Server 向けのフルマネージド リレーショナル データベース サービスです。本セッションでは、その最新機能と利用前に有効にしておきたい設定をご紹介します。

<table>
	<tr>
		<th>質問</th>
		<th>返答</th>
	</tr>
	<tr>
		<th>MySQLでQuery Insightsの提供予定はあるのでしょうか。</th>
		<td>ご要望はいただいておりますので、Query Insights については PostgreSQL 以外のエンジンについても検討をしております。</td>
	</tr>
	<tr>
		<th>確約割引の適応範囲はプロジェクト単位になりますか？請求アカウント単位であったら嬉しいですが...</th>
		<td>確約利用割引の提要範囲は、請求先アカウント単位です。詳細はこちらをご確認ください。 https://cloud.google.com/sql/cud?hl=ja</td>
	</tr>
	<tr>
		<th>同期レプリケーションの場合の同期による遅延はどれくらいでしょうか。また、非同期レプリケーションのレプリカへの伝播はどのくらい遅延するのでしょうか。</th>
		<td>同期による遅延、リードレプリカのレプリカへの伝播ともにデータの更新量などのワークロードに依存するため、一概には申し上げらません。この点についてはお客様のワークロードを元にベンチマークなどでご確認いただきたいと考えています。</td>
	</tr>
	<tr>
		<th>GAS から Cloud SQL を利用する場合 MySQL のバージョンが 5.6 に限定されてしまうのですが、このあたりは今後改善されますでしょうか？</th>
		<td>Apps Script より JDBC 接続を用いて Cloud SQL への接続をされたいということでしょうか。特にバージョンが5.6に限定されるようなことはない認識ですので、想定通り行かない場合はサポートにお問い合わせいただくとよいかと存じます。</td>
	</tr>
	<tr>
		<th></th>
		<td>JDBC 接続: https://developers.google.com/apps-script/guides/jdbc</td>
	</tr>
	<tr>
		<th></th>
		<td>質問に誤りがありました。バージョンの縛りというわけではなく MySQL 8.0 で GAS から接続した時に JDBC エラーが発生するので5.7 を選択しています。</td>
	</tr>
	<tr>
		<th></th>
		<td>ネットでも同じ現象が報告されてます（https://www.xenos.jp/~zen/blog2/index.php/2020/11/15/post-4697/）。</td>
	</tr>
	<tr>
		<th>Cloud SQLに関連する内容として質問させていただきたいのですが、BigQuery Cloud SQL 連携機能のサポートは現在MySQLとPostgreSQLのみですが、今後SQL Serverがサポートされる予定はございますでしょうか？</th>
		<td>ご要望はいただいておりますので、今後もお客様の声をお聞きしていきたいと思います。よろしくお願いいたします。</td>
	</tr>
</table>

<table>
	<tr>
		<th>切り口</th>
		<th>内容</th>
	</tr>
	<tr>
		<th>マネージドデータベースを使う理由</th>
		<td></td>
	</tr>
	<tr>
		<th>クエリの改善</th>
		<td>分析の速度を上げることが可能になる。</td>
	</tr>
	<tr>
		<th>利用時のポイント</th>
		<td></td>
	</tr>
	<tr>
		<th>運用前にチェックしておきたい機能</th>
		<td></td>
	</tr>
</table>

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/84c97f1c-9ad0-4053-060c-c6d41aab0ca2.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/48975515-430f-0345-e3f8-59bec7032dab.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/e113f83a-65dd-d8b3-0e96-56e8bcc612ba.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/2880ad7e-9f5c-867a-0386-dc687dd96b4b.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/ac3ad4c9-c9e0-0e34-1423-55296e4e6371.png)
【Google Cloud Day'21】「リクルートのオンプレミス Hadoop を BigQuery へマイグレーションした事例」を視聴して

リクルートのオンプレミス Hadoop を BigQuery へマイグレーションした事例
https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d2-da-03
リクルートの複数メディアで活用されている、10 クラスタ、100 ノード以上の Hadoop システムを BigQuery へ移行した事例を紹介します。どのような検証を経て採用にいたったのか、移行の中でどのような苦労があったのか、移行した結果どのような変化が起こったのか、などを紹介させていただきます。

<table>
	<tr>
		<th>質問　</th>
		<th>回答</th>
	</tr>
	<tr>
		<th>移行先DWHはBQ以外に候補はあったでしょうか。BQの良さはお伝えいただきましたが、その中でも一つ、決め手となったものを教えてください。</th>
		<td>一番の決め手は、コンピューティングリソースとストレージが分離されていたところです。我々の抱えていた課題解決に直結しました。</td>
	</tr>
	<tr>
		<th>かなりの対応、データ量ですがマイグレにはどの程度期間が必要となったでしょうか。</th>
		<td>全体では4、5年程度の期間をかけています（1クラスタにつき1~2年程度かかっています） 移行はまだ継続中ですが、現在社内にあるクラスタは最後の１つになっており、全てがBQに置き換わるゴールが見えてきております</td>
	</tr>
	<tr>
		<th>弊社もHadoopからBQへの移行を検討しています。注意点のご紹介とても助かります。ちなみに今回書き換え対象となったクエリは何本くらいあったでしょうか。</th>
		<td>書き換え対象のクエリは全体で数千本ありました ルールベースでの機械的な書き換えと人力での改修を併用して地道に移行していきました</td>
	</tr>
</table>

<table>
	<tr>
		<th>切り口</th>
		<th>内容</th>
	</tr>
	<tr>
		<th>移行の背景</th>
		<td></td>
	</tr>
	<tr>
		<th>要望</th>
		<td></td>
	</tr>
	<tr>
		<th>移行時のポイント</th>
		<td>移行してすごく早くなった。</td>
	</tr>
</table>

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/bfa0980f-32b7-5990-55d1-5b936bfd7ae4.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/548248e5-7ad6-08c4-4e67-1f39b07573e2.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/ee1b3865-217b-b107-b460-b9d3bce97eac.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/a80255a9-ad67-7a3d-77d3-9ed5588c8d90.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/4eb6b692-ca5b-47db-e106-4f8cff164004.png)
【Alpine】tar で「xz: Cannot exec: No such file or directory」エラーが解凍・展開すると返ってくる

# Alpine Linux で `.tar.zx` が解凍・展開できない

> Docker の Alpine イメージに最新版の `shellcheck` をインストールしようとしました。しかし、ダウンロードした `.tar.zx` 形式のアーカイブ・ファイルを解凍・展開しようとすると `No such file or directory` エラーが出ます。でも、ファイルは確かにあるのです。いや、本当に。

## TL; DR <sub><sup>（今北産業）</sup></sub>

1. `xz` コマンドが入っていないので `No such file or directory` と叱られます。
1. `xz` コマンドが入っていないので、当然 `exec`（実行）できないのでエラーになります。
1. `apk add --no-cache xz` でインストールします。（`xz` のスペルに注意）

## TS; DR <sub><sup>（`xz-utils` なんてなかった）</sup></sub>

```shell-session:tarも入ってる
$ which tar
/bin/tar
```

```:エラー内容の例
#8 0.467 Install shellcheck
#8 0.471 TEMP PATH: /tmp/tmp.mnPaFm TEMP FILE: /tmp/tmp.mnPaFm/shellcheck-latest.linux.x86_64.tar.xz
#8 0.485 Connecting to github.com (xxx.xxx.xxx.xxx:xxx)
#8 0.814 Connecting to github-releases.githubusercontent.com (xxx.xxx.xxx.xxx:xxx)
#8 1.183 saving to '/tmp/tmp.mnPaFm/shellcheck-latest.linux.x86_64.tar.xz'
#8 1.386 shellcheck-latest.li 100% |********************************| 1350k  0:00:00 ETA
#8 1.386 '/tmp/tmp.mnPaFm/shellcheck-latest.linux.x86_64.tar.xz' saved
#8 1.389 tar (child): xz: Cannot exec: No such file or directory // <- ここ
#8 1.389 tar (child): Error is not recoverable: exiting now
#8 1.390 tar: Child returned status 2
#8 1.390 tar: Error is not recoverable: exiting now
```

よく確認もせず `apk add xz-utils` したら、そんなパッケージはないと叱られます。「んなこたーない」と、Alpine 本家のパッケージ一覧を検索したら出て来ました。`xz` だけで良かった。

- [xz](https://pkgs.alpinelinux.org/package/edge/main/x86/xz) | edge | Packages @ pkgs.alpinelinux.org

```
apk add --no-cache xz
```

[「`"alpine" tar xz: Cannot exec: No such file or directory`」でググって](https://www.google.com/search?q=%22alpine%22+tar+xz%3A+Cannot+exec%3A+No+such+file+or+directory)も `apt` や `apt-get` の情報ばかりで、Alpine の情報がすぐに出てこなかったので、自分のググラビリティとして。

### おまけ <sub><sup><sub><sup>（shellcheck を Alpine Docker に入れるワンライナー）</sup></sub></sup></sub>

```dockerfile:shellcheckをAlpineのDockerにインストールするワンライナー
RUN echo "Install shellcheck" \
    && name_file_arch="shellcheck-latest.linux.$(uname -m).tar.xz" \
    && url_download="https://github.com/koalaman/shellcheck/releases/download/latest/${name_file_arch}" \
    && path_dir_tmp=$(mktemp -d) \
    && path_file_arch="${path_dir_tmp}/${name_file_arch}" \
    && wget -P "${path_dir_tmp}" "$url_download" \
    && tar x -v -f "$path_file_arch" -C "$path_dir_tmp" \
    && cp "${path_dir_tmp}/shellcheck-latest/shellcheck" "${GOPATH:?Undefined}/bin/shellcheck" \
    && shellcheck --version \
    && rm -rf "${path_dir_tmp:?Undefined}"
```
ec2のamazon linux2 にnginx+php-fpm+php7.4+phalcon4 セットアップ


#ログインしてrootで作業します

```

timedatectl set-timezone Asia/Tokyo
timedatectl status
localectl set-locale LANG=ja_JP.UTF-8


yum update

amazon-linux-extras install php7.4

amazon-linux-extras install nginx1

```

アップグレードの場合、旧バージョンが有効になっていたらできない。ので以下

```
 amazon-linux-extras disable php7.3
 yum remove --enablerepo=remi-php73 php-phalcon3
```

epelのインストール設定がいろいろ調べるとありますが、AmazonLinux2のamazon-linux-extras に存在したので、それをインストールして、有効にすればOKです。

```
amazon-linux-extras install epel

yum-config-manager --enable epel

yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm

yum install php-mbstring

yum install pcre-devel



curl -s https://packagecloud.io/install/repositories/phalcon/stable/script.rpm.sh | sudo bash

yum install php-devel php-opcache php-mbstring php-xml php-gd php-json
yum install --enablerepo=remi-php74 php-phalcon4


# phalconは、/etc/php.d/にあるのを確認

```