OmniAICreator/Qiita-1.07M huggingface dataset:
初心者(2年ぶり3度目)がブラウザ上からFirebaseにHello Worldをホストする

*  https://cloud.google.com/shell?hl=ja
にアクセスし、```[コンソールへ移動]```ボタンを押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/511b4bc2-29ed-c884-adbe-583f3c44bf11.png)

* (自分のGoogleアカウントでログインし、)下部のターミナルをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/2de4380c-b7bd-1adf-ea03-d769cf598c32.png)

```$ firebase -V```と入力し、firebaseが入っていることを確認（数字が出ればOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/7b24c872-885d-beef-1673-2e163db599f6.png)

* ``` [エディタを開く] ``` ボタンを押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/da8a5512-d718-ea58-59b8-f2bd7b0a9eb5.png)

エディタが開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/604976e3-f2ec-e9cf-d511-3eea134029cb.png)

* エディタ上の淡い灰色の部分(readme.txtなどが表示されている部分)で右クリック
* New Folderでフォルダを作成（ここではpublic)
* ```[ターミナルを開く]``` ボタンを押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/30bd8c79-865b-f460-21de-4013dfff4579.png)

* ```$ cd public``` でpublicフォルダに移動
* ```$ firebase init``` で初期化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/388721cd-02ba-c09d-c6ac-d25896473166.png)

* カーソルキーでHostingを選択、**スペースで確定してから** Enter

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/8e93a3f9-16bf-fdac-1bd8-463e7c78507f.png)

* ~~Create a new projectを選択~~
(```$ firebase init``` , ```$ firebaseprojects:create``` ともにうまくいかなかったので…ゴニョゴニョ)
Use an existing projectを選択、 [Firebaseであらかじめ作成](https://docs.kii.com/ja/samples/push-notifications/push-notifications-android-fcm/create-project/)しておいたプロジェクトを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/fdc34c8c-e142-2c05-cd32-57de2134055c.png)

ホスティングが成功したら

```$ firebase deploy```

でデプロイ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/d7d30497-053f-c92e-5fe3-666c4a0b0c37.png)

* Hosting URLが表示されるのでブラウザでアクセスするとデフォルトページが表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/b4a12fb0-9921-5d9a-8584-c41ec4ce71e1.png)

* Cloud Shellに戻り、```[エディタを開く]``` ボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/02c0ffd3-73cf-dc5a-5a00-3a220da26f01.png)

* public/index.htmlの中を確認するといろいろ入っているので、Hello,Worldを表示するよう書き直す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/67087ab5-0dba-2e18-fa74-fce18086632b.png)

* もう一度 ```[ターミナルを開く]``` ボタンを押して ```$ firebase deploy```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/72da9e06-aff9-ef88-31d8-e71fbf50cab1.png)

* デフォルトページをリロードすると Hello, world. が表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/3f154e2e-ed1a-a118-01dc-db3d7c0eced6.png)

・・・どうせまたすぐ忘れるんやろな。
IFTTTでTwitterの改行入りテキストをWebhookに回す方法のメモ

# 前段

IFTTTで、Twitterの「New tweet by a specific user」をトリガーに、任意のWebhookにデータを回す場合、元のツイートに改行を含むと、うまくデータが回ってくれなくて困ったので、その回避方法のメモ。
他にもありそうだがとりあえず自分の対応を載せます。

# 対応

IFTTTのThen側、つまりWebhookへの連携の設定で、Content-Typeを``application/x-www-form-urlencoded``にする。
そのうえで、Bodyの部分に``Text={{Text}}&...``などでパラメータを繋げばよい。
こんな感じ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392942/e886dded-1545-3427-6969-c2bf8bc2084e.png)

# 失敗の記録

最初はContent-Typeが``application/json``でなんとかやりくりできないかと思ったが、駄目だった。
参考までに過去の実施記録。
ちなみにtext/plainは試してません。

- 改行含むテキストがくると、マジにその部分で改行されたJSONデータをそのまんまWebhookに回そうとする。これはJSONの仕様に違反しているので、Webhook側のJSONパースが失敗する。以下のようなデータのイメージ。

```JSON
{
  "Text":"あいうえお
かきくけこ"
}
```

- だったら``TweetEmbedCode``を使ってWebhook側でHTMLパースしてやるかと思ったが、TweetEmbedCodeにはHTMLコード内にダブルクォーテーションを含み、IFTTTはこれもやっぱりマジにそのまんまエスケープせずに渡すので、やはりJSON仕様に違反しており、Webhook側でJSONパースに失敗する。以下のようなデータのイメージ。

```JSON
{
  "Text":"<blockquote class="twitter-tweet">..."
}
```

- Content-Typeが``application/json``の場合でも、改行含まないテキストのケースや、そもそもテキストを連携しないケースなら、何も問題なくWebhookにデータが回っていく。

# 補足

IFTTTのツイートトリガーの連携は、項目があまり充実していない。
例えばツイートの投稿日時を指す``CreatedAt``は``April 08, 2021 at 10:40AM``という内容値になっており、Twitter APIなら取れるはずの「秒」の値が乗ってこない。
このため、IFTTT連携は、``Text``回すより、IDとか最小限の値だけにして、あとはWebhook側でTwitter API叩いて取ってくる、とかしたほうがいいかもしれない、と思った。
少なくともこんな面倒くさいことしてまでわざわざTextの値をIFTTT経由で渡すことはなかったなと、今にして振り返っております。
なお、ツイートのStatus IDは``LinkeToTweet``という項目に入ってるので、そこから取り出してTwitter APIに投げる形になる。（※``LinkeToTweet``は``http://twitter.com/rm_blank_slash/status/1379207288490102787``という形式なので、取り出す場合はWebhook側でsplit等が必要）
automatorとシェルスクリプトで超簡易シャッフル音楽プレイヤーを作る

MacOSで動作する、超シンプルなシャッフル再生専用音楽プレーヤーを作ってみました。
アプリといっても、実体はシェルスクリプトでユーザインターフェースはありません。

# 今回作るアプリの仕様

* 再生する音楽ファイルリストはあらかじめ作っておきます。
* アプリを起動するとファイルリストの音楽ファイルをシャッフル再生します。
* 音楽ファイルを再生中にもう一度アプリを起動すると、再生が停止します。
* 操作パネルや再生中の曲名表示などのユーザインターフェースはありません。
* 再生開始と停止以外の機能はありません。

# 作ってみる

## 音楽ファイルのリストを作る
音楽ファイルリストはただのテキストファイルなので、findコマンドでサクッと作ります。
findの引数は、音楽ファイルが置かれているパスなどに適宜置き換えてください。

```macUpdateMusic.sh
#!/bin/bash
find /Volumes/root/MEDIA/MUSIC/ -type f -name "*.mp3" > ./playlist.txt
```

新しい音楽を追加した時などに再度実行することになるので、シェルスクリプトにしておくのが良いかと思います。


## シャッフル音楽プレーヤー本体を作る

```macPlayMusic.sh
#!/bin/sh

cd /Volumes/root

kill `pgrep -lf /macPlayMusic.sh|awk '{print $1}'`
IS_KILLED=$?
pkill afplay

if [ "$IS_KILLED" -ne 0 ]
then
  echo play start
  cat playlist.txt | while read x; do echo -e "$RANDOM\t$x"; done | caffeinate -i sort -k1,1n | cut -f 2- | while read x; do afplay -q 1 "$x"; done
else
  echo play stoped
fi
```

pgrepで、既に実行中のシャッフル音楽プレーヤーを探し、プロセスがあればkillし、事前に用意したファイルリストを利用してリスト内の音楽をシャッフル再生します。

まず、ファイルリストの各行先頭に乱数値を追加し、乱数値を追加したデータをソートします。
そうすると、ランダムな順番に並び替えられたファイルリストが完成するので、上から順に afplayという音楽プレイコマンドに渡すことでランダム再生を実現しています。

ランダムに並び替えられたファイルリストは、各行の先頭に乱数値がくっついているため cutというコマンドでファイル名部分のみを最抽出しています。

追記） sortコマンドには -R というコマンドラインオプションがあり、これをつけるとランダムソートができるのですが、これを最初に作ったSierraの頃は -R が使えなかったため、このようなやり方をとっています。
が、今手元のBig Surで確認したところ、 sort コマンドで　-R　パラメータが使用できたので、コマンドはもっと短くできるかと思います。

また、caffeinate　は、macでオートスリープを抑制するコマンドです。

nohupなどをつけてコマンドを実行すると、ファイルリストないの音楽がランダムな順序で再生されるはずです。
再生中に同じコマンドを再度実行すると再生が停止しします（単にkillしているだけなので、フェードアウトするような感じでは無く、ぶちっと止まります）。

うまく動かない場合、スクリプト内に書かれているファイル名やパス名などを確認してください。

## アプリ化してdockに配置する。

アプリ化することで、terminalから起動せずともdockなどから簡単に起動することができるようになります。

shell scriptは、macの標準アプリのautomatorを使うと簡単にアプリ化することができます。
automatorは、Launchpadを開いて[その他]というグループの中にいるはずです。
もしもなければ、finderでアプリケーションを開き、その中から探してください。

automatorを起動したら、作成する書類の種類から「アプリケーション」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78337/8d27e0c5-77b1-35fe-9ed9-6c9db6ab1b28.png)

左側のリストから「ユーティリティ」→「シェルスクリプトを実行」を選択し、それを右側のエディットエリアにドラッグアンドドロップします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78337/4ad57d98-7b60-14a2-dcce-de37e4712c0d.png)

右側のエディット画面にシェルスクリプトの編集画面が表示されるので、以下のように記述してください（シャッフル音楽プレイヤーのシェルスクリプトのパスは環境に合わせて適宜変更してください）。

```sh
nohup /Volumes/root/macPlayMusic.sh > /dev/null 2>&1 &
```

ここまでできたら、「ファイル」メニューから「保存」を選択することで、作成したautomatorプロジェクトがMacアプリとして保存されます。

## アプリアイコンを変更する

デフォルトのアイコンでは、音楽プレイヤーっぽくないのでアイコンを変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78337/e1bbf1ad-6910-a106-98dc-98a4792f2958.png)

アプリアイコンの変更方法は http://www.specdesign.com.au/blog/tips/mac-icons/ あたりが参考になるかと思います。


アイコンのフリー素材サイトは、下記サイトが種類も豊富で使いやすいです。

https://icon-icons.com/ja/%E6%A4%9C%E7%B4%A2/%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3/?filtro=music+player


これで完成です。アプリのアイコンをクリックするたびに、音楽ファイルのシャッフル再生開始＆停止が切り替わります。

お疲れ様でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78337/32e762aa-dd99-406c-fd0d-5976befd4d0d.png)
SwiftUIでプッシュ遷移を実装する

# 参考
[【iOS】遷移方法まとめとエンジニア1年生の独り言](https://qiita.com/iTakahiro/items/b33306c773a05845358f)

# 画面遷移について
1. モーダル ... 下から画面が出現
2. プッシュ ... 右から画面が出現
3. タブ ... 瞬時の切り替わり(タブアイテムのタップ)
4. ページ ... 左右から画面が出現(左右スワイプ)

# プッシュ遷移の実装
## 動画
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">プッシュ遷移 <a href="https://t.co/GaTXqAd9jJ">pic.twitter.com/GaTXqAd9jJ</a></p>&mdash; APPLE (@applecoder6) <a href="https://twitter.com/applecoder6/status/1380034478521733121?ref_src=twsrc%5Etfw">April 8, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## コード

```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    @State private var showingModal = false
    var body: some View {
        VStack {
            Button("Show ModalView.") {
                self.showingModal.toggle()
            }.sheet(isPresented: $showingModal) {
                ModalView()
            }
            
            Divider()
            
            NavigationView {
                NavigationLink(destination: PushView()) {
                    Text("Show PushView.")
                }.navigationBarTitle("ContentView", displayMode: .inline)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

```swift:PushView.swift
import SwiftUI

struct PushView: View {
    @Environment(\.presentationMode) private var presentationMode
    
    var body: some View {
        Button("Back to ContentView.") {
            self.presentationMode.wrappedValue.dismiss()
        }
    }
}

struct PushView_Previews: PreviewProvider {
    static var previews: some View {
        PushView()
    }
}
```

# 学習結果
## NavigationView
プッシュ遷移を実現するNavigationLinkを管理するViewです。
子Viewをスタックし、階層的にナビゲーションを行います。

## NavigationLink
プッシュ遷移を実現するボタンです。
引数のdestinationに遷移先のViewを指定することで、プッシュ遷移を実現します。

プッシュ画面から遷移元の画面に戻る方法は以下の3通りです。
- モーダル画面を下にドラッグ
- NavigationLinkの表示フラグをfalseに変更
- 環境変数`presentationMode`プロパティの`dismiss`メソッドを呼び出す

## navigationBarTitle修飾子
ナビゲーションバーのタイトルや表示形式を変更します。
引数のdisplayModeは以下の3種類を指定することができます。
1. .inline
 → 標準のナビゲーションバー
2. .large
 → 大きいスタイル
3. .automatic
 → 遷移元のナビゲーションバーを引き継ぐ
 ※ デフォルトでは.largeと同じ
RustでWebAssemblyやってみた

# TL;DR
* Rustにちょっと触りたかっただけという噂

# だいたいWebAssemblyとは
* ざっくりいうと、バイナリプログラムをブラウザ経由で実行できる
* 小さいファイルサイズ、持ち運びしやすい、ネイティブに近い速い実行速度
* watファイルとwasmファイルがあり、watは人が読めるwasmはバイナリぐらいの理解で大丈夫
* ざっくりじゃない説明が欲しい方はこちら
    * https://developer.mozilla.org/ja/docs/WebAssembly
* WebAssemblyをつくるにはc/c++/rustが対応しています
    * 今回はRustでやってみます

# まずはRustのセットアップから
* 公式に書いてある通りです

```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

* ~/.cargo/bin を PATHに追加しておきましょう
* すでにインストールしてるひとは、rustup updateで最新バージョンにアップデートしましょう

# wasm-packをインストールします
* これも公式に書いてあり通りです

```
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
```

# cargo-generateをインストールします
* コンパイルするのでまあまあ時間かかります
* 私のmacbookproではファンがウィンウィンいうてました

```
cargo install cargo-generate
```

# npmもインストール
* 割愛しますね
    * nodebrewとかnパッケージを使ってインストールしてください

# テンプレートからプロジェクト作成します

```
cargo generate --git https://github.com/rustwasm/wasm-pack-template
```

* project名入れろって言われるので適当に入れる

# ビルド

```
wasm-pack build
```

# npmでの簡易表示

```
npm init wasm-app www
cd www
npm install
npm run start
```

* ブラウザで`http://localhost:8080/`にアクセス
* やたー表示できたー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585901/ecf47a94-b25c-2847-f272-4023d39be008.png)

# 感想(あくまで個人の感想です、感じ方には個人差があります)
1. できたwasmファイルが297バイトには恐怖を感じるほど小さい、キロバイトじゃなくてバイト
1. コンパイルめんどくさい(PHPやりすぎですね)
1. jsでは重い処理(画像とか動画)を代わりに任せられそう
1. unityから呼び出すとかいう使い方が合っているような気がする
1. WASIという技術も今開発されているのでそちらでコンテナ技術側で活路を見出すのかもしれない
GASによるポップアップ表示

初投稿
勉強したのでメモ

# 【GASによるポップアップ表示】

### スクリプト実行前にアラート表示したい、、、
そんなあなたに、こんな感じで表示させるのはどうでしょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522297/057e1b22-1932-e437-983d-5b97db86400a.png)


## Code - コード
画像のような表示を出すには、以下のようなコードになる。

```javascript
function alert() {
 var answer = Browser.msgBox("確認","よろしいですか？",Browser.Buttons.OK_CANSEL);
}
```

**Browser.msgBox( "題名", "本文", 選択肢形式 );**

「Browser.msgBox」メソッドを使う。

* 第1引数　/　メッセージボックス内に題名を表示させる。引数が二つなら題名が無いとみなされる。
* 第2引数　/　メッセージボックス内に本文を表示させる。
* 第3引数　/　OK、キャンセルの様なボタン表示を指定することができる。


## 第3引数
* Browser.Buttons.OK　//　OK
* Browser.Buttons.OK_CANSEL　//　OKとキャンセル
* Browser.Buttons.YES_NO　//　はいといいえ
* Browser.Buttons.YES_NO_CANSEL　//　はいといいえとキャンセル

## 返り値

```javascript
var answer = Browser.msgBox( "題名", "本文", 選択肢形式 );
```

このコードの場合、「answer」という変数に格納されるのは

<table>
<tr> 
<td>選択肢</td>
<td>返り値</td> 
</tr>
<tr> 
<td>OK</td>
<td>ok</td> 
</tr>
<tr> 
<td>キャンセル</td>
<td>cansel</td> 
</tr>
<tr> 
<td>YES</td>
<td>yes</td> 
</tr>
<tr> 
<td>NO</td>
<td>no</td> 
</tr>
<tr> 
<td>バツ印</td>
<td>cancel</td> 
</tr>
</table>

というようになる。

## まとめ
参考：[GASリファレンス (Class Browser)](https://developers.google.com/apps-script/reference/base/browser#msgBox(String,String,ButtonSet))
PowerAppsで入力された日付の年度を算出する

日付ピッカーで設定された値から年度を算出する方法です。
大した処理ではありませんが、まだPowerAppsの関数に慣れてないので記録しておきます。

お試し用に日付ピッカーとラベルのコントロールを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125084/07923f9a-0975-82cd-108d-4ec895142175.png)

ラベルの`Text`に以下の処理を設定します。

```
If(
    !IsBlankOrError(DatePicker1.Value),
    If(
        Value(
            Last(
                FirstN(
                    Split(
                        Text(DatePicker1.Value),
                        "/"
                    ),
                    2
                )
            ).Result
        ) < 4,
        Left(
            Text(
                DateAdd(
                    DatePicker1.Value,
                    -1,
                    Years
                )
            ),
            4
        ),
        Left(
            Text(DatePicker1.Value),
            4
        )
    ) & "年度",
    ""
)
```
解説は画像で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125084/d7c320b8-30e9-5b7e-0e7f-84d3ae1f038e.png)

試しに動かしてみます。
4/1はその年が年度として設定されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125084/594a33e8-f949-6af9-a5db-58d247a8f033.png)
3/31は前の年が年度として設定されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125084/b34bbb82-df76-168e-457b-2f6a95081066.png)

配列のインデックス指定（`XXXXX.Result[2]`とか）で取れれば楽なのになぁと思いました。
AWSでWebアプリをデプロイする方法(Java)⑦

#MariaDBのインストール
MariaDBをインストールすることでデータベースを動かせる環境を整えます

###利用環境
OS:MacOS
ブラウザ:Chrome

###前提条件
Apacheがインストールできている状態
まだ、Apacheがインストールできていない方は[こちら]
(https://qiita.com/kunrenyouAcount/items/d10fb9a73e911d7f4937)

##MariaDBをインストールする

###接続する
下記のsshコマンドを入力して接続します
※キーペアのファイルのパスと、ec2-user@以降は、変更して使用してください

```
ssh -i "/Users/koyamatakumi/Documents/Development/practice/aws/myserverkey.pem" ec2-user@13.115.141.44
```

###接続確認
下記のように表示されていれば、接続完了です
![スクリーンショット 2021-04-07 0.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/f1c21fd0-8be0-ab0e-ebdf-c9592fa0a8d7.png)

##SSHでの操作とrootユーザーへの切り替え
###rootユーザーのサインイン
ソフトウェアのインストールはrootユーザーで行います
下記コマンドを入力し、rootユーザーへサインインします

```
sudo -i
```

![スクリーンショット 2021-04-07 0.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/f9b00b1e-975d-f282-6cbe-6088f256bf3e.png)

###MariaDBをインストールする
```
yum install mariadb mariadb-server
```

インストールするかどうか聞かれるので[**y**]を入力し、**Enter**
![スクリーンショット 2021-04-07 1.12.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/9c77e696-9dc1-df67-c5df-128d6ad4a425.png)


下記の画面になればインストール完了
![スクリーンショット 2021-04-07 1.12.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/7d52afe8-d330-ab9f-7a15-4cb7383e9eaa.png)


##MariaDBの起動
###起動
インストールしたら、起動して動作を確認します

```
systemctl start mariadb
```


##mysqlコマンドを使ってデータベースを操作する
下記コマンドを入力し、MariaDBへrootユーザーでサインインします
パスワードが求められますが、パスワードは設定されていないので、そのままEnterキーを押してください

```
mysql -u root -p
```

下記の画面になればMariaDBが使用可能
![スクリーンショット 2021-04-07 1.17.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/e8d0a82c-60ec-12fe-e948-3f6e31ee79a0.png)


###rootユーザーのパスワードを変更する
MariaDBのrootユーザーのパスワードを「**mydbpassword**」に変更

```
update mysql.user set password=password('mydbpassword') where user = 'root'; flush privileges;
```

下記のようになっていれば成功です
![スクリーンショット 2021-04-07 1.20.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/4cbb6984-7ce7-59a8-8ae3-fc1c650d1490.png)


##データベースとユーザーを作成する
###ユーザーを作成する
「**webapp**」というユーザーを「**mypassword**」というパスワードで作成

```
create user 'webapp'@'localhost' IDENTIFIED BY 'mypassword';
```

下記のようになっていれば成功です
![スクリーンショット 2021-04-07 1.30.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/9665a6d9-7533-5457-f780-027221d8bd43.png)


###データベースを作成する
sukkirishopという名前のデータベースを作成します

```
create database sukkirishop;
```

下記のようになっていれば成功です
![スクリーンショット 2021-04-07 1.31.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/1ce79bb6-2993-5300-44b6-3c1f2837ac0a.png)

データベースが作成されたことを確認します

```
show databases;
```


###権限を設定する
「**webapp**」というユーザーに対してsukkirishopデータベースの全権限を与えます

```
grant all privileges on sukkirishop.* to 'webapp'@'localhost';
FLUSH PRIVILEGES;
```

下記のようになっていれば成功です
![スクリーンショット 2021-04-07 1.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/f5ec84f5-99ae-a8f9-c169-fa873674521f.png)



#AWSでWebアプリをデプロイする方法⑧
[Javaのインストール](https://qiita.com/kunrenyouAcount/items/4ca08c9ac3e2e262e7b1)
excelのフォントをゴリゴリ変える方法

[フォント 色 excel ショートカット - Google 検索](https://www.google.com/search?q=%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88+%E8%89%B2+excel+%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88&oq=%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E3%80%80%E8%89%B2%E3%80%80excel%E3%80%80%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88&aqs=chrome..69i57.15576j0j7&sourceid=chrome&ie=UTF-8)

フォントの色「Alt→H→F→1」 - エクセルドクター

上司が赤い部分やっておいてって言ってきたexcelで毎回やった後
フォントの色を変更するのはアレだったので上記キーボードショートカットで色々出来てヽ(=´▽`=)ﾉ
Rxを使ったEventBusをCoroutinesのFlowに置き換えてみる

#はじめに
どこかしらでEventが発火されたら、そのEventの発火を待ち受けていた別の箇所で処理をするEventBusをRxで書いたものをKotlinのCoroutinesのFlowを用いて置き換えたのを記します。

##Rxを使ったEventBus
以下はRxを使ったEventBusの簡単な例です。
Buttonを押した時にRxを経由してEventを発火し、TextViewの文字を変えています。

```kotlin:RxEventBus.kt
class RxEventBus {

    private val bus = PublishSubject.create<String>()

    fun sendEvent(event: String) = bus.onNext(event)

    fun toObservable(): Observable<String> = bus

    companion object {
        private var rxBus: RxEventBus? = null

        fun getInstance()=
            rxBus ?: synchronized(RxEventBus::class.java) { 
                RxEventBus().apply { rxBus = this } 
            }
    }
}
```

```kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {

    private lateinit var disposable: Disposable

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //RxEventBusをsubscribeしてイベントを待ち受ける
        disposable = RxEventBus.getInstance().toObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                when (it) {
                    "EVENT_BUTTON_PUSH" -> {
                        findViewById<TextView>(R.id.text).text = "Button Pushed"
                    }
                }
            }

        findViewById<Button>(R.id.button).setOnClickListener {
            //Event発火
            RxEventBus.getInstance().sendEvent("EVENT_BUTTON_PUSH")
        }
    }
}
```
RxEventBusでイベント発火と待ち受け用のSubjectを用意して、
使いたい箇所でこれを使っています。

##CoroutinesのFlow
同じ処理をCoroutinesのFlowを用いたものが下記になります。

```kotlin:EventFlow.kt
class EventFlow {
    private val flow = MutableSharedFlow<String>()

    suspend fun sendEvent(event: String) = flow.emit(event)

    fun subscribe(scope: CoroutineScope, onConsume: (String) -> Unit) {
        flow.onEach {
            onConsume(it)
        }.launchIn(scope)
    }
}
```

```kotlin:EventFlow.kt
class MainActivity : AppCompatActivity() {

    private val eventFlow = EventFlow()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //EventFlowをsubscribeしてイベントを待ち受ける
        eventFlow.subscribe(lifecycleScope) {
            when (it) {
                "EVENT_BUTTON_PUSH" -> {
                    findViewById<TextView>(R.id.text).text = "Button Pushed"
                }
            }
        }

        findViewById<Button>(R.id.button).setOnClickListener {
            runBlocking {
                //Event発火
                eventFlow.sendEvent("EVENT_BUTTON_PUSH")
            }
        }
    }
}
```

Flowは非同期処理やRxのような処理ができるCoroutinesのライブラリで、今回はホットストリームなFlowとして扱えるSharedFlowを使います。
これにより複数箇所から呼び出してもflow側の処理数が増えることはありません。
そして、subscribe()の引数で指定したscopeの中で、flowのイベントを待ち受けます。

##参考記事
- [Android での Kotlin Flow](https://developer.android.com/kotlin/flow?hl=ja)
- [kotlin coroutinesのFlow, SharedFlow, StateFlowを整理する](https://at-sushi.work/blog/24)
【Flutter】ColorをHexカラーコード文字列へ変換する

#ColorクラスからHexカラーの文字列を取得したい
Colorクラスで指定してるカラーを"#000000"といったHexカラーコードの文字列へ変換したいと思います。

```dart
String toHex(Color color){
  final colorStr = color.value.toRadixString(16).toString();
  if (colorStr.length == 8) {
    final hexcolor = colorStr.substring(2);
    final transparent = colorStr.substring(0, 2);
    if (transparent == "ff") {
      return "#" + hexcolor;
    } else {
      return "#" + hexcolor + transparent;
    }
  } else {
    return "#" + colorStr + "00";
  }
}
```

この関数を適当なところに貼り付けて使います。
使い方は以下の通りです。

```dart
Color hoge = Color(0xffbea3cb);
print(toHex(hoge)); //#bea3cd
```
GASで一日置きに通知のくるLINEbotを作る

GASなら環境とかも整えなくても勝手に動いてくれるので、GASでLINEbotを作りました。
初心者の時に作ったのでかなり雑ですが、ここで供養…。
#はじめに
母親が一日置きにする家事を今日やったか昨日やったかいつも忘れていたので、勝手に通知してあげます。
スマホに疎くてもLINEなら使っているので通知に気づくかなと思い。
結果として考えなくても勝手に通知がくるので楽になったらしいのでやってよかったです。

#目標
**1日置きにグループラインに通知がくる**
（LINEAPIの仕様上グループラインに送るしかできないので家族のグループラインを作りました。)

* LINE Notifyのトークンを取得する
* GASを書く
* トリガーを設定
* その他

#つくりかた
**①`LINE Notify`のトークンを取得する**
https://notify-bot.line.me/ja/
LINE Notifyについてはこちらの方の記事がわかりやすいのでそちらを参考にしてみてください。

https://qiita.com/iitenkida7/items/576a8226ba6584864d95

**②GASを書く**
1日置きに通知をしたいので、簡単な日にちの計算をする。

* 今日の日にちを取得してスプレッドシートに記録
* 記録した日にちと照らし合わせて2日前なら通知して通知した日を上書き
* 1日前なら何もしない

```js
//LINE NOTIFYトークン　
var token = ["ここに取得したトークンを書いてね"];
```
(忘れちゃったけどなんで配列にしてんだろ？そうする理由が何かあったのかな？)

```js
//日付の計算をしてスプレッドシートに記載、真偽で返す
function getdate(){
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getActiveSheet();
  var date = sheet.getRange("A1").getValue();
  var fmt_date = Utilities.formatDate(new Date(date), 'Asia/Tokyo', 'yyyy/MM/dd');
  var twodays = new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()-2);
  Logger.log(twodays);
  var fmt_twodays = Utilities.formatDate(twodays, 'Asia/Tokyo', 'yyyy/MM/dd');
  var today = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd');
  
  if(fmt_date == fmt_twodays){  
  sheet.getRange("A1").setValue(today);
  return true;
    
  }else{
  return false;
  }  
};
```

後にみてわかりやすくするために、trueかfalseを返すようにしています。

```js
//1日置きにLineに通知を送る
function LineNotify(){
  var message = '今日はお風呂のお湯を替える日だよ！\uDBC0\uDC5E';
  var options = 
      {"method" : "post",
       "payload" : "message=" + message,
       "headers" : {"Authorization" : "Bearer "+ token}
      };
  
  UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
};
```
これはこういう呪文だと思った方が良さそう。
送るのにこういう形式にしないとLINEさんが認知してくれないよ。
messageの終わりに書いてある`\uDBC0\uDC5E`は絵文字。
※絵文字に関しては[こちら](https://www.pre-practice.net/2017/10/line-botline_21.html)のブログが参考になりました。めちゃくちゃありがとうございます。

```js
//LINEに送るための関数
function sendLine(){
  var bool = getdate();
  if(bool == true){
    LineNotify()
  };
}
```
これで最後！

**③トリガーを設定**
GAS側の設定で、sendLineに設定します。
同じような時間にざっくりくれば良かったので時間ベースの13時頃にくるように設定しました。
きっかりこの時間にくるように！ということならまたコード書けばできるようになります。

**その他**
最後に一番初めに通知する日をセルの`A1`に書いてあげてください。(`yyyy/MM/dd形式`で)

ウェブアプリケーションで公開を選択しないと稼働しないので注意です。
(前のIDEなら公開ボタンがあったのだけど、新IDEだとデプロイボタン押して新しいデプロイを選ぶと幸せになれる気がする。)

![こんな感じになります](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459856/b55dc874-9791-1d96-b720-be1a86b75370.png)

#おわりに
これは事務員の仕事をしていた時に教えてもらいながら勉強した知識で作れたbotなので、エンジニアじゃない人にも是非作ってみてほしいです。
あと、こういうの作って一番嬉しいのは反応があることなので、何か作ってくれた人には反応してあげれる、そういう人に私はなりたい。
(大体こういう小さい便利グッズつくって褒めてくれるのはエンジニアたち)

ここはこうした方がいいとかかあればご教示いただきたいです。。
ロジスティック写像の時系列をpythonで表す（折れ線グラフ）



#ロジスティック写像の時系列

ロジスティック写像とは以下で表される１次元写像のことである。
パラメータaの値が大きくなると軌道がカオスになることで有名である。

```math
f(x) = x_{n+1} = ax_n(1-x_n)\\
(0 \le a \le4)

```
横軸をn（ステップ数150回とする）、縦軸を x として、x の時系列を求めたい。（a = 4 のとき）
今回はロジスティック写像の時系列のプログラムを詳しく説明する。

###時系列を折れ線グラフで表す

```python
import matplotlib.pyplot as plt

x = [0.8]
a = 4.0
n = [0] 
for i in range(1,151):
    x.append(a * x[-1] * (1 - x[-1]))
    n.append(i)
    
plt.plot(n,x)
plt.xlabel("n")
plt.ylabel("x")
plt.show()
```
![スクリーンショット 2021-04-08 12.07.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067896/f3ce3e45-4b24-550d-f11f-bd0e75b7690c.png)


####解説

⒈ グラフを作成するために必要なライブラリをインポート

```python
import matplotlib.pyplot as plt
```

⒉  初期値を設定
　  最後にグラフにするときにxのリストとnのリストの値の数が同じになるようにステップnの初期値も、n=[0]を入れておく。

```python
a = 4.0
x = [0.8]
n = [0]
```

⒊ for文で150回繰り返し
　```append```でxとnのリストの中に150個の値を追加する。
　ここで、初期値n=[0]がもともと入っているため、nのリストには１から追加できるように```range(1,151)```で、１から150回繰り返せるようにする。
　それにより、for文の中のxは```x[i]```と表現してしまうと、for文の１回目の実行でx[1]がありませんというエラーが出てしまうため、```x[-1]```という表現にする。（これはxのリストの中で一番右にある値を表す。）

```python
for i in range(1,151):
    x.append(a * x[-1] * (1 - x[-1]))
    n.append(i)
```

⒋　グラフを出力

```python
plt.plot(n,x)
plt.xlabel("n")
plt.ylabel("x")
plt.show()
```


####散布図

ちなみにfor分の中でplt.plotをすると以下のような散布図になってしまうので注意

```python
import matplotlib.pyplot as plt

a = 4.0
x = [0.8]    
for i in range(150):
    x.append(a * x[i] * (1 - x[i]))
    plt.plot(n, x[i], "c.")
    
plt.xlabel("n")
plt.ylabel("x")
plt.show()
```
![スクリーンショット 2021-04-08 11.32.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067896/f2a87e44-879d-ec66-c0ef-8a7b3da78413.png)

パラメータaの値を変えると、固定点に収束したり周期点に収束したりなど様々な振る舞いをすることが分かる。
ActionMailerのViewでHelperのメソッドを使う

### ActionMailerを使用したメールの文面でHelperのメソッドを使いたい時の例

helperメソッドを使います。
https://api.rubyonrails.org/v6.1.0/classes/ActionController/Helpers.html


```Ruby:text_helper.rb
module TextHelper
  def change_text(text)
    ・・・ #テキスト変更する処理
  end
end
```


```Ruby:user_mailer.rb
class UserMailer < ActionMailer::Base
  helper TextHelper

  def mail_to_user(user)
    @user = user
    mail(to: user.email, subject: 'Title')
  end
end
```


```Ruby:mail_to_user.text.rb
<%= change_text(@user.name) %>
```

こんな感じで行ける。

###おまけ
ActionMailer Helperでググると

```Ruby
add_template_helper(ApplicationHelper)
```
を追加するって言う記事がでてくるけど
Rails 6.1で削除され動かなくなるようなので注意が必要です。
helperメソッドを使いましょう。


以上
PowerShellでweb.configのsystem.webを編集

以下のような設定ファイルがあるとして、sessionStateのtimeoutを120分から180分に変えたい。

```xml:web.config抜粋
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
        <system.web>
                <sessionState mode="InProc" stateConnectionString="tcpip:xx.xx.xx.xx"
                sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
                cookieless="false" timeout="120" />
        </system.web>
</configuration>
```

PowerShellから設定ファイルを編集するには、xmlをパースしてやりくりする方法もあるが、ここでは.NETのSystem.Configrationなるオブジェクトの力を借りたい。その名の通り設定ファイルを処理することに特化したオブジェクトである。


```powershell
#configファイルをマッピング
Add-Type -AssemblyName System.Configuration
$Map = New-Object System.Configuration.ExeConfigurationFileMap
$Map.ExeConfigFilename = '.\web.config';
$config = [System.Configuration.ConfigurationManager]::OpenMappedExeConfiguration($Map, [System.Configuration.ConfigurationUserLevel]::None)

#セッションタイムアウトの設定
$config.GetSectionGroup('system.web').SessionState.Timeout = '03:00:00';

#ファイルに反映
$config.Save();
```

実行してみると、"03:00:00"が勝手にminuteに変換され"180"で更新されていることが確認できます。非常に優秀。
ミスチルの歌詞を外国語で音読できないかの検討

# UPDATE

ネタのついでであるが、おもろいことがあり報告する。

ミスチルのTomorrow never Knowsという曲があるが、
日本人でさえ、桜井氏の歌詞を歌うのは、なかなか難しい。

#外国語ルビ
　日本語の歌詞を外国語で考えて、音読させてみる。

　GOOGLE翻訳を使う　　→　　https://translate.google.co.jp/

# 元ネタ
　https://www.utamap.com/showkasi.php?surl=54853

## 英語

Total more alcohol to wash ill and night,talking know nut cut day,e coo two more no.
wood too lee you cool much nah me war,meets you maid hate eater.

https://motochan1969.hatenablog.com/entry/20210410/1618015566

## 中国語

多都马儿口躲 我 西朗那一、多给能那个地、一股粗磨弄
物资里语库马七纳米我、米子没得以他

https://motochan1969.hatenablog.com/entry/20210410/1618016031


## 考察

　今回はミスチルぽく歌うというよりは、歌詞の朗読っぽい感じになった。
カラオケのように歌うには、もう少し工夫がいるかもしれない。

　外国人の方に、これを実際に読んでもらい、ブラッシュアップする必要がある。

# ネタとして

 普段の逆のことをやってみたが、案外日本人にとっては
日本語を外国語に当てはめる方が楽なのかもしれない。

　少なくとも外国人との会話のネタにはなるし、
語学学習者としては、なかなか面白い遊びである。

　コロナが終わったころに、またドミトリーでテストするため、
何曲かのレパートリーを所持しておきたいと思う。

って、これって大変なので、Deeplearningでやってみたらいいのではないかと思う。
MRTK ダイアグノスティクス、プロファイラの表示、非表示をプログラムから行う


# 環境
- Windows 10
- HoloLens 2
- Unity 2019.4.22f1
- Microsoft.MixedReality.Toolkit.Unity.Foundation.2.5.0

# 成功
```csharp
CoreServices.DiagnosticsSystem.ShowDiagnostics = false;
CoreServices.DiagnosticsSystem.ShowProfiler = false;
```

# 失敗

```csharp
// 以下のコードは getter と internal setter のみ
var mixedRealityToolkit = (MixedRealityToolkit)MonoBehaviour.FindObjectOfType<MixedRealityToolkit>();
Debug.Log(mixedRealityToolkit.ActiveProfile.DiagnosticsSystemProfile.ShowDiagnostics);
```

# 参考

- https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/Diagnostics/ConfiguringDiagnostics.html
HerokuへPushしたら ! [remote rejected] master -> master (pre-receive hook declined)　が出た

HerokuへPushしたら最後の行にこれがでて、 `push` できなかったのです。

```
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to
```

上の方を見てみると赤い文字で以下が表示されていました。

```
remote:  !     Failed to install gems via Bundler.
```

ググってみて、とてもわかりやすかったこちらの記事を参考に試しました。

https://yumishin.com/heroku-push-error/

https://yumishin.com/heroku-push-error-2/


しかし、私は変化なしでした。ぴえん。。。

色々試しましたが、どうやら `リモートリポジトリに反映した変更をローカルリポジトリにも反映させる（pull）` ことをしていなかったのかもしれません。

```
$ git pull origin master
```

私の場合、このコマンドの後に `git push heroku master` したらできました！！
【Unity】指定iOSバージョンのシミュレーターでアプリを実行したい

# 環境
Unity : 2019.4.20f1
Xcode : 12.4

# 経緯
- Appleのリジェクトから逃れるために App Tracking Transparency の対応を行った。
- iOS14だけじゃなくて、iOS13でも動作確認したほうがいいよね。
- iOS13 の端末が手持ちになかったのでシミュレーターで検証しよう！

と言うことになった。

# 前置き
「ipaのビルドくらいまでなら余裕でできるぜ」って人向けな内容になっているかと思います。
なので、シミュレーターに関係のない部分は説明がちょっと雑になってるかもしれません。

# 失敗談（ざっくり）
※さっさと対応方を知りたいならば、[次の項目](https://qiita.com/drafts/8a8c8e82bce46179787d/edit#成功談)へジャンプ！

- ビルド済みの「hoge.ipa」をインストールしようと思ったが、軽く調べたら「ipaはインストールできんぞ！」と言われていたので諦めた。
- 次に軽く調べたら「hoge.app をシミュレーターにドラッグ$ドロップすればインストールできるよ！」と言われていたので早速ドラッグ&ドロップ。
  - インストールできたけどアプリが即クラッシュ。
  - OSバージョンによってはインストールから失敗する。

# 成功談
### シミュレーターの準備
【OSを落とす】
おそらく、初期状態では最新のOSしか所持していないので、希望のOSを落としてきましょう
1. [Xcode]Xcode -> Preferences... -> Components を選択
2. 使用したいOSを選択。（DLマークを押すとDLが始まり、DLが終わるとチェックマークに変わります）
<img width="300" alt="スクリーンショット 2021-04-08 11.42.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275803/6a661b3e-7ec9-90c1-607f-e9cc3c3aa15c.png">

【シミュレーターの起動】
1. [Xcode]Xcode -> Open Developer Tool -> Simulator を選択でシミュレーターが起動（多分最新OSで起動）
2. [Simulator]File -> Open Simulator -> {好みのOSバージョン} -> {好みの機種} を選択で新たにシミュレーターが起動します
<img width="300" alt="スクリーンショット 2021-04-08 11.48.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275803/5fb2b835-bfb2-7c8f-dc92-b01e7ea8fcdd.png">

### アプリの準備
【Unityでの作業】
※**手順2の影響で、ビルド時に大量のimportが発生するので、シミュレータービルド用にUnityプロジェクトを複製してから対応した方がいいかもしれません**
1. [Unity]File -> Build Settings -> Player Settings... を選択でPlayerSettingsを開く
2. [PlayerSettings]OtherSettings -> TargetSDK を「DeviceSDK」から「SimulatorSDK」に変更する（これをしないとシミュレーターでクラッシュします）
3. いつも通り、XcodeProjectをビルドしましょう

(手順2の選択項目)
<img width="300" alt="スクリーンショット 2021-04-08 12.18.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275803/09d1c967-d60b-1eb6-c9e6-729f20cea1d6.png">


【Xcodeでの作業】
1. いつも通りXcodeProjectをXcodeで開きましょう
2. [Xcode]Product -> Buildを実行
3. ビルドの完了を待つ
4. [Xcodeウィンドウ内]Unity-iPhone/Products/Unity-Target-New.app があることを確認（Show in Finder で開き、容量が0KBじゃないならOK）
<img width="150" alt="スクリーンショット 2021-04-08 12.04.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275803/995639c3-21d9-5fce-5b0e-a27e2fe87d15.png">

### シミュレーターにインストール
1. [シミュレーターの準備](https://qiita.com/drafts/8a8c8e82bce46179787d/edit#シミュレーターの準備)で開いたシミュレーターにUnity-Target-New.appをドラッグするだけ！

<img width="150" alt="スクリーンショット 2021-04-08 12.11.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275803/dfdb82e1-b1c4-6075-737f-c4597a2de72e.png">
CodeIgniterで使えるディレクトリパス定数一覧


#はじめに
CodeIgniterで開発を進める中で、パスを指定するときに迷わずに適切な定数を選べるようにするために、パス定数を一覧にしました。
記載されていないバリエーションがあれば、コメントで教えて頂ければ幸いです。


#PHPの定数

```php:php
現在のパス                   //    /src/application/controllers/make/Make.php

basename(__FILE__);          //    Make.php
__FILE__ ;                   //    /src/application/controllers/make/Make.php
__DIR__ ;                    //    /src/application/controllers/make
dirname(__FILE__);           //    /src/application/controllers/make
$_SERVER['DOCUMENT_ROOT'];   //    /src/public/
```

#CodeIgniterの定数
```php:php
現在のパス       // /src/application/controllers/make/Make.php

FCPATH;          // /src/public/
SELF;            // index.php
BASEPATH;        // /src/system/
APPPATH;         // /src/application/
VIEWPATH;        // /application/views/
```

#CodeIgniterのURLヘルパー
```php:php
現在のパス                     // /src/application/controllers/make/Make.php

base_url('news/local/123');      //  http://example.com/index.php/news/local/123
site_url('news/local/123');      //  http://example.com/news/local/123
uri_string();                  // news/local/123
index_page();                  // 設定されているindexページ
```
JSONとは？？

#Jsonとは？？
JavaScript Object Notationの略です。
無理やり訳すとこんな感じです。
Javascriptオブジェクト表記。つまり、JSに基づいたものです。
JavaScriptでオブジェクトを作成する際は {} や [] などの括弧を使って記述しますのでJSONでもその記載方法を使用しています。

記述方法は
1) {} で囲む
2）　それぞれのデータはキーとValueのペア
　key: 文字列
　Value：データ型　▶　文字列はダブルクオーテーションで囲む、数値は実数で記入可能、

#XMLとは？？
JNSONが出てくる前はXMLを使用していました。
HTMLの記法を元にしたデータ定義方法で、データ定義言語と呼ばれています。
HTMLと同じようにタグを使ってデータの構造を定義しています。
ただ、最近はJSを使うことが多くなったので、上記のJSONを使っているようです。

#JSON記入例

```index.html
 <script>
  let json_obj = {"id" : 1, "name": "user01", "gender": "woman"}
  let decoded_json = JSON.stringify(json_obj, null , "");
  document.write(decoded_json);
  </script>
```
ブラウザ上で表示すると以下のようになります。

![スクリーンショット 2021-04-11 13.40.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/f24379e3-23c1-0d27-3426-cc251e9da2e5.png)
Google Earth EngineからPythonを使ってプロダクトをまとめてダウンロード（複数年）

##概要
　先日投稿した[「Google Earth EngineからPythonを使ってプロダクトをまとめてダウンロード」](https://qiita.com/shokishimada/items/6bf52183436ec1cb0026)の記事では単一年のデータをまとめてGEEからダウンロードする方法についてご紹介しましたが、対象年が複数年に渡る場合についても処理をループで回すことでGoogle Driveへのダウンロードが可能です。

##データ
　今回ダウンロードしたのは、MODISプロダクトのうちで森林火災の強度を示す指標であるFRP (Fire Radiation Power)を格納した[MOD14A1](https://developers.google.com/earth-engine/datasets/catalog/MODIS_006_MOD14A1)です。

##コード
　基本の構成は[「Google Earth EngineからPythonを使ってプロダクトをまとめてダウンロード」](https://qiita.com/shokishimada/items/6bf52183436ec1cb0026)と同一ですが、ループを使ってフォルダに名前を付けながら2002年から2019年にかけて取得されたデータをGoogle driveへとダウンロードしています。ImageCollection単位でダウンロードを行っているため、個々の画像のダウンロード自体をループで処理する場合よりもループの回数が少なくなり、処理が速いのではないかなと思います（Pythonでループを入れ子すると処理時間がとても長くなる場合が多いので）。


```python:GeeDownload.py
!pip install earthengine-api
!pip install unidecode
!pip install geetools

import ee

ee.Authenticate() #認証を求められる
ee.Initialize() 

band=['MaxFRP']　#バンドの選択
ROI =ee.Geometry.Polygon([98,58,117.995,58,117.995,50.004,98,50.004])　#関心領域の設定

from geetools import batch
from tqdm import tqdm

year=[f'{y}' for y in range(2002,2020)]　#対象年のリスト

for y in tqdm(year):
  FireData=ee.ImageCollection("MODIS/006/MOD14A1").filterDate(f'{y}-07-01', f'{y}-09-01').filterBounds(ROI);
  tasks=batch.Export.imagecollection.toDrive(
      collection=FireData.select(band),
      folder=f'FRPdata_MOD14A1_{y}',　#f-stringsを使ってフォルダ名を年毎に変更する
      scale= 500,
      region= ROI)
```
個人開発PF公開の際のサーバーベストチョイスって何だろう

#大前提、Webアプリに対応してるサーバーを選ばなければならない
>###Webサーバ
WebサイトはユーザーがGoogle ChromeやInternet Explorer、FirefoxといったWebブラウザからリクエストを行います。例えば、「企業情報を閲覧したい」というリクエスト、アパレル系ECサイトなら「ブランド名やサイズを絞った商品一覧を閲覧したい」といったリクエストです。
Webサーバはリクエストを受け付けると、その結果をWebブラウザへ返します。会社概要ページなどテキスト情報だけの静的なページであれば、そのままHTML、CSS、画像などのデータを送ります。
一方、受け付けた内容がブランド名やサイズを絞るといった動的な処理の場合、WebサーバはWebアプリケーションサーバへ処理のリクエストを依頼し、返ってきた処理をデータとして同じくWebブラウザへ送ります。

>よく利用されるWebサーバとしては、オープンソースの「Apache HTTP Server」や「nginx」、Microsoftが提供する「Microsoft Internet Information Services (IIS)」などが有名です。

 

>###Webアプリケーションサーバ
Webアプリケーションサーバでは、Webサーバから受け付けたリクエストをJavaやPHP、Rubyなどのプログラミング言語を実行して処理します。そして、実行した結果をWebサーバへと返します。
Javaアプリケーションサーバでは、オープンソースの「Apache Tomcat」が有名です。「Apache Tomcat」はJava Servletを動かすサーブレットコンテナの一つですが、簡単なWebサーバとしての機能も有するため、広く活用されています。(引用:https://bityl.co/6In8)

#初心者がFWを使ったアプリを公開する時の選択肢
自分が作ったサイトやアプリを世に公開したいならサーバーを用意しなければいけません。

しかし、エンジニアの方以外にも馴染みのあるであろう、ロリポップやエックスサーバーでは基本FWに未対応です。

なので、RailsやDjangoなどのFWを使ったアプリを公開したい場合は、FWに対応しているサーバーを選ぶ必要があります。

###選択肢①PaaS
例: Herokuなど
Platform as a Serviceの略。
IaaSのようにミドルウェアとOSを自分で容易する、というのは初心者には難しすぎるので、Webアプリさえ開発すればあとはサービス側がなんとかしてくれるPaaSが現実的な選択肢になるかと思います。
IaaS、PaaS、SaaSの違いについては[こちらの記事](https://bityl.co/6Ing)の図解がかなりわかりやすいので見てみてください。



###選択肢②VPS
Virtual Private Serverの略。
専用サーバーを物理サーバーではなく、仮想化技術（仮想サーバー）で実現したものです。専用サーバーの「コストが高くなる、導入に時間がかかる」などのデメリットを解決したものがVPSです。
サーバースペックを変更したい、となった時には解約=>再契約する必要があるらしいです。

###選択肢③クラウドサービス
例: AWSなど

「専用サーバーを仮想サーバーで実現したもの」と言う観点ではVPSと同じものですが、クラウドサーバーは、クラウドが提供する負荷分散やスケーリンングのサービスを併せて使用することで、障害に強く、必要な時に必要性能を発揮でできるスケーラブルな構成がとることが可能。





#AWS
###なんでもこいな姿勢
基本柔軟に自分が使いたいDBだったりを選択できます。
シンプルなWebアプリなら基本MySQLになるらしいのですが、例えばHerokuではデフォルトがpostgresqlになってるので、選択肢が阻められます(追加で設定すればMySQLを使えますが..)

###サーバースペックの拡張が簡単
サーバーのスペック(CPU数、メモリ容量、ディスク容量）も容易に変更することが可能で、キャンペーンECサイトだったり、バズってめちゃくちゃ人気になった、という場合でもさくっと拡張ができるので、サーバーが落ちてユーザーが離反する、ということもありません。

###従量課金制なので節約できるかクラウド破産するか...
従量課金制のため、使われなくなったらサーバー代のコストを節約できる可能性もあれば、それが災いとなって破産する場合もあります。怖い。無料枠が12ヶ月あるのですが、なんだかんだみんな課金されている印象です。

#Herokuの無料枠
###Heroku(無料枠)を使うメリット
######無料！
######結構有名なサービスなので安心
######無料ホスティングサービスの代名詞的存在で情報が豊富

###Heroku(無料枠)を使うデメリット
######デフォルトがpostgresql
なので、MySQLを使う際は設定する時間・作業コストがかかります。

######リージョンの選択が日本を選択できず、海外のみ(=日本のCDNが選べない=速度低下の可能性大)
=>これが結構本気で懸念かもしれません。
[LIFFでゲームアプリを作るまで](https://bityl.co/6ImI)のゲームアプリはHerokuにデプロイされてるのですが、初期起動の読み込みが本当に30sくらいかかりました..

######独自ドメインは設定できるがSSL化ができない。
([裏技で無料で独自ドメインでSSL化する方法もある](https://bityl.co/6Ilr)ようですが、今回のようなユーザーの個人情報がやりとりされてしまうWebアプリでは危険すぎます。)
=>公開時はとりあえず独自ドメインなしで、SSL化で公開します。

######非商用なので、広告が貼れない。
もし公開の告知をしてバズってユーザーを獲得しても、その際に発生する可能性のある広告収入をみすみす逃すことになります。
ただこれ、小さい店舗だと激混みの時に来てくれたお客さんをみすみす逃しちゃうから、最初から大きい店舗借りようぜって言って大赤字出すのと同じかと。

######画像データが30分しか保持できない
それ用のモデルを作成して、画像のみ別サービスに保存する必要がある。

https://qiita.com/you8/items/d5f157a428e3fffa35e3
モバイルアプリ開発で選択すべきフレームワーク


近年、世界中の人々にリーチするための近道を切り開くことこそが、スマートなビジネス戦略の基本ですね。そのひとつとして、ビジネスサイトをモバイルアプリへと切り替えることがあります。
しかし、ネイティブアプリ構築アプローチでは、どのフレームワークを選定すれば良いのか迷っている人のために、各フレームワークを比較して解説します。
#1. React Native
React Nativeは、Facebookが発表した高人気のクロスプラットフォームのフレームワークのひとつです。このフレームワークを使用すれば、開発者はiOSとAndroidの両プラットフォームに対応するJavaScriptのみでモバイルアプリケーションを作成できます。これはUIコンポーネントの階層を構築し、JavaScriptのコードを生成します。React Nativeで作成されたアプリには、Facebook、Airbnb、Walmart、Bloomberg、Instagram、Soundcloud、UberEatsなどがあります。
#2. Flutter
FlutterはGoogle が作ったオープンソースのネイティブアプリケーション開発フレームワークです。Dart という共通言語で開発を行います。詳しいデバッグができるので React Native で感じる「隔靴掻痒」感は少ないです。
Flutterを使うことで同一のコードベースからAndroidやiOSアプリを構築でき、その見た目もネイティブアプリです。FlutterはGoogleによる導入が2015年でしたが、2018年12月の公式リリースまではベータ段階にとどまっていました。
Flutterのユーザーは、携帯電話、テレビ、タブレット、ウェアラブルデバイス、スマートディスプレイ用のアプリを作成できます。
ちなみに Flutter Studio は Flutter の UI 作成のために使えるサイトです。ビルドのためのものではありません。Flutter を採用するなら使うことになるのではないかと思われます。Flutter ではそれぞれの Native パートをプロジェクト含めることができる。
#3. Xamarin
Microsoftが発表したXamarinは、C#プログラミング言語をサポートする最適なハイブリッドアプリフレームワークのひとつです。オープンソースのプラットフォームであるXamarinは、.NETとC#を使用したハイブリッドモバイルアプリの構築に使用されます。さらに、マイクロソフトの製品であるこの堅牢なマルチプラットフォーム開発フレームワークには6万人以上の開発者と貢献者がいて、優れたカスタマーサポートや豊富なドキュメントが用意されています。
コストを最小限とした理想的なフレームワークとなれば、Xamarinは1度のコード記述で、iOS、Android、Windows用のアプリやプラットフォームを3つ作成できるので、コスト削減にもつながります。
#まとめ
以上挙げた３つのフレームワーク以外、他にも[**モバイルアプリ開発フレームワーク**](https://kaopiz.com/ja-news-top-5-mobile-app-development-frameworks-20202021/)があります。どのフレームワークを選択するかは、要件、予算、技術的要件、そして短期的または長期的な成功の可能性に応じて、最も適したものを選ぶと良いでしょう。
肥大化したlogの削除

### bundle install が出来なかった・・・
Paizacloudで色々試している途中Gemfileに書き込んでbundle installしようとしたら・・・　出来ない！
って事が有り、調べていくと「logがいっぱいなのでは？」と言う事にたどり着いたので、忘れないように残しておきます。

### 何がどれくらいの容量を使用しているか確認
ターミナルで $ df -h するとディスクの残り容量を調べることが出来ると見つけたので早速やってみる。

```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
none            1.9G  1.7G  103M  95% /
tmpfs            64M     0   64M   0% /dev
tmpfs           997M  100K  997M   1% /run
/dev/vda2        99G   38G   57G  40% /bin/busybox
tmpfs           997M     0  997M   0% /run/lock
shm              64M     0   64M   0% /dev/shm
tmpfs           997M     0  997M   0% /sys/fs/cgroup
tmpfs           997M     0  997M   0% /proc/acpi
tmpfs           997M     0  997M   0% /proc/scsi
tmpfs           997M     0  997M   0% /sys/firmware
```
意味が分からないがPaizacloudのコンテナ再起動の読み込み時に「〇〇/1.7GiB」と表示が出てたので、一番上のnoneの所で、全体サイズが1.9G中　使用してるのが1.7Gなのかなと思い、何がそんなに使っているのかなと調べていくと・・・
$ sudo du -s -h /*　でどこにいくら使っているのか調べました。

```
$ sudo du -s -h /*
12M     /bin
4.0K    /boot
0       /dev
9.1M    /etc
24K     /fuse.deb
1.4G    /home
4.0K    /init-loader
45M     /lib
```
/home が1.4G使っているので次はhomeの中を調べます。
という風にその中のどれが使ってるのかな～？と次々調べていきます。

```
$ sudo du -sh /home/*
1.4G    /home/ubuntu
↓
$ sudo du -sh /home/ubuntu/*
4.0K    /home/ubuntu/アプリ1のフォルダ
815M    /home/ubuntu/アプリ2のフォルダ
39M     /home/ubuntu/アプリ3のフォルダ
↓
$ sudo du -sh /home/ubuntu/アプリ2のフォルダ/*
4.0K    /home/ubuntu/アプリ2のフォルダ/Gemfile
8.0K    /home/ubuntu/アプリ2のフォルダ/Gemfile.lock
12K     /home/ubuntu/アプリ2のフォルダ/lib
755M    /home/ubuntu/アプリ2のフォルダ/log
4.0K    /home/ubuntu/アプリ2のフォルダ/package.json
20K     /home/ubuntu/アプリ2のフォルダ/public
```
見付けました！やはりlogファイルが圧迫していました。
logのフォルダにはdevelopment.logが有るのでこれを空にします。

### logの削除（空にする）
logが有るアプリに移動し $ echo '' > log/development.log を実行

```
$ echo '' > log/development.log
```
すると755M 有った容量が 4kまで減りました！！

```
$ sudo du -sh /home/ubuntu/アプリ2のフォルダ/log/*
755M    /home/ubuntu/アプリのフォルダ/log/development.log

↓

$ sudo du -sh /home/ubuntu/アプリ2のフォルダ/log/*
4.0K    /home/ubuntu/アプリのフォルダ/log/development.log
```
当たり前ですがlogって蓄積されていくんですね。
これからは定期的にチェックしていきたいと思います。


### 参考にした所
http://linuxcom.info/linux-cmd-df.html

https://blog.kakeragames.com/2015/12/18/slim-xcode-data.html

https://qiita.com/Densetsu/items/30f5fe5cc9a95e47e93a
SwiftUIのNavigationViewについて

SwiftUIで書かれたコードはAppleのプラットフォームで共通で利用することが出来ます。
（iPhoneでもiPadでもmacOSでもwatchOSでもコンパイルさえ通れば同じコードが動作します）

多くの場合、アプリ開発といえばiPhoneアプリの開発となるのですがSwiftUIにはAppleプラットフォームで共通利用出来るという前提があり考慮しなければいけないことが増えてきます。

本稿ではiPhoneアプリ開発を行う上でのNavigationViewを利用するケースを見ていきたいと思います。

## デフォルトの挙動について

以下はシンプルにNavigationViewを利用する実装です。

```swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            Text("Hello")
        }
    }
}
```

SwiftUIはAppleプラットフォーム共通で利用出来るようにするために、NavigationViewはデフォルトで[UINavigationController](https://developer.apple.com/documentation/uikit/uinavigationcontroller)の機能の他に[UISplitViewController](https://developer.apple.com/documentation/uikit/uisplitviewcontroller)の機能を持っています。

実装を以下のように変更し、iPhoneとiPadでの表示を見てみると違いが確認出来ます。

```swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            Text("Primary")
            Text("Secondary")
        }
    }
}
```

<table>
  <thead>
    <tr>
      <th>画面の向き</yh>
      <th>iPhone</yh>
      <th>iPad</yh>
    <tr>
  <thead>
  <tbody>
    <tr>
      <td>縦</td>
      <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28406/eeb53fa3-9749-3942-f86c-e152655c0e36.png" width="60%"></td>
      <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28406/2e9f1382-67d4-52fe-b197-4bc8150f064d.png"></td>
    </tr>
    <tr>
      <td>横</td>
      <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28406/8e526044-c201-3d41-5504-dd826e03d4f3.png"></td>
      <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28406/028b1455-d40f-b9cb-b0a1-c7fe714d9dc6.png"></td>
    </tr>
  </tbody>
</table>

このように画面の横幅によって表示される内容が異なってくることが確認出来ます。

**尚、iPhoneは12 pro maxを利用していますが、iPhone12 miniのようにサイズの小さい端末だと横向きの場合も縦向きの場合も同じ表示になります。**

## NavigationLinkの挙動

NavigationLinkを利用する場合の挙動は以下のパターンに分けられます。

||PrimaryのNavigationLink|SecondaryのNavigationLink|
|---|---|---|
|画面の横幅（小）|Primaryに対して次の画面がPushされる|表示されることはない|
|画面の横幅（大）|Secondaryの内容が変わる|Secondaryに対して次の画面がPushされる|

## UISplitViewControllerを無効化する

上記内容を踏まえると横向きにしたケースで端末のサイズによって挙動が変わってくるiPhoneの場合、画面が分割されるケースとそうでないケースで見せ方を考える必要が出てきてしまうため実装難易度が高くなります。

これを回避するために、SplitViewを無効化するオプションがあります。
`navigationViewStyle`というmodifierを利用して、NavigationViewの挙動を変更することが出来ます。

NavigationViewはデフォルトでは[DoubleColumnNavigationViewStyle
](https://developer.apple.com/documentation/swiftui/doublecolumnnavigationviewstyle)を設定しているような振る舞いをします。
`navigationViewStyle`の引数に[StackNavigationViewStyle
](https://developer.apple.com/documentation/swiftui/stacknavigationviewstyle)を設定することでUISplitViewControllerの設定を無効化し、画面の表示を統一することが出来ます。

```swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            Text("Primary")
            Text("Secondary")
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}
```

上記のように設定すると画面のサイズがどうなってもSecondaryViewが表示されなくなり、画面サイズによる挙動が統一されます。

---

iPhoneでSwiftUIを利用する場合、UISplitViewControllerが無効になっていないと他にも問題が出たりするので安定した開発をするためにもNavigationViewには`StackNavigationViewStyle`を設定しておくのが無難です。
【Swift】ボタンを押すと遷移するNavigationBarのアイテムを共通化する

# どういうことか

想定しているのは、押すと特定のページに遷移するボタンがNavigationBarに設置されていて、それをどのページでも使えるように共通化するというもの。
ここでは `userIcon` を押すと `userInfoController` に遷移することを想定する。

## Utilityの作成

ここに共通化させるアイテム（というか処理）を書く。

```swift:NavigationBarUtility.swift
import Foundation
import UIKit

class NavigationBarUtility {
    
    // 遷移するための引数をControllerから受ける
    static func setUserIcon(userSelector: Selector, viewController: UIViewController) -> UIBarButtonItem {
        
        // ユーザーのアイコン画像と色の設定
        let userIcon = UIBarButtonItem(image: UIImage(named: "person"), style: .plain, target: viewController, action: userSelector)
        userIcon.tintColor = UIColor.black
        
        return userIcon
    }
}
```

## Controllerの処理

```swift:ViewController.swift
        // NavigationBar右上のアイコン
        navigationItem.rightBarButtonItem = NavigationBarUtility.setUserIcon(userSelector: #selector(self.toUserInfo), viewController: self)

// 中略

    @objc func toUserInfo() {
        // userInfoに遷移する
        let storyboard = UIStoryboard(name: "UserInfoController", bundle: nil)
        let vc = storyboard.instantiateViewController(identifier: "UserInfoViewController")

        vc.modalPresentationStyle = .fullScreen

        self.present(vc,animated: true)
    }
```

おわり(´・ω・｀)
`@objc` における遷移する処理は各Controllerで書かなきゃならないので、この部分も共通化できたらいいんですが。。
react-native-admobをインストールしたときのandroidでのエラー


広告を出したくてreact-native-admobを利用したがnpm installしただけで androidで起動できなくなった。

## 流れ

インストールは以下を参考に実施。
https://qiita.com/juginon/items/7f4ee4273b2c480277f3

```
npm instal  --save react-native-admob@next

```

そしてこの段階で `npm run android`以下実行してエラーが出る。


##  エラー1 react-native-admob:compileDebugJavaWithJavac FAILED 

以下のようなエラーがドバババとでる。

```
****/node_modules/react-native-admob/android/src/main/java/com/sbugert/rnadmob/RNAdMobInterstitialAdModule.java:20: エラー: シンボルを見つけられません
import com.google.android.gms.ads.InterstitialAd;
                               ^
シンボル:   クラス InterstitialAd
場所: パッケージ com.google.android.gms.ads

```

参考リンク: https://github.com/sbugert/react-native-admob/issues/448

上記リンクの一番下の対応で、このエラーはでなくなった。

node_module/react_native_admobのbuild.gradleを修正する。

```
// implementation 'com.google.android.gms:play-services-ads:+' // comment this line
implementation 'com.google.android.gms:play-services-ads:19.7.0' // add this line.
```

しかし、まだエラーが出る


## エラー2 “unexpected element <queries> found in <manifest>” error?

参考
https://stackoverflow.com/questions/62969917/how-to-fix-unexpected-element-queries-found-in-manifest-error

https://stackoverflow.com/questions/51479691/how-can-i-upgrade-react-native-gradle-version


使っているgradleのバージョンが3.5.3だったので、3.5.4に更新して対応。



```
# android/builed.gradle
    dependencies {
        ...
        classpath("com.android.tools.build:gradle:3.5.4")  
    }


```


もういっちょエラーが出る

## エラー3 The number of method references in a .dex file cannot exceed 64K

参考:https://stackoverflow.com/questions/36785014/the-number-of-method-references-in-a-dex-file-cannot-exceed-64k-api-17

android/app/build.gradle のdefaultConfigに
「multiDexEnabled true」

```
#android/app/build.gradle

    defaultConfig {
        ...
        multiDexEnabled true //bug
    }

```

## おわり

以上でエラーは一旦落ち着いた。あとは手順どおりで広告表示まで到達。