OmniAICreator/Qiita-1.07M huggingface dataset:
[Rails]BASIC認証と環境変数について

##初めに
####なぜこの記事を書きたかったのか
RailsのBasicを固めたいから！[コントローラー編]
設定したパスワードを忘れてアプリケーションを開けない状況に。。。パソコンのどこかに置いた記憶はあるけど確認方法を忘れてしまったので今後またこの事件が起きたときメモを残したかった!

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

####記事の目次
**１）What　is BASIC認証？**
**２）BASIC認証の使い方**
**３）鍵を隠す方法**
**４）最後に**

##What is  BASIC認証？
**イメージはアプリケーションに入る前にユーザーの確認をするボディーガードが間にいる感じ。**
![bodygaurdsample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/58818f33-c80a-be56-6fc3-5087a545d5ec.png)

##BASIC認証の使い方
**authenticate_or_request_with_http_basicメソッドをつかう！**

**1)application_controllerへ行き、before_actionを使って変数を設定する（今回はbasic_authにしてみる）**

```ruby
  before_action :basic_auth
```

**2)privateの後に、先程設定したbasic_authのルールを設定する**

```ruby
private

def basic_auth
end
```

**３）上記のメソッドを使う**

```ruby
  private

  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
      username == 'anijan' && password == '1234'
    end
  end
end
```
#### doの後の||内に鍵の種類を書く。
#### 次に各鍵の中身を設定してendで閉じる。

**4)ターミナルを使ってアプリケーションにアクセスすると、before_actionが作動して先程設定したパスと名前を記述しなければアプリケーション内へ移動することができない！**

```
rails s
```

##鍵を隠す方法
####なぜ隠す必要があるのか？それは、コード内を見られたら誰にでもアプリ内に入られてしまうから！(例えば、アプリケーション作成時にgithubを利用している場合、コミットされたコードはすべてウェブ上に保存されたままになる。。見られる！)

**１)ターミナルを開いてサーバー上のテキストエディターを使用する**

```
vim ~/.zshrc
```
**以下が表示してあればOK**
![zshrcsample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/de548019-d0d5-1c5a-d7de-03fea19f7a12.png)

**２)"i"キーを入力して一番下の文字が"INSERT"となれば記述可能になる。**
![insertsample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/ca205c24-af60-5378-a472-9209ecacbb13.png)

**３)先程書いた鍵の中身を上から順に記述する(マウス移動はできません)**
**※もし、zsh内に記述がある場合、その記述の下に追加しよう！あったものを削除してしまうとパソコンが正常に動かないときがあるので気をつけよう**
```
export BASIC_AUTH_USER='anijan'
export BASIC_AUTH_PASSWORD='1234'

```
**４)鍵を追加し終わったら、パソコン(macの場合)の一番左上の"esc"ボタンをタップしてから、":wq"と入力したら
、"enter"キーを押して終了させます**

**５)ターミナルでsourceコマンドをして実行させる**
****

```
source ~/.zshrc
```
**LAST)先程、application_controllerにて記述した鍵の中身を消して、鍵の場所を定義しよう！**
**すぐ確認がしたい場合は、”シークレットウィンドウ"に切り替えてlocalhostで確認しよう！**

```ruby
  before_action :basic_auth

  private

  def basic_auth
    authenticate_pr_request_with_http_basic do |username, password|
      username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]
    end
  end
end  
```
####これでコードを見てパスワード等を確認する方法はなくなって安全！

##最後に
環境変数の設定をするときgithubのようなコードを残すようなものを使うときは、設定完了してからプッシュをしよう！

ココまで読んでくださいましてありがとうございました！
JSONとXML

#JSONとXML
## JSONとXMLの両方を使用して、Webサーバーからデータを受信できます。

次のJSONとXMLの例はどちらも、3人の配列を含むemployeeオブジェクトを定義しています。

### JSONの例

<pre>{"employees":[
    { "firstName":"Bill", "lastName":"Gates" },
    { "firstName":"Steve", "lastName":"Jobs" },
    { "firstName":"Elon", "lastName":"Musk" }
]}
</pre>

### XMLの例
```xml
<employees>
    <employee>
         <firstName>Bill</firstName>
         <lastName>Gates</lastName>
     </employee>
     <employee>
         <firstName>Steve</firstName>
         <lastName>Jobs</lastName>
     </employee>
     <employee>
         <firstName>Elon</firstName>
         <lastName>Musk</lastName>
     </employee>
</employees>
```
## JSONはXMLに似ています。理由は次のとおりです。

* JSONとXMLはどちらも「自己記述型」です
* JSONとXMLはどちらも階層的です
* JSONとXMLの両方を解析して、多数のプログラミング言語で使用できます
* JSONとXMLの両方をXMLHttpRequestで読み取ることができます

## JSONとXMLの違いは次のとおりです。

* JSONはタグを使用しません
* JSONは短いです
* JSONの読み取りと書き込みが高速化
* JSONは配列を使用できます

最大の違いは次のとおりです。

XMLは、XMLパーサーを使用して解析する必要があります。また、JSONは標準のJavaScript関数で解析できます。



## JSONがXMLよりも優れているのはなぜですか？

* XMLはJSONよりも解析が困難です。
* JSONは、使用可能なJavaScriptオブジェクトに解析されます。

AJAXアプリケーションの場合、JSONはXMLよりも高速で使いやすいです。

### XMLを使用する
* XMLドキュメントを読む
* XMLDOMを使用してドキュメントをトラバースします
*変数に格納されている値を抽出します

### JSONを使用する
* JSON文字列を読み取る
* JSON.Parse JSON文字列
WindowsからLinuxへDb2を移行する

# はじめに
データベースを異なるプラットフォームで移行する場合、文字コードなどの考慮事項があります。それらを踏まえて移行方法を検討しました。

# 内容

以下の前提でIBM Db2の移行方法を説明、検討します。

- サーバーをWindowsからLinuxへ変更
- Db2をバージョンアップ
- データを移行

# 移行する環境

|  | 移行元DBサーバー | 移行先DBサーバー |
|:-:|:-:|:-:|
| OS  | Windows Server 2008 R2 | Ubuntu 20.04 LTS |
| DBMS | IBM Db2 V10.1 | IBM Db2 V11.5 |
| 文字コード(OS) | Shift JIS | UTF-8 |
| 文字コード(DB) | Shift JIS | Shift JIS |

# 移行する方法
移行するやり方は3つあります。

| 移行方法 | 特徴 | Windows-Linux |
|:-:|:-:|:-:|
| バックアップ／リストア |データベース単位にファイルに出力 | 不可 |
| エクスポート／ロード | テーブル単位にファイル出力 | 可能 |
| カーソルを用いたロード | 移行元DBに接続してselect/load | 可能 |

##### バックアップ／リストア
backupコマンドでデータベース単位にバックアップし、作成したバックアップファイルを元にrestoreコマンドで復元します。データのバージョンアップはDb2が行います。最も簡単な方法ですが、プラットフォームの互換性、Db2のバージョン間の互換性を考慮する必要があります。詳細はIBMのウェブサイトをご覧ください。

[[Db2] バックアップ・イメージの互換性](https://www.ibm.com/support/pages/db2-%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%83%BB%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E4%BA%92%E6%8F%9B%E6%80%A7 "IBMのウェブサイト")

##### エクスポート／ロード
exportコマンドでテーブル単位にファイルを出力、それを元に移行先のテーブルへloadコマンドで挿入します。もっとも可搬性が高く、DBMSを変更する際にも用いられる方法です。ファイルを出力、読み込む際に以下に注意を払う必要があります。

- 32KBを超えるレコード長
- ラージオブジェクト(LOB)
- 文字コード

エクスポート／ロードはQiitaもご覧ください。
[Db2:データベースをExportで全部移行してくれ](https://qiita.com/tsunenorikan/items/be1b3c70aafb4f553c8d "Qiita")
[Db2:データベースをLoadで全部移行してくれ](https://qiita.com/tsunenorikan/items/e71ff0a8a6c8df9bff7c "Qiita")

##### カーソルを用いたロード
移行先のデータベースに接続したうえで**移行元のデータベースをカーソルで定義、そのカーソルでselectしたレコードをload**します。ファイル出力をしないので作業用ファイルスペースを用意する必要がありません。移行元DBサーバーと移行先DBサーバーとが同じ場所でなくオンプレミスとクラウドといった場合、移行に時間がかかる可能性があります。

```sql:カーソルを用いたロード
connect to NEWDB ;
declare mycurs cursor database OLDDB user user1 using pwd1 for select two,one,three from abc.table1 ;
load from mycurs of cursor insert into abc.table1 ;
```

LOADコマンドの詳細はIBMのウェブサイトをご覧ください。
[LOADコマンド](https://www.ibm.com/docs/ja/db2/11.5?topic=commands-load "IBMのウェブサイト")

# どの方法を選ぶか
今回はWindowsからLinuxへの移行なのでバックアップ／リストアは使えません。データベースの文字コードはShift JISのままで変更なしですが**OSがShift JISからUTF-8に変わります。**エクスポート／ロードで移行する場合、文字コードに対する対応、環境設定の変更が必要な場合があります。

:::note warn
OS(Linux)がUTF-8でDBがShift JISの場合、CSVファイルをそのままインポートすると文字化けします。コードページをShift-JISに変更してからインポートします。

1.DB2CODEPAGEをShift-JISに設定
    export DB2CODEPAGE=943
2.データベースを切断
    db2 terminate
3.データベースを再接続してコードページを反映
    db2 connect to mydb
4.Shift-JISのcsvをインポート
    db2 import from file.csv of del insert into table1
:::

カーソルを用いたロードで移行する場合、ファイルを介さずデータベース間でのやり取りのため、文字コードに対する対応は不要になります。

| 移行方法 | メリット | デメリット |
|:-:|:-:|:-:|
| バックアップ／リストア | 最も単純で簡単  | Windows-Linuxは不可 |
| エクスポート／ロード | 可搬性に優れる | 文字コードの考慮が必要 |
| カーソルを用いたロード | 文字コードの考慮が不要 | リモート接続だと遅い |

エクスポート／ロードはケアレスミスで簡単に文字化けしそうです。**正直、文字化けトラブルは泥沼なので係わりたくありません。**今回のケースですとファイル出力も不要な**カーソルを用いたロード**で移行することにしました。

# おわりに
データベースの移行は前提条件によって選択する方法が変わります。今回は同じDBMSなのでカーソルを用いたロードを選択しましたが、DBMSを変更するならエクスポート／ロードを選択するか異種DBMS間を接続するアダプターを介しての移行になるかと思います。
TwilioのConnection OverridesでWebHookのエラー耐性を上げる

### TwilioのWebHookでエラー時のリカバリ
Twilioでは着信等のイベントでのWebHookで指定のサーバのAPIにデータをPOSTしてくれるWebHookの仕組みがあり、WebHookの接続エラーのリカバリとしてFallBackの仕組みが提供されています。
今回WebHookのエラー時の振る舞いをカスタマイズし、処理改善を行う案件にて「Webhooks: Connection Overrides」を使用しました。

<img width="400" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745216/bd173506-2788-aafa-c37f-de198f935905.png">
WebHookを利用するには上のTwiMLAppに登録するのが便利です。
・RequesutURL：着信などイベント発生時のWebHook先URL
・FallBackURL：WebHookエラー時のアクセス先URL
Twilio側のざっくりとしたフローは下図となり
<img width="300" alt="webhook.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745216/0de465f9-3df8-d218-568d-962d8a61c8c1.png">
赤字のエラー分岐のデフォルトは
・TCP接続：5000ms
・HTTPレスポンス待ち：15000ms
となり、リトライはありません。
この部分をカスタマイズ可能とする機能として「Webhooks: Connection Overrides」があります。
https://jp.twilio.com/docs/usage/webhooks/webhooks-connection-overrides

### Connection Overridesの設定
設定可能なパラメータ

|パラメータ名|初期値|備考|
|:--|:--:|:--|
|ct|5000|TCPコネクションのタイムアウト判定値|
|rt|5000|HTTPリクエスト後レスポンスの待ち時間|
|tt|15000|上2つを含むトータルタイム|
|rc|1|エラー時リトライ数|
|rp|ct|リトライを行うルール(4xx\5xx\ct\rt\allからカンマ区切りで複数の設定も可能)
|sni|unset|y or nでサーバ環境に合わせて設定|
|e|ashburn|近いロケーションを選ぶと処理が若干早くなる可能性があるようです|

#### やりたいこと
・RequesutURLはデフォルト(15000ms)より早めにタイムアウトしてFallBackへ流したい
・FallBackURLも早めにエラー判定をしてリトライ処理をしたい
この点を踏まえパラメータを組みました(例は3000msを処理判定の基準としています)。
<pre>・RequesutURL：TCP接続、HTTPレスポンス待ちに関わらず3秒でダメならFallBackへ
   ->https://XXXXXXXXXXXXXX/#tt=3000
・FallBackURL：絶対受け取りたいのでTCP接続、HTTPレスポンス待ちに関わらず
　　　　　　　　3秒でダメならリトライする
   ->https://XXXXXXXXXXXXXX/#tt=3000(誤った設定)&rc=5&rp=all&sni=y
</pre>

をTwiMLAppに設定して各WebHook先URLにWaitを入れてConnection Overridesが発火するようにして試験したところ、
・RequesutURL->パラメータ通りにFallBackへ
・FallBackURL->リトライが発生しない
となりました。Twilioのサポートに質問してみたところ、丁寧にご説明を頂きました(助かりました)。
ttはリトライも含めたトータル時間なので、tt=3000を設定すると3000msで処理を終了しリトライは発生しないので、
<pre>・FallBackURL：
   ->https://XXXXXXXXXXXXXX/#ct=3000&rt=3000&rc=5&rp=all&sni=y
</pre>
このようにTCP接続3000ms(ct=3000)/HTTPレスポンス待ち3000ms(rt=3000)とパラメータを設定すると正常にリトライ処理が行われました。
言われてみればその通りなのですが、安直に考え勘違いをしました。

#### 効果
この処理を行う事で、WebHook連携にてネットワークに起因してリクエストが届かないなど発生した際に、早めにリカバリ(FallBack)に回す事でサービスの提供が安定化します。
また、リトライ処理を組み込む事で取りこぼしリスクを最小に出来ます。

Twilioの詳細は下のURLになります。
https://cloudapi.kddi-web.com/
jqでオブジェクトの値だけカンマ区切りにする

このような `null` を含むオブジェクトの値を、jqでカンマ区切りにする。

```json
[
  {
    "key11": "val11",
    "key22": null,
    "key33": "val33"
  },
  {
    "key21": "val21",
    "key22": "val22",
    "key23": null
  }
]

```

* `-r` を付けないと出力1行ごとにダブルクォートで括られてしまう
* `@csv` は列ごとにダブルクォーテーションで括られてしまうので愚直に `join`
* `//` で `null` を `--` などに置換（ `false` も置換されるので注意）

```
jq -r '.[]|[.[]|.//"--"]|join(",")'
```

出力

```
val11,--,val33
val21,val22,--
```
Couchbase Server Java SDK解説：分散トランザクション〜クリーンアッププロセス（設定と監視）

## はじめに

下記の記事で触れたように、Couchbase Server　Java SDKには、分散トランザクションを実現するにあたり、クリーンアップメカニズムが含まれます。

https://qiita.com/yoshiyuki_kono/items/2d428b16b224b8c01239

まず、上記の記事でも触れた基本的な内容を振り返るところから始めます。

## クリーンアップの基本
失敗したトランザクションが、他のトランザクションを無期限にブロックしないようにするため、Couchbase SDKは、「クリーンアップ」と呼ばれるメカニズムを提供します。

トランザクションは、失敗が発生したときに、まず自分自身でクリーンアップしようとします。

### 非同期クリーンアップ
アプリケーションのクラッシュなどの原因で、そのトランザクション自身によってクリーンアップされなかった、「ロスト」トランザクションが作成される状況があります。

そのためクリーンアップメカニズムには、`Transaction`オブジェクトの作成時に開始される非同期クリーンアップのためのバックグラウンドプロセスが含まれます。このプロセスは、任意のアプリケーションによって作成された、すべてのバケットにおける期限切れのトランザクションをスキャンします。つまり、アプリケーションは、別のアプリケーションによって作成されたトランザクションをクリーンアップするケースも起こりえますが、そのことは問題となりません。

逆に開発中など、アプリケーションが継続的に実行されていないケースでは、停止したアプリケーションプロセスによってクリーンアップされなかったトランザクション情報をクリーンアップするためにアプリケーションを起動することも考えられます。

アプリケーションが実行されていない期間、非同期クリーンアップは実行されていないことに注意する必要があります。これは、単体テスト実行の場合に顕著になります。このことが問題となる場合、非同期クリーンアップが常に実行されていることを確実にするために、　`Transactions`オブジェクトをオープンするだけの単純なアプリケーションを実行しておくことが考えられます。

## 非同期クリーンアップ詳細

クリーンアップは、各バケットで実行されます。

`Transactions`オブジェクトを作成すると、バックグラウンドクリーンアップタスクが生成されます。このタスクの役割は、期限切れのトランザクションを定期的にスキャンしてクリーンアップすることです。
具体的には、バケットに含まれるアクティブトランザクションレコード（ATR）をスキャンすることによって行われます。ATRは、トランザクションが正常に完了した後のある時点、またはクリーンアップ中に削除されます。バケット上のすべてのATRは、すべてのクリーンアッププロセスを実行している全てのクライアントから削除される可能性があります（つまり、処理は分散されます）。

同じクラスターに接続してトランザクションを実行しているすべてのアプリケーションは、クラスター内の各バケットに作成される「`_txn：client-record`」メタデータドキュメントのクリーンアップを（ロータッチ通信プロトコルを介して）共同で実行します。このドキュメントは可視的ですが、外部から変更してはいけません。

#### バックグラウンドプロセスの負荷と設定
デフォルト設定は、スキャンプロセスに必要なバックグラウンド読み取りによる影響を無視できるレベルに抑えながら、期限切れのトランザクションを適度に迅速に検出できるように調整されています。具体的には、デフォルト設定では、60秒以内に期限切れのトランザクションが検出され、通常1秒あたりの読み取り数は20未満です。これがクラスターのパフォーマンスに影響を与える可能性は低いですが、設定は必要に応じて調整できます。

## クリーンアップ設定

クリーンアップ設定は次のように構成できます。


#### `cleanupWindow`

デフォルト値：60秒

この設定により、クリーンアップの「実行」の長さが決まります。つまり、このクライアントがATRドキュメントのサブセットをチェックする頻度です。

アプリケーションで、この設定を変更することができます。デフォルトの値は控えめに設定されています。この値を減らすと、有効期限トランザクションがより迅速に検出されるかわり、スキャンプロセスに使用される1秒あたりの読み取り数が増えるというトレードオフが発生します。

#### `cleanupLostAttempts`

デフォルト値：true

この設定は、クライアントが上記の分散クリーンアッププロセスに参加するスレッドを実行するかどうかを示します。
有効のままにしておくことが強く推奨されます。

#### `cleanupClientAttempts`

デフォルト値：true

この設定は、クライアント自身によって作成されたトランザクションをクリーンアップするためにスレッドを実行しているかどうかを示します。
クライアントは、自身が作成したトランザクションを優先的に処理することを目的とし、強制された場合（たとえば、アプリケーションのクラッシュ時）にのみ分散クリーンアッププロセスに参加します。
有効のままにしておくことが強く推奨されます。

## クリーンアップ監視

アプリケーションがクリーンアップを監視したい場合は、次のように、イベントをサブスクライブできます。

```java
cluster.environment().eventBus().subscribe(event -> {
    if (event instanceof TransactionCleanupAttempt || event instanceof TransactionCleanupEndRunEvent) {
        // log this event
    }
});
```

#### `TransactionCleanupEndRunEvent`
クリーンアップが終了するたびに発生し、クリーンアップ実行からの統計情報が含まれます。（実行は通常、デフォルト構成で約60秒ごとです。）

#### `TransactionCleanupAttempt`
このプロセスによって期限切れのトランザクションが発見され、クリーンアップの試みが行われたときにイベントが発生します。これには、その試行が成功したかどうかと、その試行に関連するログが含まれます。

さらに、クリーンアップが有効期限を過ぎて2時間以上経過したトランザクションのクリーンアップに失敗した場合にも、この`TransactionCleanupAttempt`イベントが、（デフォルトの`DEBUG`ではなく）`WARN`レベルで発生します。
この場合、イベントが`WARN`レベルで発生するため、典型的な環境では、イベントがログに記録されると考えられます。
何らかの外部要因（ノードダウンなど）、クリーンアップが失敗する正当な理由がない場合、問題として扱う（サポートに報告する等）日ことが推奨されます。
Google mapsにKMLファイルをロードさせるURL

#　KMLファイルをロードするときに指定するURLの注意点

KMLファイルをロードする時にのURLが、ローカル環境のURLだと不可能。
グローバル環境からアクセスできるURLが必要になる。

# 対処方法
ローカル環境を無料で外部公開できるサービスなどを使用する
https://rs-techdev.com/archives/233

今回使ったのは
localhost.run（https://localhost.run/）

# localhost.runの使い方
ターミナルで
```ssh -R 80:localhost:<ポート番号> ssh.localhost.run
```

接続時にはランダムなURLが生成
ついに正式版 GDevelop v5.0.120 がリリースされました。

:::note info
GDevelop は 4ian 氏が Google 在籍中に開発をスタートした無料でオープンソースなゲームエンジンです。
:::
**※ この投稿は「[GDevelop 無料ゲーム制作ツールを使い倒す Blog](https://gdevelop-jp.blogspot.com)」からの移植＆改訂版です。**

正式版というか、ただ beta の表記がなくなっただけではありますが、それでもついに本格始動という雰囲気になってきました！😆

印象が決まる beta 明け最初のリリースだからでしょうか。
今回は地味な安定化が主な更新内容です。
beta119 には困ったバグが多いので、すみやかにバージョンアップしましょう😅
##💝 改善点
###・テキストオブジェクトに「FontSize()」式を追加しました。
テキストオブジェクトのフォントサイズを、式で取得できるようになりました。ってか今まで出来なかったんかいｗ

###・プロファイルをいろいろ改善しました。
![2021-10-12 133924.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224830/f821673c-bc0b-9ab6-f58f-ef120d511e8b.png)
- マイ プロファイルで簡単なプロファイル（自己紹介文）が入力できるようになりました。
- メールアドレスの認証と変更機能が追加されました。
- 拡張機能とサンプルの一覧画面で、寄稿者のバッジをクリックすることで、そのユーザーのプロファイルを見ることができるようになりました。
- 存在しないユーザー名では、プロジェクトや拡張機能を保存できないようになりました。

##⚙️ 拡張機能、🎨 リソース、🕹 サンプル
プロファイル関係の手直しがいくつか入ったようですが、そのあたりは割愛。

###・リンクオブジェクト機能と経路探索ビヘイビアを合わせて使用した時に、経路探索がうまく動作しない問題を解決しました。
どんな問題だったのか知らないので、何がどう改善されたのかわかりませんが、多分こういうことだと思うｗ

##🐛 バグの修正
###・オブジェクトまたはビヘイビアで、式のパラメータダイアログが開かない問題を修正しました。
なんかシレッと書いてありましたが、これはかなりヤバいバグだったので、もっと大々的に告知して、早く修正バージョンを出すべきだったのでは？と思いました。
beta119 を使用している方は、すみやかにバージョンアップしましょう。

###・一貫性を保つために、「空のゲーム」という表記を「空のプロジェクト」に修正しました。
おかげで翻訳し直しでしたｗ
しかもインストール版のみ、その翻訳が反映されていないように見えます😢

###・すごく長いオブジェクト名がはみ出たり、一部のダイアログを台無しにしたりする問題を修正しました。
###・リソースセレクターで、リソース名が長い場合のアイコン配置とテキストの省略記号を修正しました。
そもそもリソースセレクターとはなんぞや🤤

###・GDevelop を起動した際に、ログアウトしてしまう問題を修正しました。
気が付かなかったことが逆にすごいｗ

###・ダイアログツリーでダイアログが開始されていなくても、ダイアログ状態変数を比較できるように、条件を修正しました。
これも多分、そういうこと↑だと思います🤤（原文確認推奨）

ダイアログツリーはまだ実験的段階なので、色々と機能的にあと一歩な感じなのですが、もう少し実用性が増してくれれば、RPG やノベルゲームで大活躍できる機能なので期待しています。（全然更新されないけど）

##🤓 まとめ
ついに beta の表記が取れた記念すべき最初のバージョンがリリースされました🎉

機能面ではまだ実験的段階のものもいくつかありますが、既に多くの実績もありますし、4ian 氏が GDevelop のために企業を立ち上げたこのタイミングで、beta 明けしたのは良いタイミングだと思います！

ただ個人的には、その企業がどうやって収益を上げていくつもりなのか、かなり謎な点が心配です……😅

オンラインサービスのサブスクが、そんなに好調なのでしょうか。
あの驚異的な低価格では、サーバー維持費だけで消し飛びそうな気も……（契約数にもよりますが）

引き続き、開発は無償で働いてくれる有志に期待しちゃうスタンスなのでしょうか。
まぁ色々と疑問は尽きませんが、今後の GDevelop チームの経営手腕に期待です！😉

ここで紹介した点以外にも、色々とバグ修正などもされているので、詳しくは GitHub の [GDevelop Releases](https://github.com/4ian/GDevelop/releases) ページをチェック！
iOS15のUITableViewCellとTableViewHeaderでハマりかけた事。

備忘も兼ねて。

iOS14までは問題なかったのに、iOS15になるとクラッシュしてしまう箇所があった。

下記の内容がTableViewCellを読み込んだ際にクラッシュするというもので、調べてみるとレイアウト関連が悪さしているらしい。

```
Must translate autoresizing mask into constraints to have
_setHostsLayoutEngine:YES.
```

手がかりであるsetHostsLayoutEngineで調べ見てると、
UITableView.xibの設定にある
```Layout：Autoresizing Mask → Inferred```
の修正で良いみたいなんですが、これでは私の環境ではダメでした。
また、Inferredだとレイアウトが崩れてしまっていたという事もあり、レイアウトまで触っている時間が無かった為、Autoresizing Maskに戻しました。

最終的には、UITableViewCellをソースコードで開き、tableViewCellContentViewタグ内にある
```translatesAutoresizingMaskIntoConstraints="NO"```
を削除する事により、クラッシュする事はなくなった為、問題なさそう。

TableViewHeaderでは不自然な余白が入るようになってしまっており、TableViewHeaderが原因なのは明白だった為、
[iOS15のUITableViewHeaderの上部に空白ができる](https://qiita.com/yuringo_mm/items/e86aaa80bd3ae9e35fbd)
を参考にさせていただき、Headerの高さを設定する箇所に追記した事により、無事元通りになったので、一先ずは良かったかなと。

```swift
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if #available(iOS 15,*){
        tableView.sectionHeaderTopPadding = 0.0
    }
 ~ 略 ~
}
```
分散ライブラリrayをKubernetes上で動作させる


https://docs.ray.io/en/latest/cluster/kubernetes.html
## install
```
git clone https://github.com/ray-project/ray.git 
```

## run
```
cd ray/deploy/charts
helm -n ray install example-cluster --create-namespace ./ray

```

## 確認
```
$ kubectl -n ray get rayclusters
NAME              STATUS   RESTARTS   AGE
example-cluster                       10s

$ kubectl -n ray get pods
NAME                                    READY   STATUS    RESTARTS   AGE
example-cluster-ray-head-type-5926k     1/1     Running   0          57s
example-cluster-ray-worker-type-8gbwx   1/1     Running   0          40s
example-cluster-ray-worker-type-l6cvx   1/1     Running   0          40s

# A service exposing the Ray head node.
$ kubectl -n ray get service
NAME                       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                       AGE
example-cluster-ray-head   ClusterIP   10.8.11.17   <none>        10001/TCP,8265/TCP,8000/TCP   115s

# The operator deployment.
# By default, the deployment is launched in namespace "default".
$ kubectl get deployment ray-operator
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
ray-operator   1/1     1            1           3m1s

# The single pod of the operator deployment.
$ kubectl get pod -l cluster.ray.io/component=operator
NAME                            READY   STATUS    RESTARTS   AGE
ray-operator-84f5d57b7f-xkvtm   1/1     Running   0          3m35

# The Custom Resource Definition defining a RayCluster.
$ kubectl get crd rayclusters.cluster.ray.io
NAME                         CREATED AT
rayclusters.cluster.ray.io   2021-05-14T18:44:02
```

## ダッシュボードを見る

```
$ kubectl -n ray port-forward service/example-cluster-ray-head 8265:8265
localhost:8265
```

# Ray client を利用する
10001でheadのportを立ち上げます。

```
kubectl -n ray port-forward service/example-cluster-ray-head 10001:10001
```

その後、新しいターミナルで以下を実行
```
```
Kubernetes スケジューラの挙動メモ

調べたいことがあり、スケジューラ実装のソースを読んだ際のメモです。
かなりはしょってますので、読みづらいかもしれません。

# 調べたいこと
* Priority Classを使った際にスタベーションは起きるのか
* バックフィルはあるのか

# 読む前に知識をつける
* https://speakerdeck.com/smatsuzaki/kubernetesfalsesosukodorideinguru-men
* https://www.alibabacloud.com/blog/a-brief-analysis-on-the-implementation-of-the-kubernetes-scheduler_595083
* https://www.alibabacloud.com/blog/getting-started-with-kubernetes-%7C-scheduling-process-and-scheduler-algorithms_596299

# コードリーディング準備
* vscode WSLを利用
* GitHubからクローン（コミットログ不要なので`--depth 1`をつける）
* goの拡張を入れる
  * 右クリックで参照や定義ジャンプができるようになる 

# 概要
* pkg/scheduler/internal/scheduling_queue.go
  * 3つのQueueを内部にもつ 
      * activeQ: アサインしようとしているPodをためる。実態はinternal/heap/heap.go
      * unschedulableQ: アサインを試みて無理と判断したPodをためる
      * backOffQ: unschedulableQから移したPodをためる。このQの中でbackOff完了したPodをactiveQに戻す。実態はinternal/heap/heap.go

* internal/heap/heap.go
  * container/heapパッケージのラッパー 
  * internal/heap_test/heap.go を見れば、動的に優先度を変更できることがわかる
  
# 結論
* 動的に優先度変更がキューに反映されるので、優先度の付け方次第でスタベーションは起きえる
  * あくまでキューがそうなってるだけなので、ProrityClassの変更がキューに渡らない可能性もある。
      * 要追加調査（実機検証したい）
* アサイン不能なものはいったんactiveQから出て別のキューに移動するので、キュー先頭がアサイン不能だった場合、それより優先度の低いものもアサインはされる
  * バックフィルに近い挙動である(厳密には違うが)
MNISTを用いて『自分の書いた数字』を識別させよう

#0.初めに
修士になって深層学習を扱い始めた。MNISTでの数字識別を例にしている記事が多くあったが、
**『自分が書いた数字を実際に認識させる』**とこまでやっている記事が少なかった。
自分なりに調べて、自分の書いた数字の識別まで辿り着いた。
したがって、備忘録として示しておきます。

#1.流れ
数字画像作成（通常、RGBの3次元画像として保存される)
↓
画像を加工
↓
作成したモデルに入力

**画像の加工**が本稿のポイントです。具体的には...
①画像を(縦×横×RGB3次元)→(28×28×RGB3次元に変換)
②(28×28×RGB3次元)→(28×28)のグレースケール画像に変換し、保存

28×28にするのは、MNISTのデータセットと合わせるためです。

#2.手書き文字作成(パワポ)
![スクリーンショット 2021-10-21 155605.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557479/a3523c9e-731a-5f13-83fc-8da38104802e.png)

こんな感じで、パワポの背景を塗りつぶす。そして注釈モードのペンを使って数字を書こう
何個か出来たら適当にスクショして保存

#3.実際に認識してみる

画像の加工関数は以下の通り、この記事で一番大事な部分です。

```python
def dim3RGB_to_dim1gray(file_name):
    img_bgr = cv2.imread(file_name)
    #Blue,Green,Redの順番らしい

    blue=img_bgr[:,:,0]
    green=img_bgr[:,:,1]
    red=img_bgr[:,:,2]
    
    #RGB→白黒の変換
    gray_scale=red*0.3+green*0.59+blue*0.11
    
    #これで(28,28,3)→(28,28)へ
    print(gray_scale)
    print(gray_scale.shape)

    #元ファイル名が　9.png　なら　grayscale_9.png　として保存される
    cv2.imwrite("grayscale_"+file_name, gray_scale)
```

保存が出来たら、実際に学習してみる

```python
from keras.datasets import mnist
from keras import models
from keras import layers
import cv2
from keras.utils import np_utils


#MNISTデータの読み込み
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

#モデル作成
network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))
network.compile(optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy'])

#データセットの画像をちょいと加工　必須です
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255

#正解ラベルを加工　これまた必須
train_labels = np_utils.to_categorical(train_labels)
test_labels = np_utils.to_categorical(test_labels)

#学習！！
network.fit(train_images, train_labels, epochs=5, batch_size=128)

#ここで一度精度確認
test_loss, test_acc = network.evaluate(test_images, test_labels)

#ここからがオリジナルです！！　自分が作ったファイルを開いて、モデルに入力してみる
file_name_list=["grayscale_2.png","grayscale_6.png","grayscale_9.png"]

for file_name in file_name_list:
    print(file_name)
    img = cv2.imread(file_name, cv2.IMREAD_GRAYSCALE)
    img=img.reshape(1,28*28)
    img=img.astype('float32')/255
    print(network.predict(img))

```

#4.実験結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557479/faa96a9f-8d1f-275b-af2d-21b197f337c2.png)
"2"と"9"は良い感じに識別された
"6"は精度が微妙だった。
このあたりは色々試行錯誤しながら改善できそうですね
4点から領域を作る その1 ～四角形編～

#前提条件
- 4点 A,B,C,D が二次元座標上に入力される
- 連続する3点以上が同一直線上に並ばない
- A -> B -> C -> D -> A と直線で結ぶ

この条件から得られる図形 ABCD の形を点 A, B, C, D の座標から計算した値を用いて判別することが目的です。

#今回の内容
今回は上記の条件で得られる図形 ABCD のうち、標準的な四角形の判別について取り上げます。

例：標準的な四角形
![四角.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553087/733141d1-8018-7e82-be08-051163cf9930.png)
他の図形については別の記事で取り上げます。

4点から領域を作る その1 ～四角形編～（この記事）
[4点から領域を作る その2 ～蝶型、V字型編～](https://qiita.com/tf_okrt/items/916c763303b043fdd69f)
[4点から領域を作る その3 ～三角形、スリッパ型、直線編～] (https://qiita.com/tf_okrt/items/80ca63863068f642636f)

#線分交差判定

ここで有用な手法として、線分の交差判定で用いられる、2点から得られる直線に対する他の2点の存在領域の判別手法を用います。

線分交差判定で検索していただければ計算式はわかりますが、概要を以下に記します。

例として、点 $ A(x_{A}, y_{A}) $, 点 $ B(x_{B}, y_{B}) $ の2点からなる直線 $ AB $ が平面を分割することで得られる2領域について、点 $ C(x_{C}, y_{C}) $, 点 $ D(x_{D}, y_{D}) $ の2点が同じ領域に存在するかどうかを判定します。

直線 $ AB $ の方程式は座標 $ (x_{A}, y_{A}), (x_{B}, y_{B}) $ を用いて以下の様に示されます。

```math
y-y_{A} = \frac{y_{A}-y_{B}}{x_{A}-x_{B}}(x-x_{A})
```

この式を変形すると、以下の通りとなります。

```math
(y_{A}-y_{B})(x-x_{A})-(x_{A}-x_{B})(y-y_{A})=0
```

ここで得られる $ (y_{A}-y_{B})(x-x_{A})-(x_{A}-x_{B})(y-y_{A}) $ が直線 $ AB $ から得られる2領域のいずれに存在するかの判定式となります。

この判定式にある一方の領域に存在する点の座標を代入すると正の値となり、もう一方の領域に存在する点の座標を代入すると負の値となります。

この事実を利用して、点 $ C $ の座標を代入した値 $ AB_{C} $ を以下のように計算し、 

```math
AB_{C} = (y_{A}-y_{B})(x_{C}-x_{A})-(x_{A}-x_{B})(y_{C}-y_{A})
```

点 $ D $ の座標を代入した値 $ AB_{D} $ を以下のように計算し、 

```math
AB_{D} = (y_{A}-y_{B})(x_{D}-x_{A})-(x_{A}-x_{B})(y_{D}-y_{A})
```

$ V_{AB} = AB_{C}AB_{D} $ の値を計算すると以下の判定が行えます。

| $ V_{AB} $ | 直線 $ AB $ から見た点 $C, D$ |
|:-:|:-:|
| + | 同じ領域 |
| - | 異なる領域 |

実際に線分交差判定を行う場合は直線 $ CD $ から見た点 $A, B$ についても計算を行う形となります。

#判定式の値と実際の図形

また、先ほど導出した $ V_{AB} = AB_{C}AB_{D} $ の値がプラスになる場合に得られる図形は以下の3つのうちのいずれかです。
![VABプラス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553087/48913e4f-8d4a-aa73-21a5-ff8a2ea818f8.png)
また、$ V_{AB} = AB_{C}AB_{D} $ の値がマイナスになる場合に得られる図形は以下の2つのうちのいずれかです。
![VABマイナス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553087/c8fbd898-ae9b-5dba-f553-f104c69e6686.png)

図形を見てわかる通り、まずは $ V_{AB} = AB_{C}AB_{D} $ の値がプラスにならないことには今回対象としている図形を得ることができないことが分かります。

#得られる図形を判定式で区別

ここで、$ V_{AB} > 0 $ で得られる図形に関して、$ V_{AB} $ だけでなく、$ V_{BC}, V_{CD}, V_{DA} $ についても同様に計算すると以下の様な結果となります。
（上記画像の左から図形1, 図形2, 図形3とします）

| 図形 | $ V_{AB} $ | $ V_{BC} $ | $ V_{CD} $ | $ V_{DA} $ |
|:-:|:-:|:-:|:-:|:-:|
| 図形1 | + | + | + | + |
| 図形2 | + | - | + | - |
| 図形3 | + | - | - | + |

図形3に関しては、類型として∠BCDではなく∠CDAが凹みとなっているパターンもありますが、この場合は以下の結果の通り、$ V_{BC} $ と $ V_{DA} $ の正負が入れ替わる形となります。

| 図形 | $ V_{AB} $ | $ V_{BC} $ | $ V_{CD} $ | $ V_{DA} $ |
|:-:|:-:|:-:|:-:|:-:|
| 図形3類型 | + | + | - | - |

上記の結果を基に考えると、今回対象としている図形である図形1は
$ V_{AB}>0 $ かつ $ V_{BC}>0 $ かつ $ V_{CD}>0 $
となればよいことが分かります。

#今後の予定

今回は標準的な四角形について取りあげましたが、次回の その2 では点の位置関係の考え方を拡張し、図形2のような蝶型や図形3のようなV字型に関する検証を行っていきます。

また、その3 では その2 の内容を踏まえて、前提条件の一つである「3点以上が同一直線上に並ばない」を撤廃して4点を自由に置いた場合の図形についても検証します。
[UE4] 公式チュートリアル"プレイヤー入力と Pawn クラス"でUE4初心者がつまったところ

# この記事について
UE4 初心者が UE4 公式ドキュメント内にある[プレイヤー入力と Pawn クラス](https://docs.unrealengine.com/4.27/ja/ProgrammingAndScripting/ProgrammingWithCPP/CPPTutorials/PlayerInput/)にトライした時につまづいた点の記録です。

# 環境
Windows 10
UE4 4.27.0
Visual Studio 2019

# プレイヤー入力と Pawn クラス
https://docs.unrealengine.com/4.27/ja/ProgrammingAndScripting/ProgrammingWithCPP/CPPTutorials/PlayerInput/

UE4 公式ドキュメント内にあるチュートリアルです

* プロジェクト内に四角い箱を置いて、それをキーボードから操作できるようにします
* BP (Blue Print) ではなく C++ をメインに使用します
* これを始める前に、UE4エディタの使い方、Pawnとは何か、コンポーネントとは何かを知っておくとスムーズに進みます

# 作業記録

## ドキュメント内のエディタのSSは英語
UE4 をインストールするとエディタは日本語設定になっていますが、ドキュメント内のSSにあるエディタは英語です。エディタを英語に変更する方法は下記の記事で説明されています

https://qiita.com/gansaibow/items/bb93761cce4eeaa349e9

## .h への include 追加は #include "FPSCharacter.generated.h" より前に
.h へ include を追加する際は、#include "FPSCharacter.generated.h" より前に追加する必要があるようです

https://qiita.com/herorinusu/items/5f3e9caede035e0243a3#%E3%80%87%E3%80%87generatedh

## UCameraComponent* OurCamera でビルドエラー
1 - ポーンをカスタマイズする で MyPawn.cpp に追加した**UCameraComponent* OurCamera** がビルドエラーになりました。
MyPawn.cpp の include に "Camera/CameraComponent.h" を追加するとビルドが通るようになりました。

```c++:MyPawn.cpp
#include "MyPawn.h"
#include "Camera/CameraComponent.h"
```
PHP strcmp関数のオレオレ補足

比較できるのはそのまま文字列に変換可能ものだけ。
オブジェクトとか配列を比較対象にすると怒られちゃいます（Fatal error）。
数値を比較対象にすると文字列にキャストしてから比較される。（String関数なので）
（なんかまだある気がする。。。）

####返り値
左辺が小さいと負数
同じだと0
左辺が大きいと整数

ようするに
返り値 = 左辺 - 右辺

使うとしたらこんな感じかなと（PHP8以上）

```php:strcmp_sample.php
$a = 555555555;
$b = "55555555555555555555555555555555555555";

$value = strcmp($a, $b);

if ($value !== 0) $value /= abs($value);

echo match ($value) {
	-1 => '左辺がちっちゃいです。',
	0 => 'ぴったんこ',
	1 => '左辺がおっきいです。',
	default => "なんかおかしいぞっ！！"
};
```


[strcmp（PHPマニュアル）](https://www.php.net/manual/ja/function.strcmp.php "strcmp")
Office LTSC 2021をなるべく簡潔にインストールする方法

# 概要 


Office LTSCのLTSCとは、Long Term Servicing Channelの略で、直訳すると「長期サービスチャネル」です。(google翻訳)
MicrosoftによるとOffice LTSCとは以下のために作成されたものです。

Office LTSCは、機能の更新を一度に何年も受け入れることができない規制対象のデバイス、インターネットに接続されていない製造現場のプロセス制御デバイス、時間内にロックされたままにする必要のある特殊なシステムなど、特定の状況に対応するように構築されています。


Office LTSC 2021がリリースされましたが、Visual Studio Subscriptionには項目がなく、ダウンロードおよびインストールができませんでした。

https://docs.microsoft.com/en-us/deployoffice/ltsc2021/deploy

上記のMicrosoft Docsの記事によると、Office LTSC 2021は、Office Deployment Tool(以下、ODT)を介してインストールが出来るようですので、ODTを用いたOffice LTSC 2021のインストールを試してみました。
その上でOffice LTSC 2021をインストールする、なるべく簡潔な手順を記します。

# 前提条件
以下2環境で動作確認をしました。双方ともインストールまで成功しております。
　・Windows 10 (21H1) x64 JP
　・Windows 11 (21H2) x64 JP


# Office LTSC 2021のインストール手順概要

Office LTSC 2021のインストール手順は以下の様です。

1. ODTをマイクロソフトのサイトからダウンロードし、実行する。
1. configuration.xmlを作成(編集)する。
1. Office LTSC 2021のインストールデータをダウンロードする。
1. Office LTSC 2021をインストールする。

以降では、各手順を詳細に記します。

## ODTをマイクロソフトのサイトからダウンロードし、実行する。

ODTは以下のサイトで配られています。

https://www.microsoft.com/en-us/download/details.aspx?id=49117

オレンジ色のDownloadボタンからダウンロードしてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283036/cb05fd13-140d-40e5-c619-ab4e7fca0d9e.jpeg" width="800px">

ODTをダウンロードしたあと、実行します。
実行すると、以下の5種類のファイルがダウンロードされました。

![ODT_AfterDownload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283036/c12791b3-3075-8f1e-cdc7-eb9aaa3b3804.png)


## configuration.xmlを作成(編集)する。

configuration.xmlは、名前の通りOffice LTSC 2021のインストールオプションを設定するためのファイルです。

実利用の際は以下のサイトからオプションを指定してconfiguratino.xmlを作成するとよいでしょう。

https://config.office.com/deploymentsettings

今回はお試しのため、ダウンロードしたままファイルでインストールを行っていこうと思います。

### 言語設定について

言語設定はデフォルト：英語(en-us)です。
日本語(ja-jp)でインストールしたい場合は、configuration.xmlのen-usをja-jpに置換してください。

```xml:configuration-Office2019Enterprise.xml
<Configuration>

  <Add OfficeClientEdition="64" Channel="PerpetualVL2019">
    <Product ID="ProPlus2019Volume">
      <Language ID="en-us" />    <!-- en-us を ja-jp に置換 --> 
    </Product>
    <Product ID="VisioPro2019Volume">
      <Language ID="en-us" />    <!-- en-us を ja-jp に置換 --> 
    </Product>
    <Product ID="ProjectPro2019Volume">
      <Language ID="en-us" />    <!-- en-us を ja-jp に置換 --> 
    </Product>
  </Add>

  <!--  <RemoveMSI All="True" /> -->

  <!--  <Display Level="None" AcceptEULA="TRUE" />  -->

  <!--  <Property Name="AUTOACTIVATE" Value="1" />  -->

</Configuration>
```

## Office LTSC 2021のインストールデータをダウンロードする。

Office LTSC 2021のインストールデータダウンロードのためには、setup.exeを起動引数込みでコマンドライン実行します。

```
setup /download configuration-Office2019Enterprise.xml
```

上記コマンドを実行すると、setup.exeと同じ階層に[Office]というフォルダが作成され、インストールデータがダウンロードされ始めました。

xmlでダウンロード先を指定しない場合、上記の状態になるようです。

ダウンロード完了したのを確認するためには、コマンドラインが実行可能な状態に戻っていることを確認すればよいでしょう。

## Office LTSC 2021をインストールする。

Office LTSC 2021のインストールには、前章のダウンロードと同じくsetup.exeを起動引数込みでコマンドライン実行します。

```
setup /configure configuration-Office2019Enterprise.xml
```

コマンド実行からインストール完了までの流れは以下のようです。

1. [UACダイアログ]起動　⇒　[はい]を選択する。
1. [インストール中ダイアログ]起動　⇒　完了まで待つ。
1. [インストール完了ダイアログ]起動　⇒　[Close]を選択する。

以上でOffice LTSC 2021のインストール完了となります。
CSS　よく使う操作

```css
#　横に並べたいとき
display:　flex;

#　中のものを中央に置きたい
text-align:　center；

#　中のものを左に置きたい
text-align:　left；

#　中のものを右に置きたい
text-align:　right；

#　上下上下のどれかの外枠をMaxまで、広げたいとき
margin-〇〇:　auto；

#　上下上下のどれかの幅をMaxまで、広げたいとき
padding-〇〇:　auto；

#　2つ以上のブロックを均等な幅で置きたいとき
justify-content: space-between;

#　横幅をMaxで使用したいとき
width: 100%

#　縦幅をMaxで使用したいとき
height: 100%
```
公式チュートリアルでWSL2環境にDockerを入れる際にハマったところ

#### 公式チュートリアルをコピペしたけどハマったところまとめ

```
sudo apt-get install docker-ce docker-ce-cli containerd.io

Package docker-ce is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  docker-ce-cli:amd64

E: Package 'docker-ce' has no installation candidate
E: Unable to locate package docker-ce-cli
E: Unable to locate package containerd.io
E: Couldn't find any package by glob 'containerd.io'
E: Couldn't find any package by regex 'containerd.io'
```


### 改善

```
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

を

echo \
  "deb [arch=arm64] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
にする

```

```

sudo docker run hello-worldでハマり

```

### 改善

```

①sudo groupadd docker

②sudo usermod -aG docker Ubuntuのユーザ名

③Ubuntu再起動

④sudo service docker start

```
[rviz] ラインの描画

pythonでrviz上にlineを描画するサンプルプログラムです。

```python:rviz_line_sample.py
#!/usr/bin/env python3

import rospy
from visualization_msgs.msg import Marker
from geometry_msgs.msg import Point

rospy.init_node('line_pub_example')
pub_line_min_dist = rospy.Publisher('~line_min_dist', Marker, queue_size=1)
rospy.loginfo('Publishing example line')

while not rospy.is_shutdown():
    marker = Marker()
    marker.header.frame_id = "map"
    marker.type = marker.LINE_STRIP
    marker.action = marker.ADD

    # marker scale
    marker.scale.x = 0.03
    marker.scale.y = 0.03
    marker.scale.z = 0.03

    # marker color
    marker.color.a = 1.0
    marker.color.r = 1.0
    marker.color.g = 1.0
    marker.color.b = 0.0

    # marker orientaiton
    marker.pose.orientation.x = 0.0
    marker.pose.orientation.y = 0.0
    marker.pose.orientation.z = 0.0
    marker.pose.orientation.w = 1.0

    # marker position
    marker.pose.position.x = 0.0
    marker.pose.position.y = 0.0
    marker.pose.position.z = 0.0

    # marker line points
    marker.points = []
    # first point
    first_line_point = Point()
    first_line_point.x = 0.0
    first_line_point.y = 0.0
    first_line_point.z = 0.0
    marker.points.append(first_line_point)
    # second point
    second_line_point = Point()
    second_line_point.x = 1.0
    second_line_point.y = 1.0
    second_line_point.z = 0.0
    marker.points.append(second_line_point)

    # Publish the Marker
    pub_line_min_dist.publish(marker)

    rospy.sleep(0.5)
```
実行結果は以下のようになります。

![Screenshot from 2021-11-01 17-18-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/3213c14b-4d57-f534-7b13-76af70bb0740.png)

(参考)プログラムは以下のサイトをもとにしました。
https://answers.ros.org/question/203782/rviz-marker-line_strip-is-not-displayed/
Gitで既存のレポジトリの作業に参加する

Github上の既存のリモートリポジトリの作業に参加する方法の備忘録です。
# リモートリポジトリをクローンする
はじめにリポジトリをクローンします。

```
git clone [リポジトリのURL] [クローン先のディレクトリ]
```

# ブランチを変更する
必要に応じて、作業を開始するブランチのもとになるブランチに移動します。

```
git checkout [ブランチ名]
```

# 作業用ブランチを切る
必要に応じて自身が作業するためのブランチを作成します。

```
git branch [新しいブランチ名]
git checkout [新しいブランチ名]
```

以上です。
Laravelプロジェクトのpublicを削除したい。（ロリポップ にデプロイ）

# はじめに

Laravelプロジェクトをロリポップ にデプロイした際に、つまづいた点について、残そうと思います。
また、紹介しているブログを読んでいること前提ですので、話についていけないって思ったら、そっちも一緒に読んでみるといいかもしれないです。（前提の知識が多少あるかもしれないです。）

#つまづいた点

基本的に以下のURLの人の記事を参考にデプロイ作業していました。
https://qiita.com/yuzuha3ds/items/4c6b7d3f83e88b45d968

所々、上記のブログで省略されている部分があった気がしますが、些細なことだった気がするので、（忘れてしまったので:baby_tone1:）上記のブログ見てれば、ある程度、なんとかなると思います。

つまづいた点は、本題にもある通り、

ドメイン名/publicじゃないと接続できず、
URLにドメイン名を打っても、403エラーが表示されていました。

ちなみに、上記のブログでも403が表示されていましたが、私の場合、WAFの設定が原因ではありませんでした。後、おそらく、WAFは、セキュリティ面を考えると、有効のままの方が良い気がします。

#ざっくり、何をしたか（下で詳しく述べます）
https://gfonius.net/blog/laravel-url-public/
・これ通りに.htaccessを編集した。
→ドメイン名でアクセスしても500エラー（なんでや？）。
publicを加えると、404エラー（こちらは、想定内）。
・ドメイン直下にhtmlのファイルを置いて、ドメイン名自体が使えるか試す。
→ドメイン名をURLに打つと、ドメイン直下のhtmlが表示された。ドメイン名は使えることが分かる。原因は、Laravelプロジェクト側に問題がある？
ドメイン直下に.htaccessを配置し、public/index.phpを遷移するように設定することで解決。

#上記を踏まえて、やるべきことを述べます

① そもそも、ドメイン名が使えるか調べる。

ロリポップのサーバーにssh接続し、
~/web/ドメイン名の配下に

```
// ~/web/ドメイン名のディレクトリ内にindex.htmlファイルを作成する。
$ vim index.html
// 入力モード
:i
// 適当にhtmlタグを入れる。下の例は、適宜、変更してください。できてるか確かめてないので。
例）<h2>ドメイン名は表示されたよ！</h2>
Macの場合、escタブを押し、入力モード終了。
//　:wqで保存する＋閉じる（:qで閉じるだけ）
:wq
```

ドメイン名をURLに打って、先ほど、作成したhtmlファイルが表示されるかどうか確認。表示されれば、OK。

②　ドメイン名のフォルダに.htaccessを作成＋設定する。

**.htaccess作成**

```
cd ~/web/ドメイン名
// .htaccessを設置する。
vim .htaccess
```

**.htaccess設定する**

```
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} -d [OR]
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^ ^$1 [N]

    RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
    RewriteRule ^(.*)$ public/$1

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ public/index.php

</IfModule>
```

**~/web/ドメイン名**　配下に.htaccessを設置することで、**ドメイン名がURL打たれた時、public/index.phpに遷移することができる。**

**上の補足をすると、**
public内にも.htaccessはあるが、**ドメイン名/public**にアクセスしないと使えないので、**ドメイン名**にアクセスした時に、ドメイン名/publicに遷移させないといけない。


そして、念のために、public内の.htaccessについても載せておく。（デフォルトで同じものがあると思いますが）

```
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
```

これがないと、仮に、ドメイン名から、publicのindex.phpへ遷移したとしても、CSSが反映されない状態になる。
JSON文字列化

<h1> JSON.stringify()</h1>



<div id = "intro">
<p> <strong> JSONの一般的な目的は、Webサーバーとデータを交換することです。 </strong> </p>

<p> <strong> Webサーバーにデータを送信する場合、データは文字列である必要があります。 </strong> </p>

<p> <strong> <span class = "code_marked"> JSON.stringify()</span>を使用してJavaScriptオブジェクトを文字列に変換します。 </strong> </p>
</div>



<div>
<h2> JavaScriptオブジェクトを文字列化する</h2>

<p>このオブジェクトがJavaScriptにあると想像してください：</p>

<pre>var obj = { name:"Bill Gates", age:62, city:"Seattle"};
</pre>

<p> JavaScript関数<span class="code_marked">JSON.stringify()</span>を使用して文字列に変換してください。 </p>

<pre>var myJSON = JSON.stringify(obj);</pre>

<p>結果は、JSON表記に準拠した文字列になります。 </p>

<p> myJSONは現在文字列であり、サーバーに送信する準備ができています：</p>

<h3>例</h3>

<pre>var obj = { name:"Bill Gates", age:62, city:"Seattle"};
var myJSON =  JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;
</pre>
</div>



<div>
<h2> JavaScript配列を文字列化する</h2>

<p> JavaScript配列を文字列化することもできます：</p>

<p> JavaScriptにこの配列があると想像してください：</p>

<pre>var arr = [ "Bill Gates", "Steve Jobs", "Elon Musk" ];</pre>

<p> JavaScript関数<span class="code_marked">JSON.stringify()</span>を使用して文字列に変換してください。 </p>

<pre>var myJSON = JSON.stringify(arr);</pre>

<p>結果は、JSON表記に準拠した文字列になります。 </p>

<p> myJSONは現在文字列であり、サーバーに送信する準備ができています：</p>

<h3>例</h3>

<pre>var arr = [ "Bill Gates", "Steve Jobs", "Elon Musk" ];
var myJSON =  JSON.stringify(arr);
document.getElementById("demo").innerHTML = myJSON;
</pre>
</div>



<div>
<h2>例外</h2>

<h3>日付の文字列化</h3>

<p> JSONでは、日付オブジェクトは許可されていません。 <span class="code_marked">JSON.stringify()</span>関数は、任意の日付を文字列に変換します。 </p>

<h4>例</h4>

<pre>var obj =  { "name":"Bill Gates", "today":new Date(), "city":"Seattle"};
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;
</pre>

<p>文字列を受信側の日付オブジェクトに変換して戻すことができます。 </p>
</div>



<div>
<h2>関数の文字列化</h2>

<p> JSONでは、関数はオブジェクト値として許可されていません。 </p>

<p> <span class="code_marked">JSON.stringify()</span>関数は、キーや値など、JavaScriptオブジェクトからすべての関数を削除します。</p>

<h3>例</h3>

<pre>var obj =  { "name":"Bill Gates", "age":function () {return 62;}, "city":"Seattle"};
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;
</pre>

<p> <span class="code_marked">JSON.stringify()</span>関数を実行する前に関数を文字列に変換した場合は、省略できます。 </p>

<h3>例</h3>

<pre>var obj =  { "name":"Bill Gates", "age":function () {return 62;}, "city":"Seattle"};
<span class="marked">obj.age = obj.age.toString();</span>
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;
</pre>

<p> JSONで関数を使用することは避けてください。関数はスコープを失い、<span class = "code_marked"> eval()</span>を使用して関数に戻す必要があります。 </p>
</div>



<div>
<h2>ブラウザのサポート</h2>

<p>すべての主要なブラウザと最新のECMAScript（JavaScript）標準には、<span class = "code_marked"> JSON.stringify()</span>関数が含まれています。</p>

<p>以下の表の数字は、<span class = "code_marked"> JSON.stringify()</span>関数を完全にサポートする最初のブラウザバージョンを示しています。</p>

<table class = "dataintable browsersupport">
<tbody> <tr>
<td>Chrome</td>
<td>IE</td>
<td>Firefox</td>
<td>Safari</td>
<td>Opera</td>
</tr>

<tr>
<td>Yes</td>
<td> 8.0 </td>
<td> 3.5 </td>
<td> 4.0 </td>
<td> 10.0 </td>
</tr>
</tbody> </table>
</div>
「WP Offload Media Lite」で開発時と本番時でドメインが異なると挙動がおかしくなる

## WP Offload Media Liteとは
WordPressの画像やビデオ、ドキュメント類をAmazon S3にアップロードして、Amazon CloudFrontなどで配信させることができるWordpressのプラグイン

https://ja.wordpress.org/plugins/amazon-s3-and-cloudfront/

## 問題
ウェブサイトをリニューアルする際などに本番のドメインは使えないためサブドメインなどを作って、開発する要件があった。
開発環境のWordpressで画像つきの記事を登録し、本番環境に移行すると画像が表示されないという現象が起こった。

![スクリーンショット 2021-10-22 14.45.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542793/99f8d29e-b259-d6dd-ae03-35f151cc6138.png)


本来であれば、このプラグインを使用するとS3に画像がアップロードされ、画像のパスは下記のように出力されていてほしい

```
https://[s3 bucket名].s3.ap-northeast-1.amazonaws.com/wp-content/uploads/yyyy/mm/******/image.png
```

だが本番に移行すると

```
https://[開発環境のドメイン]/wp-content/uploads/yyyy/mm/******/image.png
```

となっていた。

## 原因
**「記事登録したときのドメイン」と「記事表示しているドメイン」を比較しているため**

下記はプラグインがドメインを比較しているところ。

```php:amazon-s3-and-cloudfront.php
	/**
	 * Ensure local URL is correct for multisite's non-primary subsites.
	 *
	 * @param string $url
	 *
	 * @return string
	 */
	public function maybe_fix_local_subsite_url( $url ) {
		$siteurl = trailingslashit( get_option( 'siteurl' ) );		

		if ( is_multisite() && ! $this->is_current_blog( get_current_blog_id() ) && 0 !== strpos( $url, $siteurl ) ) {
			// Replace original URL with subsite's current URL.
			$orig_siteurl = trailingslashit( apply_filters( 'as3cf_get_orig_siteurl', network_site_url() ) );
			$url          = str_replace( $orig_siteurl, $siteurl, $url );
		}

		return $url;
	}
```

DB登録されている画像のパスはS3ではなく、登録した際のドメインのパスで登録されていた。

このプラグインはDB登録のパス（記事本文に入っている画像のパス）と設定の「サイトアドレス」を比較しているらしく
一致しないとS3のパスに書き換えてくれないようです。
![スクリーンショット 2021-10-22 14.14.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542793/164cebcf-9b7c-ebf2-dfd3-c48eb800b372.png)


## 解決方法
本番移行時に手作業でドメインを書き換える方法なども考えることができたが
数が多い場合にはエクスポートするなどして、インポートする際に一括置換で書き換える方法をとった。

```php
$path = str_replace('http://[移行前のドメイン]/wp-content/uploads', 'https://[移行後のドメイン]/wp-content/uploads', $path);
```

SQLのdumpをとって、置換もいいかも。
HelloWorldと慣習(メソッド名とクラス名)

## はじめに
自分を含め、初学者に向けて書きます。



## 記事の構成
- JavaでHelloWorldの表示
- Javaにおけるクラスやメソッドの名付け慣習

## HelloWorld

```java 
class HelloWorld{
    public static void main(String[] args){
        System.out.println("HelloWorld");
    }
}
```

1. 以上のコードをファイル名「HelloWorld.java」として保存。
1. コマンドプロンプトを立ちあげ上記ファイルを保存したディレクトリに移動
1. コンパイル→javac ファイル名
    - ファイル名では拡張子(.java)も忘れずに
1. 実行→java ファイル名
    - ここでのファイル名はコンパイル後の.classのもので、拡張子はいらない

```
cd ディレクトリ名        //保存したディレクトリへ移動
javac HelloWorld.java  //コンパイル
java HelloWorld        //実行

#実行結果
HelloWorld
```

 


## クラスやメソッドの名付け慣習
Javaでは慣習として
クラス名：単語の先頭は大文字　ex, DateList
メソッド名：先頭文字は小文字  ex, dateList
Pythonを使ってDataFrameをAmazon S3に直接アップロードする

# はじめに

[Pythonを使ってAmazon S3にファイルをアップロードする](https://qiita.com/honda28/items/bf71c2b39e8ab109fda3)では、Python 用 AWS SDK である Boto3 を用いて Amazon S3 へのファイルアップロードを行った。この際、保存されているファイルのパスを指定していたが、ローカルにファイルを残したくない場合や準リアルタイムに結果を送りたい場合、ファイルを一度保存してそのパスを指定するのは望ましくない。本記事では、Python でよく用いられる DataFrame 形式のデータを CSV ファイルとして保存することなく一時ファイルのままで Amazon S3 へアップロードすることを試みた。[S3.Client.upload_fileobj](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.upload_fileobj) を参考にした。

# S3 へファイルオブジェクトをアップロード

以下コードでファイルオブジェクトを Amazon S3 へアップロードできる。Boto3 のインストールや AWS API キーの準備、Amazon S3 へのアクセスは [Pythonを使ってAmazon S3にファイルをアップロードする](https://qiita.com/honda28/items/bf71c2b39e8ab109fda3)を参照。

```python:upload_fileobj.py
import boto3
import tempfile

def upload_to_s3(fileobj, Bucket, Key):
    client = boto3.client('s3')

    with tempfile.NamedTemporaryFile() as tf:
        with open(tf.name, 'w+') as f:
            f.write(fileobj)
        client.upload_fileobj(tf, Bucket, Key)

df = pd.DataFrame({'name': ['Raphael', 'Donatello'],
                   'mask': ['red', 'purple'],
                   'weapon': ['sai', 'bo staff']})
fileobj = df.to_csv()
Bucket = 'my-bucket'
Key = 'result/result.csv'
upload_to_s3(file_obj, Bucket, Key)
```

# おわりに

DataFrame をファイルとして保存することなく Amazon S3 に送ることができた。以前書いた[FastAPI で作成した Web API にて、リクエストボディのデータを DataFrame に直接入れる](https://qiita.com/honda28/items/2aa04e1b4f689bd3287d)や[機械学習モデルの推論結果を返す Web API を FastAPI で作成](https://qiita.com/honda28/items/1cef6e3ac63077aa893e)と合わせることで、POST リクエストで受け取ったデータをそのまま DataFrame として読み込み、学習済みモデルで予測を行い、その予測結果である DataFrame を Amazon S3 へ送るといった一連の流れが構成できる。
Raspberry Pi 上で UART通信をする Python環境で プログラム

**はじめに**
Raspberry Pi4 上で UART通信を行う プログラムを Pythonで書いてみました。

環境は、Raspberry Pi4 に標準で搭載されている [Thonny Python IDE]

---
**準備**
シリアル通信を行うためのライブラリーを Raspberry Pi4 に入れる

~~~
>$ pip install pyserial
~~~


**簡単なプログラム**

~~~Py
import serial
import time

#File Open
File = open('response.txt', 'w')

#Open SerialDevice
SerDevice = serial.Serial('/dev/ttyS0', 115200, timeout=10)

#Set Command
#'GetVersion' という文字列のコマンドを出す
Command = "GetVersion\r"

#Send Command
SerDevice.write(Command.encode())


#******************************
#Recieve Response
while True:
    #Read data one Line (top->'\r\n')
    L_RecieveData=SerDevice.readline()
    RecieveData = L_RecieveData.decode()

    #Get Data Length
    DataLength = len(L_RecieveData)

    #If DataLength = 2, then Response END!!
　　#1行の文字列が2文字があることが受信データの終わりという条件にした
   if DataLength==2: break
    else:
        File.writelines(RecieveData)
        print(RecieveData)

#******************************
#Close Serial Device
SerDevice.close()
#File Close
File.close()
~~~

---
☆2021年10月21日(木) 午後2時45分 初版 (Ver1.00) 作成
☆2021年11月09日(火) 午後2時30分 初版 (Ver1.10) 作成 <簡単なプログラムの入れ替え>
macの画面でリモート接続先のJupyterを使いたい

# 概要
　macからsshを使って研究室サーバへリモート接続はできるけど、接続先のjupyterをmac側で表示させたい...！ NVIDIA GPU　使いたい...!と思い,調べて,やってみたことのメモです.
　参考資料そのままですが,改めて参照できるようにまとめてみました.

# 前提環境
 1. mac側のconda環境が整っている
 1. ssh接続先のアドレスやアカウント名がわかっている
 1. ubuntu側のjupyter環境が整っている

「1.mac側のconda環境が整っている」については,各自で調べるか,以前mac購入時に私が書いた,『[MacBook(m1)のpython環境構築メモ](https://qiita.com/KisaMM/items/2f57be7755b1b0edda64)』に簡単にメモしていますので参考までに.
それ以外の環境が整っていない場合もここでは扱いませんので調べてください.


# PCサーバ環境
#### 1. リモート接続(mac)側
 -macOS Big Sur
 -バージョン 11.6　(2021年10月)
 -MacBook Pro (13-inch, M1, 2020)
 -チップ　Apple M1
#### 2. リモート接続先(研究室サーバ/ubuntu)側
 -UbuntuOS 
 -バージョン 16.04.7 LTS
 -CPU Intel(R) Xeon(R) CPU × 2
 -GPU NVIDIA Corporation GP102 [TITAN Xp] × 4

#  接続方法
1． terminalを２つ（terminal①,terminal②）開いておく
2． terminal① conda環境に入る

```
conda activate <環境名>
```
3． terminal② sshでリモート接続先(研究室サーバ/ubuntu)にログインする(ローカルからの場合も同じ)

```
ssh <USERNAME>@<SERVER_ADDRESS>
```
4．　terminal②でjupyter notebookを起動する

```
jupyter notebook --no-browser --port=8080
```

--no-browser は jupyter notebook起動時にブラウザが起動してこないように.
--port=8080 は jupyter notebookのポート番号(ポート番号は8888でも9999でも9090でも空いていればいけます.)

5．　terminal① mac側ブラウザから, 起動したjupyter notebookにアクセスする

```
ssh -N -L 8080:localhost:8080 <USERNAME>@<SERVER_ADDRESS>
```
6．mac側のブラウザから localhost:8080 にアクセスする
![ブラウザからlocalhost:8080を入力した.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254218/63262899-19ba-fccc-cbc5-1398ff56b65a.png)

※ control+c でサーバシャットダウン


# 参考
参考１：　
『[機械学習をやるのにGPUベースでやりつつもmacOSの画面で作業はしたい](https://qiita.com/dropcontrol/items/c62ae19ee369ca3ee443)』
参考２ (参考１転載記事)：　
『[機械学習をやるのにGPUベースでやりつつもmacOSの画面で作業はしたい](https://note.com/dropcontrol/n/n73b3f73381e3)』
参考3 (conda環境):
『[MacBook(m1)のpython環境構築メモ](https://qiita.com/KisaMM/items/2f57be7755b1b0edda64)』
JSONオブジェクト

<H1> JSONオブジェクト </H1>
<div>

<h2>オブジェクト文法</h2>
<h3>例</h3>
<pre>{ "name":"Bill Gates", "age":62, "car":null }</pre>
<p><strong>JSONオブジェクトは、中括弧<span class="code_marked">{}</span>で囲まれています。</strong></p>
<p><strong>JSONオブジェクトは、キーと値のペアで記述されます。</strong></p>
<p><strong>キーは文字列キーは文字列ではなければなりません、値は有効なJSONデータ型（文字列、数値、オブジェクト、配列、ブール値、またはnull）ではなければなりません。</strong></p>
<p><strong>キーと値はコロンで区切られます。</strong></p>
<p><strong>キーと値の各ペアはコンマで区切られます。</strong></p>
</div>

<div>

<h2>オブジェクト値のアクセスについて</h2>

<p>ドット（<span class="code_marked">.</span>）を使用してオブジェクト値にアクセスできます。</p>

<h3>例</h3>

<pre>
myObj =  { "name":"Bill Gates", "age":62, "car":null };
x = myObj.name;
</pre>

<br><br>
角かっこ（<span class="code_marked">[]</span>）を使用して、オブジェクトの値にアクセスすることもできます。

<h3>例</h3>

<pre>
myObj =  { "name":"Bill Gates", "age":62, "car":null };
x = myObj["name"];
</pre>


</div>

<div>

<h2>オブジェクトをループする</h2>

<span class="code_marked">for-in</span>を使用して、オブジェクトのプロパティをループできます。

<h3>例</h3>

<pre>
myObj = {"name"："Bill Gates","age"：62,"car"：null};
for (x in myObj) {
   document.getElementById("demo").innerHTML + = x;
}
</pre>

<br><br>
for-inループでは、括弧を使用して属性値にアクセスします。

<h3>例</h3>

<pre>
myObj = {"name"："Bill Gates","age"：62,"car"：null};
for (x in myObj){
   document.getElementById("demo").innerHTML += <span class="marked">myObj[x]</span>;
}
</pre>


</div>

<div>

<h2>ネストされたJSONオブジェクト</h2>

JSONオブジェクトの値は、別のJSONオブジェクトを含むことができます。

<h3>例</h3>

<pre>
myObj = {
   "name"："Bill Gates",
   "age"：62,
   "cars"：{
       "car1"："Porsche",
       "car2"："BMW",
       "car3"："Volvo"
   }
}
</pre>

<br><br>
ドットと括弧を使用して、ネストされたJSONオブジェクトにアクセスできます。

<h3>例</h3>

<pre>
x = myObj.cars.car2;

<span class = "code_comment">//或いは：</span>

x = myObj.cars ["car2"];
</pre>


</div>

<div>

<h2>値の変更について</h2>

ドット表記を使用して、JSONオブジェクトの任意の値を変更できます。

<h3>例</h3>

<pre>myObj.cars.car3 = "Mercedes Benz";</pre>

<br><br>
括弧を使用して、JSONオブジェクトの値を変更することもできます。

<h3>例</h3>

<pre>myObj.cars["car3"] = "Mercedes Benz";</pre>


</div>

<div>

<h2>オブジェクト属性の削除について</h2>

<span class="code_marked">delete</span>を使用して、JSONオブジェクトの属性を削除します。

<h3>例</h3>

<pre>delete myObj.cars.car1;</pre>


</div>