OmniAICreator/Qiita-1.07M huggingface dataset:
ベクトル「静岡大学１９９９年前期Ｍ１第２問・Ｍ２第１問」をsympy でやってみた。


オリジナル
△ABCの辺の長さ15,14,13(一工夫13,14,15の順でありません。)

https://mathmathmass.exblog.jp/31872035/

上と同じです。大学入試数学問題集成＞【２】

https://mathexamtest.web.fc2.com/1999/199910461/1999104610100mj.html#top-0102



# sympyで
Pointが、solve内で使えました。

```python
from sympy import *
var('s t')
AB,BC,CA=15,14,13
pB,pC=Point( 0,0),Point(14,0)
#
pA=Circle(pB,AB).intersection(Circle(pC,CA))[1]
pO=Triangle(pA,pB,pC).circumcenter
pI=Triangle(pA,pB,pC).incenter
print("#(1)",pA)
print("#(2)",pO)
print("#(3)",solve((pA-pO)-(s*(pB-pO)+t*(pC-pO)),[s,t]))
print("#(4)",solve((pI-pO)-(s*(pB-pO)+t*(pC-pO)),[s,t]))
#(1) Point2D(9, 12)
#(2) Point2D(7, 33/8)
#(3) {s: -169/154, t: -125/154}
#(4) {s: -13/231, t: 20/231}
```

# 参考

https://qiita.com/mrrclb48z/items/e83f2512f5008e35e15a
【デザインパターン】悪戦苦闘！デザインパターン ~Proxy・Flyweight編~

## はじめに
本記事は、デザインパターン学習中の私が学習中に詰まったポイント、間違えてしまったポイントをもとに学んだことを書いたものです。
個人の理解に基づいておりますため、間違いがあれば教えていただけると幸いです。

★9ヶ月前くらいにデザインパターンの勉強のために執筆し、社内で公開していた記事をこちらにも投稿したものとなります。 

## 「これ、どっちのパターンなんだろう？」

Proxyパターンを学習していたときのことです。

私はサンプル実装として、以下のようなコードを作成しました。

- 選択した画像を表示するプログラム
- 選択した画像がキャッシュに存在する場合はキャッシュの画像を表示する
- 選択した画像がキャッシュに存在しない場合はフォルダから画像を読み込んで表示する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062427/bb8f6c53-d168-71ca-b652-edee2ed981dd.png)

このとき、キャッシュの画像を表示するサービスのクラスをProxy（代理人）クラスとし、フォルダから読み込んだ画像を表示するクラスをRealSubject（主体）クラスとしています。

キャッシュにすでに読み込まれた画像があるときはProxyが処理を肩代わりし、キャッシュにない画像を指定されたときに初めてRealSubjectが画像読み込み処理を行う、ということで、Proxyパターンには当てはまっているように思えます。

しかし見方を変えると、このプログラムは、画像のインスタンス（BitmapImage）を生成してキャッシュに登録し、可能な限り（キャッシュに存在する画像が呼ばれる限り）すでに作成したインスタンスを使って画像を表示する、というものになります。

#### あれ？それって、Flyweightパターンじゃない？

#### Proxyパターンで間違いはないはずだけど、うまく説明できないぞ？

## 整理してみる

Proxyパターンとは、オブジェクトの処理をオブジェクトの代わりに処理するクラス（Proxy）を用意することで、オブジェクトの **処理を分散**することを目的としたパターンです。

たとえば、とあるインスタンスの生成処理が重い場合に、インスタンスに設定する値を取得する等の、インスタンス自体が存在しなくても行える軽い処理をProxyクラスに任せます。そのうえで本当にインスタンスが必要になったときにはじめてインスタンス生成処理を行うことで、重い処理の実行を本当に必要なタイミングまで遅延させることが可能です。

Flyweightパターンとは、すでに生成したインスタンスを要求された場合に新しく作らず、すでにあるインスタンスを返すことで同じインスタンスを再利用し、 **処理を軽くする** ことを目的とするパターンです。作ってあるインスタンスを返すということでSingletonパターンっぽいな？とも思えますが、Singletonパターンとは違い、「1つのクラスについてインスタンスが1つだけ」という決まりはありません。

## 結局間違っていたのか

私が作成したプログラムは、

#### 「キャッシュにない画像が呼ばれるまで画像の読み込み処理を遅延させる」

という部分がProxyパターン、

#### 「画像のインスタンスをキャッシュに保持して再利用する」

という部分がFlyweightパターンに当てはまっていました。見方によってはどちらのパターンとして見ることもできるものになっていたんですね。

デザインパターンとは、**クラス・ライブラリの設計においてしばしば直面する問題に対処する設計**をまとめたものです。どのような問題を解決したいかによって、適用できるパターンは変わります。

今回、（Proxyパターンの学習用の試作ではありますが、）解決したかった問題は「『画像をフォルダから読み込んで表示する』処理を、本当に必要な時にだけ行いたい」という問題でした。

そこで、「読み込んだ画像をキャッシュに保持しておき、既に一度読み込んだ画像が呼び出されたときにフォルダから画像を読み込むクラスの『代わりに』キャッシュの画像を表示する」クラスを作成しました。

Proxyパターンのメリットである「オブジェクトの処理を分散できる」ことを利用して問題を解決できています。
そのうえで、Proxyクラスにさせたい処理である「キャッシュの画像を再利用する」部分をFlyweightパターンで実現していたんですね。

## まとめ

複数のデザインパターンを無意識に活用していたことで混乱してしましたが、各デザインパターンについて、「どういう設計の問題を解決できるパターンなのか」を理解する必要があると改めて思いました。

「ここは○○パターンでクラス間の依存が切れる！」とか、言えるようになりたいです。

◆◆◆
最後まで読んでいただき、ありがとうございました。 
以下は前回のデザインパターンの記事です。よければ合わせてどうぞ。
[【デザインパターン】悪戦苦闘！デザインパターン ~State・Strategy編~](https://qiita.com/kamikawa_m/items/b6bd075b4c96ec842e7b)
GitHubでdefaultブランチを変更する方法

## はじめに
Gitにおけるmainブランチは、デプロイする準備が完了している状態にしておくことが一般的です。
そのため、頻繁にマージさせずにdevelopブランチ等を用意して、そちらにマージすることが多くなります。
GitHubでPull requestを作成するときは、そのままの設定だとdefaultブランチがmainブランチになっているため、気を抜くとmainブランチにマージさせてしまう可能性があります。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1230134/27de5bd0-a10b-d805-3a25-acf93153bc28.png)
そこで、GitHub上でdefaultブランチを他のブランチ（今回はdevelopブランチ）に変更する方法をご紹介します。

## 流れ
1. 任意のリポジトリでSettingタブを開く
1. サイドバーのBranchesを開き、Default branchのアイコンを開く
1. Switch default branch to another branchでdefaultにしたいブランチを選択する
1. I understand, update the default branch.を押して変更する
1. Pull request作成時にdefaultが変更されているか確認する

以下で、画像を交えて説明いたします。

## 1.任意のリポジトリでSettingタブを開く
まず、上部にあるSettingsのタブを開きます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1230134/a84b6a8f-5999-35bb-4fff-04abb396f7a7.png)

## 2.サイドバーのBranchesを開き、Default branchのアイコンを開く
次に、1.と同じ画面において、サイドバーのBranchesを押し、Default branchを表示させます。
ここに現在のdefaultブランチが表示されます。（初期状態ではmainもしくはmaster）
両矢印ボタン⇆を押します。

## 3. Switch default branch to another branchでdefaultにしたいブランチを選択する
セレクトボックスが表示されるので、defaultに設定したいブランチを選択し、Updateボタンを押します。
（今回は、developブランチをdefaultに設定）
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1230134/568eef56-4705-a86b-42bc-1d9bf9c4f755.png)

## 4. I understand, update the default branch.を押して変更する
赤いボタンの「I understand, update the default branch.」が表示されるので、そちらを押して設定を変更します。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1230134/ebd30769-5386-955c-8577-53170992bec2.png)

## 5. Pull request作成時にdefaultが変更されているか確認する
再度、プルリクを作成し、baseが先ほど設定変更したブランチになっていれば、完了です。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1230134/4aea07cf-ec7e-bbdb-a177-5c3a1428e707.png)

## 最後に
これで、間違えてmainブランチにマージしてしまうことがなくなります。
逆にdevelop→mainにマージする時は、選択し忘れないように注意してください。
【デザインパターン】悪戦苦闘！デザインパターン ~State・Strategy編~

## はじめに
本記事は、デザインパターン学習中の私が学習中に詰まったポイント、間違えてしまったポイントをもとに学んだことを書いたものです。
個人の理解に基づいておりますため、間違いがあれば教えていただけると幸いです。

★9ヶ月前くらいにデザインパターンの勉強のために執筆し、社内で公開していた記事をこちらにも投稿したものとなります。 

## 「それ、Stateパターンじゃない？」

Strategyパターンの勉強としてクラス図とコードを作ってみたところ、こんな指摘をいただきました。

私が学習の題材として作成したコードは以下のようなもの。（オンラインショップの送料や割引などの料金計算をイメージしていました）

- 料金の計算方法が三通りある
- 入力した金額をもとに料金計算の方法を切り替える

![試作](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062427/3fae0a95-405d-4ba8-af5d-04ce465f54fb.png)


書籍と比べてもクラス図は合っていそう。ちゃんとStrategyごとに実体のクラスも分けている。切り替えられるようにも作っている。

**じゃあいったい何が違うんだ……？**

## 何が違ったのか

まず、Strategyパターンとは、

アルゴリズムをプログラムの他の部分から分離し、アルゴリズムの動的な切り替えを可能とすることを目的としたパターンです。アルゴリズムをクラスとして定義し、プログラムから委譲によって利用します。
![Strategyパターン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062427/f1f2a7ce-cb10-c6b3-0827-20991bc12cc7.png)


次に、私が意図せず作成したStateパターンとは、その名の通り、システムの状態をクラスで表すことを目的としたパターンです。状態をクラスとして定義し、状態に依存した振る舞いをそのクラスのメソッドとして定義しています。プログラムが持っているクラスが変わることで状態が変わり、その時の状態に応じて処理が変わります。

![Stateパターン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062427/759098fe-19f8-3e37-f346-ac9e0ba2bc77.png)


つまり、Strategyパターンはクライアント側が能動的にStrategy（戦略）を切り替えることで処理が変更されるパターンであり、

Stateパターンは何かしらの要因でState（状態）が切り替わり、それによって処理が変わるパターンです。

クラス図を比較すると全く同じですが、目的が異なっています。

最初に私が作成したコードでは、料金という**状態**が切り替わることで処理（計算方法）が変更されていました。「料金の入力」というユーザーの操作を前提としたことでわかりにくくなっていましたが、ユーザーが能動的に料金計算方法を切り替えているわけではないため、これはStrategyパターンには当てはまりません。

もしこの題材でStrategyパターンのプログラムを作成するなら、

- 料金の支払方法をStrategyにする（カードか、コンビニ払いか、はたまた着払いか……など）
- 入力金額ではなく、ユーザーが能動的に支払方法を変更できるようにする

……というわけで、以下のようなプログラムであればよかったのでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062427/90fa9219-0c05-5296-5a45-21cfd4f7607c.png)

## まとめ

デザインパターンは、 **「設計を行ううえでよく突き当たる問題を解決するための設計のノウハウをまとめたもの」** です。
しかし、いくらノウハウを知っていても間違えて使ってしまっては意味がありません。間違った理解のまま学習を終えなくてよかったと思いました。
デザインパターンを学ぶうえで、
 **このパターンのメリットは何か** 
 **どんな設計の問題を解決できるのか** 
という部分をきちんと学習で理解して、設計に活用できるようになりたいです。
そのためには、今回のように「似ているけれど目的が違う」パターンには注意する必要があると感じました。

◆◆◆
最後まで読んでいただき、ありがとうございました。
こんな感じのデザインパターン記事を何本か投稿するつもりなので、良ければまた読んでいただけると嬉しいです。
連続数のヘロン三角形を調べてみた。

オリジナル

https://ikuro-kotaro.sakura.ne.jp/koramu/4396_a5.htm

# sympyで

漸化式は、わかりませんでした。アドバイスを頂けると助かります。

```python
# 【２】連続数のヘロン三角形
#  https://ikuro-kotaro.sakura.ne.jp/koramu/4396_a5.htm
from sympy import *
from sympy.solvers.diophantine.diophantine import diop_solve
var('x y a b c h s m t')
def myHerons(a, b, c):
    s = (a + b + c) / 2
    return sqrt(s * (s - a) * (s - b) * (s - c))
def myDefPell(b,h,S2):
    myEq = Eq((((b * h) / 2) ** 2).subs({b:2*m}).simplify(), S2.subs({b:2*m}).simplify())
    myEq = Eq(myEq.lhs/(m**2),myEq.rhs/(m**2))
    return myEq
def myCalH(siki,n):
    ans=str(list(siki)[0][0])
    h=sympify(ans.replace("*t", "*"+str(n))).simplify()    # subsでなく、文字列の置換
    return h
def myCalabc(f,siki,n):
    ans=str(list(siki)[0][0])
    h=sympify(ans.replace("*t", "*"+str(n))).simplify()
    f=f.subs({x:h})
    b=solve(f,y)[1].simplify()*2
    return b-1,b,b+1
a=b-1
c=b+1
S2=myHerons(a,b,c)**2
myEq=myDefPell(b,h,S2)
myEq=myEq.subs({h:x,m:y})
f=myEq.lhs-myEq.rhs
ans=diop_solve(f)
#
print("# S^2",S2)
print("# ペル",myEq)
for i in range(1,7):
    print("#",myCalabc(f, ans, i))
# S^2 3*b**2*(b/2 - 1)*(b/2 + 1)/4
# ペル Eq(x**2, 3*y**2 - 3)
# (3, 4, 5)
# (13, 14, 15)
# (51, 52, 53)
# (193, 194, 195)
# (723, 724, 725)
# (2701, 2702, 2703)
```


# 参考 
幾何学においてヘロンの三角形（ヘロンのさんかくけい）とは、3辺の長さと面積の全てが整数となる三角形である。＜

https://ja.wikipedia.org/wiki/%E3%83%98%E3%83%AD%E3%83%B3%E3%81%AE%E4%B8%89%E8%A7%92%E5%BD%A2

In geometry, a Heronian triangle is a triangle that has side lengths and area that are all integers.＜

https://en.wikipedia.org/wiki/Heronian_triangle

oeisに漸化式がありました。
a(n) = 4*a(n-1) - a(n-2) with a(0) = 2, a(1) = 4.

https://oeis.org/A003500
Jetpack Composeを現場のアプリ開発で使用してみて思ったこと

最近、Androidのアプリ開発においてJetpack Composeを使用する機会が増えました。

ということで、私が特に現場でJetpack Composeを使用してみて感じた（ている）ことを書いていこうと思います。(2022/6/24時点の感想）
知識不足で間違っている点あればご指摘ください。

# 良いと感じている点
### レイアウトの変更・管理がしやすい
- Kotlinコードでレイアウトを書いていくので、個人的にXMLベースよりコードのネスト構造が浅くなる（りやすい）傾向があります。
- Kotlinコードで管理するので、XMLファイルといった形式の異なるレイアウトファイルを管理する必要がほぼなくなります。見るのがKotlinコードに一元化されるので管理がしやすいです。
- 同じKotlinファイル内に複数のComposable定義を記述できるのでグルーピングしたい時とか便利

個人差はあるので、上記はいまいちピンと来ない方がいるかもしれませんが、XMLよりKotlinに慣れ親しんでいるエンジニアは頷けると思います。

### 状態に応じたUIの出しわけがやりやすい
その時の状態に応じたUIを宣言的に記述するというのがJetpack Composeの思想なので、やはりUIの出し分けを見通しよく表現することに優れています。UI出し分けの実装漏れとかは少なくなります。

### LazyColumnが便利
何気に一番感動した点かもしれません。
RecyclerViewやListViewを使っていた頃は、AdapterクラスやXMLレイアウトの作成などが必要でしたが、Jetpack ComposeではLazyColumnを使えば一瞬で終わります。リスト形式のViewを作成する工数大幅減。

# 使いづらいと思っている点
### UI開発が飛躍的に向上するとは限らない
LazyColumnとか開発速度が向上するようなコンポーネントもありますが、XMLファイル時代と比べて開発速度が飛躍的に向上したかと言われると、そんなに変わっていない気がします。
シンプルなUI開発は確かに早く作れますが、UIにこだわったアプリなどはComposeといえどある程度レイアウトの作り込みが必要なので、結局それなりの時間がかかります。
### Preiview機能によるレンダリングに時間がかかる
XMLレイアウトのプレビューのレンダリングの方がやっぱり早いので、若干ストレスです。
### 既存のAndroidViewに比べてAPIが不足している
標準のCompose APIでは実現が大変なUIは結局自前で実装になる
- CoordinatorLayoutチックなUIを表現する標準APIが見当たらない。NestedScrollConnectionを使用すれば模倣できますが、自前の実装が多くなり管理が大変です。
- その他、Scaffoldベースだとカスタマイズがきついので、結局自前で作ったりしがち。

### XMLやAndroidViewベースでサポートされていた機能がサポートされていなかったりする
- Textに対してカスタムフォントを適用するときに、XMLのTextViewでいうところのincludeFontPadding属性とかが見当たらなくて困った
- まだ新しいツールなので、ここら辺のサポートはまだまだ足りない
上記のような事象が発生したらプロダクトオーナーに事情を説明して許容してもらったりしました。

### 毎回State(状態)管理するのもだるい
TextFieldの入力文字列やダイアログの表示制御など、逐一State管理する必要があるのでさっと動きを確認したいときや単純な画面を作りたい時など面倒に感じることがあります。

### Application（Activity）のライフサイクルに応じたCompose上の処理制御が難しい
以下の記事とかで対応方法は書いてあったりしますが、ActivityとComposeのライフサイクルは１対１に紐づいているわけではないので、管理が難しいです。
https://stackoverflow.com/questions/66546962/jetpack-compose-how-do-i-refresh-a-screen-when-app-returns-to-foreground


# 新規プロジェクトでJetpack Composeを導入する際に配慮したいこと
自社サービスとかならアプリ設計の融通はある程度聞くかもしれませんが、受託開発ではそうもいかないこともあります。そんなときに予め注意しておきたい点は次のようなものが挙げられると思います。
### メンバー全体の開発レベルを考慮する
今までXMLに慣れ親しんだエンジニアにとってはパラダイムシフトになるので、キャッチアップするにはそれなりのコストがかかります。キャッチアップコストが開発コストに見合わないようであれば、Composeの採用を見送ることも考えないといけません。
素養のある人ならすぐキャッチアップできるかもしれませんが、最低２週間くらいの学習期間は見ておいた方がいいかも。
### Jetpack Composeでアプリ要件を満たしたUI開発ができることを最低限検証しておく
最悪、基本的なRowやColumnのようなコンポーネントを組み合わせれば、事実上どのようなUIでも実現はできそうですが、開発コストに影響します。
- 前述のCoordinatorLayoutなど、まだまだ以前のAndroidViewを使用した方が楽に実装できるUIパターンもありますので捨てたものではありません。
- アプリによっては、アプリの操作ログを画面のライフサイクルに応じて記録したりすることがあると思います。そのようなときに、Composeを使用しても無理なく実装できるか最低限シミュレーションしておいた方が良いです。
- Composeのライフサイクルを事前に学習しておかないと結構ハマります（ON_CREATEの呼ばれるタイミングとか、LaunchedEffectでの処理制御とか）。コストに余裕がないのであれば、マルチActivity（1Composable(Screen):1Activity)で行った方が良い場合もあると思います。ライフサイクル制御が難しい部分や、些細なState管理が面倒な部分はActivityに処理を委譲してしまうのも一つの手段です。

# Jetpack Composeは今後さらに広まるのか
なんかネガティブな点を結構書いておいてなんですが、なんだかんだ広ま（ってい）るんじゃないでしょうか。
やはり、ロジックもUIも同じKotlinベースで管理できるのは楽です。あとLazyColumnが素晴らしい。
前述のデメリットに対する対応案は日々Tipsが溜まって行くと思いますし、あまり悲観はしていません。
APIがまだまだ不足していますが、Jetpack Composeの開発は盛んに行われているので、2~3年後くらいにはその不足もかなり解消しているような気がします。
「つくりながら学ぶ！PyTorchによる発展ディープラーニング」の自然言語処理の章(7,8章)をローカルPCのDocker上で動かす

# はじめに

「つくりながら学ぶ！PyTorchによる発展ディープラーニング」というPyTorchの良書があります。本の内容は以下。

https://qiita.com/sugulu_Ogawa_ISID/items/07253d12b1fc72e16aba

この本の第7,8章を動かすためのDocker環境構築です。(GPUは非対応です。)

# なぜDocker？

素晴らしい本ですが、AWSインスタンスを立てて動かす方法しか書いてありません。学習を回すにはGPUが必要なのでAWSを使うといいと思いますが、著者が学習済みの重みを配布してくれていますし、コードは全て写経して、実行するのは学習以外ならば、ローカルCPUマシンで十分です。

ですが、特に第7,8章の自然言語処理は、OSのパッケージのインストールが必要ですし、Linux環境が前提の記述です。そこで、Dockerを用いて誰でも簡単に環境構築を済ませてしまおうというのがこの記事の目的です。

# Dockerのインストール

詳細はググってください。

- Windowsの方
Docker Desktop for Windows をインストールしてください。

- Macの方
 Docker Desktop for Mac をインストールしてください。

# Dockerイメージのダウンロード

私のDockerHubにイメージをアップロードしています。

```bash:ターミナル
docker image pull yhaneji/nlp-japanese:1.0.0
```

# Dockerコンテナの起動

上記イメージはJupyter公式イメージをベースにしています。そのためJupyter Lab が使えます。「プロジェクトのディレクトリ」を自分のプロジェクトディレクトリのパスに書き換えてください。

```bash:ターミナル
docker container run --rm -it -p 8888:8888 -v プロジェクトのディレクトリ:/tmp/working
```

# Dockerfile

詳細が気になる方のために、Dockerfileを私のGitHubレポジトリに置いています。VSCodeのRemote Containerを利用するための設定ファイルも置いています。是非ご利用ください。

https://github.com/Y-Haneji/nlp-japanese-docker
マークダウン記法ってなに？

# マークダウン記法とは

## マークダウンって？
軽量マークアップ言語
拡張子は「.md」
文章を見やすくするための書き方です。

## どこで使われているの？
evernote
vscode
slack...
Qiitaの記事投稿にも使われています。


## なぜマークダウンで書くの？
HTMLよりシンプルで記述が少ない（タグを書く必要がない）
書き方が簡単で覚えやすい

## どんなときに使うもの？
チームで要件をまとめる時に
ブログの下書き
メモ代わり

# 書き方（最低限）
## 見出し
文章の頭に「# 」
#を増やすとフォントサイズが小さくなっていく
## リスト
文章の頭に「- 」
番号付きリストの場合は「1.」
ネストでも書ける
「丸投げ」と「任せる」の違い　ー 「任された」と感じさせる指示とは？


# はじめに

上司が部下に仕事を「丸投げする」のと「任せる」のは、実はどちらも仕事をまるまる渡す点では同じです。

では、上司の何が、部下の感じ方の違いを生み出すのでしょうか？

自分なりに考えてみたので、ご笑覧ください。

# 部下の感じ方の違い

「丸投げされた」と感じる場合、上司に対する不満がたまります。「めんどうな仕事を投げつけられた」「自分より給料が高いのに、無責任ではないか？」といった具合です。本音はもちろん口には出せません。

一方「任せられた」仕事にはやりがいを感じ、
むしろ生き生きとするでしょう。

# 「丸投げされた」と感じさせる上司の3条件(OR)

仕事を「丸投げされた」と感じさせる上司は
次のいずれかの特徴をそなえていれば十分です。

1つ目は、部下と **信頼関係** ができていないことです。信頼関係ができていない上司から受ける仕事は、たとえ指示のしかたに問題がなくてもやりがいは感じにくいでしょう。

2つ目は、部下との **役割分担** が不明確であることです。上司が「楽な部分しかしていない」と感じたり、「責任を避けている」と感じたりすれば、不満はたまっていきます。

3つ目は、 **指示が消極的感情** を抱かせることです。仕事の目的・目標がわからない、仕事がなぜ自分に割り当てられたのかわからない、自分の職務範囲と思えない、仕事の必要性が感じられない、仕事に興味がない、自分の成長につながりそうにない。このように感じれば不満がたまります。

# 「任された」と感じさせる上司の3条件(AND)

仕事を「任された」と感じさせる上司は次のすべての特徴をそなえていることが必要です。

1つ目は、部下と **信頼関係**  ができていることです。技術や人間性など尊敬できる部分がある上司。部下の上回る点を日ごろから認めている上司。「いざというときに守ってくれる」と部下に感じさせる上司です。

2つ目は、部下との **役割分担** が明確であることです。

3つ目は、部下への **指示が積極的感情** を抱かせることです。

# 「任された」と感じさせる指示の出し方

1つ目の信頼関係は一朝一夕にはできませんが、2つ目の役割分担や3つ目の指示は言い方しだいです。そこで、任せるなら、指示や進捗確認の際に次のような言動をするのはどうでしょうか。

役割分担を明確にするための言動：
- 調整など、その仕事のめんどうな役割や重大な役割を上司が引き受けると部下に理解させる。
- 部下と交渉して部下が抱える他の仕事を引き取る。
- リソース追加の必要性を部下に尋ねる。
- 「やり方は任せる」などと任せる範囲を言明する。任せた範囲には後から口を出さない。
- 「ほかに自分がしてあげられることはあるか」とさらなる支援を申し出る。

積極的感情を抱かせるための言動：
- その仕事の顧客や後工程にとっての重要性（価値）を示す。
- 自分なりに必要と想定したインプットをそろえて渡す。（吟味もせず「情報はとりにこい」「自分で探せ」といういきなりの受け身は×）。
- 上司自身がその仕事に関与できない事情（能力不足、要領の悪さ）をすなおに認め伝える。
- ほかではなくその部下に頼む理由を述べる。
- 部下が興味を持っていそうな仕事を選んで渡す、そのことを訴求する。
- 指示のメールで、上司の責任の取り方を表明する。たとえば「失敗したときは自分が～するから思い切ってやってください」と書く。（この表明は口頭よりむしろ記録に残すとなおよい）
- 「心配事はあるか」と尋ね、リスクを共有・ヘッジ・テイクする。
- その仕事が部下の成長にどうつながるかを訴求する。
- 部下がその仕事を受けた（進めた）ことへの感謝を伝える。
- 出来栄えを褒める。
- 失敗を部下とともに振り返り励ます。

他にもアイデアがありましたら、コメント欄まで！
MySQL インデックス、MVCCの仕組み


# はじめに
この記事では、MySQL の MVCC がどういう仕組みで実現されているかということを説明します。

# トランザクション分離レベル

| 分離レベル | ダーティ・リード | ファジー・リード | ファントム・リード|
| ----------| ----------------|-----------------|------------------|
| READ UNCOMMITTED | 〇 | 〇 | 〇 |
| READ COMMITTED | × | 〇 | 〇 |
| REPEATABLE READ | × | × | 〇  |
| SERIALIZABLE | × | × | × |

**分離レベル**という言葉はDBMS一般の概念で、「トランザクション同士がどの程度分離しているか」を示します。

トランザクションというのは処理の単位であり、トランザクション同士が干渉しあうことは一般的に望ましいことではありませんが、トランザクションがほかのトランザクションと「どの程度独立しているか」ということには4つのレベルがあり、それを**分離レベル**と呼びます。

MySQL の分離レベルはデフォルトでは **REPEATABLE READ** です。

一般的にこの分離レベルでは、**「同一トランザクション内で、他トランザクションによる追加・削除の影響を受ける」** という意味の **ファントム・リード** が発生しますが、MySQL ではロックをとらずともこの影響が発生しないよう、 **MVCC** という仕組みが備わっています。

ファントム・リードを起こさないための仕組みというより、その影響を受けないようにするための仕組みという感じが近いかもしれません。

# MySQL における MVCCのしくみ

MVCC(Multi Version Concurrency Control) は分離レベルが READ COMMITTED 、REPEATABLE READ のときに使われる機能で、複数のバージョンのデータを持ち、トランザクションに対して適切なバージョンのデータを返すことで、他トランザクションの処理の影響を受けないようにしています。

ある行データについて、仕掛り中のトランザクションごとに複数管理しておけば、あるトランザクションから行データを要求されたときに、そのトランザクションが見える"べき"値を返すことができる、といった感じです。

このMVCCを実現させているのは **Undo ログ** という仕組みですが、これを下に図示します。

![mvcc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493435/e2c3f9ac-0b11-a771-88a8-3f85949be2f3.png)

主キーインデックスのリーフノードには様々な情報が格納されています。

その値を変更したトランザクションのIDを示すTRX_ID (transaction_id) であったり、MySQL のインデックス構造は B+Tree であるため、隣同士のインデックスを参照しあうためのポインタであったりします。

その中のひとつのポインタが、Undo ログへの参照を持っています。

Undo ログの中には複数世代の行データがリンクでつながって管理されており、リンクをたどるほど古い世代の値になります。

それぞれの値は、どのトランザクションIDによって更新された値なのかがわかるよう、**TRX_ID** と古いデータが一緒に管理されています。

**TRX_ID** はトランザクションが発行されるたびにインクリメントされて採番されるようで、これによってトランザクション同士の新旧比較が可能になっています。

# MVCC の例
![mvcc2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493435/622a757d-73b8-a413-ac5c-57a48f39e2bd.png)

ここではMVCCの挙動をがんばって表現してみます。

まず、**TRX_ID : 96** でなんらか SELECT 文（図右上）が発行されたとします。

主キーインデックスのリーフノードにたどりつき、その内容を見てみると DELETED フラグが立っているためもう削除済みであることがわかります。

削除済みなんですが、それを実行したトランザクションは **TRX_ID : 100** と、自身（96）より新しいトランザクションによる処理であるため、自分（96）はその結果に影響をうけないようにしたいです。

そこで利用されるのが Undo ログで、インデックスのリーフノードの **ROLL_POINTER** の宛先の Undo ログを確認します。

すると、リンク先には1世代前の値が登録されています。
しかし、これも **TRX_ID : 98** であり、自身より新しいため、さらにリンクをたどります。

次の値は **TRX_ID : 95** であり、これは自身より古いトランザクションによる更新であるため、ここに登録されている値を取得します。

このように、複数世代の値を管理することで分離レベルが **REPEATABLE READ** であってもファントム・リードを影響を受けないようにしています。



# MVCCの注意点

詳細は以下記事を参照いただければとおもいますが、ロストアップデートという問題を起こさないようにするため、通常の `SELECT` か、更新ロックつきで `SELECT ... FOR UPDATE` とするかで挙動がかわるようです。

実装時に気をつけておくこととしては、MySQL はデフォルトの分離レベルでは、

- 単に `SELECT` するだけなら `FOR UPDATE` はつけなくてもファントムは MVCC によって発生しない。
- 同一トランザクション内で更新もするときにはロストアップデートを防ぐために `SELECT ... FOR UPDATE` とする。

といったところでしょうか。

http://nippondanji.blogspot.com/2013/12/innodbrepeatable-readlocking-read.html

# そのほか懸念事項

また、別の注意点として、Undo ログの存在がパフォーマンスに悪影響を及ぼす可能性を念頭にいれておく必要があるとおもいます。

Undo ログのチェーンはトランザクションごとに作られるらしいのですが、これは基本的には定期的にパージされているようです。

トランザクションが短い時間で完了するものばかりであれば、Undo ログの短い時間間隔でパージして問題ないですが、時間の長いトランザクションがあると、Undo ログがパージできず、Undo ログのサイズが肥大化していくことが懸念されます。

MySQL のパフォーマンスの問題が発生したときにはこの点を疑ってみてもいいかもしれません。
1分でREST APIのモックサーバーを作る

[json-server](https://github.com/typicode/json-server) を使ってAPIのモックを作る手順を備忘録として残す。


# 手順
1. `package.json` の作成
1. json-server のインストール
1. jsonの追加
1. サーバ起動

# 1. `package.json` の作成
Node.jsインストール済みの環境で、プロジェクトとなるディレクトリ(ここでは`api-mock`)を作成し、そのディレクトリへ移動したら、`$ npm init`コマンドを実行。

`package.json`が生成される。

※今回はyarnではなくnpmを用いている


```:package.json
{
  "name": "api-mock",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
}

```

# 2. json-server のインストール
`$ npm install json-server --save-dev`を実行すると、開発環境にjson-serverがインストールされ、devDependenciesに追加される。同時に、`package-lock.json`、`node_modules`が生成される。

```:package.json

〜〜〜〜省略〜〜〜〜
  "devDependencies": {
    "json-server": "^0.17.0"
  }
```

# 3. jsonの追加
レスポンスデータを記述するjsonファイルを作成する。

```:db.json
{
  "posts": [
    { "id": 1, "title": "春日", "author": "若林" }
  ],
  "comments": [
    { "id": 1, "body": "リトルトゥース", "postId": 1 }
  ]
}
```

# 4. サーバ起動
`package.json`のscriptsを追加。

```:package.json
{
  "name": "api-mock",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    // 追加
    "json-server": "json-server --watch db.json"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "json-server": "^0.17.0"
  }
}

```

`$ npm run json-server`を実行。
以下の表示が出れば成功。
![スクリーンショット 2022-06-24 1.02.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1481264/03461145-d2b9-2d08-6654-c3ffd16487f6.png)

`http://localhost:3000/posts`　を開くとレスポンスを確認できる。

![スクリーンショット 2022-06-24 1.03.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1481264/78e0e0ba-30fa-9a2d-86b7-bd95367070d5.png)
6.14 (標準) 最尤推定8，最尤推定量の漸近正規性

## 方針

最尤推定量の漸近正規性について．

![知ったこと-87.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1702786/cd8916c5-a8f1-a7ed-4de1-0d065f4a9df8.jpeg)
![知ったこと-81.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1702786/10118d8c-df81-1e06-b52f-7665297bb142.jpeg)

## 答案

![6. 2周目-34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1702786/0016ed23-e352-bfd4-681c-6a78b621f27e.jpeg)
![6. 2周目-35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1702786/e3431e4d-2a13-40e2-21d3-dc628ee58053.jpeg)

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
RailsのWebpackerがコンパイルしているのにJavaScriptを実行してくれない、ホットリロードが効かない

# はじめに

以前、Dockerを利用したRails+Webpackerの環境を作成したのですが、改めて作成する機会がありやってみたところ、webpackでつまづいてしまったのでその個所をまとめます。

# 問題

## 1. Webpackを設定したがコンパイルが行われない

`/bin/webpack-dev-server`を起動したところ、`public/packs/manifest.json`ができるけれども、`public/packs/js`のディレクトリは作成されなかった。また`/bin/webpack`を実行するとコンパイルが実行されていたが、なぜかJavaScriptは読み込まれておらず、うまくコンパイルが行われていないようだった

以下の記事をみつけた

https://qiita.com/undrthemt/items/52a557cb937d133b7140

`./config/webpacker.yml`のホストが`localhost`になっていたので、docker-compose.ymlのwebpackerコンテナの名前に変更することでJavaScriptがコンパイルされるようになった

```yml:./config/webpacker.yml
development:
  <<: *default
  compile: true

  # Reference: https://webpack.js.org/configuration/dev-server/
  dev_server:
    https: false
    host: webpacker # 変更
    port: 3035
    public: localhost:3035
    hmr: false
```

```docker-compose.yml
  webpacker: # ホスト名
    <<: *base
    environment:
      NODE_ENV: development
      RAILS_ENV: development
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    command: ./bin/webpack-dev-server
    ports:
      - '3036:3036'
    volumes:
```

## 2. Webpackerのホットリロードが効かない

`/bin/webpack-dev-server`を時tぅこうしたところ
JavaScriptが初回時にコンパイルされるだけで、ファイルを変更してもホットリロードが効かなかった
webpackerのコンテナに入ってファイルをcatで表示したところローカルの変更が反映されていなかった

つまり、マウントをし忘れていた！

docker-compose.ymlのVolumesに追加をして解決

```docker-compose.yml
    command: ./bin/webpack-dev-server
    ports:
      - '3036:3036'
    volumes:
      - .:/app # 追加
      - public-data:/app/public
    container_name: webpack
```

# おわりに

Webpackは毎回何かしら問題が起きている気がします。
しっかりと動きを理解することが大切です。

# 参考
- [Rails6をdocker-composeでホットリロードできる環境を構築する](https://qiita.com/undrthemt/items/52a557cb937d133b7140)
Qiita Conference 2022 復習２

Qiita Conference 2022 予習

https://qiita.com/kaizen_nagoya/items/a6ab098dbe6a1ae35368

１日目、お一人の話を視聴させていたたいた。

Qiita Conference 2022 復習

https://qiita.com/kaizen_nagoya/items/78d2764ac3e82ba70c33

２日目、お一人の話を視聴させていただいた。


# 8. さくらインターネット株式会社 / 代表取締役社長 田中 邦裕
>1978年大阪生まれ。1996年舞鶴高専在学中にさくらインターネットを創業。
2005年東証マザーズ上場、2015年東証一部上場。2022年の市場再編に伴い、現在はプライム市場。
元々のバックグラウンドはエンジニアでありながらも、自らの起業経験などを生かし、スタートアップ企業のメンターや、学生エンジニアの指導等にあたる。また、業界発展のためSAJやJDCC等、各種団体に理事や委員としても多数参画。
この世の中はソフトウェアを軽視しすぎている！～デジタル敗戦から日本が復活するために～
パソコンやソフトウェアって、小さい頃は楽しいものだと思っていたのに、どうして仕事になるとつまらなくなるんだろう・・・？
使われそうにないシステムの開発や改修に明け暮れる日々になるのはなぜなんだろう・・・？日本のデジタルって、どうしてこうなんだろう・・・？
やりたいと思っていたITエンジニア、こんなはずじゃなかったのに・・・
等々、思ったことはありませんか？
エンジニアから社長になり、最近は業界団体の偉い人にまでなってしまったからこそ見えてきた、
これらから得た視点や今までの経験をひっくるめて、デジタル・ソフトウェア産業をどう変えるべきなのか、
今私が考えていることを、皆様にお伝えしたいと思います。

https://net.keizaikai.co.jp/53977

https://signal.diamond.jp/articles/-/51


>保守的なことと寛容性が相入れない。

1983年ころからの話は、実時間で経験してきたことだということもあったかもしれない。

さくらインタネットが面白いことを企画したら、何か一緒にやれたらいいなと思った。

>技術、寛容性　才能

> 大事なのは寛容性、多様性

> 「やりたいこと」　を　「できる」　に変える
Firebase AuthenticationのGoogle認証画面で「400: redirect_uri_mismatch」のエラー画面が表示される

# 背景
- Firebase + next.jsでWebアプリを開発
- 巷に溢れているサンプルプログラムを参考にし、signInWithPopupでGoogleログイン画面を実装
- Googleアカウント認証画面はポップアップしたが、「400: redirect_uri_mismatch」のエラーが表示された。かなり詰まったので備忘録として残す
![スクリーンショット 2022-06-24 0.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37298/a85ee7aa-1e27-2df9-0178-c3e8b5ecf7a1.png)


# 解決
- firebaseのAPIキーの値が、おそらくGoogle Authentication Providerを有効にしたタイミングで変わっていた
- firebaseのコンソール画面でAPIキーを確認、設定し直したら解決した

# 経緯
- よく分かっていないけど、初めはfirebase Authentication自体全く触らず、firestoreにデータを保存・参照するだけのWebアプリを作っており、途中でログイン機能を追加するために有効化したのが原因かもしれない
- 変わる前のAPIキーでもfirestoreへのアクセスはできていたので気づかず、メッセージに従ってGCPコンソールのOAuth2.0設定を何度も見直したり、解決に何日もかかった。。。
[Linux]ポート疎通確認

# 概要
- ある特定のポートでリッスンする(はずの)サービスをEC2上で起動している
- EC2にはEIPを割り当てて外部公開もしている。
- セキュリティグループ,ネットワークACL,iptablesも設定して、特定のIPをアクセス元とする特定のポートに対するアクセスのみを許可している。

というような状態で、外部からの疎通確認をしたいときに。

# 1. サーバー内での各ポートのリッスン状況を確認
```
# リッスンしているポート番号の確認
netstat -atn | grep LISTEN
=>
Proto Recv-Q Send-Q Local Address   Foreign Address   State
tcp        0      0 0.0.0.0:22      0.0.0.0:*         LISTEN
tcp6       0      0 :::22           :::*              LISTEN
※↑はIPv4, IPv6のポート22でリッスンしてるものがある状態

# ポートをリッスンしているコマンドの確認
lsof -i:<ポート番号> | grep LISTEN
COMMAND PID   USER   FD   TYPE  DEVICE   SIZE/OFF NODE NAME
sshd    2600  root   3u   IPv4  19658    0t0      TCP  *:ssh (LISTEN)
sshd    2600  root   4u   IPv6  19660    0t0      TCP  *:ssh (LISTEN)
※↑はsshdというプロセスが入力したポート番号のポートをリッスンしている状態
```

※tcp6やIPv6のみが表示されていても、IPv4側のポートも空いている可能性あり(サービスによる)
参考: https://qiita.com/fetaro/items/d5164ba8271114d8a0c8


# 2. 外部 → EC2 へ特定ポートでアクセスできるかを確認
```
# 許可しているアクセス元のIPから
nc -vz <EC2インスタンスのパブリックIPアドレス> <ポート番号>

# 特定ポートをリッスンするサービスの起動前に、そもそも特定IPから特定ポートへのアクセスが可能であるかを確認する場合は、
# サーバー内で↓を実行しておいた上で、↑を実行する。正常にアクセスできたら↓のプロセスが終了する
nc -l <ポート番号>
```
スプリントプランニングをちゃんとやって幸せになる話。

### こんなことがありました。
*20xx年6月1日*
PM「本日の進捗どうですか？」
ぼく「問題ありません」

*20xx年6月2日*
PM「本日の進捗どうですか？」

ぼく「(あかん。。思った以上に範囲大きすぎて、わからへん。。。まぁ多分終わるやろ)
ぼく「問題ありまへん！」

*20xx年6月5日*
PM「本日の進捗どうですか？」
ぼく「あかんで(^)(^) １週間ほど遅れそうやわ、原因は既存実装の複雑さが予想以上にあったことや、調査不足ですまんな〜＾q＾」
PM「」


### なぜ起きたか
- タスクの粒度が大きすぎる（ざっくりと　A機能の開発　みたいな）
- 実装箇所についての調査不足
- 進捗確認でどこまで終わったか？どのぐらい終わったか？の確認がない
- タスクの期限が不明瞭



### なんちゃってプランニングはやっていた
1. PMがやってほしいタスクを説明
2. エンジニアチームにタスクを振る（期限は決まってはいるものの　6月に開始して　8月初旬には〜みたいなタスクもあった）
2. ２週間ごとに再プランニング

30分ぐらいで終わっていた

#### 問題点
- 期限が明確でないので進捗もよくわからない
- ２週間単位なので大きいタスクでも振れてしまう（タスクの細分化を意識しない
- やるべきこと　ばかり多く、それが本当にサービスの価値につながるか？の議論は少なめだった


## ちゃんとした　スプリントプランニング　とやらをやってみよう！

### スプリントプランニングの流れ
スプリント期間の設定（今回は１週間とした）

1. スプリントゴールの設定
1. 実行するタスクの選定
1. 選定したタスクの細分化


今まではゴールが明確ではなかったのと、タスクの細分化が行われていなかった。

例：
**スプリントゴール**
ユーザー数の増加とともにDAUを増やす。

**実行するタスクの選定**
登録中の離脱率が高いのでリマインドメールの実装
継続的にコンテンツを見れるようにスライダーの利用

**選定したタスクの細分化**
- リマインドメール機能
    - 要件決め
    - 設計
    - 実装
    - テスト実装
    - 手動テスト
- スライダーの実装
    - 利用するライブラリの選定
    - 実装
    - テスト
    
細分化したタスクをスプリント内で実施する。
細分化の基準は1日で終わるぐらいまでやったほうがいい。

例えば実装に２日かかるなら
XXまでを1日
YYまでを1日
といったように、更に細分化していく。


## やった結果どうなったか
*20xx年6月1日*
PM「ぼく君、本日のA機能の調査について進捗どうですか？」
ぼく「はい！A機能についてですが、既存機能の修正がありそうなので実装のタスクが1日ほど伸びそうやで！」
PM「おけまる水産」

*20xx年6月2日*
PM「本日の実装の進捗どうですか？」

ぼく「実装のうちAPI開発については終わったで！既存の修正を明日やる感じや！」
PM「OK牧場」

*20xx年6月5日*
PM「本日のA機能のテストの進捗どうですか？」
ぼく「問題ないで！遅れもなく期限通り終わりそうや！」

### 結果: (^)(^) にっこり
機能を細分化したことで遅れが発生した際もカバーできる範囲になり、結果として全体の進捗への影響も少なくなった。
またプランニングの時点で価値提供を考え行ったことで無駄のない開発が行えた。
AWS OpenSearch インデックスのマッピングのデータ型変更の手順 


現在AWS OpenSearch マッピングのデータ型が変更できないので、一時のインデックスを経由で、インデックスを再作成して、インデックスのマッピングのデータ型を変更する。
例：以下のインデックスの`field:test-text`が`float`から`keyword`に変更する場合、
```
{
  "sample_index" : {
    "aliases" : { },
    "mappings" : {
      "dynamic" : "true",
      "_meta" : { },
      "dynamic_date_formats" : [ "strict_date_optional_time", "yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z", "basic_date_time" ],
      "dynamic_templates" : [ ],
      "date_detection" : true,
      "numeric_detection" : false,
      "properties" : {
        "field:test-text" : {
        "type" : "float"
      }
    }
  }
}
```
### ・ステップ1：一時のインデックス作成
```
PUT /sample_index_bk
{
  "mappings" : {
    "properties" : {
      "field:test-text" : {
        "type" : "keyword"
      }
    }
  }
}
```
### ・ステップ2：既存のインデックスのデータを一時インデックスへコピーする
```
POST _reindex
{
   "source":{
      "index":"sample_index"
   },
   "dest":{
      "index":"sample_index_bk"
   }
}
```

### ・ステップ3：既存のインデックスを削除する
```
DELETE /sample_index
```

### ・ステップ4：マッピングを変更したいインデックスを作成する
```
PUT /sample_index
{
  "mappings" : {
    "properties" : {
      "field:test-text" : {
        "type" : "keyword"
      }
    }
  }
}
```

### ・ステップ5：ステップ2のように一時インデックスのデータをステップ4に作成したインデックスへコピーする
```
POST _reindex
{
   "source":{
      "index":"sample_index_bk"
   },
   "dest":{
      "index":"sample_index"
   }
}
```

### ・ステップ6：一時インデックスを削除する
```
DELETE /sample_index_bk
```
Ubuntu で日本語入力と英語入力の切り替えをホームポジションから手を離さずに行う

# はじめに
Ubuntuで日本語入力と英語入力の切り替え設定で苦労したので一例をまとめます。
Mozcを使います。デフォルトだと左上のE/Jキーで切り替えを行うと思いますが、自分の環境ではうまく動作しなかったのに加えてホームポジションから手を離す必要がありました。
今回紹介する設定のメリットはホームポジションに手をおいたまま左右の親指で入力の切り替えができることです。

![Screenshot from 2022-06-29 07-38-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123822/11abf8ee-6a85-99c6-765a-b122934ad05e.png)


使用キーボード:realforce r2
OS: ubuntu20.04
# 1. Mozcが導入されていることを確認
右上の言語メニューでMozcを確認します。<strong>日本語 jaはいりません。</strong>
![Screenshot from 2022-06-24 17-58-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123822/df81987d-04e3-dc5d-f7f8-a482b241c331.png)

# 2. Mozcの設定を編集
Mozcの設定を編集します。ツール->プロパティでMozcのプロパティを開きます。
![Screenshot from 2022-06-24 18-01-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123822/ed6505a1-4a34-963d-3d26-8264c52d9db3.png)

キー設定の選択　編集をクリック
![dfadf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123822/4eb8ed40-bd9c-b4fb-1458-70a3e8b0172b.png)


日本語入力に切り替えるには「ひらがなに入力切替」に割り当てたキーを押します。今回は以下の画像のように項目を編集します。
使用しているキーボードのKANAキーが押しづらかったのでHenkanキーにしました。お好みで。
![Screenshot from 2022-06-24 17-55-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123822/ad6e128a-eaa7-fdfa-2067-2d17f28bb442.png)


英語入力に切り替えるには「IMEを無効化」に割り当てたキーを押します。著者はMuhenkanキーを選びました。
![Screenshot from 2022-06-24 17-53-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123822/ee0f168d-2b67-e442-b6fc-5b3f014acdd0.png)


入力キーが複数のコマンドに紐付いているとうまく動作しません。上の例ではHenkanキーはデフォルトで別の動作に割り当てられていたので項目を削除しました。設定が完了したらOKボタンを押して設定を保存するのを忘れずに:v:


# おわりに
以上の設定で左親指でスペースキー左隣のキーを押すと英語入力、右親指で右隣のキーを押すと日本語入力になります。
Cypress+DockerでCertVerifyProcBuiltin for xxxxx failed

## 事象
- CypressをDockerで動かすと以下のようなエラーが出ます。(証明書のエラー)
```
[231:0624/174959.819274:ERROR:cert_verify_proc_builtin.cc(681)] CertVerifyProcBuiltin for redirector.gvt1.com failed:
Certificate i=0 (OU=Cypress Proxy Server Certificate,O=Cypress Proxy CA,L=Internet,ST=Internet,C=Internet,CN=redirector.gvt1.com) -----
ERROR: No matching issuer found
```

## 原因
- Dockerにブラウザがインストールされていない、もしくはブラウザを指定していない。


## 対応
- `cypress/browsers:node16.14.0-chrome99-ff97`のようなブラウザが設定されているコンテナを利用する
- `cypress run --headless --browser chrome`のようにブラウザを指定してテストを実行する
Composableをスクロールに応じて動かす

### スクロールで動かす

<img width="240" alt="ugokuyo" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/4c740481-3193-a515-b53d-4d398a0c21a1.gif">

### やり方
ScrollStateの値でComposableのOffSetを変更し続ければよい

以下のようなComposableを作る。
```kotlin
@Composable
    fun Blue(scrollProvider: () -> Int) {
        Column(
            modifier = Modifier
                .offset {
                    val scroll = scrollProvider()
                    val offset = (ScrollHeight - scroll).coerceAtLeast(80)
                    IntOffset(x = 0, y = offset)
                }
                .padding(bottom = 32.dp)
                .background(Color.Cyan)
        ) {
            Spacer(Modifier.height(16.dp))
            Text(
                text = "うごくよ",
                style = MaterialTheme.typography.h4,
                modifier = HzPadding
            )
            Text(
                text = "message",
                style = MaterialTheme.typography.subtitle2,
                fontSize = 20.sp,
                modifier = HzPadding
            )
        }
    }
    @Composable
    fun Body(scrollState: ScrollState) {
        Column(modifier = Modifier.verticalScroll(scrollState)) {
            Spacer(modifier = Modifier.height(ScrollHeight.dp))
            val dataList = mutableListOf<String>("a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a",)
            dataList.forEach {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(120.dp),
                    verticalArrangement = Arrangement.Center
                ) {
                    Text(text = it)
                    Box(modifier = Modifier
                        .fillMaxWidth()
                        .height(60.dp)
                        .background(Color.Red))
                }
            }
        }
    }
```

よびだしはBoxで。

```kotlin
               Box(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(Color.LightGray)
                ) {
                    val scrollState = rememberScrollState(0)
                    Body(scrollState = scrollState)
                    Blue { scrollState.value }
                }
```


### 参考
https://github.com/android/compose-samples/tree/main/Jetsnack
「英数字を含めた13桁のパスワードなので解除は難しい」のか【検証してみた】

# 初めに
2022年 6月23日、兵庫県尼崎市でこのようなニュースが流れました。

https://news.yahoo.co.jp/articles/0974f871f11fa17d9011fe7f275bbe2560139371

個人情報を紛失してしまった点についても落ち度はありますが、この会見で**パスワードの桁数***や***利用されている文字種**を公開してしまったことで世間を騒がせています。
(そもそも機密情報を簡単に持ち出せる仕組みがNGですが...)
今回は「13桁とわかっているパスワードはどのくらいの速さで解読されてしまうのか」を検証して、ITリテラシーの啓蒙活動をしたいと思います。


# 検証環境
パスワード付きのUSBが用意できなかったので、解読速度の低いPC(低スペックのPC)で検証しました。

- 端末：ラズパイ4B
- CPU：4コア(1.5GHz)
- メモリ：4GB

# 検証結果
Pythonスクリプトを作成し、実行してみました。
また今回は大文字を含む英数字(0~9, a~z, A~Z)の総当たり(ブルートフォースアタック)で検証を行います。

```sh
$ sudo python3 pass_unlock.py
0000000000000
0000000000001
0000000000002
....
```

～数分後～
```sh
0000000050XV4
0000000050XV5
0000000050XV6
....
```
...全然解析が終わりません。
少しずるいですが、1分経過したタイミングでの解析数をもとに計算してみます。(鉄は熱い内に..ってやつです。)


計測した結果、1分時点の結果は以下でした。

```sh
0000000004JGK
```

つまり1分間あたり「**約140,000**」の計算量になります。

仮にパスワードが「**amagasaki2022**」だった場合、「**約40,005,707,853,733,957,781,094 通り目**」ですので、ラズパイで解析にかかる想定時間は「**約9億年**」ですね！

**9億年！？**
数分で終わるかと思ったのですが、思ったより時間がかるんですね。

**※9億年かかるからって、もちろん安全ってわけではないです。今回のプログラムは「確認のために毎回コンソール出力する」かつ「並列処理」も行っておりません。**
**プロプラムの最適化やマシンを変更したら、何10倍何100倍も計算結果が変わると思います。**

<details><summary>ソースコード全文はこちら！</summary><div>

```py:pass_unlock.py
import itertools
import sys
import random
import string
import time

# 時間計測開始
time_start = time.perf_counter()


# パスワード生成関数
def get_random_password(length):
    letters_and_digits = string.ascii_letters + string.digits
    result = ''.join((random.choice(letters_and_digits) for i in range(length)))
    print('パスワード: '+ result)
    return result


#ランダム生成された13桁のパスワード
password_answer = get_random_password(13)

#パスワードの確認に使用する文字
characters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

#パスワードの桁数の設定
count = 13

#総当たり開始
for password in itertools.product(characters,repeat=count):
    password = ''.join( password )
    print(password)
    if password==password_answer:
        # 時間計測終了
        time_end = time.perf_counter()
        time_result = time_end- time_start
        print('パスワードの解析に「' + str(time_result) + '秒」かかりました。')
        #処理終了
        sys.exit()
```

</div></details>


# 最後に
IPAでは今回のパスワード件以外にも、様々な情報セキュリティ対策が記載されたガイドラインがあります。
今回の件を機に、エンジニアだけでなくITを活用する「**ユーザー側のリテラシー**」が向上するきっかけになればと思います。

https://www.ipa.go.jp/security/antivirus/shiori.html

https://www.ipa.go.jp/security/measures/index.html

USB見つかったんですね！！
よかった！！

https://news.yahoo.co.jp/articles/21dc39e824e6ca4ac7b7826ae9220ed357bb1e0a
rbenv installのエラーを解決


# 経緯
Herokuへデプロイしていたら、Rubyのバージョンが合わなかったので、
バージョンの変更をしようとした。

エラーの抜粋として
BUILD FAILED (macOS 12.1 using ruby-build 
や
xcrun: error: invalid active developer path
が表示された。

# 結論
上記のエラーで検索するとXcodeが最新版でないことが原因とのこと。

# 解決策
ターミナルで下記コマンドで最新版にし、必要としていたRubyのバージョンを
無事インストールできました。


~~~
$xcode-select --install
~~~

# 参考記事
https://cpoint-lab.co.jp/article/202103/19336/
WSL から Windows native の python 環境(e.g. conda)を呼び出したいメモ

## 背景　

Conda で Python アプリを作っている.

実行は Windows native の Python 環境で行いたい(tkinter で GUI 使っていたり, pytorch で GPU 使っているなどで, Windows native の Python 環境を呼び出す必要がある).
でもファイル操作とか Windows だとめんどい(bash for windows つかったとしても)ので, WSL で行いたい.

## 方法

conda activate して WSL(bash)上で Windows native 側の conda 環境に入るみたいなのはやはりシェルが違うからダメでした.

windows で直接実行したいスクリプトを呼ぶのを batch file で wrap して, それを WSL から呼び出すことになります.

```
rem myscript.bat
call conda.bat activate myenv
python.exe myscript.py
```

を用意して, WSL から

```
$ cmd.exe /c myscript.bat
```

のようにします. `.` による相対パス指定できないようなので, `.bat` がカレントフォルダにない場合は Windows の絶対パス(e.g. `C:/Users/<yourname>/myscript.bat`)で指定します

また, WSL のフォルダで実行すると UNC path 対応していませんエラーがでるので, `/c/Users/<yourname>/` などの Windows のディレクトリで実行が必要です.

## TODO

* [ ] PowerShell にしてもう少し使いやすくならないか調べる
Watson StudioでJupyterに割り当てるランタイムを変更する

CP4DaaSのWatson StudioのJupyterNotebookを起動する際にランタイムを変更できます。
大きなデータを扱う場合には大きなリソースの環境を選び、逆に小さなデータを扱う場合には小さなリソース環境を選ぶことができます。

利用するリソースによって課金単位のCapacity units per hour（CUH）が異なります。適切なランタイムを選ぶことで課金を最小化することができます。
https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/track-runtime-usage.html?locale=en

# 1.新規ノートブックでのランタイム選択

新規資産でJupyterを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/359c0340-9fc2-ea42-235f-09fa191293a3.png)

以下でランタイムを選ぶことができます。デフォルトはXSで、2vCPU 8GBRAMで1CUHのランタイムです。XSSの場合は1vCPU 4GBRAMで0.5CUHのランタイムです。つまりXSSはXSの倍の時間利用することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e8169321-5934-75c7-d0a2-2e3652e1f77a.png)

# 2.既存ノートブックでのランタイム選択

既存ノートブックはランタイムが紐づいています。これを変更します。

まず、ロックされている場合にはロックを解除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/0d2d95b8-a905-330e-4019-728ebf5a40ab.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/215ade9f-6e3a-7af0-8366-92bbb87d107a.png)

「…」メニューから「環境の変更」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cc08fe6a-eb40-b9c8-05f1-6efb05f765ac.png)

変更したいランタイムを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/250e1e80-f1d8-d88d-89f0-d312421a82cd.png)
goで画像のトリム処理を行う

# はじめに

こんにちは、icemint0828です。
今回は自作パッケージの紹介も兼ねて、goでの画像のトリム処理の方法を紹介します。


## 動作環境
go 1.18.3

## 使用パッケージ

* icemint0828/imgedit
画像のトリム処理に使用しています。
画像ファイルの拡張子の変換にも使用しています。

https://github.com/icemint0828/imgedit

## インストール

```shell
$  go get github.com/icemint0828/imgedit@v1.5.0
```

# 画像のトリム処理

```main.go
package main

import (
	"github.com/icemint0828/imgedit"
)

func main() {
	// 切り取り開始位置の指定（px）
	left, top := 100, 100	

	// サイズの指定(px)
	width, height := 400, 400

	// FileConverter
	fc, _, err := imgedit.NewFileConverter("srcImage.png")
	if err != nil {
		panic(err)
	}
	// トリム
	fc.Trim(left, top, width, height)
	
	// 保存(jpeg, gif形式での保存も可能)
	err = fc.SaveAs("dstImage.png", imgedit.Png)
	if err != nil {
		panic(err)
	}
}

```

切り取り開始位置は画像の左上の位置を指定して下さい。
元画像の範囲外を選択すると、正常にトリム処理が出来ません。
サイズの指定は切り出したい画像のサイズを指定して下さい。

`fc.SaveAs`の第二引数では以下の形式で保存するファイルの形式を選択出来ます。
* `imgedit.Png`
* `imgedit.Jpeg`
* `imgedit.Gif`

# 画像のトリム処理(image取得)
```main.go
package main

import (
	"image"

	"github.com/icemint0828/imgedit"
)

func main() {
	// 切り取り開始位置の指定（px）
	left, top := 100, 100	

	// サイズの指定(px)
	width, height := 400, 400

	// srcImgを何らかの方法で取得
	var srcImg image.Image

	// FileConverter
	c := imgedit.NewConverter(srcImg)

	// トリム
	c.Trim(left, top, width, height)
	dstImg := c.Convert()

	// dstImgを使用
}

```

ファイルを介さずにimageを処理したい場合は、上記のように`imgedit.NewConverter`で直接画像の加工が出来ます。

# パッケージ内の処理の説明

[imgedit](https://github.com/icemint0828/imgedit)パッケージ内の`converter.go`でトリム処理を実施しています。

```converter.go
// Trim trim the image to the specified size
func (c *converter) Trim(left, top, width, height int) {
	dst := image.NewRGBA(image.Rect(0, 0, width, height))
	dstSize := dst.Bounds().Size()
	for x := 0; x < dstSize.X; x++ {
		for y := 0; y < dstSize.Y; y++ {
			srcX, srcY := x+left, y+top
			dst.Set(x, y, c.Image.At(srcX, srcY))
		}
	}
	c.Image = dst
}
```

引数からサイズを取得し、`*image.RGBA`に対して、各ピクセルの色情報の書き込みしています。
書き込みをする際に元画像の`x+left`, `y+top`を参照することで左方向・上方向の切り抜きを実施し、その位置からの`width`, `height`を取ることで右方向・下方向の切り抜きを実施しています。

# おわりに
簡単な内容とはなりますが、画像のトリム処理を紹介させて頂きました。
最後まで読んで頂き、ありがとうございました。

#### 前の記事
[goで画像のリサイズ処理を行う](https://qiita.com/icemint0828/items/3c854d8f0361abc36b55)

#### 次の記事
[goで画像の反転処理を行う](https://qiita.com/icemint0828/items/32aacfebed52be4fa40d)
【Rails】他ユーザーの投稿やコメントを削除、他ユーザーの投稿を編集といった操作ができる状態になっていた件

プログラミングを初めて3ヶ月。
備忘録としてつまづいたところを記載し、アウトプットツールとして活用していきます。

ポートフォリオを作成し、学習段階で身につけたスキルだったはずですが
うっかり漏れていてメンターから指摘を受けたので再発防止、備忘録の為、記載します。

# 他ユーザーの投稿やコメントを削除、他ユーザーの投稿を編集といった操作ができる状態になっていた。
編集ページのurlを直接打ち込んだり、削除リンクを検証ツールから書き換えることで可能なので注意しなくてはならない。
編集や削除といった操作を実装する場合、ログインユーザーのデータなのかチェックを挟む必要がある。

# 直打ち禁止のコード

直打ち禁止対象のcontrollerを開き
（今回は、posts_controller.rb）

```ruby:posts_controller.rb
class PostsController < ApplicationController
  before_action :authenticate_customer!, except: [:show, :index]
  before_action :correct_post, only: [:edit, :update]
```

before_action :authenticate_customer!　は、ログインしている会員のみが使用可能という意味。
今回は、except: [:show, :index]としているので、会員でなくてもshow,indexは閲覧（使用）可能。

before_action :correct_post,only: [:edit,:update]を追加。
さらに、同じposts_controller.rbに下記のコードを追加。

```ruby:post_controller.rb
def correct_post
  @post = Post.find(params[:id])
  unless @post.customer.id == current_customer.id
      redirect_to post_path, alert: 'このページへは遷移できません。'
  end
end
```
redirect_to xxxxxxx 　は、投稿者以外が直打ちした時に、遷移するページのリンクを記載。
これで、直打ち禁止ができるようになった。

# 削除リンクは検証ツールから書き換えることでリンクの変更が可能になっていた
例えば、、、
URLーーーーーーーーーー/post/1
URLーーーーーーーーーー/post/２
の会員が別々だとすると、post/1を投稿した会員は普通ならばpost/２の投稿は削除できないのが当たり前である。
しかし私は、、、

```ruby:posts_controller.rb
def destroy
  @post = Post.find(params[:id])
  @post.destroy
  redirect_to posts_path
  flash[:notice] = "投稿を削除しました"
end
```
上記のように、ログインユーザーのデータなのかチェックをしていない。
この場合、デベロッパーツール（検証ツール）で削除リンクの
hrefの部分をpost/1をpost/２に変更することで
投稿した会員とは違う会員でも削除できてしまうのである。
完全に盲点であった。。。

なので、、、、下記のようにコードを修正。


```ruby:posts_controller.rb
def destroy
  @post = Post.find(params[:id])
  if @post.customer_id == current_customer.id
    @post.destroy
    redirect_to posts_path
    flash[:notice] = "投稿を削除しました"
  else
    redirect_to posts_path
    flash[:alert] = "他人の投稿は削除できません"
  end
end
```

このように
編集や削除といった操作を実装する場合、ログインユーザーのデータなのかチェックを挟む必要がある。

ということを改めて学ぶことができた！！！
16進数から10進数への変換方法を学んだ

# はじめに
現在プログラミングを学んでいますが、【課題の中で0xBFは10進数では幾つになるか】というような、2進数・10進数・16進数を自分の頭でそれぞれ変換して回答しなければならない問題があり、どのように考えて変換するのかを調べた結果を備忘録として書き記します。

下記のサイトがとても分かりやすくまとめてくださっており、学ばせていただきました。
参考：https://www.infraexpert.com/study/ip2.html

# 10進数と16進数
10進数が【0〜16】の時16進数に置き換えると下記の図のようになります。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666919/7e98c70a-2047-e6d9-7abe-4f9b095e230e.png)


10進数の【10〜15】までは16進数では【A〜F】を数字として使用します。
そのままでは数字だけの時に10進数と区別がつかないので16進数では数値の先頭に【0x】（ゼロエックス）をつけます。

# 2進数から16進数へ変換
10進数への変換を行う前にまずは2進数から16進数の変換を理解します。下記の図のように10進数の基準値をもとにすると分かりやすく変換できます。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666919/dae57134-2587-b3fa-2bb4-e07364204229.png)
上図のように2進数の【01011100】は16進数では【0x5C】ということがわかりました。逆の要領で行えば16進数を2進数に変換することも可能です。

# 16進数から10進数への変換
上記の2進数から16進数への変換を利用して16進数から10進数へ変換します。10進数の基準値を利用して2進数を10進数に当てはめて計算をすると合計値が10進数での数値となります。
詳細は下図参照

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666919/e70994d7-d415-056a-5385-9731c7c70bd6.png)

# さいごに
他の方法での変換もあるのかもしれませんが、自分はこの変換方法が一番しっくりきて理解しやすいと思いましたので、記事にさせていただきました。
CentOSのyumで指定したバージョンのパッケージを入れる

### インストール可能なバージョンを表示する

```
$ yum --showduplicates list openssl



openssl.x86_64                                                    1:1.0.2k-19.el7                                                       base
openssl.x86_64                                                    1:1.0.2k-21.el7_9                                                     updates
openssl.x86_64                                                    1:1.0.2k-22.el7_9                                                     updates
openssl.x86_64                                                    1:1.0.2k-24.el7_9                                                     updates
openssl.x86_64                                                    1:1.0.2k-25.el7_9                                                     updates
```

バージョンを指定してインストールする

```
$ yum install <packagename>-<versionname>
```

依存関係を調べる

```
$ yum deplist <packagename>
```
「n進数」の扱いに慣れる

nは幾つになったら桁が上がりますよと示す数字
例えば普段桁をは数えるとき基準にする数字は１、１０、１００、１０００などがある。
なのでnは桁を上げる時の基準する数字なのだ。
0から９まで数えると桁を変えるために１０にする次の１００までは１０倍しなければならない。
これを```１０進数```と呼ぶ。
ではコンピュータは１と０しか理解、処理できない。
そうするとこれを```２進数```と呼ぶ。

## 気づき
n進数のnとは桁を上げる基準となる数字のことを表していたのか。

## よく使われるn進数
１０進数、２進数、８進数、１６進数の４つが情報処理で使われるn進数として挙げられる。
```２進数だけだと桁が上がりすぎて扱いづらい。```

## 気づき
２進数と10進数しか知らない。
８、１６進数って何に使うのだろう？
どうやら８は2の3乗、１６は2の４乗になる。
そこが鍵らしい。
今はこれでいいらしい。

## 2進数であらわす数値を見てみよう
これから桁を上げていく。
０、１、１０、１１、１００、１０１、１１１、１０００、１００１...といく桁が上がっていく。

## ８進数と１６進数だとどうなるか
### 8進数
```０、１、２、３、4,5,6,7```
### １６進数
```０、１、２、３、４、５、６、７、８、９、A、B、C、D、E、F```

## 気づき
１６進数は１０になると桁が上がるから英語になるのかな。
そもそもなんでこれ使うんだろう？
次

## それぞれを２進数で表すと
８進数は0〜７を表す、そうすると０〜１１１で表す。
つまり```０００〜１１１```になる
１６進数は０〜Fを表す。そうすると０〜１１１１で表せる。
つまり```００００〜１１１１```になる。

## 気づき
この０００〜１１１と００００〜１１１１が肝らしい。
これが次につながる。

## ２進数と８進数と１６進数を```bit```で表す
２進数で一桁は１ビット
８進数で一桁は３ビット
１６進数で１桁は４ビット

## 気づき
１ビットは豆電球のイメージは想像しやすい。
３、４ビットで表せるから何？

## コンピュータの処理
当時のコンピュータは3の倍数ビット数で処理するのが珍しくなかった。
なので
一桁３ビットの８進数は都合がよかった。
また今のコンピュータは4の倍数ビット数で処理するのが普通になった。
一桁４ビットの１６進数は都合がよかった。

ちょっと長すぎた次に書く。

出典　キタミ式イラストIT塾基本情報技術者　令和０３年
Lambda で S3にアクセスするのに access id と secret key はいらない

S3にアクセスしたい！から　boto3を使うよ！
普通はこんな感じで、 id と key 渡す
```python:qiita.rb
s3 = boto3.resource('s3',aws_access_key_id,　aws_secret_access_key)
```
でも Lambdaでは
```python:qiita.rb
s3 = boto3.resource('s3')
```
でよいんですと。

でも`IAM設定ってものがいる`

# S3を使うための、IAM設定
1. 設定 > アクセス権限　
1. 「実行ロール」の中のロール名をクリック![スクリーンショット_2022-06-24_14_51_26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/a9718783-2986-5017-c775-5dbc063c0b20.jpeg)
1. 許可 「許可ポリシー」の右「許可を追加」から、「インラインポリシーを作成」![スクリーンショット_2022-06-24_16_07_31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/c902a551-263f-07de-b1e6-e744011d49ac.jpeg)
1. サービスの選択　で 「S3」を検索して選択
1. アクセスレベルを選択。　下記をチェック
    - リスト
    - 読み込み
    - 書き込み　
    書き込みするのに、読み込み権限も必要だったりするらしい。
1. リソースにでてきたエラーのもの、アクションのチェックをはずす. bucket以外![スクリーンショット_2022-06-24_16_34_39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/162cade6-d1ae-05f1-11c9-d67889f3f69c.jpeg)

1. bucketの「ARNの追加」
1. アクセスしたい、Bucket name　を入れる　<img width="400" alt="bucket name" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/7d2a39e6-af74-decc-d563-f585f8316ca0.png">
1. 「ポリシーの確認」
1. ポリシーの確認画面で、適当な名前を入れる　
1. 「ポリシー作成」
### イェぃ！

ちなみに、devで作ってテストして、本番あげる時にまたやらなきゃで面倒くせい。
そんなときは、JSONコピペでゆけるってよ！
バケット名はちゃんと変えてね。
SpigotプラグインにおけるTagを用いた処理の制御

## 最初に
~~今回はいつものダラダラ解説ではないです。~~

# Tagを用いて処理の実行を制御する
## Tagの操作
処理の条件にはTagを使いましょう。
裏側でファイルやデータベースを用いて判定してもいいですが、なにかと用意が面倒くさいと思います。
というわけでマインクラフトに搭載されているTagという機能を使って処理の制御をしてみましょう。

### Tagの付与
Tagの付与は簡単です。
```
player.addScoreboardTag("Tag名");
```
で付与することができます。
付与することのできるTag名には一部使うことのできない記号があるので注意しましょう。

:::note warn
マインクラフト側からでは空白、/は使用することができないのでプラグインでも同じだと思われます。
またこれら以外にも使えない文字があると思われます
:::

### Tagの取得
TagはSetに格納されているのでListのように番号を指定して取得することができません。
toArrayなどを用いれば全要素の取得をすることができます。

### Tagの存在確認
タグ名が明確に分かっている場合は
```
Set Tags = player.getScoreboardTags();
boolean TagExist = Tags.constains("確認したいTag名");
```
のようにして論理型で取得することができます。

Tag名が分からない場合にはforとtoArrayを用いて一つずつindexOfなどの処理を通していくことになるかと思います。

### Tagの削除
Tagを削除するときは
```
player.removeScoreboradTags("Tag名");
```
で削除することができます。

## Tagの利用
TagはOP権限のないプレイヤーからは取得、変更することができない上にサーバーから抜けても情報が保持されるので使い勝手は極めて良いと言えます。
私が作成しているGUIメニュープラグインではどのページを開いているかをTagを用いて取得しています。

Tagの個数上限は1エンティティにつき1024個なので使い切ることはないと思いますがむやみやたらに付与すると(多分)大変なことになるので気を付けましょう。

## さいごに
みなさんもTagを用いて楽々プラグインづくりをしてみませんか？
それでは良いプラグインライフを～

## 追記
追記 2022/10/01
(ストックされていたので最近思うことを少し。)
タグを使うのは良いですが、出来るだけプラグイン側でデータを保持するようにしましょう。
(HashMapを使うなり、コンフィグファイルを使うなど。）
タグの衝突が発生する確率がゼロではないので危険です。
それにHashMapなどに入れれば検索や取り出しが簡単になるので、ぜひ活用してステップアップしましょう。

それでは。


-坂木啞ルカ-