OmniAICreator/Qiita-1.07M huggingface dataset:
WSL2 での開発を快適にするためのいろいろ

そんなにないです。

## リモート接続が死ぬ

### WSL の再起動

Visual Studio Code でリモート接続して開発してるんですが、スリープしたりするとよく死んでます。そういうときはプロセスを再起動します。

PowerShell を管理者権限で起動して `net stop LxssManager` と打てば止まります……が、うまくとまらないことがあります。止まっても勝手に再起動してしまって起動してることがあります。なので何回か打ちます。

```
PS C:\WINDOWS\system32> net stop LxssManager
LxssManager サービスを停止中です.
LxssManager サービスは正常に停止されました。

PS C:\WINDOWS\system32> net stop LxssManager
LxssManager サービスは開始されていません。

NET HELPMSG 3521 と入力すると、より詳しい説明が得られます。

PS C:\WINDOWS\system32> net stop LxssManager
LxssManager サービスは開始されていません。

NET HELPMSG 3521 と入力すると、より詳しい説明が得られます。
```

「LxssManager サービスは開始されていません。」と出ていれば、ちゃんと止まってます。

 `net start LxssManager` で起動します。これは失敗することはないです。

#### 2024/05/07 追記

この公式のイシュー（ https://github.com/microsoft/WSL/issues/8644#issuecomment-1194772945
 ）を見ると、Windows Store からインストールするとサービス名が WslService になるようです。まじかよ。

### Docker Desktop の再起動

ただ、再起動すると Docker Desktop for windows が死んでます。

![DokcerDesktopDead.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16728/2fd44f7f-3c07-de41-efbd-6223769a70fd.png)

こうなっていると死んでる証拠です。右クリックして Restart Docker を選んでやります。

余談

この作業を毎回やってると右クリックで「管理者権限で起動」が面倒になってきますので三回ストップしてスタートするスクリプトでも書いておくといいかもしれません。

### メモリ食べ過ぎ問題

WSLに入って、メモリをフラッシュします。

```powsershell
wsl
sudo sh -c "/usr/bin/echo 3 > /proc/sys/vm/drop_caches"
```
【iOS15】タブバーの背景を有効にしたい

### 注意
執筆時点でベータ版を扱っているため、正式版と挙動が異なる可能性があります。

# UITabBarAppearanceを使う

```Sample.swift
...
let appearance = UITabBarAppearance()
appearance.backgroundColor =  UIColor.gray
UITabBar.appearance().standardAppearance = appearance
UITabBar.appearance().scrollEdgeAppearance = appearance
...
```

# 環境
- Xcode 13.0 beta 5
- iOS 15.0

# 背景
`iOS 15`から`UITabBar`の背景が取り除かれたため、明示的に背景色を指定する必要があった。

- UITabBarについて
  - WWDC2021のビデオ 5:40〜 https://developer.apple.com/videos/play/wwdc2021/10059/

# 実装にあたり
`UITabBar`クラスの`standardAppearance (iOS 13.0+)`と`scrollEdgeAppearance （iOS 15.0+）`の２つのプロパティに`UITabBarAppearance`のインスタンスをセットしてタブバーの背景を有効にする。

`standardAppearance (iOS 13.0+)`をセットしないとデフォルトの外観（白？）が設定される。
https://developer.apple.com/documentation/uikit/uitabbar/3198046-standardappearance?changes=_7
（The default value of this property is an appearance object containing the system's default appearance settings.）

`scrollEdgeAppearance （iOS 15.0+）`が`nil`にしてしまうと、背景が透明になる模様。
https://developer.apple.com/documentation/uikit/uitabbar/3750912-scrolledgeappearance?changes=_7
（If the value of this property is nil, UIKit uses the value of the tab bar’s standardAppearance property, modified to have a transparent background.）

# 参考サイト
- StackOverFlow 
  - https://stackoverflow.com/questions/68688270/ios-15-beta-4-uitabbarcontrollers-tabbar-background-color-turns-black
- ドキュメント
  - UITabBar https://developer.apple.com/documentation/uikit/uitabbar?changes=_7
  - UITabBarAppearance https://developer.apple.com/documentation/uikit/uitabbarappearance
  - UIBarAppearance https://developer.apple.com/documentation/uikit/uibarappearance
PowerShellで一日間隔に古いタイムスタンプのファイルを出力する

ファイルのハウスキープだったり、ログローテーションだったりファイル日付で処理判定をしたいケースでは、テストでファイルのタイムスタンプが一日間隔で古くなるファイル群が必要になるケースがあるかと思います。

今回は、そのようなファイル群を生成する`PowerShell`ワンライナーについて。

```PowerShell
# testfile.yyyyMMdd というファイル名で古くなって行くファイルを出力
0..-365 | %{$date=(Get-Date).addDays($_);New-Item -ItemType File -Name "testfile.$((get-date).addDays($_) | Get-Date -Format "yyyyMMdd")" -PipelineVariable newFile | %{ $newFile.CreationTime , $newFile.LastAccessTime ,$newFile.LastWriteTime = $date,$date,$date } }

# testfile-0000-days-ago というファイル名で古くなって行くファイルを出力
0..-365 | %{$date=(Get-Date).addDays($_);New-Item -ItemType File -Name "testfile-$("{0:0000}" -f [math]::Abs($_))-days-ago" -PipelineVariable newFile | %{ $newFile.CreationTime , $newFile.LastAccessTime ,$newFile.LastWriteTime = $date,$date,$date } }
```

実行すると下記のように`CreationTime`、`LastAccessTime`、`LastWriteTime`が一日間隔で古くなるファイル群が生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/4840537f-c402-180f-aefc-2eba4ec54c2f.png)

やっている事としては、`New-Item`コマンドレットで新規ファイルを作成して、作成したファイルの`CreationTime`、`LastAccessTime`、`LastWriteTime`を変更しているだけですね。

## 総評

今回はファイルについては0byteのファイルを生成しますが。
少し改良すれば、任意のファイルサイズだったりで行数で生成する事もできます。
ちょっと感動したflexbox の使い方

試験問題：3つの子要素を、「上下左右中央」に「縦並び」で配置せよ
　　　　（ただしpositionは使用してはいけない）

「display: flex;」を使う必要があるのは分かっていたので、

　「justify-content」水平方向の調整
　「align-items」垂直方向の調整
　「flex-direction」並び順の調整

上記のプロパティを組み合わせてやってみるが、

「縦並びで左右中央だけど、要素が一番上に配置されている」
「上下左右中央だけど、要素が横並びのまま」

と言った感じで、なかなか上手くいかない…。


しばらく考えた結果、「もしかして全部を同時に使う…！？」という考えに至り、
実行してみたところ、見事成功！
全てを同時に使う学習はしてこなかったので、この発想を自分でひらめけたことが
とても嬉しかった。

【実行結果】
　「justify-content: center;」水平方向の調整
　「align-items: center;」垂直方向の調整
　「flex-direction: column」並び順の調整
AWSのEC2の本番サーバーにSSHできなくて詰んだときにやること

### 忙しい人は結論だけ読めばOK
# 本番サーバーにSSHできなくなったから再起動してみるか

EC2サーバーで運用しているサーバーが急にSSHできなくなりました。デプロイ作業時にSSHする必要があったため、SSHしてみると、SSHコマンドが「返事がない、ただの屍のようだ」状態になっていることに気づきました。
（※20−30分放置するとエラーが返ってきます）

経験上、メモリリーク等々でメモリが100％になるとSSHできなくなることは何度か経験していたのですが、サービス自体は正常に動いている模様。まあ、サーバーを再起動すればメモリが開放されますし、大抵SSHできるようになることは知っていたので、メンテナンスのお知らせを出して今回も再起動のボタンをポチッ

# あれれ、おかしいな動かない。しかもSSHできなくて手の施しようがない詰んだ

再起動したらサービスが心停止しました。しかもサーバーにSSHできないので我々はただただ目の前のAWSコンソールに映るサーバーのステータスチェックを見守るのみです。心の中はステータスがお通夜モードに突入！

最悪AMIを取得してサーバーを立て直すかと考えましたが、Docker( ECS )ではないので万が一のことがあるとサーバー環境構築含め、かなり時間がかかってしまいます。嫌な汗が出てきます。

メモリはアラートが出てないし再起動で解消されるはずだからメモリじゃない。じゃあ何だと悩んでいたところもう1つの可能性にたどり着きました。
EBS(ストレージ)のディスク使用率が100％になっていたのです。そこで、まずボリュームサイズを増やすことにしました。でもですね、追加したボリュームはSSHしてマウントしてシステムにここにストレージがあると認識させないといけないんですよ普通は。

でも、SSHできない

詰んだ

# ザオラルを唱える

再起動したらもしかしてボリュームサイズの変更を自動で認識してサーバーに新しくアタッチしてくれるのではないか？ AWSはすごいからきっとそういうことをしてくれるんじゃないか？という一抹の望みを込めてザオラル(再起動)ボタンをコンソールから押します。

# 祈る
懸命に祈りましょう。祈りが届けばサーバーは答えてくれる。日頃の行いがいいので私の祈りは届きました。なんとサーバー再起動でストレージサイズを大きくしたEBSをサーバー側が自動で認識してくれたのです。ありがとう。ちなみにストレージを圧迫した犯人は溜まりに溜まったログファイルでした。あるある過ぎて逆にビックリ。

# 結論

急にSSHができない原因は大抵この2つ

1. サーバーのメモリが<b>100％</b>になる
1. ディスク利用率が<b>100%</b>になる

メモリの場合、サービスの応答速度が遅くなるので気づきやすいのですが、ディスク利用率の場合、サービスは普段どおりに動いたりします。
後者の場合、メモリ問題と勘違いしてサーバー再起動すると私のケースのようにSSHできなくてサービスの復旧が困難になるパターンがあります。ですから、
メモリとディスク容量は最低限、再起動を行う前に確認しておきましょう。はじめからディスク容量と気づいていたらボリュームを増やして再起動するだけで問題は解決していました。（再起動でなんとかなるのはAWSのおかげ。Amazon社に足を向けて寝れない）

また最悪ケースに備えてAMIも再起動前に取っておくと後の障害対応時の復旧が早くなるかもしれません。

SSHできない、何もできないから、とりあえず再起動は辞めましょう。

# おまけ
ログの削除に便利なcronで動かせるコマンドを置いておきます。

```
0 7 * * * /bin/find /var/www/app/log -name '*log*' -mtime +60 -delete
```
「findコマンドを使って logディレクトリ以下にあるlogという名前が含まれるファイルのうち、60日以上更新がないものを削除する。」というコマンドをcronで毎朝7時に起動するという設定です。
LaravelでS3を導入

# はじめに
AWSのS3へ画像をアップロード途中に出会ったエラーがあったので記録として残します。

# 環境
```bash
macOS: "11.2.3 Big Sur"

php artisan -V
# > Laravel Framework 6.20.30

php -v
# > PHP 8.0.8 

nginx -v
# > nginx version: nginx/1.12.2

mysql -h エンドポイント -u マスターユーザー名 -p データベース名
Enter password:
# > Server version: 8.0.25

git --version
# > git version 2.32.0
```

# もくじ
[1. S3パッケージのインストールでエラー](#1-s3パッケージのインストールでエラー)
[2. S3のアップロードでエラー](#2-s3のアップロードでエラー)


# 1. S3パッケージのインストールでエラー 

パッケージをインストールしようとしたら以下のエラーが。

```terminal
# composer require league/flysystem-aws-s3-v3

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - league/flysystem-aws-s3-v3[2.1.0, ..., 2.x-dev] require league/flysystem ^2.0.0 -> found league/flysystem[2.0.0-alpha.1, ..., 2.x-dev] but the package is fixed to 1.1.3 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
    - Root composer.json requires league/flysystem-aws-s3-v3 ^2.1 -> satisfiable by league/flysystem-aws-s3-v3[2.1.0, 2.x-dev].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.
```
色々調べていると、バージョンの違いが原因でインストールできないらしい。

https://readouble.com/laravel/8.x/ja/filesystem.html#composer-packages

https://qiita.com/ucan-lab/items/61903ce10a186e78f15f

公式に記載されているコードでもう一度入力すると無事パッケージがインストールされました。

```
# composer require league/flysystem-aws-s3-v3 "^1.0"
```



#2. S3のアップロードでエラー

## The PutObject operation requires non-empty parameter: Bucket
画像をアップロードしようとしたら以下のエラーが。

```
The PutObject operation requires non-empty parameter: Bucket

（訳） PutObject操作には、空でないパラメーターが必要です
```

## 解消
以下のサイトを参考に上記のエラーは無くなりました。

https://spreadsheep.net/post-814/

```terminal
# php artisan config:clear
```
やはりキャッシュ削除は忘れがち。
一通りのキャッシュを削除する癖をつけないといけないですね。

```
# php artisan cache:clear
# php artisan route:clear
# php artisan view:clear
```

# 参考
実装にあたり以下のサイトを参考にしました。

https://qiita.com/nobu0717/items/51dfcecda90d3c5958b8#view-1
【資格】G検定に受かったから記録を残す

# はじめに
オッス、オラIT革命戦士！
2021/7/17(土)にG検定っていう試験を受けて合格したから勉強方法とか書いてくぞ！

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461645/ba9d8bdf-9838-3d53-d825-1f713674b626.png)|
|:--|

オラはなんとか合格したのに合格率高めで世の中つえぇやつばっかだなって実感したぞ！


# G検定とは

https://www.jdla.org/certificate/general/#general_No01

G検定ってのは日本ディープラーニング協会(JDLA)っていうところがやってる試験で、機械学習やディープラーニングの歴史的経緯や基本的な知識、日本での関連法律が問われる試験だぞ。統計の尤度比検定のことじゃないからな！

試験の目的はWikipediaによると

> 特にディープラーニングの基礎知識を有し、適切な活用方針を決定して事業応用する能力を持つ人材の輩出を目的として

らしいぞ！

https://ja.wikipedia.org/wiki/JDLA_Deep_Learning_For_GENERAL

この試験は年3回開催されてて、次は2021/11/6(土)だから受験予定のやつは忘れないように！

# オラのことが知りてぇってか？おめえ変わってんな！
私は某メーカー系のIT子会社に勤務しており、日頃は工場向けの生産管理システムの開発や運用に従事しております。
昨年度から、製造現場向けにAIを活用したソリューションを提案できないか模索しており、画像認識や音声認識に関するAI技術の調査を行っております。
この活動の中で、独学でPythonとTensorFlowを使ってCNNのAIモデルを作成したり、AWSやAzure、GCP、IBM Watsonなどのクラウドサービスに用意されたAIサービスをがどの程度実用に耐えうるのかなどを検証したりしていました。
今回、せっかくAIについて勉強しているのだから、ディープラーニングの入門試験としてG検定を受験しようと思った次第です。

私がG検定のために勉強したのは30時間程度ですが、上記の通り事前知識が少しあったので、全くの無知識の状態からより短いかもしれません。
ちなみに大学では、様々な環境で微生物を培養してどんなタンパク質が多く発現するかなどを調べており、機械学習やディープラーニングの知識は全くありませんでした。

# 勉強方法
よっしゃ！ここからはオラが受験までにやった勉強内容を紹介すっぞ！
つってもそんな特別なことやったわけじゃねーから期待すんなよ！

## 1. 本を読む
JDLAが推薦してる本を2冊読んだぞ！

最初に読んだのが「人工知能は人間を超えるか」だ！
これまでAIを専門的に扱ってきたわけじゃなかったから、優しい内容で始めたかったからこれを選んだんだ！
AIの歴史や、AIの得意・不得意、3つあったAIブームの内容、そんでAIがこれからどうなっていくのか、それを見据えてどう準備しておいたほうがいいのかなど読みやすい内容で書かれてるぞ！
この本はKindle版を買ったんだが、個人的に電子書籍は頭に入りにくくて紙の本で買えば良かったと思ったぞ！

https://www.amazon.co.jp/gp/product/B00UAAK07S/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

<br/>
次に読んだのが、「G検定公式テキスト第2版」だ！これは最初から紙の本を買ったぞ！
内容は「人工知能は人間を超えるか」のディープラーニング手法の部分が深堀りされた感じの内容だった！正直全部は理解できなかったぞ！
AIの歴史とかの部分も最初にあったけど、そこは「人工知能は人間を超えるか」とかなりかぶってた感じだ！

https://www.amazon.co.jp/gp/product/4798165948/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

## 2. 練習問題を解く
テキスト2冊読んだあとは、紙の本の問題集とStudy-AIってサイトの練習問題を解いたぞ！
解けない問題も結構あったが、解説読んでなんとなくわかった感じで進めてって、とりあえず数をこなしていったぞ！

紙の本の問題集はどれ選べばいいかわからなかったから、Amazonで評価が高そうなやつを適当に選んだぞ！
最後までやる時間はなかったけど、ディープラーニングの手法のところが苦手そうだったからそこを中心的にやったぞ！

https://www.amazon.co.jp/gp/product/429711609X/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

</br>
Study-AIでは太っ腹なことにタダでG検定の解説付き例題を200問近く出してくれてるぞ！
ユーザ登録が必要だからそこだけ注意な！

https://study-ai.com/generalist/

# 最後に
2時間で200問前後が出されるから、パッパッパと解いていって、わからなかった問題はマークして余った時間で考えるようにするのがいいと思った。
練習問題と似た問題は何個か出た。バッチリ同じ問題だったのも2問くらいでた。
この資格がなんかの役に立つかと言われれば多分立たないし認知度も低いけど、足の爪の先くらいはAIに関するジェネラリストになれた気分がする。
受験前、個人的にはAIの歴史的経緯とか法律周りとか覚えるの面倒そうだなって思ったけど、むしろそこは楽しく覚えられるし一般常識で通じる。やはり敵はディープラーニングの技術に関する問題。略語が多くて頭こんがらがるんじゃい！

じゃあね、チュッ❤
Dockerとは？

##[Docker]の概念。
Dockerとは、Go言語で作成されたリナックスコンテナ基盤のオープンソース仮想化プラットフォームだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465875/a2312406-cabc-bdbc-e069-94b0f336d3ed.png)

###仮想化を使う理由は？

向上したコンピュータの性能をより効率的に使うために仮想化技術が多く登場した。
サーバー管理者の立場では、CPU使用率が10%台にしかならない活用度が低いサーバーのリソースの無駄にならざるを得ない。 
だからといって、全てのサービスを一つのサーバーの中に入れると、安定性に問題が生じかねない。 
そこで安定性を高め、リソースも最大限に活用できる方法で現れたのがサーバー仮想化である。 
皆さんが知っている代表的な仮想化プラットフォームとしてVMがあります。

####コンテナとは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465875/d0cb7f3a-c726-b4c7-a125-b57ae636c00c.png)
コンテナは、仮想化技術の一つとして、代表的にLXC（Linux Container）がある。 従来OS を仮想化させていたものと異なり、コンテナはOS レベルの仮想化でプロセスを隔離して動作する方式で行われる。
一サーバの複数のOSを仮想化して使用するのと、コンテナ方式でプロセスを隔離して動作するのとでは、どのような違いがあるのか？

####VM仮想化プラットフォームvsDocker仮想化プラットフォーム

既存の私たちに慣れたVMの場合は、HostOSの上に仮想化させるためのHypervisorエンジン、そしてその上にGuestOSをのせて使う。
これは仮想化されたハードウェアの上にOS が乗っかる形でほぼ完璧にHost と分離されると考えてよい。 
反面、コンテナ基盤の仮想化はDockerエンジンの上にApplication実行に必要なバイナリだけが上がるようになる。 
OS仮想化を見ると、Host OSと完全に分離されるメリットはありますが、OSの上にOSを乗せるために重くて遅くならざるを得ませんが、コンテナ基盤の仮想化は、Host OSそしてDockerエンジンの上ですぐに動作し、Hostのカーネルを共有します。 
カーネルを共有すればio処理が簡単になり性能の効率を高めることができる。
コンテナを使用することは、仮想マシンを生成するのではなく、HostOS が使用するリソースを分離して、様々な環境を作れるようにすることである。 

コンテナ基盤はOS仮想化より優れていると言われているが、必ずしもそうではない。

OS 仮想化はコンテナベースの仮想化よりも高い隔離レベルをサポートしている。 
これはセキュリティ的な面でさらに有利だ。
またOS 仮想化のカーネルを共有しないメリットもある。 
カーネルを共有しないため、マルチOSが可能だ。 
カーネルを共有しないためにマルチOSが不可能であることは、Linux 上にWindow を載せることができないという短所がある。 
にもかかわらず、なぜDockerを使う理由は<b>性能向上、優れた移植性、簡単にScale Outができる</b><font color="deep pink">柔軟性</font>だ。
【Xcode】ビルド時にエラー "error: exportArchive: Provisioning profile “App Name” doesn’t support the Associated Domains capability."

# どういうことか

多分あなたはFirebase Dynamic Linkの実装をするとかで `Associated Domains` あたりの設定を変更したらこんなエラーが出てビルドできなくなったのでは？

---

:x: error: exportArchive: Provisioning profile “App Name” doesn’t support the Associated Domains capability.
:x: error: exportArchive: Provisioning profile “App Name” doesn’t include the com.apple.developer.associated-domains entitlement.

---

新しくProvisioning Profile（署名）をダウンロードして更新してあげたら直る。

## 手順

Apple DeveloperのProfilesの一覧の右端が **Download** という表記ではなく **Invalid** になっていて署名がダウンロードできなくなっている。
選択して **Edit** を押し、特に何もいじらなくていいので **Save** するとダウンロードできるようになった。あとは署名をダブルクリックしてXcodeに登録するだけ。

**【iOS】プロビジョニングプロファイル更新手順**
<https://qiita.com/Labi/items/d93624e4f6ec7d073e76>
Prisma2とは？

最近ノード.jsでサーバ開発を進める際にPrisma2を使っている。 それで簡単にまとめてみる。 
ちなみにprisma2 はprisma1 とは異なる。 (ここではprisma2をprismaと説明する)

始める前にORMの概念を整理しておいたので、軽く読んでくるのがおすすめだ。
 
https://qiita.com/justNOZA/items/8e9ac1301ccdefa155a4

###prismaはORMなのか？

prismaがORMであるかと聞かれたら、ORMと同じ目的を持っているが、他のアプローチを使用していると答えることができる。 つまり、違うという。

データをモデリングしてPrismaクライアントを生成すると、上のようにprisma.userを通じてUserテーブルにアクセスできます。
ただし、Prismaは常にJavaScriptオブジェクトを返却するため、開発者は返還されるオブジェクトの形態を知っていなければなりません。


###PRISMAは何だ？

Prismaはデータベースツールキットである。 ツールキットと呼ばれる理由は、三つの要素からなるセットであるからである。

1. Prisma Client : Node.js & TypeScriptのためのクエリビルダー
2. Prisma Migrate : データモデリング&マイグレーションシステム
3. PrismaStudio : モデリングとデータ管理ができるGUI

前述のPrisma スキーマはPrisma のツールを使うための始まりである。 Prismaスキーマはschema。prismaというファイルで管理される。 schema.prismaを通じてモデルを宣言することができ、既に存在するDBをインポートしてもらうことができる。

データをモデリングしてPrisma CLIを使用すれば、モデリングと意味が同じテーブルが自動的に生成される。(テーブル間のRelationまで)
このようなモデリングを行う場所がschema.prismaだ
【UNITY　C＃】自身の子オブジェクトを全てコピーして、任意のオブジェクトの子オブジェクトとしてペーストするテンプレ


public Transform SampleTran;//任意のオブジェクトの位置をパブリックで取得
      //（インスペクターからドラッグアンドドロップで設定してね）

    public void Copy()
    {
        // 子の数を数える
        int ChildNum = transform.childCount;

        //forを使って子の数の分だけ繰り返す
        for (int i = 0; i < ChildNum ; i++)
        {
            //子オブジェクトをゲームオブジェクトとして取得
            GameObject Mychild = transform.GetChild(i).gameObject;

            //子オブジェクトのコピーをSampleの子オブジェクトとして生成(位置や大きさは上で設定した任意のオブジェクトに依存）
            GameObject MychildrenClone = Instantiate(Mychild);
            MychildrenClone.transform.SetParent(SampleTran, false); 
        }
    }



基本コピペで動く筈
不具合とかあったら教えてクレメンス

追記　多分２D限定
https://mizutanikirin.net/unity-clonegameobject
ここに３D用のアレコレとか書かれてる
ORM（Object-Relational Mappings）とは何だろうか。


##ORM?

ORMというものを単純に表現してみると、オブジェクトとの関係との設定？ ぐらいだと言える。 ここでいうオブジェクトとは、OOP(Object-Oriented Programming)のオブジェクトであり、関係というものが意味するものは、開発者がよく使っている関係型データベースを意味する。

##これを利用する理由？

オブジェクトと関係型データベース間のマッピングをサポートするFrameworkやToolが出てくる理由はBacktobasicsだと言える。 すなわち、よりOOPらしいプログラミングをしようということから出発した。

開発者があるアプリケーションを作る際に関連する情報はオブジェクトに格納されることになる。 

####例えば住所録を作ると考えてみよう。 
* 住所録に人という客体があり，その客体にはマイナンバー，名前，身長，体重などが保存されている。
* 住所または電話番号が保存される他のオブジェクトもある。 

これを永久的に保存するためにファイルやデータベースに入力をするとすれば、オブジェクトとオブジェクトの関係をデータベースのテーブルに保存することになる。 

つまり、テーブルにオブジェクトが持っていた情報を入力し、テーブルをjoinのようなsqlquery文で関係を設定することになる。 

##### 問題はtableとオブジェクト間の異質性が発生するということだ。

ORM Frameworkは異質性を解決するためにオブジェクトとテーブルとの関係を設定して自動的に処理してくれるものである。

次のようなPerson というオブジェクトがあると仮定する。

```java
public class Person {
   private String name;
   private String height;
   private String weight;
   private String ssn;
  // implement getter & setter methods
}
```
iBatis の場合には、次のようにmapping file 内で当該query の結果を受けるオブジェクトを指定することができる。

```xml
<select id="getPerson" resultClass="net.agilejava.person.domain.Person">
  
  SELECT name, height, weight, ssn FROM USER WHERE name = #name#;

</select>
```
getPersonと定義されたqueryの結果はnet.agilejava。person.domain の Person オブジェクトに自動で mapping されるものである。 
Hibernateの場合には、mappingファイルで次のように表現してくれる。

```xml
<hibernate-mapping>
        <class name="net.agilejava.person.domain.Person" table=person”>
               <id name="name" column="name" />
               <property name="height" column="height" />
               <property name="weight" column="weight" />
               <property name="ssn" column="ssn" />
        </class>
</hibernate-mapping>
```

複雑に見えるかもしれないORMだが、使ってみると思ったより楽になる。 単純にgetsetだけをしてあげることが目的ではなく、オブジェクト指向的なシステムのために関係型データベースの設計から変化を与え、設計されたデータベースとオブジェクトとの関係に対する設定などを含めてよりオブジェクト指向的なシステムの完成のためのツールである。
並列処理(マルチスレッド)についての備忘録①

## スレッドとは
- プログラムを実行した処理の最小単位
- javaコマンドを実行すると新しいスレッドを作成し、そのスレッド上で指定したクラスのmain()メソッドを実行している

## スレッドを作成する方法
#### Threadクラスを継承してサブクラスを定義
- run()メソッドをオーバーライド
- メインメソッド内でstart()メソッドを実行

```java
package cp8.no1;

public class Main {

	public static void main(String[] args) {

		// スレッドの作成
		ThreadA threadA = new ThreadA();
		ThreadB threadB = new ThreadB();

		// スレッドの実行開始
		threadA.start();
		threadB.start();
	}
}

// 1つめのクラス(Threadクラスを継承)
class ThreadA extends Thread {

	@Override
	public void run() {

		for(int i = 0; i < 3; i++) {
			System.out.println(i + "回目：ThreadAを実行");
		}
	}
}

// 2つめのクラス(Threadクラスを継承)
class ThreadB extends Thread {

	@Override
	public void run() {

		for(int i = 0; i < 3; i++) {
			System.out.println(i + "回目：ThreadBを実行");
		}
	}
}

```

### 一回目の実行結果
```console
0回目：ThreadAを実行
0回目：ThreadBを実行
1回目：ThreadAを実行
1回目：ThreadBを実行
2回目：ThreadAを実行
2回目：ThreadBを実行
```
### 二回目の実行結果
```console
0回目：ThreadAを実行
1回目：ThreadAを実行
2回目：ThreadAを実行
0回目：ThreadBを実行
1回目：ThreadBを実行
2回目：ThreadBを実行
```

※実行結果が毎回変わる。それぞれのスレッドが独立して動作している為。

#### Runnableインターフェイスの実装
- run()メソッドをオーバーライド
- Runnableインターフェイスを実行したクラスオブジェクトをThreadクラスのコンストラクタの引数にわたす
- メインメソッド内でstart()メソッドを実行

```java
package cp8.no2;

public class Main {

	public static void main(String[] args) {

		// スレッドの作成
		Thread threadA = new Thread(new ThreadA());
		Thread threadB = new Thread(new ThreadB());

		// スレッドの実行開始
		threadA.start();
		threadB.start();
	}
}

// 1つめのクラス(Runnableインターフェイスを実装)
class ThreadA implements Runnable {

	@Override
	public void run() {

		for(int i = 0; i < 3; i++) {
			System.out.println(i + "回目：ThreadAを実行");
		}
	}
}

// 2つめのクラス(Runnableインターフェイスを実装)
class ThreadB implements Runnable {

	@Override
	public void run() {

		for(int i = 0; i < 3; i++) {
			System.out.println(i + "回目：ThreadBを実行");
		}
	}
}

```

### 実行結果
```console
0回目：ThreadAを実行
0回目：ThreadBを実行
1回目：ThreadAを実行
2回目：ThreadAを実行
1回目：ThreadBを実行
2回目：ThreadBを実行
```

#### Runnableインターフェイスのrun()メソッドは匿名クラスやラムダ式を用いて実装することも可能
- Runnableインターフェイスは関数型インターフェイス。抽象メソッドがrun()ただ一つだけ

``` java
package cp8.no3;

public class Main {

	public static void main(String[] args) {

		// 匿名クラスを使用
		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("匿名クラスの実装");
			}
		}).start();

		// ラムダ式を使用
		new Thread(() -> System.out.println("ラムダ式で実装")).start();
	}
}

```

### 実行結果
```console
匿名クラスの実装
ラムダ式で実装
```

## ふりかえり
- マルチスレッドとはプログラムの実行単位を複数スレッドに分割して実行すること
- マルチスレッドで実行すると結果が毎回異なる
- マルチスレッドを実装するには①Threadクラスを継承, ②Runnableインターフェイスを実装する
- run()メソッドの実装には匿名クラスやラムダ式の使用ができる

## その②へ
https://qiita.com/takaakitanaka_cre-co/items/62f8610ee181f07f5fe6
なぜ見積もりの段階で実装されるのか

先日Twitterで「作業見積もりを聞きたいだけで完成した物が出てきて困惑している」というものがありました
今回はその理由を掘り下げたいと思います

## 下調べしたら終わった

作業見積もりって実はコストがかなり高いです。
商品開発に5年かかった、みたいなことはたまに聞きますし、
その場合、5年前に「5年かかります」と答えられるかというと、そんなはずはないですね。

一度やり方を確立したものは見積もりを出せますが、
そういうのがない状態では見積もりなんて出せません

場合によっては、調べたら前担当者がすでに作っていたとか、
特定のデータを参照するだけで欲しい物が出てきたとか、
逆にあっという間に終わる場合もあり、そういう場合は終わった、となります

## 機能を絞っている

「6月の集計データを見たい」といってすぐにデータが出てきました
では、「任意の月のデータが見たい」となるとどうでしょうか

まず任意の月の入力をどうするか、という問題があります
カレンダー画面を出して指定したい、となればその機能を使う方法を調べる必要があります

また、祝日データを登録する必要があるかもしれません
6月のときはカレンダーをみてぱぱっと登録したわけですが、
今年みたいに祝日が移動すると考えると祝日設定画面も必要になります

また、結果も別のデータと突き合わせて問題ないと確認できますが、
すべての月に対して問題ないのかも確認しないといけません

実際、例外ケースというのはそんなに発生しないことが多いですが、
その例外も10個20個と数を増すと、かなりの量になります
実際、作業の大半がその例外ケースの対応ということも珍しく有りません

今欲しいものを手作業でやるのは簡単だけど、
量産化となると手間が増えるのですぐにはできない、という感じが
わかりやすいかもしれません

## 触らないとわからない

話の中でも「すぐに作ってくれるのはありがたいが、ぜんぜん違うものができていた」と
困惑する様子もあります

実は考えを言語に落とし込むのは相当難しいです
「頭の中では完全にできている」というのは誰でもできますが、
それを外部に見える形にアウトプットできるのは少数です

[顧客が本当に必要だったもの](https://dic.nicovideo.jp/a/%E9%A1%A7%E5%AE%A2%E3%81%8C%E6%9C%AC%E5%BD%93%E3%81%AB%E5%BF%85%E8%A6%81%E3%81%A0%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE)

「○○(ブランコのような説明だが、ブランコという単語は出てこない)が
ほしいんだけど見積もり出してくれない？」と来たらどうでしょうか

そういう受注を受けた場合、くどくどと話し合うより
木にロープをくくりつけたものを見せて「ぜんぜん違うんだけど？」というところから
話を発展させたほうが早い、ってなります

さらに、今回は違うかあっているかの確認が目的なので、
ロープの代わりにタコ糸、板の代わりにダンボールでも構わないわけです
そこで、イメージ通りだった、となったときに初めて
人が乗っても大丈夫なロープや板に切り替えていく、という感じです
[Android] 簡単にSnackBarに戻るボタンの動作(ActionButton)を追加してみる

# 初めに
スナックバーの戻るボタンの動作（アクションボタン）が案外簡単に実装できるようになっていたためここにメモ代わりに保存しておくことにした。
案外簡単で分かりやすくまとまっていると思ったので、ぜひ使ってみてほしい。

![IMG_20210813_121448.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209385/d51ec3c2-fd7d-6b34-84e9-a437cb245066.jpeg)


# 動作の内容

```kotlin
//MainActivity.kt

Snackbar.make(findViewById(android.R.id.content),"保存しました", Snackbar.LENGTH_SHORT)
　　　　　　　　　　　　//戻るボタンの動作
                    .setAction("元に戻す"){
                        Log.d("debug","もとに戻る動作を書くよ！！")
                    }
　　　　　　　　　　　　//戻るボタンの色
                    .setActionTextColor(ContextCompat.getColor(this@MainActivity, R.color.color_name))
                    .show()
```

# 動作の解説

##### スナックバーの作成
```kotlin
Snackbar.make([表示される場所],[表示される文字], [表示される長さ])
```

##### アクションボタンの作成
```kotlin
.setAction([アクションボタンに表示される文字]){
　　　　[ボタンを押したときに動作する内容]
}
```

##### アクションボタンの文字の色の指定
```kotlin
.setActionTextColor(ContextCompat.getColor(context, [カラーXMLに記入している名前]))
```

##### スナックバーの表示
```kotlin
.show()
```

# 参考資料

https://developer.android.com/training/snackbar/action?hl=ja

https://www.fixes.pub/program/44722.html
さくらインターネットのHacobuneでNode-REDの公式イメージを動かしてみる。

さくらインターネットで2021年8月12日にHacobuneというKubernetesベースのPaaS型クラウドサービスのオープンβがスタートしました。
私自身はガッツリエンジニアというわけではないですが、公式のNode-RED公式コンテナイメージを使って簡易的なBasic認証を含めてデプロイするところまでをメモ書きとして残しておきます。

アカウントの作成および基本的な使い方は @Yoshihiro-Hirose さんの以下記事を参照ください。
この記事ではプロジェクトが作成された後のアプリケーションの作成から紹介します。
https://qiita.com/Yoshihiro-Hirose/items/7a3107fa3b0bd39603fe

# アプリケーションの新規作成
* 作成したプロジェクトをクリック
* 新規作成ボタンをクリック
* アプリケーション名を入力
* デプロイ方法で __Docker__ をクリック
* Dockerイメージ名に __nodered/node-red:latest__ を入力
* ポートにNode-REDのデフォルトポートである __1880__ を入力
* 外部公開を __有効__ にして、任意のサブドメインを入力およびドメインを選択
* Basic認証を __有効__ にして、追加ボタンをクリックしてユーザー名およびパスワードを入力
* 作成ボタンをクリック

作成画面としてはこんな設定がされていればOKです。
![作成画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217223/2f64b181-3f69-49f1-0665-91a9b5d460e0.png)

#動作確認
プロジェクト画面に戻ってしばらくすると作成したアプリケーションが稼働中ステータスになります。
![プロジェクト画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217223/abdd20c0-6cbc-4c06-6c54-bbb59976910c.png)

リンクをクリックするとBasic認証のダイアログが表示されるので事前に指定したユーザー名およびパスワードを入力します。
![Basic認証ダイアログ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217223/02b6dc93-df9f-7a73-3801-6affd6a236c6.jpeg)

認証を通過してNode-REDのエディタ画面が表示されることを確認します。
![FireShot Capture 218 - Node-RED _ ny-nodered.c1.hacobuneapp.com - ny-nodered.c1.hacobuneapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217223/6045b1de-0973-36c0-4f1a-21cd09d46dbe.png)

:::note info
エディタ画面が表示されずBadGateway画面が表示される場合は、ポートが80番等、1880以外が指定されていないか確認しましょう。
:::

#終わりに
以上がHacobuneに簡易的にNode-RED環境を立ち上げる手順となります。
今の内容だとバージョン指定や作成したフローが永続化されずコンテナの再起動等で消失してしまうかと思います。
今後手が空いたら、勉強がてら永続化やDockerfileによる任意の初期設定の追加についても書いてみたいと思います。
(Unity  C#) 日本語化したUNITYでプレハブ化したオブジェクトを解除する方法

![スクリーンショット 2021-08-13 124349.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1884261/f752d76e-543c-7122-8dda-e51057569440.png)

プレハブ化したオブジェクトを右クリック
プレハブを選ぶ
展開をクリック

要するに写真の通り。

終わり！　閉廷！
名刺をデータ化していつでも検索できる仕組みを作ろう

#取引先の連絡先を知りたいけど、連絡先がわからない事を解決したい
自分の仕事は何十もの取引先があり、百人単位の相手がいます。
昨日、「この人の連絡先知らない？」と先輩に言われて、メールの署名から探したのですが、読み返しても、署名が書いていない人でした。
でも「あの時名刺を貰ったな。どこに保管していたっけ？」と山積みになった名刺からその人を探しました。
#名刺をデータ化すれば解決するのでは？
考えてみると連絡先に限らず、品物を送るための住所を調べるのにも毎回名刺や、膨大なメールの中から検索している事に気が付きました。
これは無駄な時間ではないでしょうか。
Excelやメモ帳に記入する事もしていましたが、<font color = "RED">紙に書いてある事を転記するのは手間がかかるので、やりたくないし、つい忘れてしまいます。</font>
そこでLINEのScan text機能を利用して、OCRでデータ化し自分自身のメールアドレスにとりあえず送っておき、データとして保管する仕組みを考えました。
#利用した機能
LINE
integromat
Gmail
#処理の流れ
##①LINEのSCAN textで写真を撮って、OCRの内容をintegromatに送ります。
【やり方について】
https://appllio.com/line-how-to-use-ocr
##②メールが届きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1806653/79eb2e50-3176-1f63-174a-dc1d5aef2c63.png)
#integromatの設定
LINEのWatch EventsとGmailのSend an emailを利用しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1806653/433cf853-368d-d867-bef0-1a2875697d11.png)
##①Watch Eventsの設定
ChannelAccessTokenとUserIDをLINEDevelopersから取得し入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1806653/aec8ac39-fe90-0712-c31b-020e4909959c.png)
WebhookのURLが発行されるので、LINE DevelopersにあるWebhook設定に発行されたURLを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1806653/5ab337c8-9f76-25d4-63d7-e1c29e7bf882.png)
##②Send an emailの設定
事前にGoogle Cloud PlatformでintegromatでGmailが利用できるように設定が必要です。
【手順】
https://www.integromat.com/en/help/connecting-integromat-to-google-services-using-a-custom-oauth-client
Toや見出し、Contentには2.Events[1]:Message:Text（LINE本文）を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1806653/e576630d-e2e2-49be-3f42-fa9d117e528c.png)
うまく設定できるとメールが自動で送信されます。
#連絡先を検索する手間が無くなった
とりあえず自分のメールフォルダに名刺のデータを入れておくことにしました。
今後はそこで検索するだけで、連絡先や住所がわかるので、いちいち探す必要もなくなります。
今までは業務自体を改善する事を考えましたが、日常のちょっとした煩わしさをなくす事でやりたい事に注力できるはずです。
初級：Javascript勉強

#基礎知識
##変数の基本的な考え方
変数とは、特定の名前をつけて、それに該当するデータを入れる箱。中に入るデータはコードによって入れ替わる。
値とは、変数の箱に入れるデータ。

##変数の命名
1. 推奨
    1. 英単語を用いる
        1. number
    1. 2語以上の場合は、２語目以降の単語の１文字目を大文字にする
        1. companyName
1. 禁止
    1. 数字で始まる
        1. 1number
1. 非推奨
    1. ローマ字を使用する
        1. kaisyamei
    1. 日本語を使用する
        1. 会社名

##変数に関する記法

###変数を定義する
変数を定義するには let を使用する。
let 変数名　= 値;

```js
例
let name = "高橋";
```

###変数を出力する
特定の値が変数に代入されている状態で、変数を出力すると、その時に変数に代入されている値を出力できる。
変数を使用する際には、クォーテーションでは囲わない。（囲うと文字列だと認識されてしまう）

```js
例
console.log(name);
```

###変数を文字列や数値として使う
また変数は、文字列や数値と同じく、計算や連結に使用ができる。

```js
例
console.log(name + "くん");
let number = 8;
console.log(number + 4);
```

###定義済みの変数に値を代入する
定義済みの変数の値を変更したい際には、letは使用せずに、「変数名 = 値」で値を変更できる。
その際に、元々格納されていた値に上書きされて新しい値が代入される。

```js
例
name = "江原";
```

###定義済みの変数の値を基準に変更を加える
定義済みの変数の値（例.数値の3）に、5を加えた数字を変数に格納したい場合は、「変数 = 変数 +5」をという書き方をする。

```js
例
number = number + 5;
```

またこれには省略した書き方存在する。

```js
number = number + 5;
=> number += 5;

number = number - 5;
=> number -= 5;
```

##定数の基本的な考え方
変数と同じような使い方をするが、定数は「一度定めた値を変更できない」という性質を持つ。
※変更を行おうとすると、エラーが発生する。
変更が必要がないデータに対して、意図せず変更を加えてしまうことを防止する効果がある。

##定数の命名
定数を定義する際には「const 変数名 = 値」を使用する。

```js
const name = "会社名";
```

##テンプレートリテラルについて
文字列や定数の連結に「+」を使用する方法もあるが、テンプレートリテラルを使用すると、文字列の中に定数や変数を埋め込むことができるようになる。

書き方は　${変数or定数}　を使用する。
※この際に「``（バッククォーテーション）」で文字列を囲うことに注意する。

```js
let language = "英語";
let yearLearn = "8";
console.log(`僕は${language}を${yearLearn}年勉強しています。`);
```

##条件分岐について
条件分岐とは「ある条件が成り立つ時に、ある処理を行う」という分岐のこと。
条件分岐のある処理を行うには、if文を使用する。

if文は、条件をまず書き、それが成り立つ場合の処理を{}の中に記述する。

```js
let number = 10;
if(条件を書く){
  console.log("numberは５より大きいです");
}

条件を書くと
if(number > 5){
  console.log("numberは５より大きいです");
}

```


#記法
##コンソールに文字を出力する

```js
console.log("Hello World");
console.log("3 + 1"); // 「'」 「"」で囲うことで文字列として出力できる
```

##数値を計算する
```js
足す：
console.log(8 + 2);

引く：
console.log(3 - 1);

かける：
console.log(9 / 3);

割る：
console.log(2 * 4);

割って余りを求める：
console.log(7 % 2);
```

##文字列を結合させる

```js
console.log("東京都" + "練馬区");
console.log("20" + "21");
```

##変数に値をいれる（代入する）
```js
let 変数名 = 値
```
letsenrypt ssl ドメイン追加（サーバー間移動）

ドメインをサーバー間で移動したい。
新しい移転先サーバーで新しくletsencryptの設定をするだけで良い。

# 前提

・ネームサーバーの設定が完了している
・サーバーのコントロールパネルでDNSを当該サーバーに向けている

# 1 まずは新サーバーのnginxにドメインを追加


```/etc/nginx/conf.d/default.conf

server {
    listen 80;
    server_name pro-nail.me;
    return       301 https://pro-nail.me$request_uri;
}

```

再起動
` sudo systemctl restart nginx`

# 2 certbot をスタート

それぞれパスを変更してね

```

/home/hideki/certbot/certbot-auto

```

今回は nginx なので、最初の設問は

```

2: Nginx Web Server plugin (nginx)

```

を選択。

```

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
1: xxx.com
2: pro-nail.me
3: twi.ski
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

```

ドメイン追加されましたね。
では、2を入力してエンター。

```

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:

```

って表示されたらOK

# 3 nginx の設定を変更

`/etc/nginx/conf.d/default.conf` の設定を変更する。
コツとしては、旧サーバーから新サーバーに移転する場合は、旧サーバーの設定をそのままコピーすると動かない場合がある。

よって、新サーバーに設定されている他のドメインの設定をコピーして、
ドメイン名だけ変更すると動く。
【Swift】Pusherを使ってリアルタイム双方向通信を実現する

## Pusherとは
[公式Webサイト](https://pusher.com/channels/pricing)
- WebSocketを用いてリアルタイムの双方向通信機能をWebやモバイルアプリに組み込むサービス

※今回はモバイル側の実装のみ書いています

## PusherをiOSに組み込む
### ライブラリの導入
[PusherSwift](https://github.com/pusher/pusher-websocket-swift) を使用する。

- PodfileにPusherSwiftを追加する

```Podfile
pod 'PusherSwift'
```

## Swift側での受け取りを実装する
- Pusherのdataはjsonで定義して、フロントでは構造体にマッピングすると使いやすいです


```swift
private func setObservePusher() {
    pusher = Pusher(key: "APP_KEY")
    let channelName: String = "CHANNEL_NAME"
    let channel = pusher?.subscribe(channelName)
    channel?.bind(eventName: "EVNT_NAME", callback: { (data: Any?) -> Void in
        // Pusherの通知が来るとここに入る
        // 私のおすすめはCodableで構造体にマッピングすること
        let json = try JSONSerialization.data(withJSONObject: listener, options: [])
        guard let jsonStr = json.toString else { return }
        guard let transrate = PusherResponse().transrate(jsonStr: jsonStr) else { return }
    })
}

// MARK: Pusher側のメッセージをjsonの形で送る
// それに合わせて構造体を定義する
class PusherResponse: Codable {
  var id: Int
  var name: String
}

extension PusherResponse {
    func transrate(jsonStr: String) ->PusherResponse? {
        var response: PusherResponse?
        do {
            let jsonString = (jsonStr)
            let jsonData = jsonString.data(using: .utf8)!
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            response = try decoder.decode(PusherResponse.self, from: jsonData)
        } catch let error {
            print("error: \(error.localizedDescription)")
        }
        return response
    }
}
```

## Debug Consoleでテストしてみる
- PusherにログインしてDebug Consoleを開く
- 必要な情報を入力してSend eventを押下するとリアルタイム通信が送られます
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/f21860dd-871b-ac67-c86d-9d25c008144d.png" width=80%>
突然WARNING: `pyenv init -` no longer sets PATH.と出た日の対処法

# ターミナルを開いたら変な文字が…

今日、ターミナルを開いたら、突然以下のメッセージが表示された。。

![スクリーンショット 2021-08-13 11.19.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262827/c2ecf076-8292-42df-e821-51a59a5b934b.png)



# 実行環境と状況
macOS Mojave
* ターミナルはzshではなく、bashです。

python2.7とpython3.7が入っていて、npmのパッケージで一部python2系が必要だったので、完全に3系に移行はできない状態ということもあり、これまでいじり倒しすぎてpython環境がわけわからないことになっていたので、Anaconda消したり最近整理中で迷走中です。

とりあえずpyenvが使えないと切り替えができないので困ったという状況でした。


# 試したこと
### エラーメッセージに書いている通り$ pyenv -initしてみる
訳がわからない…

とりあえずエラーメッセージで促された通り、　`$ pyenv -init`をターミナルへ入力してみました。
出力内容はこんな感じ。

```terminal
$ pyenv init

# (The below instructions are intended for common
# shell setups. See the README for more guidance
# if they don't apply and/or don't work for you.)

# Add pyenv executable to PATH and
# enable shims by adding the following
# to ~/.profile:

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"

# If your ~/.profile sources ~/.bashrc,
# the lines need to be inserted before the part
# that does that. See the README for another option.

# If you have ~/.bash_profile, make sure that it
# also executes the above lines -- e.g. by
# copying them there or by sourcing ~/.profile

# Load pyenv into the shell by adding
# the following to ~/.bashrc:

eval "$(pyenv init -)"

# Make sure to restart your entire logon session
# for changes to profile files to take effect.
```


### すすめられるままにREAD MEを読んでみる
`shell setups. See the README for more guidance`と、オススメされていたので、読んでみました。
[README.md](https://github.com/pyenv/pyenv/blob/master/README.md)


READMEによると以下の通り記述がありました。

>MacOS note:
>If you installed Pyenv with Homebrew, you don't need to add the PYENV_ROOT= and PATH= lines. You also don't need to add commands into ~/.profile if your shell doesn't use it.

私はmacで、bashで、Homebrewからpyenvを入れました。
どうやらそういう人は以下の2行は入力の必要がないらしいです。

```terminal
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
```

入力する必要があるのは以下のみの模様。

```terminal
echo 'eval "$(pyenv init --path)"' >> ~/.profile
```


### いざ入力してみる

.bashrc向け、.profile向け、.zprofile向けの編集方法がREADMEには書かれていましたが、とりあえず私はzshではなくbashだし、macでHomeberwからpyenvを入れました。

.profileと.bash_profileなど、どんなファイルがあるのか`$ ls -a`で見てみたところ、.profileは存在せず、.bash_profileがあり、`$ vi .bash_profile `で開いて見たところ以下の記述がありました。

```terminal
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

これは自分で編集したものではないです。
おそらくこの記述、Homebrewでpyenvを入れた際に自動で書き込まれたのではないかと。。。
だからmacでHomebrewから入れた人は以下の2行は入れる必要がない(=すでに入っているから追記する必要がないよ)ということなのでは、と思いました。

READMEには.profileファイルに書き込む様に案内されていましたが、これを行うためには.profileファイルを作って、そこに記述しなければいけませんし、macだと省略していいよと言われている2行も入れないといけない様な気がします。

そのため、3行目の記述を以下に変更しました。

```terminal
eval "$(pyenv init --path)"
```


最後に以下のコマンドで、入力内容を反映させて…

```terminal
$ source .bash_profile
```

そしたら無事に冒頭のエラーメッセージが出なくなり、mac標準のPython2系が使われず、pyenvで入れたPython3系が無事にGlobalで使える様になりました。

.bash_profileとか.profileとか、わからないので調べてみようと思います。。
Spring 処理を定期的に実行する

@Scheduledを使ってメソッドを定期的に動かす実装をしたので備忘録として

####実装自体はとても簡単！

[@SpringBootApplication](https://spring.pleiades.io/spring-boot/docs/current/reference/html/using.html#using.auto-configuration)アノテーションが使用（ルーティング処理）されているアプリケーションクラスに

※Springでよく使うアノテーションまとめ（見やすかったのでリンク）→https://www.sria.co.jp/blog/2021/06/5712/

```MyApplication.java
@SpringBootApplication 
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}
```

@EnableSchedulingアノテーションをつける！
↓こんな感じ

```MyApplication.java
@SpringBootApplication 
@EnableScheduling
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}
```

・参考記事たち
https://qiita.com/rubytomato@github/items/4f0c64eb9a24eaceaa6e
https://dev.classmethod.jp/articles/spring-boot-java-annotation-scheduled/
https://reasonable-code.com/spring-boot-scheduling-tasks/
https://blog.enjoyxstudy.com/entry/2017/02/19/000000
https://tech-lab.sios.jp/archives/10859
https://zenn.dev/sugaryo/books/spring-boot-run-up/viewer/scheduled_annotation
わかりやすい記事がたくさんありました〜


####次に、定期的に実行したい処理に
[@Scheduled](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html)アノテーションを付与する！

（クラスを作って[@Component](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/stereotype/Component.html)アノテーションをつける※付与することでApplicationContextに登録され、DI対象のクラスとなる。）

（※あと、私は＠Autowiredも使って実装しました。
この[Spring入門記事](https://qiita.com/gksdyd88/items/7886f54ee8a22d311400)はアノテーションやDIについて説明されててわかりやすい）

```Scheduler.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class Scheduler {

    @Scheduled(cron = "0 0 0 * * *", zone = "Asia/Tokyo")
    public void doSomething() {
//定期的に実行したい処理
    }
}
```

@Scheduled(cron = "0 0 0 * * *", zone = "Asia/Tokyo")
↑この部分の実装で毎日０時０分０秒にメソッドが実行される

https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html


私は、毎日同じ時間に処理を実行したかったのでこの書き方にしました。
この部分の実装方法は色々あるみたいで、、

↓cronの書き方（内容）はこの記事がわかりやすい
https://qiita.com/rubytomato@github/items/4f0c64eb9a24eaceaa6e

#####Scheduledで指定できるパターンは3つあるそう

fixedDelay : 前回タスクの実行完了時点から指定時間後にタスクを実行する。単位はms。
fixedRate : 前回タスクの実行開始時点から指定時間後にタスクを実行する。単位はms。
cron : 指定した周期でタスクを実行する。(Linuxのcronと似た書式)

#####設定ファイルで指定する方法もある
（※私は上記のScheduledで指定できるパターンのcronで実装、こっちはやってない）
↓書き方の違いはこの記事がわかりやすい
https://blog.enjoyxstudy.com/entry/2017/02/19/000000


あとはメソッドの処理を書いて動きました〜！！
思ってたより簡単で参考記事が多く助かりました✌︎('ω'✌︎ )
JavaScript　繰り返し処理

JavaScriptの学習の備忘録と振り返りの記事です。
何かの参考になれば幸いです。
付け足しや訂正などある場合ご教授いただけると
大変嬉しく思います！！

#繰り返し処理とは
`ある条件を満たす間に行われる処理`を繰り返し行う処理の事
##種類
**while文**・・・条件式がtrueの間、{ }内の処理を繰り返すことができる
**for文**・・・while文と同じ　&　`while文よりもシンプルに記述できる`

##書き方
<details><summary>**while文**</summary>
while(`条件式`){
`処理`
}`;`セミコロン入れない</details>

::: note warn
値を更新するコードを書き忘れると無限ループになるので忘れないように！！
↓↓↓
while(month <= 12){
  console.log(month);
   'month += 1; '　←更新コード
}
:::

```js
let month = 1

while(month <= 12){
  console.log(month);
   month += 1;
}
```

**出力結果**
1
2
3
4
5
6
7
8
9
10
11
12


<details><summary>**for文**</summary>
for(`変数の定義` ; `条件式` ; `変数の更新`){
`処理`
}`;`セミコロン入れない
</details>

::: note info
変数の更新は省略して書くことができます。
例「number += 1」 ⇨ 「number ++」
　「number -= 1」 ⇨ 「number --」
:::

```js
for(let month = 1 ; month <= 12 ; month++){
   console.log(month);
}
```

**出力結果**
1
2
3
4
5
6
7
8
9
10
11
12
fast.ai個人的クイックスタートガイド

世間で評判がいいfastaiを夏休みに学習することにしました。
fastaiはこんな感じのコースで、既存のコースと違い、実用的な観点からトップダウンで知識を得ることができるようになっているみたいです。

>Deep Learning for Coders with fastai and PyTorch: AI Applications Without a PhD - the book and the course


「PhDなくてもworld-classのmodelを作ることは可能だよ！」
「ResNet作った人も当時は大学生だったし！」
「イーロンマスクも実務経験ある人ならPhDなしでもOKらしいよ」的なモチベーションを高めてくれるイントロからコースはスタートします。

https://course.fast.ai/

# 選択肢があると選べない
fast.aiは環境構築やノートとかに色々な選択肢がありますが、**選択肢があると人はなかなか選べない**ものですね。。。ノートブックもGitHubに色々なバージョンのリポジトリがあるので、多少ややこしかったです。

いや俺はローカルでできるけど？とか**変な意地を張らず**に、Colabで幸先の良いスタートを切ってみましょう。

# 実行環境の整備　- ノートを見つける

- Google Colabを開く
- File -> Open Notebookを選択
- ソースとして*GitHub*を選択
- fastaiのリポジトリの中からfastai/fastbookを選択

**注意**：他にも過去のバージョンなど似たようなリポジトリがありますが、実質**fastai/fastbook**が全部入りのマシマシ野菜ですので惑わされないでください。

![スクリーンショット 2021-08-13 11.06.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614389/1665b2d5-07e7-aacc-6cfa-bae29d285fb4.png)

# ノートを開く

### 基本的に参照する資料
トップディレクトリにあるノートブックが基本的に参照するものです。動画を見ながら、適宜参照することをお勧めします。


### Stripped Versionとは？
clean/にあるノートは**stripped version**と呼ばれていて、コードブロック以外はほとんど削除されています。これは課題で参照することものちにありますので、覚えておいてください。復習用に有効です。


# 実行環境の整備　- GPUを有効にする
- Edit -> Notebook Settingsを選択
- Hardware acceleratorをGPUにする


はい、これで最速でfast.aiの学習の準備が整います。


# なぜColabを使う？
Notebook環境はなんでもいいとは言いますが、

- GPUが無料で使える
- セットアップが簡単（GitHubから読み込める)

ということからColabを使いました。GPUないとLesson 1のサンプルコードの学習がゴンゴンに遅いです。なお、ColabのTPUでも試してみましたが、TPUはfastaiにはチューニングされていないのか、CPUと同程度に遅かったです。(fastaiはTPU対応のPyTorchを使ってるのになんでだろ・・・？)

これを自分で環境構築すると、以下のようにクレイジーな作業が発生します。やったことある方はわかると思いますが、かなり面倒です。

- GPU入りのマシンを拾ってくる
- CUDA関係のインストール
- Jupyter labとかのインストール
- PyTorch, fastaiなどのインストール
- [Optional] 今までの作業を全てDockerにぶち込む
- [Optional]DockerならDocker compatible packageとか設定をゴン攻めにする

**はい、というわけで、Google Colabを使って巨人の肩に乗りましょう。**


日本語のfastaiの情報があまり見つからなかったので、これからいくつかQiitaに書いていきます。

ここまで読んでいただきありがとうございました！
Golangで構造体に構造体を入れて、複雑なJsonを出力する

変数名とか適当です。

Kouzou_oyaの中にはKouzou_kobunというキーがあり、
変数の型がKouzou1という構造体になってる感じです。（事前にこういう定義をしないと行けないのがGo言語特有な気がします）


```main.go
package main

import (
	"encoding/json"
	"fmt"
)

type Kouzou1 struct {
	Var1 string
	Var2 int
}

type Kouzou_oya struct {
	Status       string
	Message      string
	Kouzou_kobun Kouzou1
}

func main() {
	// resultに構造体と値をセット
	result := Kouzou_oya{
		Status:  "22222",
		Message: "構造体テスト",
		Kouzou_kobun: Kouzou1{
			Var1: "aaaa",
			Var2: 2,
		},
	}

	//fmt.Println(result)

	// json 変換
	json_result, err := json.Marshal(result)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(json_result))

}
```


```bash
$ go run main.go | jq .
{
  "Status": "22222",
  "Message": "構造体テスト",
  "Kouzou_kobun": {
    "Var1": "aaaa",
    "Var2": 2
  }
}
```

Go言語は他の言語と違って変数の扱いが非常に難しく思えます。
構造体へのデータの参照や代入。
定義などを事前にしっかりしておかないと行けないっぽいので、Pythonの感覚だと動かないですね…。
【個人開発】コロナ禍で加速するTwitterの荒れを防ぐために、きのこでわかるツイートのネガティブ診断を作ってみた

※本サービスは2021年10月14日に停止しました。
# はじめに

はじめまして。megと申します。

コロナ禍でストレスが溜まり、荒れるツイートを無意識につぶやく子羊たちに向けて、ツイートのネガティブ度を図る

「きのこネガティブ診断」を作成しました。

きっかけは、友人のTwitter。

おそらく無意識で怨嗟の言葉を吐いているのか、コロナ禍に入り、心配になるようなツイートが増えてきました。

個人的にツイートの怖いところは、自分のツイートはなかなか見直さないけれど、他の人は意外と不特定多数の人がチェックしているということ。

特に公開アカウントは注意しなければなりません。

客観的に自分がどれだけストレスを溜めているか、深刻になりすぎずポップに見つめ直せるように、どのくらいネガティブなツイートを世に出しているのかを診断できるアプリを作成しました。

[![Image from Gyazo](https://i.gyazo.com/6bba1f04012b84c909a5b581d275701f.png)](https://gyazo.com/6bba1f04012b84c909a5b581d275701f)

# サービス概要

ユーザー名を入力、プライバシーポリシーと利用規約にチェック、診断、以上！いかに手軽に使えるかを念頭に作成しました。

1~10のレベルで直近のツイートのネガティブ度を算出し、結果はきのこで出てきます。

# 使用技術

- Ruby 3.0.1
- Rails 6.1.3.2
- JavaScript

# 外部API

- Twitter API

    入力した公開アカウントのツイートなどを取得。

- AWS comprehend

    Neutral・Positive・Negative・Mixedの4種類の感情の割合を分析。

# デプロイ

- Heroku

# こだわり

結果のきのこは1週間程度悩み、描きました。

日本に生息しているきのこで、面白いきのこを図鑑やネットで探し、10種類に絞り込み、可食かどうかについても調べて選定しました。

きのこって奥深いですよね。

大学時代に教授から、「世界で一番大きな生物で、大きいものだと何kmもある」という話を聞いてから、その辺にキノコが生えてると立ち止まってみてしまいます。

きのこって興味深いですよね。

結果の絵やトップ画面のきのこは手書きしました。
いかに緩くできるかに苦心し、ゆるい世界観を大事にしました。

cssでバルーン上にしたり、jsでクリックイベントをつけたりしました。(サービス開始前、浮いてるキノコを追ってる人が何人もいたようなので)

弱ってる時とテンションが上がってる時は、頑張ろうと思える言葉は違うと個人的に思ったので、結果の名言がネガティブレベルに応じて少し変化をつけました。

# さいごに

最後まで読んでいただきありがとうございました。

このアプリの使い方は色々あると思います。

自分のメンタル管理に使ってもいいですし、
ツイートが荒れてる友達に使ってもらってもいいと思います。

ストレス社会だからこそ、手軽に投稿できるツイートで心ない言葉などをついつい無意識に投稿してしまう人が多いと思いますが、ネガティブツイートをし続けているということは、心が疲れている証拠です。

現代社会の人はとかく、色々なストレスを溜めやすいので、己の心の疲労度を測ることに使用していただければと思います。
unityの2Dプロジェクトで画面の1pixel=テクスチャの1pixelにする方法

unityのことをある程度分かっている人で、なおかつ2Dのプロジェクトを作る人には結構意味があるかなって話。
同じことを書いてる記事を見たことがないので、メモ代わりに残しておく。

unityではいろんなものの単位のベースに**１unit**というものがある。これは3Dワールドではだいたい1メートルぐらいに思っておけばいい。
ここでテクスチャをunityにインポートすると**100PPU**という単位でインポートされる。これは**1unit=100pixels**でインポートされるって意味だ。
これが3Dプロジェクトである間は「さよですか」と言っておけばいいのだけど、問題は2Dになったときだ。
2Dでは当たり前だけど**テクスチャの１ピクセル=画面の１ピクセル**であって欲しい。
では、カメラとスプライトの間にどのような関係を置けばそれがうまくいくのか？
チュートリアルサイトではだいたい素知らぬ顔をしていて、スプライトを置いてしまっていて、適当な扱いをしているので、ここらへんがさっぱりわからず、気持ち悪くてしょうがなくて、再学習したときに覚えたことだったのだけど、メモとして残しておきたい。

まず大前提。

1. カメラサイズの"1"は"1 unit"の1…というか、unity世界では長さの単位はあまねく"unit"。
1. 1 unit = 100ppu。すなわち0.01 = 1pixelになる。
1. カメラは中心からの高さと幅で設定する。だから実際の画面の広さは2倍になる。これは誰でもわかってると思う。

上記を前提として、2Dプロジェクトをセットアップするとき、例えば下のようにする。

1. 例えば懐かしのiphone 4S設定の540x960に置いたとする（ポートレート）。
1. 縦を２で割ると480。横を2で割ると270
1. さらに100で割って、カメラサイズを縦4.8x横2.7にする。
1. すると9:16のポートレートモードで**1pixel動かすのに0.01**の超わかりやすい画面が出来る。

解像度を**1920x1080**にするなら、**縦は5.4、横は9.6**。これでやっぱり**0.01=1ドットの超わかりやすい画面**になる。

またチュートリアルサイトなどでppuをいじっているサイトもあったりするけれど、基本的にはppuはいじらない方が絶対にいい。
なぜならunityは物理エンジンとかいろんなものがunitに結構結びついているので100ppuをいじると、物理エンジンを使った瞬間、スケーリングの問題が出てくるので、面倒の山になる。
同じ理由で画面サイズを1920x1080とかに設定する人もいるけれど、これは192ox1080メートルみたいな画面を作っているに等しいので、物理とか使うとき面倒だらけになるので、お勧めできない。
キャンバスを同じサイズにしたいなら、canvasのカメラの設定を設定しましょう。

3Dではunitと画面の広さは結びつかないけど､2Dでは結びつくのに結びつき方を説明しているモノが全然なくて、ホント気持ち悪かったが、今はもうunityの2Dは気持ち悪くない。
なお、3Dでもcanvasが出てくると、上の考え方は使えるので覚えておいても損はないと思う。
自分専用のブラウザー拡張機能を作っている話

## はじめに

Web ブラウジング体験をプチ改善したいことって本当によくあります。 Partially Persistent Headers のようなユーザーを邪魔するだけの要素は本当にイライラするので撲滅したい。

- スクロールで出たり消えたりするヘッダー（Partially Persistent Headers）をページ上部に固定したい（「マイナビニュース」「DevelopersIO」など）
- テキスト選択時に出てくるポップアップを間違えて押さないよう非表示にしたい（「Medium」「note」「Yahoo!ニュース」など）
- 省略表示（...）されて途中までしか読めない文を全文表示したい（はてブのホッテントリのタイトルなど）
- Amazon の商品ページの URL を `/dp/{asin}` 形式に正規化したい
- <a rel="noopener nofollow" target="_blank" title="ブコメの熊がウザいので、削除するブックマークレット作った | はてな匿名ダイアリー" href="https://anond.hatelabo.jp/20210803012020">ブコメの熊を消したい</a>

いずれも数行の CSS または JS で実現できることばかりです。ユーザースタイルシートやユーザースクリプトさえ書ければ。

ユーザースタイルシートやユーザースクリプトを導入するサードパーティ製のブラウザー拡張機能は存在しますが、サードパーティ製のブラウザー拡張機能はセキュリティの懸念が大きすぎて気軽には導入できません。

- なぜ拡張機能にマルウェアが仕込まれる問題が後を絶たないのか？ - GIGAZINE  
  https://gigazine.net/news/20210218-open-source-extensions-malware/

そこで私は自分専用の小さなブラウザー拡張機能を作っています。


## つくりかた

### 実装

フォルダーを作って manifest.json と CSS や JS を置きます。私のはこんな感じです。 Chrome や Edge なら `manifest_version` を `3` にしても OK。

- manifest.json

```json
{
  "manifest_version": 2,
  "name": "my browser extension",
  "version": "0.0.0",
  "description": "これは自分専用です。",
  "content_scripts": [
    { "matches": ["https://news.mynavi.jp/*"], "css": ["mynavi.css"] },
    { "matches": ["https://*.yahoo.co.jp/*"], "css": ["yahoo.css"] },
    { "matches": ["https://b.hatena.ne.jp/*"], "js": ["b.hatena.js"] },
    {
      "matches": ["https://www.amazon.co.jp/*"],
      "js": ["amazon.js"],
      "run_at": "document_end"
    }
  ]
}
```

- mynavi.css

```css
.header {
  position: static !important;
}
```

- yahoo.css

```css
#yjSearchPop {
  display: none !important;
}
```

- b.hatena.js

```js
document.querySelectorAll('a[data-entry-id]').forEach(a => a.textContent = a.title)
```

- amazon.js

```js
const asin = document.getElementById('ASIN')?.value
if (asin) {
  const normalizedUrl = `https://www.amazon.co.jp/dp/${asin}`
  if (location.href !== normalizedUrl) {
    console.log('replace url:', location.href, ' -> ', normalizedUrl)
    history.replaceState(0, '', normalizedUrl)
  }
}
```

※ 8月13日時点。当然ですがサイトの DOM 構造が変わると機能しなくなります。

### 適用

#### Chrome

拡張機能管理ページ（chrome://extensions/）を開いて「デベロッパー モード」を ON にします。「パッケージ化されていない拡張機能を読み込む」ボタンを押して manifest.json を含むフォルダーを選択します。

#### Edge

拡張機能管理ページ（edge://extensions/）を開いて「開発者モード」を ON にします。「展開して読み込み」ボタンを押して manifest.json を含むフォルダーを選択します。

#### Firefox

about:debugging#/runtime/this-firefox を開き、「一時的なアドオンを読み込む...」ボタンを押して manifest.json ファイルを選択します。

#### Safari

- Safari向けに既存のWeb Extensionを変換する方法 - 見つける - Apple Developer  
  https://developer.apple.com/jp/news/?id=qiz0arxc


## おわりに

サイトあたり数行のプチ拡張で、 Web ブラウジングは非常に快適になります。とても手軽なので、みんなやればいいのに、と思います。ぜひお試しください。


## 参考

- 初めての拡張機能 - Mozilla | MDN  
  https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension
- manifest.json - Mozilla | MDN  
  https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json
さくらインターネットのHacobuneを触ってみる

# 概要
- Hacobune(はこぶね)というサービスが出た
    - https://www.sakura.ad.jp/information/announcements/2021/08/12/1968207782/
- Docker コンテナを用意するだけでオッケーという面白そうな PaaS を触ってみる
    - IP 制限ができるも○
- 単純な html を公開してみたい

# ドキュメント
- https://manual.c1.hacobuneapp.com/docs

## 公開する Web アプリケーションを用意
- github.com にリポジトリを作成して、html ファイルと Dockerfile を用意
    - 参考: https://github.com/Yoshihiro-Hirose/hacobune-html
    - nginx で html を公開する単純なもの

# 手順
## さくらインターネット会員登録
こちらから会員登録。各種個人情報を入力。
https://secure.sakura.ad.jp/signup3/member-register/input.html

## さくらのクラウドページに移動する
初回アクセス時はいろいろ聞かれる
https://secure.sakura.ad.jp/cloud/

## Hacobune を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517184/9df88ca4-74c2-a75b-1b9b-88c23e66b8ab.png)

## プロジェクトを新規作成する
- 上部メニューからプロジェクトを選択
- 新規作成ボタンをクリック
- プロジェクト名を入力して作成ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517184/d5a85de8-1234-7ecf-49bf-2e3c65d312ca.png)

## アプリケーションを新規作成する
- 作成したプロジェクトをクリック
- 新規作成ボタンをクリック
- アプリケーション名を入力
- デプロイ方法で Github を選択
    - github の認証と連携を行う
- 用意しておいたリポジトリとブランチを選択
- 公開で外部公開を有効にする
- サブドメイン名を入力して c1.hacobuneapp.com を選択
- 下までスクロールして作成ボタンをクリック

## 確認
- アプリケーション一覧に戻るのでビルドが完了して稼働したら URL をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517184/3f7b7e79-bfc0-7052-4aab-20135f2545c5.png)

# 所感
- コンテナだけ用意すれば良いというシンプルさが分かりやすい
- Nuxt.js, Next.js などでサイトを生成するケースを試したい
    - Github Actions などでビルドして Docker HUB や Github Packages にデプロイ?
    - ローカルでビルドしたファイルをソースコード管理する?
        - Dockerfile で dist をコピー
    - Dockerfile 内でアプリケーションをビルドできる?
        - こちらを参考
        - https://qiita.com/Yoshihiro-Hirose/items/a88da5fd331c3fd4d6c1
- SPA を実装する場合にバックエンドも用意できる?