OmniAICreator/Qiita-1.07M huggingface dataset:
Delta Lakeのテーブルプロトコルのバージョン管理

[Table versioning \| Databricks on AWS](https://docs.databricks.com/delta/versioning.html) [2022/2/1時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

Deltaテーブルのトランザクションログには、Delta Lakeのエボリューションをサポートするバージョン管理情報が含まれています。[Delta Lakeはreaderとwriterの最小バージョン](https://docs.databricks.com/delta/delta-utility.html#detail-schema)を別々にトラックします。

Delta Lakeは*後方互換性*を保証します。バージョンの新しいDatabricksランタイムは常に古いバージョンによって書き込まれたデータを読み込むことができます。

Delta Lakeは時に*後方互換性*を破壊します。古いバージョンのDatabricksランタイムでは新しいバージョンのDatabricksランタイムによって書き込まれたデータを読み取れなくなる場合があります。古すぎるバージョンのDatabricksランタイムでテーブルを読み書きしようとする際には、アップグレードすべきということを告げるエラーを受け取ることでしょう。

テーブルを作成する際、Delta Lakeはスキーマやテーブルプロパティのようなテーブル特性に基づき、要求する最低プロトコルバージョンを選択します。SQL設定によりデフォルトのプロトコルバージョンを設定することもできます。

- `spark.databricks.delta.properties.defaults.minWriterVersion = 2` (デフォルト)
- `spark.databricks.delta.properties.defaults.minReaderVersion = 1` (デフォルト)

テーブルが新しいバージョンのプロトコルをサポートするようにアップグレードするには、`DeltaTable.upgradeTableProtocol`メソッドを使用します。

```py:Python
from delta.tables import DeltaTable
delta = DeltaTable.forPath(spark, "path_to_table") # or DeltaTable.forName
delta.upgradeTableProtocol(1, 3) # upgrades to readerVersion=1, writerVersion=3
```

```scala:Scala
import io.delta.tables.DeltaTable
val delta = DeltaTable.forPath(spark, "path_to_table") // or DeltaTable.forName
delta.upgradeTableProtocol(1, 3) // upgrades to readerVersion=1, writerVersion=3
```

:::note warn
**重要！**
プロトコルのアップデートは不可逆であり、Delta Lakeの新機能を利用するなどで必要な場合には特定のテーブルのみをアップグレードすることをお勧めします。
:::

# プロトコルバージョンでサポートされる機能

| 機能 | `minWriterVersion` | `minReaderVersion` | 導入バージョン | ドキュメント |
|:--|:--|:--|:--|:--|
| 基本機能  |2   |1   |-   |[Delta Lake guide](https://docs.databricks.com/delta/index.html)|
|`CHECK`制約   |3   |1   | [Databricks Runtime 7\.4 \(未サポート\)](https://docs.databricks.com/release-notes/runtime/7.4.html)  |[CHECK constraint](https://docs.databricks.com/delta/delta-constraints.html#check-constraint)|
| チェンジデータフィード  | 4  | 1  | [Databricks Runtime 8\.4 \(未サポート\)](https://docs.databricks.com/release-notes/runtime/8.4.html)  |[Change data feed](https://docs.databricks.com/delta/delta-change-data-feed.html)|
| ジェネレーテッドカラム  | 4  | 2  | [Databricks Runtime 8\.3 \(未サポート\)](https://docs.databricks.com/release-notes/runtime/8.3.html)  |[ジェネレーテッドカラムを使う](https://qiita.com/taka_yayoi/items/47b58eb8696b278a3a82#%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%83%86%E3%83%83%E3%83%89%E3%82%AB%E3%83%A9%E3%83%A0%E3%81%AE%E4%BD%BF%E7%94%A8)|
| カラムマッピング  | 5  | 2  | [Databricks Runtime 10\.2](https://docs.databricks.com/release-notes/runtime/10.2.html)  |[Delta column mapping](https://docs.databricks.com/delta/delta-column-mapping.html)|

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
動画で得た再帰関数の知識をまとめる回

参考にした動画
https://youtu.be/vYquumk4nWw
英語の動画だけど、すごい聞き取りやすいし分かりやすいね
この動画の例ではフィボナッチ数列を使ってたから、フィボナッチ数列を求めるための再帰関数書いていくよー。
まずは簡単なやつ

```python:practice.py
def fib(n):
    if n == 1 or n == 2:
        result = 1
    else:
        result = fib(n-1) + fib(n-2)
    return result
```

例えばn=５の時はまず、n=3とn=4に分岐して、そこからn=3⇨(n=2,n=1)となっていって、n=4⇨((n=3⇨n=2,n=1),n=2)みたいにn=2かn=1まで分裂を繰り返していく、分裂が完全に完了したら分裂の数分、数が足されていって、最終的にn=5の値5が戻り値として戻ってくる。
しかし、毎回毎回一からやっていったら計算量がバカにならないので、初めてでた数字はリストに追加していくようにするともっと良くできる。

```python:practice.py
def fib(n, memo):
    if memo[n] != None:
        return memo[n]
    if n == 1 or n == 2:
        result = 1
    else:
        result = fib(n-1) + fib(n-2)
    memo[n] = result
    return result
```

今回は作らないけれど、本番では問題や状況にあったmemoリストを作ります。そして最初に既にその数字が求められていたのなら、その数字を返します。もし初めての数字ならば一個前のコードと同じ処理をしてnの数字を求め出してリストに格納していきます。上の動画によると計算量がO(2**n)からO(n)まで減るらしいので、memoを用意しておく効果は絶大です！
Pythonがプログラミング初学者に嬉しい理由

[Python、2021年のTIOBEプログラミング言語オブザイヤーを受賞：CodeZine（コードジン）](https://codezine.jp/article/detail/15438)
[index | TIOBE - The Software Quality Company](https://www.tiobe.com/tiobe-index/)
Python、相変わらず一番人気らしい。というポエムです。


## 教える方と教わる方のギャップ

ギャップがあると楽しくない、という話があります。

https://twitter.com/satoru_takeuchi/status/1172725333650366464?s=20&t=2KGjYIG96zWUN0L7QBvNcA

> プログラミング教育では
> 「まず手を動かしてみよう。これを打ち込んで！」
> 「(ｶﾀｶﾀ)」
> 「これをビルドして…」
>
> $ ./hello
Hello, world!
$ 
>
> 「ほら文字が出た、すごいよね！？」
> 「(だから何…？)」
> というのがよくある。

だからたとえそれがPythonだとしても「プログラミング」はクリエイティブでカッコイイ何某かがギューンとかバーンとか考えている人にとっては

```
root@0230359a1b81:~/opt# python hello.py
Hello World!
```

「...エッ？」みたいな。
ただそれだけのことに嬉しさはなかなかないですよねとも思う。

## 柔軟に考える

「教えられる側はプログラミングの初学者ですが、教える方も教える活動の初学者ですから、柔軟に考えるのがいいと思います。」と結城先生が仰っています。

https://mm.hyuki.net/n/n3d021931fbeb

> 一般論としては、「動くもの」を早めに提示する方がいいと思います。
> 
> どうしてそう思うかというと、現実的に「動くもの」があると楽しいし、自分は正しいことをやっているという安心感が得られるからです。いったん動くプログラムを提示してから、それを少しずつ変えて動きの変化を見てもらったり、ときには変えて動かなくなったりするのを見てもらうのがいいでしょう。
> 
> 動かなくなっても焦る必要はない。最後の変更を元に戻せば、また動く。ということを体感することは大事です。


## そこでPython

`pip install art`

```hello.py
import art

art.tprint("Hello World!")

art.tprint("What's up")

art.aprint("random") 

art.aprint("random") 

art.aprint("random") 

art.tprint("art",font="block",chr_ignore=True) 
```


```
root@0230359a1b81:~/opt# python hello.py
 _   _        _  _         __        __              _      _  _
| | | |  ___ | || |  ___   \ \      / /  ___   _ __ | |  __| || |
| |_| | / _ \| || | / _ \   \ \ /\ / /  / _ \ | '__|| | / _` || |
|  _  ||  __/| || || (_) |   \ V  V /  | (_) || |   | || (_| ||_|
|_| |_| \___||_||_| \___/     \_/\_/    \___/ |_|   |_| \__,_|(_)


__        __ _             _    _
\ \      / /| |__    __ _ | |_ ( ) ___   _   _  _ __
 \ \ /\ / / | '_ \  / _` || __||/ / __| | | | || '_ \
  \ V  V /  | | | || (_| || |_    \__ \ | |_| || |_) |
   \_/\_/   |_| |_| \__,_| \__|   |___/  \__,_|| .__/
                                               |_|

B-)
><((((>
{{{(>_<)}}}

 .----------------.  .----------------.  .----------------.
| .--------------. || .--------------. || .--------------. |
| |      __      | || |  _______     | || |  _________   | |
| |     /  \     | || | |_   __ \    | || | |  _   _  |  | |
| |    / /\ \    | || |   | |__) |   | || | |_/ | | \_|  | |
| |   / ____ \   | || |   |  __ /    | || |     | |      | |
| | _/ /    \ \_ | || |  _| |  \ \_  | || |    _| |_     | |
| ||____|  |____|| || | |____| |___| | || |   |_____|    | |
| |              | || |              | || |              | |
| '--------------' || '--------------' || '--------------' |
 '----------------'  '----------------'  '----------------'

```

... と、たったこれだけなんだがHello Worldもこのほうが少し嬉しいんだよなあ。
こういうライブラリが簡単に使えるPython、だから初学者に嬉しいところなのかもしれないなと感じた。

どこかで「バイオリンは弾けるようになるまでが難しすぎて挫折しちゃう」「ピアノはその点、押せば音が出る」という話を聞いたことがあるのでそれだよな等。

https://pypi.org/project/art/

社内にてプログラミング初歩をモブプロで楽しむ会が始まったのですが、 `art` とやらが出てきて、へええと思ったので書きました。以上です～
JSON Editor Onlineもいいけど、JSON Blobもあるよ ～ 解析用編集画面へJSONをアップするAPIを叩く関数をコピペ用に公開～ 

自動化・連携開発に触るのはもっぱらJSON。iPaaS以外での開発はもっぱらPythonなのですが、
# pprint限界っす
100件分とか、件数が肥大するとpprintじゃ無理。収まりきらないし、目視が限界。
もちろん件数絞るし、まあ.jsonとして保存してもいいのだけど、
- ビルドの過程のその場限りで見るだけ、使い捨てのものなので、一つのエンドポイント叩くごとにいちいちPath記述してファイル保存する気にならなかった。
- ファイル保存すると、ファイル増えすぎて邪魔。綺麗なフォルダ構成に整理するのもそのためにパス調整するのも面倒。
- postmanもあるけど、API叩くのはSDKの方が楽だよね。
- そもそもコードでのjsonの加工結果を見たい時だってある。

# JSONのオンラインエディターはJavaScript用
そんな時、JSON Editor OnlineでもJSON Blobでも、Python記述をテキストエディタで下記のような置換を施した上でコピペするというのを繰り返していた。
- None -> null
- True/False - true/false
- ' -> "

# そこでアップロードAPIのあるJSON Blob
元々どちらかというとUI的に好みで、[JSON Editor Online](https://jsoneditoronline.org/)ではなく[JSON Blob](https://jsonblob.com/)を使っていた(JSON Editor Online、前までど真ん中に広告がなかったっけ？あれが嫌だった。あと緑とオレンジって配色も好きじゃないっす)。
ある日、jsonblob.comを触っていてふと画面の隅っこに目をやると、何か**API**って書いてある！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1984110/4fff394b-44fb-824d-6fef-96b15c109106.png)
見ると、[APIを使ってJSONをアップできるんだとか](https://jsonblob.com/api)。
うわーこれ、今までやってたコピペを省略できんじゃん！
これは多用間違いなし！

# ということで早速、関数書いた。
```Python
import requests, webbrowser

def upload_to_jsonBlob(body):
     endpoint = "https://jsonblob.com/api/jsonBlob"
     headers_ = {"Content-Type": "application/json" ,"Accept": "application/json"} 
     response = requests.post(endpoint, json = body, headers = headers_) 
     json_file = response.headers["location"]
     doc_id = json_file.split("/")[-1]
     print(f"Json File :{json_file}\n編集画面 :https://jsonblob.com/{doc_id}")
     webbrowser.open(f"https://jsonblob.com/{doc_id}",new=2) #可能であれば新しいtabで開く

test = {"test":"test"}
upload_to_jsonBlob(test)
# Json File : http://jsonblob.com/api/jsonBlob/949773552949936128
# 編集画面 : https://jsonblob.com/949773552949936128
```
※保存期間は最終アクセスから30日間
# getもあるよ
```python
def get_from_jsonBlob(blobID):
    endpoint = "https://jsonblob.com/api/jsonBlob"
    headers_ = {"Content-Type": "application/json",
                "Accept": "application/json"}
    response = requests.get(endpoint+"/"+str(blobID), headers=headers_)
    return response.json()
```
UpしてOKだったjsonを再利用してテストをスピードアップ。

# ちなみに
[JSON Editor OnlineにもAPIある](http://api.jsoneditoronline.org/)ようなのだけど、

```python
from datetime import datetime as dt

def jsoneditoronline(body):
    endpoint = "http://api.jsoneditoronline.org/v1/docs/"
    headers_ = {"Content-Type": "application/json" ,"Accept": "application/json"} 
    data_ = {"name":dt.now().strftime("'%Y/%m/%d %H:%M:%S'"),"data":body}
    response = requests.put(endpoint, json = data_, headers = headers_)
    #もしくはPOST
    print(response.text)
    doc_id = response.json()["id"]
    print(f"https://jsoneditoronline.org/#left=cloud.{doc_id}")

test = {"test":"test"}
jsoneditoronline(test)
# {"ok":true,"id":"d23a0a0eab8c4a33a9ef7c7501fd4a8b"}
# https://jsoneditoronline.org/#left=cloud.d23a0a0eab8c4a33a9ef7c7501fd4a8b
```
名前を付けたファイルは作れても、Bodyは反映されなかった。ファイル作成できるだけなのかな？
TypeScript: Conditional Types [アウトプット全くしてこなかったのでアウトプットする007]

type-challengeをやっていてまた自分がこれまで目を背けてきたものがあったのでここでアウトプットします。

それは`Conditional Type`です。

ちなみに自分が全くわからなかったのが以下の問題です

https://www.typescriptlang.org/play?#code/PQKgUABBCMAsEFoIDECWAnAzgFwgewDMIBBddAQwE9JEE76aAjSkgO2wAs9WXkBXCAAoAAuXYE+ASggBiQLhKgLF9Z5MlRo0ZmiICuYwPKq6qIFlEwOhKAAwAqpwEkMgdeVAigyA15UBRDIEAGQLoMgOwZAAOZyPgdYZAW4ZARYZAMYZAYoYPQGj1K0AV+MBNBlM0LGwAHnMAPmtAfO1AUYjAdQZAPwY4wCAGAwhAaPlACQZABwYy03rsTBpsSgAHAFMIFXRoCABeCABtAHJyYYAaCGHGCamAY2GAXWa2zu6AJn6hgGZJ9cnoZagVjogOdvIAE16BpJwU7uh0iGBgCHaADw657HbLiGweAgjE6o2GJ065yum1uGHuG2er3eX3aPz+AKBIIg2xo9VMZWeAHFUNgABJ8RiAcwZAF0egFiouKAaIZAFj-HGw2FamAAXK9GnMOAA6ABWmH5eHQAHNgHBgILyGAQMAwErQBAAPrqjWajUQQDKDDrANYMgGaGQA-DIBJhisgAwowCmimqtXbVRAFcq3i1TndUuZkb9WJdMEIcOhUKxxRAAD4QVh8AC2IPQYaEgmkfWekZj7Tj4cjABss-G+D72gQg39JJJBotngNzIMAAzLV2dd1pL3tH1+sSUcuViCez7e30QADeECzrfFnE5EBrEAAvhAAPwR9oAN3TEEn1brSrAKvtdogIUAnQyACYZAI0MxsPtr32qdqCjrTFuGHAFEAI58chZybPlE-WcQAh0DwKMpmEBsED5T9R2DdpMGAPhsFQLNMHBMAGwgOZyEwWCtkGGgf2+VI3w-LMUibQZdggfYYArSZtnSdJxnw38iPfT8yLhVJBkTfpnmgdZKOHchJwDIMQxnWihCTPiBIYpioAI1FWJIjjkhSLtJlYFd0zk5jCJSYj2PI-NLkLYtLkkkyzK0y4GLAZZt13a9tUAQmsPEPEJAGGGPwr2cx1FVAGhnkAY8jABVvKxAEdFQBIc0ZFk2Q5blgF5AVhVFCUpVgYAxEwAB3dMZTlKAQvCwBoyOZVl2S5HlMD5IURTFSVpUwPAswQ1BuCaIqIE8QA1uQ8QAmqMAGQy4sqxLkrqtLJVleVFTAIA


問題は

> 配列Tを受け取り、その最初のプロパティの型を返すFirst<T>を実装します。

というもの


```ts
[3, 2, 1],
[() => 123, { a: string }],
[],
[undefined],
```

上記がテストとして渡されて型に0番目の値が渡ってくれば合格というものでした。

自分は迷いに迷って以下のようになりましたが、nullとundefinedのテストがエラーになりました。

```ts
type First<T extends (string | number | (() => number | null | undefined))[]> = T[0]
```

答えは以下です。

```ts
type First<T extends any[]> = T extends { length: 0 } ? never : T[0]
```

`T extends { length: 0 } ? never : T[0]`

これがconditional typeと呼ばれるものです。

> Conditional Typesは読んで字の如く、型定義における条件分岐です。次の構文で表現します。

```ts
type MyCondition<T, U, X, Y> = T extends U ? X : Y;
```

観察
1. 三項演算子が使われています。
`extends`を知っていればいけそうです。

https://qiita.com/cawauchi/items/0fea0540e3d47d64b9fb

2. ジェネリクスに4種類の型T,U,X,Yが渡されています。

これを読み解くと
T型がUに内包されていれば、`X`型を使用
そうでなければ`Y`型を使用
ということになります。

自分がわからなかった問題の答えを見てみます。

```ts
type First<T extends any[]> = T extends { length: 0 } ? never : T[0]
```

まず左辺には`any`[]として配列であればなんでも渡せるというかなり緩めの`制約`がついています。
次に右辺には渡された型Tのlengthが0であれば`never`型を返し、そうでなければ型の一番最初のものを返すとしています。

ここで　`{length: 0}`はどこからきたのか疑問が湧きました。

これについてはざっと調べたのですが、TypeScriptでの情報をうまく集めることができなかったので見つけたら記事化します。

参考

https://qiita.com/Quramy/items/b45711789605ef9f96de

強くなりたい!!!!!!!
Json形式のファイルをApexで処理する


個人的にはClassを定義して一発で変換する方法が好きですが、１つずつ変換する方法での質問に答えました。

このファイルを変換します。

```
{
    "d": {
        "results": [
            {
                "__metadata": {                    
                    "uri": "https://itsm-webservice.com:5000/CMDS/GetMaterial?id=80016757&Srnum=26090"
                },
                "ItemNumber": "0003",
                "Sernr": "359117093739281G",
                "Batch": "7500038949",
                "Documentyear": "2019",
                "Qty": "1.000",
                "Ittagno": "359117093739281",
                "Pempno": "84236527"
            }
        ]
    }
}
```

質問者さんのコード

```
Map<String, Object> mapResponseData = (Map<String, Object>)Json.deserializeUntyped(res.getBody());
Map<String, Object> dataToBePassed = (Map<String, Object>)mapResponseData.get('d');
system.debug('dataToBePassed::'+dataToBePassed);
String Sernr = String.valueOf(dataToBePassed.get('Sernr'));
String Batch = String.valueOf(dataToBePassed.get('Batch'));
String Ittagno = String.valueOf(dataToBePassed.get('Ittagno'));
system.debug('Sernr::'+Sernr);
system.debug('Batch::'+Batch);
system.debug('Ittagno::'+Ittagno);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fb6f7cc8-4ae0-efbb-faab-9b1897d60d6e.png)

Sernr、Batch、Ittagnoに値がないようです。
よくJsonのデータを見ると、resultsの構成を変換してないように思います。まずはresultsを読みましょう。

私のコードは以下です。


```
Map<String, Object> mapResponseData = (Map<String, Object>)Json.deserializeUntyped(res.getBody());
system.debug('mapResponseData::' + mapResponseData);
       
Map<String, Object> dataToBePassed = (Map<String, Object>)mapResponseData.get('d');        
system.debug('dataToBePassed::'+dataToBePassed);
        
List<Object> dataToResults = (List<Object>)dataToBePassed.get('results');  
system.debug('dataToResults::'+dataToResults);
        
String Sernr = (String)((Map<String, Object>)dataToResults[0]).get('Sernr');
system.debug('Sernr::'+Sernr);
String Batch = (String)((Map<String, Object>)dataToResults[0]).get('Batch');
system.debug('Batch::'+Batch);
String Ittagno = (String)((Map<String, Object>)dataToResults[0]).get('Ittagno');  
system.debug('Ittagno::'+Ittagno);
```

ポイントはresultsは各フィールドが存在するList型の変数になるということです。
また、そのList変数の各値を読むためには無理やり(Map<String, Object>)にキャストします。
これで読めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/01f77421-e2b6-934e-732e-5075a03c9369.png)

[Salesforce external Web Service Issue](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FY9EASA1)
Systemクラスのクラス変数について

Systemクラスのクラス変数について

〜JavaAPIを読んで見るシリーズ〜　個人メモ用
以外に奥が深かったよSystem.out.printlnの巻


Systemクラスにて宣言されているクラス変数について、色々わからなかったので調べてみました。
```java:System.java
public final static InputStream in = null;
public final static PrintStream out = null;
public final static PrintStream err = null;
```

【疑問点1】
・System.out.println　の変数 out には null が入っているはずなのに
　なぜprintlnメソッドを呼び出せるのか
・変数outはfinal修飾子であり、nullで初期化しているのであとから変数を
　代入することは不可能なはず?

■final修飾子にあとから値を代入する例
```java:TEST1_final.java
public class TEST1_final {
    public final static String value1 = null;

    public static void main(String[] args) {
        value1 = "aaa";
        System.out.println(value1);
        }
}
```

■実行結果
```console:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	final フィールド TEST1_final.value1 には代入できません

	at javaAPI_練習用/TEST1.TEST1_final.main(TEST1_final.java:6)
```
やはりエラーでした。

というか、System.inとかSystem.outを出力したら変数の中身ある…
```java
public class TEST1 {
    public static void main(String[] args) {
        System.out.println(System.in);
        System.out.println(System.out);
        System.out.println(System.err);
    }
}
```

■実行結果
```java
java.io.BufferedInputStream@448139f0
java.io.PrintStream@7cca494b
java.io.PrintStream@7ba4f24f
```
いつ誰が代入したの…



【調べた結果まとめ】
同Systemクラス内にinitializeSystemClassというメソッドがあります。
このメソッド内にて値を設定しています。
ちなみに、このメソッドはJVM初期化時に動いているらしいです。
```java:System.java
    private static void initializeSystemClass() {
        
        …(省略)
        
        setIn0(new BufferedInputStream(fdIn));
        setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
        setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
```
■定義元（同Systemクラス内）
```java:
    private static native void setIn0(InputStream in);
    private static native void setOut0(PrintStream out);
    private static native void setErr0(PrintStream err);
（native修飾子がついているので、このメソッドは別言語で実装されていて、そこで値を設定している。）
```

【疑問への回答】
・Systemクラスの各final変数は同クラス内のinitializeSystemClassメソッドを使って値を代入している。
・低レイヤーな他言語（多分Cとか）で代入している。
・initializeSystemClassはJVMの初期化辺りのタイミングで呼ばれる。
※呼ばれるタイミングについては理解がまだ曖昧です。。調べるの時間かかりそうなので後回し

以上

【参考】
https://stackoverflow.com/questions/19173965/why-are-the-printstream-out-and-inputstream-in-null
https://ytetsuwo.hatenadiary.org/entry/20110816
MacでUbuntuのインストールUSBを作成する


#目次
[1. やりたいこと](#1-やりたいこと)
[2. 用意するもの](#2-用意するもの)
[3. 作成手順](#3-作成手順)

# 1. やりたいこと
MacのターミナルでUSBフラッシュメモリにUbuntuのisoイメージファイルをコピーしてインストールUSBを作成する

# 2. 用意するもの
macOS Big Sur 11.6.3
コピーしたい [Ubuntuのisoイメージファイル](https://jp.ubuntu.com/)
isoイメージファイルより容量のあるUSBフラッシュメモリ


# 3. 作成手順
1.USBフラッシュメモリをMacのUSBポートに挿して`diskutil list`コマンドで対象のドライブを確認

```
$ diskutil list
/dev/disk0 (internal):

   略

/dev/disk1 (synthesized):

   略

/dev/disk2 (external, physical):
   #:               TYPE NAME         SIZE     　IDENTIFIER
   0:               NO NAME           *8.1 GB   　disk2
```
　
2.今回作業を行うのUSBフラッシュメモリは /dev/disk2(externalとphysical) なので、これを初期化
```
$ diskutil eraseDisk MS-DOS MYDISK /dev/disk2

Started erase on disk2 NO NAME

   略

Finished erase on disk2

```
　

3.`Finished erase on disk2`が表示され初期化に成功したらマウントを解除

```
$ diskutil unmountDisk /dev/disk2
Unmount of all volumes on disk2 was successful
```
　
4.ddコマンドでUSBフラッシュメモリにisoイメージファイルをコピー

```
sudo dd if=./ubuntu-20.04.2.0-desktop-amd64.iso of=/dev/disk2 bs=1m
```
　
5.コピーが完了したら取り出す

::: note alert
コピーが終わる前にUSBフラッシュメモリを抜くと破損の原因になります
:::


```
$ diskutil eject /dev/disk2
```
　
6.再度`diskutil list`コマンドで対象のドライブが取り外されていることを確認して完了

```
$ diskutil list
/dev/disk0 (internal):

   略

/dev/disk1 (synthesized):
```
DockerコンテナをLaravel sailコンテナを再ビルドしようとしたらビルドできなくなった

# 経緯
* MySQLに日本語入力ができないため、Dockerfileを書き換えて再ビルドしようとした
* Unable to locate package php8.1-cli となり、MySQLを日本語化するための行を削除しても治らない。
* それからDockerのキャッシュ削除、イメージ削除、アンインストールを試しても治らず、環境構築をgit cloneからやり直す。
* それでもエラーが解決せず、sailのissueを発見(https://github.com/laravel/sail/issues/)
    書いてあることを実行して解決
* リンク内に「vendorディレクトリ内のファイルは絶対に編集しないでください。」と記載されていたため、↓の手順を実行し、解決済み

# 手順
```bash
# docker/{ubuntuVer}/Dockerfileを現在のディレクトリに作成
# docker-compose.ymlの context: /vendor/laravel/sail/runtimes/8.0/Dockerfile を context: ./docker/8.0に変更する
php artisan sail:publish 
```
```diff:docker-compose.yml
- context: ./docker/8.0
+ context: ./docker/8.1
```

```diff:docker/8.1/Dockerfile
- FROM ubuntu:21.04
+ FROM ubuntu:21.10
```

```diff:docker/8.1/Dockerfile
- && echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu hirsute main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
+ && echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu impish main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
```

```diff:.env
+ WWWGROUP=1000
+ WWWUSER=1000
```

```bash
docker-compose build --no-cache
```
カメラプロジェクションアドオン

カメラの「下絵」で設定した画像の設定を元に
カメラマップ投影をするノードを作成するアドオンの解説です。
Gumroadで公開しています。
https://yukimituki11.gumroad.com/l/tdscvy

![220221.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/190d8672-440c-e063-8bda-de67c983fd70.gif)
カメラから見た状態で画像を張り付けたようなマテリアルを作成できます。

カメラの**透視投影**と**平行投影**の設定に対応しています。

# 下絵の設定
まずは下絵機能について説明しておきます。

Blenderはカメラオブジェクトのカメラビュー表示で画像を重ねて表示できる下絵機能があります
カメラオブジェクトを選択してオブジェクトデータプロパティの「下絵」のチェックボックスをオンにして
「画像を追加」のボタンで追加できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/4a19a70a-ef8c-d773-81fc-1933eea5c41b.png)
**不透明度**は画像表示の透明具合
**深度**は下絵画像を３Dビュー上にあるオブジェクトの手前に表示するか奥に表示するかの設定です
これらは画像の位置合わせで場合によって変更するものですので　アドオンでは利用しません

**フレーム方式**はカメラのフレームに対して画像をどういう範囲で重ね合わせるかの設定です。
カメラの縦横比はレンダリング解像度で決まっています。
**ストレッチ**はカメラの4隅に画像を合わせます　レンダリングと下絵の縦横比が異なると画像歪むことになります
**フィット**は画像の縦横比を保ったまま画像を全部収めます　比率が違う場合には画面に隙間が空きます
**トリム**は画像の縦横比を保って画面内を全て埋めるようにします　比率が違う場合は はみ出す部分が出ます

カメラマップ用に設定する場合にはトリムの設定が扱いやすいようです

**オフセット**はカメラに対して画像の位置をずらす設定で、フレームの幅を1.0とした割合です
**スケール**は画像の拡大縮小です

回転で画像の回転を指定できますが、アドオンでは対応していません。

下絵はカメラオブジェクト個々に設定できるので
ローカルビューの指定等でカメラを切り替えることで別の方向からの画像も指定して調整できます
また、下絵もカメラに対して複数指定できるので　違った画像や設定を指定することもできます

# アドオンの基本操作
アドオンのパネルはシェーダーエディタ上のサイドバーのノードタブに表示されます

カメラのプルダウンで投影に利用したいカメラを選択します
指定したカメラに下絵が設定されていない場合には「下絵」以下の項目は表示されません
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/a1a79ddc-e9eb-df91-492e-53f8095e2356.png)
下絵の設定されたカメラを指定した後　下絵のプルダウンから利用したい画像を指定して
**Make CameraProjection Nodes**のボタンを押すと
[カメラ名]_[画像名]_Projection といった名前でノードグループが作成されます

シェーダーエディタでマテリアルを表示している場合には　マテリアルに作成したノードグループを追加します
マテリアルを表示していなかった場合や　別のマテリアルで利用したい場合には
**追加**メニューのグループの項目から選択します。

# ノードの使い方
作成したノードの**カラー**の出力をシェーダーのカラー入力に繋ぐことで
下絵で指定した通りにカメラから画像を投影した状態になります。

下絵にアルファで透過した画像を利用していた場合には
カラーの入力で指定した色や画像と合成した色が出力されます

また、カメラと投影した面との角度が　**制限角度**で指定したよりも大きい場合にカラー入力の値を使う機能もあります
**ぼかし**の設定で角度制限の境目をグラデーションにするように設定できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/06e1c18c-9cb7-452f-8487-9a415babbfd8.png)
キャプチャではカメラからの角度が60度以上の部分にはレンガテクスチャが表示されるようにしてみました

90度に設定すると投影したオブジェクトのカメラから見た裏側に投影しないようになります


ノードの出力の**UV**は画像をカメラプロジェクションするための情報をそのまま出力しています
同じ設定で別の画像を投影するのに使用できます。
**内積**は角度制限の項目で使っているデータでカメラと面との角度のデータを出力しています

# 使用例
私はこのアドオンでは
・テクスチャを投影しながらモデリング
・面の方向に応じて複数のテクスチャを合成
・レンダリングした画像を元に部分的にレタッチ
といったことに利用しています。
最終的にデータをエクスポートする場合にはベイク操作が必要ですが、
レンダリングまでBlender内で済ませる場合には　使い方によってはUV展開せずに作業を進めることが可能となっています。
何かの一助になれば幸いです。
AWS Hands-on for Beginners　Network編#3

## はじめに
AWS Certified SysOps Administrator - Associateの試験ラボを乗り切るために、勉強していることをなんとなくメモっていきます。
基本的なハンズオンの内容は説明せずに出てきた単語を少し深掘りしていきます。

行うこと
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/
Network編#3 クライアントVPNをつかって、リモート接続環境を構築しよう
本人情報
IT現場雑用員（SEで採用されながら一生Excel触ってる人）
半年前にAWS SAA取得済み

<br>


## 全体の流れ
![Network編3.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512706/25aba94f-f6a9-288a-02ef-bfd0f3d6863e.png)
自宅、あるいは外出先からVPN接続を通ってクライアントエンドポイントに接続を行い、ACM証明書を使って送信元の証明を行います。その後ENIを経由してEC2に接続を行います。ENIは送信元のIPアドレスを変換することになるため、SNATとして働いていると言えます。
手順は
VPC,EC2の作成 → ログの出力先　→ 証明書の作成　→ VPNエンドポイント　→ VPN接続とログの確認の順に行います。

### AWS Client VPNとは
どこからでも安全な形でAWSのリソースにアクセスできるマネージドVPNサービスです。OpenVPNというサーバー間に暗号化されたトンネルを作るオープンソースのソフトウェアがベースになっています。マネージド型サービス、高可用性、高伸縮性といったAWSとしてのサービスのメリットが多く含まれています。

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/what-is.html

<br>

## ACM証明書管理
クライアントがクライアントVPNへの接続が許可されているのかを確かめるために使用します（クライアント認証）。クライアントVPNでは３種類のクライアント認証を利用できますが、今回はハンズオンに沿って相互認証を利用します。相互認証では、サーバー、クライアントの秘密鍵と認証局に署名された公開鍵を含む証明書をそれぞれ作成します。クライアントVPNエンドポイント、クライアントに登録することによって通信元の確認を行います。

<br>

~~~
新しい認証局 (CA) を構築するには、このコマンドを実行し、プロンプトに従います。
./easyrsa build-ca nopass
~~~
公開されている中間認証局を使用せずに、自分で認証局を作成して証明書を発行することもできます。自分で作成した認証局で証明書を作成することをオレオレ証明書と呼び、一般的にはあまり推奨されていません。しかし今回のような正しい証明書クライアント側に登録されたことがしっかりと確認できる場合は、それ以降の通信を保証する役割を十分に果たせるため利用されます。会社内での少ない端末を利用する際にも同じことが言えるかと思います。

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/client-authentication.html

<br>

## 疎通確認
### AWS VPN Clientの確認
![スクリーンショット 2022-03-06 0.16.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512706/1fbff6b9-6e16-22da-6f68-3eb957b28485.png)




### CloudWatch logsの確認
~~~
{
    "connection-log-type": "connection-attempt",
    "connection-attempt-status": "successful",
    "connection-attempt-failure-reason": "NA",
    "connection-id": "cvpn-connection-00cf634d0baa04624",
    "client-vpn-endpoint-id": "cvpn-endpoint-0f2a98254f14829db",
    "transport-protocol": "udp",
    "connection-start-time": "2022-03-05 15:13:21",
    "connection-last-update-time": "2022-03-05 15:13:21",
    "client-ip": "100.64.0.2",
    "common-name": "client1.domain.tld",
    "device-type": "mac",
    "port": "43818",
    "ingress-bytes": "0",
    "egress-bytes": "0",
    "ingress-packets": "0",
    "egress-packets": "0",
    "connection-end-time": "NA",
    "connection-duration-seconds": "0"
}
~~~


無事疎通を確認することができました。


### 補足
ハンズオン内ではsubnet255のENIについて深く説明がありませんでしたが、疎通確認まで行った段階で２つのENIが作成されていることを確認しました。これはクライアントVPNエンドポイントとsubnet255を関連付けた時とsubnet１内の EC2インスタンスに接続される時でそれぞれ使用されるものです。インスタンスのENIとは違い、サブネットのENIは自動的に作成されます。

![スクリーンショット 2022-03-06 1.58.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512706/727b2a5a-0f7d-d5d7-8850-8102416d787b.png)
github slack 連携の個人的メモ

## ポイント

`/github subscribe owner/repository`

の

`owner/repository`

これは
githubのこの部分になる

![スクリーンショット 2022-03-06 2.01.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118047/609bfc42-7713-909c-077e-3d9c69370366.png)


よって入力はこうなる↓

`/github subscribe test/web-homepage`

その後に

`/github subscribe test/web-homepage reviews,comments,branches,commits:*`


このように設定すると

通知が届くようになりました！


## 個人的メモ

`/github subscribe owner/repository`

と書いてるとよくわからなかったので、

個人的メモとして



## 参考記事（拝見させていただいております🙇‍♂️）
https://qiita.com/unsoluble_sugar/items/e42ac352400598a24915

https://ponsuke-tarou.hatenablog.com/entry/2021/06/01/212827#Either-the-app-isnt-installed-on-your-repository-or-the-repository-does-not-exist-Install-it-to-proceed
シンプルな縦グラデーションカラーのSkyboxシェーダ

![スクリーンショット 2022-03-06 013652.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/b7576eca-13f7-b1e2-fb19-f6de0f342cd4.png)
ふと「光源位置やら、大域照明やら、そんな事どうでも良いから、指定した色を線形にグラデーションしてくれるようなSkyboxが欲しい！」と思ったので作ってみました。

# シェーダ

という事でシェーダコードです。
```hlsl:GradationSkybox.shader
Shader "ScreenPocket/Skybox/Gradation"
{
    Properties
    {
        _TopColor ("Top", Color) = (1, 0, 0, 1)
        _MiddleColor ("Middle", Color) = (0, 1, 0, 1)
        _BottomColor ("Bottom", Color) = (0, 0, 1, 1)
        _Length ("Length", Float) = 1
    }

    SubShader
    {
        Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
        Cull Off ZWrite Off

        Pass {

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            uniform half3 _TopColor;
            uniform half3 _MiddleColor;
            uniform half3 _BottomColor;
            uniform half _Length;

            struct appdata_t
            {
                float4 vertex : POSITION;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4  pos            : SV_POSITION;
                float3  color          : TEXCOORD0;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            v2f vert (appdata_t v)
            {
                v2f OUT;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
                
                OUT.pos = UnityObjectToClipPos(v.vertex);
                OUT.color = lerp(lerp(_MiddleColor,_TopColor,saturate(v.vertex.y/_Length)),_BottomColor, saturate((-v.vertex.y)/_Length));
                return OUT;
            }
            
            half4 frag (v2f IN) : SV_Target
            {
                return half4(IN.color,1);
            }
            ENDCG
        }
    }
Fallback Off
}

```
ポイントは下記

* MVP変換前のv.vertex.yは-1～0～1の球になっているので、その座標位置をそのまま使って線形補間(lerp())しました。
* Topが天球の一番上、Middleが水平線、Bottomが天球の一番下の色となります。
* 色の補間はFragmentシェーダでやろうかと思いましたが、頂点シェーダで行っても十分滑らかだったので、負荷を抑えるために頂点シェーダ側で行いました。
* グラデーションの具合をある程度調整したいので、Lengthの値でグラデ幅を調整できるようにしています

# 使い方

1. 適当にシェーダを作る
1. 上記のコードをコピペ
1. 適当なマテリアルを作って、ScreenPocket/Skybox/Gradation シェーダを設定
1. Top、Middle、Bottomの色を確定し、Lengthでグラデーション幅を決める
1. Window/Rendering/LightingでLightingパネルを開き、Environmentタブを選択し、Skybox Materialに作ったマテリアルを設定する
1. カメラのInspectorからEnvironment/Background TypeをSkyboxにする

で確認できるかと思います。

ちゃんと上を見ると赤に
![スクリーンショット 2022-03-06 020124.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/4cd3c999-dbf3-08e7-bf52-eefc3cf60a04.png)
下を見ると青になっています
![スクリーンショット 2022-03-06 020156.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/c615de25-a763-0ae7-5cae-b95176346da7.png)


# 終わりに

厳密なSkyboxは必要ないけど、単色で塗りつぶすのは面白くないなぁ…という時や、水中の表現に使えるかと思います。
カーブを線形以外に対応したり、Gradientで自由な色テーブルに対応出来たりすると汎用性が上がりそうですね。

↓水中の一例
![スクリーンショット 2022-03-06 020851.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/71aca975-0046-2a91-8508-b5c47ceaf108.png)
【React】React Slickでスライダーを実装する際にロジックで画像指定を行う

## 概要
React Slickは、この[ドキュメント](https://react-slick.neostack.com/)のページにある通り、画像をスライダー形式で表示が行えるライブラリです。ユーザがポインターを選択すると、その画像が表示されます。
今回は、画像の指定をロジックで行うにはどうすればよいかというのをメモ書きします。

## 対応
[こちら](https://react-slick.neostack.com/docs/example/slick-go-to/)のドキュメントページにて記載されている、`slickGoTo`メソッドを使用すれば実現できます。`slickGoTo`を使用するには、sliderのオブジェクトを取得する必要があり、sliderのオブジェクトからメソッドを呼び出す形になります。

## 実装サンプル
ドキュメントではClass Componentで`this`を用いてましたが、Functional Componentでsliderオブジェクトを一度sliderメソッドに入れる実装を記載します。

```react
import React, { useState } from "react";
import { Button } from "react-bootstrap";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";

export default function CoordinatePostImageRegisterComponent(prop) {
  const [displayImages, setDisplayImages] = useState(prop.images);
  const [imageSlider, setImageSlider] = useState(undefined);
  // サンプルで最終画像に移動するメソッド
  function setSelectLastImage() {
    imageSlider.slickGoTo(displayImages.length - 1);
  }

  return (
    <>
      <div>
        <Button
          onClick={() => {
            setSelectLastImage();
          }}
        >
          最終画像へ移動
        </Button>
      </div>
　　　　　　　　　　　{/* refからstateにセット */}
      <Slider ref={(slider) => setImageSlider(slider)} {...slideSettings}>
        {displayImages.map((i) => (
          <div>
            <img id={i.key} src={i.url} />
          </div>
        ))}
      </Slider>
    </>
  );
}
```
Java Silverに出題されるダウンキャストについて整理してみた

以前にJava Silverの資格の勉強をしていた時に、ダウンキャストに関する問題で苦労した記憶があったので、理解を深める意味も込めて要点を整理してみます。

## ダウンキャストとは
ダウンキャストとは、あるインスタンスや変数の型を継承関係にある子クラスの型に変更する処理になります。その名の通り親から子へと下がる（ダウン）型の変更（キャスト）をしているわけですが、型の変更をするだけでインスタンスの実体には変化がない点がポイントになります。

したがって、どのような場合でもこのダウンキャストに成功する訳ではなく、問題ないケース、実行時例外が発生するケース、コンパイルエラーが発生するケースの3パターンがあり、どのパターンに当てはまるかについて試験で狙われることも多いのでそれぞれ整理していきます。　

## 問題ないケース
```Java
Object o = new Integer(1);
Integer i = (Integer) o;
```

1行目では、IntegerクラスのインスタンスをObjectクラス型の変数に代入しています。
＊Objectクラスは全クラスに共通する最上位のスーパークラス

ここでは子クラスのインスタンスを親クラスの型に変更しているのでダウンキャストの反対でアップキャストと呼ばれており、アップキャストの場合は親クラスへの型に代入していればキャスト後の型を明示的な指定は不要になります。

（あえて明示的に指定するとしたら以下のように書くことができます。）
```Java
Object test = (Object) new Integer(1);
```

次に2行目では、Object型の変数をInteger型にダウンキャストして、Integer型の変数に代入しています。ダウンキャストの場合はキャスト後の型を明示的に指定する必要があり、```(Integer)```の箇所で指定しています。

さて、Java Silverの試験では主に冒頭でお話しした３つのパターンのどれに当てはまるかが問われますが、以下の2つの観点から調べることで求めることができます。


```
①変更前の型のクラス > 変更後の型のクラス である
②変更前のインスタンスの元クラス = 変更後の型のクラス 
　または
　変更後の型のクラス > 変更前のインスタンスの元クラス
*ここでは親子関係を 親クラス　> 子クラス と示しています

1. 2つも当てはまる.. 問題なし
2. ①のみ当てはまる... 実行時例外が発生
3. その他... コンパイルエラーが発生
```

今回の例では、以下のように2つとも当てはまるため、コンパイルエラーも実行時例外も発生せず問題なしとなります。

### ①変更前の型のクラス(Object) > 変更後の型のクラス(Integer) 
1行目では、Object型の変数に代入しており、2行目でInteger型にダウンキャストしています。

... IntegerクラスはObjectクラスを継承しており親子関係である
... 当てはまる

### ②変更前のインスタンスの元クラス(Integer) = 変更後の型のクラス(Integer)
1行目では、Integerクラスのインスタンスをアップキャストして変数に代入し、2行目でInteger型にダウンキャストしています。

... Integerクラス = Integerクラスで一致している 
... 当てはまる


## 実行時例外が発生するケース
実行時例外が発生するケースは①は当てはまるものの②に当てはまらないケースで、例としては以下のようなコードが挙げられます。

```Java
Object o = new Integer(1);
String s = (String) o;
```

変更点としては、2行目のキャスト後の型がString型になっている点になります。

### ①変更前の型のクラス(Object) > 変更後の型のクラス(String)
1行目では、Object型の変数に代入しており、2行目でString型にダウンキャストしています。

... StringクラスはObjectクラスを継承しており親子関係である
... 当てはまる

### ②変更前のインスタンスの元クラス(Integer) != 変更後の型のクラス(String)
1行目では、Integerクラスのインスタンスをアップキャストして変数に代入し、2行目でString型にダウンキャストしています。

ダウンキャストは型を変えるだけでインスタンス自体は変わらず、Integerクラスのインスタンスの型Integerの親クラスではないString型にすることはできず、実行時に```ClassCastException```がスローされます。

... IntegerクラスとStringクラスは一致せず、StringクラスはIntegerクラスの親クラスでもない
... 当てはまらない


## コンパイルエラーが発生するケース
最後に、その他の場合はコンパイルエラーが発生するケースとなり、例としては以下のようなコードが挙げられます。

```Java
Integer i = new Integer(1);
String s = (String) i;
```
変更点としては、1行目でアップキャストせずIntger型のインスタンスをそのままInteger型の変数に代入している点になります。

### ①変更前の型（Integer) != 変更後の型(String)
1行目では、IntegerクラスのインスタンスをInteger型の変数に代入し、2行目でString型にダウンキャストしています。

... IntegerクラスはとStringクラスは親子関係ではない
... 当てはまらない

実際には①に当てはまらない時点でコンパイルエラーとなりますが、
以下のように2にも当てはまらないことを確認できます。

### ②変更前のインスタンス（Integer) != 変更後の型(String)
... IntegerクラスとStringクラスは一致せず親子関係ではない
... 当てはまらない


## まとめ
・ダウンキャストはあるインスタンスや変数の型を継承関係にある子クラスの型に変更する処理
・問題ないケース、実行事例が発生するケース、コンパイルケースの3パターンに分けられる
・3パターンのうちどれに当てはまるかは以下の2つの観点から確認して求めることができる
```
①変更前の型のクラス > 変更後の型のクラス である
②変更前のインスタンスの元クラス = 変更後の型のクラス 
　または
　変更後の型のクラス > 変更前のインスタンスの元クラス
*ここでは親子関係を 親クラス　> 子クラス と示しています

1. 2つも当てはまる.. 問題なし
2. ①のみ当てはまる... 実行時例外が発生
3. その他... コンパイルエラーが発生
```
shopifyのAPIで250件以上のデータを取る方法

```php
   $sumarray = array();
        $since_id = 1;
        while (true) {
            $base_url =
                'https://hogehoge:hogehoge@hoge.myshopify.com/admin/api/2020-04/orders.json'
                . '?status=open'
                . '&limit=250'
                . '&since_id=' . $since_id
                . '';
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $base_url);
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($curl);
            $data = json_decode($response, true)['orders'];
            curl_close($curl);
            $sumarray = array_merge($sumarray, $data);
            if (count($data) == 250) {
                $since_id = $data[249]["id"];
            } else {
                break;
            }
        }
        return $sumarray;
    }
```
Windows環境でネットワークアダプターを切り替えるスクリプトを作成する

こんにちは。
半年前引っ越した部屋のネットワーク環境があまりよろしくなく、さらに新しく光回線を引ける環境ではなかったため、
既存の有線の回線（VDSL）と、ホームルーターの2回線を用意して、用途によって使い分けています。

いい加減物理的に配線を切り替えるのが面倒になったため、ネットワークアダプターを切り替えるスクリプトを作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2259269/b6d1c06c-7d56-593f-50b5-c70d7a0bb28d.png)

用意するのは以下２つのファイルです。
１．ネットワークアダプターを切り替えるためのPowershell
２．上記１を実行するためのbat


## ネットワークアダプターを切り替えるためのPowershell
```powershell
# 管理者として実行するためのお約束文
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) {
 Start-Process powershell.exe "-File "$PSCommandPath"" -Verb RunAs
 exit
}

# 切り替えるためのネットワークアダプター名を変数にする
$adapter1 = Get-NetAdapter -Name 'Ethernet from motherboard'
$adapter2 = Get-NetAdapter -Name 'Ethernet 2 from USB'

# 切り替えと現在どちらのネットワークが有効になってるかポップアップで表示する
if ($adapter1.Status -eq 'Up') {
$adapter1 | Disable-NetAdapter -Confirm:$false -Verbose
$adapter2 | Enable-NetAdapter -Verbose
# ポップアップで切り替えを通知
$wsobj = new-object -comobject wscript.shell
$result = $wsobj.popup("ドコモ Home5G が有効")
}else{
$adapter1 | Enable-NetAdapter -Verbose
$adapter2 | Disable-NetAdapter -Confirm:$false -Verbose
$wsobj = new-object -comobject wscript.shell
$result = $wsobj.popup("VDSL が有効")
}
```

## Powershellを起動するためのbatファイル
```bat
powershell -NoProfile -ExecutionPolicy Unrestricted '.¥powershell.ps1'
```

batファイルをダブルクリックで実行するとPowershellが呼び出され、ネットワークアダプターが切り替わるようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2259269/8e86d6e3-db29-3558-9d21-c6156e7566c1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2259269/67848721-b1cb-e809-641d-e513b7daae67.png)


~~2022年にもなって不動産情報にVDSLを高速インターネットって書くのやめませんか…~~

## 参考文献
https://teratail.com/questions/130860
正規表現のメタ文字を例を挙げながら解説

# 概要

`. ^ $ * + ? { } [ ] \ | ( )`

こいつらのせいで正規表現がよく分からない。  
実際に動かしてみればわかるはず！

https://weblabo.oscasierra.net/tools/regex/

## `.` ワイルドカード

何か1文字。

### ワイルドカードの使用例

| 表記 | 意味 | OK例 | NG例 |
| ---: | :--- | :--- | :--- |
| . | なんでも良い1文字 | a, b, 0, ~, . | 無し |
| a.c | aから始まりcで終わる3文字 | abc, aac, a.c | ac, abbc, |

## `^` `$` 行頭、行末

`^`は行の先頭、`$`は行の末尾を表す。

### `^` `$`の使用例

| 表記 | 意味 | OK例 | NG例 |
| ---: | :--- | :--- | :--- |
| ^abc | 行の先頭のabc | abc | aabc, ab, ...abc |
| abc$ | 行の末尾のabc | abc | abcd, bc, ...abc... |

## `*` `+` `?` `{}` 繰り返し

直前に書かれた文字を何回か繰り返す。

| 記号 | 意味 |
| ---: | :--- |
| `*` | 直前の文字を0回以上繰り返す |
| `+` | 直前の文字を1回以上繰り返す |
| `?` | 直前の文字を0回または1回繰り返す |
| `{n}` | 直前の文字をn回繰り返す |
| `{m, n} | 直前の文字をm回以上、n回以下繰り返す |

### 繰り返し記号の使用例

| 表記 | 意味 | OK例 | NG例 |
| ---: | :--- | :--- | :--- |
| a*bc | aが0回以上繰り返し | bc, abc, aaaabc | abbc |
| a+bc | aが1回以上繰り返し | abc, aaaabc | bc, abbc |
| a?bc | aが0~1回繰り返し | bc, abc | aaaabc | 
| a{3}bc | aが3回繰り返し | aaabc | bc, aabc |
| a{2,4}bc | aが2~4回繰り返し | aabc, aaabc, aaaabc | abc | 

## `[]`文字クラスを作る

様々な文字をまとめて1文字を作る。

### 文字クラスの中で使用できる特殊な文字

`-` `^`
これらは文字クラスの中で書かれた場合に特殊な意味を持つので注意。

| 記号 | 意味 |
| ---: | :--- |
| `-` | 文字クラスの最初、最後以外で記述された場合に範囲を指定する |
| `^` | 文字クラスの最初で記述された場合に否定を意味する |

### 文字クラスの使用例

| 表記 | 意味 | OK例 | NG例 |
| ---: | :--- | :--- | :--- |
| [abc] | aかbかc | a, b, c | d, e, 0, - |
| [^abc] | aとbとc以外| d, 0, - | a, b, c |
| [a^bc] | aかbかcか^ | a, b, ^ | d, 0, - |
| [a-z] | 小文字のアルファベット | a, b, z | 0, -, A |
| [-az] | -かaかz | -, a, z | b, 0, ` |

## `\` エスケープ文字

メタ文字を普通の文字として扱う。

### エスケープ文字の使用例

| 表記 | 意味 | OK例 | NG例 |
| ---: | :--- | :--- | :--- |
| \\..c | .から始まりcで終わる3文字 | .bc, ..c | .a.,a abc |
| ^\\^abc | 行の最初の^abc | ^abc | abc, ^\^abc |
| a\\*c || a*c | abc, ac, aaaac |

## `|` OR条件

複数の条件を並べる。

### OR条件の使用例

| 表記 | 意味 | OK例 | NG例 |
| ---: | :--- | :--- | :--- |
| abc|def | abcまたはdef | abc, def | bcd, efg |

## `()`グループを作る

文字列のグループを作ってマッチングする。

### `()`の使用例

| 表記 | 意味 | OK例 | NG例 |
| ---: | :--- | :--- | :--- |
| a(b\|c)d | abdかacd | abd, acd | abcd, ad |
| a(b\|cc)d | abdかaccd | abd, accd | abbd, acd |
| a(aa)* | aが奇数連続する | a, aaa, aaaaaaa |  |
| [a(b\|c)d] | 文字クラスに入っても意味はない | a, b, \|, ( | |

# まとめ

+ `.`はワイルドカード文字
+ `^$`は行頭、行末
+ `*` `+` `?` `{}`は繰り返しの指定
+ `[]`複数の文字をまとめて1つのクラスを作る
+ `\`メタ文字を普通の文字として扱う
+ `|`複数の条件でマッチング
+ `()`括弧内の文字列をグループ化する

## 参考文献
[正規表現チェッカー](https://weblabo.oscasierra.net/tools/regex/)
[サルにもわかる正規表現入門](https://userweb.mnet.ne.jp/nakama/)
[すぐ使える正規表現サンプル集](https://hodade.com/seiki/)
MySQLのインストールと起動・停止・リスタート方法を再確認

開発畑でもないのにWebを開発することとなりReact+TypeScriptを使用したFrontendばっかりやっていたらなぜかbackendも担当することとなり久々にデータベースも触ることとなってしまいました。
手を動かさないと勘が戻らないので勉強していきたいと思います。

### 学びたいこと
- MySQLのインストール方法
- MySQLの起動方法
- MySQLの停止方法
- MySQLのリスタート方法

![3156627.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530779/e3aa4184-2d97-14e0-1308-ec017fb0ee82.jpeg)<a href='https://jp.freepik.com/vectors/data'>Storyset - jp.freepik.com によって作成された data ベクトル</a>

## MySQLとは
Oracle社が運営管理するOSSのリレーショナルデータベースマネジメントシステム（以下RDBMS）。
DB業界においてOracle Databaseに次ぐ第二位のシェアを持つ。どっちもOlacleですね。
MySQL Community Editionは無料となっています。

### RDBMS(リレーショナルデータベースマネジメントシステム）
複数の表を関連付けることで複雑なデータ処理を可能とするリレーショナルデータベースを管理するシステム。
Olacle Database、SQL Server、MySQL、PostgreSQLなどがあります。

## MySQLのインストール
ローカル環境をあまりごちゃごちゃしたくないのでDockerで環境構築するのですが、その前にハンズオンで手順確認をしておこうと思います。
インフラ関係の環境構築を体験できる[Envader](https://envader.plus/ "Envader")で実施します。

ターミナルでsudoを使用し以下のコマンドを入力しインストールします。

```
sudo apt update
sudo apt install mysql-server
```
[Enbader](https://envader.plus/course/2/scenario/1035/ "MySQLの世界へようこそ！")の環境ではMariaDBがインストールされるようです。

:::note info
MariaDBとは
MySQL5.5をベースに開発された派生版。
MySQLとの違いはコミュニティが管理していることと、高いパフォーマンスと堅牢性やセキュリティの高さが挙げられています。
:::

### MySQLの起動

```
sudo service mysql start
```
### MySQLの停止
停止したい時は以下をsudoで
```
sudo service mysql stop
```

### MySQLのリスタート
リスタートする時は以下をsudoで
```
sudo service mysql restart
```

### passwordの設定

```
sudo mysql_secure_installation
```

以下に設定するpasswordを入力します。他はYesでいいと思います。
```
New password:
Re-enter new password:
```

### DBへの接続
設定したpasswordを入力して下さい。
```
sudo mysql -u root
```

### 認証pluginのインストール
DBに接続後以下を入力し認証pluginをインストールします。
ユーザー認証するために必要とのこと。

```
USE mysql;
UPDATE user SET plugin='mysql_native_password' WHERE User='root';
FLUSH PRIVILEGES;
exit;
```
### ローカルでDBに接続する
```
mysql -u root -p
```

passwordを求められるので設定したpasswordを入力してログインできれば完了です。

## 学んだことまとめ
石橋はとりあえずワンパン入れる性質なのでローカル環境にインストールする前に手順の確認をすることが出来ました。
次はDockerでの環境構築ですが覚えること多くて大変です:innocent:


## 参考資料
以下のサイトを参考に記事を作成しました。

MySQLについて

https://online.dhw.co.jp/kuritama/about-mysql/

https://www.kagoya.jp/howto/it-glossary/web/mysql/

仮想環境

https://envader.plus/course

RDBについて

https://www.topgate.co.jp/rdb

https://qiita.com/kamihork/items/deeaf449254e3845311d

MariaDBについて

https://www.winserver.ne.jp/column/about_mariadb/
Laravelのartisanでmigrate:rollback時にstepを必須にする

# 概要
本番環境でやらかさない為に。

php artisan実行時に
・migrate:rollbackする時にstep指定を必須
・migrate:fresh|resetを実行禁止

Laravel:8.81
PHP:8.1

# 参考
こちらの記事から追記・修正させて頂きました
https://cpoint-lab.co.jp/article/202010/17274/

# コード
```php:App/Console/Kernel
namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Str;
class Kernel extends ConsoleKernel
{

    // コマンド一部禁止
    public function handle($input, $output = null)
    {
        $this->bootstrap();// Laravel 関連の色々を使うために実行するべきメソッド

        // 指定ワードが含まれている場合に色々と処理
        // @see https://cpoint-lab.co.jp/article/202010/17274/
        foreach ($_SERVER['argv'] as $arg) {
            // reset関連
            if (Str::contains($arg, 'migrate:fresh') || Str::contains($arg, 'migrate:reset')) {
                // dd でコマンド実行前に処理を打ち切り
                dd('STOP! Don\'t such a command.');
            }

            // rollback はstep指定必須
            if(Str::contains($arg, 'migrate:rollback')){
                $step_contain_flag = false;
                foreach ($_SERVER['argv'] as $arg2) {
                    if(str_contains($arg2, 'step')){
                        $step_contain_flag = true;
                    }
                }
                if($step_contain_flag === false){
                    dd('STOP! Rollback must "step"!');
                }
            }
        }

        // 特別打ち切りをする必要がないならば予定されていた処理を実行
        return parent::handle($input, $output);
    }
}
```
フロントエンドVue.jsとバックエンドJavaを同時にローカルで立ち上げて疎通確認

# やりたいこと
- フロントエンドとバックエンドの疎通確認をローカルで行いたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304445/1232bf95-8954-3a30-d373-ade208e68c60.png)

# 状況
- フロントエンドとバックエンドは別々の言語で開発している
    - フロントエンドはJavaScript、Vue.jsで実装
    - バックエンドはJava、Springで実装、REST API
- 実行確認の際は、各プロジェクトを個別にlocalhost:8080で立ち上げて確認していた
- フロントエンドとバックエンドを同時に立ち上げて疎通確認をするにはどうしたらよいのかがわからなかったので調べて実行してみた

# どうすればできそうか
- フロントエンドとバックエンドそれぞれを、異なるポート番号を指定して立ち上げる
- フロントエンド側からバックエンド側のAPIをたたく

# やったこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304445/64e8b0a8-d07c-91a8-5af0-dfa8051327d9.png)
- バックエンドのJavaを`localhost:8080` で立ち上げ、フロントエンドのVue.jsを`localhost:3000` で立ち上げる
    - イメージは以下ページの"前提条件"項の末尾にある図
        - https://ichi.pro/java-bakku-endo-o-shiyoshite-vue-js-apuri-o-kaihatsu-oyobi-kochikusuru-hoho-86438141725925
    - フロントエンド側は以下のコマンドで立ち上げる
        - `npm run serve -- --port 3000`
        - ブラウザで`http://localhost:3000/` で起動していることを確認
            - https://stackoverflow.com/questions/47219819/how-to-change-port-number-in-vue-cli-project
    - バックエンド側は個別に立ち上げていた時と同じように立ち上げる
        - 自分の場合は使用しているIDEの実行ボタンで実行していた
- フロント側のVue.jsでは、axiosを使用してhttpリクエスト送信
    - 例：`axios.get('http://localhost:8080/api/todoList')`
    - https://qiita.com/ksh-fthr/items/2daaaf3a15c4c11956e9
Windows11の新PC買った時に即ダウンロードしたアプリ備忘録

# 背景

仕事でもプライベートでも新しいPCを買うときに、アプリ (ソフトウェア)をダウンロードしてインストールする。
それをメモしておこうという取り組みです。

# ダウンロードした順に記録

- [Chrome](https://www.google.com/intl/ja_jp/chrome/)
- [Discord](https://discord.com/)
- [Google日本語入力](https://www.google.co.jp/ime/)
- [Monosnap](https://monosnap.com/download/win)
- [Visual Studio Code](https://code.visualstudio.com/download)
- [Unity Hub](https://unity.com/ja/download)
- [Epic](https://www.unrealengine.com/ja/download)
- [Blender Launcher](https://github.com/DotBow/Blender-Launcher/releases)
- [Fork](https://git-fork.com/)
- [Git](https://git-scm.com/)
- [Slack](https://slack.com/intl/ja-jp/downloads/windows)
- [Visual Studio](https://visualstudio.microsoft.com/ja/downloads/)
- [nvm-windows](https://github.com/coreybutler/nvm-windows/releases)
- [ZOOM](https://zoom.us/download)
- [ffmpeg](https://github.com/BtbN/FFmpeg-Builds/releases)
AWS IoT Message BrokerのMQTTでpub/sub

# はじめに
AWS IoT Message BrokerのMQTTでpub/subをやってみようとしたら参照した記事の通りではうまくいかなかったので、メモを残します。

https://dev.classmethod.jp/articles/pub-sub-with-aws-iot-over-mqtt/

結論から言うと、ATSエンドポイントとAmazon Root証明書を使用するの2点

# 環境

- RaspberryPi 3
- Raspbian GNU/Linux 9 (stretch)
- aws-cli/1.18.223 Python/3.5.3 Linux/4.19.66-v7+ botocore/1.19.63
- jq-1.5-1-a5b5cbe

# 手順
1. Mosquittoインストール
1. Mosquittoローカル動作確認
1. AWS IoT用のユーザー作成
1. AWS IoT Message Brokerクレデンシャル等取得
1. AWS IoT Root証明書入手
1. AWS エンドポイントでのMosquitto動作確認

# Mosquittoインストール

``` bash
$ sudo apt install mosquitto mosquitto-clients
```

# Mosquittoローカル動作確認

```bash
mosquitto -d
mosquitto_sub -d -t topic/one -u mqtt -P mqtt
```
これで待ち受け状態になるので、別端末を開いて以下を実行
```bash
mosquitto_pub -d -t topic/one -m "This is message" -u mqtt -P mqtt
```
これで先ほどの端末でメッセージが表示されます

オプションの意味は
> -d デバッグ情報出力
> -t トピック名
> -u ユーザー名
> -P ユーザーパスワード
> -m 送信メッセージ

https://mosquitto.org/man/mosquitto_pub-1.html

# AWS IoT用のアカウント作成

専用のアカウントmqtt_userを用意した。
AWSのIAM、ユーザーからAWS CLI用のアカウントを作成。アクセスキー - プログラムによるアクセスだけチェックし、コンソールでは使わないのでパスワードはなし。
既存のポリシーを直接アタッチでAWSIoTFullAccessを選択
キーIDとシークレットを以下で設定
```bash
$ aws configure
```

# AWS IoT Message Brokerクレデンシャル等取得

以下[参照記事](https://dev.classmethod.jp/articles/pub-sub-with-aws-iot-over-mqtt/#toc-4)に沿って

```bash
$ aws iot create-keys-and-certificate --set-as-active > cert.json
$ cat cert.json | jq .keyPair.PublicKey -r > mqtt_user-public-key.pem
$ cat cert.json | jq .keyPair.PrivateKey -r > mqtt_user-private-key.pem
$ cat cert.json | jq .certificatePem -r > cert.pem
```

# AWS IoT Root証明書入手

元の記事ではシマンテックサイトから取得していたが、シマンテックのRoot証明書は無効になっているようでした。
その代わり現在はAmazonが発行している証明書が使えるようでしたので、Amazon Root CA 1をAmazonRootCA1.pemとしてダウンロードしました。
``` bash
$ wget https://www.amazontrust.com/repository/AmazonRootCA1.pem
```
https://aws.amazon.com/jp/blogs/news/aws-iot-core-ats-endpoints/

https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/server-authentication.html

# IAM Role の設定

[参照記事](https://dev.classmethod.jp/articles/pub-sub-with-aws-iot-over-mqtt/#toc-5)の通り

# AWS エンドポイントでのMosquitto動作確認

## MQTT エンドポイントの確認

ここでエンドポイントタイプを指定することで、ATS エンドポイントを取得しています。

``` bash
$ aws iot describe-endpoint --endpoint-type iot:Data-ATS
```
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/server-authentication.html

## Subscribe

取得できたエンドポイントを-h オプションで指定してsubscribe
```bash
mosquitto_sub --cafile AmazonRootCA1.pem --cert cert.pem --key mqtt_user-private-key.pem -h "DUMMY-ats.iot.ap-northeast-1.amazonaws.com" -p 8883 -q 1 -d -t topic/test -i clientid1
```
## Publish

別端末でpublishしてみます。
```bash
mosquitto_pub --cafile AmazonRootCA1.pem --cert cert.pem --key mqtt_user-private-key.pem -h DUMMY-ats.iot.ap-northeast-1.amazonaws.com -p 8883 -q 1 -d -t topic/test -i clientid2 -m "Hello, World!"
```
subscribeした元の端末にメッセージが表示されれば動作OK
Djangoの開発の流れをサラッと ~モデル作成まで~

# はじめに
- しっかり学びたい人はこの記事読むよりも公式リファレンス読む方が良いです。
- なぜその作業を行うかを重視しています。
- python3, venv導入が前提となっています。


## 環境の作成
```
mkdir project -> projectディレクトリの作成
cd project -> projectディレクトリに移動


python3 -m venv project -> venvでprojectという名前の仮想環境を作る
source project/bin/activate -> 仮想環境に入る
```

#### なぜ仮想環境を使うか？
仮想環境を作ることでバージョンが異なる環境を作ることができるため

```
pip install -upgrade pip -> pipをアップデートする
pip install django -> Djangoをインストールする
```

```
django-admin startproject newproject -> newprojectというプロジェクトを作る
cd newproject -> newprojectディレクトリに入る
python manage.py migrate -> データベースに反映させる
```

#### 試してみよう
これまでの作業が出てきてれば下記コマンドでサーバーが立ち上がるはず！

```
python manage.py runserver -> サーバーの立ち上げ
```

```
python manage.py startapp newapp -> newappというアプリを作る
```
## アプリの登録
```newproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'newapp', <- 作成したアプリを追加する
]
```
## モデルの作成
```newapp/models.py
from django.db import models

class Product(models.Model):
    title = models.CharField(max_length=30)
    explain = models.CharField(max_length=100)

-> title, explainフィールドを持つProductクラスを作成
```

#### どうやってデータを作ってるの？
オブジェクトリレーショナルマッパーというデータベース上のデータとプログラム上のデータとの相互の変換を行うためのプログラミング技法がDjangoに備わっているためmodelを書くとデータを作れる。

```
python manage.py makemigrations -> migrationファイルを作成
python manage.py migrate -> migrationファイルの内容をデータベースに反映させる
```