OmniAICreator/Qiita-1.07M huggingface dataset:
Cypressでカスタムコマンドが認識されない

# 詰まったポイント

Cypressでcommands.jsにカスタムコマンドを作り、テストコードで呼び出しを試みるとカスタムコマンドが認識されなかった。

```javascript:support/commands.js
Cypress.Commands.add('addFiveToDo',() =>{
    cy.get('.new-todo').as('toDoInput')

    const TODO_ITEM_ONE = 'walk a dog1'
    const TODO_ITEM_TWO = 'walk a dog2'
    const TODO_ITEM_THREE = 'walk a dog3'
    const TODO_ITEM_FOUR = 'walk a dog4'
    const TODO_ITEM_FIVE = 'walk a dog5'

    cy.get('@toDoInput').type(`${TODO_ITEM_ONE}{enter}`)
    cy.get('@toDoInput').type(`${TODO_ITEM_TWO}{enter}`)
    cy.get('@toDoInput').type(`${TODO_ITEM_THREE}{enter}`)
    cy.get('@toDoInput').type(`${TODO_ITEM_FOUR}{enter}`)
    cy.get('@toDoInput').type(`${TODO_ITEM_FIVE}{enter}`)

} )
```

```javascript:integration/practice.spec.js
 it('adds five todos', () => {
   cy.addFiveTodo()
    cy.get('.todo-list li').should('have.length', 5)
  })
```

# 解決法

カスタムコマンドを一度関数にしてCypress.addすることで解決。


```javascript:support/commands.js
function addFiveToDo(){
    cy.get('.new-todo').as('toDoInput')

    const TODO_ITEM_ONE = 'walk a dog1'
    const TODO_ITEM_TWO = 'walk a dog2'
    const TODO_ITEM_THREE = 'walk a dog3'
    const TODO_ITEM_FOUR = 'walk a dog4'
    const TODO_ITEM_FIVE = 'walk a dog5'

    cy.get('@toDoInput').type(`${TODO_ITEM_ONE}{enter}`)
    cy.get('@toDoInput').type(`${TODO_ITEM_TWO}{enter}`)
    cy.get('@toDoInput').type(`${TODO_ITEM_THREE}{enter}`)
    cy.get('@toDoInput').type(`${TODO_ITEM_FOUR}{enter}`)
    cy.get('@toDoInput').type(`${TODO_ITEM_FIVE}{enter}`)

}

Cypress.Commands.add('addFiveTodo', addFiveToDo)

```

# 参考にしたサイト
https://github.com/cypress-io/cypress-documentation/issues/2565
【トリビアのDelta Lake】#6 AWS S3にあるZipファイルをPythonで解凍してDelta Lakeにブチ込む

「シャ！S3に生データ入れたぜ！あとはspark.read.csvで楽勝やな！って、あれ？？」


…CSVが存在するはずだったそのS3プレフィックスには、謎のZipファイルが置かれていました。

# Zipファイルで固められている
おかしい。
慌てて、S3にあるZipファイルをダウンロードします。

それを解凍すると、確かにCSVファイルが存在します。これを読みたいだけなのに、自動取得の方法を取るとS3にはZipファイルとして置かれるみたい…

あんまりないシチュエーションだと思いますが、こういうときはどうすればいいのでしょうか。

# ドキュメントを漁るも…
Pysparkに関連するドキュメントを漁りまくり、結論、「**PysparkはZipに対応していない**」。

参考記事：

https://qiita.com/manabian/items/04df5d5c88831590be89

https://qiita.com/taka_yayoi/items/0197d5c985089255f16a

.gzには対応しているが、.gzipや.zipには未対応とのこと。
はい、試合終了！

…とはなりません。なんとかしてPythonでZipを溶かす必要に迫られました。

# 困ったときのPandas展開
やはり、困ったときはPandas先輩の出番です。
Pandasのread_csvにはめちゃくちゃ多くの引数があり、そのなかの「**compression='zip'**」がどんぴしゃり。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

さらには今回データソースがS3にあるので、それを見に行くのに必要なライブラリも数点追加して、サンプルコードとしてはこんな感じに。
```python:melt_zip.py
import zipfile
import pandas as pd
import fsspec
import s3fs

pandas_df = pd.read_csv("s3://<bucket>/<prefix>/sample.zip",compression = 'zip')
```

ちゃんとファイル実態までS3パスを書くことがキモです。
もし、複数プレフィックスにまたがってデータを読み込みたいときは、/と*をうまく使ってパスを書けばイケると思います。

また、Pandasのread_jsonでも同じ引数があったので、JsonがZipで固められている場合でも泣かなくてすみますね…！

https://pandas.pydata.org/docs/reference/api/pandas.read_json.html
# Into your Delta Lake
Pandasデータフレームとして定義できてしまえば、あとはこっちのもの。
spark.createDataFrame()でSparkDataFrameに変更し、あとはいつもの方法で**Into your Delta Lake**です！

PandasとかSparkとかの変換については、以前まとめましたのでご覧くださいませ。

https://qiita.com/yuulian/items/836fad4aab6c7cf19ed1

# このシリーズの目的
クラウドストレージに蓄積された生データ（CSV,JSON等）を加工するのに必要なPysparkの知識を溜めていく、まさにPysparkに関するトリビアのDalta Lakeを目指しています。
Pysparkに関する記事はまだ海外のものが多く、このシリーズが私のような国内の駆け出しデータエンジニアの一助になることを願っています。
ダミーファイルを大量に作成する

Linux環境でダミーファイルをまあまあの数作成する必要がある場合の自分用メモ。
大昔、某Firewallが特定の数字パターンを持つファイルのみFTP送信しないという、そんなことある！？問題に遭遇して以来、ファイル送受信系で事ある毎にダミーファイルを作ることにしているため。
数年に一度くらいの作業なのでいつもExcelで連番作ってtouchコマンドを1000行書いたスクリプト書いてた。
数年ぶりにLinuxを触ることになったがもうちょい賢い方法あるだろと思って調べた。
巨大なファイルが必要ならddコマンドがいいのだろうが、覚えてられないし100バイト程度あればいい。

# 要件
+ ファイルサイズは1バイト以上
lsコマンドで一目でサイズ確認できるようキリのいいサイズに統一
+ ファイル内容は何でもいい
"0"埋め

# 手順
```
$ for i in {1..100}; do echo -n "0" >> test0001.dat; done
$ for i in {0002..1000}; do cp test0001.dat test${i}.dat; done
```
0バイトでよければtouchコマンドだけで済むね。
```
$ touch test{0001..1000}.dat
```
VirtualBoxでゲストOS(CentOS7)同士のNW疎通をとれるようにする

# サマリ
VirtualBoxで2つ以上のゲストOS同士（今回はCentOS7）で疎通をとれるように設定を行いました。

# 背景
基本的に勉強や遊びではVirtualBoxでやることが多いのですが、ゲストOS間でPing打ったり、通信を行いたいときに設定方法がいまいちわかっていなかったので今回対応することにしました。

# ゴール
VirtualBoxで作成した二つのゲストOS（CentOS7）でPingが通るようにする。

# 対象読者
- 自分自身（備忘のため）
- VirtualBox初心者の方

# 前提
- VirtualBoxのインストールが完了している
- ゲストOSのインストールが完了している
- 基本的なコマンドラインの操作が可能

# 環境
- ホストOS：Window10 Home
- VirtualBox：バージョン6.1.14 r140239(Qt5.6.2)
- VirtualBox内のCentOS：CentOS7

# 手順
基本的には二つの記事を参考にさせていただきました。
ありがとうございました。

考え方としては、
デフォルトだとNAT設定になっており、ゲストOS-インターネットのみ通信可能でゲストOS同士やゲストOS-ホストOSでの通信は不可の状態になっているため、
内部ネットワーク用の設定を行い、各ゲストに固定IPを振ります。
（理解が不十分なのでざっくりイメージですが…）

大きな流れは以下です。
- VirtualBox側で各ゲストに内部ネットワーク用のアダプターを作成する。
- それぞれのゲストで内部ネットワーク用のNICを作成、固定IPを振る（固定出なくていいのかもしれませんが今回はただPingをうつだけでなく、別用途での通信も考えており固定にしました。）

### VirtualBoxの設定

https://qiita.com/areaz_/items/c9075f7a0b3e147e92f2

まずは上記の記事を参考に、VirtualBoxの設定を行います。
> ①対象となるゲストOSを選択します。
> ②「設定」ボタンをクリックします。
> ①「ネットワーク」をクリックする
> ②「アダプター２」をクリックする
> ③「ネットワークアダプターを有効化」にチェックして、「割り当て」に「内部ネットワーク」を選択する
> ④「OK」ボタンをクリックする

ここで地味に忘れがちなのが、**対象のゲストOSの電源を落とす**ことです。
電源を落としておかないとアダプター２が選択できませんのでご注意ください。

### ゲストOS内の設定

https://www.kakiro-web.com/memo/centos-network-setting-nat-hostonly-2.html

まずは、以下の通りコマンドを打ち設定ファイル`/etc/sysconfig/network-scripts/ifcfg-enp0s8`を作成します。

```
# nmcli connection add type ethernet con-name enp0s8 ifname enp0s8
```

調べたサイトによってはテキストエディタで直接設定ファイルを作成する内容のものもありました。
試しにやってみましたが、設定内容が不適切だったのかうまく疎通が取れなかったので、このやり方がシンプルでいいかと思いました。


続いて、IPアドレスを設定します。
```
# nmcli connection modify enp0s9 ipv4.method manual ipv4.addresses xxx.xxx.xxx.xxx/xx
```

最後に、ネットワーク設定を有効にします。
```
# systemctl restart network.service
```

これをもう1ゲストでも行います。



# 結果
- ひとまず、NWレベルでの疎通は通りました。（よかった…）
![pingOK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/e7aae326-2867-40d3-6dd3-020233f42cf1.png)
- ゲスト間のPingは飛ぶし、インターネットにもつながる状態

# 学び
- NAT用の設定と内部ネットワーク用の設定は共存できる（あたまり前ですかね）
- 固定IP設定もnmcliコマンドでできる

# まとめ
- なんだかんだで長らく（1年近く）対処しないまま来ていたので（おい）、改めて今回対処できてよかったです。
- まだPingが通っただけなので、L7レベルでの疎通まで通るのかはなんとも言えないですが、問題が出た際はまた対処・記事にしたいと思います。
- nmcliコマンドもそうですし、まだVirtualBox自体やネットワークの理解も浅いため、今後もいろいろ触りながら勉強していきたいです。

# 参考
nmcli関連のコマンドはこちらを参考にさせていただきました。

https://qiita.com/yasushi-jp/items/4c8941a66892c621bdec

VirtualBoxののネットワーク設定周りはこちらの記事が非常にイメージつかみやすかったです。

https://qiita.com/feifo/items/0fde474005589afcff68
オルタネートルート とは

## 勉強前イメージ

ルートを変える的な？

## 調査

### オルタネートルート とは

Alternate Roots と書き、独自の体系を持つドメイン空間のことを指します。
元々ドメインは世界中のどこからの問い合わせでも同じものを表示する必要があります。
そのためにDNSはICANNが管理する階層構造を保つ必要がありますが、
オルタネートルートは、独自のルートサーバを立ち上げてICANNが管理していないドメイン空間を構築したものです。
ドメイン名の一意性が保証できなくなってしまいます。

## 勉強後イメージ

DNSじゃない、独自のドメイン空間を別で作ってるってことか・・・
そんな事できるのん、、、

## 参考

- [オルタネート・ルート（Alternate Roots）](https://jprs.jp/glossary/index.php?ID=0069)
自動テストツールCypressでfor文を使う方法

# 詰まったポイント

Cypressの練習用アプリでのテスト実装の練習中、複数のリストにまとめてチェックを入れたい場面に遭遇。

![スクリーンショット 2022-04-29 13.24.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632129/1916e7a9-ce4a-be7e-950b-3ba12cd13b40.png)

公式がCypressは基本的にJavaScriptであると謳っているので、以下の繰り返し処理を書いてみたが動作しない。

```javascript

    for(let i = 1; i < 5; i++){
      cy.get('.todo-list li').eq(i).find('.toggle').check()
    }
```

# Cypressでfor文を使う

調べてみたところ、CypressではLodashがデフォルトでバンドルされており、以下のような書くことで解決。

```javascript
 Cypress._.times(5, (k) => {
      cy.get('.todo-list li').eq(k).find('.toggle').check()
 })

```

まとめてチェックを入れられた！

![スクリーンショット 2022-04-29 13.34.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632129/7821acb8-a479-f61b-45c3-025096f636c3.png)


# 参照先
解決するのに参考になったstackOverFlowの記事です。
https://stackoverflow.com/questions/52212868/cypress-io-writing-a-for-loop
SSDを換装した(Acronis True Image WD Edition)

# 前提条件
・OS：Windows10
・m.2 SSDを購入したので、換装手順を備忘録としてまとめます。
・所要時間：225GBくらいで1h程度でした。
・EaseUS以外の手順が少なかったので、作成しました。
・環境によって異なる点が多いので、あくまで参照程度としてご認識ください。

# 手順
+ [Acronis True Image WD Editionのダウンロード](https://www.westerndigital.com/ja-jp/support/software/acronis)

+ ツールを起動後、ディスクのクローン作成を押す
+ ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482566/b17c803c-acba-d48e-46fa-6775e7830fd3.png)


+ クローンモード（自動）を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482566/d582d6f1-705f-cebd-a822-7b35dbef4972.png)

+ ソースディスク（換装元-データが入っているディスク）を選択し、次へを選択
+ ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482566/f6e20ffc-a292-607e-d4f8-f2657a190f66.png)

+ ターゲットディスク（換装先-空のディスク）を選択し、次へを選択
+ 実行が完了したらクローンは完了
+ PCをシャットダウン
+ PCを起動後、BIOS画面でDISKの起動優先順位を変更する

#### 変更前起動順
1. 換装前のDISK
2. 換装後のDISK
### ↓
#### 変更後起動順
1. 換装後のDISK
2. 換装後のDISK

:::note warn
警告
起動後のBIOS画面を表示する方法は、マザーボードの種類によって違います。私はF12で起動しました。
ご利用のマザーボードのサポートページを確認し、
DISKの起動順序変更手順を確認してください。
:::


+ Windows起動後、換装前のDISKをフォーマットする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482566/fab0ab1f-704b-1b88-fce6-ae19e2784f38.png)

:::note warn
警告
削除前にバックアップを取っておくことを推奨します。
:::

+ 完了！お疲れさまでした！

# 悩んだところ
起動順序変更をしなかったので、BIOSにリカバリするか聞かれました。。
JavaでPDFに複数のヘッダーを追加する方法

ヘッダーは、多くの場合、ドキュメントの追加情報を表示するために使用されます。時間、グラフィックス、会社のロゴ、ドキュメントのタイトル、ファイル名、作成者名などを挿入できます。この記事では、[Spire.PDF for Java](https://www.e-iceblue.com/Introduce/pdf-for-java.html)を使用してJavaプログラムでPDFに複数のヘッダーを追加する方法について説明します。
Spire.PDF for Javaを追加する
まず、Spire.PDF for JavaをJavaプロジェクトに追加する必要があります。Jar ファイルは、このリンクからダウンロードできます。Mavenを使用する場合は、次のコードをプロジェクトの pom.xmlファイルに追加する必要があります。
```
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.cn/nexus/content/groups/public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.pdf</artifactId>
        <version>5.2.3</version>
    </dependency>
</dependencies>
```
## ヘッダーを追加する
**Javaコード一覧**
```
import com.spire.pdf.*;
import com.spire.pdf.graphics.*;
import java.awt.*;
import java.awt.geom.*;

public class addDifferentHeaders {
    public static void main(String[] args) {
        String output = "output/addDifferentHeaders.pdf";

        //サンプルPDFドキュメントをロードする
        PdfDocument doc = new PdfDocument();
        doc.loadFromFile("Sample.pdf");
        String header1 = "Add header by Spire.PDF";
        String header2 = "Different header";

        //スタイルを定義する
        PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial",  Font.BOLD,12));
        PdfBrush brush= PdfBrushes.getBlue();
        Rectangle2D rect = new Rectangle2D.Float();
        Dimension2D dimension2D = new Dimension();
        dimension2D.setSize(doc.getPageSettings().getSize().getWidth(),50f);
        rect.setFrame(new Point2D.Float(0, 20), dimension2D);
        PdfStringFormat format=new PdfStringFormat();
        format.setAlignment(PdfTextAlignment.Center);
        //最初のページにヘッダーを追加する
        doc.getPages().get(0).getCanvas().drawString(header1,font,brush,rect,format);

        //2ページ目のヘッダーを追加する
        format.setAlignment( PdfTextAlignment.Left);
        doc.getPages().get(1).getCanvas().drawString(header2, font, brush, rect, format);

        //ドキュメントを保存する
        doc.saveToFile(output, FileFormat.PDF);
    }
}
```
**スクリーンショット一覧**
ヘッダーを追加したPDFドキュメント
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/dab43cbc-b1f5-cd64-16e8-31efc2d89c30.png)

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/94b9081d-0787-9fa4-d990-58de897fa97d.png)

今回のJavaを使用してPDFに複数のヘッダーを追加する方法は以上でした。最後まで読んでいただきありがとうございました。
入社3年目、業務以外の知識がない自分がGWを捧げてサービス・アプリケーションを勉強してみた！〜0日目〜

# 進捗
https://qiita.com/hugo-crt/items/3cebbbf16db1d2fde063

https://qiita.com/hugo-crt/items/40c4bcb883c74085e539

https://qiita.com/hugo-crt/items/662eb5726d7d12b83bfe

https://qiita.com/hugo-crt/items/61ad9a60d599ee5d9b47

https://qiita.com/hugo-crt/items/7819a61ea4cb63532787

https://qiita.com/hugo-crt/items/aa128860f7b0f494e6e3

https://qiita.com/hugo-crt/items/24c4147d851cf30bcf22

# はじめに

入社3年目、新卒入社の頃から気持ちは変わらないものの、
徐々に自分の裁量で仕事をできるようになっている私。

通勤電車で日経新聞を読むサラリーマンを横目に、
Quitaで目についた記事を読んではストックし、
頭でっかちになっている私。

〇〇なサービスがあって、こういうのやってみたいんですよね〜と
会社の先輩にイキって言ってしまうが、
実際に触ってみたら何もできないであろう。

たまにはINPUTしたことをここに吐き出して自分の血肉となればと思い、
GWを捧げて学習したことを記事にしようと思いつきました！

業務内外のスキルアップにしろ、転職にしろ、
故スティーブ・ジョブズ氏が言った、__点がいつか線になる__　という言葉が
自分の数少ない経験でも共感できることがあり、
自分にとって学んだこと以上の付加価値になると信じてお勉強します！

※ちなみに今回学習するのはAWS（クラウドプラクティショナーレベル）、Git（初心者レベルのハンズオン）、
Docker（これまた初心者レベルのハンズオン）、その他（未定）と、
メジャーかつ　__えっ、いまさら！？__　というような内容が対象です。
サービスを作るための逆算的な選定理由ではなく、業務外の世界を覗き見に行く感じです。

どうか温かい目で読んでいただいて、成長につながるようなコメントをいただければ幸いです。


# 予定

- AWS
  1. ちょっと前に触り始めたAWS Cloud Quest: Cloud Practitioner
  まだ何項目か残っているけど、これは今回記事にはしません。
__→2022/04/28 追記：　全項目終了するとCPの模擬試験をタダで受けれるフリーコードもらえるんですね！嬉しい！__

  2. クラウドプラクティショナーの公式ビデオを見てお勉強
  おそらくこれはハンズオンなもののため、実践的な感じだと思われる
（まだ試聴していないので一体どんなものなのかはわからないというのが現状）
>【視聴予定一覧】
>https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/
>https://aws.amazon.com/jp/getting-started/hands-on/?awsf.getting-started-category=*all&awsf.getting-started-level=*all&awsf.getting-started-content-type=*all
>https://aws.amazon.com/jp/training/course-descriptions/cloud-practitioner-essentials/

- Git
　1. ハンズオンを見て一通りの扱い方を学習
 >ハンズオン
 >https://qiita.com/TakumaKurosawa/items/79a75026327d8deb9c04
 >https://qiita.com/segur/items/1fb600400230a037587d
 >参考資料
 https://speakerdeck.com/brainpadpr/git-hands-on

- Docker
 1. ハンズオンを見て一通りの扱い方を学習
 最終的には開発環境とか作れたらいいなーと思います。
  >https://deepsquare.jp/2020/02/docker01/

- その他
　　1. ハッキング・ラボのつくりかた 仮想環境におけるハッカー体験学習　という書籍でお勉強
　　事前にお断りしておきますが、法を犯すような行為をしたいと思ったのではなく、
　　最近読んでいる　__王様達のヴァイキング__　という漫画から、
　　__全く知らないセキュリティに関連することにも足を伸ばして勉強してみたいという意図です。__ 
　　読み進めている感じ、ところどころMacに読み替えて進める予定です。

　　　2. 時間が余れば業務に関連するお勉強
　　　Oracleのブロンズ本をそろそろ資格手当てに昇華させるべく、
　　　何かしらの記事にする予定。
　　　1冊を要約するため、GW中には終わらない予感がしています・・・
　　　
 
# 最後に

予定として書き出しましたが、参考URLなどは増えていくと思います。
どうしても知識が不足していて読み解けない可能性があるからです。
記事の説明がわかりづらいから、という意味ではなく、
初学者としてどのように調べて理解したかの道のりを
私と同じような初学者の方にシェアできたら知識も身について一石二鳥！といった具合です。
pythonで気軽にwebスクレイピング


### python でwebスクレイピングを実施してみたい


webスクレイピングとは
（プログラムで）ホームページの情報を集めることです

https://wa3.i-3-i.info/word12494.html


本記事のタイトルでも　ある「気軽に」という　ポイントがありますので
python の実行環境は　googleアカウントがあれば実施可能な
Google Colaboratory
を利用したいと思います

https://aiacademy.jp/media/?p=1037

Google Colaboratory（グーグル・コラボレイトリーもしくはコラボラトリー）とは、Googleが機械学習の教育及び研究用に提供しているインストール不要かつ、すぐにPythonや機械学習・深層学習の環境を整えることが出来る無料のサービスです

上記の記事を参照してノートブックの作成を実施します


### CEML（臨床工学技士機械学習研究会）のサイトをスクレイピング
私が機械学習を使えるようになったきっかけ
https://sites.google.com/view/ce-machine-learning-lab/home
CEML（臨床工学技士機械学習研究会）
のサイトの（プログラムで）ホームページ情報を集めてみるソースコードを書いてみます

```
!pip install requests
```

まずはrequestsインストールしました
次にrequestを使用します

```

from urllib import request

response = request.urlopen('https://sites.google.com/view/ce-machine-learning-lab/home')
content = response.read()
response.close()
html = content.decode()

title = html.split('<title>')[1].split('</title')[0]
print(title)

```


### サードパーティライブラリ

上記のソースコードで使用されているのは
request　という　サードパーティライブラリ　です

サードパーティライブラリ
Pythonで強力にカスタマイズされたライブラリで

https://insource-mkd.co.jp/staff-blog/27669.html

代表的なサードパーティライブラリ	用途　の例でいうと
numpy	数値計算
matplotlib	グラフ作成
pandas	データ操作、データ集計
Request	リクエストモジュール
BeautifulSoup	スクレイピングライブラリ
scikit-learn	機械学習ライブラリ
tensorflow	深層学習ライブラリ
jupyter	実行環境、データ分析

となっております


サードパーティライブラリのrequestを使うとよりシンプルに
ホームページ情報を集めてみるソースコードが記載可能です

### requests.get()を使用してみる

requests.get()はHTTPのGETメソッドに相当します
HTTPはインターネットをするときに使うお約束事「のひとつ」です

```
import requests
url = 'https://sites.google.com/view/ce-machine-learning-lab/home'
response = requests.get(url)

response

response.text[:500]
```


HTMLファイルの内容は文字のみで構成されたテキストデータで
地の文とタグが混在した状態で表示されます

https://e-words.jp/w/HTML%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.html


### Beautiful Soup でHTMLから 必要なデータを抜き出す

Beautiful SoupはHTMLファイルなどからデータを抽出するためのPythonライブラリです

https://atmarkit.itmedia.co.jp/ait/articles/1910/18/news015.html


Google Colaboratoryを利用して　
先ほどスクレイピングしたHTMLデータを
Beautiful Soupでデータ抽出を　実行します

```
!pip install beautifulsoup4
```
まずはBeautiful Soupをインストールしました
次にBeautiful Soupを使用します

```
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, "html.parser")
soup 
```

HTML文書をBeautifulSoupの第1引数に渡して、第2引数に使用するパーサーを指定するだけで解析をしてくれます

HTMLパーサーは、HTML文書を解析して、プログラム内で扱いやすいデータに置き換える処理を行います

### まとめ

今回　
Google Colaboratoryを利用して　
CEML（臨床工学技士機械学習研究会）のサイトをスクレイピングしました

その後、スクレイピングしたHTMLデータを
Beautiful Soupでデータ抽出を実行しました


次回はyahooニュースをスクレイピングして形態素解析をします

https://qiita.com/TaichiEndoh/items/85e20bd704acb65b55ff
これを読めば一撃で理解できる！　Laravel のデバック(dd)の使い方!

# ddとは
***ddはLaravelで開発する時にデバック***で使います。
***実際に処理がされているのかを確認してエラーの原因などを探して***いきます。
Rubyでいうところのbinding.pry、JavaScriptでいうところのdebuggerですね。

# 使い方
```dd($変数)```をコードに入れていきます。
下のコードを例にみていきます。


# ユーザー認証
```FolderController.php
public function index()
    {
// ログイン中のユーザー情報
        $folder = Auth::user();
        dd(Auth::user());
        return view('folder.index')->with('folder',$folder);
}
```
ddを入れてみると下のようになります。
認証ユーザーがちゃんと通って***処理がされていれば下のようになりますし処理されていなければ
下のようになりません。***


![スクリーンショット 2022-04-29 11.24.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/a259b965-aab1-ce7d-5f30-de3aa40f173c.png)


他にもddを入れてみます。

```FolderController.php
public function create(Request $request)
    {  
        //フォルダモデルのインスタンスを作成
        $folder = new Folder();
        dd($folders);
        //タイトルに入力値を入れる
        $folder->title = $request->title;
        return view('folder.create');
        //インスタンスの状態DBに書き込む
        $folder->save();
        

        return redirect()->route('tasks.index',[
            'id' => $folder->id,
        ]);
    } 
```

![スクリーンショット 2022-04-29 11.36.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/a9a7218b-a7e4-5ffb-f805-5f50716ea853.png)








# エラーの原因を見つける
ddを入れて処理が止まれば　ddより上に問題はない。
ddを入れて処理が止まらない場合は処理が走っていないのでddの上に
問題があったりします。


# 資料
https://qiita.com/ky0he1_0/items/ba596b57d6027cc21166
『良いコード/悪いコードで学ぶ設計入門』著者トークに行ってきたので学びを綴る


# はじめに
https://gihyo.jp/book/2022/978-4-297-12783-1

https://modeling-how-to-learn.connpass.com/event/242976/?utm_campaign=event_finish&utm_source=notifications&utm_medium=email&utm_content=title_link

私は1年目のエンジニアとして、保守性や拡張性を意識したコーディングができるようになりたいと思っていた。そんな私にとってこの本は発売前から非常に魅力的であった。

たまたま外出中の妻に池袋のジュンク堂へ寄ってもらい、先行発売されていたこの本を無事ご購入。一応トークイベントまでに一読は済ませていた。

以下では基本的にはトークイベントでの学びを書いていくが、若干本の内容にも言及している。


# 意外と設計をするということが当たり前になっていない

著者の仙塲さん（以下、ミノ駆動さん）のお話を聞いてとても意外に思ったのが、設計やリファクタリングに対してネガティブな印象を持つ人が結構存在するということである。
良い設計をしていこうというムーブはエンジニア界にまだまだ浸透していないようなのだ。

私はこれまで勝手に、クリーンアーキテクチャなどの設計やリーダブルコードといった知識は、エンジニアにとって普通に知っているべき内容だと思っていた。

スライドでは「そもそも変更容易性すら認識されているか疑問」であるとも書かれていた。衝撃的だった。

# 人間にも悪魔は取り憑く

ミノ駆動さんは昔、自身が一生懸命リファクタしたコードを、後日別の人によって元の悪しきコードに書き直されるといういわば「逆リファクタリング」を経験したことがあるとお話しされていた。

ところで、この本にはよく「悪魔」という言葉が出てくる。

本の冒頭に

> 本書では、開発力をおとしめ、ソフトウェアの成長を阻害する、設計や実装上の問題を「悪魔」とたとえます。
> 

というふうに書かれている。

悪しきコードや設計が「悪魔」と例えられているが、逆リファクタリングを行ったエンジニアもまた悪魔的である。

コーディングの理想形を知らないというのに加えて、自分がよくわかっていない、理解できないものに対する抵抗感というのも悪魔を産む要因の一つとなっているのかもしれない。

ならばシンプルにこの本などでコードの理想形やアンチパターンを知ることでこのような惨状を防げるのではと思いきや、結構問題は複雑な模様。

会社の文化や仲間達の価値観といった環境によって悪魔が飼い慣らされる可能性もある。

# これは「仲間を増やす本」である

「仲間を増やす本」というのは、zoomのコメントの中でとてもいいフレーズだなと思い、引用させていただいた。

組織内において、一人が設計に対して意欲的だったとしても他のメンバーが消極的ならあまり効果的ではない。ミノ駆動さんが昔社内で設計をもっと良くしていきたいという話をしたら「学者風情」などと罵られうまく話が進まなかったというようなお話しがあった。

これは設計を良くしていこうという仲間がいれば起きなかったはずである。

この本によって、エンジニア界全体に設計を浸透させていきたいという趣旨のお話もあった。

私も、この本でもっと勉強して「仲間」になれるように頑張りたい。

# あなたには現状を打破する力がある

最近読んだ達人プログラマーから引用した。ミノ駆動さんのリファクタリングを反対された話をきいてパッとこのフレーズが思い浮かんだ。

https://www.ohmsha.co.jp/book/9784274226298/

リファクタリングによって開発スピードが落ちるというのも理解できる。

しかし、だからといって何もしないのではなく、どうしたらより良い設計やコーディングができるかを少しでも考える努力をすることが大事だと思った。

# アプリケーションアーキテクト面白そう

個人的に、今後のキャリアパスの方向性の一つとしてアプリケーションアーキテクトを知ることができてとてもよかった。

### 技術的負債によって経済的損失が生まれる

2025年以降、技術的負債によって年間12兆円もの経済損失があるという。アーキテクトとして技術的負債をなくすべく働くこと自体に社会貢献性がある。

### エンジニアとしての知識、経験といった持てる力の全てを設計に落とし込んでいくプロセスが楽しそう

本の最後の方でミノ駆動さんが設計にのめり込んでいった経緯が語られるところがある。

> 複雑で混乱したロジックがきれいに整頓されていく有様があまりにもおもしろかった
> 

ということが書いてあって、とてもやりがいがありそうだなと思った。

### 負けず嫌いな性分が活きそう

ミノ駆動さんは自身が負けず嫌いだったからこそ悪しきコードたちと戦い続けることができたのではないだろうかとお話しされていた。

設計に対する意識が低い人たちや悪しきコードとの戦いは、一筋縄にはいかないと思う。それでも周囲の環境や、自分自身に負けたくないという気持ちを持って、逆境を乗り越えていくプロセスを楽しめるのだと思う。

そういったチャレンジングな日々を過ごしてみたいと心から思えた。
可変長引数でディレクトリ、ファイル名を結合する

phpでディレクトリを複数結合してパスを取得するfunctionを作りました。
引数の前後のスラッシュを意識する必要はありません。

```php
	function __getPath() {
		return preg_replace('/(?<!:)\/+/', '/', implode('/', array_filter(array_map('trim', func_get_args()), 'strlen')));
	}
```

使用例
```php
	echo __getPath('/', '/images/common/', 'logo', 'thumb_logo_bsquare.svg');
```

結果
```
	/images/common/logo/thumb_logo_bsquare.svg
```

引数にnullやスペース、スラッシュが複数入っていても大丈夫です。
```php
	echo __getPath( null, '', '  ', '///images/common/', 'logo', 'thumb_logo_bsquare.svg')；
```

結果
```
	/images/common/logo/thumb_logo_bsquare.svg
```

先頭にスラッシュがない場合は相対パスとして出力されます。
```php
	echo __getPath('', 'images/common/', 'logo', 'thumb_logo_bsquare.svg')；
```

結果
```
	images/common/logo/thumb_logo_bsquare.svg
```

http(s)から始まる場合
```php
	echo __getPath('https://www.sample.com/', 'images/common/', 'logo', 'thumb_logo_bsquare.svg')；
```

結果
```
	https://www.sample.com/images/common/logo/thumb_logo_bsquare.svg
```

以上です。
EC2+Mysql8.0+Railsまでの構築の流れ

# 概要
EC2にMysql,Ruby,nginxを構築しELB,RDSとの連携まで行い完成を目指す。

#### 構築の際の環境
- Mac (M1 MacbookAir)
- OS : Amazon Linux2
- rbenv ver : 1.2.0
- Ruby ver : 3.1.2
- rails ver : 
- mysql ver : 8.0.28

#### 前提準備 (作成済みなもの）
- VPC×1
- Subnet(public×2 , private×2)
- EC2×1
- RDS×1
- route table
- internet Gateway
- seculity group (EC2用)×1
- seculity group (RDS用)×1
- githubに新規リモートリポジトリ×1
- EC2へのssh接続設定済み
- GitHubのターミナルへのインストー設定済み

## 設定用ツールのインストール
Rails搭載JavaScriptのパッケージを管理するためのパッケージマネージャ
```ruby:
$ sudo yum -y update
$ sudo yum -y install git make gcc-c++ patch libyaml-devel libffi-devel libicu-devel zlib-devel readline-devel libxml2-devel libxslt-devel ImageMagick ImageMagick-devel openssl-devel libcurl libcurl-devel curl
```

## node.jsをインストール
サーバーサイドで動くJavaScriptのパッケージ
```ruby:
$ sudo curl -sL https://rpm.nodesource.com/setup_10.x | sudo bash -
$ sudo yum -y install nodejs
```

## Yarnをインストール
```ruby:
$ sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo
$ sudo yum -y install yarn
```

## rbenvとruby-buildをインストール
```rust:
# rbenvのインストール
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv

# パスを通す(どのディレクトリからもアプリケーションを呼び出せる状態にする)
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile

# rbenvを呼び出すための記述
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# bash_profileの読み込み
$ source .bash_profile

# ruby-buildのインストール
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

# rehashを行う
$ rbenv rehash
```

## Rubyのインストール
Rubyのバージョンは自分の求める環境に合わせる.
rubyのインストールは時間がかかるが、エラーでは無いのでご安心を。
```ruby:
$ rbenv install -v 
$ rbenv global  2.6.5
$ rbenv rehash
$ ruby -v 
```


## bundlerのインストール
```ruby:
$ gem install bundle
$ bundler -v
```


## Railsのインストール ver:6.0.2.1
```ruby:
$ gem install rails -v 6.0.2.1
```


## MySQL（Client)の準備
#### インストール済みのMariaDBを取り除く
まずはMariaDBの状況を確認
```rust:
$ yum list installed | grep mariadb

# MariaDBの削除
$ sudo yum remove mariadb-libs
```


#### MySQLのインストール
```rruby:
$ sudo yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
```


## Mysql8.0のリポジトリを有効化
```rust:
# MySQL5.7のリポジトリの無効化
$ sudo yum-config-manager --disable mysql57-community

# MySQL8．0のリポジトリの有効化
$ sudo yum-config-manager --enable mysql80-community
```


## mysql-community-clientをインストール
新しいGPGキーをインポートしてから、MySQLをインストールする.
MySQLのGPGキーの有効期限切れのため、MySQL8.0.28では新しいキーで署名される。
```rust:
$ sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
$ sudo yum install -y mysql-community-client

# MySQLのバージョンの確認
$ mysql --version
```


## 参考にさせていただいた記事
https://qiita.com/yamato1491038/items/ec343a1bce41d3252473#rbenv%E3%81%A8ruby-build%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
固定長ファイル分析のために１文字ずつスプレッドシートに貼る手順

固定長ファイルを１文字ずつスプレッドシートに貼って、各列（各文字）の分析や説明書きをしたかったので以下の手順でスプレッドシートを作成した。

1. VSCodeあたりのテキストエディタで対象のファイルを開いて正規表現で`(.+?)`を`$1\t`に置換する。
1. １文字ごとにタブが入るのでそれをスプレッドシートに貼り付ける。
1. 列名を変えることはできないがA列とかのままだと分かりづらいので、`column()`で列数を表示して、`表示形式`＞`回転`することで、見やすく列番号がわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691945/090b94c7-9bc8-d459-1cd7-c5117722f6f3.png)
plunkerでshadertoy sandbox その 5

# 概要
plunkerでshadertoyのglsl動かしてみた。
iGlobalTime、iChannelTime、実装してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/fbf208d0-6894-8f62-e5fb-86d622fd1197.png)


# 成果物

https://embed.plnkr.co/plunk/rNtZLLZ5gZNqGOwy

以上。
Rubyのwp2txtライブラリを使えるようにする

# 背景
私はRubyをほぼ使ったことがありません。pだけでプリントができるということを知っているくらいです。
今回はpythonを使って自然言語処理をしようと思ったときにWikipediaの全文データ(xml)を取得してテキストファイルに変換する際にwp2txtというライブラリ？を使うためにインストールしました。

# エラーが起きる
機械学習の本を買ってその通りにやっていたところ
```
[root@server ~]$ wp2txt --input-file ./jawiki-latest-pages-articles.xml
[DEPRECATION] This gem has been renamed to optimist and will no longer be supported. Please switch to optimist as soon as possible.
/root/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/wp2txt-0.9.1/lib/wp2txt.rb:37:in `initialize': uninitialized constant Wp2txt::Runner::Etc (NameError)
	from /root/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/wp2txt-0.9.1/lib/wp2txt.rb:62:in `new'
	from /root/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/wp2txt-0.9.1/lib/wp2txt.rb:62:in `<top (required)>'
	from /usr/local/bin/wp2txt:23:in `load'
	from /usr/local/bin/wp2txt:23:in `<main>'


```
というエラーが出ました。
調べても古い結果しか出てこなかったですがteratailで素晴らしい回答を見つけました。

https://teratail.com/questions/159798?sort=1

こちらを見ていただけるとわかります。
このようなことを見つけられる方は本当にすごいですね。
# 解決策
```
find / | grep wp2txt.rb
```
などで検索して出てきたライブラリの場所をvimで編集します。
```
[root@server ~]$ vi /root/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/wp2txt-0.9.1/lib/wp2txt.rb
～～～～～～
      @parent = parent
      @fp = nil

      @input_file = input_file
      @output_dir = output_dir
      @tfile_size = tfile_size
      @convert = convert
      @strip_tmarker = strip_tmarker
      num_cores_available = Etc.nprocessors　　　　　　←ここ
      @num_threads = num_threads <= num_cores_available ? num_threads : num_cores_available
～～～～～～
```
37行目付近です。
ここはプロセッサ数を初期化しているらしいので２や４といった数値を直接入れることで動きます。
これで無事解決です。
```
num_cores_available = 4 #Etc.nprocessors
```

# 終わり
今回はこれだけです。
初めてライブラリを書き換えました。こんなこともあるんですね。
このteratailの回答者の方もそうですが、世の中のエンジニアの人は本当にすごいですね。
私も、いつか誰かの役に立てるようなエンジニアになれるように勉強します。
とりあえず機械学習系をいろいろやってみようかな。
Rails PumaのDaemonaization設定

### 概要
 EC2にnginxの構築を完了し、RailsのPamaデーモン化を構築した際の備忘録として。

### 環境
- Mac M1 macbookAir
- Rails 6.0.4.8
- ruby 2.6.5
- Bundler 1.17.2



### Gemfileに追記し、bundle installの実施
```ruby:Gemfile
<省略＞

# Use Puma as the app server
$ gem 'puma', '~> 5.0'　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　#５.０に変更
$ gem 'puma-daemon', require: false　　　　　　　　#追記

＜省略＞

# bundle installの実施
$ bundle install --path vender/bundle
```
### config/puma.rbに追記し、pumaを起動
```ruby:Config/puma.rb
＜省略＞

require 'puma/daemon'                            #この行を追加
root_dir="/var/www/〇〇〇〇"　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 #〇〇〇〇には自分のアプリ名を入力
bind "unix://#{root_dir}/tmp/sockets/puma.sock"  #（root_dir）部分のみ修正
workers 3     　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　#この行を追加
threads 2,3  　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　#この行を追加
daemonize  　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　  　　#この行を追加

＜省略＞

# pumaの起動
$ bundle exec pumactl start
```

この状態が表示されたらOK
![スクリーンショット 2022-04-29 10.05.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601549/98f739c1-551b-ad47-f8f4-ed030ee32cf3.png)
SAP Business Technology Platform (BTP)の基本的なことのまとめ

# はじめに

このたび、SAP社様から「SAP Business Technology Platform（SAP BTP）チャンピオン」に選出していただきました。それに際してと言いますか、日々の仕事の中でも「BTP」という言葉だけが一人歩きをしており、基本的なことがしっかりと理解されていないと感じることも多かったため、基本的な事項を簡単にまとめました。

テクニカルな内容ではなく、幅広く閲覧していただきたいため、プラットフォームとしては、Qiitaを選びました。（個人で使っているNotionのマークダウンメモがコピペしやすいという理由もあります。）

SAP BTP関連の情報は、日本語のものが少なく、かなり散在している感じがありますので、まずはざっと全体感をつかむことに利用していただければ幸いです。
また、本記事は概要把握や個人のトライアル利用の参考としてまとめたものなので、プロジェクトでの利用の際は、SAP社への問い合わせや正式情報であるHelp Portalを活用してください。

ちなみに「[SAP Business Technology Platform（SAP BTP）チャンピオン](https://news.sap.com/japan/2022/03/sap-award-of-excellence-2022%E5%8F%97%E8%B3%9E%E3%83%91%E3%83%BC%E3%83%88%E3%83%8A%E3%83%BC%E3%82%92%E7%99%BA%E8%A1%A8/)」とは、「SAP BTPを活用した開発・実装プロジェクトを通じて、お客様・社会における新たな価値創出に貢献された方、優れた開発実績や経験をもとに市場やコミュニティにおけるSAP BTPの普及に貢献された方を表彰する個人賞です。」


# 一言で言うと (SAP BTPとは？)

SAP社が提供するクラウドのアプリケーション開発プラットフォームです。マイクロソフトのAzureやIBMのIBM CloudのPaaSより上位レイヤーが競合にあたる製品です。

SAP社がマネージする、基本的にはhyperscalersのインフラ上で動き、利用者はSAP社と契約することで、利用可能になります。（インフラ面の詳しい話は下記の「[SAP BTPのインフラ概要](https://qiita.com/Yanagawa_Yoshihisa/items/073dc9723c50f463d2a6)」をご確認下さい。）

主な利用用途は、SAPの業務アプリケーション（S/4HANAやSuccess Factorsなど）の標準機能で補えない部分を拡張開発する際のプラットフォームです。

以下の目次で準備しました。時間がある方は上から順にご覧いただければと思います。

## 目次

- [SAP BTPの歴史と現在の位置付け](https://qiita.com/Yanagawa_Yoshihisa/items/41ff8300c74a42147690)
- [SAP BTPのアプリケーション概要](https://qiita.com/Yanagawa_Yoshihisa/items/af1f187980493ebf0642)
- [SAP BTPのサービス提供のイメージ](https://qiita.com/Yanagawa_Yoshihisa/items/9b78f80c1fe4c4951004)
- [SAP BTPのインフラ概要](https://qiita.com/Yanagawa_Yoshihisa/items/073dc9723c50f463d2a6)
- [SAP BTPの情報の調べ方](https://qiita.com/Yanagawa_Yoshihisa/items/9940b1e0c525682944fb)
- [SAP Business Technology Platform (BTP) の認定資格](https://qiita.com/Yanagawa_Yoshihisa/items/0cb22bc7e35296854c3d)

名称と対象範囲が時代とともに変遷してきたため、混乱を招きやすい状況です。まずは歴史を簡単に振り返って、理解を深めていきましょう。
VueでBootstrapを使う

## 必要なパッケージのインストール

```
$ yarn add bootstrap @popperjs/core sass sass-loader
```

## Vueの書き方

```vue:src/App.vue
<template>
  ...
</template>

<script>
import 'bootstrap';
...

export default {
  name: 'App',
  components: {
  ...
  },
  methods: {
  ...  
  }
}
</script>

<style lang="scss">
  @import "../node_modules/bootstrap/scss/bootstrap.scss";
</style>

```

`<style lang="scss">`とするところがポイントかと思います
Glideで作成したアプリをGoogleAnalyticsを使ってアクセス解析してみる

# やること
Glideで作成したアプリに対して、アクセス解析をやりたいと思います。
Glideでのアクセス解析の方法をいろいろ調べてみたのですが、GoogleAnalyticsを使用する方法が無難な感じがして、とりあえず、今回はそれで試しています。後述していますが、その場合は、Glideを有料プラン(Pro)にする必要があるので、お財布には少々優しくないです。
※何とか無料で出来ないかと、調べていたのですが、良い方法が見つからず

# Glideのプラン
有料プラン(Pro)が必要になります。
2022/4月時点では、$99/monthの金額が必要となります（結構、高い）。

# Google Analyticsのプロパティ
Googleアナリティクス4(GA4)を使用して下さい。
ユニバーサルアナリティクス(UA)にしか対応していないサービスもありますが、GlideではGoogleアナリティクス4(GA4)を使います。

# 簡単な流れ
詳細は、以下の公式ドキュメントが参考になります。

1. Glideでアプリを有料プランにアップグレートする
1. GlideのアプリでトラッキングIDを設定できることを確認
1. GoogleAnalyticsでGA4プロパティを作成
1. トラッキングIDをコピーして、Glideのアプリに設定する
1. GoogleAnalyticsでリアルタイム解析などを使って、動作確認をする

完了です！

# 参考
こちらが、公式ドキュメントになります。
英語ですが、正確にはこちらを見てもらうのが良いと思います。

https://docs.glideapps.com/all/topics/integrations/analytics

# おまけ
それでもなんとか無料でやれる方法はないかと考えている案としては、リダイレクト用にサーバーを準備して、そのサーバー経由でGlideアプリを開くようにすれば、リダイレクトされた回数ぐらいは分析できるような気がしています。詳しい分析までは無理ですが、なんとなくどれぐらいの頻度でしようされているかぐらいならこの方法で分かるのではないかと思います。
pulpとnetworkxの使い方

AtCoder231 H - Minimum Coloringを対象としたサンプルプログラムを以下に示します。
格子状のマス目にコストが設定されていて、それぞれの行と列から一つ以上のマス目を
選択する場合のコストの合計の最小値を求める問題です。

https://atcoder.jp/contests/abc231/tasks/abc231_h

pulpを使用した場合のサンプルプログラムを以下に示します。
本番環境ではpulpは使用できません。

https://coin-or.github.io/pulp/

```python
H,W,N = list(map(int, input().split()))
abc_list = []
for _ in range(N):
    a,b,c = list(map(int, input().split()))
    abc_list.append((a-1,b-1,c))

import pulp
problem = pulp.LpProblem(sense=pulp.LpMinimize)

from collections import defaultdict
var_list = []
coef_list = []
row_dict = defaultdict(list)
col_dict = defaultdict(list)
for i in range(N):
    a,b,c = abc_list[i]
    n = f'v_{a}_{b}'
    v = pulp.LpVariable(n, 0, 1, 'Integer') 
    var_list.append(v)
    coef_list.append(c)
    row_dict[a].append(v)
    col_dict[b].append(v)

problem += pulp.lpDot(coef_list, var_list)
for v in row_dict.values():
    problem += pulp.lpSum(v) >= 1
for v in col_dict.values():
    problem += pulp.lpSum(v) >= 1

result = problem.solve(pulp.PULP_CBC_CMD(msg=False))
ans = int(pulp.value(problem.objective))
print(ans)

# print(pulp.LpStatus[result])
# for i in range(N):
#     a,b,c = abc_list[i]
#     v = var_list[i].value()
#     print(a,b,c,int(v))
```

networkxを使用した場合のサンプルプログラムを以下に示します。

https://networkx.org/

実装方法は以下の解説に従っています。
最小重み辺被覆を最小重み完全マッチングに変換して解きます。

https://atcoder.jp/contests/abc231/editorial/3092

```python
H,W,N = list(map(int, input().split()))
abc_list = []
for _ in range(N):
    a,b,c = list(map(int, input().split()))
    abc_list.append((a-1,b-1,c))

INF = max([c for _,_,c in abc_list])
ac_min = [INF] * H
bc_min = [INF] * W
for a,b,c in abc_list:
    ac_min[a] = min(ac_min[a], c)
    bc_min[b] = min(bc_min[b], c)

import networkx as nx
G = nx.Graph()

# U=a, W=b+H+W, U'=a+H+W+W, W'=b+H
for a in range(H):
    G.add_node(a)
    G.add_node(a+H+W+W)
for b in range(W):
    G.add_node(b+H)
    G.add_node(b+H+W)

from collections import defaultdict
c_dict = defaultdict(int)
for a,b,c in abc_list:
    G.add_edge(a,b+H+W,weight=c)
    c_dict[(a,b+H+W)] = c
    G.add_edge(b+H,a+H+W+W,weight=c)
    c_dict[(b+H,a+H+W+W)] = c
for a in range(H):
    G.add_edge(a,a+H+W+W,weight=ac_min[a]*2)
    c_dict[(a,a+H+W+W)] = ac_min[a]*2
for b in range(W):
    G.add_edge(b+H,b+H+W,weight=bc_min[b]*2)
    c_dict[(b+H,b+H+W)] = bc_min[b]*2

top_nodes = list(range(H+W))
result = nx.bipartite.minimum_weight_full_matching(G,top_nodes=top_nodes)
ans = 0
for a,b in result.items():
    if a > b: continue
    ans += c_dict[(a,b)]
print(ans//2)
```
100日後くらいに個人開発するぞ！day011

## 今日はヘッダーを作ってみた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/3aba3dac-37f5-dad2-796d-1553a8c762d3.png)


## 今日のアウトプット

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/212ddfc6-b74e-5ba8-4aff-202105e8e36e.png)

## 今日の学び

### 背景色のみ透明にする方法
- opacityとrgbaの違い
    - opacity：要素の中身全てを透明にする
    - rgba:特定の色だけ透明にする
- 色を指定するrgb
    - rgbは色の指定方法の一種で3つの値を組み合わせて色を指定する
        - 例：背景色を指定する場合
            - `{background-color:rgb(255,147,30);}`
        - （例：#ffffffのような記法で背景色を指定する場合）
            - `{background-color:#ff931e;}`
- rgbaで特定の色を透明にする場合
    - rgbaは4つ目の値0~1で透明度を指定する
        - 例：背景色の透明度を0.5にしたい場合
            - `{background-color:rgba(255,147,30,0.5);}`


### アニメーションを付ける方法
- transiton：「変化の対象」や「変化にかかる時間」を指定できる
    - 例：全てのプロパティを対象として変化にかかる時間を1sにしたい場合
        - `div{transition:all 1s;}`
    - 例：背景色のhoverを0.5sで変化させたい場合
        - `div:hover{transition:background-color 0.5s}`



### 縦の中央揃えをする方法
- line-heightプロパティ
    - 行間を指定することができる
        - 例：行の高さを10pxに指定する場合
            - `{line-height:10px;}`
    - 要素の高さと行間の高さを同じにすることでテキストを縦の中央に揃えることができる


### `<a>`タグの範囲を要素全体に広げる方法
- `<a>`タグのdisplayプロパティをblockに指定すると`<a>`タグを要素全体に広げることができる
読んだ論文メモ（4/28）

## Younis, E. (2015). Sentiment Analysis and Text Mining for Social Media Microblogs using Open Source Tools: An Empirical Study. International Journal of Computer Applications, 112(5).

- 目的：Twitterから消費者の評価を分析する
- 手法：クリスマスシーズンのTesco、Asdaに関するツイートを収集し、ポジティブワード数、ネガティブワード数を分析。ワードクラウドによる出力と、それぞれのSentiment Scoreを分析
- 分析モデル：Word Cloud, Lexicon-based approcach
Ubuntu 22.04 での go のインストール

# Ubuntu 22.04 での go のインストール

https://qiita.com/m-tmatma/items/dff66b3e294293115661 で ubuntu に apt で golang をインストールする方法を記載したが、

https://github.com/longsleep/golang-deb/issues/9#issuecomment-1111964990 によると Ubuntu 22.04 では
標準リポジトリで go のインストールに対応したらしい。

以下でインストールできる。

```
sudo apt  install -y golang-go
```

2022/4/29 現在で ver 1.18.1 がインストールされた。

```
$ go version
go version go1.18.1 linux/amd64
```
[ARKit]身体を認識してみる メモ

### 身体を認識する流れ
1 ARBodyTrackingConfigurationをインスタンス化する
2 ARViewのARSessionにセットしてrunする
3 ARSessionDelegateのメソッドで下記のメソッドを呼び出してARBodyAnchorを取得する

```swift
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
 for anchor in anchors {
     guard let bodyAnchor = anchor as? ARBodyAnchor else { return }

}
}
```

#### ARBodyAnchorから取れる情報
ARBodyAnchorはARAnchorを継承しているので他のARImageAnchorやARPlaceAnchorと同様,simd_float4x4型のtransformプロパティを持っている。(これはそのアンカーのワールド空間における座標を示している。）

ARBodyAnchorで他によく使いそうなのは下記のプロパティ

```swift
var skeleton: ARSkeleton3D { get }
```
これは3Dで身体の動きを追跡している情報が入っている。
SkeltonにはJointと呼ばれる身体のパーツを表した91個のタイプが存在し、それをそれぞれ下記のSkeltonのプロパティを利用することで情報を取得できる


```swift

func localTransform(for: ARSkeleton.JointName) -> simd_float4x4?
指定された名前のジョイントが親ジョイントから見てどれだけ移動や回転したかを表す4✖️4の行列を返す

func modelTransform(for: ARSkeleton.JointName) -> simd_float4x4?
指定された名前のジョイントが Skelotonの中心である腰のジョイントからみてどれだけ移動や回転したかを表す4✖️4の行列を返しす。
```
SElinuxを無効にしたらOS起動しなくなった







環境
VMware vSphere Web console
Red Hat Linux Enterprise 8.1

SElinuxの無効化に失敗してOSが起動しなくなった話
https://qiita.com/daisuke0115/items/4b0ed3a5888cf81efd0a

これと同じことしちゃいました。

＞設定ファイルのSELINUXTYPEをtargetedに戻します。

ここで、なぜかキーボードが英字キーボード（キーボード配置が日本語と違う）になっていて結局OS作り直しました。開発環境だったので…


https://www.nagasaki-gaigo.ac.jp/toguchi/pc/multilingual/keyboard_us_jis.htm

こちらを参照し、入力。
個人的には、「：」位置が違うことに焦りました。

書き込みを保存し、起動しました。
よかった。
STM32G031のタイマー割り込みで遊ぶ



目的
オリジナルI2C超音波距離センターからの値の取得に使う



leafonyさんのページより引用


![o_con362.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/29fc0b10-d34d-a479-6a94-4a83253698f3.jpeg)





参考


STM32 MCU の Arduino IDE 設定


https://docs.leafony.com/docs/environment/stm32/arduino_ide/



TM32F103 + Arduino_STM32 で タイマー


https://qiita.com/nanbuwks/items/570126691ac089009415




```c++



#include <Arduino.h>

#define LOOP_INTERVAL 150000
#define BOARD_LED_PIN PA11

HardwareTimer *timer2 = new HardwareTimer (TIM2);

void setup() {
    pinMode(BOARD_LED_PIN, OUTPUT);
    
  timer2->setOverflow(LOOP_INTERVAL, MICROSEC_FORMAT);       // 125ms
  timer2->attachInterrupt(intTimer);
  timer2->resume();
  
}

void loop(){

//handler_led();

delay(500);

}

void intTimer(void){
  
    static int LEDstate = 0;
    digitalWrite( BOARD_LED_PIN,LEDstate);
    if ( 0 < LEDstate )
    { LEDstate = 0; } else { LEDstate = 1; }

}




```
やらかしたときによく使うGitコマンド

やらかしたときに都度調べ直すので備忘録。
いい加減やらかすの止めたい。


## ブランチ削除

#### ローカルのブランチを削除する場合
```
git branch -d {ローカルブランチ名}
```

#### リモートのブランチを削除する場合
```
git push origin --delete {リモートブランチ名}
```

## コミット打ち消し
```
git revert {コミットのハッシュ値}
```
- 指定したコミットの状態にまで戻してコミットを行う

## コミットを取り消す

#### 直前のコミットだけ消す
```
git reset --soft HEAD^
```
- HEAD^　: 直前のコミット
- --softのオプションをつけることでワーキングツリーはそのままの状態にできる

#### 直前のコミットを消し、ワーキングツリーも消す
```
git reset --hard HEAD^ 
```
- --hardのオプションを付けることでワーキングツリーも1つ前のコミットの状態に戻せる

#### コミット後の変更を全部消す
```
git reset --hard HEAD
```
man、less、moreコマンドのキー操作覚え書き

|キー操作|説明|
|:-:|:-:|
|d|画面半分、下に移動する|
|u|画面半分、上に移動する|
|f|1画面、下に移動する|
|b|1画面、上に移動する|
|g|1番上に移動する|
|G|1番下に移動する|
|{N}G|N行目に移動する 例 100G|
|/|下方向に検索する(n:下に検索する、N:上に検索する)|
|?|上方向に検索する|
Processing Video library 動かない問題メモ[macOS Monterey]

現在、2022年4月。
とりあえず動いたので、メモとしてこの記事を残しておきます。

## 環境
- macbook Pro 2018 13inch
- macOS Monterey 12.3
- Processing4 （4.0beta7）

## 試したこと

- Videoライブラリを削除
- 今入ってるProcessingを削除
- Processingの最新バージョンをインストール(4.0beta8 : 22/4現在)
- [Sketch]→[Import Library]→[Manage Libraries]から
**Video library for Processing4**をインストール
- 以下のプログラムを実行

```java
import processing.video.*;
Capture cam;

void setup() {
  size(640, 480);
  println(Capture.list());
  //カメラデバイスとフレームレートを指定する
  cam = new Capture(this,640, 480, Capture.list()[0], 30);
  cam.start();
}

void draw() {
  if (cam.available()) {
    cam.read();
  }
  image(cam, 0, 0);
}
```

とりあえず、これで動きました。
フレームレート指定しないと下記のエラーが出ると思います。
```
BaseSrc: [avfvideosrc0] : Internal data stream error.
```

もし、これ方法でダメだった、他の方法で行けたって方がいましたら、是非コメントお願いします。
標準ライブラリに 「すべて同じか判定する関数」 は無いのか？

範囲のすべての要素が同じであるか判定する関数(例えば {1,1,1,1}に対してtrue)が欲しくなることがよくあるのですが直接的な関数は標準ライブラリに存在しません。そこで色々と考えてみましたが良さそうな方法は all_of とラムダ式を使ったものですね。先頭の要素をすべての要素と比較させる方針です。

```
return all_of(begin(v), end(v), [&v](auto& a) { return a == *begin(v)); });
```

似た方針としては count を使って

```
return count(begin(v), end(v), cref(*begin(v))) == ssize(v);
```
ちょっとcrefの箇所が怪しいので空要素かどうかのチェックを入れたほうが良さそうです。
他にも equal, mismatch, adjacent_find も使えます。
equal と mismatch はイテレータをずらして一つ前の要素と比較させます。集合が空の場合にはそのまま使えないのでチェックを入れる必要があります。

```
return v.empty() || equal(next(begin(v)), end(v), begin(v));
```

```
return v.empty() || mismatch(next(begin(v)), end(v), begin(v)).first == end(v);
```

```
return adjacent_find(begin(v), end(v), not_equal_to()) == end(v);
```

minmax_elementを用いて順序比較できる型にしか使えませんがこんな方法もあります。==,!=で比較するほうが<>で比較するよりも効率的なことがあるのでおすすめはできません。

```
auto p = minmax_element(begin(v), end(v));
return p.first == p.second || *p.first == *p.second;
```

sortを用いて破壊的に計算量O(N*log(N))
シンプルな見た目をしていますが一番制約が厳しく汎用性に欠けます。

```
sort(begin(v), end(v));
return v.empty() || v.front() == v.back();
```
【Go】json-iterator/goのライブラリを使用してJsonから特定の値を取り出す

## 概要
Golangにて、標準ライブラリの使用でJsonから特定の値だけを取り出すことは可能ですが、interface型なので値の取り出しが少し面倒です。何か良いライブラリがないかと探していたところ、[json-iterator/go](https://github.com/json-iterator/go)というものを見つけました。
`json-iterator/go`は標準のライブラリよりも処理が速そうなのと、[こちら](https://github.com/json-iterator/go/tree/master/any_tests)のサンプルにある通り、Jsonから特定の値を取り出すこともできそうです。今回はこのJsonから特定の値を取り出す部分の実装サンプルを紹介します。

## 実装サンプルの前提とするJson
以前に[【OpenWeatherAPI】リクエスト・レスポンスの項目に関するメモ書き](https://qiita.com/someone7140/items/0d6bd671458904ff49d6)で紹介した、OpenWeatherAPIのレスポンスを今回の題材にしたいと思います。
```json
{
  "cod": "200",
  "message": 0,
  "cnt": 40,
  "list": [
    {
      "dt": 1650790800,
      "main": {
        "temp": 17.04,
        "feels_like": 16.39,
        "temp_min": 17.04,
        "temp_max": 17.04,
        "pressure": 1014,
        "sea_level": 1014,
        "grnd_level": 1013,
        "humidity": 61,
        "temp_kf": 0
      },
      "weather": [
        {
          "id": 500,
          "main": "Rain",
          "description": "light rain",
          "icon": "10d"
        }
      ],
      "clouds": { "all": 100 },
      "wind": { "speed": 2.46, "deg": 15, "gust": 2.72 },
      "visibility": 10000,
      "pop": 0.54,
      "rain": { "3h": 0.2 },
      "sys": { "pod": "d" },
      "dt_txt": "2022-04-24 09:00:00"
    },
    ・
    ・
    ・
  ]
}
```

## 実装サンプル
上記のjsonから、`dt`、`weather`の`icon`、`feels_like`、`rain`の`3h`を取り出してみます。

```go
func getWeatherResponseStrJSONConvert(jsonStr string) {

	// Json文字列からオブジェクトに変換
	weatherJson := jsoniter.Get([]byte(jsonStr))
	// list項目を取得
	weatherJsonList := weatherJson.Get("list")
    // 動的型付けっぽい振る舞いをするのでサイズの取得ができる
	for i := 0; i < weatherJsonList.Size(); i++ {
        // 配列項目の場合はindex指定ができる
		response := weatherJsonList.Get(i)

        // dtの取得
		unixTime: = response.Get("dt").ToInt64()
        // weatherのiconの取得
		weatherIcon = response.Get("weather").Get(0).Get("icon").ToString()
        // feels_likeの取得
		weatherInfo.TempFeelsLike = response.Get("main").Get("feels_like").ToFloat64()
		// rainは特定条件のみ現れる項目のため、存在判定のためにまずはstringで取得
		var rainFall *float64
		rainFallStr := response.Get("rain").Get("3h").ToString()
		if rainFallStr != "" {
			rainFallFloat := response.Get("rain").Get("3h").ToFloat64()
			rainFall = &rainFallFloat
		}
		・
		・
		・
	}
}
```
Powershellでワンライナー(iniファイル内の文字列置換)

# はじめに
今はバッチで色々スクリプト組んでますが、やりたいことを簡単に実現させたいので(1行で貼りつけるだけで簡単にできるので楽)

# ワンライナー
```powershell:IniFileReplace.ps1
# sample.ini内の文字列を今日の日付に置換
Get-Content sample.ini | ForEach-Object { $_ -replace "YYYY/MM/DD",(Get-Date).ToString("yyyy/MM/dd") } | Out-File -Encoding default sample.ini
```

# 参考サイト
※関係ないサイトもあるのですが、後で使うことあるかもなので
◆【Powershell】ファイル内の文字列を置換して上書きする方法
　https://pig-log.com/powershell-replace-overwrite/
◆PowerShell でファイル内の文字列をワンライナーで置換する
　https://qiita.com/kaku10/items/7c28fa5ebc829efe301c
◆yyyymmdd 形式の文字列で現在日付を取得する方法
　https://bayashita.com/p/entry/show/38
◆【PowerShell】前日の日時を取得しフォーマットする
　https://kharuka2016.hatenablog.com/entry/2017/02/28/201531
◆PowerShell/当日・指定日付の曜日を取得する方法
　https://win.just4fun.biz/?PowerShell/%E5%BD%93%E6%97%A5%E3%83%BB%E6%8C%87%E5%AE%9A%E6%97%A5%E4%BB%98%E3%81%AE%E6%9B%9C%E6%97%A5%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95
◆Powershellでの高度な置換
　https://qiita.com/acuo/items/a4f83d886c4b8a7fcf52
◆powershellでiniファイルを扱いたい
　http://nmksb.seesaa.net/article/473354419.html
◆PowerShellで"="や":"区切りの設定ファイルを読み込む
　https://yomon.hatenablog.com/entry/2014/05/21/PowerShell%E3%81%A7%22%3D%22%E3%82%84%22%3A%22%E5%8C%BA%E5%88%87%E3%82%8A%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80
◆Using the ConvertFrom-String cmdlet to parse structured text
　https://powershellmagazine.com/2014/09/09/using-the-convertfrom-string-cmdlet-to-parse-structured-text/
◆Powershellで色々とJSON形式に変換する
　https://qiita.com/digitalMagicbox/items/441f692ee040a476ead3
【windowsの人は】Windowsの人がwsl2を用いてubuntu20.04を導入する方法【Linuxを使おう(過激派)】

## 前提

### 筆者の環境
- Windows11
- wsl2
- Ubuntu20.04
- MacのOSを利用していたため、Windowsのシェルが使いにくい

### 一次情報には触れましたか？
[こちらのサイト](https://docs.microsoft.com/ja-jp/windows/wsl/)を確認し、この記事を読み進める前にご自分で確認してみましょう。

私は一次情報をないがしろにして技術ブログや技術記事を読み漁った結果、
いろいろな情報に踊らされて１日潰しました（経験談）

### 注意
本記事ではLinuxをGUIで動かすことを目的とせず、あくまでwsl2を用いて
ターミナル上でlinux操作をすることを目的としています。

私自身まだ至らない部分もあります。
上記に示す通り私の記事含め二次情報を鵜呑みにするのではなく、
あくまで一次情報を咀嚼しやすくするものとして見ていってください。
また、おかしな点があればコメントでのご指摘お待ちしております。


## 導入方法

### 1. linuxのディストリビューションを確認する
[一次情報の該当箇所](https://docs.microsoft.com/ja-jp/windows/wsl/install#change-the-default-linux-distribution-installed)
```bash
$ wsl -l -o #利用可能なlinuxディストリビューションを表示させるコマンド
```

まずはこちらのコマンドで利用可能なディストリビューションをチェックしましょう。
おそらくこれからlinuxを触る人にとって聞きなじみのあるディストリビューションは
`Ubuntu`か`Demian`あたりではないでしょうか。
困ったら`Ubuntu-20.04(2022/4/29時点)`を利用しておけば間違いないです。

### 2. linuxディストリビューションをインストールする
[一次情報の該当箇所](https://docs.microsoft.com/ja-jp/windows/wsl/install#install)
```bash
$ wsl --install -d $NAME #[$NAME]には利用したいディストリビューションのNAMEを入れてください。

#Ubuntu20.04を入れる場合
$ wsl --install -d Ubuntu-20.04
```

利用したいディストリビューションが決まったら、実際にインストールしてみましょう。

### 3. linuxの環境設定を終了させる
[一次情報の該当箇所](https://docs.microsoft.com/ja-jp/windows/wsl/setup/environment#set-up-your-linux-username-and-password)

後は画面の指示に従ってユーザー名とパスワードを設定していきます。

### 4. レッツ開発
**お疲れ様でした！！！**
ここまでで環境設定は終了です。
Linuxを使って快適な開発ライフを楽しみましょう！

以下はTipsになります。
飛ばしていただいてもかまいません。

## Tips
### Windows Terminalを使おう
[microsoft store](https://www.microsoft.com/ja-jp/p/windows-terminal/9n0dx20hk701?SilentAuth=1&wa=wsignin1.0&activetab=pivot:overviewtab)から`Windows Terminal`をインストールしましょう。

windows当初の規定アプリは`Powershell`なのですが、`Terminal`を用いることで簡単にwindows環境とlinux環境をいったりきたりできるようになります。
タブで複数のコンソールを動かせるのがすごい便利・・・

### 実はMicrosoft storeからもディストリビューションが入手可能
[一次情報](https://docs.microsoft.com/ja-jp/windows/wsl/install#ways-to-run-multiple-linux-distributions-with-wsl)
[ダウンロードサイト](https://www.microsoft.com/ja-jp/p/windows-terminal/9n0dx20hk701?SilentAuth=1&wa=wsignin1.0&activetab=pivot:overviewtab)

実はコンソールからじゃなくてもインストール可能だったりします。
ただ、私はコンソールからしかlinuxをインストールしたことがないため、
責任を持てないので興味がある方は上記の一次情報からチェックしてみてください。

### ディストリビューションをインストールした後にubuntuを開けない人へ
[一次情報](https://docs.microsoft.com/ja-jp/windows/wsl/install#ways-to-run-multiple-linux-distributions-with-wsl)

スタートメニューからダウンロードしたディストリビューションの名前を検索することで
直接linuxのシェルを開くこともできます。

### VScodeユーザーに向けて
[一次情報](https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscode)

microsoft様がVScodeに向けた素晴らしい拡張機能を提供してくれています。
是非活用しましょう。
UnityのPositionとRotation(親が異なる座標系での、孫以下の正面が異なるオブジェクトの相対位置と姿勢を合わせる方法！)

# Position と Quaternion のイメージ

Position -> ベクトル

![スクリーンショット 2022-04-29 015527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/415b9bfd-9089-11da-0795-5020d1a6f4e3.png)

```PositionSample.cs
Transform ObjectA;
Transform ObjectB;

var differecePosition = ObjectB.position - ObjectA.position;
```

### position -> シーンの原点(0.0f, 0.0f, 0.0f)からのそのオブジェクトまでのベクトル

### localPosition -> 親のオブジェクトの座標の原点から子のオブジェクトまでのベクトル

Quaternion -> オブジェクトのもつ座標系同士の差

![スクリーンショット 2022-04-29 020313.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/3a5021cc-9b3d-9e2c-0c98-f1db7ada03a8.png)

```RotationSample.cs
Transform ObjectA;
Transform ObjectB;

var differeceRotation = ObjectB.rotation - Quaternion.Inverse(OjbectA.rotation);
```

# 親が異なる座標系での、孫以下のオブジェクトの正面が異なる相対位置と姿勢を合わせる方法！

### 目的 : 異なる座標系を持つオブジェクトとAとBとし、Aのオブジェクトの孫以下のオブジェクトaに対するAから見た位置と姿勢に基づいて、Bのオブジェクトの孫以下のオブジェクトbに対するBから見た位置と姿勢を移動・回転させる！ただし、bとaの正面が異なるので、それも考慮して、回転させる。

基準にしたいオブジェクトとその孫以下のオブジェクトをそれぞれを OBJECTA,　objectA　とします。
基準とは異なる座標系をもつオブジェクトとOBJECTAとobjectAの位置と姿勢の関係に合わせて、異なる座標系で位置と姿勢を合わせるオブジェクトをそれぞれ OBJECTB, objectBとします。

### 手順

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/4d18bdb2-33c9-1895-9ad7-077a655a885c.png)

1. OBJECTAを基にしたobjectAのベクトルをとります。

2. 取り出したベクトルの座標系をOBJECTAからOBJECTBのものへと変換します

3. objectBの位置と姿勢を、変換したベクトルを用いて回転と移動を行います

4. objectA と objectBの持つ正面の座標同士の変換を行います。

```objectA2ojbectB.cs
Quaternion rotationab = Quaternion.Euler(0.0f, 90.0f, 90.0f);

var vectoraA = objectA.position - OBJECTA.position;
var rotationAB = OBJECTB.rotation * Quaternion.Inverse(OBJECTA.rotation);
var vectorbB = rotationAB * vectoraA;

objectB.position = vectorbB + OBJECTB.position;
objectB.rotation = rotationab * objectB.rotation
```

#### 伝えたかったことは 基準にしたいオブジェクトのもともと持つ回転座標同士の差と姿勢を制御したいオブジェクトの正面の回転座標同士の差を別々に考えないとめちゃくちゃバグるってこと...。

以上！