OmniAICreator/Qiita-1.07M huggingface dataset:
Gitコマンド一覧

PJでGitを使用することになったため、備忘録として記載します。
# init
Gitの作業リポジトリ作成
~~~
$ git init
~~~
【補足】
GitHubとの紐づけを実施
~~~
$ git config --global user.name "username"
$ git config --global user.email {mail@example.com}
~~~

# clone
既存のリモートリポジトリをクローンしてくる
~~~
$ git clone https://github.com/user/XXX.git
~~~

# remote add
今後リモートリポジトリへの操作時、＜リモート名＞を打つことでURLを入力不要にするための設定
~~~
$ git remote add ＜リモート名＞ ＜リモートURL＞
~~~

# fetch
リモートリポジトリ→ローカルリポジトリに取得
~~~
$ git fetch ＜リモート名＞ ＜ブランチ名＞
~~~

# merge
指定ブランチから今いるブランチにマージする
※コメントを求められた場合、「Ctrl＋shift＋X」で抜けられる
~~~
$ git merge ＜ブランチ名＞
~~~

# pull
フェッチ＋マージ
今いるブランチにマージされる
~~~
$ git pull ＜リモート名＞ ＜ブランチ名＞
~~~

# brunch
今いるブランチを確認
~~~
$ git branch
~~~

# status
状況確認
~~~
$ git status
~~~

# add
ステージに追加
~~~
$ git add ＜ファイル名＞

# すべて追加
$ git add .
~~~

# commit
ステージのファイルをローカルリポジトリにコミット
~~~
$ git commit -m "comment"
~~~

# push
プッシュ（ローカルリポジトリ→リモートリポジトリへのコミット）
~~~
git push origin master
~~~

# diff
差分比較
~~~
git add前の差分
$ git diff ＜ファイル名＞

git add後の差分
$ git diff --staged  ＜ファイル名＞
~~~

# log
コミット履歴を表示
~~~
一行で変更履歴を表示
$ git log --oneline

＜ファイル名＞の変更履歴表示
$ git log -p ＜ファイル名＞

N件の変更履歴を表示
$ git log -n N
~~~

# rm
削除
~~~
ステージ、ワークツリーのファイル削除
$ git rm ＜ファイル名＞

ステージ、ワークツリーのフォルダ削除
$ git rm -r ＜フォルダ名＞

ステージのファイル削除（ワークツリーには残る）
$ git rm --cached ＜ファイル名＞
~~~

# mv
ファイルの移動、ファイル名変更
~~~
$ git mv ＜旧ファイル＞＜新ファイル＞
~~~

# checkout
ワークツリーの変更を取り消す
~~~
git checkout .
~~~
ブランチを切り替える
~~~
git checkout ＜ブランチ名＞
~~~

# reset
ステージ上の変更を取り消す
※ワークツリーの中身は変わらない
~~~
git reset HEAD ＜ファイル/フォルダ名＞
git reset HEAD .
~~~

直前のコミットを取り消す
※ローカルリポジトリのみでの使用推奨
~~~
$ git reset --soft HEAD^
~~~


# stash
作業内容の退避
~~~
$ git stash save
$ git stash save "コメント"
~~~
stashした作業内容一覧
~~~
$ git stash list
~~~
stashした作業内容反映
※nには反映したいstashの番号を入れる。一覧で確認可能
~~~
$ git stash pop stash@{n}
~~~
stashした作業内容削除
~~~
$ git stash drop stash@{n}
~~~
文系卒未経験のSEがオンライン会議のとき意識してること3つ

# はじめに
去年の8月から今の現場に入り早1年4ヶ月が経とうとしていますが、
相変わらず、日々悪戦苦闘しながら業務をおこなっています。

去年は現場入りたてということもあり、
実際の作業やドキュメント作成など、
すでに土台があるものの仕上げをするような業務を担当することが主でした。
しかし現在では、エンドユーザー様のNW環境のヒアリングや製品の説明など
案件を進めるうえでの土台となる部分の業務も担当するようになりました。

これまた自分にとってかなりハードルが高く、
案件の進捗状況を調整しつつ、製品やNWについての勉強、実際の作業や問い合わせ対応など、慣れるまではそれぞれでのタスク管理が大変で目が回りそうになっていました。

このように業務が増えた中で私が一番難しいと感じているのが、
**オンラインでのお客様との打ち合わせ**です。

現地での作業の際にお話するのとは違い、
相手の顔が見えないため表情やリアクションがわかりにくく
自分が伝えたいことを齟齬なく伝えることの難しさを実感しました。

ですが、最近ではオンラインでの打ち合わせや会議が当たり前になっています。
そこで、今年は私が苦手とするオンラインでのやりとりについて、
現在も試行錯誤していますがこれだけは意識しよう！としている**三つのポイント**を紹介します。

# ①会議に参加したら挨拶をする
当たり前のことになりますが、まずはこれです。
私はオンラインだと変に緊張するので、自分の声出しの意味もかねて挨拶をします。
一回声を出すだけでも、少し緊張がマシになります(笑)

特に顔が見えないオンラインでのやりとりでは、**声だけが相手の状態を知る手がかり**なので、
挨拶でも相手のリアクションを確認できると安心できます。

また、最初に声を出すことで自分の音声設定も確認できますし、
こういった会議で挨拶されて嫌な人なんていないのでやって損することはないです！


# ②「えー」や「えーっと」を必要以上に言わない
これは本当に難しいです。
私は会議などで話すとき、必要以上に「えー」や「えーっと」を連発していることを
現場の上司に教えていただきました。
たった少しの「報告」だけでも何回も言っていて、
確かに言われてみればつい口に出してしまっている自覚もありました。。

あらためて自分で振り返ってみると、
私のこの癖は、オンライン会議などで緊張していたりてんぱっていると、
自分を落ち着かせる時間を稼ぐために言ってしまい、
でもそれくらいでは落ち着かずさらに重ねて言ってしまっている、ということに気づきました。

このような「えー」や「えーっと」というつい口から出てしまうような言葉は、
少しであれば気になりませんが、何度も言われると話がききにくい印象となり、
相手に伝えたいことも伝わらなくなります。

癖というのはなおすことが難しいですが、
まずは**意識することが大事**と考え、
自分の視界に入るPCのどこかに注意の付箋を貼る、
会議前に話すことをしっかり整理して慌てなくていいように準備するなど、
私なりに改善できるよう気を付けています。


# ③会話のキャッチボールを心がける
これは私ができるようになりたいことです。現時点では全然できていません。。

オンラインの会議では、画面共有をして色々な説明や打ち合わせなどをすることが多いと思いますが、
その際、相手の顔が見えないとつい一方的に話してしまいがちになります。
オンライン会議で相手の顔が見えないと、相手の状況や話の理解度などをはかる手がかりは**声**しかありません。

そのため、オンラインの会議や打ち合わせこそ、相手との**会話のキャッチボール**が必要となります。
今相手がどこまでついてこれているのか、お互いの認識に齟齬はないか、自分が伝えたいことが相手に伝わっているか
これらは相手と会話することでやっとわかります。

私の場合、変に緊張して説明や話すことでいっぱいいっぱいになりがちのため、
伝えたいことを一方的に投げる壁打ちのようになってしまうことが多いです。

「伝えたいことを話す！ヒアリングしたいことをきく！」ではなく
**「相手との会話の中で引き出す、伝える**」を意識して、壁打ちから卒業できるように引き続き頑張りたいと思います。


# おわりに
この記事を作成するにあたり、自分が頭の中で意識していることを言語化することができてよかったです。
言語化することで、より日々の業務で意識しやすくなった気がします。
今後もできていないことはできるように、できていることは無意識でできるように、頑張っていきたいと思います。
ここまで閲覧いただきありがとうございました。
【SAPUI5】Fiori Launchpadでローカルリソースが読み込めない時の対処法

# はじめに
JSON ModelをControllerで読み込む際に、loadData()で相対パスを指定していましたが、ローカルデバッグの際、Launchpadを経由するとパスが異なり、Modelを読み込めないという問題が発生しました。
今回は、上記の事象の解決方法について記載しました。


## 経緯
下記の相対パスで`sampleData.json`ファイルを指定してモデルを読み込みを行っていました。

```js
let oModel = new JSONModel();
oModel.loadData("./model/sampleData.json");
```
直接アプリケーションを開く方法でのデバックでは問題なく読み込みができましたが、
Launchpadから開くと次のような404エラーで読み込めていませんでした。

![スクリーンショット 2023-11-27 182552.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3345291/ff7acb5f-8f06-da1b-8c1e-ca6996f94d61.png)

原因について調査したところ、
具体的なパスについては省略しますが、
Launchpadからアクセスすると、直接アプリケーションを開いた時とはパスが異なっていました。

JavaScriptの相対URLはHTMLページに対して相対的であるため、アプリケーションが異なる場所からロードする場合、静的なパスでは読み込めない場合があります。
# 解決方法
 `jQuery.sap.getModulePath`で動的にパスを取得する。
```js
var path = jQuery.sap.getModulePath("<名前空間>","<リソースファイルのパス>")
```

今回の事例では、model配下のsampleData.jsonを読み込みたい為、下記のようになります。
```js
let oModel = new JSONModel();
var path = jQuery.sap.getModulePath("<名前空間>","/model/sampleData.json")
oModel.loadData(path);
```



# まとめ
今回の事例ではLaunchpadでのロードエラーでしたが、
アプリケーションが動作するプラットフォームやシステムが異なる場合には、静的なリソースの場所やデータソースへのパスが異なる場合があります。したがって、リソースパスを指定する際は動的にすることを推奨します。

# 参考
・https://help.sap.com/docs/cloud-portal-service/sap-cloud-portal-service-for-neo-environment/access-remote-content-from-application?locale=ja-JP
・https://answers.sap.com/questions/677930/json-model-loaded-but-no-data.html
開発者体験が大幅改善！フロントエンド開発にNxを導入した話

これは[Hubble Advent Calendar 2023](https://qiita.com/advent-calendar/2023/hubble)の2日目[^1]の記事です。


## はじめに

株式会社Hubbleのフロントエンドを担当している @KOHETs です。

普段はAngularのことばかり考えているんですが、その素晴らしさは[note](https://note.hubble-docs.com/n/neb9b8119bb23)でお話させていただいたので、今回は3年ほど前から利用している[Nx](https://nx.dev)というビルドシステムを導入して得られたメリットを紹介したいと思います。

## Nxってなに？

NxはNrwl社が開発しているオープンソースのビルドシステムです。モノレポ管理ツールとして知られていますが、実際には「開発者の生産性向上、CIパフォーマンスの最適化、コード品質の維持を支援するツールや技術を提供」[^2]と書かれている通り、フロントエンド開発のさまざまな場面で活躍してくれます。

## 生産性の向上

Nxを導入する前は、UIコンポーネントをnpmで公開して各アプリケーションで利用していました。そのため、コンポーネントを変更するたびにnpmに公開し、各アプリケーションのpackage.jsonを更新する必要があり、手間がかかっていました。

Nxを導入したことにより、コンポーネントを変更するたびに公開・package.jsonの更新がなくなり、手間が大幅に削減されました。また、共通化する範囲も自由に調整できるようになり、管理しやすくなりました。

## CIパフォーマンスの最適化

Nxでは、ライブラリやアプリケーションの依存関係を自動で管理し、影響のあるものを判断してくれる[Affected](https://nx.dev/nx-cloud/features/affected)という機能を提供しています。これにより、CIでのテスト対象を最適化することができ、実行時間を短縮することができます。

この機能を十分に利用するために、Hubbleではライブラリへの切り出しを積極的に行っていて、現在100個以上のライブラリが作られています。全てのライブラリに影響する変更はそれほど多くないため、Affected機能の活用によって、CIの実行時間を大幅に短縮することができました。

## コード品質の維持

Nxでは、定期実行するコマンドやテンプレートの作成などが出来る[Generator]( https://nx.dev/extending-nx/recipes/local-generators)という機能を提供しています。これにより、独自にカスタマイズされた設計規則や慣例を反映したテンプレートを作成することができます。

Hubbleでは、独特なディレクトリ設計を採用しています。Generator機能を活用して、その設計に合わせたライブラリやコンポーネントの生成を行っています。また、MakefileやスクリプトなどもNxのコマンドとして登録できるので、テンプレートの生成にも、定期実行タスクをまとめて管理するのにも便利です。

## まとめ

Nxは、フロントエンド開発のさまざまな場面で役立つビルドシステムです。今回紹介したメリット以外にも、さまざまな機能が用意されていて、日々の体験をより良くしてくれます。

Nxの導入を検討している方は、ぜひ一度試してみてください。

明日は @hiroykam さんです！

[^1]: 平日のみの投稿なので4日ですが、2日目の記事としています。
[^2]: [Intro to Nx](https://nx.dev/getting-started/intro)に書かれているものを抜粋して日本語にしています。
表記の訂正 (paizaランク C 相当)

https://paiza.jp/works/mondai/string_primer/advance_step7

>・ ミス 1
先頭に必要のない 0 がいくつかついてしまう
・ 本来 1 である数値が 0001 と表記されてしまう
・ 本来 0.001 である数値が 00.001 と表記されてしまう
>
>・ ミス 2
小数である数値の末尾に必要のない 0 がいくつかついてしまう
・ 本来 0.1 である数値が 0.10 と表記されてしまう
>
>・ ミス 3
小数である数値に小数点が複数個ついてしまう
ただし、 1 つめの小数点の位置が正しい小数点の位置であるものとします
・ 本来 0.123 である数値が 0.1.2.3 と表記されてしまう。
>
>表記が正しくない可能性のある数値を表す文字列 S が与えられるので、その数値を正しい表記にしてください。
>S を数値として扱うと上手く処理が行えないので気をつけてください。


はい。すっげえ難しく３０分過ぎてもできなかったのでギブアップ。

ひとまず考えとして
・小数か整数かで場合分け
・整数なら、正規表現で先頭の000だけ消せばいけるんでは
・小数なら、まず集合を用意して、0と.だけ登録してもし集合にあればスキップして、1-9がでてきたら抜ければいいんでは
=>サンプル３で、０はそもそも、一番最後だけで、途中にあってもよいのでここで詰まる。


```py
def istype(S):
    #小数なら1 整数なら0のまま
    flag = 0
    for i in S:
         if i == '.':
            flag = 1
            break   
    return flag

#小数点がある場合の処理
def process_for_miss1(S):
    tmp =set()
    ans = []
    for i in S:
        if '.' in tmp:
            if i != '0':
                ans.append(i)
                break
            else:
                ans.append(i)
        if i == '0' or i == '.':
            if  i not in tmp:
                tmp.add(i)
                ans.append(i)
        else:
            ans.append(i)
    return ans
    
def process_for_miss2(S):
    import re
    pattern = '\b0+'
    result = re.sub(pattern,"",S)
    return result

S = input()
decimal_type = istype(S)
#フラグが０なら整数の処理、1なら小数の処理
if decimal_type == 0:
    ans = process_for_miss2(S)
    print(ans)
else:
    ans = process_for_miss1(S)
    print("".join(ans))
```

答えを見るとこんな感じ。
とりあえず考え方を#で書いてます。

```py
s = input()

#小数点があるかで分岐
if "." not in s:
    #整数
    i = 0
    #文字数を桁と捉えて左から順番にループしていく
    #s[i]が０でなくなるまでループ
    while i < len(s):
        if s[i] != "0":
            break
        i += 1
    #もしiが最後の桁までいったら、0でOK，もし途中だったらそこから最後まで出力
    if i == len(s):
        print(0)
    else:
        print(s[i:])
else:
    #小数
    ans = ""
    start = 0

    for i in range(len(s)):
        #整数と同じ考え方でループ
        #０でなくなっただけなら、そこから出力開始と考える
        #０でなく.だったら、0をつける
        if s[i] != "0":
            if s[i] == ".":
                ans += "0"
            #開始位置を更新
            start = i
            break
            
    #終了位置を考える
    last = 0
    for i in range(len(s)):
        #ここで最後に0以外になったら更新、0だったら未更新でそのまま終わりになる
        #読み飛ばす位置がわかる
        if s[i] != "0":
            last = i
    #最初の小数点の位置を確認
    first_dot = s.find(".")
    #開始位置〜終了位置までループ
    for i in range(start, last + 1):
        #小数点でなければ出力
        if s[i] != ".":
            ans += s[i]
        #first_dotの位置であれば出力
        elif i == first_dot:
            ans += s[i]

    print(ans)

```
なるほど〜〜〜〜〜
なかなか難しかったです。
数値で考えたからかな。。。。
とはいえこの書き方は思いつかなかったので、勉強です。

で、小数点がふくまれていなければ、`int()`を使って
`print(int(S))`で先頭の０が含まれない形になるのでこれも覚えておきたいところ。
Hyper-Vに関連するイベントIDまとめ

Hyper-Vの仮想マシンに関するイベントIDまとめ
随時更新していきます。

イベントビューアー(ローカル)\アプリケーションとサービスログ\Microsoft\Windows\
- Hyper-V-VMMS\Admin
    - 作成
        - 成功　13002
    - 起動
        - 失敗(メモリ不足)　19544
    - チェックポイント作成
        - 操作失敗　18012
        - 操作取り消し　18014
    - エクスポート
        - 正常に完了 18303
        - 失敗(保存先容量不足)　18450
    - ディスク結合
        - バックグラウンドで開始　19070
        - 同中断　19090
        - 同正常終了　19080
        - 同失敗(アクセス権)　19100
    - メモリ
        - サイズ変更失敗(時間が掛かったため)　23147
        - サイズ変更失敗(予期しないエラー)　23153
    - その他
        - ファイルコピー失敗(容量不足)　18112
- Hyper-V-Worker\Admin
    - 仮想マシン側で再起動　18514

気になる点
- チェックポイント作成の成功は記録されないのか
【Nuxt3】Client Side Rendering で .output/public/ に index.htmlファイルを生成したい

# Lumos Advent Calendar 1日目🎉

横浜国立大学のテック系？ サークル **Lumos** に所属している @tomoyahiroe です。普段は Nuxt.js などを使用した個人開発をしています。
Lumos としてアドベントカレンダー回したい！と運営の子にお願いしたところ、Goサインが出たので10人前後の人数を集めて初参加させてもらいました！

## Lumos の紹介
基本誰でも入れるインカレサークルです！ メンバーの興味分野はめちゃくちゃ多種多様です。Web 開発・機械学習・ゲーム開発・モバイルアプリ開発・CTF などのセキュリティ分野・競技プログラミングなど...です。唯一やってる人がいなさそうなのは組み込み系ですかね(IoTとかやってみたい)。基本パソコン使ってやることはなんでもやれるサークルです。

普段の活動では、Discord上でもくもく会やったり、雑談しながら作業したり、自分がやってることの進捗を共有したりしています。また、大学祭では LT 会を開催していました。イベントとしては、鎌倉行ったり猿島行ったり、夏はバーベキューして冬はスキー行ったりとサークルっぽいウェイウェイなアクティビティもたくさんあります。

X (旧Twitter) のアカウント名は @lumos_program です。 

# 本編

Nuxt3 を使用していると、レンダリングモードを結構柔軟に選ぶことができます。
- CSR (Client Side Rendering)
- SSR (Server Side Rendering)
- SSG (Static Site Generation)
- Hybrid Rendering


[Nuxtのレンダリングに関するドキュメント](https://nuxt.com/docs/guide/concepts/rendering)

などなど。正直、ESRとかISRとかもうレンダリング方法色々ありすぎてまだ理解できていません。
しかし、現在開発しているサイトを Firebase Hosting する際に、クライアントサイドでレンダリングしたいと思いました。

## なぜクライアントサイドでレンダリングしたいのか

主に以下の理由で CSR を選びました。

- 開発途中の段階でもデプロイは継続的にし続けたいので、サーバに対するリクエスト回数を減らしたい(請求が怖い)
- まだコンテンツがそんなにないので正直初期読み込みの遅さは問題にならない

Firebase の料金形態をまだきちんと読んでいないのですが、「サーバへのリクエストは少ないほうが安く済むだろう」というだいぶ適当な考えでリクエスト回数が少なくて済む CSR を選択しています。

:::note info
Firebase のBlazeプラン(従量課金プラン)を調べたら、データ転送とストレージに対して課金されるので、リクエストごとに単一のページを返す SSG　の方がコストが抑えられそうです。
(今回は、CSRでindex.htmlを生成する方法についての記事なので許してほしい...)
:::

[Firebaseの料金プラン](https://firebase.google.com/pricing?hl=ja)

## CSR でエントリーポイントとして HTMLファイルを生成する

ホスティングサービスにデプロイするためにはビルドする必要があるわけですが、レンダリングモードやデプロイする環境よってビルドの方法が異なります。CSRでの方法とともにいくつか紹介します。
[Nuxtのデプロイに関するドキュメント](https://nuxt.com/docs/getting-started/deployment)

- Node.jsサーバにデプロイしたい

`nuxt build`コマンドで、エントリーポイントが `.output/server/index.mjs`になります。

- 静的ホスティングしたい

`nuxt.config.ts`で`ssr:true`にして `nuxt build`コマンドを実行すると、 `.output/public`に静的コンテンツが生成されるはず。

- Client Side Rendering したい

`nuxt.config.ts`で`ssr:false`にして、 `npx nuxi generate`コマンドを実行する。
[nuxi generateのドキュメント](https://nuxt.com/docs/api/commands/generate)

## 結論

`nuxt.config.ts`ファイルで `ssr: false`と設定したうえで、 `nuxi generate`コマンドを実行すれば、 `.output/public/index.html`が出現します。

# 雑談
 FirebaseのCLIがめちゃくちゃ便利でした。1コマンドで　github actions のワークフローまで作成していて感動しました。 CSR で ホスティングする際は、デプロイするコマンドを`nuxi generate`に書き換える必要がありますが、そんなもの大した手間ではなかったです。
 Lumos は初年度ということもあって、毎日投稿は厳しそうですが、これからもメンバーの記事が投稿されていくと思うのでお楽しみに〜
【8080を使ってるのは誰だ】error [http11protocol] エンドポイントを起動中のエラーです

こんにちは！tuna828です。
Windows上のEclipseでJBossを起動しようとしたところ、タイトルのエラーが出て起動できませんでした。。

## 8080使ってるよって言われても…
とりあえずほんまに使ってるのかを確認！
``` 
netstat -ano 
```
↓
```
プロトコル  ローカル アドレス      外部アドレス           状態            PID
...（省略）
TCP         0.0.0.0:8080           0.0.0.0:0              LISTENING       10192
...（省略）
```
使ってますね。

## 何をどうしたらポート開放してもらえるの？
PID（上の実行結果の一番右のやつ）からどのサービスがそのポートを使ってるのか特定できるようです。
なので、

①タスクマネージャーを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3501589/10ceb501-c2d4-4d81-2580-2bf44c2c9ad5.png)

②一番上の検索窓にPID（上の例なら10192）を入れて検索

→出てきたやつが犯人です！

## Apache二重起動してただけでした
私の場合はApacheが動いてました。
止まっていただいて問題ないので、検索結果のタスクの上を右クリック→タスクを終了。

EclipseからJBossを再度実行し、無事localhost:8080で起動を確認！

## 学び
PIDさんありがとう。
【Java】Stringがどのようにメモリに保存されるのか調べてみた

# はじめに
Stringはjava.lang.Stringクラスの不変オブジェクトで、ヒープ領域に保存されます。

** Stringオブジェクトの不変性については、こちらの記事をご覧ください。
[【Java】不変オブジェクトのStringと可変オブジェクトのStringBuilder](https://qiita.com/shibainuu/items/05340b4b0c35083f51d9)

# Stringオブジェクトの作り方
1. Stringリテラルを使用
2. newキーワードを使用

```
String s1 = "hello";
String s3 = new String("hello");
```

# Stringはヒープメモリに保存される
Javaのオブジェクトはヒープメモリに保存されるため、Stringも例外なくヒープメモリに保存されます。しかし、Stringオブジェクトの作成の仕方によって保存のされ方が異なります。

## 1. Stringリテラルを使用した場合
この方法で作成されたStringは、Stringコンスタントプール（String constant pool）に保存されます。Stringコンスタントプールとは、JVMによってStringが保存されるヒープ領域内の特別な場所です。

JVMはhelloというStringオブジェクトをStringコンスタントプールに保存します。
```
String s1 = "hello";
```
次に、helloという文字列が再び定義する。
```
String s2 = "hello";
```
JVMはStringコンスタントプールに同じhelloをもつStringオブジェクトが存在するか確認します。もし、存在する場合は新しいオブジェクトが作成されるのではなく、すでに存在するStringオブジェクトの参照（メモリアドレス）を変数s2に渡します。Stringの不変性により文字列が変更されないことが保証されているため、JVMは一つのhelloを使い回すことでメモリを節約します。

## 2. newキーワードを使用した場合
```
String s3 = new String("hello");
String s4 = new String("hello");
```
newキーワードを使用する場合は、JVMはStringプールに同じStringオブジェクトが存在していたとしても、新しいStringオブジェクトをヒープ領域内に作成します。

## 図示してみる
![スクリーンショット 2023-11-29 11.17.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576475/2afd3de5-51ab-cab1-330f-76756b84a8ca.png)

# 参考文献
* [Storage of String in Java - GeeksforGeeks](https://www.geeksforgeeks.org/storage-of-string-in-java/)
* [String Constant Pool in Java - GeeksforGeeks](https://www.geeksforgeeks.org/string-constant-pool-in-java/)
* [How and where does String literals in Java stored in the memory? - tutorialspoint](https://www.tutorialspoint.com/how-and-where-does-string-literals-in-java-stored-in-the-memory)
* [Guide to Java String Pool - Baeldung](https://www.baeldung.com/java-string-pool)
mindの研究 その42 - mindで俺cpuアセンブラを書く

# 概要
mindが、謎なので調べてみた。
練習問題、やってみた。

# 練習問題


俺cpuをアセンブルを実行する、インタープリタを書け

# 俺cpu アセンブラ仕様

|ニーモニック|	意味	|					stackの状態
|:--|:--|:--|
|%			|stack-1, stackの剰余を求める。	|1個減る		
|+			|stack-1, stackの加算を求める。	|1個減る		
|/			|stack-1, stackの除算を求める。	|1個減る		
|*			|stack-1, stackの乗算を求める。	|1個減る		
|-			|stack-1, stackの減算を求める。	|1個減る		
|=			|stack-1, stackの等しいを求める。|1個減る		
|>			|stack-1, stackの大を求める。	|1個減る		
|<			|stack-1, stackの小を求める。	|1個減る		
|1-255		|stackに整数を積む。			|	1個増える	
|set i		|変数iにstackを入れる。		|	1個減る		
|get i		|stackに、変数iの値を入れる。|	1個増える	
|out			|stackを数値で印字する。		|	1個減る		
|jz i		|stackが真ならiへ飛ぶ。		|	1個減る		
|jnz i		|stackが偽ならiへ飛ぶ。		|	1個減る		
|jmp i		|無条件でiへ飛ぶ。			|	変化無し	




# サンプルコード


```
コードは　40個の　文字列。
コード数は　変数。
スタック1は　変数。
スタック2は　変数。
aは　変数。
bは　変数。

アセンブラとは
　コード（コード数）に　入れ
　コード数に　１を　加えて　コード数に　入れる
。


行検索とは
　数１は　変数
　数2は　変数
　数1に　入れ
　数2に　5を　入れ
　数2を　返す
。


RUNとは
　文字列１は　文字列
　単語1は　文字列
　単語2は　文字列
　数１は　変数
　数２は　変数
　合否は　変数
　ｎは　変数
　スタック1に　0を　入れ
　スタック2に　0を　入れ
　aに　0を　入れ
　bに　0を　入れ
　ｎに　１を　入れ
　ここから
　　もし　ｎが　コード数より　大きい
　　ならば
　　　終り
　　つぎに
※　　コード（ｎ）を　一行表示する
　　コード（ｎ）を　文字列１に　入れ
　　文字列１から　単語切り出し　単語1に　入れ
　　文字列１から　単語切り出し　単語2に　入れ
※　　単語2を　表示する
　　もし　単語1が　「stop」に　等しい文字列
　　ならば
　　　打ち切り
　　つぎに

　　もし　単語1が　「*」に　等しい文字列
　　ならば
　　　スタック2と　スタック1を　掛けて　スタック1に　入れる
　　つぎに

　　もし　単語1が　「+」に　等しい文字列
　　ならば
　　　スタック2と　スタック1を　加えて　スタック1に　入れる
　　つぎに

　　もし　単語1が　「>」に　等しい文字列
　　ならば
　　　もし　スタック1より　スタック2が　大きい
　　　ならば
　　　　スタック1に　1を　入れる
　　　さもなければ
　　　　スタック1に　0を　入れる
　　　つぎに
　　つぎに

　　もし　単語1が　「drop」に　等しい文字列
　　ならば
　　　スタック1に　スタック2を　入れる
　　つぎに

　　もし　単語1が　「out」に　等しい文字列
　　ならば
　　　スタック1を　数値表示し　「 」を　表示し
　　つぎに

　　もし　単語1が　「ret」に　等しい文字列
　　ならば
　　　改行し
　　つぎに

　　もし　単語1が　「get」に　等しい文字列
　　ならば
　　　もし　単語2が　「a」に　等しい文字列
　　　ならば
　　　　スタック2に　スタック1を　入れ
　　　　スタック1に　aを　入れる
　　　つぎに
　　　もし　単語2が　「b」に　等しい文字列
　　　ならば
　　　　スタック2に　スタック1を　入れ
　　　　スタック1に　bを　入れる
　　　つぎに
　　つぎに

　　もし　単語1が　「set」に　等しい文字列
　　ならば
　　　もし　単語2が　「a」に　等しい文字列
　　　ならば
　　　　aに　スタック1を　入れる
　　　　スタック1に　スタック2を　入れ
　　　つぎに
　　　もし　単語2が　「b」に　等しい文字列
　　　ならば
　　　　ｂに　スタック1を　入れる
　　　　スタック1に　スタック2を　入れ
　　　つぎに
　　つぎに

　　もし　単語1が　「if」に　等しい文字列
　　ならば
　　　もし　スタック1より　0が　小さい
　　　ならば
　　　　単語2で　行検索し　ｎに　入れる
　　　つぎに
　　つぎに

　　単語１を　数値変換し　数１と　合否に　入れ
　　もし　合否が　真？
　　ならば
　　　スタック2に　スタック1を　入れ
　　　スタック1に　数1を　入れる
　　つぎに
　　ｎに　１を　加えて　ｎに　入れる
※　　スタック１を　数値表示　「,」を　表示し　スタック２を　数値表示　「,」を　表示し　aを　数値表示し　「,」を　表示し　bを　数値表示し　「,」を　表示し　ｎを　数値表示し　改行する
　繰り返す
。

メインとは
　コードを　クリアし
　1を　コード数に　入れ
　「1     」を　アセンブラし
　「set  a」を　アセンブラし
　「1     」を　アセンブラし
　「set  b」を　アセンブラし
　「L1    」を　アセンブラし
　「get  a」を　アセンブラし
　「get  b」を　アセンブラし
　「*     」を　アセンブラし
　「out   」を　アセンブラし
　「drop  」を　アセンブラし
　「get  a」を　アセンブラし
　「1     」を　アセンブラし
　「+     」を　アセンブラし
　「set  a」を　アセンブラし
　「10    」を　アセンブラし
　「get  a」を　アセンブラし
　「>     」を　アセンブラし
　「if  L1」を　アセンブラし
　「ret   」を　アセンブラし
　「get  b」を　アセンブラし
　「1     」を　アセンブラし
　「+     」を　アセンブラし
　「set  b」を　アセンブラし
　「1     」を　アセンブラし
　「set  a」を　アセンブラし
　「10    」を　アセンブラし
　「get  b」を　アセンブラし
　「>     」を　アセンブラし
　「if  L1」を　アセンブラし
　「stop  」を　アセンブラし　RUNする。






```
# 実行結果


```
>asm
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81

```

以上。
【Flutter】cupertino_iconsを使ってみた

`pubspec.yaml`に`cupertino_icons`が入ってたけど全然知らなかったから勉強。

https://api.flutter.dev/flutter/cupertino/CupertinoIcons-class.html

# cupertino_iconsとは
iOSのアイコン。
# 使い方
1. 使いたいアプリの`./lib/main.dart`に`import 'package:flutter/cupertino.dart';`を記述
2. 使うアイコンの名前を控える
    - [公式の説明ページ](https://api.flutter.dev/flutter/cupertino/CupertinoIcons-class.html)から探す。
    - ここでは`zzz`で試す
3. 使いたい箇所に下記のようなコードを記述
  `zzz`のところを控えていた名前に変えれば好きなやつに変えられる
   ``` dart
    CupertinoButton(
      child: Icon(
        CupertinoIcons.zzz,
      ),
      onPressed: () {},
    ),
   ```
# 感想
さっくりわかりやすかった。適宜つかいたい。
# 参考

https://api.flutter.dev/flutter/cupertino/CupertinoIcons-class.html

https://www.choge-blog.com/programming/fluttercupertino-icon-button/
【Flutter】パッケージ

[chatGPT に立ててもらったスケジュール](ceecf4a987d3f75b6d93)に準じてパッケージを勉強。
> - Day 3: Flutterパッケージの利用
>     - Flutterパッケージの探索と選択の方法を学ぶ
>     - 使用頻度の高いパッケージの導入と使用方法を学ぶ
# Flutterパッケージの探索と選択の方法
- [pub.dev](https://pub.dev/packages?q=sdk:flutter)からパッケージを探す
  - 上記公式がLIKE順に並んでいるので選択しやすそう。使う人が少ないと情報も少ないのでなるべく多いやつがいい。はず。
- 他にも参考になりそうなページ

  https://zenn.dev/namioto/articles/0ac39083ddda15

# パッケージの導入と使用方法
ランダムに英単語を生成する`english_words`を例に使ってみる
1. `/pubspec.yaml`に取り込むパッケージを記載
   ``` yaml
   dependencies:
         flutter:
           sdk: flutter
         cupertino_icons: ^0.1.2
         english_words: ^3.1.0 # 追加部分
   ```
2. `./lib/main.dart`にimportする
   ``` dart
   import 'package:english_words/english_words.dart';
   ```
3. ターミナルでコマンドを実行して依存関係として追加
   ``` 
   $ flutter pub add english_words
   ```
4. 使う場所に取り入れる
   ``` dart
   @override
    Widget build(BuildContext context) {
      final wordPair = WordPair.random(); // 追加部分
      return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Text(wordPair.asPascalCase), // 追加部分
        ),
    }
   ```
# 気になったところ
`cupertino_icons`が最初から入ってたけど何？と思ったのでそれも調べて使ってみた。
明日公開予定。
<!-- https://qiita.com/gi-ra-ffe/private/26fe17c1b0c10f7ef9e4 -->

`$ flutter packages get`でパッケージ取得できるよ〜ってあったけど、取得だけしてもだめだったみたいでつまずいた。初心者は大変。
（もしかして`pub add`と両方やる必要があった？よくわかんない…）

# 参考

https://flutter.ctrnost.com/tutorial/tutorial04/

https://nobushiueshi.com/flutter%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%92%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8B%E3%82%89%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9/
Amazon DynamoDBの耐障害性を考える

# はじめに
この記事はDevOps on AWS大全の一部です。
DevOps on AWS大全の一覧は[こちら](https://qiita.com/tech4anyone/items/b06f88035d27c6ef13b2)。

この記事ではAmazon DynamoDBを耐障害性の観点から超詳細解説しています。

具体的には以下流れで説明します。

- Amazon DynamoDBとは
- Amazon DynamoDB for Advance
- Amazon DynamoDBのスケーラビリティ
- Amazon DynamoDBのディザスタリカバリ

AWSの区分でいう「Level 200：トピックの入門知識を持っていることを前提に、ベストプラクティス、サービス機能を解説するレベル」の内容です。

# この記事を読んでほしい人
- Amazon DynamoDBを採用するときのベストプラクティスを説明できるようになりたい人
- Amazon DynamoDBの耐障害性に不安を感じている人
- AWS Certified DevOps Engineer Professionalを目指している人

# Amazon DynamoDBとは
Amazon DynamoDBは、高い可用性、耐障害性、およびスケーラビリティを備えた、完全にマネージドされたNoSQLデータベースサービスです。

DynamoDBはTalbeと呼ばれる単位で構成され、各テーブルが必ず1つのPrimary Keyを保持しています。

# Amazon DynamoDB for Advance
## ストリーミング
DynamoDB Streamsは、データベース内の変更をリアルタイムで捕捉する機能を提供します。
これにより、データの変更に対してトリガーを設定して、リアルタイムアプリケーションやイベント駆動型サービスを構築できます。

以前はDynamoDBのストリーミングはDynamoDB Streamsのみでしたが、最近になってKinesis Data Streamsとも連携できるようになりました。

![](https://storage.googleapis.com/zenn-user-upload/8587e97601de-20231129.png)

基本的にはDynamoDB StreamsはDynamoDBテーブルへの変更をトリガーにLambdaあるいはKCL Adapterに連携するために利用します。

一方、Kinesis Data Streamsはより広域な目的に利用できるため、DynamoDB Streamsで満たせない要件があるときにはKinesis Data Streamsの利用を検討しましょう。

最後に比較表をまとめたので参考にしてください。

|機能 | DynamoDB Streams | Kinesis Data Streams|
|--- | --- | ---|
|目的 | DynamoDB テーブルへの変更をキャプチャ | データストリームを処理|
|対応するデータ | DynamoDB テーブル | 任意のデータ|
|データの順序 | 保証される | 保証されない|
|設定の容易さ | 比較的容易 | 比較的大変|

# Amazon DynamoDBのスケーラビリティ
## キャパシティモード
DynamoDBは、オンデマンドモードとプロビジョニングモードという2つの異なるキャパシティモードを提供しています。

オンデマンドモードではトラフィックに応じて自動的にスケーリングされ、課金は使用量に基づいて行われます。
急激なトラフィック変動に対応し、柔軟な利用が可能です。

プロビジョニングモードでは事前に設定したスループット容量に基づいて課金され、定常的なワークロードに最適です。
トラフィックの変動が予測可能な場合に適しています。

## DynamoDB Accelerator
DynamoDB Accelerator（DAX）は、インメモリキャッシュを提供し、ミリ秒単位のレイテンシでデータへのアクセスを可能にします。

![](https://storage.googleapis.com/zenn-user-upload/a3b14423c03b-20231129.png)

DAXを使用することで、データベースへのアクセス速度が向上し、アプリケーションのパフォーマンスが向上します。

なお、AWSではインメモリキャッシュとしてAmazon ElastiCacheが提供されていますがDAXとElastiCacheはそれぞれ異なる使用ケースに適しています。

DAXはDynamoDBに特化しており、DynamoDBへのアクセスを高速化する際に理想的です。
一方、ElastiCacheはRedisやMemcachedを使用することで、汎用的なデータキャッシュソリューションとして広く利用されます。

# Amazon DynamoDBのディザスタリカバリ
## DynamoDB Global Table
DynamoDB Global Tablesは、複数のAWSリージョンにまたがるデータの自動的なレプリケーションをサポートします。
これにより、地域全体の障害に対処し、ユーザーエクスペリエンスを向上させることができます。

グローバルテーブルは、書き込み可能なプライマリリージョンと、読み取り専用のセカンダリリージョンを指定でき、地理的な近接性に応じてトラフィックを分散させることが可能です。

## Point-in-Time Recovery
Point-in-Time Recovery（PITR）は、誤って削除されたテーブルやアイテムを特定の時点まで復元できる機能を提供します。

データの損失を防ぎ、データの安全性を確保します。PITRを使用することで、意図しないデータの変更に対処できます。

## オンデマンドバックアップ
DynamoDBでは、オンデマンドバックアップを手動で作成できます。
これにより、データの安全性を確保し、災害復旧やデータ損失に備えるための手段となります。

# まとめ
この記事ではAmazon DynamoDBを耐障害性の観点から超詳細解説しました。

- Amazon DynamoDBとは
- Amazon DynamoDB for Advance
- Amazon DynamoDBのスケーラビリティ
- Amazon DynamoDBのディザスタリカバリ

次回はDBの耐障害性と絡めてAWS DMSを用いた耐障害性を考えます。
Amazon Kendra無料枠にご注意を。

2023年10月の20日ごろだったか、何かの拍子にAWSサイトでAmazon Kendraを知り、元CRMのプリセールスの私、もちろんFAQの知見もあるので「会社のために一発社内FAQサイトのデモでも見せてやるか。」と思ったのが間違いの始まり。平日昼間はPM業務をおこなっているので、技術検証も兼ねてあくまで趣味の範疇として自分のアカウントで開始。

ある日何気にAWS Cost Explorerを開いたら、あらまビックリ仰天。
![billing1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522326/f794f3c0-e591-c32c-2a5f-67ff0f63a7b1.png)
$600弱？この円安の時に...。

原因の追究はこの画面を下にスクロールするとサービス別のコストの確認ができます。
![billing2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522326/50604a79-4396-8741-16a3-26398a73f54a.png)
「Kendra」の左側が「-」になっていますが、デフォルトは「+」でリージョンが隠れた状態ですが、ここで犯人はKendraであることが確認できます。

老後資金取り崩さねば...。など考えつつも「750h分の無料枠があったはず」と思いサイドメニューの「無料利用枠」をクリックすると
![billing3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522326/1e1fb7ec-b9a5-4227-0115-3f2fe9fef862.png)
Kendraにフォーカスすると下図の通り「現在の使用量」が279hと表示されていて、すなわち750hに達していません。
![billing4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522326/e8a1e1ec-09fa-fb9c-1948-9645bf2a4f12.png)

ここで、「どういうこっちゃ？」と思いサポートへ問い合わせた結果がこちら。
![billing5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522326/39111dd7-b564-dfb9-d075-ad6d8cd443bd.png)

要約すると、「開始から30日間無料」なので、10月に使った分があり、現在の請求見積額は11月分なので、当たり前の話ですが無料枠の750hから10月利用分が差し引かれた時間に対する超過分を請求します。というものです。繰り返しですが当たり前の話です。
10月の無料枠が512.283h、11月が279.258hが無料とのことなので合計791.541h分と750h以上無料にしていただけるようですが、それでも337.10h＋消費税は請求されるようです。

Kendraの操作等は別の方の記事に委ねて、本件では割愛いたしますが、とにかく時間がかかる処理です。数百ページのpdfファイルなんかのIndex化だと一晩は平気でかかります。
確かに今思えばこのような学術的ファイルを複数Index化させましたが...。こんなに時間がかかるとは思わなかったし...。（完全にあとの祭り）
AWS Pricing calculatorで計算しようとも、「Amazon Kendra Developer Edition の時間 (1 か月あたり)」の入力を促されるのですが、そもそもこの時間が読めません。Enterprise Editionの場合は「接続されたドキュメントの合計数」と「1 日あたりの検索/クエリの総数」を入れることができるので、いくらかは読めるのかなとも思いますがEnterprise Editionには無料枠はありません。

Amazon Kendraの機能については操作も簡単で、半日程度でFAQサイトを作ることができました。
ですが、料金実績に伴うファイルサイズの要領が理解できるまでは、回答用のファイルサイズはできるだけ小さなもので始められることをおススメします。
【Unity】InputSystemで1つのキーボードで2人分の操作を実装する方法

# ■はじめに
UnityでInputSystemを利用して、キーボードをWASDと矢印キーで2人分使いたいなーと思いましたが、情報が少なかったので提供します

## ●結果
こんな感じで動かせます
![InputTest.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/612eae3c-1a5d-97ce-1499-0fe426c6e3ac.gif)


# ■方法
## ●InputAction
1. InputActionの**AllControllScheme**ってとこをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/e3a64ab4-3c11-e9c7-a131-d48db22dd352.png)

2. こんなのが出てくるので、図の[KeyboardLeft]と[KeyboardRight]のように、キーボード用のスキームを2つ作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/039af89e-b155-8a80-a7d7-ce9b690488c9.png)

3. 作ったスキーム用のActionをそれぞれ作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/ff9da486-e0dc-b2b8-e859-a6a71a9fdd55.png)

4. 作ったBindingにスキームを割り当てる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/d8587756-b8c8-60a1-4bd2-4a0a2fe79b45.png)



## ●コード
- `PlayerInput`コンポーネントをつけたプレハブを **`PlayerInput.Instantiate()`で生成する**
    - 生成時に先ほど作ったスキームを割り当てる

```InputManager.cs
    PlayerInput JoinProcess(string schemeName)
    {
        // 生成 (戻り値：PlayerInput)
        var player = PlayerInput.Instantiate(
            playerPrefab.gameObject, controlScheme: schemeName, pairWithDevice: Keyboard.current);
        
        player.defaultControlScheme = schemeName;
        player.gameObject.transform.SetParent(playerParent);
        
        return player;
    }
```

# ■動作確認
`Window/Analysis/InputDebugger`から、ユーザーに割り当てられたキーを確認できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/c8fb59a2-d86b-362d-ddfa-88143efe848d.png)


# ■さいごに
マルチプレイゲームをデバッグ時に1人でテストプレイするときに便利～！

## ●参考
https://forum.unity.com/threads/multiple-players-on-keyboard-new-input-system.725834/

[PlayerInput.Instantiate() / 公式リファレンス](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/api/UnityEngine.InputSystem.PlayerInput.html#UnityEngine_InputSystem_PlayerInput_Instantiate_UnityEngine_GameObject_System_Int32_System_String_System_Int32_UnityEngine_InputSystem_InputDevice_)
pygameをいじっていて、早めに理解したかったこと

chat GPTとかの回答をそのまま貼り付けることがあります。
作りながら気づいたことを随時追加していきます。
認識違いや追記などございましたら、ご指摘いただけると嬉しいです。

## surfaceとdisplay surfaceの違い
>pygameにおいて、'surface'と 'display surface'は異なるものですか?


はい、Pygameにおいて「surface」と「display surface」は異なる概念ですが、両者は関連しています。

Surface: Pygameでは、Surfaceは画像や図形を描画するための基本的なオブジェクトです。これは基本的にピクセルの2次元配列で、いかなるグラフィカルコンテンツもこのSurfaceに描画されます。あなたは多くのSurfaceオブジェクトを作成し、それらに異なるグラフィック（スプライト、テキスト、図形など）を描画することができます。

Display Surface: display surfaceは特別なSurfaceで、これはPygameウィンドウまたはスクリーン上に表示されるメインの画面です。pygame.display.set_mode()関数を使って初期化され、これにより画面のサイズと特性が設定されます。他のすべてのSurfaceオブジェクトは、このdisplay surfaceに描画されるか、あるいはdisplay surface自体に直接描画されます。

簡単に言うと、Surfaceはキャンバスのようなもので、display surfaceはそのキャンバスを展示するギャラリーの壁のようなものです。他のSurfaceオブジェクトはdisplay surfaceに描画されることで、最終的にユーザーのスクリーン上に表示されます。

## 色々やって、display surfaceに描きこむ→display 画面を更新してdisplay surfaceのと同期する、の流れ
文字であれば、
文字を描く
→その文字用のサイズの小さなsurfaceができる
→そのsurfaceをdisplay surfaceに描きこむ
→画面を更新して、現在のdisplay surfaceの内容に更新する

## 実際の描画の部分は、OSの機能を呼び出していて、場合によっては不思議な挙動はそっちが関係する
参照：https://github.com/pygame/pygame/issues/251#issuecomment-619552646

pygame.display.update(rect)を呼び出した後、色々あってSDL_UpdateWindowSurfaceRects関数を呼び出す
そこから、OSのグラフィック描写ライブラリが呼び出される

これによって生じた環境起因の分かりにくい挙動：
https://teratail.com/questions/6ibljaslxoffl6
API Gateway+LambdaからECS Fargateへの移行

# はじめに
[Globee Advent Calendar](https://qiita.com/advent-calendar/2023/globee)11日目の記事です。
abceedのサーバーサイドの開発及びインフラを担当している清水が、abceedが現在抱えている課題とその改善案についてご紹介します。

# abceedインフラの現状
abceedのバックエンドには、APIサーバーが稼働しており、abceedの大半の機能が実装されています。
このAPIサーバーのインフラは、下図の通り、AWS API GatewayからLambdaを実行するシンプルな構成となっています。

現在のインフラ構成（一部抜粋）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165221/90423fa4-2170-2c5b-4b9a-4398d65a907b.png)


# 解決したい問題
API GatewayとLambdaを組み合わせた構成は、フルマネージドのサーバーレス環境のため、コストを抑えて運用でき、規模が小さいWebサービスでは問題が起こりづらいですが、規模が大きくなるに従って、以下のような制約が次第に開発に影響を与える様になってきました。
- Lambdaクォーターが250MB上限であり、現状アプリケーションのサイズが上限近くになっているため、新しいレイヤーやライブラリの追加が容易にできない
- Lambda関数のタイムアウトなどの実行時間に関する制限があり、時間のかかる処理が行えない
    - SQSなどを使用して、別の仕組みを用意する必要があります
- サーバーレスフレームワークとして[Zappa](https://github.com/zappa/)を使用していることもあり、ファイルを直接ダウンロードするようなAPIを実現できない
    - ファイルをダウンロードしたい場合は、対象のファイルをS3に保存して、別途S3からダウンロードするフローになります
    - ファイルサイズが小さいことが想定される場合は、ファイルをBase64でエンコードしてテキストで返すことはできますが、レスポンスサイズが大きくなり、フロント側でデコード処理も必要になります

# 移行計画
これらの制約を解消するため、下図のようにAPIサーバーをECS Fargate環境に移行することを検討しています。

改善後のインフラ構成（一部抜粋）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165221/83334ef5-8505-bace-bd7d-efa8480a2292.png)

ECSは、用意したDockerコンテナでアプリケーションを実行できます。開発時のローカル環境ではDockerを使用しているため、ECSでAPIサーバーのインフラを構築することは難しくありませんでした。
ただ、現在abceedはMAU30万を超えるアクセスがあり、API Gateway+LambdaからECS Fargateに一気に切り替えるのはリスクが高すぎると考えました。
そこで、API Gateway+LambdaとECS Fargateを並行稼働させて、トラフィックの比率を徐々にECS Fargateに移していくことで、最小限のリスクで安全に移行させていきます。

上記を実現するために、API GatewayとECS Fargateにリクエストを分散させる必要があります。リクエストを分散させるために、最初ALBのルールでターゲットグループへの重みを振り分けることで実現しようと考えていました。

移行中のインフラ構成（ALBを使用したリクエスト分散）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165221/2336229c-b0f5-9425-d4fd-d52f6a335996.png)

ところが、この方法では以下の問題が発生し、実現できないことがわかりました。
- ターゲットグループにAPI Gatewayのステージを直接指定することができない
- VPNエンドポイント経由することで、API GatewayにPrivate IPを割り当て、ターゲットグループに指定することは可能ですが、その場合URLのパスの接頭にAPI Gatewayのステージ名を指定する必要です
    - 例） https://abceed.com/stage_name/hoge/fuga
    - 今回はAPI GatewayとECSで同じURLからアクセスして、AWS Cloud内でリクエストを分散させたいので、パスが変わってしまうこの方法は採用できません

そこで、Route53の加重ルーティングを使用して、リクエストを分散させることにしました。
加重ルーティングは、同じレコード名のレコードに対して、個々に指定した重量（重み）に応じた比率でリクエストを分散させてくれます。

[AWS Route53 加重ルーティング](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/routing-policy-weighted.html)

移行中のインフラ構成（Route53加重ルーティングによるリクエスト分散）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165221/e69d5e03-5544-e997-53b7-8877151c30fa.png)

これで、API GatewayとECS Fargateを並行稼働させつつ、徐々にリクエストの比重をECS Fargageに移していく環境が構築することができました。
最終的には、API Gatewayの重量を0、ECS Fargateの重量を100に設定して、完全にECS Fargateに移行し、API Gateway+Lambdaの環境を廃止することができます。

# 終わりに
API Gateway+LambdaからECS Fargate並行する準備としては、更に以下のことを検討する必要がありますが、今回は割愛します。
- 本番環境の負荷状況を想定した負荷試験
- ECS Fargate環境で稼働させた場合のインフラコストの試算

本記事で紹介した移行計画は、現在開発環境で検証を行っている段階で、本番環境へのリリースは近日行う予定です。abceedのインフラ及びAPIサーバーは、多くの課題を抱えているので、今後もインフラ環境を改善して開発スピードを上げ続けていきます。

株式会社Globeeでは、バックエンドエンジニアを積極的に募集しております。カジュアル面談にて弊社の「教育」にかける思いや「ものづくり」の考え方についてお話できればと思いますので、お気軽にご応募ください。
[採用サイト](https://globee.notion.site/Globee-d184eefc3561480292481299c64b04bc)
python の websocket 通信で proxy を通したい

本日(2023/11/29)で通用する方法です。
公式に描いてあります

```shell
pip install websocket-client
```

コード側:

```python
proxy_settings = {
    'proxy_type':'http',      # <- 忘れずに
    'http_proxy_host':'proxy.servername.com',   # <- http: とかいらない
    'http_proxy_port':8080
}

ws_app = websocket.WebSocketApp(
    ws_uri,
    on_message=on_message,
    on_error=on_error,
    on_close=on_close,
    on_open=on_open
)

ws_app.run_forever(**proxy_settings)

```

簡単！
[AWS Lambda]Line bot作成でつまづいた､zip内のフォルダ構成

# 概要
AWS Lambdaを使用したオウム返しline botをつくった。
するとオウム返しどころか、全く動作しなかった。
ログを見ていくと"lambda_function"が見つからないらしい。
zip直下に"lambda_function"などのファイルを置くことで解決した。

# 参考にしていた手順
https://qiita.com/i3no29/items/6329f0e114dad1b6a525

これの通りやったのに、できなかった

# エラーの内容
#### ① API endpointのURLを踏むと"Internal Server Error"
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1741372/9f7b5863-6c6e-8fe4-53db-5cc9b6501c07.png)
ここを踏むと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1741372/d5575c8b-25bf-6b33-4c27-aa2779dcaee1.png)
Internal Server Error

#### ② Messaging APIのWebhook URLにAPI endpointを設定しても"Internal Server Error"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1741372/2c88e97a-5634-1558-28c9-fe23509d14ef.png)


#### ③ Lambdaのログを見ると"No Module"
モニタリングタブ > "CloudWatch Logs"
Messaging APIのwebhook urlに設定して｢検証｣した時のログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1741372/7c4444db-b507-ffef-9d91-49b95dacc3f5.png)
"lambda_function"が見つからないエラー

# 解決まで
#### 参考
https://qiita.com/swallowgreen/items/3a13b7dc2eda377fd764
>zipファイル名は作成するlambda_function名と同じにする。
しないと、zipファイルを読み込みときに階層がずれてしまう。

これを読んだときに、｢階層ずれてるのかも？｣と推測

#### 階層を1つ上げてみた

```
//変更前
lmda-line.zip
    └ lmda-line
        ├ lambda_function.py
        └ その他のファイル
```

```
//変更後
lmda-line.zip
    ├ lambda_function.py
    └ その他のファイル
```

# 解決
#### webhook urlの検証
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1741372/dfabfd3b-7734-a5d6-9437-e97952938e3b.png)

#### オウム返しbot
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1741372/9b0919e6-ec39-4f89-dae4-9637f94661d3.png)
成功！

# 補足
API endpointを踏んだときのInternal Server Errorは変わらなかった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1741372/d5575c8b-25bf-6b33-4c27-aa2779dcaee1.png)
単にexceptになってるだけだと思う
【お試しBun🥟】インターン先のCIを肉まんに置き換える検証

## これは何？
:::note info
💡 JSのツールキット・ランタイムであるBunを使ったCIの速度向上の実環境での検証
:::

## 🥟 Bunとは

### なに
2023/5 デビューJavaScript向けツールキット・ランタイム

https://bun.sh/


### 何をしてくれる

- 例えば `bun install`（パッケージマネージャー）
- 例えば `bun test` （テストツール）
- 例えば `bun build` （ビルドツール）

### 何がすごい

圧倒的速さ（JavaScriptCoreというのを使ってるらしい）

▼ `install` を行った際の速度比較（公式サイトより）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/2172ce57-7c20-3366-b843-d0501370b372.png)

### どれぐらい早い

公式のベンチマークでは `npm i` の 25倍速いらしい

グローバルにキャッシュを持っていて、そこから依存を取ってきているから速い(`pnpm`に近い)

- pnpm：node mobule はシンボリックリンク
- bun：node mobule はキャッシュから取った実体

### なんで生まれた

webpack・esbuild・babel等のJS向けツールキットの乱立による依存問題・速度問題の解決
→ 思想としてはRome toolsに近い

## ✅ CIをBunに置き換えてみる

### やったこと

インターン先のプロジェクトにて、簡単なCIを組んで速度比較をしてみた

### 環境
- node：v18.16.0
- Bun：v1.0.11
- act

### actあんまり有名じゃない

GithubActionsをローカル（Docker上）でテストする環境

https://github.com/nektos/act#installation-through-package-managers

#### actのいいところ
- ローカルでテストできるので、GithubActionsがコケたメールにもう怯えなくていい✅
- Docker環境があれば簡単に使える
- コマンドがめちゃくちゃ簡単

#### 使い方
引数無しで実行すると`push`の動作が実行される（別のジョブ・オプションがあるので調べてみてね）
```zsh
act
```

### CIの内容

| 内容 | npm | bun |
| --- | --- | --- |
| チェックアウト | actions/checkout | actions/checkout |
| bunのインストール |  | npm i -g bun |
| 依存関係のインストール | npm i | bun i |
| Lintの実行 | npx eslint | bunx eslint |

※ bun が単体のJS・TSファイルのビルドしかサポートしてないため`build`は無し

### 結果

|  | npm | bun |
| --- | --- | --- |
| 1回目 | 29.07s | 19.22s |
| 2回目 | 29.92s | 19.52s |
| 3回目 | 29.60s | 19.50s |

→ 平均して34%高速になった（およそ10秒程度）

### install・lint だけ置き換えてみた

プロジェクトの`build-and-test` のまま `npm i・npx eslint` を `bun i・bunx eslint` に置き換えてみた

|  | npm | bun |
| --- | --- | --- |
| build-and-test | 42.25s | 37.37 |

→ 11%高速になった（およそ5秒程度）

## 💁まとめ

まだ完全に既存のツールを置き換えられるものではないが、性能は良いので部分的に使いつつアップデートを楽しみにする。
現状では`pnpm`が使いやすく、かつ高速な感じ。

## 📚参考資料置き場

### ▼Bun公式サイト
https://bun.sh/

### ▼Bun Bunlderに関する公式ブログ
https://bun.sh/blog/bun-bundler

### ▼actのリポジトリ
https://github.com/nektos/act#installation-through-package-managers

### ▼bun install はなぜ速いのか
https://zenn.dev/laiso/scraps/9a787a6888e228
[JavaScript] 複数の非同期処理の完了後に何かしたい場合

## どちらが先に終わるかわからない。
同時に始めた非同期通信はどちらかが先に終わるかわからない。
たとえば同じ関数内で非同期通信を同時に始めて、両方のレスポンスが終わったら何かしたい、というケースはよくあると思う。

その場合、自分は下記のように、responseがOKでなかったらreturnする処理をそれぞれの通信に書いていた。

```js
    if (!response.ok) {
      console.error("エラー:", response);
      return;
    }
    // これを非同期通信の数だけ書く
```

しかし、もっともパフォーマンスがよいのは、**Promise.all** かもしれない。

## Promise.all
```js
async function waitMultiple() {
  const promises = [
    wait(3), // 非同期A
    wait(5)  // 非同期B
  ];
  const messages = await Promise.all(promises);
  console.log(messages); // 必ず5秒後に呼ばれる。
}
waitMultiple(); 
```

通信をpromisesに配列としてまとめて、それを Promise.all()関数の引数に入れている。これで確実に二つが終わったあとの処理となる。

入れ子にもできる。しかしそれは**コールバック地獄の再来**である。
PromiseやAsyncを作ってくれた人たちに対する冒涜かもしれない。

つまり、書きかたによってはコード全体の見通しが悪くなるかもしれない。
構成は要検討です。

JSの非同期は難しすぎる。想像の3倍難しい。
SpringBootでgRPCアプリを作成し、Auth0などでJWT認証を行う

この記事は[SRA Advent Calendar 2023](https://qiita.com/advent-calendar/2023/sra)の1日目の記事です。

こんにちは！　関西事業部の佐々木です。

# SpringBootでgRPCアプリを
RESTアプリケーションなど、SpringBootを使ってWebアプリを作るのに慣れているJava技術者は少なくないはずです。
gRPCアプリを作る時にも慣れ親しんだSpringを使いたいと思うのは自然でしょう。
SpringBootを使ってgRPCアプリケーションを作るのは簡単で、LogNetのgrpc-spring-boot-starter([https://github.com/LogNet/grpc-spring-boot-starter] (https://github.com/LogNet/grpc-spring-boot-starter)) を依存関係に追加します。

gradleなら

```deuild.gradle
dependencies {
  implementation 'io.github.lognet:grpc-spring-boot-starter:5.1.5'
}
```    

と設定し、protoファイルから生成した XxxGrpc.XxxImplBase クラスを継承して実装するだけです。
これでSpringBootを使ってgRPCアプリケーションは作成できるのですが、その作ったgRPCアプリでAuth0を認可サーバとしてJWT検証を組み込みたい場合はどうすればいいでしょうか。

実はネットで検索するとそれなりに情報がヒットするのですが、意外とストレートに解説している記事は少ないです。上記のLogNetのgrpc-spring-boot-starterでは「10. Spring Security Integration」の項目で Basic, Bearer, Custom のスキーマについて必要な依存ライブラリが記載させています。
gRPCのAuth0によるJWT検証ではメタデータに「Authorization」というキーに「Bearer ＜Auth0発行のJWT＞」という値を設定してリクエストを行いますので、これらのうち「Bearer」が該当します。
そこでBearerに必要な依存ライブラリを見ると

* org.springframework.security:spring-security-config
* org.springframework.security:spring-security-oauth2-jose
* org.springframework.security:spring-security-oauth2-resource-server

と書かれています。
これら３つのライブラリを馬鹿正直に設定してもいいのですが、私のような面倒くさがりは

* org.springframework.boot:spring-boot-starter-oauth2-resource-server

の一つの設定で済ますのが楽でしょう。
（この設定で上記3つのライブラリも追加されます）

これらのライブラリが依存関係に追加されると、Spring Securityの検証処理が実行されます。
（なのでこのままでは呼び出してもUNAUTHENTICATEDエラーが返ってきます）

次に必要な設定はJWKSを取得するためのサーバ（認可サーバ）としてAuth0のURLをapplication.ymlに設定します。

```application.yml
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://osakeganomitai.jp.auth0.com/
```

spring.security.oauth2.resoruceserver.jwt.issuer-uriがAuth0のサーバを設定するキーです。
最後のスラッシュ「/」を忘れないようにしてください。

アプリ側としては以上で終わりです。
アプリケーションを起動し、gRPCメタデータにJWTをセットしてリクエストを実行してみてください。
UNAUTHENTICATEDエラーにならなければ成功です。

### SpringBootTestはどうするか

普通のメソッド単位の単体テストなら関係ないですが、`@SpringBootTest`によるテストの場合、実際にこのアプリケーションが起動しますので、JWT検証の機能が動きます。
単体テストコードの中でAuth0にアクセスしJWTを取得すれば問題ないですが、色々と面倒です。
こういった場合、`src/main/resources` でなく `src/test/resources` の下にapplication.ymlを作成し、

```application.yml
grpc:
  security:
    auth:
      enabled: false
```

と設定することでテスト実行時のみJWT検証を無効化できます。

以上、参考になれば幸いです。
【JSTQB ALTM】シラバスまとめ（第5章）

<iframe src="https://www.slideshare.net/slideshow/embed_code/key/z521QKOj5hRa4?hostedIn=slideshare&page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

:::note warn
筆者（私）独自の解釈・理解をまとめた資料のため、誤りがある可能性があることにご留意ください
:::
PostgreSQLにおける行ロック

https://www.postgresql.org/docs/current/explicit-locking.html

https://www.postgresql.jp/docs/9.4/explicit-locking.html


各行ロックに対するキーであるカラムと非キーであるカラムにおけるロックの種類（共有ロック or 排他ロック）
| name | key | not key |
| :-: | :-: | :-: |
| FOR UPDATE | EXCLUSIVE LOCK | EXCLUSIVE LOCK |
| FOR NO KEY UPDATE | × | EXCLUSIVE LOCK |
| FOR SHARE | SHARE LOCK | SHARE LOCK |
| FOR KEY SHARE | SHARE LOCK | × |
【Python/Git】pycacheをgit ignoreする

Pythonのパッケージを実行すると、各パッケージに`__pycache__`フォルダーが自動生成されますよね。
ソース管理上邪魔ですよね。
こうすればいいです。
```:.gitignore
**/__pycache__/**
```
こうすることにより、全ディレクトリにある`__pycache__`ディレクトリが全てignoreされます。

:::note
この記事を読んでいる方は、次の記事も読んでいるのかもしれません
* [とりあえず周りと仕事ができるGitHub入門](https://qiita.com/konbraphat51/items/8d4907bf02cfff518462)
:::
【AWS re:Invent 2023】Amazon ElastiCache Serverless がGAになったことに関する考察

# これは何？

AWS re:Invent 2023のMonday Night Liveにて、Amazon ElastiCache ServerlessのGA(一般利用開始)が発表されたので、その内容と考察してみました。

# 概要

https://aws.amazon.com/jp/blogs/aws/amazon-elasticache-serverless-for-redis-and-memcached-now-generally-available/

### ElastiCache Serverlessとは

・ユーザーが 1 分以内にキャッシュを作成し、アプリケーションのトラフィック パターンに基づいて容量を即座に拡張できる新しいサーバーレス オプションです。

・現在ElastiCacheで利用できるデータベースストアである、Redis および Memcached のどちらにも互換性があります。

・Serverlessと名がついてることから分かる通り、「ワークロードのアクセスパターンの変化に合わせた即時スケーリング」「複数のアベイラビリティーゾーンにわたる自動レプリケート」を備えています。

・すべてのワークロードに対する最大 99.99%のSLAが保証されます。



コンソール画面では反映済み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/9cd2cdee-3686-0f82-65ed-cbbbb0b3f150.png)



# 良い点と今後の改善を期待する点

## 良い点
・　非常にシンプル。　インスタンスのタイプを選んだり、帯域幅の注意しつつノードのTPS制限を気にしなくてよい。

・ユーザーが速やかに新規でCacheサービスを構築できる（1分ほど）。
・デフォルトでMulti-AZ構成であり、HAの設定を気にする必要がない。構成変更による追加課金の心配がない。
・Auto Scailing Groupが無くなった。

・エンジンバージョンのアップグレード
自動かつ透過的に適用されますが、アプリケーションへの影響はありません。
・CloudWatchによるメトリクス監視が可能
メモリ使用率 (BytesUsedForCache), CPU使用率 (ElastiCacheProcessingUnits)やその他のキャッシュメトリクスが利用できます。
・セキュリティ、コンプライアンス
VPC内からのアクセスが可能で、IAMを利用したデータプレーンへのアクセスが可能、KMSを利用した保存時・転送時の暗号化もサポートしています。

## 今後の改善を期待する点

### VPCを必要とする
残念ながら VPC が必要です。そのため、例えばLambdaを VPC の外で実行している場合は、ElastiCache ServerlessにアクセスするためにLambdaを VPC に配置する必要があります。

### スケーリングパフォーマンスが現実的なユースケースと適合しない。
ローンチ時点でのベンチマークはrpsが上昇した際に、10分ごとに容量を 2倍にすることができることを示しています。 Serverful elasticache を使用すると、より多くの容量をプロアクティブにプロビジョニングするために使用できる自動スケーリング ルールを使用できます。つまり、現状のオーバープロビジョニングなEllastiCacheから劇的に改善されているとは言えないのでは？という感想を持っています。
またこの点に関して、考慮しておかなくてはならないのは、実際のトラフィックにおいて、スパイクの負荷というものは2倍であるとは限らない可能性があることです。 実際のユースケースでは当然、10倍になる可能性だってあります。その場合、スケールアップには最大40分かかってしまう可能性があります。 
その頃にはスパイクって終わってるかもしれないですよね？。。。

### コストパフォーマンスが良くない
前提として、サーバレスなので従量課金制となりますが料金設定がちょっとイケてない印象を受けます。
最低料金は＄90（約￥13,500）ですが、ElastiCacheServerlessに保存されたデータに +αの転送量を支払います。
データ転送量は1GBあたり34セント。つまり、最低料金は$90だが、$90+月/GB+34セント/GBのデータ転送量を支払うことになります。
尚、ストレージは最も近いGB に切り上げられます。

https://aws.amazon.com/jp/elasticache/pricing/#Serverless


## まとめ

AWSがElastiCache Serverless のGAをリリースしたことは素晴らしいことだと思います。
ElastiCacheは性質上、スパイクに備える必要があり、サーバフルインスタンスだと、オーバープロビジョニング必須のサービスであるからです。
さらに、スケールアップ、ダウンにおいて、ダウンタイムが必須であり、メンテナンスに課題が多いサービスでした。

今回のGAにより、大きな一歩を踏み出したと言えます。

ただ、前述の通り、課題が多く残り、まだサーバレスの恩恵を受けるサービスとは言い切れない部分が多々あります。

今後のアップデートに期待したいです。
じゃんけんゲーム python

# Python初心者が最初に作るゲーム
python を学習してモチベーションが上がらなくなった人向けにコードをかいてみました  
ちょっとpythonを学んだけど次何つくっていいかわからない人向けです  
  
エラー処理もfor文も使っていません  
最低限の命令文と条件分岐だけで書いたのでツッコミどころ満載ですが逆に初学者がこれより立派なコードが書けたら熟達者は褒めてあげてください。  
今回、極力シンプルに関数も使わず書きました  

最後の end=input('お疲れ様でした')　の一文はプロンプトのクローズ防止対策です
```python:janken.py
import random 
bot_data = random.randint(1,3)
print ("じゃんけんをしましょう")
print ("1が’ぐー’、2が’チョキ’、3が’パー’")
watasi = input ('何を出しますか？')
watasi_data = int(watasi)
kekka = bot_data*10+watasi_data
print('結果')
if kekka ==11 or kekka ==22 or kekka == 33:
    print ('あいこです')
if kekka == 12 :
    print ("コンピューターは’ぐー’")
    print("コンピューターの勝ち")
if kekka == 13 :
    print ("コンピューターは’ぐー’")
    print("あなたの勝ち")

if kekka == 23 :
    print ("コンピューターは’チョキ’")
    print("コンピューターの勝ち")
if kekka == 21 :
    print ("コンピューターは’チョキ’")
    print("あなたの勝ち")

if kekka == 31 :
    print ("コンピューターは’パー’")
    print("コンピューターの勝ち")
if kekka == 32:
    print ("コンピューターは’パー’")
    print("あなたの勝ち")

end=input("お疲れ様でした")


```
React Native(Android)でキーボードの上に表示されるinputの位置がズレる問題

# 前提
- React Nativeで開発しているAndroidアプリ
- キーボードの上に表示されるinput(いわゆるチャットアプリ的なUI)を作りたい

↓いわゆるチャットアプリ的なUIとはこういうもの
![Screenshot_1701216944.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268579/27059d79-4044-c4de-ac3d-224e89890e71.png)

# 問題

``` InputScreen.tsx
return (
    <SafeAreaView
      style={{ flex: 1 }}
    >
        <KeyboardAvoidingView
          behavior={Platform.OS === "ios" ? "padding" : "height"}
          style={{ flex: 1 }}
          keyboardVerticalOffset={headerHeight}
        >
          <TextInput
            value={value}
          />
        </KeyboardAvoidingView>
    </SafeAreaView>
);
```

↑こんな感じで`KeyboardAvoidingView`を使うと`keyboardVerticalOffset`を設定しても、キーボードを表示したときにinputがキーボードの裏に隠れてしまう。

↓こんな感じ
![Screenshot_1701217802.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268579/b0a35a74-fe50-3586-5bd3-005660cac1a4.png)


ちなみにiOSではちゃんと機能する。
![Simulator Screenshot - iPhone 15 - 2023-11-29 at 09.16.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268579/2228b8fd-2014-3d5d-0ddb-c80724d8d712.png)


# 解決方法
**Androidでは`KeyboardAvoidingView`を使わない**が正解

[React Nativeの公式では`KeyboardAvoidingView`の使用が推奨されている](https://reactnative.dev/docs/keyboardavoidingview)し、ネット上で他の情報を調べても大体`KeyboardAvoidingView`を使う前提の記事が多い。

キーボードに対してinputの位置がずれてしまうという問題に対しても「
`KeyboardAvoidingView`の`behavior`プロパティを適切に設定したり、`keyboardVerticalOffset`プロパティに適切な値を入れよ」という情報しかなかった。

しかし、実際にはAndroidは`KeyboardAvoidingView`を使わなくても、勝手にキーボード分だけ画面の高さを縮小してくれるので、`KeyboardAvoidingView`は必要なかった。

実際のコードはこんな感じ↓

``` InputScreen.tsx
return (
    <SafeAreaView
      style={{ flex: 1 }}
    >
      {Platform.OS === "ios" ? (
        <KeyboardAvoidingView
          behavior="padding"
          style={{ flex: 1 }}
          keyboardVerticalOffset={headerHeight}
        >
          <TextInput
            value={value}
          />
        </KeyboardAvoidingView>
      ) : (
        <TextInput
            value={value}
          />
      )}
    </SafeAreaView>
);
```

`Platform.OS`でiOSかAndroidかで`KeyboardAvoidingView`を使うかを切り替えている。


# おわりに
ちなみにこの問題で2週間近く溶かした個人開発アプリは↓です
[【個人開発】「後で」返事ができる文通チャットアプリ「レイター」を作った話：技術編](https://qiita.com/0ba/items/2dc7eb1e7f16289ae739)

XやThreadsでも個人開発について発信しています
→https://twitter.com/ObataGenta
→https://www.threads.net/@g.0bt
WinMergeで大文字小文字の区別をするかどうかを切替

# やり方（設定画面経由）

『編集』 → 『設定』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f366ac35-09bb-c14b-9415-8388fe94d37d.png)

『比較』 → 『一般』 → 『大文字と小文字を区別しない』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/168cd764-3fb5-3ee2-416a-5034de439cab.png)

# やり方（ツールバー経由）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/43557923-7aae-26a4-4aea-dba845745407.png)

# 参考サイトさん

https://arkgame.com/2022/02/22/post-305126/

# バージョン

Microsoft Windows [Version 10.0.19045.3693]
Win Merge 2.16.28.4
eclips+MercurialでUnexpectedServerTerminationExceptionが出て困った時の対処録

eclips開発環境の作成中に以下のようなエラーが出た。
```エラー文（意訳）
UnexpectedServerTerminationException : Server process terminated unexpectedly with exitvalue eclips
```

eclipsをeclipsc.exeで起動してエラーを見たところ、
```エラー文（抜粋）
LookupError: unknown encoding: windows-31j.
```

というエラーが出ていたので、エラー文でググってみると
> 注意事項
主にWindowsでの話になりますが、Mercurialの操作を行うと「abort: unknown encoding: Windows-31J」というエラーが出ます。この手のエンコード問題はまともに取り合うとややこしいので、リスト2のように環境変数HGENCODINGを設定してやり過ごしています。
リスト2　環境変数:HGENCODINGの設定例
HGENCODING=utf-8

https://gihyo.jp/dev/serial/01/android_studio/0031

とのことだったので環境変数を見てみると、「HGENCODING=cp932」になっていたので、utf-8に変えたところ動いた。
やった～～～！