OmniAICreator/Qiita-1.07M huggingface dataset:
Visual Studio Code ServerをDockerで構築

ブラウザで利用できるVSCodeが公式より案内されました。
https://code.visualstudio.com/blogs/2022/07/07/vscode-server

今回、Dockerでvscode-serverが利用できる環境を構築します。

# Dockerfile
```:Dockerfile
FROM ubuntu:22.04
RUN apt update && apt install wget -y
RUN wget -O- https://aka.ms/install-vscode-server/setup.sh | sh
```

# Docker Build
```run
docker build . -t code-server
```

# Docker RUN
```run
docker run --name code-sv --rm -it -p 8000:8000 -v work:/work -w /work code-server code-server serve-local --host 0.0.0.0 --accept-server-license-terms
```

# アクセス
コンソールにトークンの含まれたURLが表示されるのでlocalhost部分を利用される環境に合わせて指定してください。
```run
Web UI available at http://localhost:8000/?tkn=7845fb65-bc17-4cb0-9281-388da8d72b6d
```

新しい技術にどんどん触れて、自身をアップデートしていこう！
【Flutter】AndroidでSQLiteのテーブルのデータを確認する

Flutterを使って個人で以下のスマホ向けのおみくじアプリ（大御心アプリ）を開発・運用しています。

<img width="130" alt="Screenshot_home.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/d4a6102b-53cd-eb2c-f333-5e23392e7f29.png">
<img width="130" alt="Screenshot_fortune_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/ccc35e8e-f92e-308a-3fb8-8d194e2edc16.png">
<img width="130" alt="Screenshot_fortune_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/c6959d28-9900-9789-84b1-d909607acc40.png">
<img width="130" alt="Screenshot_emperor_list.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/34b47a38-04e2-1ac9-baf8-6da0e8848086.png">
<img width="130" alt="Screenshot_emperor_detail.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/d68400a0-2926-1b1c-764f-76efaa7729e3.png">

[iOS]
https://apps.apple.com/us/app/%E5%A4%A7%E5%BE%A1%E5%BF%83%E3%82%A2%E3%83%97%E3%83%AA/id1627544916

[Android]
https://play.google.com/store/apps/details?id=jp.sikisimanomiti.oomigokoro

上記おみくじアプリはSQLiteを使ってローカルにAPIからの一部のデータを保持しているのですが、アプリを開発・デバッグする過程でSQLiteのテーブルのデータをGUIで確認したくなったので確認方法を調べました。

# AndroidでSQLiteのデータを確認する方法
- ①Android StudioのDatabase Inspectorを使って確認する
- ②ADBコマンドを使う

## ①Android StudioのDatabase Inspectorを使って確認する
1  エミュレータでアプリを実行します。
2 メニューバーで「View」 > 「Tool Window」 > 「App Inspection」を選択します。
<img width="500" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/3d925e17-b2bf-c4f6-c3a0-a0550e5d0736.png">

3 「App Inspection」が開いたら、実行中のアプリプロセスを選択します。
![スクリーンショット 2022-07-25 22.30.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/94250dd5-75bc-8c41-dab5-3a1d08211b13.png)

4 「Database Inspector」タブを選択します。
![スクリーンショット 2022-07-25 22.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/c8fe63fe-7abf-4851-9564-ad1efea947f1.png)

5 「Database」ペインに接続したアプリのデータベースを表示します。確認したいテーブルをクリックすると、実際に格納しているデータを閲覧できます。セルをダブルクリックすると、編集でき反映することができます。
![スクリーンショット 2022-07-25 22.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/193167ef-b317-497a-d261-034c8c8b25c5.png)

### 参考
[Database Inspector を使用してデータベースをデバッグする](https://developer.android.com/studio/inspect/database?hl=ja)

## ②ADBコマンドを使う
DB Browser for SQLiteで直接AndroidのSQLiteファイルを参照することはできませんが、ADBコマンドを使うことでAndroidのSQLiteファイルを実機やエミュレータからローカルにコピーすることができます。ローカルにコピーして、DB Browser for SQLiteで開きたいと思います。

SQLiteファイルは端末内の以下のディレクトリに`/data/data/[パッケージ名]/files/`にあったので、以下のコマンドでローカルにコピーします。

```
// ファイルへのアクセス権限を取得 & 参照可能なディレクトリにコピー & ローカルにコピー
$ adb shell 'run-as [パッケージ名] cat /data/data/[パッケージ名]/files/sample.db > /sdcard/sample.db' && adb pull /sdcard/sample.db ./sample.db

// DB Browser for SQLiteでローカルにコピーしたSQLiteを開く
$ open -a "DB Browser for SQLite.app" sample.db
```

# 感想
①の方法はGUIでデータを確認しつつ、変更・反映してアプリの動作をチェックすることもできたので、快適に開発できると思います。


### 参考
[ADBとDB Browser for SQLiteでAndroid実機のDBを確認する on Ubuntu 15.04](https://www.memory-lovers.blog/entry/2015/09/24/221435)
決定係数を非線形モデルで非推奨の理由

決定係数について、非線形モデルに対する評価指標として良くないと先日知りました。
あまり詳しく書きませんが、リンク集とコメントを少し。

# 非推奨の理由
もともとはここに書かれていた内容を見ました。

https://blog.minitab.com/en/adventures-in-statistics-2/why-is-there-no-r-squared-for-nonlinear-regression
 
上記で大事だと思った部分を太字強調しました。

> For linear models, the sums of the squared errors always add up in a specific manner: **SS Regression + SS Error = SS Total**.
This seems quite logical. The variance that the regression model accounts for plus the error variance adds up to equal the total variance. Further, R-squared equals SS Regression / SS Total, which mathematically must produce a value between 0 and 100%.
In nonlinear regression, **SS Regression + SS Error do not equal SS Total!** This completely invalidates R-squared for nonlinear models, and it no longer has to be between 0 and 100%.

# そもそも決定係数とは
で、決定係数を復習しました。以下のサイトが非常にわかりやすい。

https://bellcurve.jp/statistics/course/9706.html

決定係数に関して数式を見ると非線形モデルで成立しないことがわかります。**全変動の式展開時に推定値の代入ができない**。
 
# 元論文
元論文「An evaluation of R2 as an inadequate measure for nonlinear models in pharmacological and biochemical research: a Monte Carlo approach」で詳しく書かれている模様。あまり見られていない。

https://bmcpharma.biomedcentral.com/articles/10.1186/1471-2210-10-6

代替指標を探す際に以下の文言が気になりました。

> The bias-corrected AICc and also BIC performed significantly better in this respect.

＃ TensorFlow と指標

そういえば、tfのような非線形のNNにはMetricsにいないですね(v2.9.1時点)。

https://www.tensorflow.org/api_docs/python/tf/keras/metrics

tfa にはあった。

https://www.tensorflow.org/addons/api_docs/python/tfa/metrics/RSquare
【Python】娘(当時1歳半)との尊い会話シミュレーター

## 概要

娘(当時1歳半)との尊い会話のシミュレーターを、Pythonで再作成しました。

ExcelVBAバージョンはこちら。

https://qiita.com/AnPanda/items/da66bbf657e8712f1322


## コード

```python
import random

words = ["ばなな", "もも", "すいか", "りんご", "ぱんだ",
"いぬ", "ねこ", "たこ", "いか", "なっとう"]
n = random.randint(1,6)  #1-6でランダム

for i in range(n):  #質問を最大6回繰り返す
    nani = input("なーにーなーにー？ >>")

    if nani == "":  #空白の場合、再度質問
        continue
    elif nani in words:  #単語リストに存在する場合、応答
        print(nani + "！")
    else:  #単語リストに存在しない場合
        yesno = input("？ (y/n)>>")

        if yesno == "y":  #yを押すと単語リストに追加
            words.append(nani)
            print(nani + "！")  #単語リストに追加後、応答
```

## 実行結果(n=6)

```
なーにーなーにー？ >>たこ
たこ！
なーにーなーにー？ >>えび
？ (y/n)>>y
えび！
なーにーなーにー？ >>ひとで
？ (y/n)>>n
なーにーなーにー？ >>えび
えび！
なーにーなーにー？ >>
なーにーなーにー？ >>おしまい
？ (y/n)>>y
おしまい！

※終了時のwords：
['ばなな', 'もも', 'すいか', 'りんご', 'ぱんだ', 'いぬ', 'ねこ', 'たこ', 'いか', 'なっとう', 'えび', 'おしまい']
```

## まとめ

* リストとの照合・リストへの追加は、Pythonの方が圧倒的にラクでした。
* 変数を定義せずに、As Variantな感じで使えるのもラクです。
* やりとりがコマンドラインなので、VBAの時より見栄えはよくないです。VBAの見た目を再現するには、ウィンドウを表示するモジュール(tkinter)を追加する必要があるようです。
* 今回のプログラムは、一度終了すると単語リストも初期化されてしまいます。単語リストを別ファイルで保持して、初期化されないバージョンも作成してみたいと思いました。
* 娘は2歳半になり、覚えている単語はすでに相当な数になっているし、文章である程度会話もできます。子どもの成長は驚くべきスピードですね。
直接書面等による個人情報の取得

### [全体の目次](https://qiita.com/tetz1/items/da4eb31b920f2acf4349)
---

# 直接書面等による取得
 **[個人情報の保護に関する法律についてのガイドライン（通則編）- 定義 - 3-3-4](https://www.ppc.go.jp/personalinfo/legal/guidelines_tsusoku/#a3-3-4)**

### 下記等の書面（電子含む）により直接本人から個人情報を取得する場合、あらかじめ、本人に、その利用目的を明示しなければならない
- <B>例）契約書や懸賞応募はがき等の書面等による記載により直接本人から取得</B>
- <B>例）ユーザー入力画面への打ち込み等の電磁的記録により直接本人から取得</B>

<b>（※）ただし、人の生命、身体、財産の保護のために緊急に必要がある場合は除く</B>

<details>
<summary><B>「利用目的の明示」とは？ </B></summary>
<a href="https://www.ppc.go.jp/personalinfo/legal/guidelines_tsusoku/#a3-3-4">（個人情報の保護に関する法律についてのガイドライン（通則編）- 3-3-4（直接書面等による取得））</a>

>「利用目的の明示」とは、その利用目的を明確に示すことをいい、事業の性質及び個人情報の取扱状況に応じ、内容が本人に認識される合理的かつ適切な方法による必要がある

</details>


#### あらかじめ、本人に対し、その利用目的を明示しなければならない例
- 例）本人の個人情報が記載された申込書・契約書等を本人から直接取得する場合
- 例）アンケートに記載された個人情報を直接本人から取得する場合
- 例）自社が主催するキャンペーンへの参加希望者が、参加申込みのために自社のホームページの入力画面に入力した個人情報を直接本人から取得する場合

#### 利用目的の明示ができている例
- 例）利用目的を明記した契約書その他の書面を相手方である本人に手渡し、又は送付する場合
- 例）ネットワーク上において、利用目的を、本人がアクセスした自社のホームページ上に明示し、又は本人の端末装置上に表示する場合

  - ##### 契約約款・利用条件等の書面（電磁的記録を含む）中に利用目的条項を記載する場合の補足
      本人が実際に利用目的を確認できるよう留意することが望ましい
      - 裏面約款に利用目的が記載されていることを伝える
      - 裏面約款等に記載されている利用目的条項を表面にも記載する
      - 社会通念上、本人が認識できる場所及び文字の大きさで記載する
      等


  - ##### ネットワーク上において個人情報を取得する場合の補足
      ネットワーク上において個人情報を取得する場合は、本人が送信ボタン等をクリックする前等にその利用目的（利用目的の内容が示された画面に1回程度の操作でページ遷移するよう設定したリンクやボタンを含む）が本人の目に留まるようその配置に留意することが望ましい



#### 補足（名刺等の例外）
名刺などは、一般の慣行として、自身の個人情報を、本人の自発的な意思で、任意の簡便な形式により相手に提供するものであり、申込書、アンケート調査票、懸賞応募はがき等のように、個人情報取扱事業者が一定の書式や様式を準備した上で、本人が当該事業者の求めに沿う形で個人情報を提供する場合とは異なることから、本項の義務を課するものではないが、その場合は法第21条第1項に基づいて、あらかじめ利用目的を公表するか、取得後速やかに、その利用目的を、本人に通知するか、又は公表しなければならない（ただし、3-3-5（利用目的の通知等をしなくてよい場合）参照）。口頭により個人情報を取得する場合についても同様である。

#### 緊急に必要がある場合
人（法人を含む）の生命、身体又は財産の保護のために緊急に必要がある場合は、あらかじめ、本人に対し、その利用目的を明示する必要はない
ただし、その場合は法第21条第1項に基づいて、取得後速やかにその利用目的を、本人に通知し、又は公表しなければならない（3-3-3（利用目的の通知又は公表）参照）
Pythonのクラスについての詳しいところをまとめとく(自分用)

以前Twitterでクラスのわからん点を書きなぐったは良いものの忘れるたびにTwitterを履歴を漁ってたがよくよく考えると面倒なのでここにまとめときます。

## クラスって何？
クラスとかインスタンス化とかをポケモンで例えてみると、
ポケモンでポッポっていますよね？あの最初の草むらでめっちゃ出てくる奴。あれを実際にプログラムするとして、出てくるポッポ全部別々で作ってたら、死にますよね？数量限定の手作りパンと違って草むらにいれば無限に出てくるので
なので、頭がいい人は気づいたわけです。先にポッポのある程度のデータを決めた「型」を創っちゃえと。これがクラスです。例えば種族値が
40 45 40 35 35 56　であるとか、見た目はどうとか。
プログラムでも複数回使うものに関しては先に型を創っちゃえって考えで生まれたのがこの「クラス」です
そしてインスタンスとはその型を用いて生まれてたポッポの事です。
ポッポの種族値や見た目は全て同じですが、例えば個体値はそれぞれ違いますよね？同じLv.20のポッポでも優劣はあるわけです。
そんな一体一体違うポッポそれぞれをインスタンス
と呼び、クラスを用いて作る事をインスタンス化と言います

## def __init__って何？
__init__自体はインスタンスが作成される際に出てくる特殊なメソッド。
まずメソッドとはクラス中のデータを処理するためのクラス内の関数。
そして__init__はそんなメソッドの中でも「コンストラクタ」と呼ばれている。
こいつの役割はインスタンスを構築する事である。
では実際の所何をしているのか。簡単に言えば、クラスの初期設定を定義している。
「初期化」と聞くとリセットを思い浮かべる方も多いかと思いますが、正確にはデフォルト値を設定するイメージです。
この__init__を使うことでクラスをベースにインスタンス化する度、デフォルトの設定定めることが可能。

## selfって何？
selfとはpythonでクラスを使用する際、メソッドやコンストラクタの第一引数となるもの。
意味としては、インスタンス自身を示すもの(なのでself)。
もう少し詳しく説明すると、クラスをもとに作ったもの(インスタンス)自身を指している。
要はこのselfっていうのは個人を特定していて、クラス内で
self.変数と来た場合には個人の変数を定義している。
WordPressのDBのダンプファイルを取得する方法

## はじめに
WordPressのDBのダンプファイルを取得する機会があったので、対応方法をご紹介します。

## 前提
- WordPressが既に導入済みであること
- WordPressが導入されているサーバーにssh接続ができること

## 作業手順
- WordPressのインストールディレクトリへ移動し、以下コマンドを実行。

```zsh:コマンド
wp db export
```

```zsh:実行例
$ wp db export
Success: Exported to 'hostname_wt1-2022-07-27-5c5c0cf.sql'.
$
```

:::note warn
レンタルサーバーを使用している場合は、レンタルサーバー運営会社の公式サイトでWordPressのインストールディレクトリをご確認下さい。
:::

- WordPressのインストールディレクトリの中にDBのダンプファイルが作成されていることを確認。

```zsh
$pwd
/home/hostname/domain/public_html
$ ls -l | grep sql
-rw-r--r--  1 hostname members 51161146  7月 27 04:15 hostname_wt1-2022-07-27-5c5c0cf.sql
$
```

- 必要に応じて、任意の場所へダンプファイルを移動させる。


## 参考
https://developer.wordpress.org/cli/commands/db/export/

https://knowledge.amimoto-ami.com/knowledge/managed-how-to-downloading-sqlfile-with-wp-cli
KLダイバージェンスの性質について

# イェンゼンの不等式
- 主張
凸関数 $f : \mathbb{R} \to \mathbb{R}$ と可積分関数 $g : \mathbb{R} \to \mathbb{R}$ に対して以下の不等式が成り立つ. 
$$ f(\mathbb{E}[g(x)]) \leq \mathbb{E}[f \circ g(x)] $$
- 等号成立条件
$f$ が狭義凸であるとき, 等号成立条件は $g(\cdot) = \mathbb{E}[g(x)] \quad a.s.$ である. 

# KLダイバージェンス
- 定義
確率密度関数 $p(x), q(x)$ に対して, KLダイバージェンス $KL(p || q)$ は以下で定義される. 
$$ KL(p || q) = -\int_{\mathbb{R}} p(x) \log \left( \frac{q(x)}{p(x)} \right) dx $$
ただし $p(x) = 0$ のときは $p(x) \log \left( \frac{q(x)}{p(x)} \right) = 0$ とする. 

- 性質
KLダイバージェンスは以下の性質が成り立つ. 
    1. 任意の確率密度関数 $p, q$ に対して, 
$$ KL(p || q) \geq 0 $$
    1. $KL(p || q) = 0 \Leftrightarrow p(x) = q(x) \quad a.s.$

- 証明
イェンゼンの不等式を用いる. $-\log x$ が凸であることから $g : \mathbb{R} \to \mathbb{R}$ に対して, 
$$ -\log \left( \int_\mathbb{R} g(x) p(x) dx \right) \leq - \int_\mathbb{R} p(x) \log g(x) dx $$
が成り立つ. ここから
```math
g(x) = 
\left\{
\begin{array}{l}
\frac{q(x)}{p(x)} & (p(x) \neq 0) \\
1 & (p(x) = 0)
\end{array}
\right.
```
として $g$ を定義し, $A := \\{ x  \in \mathbb{R} \mid p(x) = 0\\}, B := \\{ x \in \mathbb{R} \mid p(x) \neq 0 \\}$ を定義すると, 
```math
\begin{align*}
KL(p || q) &= -\int_\mathbb{R} p(x) \log \left( \frac{q(x)}{p(x)} \right) dx \\
&\geq -\log \int_\mathbb{R} \frac{q(x)}{p(x)} p(x) dx \\
&\geq -\log \int_B q(x) dx \geq 0
\end{align*}
```
より $KL(p || q) \geq 0$ がいえた. ここで $-\log x$ は狭義凸よりイェンゼンの不等式の等号成立条件は $g(\cdot) \equiv \mathbb{E} [g(x)] \quad a.s.$ であったことから, 
```math
\begin{align*}
KL(p || q) = 0 &\Leftrightarrow g(\cdot) \equiv \mathbb{E}[g(x)] \quad a.s. \\
&\Leftrightarrow \frac{q(x)}{p(x)} = 1 \quad a.s. \\
&\Leftrightarrow p(x) = q(x) \quad a.s.
\end{align*}
```
AtCoder Beginner Contest 261 不参戦記

# AtCoder Beginner Contest 261 不参戦記

## [ABC261A - Intersection](https://atcoder.jp/contests/abc261/tasks/abc261_a)

WA2. 2つの線の位置関係とか考えるより素直に色塗りするべきだった.

```python
L1, R1, L2, R2 = map(int, input().split())

a = [0] * 100
for x in range(L1, R1):
    a[x] += 1
for x in range(L2, R2):
    a[x] += 1
print(a.count(2))
```

## [ABC261B - Counterclockwise Rotation](https://atcoder.jp/contests/abc261/tasks/abc261_b)

書くだけ.

```python
N = int(input())
A = [input() for _ in range(N)]

for y in range(N):
    for x in range(N):
        if x == y:
            continue
        if A[y][x] == 'W' and A[x][y] != 'L':
            print('incorrect')
            exit()
        if A[y][x] == 'L' and A[x][y] != 'W':
            print('incorrect')
            exit()
        if A[y][x] == 'D' and A[x][y] != 'D':
            print('incorrect')
            exit()
print('correct')
```

## [ABC261C - NewFolder(1)](https://atcoder.jp/contests/abc261/tasks/abc261_c)

こういう現実っぽい問題良いですね.

```python
from sys import stdin

readline = stdin.readline

N = int(readline())

result = []
d = {}
for _ in range(N):
    S = readline()[:-1]
    if S not in d:
        result.append(S)
        d[S] = 1
    else:
        result.append('%s(%d)' % (S, d[S]))
        d[S] += 1
print(*result, sep='\n')
```

## [ABC261D - Circumferences](https://atcoder.jp/contests/abc261/tasks/abc261_d)

どストレートな DP で特に難しいところはなかった.

```python
from sys import stdin

readline = stdin.readline

N, M = map(int, readline().split())
X = list(map(int, readline().split()))

a = [0] * (N + 1)
for _ in range(M):
    C, Y = map(int, readline().split())
    a[C] = Y

dp = [0] * (N + 1)
for i in range(N):
    t = [0] * (N + 1)
    for j in range(i + 1):
        t[j + 1] = max(t[j + 1], dp[j] + X[i] + a[j + 1])
        t[0] = max(t[0], dp[j])
    dp = t
print(max(dp))
```
RailsのDateTime月の相対時間計算における、since関数と四則演算の結果の違いに注意

# 2022/07/27追記
@koki_73 様からコメントをいただき、DateTimeクラスは非推奨になっているようです。
結論として、DateTimeは使わないようにするというのが正しい対処です。
@koki_73 様ありがとうございます！！

# 結論
**DateTime**におけるsince関数は現在の日付に **30日加算しているだけ** です。

例えば、1月31日の1か月後を求める場合以下のような違いがあります。
| 方法 | 結果 |
| ---- | ---- |
| .since(1.month) | **3月2日** |
| + 1.month | 2月28日 |
| next_month | 2月28日 |
| months_since | 2月28日 |

# 注意
これはDateTimeの場合だけです。Dateはすべて2月28日になります。

# プログラム例
```ruby:irbの結果
# DateTimeクラスの場合はsince関数だけ結果が違います
a = DateTime.new(2022,1,31) # => Mon, 31 Jan 2022 00:00:00 +0000
a.since(1.months)           # => Wed, 02 Mar 2022 10:29:06 +0000(!!!!!!!)
a + 1.months                # => Mon, 28 Feb 2022 00:00:00 +0000
a.next_month                # => Mon, 28 Feb 2022 00:00:00 +0000
a.months_since(1)           # => Mon, 28 Feb 2022 00:00:00 +0000

# Dateクラスの場合はすべて2月28日になります。
a = Date.new(2022,1,31)     # => Mon, 31 Jan 2022
a.since(1.months)           # => Mon, 28 Feb 2022 00:00:00.000000000 JST +09:00(DateTimeクラスになる)
a + 1.months                # => Mon, 28 Feb 2022
a.next_month                # => Mon, 28 Feb 2022
a.months_since(1)           # => Mon, 28 Feb 2022
```
AtCoder Beginner Contest 260 不参戦記

# AtCoder Beginner Contest 260 不参戦記

## [ABC260A - A Unique Letter](https://atcoder.jp/contests/abc260/tasks/abc260_a)

書くだけ.

```python
S = input()

d = {}
for c in S:
    d.setdefault(c, 0)
    d[c] += 1

for c in d:
    if d[c] == 1:
        print(c)
        exit()
else:
    print(-1)
```

## [ABC260B - Better Students Are Needed!](https://atcoder.jp/contests/abc260/tasks/abc260_b)

ソートして言われた順に取るだけではあるけど、ソートの応用編を知らないと大変そうではある.

```python
N, X, Y, Z = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))

result = []

a = list(range(1, N + 1))

a.sort(key=lambda x: (A[x - 1], -x), reverse=True)
result.extend(a[:X])
a = a[X:]

a.sort(key=lambda x: (B[x - 1], -x), reverse=True)
result.extend(a[:Y])
a = a[Y:]

a.sort(key=lambda x: (A[x - 1] + B[x - 1], -x), reverse=True)
result.extend(a[:Z])

print(*sorted(result), sep='\n')
```

## [ABC260C - Changing Jewels](https://atcoder.jp/contests/abc260/tasks/abc260_c)

何も考えずにメモ化再帰するのが楽そう.

```python
from sys import setrecursionlimit
from functools import lru_cache

setrecursionlimit(10 ** 6)

N, X, Y = map(int, input().split())

@lru_cache(maxsize=None)
def red(level, count):
    if level == 1:
        return 0
    return (red(level - 1, 1) + blue(level, X)) * count

@lru_cache(maxsize=None)
def blue(level, count):
    if level == 1:
        return count
    return (red(level - 1, 1) + blue(level - 1, Y)) * count

print(red(N, 1))
```
FactoryBotをSeedで使う

# 結論
`require 'factory_bot_rails'`をseedファイルの上部に記載することでFactoryBotが使えます。

```ruby:seedファイル
# rquireが重要！！！わすれないで！！
require 'factory_bot_rails'

# 例１：1個データを作る
FactoryBot.create(:parent, name: '親1')
# 例２：いっぱいデータ作る
FactoryBot.create_list(:child, 5, name: '子')
# 例３：戻り値を使って作ったデータを取得する ＆ データをセットする
parent = FactoryBot.create(:parent, name: '親1')
FactoryBot.create_list(:child, 5, name: '子', parent: parent)
```

# 事前準備
## Gem
Gemの`factory_bot_rails`が必要です。Gemfileに追記しましょう。

## Factory
上記例の場合、このような感じのFactoryが必要です。
```ruby:factoryファイル
# Parent側
FactoryBot.define do
  factory :parent do
    sequence(:name) { |n| "親#{n}" }
    sequence(:age) { rand(15..100) }
  end
end

# Child側
FactoryBot.define do
  factory :child do
    association :parent

    sequence(:parent_id) { parent.id }
    sequence(:name) { |n| "子#{n}" }
    sequence(:age) { rand(0..20) }
  end
end
```

# 何が嬉しいのか
- データ作成をすべてFactory側に集約できる
- create_listを使って一気にデータを作れる


# 参考
https://stackoverflow.com/questions/5382295/how-can-i-use-factorybot-in-db-seeds

FactoryGirlの記事はあったが、FactoryBotの記事が無かったので。ご参考になれば幸いです。
【Rails】ランキング形式で投稿を表示する。(部分的にパーシャルの内容を変更)

# はじめに
投稿をランキング形式で表示する際に、テンプレートは流用しつつ、第1位、第2位、、、のような数字部分を変えていく動作を加える。

# 前提
下記は作成済み
ユーザーテーブル
マイクロポストテーブル
| No |    項目     |   内容    |
|---:|-------------|------------|
| 1  |      OS       |   Mac     |
| 2  |       Ruby      |   2.6.3   |
| 3  |       rails      |      6.0.4 |

# 基本
ただ投稿内容を繰り返し表示していくには、下記のコードでOK。
```言語名:app/views/microposts/index.html.erb
<%= render @microposts %>
# => <%= @microposts.each do |micropost|%>
#    　　　　第○位
#      <%= render partial: 'microposts/micropost', locals: { micropost: micropost } %>
#    <% end %>
```
デフォルトでmicropostというファイル名のパーシャルを参照し、@micropostsに格納された要素を一つずつ"micropost"という変数に渡していく。それにより、該当のパーシャル内で要素一つ一つを扱うなり表示することが可能になる。
ただ今回の目的は、これにランキングをつけるために、"第○位"という文字列を加えたい。
render で展開するのではなく、eachを使って扱いやすい形にしていく。

```言語名:app/views/microposts/index.html.erb
<%= @microposts.each do |micropost|%>
　　　　第○位
  <%= render partial: 'microposts/micropost', locals: { micropost: micropost } %>
<% end %>
```
render partial: "呼び出すファイル名", locals:{ local変数(呼び出すファイル内で用いる変数名): 渡す値 }
参考元：[URL](https://qiita.com/clbcl226/items/fe1b8e90b121332d1ca2)

# ランキング形式で繰り返す
each_with_indexメソッドにより、each文同様に繰り返し、その繰り返し試行ごとに数字(i)が+1していく。
``` 言語名:app/views/microposts/index.html.erb
# 第○位　+　<% render @microposts %>を実現したコード
<%= @microposts.each_with_index do |micropost, i|%>
  第<%= i %>位
　　　　# => 第0位、、、
  <%= render partial: 'microposts/micropost', locals: { micropost: micropost } %>
<% end %>
```
each_with_indexのデフォルトのiの初期値は0のため、初期値を(1)に設定して、第1位、第2位、、、と表示されるようにする。

ここで注意が必要なのは、上記のコードにそのまま引数を持たせて、**each_with_index**(引数)としても、うまく動いてくれないこと。
**each.（ドット）with_index**(引数)としなければ引数を受け付けてくれない。
よって、下記のように書き換える必要がある。
``` 言語名:app/views/microposts/index.html.erb
# each_with_indexをeach.with_index(引数)に書き換える
<%= @microposts.each.with_index(1) do |micropost, i|%>
  第<%= i %>位
　　　　# => 第1位、、、
  <%= render partial: 'microposts/micropost', locals: { micropost: micropost } %>
<% end %>
```
これで、
第1位
〜〜〜
第2位
〜〜〜
のように表示される。

# おわりに
下記のメソッドについてまとめる。
・**each_with_index**: each文同様に繰り返し、数字をカウントアップしていく。最初は0からスタート。
・**each.with_index(引数)**: each文同様に繰り返し、数字をカウントアップしていく。最初は引数の数字からスタート。
【Ruby】GemをGitHubからインストールする方法

## Gemfileを使用する
`Gemfile`に以下のように記述します。
```Gemfile:Gemfile
  gem "Gem名", git: "git@github.com:ユーザー名/リポジトリ名.git"
```

`bundle install`します。
```:ターミナル
$ bundle install
```

`group`, `platform`, `require`オプションが使用できます。
リポジトリには`.gemspec`ファイルが含まれている必要があります。

## `gem install`する
以下のコマンドを実行することでインストールできます。
```:ターミナル
$ gem install specific_install
$ gem specific_install -l 'https://github.com/ユーザー名/リポジトリ名'
```
【Rails】本番環境（heroku）でうまく動作しない。(メールでの本人確認)【Action_mailer】

# はじめに
開発環境である程度アプリケーションを作り、それをいざ本番環境で作るとなったとき、エラーになりうまく動かなかった。そこでherokuで正常に動作できるよう改善していく。

# 前提
デプロイしたところから開始する。

| No |    項目     |   内容    |
|---:|-------------|------------|
| 1  |      OS       |   Mac     |
| 2  |       Ruby      |   2.6.3   |
| 3  |       rails      |      6.0.4 |
| 4  |       heroku     |      Heroku-20 |

# heroku の状況確認
herokuコマンドで原因を探る。
```言語名:ターミナル
$ heroku logs
```
▼エラーに対して、下記の記事を参考に解決していく。

https://qiita.com/kobayashimakoto/items/c7a96ea9f6cbc8d2da77



# 本番環境の設定
本番環境の設定を見直す。
```production.rb
...
  config.action_mailer.perform_caching = false
  config.action_mailer.raise_delivery_errors = true
  host = 'https://toushitsutown.herokuapp.com'
  config.action_mailer.default_url_options = { host: host }
  config.action_mailer.delivery_method = :smtp
  ActionMailer::Base.smtp_settings = {
    :port           => 587,
    :address        => 'smtp.gmail.com',
    :user_name      => ENV['GMAIL_USER'],
    :password       => ENV['GMAIL_PASS'], # Googleが発行する、16桁のアプリケーションパスワード
    :domain         => 'gmail.com',
    :authentication => :plain,
    :enable_starttls_auto => true
  }
...
```
環境設定をターミナルで行う。
```言語名:ターミナル
heroku config:set GMAIL_USER='使用するemail'
heroku config:set GMAIL_PASS='上記メールのpassword'
```
# ちなみに、開発環境の場合
▼開発環境の設定

https://qiita.com/yuichir43705457/items/7cfcae6546876086b849

development.rbに、本番環境同様のsmtp_settingを記載する。
```development.rb
...
  config.action_mailer.asset_host = 'http://localhost:3000'
  config.action_mailer.perform_caching = false
  config.action_mailer.raise_delivery_errors = true
  host = 'localhost:3000'
  config.action_mailer.default_url_options = { host: host, protocol: 'http' }
  config.action_mailer.delivery_method = :smtp
  ActionMailer::Base.smtp_settings = {
    :port           => 587,
    :address        => 'smtp.gmail.com',
    :user_name      => ENV['GMAIL_USER'],
    :password       => ENV['GMAIL_PASS'], # Googleが発行する、16桁のアプリケーションパスワード
    :domain         => 'gmail.com',
    :authentication => :plain,
    :enable_starttls_auto => true
  }
...
```
次に、環境変数を設定する。
~/.zshrcに記載する。bashを使用している場合は~/.bash_profileに記載する。
```~/.zshrc
# 環境変数
export GMAIL_USER='使用するemail'
export GMAIL_PASS='上記メールのpassword' # アプリパスワード
```
# おわりに
これで環境設定が完了した。

# 参考
▼Action Mailerでメール送信機能を作る

https://qiita.com/annaaida/items/81d8a3f1b7ae3b52dc2b
【Heroku】【Mac】デプロイする

# はじめに
私は、herokuにデプロイしよう、思う。

# 前提
| No |    項目     |   内容    |
|---:|-------------|------------|
| 1  |      OS       |   Mac     |
| 2  |       Ruby      |   2.6.3   |
| 3  |       rails      |      6.0.4 |
| 4  |       heroku     |      Heroku-20 |

# herokuをイントール
```言語名:ターミナル
$ heroku --version
zsh: command not found: heroku
```
コマンドラインインターフェイス(CLI)をinstallされていないため、インストールする。
```言語名:ターミナル
curl https://cli-assets.heroku.com/install.sh | sh
```
これでインストールできたので、もう一度確認すると、バージョンが表示できた。
```言語名:ターミナル
$ heroku --version                                  
heroku/7.60.2 darwin-x64 node-v14.19.0
```

# herokuにログイン
Herokuユーザー登録時に使用したメールアドレスとパスワードを入力してログインする。
```言語名:ターミナル
heroku login --interactive
```

# heroku上に、実行環境の作成
Heroku上に、アプリケーションを実行するための本番環境を作成する。
```言語名:ターミナル
heroku create
```
# herokuにデプロイ
最後にデプロイする。
```言語名:ターミナル
git push heroku master
```
# 終わりに
ついでに、URLがheroku createで作ったデフォルトの名前になっているので、改名することが下記コマンドでできる。
```言語名:ターミナル
heroku rename <アプリ名>
```
# 参考
https://railstutorial.jp/chapters/beginning?version=6.0#sec-deploying
pip installしようとしたら"exit code1"、"Microsoft Visual C++ 14.0 is required"と表示された(Annoyの場合)

## はじめに
PythonのAnnoyというパッケージをインストールしようとした際に、以下の表示が出てインストールできなかったので対処した際のメモ。

-  exit code 1
-  error: Microsoft Visual C++ 14.0 is required. Get it with “Build Tools for Visual Studio”

#### 実行環境
- Windows11(勝手にアップデートされてた。。)
- Python 3.9.7 (Anaconda使用)

## Annoyとは
Approximate Nearest Neighbors Oh Yeahの略。近傍探索に用いられるアルゴリズム。
Spotifyが作成、実装がしやすいので人気が出たらしい。
https://github.com/spotify/annoy

参考：
[近傍探索ライブラリ「Annoy」のコード詳解](https://techblog.zozo.com/entry/annoy-explanation)
[近似最近傍探索の最前線](https://speakerdeck.com/matsui_528/jin-si-zui-jin-bang-tan-suo-falsezui-qian-xian?slide=43) 
#### 近傍探索とは
d次元のデータ$x_0=(a_1,a_2,...a_d)$に対し、同じようなN個のd次元データ$x_1,x_2,...x_N$から、近いデータを取ってくる手法。
短く言えば、N個のベクトルのうち、与えられたクエリと距離の近いベクトルを取ってくること。

## Annoyをインストールしてみる
コンソールで```pip install annoy```を実行する。

![スクリーンショット 2022-07-24 011053.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259842/03e225c3-469c-d28f-6df5-86697bb8982a.png)

エラーでインストールに失敗。

## 対処法1：Visual C++ Build Toolsをインストール

```Microsoft Visual C++ 14.0 is required. Get it with “Build Tools for Visual Studio”```とのことなので、言われた通りVisual C++ Build Toolsをダウンロードする。

参考：[python pip実行時に「error: Microsoft Visual C++ 14.0 is required. Get it with “Build Tools for Visual Studio”」が発生した場合の対処法](https://mebee.info/2020/07/18/post-13597/)

参考サイトの通り、「Build Tools for Visual Studio 2019」と、「MSCV v140」にチェックを入れてインストール。(要再起動)

![スクリーンショット 2022-07-26 232412.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259842/8b6f41c9-e78f-c458-2b33-cf60ad8a3326.png)

無事インストールに成功。
![{5DB2ECAB-E045-4E79-BEA6-90E21F38D16E}.tmp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259842/b4d86d40-e860-1ce0-07b9-088af528ad45.png)

## 対処法2：古いバージョンのPythonでインストールする
Visual C++ Build Toolsをインストールすると3GB以上になる。インストールしたくない場合、古いバージョンのPythonが入っている状態で、```py -3.7 -m pip install ``` のように別のバージョンを指定してインストールする。

参考：
[pip installでエラーになりインストールできない場合（Windows）](https://gammasoft.jp/support/pip-install-error/)の原因4を参照


古いバージョンのPyhonフォルダにwheelファイルを入れてpipでインストールするという方法もあるらしいのだが、[Annoyのダウンロードページ](https://pypi.org/project/annoy/#files)のBuilt DistributionのwheelファイルはMacOSのみのため使えない。

参考：
["ERROR: Command errored out with exit status 1"と出たときの解決策 - エンジニア くま Blog](https://grapebanana.com/python-slycot-error-748/)

ちなみに、wheelファイルの名前には"cp37"が含まれているので、少なくともPython3.7であればインストールは可能だろうと判断できる。
(cp＝CPython≒Pythonのバージョンを表す)
Dual-Boot  Ubuntu and Windows

# REMOVING UBUNTU from DUAL-BOOT (Windows)
***Change the boot order***
-  "Before you go on and delete the Linux partition, it will be a wise move to check if you can make Windows boot manager as the default boot option. This way, when you remove Linux, your boot process won’t be disturbed."

    1.  Access UEFI boot settings
        1.  Change advanced startup options (このPCの起動オプションを変更する)
        1.  Troubleshoot
        1.  Advanced Options　（詳細オプション）
        1.  UEFI Firmware Settings　（UEFIファームウェアの設定）
        1.  Hit restart button　（再起動）

    1. Move "Windows Boot Manager" UP the boot order
        - select Windows Boot Manager ->Now, my system should boot straight into Windows.



***Delete the Ubuntu partition from Windows***
- " delete the Linux partition and extend your Windows disk with available freespace"

    1. open disk management : press Windows+R -> type diskmgmt.msc
    1. identify Linux partition
        - linux partition do NOT have a file system nor drive number. (windows have. and windows are labeled with a drive number,e.g., C, D, E)
            - I created 3 linux partitions
    1. Delete Linux partition
        - "Select the Linux partition(s), right click on them and opt for the Delete Volume option."

    1. Extend Windows partition
        - create a new drive(=volume=partition) by clicking the free space->select "new simple volume"
   


---
---
---
---
---

# DUAL-BOOT UBUNTU on WINDOWS
- process 
    1. create a live USB
    1. boot into live USB 
        - plug the USB into pc 
        - select "live USB"
    1. start the installation
        -  install ubuntu separately from the windows boot manager!
    1. Prepare/setup the Partition
    1. option: setup BIOS order accordingly 


---
---
---
---
---


# ERROR: black screen -login issues on Ubuntu
- "If you try logging in and you just see a black screen, or Ubuntu brings you back to the login screen, you're experiencing a login loop. There are several causes for login loops:
    - Configuration files in your home directory are not compatible with new versions of software
    - The display/login manager is not working correctly
    - The NVIDIA driver has been updated and is causing an issue
    - The AMD radeon driver is being loaded and causing issues"

- what I did:
    - switch toterminal: Ctrl+Alt+F5
    - Type my username, press enter, and type my password and press enter again
    - start my desktop - command: startx
    - REBOOT 




    - ※Grub bootloader :
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1089224/785f364b-5c1d-e80f-96f5-e5ac86a0390c.png)


### Reference
https://itsfoss.com/uninstall-ubuntu-linux-windows-dual-boot/
基礎情報技術者理論(2)－集合

集合
集合は，ある条件で集まったグループです。例えば，集合A「コーヒーが好きな人」，集合B「紅茶が好きな人」とすると，コーヒーが好き，紅茶が好き，というのが条件です。
集合を視覚的に分かりやすく表すために，ベン図という図が
用いられます。二つ以上の集合を組み合わせることが多く，代表的な組合せに次の五つがあります。

①和集合（A OR B，A＋B，A∪B，A∨B） 二つの集合を足したものです。上記
の例では，「コーヒーか紅茶が好きな人」になります。


②積集合（A AND B，A・B，A∩B，A∧B） 二つの集合の両方に当てはまるもの
です。前記の例では，「コーヒーも紅茶も好きな人」になります。

③補集合（NOT A，A）
ある集合の否定です。前記の例では，「コーヒーが好きではない人」になります。

-参考- 
その他の集合としては，二 つの集合演算をかけ合わせた NAND（NOT ＋ AND）， NOR（NOT ＋ OR）などもあります。
さらに，データベースなどで使用する集合演算には， 直積，射影，選択，商などもあります。


④差集合（A−B）
ある集合から，別の集合の条件にあてはまるものを引いたものです。前記の例では，「コーヒーは好きだけれど紅茶は好きではない人」になります。

⑤対称差集合（A XOR B，A⊕B，A △B） 二つの集合のうち，どちらかの条件
にあてはまるものから，両方の条件にあてはまるものを引いたものです。前記の例では，「コーヒーか紅茶が好き， しかし両方は好きではない人」になります。

理論演算

コンピュータの内部表現では，数値のほかに論理（真か偽か） も表現できます。論理演算とは，データを論理で表現し，その組合せを演算することです。
通常，真（TRUE，YES，正しい）を1，偽（FALSE，NO，正しくない）を0 で表します。そして，それについてビットごとに論理和，論理積などを考えることによって，論理演算を行います。
【CSS】学びメモ

solid:実線
* { :全体を指定
box-sizing: box-border;　paddingを含める

学びメモ形式で書いてみたけど何にも理解できひん。
そのとき理解してても見返したときに分からんかったら意味ないから、
2回目に見る自分は他人やと思ってメモしておく。
初めは時間かかるかもしれへんけど、慣れやと思うからとりあえずひたすら続ける。
Java Silver番外編（キャストのコンパイルエラーと実行時例外）

Java Silverを学習中、クラスのキャストについて学んだことがあったので復習も兼ねて投稿します。

# ■クラスのキャストによるエラー
クラスをキャストする際には、コンパイルエラーをする場合と実行時エラーとなる場合がある。

```java
public class A {}

public class B extends A {}

public class C extends A {}

public class Main {
	public static void main(String[] args) {
	
	// 実行時エラーのパターン
 	A a1 = new A();
 	B b1 = (B)a1;
 	
 	// コンパイルエラーのパターン
 	B b2 = new B();
  	C c = (C)b2;
  	
	}
}
```
# ■解説
### 結論：可能性があるなら実行時エラー、全く関係ないならコンパイルエラー

#### AとBの関係
AとBの場合、両者にはスーパークラスとサブクラスという関係があるので、キャストが成功する可能性もある。
以下のような場合はコンパイルも実行も成功する。
```java
public class A {}

public class B extends A {}

public class Main {
	public static void main(String[] args) {
	
 	A a1 = new B();  // ポリモーフィズムによる生成であれば、このキャストは成功する。
 	B b1 = (B)a1;
 	
	}
}
```
失敗のケースでは、A型でAインスタンスを代入している。
AはBを継承しているわけではないので、A型のインスタンスを参照に持っているa1を、Bにキャストすることはできない。


#### BとCの関係
BとC間には継承関係等の関係は全くない。全く関係のない型をキャストすると、コンパイルエラーになる。

## 参考文献
https://teratail.com/questions/186301
【Windows編】Jenkinsを起動する（warファイルから直接起動）

はじめに
-
PCにインストールができない環境の場合、Jenkins.warファイルを実行することで起動が可能です。
今回は起動までの最低限の手順を記載します。
プラグインの導入については今後調査して追加していきます。

###### 必要なもの
- Java 1.8以上  
　※インストールされている前提とします。（バージョンは11以上を推奨）
- 7zip
- Jenkins.war 
  ※Jenkinsのサイトからwarファイルをダウンロードしてください。
  https://www.jenkins.io/download/


手順
-

###### １.Jenkins.warの配置

任意のディレクトリに「Jenkins.war」を配置します。
今回はC:¥Jenkins直下に配置します。

###### ２.起動用バッチファイルの作成

Jenkinsを起動するためのバッチファイルを作成します。
warファイルはデフォルトではユーザ配下に「.jenkins」が作成され、その中に展開されます。
今回は任意のディレクトリに展開するよう環境変数（JENKINS_HOME）を指定します。
また、ポート番号についても今回は任意で指定します。

```ruby:Jenkins_start.bat
@echo off

@rem ホームの設定
set JENKINS_HOME=C:\jenkins\.jenkins

@rem ポート8880を指定してwarを実行する。
java -jar jenkins.war --httpPort=8880

```

###### ３.バッチファイルの実行

以下、キャプチャのような構成になっていることを確認し、「jenkins_start.bat」を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333971/6f74eaf2-d575-d6a0-13d2-ce15915b25a3.png)

バッチファイルが異常終了しなければ動作自体は成功しています。
※コマンドプロンプトにて例外が発生していますが原因が分かり次第更新します。
　エラーが出ている状態でもこの後の設定は可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333971/b4d4902a-2f23-a85a-0827-2381c3106c5f.png)


###### ４.Jenkinsの初期設定

①以下、URLにアクセスします。
http://localhost:8880/
※ポート番号はバッチファイルに設定した番号に合わせてください。

② 初期パスワードの入力を求められるので赤字のパスにあるファイルの内容を貼付し、「Continue」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333971/69c7fac4-ac4e-f919-dd58-f6fdb86b4fb8.png)

③接続の設定はスキップするので「Skip Plugin Installations」を押下します。
※Jenkinsの管理画面から設定可能のため、今回は実施しません。
　バッチファイル起動時のエラーが原因でOFFLINEとなっているので原因が分かり次第追記します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333971/73a100b9-48e4-3b24-8c4b-e24be4aff1d9.png)

④各項目を入力し、「Save and Continue」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333971/4ae29882-e96a-e018-61b8-1cf5312037ed.png)

⑤何も変更せず、「Save and Finish」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333971/333057d4-dc74-8fcc-3362-1ae61f00648d.png)

⑥「Start using Jenkins」を押下します。
　これで準備は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333971/ae8a63fb-cfb2-f99d-d8bd-8d7f11a7aed5.png)


###### ５.Jenkinsの管理画面を開く
初期設定が完了し、管理画面を開くことができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333971/e0a7a103-c67c-b63b-8b55-351e3da8b5c9.png)

おわりに
-
今回はJenkinsを起動するまでの手順となりましたが
ここからプラグイン等を導入し、拡張をしていきます。
起動時に設定したほうが良いパラメータ等があれば随時反映をしていきます。
トランザクションログ（LDF）解析への道

「トランザクションログ（LDF）のサイズが肥大化しているので調べて欲しい」と言われ、そもそもLDFの中には何が入っているのだろうか？と思いたち調べた結果を書きおこします。

## どこまで分かる？
どのようなトランザクションが発行されているかや、その数や操作を分析できるようになります。もちろん、後述のコマンドを実行することでSQLコマンド実行前後のレコードを理論上は解析することが可能です。しかし、１６進数を読み解く必要があるので現実的ではありません。とはいえ、海外の「Apex SQL」などのサービスはそれを可能としているので、解析までの努力に思いを馳せると脱帽の念です。日本の「Sarasa」ってサービスもほぼほぼLDFを分析できるのでスゲェ。

## どんな時に使える？
- 前任者がDBのレコードをいじってテストデータ作ったみたいだけど、どのテーブルにどのような操作（INSERT,DELETE,UPDATE）をしたのか。
- データが操作された時間の当たりをつけたい。
- トランザクションがどの範囲ではられているのか当たりをつけたい。

## コマンド
以下の２つのコマンドでLDFのレコードを確認可能です。ちなみに、どちらもサポートされていない（Undocumented）コマンドです。そのため、MSDNには使い方などの記載はありませんし、急に仕様が変更される可能性があるとのことです。

```sql
DBCC Log('テーブル名', 4)
```
「テーブル名」には実際に調べたいテーブル名を入力します。
第２引数の「４」はログの詳細度を意味します。４は一番詳しいログを出力してくれます。

```sql
SELECT * FROM sys.fn_dblog(null, null)
```
第１引数と第２引数には検索したいLSN（後述）を入力します。NULLにすることにより、すべてのトランザクションログを出力してくれるのでここではNULLをサンプルとしています。

私見として、sys.fn_dblogの方がDBCC Logよりも詳しいデータを出力してくれる＆SELECTする数や種類を選択できるので重宝しています。加えて、ググった時に検索結果として出てくるのはsys.fn_dblogの方が多いです。

## 実践
適当なDBを作成します。

```sql
IF EXISTS (SELECT name FROM sys.tables WHERE name='student')
	DROP TABLE dbo.student
GO
CREATE TABLE [dbo].[Student](
      [Sno] [int] NOT NULL,
      [Student ID] nvarchar(6) Not NULL ,
      [Student name] [varchar](50) NOT NULL,
      [Date of Birth]  datetime not null,
      [Weight] [int] NULL)
GO

Insert into dbo.[Student] values (1,'STD001','Bob','2003-12-31',40)
Insert into dbo.[Student] values (2,'STD002','Alex','2004-11-15',35)

Update [Student] Set [Student Name]='Bob '
```

## 解説
sys.fn_dblogやDBCC LOGはいわゆるアンドキュメンテッドなコマンド、つまりマイクロソフトから仕様が公開されていないコマンドであるため、正確なところは分かりません。しかし、大体の列の意味についてのあたりをつけると以下のような感じです。

### Current LSN
LSNとはLog Sequence Numberの略でトランザクションログを識別するためのものです。

### Operation
UPDATEやDELETEといったどのようなコマンドを実行したかが記録されています。以下のようなコマンドがあります。

| Operation | 意味 |
| ---- | ----|
|  LOP_DELETE_ROWS  |  行がDELETEコマンドによって削除された  |
|  LOP_MODIFY_COLUMNS  |  UPDATEコマンドの結果行が更新された  |
|  LOP_MODIFY_ROW  |  UPDATEコマンドの結果列が更新された  |
|  LOP_INSERT_ROWS   |  INSERTコマンドによって行が挿入された  |
|  LOP_COMMIT_XACT   |  トランザクションがコミットされた  |

### Transaction ID
トランザクションごとに割り当てられているIDです。

# ごめんなさい
約１年前に下書きとして書いて以来、まとめられなかったです。すこしでも役に立てればと思い世に放りだします...

# 参考URL
- http://rusanu.com/2014/03/10/how-to-read-and-interpret-the-sql-server-log/
- https://raresql.com/2011/10/22/how-to-recover-deleted-data-from-sql-sever/
数値入り文字列を並び替える方法（VBA）

VBAで以下のような文字列を並び替えたいときに意図しない変換がされてしまう。

例）

| sort前 | sort後 | 狙い |
| --- | --- | --- |
| aa5 | aa1 | aa1 |
| aa10 | aa10 | aa5 |
| aa1 | aa15 | aa10 |
| aa15 | aa5 | aa15 |

sort後の配列と狙いの配列に違いが出る理由は、
aaの後の数値が文字列として扱われているためにおこる現象となっている。

これを改善するため、文字と数値を別のセル分割して入力し、
並び替えを行うことで解消した。

このマクロは長い文字列で数値と文字列が複雑に混ざっているものでも
sortできるようになっている。

http://officetanaka.net/excel/vba/tips/tips171.htm

``` sample.bas
Sub Sample()
    Dim A As Variant, i As Long, j As Long
    Dim MaxColumn As Integer
    Dim MaxRow As Integer
    MaxRow = 1
    
    MaxColumn = WorksheetFunction.CountA(Range("A:A"))
    For i = 1 To MaxColumn
        A = Splits(Cells(i, 1))
        For j = 0 To UBound(A)
            Cells(i, j + 2) = A(j)
        Next j
        If MaxRow < UBound(A) + 2 Then MaxRow = UBound(A) + 2
    Next i
    
On Error GoTo ErrorHandler
    Range(Cells(1, 1), Cells(MaxColumn, MaxRow)).Select
    With Range(Cells(1, 1), Cells(MaxColumn, MaxRow)).SpecialCells(xlCellTypeBlanks)
        .Value = "'"
    End With
    
ErrorHandler:
   
    For i = MaxRow To 2 Step -1
        Cells(1, i).Sort key1:=Cells(1, i), order1:=xlAscending
    Next

End Sub

Function Splits(A As String)
    Dim i As Long, flag As Boolean, B As String, cnt As Long, c() As String
    flag = IsNumeric(Left(A, 1))
    For i = 1 To Len(A)
        If flag <> IsNumeric(Mid(A, i, 1)) Then
            ReDim Preserve c(cnt)
            c(cnt) = B
            B = ""
            cnt = cnt + 1
            flag = Not flag
        End If
        B = B & Mid(A, i, 1)
    Next i
    ReDim Preserve c(cnt)
    c(cnt) = B
    Splits = c
End Function

```

行っていること
1. A列のセルを数値と文字列で分割してB列以降に表示
2. 分割したセルを一番右からsortする

一番右から順にsortすると、
右側ほどsortの上書きがされるため、重要度が低くなるという役割を持つ。
Java Silver番外編（Integerと==演算子）

Java Silverの学習中、Integerと==演算子の比較の関係で知ったことがあったので、復習も兼ねてまとめようと思いました。

## ■Integerの生成方法の違いによる＝＝演算子の結果
```java

public class Main {
	public static void main(String[] args) {
	
 	Integer i1 = Integer.valueOf(127);
 	Integer i2 = Integer.valueOf(127);
    System.out.println(i1 == i2);      // true
 	
 	Integer i3 = Integer.valueOf(128);
 	Integer i4 = Integer.valueOf(128);
	System.out.println(i3 == i4);     // false
 	
 	Integer i5 = 127;
 	Integer i6 = 127;
	System.out.println(i5 == i6);     // true

    Integer i7 = new Integer("10");
    Integer i8 = new Integer("10");
	System.out.println(i7 == i8);     // false
    
    Integer i9  = new Integer(10);
    Integer i10 = new Integer(10);
	System.out.println(i9 == i10);    // false
	
	}
}
```
# 解説（なぜ結果が違うのか）
## ■valueOfで生成した場合　＋　数値をそのまま代入した場合

Integerクラスの内部にはIntegerCacheを持っている。
このキャッシュはデフォルトでは 

<font color="red">-128 ~ 127の整数値をキャッシュし、</font>
<font color="red">128以上は新しいIntegerオブジェクトを生成する</font>

という処理を行う。

Integer.valueOf()メソッドは、キャッシュの範囲に該当するオブジェクトを返すので、
i1とi2は同じオブジェクトを指す事となり、trueが表示される。

i3とi4は128でキャッシュの範囲外なので、新しいIntegerオブジェクトとして生成される。
結果参照先が異なり、falseとなる。

また、リテラルで直接数値を代入した場合（i5,i6）、valuOfメソッドを使用したのと同じ事になるので、同様にtrueとなる。

## ■newとコンストラクタで生成した場合
newとコンストラクタを用いた生成では、引数で指定した数値をもつオブジェクトの、
メモリアドレスの値が代入される。

結果、i7,i8,i9,i10はそれぞれ新しいオブジェクトのアドレスがそれぞれ代入されているので
falseとなる。


## 参考文献
https://meetup-jp.toast.com/1808
異職種から信頼されるエンジニアの5つの特徴

## はじめに

この記事はこれまで私が15年ほどの社会人経験の中で見てきた「異職種から信頼されている」エンジニアの特徴をまとめています。
今回は「異職種から〜」なので、例えば営業、マーケティング、デザイナー、事務職などなどの「エンジニア以外の人から信頼されているエンジニア」の話です。あくまで私の経験からの内容のため一例として読んで頂ければと思います。

昨今の組織では上司からの評価だけではなく、一緒に働くメンバーからの360度評価を採用している組織もあるかと思います。その中で、同じエンジニアからだけではなく、異職種のメンバーも含めた360度評価もあるかと思うのでその際の参考にもなれば幸いです。

また「評価のため」だけではなく、様々な職種で仕事を進めていく際に良い状態で臨むためにも参考になれば幸いです。



## 異職種から信頼されるエンジニアの特徴
**目次**

* [①出来る方法を一緒に考えてくれる](#出来る方法を一緒に考えてくれる)
* [②期限を過ぎる場合に説明が丁寧](#期限を過ぎる場合に説明が丁寧)
* [③開発に関わるリスクを指摘してくれる](#開発に関わるリスクを指摘してくれる)
* [④エンジニアならさっと出来ることを拾ってくれる](#エンジニアならさっと出来ることを拾ってくれる)
* [⑤技術者として矜持がある](#技術者として矜持がある)
* [最後に](#最後に)


## ①出来る方法を一緒に考えてくれる
異職種からすると開発に関する詳細な部分はイメージしづらく、エンジニアに相談をして判断を仰ぐことが多いかと思います。

例えばある開発に関する相談をした際に、
A 「それは無理ですね」「出来ません」
B 「そのままでは無理ですが、こうすると近い形に出来るかもしれません」

このようなときに、Aのような回答をされると（例えそうだとしても）持っているスキルの分野が違うため、異職種からするとそれ以上の発展的な話が難しいです。
Bのようなコミュニケーションをとってくれるエンジニアは、発展性を与えてくれるため周りからの信頼を得られるエンジニアだと思います。


## ②期限を過ぎる場合に説明が丁寧
例えば納期やリリースが延期になってしまう場合。
様々な理由があると思いますが、エンジニア同士であればその理由が正当であれば納得感もあり腹落ちもしやすいと思います。
これが異職種から見ると、理由自体は理解出来るけどその妥当性については理解することが難しい場合があります。それが数回続くと例え正当な理由があったとしても「なんだか良く遅延する人」になってしまいがちです。
なので、特に異職種の人に対しては、理由をわかりやすく丁寧に説明をする意識が必要です。


## ③開発に関わるリスクを指摘してくれる
これは特に営業やマーケティングサイドの人とのやりとりで起こることが多いと思います。
商品を売る、プロモーションすることがミッションである彼らにとって、そのために「動く」状態以外のことは残念ながら念頭に無い（もしくは思いつくことが出来ない）場合もあります。
例えば「今回の受注のために○○の機能を追加して欲しい」というオーダーがあった際に、それを実装すると大きなリスクを孕むことになってしまう場合。そのままそれを受け入れて開発をするのか、追加は可能だけど△△のリスクがあります、と忠告をするのか。
仮のその機能のリリース後にリスクが露呈してしまった場合「営業サイドのオーダー通りに開発したので」ということで責任を取る必要はないかもしれませんが、信頼という点ではなかなか厳しい結果になると思います。
※この話は営業やマーケティングサイドの人間のリテラシーや相互の関係性も影響するので一概には言えませんが。

## ④エンジニアならさっと出来ることを拾ってくれる
例えばビジネスメンバーが欲しがっているデータを「出しておきましょうか？」と出してあげる、Slackのbot設定をしてチームのコミュニケーション効率化をしてあげる、などエンジニアであれば異職種に比べて短時間で、ともすれば1/10の労力で出来てしまうようなことです。
「それくらい非エンジニアでもやるべき」「そんなことにエンジニアのリソースを使うべきではない」という考えももちろんなのですが、出来ない人から見ればとても難しいことをやってくれたという感謝は大きいです。
こういうことで信頼を得ることで、もし自分が苦手な分野で困っているときに、得意な人がさらっと協力してくれることもあるでしょう。
そうすればお互いに1/10の労力で10倍のリターンを得られる素敵な関係が出来るかもしれません。

## ⑤技術者として矜持がある
扱っている技術や作っているモノに対してのこだわりや譲れないラインを持っている人です。もちろん組織や会社で妥協しなければいけない部分や、本当はこうしたいけど出来ないことは現実あるかと思います。ですが、自身の中にそういう譲れないラインや理想を持っていて、それに近づくために努力をしている人は周りからも尊敬されて信頼されるエンジニアであることが多いです。異職種からすると、その中身自体を詳細に理解することは難しいですが、そういう姿勢を日々見ることで、「この部分に関してはこの人に任せられる」という信頼に繋がっていくのだと思います。





## 最後に
「信頼されるエンジニア」という観点ではこれ以外にも様々なものがあるかと思います。今回は「異職種から」という見方でまとめてみましたが、組織やチームで様々な職種のメンバーと事業やサービスの運営をしていく際の参考になれば幸いです。
webpack 5を使ってみる



公式サイトの[Getting Started](https://webpack.js.org/guides/getting-started/)を参考に簡略してやっていきます。

開発環境は、
- Windows10 Pro(64bit)
- node v16.16.0
- npm 8.11.0


Cドライブ直下に、webpackディレクトリを作成し、カレントディレクトリにします。
```
cd c:\ && mkdir webpack && cd webpack
```
以下のコマンドでpackage.jsonを作成
```
npm init -y
```
以下のコマンドで必要なパッケージを取得
```
npm install --save-dev webpack webpack-cli webpack-dev-server
```
srcディレクトリを作成
```
mkdir src
```
今回、バンドルするためのパッケージのlodashをインストール
```
npm install lodash
```
srcディレクトリ内に以下のファイルをindex.jsという名前で作成
```javascript
import _ from 'lodash';

function component(){
  const element = document.createElement("div");
  element.innerHTML = _.join(["Hello", "webpack"], ' ');
  return element;
}

document.body.appendChild(component());
```
distディレクトリを作成
```
mkdir dist
```
distディレクトリ内に以下のファイルをindex.htmlという名前で保存
```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Getting Started</title>
</head>
<body>
    <script src="./main.js"></script>
</body>
</html>
```
開発用サーバーを設定するために、以下のファイルをwebpack.config.jsという名前で保存します。
```javascript
const path = require('path');

module.exports = {
    devServer: {
        static: {
            directory: path.join(__dirname, 'dist'),
        },
        compress: true,
        port: 9000,
    },
};
```
以下のコマンドでバンドル開始
```
npx webpack
```
続いて、以下のコマンドで開発用サーバーを実行
```
npx webpack serve
```
Webブラウザでlocalhost:9000にアクセスすると、以下のようにWARNINGが表示されますが、無視して、×ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739418/ff1a919d-5134-ecf4-09b7-bdbd1bd49fa5.png)
すると、以下のように、きちんと表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739418/de11f334-d10d-d6ae-de15-b8b4622e9268.png)

### リンク
- [Getting Started](https://webpack.js.org/guides/getting-started/)
- [DevServer](https://webpack.js.org/configuration/dev-server/)
npm versionコマンドでpackageのバージョンを上げる

npmのバージョンを上げ、タグを切ってくれるコマンドがnpmにあるのを知らなかったので、触りながら調べてみました。

https://docs.npmjs.com/cli/v8/commands/npm-version

## sandbox用のpackage作成

`npm init`をして、最初にversion 0.0.0で作ったpackageを使っていきます。

npm versionのコマンドの使い方はこちらです。

```bash
$ npm version -h
Bump a package version

Usage:
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]

Options:
[--allow-same-version] [--no-commit-hooks] [--no-git-tag-version] [--json]
[--preid prerelease-id] [--sign-git-tag]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--no-workspaces-update] [--include-workspace-root]
```

## versionを上げる

まずはpatchバージョンを上げてみます。

```bash
$ npm version patch
v0.0.1
```

これにより、versionを上げるcommitが追加され、tag(`v0.0.1`)が追加されています。

```diff
commit e124b89ba7545949a1440dcba4b45cf3b872a317 (HEAD -> main, tag: v0.0.1)
Author: kyntk
Date:   Tue Jul 26 22:57:23 2022 +0900

    0.0.1

diff --git a/package.json b/package.json
index 8d2bf39..633e565 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "version-sandbox",
-  "version": "0.0.0",
+  "version": "0.0.1",
   "description": "",
   "main": "index.js",
   "scripts": {
```

次にminorバージョンを上げてみます。

```bash
$ npm version minor
v0.1.0
```

## prerelease

minorバージョンアップのprereleaseのバージョンをあげます。
`preminor`で上げたものを更にバージョンアップするには`prerelease`を使います。

```bash
$ npm version preminor
v0.2.0-0

$ npm version prerelease
v0.2.0-1
```

実際にminorバージョンアップするときは同じです。

```bash
$ npm version minor
v0.2.0

$ git log --oneline
2219d90 (HEAD -> main, tag: v0.2.0) 0.2.0
a5ec9c8 (tag: v0.2.0-1) 0.2.0-1
e9df7dd (tag: v0.2.0-0) 0.2.0-0
7cb690a (tag: v0.1.0) 0.1.0
e124b89 (tag: v0.0.1) 0.0.1
3d638fd Initial commit
```

## [preid](https://docs.npmjs.com/cli/v8/commands/npm-version#preid)

prereleaseのprefixをつけることができます。
alphaやbetaなどおなじみです。

```bash
$ npm version premajor --preid alpha
v1.0.0-alpha.0

$ npm version prerelease
v1.0.0-alpha.1

$ npm version premajor --preid beta                                                                                                                                                                  [main]
v2.0.0-beta.0

$ npm version prerelease
v2.0.0-beta.1

$ npm version prerelease
v2.0.0-beta.2

$ npm version major
v2.0.0
```

Semantic Versioningの仕様にあるように、patch versionまで一致しているときのバージョンのバージョンの大小は以下のようになります。

> 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.

https://semver.org/#spec-item-9

## [Description](https://docs.npmjs.com/cli/v8/commands/npm-version#description)

`-m`オプションをつけることで、コミットメッセージの設定ができます。
このとき、`%s`を使うと、バージョンに置き換えてくれます。

```bash
$ npm version patch -m "Upgrade to %s"
v2.0.1

$ git log
commit cda46e53d054e2b6ab3edef67ba8da1a7985a6c5 (HEAD -> main, tag: v2.0.1)
Author: kyntk
Date:   Tue Jul 26 23:24:14 2022 +0900

    Upgrade to 2.0.1
```

## その他

`npm version`の前後に処理をはさみたい時ようのscriptの設定など他にもあるようですので、興味のある方は見てみてください。

https://docs.npmjs.com/cli/v8/commands/npm-version
git fetchしようとしたら　fatal: bad object refs/heads/master 2

メモやでいつか丁寧に書くかも

```ターミナル
remote: Enumerating objects: 1016, done.
remote: Counting objects: 100% (1016/1016), done.
remote: Compressing objects: 100% (349/349), done.
remote: Total 1016 (delta 707), reused 904 (delta 637), pack-reused 0
Receiving objects: 100% (1016/1016), 253.71 KiB | 1.36 MiB/s, done.
Resolving deltas: 100% (707/707), completed with 64 local objects.
fatal: bad object refs/heads/master 2
error: XXXXXXXXXXXXX.git did not send all necessary objects

Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
warning: The last gc run reported the following. Please correct the root cause
and remove .git/gc.log
Automatic cleanup will not be performed until the file is removed.

fatal: bad object refs/heads/master 2
fatal: failed to run repack
```
何やらgcがうまく動いてくれていないらしい

2.3時間つまった

原因掴めてないけどいらないファイルを消してあげると動く
調べなくてわ。。。

解決手順
1. 邪魔していたものを消す
1. エラーログに書かれていたのでそれを実施
1. gcを動かしてみる
1. そしたらあら不思議引っ張ってこれる
```
rm .git/refs/heads/master\ 2
rm .git/gc.log
git gc
git fetch
```
### Ref
- https://amerkhalid.com/2022/01/git-error-github-comabc-xyz-git-did-not-send-all-necessary-objects/
SPIKE primeのケーブルのメスコネクタを作った話

# SPIKE primeのケーブルのメスコネクタを作った
SPIKEのセンサを自作するためにハブとセンサの通信を見たくメスコネクタが必要になったので作った。
アリエクで互換のあるWedo2.0のコネクタ売ってるが今回は自作。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/cd316b79-ec49-e7f0-648e-1e0c2e459b98.png">

## 3Dモデル作成
Fusion 360でささっと作成した。ノギスが出もとになかったので定規で測りながら現物合わせで調整した。
大体の寸法なので過信しないように。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/84f33bfa-d8c8-e411-eabe-dcfb1a1d1f0e.png">
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/2ef96d62-bf5f-8e3c-ffbe-228e803824dc.png">
## 3Dプリンタで出力
結構前に買ったELEGOO Marsで印刷。0.1 mmで積層し、斜めに印刷した。 
出来上がったのがこれ。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/8df22002-4a98-e25f-05e5-f77cc576a3d8.png">

しっかり二次硬化しないと固いので気を付けること

## 接点の制作
コネクタの枠はできたのであとは電気接点をつくる。
接点なにで作ろうかといろいろ考えた結果、0.3 mm の真鍮線した。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/c1a2b003-6f6d-a9b2-3ad2-ee0a1e97964a.png">
真鍮線をこんな感じにまげて3Dプリンタに出力したコネクタにセットする。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/7fef1f1e-1c7e-023a-1211-11baf16a626c.png">
あとは真鍮線が外れないようにレジンをたらしで硬化して完成。


## ピンヘッダを付けて完成
ピンヘッダを付けてブレットボードで使えるようにしてみた。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/8160073a-bc1f-f60f-2f0f-33a0054b82d9.png">

これでシリアル通信をオシロスコープで見れる準備が整った。
ハブとモジュールの通信についてはまた別の記事で公開します。

# 3Dモデルはフリーで公開予定
もっといい感じのできたら公開します