OmniAICreator/Qiita-1.07M huggingface dataset:
div社とマコなり社長が炎上している件について思う事

##プログラミングスクールのdiv社が燃えている
このブログにも投稿したけど、異国にてコロナロックダウンを受け、１５年ぶりにプログラミングの勉強を始めたわけだけど、やっぱり最初はどうやって勉強していいか分からないから、“プログラム　スクール”みたいなキーワードで探すんだよね。で、その時に猛烈にヒットしたdiv社が燃えている。 

![6215976b44b8e472a9082796f620bd0f (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1204968/fe434497-c433-fd61-6df5-0c0101bd046f.jpeg)


数十億規模の投資を受けたというのに、資金がショート、大規模リストラから社内向けヴィデオやメールの流出で大変なことになっているのである。
最初にdivの「TECH CAMP」のページを見た時の印象は、**日本のスクール高杉ﾜﾛﾀ** で、**プログラミングって、半年位勉強すれば、採用されるレベルになるのか！**　という感じであった。 
勿論、英語で海外のオンラインスクールを探すと、高くても$50位が相場であり、さらに自身がプログラミングを毎晩かかさずに勉強はじめて、半年では無理だわと気付くまでにはそんなに時間はかからなかったわけである。特に海外で探すと、150-200ドルもする様なスクールはほぼほぼゴミ扱いで、ぼろくそに言われている惨状である。内容がよっぽど最高至高の内容で、随時内容をアップデート、究極のフォローアップが付かないと、１万５千円さえ取れないのである。無料の優良コンテンツが豊富にあるからである。 
良いなあと思うのは、教えるのが上手いプログラマーやコンテンツ制作者に、IT企業がスポンサーにつき、コンテンツ制作者は無償でビギナーにコースを開放するみたいなカルチャーが根付いていて、やる気があれば、お金がなくても学べるよ　っていう気風がある。 
[以前の記事](https://qiita.com/monsoonTropicalBird/items/a5a89cc689a81e6ba71e)で**無料で学べる最強のプログラミング学習サイト**っていう記事を書きましたが、まさにやる気があれば学習コストは限りなくゼロになるし、プログラミングを半年で戦力レベルまで上げるのが無理なのは、ここの諸先輩方が一番よくわかってらっしゃると思うのです。 
つまり、div社のサービスって、結局は情報弱者向けのコンテンツで、マコなり社長のキャラや知名度みたいなもので売ってる情報商材的なにおいがどうしてもしてしまうわけです。 
現役のエンジニアの方々は、ああいう超高額で短期習得を売りにするスクールビジネスに対して、どういう意見をお持ちなのか、非常に気になるところ。

##プログラミングは結局独学
これは僕個人の学習経験から思う事なんだけど、本当にこの世界は使える技術や知識が１－２年で変わっちゃう。 
個人的には英語ベースでYouTubeのチュートリアルや実際のコードを見ながら勉強するわけだけど、３年前の情報でぎりぎり、４年前のものだと、もう今から勉強する意味無いよねっていう感じなので、常に勉強し続けないといけない世界だなと。 
つまり、**独学するしかないんだよね。** 
学校で全て揃えてもらって、箸の上げ下ろし方から教えてもらっても、数年するともう習った事は陳腐化するわけで、その後は独学を続けていくしかなくて、そうならば、自分なりの独学術みたいなものを構築しておいた方が安上がりだし、生涯役に立つよね。 
で、**独学ってやっぱり情熱や学んでいる対象に対する愛がないと続かない**。 
これはやばい、使いたい、こんなに簡単にあの仕様を実装できるようになったのか！みたいな好奇心がないと厳しいよね。 
あと、言語を１個２個知ってるだけでは、結局何も出来なくて、その周辺知識やライブラリの扱い方、多言語をどう用途によって組み合わせるかも知ってないと、全体的なものは何も作れないってことになる。サービスやアプリって、色々な部品が組み合わされて出来てるからね。 
[プログラミングと英語](https://qiita.com/monsoonTropicalBird/items/2dc9dd7d31c35f426c5b)についても書いたけど、リアル言語と一緒で、とにかく書いて、書いて、動かして、直す　っていう事の繰り返し以上に道はないんだと思うんだよね。 
プログラミングを勉強してみようと思って、高額なスクールにお金を振り込む前に、本当に自分はこれがやりたいのか、作りたいものはあるのか、プログラミングで何をしたいのか　を考えた方が良いと思うよ。多分就職に有利くらいのモチベーションだと楽しめないし、続かないからね。
VMware Cloud on AWS や VMware HCX 関連のリンクまとめ

# はじめに
<!-- 発端や概要を記載 -->
VMware Cloud on AWS（VMC）およびVMware HCXに関してどこでドキュメントを確認できるか、どこから有用な情報を入手できるか、質問を頂くことがありまして良い機会なので個人的に良く参考にさせて頂いているリンクをまとめてみました。
まとまったリンク集をこれまで見つけた事がなかったので多少は役立つかもしれません。



<!-- 各チャプター -->
<a id="#リンク"></a>
# おすすめリンク集
* [VMC製品ページ](https://www.vmware.com/jp/products/vmc-on-aws.html)
* [VMCドキュメント](https://docs.vmware.com/jp/VMware-Cloud-on-AWS/index.html)
* [VMC FAQ](https://www.vmware.com/jp/products/vmc-on-aws.html#faq)
* [VMC Sizer（サイジングツール）](https://vmc.vmware.com/sizer/quick-sizing)
* [VMC Pricing Calculator（料金試算）](https://www.vmware.com/jp/products/vmc-on-aws/pricing-calculator.html)
* [VMware Configuration Maximums（VMCに関する構成の上限が確認できる）](https://configmax.vmware.com/)
* [VMCのリファレンスアーキテクチャ（VMwareサイト）](https://www.vmware.com/jp/products/vmc-on-aws.html?resource=resource-listing%3Areference-architectures)
* [VMCのリファレンスアーキテクチャ（AWSサイト）](https://aws.amazon.com/jp/vmware/resources/)
* [VMware Compatibility Guide（サポートされるゲストOSの確認）](https://www.vmware.com/resources/compatibility/search.php?deviceCategory=software&details=1&productNames=24&page=1&display_interval=10&sortColumn=Partner&sortOrder=Asc&testConfig=16)
* [VMware Japan Blog（VMC関連）](https://blogs.vmware.com/vmware-japan/product/vmware-cloud-on-aws)
* [AWS Web Services ブログ（VMC関連）](https://aws.amazon.com/jp/blogs/news/category/compute/vmware-cloud-on-aws/)
* [VMware HCX ドキュメント](https://docs.vmware.com/en/VMware-HCX/index.html)
* [HCXで必要となる通信要件一覧](https://ports.esp.vmware.com/home/VMware-HCX)
* [Network Diagrams for VMware HCX](https://ports.esp.vmware.com/network-diagrams/VMware-HCX)
* [VMware HOL](https://labs.hol.vmware.com/HOL/)
    * VMCやHCXのハンズオンができる。VMCに関してはEmulatorによる操作感の確認。HCXに関しては色々触れる
    * 利用にあたってはユーザー登録が必要（無料）
* [クラスメソッドさんが運営するDevelopersIOでのVMware Cloud on AWSの記事一覧](https://dev.classmethod.jp/tags/vmware-cloud-on-aws/)


<a id="#個人ブログ"></a>
# 個人ブログ
個人的にVMC関連のブログをやっている人でお勧めのブログサイトをいくつか紹介します

* [In the Clouds ...](https://www.gilles.cloud/)
* [Route179](https://route179.dev/)
* [jonamiki.com](https://jonamiki.com/)
* [Qiita(Toshihisa Noguchiさん)](https://qiita.com/damepanda_supra)
* [Qiita(sanjushi003さん)](https://qiita.com/sanjushi003)



<a id="#さいごに"></a>
# さいごに
他にもおすすめリンクなどがあれば教えてください！
追加で良いのを見つけたら不定期で追加していきたいと思います。
プログレスバーを文字列で表現する関数

車輪の再発明。もはや趣味。
printしてもいいし、TkinterのlabelのtextVariableを変えてもいいかも

```Python
def progressbar(current, max) -> str:
    '''
    args
        current: int/float 現在値
        max: int/float 最大値

    length:いじれる。表示したい長さに合わせる。
    bar:いじれる。好みでどうぞ。今見えてるやつは、プロポーショナルフォントでも使える
    '''
    ratio = current / max
    length = 20
    progress = int(ratio * length)
    bar =  f'[{"■" * progress}{"□" * (length - progress)}]'
    percentage = int(ratio * 100)
    return f'{bar} {percentage}%'
    '''
    [■■■■■■■■■■□□□□□□□□□□] 54%
    [■■■■■■■■■■■□□□□□□□□□] 58%
    [■■■■■■■■■■■■□□□□□□□□] 62%
    [■■■■■■■■■■■■■□□□□□□□] 66%
    [■■■■■■■■■■■■■■□□□□□□] 70%
    [■■■■■■■■■■■■■■■□□□□□] 75%
    [■■■■■■■■■■■■■■■□□□□□] 79%
    [■■■■■■■■■■■■■■■■□□□□] 83%
    [■■■■■■■■■■■■■■■■■□□□] 87%
    [■■■■■■■■■■■■■■■■■■□□] 91%
    [■■■■■■■■■■■■■■■■■■■□] 95%
    [■■■■■■■■■■■■■■■■■■■■] 100%
    （呼び出してprintした時のイメージ）
    '''
```
【Laravel】Storage::disk('local')->append() で out of memoryする

# Storage::disk('local')->append() で out of memory
正確には何度も繰り返しappend()していたらout of memoryとなりました。
原因は少し前のissueになりますが、githubにありました
[Storage::disk('local')->append method run out of memory #24439](https://github.com/laravel/framework/issues/24439)
issueによるとライブラリの関係でappendを呼ぶ度に、ファイルの中身をメモリに読み込んでいるのが原因のようです。

## 対応
これはローカルファイルに書き込む場合に起きるのでLaravel使わずにやります。

```php:example.php
$handle = fopen(storage_path("app/hoge.csv"), "a"); // aで追記モード
fwrite($handle, ",");
fclose($handle);
```

むちゃくちゃ簡単な対応ではあるのですが、メモリが足りない理由がどこかはっきりわからないのでしばらく困ってしまいました。
書き込むデータが大きいのが原因のようにも見えてしまうのですが、フレームワーク側の問題でした。
Python SQLAlchemyとPostgreSQLのローカルテスト環境を作成する

表題の通り、SQLAlchemyの動きをローカルで確認しながら実装したかったので、環境を作りました。
また、誰でも使えるように、githubに公開しました。

https://github.com/engineer-taro/sql-alchemy-postgres-test

# 何に使うか
SQLAlchemyの動作が分からず、簡単にローカルで試したいときに使ってみてください。
SQLAlchemyは英語ドキュメントしかなく、私が実装した際にも動きが分からないところが多くあったため作成しました。


# 使用方法
ここからはREADMEファイルに記載してある内容です。
READMEファイルと内容に齟齬がある場合、READMEの方を信用してください。

1. Docker の起動
1. Python 仮想環境の起動
1. テストしたいコードの実装

## Docker の起動

1. docker フォルダに移動
1. `docker-compose up -d`コマンドを実行
1. 5432 ポートにて PostgreSQL の環境が立ち上がっていることを確認

## Python 仮想環境の起動

※Windows の場合、PowerShell で権限を通す設定が必要になる場合があります。  
参考: https://qiita.com/enya314/items/0e62b68fe70f52a628bf

1. `python -m venv sql_alchemy_postgres_test_env`を実行
1. `pip install -r requirements.txt`を実行

## テストしたいコードの実装

1. app\test.py に、テストしたいコードを記載。
1. `python test.py`で実行。
1. import のエラーが出る場合、app\database\_\_init\_\_.py に app フォルダへの絶対パスを記載する。
[Github]git push origin master後、password入力後エラー(Authentication failed for~)

# はじめに
本記事では、`git push origin master後、password入力後のエラーについて`を記述します。

# 本題
## ターミナルにて

```
 % git push origin master
Username for 'https://github.com': ユーザー名
Password for 'https://mkato1013@github.com': パスワードを入れてみた
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/ユーザー名/リポジトリ名/'
```

パスワードは何度入力しても同じだし、
パスワードを変更してみても、だめでした。

## 結論
2021年8月13日以降、
GitHubのリポジトリにアクセスするには、
ユーザ名とパスワードではなく`アクセストークン`が必要になったようです。

知らなかった。。。

### 方法
Githubにログイン後、右上アイコン選択し、`Settings`へ。
[![Image from Gyazo](https://i.gyazo.com/042c00c6b8c8045ffcf627418b1fa6b6.jpg)](https://gyazo.com/042c00c6b8c8045ffcf627418b1fa6b6)

左下の`Developer settings`へ。
[![Image from Gyazo](https://i.gyazo.com/d535ce2b7e49e5935c6715ba1051dd53.jpg)](https://gyazo.com/d535ce2b7e49e5935c6715ba1051dd53)

`Personal access tokens`からの`Generate new token`へ。

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

`New personal access token`へたどり着いたら、
少なくとも`repo`にチェックをつけます。

その後は、`Generate token`します。

また

```
トークンは、後で確認することができないので、どこかにメモしておきます。
```

## もう一度

```
 % git push origin master
Username for 'https://github.com': ユーザー名
Password for 'https://mkato1013@github.com': 先ほどのトークン
Enumerating objects: 113, done.
Counting objects: 100% (113/113), done.
Delta compression using up to 8 threads
Compressing objects: 100% (100/100), done.
Writing objects: 100% (113/113), 27.89 KiB | 4.65 MiB/s, done.
Total 113 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), done.
To https://github.com/ユーザー名/リポジトリ名
 * [new branch]      master -> master
```

無事に通りました。

以上です。

# 終わりに
情報は大事ですね。
知らないと痛い目を見る典型例ですね。

以下参考サイトです。
[GitHubのリポジトリにアクセス時に「remote: Support for password authentication was removed on August 13, 2021.」エラー](https://note.kiriukun.com/entry/20210904-github-password-authentication-was-removed)
[GitHubでパスワード認証が廃止されるので二要素認証とトークン認証の設定方法をまとめた](https://predora005.hatenablog.com/entry/2021/02/04/190000)
[GitHub、パスワード認証やめるって？](https://qiita.com/BROs/items/4701bd16c7549993659f)

明日も頑張ります！
[OutSystems]標準のExcelエクスポート／インポートで日本語対応する

OutSystemsには、標準でRecord ListとExcelファイル間の変換を行う機能が備わっています。
一覧表形式のExcelとしてエクスポート／インポートを行えるのですが、ヘッダ行にはRecordの各AttributeのNameプロパティから出力されます。
よって、標準的にはヘッダ行はアルファベットで出てくるわけですが、代わりに日本語を出力する方法です。

# 確認環境
Personal Environment(Version 11.13.0 (Build 31107))
Service Studio (Version 11.12.0)

# エクスポート
まずは、Recordに設定するEntityやStructureを設定します。
ヘッダ行に名前を日本語で出力したいAttributeを選択し、Labelプロパティに出力したい名前を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/6e2f7bfe-196e-a726-2428-65c83cbe1698.png)

EntityやStructureのListをRecord List To Excelに渡すと、Excelファイルのバイナリデータが返ります。
下の例では、EntityのListをAssignでStructureのListに詰め替え（こうすることで任意のLabel等を持つStructureをExcel出力用に指定できる）、その全ての属性をExcelに出力しています。この場合、後続ステップで「RecordListToExcel1」でExcelバイナリにアクセス可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/8fe06427-a54f-5c66-c73b-d14bf5208e12.png)

出力したExcelのサンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/e7b251c6-8065-801f-8a67-7fbaf083eaf2.png)

# インポート
StructureやEntityのLabelを設定する点はエクスポートと同じ。
こちらでは、Excel To Record Listを使います。

Record Definitionには、StructureかEntity自身を指定。
File ContentにはExcelファイルのバイナリデータを設定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/aa5aa63f-a394-f069-c287-a933f0eccbb2.png)

エクスポートしたファイルと同じ形式のデータをインポートできます。
なお、ヘッダ列はNameプロパティかLabelプロパティと一致すれば良さそうです。
公式のUnity2D入門をv2020.3でやってみる(5)



[前](https://qiita.com/DiveMasakazu/items/5f8db27dc657f1bb5aa4)



## ワールドとのインタラクション　ダイアログ用レイキャスト

* 新キャラクターの作成
* レイキャスティング（Raycasting）
* 位置指定キャンバスの作成とテキスト
* 表示スクリプト

自キャラの前方等に判定を作成して、その中に入った物を判定してイベントを起こす
というのが例キャスティングのイメージ。

ゲームオブジェクトの子としてキャンバスを作成するのは分かるが、
大きさの指定でスケールを0.01にする理由
300*200で設定するとワールド設定になっているのでピクセルではなくゲーム内単位になるから
3*2にするために0.01を設定しているという意味だと思われるけど、3,2にしたときの影響範囲が読み取れず。
キャンバス内に配置する別オブジェ向けの設定という事だと理解しておけば良さそうな雰囲気

スクリプトは特に難しいものはない

## オーディオ

* オーディオリスナーとオーディオソースについて
* コード追加とオブジェクトへの割り当て
* 2Dでの立体音響


確か遅延の少ない方法で再生するためのプラグインみたいなのをどこかが出していた気がするが、
チュートリアルなので通常の方法

`オーディオソースを追加した場合、Prefab モードではなく、Inspector でオーバーライドを適用してください`
理由が書いていないので、何故かは不明

## ビルド、実行、配布する

とりあえずWindows向けのビルドは出来た。
（iPhone向けはMacもiPhoneも持ってないので試せない）

Android向けにビルドしてappとして動くかはまた確認したい

お　わ　り
Elixir Nervesでssh my-nerves-app-name.local

Nervesの初期設定では、hostnameが`"nerves"`になっており、そのためNervesデバイスのIEｘにアクセスするときには`ssh nerves.local`をよく使うと思います

それを自分のアプリ名に変更する言う話です

```diff_elixir:config/target.exs
  config :mdns_lite,
    # The `host` key specifies what hostnames mdns_lite advertises.  `:hostname`
    # advertises the device's hostname.local. For the official Nerves systems, this
    # is "nerves-<4 digit serial#>.local".  mdns_lite also advertises
    # "nerves.local" for convenience. If more than one Nerves device is on the
    # network, delete "nerves" from the list.

-   host: [:hostname, "nerves"],
+   host: [:hostname, "my-nerves-app-name"],
    ttl: 120,
```

これで`ssh my-nerves-app-name.local`でIEｘにアクセスできるようになりました

ネットワーク上にそのアプリが一つだけ存在している場合に、直感的にアクセスできるので気にいってます

そういえばどこかで見たことがあるな〜と思っていたら、やっぱりストック記事の中にありました

https://qiita.com/nishiuchikazuma/items/e1f9bb17794ce31efadf
Windows＋Docker＋GitLabを構築した時の話


最終的にGitlab Runnerを使ってCI/CDしたいので、まずはWindowsにローカル環境を立てた話
(会社のサーバは権限なくていじれないので。。。)
Dockerのインストールやら、GitLabのceとかeeについての説明は割愛。

:::note 
下記記事にて、ローカルGitlabについて記載しました。
:::
- [Windows＋Docker(Compose)でGitlabをローカルに立ち上げた時の話](https://qiita.com/beeeegle/items/b8d8da113f272f61af44)

# 前提
- OS：Windows10
- Docker：version 20.10.7

# コンテナを動かす
1. GitLabのコンテナをPull
今回はコミュニティエディション（無料版）を使っていきます。
コンテナイメージはeeもあり、末尾のce→eeにするとEEのイメージになります。
```docker pull gitlab/gitlab-ce```

1. コンテナを動かす
Port：80は別のアプリが使用しているので、8081にします。
`docker run -itd --name gitlab-ce -p 8081:80 gitlab/gitlab-ce`

`run`したら、しばし待つ。。。（環境にもよりそうだけど、2～3分かかるイメージ）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/39cce952-0d89-ef6f-c6a4-97f62b76f85e.png" width=50%>
502エラーがしばらくすると・・・
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/b27f9fd0-9359-ac90-5a6e-303f72f5f1d7.png" width=50%>
ログイン画面が表示される。


# ログインする
初回アクセスすると`root`ユーザーのパスワード決めるという記事があったのですが、
↑のスクショの通り、どうも普通のログイン画面っぽい。
こうなると、コンソールからパスワードを設定するしかない模様。

1. DockerコンソールからCLIを開きRilsコンソールを起動する

```
# gitlab-rails console -e production
--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-linux]
 GitLab:       14.3.2 (92acfb1b8a9) FOSS
 GitLab Shell: 13.21.1
 PostgreSQL:   12.7
--------------------------------------------------------------------------------
Loading production environment (Rails 6.1.3.2)
```

2.『>』以降のコマンドを実行する
下記は、パスワードを『password』に設定した例

```
irb(main):001:0> user = User.find(1)
=> #<User id:1 @root>
irb(main):002:0> user.password = 'password'
=> "password"
irb(main):003:0> user.password_confirmation='password'
=> "password"
irb(main):004:0> user.save!
Enqueued ActionMailer::MailDeliveryJob (Job ID: 0815a361-498c-4906-a307-7129eaf9f917) to Sidekiq(mailers) with arguments: "DeviseMailer", "password_change", "deliver_now", {:args=>[#<GlobalID:0x00007fa509bbe9b8 @uri=#<URI::GID gid://gitlab/User/1>>]}
=> true

```

3.　IDに『root』、Passwordに先ほど設定した『password』を入力して・・・

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/e5df9f92-66b0-3421-1a72-9682e60ffa3a.png" width=50%>
無事ログインできましたー！

# 関連記事
- 改善版：[Windows＋Docker(Compose)でGitlabをローカルに立ち上げた時の話](https://qiita.com/beeeegle/items/b8d8da113f272f61af44)
Rails devise_token_authの各種メソッドについて

# devise_token_authとは
***ユーザー認証するためのgem***のことです。
ユーザー認証のためには***devise***を使います。
例えば新規登録、ログイン、ログアウト、アカウント削除、ゲストログインなどです。


⚫︎補足
```ゲストログインとは```
通常はログインをするときはそのアカウントの持ち主だけしかログインしませんが
ゲストログイン機能があるとアカウントの持ち主でなくてもログインできる機能です。
就職活動でポートフォリを作成する時でも、採用担当がアプリの中身を見れるので
よく使われるみたいです。
https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104

#devise_token_authで提供されているメソッド

公式ドキュメントに載っているcontrollerメソッドは下の4つです。
　
1 ***before_action :authenticate_user!***

2 ***user_signed_in?***

3***current_user***

4***user_session***


それぞれのメソッドを説明していきます。

●公式ドキュメント
https://devise-token-auth.gitbook.io/devise-token-auth/usage/controller_methods
https://sainu.hatenablog.jp/entry/2018/08/11/194319


# before_action :authenticate_user!
これはユーザーがサイインしている時に、アカウントの持ち主のユーザーはサイインできるが、
そうでない場合はサイインできないというメソッドです。
アカウントの持ち主ではない場合は、ステータスコードの401(リクエストに誤りがあった)が返ってきます。

例えば使い方は下のように使います。

```memo_controller.rb
class MemoController < ApplicationController
  before_action :authenticate_user!, except: [:index,:show]

  def index
     @user = User.all
  end

end

```
ログインしたユーザーのみが使う設定です。

# user_signed_in?
これはユーザーがちゃんとサイインしているかを確かめるメソッドです。
サイインしていない場合はfalseが返ります。

# current_user
これはサイインしているユーザーデータを取得するためのメソッドです。
取得できない場合はnilが返ります。

# devise_token_auth_group
複数のユーザーの認証機能がある時に使い、それぞれユーザーのグループとして扱い操作するメソッドです。






⚫︎参考資料
https://qiita.com/tomokazu0112/items/5fdd6a51a84c520c45b5
https://qiita.com/k4ssyi/items/3edcd0e5373a41677dee
ヒーローズジャーニーとは？

# きっかけ
先日新人教育の業務の中で耳にしたが、お恥ずかしながら知らないワードであったため。
また、自分自身の成長においても活用できるかもと感じたため。

# ヒーローズジャーニーとは？
世界中の神話を研究したジョゼフ・キャンベル氏が提唱したフレームワークの1つ。
数あるストーリーにおいて、姿や形、世界観などは違っていても主人公たちがたどっている道のりには多くの共通点があり、
この世界のヒーローたちが巡っていく成長のストーリーのことを「ヒーローズジャーニー」と名付けた。
以下12のステップで構成されている。

# ヒーローズジャーニーの12のステップ
※各ステップの細かい説明は割愛しています。興味があれば一番下のリンクから飛んでいただければと思います。
##### ステップ1：平凡な日常
主人公は平凡な日常生活を過ごしており、まだ問題は起きていない。
##### ステップ2：非日常への誘い
主人公に対して新たな旅立ちへの誘いが訪れる。多くのストーリーでは主人公が望まぬ形で旅立たされる。
##### ステップ3：非日常の拒絶
ステップ2の誘いに対して懐疑的、または恐怖を感じ、旅立ちを拒むが、それを乗り越えて旅立っていく。
##### ステップ4:師との出会い
未知なる場所へと進む中で師匠と出会う。この師匠は主人公に対してアドバイスをくれる存在。
##### ステップ5:事件の始まり
主人公が旅立ちを受け入れて物語の事件へと関わっていく。これ以降ではもう元の平凡な日常には戻れない。
##### ステップ6:試練、仲間、宿敵との出会い
主人公がたくさんの試練に立ち向かい、それを乗り越えるために仲間や宿敵となる存在に出会う。
##### ステップ7:もっとも危険な場所への接近
主人公は最も危険な状況に立ち向かうため、その状況へと近づいていく。それを乗り越えないとストーリーの目的が達成できないことが分かっている。
##### ステップ8:最大のチャレンジ
ステップ7の最も危険な状況に立ち向かっている状況。
##### ステップ9:報酬、宝
最大のチャレンジを乗り越えた主人公が報酬を手に入れる。報酬の中身としては世界を救うことや自らの成長など。
##### ステップ10:帰路
ステップ9での報酬をもって帰路に就く。まだ敵に終われていたり最後の危険が孕んでいるストーリーもある。
##### ステップ11:復活
主人公が特別な体験から戻ってき、自分が生まれ変わったことを実感していく。
##### ステップ12:日常への帰還
最終的に主人公は元の日常に戻ってくる。同じ世界ではあるものの、たくさんの宝を得たうえで戻ってくるため新たな次元に達している。

# 12のステップを学習してみて
個人的に好きなドラゴンクエストのストーリーで各ステップをイメージしながら学習しましたが、概ね12ステップすべてに当てはまるなと感じました。(ドラクエの主人公はあまり感情をあらわにしないので、ステップ3の”非日常の拒絶”はイマイチでしたが…)
ただ、このステップに自分を当てはめてみると、普段とは異なった視点で自分のことをとらえなおすことができ、非常に有用なフレームワークだなと効果を実感することができました。(普段の勉強がレベリングに思えてきて、ちょっと楽しい気分になります笑)
ゴールを明確にするという部分は、なかなか自分は実践できていないので、今後もこの「ヒーローズジャーニー」を活用しつつ、ほかのフレームワークについても学習していきたいと思います。

# 参考にさせて頂いたリンク
■[ヒーローズジャーニーとは？：教育やビジネスにも活用できる成長物語の仕組み](https://www.katsuiku-academy.org/media/heros-journey/)
Active Modelについて

# Active Model
Active Modelは、Active Recordからデータベースに関連する部分を切り除いた機能を提供する。
それらのうちいくつか主要なモジュール、FormObjectで使用するモジュールなどについて説明していく。

# ActiveModel::AttributeMethods
attr_accessor で定義されたアクセサに対して、一括で値を設定することができる機能を提供する

# ActiveModel::Callbacks
コールバックを提供するモジュール。標準で提供されている[コールバック](https://railsguides.jp/active_record_callbacks.html#%E5%88%A9%E7%94%A8%E5%8F%AF%E8%83%BD%E3%81%AA%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF)の他に、カスタムでコールバックを追加するための[メソッド](https://railsguides.jp/active_model_basics.html#callbacks%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)も提供されている。

# ActiveModel::Conversion
active modelへの変換メソッドや重要な値を返す変換メソッドを提供する。
`id`、`persisted?`メソッドが定義されているとこのモジュールをインクルードしたオブジェクトに対して次のようなメソッドが使えるようになる。

* to_key
* to_param
* to_partial_path

など

[Github](https://github.com/rails/rails/blob/main/activemodel/lib/active_model/conversion.rb)

# ActiveModel::Validations
データを検証するためのメソッドを提供する。
[機能一覧](https://qiita.com/catkk/items/3b52b2590fece6fefcb6)
[Github](https://github.com/rails/rails/blob/main/activemodel/lib/active_model/validations.rb)

# ActiveModel::Naming
モデル名に対するヘルパクラスメソッドを提供する
[Rails Guide](https://railsguides.jp/active_model_basics.html#naming%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)

# ActiveModel::Translation
オブジェクトとRails国際化（i18n）フレームワーク間の統合機能を提供する

独自のロケールファイル内で定義されたものを`human_attribute_name`が参照し属性名を変換する。

# ActiveModel::Model
Action PackやAction Viewと連携するための機能を提供する。
このモジュール内では次のモジュールをincludeしている。

* [ActiveSupport::Concern](https://railsguides.jp/active_support_core_extensions.html)
* ActiveModel::AttributeAssignment
* ActiveModel::Validations
* ActiveModel::Conversion
* ActiveModel::Naming
* ActiveModel::Translation

また、`ActiveModel::Validations`内で`ActiveModel::Callbacks`もincludeしているためこの機能も使える。

大まかに以下のような機能を提供している。

* モデル名の調査（Naming)
* 変換(Conversion)
* 翻訳(Translation)
* バリデーション(Validation)

これらの機能をFormObjectにMix-inさせることで、ActiveRecordモデルと対応していないオブジェクトでもモデルのような振る舞いを獲得できる。


# ActiveModel::Serializers::JSON
JSONシリアライズ/デシリアライズ機能を提供する

[Rails Guide](https://railsguides.jp/active_model_basics.html#activemodel-serializers%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)

# まとめ
FormObjectを作成する際は、`include ActiveModel::Model`させることにより、バリデーションやi18nによる翻訳機能を獲得し、`ActiveModel::Conversion`メソッドを適切にラップさせることによって`form_with`などのヘルパーメソッドに渡すことも可能になる。

# その他

# ActiveModel::Attributes
属性の値を代入する際、型を意識しなくても自然に求める型に変換してくれる機能を提供する。
https://qiita.com/alpaca_taichou/items/bebace92f06af3f32898

# 参考記事
[Railsガイド Active Model の基礎](https://railsguides.jp/active_model_basics.html)
https://naokirin.hatenablog.com/entry/2019/02/20/231317
Java データ型

#データ型

データ型とは、変数に入れるデータの集類のことです。

データ型は、４つに分かれます。

* 整数
* 小数
* 文字
* ブール型（真偽値型）

#整数系のデータ
整数系のデータ型は,byte,short,int,longの４つ。
__数値の範囲が異なる__

| 型名 | 扱える整数値の範囲 |
| :---: | :---:|
| byte | -256~255 |
| short | -32768~+32767 |
| int | -約20億~+約20億 |
| long | 「京」の桁以上 |

__※longの場合、最後に小文字か大文字の「L」をつける必要がある。__

```java:
public class Lesson07_01 {
    public static void main(String[] args) {
        byte var01 = 1;
        short var02 = 12345;
        int var03 = 1234567890;
        long var04 = 123456789000L;

        System.out.println(var01);
        System.out.println(var02);
        System.out.println(var03);
        System.out.println(var04);
    }
}
```

#小数

小数系のデータ型は、floatとdoubleの２つ。
floatとdoubleは、扱える小数点以下の桁数に違いがある。

doubleはfloatより多くの桁数の焦点を扱える。

floatは、longのときと同じように終わりにアルファベット「F」をつける。

```java:
public class Lesson07_02 {
    public static void main(String[] args) {
        double var01 = 1.23456789;
        float var02 = 1.234F;

        System.out.println(var01);
        System.out.println(var02);
    }
}
```

#文字

文字系のデータ型は、charとStringの２つ。
文字１つの場合はcharを使い、文字２つ以上の場合Stringを使う。

| 型名 | 文字を囲む文字 |
| :---: | :---:|
| char | シングルクォーテーション (') |
| String | ダブルクォーテーション (") |

```java
public class Lesson07_03 {
    public static void main(String[] args) {
        char var01 = 'c';
        String var02 = "hellow,World!";

        System.out.println(var01);
        System.out.println(var02);
    }
}
```

#ブール型
ブール値（真偽値）のデータ型は、boolearn。

| ブール値 | 意味 |
| :---: | :---:|
| true | 真 |
| false | 偽 |

```java
public class Lesson07_0４ {
    public static void main(String[] args) {
        
        int var_a = 10;
        int var_b = 1;
        boolean var_bool;

        var_bool = (var_a > var>b);

        System.out.println(var_bool);
    }
}
```
「ドメインオブジェクト」を理解したい。

https://gihyo.jp/book/2017/978-4-7741-9087-7

における、「**ドメインオブジェクト**」（ないし、**ドメイン**）の説明が個人的にとても分かりやすかった。

そこで、当書とは別の題材を例に「ドメインオブジェクト」の文脈の解説を試みる。

<br>

### 「郵便番号」をプログラムで扱うこと考える

「郵便番号」は次のような概念を持っている。

- 7けた
- 3けた目と4けた目の間にハイフンを入れる
- 旧郵便番号に従う3けたもしくは5けたの「郵便区番号」と、それぞれ4けたもしくは2けたの「町域番号」からなる

―― 日本郵政HP https://www.post.japanpost.jp/zipcode/zipmanual/p04.html より2021年10月2日現在

<br>

プログラムで扱うことを考えると、ハイフンを含めて8文字の文字列であるから愚直に ↓ のように書くこともできる。

```Java
String zipCode = "350-1106";
```

しかし、このように扱うといくつか問題が出てくる。

<br>

**① ハイフンを含むのか含まないのか使う側で意識する必要がある**

```Java
/**
 * 郵便番号からお届け日数を算出する
 * @param 郵便番号
 * @return お届け日数
 */
int calculateDeliveryDays(String zipCode) [
  // zipCode が　ハイフンを含むのか、含まないのかを意識する必要がある
}
```

**② けた数間違いや番号の妥当性を都度検査する必要がある**

```Java
String zipCode = "350-1106";

// けた数の検査
if (zipCode.replace("-", "").length() != 7) {
  throw new IllegalArgumentException("郵便番号のけた数が不正です");
}
```

**③ 郵便番号から郵便区番号や町域番号を取り出す同じような処理が散らばる**

```Java
String zipCode1 = "350-1106";
String zipSectionCode1 = zipCode.replace("-", "").substring(0, 5)

// zipSectionCode1 を使う処理

String zipCode2 = "163-8001";
String zipSectionCode2 = zipCode.replace("-", "").substring(0, 5)

// zipSectionCode2 を使う処理
```

<br>

### 「郵便番号」クラスで諸問題を解決する

```Java
class ZipCode {
  static final int ZIP_CODE_LENGTH = 7;
  static final int HYPHEN_SEPARATED_INDEX = 3;
  static final int ZIP_SECTION_CODE_LENGTH = 5;

  String withHyphen; // 利用者側はよしなに使い分けられる（①を解決）
  String withoutHyphen; // 利用者側はよしなに使い分けられる（①を解決）

  ZipCode(String value) {
    withoutHyphen = value.replace("-", "");
    withHyphen = value.insert(HYPHEN_SEPARATED_INDEX, "-");

    if (withoutHyphen.length() != ZIP_CODE_LENGTH) {
      throw new IllegalArgumentException("郵便番号のけた数が不正です"); // インスタンス生成時に桁数を検査（②を解決）
    }
  }

  /**
   * 郵便区番号を取得する
   * @return 郵便区番号
   */
  String getZipSectionCode() {
    return withoutHyphen.substring(0, ZIP_SECTION_CODE_LENGTH) // メソッドを共通化（③を解決）
  }
}
```

※ これはあくまで例で、厳密には郵便区番号は3けたの場合があったり、番号の妥当性を検査する必要がある。

<br>

### 「郵便番号」クラスはドメインオブジェクト

「郵便番号」クラスのように、業務で使われる用語に合わせて、その用語の関心事に対応するクラスを**ドメインオブジェクト**と呼ぶ。

DDDにおける、アプリケーションの対象領域（**ドメイン**）の関心事を記述したオブジェクトという意味だ。

<br>

https://gihyo.jp/book/2017/978-4-7741-9087-7

ご意見ご感想等ございましたら、コメントお願いします :bow:
AtCoder  ABC221 挑戦！

ABC221、コンテスト3回目の挑戦です！
ついにC問題を落としてしまう。
着眼点は良かったが、抜け漏れがあった。悔しい。。。

```ruby:ABC221A
A, B=map(int, (input().split()))

# 32**{(A-1)-(B-1)}=32**(A-B)が答え。
print(32**(A-B))
```

そのまま算数の問題。

```ruby:ABC221B
#長さ2以上100以下の文字列 S, T
S=input()
T=input()

Flag=False #判定用のフラグ
#全探索する
#並び替えずに一致するか
if S==T:
    Flag=True
    print('Yes')
#一致しない場合は、隣り合う文字について入れ替えて、一致するか判定
else:
    for i in range(len(S)-1):
        ex_S=[_ for _ in S]#最初の文字列Sのリストで初期化
        ex_S[i],ex_S[i+1]=ex_S[i+1], ex_S[i]
        ex_S_join=''.join(ex_S)
        # print(ex_S_join)
        if ex_S_join==T:
            print('Yes')
            Flag=True
            break
        else:
            pass
if Flag==False:
    print('No')
```

手間取った部分が、文字列の入れ替え。
文字列については、S[i]でSのi番目を取り出せるので、それで入れ替えられると思っていたのだが、エラーが出てうまくいかず、やむなくリストに取り出してから、入れ替えて再結合した。

```ruby:ABC221C_一部AC
N=int(input())

#Nの数字の配列をつくる
N_list=[]
for i in range(len(str(N))):
    N_list.append(int(str(N)[i]))
# print(N_list)

#降順に数字を並び替える
sorted_N_list=sorted(N_list, reverse=True)
# print(sorted_N_list)

#A, Bに大きい順に数を分割する。
A, B='', ''
for i in range(len(sorted_N_list)):
    if i%2==0:#iが奇数のとき
        A+=str(sorted_N_list[i])
    else:#偶数のとき
        B+=str(sorted_N_list[i])

C, D='', ''
for i in range(len(sorted_N_list)):
    if i%2==0:
        if i==2:
            D+=str(sorted_N_list[i])
        else:
            C+=str(sorted_N_list[i])
    else:
        if i==3:
            C+=str(sorted_N_list[i])
        else:
            D+=str(sorted_N_list[i])

# print(A, B, C, D)
print(max(int(A)*int(B), int(C)*int(D)))
```
C問題。結果は、AC16個、WA14個で、取れず。
探索数がオーバーしそうだったので、工夫した。(実際は、探索する方法もあったっぽい。早々に諦めてた。)

##着想
・積を最大にするので、数字が大きい方から、桁数の大きいもの同士に使っていくのがよい
・また、サンプルケースで試していくと、どうやらそのままだと積は最大にならない。(ここがふわふわしてコードに落とし込めていなかったため、WAだった)
→サンプルケースの例
123の場合: 
A=3, 1 B=2 で31*2=62
A=3, B=2,1 で3*21=63 
で後者の方が大きくなる。

998244353の場合:
A=98432, B=9543で98432*9543=939336576
A=95432, B=9843で95432*9843=939337176
でこちらも後者の方が大きい。メカニズムはよくわからんが、おそらくちゃんとやれば証明できるんだろうね。

##WAの要因: 抜け漏れがあった。
具体的には、5桁目以降で違う数字が表れたときに、入れ替えができていないので、正しい答えが出ない。
9999321などの場合:
9931*992=9851552
9921*993=9851553

上記を落とし込むと下記の様になる。
コンテスト後に、提出すると、無事ACだった。

```ruby:ABC221C_AC
N=int(input())

#Nの数字の配列をつくる
N_list=[]
for i in range(len(str(N))):
    N_list.append(int(str(N)[i]))
# print(N_list)

#降順に数字を並び替える
sorted_N_list=sorted(N_list, reverse=True)
# print(sorted_N_list)

#A, Bに大きい順に数を分割する。
A, B='', ''
for i in range(len(sorted_N_list)):
    if i%2==0:#iが奇数のとき
        A+=str(sorted_N_list[i])
    else:#偶数のとき
        B+=str(sorted_N_list[i])


#初めて異なる文字が出てきた部分を入れ替える。
for i in range(min(len(A),len(B))):
    if A[i]!=B[i]:
        list_A=list(A)
        list_B=list(B)
        list_A[i], list_B[i]=list_B[i], list_A[i]
        #入れ替え後のA, Bをjoinで作る。
        A=''.join(list_A)
        B=''.join(list_B)
        break
    else:
        pass

print(int(A)*int(B))
```
上記のコードでも、B問題の文字列の入れ替えが出てきて、いちいちリストに変換して入れ替えるのがおっくうだった。なんかうまいコードとかあるんだろうか。

3回目にして、ついにC問題が取れませんでしたが、惜しいところまではいけたので悔いはありません。実際、時間内にエラーを解消するのは厳しかったと思います。

来週も頑張りましょう。お疲れさまでした。
SwiftUIに関する非推奨のmodifierとその代替を一覧にしてみた

## はじめに
SwiftUIもiOS13から登場して今年で３年目になります。
初期の頃から見るとかなり使いやすく、また意図しない動作も減ってきています。
またその過程で非推奨もどんどん増えてきていますので
2021.10.1時点での非推奨と代替の一覧を作ってみました。
また以下公式ドキュメントにもありますので詳細はこちらをご覧ください。

[Deprecated Modifiers](https://developer.apple.com/documentation/swiftui/view-deprecated)

## 一覧
|非推奨|代替|
|---|---|
|colorScheme| preferredColorScheme|
|listRowPlatterColor|listItemTint|
|background(_:alignment:)|background(alignment：content :)|
|overlay(_:alignment:)|overlay(alignment:content:)|
|autocapitalization(_:)|textInputAutocapitalization(_:)|
|navigationBarTitle|navigationTitle|
| contextMenu(_:) |contextMenu(menuItems:)|
| DoubleColumnNavigationViewStyle | ColumnNavigationViewStyle |
| edgesIgnoringSafeArea | ignoresSafeArea |
| accentColor | tint |
|animation(_:)|withAnimation(_:_:) or animation(_:value:)|
| actionSheet | confirmationDialog |
|alert(isPresented:content:)|alert(_:isPresented:actions:message:)|

## 補足

### textInputAutocapitalization
#### Type Properties

```swift
.characters
```
すべての文字を大文字にする自動大文字化動作を定義します。

```swift
.never
```
大文字小文字の区別をしない自動大文字入力の動作を定義します。
(大文字小文字を自動的に変換せず、そのまま返します)

```swift
.sentences
```
すべての文の最初の文字を大文字にする自動大文字化動作を定義します。

```swift
.words
```
すべての単語の最初の文字を大文字にする自動大文字化動作を定義します。


### その他
onCommit → onSubmit

https://developer.apple.com/documentation/swiftui/textfield/init(_:text:oneditingchanged:oncommit:)-588cl

## 感想
iOS15から本格的に使用できる状態になってきた印象です。
iOS13は本当に不安定です。
同じコードでもiOS14からの挙動とiOS13の挙動で違いがあるくらいなのでiOS13を切れるなら切る事をオススメします。笑
DNSoverTLS(Linux)クライアント側の設定

ラップトップのLinuxでDoTを有効にしました。
DoTよりもDNSSECとか、ドメインを管理しているレジストラやプロバイダが標準で提供して対応できることが重要だと思います。
ルートサーバ同士は対応しているので、他でもそれができたらいいですね。
一般のユーザーとしては、プロバイダのDNSが信頼できるものであれば、本来はDoTは不要だと思うのです。
プライバシーといっても、DNSの問い合わせを知られては困るという、状況の人はあまりいないと思います。
でも一応、DoTの対応の手順を確認しておこうと思いました。
ただDNSの応答が集中するから、負荷が高いだろうなと思います。
時々、反応が遅くなりますね。

https://chabik.com/2020/05/dot-with-stubby-and-dnsmasq-on-macos/

上のサイトが参考になります。
流れとしては、

1. stubby、dnsmasqの導入
1. NetworkManagerによる/etc/resolv.confの自動生成を停止する。 
1. systemd-resolvedの無効化
1. /etc/resolv.confの設定

といった感じです。

stubby,dnsmasqの導入

```sh
sudo pacman -S stubby dnsmasq

#サービスを有効にします。
sudo systemctl enable stubby
sudo systemctl enable dnsmasq

cat << EOF > dnsmasq.conf
no-resolv
proxy-dnssec
server=::1#53000
server=127.0.0.1#53000
listen-address=::1,127.0.0.1
EOF
#環境に応じて設定してください。ここでは設定を追記しています。
sudo cat dnsmasq.conf | sudo tee -a /etc/dnsmasq.conf
```

```sh
cat << EOF > stubby.yml
resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
  - GETDNS_TRANSPORT_TLS
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 128
edns_client_subnet_private : 1
round_robin_upstreams: 1
idle_timeout: 9000
listen_addresses:
  - 127.0.0.1@53000
  - 0::1@53000
dnssec: GETDNS_EXTENSION_TRUE
appdata_dir: "/var/cache/stubby"
upstream_recursive_servers:
  - address_data: 1.1.1.1
    tls_port: 853
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 1.0.0.1
    tls_port: 853
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 8.8.8.8
    tls_port: 853
    tls_auth_name: "dns.google"
  - address_data: 8.8.4.4
    tls_port: 853
    tls_auth_name: "dns.google"
  - address_data: 2606:4700:4700::1111
    tls_port: 853
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 2606:4700:4700::1001
    tls_port: 853
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 2001:4860:4860::8888
    tls_port: 853
    tls_auth_name: "dns.google"
  - address_data: 2001:4860:4860::8844
    tls_port: 853
    tls_auth_name: "dns.google"
EOF
sudo cat stubby.yml | sudo tee -a /etc/stubby/stubby.yml
```

```sh
sudo systemctl start stubby
sudo systemctl start dnsmasq
```
以上で、stubby,dnsmasqによるDNSoverTLSの設定ができました。

```sh
sudo systemctl status stubby
sudo systemctl status dnsmasq
```

次に、NetworkManagerとsystemd-resolvedによる/etc/resolv.confの自動生成の無効化を行います。

systemd-resolvedの無効化は、

``` sh
systemctl disable systemd-resolved
systemctl stop systemd-resolved
```

``` sh
cat << EOF > disabled-systemd-resolved.conf
[main]
dns=none
EOF
sudo cat disabled-systemd-resolved.conf | sudo tee -a /etc/systemd/resolved.conf
sudo cp disabled-systemd-resolved.conf /etc/NetworkManager/conf.d/
```

DNSの名前解決をstubby,dnsmasqを利用するので、resolv.confを下記のように修正します。
自動生成による上書きが無効になるので、設定ファイルが書き換わることはありません。

``` sh
cat << EOF > resolv.conf
options inet6 edns0 trust-ad
nameserver 127.0.0.1
nameserver ::1
EOF
sudo cp resolv.conf /etc/resolv.conf
```

NetworkManagerを再起動しても、/etc/resolv.confが変更されないか確認します。

```sh
sudo systemctl restart NetworkManager.service
sudo cat /etc/resolv.conf
```

最後にDNSの名前解決が問題なく行えているか確認しておきましょう。

```sh
drill +dnssec sigok.verteiltesysteme.net @127.0.0.1
```

以上、お疲れ様でした。
最近、配列で使用したメソッド復習

#今回の内容

* `.contains`、`.reverse()`、`.randomElement()`について簡単に復習です

#コードと簡単解説

```Swift:
    var contentsArray = ["UITableView",
                         "UISearchController",
                         "UIView",
                         "UIColor",
                         "UICollectionView",
                         "UISwich",
                         "UIKit",
                         "UITextField",
                         "UIViewController",
                         "UILabel"]
```

##.contains

* `contentsArray`の中に`UIView`の値が存在するので`true`を返します。

* `contentsArray`の中に`UIImage`の値が存在しないので`false`を返します。

```Swift:.contains
        print(contentsArray.contains("UIView"))
        print(contentsArray.contains("UIImage"))
```
```:print結果
        true
        false
```
##.reverse( )

* 配列内の値の順番を逆にします。

```Swift:.reverse
        contentsArray.reverse()
        print(contentsArray)
```
```:print結果
        ["UILabel", "UIViewController", "UITextField", "UIKit", "UISwich", 
         "UICollectionView", "UIColor","UIView", "UISearchController", "UITableView"]

```
##.randomElement( )

* 配列内の値からランダムに値を取得します。

```Swift:.randomElement
        print(contentsArray.randomElement() as Any)
```
```:print結果
        Optional("UICollectionView")
```

# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
gradleでgoogleのguavaをインポートする

gradle7系から依存関係の書き方が変わりました。
(これを知らなくて詰まりました。。)

https://docs.gradle.org/current/userguide/upgrading_version_6.html#sec:configuration_removal

以下を設定し、gradleプロジェクトを更新すればOKです。

```gradle
dependencies {
    implementation("com.google.guava:guava:31.0.1-jre")
}
```

最新情報は公式のREADMEを見るのがよさそうです。

https://github.com/google/guava
SCSSって？


※エンジニアたまごによる学習記録なので、内容に不備等があるかもしれません。
　また、ノート的な役割なので随時更新していく予定です。
# SCSS(SASS)とは？
一言でいうと、**CSSを拡張して、より効率的に描くことができる言語**のこと。
SASSは"Syntactically Awesome StyleSheet"の略。(そもそも名前にAwesomeと入っている)
SCSSはCSSと似た記述、SASSはRubyと似た記述になっている。

# SCSS(SASS)を使うメリット
①CSSのコード量を減らすことができる(入れ子や変数を使うことで簡易化できる)。
②コードの保守や管理がしやすい(コード量が減り、視認性が高まる)。
③バグを減らすことができる(コード量が減ることで人為的ミスが減る)。
④CSSにはない機能を利用できる(変数やMixinなど)。

# SCSS(SASS)を使う上での注意
SCSS(SASS)で作成したコードは、CSSにコンパイル(変換)する必要がある。

# 参考にさせて頂いたサイト
[SCSS(SASS)とCSSの違いについて](https://blog.maromaro.co.jp/archives/8010)
[Sassは絶対に使った方が良いよ！使い方入門編](https://webdesignday.jp/inspiration/technique/css/5819/)
Eloquentのsave()とupdate()の`updated_at`の扱い

## 背景

保存するデータに変更がなくても `updated_at` を更新してほしいケースがあって、
[こちらの記事](https://qiita.com/gomaaa/items/91e5cbd319279a2db6ec) を参考に実装してみたけど、`update()`でも `updated_at` が更新されず。
バージョン差分とかで変わったのかなと思い調べてみました。

ちなみにデバッグしてたのは Laravel 5.7 です。(古いバージョンの情報ですみません...)

## 結論

`save()`, `update()` のどちらも同じ。

- 保存するデータに差分があれば `updated_at` は更新される。
- 保存するデータに差分がなければ `updated_at` は更新されない。

## 詳細

コードを見てみる。

### `save()`
https://github.com/illuminate/database/blob/9c9aec558577259c6ceb026a16d65461e05bc774/Eloquent/Model.php#L642-L645

データに変更があるかチェックしてる。

```php
    $saved = $this->isDirty() ?
                $this->performUpdate($query) : true;
```

### `update()`
https://github.com/illuminate/database/blob/9c9aec558577259c6ceb026a16d65461e05bc774/Eloquent/Model.php#L591

```php
    return $this->fill($attributes)->save($options);
```

結局 `save()`　呼んでるやん！

Laravel 8 でもコードは同じでした。
https://github.com/illuminate/database/blob/8.x/Eloquent/Model.php


## じゃあ `updated_at` を更新したいときは?

```php
$model->touch();
```

これでOK！


## まとめ
久しぶりにLaravel(というかEloquent)のコードを見たので、たまには書いてみました。

---

## 参考: 背景の詳細と課題
なんで `updated_at` を更新したかったかというと、
プログラム上は1つのオブジェクトだけど、DBのテーブルは2つに分かれている、というオブジェクトを扱いたかったから。
(商品マスターテーブルとその属性テーブルみたいな感じ)

このオブジェクトの更新日データはマスター側の `updated_at` を参照してたんだけど、属性テーブルのデータしか更新が発生しなかった時に、更新したのにソート順が変わらない、みたいなことが起きました。
画面上は更新ボタンを押すので、商品マスターテーブルの更新は毎回 `updated_at` が更新されるようにしてもいいかな、と考えてこの記事に書いたことを調べてました。

### もっといい方法はないのか
(ここはちょっとメモです)

テーブルはあくまで2つとしたとき、どうするのが良かったのかな〜。
↓こんな感じ?

1. Aを`save()`
1. Bを`save()`
1. Bが更新されてたら、Aを`touch()`して`save()`
1. Bが更新されてなかったら、何もしない

Aを2回`save()`は無駄な感じがします。。。

1. Aを`fill()`まで
1. Bを`save()`
1. Bが更新されてたら、Aを`touch()`して`save()`
1. Bが更新されてなかったら、Aを`save()`

これなら少しDBアクセス減りますね。
[Swift]理解が難しいクロージャの処理をドラクエ風にして分かりやすくしてみた

##はじめに

swiftのクロージャは、関数と同じくひとまとまりの処理として使用することができますが
クロージャーを学ぶ上で、処理の追い方がわかりづらいと感じました。

なので馴染みのあるドラゴンクエスト風にアレンジしてみました。　
セーブの処理に見立ててコードを追ってみます。

##コード

```ruby:セーブメソッド（クロージャーを引数に取る関数）
func save(savepoint:String, completion: ( (String?) -> Void )? ){
   
    print("[1]   冒険の書を確認")
    #//下のコードはセーブに3秒かかると想定したもの
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        print("[3]   冒険の書に記録しました")
        print("\(savepoint)")
        completion!("タロウ")
        
    }
}

```
completionは「この関数が終わったら最後に実行するクロージャー」という意味。
callbackと書く人もいるそうです。
今回の場合は冒険者名である`タロウ`を渡しています。



そして下のコードで上のメソッドを実行します。

```ruby:実行処理
save(savepoint: "始まりの街") { (value: String?) in
#nilでなければ抜ける
    guard let _value = value else {
        return
    }
    print("冒険者 : \(_value)")
}
print("[2] 冒険の書に記録中")

```
savepointで”始まりの街”を渡し、seveメソッドでもらったvalueがnilでなければ
冒険者としてプリントされます。

実行結果を見ると…

```ruby:実行結果
[1]   冒険の書を確認
[2] 冒険の書に記録中
[3]   冒険の書に記録しました
始まりの街
冒険者 : タロウ
```

これから分かることはsaveメソッドを実行し、セーブ３秒間後に`タロウ`が渡されるまで
クロージャー内の処理は行われないということ。

実行した{　}の中身の処理は一旦保留し、渡した先で実際にその引数の処理が求められた時に、クロージャが実行されるイメージです。

なので先に`print("[2] 冒険の書に記録中")`がプリントされます。

##おわりに

ドラクエ風に置き換える上で、間違っている箇所もあるかとは思いますが分かりやすくはなったかと思います（笑）

体系的に覚えることももちろん大事だとは思いますが、感覚的に覚えると記憶として定着しやすいかなと感じました。
Miracast(chromecast)不調(なおりました)

日本発のArchベースのAlterLinuxをインストールしました。

https://alter.fascode.net

https://www.ventoy.net/en/index.html

AlterLinuxのISOはventoyからブートできませんでした。UEFI関係の影響のようです。GRUBだったら、起動できたのだろうと思います。SereneはGRUBだったので、起動できました。

さて、しばらく前に、xubuntuのブラウザのVivaldiやEdgeベータ版でMiracast（Chromecast）ができていたのが、なぜか出来なくなっていたので、いろいろ調べるついでに、OSの使い勝手を検証しなおしていました。
最終的にAlterに落ち着きました。
DNS over TLSの設定でsystemd-resolvedの挙動とNetworkManagerの/etc/resolv.confの上書きに手こずりましたが、それ以外は問題なく落ち着いています。DoT設定については、次のサイトが参考になります。

https://chabik.com/2020/05/dot-with-stubby-and-dnsmasq-on-macos/

GNOME41はまだ未導入ですが、GNOME40でgtk4の洗練かつ軽快なデスクトップ環境に満足しています。
日本語入力も標準インストールです。
あと多言語関係は、いろいろなフォントが手軽に導入できるようになると嬉しいですね。
以前は、スクリプトでやってた気がしますが、今は、どうやるのがいいのかな。
好みもあるでしょうが、標準でもう少しあるといいなぁ。いかんいかん、欲張りさんがでてきましたね。

最近のLinuxのインストーラーは、だいたい統一されてきたのと、洗練されていて、かなり安心してインストールできますね。私が、最近のメインブラウザをVivaldiにしたのは、

- 設定の同期がとれる。（複数端末で共有できる。）
- IMAPのメールも一応扱えてgmailにも対応している。
- Chrome拡張を利用できる。 ​

といった点です。

メールは複数アカウント使い分ける必要がなければ、十分使えると思います。
ちなみに多要素認証はAuthy、パスワードマネージャーはbitwardenを使っています。
いろんなOS混在の環境で扱えるので、便利な組み合わせです。

さて、Miracast(Chromecast)についてですが、もともとはWindowsのfirefoxのfx_castがうまく動作しなかったので、いろいろ探して、結局Linux版のVivaldiで動作することに気づいて喜んでいました。
ブラウザのVivaldiやEdgeでは標準機能でメニューに実装されていて、スクリーンキャスト（ディスプレイのワイヤレス接続）できるのです。
ただ、今回、いろいろ確認したところ、Linuxのいろんなディストリビューションで試しましたが、Vivaldi,Edgeベータ版、fx_cast、どれも私の環境では動作しなくなっていました。
Windows版のVivaldiやEdgeでも、またWindows11のワイヤレスディスプレイ接続も動作せず。

画面が乱れて、使い物にはなりそうにありませんでしたが、GNOME network displaysというアプリは少し動作してくれました。スマホからのスクリーンキャストは通常に行えています。
ラップトップPCのハードウェアの問題かWifiの無線の問題かとも思いましたが、ソフトウェア側に問題が起きている可能性が大きい気がします。
GNOME netowork displaysは、ディストリビューションによっては、動作したり、しなかったり、不安定な印象でした。（転送効率が悪いのか画像も乱れました。デスクトップ全体を送信しているからサイズが大きいからかもしれません。）

Miracastは、画面や音声を他のテレビなどのディスプレイに無線で飛ばして、楽しめる機能です。
今ではスマホからでも飛ばせて、楽しめる時代ですね。これが普通にできるようになって、より大きな画面で動画や音楽のストリーミングサービスを楽しめるようになっているのは嬉しいですね。
Linuxでも無線のハードウェアによるかもしれませんが、できるんだなぁと思って感心していたのに、いったいどうしたことでしょう。Chromiumベースの問題かとも思いましたが、Windowsのワイヤレスディスプレイ接続も動作せず。
見つからない状況です。ということで、原因不明の手詰まりとなっております。
しばらくラップトップのPCのスピーカーで我慢します（笑）

ソフトウェアの問題として考えられるのは、最近行った設定変更なども合わせると多岐に渡るのですが、
kernelの更新（またそれに伴うライブラリやアプリとの整合性が変わって、動作しなくなった可能性。）
いろいろアプリの更新が他にもありましたから、その影響もあるのかもしれません。
ネットで調べていると、wpa_supplicantがP2P、WIFI_DISPLAYオプションを有効にしてコンパイルされていることを確認してみるように書かれていました。そういった情報も、実際ビルドしたりして、試しましたが有効ではなかったです。

ただネットワーク周りの設定だと、ファイアウォールの関係もあるのでしょうか？
ネットワークやデバイスを探索する時間のタイムアウトもあるのかもしれません。
症状としては、キャスト対象のデバイス、受像側が見つからないという状態です。
以前一時的にできていたのに、機能しなくなると、原因をつきとめたくなるものですね。
でも原因究明は無理そうだったので、Linuxのいろんなバージョンをインストールして、比較しながら、動作検証を久しぶりに行いました。
その結果、どのディストリビューションでも、ほとんどできなくて、一部、不完全ではあるものの、GNOME network displaysでは送信できるという結果でした。Windows11でも無理だったので、ハードウェアの故障の可能性も少しだけはあるのかなぁ？
ネットワーク周りの影響なので、ルータの設定を見直したり、IPv6やDNS over TLSを有効にしたりしていたので、その関係も影響しているかもしれません。また無線の電波干渉の影響もあるのかもしれませんね。機器も熱もっていたし。

PS
ルーターの設定を見直して再起動させたら、miracastができました。
原因切り分けできていませんが、Google Chrome以外でもスクリーンキャスト（Miracast,chromecast）ができますね。
Xcode13にバージョンアップしたら、Undefined symbolエラーでビルド出来なくなった

Xcode:13
React Native:0.65.1

xcode13にバージョンアップしたら、急に以下のようなエラーが...

##エラー一つ目：Undefined symbol:
```
ld: warning: Could not find or use auto-linked library 'swift_Concurrency'
ld: warning: Could not find or use auto-linked library 'swiftFileProvider'
ld: warning: Could not find or use auto-linked library 'swiftDataDetection'
Undefined symbols for architecture x86_64:
  "__swift_FORCE_LOAD_$_swiftDataDetection", referenced from:
      __swift_FORCE_LOAD_$_swiftDataDetection_$_YogaKit in libYogaKit.a(YGLayoutExtensions.o)
     (maybe you meant: __swift_FORCE_LOAD_$_swiftDataDetection_$_YogaKit)
  "__swift_FORCE_LOAD_$_swiftFileProvider", referenced from:
      __swift_FORCE_LOAD_$_swiftFileProvider_$_YogaKit in libYogaKit.a(YGLayoutExtensions.o)
     (maybe you meant: __swift_FORCE_LOAD_$_swiftFileProvider_$_YogaKit
```
![スクリーンショット 2021-09-30 16.35.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573515/98d16f79-b35c-9565-526c-82019f283263.png)

＜解決方法＞
[こちら](https://github.com/zalando/SwiftMonkey/issues/80)を参考に、Xcodeで[target]/[target]/にvoid.swiftファイルを作る。

![スクリーンショット 2021-10-02 22.50.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573515/42aae3e3-fbab-1441-d73b-5622da01e8fb.png)

##エラー二つ目：Command PrecompileSwiftBridgingHeader failed with a nonzero exit code
先ほどのエラーは消えたものの、新しいエラーが...

```
Command PrecompileSwiftBridgingHeader failed with a nonzero exit code
```

＜解決方法＞
[Target] -> Built Settings -> Objective-C Bridging Header の [target]-Bridging-Header.hを消す。
![スクリーンショット 2021-10-02 22.55.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573515/0bea1ed4-76dc-effa-6931-dd3e8aa5a3a9.png)

エラー出なくなりました！解決！
ABC221 C - Select Mul が解けた + おまけ B 問題

https://atcoder.jp/contests/abc221/tasks/abc221_c

![abc221_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/2d9ba9a5-40a9-d4e9-65d3-2b87d250d300.png)
![abc221_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/f8c252a9-cb58-9390-ebb8-de665546b483.png)
![abc221_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/8c25a786-5da3-6862-a9c1-1be2e0a5f468.png)
![abc221_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/0abb3bee-be9b-dd7b-69c8-34065153aa15.png)

全探索すれば、"0" が頭とか関係ないかな。
今回は最大値が欲しいわけだし。

あとは、入力を文字で受け取って
桁の中央で分割し、掛け併せて最大値を炙り出す。

```SelectMul.py
N = list(input())

from itertools import permutations
ans = 0
for i in permutations(N,len(N)):
    nums = list(i)
    A = int( "".join(nums[:len(N)//2]))
    B = int( "".join(nums[len(N)//2:]))
    if ans < A*B:
        ans = A*B
print(ans)
```

入力を中央を分割した A,B を掛けたら最大値になる根拠は
特に自分の中になかったが、そこは雰囲気で対応した。
運がよかったのかな。

##おまけ

https://atcoder.jp/contests/abc221/tasks/abc221_b

**高々1 回** ではなく、2回以上なら No という風に
書いて WA を引いた。

そう、敗因は**隣り合う**要素について高々1回なのだ。
残念。

当日は以下で通った。

```typo_r0.py
S = list(input())
T = list(input())
S_ = sorted(S)
T_ = sorted(T)
for a, b in zip(S_, T_):
    if a != b:
        print("No")
        exit()
 
cnt = 0
i = 0
lis = []
for s, t in zip(S, T):
    if s != t:
        lis.append(i)
        cnt += 1
        if cnt > 2:
            print("No")
            exit()
    i += 1
 
for i in range(len(lis)-1):
    if lis[i+1]-lis[i] != 1:
        print("No")
        exit()
 
print("Yes")
```

B で WA を引くと**焦る**
持ち直すために一個一個潰しながら丁寧に書いている様が見て取れる(笑)
後日、周囲の回答を読んで
面白い記述があったのでチラ見したあと、
イメージしながら書いてみた。

```type_r1.py
S = list(input())
T = list(input())

for i in range(len(S)-1):
    if S[i] != T[i]:
        if S[i] == T[i+1] and S[i+1] == T[i]:
            if i+1 == len(S)-1 or S[i+2:] == T[i+2:]:# <= ココ
                print("Yes")
                exit()
            else:
                print("No")
                exit()
        else:
            print("No")
            exit()
print("Yes")
```

上記のコメントにある**ココ**が素晴らしかった。
具体的には **S[i+2:] == T[i+2:]**。
交換後した以降の文字列が一致してたら print("Yes").
その通りだよなー

勉強になりました m(_ _)m

***

C もやり直したが B もやり直した。
連続する 2 文字に関して、S,T ともに
異なる場合は、1 反転させる。
念のため反転回数は数えておく。

反転回数が 2 回以上なら必然的に No
反転回数が 1 回以下で、かつ S == T なら Yes.

以下のような回答も書いてて面白いと思った。

```abc221c.py
S = list(input())
T = list(input())
cnt = 0
def check(S,T):#S==T or S != T を確認
    for s,t in zip(S,T):
        if s != t:
            return False
    return True

for i in range(len(S)-1):#連続する文字が異なる場合、反転
    if S[i] != T[i] and S[i+1] != T[i+1]:
        if S[i] == T[i+1] and S[i+1] == T[i]:
            T[i],T[i+1] = T[i+1],T[i]
            cnt += 1 #<= 反転回数を数える

if cnt <= 1 and check(S,T):
    print("Yes")
else:
    print("No")
```
様々な言語での日時表記

#背景
日時表現は割とよく使うけど、言語で書き方統一されてなくて正直やり辛いな～～
似てるけどちょっと違う、が多くてよくミスってしまうな〜〜
と思ったので覚書程度にまとめます。

というわけで、いろんな言語で現在の年月日・時刻を「2021年10月02日 23時00分00秒」の形式で出力します。
とりあえずはJava, Ruby, Python3, Go, php。適宜更新します

#Java(8以上)
SE8から加わったDate and Time APIのおかげで実装がぐっと楽になりました。

```Java:Main.java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
	public static void main(String[] args) {
		// SE8から加わったクラス。現在の日時を取得
		LocalDateTime dateTime = LocalDateTime.now();
		
		// 独自のフォーマットを準備する
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH時mm分ss秒");
		
		// 現在の日時に対するフォーマットの適用
		String showDate = fmt.format(dateTime);
		
		System.out.println(showDate);　
	}
}
```


#Ruby

```ruby
require "date"

# 現在日時の取得
t = Time.now

# フォーマットを適用して出力
p t.strftime("%Y年%m月%d日 %H時%M分%S秒")
```

`%Y`だと西暦4桁、`%y`だと西暦の下2桁になります
また`%H`は24時間制の時を指しますが、`%I`にすると12時間制の時を表します


#Python3

```Python
import datetime

# 現在日時の取得
datetime_now = datetime.datetime.now()
print(datetime_now.strftime('%Y年%m月%d日 %H時%M分%S秒'))
```

現在時刻を取得するのにdatetimeモジュールのdatetime.now()を使うのでdatetimeが続いてしまいます。
`import ... as ...`で別名をつけたい気持ちになります。

フォーマットはRubyととても似ていて、`%Y`だと西暦4桁、`%y`だと西暦の下2桁になります。
要注意なのは`%H`は24時間制の時を指しますが、12時間制の時の指定には`%h`を使います。

#Go
Goで日付を初めて実装したとき、文化の違いをひしひしと感じました。

```go
package main

import "fmt"
import "time"

func main(){
    // 現在の日時を取得
    t := time.Now()

    // 独自のフォーマットを準備する
    const DateFormat = "2006年01月02日 15時04分05秒"

    // 現在の日時に対するフォーマットの適用
    showDate := t.Format(DateFormat)

    fmt.Println(showDate)
}
```

フォーマットのクセが強すぎる
なぜこんなフォーマットなのかは[この記事](https://qiita.com/ruiu/items/5936b4c3bd6eb487c182)がわかりやすいので一読しておくと良いです

#php

```php
<?php

// フォーマットを指定して現在日時の取得
$today = date("Y年m月d日 H時i分s秒");

print_r($today);

?>
```

Pythonと似てる…というよりも、きっとPythonがPHPに寄せたんでしょう。
例によって`Y`だと西暦4桁、`y`だと西暦の下2桁になります。
一方で分を表すのには`i`を使います。
そういえばRubyでは大文字のIで12時間制の時を表しますね…うっかりミスりそう……要注意ですね
Denoでお試しMBTilesサーバーを書いた

## TL;DR

https://github.com/Kanahiro/deno-mbtiles-server-sample

```TypeScript
import { listenAndServe } from 'https://deno.land/std@0.109.0/http/server.ts';
import { DB } from 'https://deno.land/x/sqlite@v3.1.1/mod.ts';
import { expandGlob } from 'https://deno.land/std@0.109.0/fs/expand_glob.ts';
import { gunzip } from 'https://deno.land/x/compress@v0.4.1/mod.ts';

// make connections to .MBTiles files in './tiles'
const connections: { [key: string]: DB } = {};
for await (const mbtiles of expandGlob('tiles/*.mbtiles')) {
    connections[mbtiles.name.split('.')[0]] = new DB(mbtiles.path);
}

listenAndServe(':8000', (request) => {
    const [tilename, z, x, y] = request.url.split('/').slice(-4);
    const fy = Math.pow(2, Number(z)) - Number(y.split('.')[0]) - 1;

    if (typeof connections[tilename] === 'undefined') {
        return new Response('mbtiles is not exist', { status: 404 });
    }

    const pbf = connections[tilename].query(
        `select tile_data from tiles where zoom_level=${z} and tile_column=${x} and tile_row=${fy};`,
    );
    if (pbf.length === 0) {
        return new Response('tile is not exist', { status: 404 });
    }

    return new Response(gunzip(pbf[0][0] as Uint8Array));
});


```

- 30行くらいしか書いてない
- HTTPサーバーのAPIの変更が激しくてドキュメントがないっぽい
- MapboxVectorTile形式にしか対応してない（画像には非対応）


## 使い方

1. copy MBTIles files into tiles directory.
2. launch server

```sh
deno run --allow-net --allow-read --allow-write server.ts
```
【Git】git reset HEADでgit addしたファイルの変更を取り消そう

#はじめに
今回は、`git reset HEAD`について見ていきましょう。

#git reset HEAD
`git reset HEAD`コマンドを使うと、`git add`によってステージングされたファイルやディレクトリの変更を取り消すことができます。
具体的には、現在のブランチの直前のコミットの情報をもって、ステージのファイルやディレクトリを上書きすることで、変更を取り消していきます。
取り消されるのはあくまでステージのファイルやディレクトであって、ワークツリーのファイルやディレクトリの変更は取り消されません！！

```git:ターミナル
git reset HEAD <ファイル名>or<ディレクトリ名>
git reset HEAD .
```

このコマンドを実行すると、以下のような文が出力され、ステージを変更から取り消されたことが分かります。

```git:ターミナル
Unstaged changes after reset:
M       ファイル名
```

前述したように、ワークツリーのファイルの変更は取り消されていないので、そっちの変更も取り消したいのであれば、`git checkout`コマンドを使って取り消す必要があります。

###参考
Udemy 「Git:もう怖くないGit！チーム開発で必要なGitを完全マスター」 山浦 清透さん
コンピュータサイエンス基礎(1)

web系エンジニアにコンピュータサイエンスの基礎知識が必要と思い、本日から学習しようと思います。

今日はn進数とシフト演算、2進数のかけ算・わり算を学習し、2進数・8進数・16進数の基数変換の問題に論理シフト・算術シフトの問題を解きました。