OmniAICreator/Qiita-1.07M huggingface dataset:
AUTOSAR R23-11 資料整理の計画（年越し懇親会遠隔開催時間投票含む）OSEK(54)

AUTOSAR

https://www.autosar.org/

は、自動車のソフトウェアの自動生成を目指した業界標準化組織です。　

# 課題

ISO, IEC< ITUなどの標準化団体とはまだリエゾンを結んでいないことが課題です。

AUTOSAR Classic Platformは、ISO CANとISO OSEK/VDX OSを元にした技術で、　
国際規格との差異を示しています。　

AUTOSAR Adaptive Platformは、IEEE/ISO/IEC POSIX, IEEE/ISO/IEC 802.3 
を元にした技術で、国際規格との差異を示しています。

残念なのは、AUTOSARで定着した仕様を国際規格に提案しようとしていないことかもしれません。

Adaptive Platformの基礎となっている技術は、車載EthernetではIEEEに提案して、　
AUTOSARも採用しています。　

Adaptive Platformの基礎となっているもう一つの技術、車載LinuxはISO/IECへの提案団体である
Linux Foundationでの調整が今後の課題かもしれません。　

AUTOSAR Classic PlatformとAUTOSAR Adaptive Platformの両方を含む　
AUTOSAR Abstract Platformでは、20年前のAUTOSARの基本に戻り、　
Modelからの自動生成に商店を絞りなおしています。

https://www.autosar.org/fileadmin/standards/foundation/22-11/AUTOSAR_TPS_AbstractPlatformSpecification.pdf

# R23-11
AUTOSARでは、この５年、１１月末に仕様を策定しています。

策定の023年11月末以降に、AUTOSARの新しい資料が公開される見込みらしい。　

一般公開は12月になってからの可能性が高く、月末までに資料を整理するのに、　
今から準備を始めている。　


2023 書き初め

https://qiita.com/kaizen_nagoya/items/d494737e2627127b530d

年末にできれば100記事を30点に仕上げる。結局年越した。

https://qiita.com/kaizen_nagoya/items/3ffdc82caee3a325d1d7

# 資料整理


2022/12/25までに、Qiitaに記事のファイルを掲載するのが第一段階。中身の最低限はTemplate＋表題。2022/12/25に完了。
2022/12/31までに、過去の記事以上の内容にするのが第二段階。実際には2023/01/02に完了。　
中身を精査し、50点くらいの資料に、春のDemonstrator配布後１週間くらいを目処に整理するのが第三段階。


Classic Platform Release Overview, AUTOSAR R22-11, CP, ID.0,

https://qiita.com/kaizen_nagoya/items/32b660800e51115ecb89

に文書番号がついていない。文書番号をつけておいた。今度は作業がだいぶ楽になるはず。　


AUTOSAR R21-11で廃止になりR22-11では発行していない文書など

https://qiita.com/kaizen_nagoya/items/0f9284fedf4a4b940aa6

# 年越し懇親会遠隔開催


12/31 までには作業を終わって、テレビ会議で忘年会をしようかなって計画を立ててみます。

なお、時間終わるために、年越し懇親会を遠隔開催する方向で調整しています。　

開催予定をご連絡さしあげるために、ぜひ、ご投票ください。


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">2023年12月31日　AUTOSAR Abstract Platform User 予定。開催時間のご希望をご投票ください。それ以外の時間の場合には、ご返信ください。19:00より前の時間には作業が終わっていません。作業分担会でよろしければ、18:00以前のお時間も可能です。</p>&mdash; wocs2017 (@wocs2017) <a href="https://twitter.com/wocs2017/status/1609929778198646785?ref_src=twsrc%5Etfw">January 2, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.

# 文書履歴(document history)
ver. 0.01 初稿 20230102
ver. 0.02 URL追記　20230103

### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
毎日１回YahooにPingを打つだけのお仕事（別冊）

# この記事は

https://qiita.com/t13801206/items/67f0ddf625d3bdcf0b4d

前回記事（↑）の補足の記事

ExPingではNG時の動作として、オプションに4つの引数が使える

```
%n  ･･･  対象アドレス
%d  ･･･  日時
%s  ･･･  ステータス
%e  ･･･  備考
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/3e0e6cb9-5d71-f64c-515b-30b7e8a444e6.png)

これをバッチで捕捉し、PowerShellに渡すことで
死活監視用のメールに情報をのせることができる（ログから情報を拾ってこなくとも）

## バッチ

`-File`で実行するPowerShellスクリプトを指定し、そのあとに続けてExPingから渡ってきた4つの引数を書く

```bat:taskWithArgs.bat
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Unrestricted -File .\mainWithArgs.ps1 %1 %2 %3 %4
```

### PowerShell

```powershell:mainWithArgs.ps1
Write-Host $args[0]
Write-Host $args[1]
Write-Host $args[2]
Write-Host $args[3]
return
```

## 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/18b13624-7ae0-e73c-77bf-85042d1a10f6.png)

## 受信メール内容

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/941345c8-bfc6-87d2-723d-6ffa19c452f4.png)
【DB】DDLの書き方

## CREATE

CREATEはデータベースに空のテーブルを作成します。  

```sql
CREATE TABLE テーブル名 ( 
  カラム名1 データ型 制約,
  カラム名2 データ型 制約,
            ：
  テーブルの制約1, 
  テーブルの制約2, 
            ：
);
```

- データ型  

| データ型 | 説明                                                                 |
| :------: | :------------------------------------------------------------------- |
| INTEGER  | 整数（小数は不可）                                                   |
|   CHAR   | 固定長文字列。続けて`(数字)`を記述することで最大文字数を指定できる。 |
| VARCHAR  | 可変超文字列。続けて`(数字)`を記述することで最大文字数を指定できる。 |
|   DATE   | 日時                                                                 |

- 制約

|    制約     | 説明                                                   |
| :---------: | :----------------------------------------------------- |
|  NOT NULL   | NULL 値が列に入力されないようにする                    |
| PRIMARY KEY | 主キーを設定する。必ずNOT NULL制約をつける必要がある。 |
| FOREIGN KEY | 外部キーを設定する                                     |

### 例

```sql
CREATE TABLE Users (
  user_id            INTEGER      NOT NULL,
  user_name          VARCHAR(15)  NOT NULL,
  user_address       VARCHAR(100) NOT NULL,
  user_phone_number  CHAR(13),
  PRIMARY KEY (user_id)
);

CREATE TABLE Orders (
  order_id   INTEGER NOT NULL,
  order_date DATE    NOT NULL,
  user_id    INTEGER NOT NULL,
  PRIMARY KEY (order_id),
  FOREIGN KEY (user_id) REFERENCES Users (user_id)
);

```

![スクリーンショット 2023-01-02 23.01.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/42005c94-1892-722f-18ab-d0f77f63c35d.png)

## DROP

`DROP`はテーブルを削除します。  

```sql
DROP TABLE テーブル名;
```

## ALTER

`ALTER`は定義済みテーブルを変更する。  

- カラムを削除する

```sql
ALTER TABLE テーブル名 DROP COLUMN カラム名;
```

- カラムを追加する

```sql
ALTER TABLE テーブル名 ADD COLUMN カラム名 データ型 制約;
```

- テーブル名を変更する

```sql
ALTER TABLE 旧テーブル名 RENAME TO 新テーブル名;
```
GitHubの設定をしてみた

#### Ⅰ.この記事を記載した理由
 ① 初心者向け
 ② 仕事でSVNやTortoiseGitのみしか使ってない
 ③GitとGitHubは同じだと思ってる
 ④グーグル先生に質問すると、断片的な情報しかもらえず混乱するサイトばっかだった。
 
自分は、②と③で改めて私物ＰＣで設定すると驚いた。
また、最初は自分の調べ方が悪いのか、断片的なことしか出てこなかった。たぶん、仕事で理解してる単語のみ入れてたから。

#### Ⅱ.環境
注意）PCのOSはWindows11です。
　　　MacとLinxの方はご了承ください。でも、一部読み替えれば理解はできるはず。

#### Ⅲ.「Git」と「GitHub」は別物だ
”Git”という文言がくっついているため、両方とも同じように感じる。
だが、以下の内容により別物だ。

- 「Git」→　ローカルのパソコンで編集作業を行いファイルの修正履歴も管理できる分散型
           バージョン管理システムである。

- 「GitHub」→　Gitを用いたソフトウェア開発プロジェクトのための共有ウェブサービス


#### Ⅳ.自分のＰＣに設定し、GitHubまで使えるようにするためにどうしたらいいか
大まかな流れとして、以下である。

①Gitのインストール
②Gitの初期設定
③GitHubのアカウントを作成
④リモートリポジトリを作成する
⑤GitHubにSSHの設定をする
⑥ローカルリポジトリを作成する
⑦ファイルを作成する
⑧ローカルリポジトリにコミットする
⑧リモートリポジトリにプッシュする

サイトやYouTubeによって順番が多少異なるが、たいていはこのような流れ。
余談だが、私は最初のころとりあえずGitHubのアカウントを作成すればいいのかなーと、アカウント作成から実施してしまった…。なんとか設定はできたが。

#### Ⅴ.GitHub設定で参考になってよかったサイト
色々なサイトを見ていた中で、以下のサイトがわかりやすい。

■Progatさんのサイト（ログインなしで中身が見れた）
上記の流れを一通り解説してくれる内容

https://prog-8.com/docs/git-env-win

■わかる・たのしい・実は深い！　IT入門書籍　スッキリシリーズ
Gitインストール手順の説明が詳細に解説。
Gitインストールのことを100％理解したい方におすすめ
https://sukkiri.jp/technologies/devtools/git/git_win.html

■Git入門講座 合併版】この動画1本でGitとGitHubの基礎をゼロからマスター！【初心者向け】
YouTubeの動画
GitとGitHubの基本的な仕組みをわかりやすく解説。
設定の説明、コマンドの説明もとてもわかりやすかった。
https://www.youtube.com/watch?v=WHwuNP4kalU

#### Ⅵ.終わりに
　GitやGitHubの違い、コマンドの区別、用語など、
　初心者には難しいことばかりのGitHubですが、コード管理とチーム開発には欠かせないもの。
　がんばって操作方法やコマンド覚えていきたい。
投稿のコメントにYoutubeのURLを入れ込む方法

今回はユーザーが投稿した投稿にコメントをする際にYoutubeのURLを埋め込む方法を紹介します。

投稿のコントローラー：favorite(普段自分が使っているコントローラー)
コメントのコントローラー：comment

①commentsテーブルにyoutube_urlカラムを追加します。

```ruby:コマンドプロンプト
rails generate migration AddYoutube_urlToComments youtube_url:string
```
```ruby:コマンドプロンプト
rails db:migrate
```

②commentコントローラーに、コメント内でYoutubeのURLを埋め込むためのコードを書きます。

```ruby:app/controller/comments_controller.rb
def create
    favorite = Favorite.find(params[:favorite_id])
    comment = favorite.comments.build(comment_params) 
    comment.user_id = current_user.id
#ここまでは教材でできているはず！だから特に変えなくていいよ！
    url = params[:comment][:youtube_url]
        url = url.last(11)
        comment.youtube_url = url
#変更する所は上の3行だけ！
    if comment.save
      flash[:success] = "コメントしました"
      redirect_back(fallback_location: root_path) 
    else
      flash[:success] = "コメントできませんでした"
      redirect_back(fallback_location: root_path) 
    end
  end
```

③コメント投稿をするときにYoutube_urlを受け取るために以下のコードを書きます。

```ruby:app/controller/comments_controller.rb
private

    def comment_params
      params.require(:comment).permit(:content, :youtube_url)#youtube_urlを追加
    end
```

④viewページにyoutubeの動画を入れる＆表示させるためのコードを挿入

```ruby:app/views/favorites/show.html.erb
#省略
<div class="comment-wrapper">
  <p>コメント一覧</p>
  <% @comments.each do |c| %>
    <div>
      <%= c.user.email unless c.user.blank? %>
      <br>
      <%= c.content %>
      <br>

      
      <% if c.youtube_url? %>　#ここから
      <p><iframe width="560" height="315" src="https://www.youtube.com/embed/<%=c.youtube_url%>" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
      <% end %> #ここまでを追加

    </div>
      <br>
  <% end %>

  <% if user_signed_in? %>
    <%= form_with(model: [@favorite, @comment], local: true) do |f| %>
      <%= f.text_area :content %>
      <%= f.text_field :youtube_url, :size => 140 %><br> #この1行を追加
      <%= button_tag type: "submit" do %>
        <i class="far fa-comments"></i> コメントする
      <% end %>
    <% end %>
  <% end %>
</div>
```

これでできるはず！以下の写真みたいになります！！(著作権の問題で動画表示できてないけど、、、笑)![スクリーンショット (309).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088237/c700eedc-8f28-1766-9634-07d31a12f802.png)
docker-composeでJenkinsを動くようにする

# 概要
docker-composeでとりあえずJenkinsをローカルでも動くようにすることがあるための覚書
hookで色々動かすのはまた後日

```docker-compose.yml
version: "3"
services:
  jenkins:
    container_name: jenkins
    image: jenkins/jenkins:latest
    ports:
      - 8080:8080
    volumes:
      - ./jenkins_home:/var/jenkins_home
```
ruby 練習問題48　（アウトプット用）

以下の仕様にしたがってコードを記述する問題。

・Personクラスはプロパティ name, ageを持っている。
・StudentクラスはPersonクラスを継承している。
・Studentクラスにはintroduceメソッドが定義されている。実行すると
　「私の名前は◯◯です。◯歳です」と表示がされる。
・Studentクラスのインスタンスを作成し、introduceメソッドを実行する。

以下、模範解答
```ruby
class Person
  def initialize(name, age)
    @name = name
    @age = age
  end
end

class Student < Person
  def introduce
    puts "私の名前は#{@name}です。#{@age}歳です"
  end
end

yamada = Student.new("山田", 20)
yamada.introduce
```
以下、解説
まずクラスの継承について
クラスの継承とは、利用したいすべてのクラスを最初から作成することなく、共通する部分を受け継ぐことができる。
以下、使用例
```ruby
class クラス名 < 継承したいクラス名（親クラス）

end
```
模範解答ではclass Student < Personの文でクラスの継承を行っているのでintroduceメソッドないで@nameと@ageを使用する事ができている。
[Truth] MapSubject#containsExactlyEntriesIn()とMapSubject#containsAtLeastEntriesIn()の違い

## 概要
ユニットテストを書いていて、Truthの `MapSubject#ontainsExactlyEntriesIn()` と `MapSubject#containsAtLeastEntriesIn()` の違いが分からなかったのでまとめました。

## 環境
``` app/build.gradle
implementation com.google.truth:truth:1.1.3
```

## メソッドの説明から見る「違い」
それぞれのメソッドコメントを直訳しました。
### MapSubject#containsExactlyEntriesIn()
> Fails if the map does not contain exactly the given set of entries in the given map.
> 与えられたマップに少なくとも与えられたエントリのセットが含まれていない場合、失敗します。

### MapSubject#containsAtLeastEntriesIn()
> Fails if the map does not contain at least the keys in the given map, mapping to values that correspond to the values of the given map.
> 与えられたマップの値に対応する値にマッピングされた、少なくともマップのキーを含んでいない場合、失敗します。

訳したところで、もちろん私の脳では理解できません。

## ユニットテストの実行結果から見る「違い」
assertThat(mapOf(“0” to “a”, “1” to “b”)).containsExactlyEntriesIn(mapOf(“0” to “a”))
実行結果　→ 失敗
```
unexpected keys
for key         : 1
unexpected value: b
---
expected        : {0=a}
but was         : {0=a, 1=b}
unexpected keys
for key         : 1
unexpected value: b
---
expected        : {0=a}
but was         : {0=a, 1=b}
```
---
assertThat(mapOf(“0” to “a”)).containsExactlyEntriesIn(mapOf(“0” to “a”, “1” to “b”))
実行結果 → 失敗
```
missing keys
for key       : 1
expected value: b
---
expected      : {0=a, 1=b}
but was       : {0=a}
missing keys
for key       : 1
expected value: b
---
expected      : {0=a, 1=b}
but was       : {0=a}
```
---
assertThat(mapOf(“0” to “a”)).containsAtLeastEntriesIn(mapOf(“0” to “a”, “1” to “b”))
実行結果 → 失敗
```
missing keys
for key                     : 1
expected value              : b
---
expected to contain at least: {0=a, 1=b}
but was                     : {0=a}
missing keys
for key                     : 1
expected value              : b
---
expected to contain at least: {0=a, 1=b}
but was                     : {0=a}
```
---
assertThat(mapOf(“0” to “a”, “1” to “b”)).containsAtLeastEntriesIn(mapOf(“0” to “a”))
実行結果 → 成功
```
成功のためログはありません
```

## 上記を踏まえて、私から見た「違い」
### MapSubject#containsExactlyEntriesIn()
要素が完全一致していないと成功しない？（自信なし）

### MapSubject#containsAtLeastEntriesIn()
引数で指定した要素が全て含まれていれば成功
RISC-V QEMU + busyboxでlinuxをブートさせる

# やりたいこと

64bit RISC-VプロセッサをエミュレートするQEMU上でlinuxをブートさせたい。ユーザーランドは最低限のbusybox環境で済ます。とりあえず記憶と他サイトの記述から抜粋してメモ書き。細かいところは間違っているかもしれないので後で更新する。

# 環境

- Ubuntu 22.04LTS
- QEMU 6.2.0
- linux kernel v5.8
- busybox (マスター使っちゃった）

# 手順

## 1. クロスコンパイル用のツールを準備
https://toolchains.bootlin.com/ からarch = riscv64、libc = glibc を選択してダウンロード、展開。パスを通す。その他の方法でも良い。

## 2. linuxカーネルのビルド

```shell_session
% git clone --depth=1 -b v5.8 https://github.com/torvalds/linux
% cd linux
% make ARCH=riscv CROSS_COMPILE=riscv64-linux- defconfig
% make ARCH=riscv CROSS_COMPILE=riscv64-linux- menuconfig
% make ARCH=riscv CROSS_COMPILE=riscv64-linux- all
```

## 3. busyboxのビルド

```shell_session
% cd ..
% git clone https://git.busybox.net/busybox
% cd busybox
% make CROSS_COMPILE=riscv64-linux- defconfig
% make CROSS_COMPILE=riscv64-linux- menuconfig
```

menuconfigにおいて、以下のオプションのオンにしてstatic binaryを生成する。

```shell_session
Settings
  Build Options
    [*] Build static binary (no shared libs) 
```

ビルドとインストール。

```shell_session
% make CROSS_COMPILE=riscv64-linux- all
% make CROSS_COMPILE=riscv64-linux- install
```

## 4. ルートファイルシステムの作成

```shell_session
% cd ..
% dd if=/dev/zero of=root.bin bs=1M count=64
% mkfs.ext2 -F root.bin
% mkdir mnt
% sudo mount -o loop root.bin mnt
% sudo cp -r busybox/_install/* mnt/
% cd mnt
% sudo mkdir dev etc proc run sys
% cd dev
% sudo cp -a /dev/console .
% sudo cp -a /dev/tty[0-4] .
% cd ../..
% sudo umount mnt
```


## 5. QEMU導入と起動
QEMUはapt-getで入れた。

```shell_session
% qemu-system-riscv64 -M virt -nographic -kernel linux/arch/riscv/boot/Image -append "root=/dev/vda rw console=ttyS0" -drive file=root.bin,format=raw,id=hd0 -device virtio-blk-device,drive=hd0
```



# 参考にしたサイト
- https://risc-v-getting-started-guide.readthedocs.io/en/latest/linux-qemu.html
- https://kurun-pan.github.io/post/2020-09-26/
- https://zenn.dev/miwarin/articles/d2fb1532185891
- http://www.ne.jp/asahi/it/life/it/embedded/arm9/arm9_root_file_system.html
DELL Inspiron 1501にWindows 7をインストールした時のタッチパッド用ドライバ

DELL Inspiron 1501(生まれてはじめて買ってもらったノートパソコン！涙)にWindows 7 Pro(x64)をクリーンインストールしたらドライバを集めるのに苦労した。
特に困ったのがSynaptics Touchpadのドライバで、デフォでもタッチパッド自体は使えるけど、ドライバを入れないとスクロール機能が死んでしまうっぽい。
DELLの公式から[ダウンロードできるやつ](https://www.dell.com/support/home/ja-jp/drivers/driversdetails?driverid=kh5f6)(※1)は、OSがWin2000かXPじゃないと実行できなくて詰む。うまいことやれば無理やりインストールできるのかな？
いろいろ調べ回った結果ダメ元で[これ(公式だよ)](https://www.dell.com/support/home/ja-jp/drivers/driversdetails?driverid=wfc1x)(※2)実行したらうまくいったので、もしかしたらどこかの誰かに役立つかもしれないのでメモ代わりに残しておきます。

※1. Synaptics Touchpad, v.8.2.4.6, A17
※2. Synaptics Touchpad, v.13.2.2.2, A06
［初心者］tableau publicを触ってみてディメンションとメジャーの違いについて意味わかった気になっているので自分の頭の中をメモしてみた。

DATA Saber APPRENTICEとしての旅の１ページ
初心者なので書き方などご容赦ください。
Qiita記述についてはMarkdown記法 チートシートを参考にしています。

初心者がtableau publicを触ってみてディメンションとメジャーの違いについて意味わかった気になっているので自分の頭の中をメモしてみました。
メモった理由：計算をする際にメジャーからなんでもいいんでvalueを持ってきて計算した場合と、ディメンションだけを利用した場合に、処理量が多いとヴィジュアライゼーションにアクセスした際の重たさが違う（指摘もいただき）と思ったからです。
※他の説明を見ていたのですが、腹落ちしませんでした。

環境：tableau public2022.4.0(64bit)、win11　
※ubuntuで利用しようとしたらtableau publicのインストールパッケージがありませんでした。linux系で利用する場合はブラウザから利用しましょう。

まずディメンション(Dimension)について私の頭の中はこんなイメージです。
![ディメンション、1Ｄ（次元）から4Ｄまで](https://github.com/Kaysan555/Newbie_on_tableau_public/blob/main/%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B31to4.jpg?raw=true)

１次元：一本の線
２次元：正方形
３次元：立方体
４次元：立方体の3次元空間を押し込むような形

次に、4Dimensionまで書くとわかりにくいので3Dimensionまでとして以下を考えていきます。
![1D～3Dまで](https://github.com/Kaysan555/Newbie_on_tableau_public/blob/main/%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8C%E3%81%82%E3%82%8B%E3%81%8B%E3%81%AA%E3%81%84%E3%81%8B.jpg?raw=true)



メジャー（measure）についてはこのX・Y・Zの軸上に例えばですがある程度の長さがあると示されたときに、値があるものとして計算や認知できる状態にあると理解しました。
※仮定している状態
X軸の場合はオレンジの長さ分値がある。
Y軸の場合はピンクの長さ分値がある。
Z軸の場合は紫の長さ分値がある。
![メジャーを入れた状態](https://github.com/Kaysan555/Newbie_on_tableau_public/blob/main/%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8C%E3%81%82%E3%82%8B%E3%81%8B%E3%81%AA%E3%81%84%E3%81%8B_%E3%81%9D%E3%82%8C%E3%81%A8%E3%83%A1%E3%82%B8%E3%83%A3%E3%83%BC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6.jpg?raw=true)

以下おまけ（演算処理中のリソースについて）
Tableau public上の計算を考えてみます。
A：Dimensionだけ用意している分にはX・Y・Zの軸を用意するリソースだけ食います。
B：Measureを利用している際は、Dimension自体も用意して？？数値計算もしているのでその分リソースを多く必要とするのではないかと考ます。
![メジャーはいらないよね？](https://github.com/Kaysan555/Newbie_on_tableau_public/blob/main/%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8C%E3%81%82%E3%82%8B%E3%81%8B%E3%81%AA%E3%81%84%E3%81%8B_%E3%81%9D%E3%82%8C%E3%81%A8%E3%83%A1%E3%82%B8%E3%83%A3%E3%83%BC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A62.jpg?raw=true)


後日書きますが、特定の属性がある・ないだけ見せたいのであればDimensionだけ用意すれば表現できると考えます。
数値処理が必要ない場合はTableau public上はDimensionだけ用意して軽くするのがいいかも。


もし理解が違ったらだれか教えてください！
WhisperX(音声認識 + アラインメント) のメモ

Whisper で音声認識 + 単語(word)単位でのアラインメント(単語がどの時刻に出てくるか)までやってくれます!

https://github.com/m-bain/whisperX

音声のアラインメントについてのメモ
https://qiita.com/syoyo/items/e43d9d5d564fded3a2b6

インストールは特に難しいものではありません.

中身的には Whisper + word2vec の wrapper という感じでしょうか.

README.md には書かれていないのですが, 日本語対応がされています.
(単語単位でアラインメントしてくれます)

https://github.com/m-bain/whisperX/pull/8
https://github.com/m-bain/whisperX/blob/main/EXAMPLES.md

`--language ja` 指定すると wav2vec に`jonatasgrosman/wav2vec2-large-xlsr-53-japanese` を使うようになっています

## 実行

最高性能でやります. wav2vec2-large-xlsr-53-japanese は model 1.2 GB くらいでした. Whisper large (5 GB くらい)より少ないので, 12 GB のメモリある GPU なら動くと思われます(3090 では動作確認).



```
$ whisperx --model large-v2 input.wav --language ja
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/54e4d33c-2b9b-fec6-14d2-9a56b2abbc21.png)

`input.wav.word.srt` に, ワード(日本語の場合は単語)ごとのアラインメント結果が得られます.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/915e9f6f-4de0-63d9-6eef-f55ad6e296f7.png)

Voiala!

## 日本語で音素単位とかでアラインしたい...

このあと text-to-speech させたり, 顔認識してそれぞれの発音時点での顔表情を取得したいなどで, 音素(phoneme)単位でのアラインメントがほしいときがあります.

https://en.wikipedia.org/wiki/Japanese_phonology

音素とか取り出したい場合はここから mecab か openjtalk あたりで変換するのがよいでしょうか(文節も解析して無声音とかも扱えたりするじゃろか?)

tdmelodic と合わせてアクセント推定するのもできそうです!

https://github.com/PKSHATechnology-Research/tdmelodic

そのうち transformer あたりで音声あたえたら音素やアクセント推定など一式ぺろっと推定してくれるモデルがでてきそうですネ.
[Jetpack Compose] 再コンポジションされているのにUIが更新されない

## 概要
Jetpack Composeを使用して画面を作成した際、コード上は再コンポジションされているのに、端末上のUIが更新されないという事象に遭遇しました。
``` MainActivity.kt
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val counterState = remember { mutableStateOf(0) }
            Counter(
                count = counterState.value,
                updateCount = { newCount ->
                    counterState.value = newCount
                }
            )
        }
    }
}

@Composable
fun Counter(count: Int, updateCount: (Int) -> Unit) {
    Button(
        onClick = { updateCount(count + 1) },
        colors = ButtonDefaults.buttonColors(
            contentColor = if (count > 5) Color.Green else Color.White
        )
    ) {
        Text("I've been clicked $count times")
    }
}
``` 
上記コードを実行してボタンを押すると、ボタンのテキストが「~ 1 times」、「~ 2 times」と増えていくはずです。
![20230102-215852.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610553/66a81177-925f-10a4-bfc0-5004f88e3fb3.png)
しかし実際は、ボタンを押すたびに `Counter` コンポーザブルは呼び出されるものの、画面のボタンテキストが「I've been clicked 0 times」から変わりませんでした。
`Counter` コンポーザブルが呼び出されることは、ログを仕込んで確認しています。


## 実行環境
端末：Google Pixel 4a(5G)
OSバージョン：Android13
``` app/build.gradle
compose_version = '1.3.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
```

## 修正方法
Compose UIのバージョンを `1.4.0-alpha02` 以上に上げるか、 `1.2.1` 以下に下げてください。
`1.4.0` まで上げることを修正方法としていないのは、現時点で最新のバージョンが `1.4.0-alpha03` だからです。

## 原因
今回の事象が発生するバージョンを調べました。
* 1.2.1 → 発生しない
* 1.3.0 → 発生する
* 1.3.1 → 発生する
* 1.3.2 → 発生する
* 1.4.0-alpha01　→ 発生する
* 1.4.0-alpha02 → 発生しない
* 1.4.0-alpha03 → 発生しない

つまりCompose UIの `1.3.0` で今回の事象が発生するような対応がされ、 `1.4.0-alpha02` で修正されたと推測できますが、[リリースノート](https://developer.android.com/jetpack/androidx/releases/compose-ui?hl=ja) を見ても分かりませんでした...。
調べてもこのような事象に遭遇している人が見つからなかったので、何か他ライブラリのバージョンとの組み合わせによるものかもしれません。
誰か分かる方いたら教えてください。
【PHP】エラーハンドリング ~Exceptionクラス~

## PHPの例外処理
プログラムの異常終了を防ぐために、例外として処理する。
PHPではExceptionクラスを使う。
https://www.php.net/manual/ja/language.exceptions.php 

## Exceptionクラスの使い方

例外をスローする。（例外が発生することを例外を投げるという）
```php
<?php
throw new Exception();
?>
```
例外が発生する可能性のあるコードをtryで囲み、例外を受け取った後のコードをcatchに記述する。

```php
<?php
try {
    // 例外が発生する可能性のあるコード
} catch (Exception $e) {
    // 例外を受け取った後のコード
?>
```

変数$flgの値がtrueの時はOKと返し、falseのときに例外として返す。
```php
<?php
function checkFlg($flg)
{
    try {
        if ($flg == false) {
            throw new Exception('エラーはキャッチ');
        }
        $message = "エラーなし";

    } catch (Exception $e) {
        $message = $e->getMessage();    
    }
    echo $message;
}

checkFlg(true); // エラーなし
checkFlg(false); // エラーはキャッチ
?>
```
getMessage()にて例外メッセージを持たせることができる。例外メッセージはどのようなエラーが発生したかのか示すために使われる。


## Exceptionクラスの拡張
Exceptionクラスを拡張し、独自の例外クラスを使用することができる。例外クラスを拡張するとは、Exeptionクラスを継承する。
```php 
<?php
// Exception拡張する
class ExpansionException extends Exception {
}
try {
    throw new ExpansionException();
} catch (ExpansionException $e) {
    echo "拡張したExceptionクラス";
} 
?>
```
gdstkでフォトマスク設計①

今回からは実際にフォトマスクの設計について学んでいきたい。

今回も@isourouさんの記事を参考にして自分の備忘録として残していく。

まず、以下のコードを実行した。
```
import gdstk

lib = gdstk.Library() #特に指定しなければ単位はum
topcell = lib.new_cell("Top") #Topセルを作成

subcell = lib.new_cell("subcell") #サブセルを作成
box = gdstk.rectangle((0,0), (1,2)) #左下(0,0),右上(1,2)の四角形を作成
subcell.add(box) #四角形をサブセルに追加
ref = gdstk.Reference(subcell, origin=(0,0), columns =3, rows =2, spacing = (5,5)) #サブセルへの配列リファレンスを原点(0,0)に挿入。3行2列で、間隔は(5,5)
topcell.add(ref) #サブセルへのリファレンスをTopセルに挿入。


text = gdstk.text('First GDS',2, (0,10)) #高さ2のテキストを位置(0,10)に挿入。
topcell.add(*text) #gdstk.textは1文字ずつのPolygonのリストを返すので、*textでリストをunpackしてadd()に渡す。

lib.write_gds('output.gds') #gdsファイル出力
topcell.write_svg('output.svg') #svgファイル出力
```
早速1行毎に追っていきたい。
```
import gdst
```
gdstkモジュールをインポートしている（おまじない）
```
lib = gdstk.Library()
```
gdstkクラスのLibraryメソッドで、libに設計ルール（寸法など）やセルを含むライブラリを作成している
class gdstk.Library(name='library', unit=1e-6, precision=1e-9)
name: ライブラリ名の文字列。
unit: ライブラリ名で用いられる長さ単位[m]。特に指定しなければ1 umになる。
precision: ライブラリ内で用いられる寸法精度[m]。リソグラフィ装置の仕様に応じて決定すること。特に指定しなければ1 nmになる。ライブラリ内部では、寸法はprecisionを1とした整数値として保存される。
```
topcell = lib.new_cell("Top")
```
libに"Top"という名前のセルを追加し、変数topcellに格納する。
```
subcell = lib.new_cell("subcell")
```
1行上と同じような内容
```
box = gdstk.rectangle((0,0), (1,2))
```
rectangleメソッドで長方形を変数boxに代入する
```
subcell.add(box)
```
セル（subsell）にジオメトリ要素を追加する
```
ref = gdstk.Reference(subcell, origin=(0,0), columns =3, rows =2, spacing = (5,5))
```
他セルへのリファレンスを出力する
セル（subcell）を基に、(0,0)の位置からx方向に5、y方向に5開けてx方向に3つ、y方向に2つ複写する
（他の引数は公式を参照してください）
```
text = gdstk.text('First GDS',2, (0,10))
```
テキストパターンを出力してtextに格納している
```
topcell.add(*text)
```
gdstk.textは1文字ずつのPolygonのリストを返すので、*textでリストをunpackしてadd()に渡す。

```
lib.write_gds('output.gds')
```
ライブラリ（lib）をgds形式で出力
```
topcell.write_svg('output.svg')
```
セル（topcell）をsvg形式で出力

殆どが参考にした記事の写しになってしまいました、、、
後々はboolean処理やPathについても説明を加えていきたいと思います。
ChatGPTでスクレイピングをする(その1)

ChatGPTを使ってスクレイピングをする。またはスクレイピングを行うコードを出力する。

# ケース1. 単純なHTMLの表

#### 質問:
Scrape following html and answer my question. How old is Jane Doe?
<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="contents">
<table>
<tr><th>name</th><th>age</th></tr>
<tr><td>John Doe</td><td>30</td></tr>
<tr><td>Jane Doe</td><td>29</td></tr>
</table>
</div>
</body>
</html>

#### 回答: According to the html provided, Jane Doe is 29 years old.
#### 評価：正解

# ケース2. JavaScriptのプログラムを生成
質問: Could you show me the source code for scraping age in JavaScript?

回答:
Certainly! Here is some code that would allow you to scrape the age of Jane Doe from the HTML you provided using JavaScript:
```
const table = document.querySelector("table");
const rows = table.querySelectorAll("tr");

let janeDoeRow;
for (const row of rows) {
  const nameCell = row.querySelector("td");
  if (nameCell.textContent === "Jane Doe") {
    janeDoeRow = row;
    break;
  }
}

const ageCell = janeDoeRow.querySelector("td:nth-child(2)");
const age = ageCell.textContent;

console.log(`Jane Doe is ${age} years old.`);
```
This code first selects the table element and then finds all of its rows. It then loops through the rows and finds the one that contains the name "Jane Doe". Once it finds the correct row, it selects the second cell (which contains the age) and logs the age to the console.

I hope this helps! Let me know if you have any questions.

#### 評価: 正解。でもこれだと出力がハードコードされてしまっている。


# ケース3: ハードコードしないプログラムの生成

質問: Could you show me the source code for scraping the list of names and ages from above html in JavaScript? 

回答: Certainly! Here is some code that would allow you to scrape the names and ages from the HTML you provided using JavaScript:
```
const table = document.querySelector("table");
const rows = table.querySelectorAll("tr");

const namesAndAges = {};

for (const row of rows) {
  const nameCell = row.querySelector("td");
  const ageCell = row.querySelector("td:nth-child(2)");

  if (nameCell && ageCell) {
    const name = nameCell.textContent;
    const age = ageCell.textContent;

    namesAndAges[name] = age;
  }
}

console.log(namesAndAges);
```

#### 評価: 正解

# ケース4: スクレイピング結果をSQLに変換
#### 質問: Could you show me the SQL script for scraping the above html, extracting the names and ages and storing the data in a SQL database?

回答: Here is a SQL script that would allow you to scrape the names and ages from the HTML you provided and store the data in a SQL database:

```
CREATE TABLE people (
  name VARCHAR(255),
  age INT
);

INSERT INTO people (name, age)
VALUES ('John Doe', 30),
       ('Jane Doe', 29);
```

#### 評価： 正解

# まとめ
まぁ、これは出来るだろうなと思ってました(偉そう）。続く
Isaac Sim 2022.2でROS2関連にアップデートが入った話

# はじめに
Isaac Simお馴染みのびっくりアップデートです。
最近配信されたアップデートのリリースノートに`ROS2 Windows Beta`と`ROS2 Humble Beta`との記載があり調査しました。

## ROS2 Windows Beta
名前の通りWindows版のIsaac SimでROS2が使えるようになりました。インストール方法とIsaacSimの起動方法(ROS2を使うにはlauncherから起動できません)は以下を参照してください。

https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/install_ros.html#ros-2-windows-beta

個人的にはWindowsネイティブROSは使えるパッケージが少なかったりするのでHyper-VでROS2実行VMを用意した方が良いと思います。

https://twitter.com/tg3517/status/1609432807239217152?s=20&t=lRj-kqXf0YqmjtDiVdlHuA

## ROS2 Humble Beta
Humble対応が入りました(公式)。ROS2 Humble Bridgeというものが追加されましたが中身は内包しているDDSをアップデートした物のようです。
ですので以下のバージョンで動作することを確認しました(Ubuntu 20.04)。
- ROS2 Humble (Source build)
- ROS2 Foxy (Debian packages)
- ROS2 Galactic (Debian packages)

## ROS2 Bridge
元からあるやつですがついに最新の**Foxy**と**Galactic**でも動かなくなりました。おとなしく**HumbleBridge**使いましょう。
zshを学ぶには？

新たにプログラミング言語などを学ぶとき、効率的な方法はどういう方法だろう？
最近だとYouTubeなどの動画で勉強する人が多いのだろうか？

自分はマニュアルなどのドキュメントを読んで、実際にコードを書いて動きを確かめたい人間なので、チュートリアルやガイドみたいなものを探してみました。
以下のユーザーズガイドが見つかったので、これのOnline versionを読み進めたいと思います。
[A User's Guide to ZSH](https://zsh.sourceforge.io/Guide/)

Wikipediaで知ったけど、macOS 10.15 Catalinaからユーザーが使用するシェルのデフォルトとしてzshが採用されているとのこと。過去に2年半ほどMacbook Airを使っていたけど10.14 Mojaveでbashのまま使っていました。
[Z Shell - Wikipedia](https://ja.wikipedia.org/wiki/Z_Shell)

当時は何も考えなかったけど、最近は色々使ってみて幅を広げてみることもいいんじゃないかと考えるようになりました。コードを書くことにもよい影響があることを期待しています。
Dockerにて構築されたPHP(Laravel)環境で、MailHogを使ってメール送信処理をテストする

# 概要
ローカル環境でメール送信処理をテストする際。
実際にメール送信されないようにしつつ、挙動をテストするため、MailHogを利用しました。
設定方法などメモします。

# 環境
- PHP8.1系
- Laravel9系
- ローカル環境はDockerにて構築

# 設定方法
## MailHogを導入
`docker-compose.yml`にMailHogの記述を追加します。（ここで立ち上がるコンテナが、ローカル用のSMTPサーバーとなります）
[DockerHubに公開されているイメージ](https://hub.docker.com/r/mailhog/mailhog/)をそのまま利用できます。

```yml
services:
  mailhog:
    image: mailhog/mailhog:latest
    ports:
      - "8025:8025"
      - "1025:1025"
```

`1025`はSMTPポート用、`8025`はHTTPポート用（ブラウザからMailHog管理画面にアクセスする用）として設定しています。

## (PHP用設定)mhsendmailを導入
PHPのメール送信処理は、デフォルトでは内部で`sendmail`を用いています。[参考](https://www.php.net/manual/ja/mail.requirements.php)
MailHogを利用する場合は、メール送信コマンドを`mhsendmail`に変更する必要があります。

mhsendmailをインストール。

```dockerfile
RUN curl -sSL https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 -o mhsendmail && \
  chmod +x mhsendmail && \
  mv mhsendmail /usr/local/bin/mhsendmail
```

`php.ini`に以下の設定を追加。

```
sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"
```

## (Laravel)環境変数設定
メール関連の環境変数を以下のように設定します。

```
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_FROM_ADDRESS="送信元アドレス"
```

# 動作確認
`http://localhost:8025`にアクセスすることで、画面上からメール送受信を確認することができます。

```php
mail(
    'test1@example.com',
    'test',
    'test',
    'From: test2@example.com'
);
```

![スクリーンショット 2023-01-02 21.13.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/9db56393-5994-30f5-e924-2c30c1da4854.png)

# 参考
- https://www.php.net/manual/ja/book.mail.php
- https://mailtrap.io/blog/mailhog-explained/#What_is_mhsendmail
変数の定義　基本的な使い方

前回までは文字列、数値と言うように値を呼んでいましたが、今日からは、データ型と呼びます。
```text:データ型
"Hello World"(文字列）→→→→　String型
3（整数）→→→→　int型
```
簡単に説明するとStringは文字列、int(integer)は整数を意味します。
あと<font color="Red">注意する</font>ところは、
```
String型は大文字から始まり、
int型は小文字から始まる。
```
基本なので間違えないように！
[このようなこと](https://qiita.com/singekino-ojisan/items/12a51976b827e7dedb1c#comment-7c3391dbc179490cbf3d)もあるとご指摘いただいただきました。
ご教授いただきありがとうございます！


次に変数について。
簡単に言うと、
```
データ(値)を入れておく箱（変数）

箱（変数）には名前（変数名）がついていてその名前を使い、
変数から値を取り出すことができる。
```
| 箱(変数) |                         
|:-:|
|   箱の中のデータ(値)|

うまく作れずわかりずらいですが、こんな感じです。笑
これはプログラミングではお決まりのことなので忘れないようにしましょう。
***
<font color="Green">**変数の使い方**</font>
変数を使うには、まず、変数を定義しなければなりません。
卒業証書をもらうときに先生が<font color="blue">**「何年何組〜くん」**</font>と<font color="blue">**何年何組の**</font>と指定しますよね？
そんな感じで、「何年何組（変数）」と定義し、その中から「〜くん(値)」を取り出して使います。

変数を定義することで箱が作られます。
Javaで変数を定義するためには
```
変数にいれる値のデータ型を指定する
```
```
変数の名前を決める
```
この2つが必要になります。

変数を定義したら変数に値を入れて行きます。
これを代入と言い
```
「変数名 = 値」
```
とすると代入できます。
例えば、**number**と言う**int型**の変数を定義します。
その中に、**2**と言う値を代入します。
```java:Main.java
int number;
number = 2;
```
これでnumberと言う変数に２と言う値を代入できました。
String型も同じように、
例として、**name**と言う変数に**Sato**と言う値を代入します。
```java:Main.java
String name;
name = "Sato";
```
<font color="Red">ここで注意が、String型は、整数でなく、文字列を代入するので、「""」ダブルクォーテーションを忘れずに！</font>

あと、プログラミングで「＝（イコール）」は、右の値を左のものに代入するという意味になります。
数学のような同じと言う意味ではないのでお気をつけて！

入れたんだから、取り出そう！
と言うことで、変数から値を取り出してみましょう。
```java:Main.java
int number;
number = 2;
System.out.println(number);

String name;
name = "Sato";
System.out.println(name);
```
そう！これだけ！
順に説明すると、
```
①変数を定義
②変数に値を代入
③値を取り出し処理
```
これにより
```text:java:コンソール
 2
 Sato
```
となるわけです。
***
<font color="Green">**変数の初期化**</font>

変数の値の代入は変数定義と同時に行うこともできちゃいます。
```java:Main.java
int number = 5;

String name = "tanaka";
```
このように定義と同時に代入を行うことを<font color="Green">**変数の初期化**</font>と言うらしいです。
なぜ初期化？と皆さん思いますが、大丈夫です。
私も思ってます。
気になったので調べてみました。こちらをどうぞ！
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word12961.html#:~:text=int%20i%20%3D%2010%3B,%E5%88%9D%E6%9C%9F%E5%8C%96%E3%80%8D%E3%81%A8%E8%A8%80%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)

次回は、
色々な使い方を記事にしていこうと思います。

ありがとうございました。
Elixirから覚えるJavaScript　〜sort(変数の挙動)〜

僕は普段はElixirを使ってます
必要になったのでJavaScriptの勉強をはじめました
題名はElixirから覚えるJavaScriptですが、逆もできるかも？

今回はsortについて挙動を確認したいと思います
別にsortでなくてもよい、変数がどのように管理されているか知りたかった

# Elixir

```elixir
arr = [5, 4, 3, 2, 1]
x = arr |> Enum.sort()
IO.inspect(arr)
IO.inspect(x)
```

```elixir:実行結果
[5, 4, 3, 2, 1]
[1, 2, 3, 4, 5]
```

# JavaScript

```javascript
arr = [5, 4, 3, 2, 1];
x = arr.sort();
console.log(arr);
console.log(x);
```

```javascript:実行結果
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 3, 4, 5 ]
```

arrが書き換わってしまう…

と言うことで対策
スプレッド構文`...`を使ってみる

```javascript
arr = [5, 4, 3, 2, 1];
x = [...arr].sort();
console.log(arr);
console.log(x);
```

```javascript:実行結果
[ 5, 4, 3, 2, 1 ]
[ 1, 2, 3, 4, 5 ]
````

無事に同じ結果になりました


https://qiita.com/t-yamanashi/items/263b53d889dc5f7ddf17
フォトマスク作成にはgdstkが良いかも？

フォトマスクの設計を学びたく、layout Editorを弄っていたが、
迷走しているうちに@isourouさんの「gdstkでPython最速のGDSII layout制作環境を作る」
という記事を発見した。

どうやらpythonでgds形式のファイルが作成できるとのことで、
繰り返しパターンの多いフォトマスクの設計に打ってつけだと感じ、
Layout Editorをほっぽりだして早速取り組んでみた。

今回の記事では、環境の構築で手間取った点について備忘録として残す。

・環境構築で手間取った点
これについては@isourouさんの記事に詳しいが、
注意点として、<font color="#ff0000">python3ではパッケージがインストールできない</font>ことが挙げられる。
この問題について検索したところ、python2でないとインストールできないとの記事を発見した。

そこでpython2.7の仮想環境を準備したところ、あっさりインストールできた。
仮想環境の構築からインストールまでの手順を備忘録として以下に示す。
（＊Anacondaを使用した場合）
1.python2.7の仮想環境を準備
conda create -n ”作成したい仮想環境名” python=2.7
2.activateする
activate ”作成したい仮想環境名”
3.パッケージをインストール
conda install gdstk

これで準備は完了です。

次回以降は簡単なパターンの作成方法について、備忘録として残していきます。
（今までプログラミングから逃げてきちゃったから、不安だなぁ、、、）
OAuthに関する学習メモ

## 学習背景

実務でgoogle apiを使用するにあたり、OAuthという用語を見かける機会があり、どいういう意味だったのか過去にも書籍やネットで調べてみましたが、腑に落ちなかった記憶があり、改めて学習し直しました。以下の山浦清透さんが出されている解説動画がとてもわかり易かったため、解説動画を見て、自身の知識を整理するためにも記事を書きました。

https://www.youtube.com/watch?v=w4gUaBMDm7A

## OAuthとは

サービスにログインする際にID・パスワードを使用せずに以下の赤枠で囲ったボタンを押すことによって、サービスにログインできるようになりました。その際に利用している仕組みがOAuth（オーオース）です。

![ログイン_-_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673263/4f136178-7f57-2df9-e9b8-c8a5d572c874.png)

このOAuthを使うと何が嬉しいのかと言いますと、
`まずID・パスワードを使用せずにログインすることができるため、それらの管理が不要であることや変更する手間がいらないことです。
また、セキュリティ的にも安全であることです。`例えば、googleスプレッドシートに書いてあるデータをグラフ化するサービス（サードパーティアプリ（※））があったとします。そのサービスを利用するために、OAuthを使用しなかった場合、そのサービスからスプレッドシートにアクセスするために、googleのID・パスワードをサードパーティアプリに保存しなければいけません。そのため、サードパーティアプリからID・パスワードが外部に漏れる可能性もございます。しかし、OAuthを使用すると、サードパーティアプリでは、googleのID・パスワードの管理が不要になるため、セキュリティ的にも安全です。
他にもサードパーティアプリからサービスへ限定的にアクセスさせることができるため、セキュリティ的に安全になります。例えば、上記のサードパーティアプリがスプレッドシート以外にもgoogleメールのようなサービスを操作できてしまうと、個人情報が外部に漏れてしまったり、データが消されてしまったりする可能性があります。OAuthを使用すると、サービスを限定的にアクセスさせるようにできるため、上記のような事態を防ぐこともできます。


※そもそもサードパーティアプリとは、ある特定アプリの非純正の関連アプリのことです。

OAuthをまとめると以下です。

>認可（※）のフレームワーク
>サードパーティアプリがHTTPサービスへ限定的にアクセスできるようにする。
>ID・パスワードなしでサービスをアクセスできる。

※認可とは認証されて、利用権限があるサービスを使用して良いという許可されていること。例えばGoogleのメールだけ使用権限がある場合はメールを使用できるが、スプレッドシートの権限がない場合は許可がないため、使用できない。
Angularでシステム環境変数(process.env)を簡単に使う方法 @ngx-env/builder

Angularではシステムの環境変数を下記のように使用することはできません。
```environment.ts
export const environment {
  hoge: process.env['FUGA']
}
```

これを解決するためには、[custom-webpackを使う方法](https://qiita.com/sengoku/items/0a847b5a149c005f065e)がありますが、今回はこちらの方法ではなく、ngx-envというpackageを使って簡単に実現する方法を紹介します。

https://github.com/chihab/ngx-env

## Version
angular version : 14.2.10
angular15にはまだ対応していない模様ですので注意してください。(2023/01/02現在)

## How to use ngx-env
1. ng add @ngx-env/builder
2. src/env.d.tsで変数定義
3. tsconfig.jsonでexclude

### 1. ng add @ngx-env/builder
angularプロジェクトの中で下記コマンドを実行します。

```bash
ng add @ngx-env/builder
```

```bash
ℹ Using package manager: npm
✔ Found compatible package version: @ngx-env/builder@2.2.0.
✔ Package information loaded.

The package @ngx-env/builder@2.2.0 will be installed and executed.
Would you like to proceed? Yes
✔ Packages successfully installed.
CREATE src/env.d.ts (174 bytes)
UPDATE angular.json (3049 bytes)
```
src/env.d.tsというファイルが作られ、angular.jsonはUpdateされました。

## 2. src/env.d.tsで変数定義
src/env.d.tsというファイルの中身を見ると、下記のような中身になっています。
```default src/env.d.ts
declare var process: {
  env: {
    NG_APP_ENV: string;
    // Replace the line below with your environment variable for better type checking
    [key: string]: any;
  };
};
```

ここに使用する環境変数の型定義を書けばOKです。
私はNG_APP_API_URLという環境変数を使いたいので、こう書きました。
```modified src/env.d.ts
declare var process: {
  env: {
    NG_APP_API_URL: string;
  };
};
```

ちなみに、環境変数はNG_APP_から始まる必要があります。
dotenvにNG_APP_*と書いて使うこともできます。

### 3. tsconfig.jsonでexclude

このまま使おうとすると、下記のようなTypeエラーが出てしまうので、tsconfigでenv.d.tsを無視するようにします。
```bash
Error: src/env.d.ts:1:13 - error TS2403: Subsequent variable declarations must have the same type.  Variable 'process' must be of type 'Process', but here has type '{ env: { NG_APP_ENV: string; }; }'.

1 declare var process: {
              ~~~~~~~

  node_modules/@types/node/ts4.8/globals.d.ts:27:13
    27 declare var process: NodeJS.Process;
                   ~~~~~~~
    'process' was also declared here.
```

tsconfig.jsonの末尾にexcludeを追加します。
```diff
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  },
+  "exclude": ["src/env.d.ts"]
}
```

### おわり
以上です。
直接process.envを使うのも、environment.tsの中でprocess.envを使うのも可能です。

## Appendix 
ちなみにangular.jsonは次のように書き換えられています。
builderが@angular-devkit/builder/angularから、@ngx-env/builderに変わっている様子です。
```diff
-          "builder": "@angular-devkit/build-angular:browser",
+          "builder": "@ngx-env/builder:browser",
-          "builder": "@angular-devkit/build-angular:dev-server",
+          "builder": "@ngx-env/builder:dev-server",
-          "builder": "@angular-devkit/build-angular:extract-i18n",
+          "builder": "@ngx-env/builder:extract-i18n",
-          "builder": "@angular-devkit/build-angular:karma", 
+          "builder": "@ngx-env/builder:karma",
```


## Reference

https://itnext.io/how-to-use-system-environment-variables-process-env-in-angular-application-b9e7104dcc98

https://qiita.com/sengoku/items/0a847b5a149c005f065e
AWS Certified Solutions Architect - Associate（SAA）試験　合格体験記

## はじめに
以前合格したAWS Certified Cloud Practitionerに引き続き、AWS Certified Solutions Architect - Associate（SAA）にも合格したので、こちらについても共有しようかと思います。
~~下書きに書いたまま投稿忘れてました。~~

[Cloud Practitionerの記事](https://qiita.com/johnjohn622/items/e4a749e399142607a1ef)

# 概要
https://aws.amazon.com/jp/certification/certified-solutions-architect-associate
720/1000点で合格

### 試験構成
| 分野 | 出題の比率 |
| --- | --- |
| 第 1 分野: 弾力性に優れたアーキテクチャの設計  | 30% |
| 第 2 分野: 高性能アーキテクチャの設計 | 28% |
| 第 3 分野: セキュアなアプリケーションとアーキテクチャの設計  | 24% |
| 第 4 分野: コストを最適化したアーキテクチャの設計 | 18% |
| 合計 | 100% |

※今回私が受験したC-02は2022年8月29日が試験の最終日。C-03以降は範囲が変更され（増え）る。

- CBT形式
- 全て選択問題
    - 択一選択問題: 正しい選択肢が 1 つ、誤った選択肢 (不正解) が 3 つ提示される
    - 複数選択問題: 5 つ以上の選択肢のうち、正解が 2 つ以上ある
- 自宅受験も可
    - 条件あり
- 試験は140分
    - 試験本体は130分
    - 最初5分が試験の注意事項などを確認する時間
    - 最後5分がアンケート
    - 試験終了したら途中退室可
        - 自宅受験でも可能かは不明


### 印象
クラウドプラクティショナーと違い、用語を知っているだけでは合格は難しい。
ユースケースを意識して理解する必要があるので、そういう意味では実践的な資格と感じる。

### 受けた時期

- 2022年8月11日
    - 767点で合格
- Cloud Practioner（CLF）には合格済み

### 勉強法

使ったテキスト：
1. [【2022年版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)

進め方：
1. Udemyの模試（基本1つ、応用5つ）を2周。

- 1か月とか短期間で集中的にやった方がよい。
- AWSの一部サービス（EC2、Lambda、Cognitoあたり）には触った。

※Udemyの模試結果（70%が合格ライン）

|  | ① |  ② | ③ | ④ | ⑤ | ⑥ |
| --- | --- | --- | --- | --- | --- | --- |
| 1回目 | <font color="#d61b09">66%</font>（2022/3/25） | <font color="#d61b09">47%</font>（2022/4/13） | <font color="#d61b09">49%</font>（2022/5/16） | <font color="#d61b09">44%</font>（2022/7/20） | <font color="#d61b09">53%</font>（2022/7/26） | <font color="#d61b09">43%</font>（2022/7/29） |
| 2回目 | <font color="#069417">75%</font>（2022/8/2） | <font color="#d61b09">67%</font>（2022/8/3） | <font color="#069417">76%</font>（2022/8/6） | <font color="#069417">80%</font>（2022/8/7） | <font color="#069417">73%</font>（2022/8/8） | <font color="#069417">80%</font>（2022/8/9） |

# 試験対策
- Udemyの問題を学習のベースにするのが良い
    - 1から6まで順番に解く
        - 問題に重複がほぼないので1周目は点が上がらない
        - スマホアプリを使えばどこでも勉強できて便利
    - 8割くらいは取れるまで復習した方が良い
        - 模試だけだと知らない単語も出てくる
            - 推測はできなくはない
    - CLFと比べて問題が長い分、日本語がおかしい率が上がっている
    - 本番と同じくらいの難易度に感じた

### おさえておくべき知識
- 各サービスの中で、どういう場合に何を選ぶかを整理しておく
    - 問題文中にいくつかの要件が出てくるので、それにひとつひとつ対応できている選択肢を選ぶ必要がある

### その他
- 身分証が2つ必要なので注意
    - 免許証と保険証を出した
- テストセンター受験では途中退室可
- Udemyは定期的にセールされるので、受ける予定があるならそのタイミングで買っておくとよい
- 申込時に日本語を選択するのを忘れない
    - 問題は英語表示もできる

## 紛らわしい内容整理
個人的に紛らわしいと感じた内容を整理するために使った参考リンクやメモです。

### 全般
https://snowsystem.net/category/cloud/aws/ssa/

### インスタンスの選び方
https://biz.nuro.jp/column/aws-mama-022/#column-1

### S3のストレージクラス
https://dev.classmethod.jp/articles/should_i_choice_s3_storage_class/

### ELB
ALBはHTTP(S)、NLBはTCP/UDP
CLBは非推奨

### ElastiCache

MemCachedはマルチスレッド、Redisはシングルスレッド。
Redisの方が色々機能があって強い。
Snowflakeのカスタムロールで親子関係を作る際の注意点

## はじめに
Snowflakeの運用保守を担当した中で、ロール間で親子関係を構成した際の権限の継承に対する理解が十分でなかったためにトラブルシューティングで苦労したので注意点を記事に残そうと思いました。

## カスタムロールで親子関係を構成する時に注意すること
複数のカスタムロールの間で親子関係を構成する際、以下を注意して親ロールを指定する必要があります。

<font color="red">**・親ロールに指定されたロールは、子となるロールが持つ全ての権限を持ちます。**</font>
<font color="red">**・カスタムロールの親子関係の中で最上位のカスタムロールでは、親ロールにSYSADMINロールを指定する必要があります。**</font>

↓親子関係で最上位となるカスタムロールを作成する時に指定する親ロール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925708/b86c04a5-ded0-1318-a954-e1b04bbf2219.png)

- 参考：[カスタムロールの管理](https://docs.snowflake.com/ja/user-guide/security-access-control-considerations.html#managing-custom-roles)

## カスタムロールの構成例
以下のカスタムロールを作り、親子関係を構成しています（R_PARENTロールは、R_CHILD1ロールとR_CHILD2ロールの親ロールです）。

・**R_PARENTロール**
・**R_CHILD1ロール**
・**R_CHILD2ロール**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925708/9ad97b39-9c38-366e-44eb-85c665c4c51c.png)

R_CHILD1とR_CHILD2ロールは、それぞれデータベースに対するUSAGE、スキーマに対するUSAGEとCREATE TABLE、ウェアハウスに対するUSAGEとOPERATE権限を持ちます。

R_CHILD1とR_CHILD2ロールにおいて、親ロールにR_PARENTロールを指定すると、R_PARENTロールは子ロールが持つ権限を継承するため、R_CHILD1とR_CHILD2の両方のロールの権限を持つことができます。

さらに、カスタムロールの親子関係で最上位であるR_PARENTロールでは、親ロールにSYSADMINロール(システム定義ロール)を指定する必要があります。

SYSADMINロールを親ロールにすることで、SYSADMINロールがカスタムロールで作成された全てのデータベースオブジェクト(テーブル、タスクやストリーム等)を管理することができます。

もし、親ロールにSYSADMINロールを指定していないと、SYSADMIN並びにACCOUNTADMINですら、カスタムロールで作成されたデータベースオブジェクトを管理できなくなってしまいます。
(例えば、ACCOUNTADMINがカスタムロールで作成されたテーブルに対してデータを登録したり、テーブルの削除もできません）

**例) カスタムロールの権限が継承されていない状態で、ACCOUNTADMINがカスタムロールで作成されたテーブルを削除しようとした場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925708/f1e22a54-a4ab-ca6b-3e2d-daef99195465.png)

## おわりに
Snowflakeの運用では権限のコントロールが課題となります。利用者の用途が増えると、新たな要件が加わり、権限のコントロールも複雑になって見直しを迫られる場合もあります。今後もSnowflakeの運用で試行錯誤した経験を記事に掲載していきたいと思います。

# ご案内
株式会社ジールでは、「ITリテラシーがない」「初期費用がかけられない」「親切・丁寧な支援がほしい」「ノーコード・ローコードがよい」「運用・保守の手間をかけられない」などのお客様の声を受けて、オールインワン型データ活用プラットフォーム「ZEUSCloud」を月額利用料にてご提供しております。
ご興味がある方は是非下記のリンクをご覧ください：
https://www.zdh.co.jp/products-services/cloud-data/zeuscloud/?utm_source=qiita&utm_medium=referral&utm_campaign=qiita_zeuscloud_content-area
PHPのクラスについて

PHPのクラスについて学習した事のアウトプットです。

## クラス
クラスとは定数や変数（プロパティ）と関数（メソッド）をまとめたです。
※PHPマニュアルには”クラスの中にはプロパティそしてメソッドを含めることができる”と記載されている

~~~md:SimpleClass.php
<?php
class SimpleClass
{
    // プロパティの宣言
    public $var = 'a default value';
    
    // メソッドの宣言
    public function displayVar() {
        echo $this->var;
    }
}
?>
~~~
## 疑似変数 $this

PHPマニュアルには”メソッドがオブジェクトのコンテキストからコールされる場合は、 疑似変数 `$this` が利用可能。 `$this` は、呼び出し元オブジェクトの値”と記載されている。
サンプルコードを作成し考察する。
~~~md:SimpleClass1.php
<?php

$var = 'global value';
class SimpleClass
{
    // プロパティの宣言
    public $var = 'property value';
    
    // メソッドの宣言
    public function displayVar() {
        $var = 'local value';
        echo $this->var;  // 'property value'を出力
        echo "<br>";
        echo $var;  // 'local value'を出力
        echo "<br>";
        echo $GLOBALS['var'];  // 'global value'を出力
    }
}

$simpleclass = new SimpleClass;
$simpleclass->displayVar();
~~~
`$this->var`はクラス内で宣言しているプロパティ値'property value'である。
`$var`はメソッド内で宣言している変数値'local valur'である。
`$GLOBALS['var']`はクラス外で宣言している変数値'global value'である。

以上より、疑似変数 `$this` は自身のクラス内で宣言しているプロパティ値を参照するものであることがわかる。


## 参考文献
[PHPマニュアル](https://www.php.net/manual/ja/index.php)
[PHPのthisと->の意味がわかりません。teratail【テラテイル】｜ITエンジニア特化型Q&Aサイト](https://teratail.com/questions/123391)
TerraformでAWS環境をデプロイする前にしておくべきこと（tfstate.tf / provider.tf / output.tf / ディレクトリ構造）

前回の記事で「[TerraformでAWSリソースをデプロイしてみる](https://qiita.com/hiyanger/items/ca337f70ad4801072850)」を書きましたが、内容としては単にデプロイを目指すところまでの内容でした。なのでこの記事ではもう一歩踏み込んだ、Terraform環境を構築したところから、実際にコードを書き始める前に準備すべき（知っておくべき）ことを書いていきます:fire:

## tfstateファイルの配置場所
Terraformではデプロイ時にこの**tfstateファイル**にデプロイの情報を記録しています。なので、複数人でデプロイする場合に個別で（ローカル）このファイルをもってしまうと、デプロイに不整合が起こります。そのため、複数人でデプロイをする場合は必ずこのtfstateファイルを**S3**に配置しましょう。

#### 配置方法
①S3にバケットをバージョニングありで作成します。
②tfstate.tfを作成し、以下を記述します。

```tfstate.tf
terraform {
  backend "s3" {
    bucket = "①で作成したバケット名-アカウントID"
    key    = "terraform.tfstate"
    region = "ap-northeast-1"
    profile = "AWSプロファイル名"
  }
}
```
③terraform initを実行します。
```terminal:terminal
terraform init
```

## provider.tf
変数はこのファイルにかいてあげましょう。**アカウント番号や環境名、VPCのCIDRあたり**を中心にかいてあげるとよいです。

#### 変数の記述（provider.tf）
```provider.tf
locals{
  env = "環境名"
  account-id = "アカウントID"
}
```
#### iamrole.tf
```terraform
resource "aws_iam_role" "IAMロール名" {
  name = "${local.env}-IAMロール名"
}
```
#### jsonへの受け渡し（iampolicy.tf）
.tf→jsonへの受け渡しが可能です。こっちのパターンの方がよく使う印象です。
```
policy = templatefile("ディレクイトリ名/ポリシー名.json",{account-id ="${local.account-id}"})
```
## モジュール間の値受け渡し（output.tf）
Terraformはソースコードをモジュール化（テンプレート化）させることができます。VPCIDなど一度生成しないと判別できない値を他モジュールに受け渡しをする場合にこの手法を使います。
```output.tf
output "vpcid" {
  value = "${aws_vpc.vpc01.id}"
}
```
※モジュール参考

https://zenn.dev/sway/articles/terraform_biginner_modules

https://dev.classmethod.jp/articles/terraform_module_coordination/#toc-1

#### SecurityGroup.tf
```
vpc_id = aws_vpc.vpc01.id
```

## ディレクトリ構造
実際にコーディングしてみないとわからない部分かと思いますが、プロジェクトの規模感からできる限り見通しをたてておくと良いです。このディレクトリ構造に関しては、自分なりに考えたり勉強したり経験したりして常にベストプラクティスを追求する必要がありそうです。

#### リソースごとのディレクトリ
環境の規模からくる記述量によります。小さい環境（=コード量が少ない）ならリソースごとのディレクトリは作成しなくてよいですが、セキュリティグループなど、コードが冗長になりやすいリソースは個別にディレクトリをきった方がコーディングしやすくなります。デプロイの時間短縮や個別化という意味でも役に立つ手法です。

また、ポリシーなどが記載されるjsonは増えやすいファイルなので、基本ディレクトリ切る前提で考えてよいです。

#### 環境ごとのディレクトリ
具体的位には本番、ステージング、開発環境などの環境分をどうするかというところですが、 **各環境に対してディレクトリをきる**が一番安定かなと思います。変数が完璧に整えられ、各環境でコードが同一になるのであれば、新たにディレクトリは切らずに変数だけを変えるという選択肢もありますが、実際それで成立するケースは少ないだろうというのが理由です。

※こちらは以下の記事が参考になりました

https://qiita.com/reireias/items/253529c889cafb3fa4c7
【SwiftUI】ProgressView小さくない？

# はじめに
通信するアプリには必ずローディング画面があると思います。
ローディング画面で必須になってくるのが`ProgressView`だと思います。
しかし、SwiftUIの`ProgressView`ちっさすぎません？？？

いまいちイケてないのでもうちょっと大きくしたいです。
大きくした時のことをここに記録しておきます。

# 実装
```swift
import SwiftUI

struct ScaleEffectProgressView: View {
    private let scaleEffect: CGFloat

    init(_ scaleEffect: CGFloat) {
        self.scaleEffect = scaleEffect
    }

    var body: some View {
        ProgressView()
            .progressViewStyle(.circular)
            .scaleEffect(scaleEffect)
            .frame(width: scaleEffect * 20, height: scaleEffect * 20)
    }
}
```

```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ScaleEffectProgressView(3)
    }
}
```

![Simulator Screen Recording - iPhone 14 - 2023-01-02 at 18.44.55.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2857aaee-5a55-1477-7a94-42a54696e239.gif)

# 解説
`ProgressView`は`frame`では大きさが変わりません。
大きさを変更するには`scaleEffect`を使用する必要があります。

```diff_swift
struct ScaleEffectProgressView: View {
    private let scaleEffect: CGFloat

    init(_ scaleEffect: CGFloat) {
        self.scaleEffect = scaleEffect
    }

    var body: some View {
        ProgressView()
            .progressViewStyle(.circular)
+           .scaleEffect(scaleEffect)
    }
}
```
![スクリーンショット 2023-01-02 18.49.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/72838afd-5d2b-3555-54e2-7da60123a3ac.png)

これでもいい感じに思います。

しかし、これでは問題があります。

以下のように縦に並べてみます。
```swift
struct ContentView: View {
    var body: some View {
        VStack(spacing: 0) {
            ScaleEffectProgressView(3)
            Text("テスト")
        }
    }
}
```

そうすると重なってしまいます。

![スクリーンショット 2023-01-02 18.51.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/5e2b16c9-d19b-2a22-1cc3-a2d10067bdb8.png)

`ProgressView`に背景色をつけて確認してみます。
![スクリーンショット 2023-01-02 18.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/af2b94ab-8e78-4a8b-e4e9-2eb4d34c2144.png)
このように`scaleEffect`はコンポーネント自体の領域は広がらないみたいです。
ですので`frame`を使用してコンポーネント自体の領域を広げる必要があります。
`scaleEffect`で指定した数値の20倍でちょうどいい大きさになります。
```swift
struct ScaleEffectProgressView: View {
    private let scaleEffect: CGFloat

    init(_ scaleEffect: CGFloat) {
        self.scaleEffect = scaleEffect
    }

    var body: some View {
        ProgressView()
            .progressViewStyle(.circular)
            .scaleEffect(scaleEffect)
            .frame(width: scaleEffect * 20, height: scaleEffect * 20)
            .background(Color.red)
    }
}
```

![スクリーンショット 2023-01-02 18.56.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/37fc34a9-db5c-a0f0-6c29-9cfd99fcede1.png)

# おわり
`ProgressView`にラベルなどをつける場合にはもう少し考えないといけなそうです。