OmniAICreator/Qiita-1.07M huggingface dataset:
.gitignoreの内容が反映されないときに確認するべきこと

#.gitignoreに書いてあるのに反映されない！！
ご存知の通り、`.gitignore`ファイルに指定したファイルやフォルダは、gitの**管理対象外**になります。
つまり、いくら変更を加えてもSourceTreeで確認することはできません。
![スクリーンショット 2021-01-18 15.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/f12598cf-9475-7b90-3c7c-2c068b7d85bb.png)

しかし、なぜか`.gitignore`に書いてある内容が反映されないのです:worried:
書き方が間違ってるわけでもないのに・・・

#原因は「リモートリポジトリ」に管理対象外にしたいファイルが残っているから
例えば、下記のような`.gitignore`ファイルがあったとします。

```console
node_modules
.env
local_properties.json

# editor
.idea/
.vscode/
.settings/
.editorconfig
```

**プロジェクト直下にある`local_properties.json`は`.gitignore`ファイルに記載があるのに、なぜかgitの管理対象になっています。**

なぜか？

**リモートリポジトリに`local_properties.json`が存在していたため、ローカルでも管理対象になっていたようです。。。**

一度gitにアップ（つまりリモートリポジトリにpush）したファイルである`local_properties.json`を、`.gitignore`に追加しても追跡され続けていたのが原因でした:disappointed_relieved:
悩む画像の拡張子問題を解決！

様々な拡張子がある中どの拡張子で画像を保存すればいいかを考えることがあると思います。
それぞれの拡張子について書いてあることはあっても用途別で書いてるところがなかったのでこちらでまとめてみようと思います。

#写真などの色彩豊かな画像
![redstZA019_TP_V4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/840867f1-6dc5-bcfd-6571-c2fa18cf2e77.jpeg)
####最適な拡張子 : JPG or WebP
こちらは今まではJPG一択だったのですが、近年新しくWebPが出てきました。
WebPはios14から対応となりましたので、これで全てのosとブラウザが対応することとなりました。
圧縮率が高くサイズを軽くできるというのと、透過もできるというのが強みになります。
ただ、最新のブラウザのみでしか対応できておりませんので注意が必要です。
よってJPG or WebPとなります。

もしさらに透過も加えたい場合はPNGを次点として上がってくるとは思いますが、
ファイルサイズが大きくなるので透過自体をおすすめはしません。

#アイコンや色数の少ない画像
![スクリーンショット 2021-01-18 15.49.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/726f7b8b-17c7-3a69-4dc2-f1aeb9410c7a.png)

####最適な拡張子　:　SVG > PNG > GIF

こちらはSVGが一番いいと思います。
ベクターデータのSVGは拡大縮小してしても画質が落ちないという点やファイルサイズも少なくすむという点で１番です。
次はPNGです。
ファイルサイズは少し大きくはなりますが、GIFとは違い画像の質を落とすことがなく表現することができます。

ちなみにあげた三つの拡張子は全て透過可能です。


#アニメーションを加えた画像
![ezgif-5-249fcdb6cdcb.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/b400e513-1cd7-fdec-afcf-19fc4731ce45.gif)
###最適な拡張子　:　SVG > GIF
こちらはSVGがいいと思います。
GIFもアニメーションを加えて作成できますが、ファイルサイズが大きくなってしまいます。
そのためSVGの方が最適といえます。

#まとめ
正直私はこのように思っていますが、
いろいろな環境や状況によってはこれに当てはまらないことがあると思います。
だからみなさん書いてないのかもしれません。
もしこの拡張子はこれに当てはまるなどの情報がありましたら教えていただけますと幸いです！
【TypeScript】.ts拡張子と.tsx拡張子

# .ts拡張子と.tsx拡張子の違い
## .ts拡張子
- 純粋なTypeScriptファイル
- JSX要素の追加をサポートしない

## .tsx拡張子
- JSXを含むファイル
- 型アサーションの記法として `value as type` と `<type>value` の2通りあるが、後者は `.tsx` には書けない  
（ `<>` はJSXタグのマーカーであるため）

# Reactを使うプロジェクト内のTypeScriptファイルは全て.tsxではダメなのか
## 結論
- `.ts` と `.tsx` は明示的に分けるべき

## 理由
- 拡張子で明示的にしておくことで、「このファイルにJSXを書くべきではない」ことを表すことができるため  
（UIコンポーネントのファイルか、ロジックを書くファイルか）
【Laravel】publicとresourcesディレクトリのassets（img, css, js）の違いについて

Laravelのimageファイルやjs, cssファイルの置き場所を探したときに、publicとresourcesディレクトリに混在していることがある。

このpublicとresourcesディレクトリの違いについて。

**▼イメージ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/5da29bef-cd10-e974-0e7d-63731696f11d.png)


##publicとresourcesディレクトリの違い
公開範囲が異なる。

**・publicディレクトリ**
名前（public）の通り、中身が公開されており、ブラウザが直でアクセスできるデータ。


**・resourcesディレクトリ**
公開はされておらず、コンパイル前のデータが置かれている。

viewsディレクトリのビュー（.blade.php）もコンパイル前はPHPを含んでいるが、コンパイル後の公開するファイルはHTMLのみとなる。


<br>
##publicとresourcesディレクトリの使い分け
publicファイルにはブラウザが直でアクセスしてもいいデータを置く。

resoucesの使い方は主に２つ。

**(1)サブの画像などを置いておく**
公開されないので何を置くかは自分次第。

**(2)コンパイルが必要なファイルをおく**
.blade.phpやscssなどコンパイル前の元ファイルを置いておく。
RDSのDBパラメーターグループ関連のコマンドめも

#はじめに
* RDSのDBパラメーターグループ関連のコマンドメモとしての備忘録
* 本手順では、AWS-CLIでの操作となります。

#実施手順

##DBパラメーターグループ名の一覧を出力

```
[root@localhost ~]# aws rds describe-db-parameter-groups --query 'DBParameterGroups[].DBParameterGroupName'
[
    "aurora-postgresql11",
    "postgresql11"
]
```

※現在、登録してあるDBパラメーターグループは「aurora-postgresql11」「postgresql11」の2つです。

##DBパラメーターグループの設定値をファイルに出力

▼DBパラメーターグループの設定値をJSON形式(デフォルト)で出力

```
・aurora-postgresql11 の場合
# aws rds describe-db-parameters --db-parameter-group-name aurora-postgresql11 > /tmp/aurora-postgresql1_parameters.json
```

▼DBパラメーターグループの設定値をCSV形式(出力結果を成形した状態)で出力

```
# aws rds describe-db-parameters --db-parameter-group-name aurora-postgresql11 \
    | jq -r '["名前","値","許可された値","変更可能","送信元","適用タイプ","データ型","説明","ApplyMethod","MinimumEngineVersion"], (.Parameters[] | [.ParameterName,.ParameterValue,.AllowedValues,.IsModifiable,.Source,.ApplyType,.DataType,.Description,.ApplyMethod,.MinimumEngineVersion]) | @csv' \
    | iconv -t sjis > /tmp/aurora-postgresql11_parameters.csv
```

※上記のコマンドは、以下のブログが参照したものである。
https://dev.classmethod.jp/articles/rds-parameter-group-export-to-csv/


##DBパラメーターグループの削除

```
・aurora-postgresql11 の場合
# aws rds delete-db-parameter-group  --db-parameter-group-name  aurora-postgresql11 
```


#参考URL
https://dev.classmethod.jp/articles/rds-parameter-group-export-to-csv/
https://blog.manabusakai.com/2017/02/rds-parameter-group-diff/
Docker+Railsにdotenvを導入して環境変数を管理する


# 実現したいこと
Dockerを使ったRails開発で、公開してはならないAPIキーやパスワードなどを別ファイルでGit管理する方法。

# 大雑把な順番
1. gemを追加
2.  .envファイルにプロジェクトで使う環境変数を記述
3.  .gitignoreに.envファイルを含める
4. erbテンプレートに従って環境変数を渡す

# 使用したバージョン
- Rails6
- ruby 2.7.2

# 手順

## gem 'dotenv-rails'を追加

```ruby:Gemfile
gem 'dotenv-rails'
```

## コンテナ内にbundle installを行う
```shell:bash
docker-compose run コンテナ名 bundle install 
```

## docker-compose.ymlを編集
yml内にenv_fileと書くことで環境変数を管理するファイルを読み込む設定ができる

```ruby:docker-compose.yml
code:docker-compose.yml
 web:
 	省略
 	env-file:
 		- .env(環境変数を管理したいファイル名を記述)
```


## コンテナをビルドする
docker-compose.ymlを編集したので改めてビルドする

```bash
docker-compose build
```


## .envファイルに設定したい環境変数を書く
```ruby:.env
 MAP_API_KEY="発行したAPIキー"
 PASSWORD="パスワード"
```
## .envファイルをgitignoreに追加

```ruby:.gitignore
 /.env
```

## viewのerbテンプレートで環境変数として渡す
```ruby:index.html.erb
 以上省略
 <script src="https://maps.googleapis.com/maps/api/js?key=<%=ENV['MAP_API_KEY']%>&callback=initMap" async defer></script>
```
ここで重要なのがerbテンプレートに従って、  `<%=ENV['']%>`と書くという事。
これをせずに、`ENV['MAP_API_KEY']`と書いて渡しており、上手くviewで表示できず、2日ほど詰まっていた。
WindowsをアップデートしたらVirtual boxの仮想マシンが起動しなくなった

##仮想マシンが起動できない
いつものように仮想マシンを起動しようとすると、、、

```
vagrant up

~中略~

There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["startvm", "28f326ad-a4fd-4ae5-9345-92b4a922c5a3", "--type", "headless"]

Stderr: VBoxManage.exe: error: Failed to open/create the internal network 'HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #2' (VERR_INTNET_FLT_IF_NOT_FOUND).
VBoxManage.exe: error: Failed to attach the network LUN (VERR_INTNET_FLT_IF_NOT_FOUND)
VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component ConsoleWrap, interface IConsole
```

そういえばWindowsの更新をしたのでそれで設定が変わってしまったのかもしれません。

##ネットワークアダプタの設定を確認

コントロールパネルから、ネットワークアダプターの設定を開きオプションを確認します。

なるほど、先ほどのエラーメッセージには``'HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #2'``とありましたが、'VirtualBox Host-Only Ethernet Adapter #3'しか表示されませんね。

##Virtual box managerで設定変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350898/8b32159f-c44b-3f40-3299-b110a852ef8e.png)

対象のVMを選択した状態で設定を開き、ネットワークタブを選択します。
アダプター2にはVirtualBox Host-Only Ethernet Adapter #2が設定されていましたが、プルダウンからVirtualBox Host-Only Ethernet Adapter #3を選択し、OKをクリックします。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350898/ab775f5b-92d5-899a-20d1-40776091cc13.png)

Virtual box managerから"起動"をクリックすると、無事起動ができました。
【小ネタ】PHPer脳の人がJavaScriptでPHPのlist()っぽいことをやってみる。

# はじめに

ドット連結の文字列を分割してそれぞれを変数にできないかなーって考えたときに、もしかしたらJSでもPHPのlist()みたいなことできるんじゃね？って思ったんですよ。

# PHPのlist()とは

右辺が配列になるとき、左辺側に列挙した変数に値を入れれるというやつです。
https://www.php.net/manual/ja/function.list.php

```php
list($jeffy, $tockey, $fagimaru) = ['犬', '猿', '雉'];

echo $jeffy; // 犬
echo $tockey; // 猿
echo $fagimaru; // 雉
```

実はPHP7.1以降は以下の書き方でもいけるんですよね。全然気づかなかった……

```php
[$jeffy, $tockey, $fagimaru] = ['犬', '猿', '雉'];

echo $jeffy; // 犬
echo $tockey; // 猿
echo $fagimaru; // 雉
```

# JSではどうするの？

実はPHPの省略構文と同じです。

```javascript
const [jeffy, tockey, fagimaru] = ['犬', '猿', '雉'];

console.log(jeffy); // 犬
console.log(tockey); // 猿
console.log(fagimaru); // 雉
```

「分割代入」っていうんですね。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
行末コード(CR)[^M]を削除する方法

Carriage Returns 
\r
^M
を削除する方法
##1つのファイルのみ
```
sed -i 's/\r$//g' <filename> 
```

##カレントディレクトリ配下の全てのファイル
```
sed -i 's/\r$//g' $(find . -type f)
```

## 参考
https://stackoverflow.com/questions/800030/remove-carriage-return-in-unix

指摘箇所修正しました。
PlatformIO のライブラリを登録してみた

PlatformIO に自作ライブラリを登録してみたのですが、意外とすんなりいかなかったので、手順をまとめてみました。

### ライブラリを作成する

おおよそ[公式ドキュメント]( https://docs.platformio.org/en/latest/librarymanager/creating.html)通りです。
このディレクトリを tar ball でかためて公開することになるので、試行錯誤したファイルなどを残さないように注意しましょう。
`.git/` ディレクトリは無視してくれるようです。

例として ExampleLibrary を作るものとすると、ディレクトリ構成はおおよそこんなかんじでしょうか。

```
ExampleLibrary/
├── LICENSE
├── README.md
├── examples
│   └── main.c
├── include
│   └── Example.h
├── library.json
└── src
    └── Example.c
```

#### library.json
これも[公式ドキュメント](https://docs.platformio.org/en/latest/librarymanager/config.html#library-json)通りで、最短だとこんなかんじでしょうか。

```json
{
  "name": "ExampleLibrary",
  "version": "0.0.1",
  "description": "Example Library Project",
  "keywords": "example",
  "repository":
  {
    "type": "git",
    "url": "https://github.com/example/ExampleLibrary.git"
  },
  "authors":
  [
    {
      "name": "John Smith",
      "email": "john@example.com",
      "url": "https://github.com/example",
      "maintainer": true
    }
  ],
  "license": "MIT",
  "homepage": "https://github.com/example/ExampleLibrary",
  "frameworks": "*",
  "platforms": "*"
}
```

自分がハマったのは "name" と "version" フィールドです。

"name" に空白を入れる、バージョン名を x.y.z-n の形式にする、というのをやってしまったのですが、これをすると色々と壊れるようです。

またバージョンは、慣れないうちは `0.0.1` とか付けておくと良さそうです。
公開したパッケージは `pio package unpublish` で取り下げることができるのですが、パッケージ自体はサーバに残るようで、同じバージョンで再度 publish してもエラーになります。
つまり失敗すると同じバージョン名で publish できなくなります。

### 公開するファイルの確認

以下を実行すると同じディレクトリに tar ball ができるので、公開前に余計なファイルが紛れ込んでいないかなど確認することができます。

```
pio package pack ExampleLibrary/ 
```

### アカウント作成

ライブラリの公開には PlatformIO.org にアカウントが必要です。
このアカウントは CLI から作成します。（Webからは作れないようです）

```
$ pio account register
Username: example
Email: john@example.com
Password: 
Repeat for confirmation: 
Firstname: Jhon
Lastname: Smith
```

完了するとメールが届くので、そのメール内のリンクを開いてconfirmします。


### 公開！

公開する前にログインしておく必要があります。

```
$ pio account login
Username or email: example
Password: 
Successfully logged in!
```

```
pio package publish $PWD/ExampleLibrary
```

ここで指定するディレクトリパスは絶対パスを指定します。（相対パスだとエラーになります）
リモートでESP32を操作する

この記事は実際に研究室でESP32をPCに接続しなくても動作される方法をメモとして書くつもりです。
まずはhttp://micropython.org/webrepl/
このリンクに入ります。入った後に下の図のように左上のところに自分のデバイスのIPアドバイスを入れておきます。そしてconnectをクリックします。
![micropython.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/739847/65acf744-1f52-557c-ca04-bac18cb8feb4.jpeg)

右側のSend a fileのところに実行するファイルを選択してからSend to deviceをクリックします。
実行したいファイルを実行する時にはexecfile("ファイル名")を入力してからenter。
lsのような機能がここでImport os--os.listdir()があります。
詳細はこのリンクを参照すればよいでしょう。https://note.nkmk.me/python-listdir-isfile-isdir/
他にもhelp('modules')のようなコマンドがあります。
コンパイラやコードを書くソフトウェアが何でもいいです。ここでただ編集済みのファイルを伝送するだけです。
Google Apps Script で PDF をテキスト化する

### はじめに

GASでPDFの内容を読み取りたい！と思った時に書いたコードの記録

### コード

```typescript
export class PDFService {

	toStringByFileId(fileId: string): string {
		const blob: GoogleAppsScript.Base.Blob = DriveApp.getFileById(fileId).getBlob();
		const resource: any = {
			title: blob.getName(),
			mimeType: blob.getContentType(),
		};
		const doc: GoogleAppsScript.Document.Document = this.toDoc(resource, blob, 'ja');
		return doc.getBody().getText();
	}

	private toDoc(resource: any, blob: GoogleAppsScript.Base.Blob, language: string): GoogleAppsScript.Document.Document {
		const options: any = {ocr: true, ocrLanguage: language};
		try {
			const file: GoogleAppsScript.Drive.Schema.File = Drive.Files.insert(resource, blob, options);
			return DocumentApp.openById(file.id);
		} catch(e: any) {
			console.error(e);
		}
	}
}
```
[Rails] Your Yarn packages are out of date! エラー解決の思考

#原因推測
**解決法・結論だけ見たい方は、向かって右の「プラン実行」をクリックして少し下にスクロールしてください。↓ここが結論↓と書いてあります。**

開発環境でAPサーバーを起動しようとした所、下記エラーが発生しました。 
 Your Yarn packages are out of date!
  Please run 'yarn install --check-files' to update.
[![Image from Gyazo](https://i.gyazo.com/5437f7d5d908934e9e020b968872aedf.png)](https://gyazo.com/5437f7d5d908934e9e020b968872aedf)

①　証拠集め
②　証拠の意味を解釈・理解
③　証拠から原因を推測

この手順で解決を図ります。それではスタート↓

①　証拠集め
英語訳します。
[![Image from Gyazo](https://i.gyazo.com/554c0d48b492d3f205ce1f798dd19e2b.png)](https://gyazo.com/554c0d48b492d3f205ce1f798dd19e2b)
[![Image from Gyazo](https://i.gyazo.com/c10d8a8a82d5f9a536f95de60143a713.png)](https://gyazo.com/c10d8a8a82d5f9a536f95de60143a713)
なるほど、コンピューターが「あなたのパッケージ古いよ！これやってね！」というアクションプランを２つ教えてくれています。有難うコンピューター。

②　証拠の意味を解釈・理解
③　証拠から原因を推測
アクションプランがあるので③を一旦飛ばします。かつ優先度が低いので、
「ヤーンパッケージとは？」のような検索は今回はしません。よって②も飛ばします。


#プラン実行
今回提示されたプランは２つ
A　% yarn install--check-files実行
B　(config / webpacker.yml）の'check_yarn_integrity'を「false」に変更

---
A　% yarn install--check-filesを実行した結果、エラーが返ってきました。
[![Image from Gyazo](https://i.gyazo.com/981758ab909a6ebe4b085ad69a5300bc.png)](https://gyazo.com/981758ab909a6ebe4b085ad69a5300bc)
「install--check-files」が見つかりません。
このコマンドのドキュメントについては、https：//yarnpkg.com/en/docs/cli/runで調べて！
と言われています。この時点でBを試します。

---
B　(config / webpacker.yml）の'check_yarn_integrity'を「false」に変更
ファイルを確認するとすでにfalseになっています。
翻訳のミスだろう。falseをtrueに変更してみよう。
[![Image from Gyazo](https://i.gyazo.com/58790cdd530a741b11d2e37d93be07b2.png)](https://gyazo.com/58790cdd530a741b11d2e37d93be07b2)
もう一度rails sを実行しても、結果はエラーのままでした。

---
よし、根本から理解するのは優先度低めなので、他の方の知識をお借りしよう！
エラー名 Your Yarn packages are out of date!でググって見ると、
下記の記事を発見しました。

==============================================================
↓ここが結論↓

一度 node_modulesディレクトリとyarn.lockファイルを削除します。
`% rm -rf node_modules/`
`% rm yarn.lock`

yarn installし直します。
`% yarn install`

rails sしたら無事に起動できました。

===============================================================

なるほど、バージョンが古いときは
一度エラーに引っかかっている ディレクトリ/ファイル を削除して
インストールしなおせば良いのか。
他への影響も多くなさそうなので、とりあえず記事通り実行してみます。すると、
[![Image from Gyazo](https://i.gyazo.com/2de1a8b79c65eeb76fb756a635e6337c.png)](https://gyazo.com/2de1a8b79c65eeb76fb756a635e6337c)
はい、無事起動できました。アプリの動作も問題ありません。

原因がなんだったか言語化できてはいないのですが、先に進みます。
本当はじっくり調べてみたい。

---
下記の記事を参照させていただきました。有難うございます。
<a href="https://motomichi-works.hatenablog.com/entry/2020/04/23/115936">rails sしたらYour Yarn packages are out of date!と表示された</a>
Emotion v11とtypescriptが喧嘩する ~jsx設定方法~

emotionの環境構築をおこなったところ、
TypeScript絡みの設定が案外手強かったので備忘録とさせていただきます。

## ざっくり環境

React v17.0.1
typescript v4.1.3
@emotion/react v11.1.4
@babel/core v7.12.10


## jsx属性認識しない問題

```react
import { jsx } from '@emotion/react'
import { FooterContainer } from '../../../style/components/block/Footer'

export default function Footer() {
  return (
    <div css={FooterContainer}>
      <p>Footer</p>
    </div>
  )
}


```
emotion v11においては、
上記のように `jsx`をimportして、reactからやってくるjsxを使わない（reactを直でimportしない）記述となります。
しかし、早速問題が...

![スクリーンショット 2021-01-18 11.42.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441432/ba97162d-f394-39bc-ff09-59877ff6b60b.png)

なんとか型定義をimportしているjsxの方に向かせたいですね。
そもそもreactのJSXの型定義はどこからきているのでしょうか？

答えはTypeScriptのコンパイルのオプションである `jsxFactory`からきています。
https://www.typescriptlang.org/tsconfig/#jsxFactory
こちらはデフォルトでは `React.createElement`になっています。

`jsxFactory`をemotionのjsxで呼べるよう変更しておきます。
ちなみにトランスパイルをbabelに任せている場合、 `"jsx": "preserve"` でOKです。

```js:tsconfig
{
  "compilerOptions": {
    "jsx": "preserve",
    "jsxFactory": "jsx",
...
}
```

これでエラーが解消されます。


## 別解:プラグマを使う
公式のドキュメントでは以下のようなコメントが差し込まれています。

```
/** @jsx jsx */
```


このコメントは**プラグマ**というTSでサポートされている機能になります。
この機能は、ファイル毎にjsxFactoryを変更できる機能です。
こちらを追加するとエラーが解消されます。


```react
/** @jsx jsx */
import { jsx } from '@emotion/react'
import { FooterContainer } from '../../../style/components/block/Footer'

export default function Footer() {
  return (
    <div css={FooterContainer}>
      <p>Footer</p>
    </div>
  )
}

```


https://github.com/Microsoft/TypeScript/pull/21218

ただ、ファイル毎にプラグマを記述しないといけないのが微妙ですね。

## わがまま
jsxを直で上書きしてしまうのはちょっと不安です。
毎度jsxを読まないといけないのもなんか微妙です。
もっといい方法があれば教えていただけると嬉しいです:runner:
contentfulでTypeError: Expected parameter accessTokenが出た時の対処法

nextJSとcontentfulでアウトプット作品を作ってる時に環境変数でアクセストークンを管理すると

```
TypeError: Expected parameter accessToken
```
このようなエラーが出て途方にくれました。
実際にstackoverflowでに同様な質問がされていましたが、解決法がなかったのでこちらで簡潔に書きたいと思います。

結論からしまして、環境変数を

```.env
NEXT_PUBLIC_CONTENTFUL_SPACE_ID=xxxx,
NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN=xxx,
```

nextJSでは.envの環境変数名.env.localに統一しないといけなかったり、
変数名の先頭にはNEXT_PUBLIC_を付け加えないといけないので注意が必要です。
Android初学者 adbコマンドでターミナルから操作してみた

adbコマンドを使ってターミナルからAndroid端末を操作してみた。

## インテント直で投げる
`adb shell am start -n パッケージ名/アクティビティクラス`

```java
adb shell am start -n com.example.bookmanager_android/.MainActivity
```

上記を叩くと端末を触らなくてもbookmanagerアプリのMainActivityが開く。

`Security exception: Permission Denial`が出た場合
AndroidManifestファイルの開きたいアクティビティ部分に`android:exported="true"`を追加する。

## 端末にまかせる
`adb shell am start -a アクション -d URL`

```java
adb shell am start -a android.intent.action.VIEW -d http://www.google.com/
```
上記を叩くと端末を触らなくてもgoogleサイトが開く。

## おまけ
アプリ側でクエリをもってるとき

```java
adb shell am start -a android.intent.action.VIEW -d testapp.v1://test?open=item\&id=2
```
testapp.v1://test?open=item&id=2 ⇔ https://www.test.com/jp/item/2　が開く

## 参考サイト
https://qiita.com/tkc_tsuchiya/items/1fd9953bc1337150dff1
ありがとうございました！
Raspberry Pi で 電波時計の校正

# 課題
鉄筋コンクリートであったり周辺環境が悪い住居の場合、室内の電波時計がうまく校正できない（うちは両方っぽい）。せめて特定の部屋では校正できるようにしたい。

#作成
自分でゼロからやるも楽しいけれど、既に[たくさんの方法](#その他参考記事)がwebで紹介されている。今回はこの方の記事をそのまま試してみた。回路図からJJY生成スクリプトまで、丸コピーである。

[Raspberry Piを使用した電波時計リピーター | ImageCanvas Annex (by Akebi)](https://blog.akebi.jp/archives/2383)

幾つかの中でこの記事を選んだ理由は下記の２点。

1. 高調波の利用ではなく目的の周波数(40kHz/60kHz)を使うため受信感度が良さそう
1. 調整しなくて良いまたは少なそう（当該記事執筆までに為された努力に敬意を表する）

また、上記1. は無駄な電波を出さないために出力を抑える観点でも重要。

折角 Raspberry Pi Zero W を使うので、Zero用のユニバーサル基盤[^1]を使って省スペースに実装してみた。配線は半田とポリエチレン線、錫メッキ線。なお、40kHzの水晶が店頭で入手できなかった事が主な理由だが、時計の校正ができれば良いので今回は60kHzに絞って作成した。

電源についてはRaspberry Pi の5Vから給電した。アンテナは電波時計用のバーアンテナが欲しかったもののすぐに入手できなかったので、とりあえず元記事通りの手巻きで作成した。

違いは小さな基盤に実装した事くらいだが、小さい事は意外と良い。
![DSC_2630_clip_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/f043380f-3843-adf3-acdd-26f089f17e88.jpeg)


#実験
初回はICの7番端子をGNDに接続し忘れていて事故りそうだった。念のためアンテナの1次コイル側に電流計を挟んでいたため、500mAを見て即座に基盤を抜いた。RPi本体のレギュレータあたりに高負荷をかけてしまった気がする。

気を取り直して回路を見直して修正し、2回目で問題なく動作した。バーアンテナ単体だと約30cmの距離でG-Shockの受信レベルがL2(3段階中)になる程度。アンテナにAM用のループアンテナを取り付けたところ、2mくらい離れても時刻校正ができた。

###スプリアスの問題
やはりというか、アンテナも同調型では無いし何のフィルタも使っていないため高調波はがっつり出ている気がする。SDR等は持っていないため確認が難しいものの、広帯域レシーバでは整数倍の周波数でよく受信する。

動画は180kHz(3倍)で受信している様子（GIFアニメのため時間軸は実際と異なる）。基盤のLEDとレシーバの入感のタイミングが同期しているのが分かる。
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/46155099-2abd-5591-1573-6d7049b3c0d0.gif)

残念ながら中波帯域のAM放送まで微弱なノイズが染み出る状況のため、これ以上高効率のアンテナを繋ぐのは止したほうが良さそうである [^2]。

#材料
手元にあったり、お店で見つからなかったものはオリジナル記事とは異なる部品を使うことになった。

- Raspberry Pi Zero W (手持ち, ピンヘッダ取り付け済)
- 水晶振動子(60kHz) [^3]
- [Raspberry Pi Zero用ユニバーサル基板 [RoHS] UB-RPI03](https://eleshop.jp/shop/g/gH7C311/) (605円) [^1]
- [パワーMOSFET(2sk4017)](https://eleshop.jp/shop/g/gE7U369/) (89円)
- 4回路2入力NANDゲート(CD4011B) [^4]
- セラミックコンデンサ 15pF (11円)
- セラミックコンデンサ 30pF (11円) [^5]
- 抵抗 10MΩ
- 抵抗 220kΩ
- 抵抗 24kΩ (元記事通り。LEDを明るくしたければもっと低い抵抗。)
- ICソケット(14pin)
- LED
- ピンヘッダ(5pin)
- ピンソケット(5pin)
- [フェライト棒φ10(mm)](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-0FAS) (303円)

#その他参考記事
[Raspberry Piで電波時計の時刻合わせ | Hobby Gardens (by Benihara Hajime)](https://www.kougen.dev/hobbygardens/article.php?id=73)
[Raspberry PI で電波時計の時刻を合わせる | コメを噛め (by rerofumi)](http://www.fumi2kick.com/komekame/archives/2504)
[受信しない電波時計の時刻合わせをするJJY発信機を500円で自作！ | ここから自由時間 (by こけんじ)](https://kokenji.net/jjyttransmitter/)


[^1]: 材料費のうちこの商品が2番目に高かった（水晶振動子を安価に入手できる場合は、材料費のほとんどはこれになってしまう）。
[^2]: 電波法にも抵触することになる。
[^3]: 日本橋デジットで購入。カウンターの中にあるので店員さんに言う。700円くらいだった。秋月だと100円
[^4]: 日本橋デジットで購入(カウンター内)。数十円だった記憶。
[^5]: 元記事では15pF*2を並列にしていた。省スペースのため合計容量を用意。
Automatic indexing「ORA-13629」エラーで動作しない


automatic indexingのテスト検証中に、エラーで動作しなくなりました。
解決できていませんので、忙しい方は読まないでください。

その時の内容を記録します。
![AI_ERROR.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113544/4f410bca-bef7-7d0c-a979-066819b04ebb.png)

##事象
エラーが頻発して自動タスク（自動索引の機能）が動かなず、
新しい自動索引が作成されない。

エラー
　ORA-13629: タスクまたはオブジェクトSYS_AUTO_INDEX_TASKは、別の操作で使用中です。

##直前の操作
自動索引機能を有効化した後、REPORT ONLY→無効化→再度、REPORT ONLYにしました。

```
スキーマを指定して、自動索引を有効化
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', 'スキーマ名', TRUE);

REPORT ONLYで設定
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','REPORT ONLY');

自動索引を無効化
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','OFF');


再度、REPORT ONLYで設定
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','REPORT ONLY');
```

実行結果を確認してみると、エラーが発生。。

```
select DBMS_AUTO_INDEX.REPORT_ACTIVITY(
TO_TIMESTAMP('2021/01/08 15:00:00.00'),
TO_TIMESTAMP('2021/01/08 18:00:00.00'),
'TEXT' ,'ALL' , 'ALL'
) FROM DUAL;

ORA-13629: タスクまたはオブジェクトSYS_AUTO_INDEX_TASKは、別の操作で使用中です。
```

前の操作が完了していないのか・・？と思って1週間ほどautomatic indexingを停止した後、
再度、有効化してもまた同じエラーで解消されず。。
該当SQLと思われるセッションをkillしてみてもエラーは解消されず。。


お手上げだったのでサポートに問い合わせしました。




・・すると、バグと同件の可能性が極めて高いと言われました。
サポート側でも再現性の確認できており、19.7では発生しないことは確認されているそう。
もっと上のバージョンでも改善されているのか質問すると、
「もしも、19.8以上等のバージョンで発生した場合は、別の不具合となる為、再度問い合わせしてほしい」と言われました。

アップグレードはメンテナンスが必要なのでなかななできません。
残念ながら、お手上げなのでautomatic indexingのテスト検証は今回はここまでにします。

アップグレード後に解消されている事を期待します。
Javascriptのスコープに関して理解を深める

##そもそも、スコープとは
プログラミングにおけるスコープ（英: scope, 可視範囲）とは、ある変数や関数などの名前（識別子）を参照できる範囲のこと。
(参照：wikipedia https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97)


##スコープを使うことでできること
・範囲外のものは参照をさせないような設計ができる(変数をスコープの外では変更できないような、安全性を確保)
・スコープがあることにより、関数名や変数名等同じものを使用してもスコープの内外で有効な範囲が変わってくるので、コード全体の命名が簡潔に済む

##スコープの種類
グローバル変数とローカル変数の二種類に分かれる。

|グローバル変数  |ローカル変数  |
|---|---|
|関数の外（トップレベル）で宣言した変数  |関数の中で宣言した変数, 関数の仮引数  |
|プログラム全体から参照できる	  |その関数の中でのみ参照できる  |


##グローバルスコープ
プログラムのどこからでもアクセス可能。
JavaScript においては、一般的にすべてのコードが実行されている Web ページがグローバルスコープとなる。

![スクリーンショット 2021-01-18 13.30.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641577/2dcc5b92-04b4-8662-0f12-af971932a174.png)

aとbは関数からでも、ブロック内でもどこでも呼び出せる。

##ローカルスコープ
ローカルスコープは二種類あり、`関数スコープ`と`ブロックスコープ`に分かれる。

##関数スコープ
関数スコープはその名前の通り、関数ごとに作られるスコープ。

![スクリーンショット 2021-01-18 13.32.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641577/42a78a2b-1ab6-004f-839e-7c9c3c7113cf.png)
↑関数内で定義したhelloに対して、関数の外から呼び出しをしようとすると、上記のようなエラーが出てしまう。

![スクリーンショット 2021-01-18 13.31.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641577/1d27b31c-b9d3-0ff3-c9a7-fc65974953da.png)

↑こちらは関数内で定義したものを関数内で呼び出している為、エラーの表示がなく、結果もしっかりと"hello world"の文字列が取得できました。
このように関数内で定義したものは関数内でしか実行できないものを関数スコープと呼ばれています。

##ブロックスコープ

ブロックスコープも関数スコープと同じくローカルスコープの仲間で、if文やfor文と組み合わせることが多いです。


![スクリーンショット 2021-01-18 13.40.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641577/fd0abda4-1c8a-1d45-331c-d7acb4809f7e.png)

↑ブロック内で宣言しているinBlockはブロックの外から呼び出してもスコープ外の為、未定義エラーが出てしまう。

![スクリーンショット 2021-01-18 13.46.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641577/3ea4df34-810f-ee0d-ddd1-4298f0cf789e.png)

↑こちらも同様にfor文の外で回数を出力しようとすると、未定義エラーが出てしまう。

##上記のスコープで注意する点
####letとvarの違い
変数宣言をする際、letとvar(とconst)があるが、それぞれスコープに違いがある。

![スクリーンショット 2021-01-18 14.00.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641577/f55292b8-7e56-8a86-d2d6-df24f01eae43.png)

↑このようにブロックスコープを定めても、letはブロックごとに読み取りの制限をすることが出来ているのですが、varを使用している場合ブロック内の`foo`を読みとってしまっている為、外部から意図しない値に書き変わってしまいバグが発生する可能性がある。

また、varにはホイスティングと呼ばれる機能があり、関数の内部で宣言されている変数は、その関数の先頭で宣言されたものと見なされるというものです。
![スクリーンショット 2021-01-18 14.07.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641577/38032657-3de0-c190-8d78-3adde3996ffb.png)

このようなサンプルコードではすぐ近くにあるので気づけますが、関数の行数が多い場合`foo`がトップレベルのfooと勘違いしてしまう可能性もあり、さらにコードがエラーを出さない為、対処が大変になってしまう可能性があります。


###最後に
Javascriptに苦手イメージがあり、ほとんど勉強をしてこなかったのですが、業務で取り扱う機会が多いので基礎から勉強しようと思いスコープを題材に取り上げました。
まだまだ、わからないことだらけなので、整理しながら勉強をしていきます。
Spring Boot+Kotlin環境でJunit5を動かしてみた

##はじめに
単体テストをしていく際に、新しくなったJUnit5を使用することが決定し、少し躓くことがあったので、備忘録として投稿します。

##開発環境
Spring Boot 2.3.4
kotlin 1.3.7
Gradle
JUnit5 

上記のバージョンでテスト用の設定を追記していきます。

### Gradle設定ファイル書き換え


```diff:build.gradle
dependencies {
- testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ testCompile('org.springframework.boot:spring-boot-starter-test') {
+       exclude module: 'org.junit.vintage'
+  }
+  testImplementation('org.junit.jupiter:junit-jupiter:5.4.0')
}

+ test {
+   useJUnitPlatform()
+ }
```
順番に、
####1.JUnit5を追加する

```diff:build.gradle
+  testImplementation('org.junit.jupiter:junit-jupiter:5.4.0')

```

こちらのJUnit5の追加だけでは、JUnit4との依存関係のエラーが発生してしまう。

####2.JUnit4の依存関係を解消する

```diff:build.gradle
- testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ testCompile('org.springframework.boot:spring-boot-starter-test') {
+       exclude module: 'org.junit.vintage'
+  }

```

sterterを使用している場合は初期でJUnit4が導入されており、'org.junit.vintage'を除くことで動くようになります。

JUnit Vintage：プラットフォーム上でJUnit3およびJUnit4ベースのテストを実行するためのTestEngineを提供するライブラリ

####3. JUnit platform を使う設定を追記

```diff:build.gradle
+ test {
+   useJUnitPlatform()
+ }

```
設定は以上になります。

##最後に

当たり前かもしれませんが、JUnit5では、JUnit4と変更点があり、注意する点もいくつか存在します。

・インポート
JUnit 5では、アノテーションとクラスに新しいorg.junit.jupiterパッケージが使われています。
例：org.junit.Testはorg.junit.jupiter.api.Testに変更

・アノテーションも諸々変更されています。

```diff
- @Test(expected = Exception.class)
+ @Test
```

```diff
- @Before
+ @BeforeEach
```
```diff
- @After 
+ @AfterEach
```
```diff
- @BeforeClass
+ @BeforeAll
```
```diff
- @AfterClass
+ @AfterAll
```
```diff
- @Ignore
+ @Disabled
```
```diff
- @Category
+ @Tag
```
```diff
- @Rule
- @ClassRule
+ @ExtendWith
+ @RegisterExtension
```

・アサーション
JUnit 5のアサーションは、org.junit.jupiter.api.Assertionsに含まれるようになっています。
assertEquals()やassertNotNull()など、引数の順番の変更やアノテーションからアサーションとして代替されているものも存在します。

JUnit5には他にもメンテナンス性の向上やその他便利な機能も充実しているとのことで、積極的に使用していきたいと思ってます。
【BizRobo!】 ページ(サイト)の表示待ちに使えるステップ開発

# はじめに
現在、RAPを実務で行っていますが、まだまだまだまだ経験が浅く、日々勉強中です。
本記事については、自身の備忘録も含め同じ様な所で頭を抱えている方に対して、
少しでもヒントになり、先に進める力となれれば良いなと思い記事にしましたーー！

## 今回のTips
何かのサイトが表示されるまでロボットを待機させる場合に、
以下の様な「Guard」で待機時間を設定するケースが多いかなと思いますが、
どれぐらい待機すればキチッと表示されるかわからない、
実行ごとに待つ時間が変動する様なケースで使用できるTipsになります。
![待機.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/de5b73dd-e72d-5eac-29a5-e8c77f5f6733.png)

## 使用ケース例
![ケース1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/a0d51de6-a2e3-0898-d3c9-303c1081da30.png)

![ケース2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/d2cb9e27-d8e3-0d79-fb1c-cd924d193267.png)

## Tips概要
ステップの概要としては、
前ステップ処理後に表示させたい画面を「Location Found」で設定し、
指定した回数分、該当のLocationが見つかるまで、反復させる処理になります。

以下の画像だと、該当のLocationが見つかるまで「1秒間」待機し、
該当のLocationを確認しにいくという処理を「120回」実施する処理になります。
(※1秒間待機×反復を120回なので、最大で120秒は待機する設定になります)
(※Locationがすぐに見つかれば、1秒で終了するステップになるので、待機に1秒～120秒まで幅を持たせる事が出来ます)
![Iteration図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/127a49e8-7f12-47b5-a0c9-13f7f7bb324f.png)


## Tips詳細
実際の設定方法については、以下の様な設定を行います。

▼DeviceAutomation(以下DA)にて、Loopステップを追加
![Loopステップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/6d1eb9f6-1124-df83-c7e0-9a4ad804924f.png)

▼「iteration」と記載し、「Guarded Choice」を追加
![Loopステップ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/ab2ac7f5-f7f9-afbb-1ba7-b8e8cef0aed6.png)

▼「Guarded Choice」に、表示待ちさせたいLocationを追加
(※オートメーションデバイスビューに表示させたい画面を表示させた上で、
　 その画面を右クリック→Guard→LocationFoundで対象のLocationをGetできます)
　GetしたlocationのComponentを、locationFoundとして設定する
![Loopステップ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/a99eb5d2-1517-1424-1946-0b0d05f9258c.png)

▼続いて、「Guarded Choice」に要素を一つ追加し、
　120回確認ループさせる様に以下の設定を追加する
![Loopステップ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/d69028da-1578-5a70-6aa0-4b6fac589dc9.png)

▼以上の設定で「Guarded Choice」は完了なので、
　表示された時にこのステップを抜けるようにする為、「Break」ステップを追加

![Loopステップ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/a7367d0f-90e8-89f5-af9d-d843ff557912.png)

以上で設定は完了です。
あとは、何度かステップをテストし、問題なく稼働するか確認する。

## まとめ

今回は、表示させたい画面が表示されるまでループして確認を行うステップの作成方法になります。
こういったTipsは公式のknowledgeBaseなどにも載っていないかなと思うので、
引き続き展開していきますので、よろしくお願いいたします！！
既存のWebコンテンツをCapacitorを使ってiOSアプリ化する

Zennと同時投稿→ https://zenn.dev/k_u_0615/articles/ece25c2b0a36f3

## 概要
Capacitorを使ったガワネイティブアプリに注目しています。
Capacitorとは、Webコンテンツをガワネイティブアプリとしてビルドしてくれるフレームワークで、[Ionic Team](https://github.com/ionic-team)が開発しています。
既存のWebコンテンツにCapacitorを使用して、アプリ化したらどのような感覚で実現できるのか気になったので、試してみました。

## アプリ化の対象
今回アプリ化するのは、[Ionic Frameworkの公式ドキュメント](https://ionicframework.com/docs)の右に表示されているデモです。

![スクリーンショット 2021-01-18 12.10.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137148/016a5c86-e8ae-28ba-73fd-ae0c6f380032.png)


Ionic FrameworkもIonic Teamが開発しており、こちらはネイティブっぽいUIや画面遷移をhtml/css/jsで再現しているフレームワークです。
このデモ自体はiframeで表示されており、以下のURLでデモ単体を表示できます。

|  対象   | URL                                                   |
| :-----: | ----------------------------------------------------- |
|   iOS   | https://ionic-docs-demo.herokuapp.com/?ionic:mode=ios |
| Android | https://ionic-docs-demo.herokuapp.com/?ionic:mode=md  |

- デモのGitHub: https://github.com/ionic-team/docs-demo

上記のリポジトリをforkして、デモのアプリ化を試みます。


forkしたリポジトリはこちら→ https://github.com/katsuyaU/ionic-docs-demo-for-ios

## 手順
### 初回のみ

- CapacitorのInstallのドキュメント→ [Installing Capacitor - Capacitor](https://capacitorjs.com/docs/getting-started)


#### ① Capacitor関連をインストール

```bash
npm install -D @capacitor/core @capacitor/cli
```

#### ② `npx cap init`を実行

- アプリ名と識別子(bundle identifier)とnpm/yarnが聞かれるので、答えます。

#### ③ capacitor.config.jsonが作成されるので、webDirを適宜編集する

- 例えば、create-react-appで作成したプロジェクトならbuildに、Vue CLIで作成したプロジェクトならならdistになると思います。

```capacitor.config.json
{
  "appId": "com.example.app",
  "appName": "Ionic Demo",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "www", // ←ここ
  "plugins": {
    "SplashScreen": {
      "launchShowDuration": 0
    }
  },
  "cordova": {}
}
```

#### ④ `npx cap add ios`を実行する

- iosディレクトリにネイティブコードなどが自動生成されます。

![スクリーンショット 2021-01-18 13.27.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137148/7b4a2abf-d0d6-2910-bf40-3f08a756582f.png)


#### ⑤ `npx cap open ios`を実行し、XCodeの設定を行う

- 実機で動作確認したいのでTeamやBundle Identifierを入力します。(ここでは詳しく解説しません。)

### 毎回
#### ① ビルドコマンドを実行、ビルド先のディレクトリにビルドされているか確認する

#### ② `npx cap copy`を実行する

- capacitor.config.jsonのwebDirがここで参照され、[プロジェクト]/ios/App/publicにコピーされます。


#### ③ `npx cap open ios`を実行する

- XCodeが開きます。

#### ④ XCodeで実行ボタンをクリックする

これで、既存のWebコンテンツをアプリ化することに成功しました！
上記のコマンドを毎回入力するのは面倒なので、npm scriptsに登録します。

```package.json
{
  "scripts": {
    "build:ios": "npm run build && cap copy && cap open ios && echo 'Please click ▶️ in XCode!'",
  },
}
```

## 感想
思いのほか簡単にアプリ化することができました！
ガワネイティブアプリといえば、Cordovaはやたらビルドエラーする印象だったり、以前の職場ではObjCでローカルサーバーを自作していたりなど、実際にアプリとして動かすまですごく面倒という印象がありました。
しかし、Capacitorは公式docsの通りにすれば簡単に実行することができました。


またIonic Frameworkの話になりますが、webなのにネイティブのようなUIをハイレベルで再現できていることにも感動しました。
この手のネイティブっぽいUIフレームワークといえば[Onsen UI](https://ja.onsen.io)が頭に浮かびますが、Ionic Frameworkの方が完成度が高いと思います。(コンポーネント自体はOnsen UIのほうが充実していますが)
最近クロスプラットフォームのアプリ開発ではFlutterが話題で、自分もサンプルを動かしてみたりしていますが、Ionic+Capacitorも良い選択なのではないかと思ってます。
2021年の流行色は？

2021年に流行するカラーがこの前発表されました。
世界的に色見本などで有名なPANTONE社やJAFCA日本流行色協会が今年の流行色を発表しました。
ご紹介する色を参考にぜひwebサイトやアプリなどを作成してみて下さい！

#PANTONE (パントーン) とは
アメリカに本社のある色見本の企業で、印刷物以外にもwebなどにも使用されるなど、幅広く使用されています。そのPANTON社は毎年12月に来年のトレンドカラーを発表しています。

##pantoneが選ぶ2021年の流行色
今年は５年ぶりに２つの色がトレンドカラーとして選ばれました。
この２色は両方使ってことそのトレンドカラーとのことなので、
それぞれ使うのではなく２色の組み合わせが今年のトレンドカラーなのだそうです。
<iframe src='https://players.brightcove.net/6057277746001/6rjuU4yA5_default/index.html?videoId=6211811116001' allowfullscreen frameborder=0></iframe>


###その１ Ultimate Gray（アルティメットグレイ）
Ultimate Gray（アルティメットグレイ）は永続的でしっかりした基盤をもたらす、強固で信頼できる要素を象徴であり、浜辺の小石の色や、風化した自然の外観は、時の試練に耐える能力を強調しています。
また落ち着きや安定、回復への思いを促しながら、穏やかに確信をもたらしてくれます。

・Ultimate Gray（アルティメットグレイ）
カラーコード : 939597
RGB : 147 149 151
![アセット 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/5a80e061-45c5-494f-7075-fb53e71b790c.png)



###その２ Illuminating（イルミネイティング）
生き生きとした輝きを放つ明るく陽気なイエローで、太陽の力を宿した暖かさを与えてくれます。
・Illuminating（イルミネイティング）
カラーコード : F5DF4D
RGB : 245 223 77
![アセット 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/49b6fee7-9fcb-becc-42b2-10a0dc118449.png)

#JAFCA日本流行色協会 とは
一般社団法人日本流行色協会（JAFCA）は、1953年設立以来、あらゆる商品分野に向けた先行き市場向けのカラー情報を選定、提案を行っています。


##JAFCA日本流行色協会が選ぶ2021年の流行色 ゼロホワイト (Zero White)
2021年を象徴する色として白を選晴れました。
白は、白紙に戻すなど「はじまり」を示す言葉によく使われます。
希望を胸に、ゼロから考えるという意味を込めて、「Zero Whiteゼロホワイト」と名付けられたそうです。

・ゼロホワイト (Zero White)
カラーコード : FFFFFF
RGB : 255 255 255
![アセット 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/dfa5dd96-0f32-ad62-fde7-96b565187495.png)


#レアトリス・アイズマン
PANTONE Color Instituteのエグゼクティヴディレクターであるレアトリス・アイズマン氏は
今年のトレンドカラーについて以下のようにコメントされています。

>永続的なUltimate Grayと明るいイエローのIlluminatingの組み合わせは、不屈の精神に支えられたポジティブなメッセージを表現しています。実用的でしっかりしていると同時に、暖かみがあり楽観的なこのカラー・コンビネーションは、私たちに回復力と希望を与えてくれます。私たちは、励まされ、元気づけられる必要があり、これは人間の精神に不可欠なものです。

2020年はコロナウイルスの影響で世界中が不安な毎日を過ごしていたと思います。
こんなコロナ禍で人々が落ち込んでいるからこそ、色によって希望を与えてくれようとしてくれているのだとお思います。
Test Apex Class でのToo many SOQL queries: 101エラー

トリガが設定されているオブジェクトを複数つかってテストをしていると、ちょっと困ったエラーです。
クエリーが101回に達しました。

困りましたねぇ、テストデータを作るとどうしてもトリガが走ってしまいます。

以下に解決策がありました。
https://salesforce.stackexchange.com/questions/105372/too-many-soql-queries-101-issue-with-unit-test-methods

By using the Test.startTest() & Test.stopTest() you get 2X governer limits.

In nutshell you have 2 context.

out side of Test.startTest() & Test.stopTest() and
inside of Test.startTest() & Test.stopTest().
In both context you get separate limits.

Test.startTest() & Test.stopTest()で囲まれた中とそうでない部分ではそれぞれ別個に
101個の制限がある。
よって、うまく分けたらいいみたいです。


確かに、適当なところで分けると問題なくテストできました。

他の回答ではトリガのSOQLを整理しろとかあったけど、それができたら苦労しないよ。
headerもmainも高さを固定にできない時。

headerの高さは固定にしたいけど内容によっって高さが変わる可能性がある。
mainも同様で、どちらの高さも決めれない場合に頭を抱えた。



## 経緯
管理画面の開発していると、ユーザの設定内容によって要素の量が異なるため、
width(幅)やheight(高さ)を固定値で決め打ちするのが難しいねん。

これではheaderを固定値にしてその固定値から計算して、
main内の高さを出すやり方が使えなかったりする。

js使ったら現在値取得して簡単にできると思うけど、
なるべくシンプルなcssで作りたいし、なんとかなんか〜、
と考えた挙句、これならどうや！ と閃めいて実装した。


## 結果

```html:html

<div class="wrapper">

　<!--- 高さが可変なヘッダー -->
　<header>
　　<div>ロゴマークなど</div>
　　<p>この要素は2行にも3行にもなるため高さ可変なると仮定</p>
　</header>

　<!--- 高さが可変な中身 -->
　<main>
　　<menu>
　　　<ul>
　　　　<li><a>menu1</a></li>
　　　　<li><a>menu2</a></li>
　　　　<li><a>menu3</a></li>
　　　　<!--- このあと4,5,6...と永遠に可変（ここはスクロールにしたい） -->
　　　</ul>
　　</menu>
　</main>

</div>
```

```sass:sass

.wrapper {
 display: flex;
 flex-direction: column;
 height: 100%;
 overflow-y: auto;
}

header {
 position:sticky;
 top: 0;
 pointer-events: unset;
 z-index: 1;
}

main {
 flex: 1 0 auto;
}

```


## 説明
とりあえずwrapperはflexにして、子要素のmainにflex:1 0 auto;を指定する。
これでmainはとりあえずウインドウの下まで伸びる。
※headerにはheightは指定しない。

あとはheaderにstickyをsetし、上部に固定する。
これだと内容（menu）はどれだけ増えても大丈夫。
※スクロールは入れとかないとね。


## ポイント
menuがstickyの下に隠れた時に、menuがクリックできてしまう。
これを防ぐためにpointer-events: none;を入れたが、なぜか効かない（クリックできてしまう）
pointer-events: unset;をいれたら効いたの（クリックできなくなった）でこれにしました。
なんでだろ。


とりあえず忘備録で走り書き。
また使う時が来ると思うので、その時にまたこの記事をバージョンアップ予定。
オブジェクトのディープコピー


メモとして。

```
const obj = [
  {
    name: 'taro',
    age: 24
  },
  
  {
    name: 'sato',
    age: 22
  },
]
const copyObj = obj.map(person => ({name : person.name ,age : person.age}))

for(let i = 0; i < copyObj.length; i++){
  copyObj[i].name = "keiko";
  copyObj[i].age = i + 20;
}

console.log(obj);
console.log(copyObj);
```

結果

```
[[object Object] {
  age: 24,
  name: "taro"
}, [object Object] {
  age: 22,
  name: "sato"
}]
[[object Object] {
  age: 20,
  name: "keiko"
}, [object Object] {
  age: 21,
  name: "keiko"
}]

```


配列も同様

```
const obj = [
  {
    answer: [
      [1,1,1],
      [1,1,1]
    ],
    remain: [2,2,2]
  }
]

const copyObj = obj.map(list => (
    {
      answer : [...list.answer],
      remain : list.remain
    }
  )
);

copyObj[0].answer[0] = [1,2,3];
copyObj[0].answer[1] = [4,5,6];

console.log(obj);
console.log(copyObj);
```

結果

```
[[object Object] {
  answer: [[1, 1, 1], [1, 1, 1]],
  remain: [2, 2, 2]
}]
[[object Object] {
  answer: [[1, 2, 3], [4, 5, 6]],
  remain: [2, 2, 2]
}]
```
params flash sessionの寿命を考えたことがあるか。

##sessionとかflashってどれくらいの間データを保持しているんだろう？
railsでウェブサイトを作っている時、定義した変数等は画面を遷移した時に、すぐに消えてしまいます。
@user等のインスタンス変数は一度の画面遷移で死んでしまう経験をしたことが多いと思います。
__sessionやflashは長生きすると聞いていたので、寿命を見てみたい！__という好奇心から記事を書きました。

##実験開始
今回は自分のPFに無理やり作ったので少し見にくくなっています。
###①コントローラにsession flash paramsの出場選手を定義
とっつきにくいイメージかもしれませんが、案外カジュアルに定義できちゃいます。

```rb:コントローラ
  def top
    session[:life]="私はsession。生きています"
    flash[:life]="私はflash。生きています。"
    params[:life]="私はparams。生きています。"
  end
```

###②ビューページに選手達を表示する記述を追加

```erb:ビュー
            <%= session[:life]%><br>
            <%= flash[:life]%><br>
            <%= params[:life]%><br>
            
            <%= yield %>
```
###③画面遷移を何度かして、どれくらい生きられるかを見る

####０遷移目
皆表示されていることを確認。
![スクリーンショット 2021-01-18 13.11.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620852/d0bc035b-4e8b-698f-45cf-38cd4ca70b42.png)
####1遷移目
早くもparamsが息を引き取ります。
![スクリーンショット 2021-01-18 13.11.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620852/74f2409a-8561-ed61-b2b0-a896c85f1912.png)
####２遷移目
ここでflashも力尽きました。
![スクリーンショット 2021-01-18 13.11.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620852/cd24719b-8cfb-7052-1227-f1150f628d0f.png)

##結言


| 名前 | 寿命 | 
|:-:|:-:|
| params  | 1遷移キル  |
| flash  | 2遷移キル  |
| session  | キルするまで生きている  |

sessionにユーザーのログイン状態が保存されていれば、
ずっとログイン状態を保っていることにも納得できます。
ログアウトはsessionに保存しているユーザーのログイン状態をdestroyしていたんですね。
【データサイエンス備忘録】 欠損値の取り扱い 【python】

#欠損値の有無を確認する。
**isnull()**関数を使用する。
``DataFrameが代入された変数.isnull()``
もし欠損値が含まれていればTrue、含まれていなければFalseとなる。

#欠損値の個数を確認する
**isnull()**関数と**sum()**関数を使用する。
``DataFrameが代入された変数.isnull().sum()``

#欠損値の削除
**dropna()**関数を使用する。
``DataFrameが代入された変数.dropna() ``
**dropna()**関数を利用した後は、別の変数に代入するか、``inplace=True``という**dropna**の引数を付け加え、実行したらそのまま変数を書き換える。

1. ``data = data.dropna() ``
2. ``data.dropna(inplace=True) ``
3. ``data = data.dropna(inplace=True) ``

特定のカラムが欠損値を含むデータを削除する場合は、
``DataFrame.dropna(subset=[‘カラム名’]) ``

#欠損値の補完
**fillna()**関数で特定のカラムの欠損値をある値で補完する。
``DataFrameを代入した変数['カラム'].fillna(値) ``

fillna()関数で特定のカラムの欠損値をある値で補完する。
`DataFrameを代入した変数['カラム'].fillna(値)`

特定のカラムをそのカラムの平均値で補完する。
`DataFrameを代入した変数['カラム'].fillna(np.mean(DataFrameを代入した変数['カラム']), inplace=True)`

特定のカラムをそのカラムの中央値で補完する。
`DataFrameを代入した変数['カラム'].fillna(DataFrameを代入した変数['カラム'].median(), inplace=True)`
【Flutter】 Androidアプリ リリース

参考サイト
①https://www.flutter-study.dev/create-app/publish-android/
②https://stackoverflow.com/questions/44352411/could-not-get-unknown-property-release-store-password-for-signingconfig-decora

###証明鍵の作成
key.jksはアプリの直下に保存される。

```

$ keytool -genkey -v -keystore ./key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key

キーストアのパスワードを入力してください:<パスワード>
新規パスワードを再入力してください: <パスワード>
姓名は何ですか。
　[Unknown]:  Yamada Taro
組織単位名は何ですか。
　[Unknown]:
組織名は何ですか。
　[Unknown]:  
都市名または地域名は何ですか。
　[Unknown]:  
都道府県名または州名は何ですか。
　[Unknown]:  Osaka
この単位に該当する2文字の国コードは何ですか。
　[Unknown]:  81
CN=Yamada Taro, OU=Unknown, O=Unknown, L=Unknown, ST=Osaka, C=81でよろしいですか。
　[いいえ]:  y
10,000日間有効な2,048ビットのRSAのキー・ペアと自己署名型証明書(SHA256withRSA)を生成しています
ディレクトリ名: CN=Kuramoto Kento, OU=Unknown, O=Unknown, L=Unknown, ST=Osaka, C=81
<key>のキー・パスワードを入力してください(キーストアのパスワードと同じ場合はRETURNを押してください):  
```

###署名付きアプリをビルドするための設定（２通り）

①パスワードを変数に置き換えて変更する。

```dart:android/key.properties
storePassword=<パスワード>
keyPassword=<パスワード>
keyAlias=key
storeFile=/<保存した場所を指定>/key.jks
```

```dart:android/app/build.gradle
android {
    ...
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword keystoreProperties['storePassword']
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}
```

②build.gradleに直接書き込む

```dart:android/app/build.gradle
android {
    ...
    signingConfigs {
        release {
            storeFile file('/<保存した場所を指定>/key.jks')
            storePassword "<パスワード>"
            keyAlias "key"
            keyPassword "<パスワード>"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}
```

①で上手くいかなかったので今回は②を使用しました。

###証明書の作成
```bash
$ flutter build apk
```
FirebaseHostingでデプロイする方法

この記事では、Firebase Hosting を使って静的サイトを公開する方法を簡潔に説明します。

初めて設定する場合は、できるだけクリーンな環境で行うことをおすすめします。

# 流れ

作業の流れは以下のようになります：


1. CLIツールのインストール
Firebase CLI をインストールします（まだインストールしていない場合は Node.jsのダウンロードも必要です）。

2. ログイン
`firebase login` コマンドで Firebase にログインします。

3. 初期設定
`firebase init` コマンドで Firebase Hosting の設定を行います。

4. デプロイ
`firebase deploy` コマンドでサイトを公開します。

順を追って詳しく説明していきます。


# 準備

まず、公開したいサイトのフォルダを準備します。フォルダ構成の例を以下に示します

mysite（任意のフォルダ名）
└ public（この名前は必ず`public`にする）

![graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456876/b0b7ed14-f512-8b02-385c-819c4fd2fa48.png)

`public`フォルダにはサイトに必要なHTMLやCSS、JavaScriptファイルのみを配置してください。
※不要なファイルを含めると、デプロイ時にエラーが発生することがあります。

Firebaseの初期設定（`init`）を行うとファイルが上書きされるため、必要であれば Git などでバックアップを取っておくことをおすすめします。


# Firebase CLI のインストール

ターミナルを開き、以下のコマンドで Firebase CLI をインストールします
```
npm install -g firebase-tools
```
インストール後、次のコマンドでバージョンを確認してください

```
firebase --version
```


# Firebase login

次に、以下のコマンドを実行して Firebase にログインします

```
firebase login
```

初回ログイン時には以下のような画面が表示されます

![privacy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456876/c92e43a8-5b7e-5180-4efa-b9cb23b0b539.png)

データ送信に関する確認画面なので、n (No) を選んでも問題ありません。

その後、ブラウザが開いてログイン操作を行います。ログインが完了すると以下の画面が表示されます。

![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456876/1e149753-5d3f-777c-c258-4dfac18d318e.png)

ログイン成功後はターミナルに戻ります。

# Firebase Hosting の初期設定（`firebase init`）

次に、公開するサイトのフォルダに移動します。

```bash
cd desktop/mysite
```

フォルダ内に移動したら、以下のコマンドを実行します
```bash
firebase init
```

![init.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456876/09b0db3c-5920-dab8-2c6f-4d4649f3b78e.png)

「`proceed`（進めるか？）」という質問には `y (Yes)` を入力します。
次に「`Hosting`」を選び、スペースキー を押して選択後、Enter を押します。

プロジェクトを新規作成する場合は「`new project`」を選び、プロジェクトIDを入力します（他のプロジェクトと重複しないIDを設定）。

既存のプロジェクトを使用する場合は「`using`」を選択します。
以下の選択肢では、適宜設定を行います：

「`use as your public directory?`」→ `public`フォルダを使用するのでそのままEnter。
「`Configure as a single-page app?`」→ シングルページアプリケーションでない場合は`n(No)`。
「deploys with GitHub?」→ GitHubを使わない場合は`n (No)`。

初期設定後、`public`フォルダ内に設定ファイルが追加されていることを確認してください。

# サイトのデプロイ（`firebase deploy`）

小時間待つと、URLが出ます。

`firebase open`、かURLを開くとサイトが表示され終了です。


初めは一発で表示まで成功しないとは思います。

失敗した場合フォルダ構造やディレクトリに問題がないか再確認しておきましょう。
Hostingで使えるファイルはHTML/CSS/JavaScriptのみです。

更新する際は再度デプロイすれば行えます。


# さいごに

ここまで書いて思いましたが、簡易的な静的サイトであればNetlifyやGitHub Pages、最近ではVercelでも十分対応可能だと思います。ただしFirebaseの無料枠でFirestoreなどの機能を活用できれば、より実用的なプロジェクトが作れるでしょう。
(※2024年追記。久しぶりに触ってみたら環境がだいぶ変わってましたので、この手法はあくまで参考程度になります)
必ず役に立つ！Ruby on Railsでの開発で使えるデバッグコード

# こ~れなんなん、これなんなん
こんにちは。

開発で最も必要とされる技術ってデバッグ力だと思っています。特にバグを大量生産することが得意な僕にとって、デバッグ力はとても大事。

そこで、普段開発で使ってるデバッグ用のコードをまとめておこうかと思います。

## デバッグコード
Ruby on Railsで使える、デバッグで役に立ちそうなコードの一覧を書いていきます。なお、Rubyで使えるコードもあります。

byebug起動時や`rails console`で使用することを想定しています。byebugの使い方よく分からんて人は以下の記事で使えるようにしてください。
https://web-nari.net/2018/03/16/byebug/

### メソッド一覧
`hoge`という変数の参照できるメソッドの中で、メソッド名に`method_name`が含まれるメソッドの一覧を返します。

```ruby
hoge.methods.select {|name| name.to_s.include?("method_name") }
```

### メソッド定義場所
`hoge`という変数の参照できる`foo`メソッドの定義されてるクラスを返します。

```ruby
hoge.method(:foo)
```

#### ソースファイルのパス
`hoge`という変数の参照できる`foo`メソッドの定義されてるファイルのパスを返します。

```ruby
hoge.method(:foo).source_location
```

### コールバック検索
`Hoge`というクラスに定義されてるsave時のコールバックの一覧を返します。`cb.kind.eql?`の引数にafterかbeforeを与えると、それぞれafter_コールバック関数、before_コールバック関数に定義されてるコールバックを返します。

```ruby
Hoge._save_callbacks.select { |cb| cb.kind.eql?(:after) }.map { |cb| cb.filter }
```

#### その他のコールバック関数
`save`だけではなくて以下のコールバック関数がそれぞれ利用可能。

```ruby
=> [:validate,
 :validation,
 :initialize,
 :find,
 :touch,
 :save,
 :create,
 :update,
 :destroy,
 :commit,
 :rollback,
 :before_commit,
 :before_commit_without_transaction_enrollment,
 :commit_without_transaction_enrollment,
 :rollback_without_transaction_enrollment]
```

例えば`after_validation`のコールバックの一覧が知りたい場合は、以下のようにすればいい。

```ruby
Hoge._validation_callbacks.select { |cb| cb.kind.eql?(:after) }.map { |cb| cb.filter }
```

### クラス化
`:string`という名前から該当するクラスに変換します。例の場合だと、`String`が返ってきます。該当するクラスがない場合は`NameError: uninitialized constant`が発生します。

```ruby
:string.to_s.classify.constantize
```

### クラスの確認
`hoge`というオブジェクトのクラスを確認する。

```ruby
hoge.class
```

#### 継承元を検索する
`hoge`というオブジェクトの継承クラスやそのさらに祖先も検索できる。

```ruby
hoge.superclass # 親クラスを検索
hoge.ancestors # 祖先を検索
```

### インスタンス変数の確認
`hoge`というオブジェクトが持ってるインスタンス変数を返します。クラス変数は`class_variables`で参照可能。

```ruby
hoge.instance_variables
```

## まとめ
タイトルの勢いの割に書いてみたらすんごい少なかった。

これからも追加していきます。
Ubuntu + Identiv Cloud 3701 FでSuicaを読み込む（下調べメモ その3）

# これはなに？

[これ](https://qiita.com/sengoku/items/ed40ac792f218078440f) の続きです。

# Suica読み込み手順

## システム 0x00 0x03 （交通系IC？）の選択

```bash
opensc-tool -s ff:40:00:00:04:00:03:00:01
```

NFCID2 `01 10 03 10 1F 19 E4 0E 03 00 03 FE 00 86 A7 ...............` が返る。

## サービス 0x00 0x8b （種別と残額）の選択

```bash
opensc-tool -s ff:42:01:00:02:00:8b
```

IDm(8バイト)、サービスまたはエリアの数(1バイト)、サービスまたはエリアのバージョン(最ービスまたはエリアの数 × 2バイト) `01 10 03 10 1F 19 E4 0E 01 FF FF ...........` が返る。


## ブロックの読み込み

```bash
opensc-tool -s ff:46:01:01:04:00:8b:00:00
```

SW1=0x69 SW2=0x82 Security status unsatisfied が返る。

# 結果

全然わかってない。。。
【PHP】IoTデバイスのHTTPリクエストから送信元IPアドレスを取得する【ESP32】

# はじめに
IoTデバイスをIPアドレスを使って識別しようとしている方，デバイスのIPアドレスをサーバ側で取得したい方向けになります．

# 環境
- IoTデバイス（ESP-WROOM-32）
- ファームウェア（MicroPython1.3）
- サーバ（Ubuntu18.04）
- Webサーバ（Apache2）
- PHP（PHP7.4）

※Apache2を起動して/var/www/html/にPHPプログラム（今回はreceive.php）を置いておくことが前提です．

# ソースコード（ESP32）

今回はESP32で適当なJSONデータのPOST送信をし，サーバで送信元のIPアドレスを取得してレスポンスとしてそのIPアドレスを返すようなプログラムにしました．

```post.py
import urequests
import ujson

#送信先のURLの指定
#"XXX.XXX.XXX.XXX"にURLを入れる
url = 'http://XXX.XXX.XXX.XXX/receive.php'

#データをDICT型で宣言
obj = {"value" : 123, "text" : "abc"}

#jsonデータで送信するという事を明示的に宣言
header = {'Content-Type' : 'application/json'}

#オブジェクトをJSONに変換し，HTTPリクエストをPOSTとして送信
res = urequests.post(
    url,
    data = ujson.dumps(obj).encode("utf-8"),
    headers = header
)

#サーバ側からのレスポンスを受け取って表示(jsonのデコードも一緒にしている)
print (res.json())

#終了
res.close()
```
# ソースコード（サーバ）

送信元のIPアドレスは`$_SERVER[REMOTE_ADDR]`に入っているのでそれを変数に入れるなりする．

```receive.php
<?php
//送られてきたPOSTデータを受け取って，JSONデータをデコードして$inに入れる．
$json_string = file_get_contents('php://input');
$in = json_decode(stripslashes($json_string),true);

//送られてきたデータを取り出す
$value = $in["value"]; // = 123
$text = $in["text"];   // = abc

//$_SERVER変数を使って送信元のIPアドレスを取得する
//レスポンスを取得したIPアドレスとし，それをJSONとして再度エンコード
//そして送信元(ESP32)へ返す．
$ipAddress = $_SERVER['REMOTE_ADDR'];
//AWS ELBを使用している場合はELBのIPアドレスを取得してしまうので
//以下のようにして元のIPアドレスを取得する
if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
        $ipAddress = array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
}
//IPアドレスをエンコードして返す
echo json_encode($ipAddress);
?>
```

# 実行結果

micropythonのWEB REPLで実行したところ，IPアドレスが返ってきました．

```shell
>>> execfile("post.py")
YYY.YYY.YYY.YYY // <- ESP32のIPアドレス
```

# 参考

この記事は以下の記事を参考に書いています

[1] 
[ESP32からMicropythonでHTTPリクエスト(POST)でデータを送信し，PHP(サーバ)で受け取る](https://qiita.com/sirius1000/items/5a4d18a76ddf67a6839c)
ブラウザのセッションとCookieの違いとRailsのsession,cookiesメソッドの違いについて

## はじめに

この記事はRails初学者が書いています。
ご容赦ください。

また、間違っている点があれば指摘していただければ幸いです。


## それぞれの違い

### ブラウザのセッション

あるサイトに接続してから切断するまでの一連の流れのこと。


### ブラウザのCookie

ユーザー側のブラウザに保存しておく情報のこと。

一時Cookieと永続Cookieがある。
前者はブラウザ終了時に自動で消える。
後者はユーザー側、サーバー側のどちらかで手動で消去するまで残っている。

HTTPプロトコルではログインしているという情報を記憶しておくことができない。
そのため、こういった機能で保存しておき、ページ移動の際に毎回Cookieを確認する必要がある。


### Railsのsessionメソッド

ブラウザの一回のセッションに必要なデータを残しておくためのもの。
具体的には、ブラウザの一時Cookieに暗号化したデータを保存するメソッド

Railsチュートリアルでは、ここにログインしているユーザーIDを保存している。
ユーザーIDを保存しておくことでブラウザを閉じるまではログイン後のページを移動することができる。

>チュートリアルには、「このデータは攻撃者に盗まれたとしてもログインすることはできないから安全である。」と書いてあるが、
ログイン中であるという情報は残っているので、これを盗めばユーザーになりすますことができるのではないか思う。
僕の勉強不足でここはわからない。


### Railsのcookiesメソッド

ブラウザ終了後にも残しておきたいデータを保存しておくためのもの。
具体的には、ブラウザの永続Cookieに、暗号化したデータを保存するメソッド

チュートリアルでは、RememberMeと呼ばれるトークンを保存している。
これを使うと、ユーザー名とパスワードを入力しなくてもログインすることができてしまう。
そのため、扱いには注意する必要がある。


## 参照

[今さら聞けないセッションとCookie、ログイン・ログアウト(Rails編)](https://qiita.com/SpicyCoffee/items/de9de9a5427adf81817a)
[Rails セキュリティガイド](https://railsguides.jp/security.html)