OmniAICreator/Qiita-1.07M huggingface dataset:
Windows環境にOpenCV導入自分用メモ

「Pythonで始めるOpenCV４　プログラミング」のインストール手順を参照。

１.Anaccondaのインストール
https://www.anaconda.com/products/individual
このページの下の方にあるAnaconda Installersの
Windows のリンクから６４か３２を選んでダウンロード。64-Bit Graphical Installer (510 MB)

２.ダウンロードしたらインストーラーを起動してインストールする。
　next → I agree → Just Me を選択して　Next →　インストール先を指定して Next
　→　Pythonをシステムのプライマリとして扱いたい場合は
　　　　　「Register Anaconda as my default Python 3.7」 にチェックしてInstall
　→　Next →　Microsoft Visual Studio Code は インストール不要なら「skip」 →　「finish」
　　
３. OpenCV インストール
　　スタートメニューから「Anaconda Prompt」

```
　　pip install opencv-python
```
　　でpythonをインストール
　　上記のコマンドでインストールできない場合は、自分の環境に合ったwhlファイルを入手する。
　　https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv
　　の「opencv_python‑4.5.4‑cp37‑cp37m‑win_amd64.whl」など
　　今回はcontribを使うので、そのバージョンをダウンロード。

※以下はエラーだった手順も記載してます。
コマンドプロンプトからScriptフォルダに移動
(base) C:\Users\○○○\anaconda3\Scripts>python -m pip install C:\Users\○○○\Downloads\opencv_python-4.1.2+contrib-cp35-cp35m-win_amd64.whl
でインストールしようとするとエラー
（ダウンロードしたファイルopencv_python-4.1.2+contrib-cp35-cp35m-win_amd64.whl）
ERROR: opencv_python-4.1.2+contrib-cp35-cp35m-win_amd64.whl is not a supported wheel on this platform.
が出る。

pip install python_contrib_python
でインストールしてみる
→同じエラーがでて失敗

pip install --upgrade pip
でpipのアップグレードしてみる

アクセス拒否のエラーがでる

pip install --upgrade pip --user　で試してみる。
ウイルスチェックが起動するが，インストール完了。

もう一度
pip install python_contrib_python C:\Users\○○○\Downloads\opencv_python-4.1.2+contrib-cp35-cp35m-win_amd64.whl
を試すが，同じエラー（サポートしてない）


pip install opencv-contrib-python
でcontribをインストール
インストール成功
AlmaLinux8にImageMagick-develを導入する際のメモ


## メモ
AlmaLinuxにImageMagick、ImageMagick-develをインストールしないといけなくなったのでメモ。
使用目的としてはPHPでImageMagickを使いたい。

必要パッケージのダウンロード

```sh:
wget https://repo.almalinux.org/almalinux/8/devel/x86_64/os/Packages/jasper-2.0.14-5.el8.x86_64.rpm
wget https://rpmfind.net/linux/centos/8-stream/AppStream/x86_64/os/Packages/jasper-libs-2.0.14-5.el8.x86_64.rpm
wget ftp://ftp.pbone.net/mirror/ftp.centos.org/8.5.2111/PowerTools/x86_64/os/Packages/jasper-devel-2.0.14-5.el8.x86_64.rpm

rpm -ivh jasper-libs-2.0.14-5.el8.x86_64.rpm  jasper-2.0.14-5.el8.x86_64.rpm  jasper-devel-2.0.14-5.el8.x86_64.rpm
または、

rpm -Uvh jasper-libs-2.0.14-5.el8.x86_64.rpm  jasper-2.0.14-5.el8.x86_64.rpm  jasper-devel-2.0.14-5.el8.x86_64.rpm
```

ImageMagickインストールに必要な依存パッケージを先に入れてから、ImageMagick、ImageMagick-develを入れていく。

```sh:
dnf install OpenEXR-devel jasper-devel ghostscript-devel lcms2-devel
dnf install ImageMagick ImageMagick-devel
```

PHPから、ImageMagickを使用したいので関連するものを入れていく。
pecl経由で連携させる。

```sh:
dnf install php-pear php-devel
pecl install imagick
```

`pecl install imagick` 実行時に、
`Please provide the prefix of ImageMagick installation [autodetect] :`
と聞かれるのでエンターを押す。ビルドが始まるので、`Build process completed successfully`と出れば成功。
`You should add "extension=imagick.so" to php.ini` ともでてるのでphp.iniに下記を追記。

```ini:
# vim /etc/php.iniの末尾に追記
[PECL]
extension=imagick.so
```

他、POST経由でImageMagickを使用する際は、サイズを増やしておくことを忘れない。

```ini:
upload_max_filesize = 20M
post_max_size = 20M
```

Apacheをgrecefulで再起動させ、`php -m `で読み込まれているモジュール一覧に、imagickがあれば読み込まれていることになる。

```sh:
httpd -k graceful
php -m 
```

```sh:
php -a
echo ini_get('post_max_size');
20M
```
[20210608雑談]現在のスキルセットについて書いてみた。

今回は、IT業界に入って約２年くらい経つのと、転職活動することになったので**実務経験で身に着けたスキル**について書いてみました。


##**開発言語**
Java,javascript(ES6),Typescript,,Node.js,jsp,Html,

## **データベース(DB)**
oracle,MySQL,AWS(DynamoDB)

##**フレームワーク**
JSF,jQuery,struts,React.js

## **開発環境(ツール等)**
xml,
SQLデベロッパー,
A5:SQL Mk-2,
Git,
teraterm,
eclipse,
SVN,
Visual stadio code,
Git,
souceTree,
Jira software(Confluence),
AWS (Elastic Load Balancing,S3,Codecommit,EC2),
windows10,
Zoom,
office365,
remoteview

##プログラミング言語使用年数
**・Javaは9か月ほど
・Javascriptは1.6年
・Typescriptは8か月
・Node.jsは8か月
・React.jsは8か月
・SQL(oracle,MySQL)は9か月
・JSFは9か月
・jQueryは9か月
・strutsは9か月
・Linuxは8か月
・gitは1.6年 
etc...**

##業務詳細
フロントエンド側をメインに実装、改修したり、たまにバックエンドの実装、改修してました。
あとは、詳細設計から総合テストまで一通り経験して、リリース作業やリリース後の調査（エラー、バグ）経験しました。

入る現場がたいてい未経験のプログラミング言語なので、最初は苦戦しましたが数か月後は読めるようになったり、実装できるようになったり、改修できるようになったりして意外とできるもんだなという印象です。（ただ知れば知るほど奥深いなと思っています。。。）


##今後
"今後のやりたいこと"としては、バックエンドを多めに経験積んでいきたいなと思っています。
最近だとGo言語学習してますが、PythonなどのWeb系の言語も使えるようにしたいです。(何かポートフォリオ作らねば...汗)

自分のキャリアを見ていると結構、**フロントエンドとバックエンドが中途半端な気がするので、
バックエンド重点的スキルをつけるみたいなイメージでキャリア形成したい**ですね。。。
Eclipse+Forgeでマイクラのmod開発～目次

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191672/cdde73c8-29c8-973a-b8ed-101112211bba.png)

マイクラのmod開発シリーズもだいぶ増えてきたので目次の記事を作りました。「そうだ、modを作ろう」と一念発起してからこの記事執筆時点で1カ月強。JavaやIDEに触れること自体数年ぶりでしたがリハビリも経てだいぶ色々遊べるようになってきました。。
今後もここの記事を充実させていこうと思っていますが、この記事を参考にして一人でも多くの人が面白いmodを作り、さらにマイクラのエコシステムが盛り上がっていくことを祈ってます。

---

環境構築編。Eclipse前提ですがEclipseからマイクラの起動、デバッグができるようにするところまでの手順を書いています。

https://qiita.com/kawamune/items/ba0d18ade13d98d817d9

---

modを作って動かすところまで。中身は空っぽのmodですが一応自作modを作って動いているのを確認するところまでを最低限の作業で実施する方法を書いています。

https://qiita.com/kawamune/items/cc31848c070bcbb3e8f4

---

イベントハンドリングの方法を書いています。イベントハンドリングに重要なForgeにおける二つのイベントバスや、イベントバスにおけるポリモーフィズムの解説、サンプルのありかなどを解説。

https://qiita.com/kawamune/items/b6aac165885f3ee70291

---

マイクラのゲーム中で使えるコマンドの実装方法を書いています。マイクラのコマンドの構造は結構ややこしい（？）のでサンプルも一杯乗せてどのように構造を定義していくのかを解説。最後にちょっと愚痴も書いてますｗ

https://qiita.com/kawamune/items/452b0ef3f580747e94b5

---

アイテムの追加についての記事。まだ何の機能もないシンプルなアイテムを追加しているだけです。今後、この記事に書いた内容をベースに身に着けられるようにしたりいろいろな機能を追加していきたいと思います。

https://qiita.com/kawamune/items/9a58fa6a3e0752ac55f5
ADX2のツールからobbを作る

#はじめに
Oculusのアプリで、極端に大きなapkだと分割してストアに上げないといけないのですが、
ADX2のデータは、Unityの標準のobb（APKの拡張ファイル）ではストリーム再生ができないので、
Android Studioにあるjobbなるツールでまとめる必要がある。

このobbを作成し、さらにOculusの実機へpushするのが手間なので、スクリプト１回実行して済ませるようなものを作ってみました。

#この記事の対象
- ADX2でjobbでobbを作りたい人
- ADX2のスクリプトで外部プロセスを呼びたい人

#環境
Craft 3.45.00

#jobb

jobbは以下

https://developer.android.com/studio/command-line/jobb?hl=ja

これを使えばよいのですが、バグがあるっぽく別途

https://github.com/idmgroup/android-sdk-fat32lib

のfat32を使う必要がある。

#adb
adbもAndroid Studioに入っている。

Android studio
JDK
などインストールや、
adb,jobbのパスなど環境変数の設定などが必要かも。

#スクリプト
subprocessで２つ実行しています。
失敗したときの処理があまりないので、変な時は手動で中断してください。

パスやデバイスIDなども適宜書き換えてください。

``` MDS_MakeObb.py
# --Description:[tatmos][Build]adx2フォルダをObbファイルにまとめる
import sys
import os
import cri.atomcraft.debug as acdebug
import subprocess
import cri.atomcraft.view as acview

# まとめるフォルダ
srcPath = "C:/MyDearest/github/MDSoundPreview/Assets/StreamingAssets/adx2/"
# 出力フォルダ
outPath = "C:/MyDearest/"
# 出力するObbファイル名
outputFileName = "ADX2.obb"
# アプリのビルドバージョン
appBuildVersion = 1
#　アプリのPackageName
appPackageName = "com.MyDearest.MDSoundPreview"

# 転送先のデバイスID : adb devicesなどで調べる
deviceId = "XXXXXXXXXXXXXX"

if not os.path.exists(srcPath):
	acdebug.log("srcPath がありません。")
	sys.exit()

# jobb
cmd1 = "jobb.bat"
cmd2 = "-d \"{0}\"".format(srcPath);
cmd3 = "-o \"{0}\"".format(outPath + outputFileName);
cmd4 = "-pn \"{0}\"".format(appPackageName);
cmd5 = "-pv {0}".format(appBuildVersion);

acdebug.log([cmd1 + " " + cmd2 + " " + cmd3 + " " + cmd4 + " " + cmd5])
message = subprocess.check_output(cmd1 + " " + cmd2 + " " + cmd3 + " " + cmd4 + " " + cmd5)
acdebug.log(message.decode().strip())

message = "続いて転送します"
button_name_list = ["続ける", "キャンセル"]
result = acview.show_dialog(message, button_name_list)
if result [ "data" ][ "button_name" ] == "キャンセル" or result [ "data" ][ "button_index" ] == "-1":
	sys.exit()

# push
cmd1 = "adb"
cmd2 = "-s {0}".format(deviceId);
cmd3 = "push {0}".format(outPath + outputFileName);
cmd4 = "/storage/emulated/0/Android/obb/{0}/{1}".format(appPackageName,outputFileName);

acdebug.log([cmd1 + " " + cmd2 + " " + cmd3 + " " + cmd4])
message = subprocess.check_output(cmd1 + " " + cmd2 + " " + cmd3 + " " + cmd4)
message2 = message.decode().strip().split("\r\n")
for m in message2:
	if not str(m).startswith("["):
		acdebug.log(m)
```

#ログ抑制
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/f2040ddd-895e-ea8e-0836-a49ef8f22596.png)

check_outputで帰ってくるメッセージに進捗的なものが含まれていて、
これをログ出力するとADX2が重くなるので、分割しつつ、不要な進捗は表示しないようにしています。

``` .py
check_output
message2 = message.decode().strip().split("\r\n")
for m in message2:
	if not str(m).startswith("["):
		acdebug.log(m)
```

# おわりに
adbコマンドも叩けるので、少し応用すれば、
サウンドデータ差し替えて、転送して、実行して、実機で確認
とかがなるべく手間なくできる環境が作れるかと思います。
アジャイル開発の考え方

#【アジャイル開発の考え方】

ユーザーが求める価値あるサービスを迅速に作り続けるために必要。
　→ サービスを良くしていくためにユーザーと対話して、変化に対応させていくことが必要になる。

チーム開発をおこなううえで、チーム全員で達成したい目標を明確にして、理解することが必要。
このような考え方のもとで、ビジネスに臨機応変に対応してくことが可能になる。

**※自分用の備忘録になります。**
**　ご指摘などありましたら、コメントいただけますと嬉しいです。**

##アジャイル開発とは。

**開発中に発生する様々な状況の変化に対応しながら開発を進めていく手法**

　※ アジャイル：素早い

チームで要件定義→設計→開発→テスト→運用を1つの機能単位として、小さいサイクルで繰り返す。
　→　個々の機能の開発が独立して完結し、仕様変更の発生に強く、リスクを最小化させることができる。
　→　ソフトウェアを開発する期間の短縮が期待できる。
　→　従来のウォーターフォール開発などよりも素早く開発ができる。

##アジャイル開発の根底にあるもの。
 
###アジャイルソフトウェア開発宣言

>私たちは、ソフトウェア開発の実践
あるいは実践を手助けをする活動を通じて、
よりよい開発方法を見つけだそうとしている。
この活動を通して、私たちは以下の価値に至った。

>プロセスやツールよりも個人と対話を、
包括的なドキュメントよりも動くソフトウェアを、
契約交渉よりも顧客との協調を、
計画に従うことよりも変化への対応を、

>価値とする。すなわち、左記のことがらに価値があることを
認めながらも、私たちは右記のことがらにより価値をおく。


>Kent Beck　Mike Beedle　Arie van Bennekum
Alistair Cockburn　Ward Cunningham　Martin Fowler
James Grenning　Jim Highsmith　Andrew Hunt
Ron Jeffries　Jon Kern　Brian Marick
Robert C. Martin　Steve Mellor　Ken Schwaber
Jeff Sutherland　Dave Thomas

[アジャイルソフトウェア開発宣言](https://agilemanifesto.org/iso/ja/manifesto.html) より引用

###アジャイル宣言の背後にある原則

>私たちは以下の原則に従う:
顧客満足を最優先し、
価値のあるソフトウェアを早く継続的に提供します。

>要求の変更はたとえ開発の後期であっても歓迎します。
変化を味方につけることによって、お客様の競争力を引き上げます。

>動くソフトウェアを、2-3週間から2-3ヶ月という
できるだけ短い時間間隔でリリースします。

>ビジネス側の人と開発者は、プロジェクトを通して
日々一緒に働かなければなりません。

>意欲に満ちた人々を集めてプロジェクトを構成します。
環境と支援を与え仕事が無事終わるまで彼らを信頼します。

>情報を伝えるもっとも効率的で効果的な方法は
フェイス・トゥ・フェイスで話をすることです。

>動くソフトウェアこそが進捗の最も重要な尺度です。

>アジャイル･プロセスは持続可能な開発を促進します。
一定のペースを継続的に維持できるようにしなければなりません。

>技術的卓越性と優れた設計に対する
不断の注意が機敏さを高めます。

>シンプルさ（ムダなく作れる量を最大限にすること）が本質です。

>最良のアーキテクチャ・要求・設計は、
自己組織的なチームから生み出されます。

>チームがもっと効率を高めることができるかを定期的に振り返り、
それに基づいて自分たちのやり方を最適に調整します。

[アジャイル宣言の背後にある原則](https://agilemanifesto.org/iso/ja/principles.html) より引用 

##おわりに。

アジャイル開発の原則を理解する。
これらの原則を理解して、より良いサービスを作れるようになりたい。

アジャイル開発で特に注意すべきことなど、新たにもっと学習していく。
以前よりも理解が深まった。
Chrome内蔵PDFviewerに設定可能なパラメータ


Qiitaに記事が無かったので自分で書いてみることにしました。
以下の方法はFirefox等の他のブラウザでは機能しませんが、同様に設定方法があるかもしれません。（未調査）
とりあえずChromeだけ。

## はじめに
ChromeでPDFを表示する時、内臓のPDFビューアで表示されますが、
このPDFビューアの表示をカスタマイズすることが出来ることはご存知でしょうか？
Chromeのドキュメント等を探しても特に記載は無いのですが、
Chroniumのissueにこんなものがあります。

https://bugs.chromium.org/p/chromium/issues/detail?id=64309

## 設定方法
以下のようにURLの末尾にパラメータを設定するだけ

``` html:
<object data="./test.pdf#toolbar=0" style="width:600px; height:800px;"></object>
```

## 設定可能なパラメータ
編集中
GPT-2にマザー２のテキスト覚えさせてマザー２ジェネレーターつくった話

# GPT-2にマザー２のテキスト覚えさせてマザー２ジェネレーターつくった

ちょっと前に株式会社りんなからgpt-2の日本語モデルが発表されて、これを使ってXX風文章の生成をやってみたいなーとずっと考えてた。

[rinna/japanese-gpt2-medium · Hugging Face](https://huggingface.co/rinna/japanese-gpt2-medium)

そんな矢先、最近わたしの一番好きなゲームであるMother2の全テキストデータが発表(リーク)された。

[名作RPG「MOTHER2 ギーグの逆襲」の貴重なデータが眠るフロッピーが26年の時を超えて発見される - GIGAZINE](https://gigazine.net/news/20210607-earthbound-floppy-original-translator/)

Mother2やったことある人であればわかると思うけど、Mother2の文章は糸井重里が繰り出す独特な世界観であふれている

様々なゲームにも多大な影響を与えていることでも有名なとても素晴らしいゲームだ

[「Undertale」にも多大な影響を与えた名作「MOTHER2」 その魅力を作中の8つのテキストから読み解く (ign.com)](https://jp.ign.com/mother-2/21913/feature/undertalemother2-8)

あの世界にずっと浸っていたい。最近~~仕事~~色々辛いので、Mother2の世界に逃げたい！ずっとあの世界に浸っていた

💡GPTにMother2のテキスト覚えこませてMother2風テキストジェネレーター作ったら永遠にMother2の世界に浸っていられるじゃないか

善は急げということで、おもむろにvs codeを立ち上げてさっそく作業にとりかかった

まずはmother2のテキストデータから余計なものを取り除いて日本語テキストのみの抽出していく

ゲーム内の変数だったり、指示書だったりが入ってるのでそれらを全部とりのぞいていく（成形データ公開したら怒られそうだから、みんなも自分で↑のサイトから拾ってきてデータクレンジングしてね。

つぎに学習させるのにgpt-2の環境を整備整備していく

ローカルでモデルのトレーニングを行うにはanaconda, pytorch, tensorflowは必須
GPUを活用するならnvidia cuda tool kitも必要になる

詳しい手順については以下のサイトを参考にモデルのトレーニングを実行していけば簡単

[Huggingface Transformers 入門 (27) - rinnaの日本語GPT-2モデルの推論｜npaka｜note](https://note.com/npaka/n/n96dde45fdf8d)

[Huggingface Transformers 入門 (28) - rinnaの日本語GPT-2モデルのファインチューニング｜npaka｜note](https://note.com/npaka/n/n8a435f0c8f69)

ちなみに今回のMother2のテキストデータは成形した結果15000行くらいになった。
私のマシンはGPU 6GB積んでいるがそれでもメモリが足りないといわれてしまった
（メモリ消費に関係してくるbatch_sizeを１してもメモリが足りなかったので、今回はgoogle collab上でGPUインスタンスを使ってモデル作成をした）

トレーニングしおわった結果がこちらです。

おしごと疲れた　に続く文章がMotherっぽい世界観で作られている

![Screenshot 2021-06-08 190211.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227518/99dd4f44-c43e-11bb-befd-6483d604001e.jpeg)



いくつか傑作選もはりつけておく：

おとなもこどもも、おねーさんも
おじさんも忘れちゃいけないよね。
砂漠地帯はにっちゃびょうに気を付けないとね。


``` おとなもこどもも、おねーさんも
おとなもこどもも、おねーさんも　 そして、おじさんも
```

```
おとなもこどもも、おねーさんも　 ご家族の皆さんも にっしゃびょうだー!
```

海外にいきたい
この回文っぽい文章と最後の…はどことなくMother2っぽい

```海外に行きたい
海外に行きたい　 って思っている あたまのおかしいヤツが いるから 海外に行きたい　...　
```

マザー２
マザー３まだー？64DD版の発売まってるんだが？

```
'マザー2　3をやった。...  ゲームをやるのをやめた...。 あのゲームは...
```

# まとめ

GPT-2とりんなすげぇ。誰でも気軽にXX風ジェネレーターが作れるいい時代だね。
これを応用したら、XXっぽいゲームとか小説が簡単に作れそう
Ansibleは構成管理ツールとしては優秀だがプロビジョニングツールとしては弱め

https://www.youtube.com/watch?v=rx4Uh3jv1cA
Ansible vs. Terraform: What's the difference?

(英語(アメリカ合衆国)>>日本語 自動翻訳字幕可)を見て、
Ansibleの(Terraformと比較して)苦手な点は以下あたりなのですね。

- プロビジョニング
- 宣言による管理
- 依存関係の扱い
- 運用


漠然と思っていたところを言語化してもらえて腑に落ちた。
確かにAnsibleにはリソース間の依存関係を扱う機能は無いですね。。

プロビジョニングをTerraform、構成管理をAnsibleにさせるとして、組み合わせ方としてすぐに思いつくのは、以下あたりか。。

- Terraformのlocal-exec provisionerなどからAnsibleを実行
- Ansible Moleculeのdelegated driverからTerraformを実行
- Ansible PlaybookからTerraformを実行
- Jenkinsなどからそれぞれを呼び出す

個人的にはMoleculeによる統合が整合性が取れていて好きだが、テスト環境限定かもしれない。
AndroidStudio　静的メニューの定義

参考書「作って楽しむプログラミング　Androidアプリ超入門」の勉強をまとめていきます。

##メニューを定義する
android端末でメニューボタンをタッチすると、設定や、保存などのオプションメニューが表示される。

メニューには、あらかじめ決められた項目を表示する**静的メニュー**と、アプリの状態に応じて変更する**動的メニュー**がある。

今回は静的メニューを作成する

メニューの定義は**XMLファイル**を作成する
->AndroidStudioでresフォルダを右クリックし、New > Android Resource File

```menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
　　　　　　　　//item1つに１のメニュー内容を記載　 
　　　　　　　　//android:id　；選択肢のid
　　　　　　　　//android:title ; 表示文字列
    <item android:id="@+id/item1" android:title="設定"></item>
    <item android:id="@+id/item2" android:title="このアプリについて"></item>

</menu>

```

item属性の中には、**app:showAsAction : アクションバーに表示するかどうか**もある。

##メニューを表示する
オプションメニューを表示するには、画面のタッチやセンサーを利用する場合と同様に**イベントに応じて呼び出されるコードを追加**する。
しかし、メニューの場合は、新たにイベントリスナーを設定する必要はなく、Activityクラスのメソッド（あらかじめ呼び出されるメソッドが定義されている）をオーバーライドするだけで表示ができる。
->AndroidStudioのmainActivity.kt　> Codeメニュー > Overrride Menthods >イベント毎のメソッドを選択
####主なメニューのイベント

| メニューのイベント |実行されるメソッド|タイミング | 
|:-----------|:------------|:-------------|
|メニューが作成される時|onCreateOptionMenu|起動時のみ|
|メニュー表示する時|onPrepareOptionMenu|毎回|
|メニューの項目を選択した時|onOptionsItemSelected|選択時のみ|
|メニューが閉じられる時|onOptionMenuClosed|毎回|


参考
https://qiita.com/watataku8911/items/5faad0384b54d0c53f6e
https://developer.android.com/guide/topics/resources/menu-resource?hl=ja
HerokuへのPush時に「Failed to install gems via Bundler.」が出た時の対処法

RailsチュートリアルでherokuへPushする際以下のようなエラーが出た。

```
remote: -----> Ruby app detected
remote: -----> Installing bundler 2.2.16
remote: -----> Removing BUNDLED WITH version in the Gemfile.lock
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.6.6
remote: -----> Installing dependencies using bundler 2.2.16
remote:        Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4
remote:        Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform
remote:        is x86_64-linux. Add the current platform to the lockfile with `bundle lock
remote:        --add-platform x86_64-linux` and try again.
remote:        Bundler Output: Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform
remote:        is x86_64-linux. Add the current platform to the lockfile with `bundle lock
remote:        --add-platform x86_64-linux` and try again.
remote: 
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote:  !
```

調べたところ、Heroku環境のbundlerのversionとローカル環境のbundlerのversionが一致していないことが原因らしい。
Herokuのbundlerがバージョン2.2.16なのに対してローカルのバージョンは2.2.19だった。

## 解決方法
下記のコマンドを順に入力したらうまくいった。

```
$ gem uninstall bundler
# ローカルのbundlerをアンインストール

$ gem install bundler --version '2.2.16'
# Herokuと同じバージョンのbundlerをインストール

$ bundler -v
# 正しくインストールされたか確認

$ rm Gemfile.lock
# 今あるGemfile.lockを削除する

$ bundle _2.2.16_ install --without production
# bundleをインストール & Gemfile.lockが作成される

$ bundle lock --add-platform x86_64-linux

$ git add -A
$ git commit -m "Change bundler version 2.2.19->2.2.16"

$ git push heroku master
```

エラー文でググったら似たような事例がたくさん出てきた。


## 追記

```
remote:  !     Unknown version "6.1"
```

このエラーは、Gemfileを書き換えるとうまくいった。

```:Gemfile
gem 'rails', '6.0.3'
```

こうする↓

```:Gemfile
gem 'rails', '6.1.0'
```
MLAPIで一人称視点で入りたい。

#やりたいこと
MLAPIでマルチプレイを実装する際に、固定カメラじゃなくて、一人称視点でゲームがしたい！！でもあんまりデモ見かけない！！ということで、実際に作ってみました。

#MLAPIとは
MLAPIは、マルチオンラインゲームを簡単に実装できるものです。Unityで正式採用されたっぽい。
#はまったこと
他の人が入室した際に、その人のカメラに切り替わっちゃう...
#解決策
一人称視点のカメラをPrefabにつけないで、プレイヤーをInstantiateした後に別個にカメラをInstantiateして、子オブジェクトとしてくっつけました。
以下スクリプト


```
private void Start()
    {

        if (this.IsOwner) { 
            //後ろのカメラ（主カメラ）
            playerCam = Instantiate(camera);
            playerCam.transform.tag = "MainCamera";
            playerCam.transform.parent = this.transform;
            playerCam.transform.position = this.transform.position + new Vector3(0, 1.5f, -0.3f);
            Debug.Log("made player Cam");
        }
    }
```


#解説

このスクリプトを、プレイヤーのPrefabにくっつけています。
まず最初に、

```
if(this.IsOwner){
```

を用いて、プレイヤーを生み出した人しかカメラを生成しないようにしています。
####（大事！！IsOwnerないともともとカメラを付けているのと変わらん）
次に、

```
playerCam.transform.tag = "MainCamera";
```

で、MainCameraとして設定して、きちんと画面そのカメラの映像が映るようにします。そして、

```
playerCam.transform.parent = this.transform;
playerCam.transform.position = this.transform.position + new Vector3(0, 1.5f, -0.3f);
```

と、カメラをプレイヤーの子オブジェクトにして、位置を設定してあげればOKです。

以上で終わりです。
何かもっといい方法、間違いがあれば教えていただけると幸いです。
ラズパイにインストールしたGravioのアップデート（再）

Gravio 4.3が出たのでラズパイにインストールしてあったGravioをアップデートした。

Gravio 4.2まではスクリプトベースだったのですが、今回からパッケージバージョンになったのでちょっと手順が複雑です。今後はパッケージでインストールされる Update Manager経由でもアップデートできるようになりますので、そのためのおまじないですね。

手順は以下のサイトのとおりです。

https://doc.gravio.com/manuals/gravio4/1/ja/topic/linux-raspberry-pi-hubkit-4-3

まずはいつものおまじない。

```bash
ubuntu@gravio-rpi4:~$ sudo apt update
ubuntu@gravio-rpi4:~$ sudo apt upgrade
```

HubKitを停止します。

```bash
ubuntu@gravio-rpi4:~$ cd hubkit/
ubuntu@gravio-rpi4:~/hubkit$ sudo docker-compose down
Stopping coordinator-gravio-1       ... done
Stopping hubkit-acm-1               ... done
Stopping hubkit-bltm-1              ... done
Stopping hubkit-com-1               ... done
Stopping hubkit-trim-1              ... done
Stopping hubkit-ivm-1               ... done
Stopping hubkit-vim-1               ... done
Stopping hubkit-mqtm-1              ... done
Stopping coordinator-gravio-redis-1 ... done
Stopping hubkit-sem-1               ... done
Removing coordinator-gravio-1       ... done
Removing hubkit-acm-1               ... done
Removing hubkit-bltm-1              ... done
Removing hubkit-com-1               ... done
Removing hubkit-trim-1              ... done
Removing hubkit-ivm-1               ... done
Removing hubkit-vim-1               ... done
Removing hubkit-mqtm-1              ... done
Removing coordinator-gravio-redis-1 ... done
Removing hubkit-sem-1               ... done
ubuntu@gravio-rpi4:~/hubkit$
```

既存のgravioユーザーのホームフォルダを削除。

```bash
ubuntu@gravio-rpi4:~/hubkit$ sudo rm -rf /home/gravio
```

ダウンロードしてあるパッケージをコピーしてインストール。

```bash
ubuntu@gravio-rpi4:~/hubkit$ cd
ubuntu@gravio-rpi4:~$ sudo apt install -y ././setup_gravio_4.3.1324-1_arm64.deb
```

`https:/<hostname>.local:8080` 、ここでは `http://gravio-rpi4.local:8080` でUpdate Managerにアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/e9047502-5447-085a-bad7-27e930d874c9.png)


Dockerからダウンロード中ですね。

ダウンロードが終わるとログイン画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/be3ff0f0-3e00-cc33-5e57-1fcaf054e4c4.png)

ここで古いデータを移行します。

```bash
ubuntu@gravio-rpi4:~$ cd /home/gravio
ubuntu@gravio-rpi4:/home/gravio$ sudo mv hubkitrepo4 hubkitrepo4_bak
ubuntu@gravio-rpi4:/home/gravio$ sudo mv /home/ubuntu/hubkit/hubkitrepo4 .
ubuntu@gravio-rpi4:/home/gravio$ sudo chown -R gravio:gravio hubkitrepo4
```

再起動します。

```bash
ubuntu@gravio-rpi4:/home/gravio$ sudo reboot
```

起動してきたら Update Managerに `gravio`ユーザーでログインします。パスワードも `gravio`。ログインするとパスワードの変更を求められますので、適当に設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/d21ff5a9-1504-6106-49f1-4aec19641685.png)

ログインできたら完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/a18b9461-c337-bbe7-e771-dee6f211b604.png)

Studioからもアクセスしてみて無事バージョンアップされてました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/72ef1e5c-2b69-12ee-d669-d9634c146ef5.png)
Slackに絵文字を追加する方法（動きをつけよう）

#はじめに
GeekSalon Webメンターの🐱のんたんです

1日のうち、一番使うSNSがSlackである私が**Slackの絵文字**の追加の仕方を伝授します😀
みんなもいっぱい作って楽しいSlackライフを送りましょ！

#絵文字を作ろう
まずは、好きな絵文字を作るところから！🍙

##文字の絵文字
[絵文字ジェネレーター](https://emoji-gen.ninja/)を使っていきます。
好きな文字を入力し、フォントと色も指定してください。

![スクリーンショット 2021-06-08 15.09.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/b1ebc25e-082e-c08c-5225-f03e755c7bb9.png)


| フォント |  絵文字  | フォント |  絵文字  |
| :---: | :---: | :---: | :---: |
|||
|  Note Sans Mono CJK JP Bold  |  ![わい_わい.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/7da1e957-9523-077c-07ca-cb520e31e54c.png)|  M+ 1p black  |  ![わい_わい (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/f6a2b830-9148-ba35-6192-3d1098b3103d.png)
  |
|  Rounded M+ 1p black  |  ![わい_わい (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/b8d2d876-beb4-14c5-4b2a-06a3c52f6bc5.png)| IPAmj明朝  |  ![わい_わい (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/6081130a-12af-b1e0-1909-e5b819169bd0.png)
  |
|  青柳隷書しも  |  ![わい_わい (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/f550f8be-8554-7c8f-213d-c478945314f4.png)|LinLibertine Bold  |  ![Waa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/b756de7c-3cf5-edc7-c312-dff90bb6e6b8.png)

好きなスタンプが作れたら、ダウンロードから保存します。
![スクリーンショット 2021-06-08 15.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/c1e36a59-e828-09df-7417-61a8029a1173.png)

##動く絵文字
[MEGAMOJI -簡単アニメ絵文字メーカー](https://zk-phi.github.io/MEGAMOJI/)を使っていきます。

もちろん、こちらでも文字の絵文字を追加することができるのですが、こちらはさらに絵文字を動かすことができます🥳

ここでは、好きな画像を動くスタンプにしていこうと思います！

![スクリーンショット 2021-06-08 15.15.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/7e3f1a36-9c54-6b57-c359-7b915a650433.png)

ファイルを選択したら、右下の<font color="DodgerBlue">**効果をつける**</font>を選択します。
そうすると、バリエーション豊かなアニメーションが出てくるので、色々と試してみてください！

![スクリーンショット 2021-06-08 15.31.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/96502fbb-4459-97da-6c95-cdfc9273764b.png)

~~ここまできたら、保存するだけ！！なのですが、~~
~~<font color="Gold">⚠️<font color="Red">**ここで注意**</font>⚠️</font>~~
~~このサイトは、「保存する」というボタンは存在しません。~~
~~変なボタンを押そうものならたちまち１からやり直しです。~~


~~このサイトでは、保存は画像を右クリックすることで保存します。~~

###追記
画像を保存するボタンが追加されました！
![スクリーンショット 2021-10-03 19.08.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/8bad4e7d-6d96-d265-9010-0993c06f2022.png)


#絵文字をSlackに追加する
ここまできたらあとは簡単です。
作った絵文字をSlackに追加しましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/a5c9c10c-20e7-2f9c-a1c1-95b114fa10fc.png" width="230" ><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/3c622a5e-a610-1e5c-f492-59b831a8bf21.png" width="240" >


1.  絵文字のところから、**絵文字を追加する**ボタンを押す
1.  画像をアップロードし、名前をつける
1.  保存する

これで絵文字の追加ができました！

#終わりに
全然難しくないでしょ！😁
みんなも楽しいSlackライフを送りましょ！

👇今まで私が追加してきたスタンプたち（一部）👇
![スクリーンショット 2021-06-08 18.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317576/551cee17-73c2-065a-8e95-9a8166dd97bc.png)
Amazon Linux2にZabbix3系を構築する

### 概要と環境
AmazonLinuxにzabbix3系をインストールする。
LAMP環境は構築済み。
php5.6系, mysql5.5系, Apache2.2系を使用する。

### 手順
必要となるパッケージのインストール

```
yum install mysql-server httpd24 php56 php56-gd php56-mbstring php56-mysqlnd php56-bcmath
```
レポジトリにzabbix3系を追加

```
rpm -ivh http://repo.zabbix.com/zabbix/3.0/rhel/6/x86_64/zabbix-release-3.0-1.el6.noarch.rpm
```
zabbix3のインストール

```
yum install zabbix-server-mysql.x86_64 zabbix-web-mysql.noarch zabbix-web-japanese.noarch zabbix-get
```
MySQLの設定。MySQL内にZabbix用ユーザを作成する。

```
mysql -u root -p

mysql> CREATE USER zabbix;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE DATABASE zabbix;
Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON zabbix.* TO zabbix@localhost IDENTIFIED BY '<パスワード>';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

mysql> exit
Bye
```
MySQLにZabbixスキーマとデータを投入

```
cd /usr/share/doc/zabbix-server-mysql-3.0.7/
zcat create.sql.gz| mysql -uroot zabbix -p
```
Apache設定にzabbix設定ファイルのコピー

```
cp /usr/share/doc/zabbix-web-3.0.3/httpd24-example.conf /etc/httpd/conf.d/zabbix.conf
```

phpの設定あれこれ

```
# タイムゾーンの設定
sed -i -e "s/;date.timezone =/date.timezone = Asia\/Tokyo/g" /etc/php.ini

# Zabbix起動時のセキュリティチェック対応
sed -i -e "s/;always_populate_raw_post_data/always_populate_raw_post_data/g" /etc/php.ini
```
zabbixサーバの設定。DBとの連携を行う。

```
vim /etc/zabbix/zabbix_server.conf
115行目のコメントアウトを外す
DBPassword=<パスワード>
```
zabbixサーバ起動

```
service zabbix-server start
service httpd start
```

あとは画面に従って初期設定を行う。

初期設定終了後のログイン情報は以下の通り。
後でちゃんとセキュアな感じに設定しておく。
Username:Admin
Password:zabbix
SwiftUI 2.0：toolbar()とToolbarItemよりnavigationBarItems()のほうがセーフ？

# SwiftUI 2.0: Use navigationBarItems() instead of toolbar() with ToolbarItem? ([English](https://qiita.com/loic-meister-guild/items/0b020490da6a52923e90))

## My problem
残念ながら、SwiftUIはナビゲーションバーのスタイルを直接公開しません。

SwiftUIアプリケーションのナビゲーションバーの外観をカスタマイズするために、[`UINavigationBar.appearance()`]()メソッドを使用して`init()`メソッドでナビゲーションバーの色を設定するというトリックを使用しました　．．．

これは、[アプリのナビゲーションバーをカスタマイズ](https://developer.apple.com/documentation/uikit/uinavigationcontroller/customizing_your_app_s_navigation_bar)する最良の方法ではありませんが、情報を探していたときにインターネットで見つけた方法はでした。これにより、以前に[`fileImporter`のスタイルを設定](https://qiita.com/loic-meister-guild/items/16a523097e41525e5027#%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AA%E3%83%B3%E3%82%B0)しようとしたときにも問題が発生しました！

```Swift:SwiftUI
structMyAppView: View {
    init() { // Color Settings
        UINavigationBar.appearance().tintColor = UIColor(named: "MyNavBarColor")
        // ...
    }
    //...
}
```
問題は、[`toolbar(content:)`](https://developer.apple.com/documentation/swiftui/view/toolbar(content:)-5w0tj)を使用してナビゲーションバーをカスタマイズしたときに始まりました：

```Swift:SwiftUI
    // ...
    .toolbar(content: {
        ToolbarItem(placement: .navigationBarLeading) {
            /// The screen title
            Text("My Title")
                .foregroundColor(Color("MyForegroundColor"))
                .font(.system(size: 30))
        }
        ToolbarItem(placement: .navigationBarTrailing) {
            Button(action: {
                showNewAchievementForm.toggle()
            }) {
                Image(systemName: showNewAchievementForm ? "multiply.circle.fill" : "plus.circle.fill")
                    .font(.system(size: 30, weight: .light))
                    .foregroundColor(Color("MyForegroundColor"))
            }
            .disabled(!canAddNewAchievement())
        }
    })
```
`UINavigationBar.appearance().tintColor`が`init()`で設定されている場合、`ToolbarItem`の前景色は無視されました。
## My solution
アプリケーション画面の1つは、代わりに[`navigationBarItems(leading:trailing:)`](https://developer.apple.com/documentation/swiftui/view/navigationbaritems(leading:trailing:))を使用していました。

```Swift:SwiftUI
    // ...
    .navigationBarItems(
        leading:
            /// The screen title
            Text("My Title")
                .foregroundColor(Color("MyForegroundColor"))
                .font(.system(size: 30)),
        trailing:
            Button(action: {
                showNewAchievementForm.toggle()
            }) {
               Image(systemName: showNewAchievementForm ? "multiply.circle.fill" : "plus.circle.fill")
                   .font(.system(size: 30))
                   .foregroundColor(Color("MyForegroundColor"))
            }
            .disabled(!canAddNewAchievement())
    )
```
__しかし__、現在は非推奨となり、[`navigationBarLeading`](https://developer.apple.com/documentation/swiftui/toolbaritemplacement/navigationbarleading)または[`navigationBarTrailing`](https://developer.apple.com/documentation/swiftui/toolbaritemplacement/navigationbartrailing)配置を備えた[`toolbar(content:)`](https://developer.apple.com/documentation/swiftui/view/toolbar(content:)-5w0tj)が推奨されています。
## 未来
SwiftUI3.0はすぐ発表されるはずので、カスタマイズは確実に改善されます。

もう少し待って見ましょう
[雑談]プログラマー、エンジニアの2社目としての振り返り

久々の更新になります。
今、派遣エンジニアとして働いてます。（登録制の派遣です。）

今回は６月末で現場を終了することになりましたので（９か月間　契約満了）、
**『現場で吸収できたこと』**の**"振り返り"**をしたいなと思います。

**まずは、現場の方々お世話になりました。またありがとうございました！！**


**★★契約終了理由★★**
①コロナでお客さんの売上下がって受注が厳しくなりお客さんとの契約もどうするか状態であること
②契約が継続するかのタイミングだった
③担当していた案件が利益が低いことが

理由みたいです。。。


**担当したシステム**は、
1. 中小企業診断士向けのWEBシステム
2. 映画館チケットのWEB販売システム(複数社)/受託パッケージシステム
の**保守開発**を担当しました。

**担当工程**は、
詳細設計、実装、単体テスト、結合テスト、総合テスト、リリース作業、保守（バク、エラー調査、改修）


**使用言語**ですが、

1. Java
2. Javascript
3. HTML
4. JSP
5. SQL


を経験できました。

次に**フレームワーク**は、
1. JSF
2. struts
3. jQuery

**ツール**に関しては、
1. Eclipse
2. コマンドプロンプト
3. Teraterm
4. Apache tomcat
5. Oracle
6. A5:SQL Mk-2
7. Zoom
8. teams
9. Backlog
10. SVN
11. powershell
12. git
13. AWS(Elastic Load Balancing等)
14. MySQL
使用しました。


**業務内容**に関しては、
1. システム調査(エラー、バグ)
2. 追加実装
3. プログラム修正
4. ページ作成
5. 動作確認
6. リファクタリング
7. ドキュメント作成
8. テスト業務
9. リリース作業のサポート


**全体的な感想**として、
入ったばかりの時は、テストが多かった印象です。
受託開発の会社だったので（系列会社はSierの大手会社）、
**別の部隊のシステムやアプリのテスト作業などのサポート**に入った思い出があります。（バグやデグレがひどくかなり予定より遅れてる案件に入りました。汗）


比率的に　**テスト　:　実装and詳細設計　＝　7　:　3**　の割合でした。

2か月くらい過ぎてくらいから、
比率が　**テスト　:　実装and詳細設計　＝　3　:　7**　 の割合になりました。


紹介している現場の前の現場も、
フロントエンド側だったこともあり（たまにバックエンドもやってました）、
今回もフロントエンド側の追加実装とか改修はほぼほぼこなしました。
バックエンドも少し追加実装したり、改修作業やりました。

あとは、Excelで実装したあとの資料作り（詳細設計andテストエビデンス）作りは初めてやったので、(自社開発でやったときはjira softwareのwikiに軽く記載程度でしたので)いい経験になったかなと思ってます。


古い技術や環境の現場ではありましたが、
周りの方は優しい方多かったです。

エンジニアは細かいところに気付くが故に、
1. **マウンティングしてしまう方**
2. **表現が言葉足らずになり切れてしまう人**
3. **知識やスキルがわからない人を置いてけぼりにする人**
多いので、この現場では比較的少なかったですね。。。笑

逆に細かいところに気付くことで、
1. **バグが起きにくい**
2. **コミュニケーションが行き届く？笑**
3. **トラブルが起きたとき対応できる**
等々みたいなメリットもあると思いますが、やりにくいので助かりました。



話はそれましたが、
今回は**要件定義、基本設計**以外は関わることができたかなと思います。


次は、Go言語勉強しているのでGo言語の現場で働きたいのが希望です。
とはいえ無理なら他の言語や今まで使ってきた言語でもよいかなと....。
**※プライベートPC（DELLのWindows10　４年強くらい使用）が調子悪くなりました。
なので、PCをMacに変更予定です。買ったら、本格的にWEBアプリケーション（チャットツールっぽいもの）開発予定です。。**



今回、２社目（**厳密に言うと５社目。最初の３つはSES事業で"経歴詐称"や"客先は面談内容と全く違う事させる"、"パワハラ、モラハラ、セクハラは当たり前"等々があるヤバい会社でした。すぐ辞めました。汗**）でしたが、よかったです。



IT関連の会社を選びときは、慎重に！！
【CakePHP3】"Test code or tested code did not (only) close its own output buffers"エラーの対処

# 何が起きたか
コントローラのテストのとあるケースで `risky` 判定されてました
その時の表示メッセージが以下

> Test code or tested code did not (only) close its own output buffers

# バージョン
* CakaPHP 3.8.13
* PHPUnit 6.5.14

# 原因調査
コントローラで新規にエンティティ作って

```php5:Controller
$this->set('ent', $this->Sample->newEntity());
```

フォームに突っ込むケースで発生してるっぽい

```php5:Template
<?= $this->Form->create($ent) ?>
```

・・・別に変な使い方ではないはず

ということでCakePHPの[リリースノート](https://bakery.cakephp.org/2020/08/29/cakephp_392_released.html)をあさってみると
> Fix output buffers not being closed when view templates or blocks are being rendered. This fixes tests being marked as risky in PHPUnit.

CakePHP 3.9.2 のバグ修正内容と今回の症状が合致してました

早速バージョン上げてテスト

```
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 683 ms, Memory: 22.00MB

OK (1 test, 2 assertions)
```

通りましたね

# 結論
CakePHPのバージョンを3.9.2以上にすれば解決
ajaxでファイルダウンロード

jqueryでshiftjisでできたファイルのダウンロードのやり方。
$ajaxだとうまくいかなかったけどこれならうまくいった

``` javascript

fetch(url, {method: 'GET'})
           .then((res) => {
                if (!res.ok) {
                    throw new Error(`${res.status} ${res.statusText}`);
                }
                return res.blob();
            })
            .then((blob) => {
                const url = URL.createObjectURL(blob);
                const a = document.createElement("a");
                document.body.appendChild(a);
                a.download = filename;
                a.href = url;
                a.click();
                a.remove();
                setTimeout(() => {
                    URL.revokeObjectURL(url);
                }, 1E4);
            })
            .catch((reason) => {
                console.error(reason);
                alert('予期せぬエラーが発生しました。');
            });

```
AtCoder Beginner Contest 204

##[A - Rock-paper-scissors](https://atcoder.jp/contests/abc204/tasks/abc204_a)

O(1)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int x, y;
    cin >> x >> y;

    if(x == y){
        cout << x << endl;
        return 0;
    }

    cout << 3 - x - y <<endl;

    return 0;
}
```

##[B - Nuts](https://atcoder.jp/contests/abc204/tasks/abc204_b)

O(N)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N;
    cin >> N;

    vector<int> A(N);
    rep(i, N) cin >> A[i];

    ll res=0;
    rep(i, N){
        if(A[i]>10){
            res = res + ((ll)A[i] - 10);
        }
    }

    cout << res << endl;

    return 0;
}
```

##[C - Tour](https://atcoder.jp/contests/abc204/tasks/abc204_c)

O(N+M)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

bool field[2000];
vector<vector<int>> tree;

void dfs(int v){
    if(field[v]) return;

    field[v] = true;
    for(auto i:tree[v]){
        dfs(i);
    }
}

int main() {
    int N, M;
    cin >> N >> M;

    tree.resize(N);

    rep(i, M){
        int a, b;
        cin >> a >> b;
        tree[a-1].push_back(b-1);
    }

    int res=0;
    rep(i, N){
        rep(j, N) field[j] = false;
        dfs(i);
        rep(j, N){ if(field[j]) res++; }
    }

    cout << res << endl;

    return 0;
}
```
Rails ログインユーザーが、URLを入力しても特定のページに遷移できないようにする

作成していた投稿アプリで
「ログインしているユーザー以外が投稿した記事の編集ページに飛ぼうとすると、トップページに遷移する」
という機能がありました。

Aさんが投稿したid=1という記事の編集（edit）にBさんがアクセスできないようにする、ということですね。

実装しなきゃいけないのは、単純にeditメソッドだけでなく、ログインユーザー以外がeditページにアクセスした時、という条件を付けなければいけないということ。

```ruby
def edit
    @prototype = Prototype.find(params[:id])
    unless current_user.id == @prototype.user_id
      redirect_to root_path
    end
  end
```

解説します。
今回でいう記事はprototypeですね。

editアクションが実行された時、prototypeから該当のidをfindで見つけて、@prototypeに格納します。

で、unlessで

```ruby
unless current_user.id == @prototype.user_id
      redirect_to root_path
end
```

という条件をつけました。
deviseを使用しているので、current_userとなりますが、要はログインユーザーと@prototypeのユーザーIDが一致しない時はリダイレクトでroot_pathに戻されます。

参考文献
[ログインユーザーが、URLを入力しても特定のページに遷移できないようにする](https://qiita.com/taka_no_okapi/items/5d33cf83e21a7ade0943)
n を使って Node.jsのバージョンをダウングレードする（macOS）


# Node.js のアンインストール
Node.js 14.17.0 を導入したものの、　Node.js 10.x にダウングレードする必要が生じました。
ダウングレードの実施方法はいろいろありますが、今回は n を利用してダウングレードを実施したため、その作業ログを残します。
 n コマンドの詳細はこちら。
https://www.npmjs.com/package/n


# 環境
macOS Big Sur 11.4

# ダウングレード手順
root ユーザーに切り替えます。suコマンドを実行し、パスワードを入力します。

```sh
$ su 
```

n をインストールします。

```sh
sh-3.2# npm install -g n
/usr/local/bin/n -> /usr/local/lib/node_modules/n/bin/n
+ n@7.3.0
added 1 package from 2 contributors in 0.343s
```

n がインストールされました。
現在導入されている node のバージョンを確認しておきます。

```sh
sh-3.2# node -v
v14.17.0
```

ダウングレード先のバージョンを引数に設定し、 n を実行します。
念の為、リリース一覧よりダウングレードするバージョン番号を確認します。
10.12.0にダウングレードすることにします。
https://nodejs.org/ja/download/releases/

```sh
sh-3.2# n 10.12.0
  installing : node-v10.12.0
       mkdir : /usr/local/n/versions/node/10.12.0
       fetch : https://nodejs.org/dist/v10.12.0/node-v10.12.0-darwin-x64.tar.xz
   installed : v10.12.0 (with npm 6.4.1)
```

ダウグレード後のバージョンを確認します。10.12.0 にダウングレードできました。

```sh
sh-3.2# node -v
v10.12.0
```
以上です。
ROSでなんかうまくいかないとき(付け焼き刃)

#※あくまで付け焼き刃である

この記事はあくまで付け焼き刃であり、完璧な解決方法ではないが、とりあえず試すとうまく行くことがある。
ROSをいじっていて困ったとき、解決方法がどこにも落ちていないときなどにやってみるとうまくいくかも、位に思っていただけると...

##環境
・ROS melodic
・Ubuntu 18.04

```
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
```

##解決した事例など
・rvizがなぜか立ち上がらない（apt update後とかにありがち）
　↓みたいなエラーコードが出る（詳細は忘れた）

```
rviz Unable to create a suitable GLXContext in GLXContext
```
・catkin_makeが通らない（変なエラーメッセージが出る）（こちらも詳細は忘れました）
・自作msgをよみこんでくれない（以下参照）

```
# msgはちゃんと存在しているっぽい
$ rosmsg show test_pkg/original_msg
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
string s
bool flag

# なのに「そんなもんはない」と言ってくる
$ rosrun test_pkg test.py 
Traceback (most recent call last):
 File "/home/.../test.py", line 9, in <module>
    from test_pkg.msg import original_msg
ImportError: cannot import name original_msg
```

##解決策
「壊れたテレビも叩けば治る」みたいな解決策なんですけどけっこうバカにならないので書いておきます。
「コンセントは抜けていませんか？」みたいなQ&Aに腹が立つ！人にはおすすめできませんよ！先に言ったからね！

**・再起動**
マジでこれに尽きる。ネットでいろいろ調べてコマンド打って直んなくて再起動したら一瞬で元通りとかザラにある。検索とかしてた時間を返せ、という...
上に書いた事例だと、rvizの話とかはこれで解決した気がする。

**・buildファイルの削除**
GitHubからcloneして別PCでcatkin_makeするとかのとき、あんま理解していなくてbuildファイルごとcloneしちゃってたんですがbuildファイルを消して再buildするとなおる。
そもそもGitHubにbuildファイルごと上げるな！なんですよね、すみません
上の事例だとcatkin_makeとmsgの2つがこれに該当する。




以上です。他にも「それで直るんかい」みたいなものがあれば追記していきます。
ネットでいろいろ調べたけどなんの成果も得られなかった...みたいな人はとりあえず試すと良いかもしれない。
Rails　投稿、入力フォームで空欄があったときにデータを保持した状態にする

作成した投稿アプリケーションの仕様上、

「空欄で投稿したときに、値は保持したままで、入力フォームに戻ってくる」

という仕様がありました。

これの再現方法について

```ruby
  def create
    @prototype = Prototype.new(prototype_params)
    if @prototype.save
      redirect_to root_path
    else
      render action: :new
    end
  end
```

いきなり結論、これでいけました。
順に解説

```ruby
@prototype = Prototype.new(prototype_params)
```

ここで@prototypeというインスタンス変数に.newメソッドで生成した値を入れておきます。

```ruby
if @prototype.save
      redirect_to root_path
    else
      render action: :new
```

これで.saveメソッドが実行された時はroot pathに戻されますが、そうではない時はrenderアクションでnewメソッドに戻ります。

つまり大事なのが、redirectとrenderの違い。
renderはインスタンス変数の値はそのままです。
そう、newメソッドに戻った時の@prototypeの値を引き継ぎます。

逆に、redirectは値を引き継がず、ページ遷移するだけです。

基本的な動作ですが、画面遷移を伴う場合、インスタンス変数が現在どの値になっているのかは正確に把握する必要がありますね。

参考文献
[フォーム入力時のバリデーション機能（値のチェック）を実装する](https://rails-study.net/validation/)
Redis の WebAPI (FastAPI)

こちらで定めた仕様を満たすサーバーサイドのプログラムです。
FastAPI で実装しました。
[Redis の WebAPI を作成](https://qiita.com/ekzemplaro/items/1746b31beef382023f2d)

## サーバープログラム

```py:redis01.py
# --------------------------------------------------------
#
#	redis01.py
#
#					Jun/08/2021
# --------------------------------------------------------
from fastapi import FastAPI
from pydantic import BaseModel
import  redis
# --------------------------------------------------------

class Item(BaseModel):
	key: str

class Item_insert(BaseModel):
	key: str
	value: str

app = FastAPI()

@app.post("/redis_get/")
async def redis_get(item: Item):
	key = item.key
	rr = redis.Redis(host='localhost', port=6379, db=0)
	json_str = rr.get(key).decode()
	return json_str


@app.post("/redis_insert/")
async def redis_insert(item_insert: Item_insert):
	key = item_insert.key
	value = item_insert.value
	rr = redis.Redis(host='localhost', port=6379, db=0)
	rr.set(key, value)
#
	return key


@app.post("/redis_list/")
async def redis_list():
	rr = redis.Redis(host='localhost', port=6379, db=0)
	keys = rr.keys('*')	
	return keys




# --------------------------------------------------------
```

## サーバーの起動

```bash
uvicorn redis01:app --reload
```

## クライアントからアクセス

キーの一覧

```text
$ http POST http://127.0.0.1:8000/redis_list/
HTTP/1.1 200 OK
content-length: 73
content-type: application/json
date: Tue, 08 Jun 2021 05:38:27 GMT
server: uvicorn

[
    "t1858",
    "t1857",
    "t1856",
    "t1854",
    "t1853",
    "t1855",
    "t1852",
    "t1851",
    "t1859"
]
```

キーを指定して値の取得

```text
$ http POST http://127.0.0.1:8000/redis_get/ key=t1852
HTTP/1.1 200 OK
content-length: 84
content-type: application/json
date: Tue, 08 Jun 2021 05:39:04 GMT
server: uvicorn

"{\"name\": \"\\u6566\\u8cc0\", \"population\": 41295, \"date_mod\": \"2003-5-10\"}"
```

値の挿入

```text
$ http POST http://127.0.0.1:8000/redis_insert/ key=t1853 value='{"name": "宇都宮","population": 8751600,"date_mod": "2021-3-17"}'
HTTP/1.1 200 OK
content-length: 7
content-type: application/json
date: Tue, 08 Jun 2021 05:39:35 GMT
server: uvicorn

"t1853"
```

## 確認したバージョン

```text
$ python
Python 3.12.7 (main, Feb  4 2025, 14:46:03) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastapi
>>> fastapi.__version__
'0.110.3'
```
[日本語化しました] Azure DevOps・Visual Studio App Center のドキュメント

皆さんごきげんよう。

Azure DevOps のドキュメントならびに、Visual Studio App Center のドキュメントがまずは機械翻訳ではありますが、日本語でご利用いただけるようになりました。

https://docs.microsoft.com/ja-jp/azure/devops/?view=azure-devops

https://docs.microsoft.com/ja-jp/appcenter/?sccid=tw_org_20210520&ocid=AID740624_TWITTER_oo_spl100002079271491

これらの製品は、まだ日本語化されていないため、ドキュメントもこれまでは英語のままでしたが、ドキュメントについてはせめて日本語を…！！というご要望を頂いておりまして、本社にてその思いをしかと受け止め、機械翻訳という形でお応えすることになりました。

なお、フィードバックと、アクセス数によって、人気のあるコンテンツから**人間翻訳にしていく予定**ですので、是非ご覧いただければ幸いです。

##フィードバックについて
ドキュメントからユーザーが直接フィードバックを上げる際には下記から挙げられます：
 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1529732/def0a1ad-ba2e-4321-abc4-7e24871fd8d5.png" width=30%>

もし社員を通して具体的なフィードバックを挙げる場合には下記のメールテンプレートのリンクをご使用ください：
https://aka.ms/docsitelocfeedback
VPN接続先のWebアプリが開けないとき（YAMAHAルーター＋Windows10）

#前提
- YAMAHA製ルーター
- Windows10のVPNクライアント
- L2PT/IPSecでVPN接続
- VPN接続先のLANにWebサーバーが居る
- VPN接続は確立しており、Webサーバーへのpingは通っている
- WebサーバーへのHTTP(S)通信はページや通信状況？で表示出来たりできなかったりする
- WebサーバーもWindowsベース（ここは未確定）

#解決方法
**VPNトンネルにMSSを明示的に設定します。**

#ルーターのVPN設定の確認
##VPNトンネルの設定からMTUを見つける
CONFIGリポートのPP anonymousの設定から、`ip pp mtu xxxx`という記述を探します。
ここで指定されている値がVPN接続のMTUです。

##VPNトンネルの設定からMSSを見つける
個々のVPNトンネル設定から、`ip tunnel tcp mss limit xxxx`という記述を見つけます。
値が`auto`になっている場合、`tunnel select ...`から`tunnel enable ...`までのブロックをコピーして、該当の`mss limit xxxx`の値を先ほど見つけたmtuから40を引いた値で上書き設定します。

##VPN接続とサイトが閲覧可能か確認します。
多分これで安定して閲覧できるようになるかと思います。

#説明
##MTUとMSS
用語の解説は[こちら](https://www.infraexpert.com/info/5adsl.htm)をご参照ください。

通常、MSSはネゴシエーションの過程で調整されるはずですが、Windows10はそれが非常に苦手なようです。
今回この記事を書く理由になったサーバーとクライアントの通信のパケットを確認したところ、ルーターからのICMP type3 code4(Fragmentation Needed and DF set)をサーバーが無視します。
このため、サーバーからのパケットが破棄され、クライアントはリクエストを再送し、やがて通信が途絶してしまいます。

VPNトンネルのMTUは設定で明示されているため、そこからTCP/IPのヘッダー長40を引いた値をMSSとして設定しておけば、安定した通信が可能になります。

YAMAHAさんはWindowsのVPNクライアントをサポートしないと明言しているため、おそらくWindowsの実装に不具合があるのでしょう…
クライアントの最適なMTUを調べて設定するのは大変ですが、ルーターがMSS書き換えに対応できるのであれば、こちらの方が楽です。
Androidstudioでのgit連携

#Githubトークン作成方法
Githubにログイン 
-> Settings 
-> Developer settings 
-> Personal access tokens 
-> Generate new token
-> Note: 名前、　
-> Select scope↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/485bf979-7dff-0195-931b-85af29342def.png)

admin：repo_hook　にもチェック！


-> VCS
-> Import into Version Control
-> share project on github
-> token入力してログイン
GoogleスプレッドシートでDeepL翻訳関数を作る

Googleスプレッドシートのデフォルトで使えるGOOGLETRANSLATE関数があまりにも精度が悪いので、DeepL関数をGoogle App Scriptで自作しました。

### 手順

#### 1. DeepL Proアカウント（無料）を作る

DeepLAPIを使うためにDeepLProアカウントを作ります。
https://www.deepl.com/pro#developer

このサイトから「DeepL API Free」を選択して手順に沿って登録します。


※クレジットカードを入力する項目がありますが、Freeプランであれば課金はされません。
※DeepL API Freeだと50万文字/月が上限のようです。（執筆時点）



#### 2. 登録後のAPI認証キーをコピーしておく

登録完了後に認証キーが表示されるのでコピーしておきます。
「XXX~XXXX:fx」というキーです。
マイページ->プランでも見ることができます。


#### 3. Google App Scriptを開く

GoogleスプレッドシートからTool->Script Editorを開きます。

![Screen Shot 2021-06-08 at 14.05.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620185/fcac19c2-6ddb-9162-4dcd-07156177d769.png)


#### 4. DeepL関数を書く

auth_keyのXXXXXは2でコピーした認証キーを入力してください。
今回は英語->日本語の翻訳ですが変えたい場合はja,enの部分を変えて下さい。

```js:deepl.gs
function deepl(text) {
  var response = UrlFetchApp.fetch("https://api-free.deepl.com/v2/translate?auth_key=XXXXX&text="+ text +"&target_lang=ja&source_lang=en");
  var json = response.getContentText(); 
  var data = JSON.parse(json); 
  var result = data.translations[0].text;
  return(result);
}
```

#### 5.保存して実行

スクリプトエディタで保存した後、Google Sheetでdeepl関数が使えるようになります。
=deepl(翻訳したい日本語または参照セル)という形で使えます。



#### 最後に

Googleスプレッドシートでセンテンス単語帳をを作ってたのですが、GOOGLE TRANSLATE関数があまりにも使えず＆プラグインも日本語対応しているものがなく、やっつけで作りました。

----
#### 追記 (2021.9.3)

Google App Scriptの仕様で、スプレッドシートを読み込むたびに関数が実行されてしまうようです。
今のところ有効な回避策がないようなので、同じファイル内で大量に関数を使用すると月額上限に引っかかりやすくなるので注意してください。
Laravelのマイグレーションで長い名前のカラムに外部キー制約を付けるときにはconstraint()ではなくforeign()を使う

長い名前のカラムに対してつけようとしたところエラーになりました。

```php:migrations/test.php
  $table->foreignId( 'something_tooooooo_much_logn_column_name_and_foreign_table_name_id' )
  ->nullable()
  ->constrained( 'foreign_table' )->onUpdate( 'cascade' )->onDelete( 'cascade' );
```

Laravelではカラム名と外部テーブル名を使って自動的に外部キー制約名を付けるのですが、その長さの制約に引っかかってしまっています。

```php:migration/hoge.php
  $table->foreignId( 'something_tooooooo_much_logn_column_name_and_foreign_table_name_id' )->nullable();
  // constrainedで外部キー制約を作ると自動で名前付けされるが、その場合には外部キー制約の名前が長すぎてエラーとなる。
  // そのため手動で制約名を付ける
  $table->foreign( 'something_tooooooo_much_logn_column_name_and_foreign_table_name_id',
  env( 'DB_TABLE_PREFIX' ) . 'too_much_long' )->references( 'id' )->on( 'foreign_table' )->onUpdate( 'cascade' )->onDelete( 'cascade' );
```

※わかりやすいようにカラム名を長くしすぎたので、もしかしたらカラム名の長さ制約に引っかかるかもしれません。