OmniAICreator/Qiita-1.07M huggingface dataset:
M5Paper: UIFlow の使い方

M5Paper で UIFlow を使う方法です。

Beta バージョンを使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/06a773b5-a1bb-1383-4240-62141d83218e.png)

Device を M5Paper にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/45851cc3-93d1-8169-cabe-312c720332d6.png)

プログラム
>Set screen show が必要です。
![m5paper01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/d9c091be-6252-a564-a534-ddb784b855ff.png)

Python での表示
![m5paper02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c190386b-4a48-5f96-fe9d-01035bba7367.png)

Run をクリックすると、プログラムがアップロードされます。
　(Wifi 経由でアップロードされます。）

![IMG_20220606_091049.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6686cc63-131e-73db-9fd1-ff4f4666c242.jpeg)
throttle関数のテスト



throttleのテストってどうやって書けばいいんだ...ってなったのでまとめます。
このテストで全部網羅できているわけではないと思うので、
「この項目もテストする必要があるよね!」等あればご教授くださいm

## 前提
jestを使用したテストです。
今回はタイマーモックを使用します。詳しくは[公式](https://jestjs.io/ja/docs/timer-mocks#enable-fake-timers)をご覧ください

## テスト対象のコード
```ts
 const throttle = (fn: () => void, interval: number): (() => void) => {
  let time = Date.now() - interval;
  return () => {
    if (time + interval < Date.now()) {
      time = Date.now();
      fn();
    }
  };
};
```

## テストする項目
今回テストした項目は以下です。

### 共通処理
タイマーモックを使うので、beforeEachで`useFakeTimers`をセットして
afterEachで`useRealTimers`でリセットします。

```ts
describe('throttle', () => {

  beforeEach(() => {
    jest.useFakeTimers();
  });
  afterEach(() => {
    jest.useRealTimers();
  });
})
```

### throttle関数の引数のfn()が呼ばれないパターン

```ts
import {　throttle　} from '置かれてる場所'

  it('fn()呼ばれないパターン', () => {
    const fn = jest.fn();
    const throttleFn = throttle(fn, 1000);

    throttleFn();
    expect(fn).not.toBeCalled();
  });
```

一見呼ばれてそうだな思いましたが、タイマーを進めていないので呼ばれていないです。



### 一定時間経過後に何回fn()が呼ばれるかパターン
```ts
  it('3回呼ばれるパターン', () => {
    const fn = jest.fn();
    const throttleFn = throttle(fn, 1000);

    throttleFn();
    expect(fn).not.toBeCalled();
    //ここまでは上のテストと同様です。

    for (let i = 0; i < 10; i++) {
      throttleFn();
      jest.advanceTimersByTime(500);
    }

    expect(fn).toBeCalled();
    expect(fn).toHaveBeenCalledTimes(3);
  });
```

`advanceTimersByTime`は指定した時間タイマーを進めることができます。
今回は引数に500を取っているので、500ms分タイマーが進みます。


throttle関数は1000ms経過後にfn()を呼び出すようにする関数です。
つまり1000ms経過しない限り呼ばれません。


```ts
    for (let i = 0; i < 10; i++) {
      throttleFn();
      jest.advanceTimersByTime(500);
    }
```

この部分をもっと噛み砕くと下記のような順番で処理が実行されます。

 i=0
 throttleFn();
 jest.advanceTimersByTime(500) //500msタイマーを進める

 i=1
 throttleFn();
 jest.advanceTimersByTime(500) //500msタイマーを進める
 ここの段階で1000ms時間経過しています。まだfn()は呼ばれません

 i=2
 throttleFn();
 jest.advanceTimersByTime(500) //500msタイマーを進める
 1500ms時間経過しているので、この段階でやっとfn()がよばれます。

## メモ
呼ばれたかどうかのチェックと余裕があれば回数チェックもできるといいかなと思いました。

## 参考記事
https://junhyunny.github.io/information/react/jest/throttle-test-with-jest/
Bundler の Platform 一覧 （Mac OS / Linux版）


## はじめに

- Bundler 2.2.x から 適切なプラットフォームを `Gemfile.lock` に記載する必要があった
- すべての環境をすぐに用意、再現できるマシンが複数手元にないため Platform 一覧を作成した
  - Mac OS は新しい OS が公開後更新します

## Platform 一覧

- Linux, Mac 別に記載します
  - 32bit 環境や Windows マシン は手元に無いため省略しています
- 以下に記載する Platform 名を `bundle lock --add-platform <Platform名>` コマンド実行時に渡すことで、実行環境の追加できます

### Linux

| OS    | x84_64       | arm64       |
| :---- | :----------- | :---------- |
| Linux | x86_64-linux | arm64-linux |

### Mac OS (darwin)

- Mac OS は新しい OS が公開されたら Platform 指定が変更になるため、アップグレード後追記します

| OS                                 | x84_64           | arm64           |
| :--------------------------------- | :--------------- | :-------------- |
| macOS Mojave 10.14.x (darwin-18)   | x86_64-darwin-18 | -               |
| macOS Catalina 10.15.x (darwin-19) | x86_64-darwin-19 | -               |
| macOS Big Sur 11.x (darwin-20)     | x86_64-darwin-20 | arm64-darwin-20 |
| macOS Monterey 12.x (darwin-21)    | x86_64-darwin-21 | arm64-darwin-21 |
| macOS Ventura (darwin-22)          | x86_64-darwin-22 | arm64-darwin-22 |
| macOS Sonoma (darwin-23)           | x86_64-darwin-23 | arm64-darwin-23 |

## Reference

https://gist.github.com/GolgothaX/4540102

https://github.com/rubygems/rubygems/blob/master/lib/rubygems/platform.rb#L14-L18

https://github.com/discourse/discourse/blob/main/Gemfile.lock

https://en.wikipedia.org/wiki/MacOS#Release_history
R言語のユーザグループ：Bakersfield Data Analytics and R Users Group

R言語のユーザグループについてちょっとピックアップしました。英語で申し訳ないですが、ちょっと面白いインタビューです。

[Bakersfield Data Analytics and R Users Group: Collaboration and the Need to Reach Out to Students](https://www.r-consortium.org/blog/2022/06/03/bakersfield-data-analytics-and-r-users-group-collaboration-and-the-need-to-reach-out-to-students)
100日後くらいに個人開発するぞ！day039

## 今日は条件分岐をやってみた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/230b3ef9-a7f6-d619-045d-888a8ae8425e.png)



## 今日の学び

### 条件分岐の方法（if文）
* 条件分岐とはある条件が成り立つときだけある処理を行うようプログラムすること
* if文を用いると「もし〜ならば・・・を行う」という条件分岐が可能になる
* if文の書き方
    * `if 条件式`
    * `　　　　　　処理  `
    * `end     `
* if文の書き方例：scoreが80より大きい場合は「よくできました」というテキストを出力する
    * `score = 94`
    * `if score > 80`
    * `puts "よくできました"`
    * `end`

### 真偽値
* 真偽値にはtrueとfalseという2つの値が存在する
* 条件式はが成り立つと「true」、成り立たなければ「false」という真偽値に置き換わる


### 大小比較
* aとbが等しい時
    * `a == b`
* aとbが異なる時
    * `a != b`
* aがbよりも小さい時
    * `a < b`
* aがbよりも小さいまたは等しいとき
    * `a <= b`
* aがbよりも大きい時
    * `a > b`
* aがbよりも大きいまたは等しいとき
    * `a >= b`
オバチャン忘れっぽいから復習するよ

以前書いた記事。

https://qiita.com/searching_saki/items/6ee952e7ee4d960400b0

noteに投稿した記事。

３Dでのヨガの試みと意気込みを一度整理しようと思う｜Saki @searching_yoga #note 

https://note.com/searcher_saki/n/n9fa2c95b49a7

なかなか思い通り進まないものですね。
[Oracle] OCI資格(1Z0-1072-21-JPN) の学習ポイント

## はじめに
これから Oracle Cloud の資格取得を目指す方のための情報をまとめています。
2022年4月から変更された部分の新情報を盛り込んでいます。

対象オラクルマスター
・1Z0-1085-21-JPN Oracle Cloud Infrastructure Foundations 2021 Associate
・1Z0-1072-21-JPN Oracle Cloud Infrastructure 2021 Certified Architect Associate
・1Z0-997-21-JPN Oracle Cloud Infrastructure 2021 Certified Architect Professional

関連記事
・[[Oracle] OCI資格(1Z0-1072-21-JPN) 概要をまとめた](https://qiita.com/nisshii0/items/8c82e93d0294703aa5f6)

## 試験 1Z0-1072-21 とは
オラクル社資料では、Cloud Architectの中級レベルに属する資格。
Oracle Cloud Infrastructureサービスの設計および運用経験が「6ヶ月」程度のレベルを想定された資格です。
Architectは、Oracle Cloudの様々なサービスが試験範囲です。
まずは「[公式サイト](https://education.oracle.com/ja/oracle-cloud-infrastructure-2021-architect-associate/pexam_1Z0-1072-21)」で試験範囲を確認しておきましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/929f58f8-e41c-046f-c414-927275ec84bc.png)


## 学習方法
オラクル社から公式の資格試験学習コンテンツが公開されています。
2022年5月現在、Oracle Cloudの試験対策本は発売されていないため、唯一の公式コンテンツとなります。
「研修講義の動画・PDFのテキスト・練習問題・模擬試験」が用意されているので活用しましょう。

このコンテンツだけで合格できるかというと、かなり難しいです。
PDFテキストを隅々まで理解しておければ、なんとか合格ラインに達すると思います。
本当に隅々まで確認していきましょう。
試験内容に言及できませんのであくまでイメージですが、PDFテキストの中でDBというコンテンツが1ページのみの紹介で
「DBの機能でxxがある」と1行しか書いていないようなコメントでも、しっかり覚えておいてください。

まずは研修動画をすべてみる！
研修動画内のリンクからPDFテキストをダウンロードできるため、あわせて活用。隅々まで確認。
これを繰り返し読み込むこと。
Oracle Cloud利用無料枠もあるので、できれば実機操作も行うとイメージがつきやすいです。


## オラクル社学習コンテンツへのアクセス
[オラクル社学習コンテンツ](https://education.oracle.com/learn/oracle-cloud-infrastructure/pPillar_640)

レベル毎に「研修講義の動画・PDFのテキスト・練習問題・模擬試験」が用意されているので活用しましょう。
利用にはオラクル社のサイトへのID登録が必要です。
ID登録については「[こちらの記事を参照してください](https://qiita.com/nisshii0/items/a80073051f790023562d)」

学習コンテンツにアクセスして、「Administrator」セクションから「Architect Associate」の「学習を開始する」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/4d62f3db-60a0-7cc7-5226-3c83a78de427.png)

学習コンテンツの内容です。
英語もあるため、とっつきにくく見えますが黄色の枠は以下の内容です。

|タイトル |コンテンツ内容 |学習時間 |
|---|---|---|
|Learn OCI & Try Hands-on Labs |研修動画とテキスト　★メインコンテンツ。これで学習します |14時間15分 |
|資格試験準備セミナー |試験の概要を把握しましょう |2時間25分 |
|Practice Exam|練習問題。本番より簡単なきがします |90分 |
|受験手続き |試験の申込や受験方法です。通常のオラクルマスター試験と異なるため確認しておきましょう |17分 |
|Online Certification Exam |ここから試験を申し込みます |実際の試験 |
|Learn OCI & Try Hands-on Labs |追加学習コンテンツです。必須ではないですがみておくとよいでしょう |14時間7分 |


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/526c8fe9-5d3d-2dcf-4208-2ecee8454a6b.png)

## 受験方法
Cloudではないオラクルマスター試験や、AWSなど、ピアソンVUE提供の資格試験になれた方には少し戸惑いがあるかもしれません。

Oracle Cloudの資格試験は前述の学習コンテンツの「Online Certification Exam」ボタンから申し込みます。
自分のPCを使った受験しか選択できません。DBのオラクルマスター試験のように試験センターに出向いての受験はできません。
受験用のPCにはカメラとマイクが必要です。
あまり厳密なチェックはありませんが、カメラにうつる背景（部屋）はきれいにしておくのがよいでしょう。
カンニングできそうな状況にみられると指摘されるかもしれません。壁を背にするとよいと思います。
なおオンライン会議でよくある仮想背景は使用不可です。

2022年5月現在、Associate試験は、火曜日から木曜日の9:30開始と、14:00開始しか選択できません。
終業後、学校の授業終了後に受けることができないのは、今後改善してほしいところです。
個人的には休日に受けたいです。

オンライン試験では試験監とオンライン接続して行いますが、会話をすることはありません。
すべて日本語のスライドで画面上で指示されますので安心してください。

試験が終わるとその場で結果が表示されます。
残念ながら不合格の場合、「翌日」から再受験できます。
このあたりもDBのオラクルマスター試験と異なります。
お金さえ許せば毎日受験できますが、同一試験は1年に5回までという制限がありますので、早めに合格できるように準備してから再受験が良いと思います。
Power PagesをVisual Studio Codeから編集できるか試してみた

今回は、先日のMicrosoft Build 2022でプレビュー版が発表された、Power PagesをVisual Studio Codeから編集するのを、早速試してみました。

## まずは、Microsoft Power Platform CLIをインストール
Microsoft Power Platform CLIとは、環境へコマンドラインでアクセスして、様々なコントロールをすることができるツールです。
今回はVisual Studio CodeなどPower Pagesのソースをダウンロードしたりできるようにする為にインストールします。

色々インストール方法はありますが、僕は単体インストーラーで試しました。
※ダウンロード先
https://aka.ms/PowerAppsCLI

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/57d6dfcf-09ff-1fda-7889-a843f6860265.png)
特に変更する部分はなくそのままインストールしました。

最新版かどうか、確認するためにWindows Power Shellから下記コマンドを発行してください。

```
pac install latest
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/d07cefee-6da1-fc17-b628-e11d0650ba9f.png)


## Windows Power Shellで環境へアクセス
Dataverse環境へアクセスするために、Power Shellから下記コマンドで認証を作成します。
コマンドライン入力後に、認証画面が表示されますので、管理者権限を持つアカウントでログインしてください。
```
pac auth create -u [環境のURL]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/43466a95-a012-3394-a77d-2c3bdd3e6402.png)
自社の有料で作成した環境にPower Pagesを作成したので、この形でアクセスができました。

接続できたら試しに環境に展開されたサイトのリストをコマンドで確認してください。
```
pac paportal list
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/e14357b2-1643-10b0-987f-33e3870d3166.png)
私の環境では、Power Pagesで展開されたサイトと、Power Apps Portalで展開された環境が確認することができました。

:::note info
環境のURLはPower Platform管理センターからPower Pagesを展開した環境を開くと、表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/2dccc1f3-a0a6-c1ba-fd9c-e722f6762a26.png)
:::

## コマンドでソースコードをダウンロード
ローカルにPower Pagesのデータをダウンロードします。
Windwos Power Shellで下記コマンドを発行しますすが、保存場所と先ほどのサイト一覧結果に表示された「WebSiteId」をデータダウンロードするのに指定します。
```
pac paportal download --path [保存場所までのパス] -id [WebSiteId]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/dc5c6407-8df7-5db7-0369-ebd509861014.png)
ダウンロードが完了したら、指定したディレクトリを確認すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/75d5b821-867d-3ebe-0462-78149e8ade7c.png)
こんな感じでファイルがダウンロードされています。

## Visual Studio Codeでファイルを編集
通常のソースコード編集は、そのままファイルを開くことで行えます。
Vusual Studio CodeのCLIから前述の操作したい方は、機能拡張から「Power Platform Tools」をインストールしてみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/a49d873f-787e-325f-a700-4f83fd044ad7.png)
早速HTMLを編集してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/5cb7f162-24ad-1d0d-0356-61d574cc5f29.png)
今回は超簡単にH1タグの文字を「お問い合わせ２」に変更しました。

内容を保存したら、Windows Power Shellから下記コマンドを発行しすると変更内容が環境へアップロードされます。
```
pac paportal upload --path [保存場所までのパス]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/5b5980ff-8d1e-ae90-3df3-731006a35d5d.png)

最後に変更内容を実際のPower Pagesのサイトで確認してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/5dcc686d-5a96-3adf-52d9-a2a082727988.png)

ちゃんと変更がサイトに反映できました。

これでローカルPCで編集する環境が構築できました。
次回は、実際にソースコードを色々変更してみたいと思います。

:::note info
Power Pagesについて詳しく知りたい方はこちらをご覧ください
https://docs.microsoft.com/en-us/power-pages/
:::
Railsプロジェクトに監視ツールSentryを導入する

Railsの監視ツールであるSentryを導入した際に、まとまっていて欲しかった情報をまとめました。

# 環境

```ruby

$ ruby -v
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]

$ rails -v
Rails 5.2.5

```

# 事前準備

- sentryの公式ページからアカウントを発行しておくこと

公式：
https://sentry.io/auth/login/o/

# インストール

- 旧式でRavenという名前になっているが、今はSentryに統一されている
- Sentryの公式ドキュメントを参照するとよい
- 以下はマニュアル通り

https://docs.sentry.io/platforms/ruby/guides/rails/

まずはライブラリをインストール

```Gemfile.rb
gem "sentry-ruby"
gem "sentry-rails"
```

```
$ bundle install
```

設定ファイルに、Sentry公式で取得したdnsファイルを指定する。
下は公式ドキュメントをコピペしてとってきたものなので、各自Sentryの公式から取ってきてください。

```config/initializers/sentry.rb

Sentry.init do |config|
  config.dsn = 'https://ae057caa888143fd8aaca98d4be139d7@o1185973.ingest.sentry.io/6305953' #ここは環境変数なりに入れる
  config.breadcrumbs_logger = [:active_support_logger, :http_logger]

  # To activate performance monitoring, set one of these options.
  # We recommend adjusting the value in production:
  config.traces_sample_rate = 0.5
  # or
  config.traces_sampler = lambda do |context|
    true
  end
end
```

これでとりあえず500エラーなどを起こすと、Sentry側で通知されるようになります。

```ruby 
Sentry.capture_message("test message") 
```

例外が発生した箇所に入れてあげると、Sentry側で捕捉します。

```ruby 

def import 
   ... 
   ...
   #何かしら失敗する処理
rescue StandardError => e 
   Sentry.capture_message(e)
end 

```


# 環境ごとのエラーの出しわけ

- productionやstaging環境などで、エラーを出し分けたい場合、sentryがよしなに`SENTRY_ENVIRONMENT`という環境変数で切り分けてくれます。
- 弊社ではHeroku上にステージング環境と本番環境が存在するので、それぞれstaging, productionを環境変数に入れています。

```.env

SENTRY_ENVIRONMENT = production
SENTRY_ENVIRONMENT = staging

```

- このように環境変数を指定すると、Environmentごとにどこでエラーが発生したのかがわかるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134704/717a5984-32d7-e9e6-4874-e47fdd301f24.png)

# Slack連携

- Alertという機能を使うと、Slackと連携してエラーを送ることができます。
- 上記で作成したEnvironmentごとにエラー通知先を切り分けることができるので、ステージングで起こったエラーと本番で起こったエラーなどが簡単に通知先分けられるのがよいです。
- ただしSlack連携は有料化しないとできないため注意が必要です。

SentryでSlackにエラーを送るAlertの設定方法
https://zenn.dev/a_ichi1/articles/0ffcadd00de3e5
「ファシリテーションの教科書」を読んで、会議とプロジェクト進行に活かしたいポイント

[ファシリテーションの教科書: 組織を活性化させるコミュニケーションとリーダーシップ | グロービス |本 | 通販](https://www.amazon.co.jp/dp/4492533486) を読んだ。

![](https://images-na.ssl-images-amazon.com/images/I/41+NmBjFPOL._SX354_BO1,204,203,200_.jpg)


ファシリテーションとは変革リーダーのコアスキルと...。

## 感想
- 単に会議の場面で議論を方向づけ、結論づける がファシリテーションかと思いきやそれだけではない、という話。
- 例えば何がしかのプロジェクト、計画、段取りにおいてどういう準備をすべきか。
- だいじなのは **全体の見取り図を描くこと** 。以下、その見取り図の描き方におけるカギをまとめる。おもに「仕込み」と「さばき」。


## 仕込み：　あるべき議論の姿を設計する
- ファシリテーションとは…
    - 議論を仕込む
        - 決定プロセスの納得性を高めるため
        - 行動を決めるため
    - 議論の出発点と到達点を明確にする

### 議論の大きな骨格をつかむ
- 合意形成のステップ
- その議論が終わった時点で、参加者や自分がどのような状態になっていればよいのか
- これって記事書くときとおなじですな

### 参加者の状況を把握する
- 議論に先立ち、参加者について考えておくべきことは何だろうか？
    - 参加者を深く知ること
    - 参加者の認識レベルを丁寧につかむこと
    - 参加者の意見、態度を予測し賛否両論かんがえること
    - 参加者相互の関係性に気を配ること

### 「論点」を広く洗い出し、絞り、深める
- 論点とは、意見が答えになるような問い
- 論点を飛ばして意見だけ述べてしまうと散らかってしまう
- 論点とは問い、問題提起
- 問題は広げたあと、絞り込み、重み付けて、深める

### 合意形成・問題解決のステップでファシリテーションを実践する
- アウトプット: 結果としての状態
- インプット: その状態に影響を与える要因・投入要素
- 論点の把握
- 最終的に議論の到達点、重要な論点とその関係を頭に刻み、論点の地図を持った状態にすることが「仕込み」のゴールである

## さばき：　議論を活性化し、思考を導く
- さばきの基本動作とは
    - 発言を引き出す
    - 発言を理解し、共有する
    - 議論を方向づける
    - 結論づける
- 発言を引き出し、**理解する**
- 発言を深く**理解する**
- 議論を方向づけ、結論づける
    - 今、議論すべきでない論点への対応
        - 他の参加者の同意を確認する
    - 議論すべき論点
        - 広げる
        - 深める
        - 止める
        - まとめる
            - どうしてもまとまらないときはより詳細化し、ある点は合意、ある点はまだ、と分ける
- 対立をマネジメントする
    - 相互の背景にある認識
        - 「ポジショントーク」の本来の意味は単にその通りポジションからの目線での意見だよななどと思った
    - 敢えて対立を「放置」し意見を引き出せるだけ引き出してから、まとめることもできる
- 感情に働きかける
- ファシリテーションは「合気道」
    - 2つのやり方がある
        - **コントロールする**
        - **敢えてコントロールしない**

## 参考記事
[「コンサル一年目が学ぶこと」](https://qiita.com/e99h2121/items/2b69ec9444ec1cc60cb7) と比べると高度だがこちらのほうが手練れの開発者向けで腹落ちする内容かもしれない、と感じる。特にリモートワークでは [リモートワークにおけるファシリテーションの方法論 - Google スライド](https://docs.google.com/presentation/d/1dQgbxB6_0kosazzgfk0Gmoa8c7dInfOy_NvZejfpneo/edit#slide=id.g814b63fdb8_0_12) こんなスライドも。

[【要約・まとめ】『ファシリテーションの教科書』をまとめてみた | ビジネス書要約ブログ -BYB-](https://business-book.sakura.ne.jp/facilitation-textbook-2/)
[【感想・ネタバレ】ファシリテーションの教科書―組織を活性化させるコミュニケーションとリーダーシップのレビュー - 漫画・無料試し読みなら、電子書籍ストア ブックライブ](https://booklive.jp/review/list/title_id/288663/vol_no/001)

以上です～
Python Controlのシステム結合を図付き解説

# はじめに
Python Controlは制御工学に便利なライブラリですが，ドキュメントに図が無いこともあってしばしば使い方を忘れるので，メモを兼ねて図付きで解説していきます．
今回は，システムの結合について解説します．

### バージョン
- Python 3.10.4
- Python Control 0.9.2

### 準備
```python
import control
```

# 解説
## `feedback()`

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1817119/7c2929ed-eaa5-b91d-0ec6-0194422e2d24.png" width="60%">

いわゆるフィードバックです．$r$から$y$のシステム$S$について，
```python
P = ...  # 任意のioシステム
K = ...  # 任意のioシステム
S = control.feedback(P, K)
# もしくは
S = P.feedback(K)
```
のように書きます．`control.feedback(P, K, sign=g)`と書くと，ネガティブフィードバックだけでなくポジティブフィードバックやゲイン付きのフィードバックができます．`sign`のデフォルトは`-1`です．

[`feedback()`の公式ドキュメント](https://python-control.readthedocs.io/en/0.9.2/generated/control.feedback.html "control.feedback")には`StateSpace`と`TransferFunction`にしか使えないように書いてありますが，`NonlinearIOSystem`などにも使えるようです（[`NonlinearIOSystem`の公式ドキュメント](https://python-control.readthedocs.io/en/0.9.2/generated/control.NonlinearIOSystem.html#control.NonlinearIOSystem.feedback "control.feedback")）．以降の関数でも同様です．

:::note info
SISOの伝達関数を使っているとき，$S=\frac{P}{1-gPK}$となるので`S = P/(1-g*P*K)`と書いてもいいのですが，`feedback()`を使った方が数値的に安定します．
:::


## `series()`

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1817119/2871dc3a-3368-ee5e-96f4-1ee7086f11b9.png" width="100%">

直列結合です．$r$から$y$のシステム$S$について，
```python
S_1, S_2, ..., S_n = ...  # 任意のioシステム
S = control.series(S_n, ..., S_2, S_1)
# もしくは
S = S_1 * S_2 * ... * S_n
```
のように書きます．

## `parallel()`

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1817119/9b1af215-7f8e-8ff3-3464-4f76fca00a13.png" width="54%">

並列結合です．$r$から$y$のシステム$S$について，
```python
S_1, S_2, ..., S_n = ...  # 任意のioシステム
S = control.parallel(S_n, ..., S_2, S_1)
# もしくは
S = S_1 + S_2 + ... + S_n
```
のように書きます．

# おわりに
中途半端ですが，とりあえずここで終わりにします．`interconnect()`についてはまた追記しようと思います．
なにか間違いがあれば教えていただけると喜びます．
Alfred上でDeepLを使用する

## はじめに
以下のようにAlfred上でDeepLを使用する方法について記載します。
![スクリーンショット 2022-06-06 午前4.27.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/edf0b616-334a-de50-4586-b8da516536c4.png)
![スクリーンショット 2022-06-06 午前4.29.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/26d28052-97ca-612d-76f1-c335076b8e8d.png)

## Alfred上でDeepLを使用する方法
`DeepL-Translate`というAlfred Workflowを使用します。

https://www.packal.org/workflow/deepl-translate

上記のページからダウンロードすることができますが、こちらからダウンロードしたものだと以下のように表示され使用できませんでした。


![スクリーンショット 2022-06-06 午前4.36.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/c8f9ed86-9265-6f56-0463-fd6ffcd30e50.png)

なのでGitHubからダウンロードします。

https://github.com/AlexanderWillner/deepl-alfred-workflow2

ダウンロードが完了したら`Deepl-Translate.alfredworkflow`を開きます。
すると、以下のような画面が表示されます。

![スクリーンショット 2022-06-06 午前4.42.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/1277b098-a6e3-1eec-41f0-9f7ae464f2d4.png)

`import`をクリックします。

![スクリーンショット 2022-06-06 午前4.45.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/5d6d381e-f337-8d52-ff30-789043c6c861.png)

上記の画面が表示されたら`dlfr`をクリックし内容を以下の画像の通りに変更します。

![スクリーンショット 2022-06-06 午前4.43.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/b665876c-8469-b0c0-8f0e-9af8cbcc42c8.png)

　`dlfr`の変更点
* Keywordを任意のKeywordに変更
* FRをENに変更

以上の設定を行うことで冒頭で示した通り、Alfred上でDeepLを使用することが可能になります。
翻訳する際には文末`.`を入力する必要がありますのでご注意ください。
コピペ用Excelでランダム文字列ワンライナー

どこかのセルに文字種や文字数をまとめておくと参照できるのだけど、
セル固定なども考えずに数式コピペ→オートフィル→範囲選択コピー→値貼り付け→保存ってやりたいとき、あるよね…。

というわけで、半角英数大小とハイフン、アンダーバーを、5-16文字出力したいときの例
```text:MS Excel関数
=CONCAT(MID("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_",RANDARRAY(RANDBETWEEN(5,16),,1,LEN("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"),TRUE),1))
```
文字種は２か所にペースト（数えるのが面倒なのでLENにもコピペする）
`RANDBETWEEN(5,16)`で文字数を制御

参考:  [いきなり答える備忘録 -（Excel）ランダムなパスワードを作成する](https://www.officeisyours.com/entry/2020/06/20/151655)
【AWS】請求書の内訳が気になったお話

## 記事の対象
インフラの勉強をしたいけど、AWSの料金が心配な方

## 経緯
請求書で金額がどーんと上がっている月があり、心配になったため、改めて料金の確認を行うことにしました。


## 注意点
あくまで個人で触る範囲でしか調べていないです。
**情報に漏れがある可能性もあるので、参考程度に見て頂けると幸いです。**


## 作業しているうちに3000円になっていた話
ある月の請求書確認すると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1705928/c9a448ee-6f38-d454-c434-b4b3ca827aee.png)

先月まで０円に近かったのに、急に料金が上がっていることに気づきました。

思い当たる節はいくつかあります。

１、EC２インスタンスたくさん起動させたままだった・・・
２、ドメイン取得したりした・・・

このあたりが怪しいですが、せっかくなので内訳をしっかり確認してみました。

## EC2
請求書を見ると、予想通り無料枠を超えていたようです。
EC２の無料枠は、以下の通りです。

**１、AWSアカウント作成後、１年間
２、月７５０時間まで
３、無料のインスタンスタイプであること（私はt2.microだった）
４、EC2インスタンス全体でカウントされる**

私は４番目の注意事項を失念しておりました・・・。
その結果、422時間分超過してしまうことに。
まあ、でも日本円で800円ほどですから（しくしく）
不要なEC２インスタンスは終了させて停止しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1705928/7d9899f3-8ede-fff2-5132-cb0e69020cb9.png)

## EBS
ここは盲点でした。
EC2インスタンスをたくさん作ってしまったせいで、EBSの無料枠のボリュームを超えてしまいました。
EBSの無料枠は、以下の通りです。

**1、月30GiBまで
２、EC2を停止してもEBSに対しての課金は停まらない**

なんと、EC２停止してもEBSのボリュームは残り続けるようです。
削除するためにはEC２を完全に削除して、しっかりとEBSのコンソール画面で確認する必要がありそうです。
私は、４つあったので32GiBで無料枠を超えておりました。
4つとも稼働していたので15GiBも超過しちゃったんでしょうか。
それと、AMIを使用したのでスナップショット分が少しだけ料金発生しておりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1705928/3ed42db0-9a3b-acc9-7361-5a8ea781b03d.png)


## ドメイン関係
残りは予想通りのドメイン取得関係でした。
内訳です。
レジストラはドメイン取得時と更新時に料金が発生します。
更新時とは取得から１年後です。
私は設定で更新をしないとした（はず）なので、１年経つとドメインがなくなりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1705928/64bba273-07d7-a61d-aaf0-434cf5f11d6f.png)

こちらはドメインを取得すると月々発生するものです。
25ゾーンまでは$0.5/月のようです。
DNSサービスは実行回数なども料金に加算されるようなので注意が必要かもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1705928/572275d2-dd47-fa08-60a1-e02528f260be.png)

## まとめ
請求書を改めてしっかり確認することで、料金設定についての知識をつけることができました。
AWSは料金の管理が怖いですよね。

学習していたら想像以上に料金が発生していた！ということがないようにしていきたいです。

以上、最後まで読んでいただきありがとうございました。
MacでBridgePointを動かす（AppleSilicon Mac向け）

> （この記事は古くなりました）
> Apple Sillicon版のバイナリが配布されるようになったので、
> M1以降のMacでも、この記事のような工夫をしなくても、
> BridgePointが利用できるようになりました。
> BridgePointのダウンロードページの、
> * Mac 64-bit (arm64)
> というリンクからダウンロードしてください。

AppleSilicon版のMac（M1 Macなど）で、BridgePointを動かすためにやったことのメモです（Thanks Levi !）。

## 作業のポイント

この記事を書いている時点では、BridgePointのMac版は、x86_64用だけを配布しています。
将来的にはAppleSilicon（arm64）版もビルド済みのバイナリーを配布するつもりだそうです）。
そして、Mac x86_64用のBridgePointをarm64用のJDKとともに使おうとしても起動しません。

そこで、arm64上で動作するx86_64用のJDKをインストールし、これを使ってx86_64用のBridgePointを動かします。
それでも、 `mcmc` というモデルコンパイラーのプレビルド版は動作しないようなので、これは削除（あるいは改名）して、ソースコード版のモデルコンパイラーを使うようにします。

## Eclipse Temurinからx86_64版のJDKを入手する

The Adoptium Working GroupのWebサイト（ `https://adoptium.net/temurin/releases
`）から、Eclipse Temurin JDKのx86_64版のMac用のJDKを入手します（ここでは11を選んでいます）。

![220606-0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3221/5e87f8dc-0e79-5591-1cb8-726b36f874cb.png)

入手バージョンを指定する方法（arm64版ではないものを入手する方法）がわかっているなら、 brew のパッケージを利用してもかまわないでしょう。

## JDKをインストールする

### 既存のJDKを削除（もしくは退避）する

もし、すでになんらかの arm64版JDKをインストールして使っている場合は、そちらが呼び出されてしまいます。これを避けるために、既存のJDKを削除するか、JAVA_HOMEを書き換えるなどして対応しましょう。
既存のJDKも共存させたい場合には、 `jenv` や `anyenv` などを使って、プロジェクトやアプリケーションごとにJDKを切り替えるようにしておくとよいでしょう。

### 入手したJDKをインストールする

入手したJDKをインストールします。 `.pkg` の方を入手していれば、いつものMacのアプリケーションと同じ用にインストールできます。

### 入手したJDKが有効になっているか確認する

インストールが終わったら、入手したJDKが利用できるようになっているか、環境を確認します。

``` shell
> java -version
openjdk version "11.0.15" 2022-04-19
OpenJDK Runtime Environment Temurin-11.0.15+10 (build 11.0.15+10)
OpenJDK 64-Bit Server VM Temurin-11.0.15+10 (build 11.0.15+10, mixed mode)
```

``` shell
> /usr/libexec/java_home -V
Matching Java Virtual Machines (1):
    11.0.15 (x86_64) "Eclipse Adoptium" - "OpenJDK 11.0.15" /Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home
```

## BridgePointをインストールする

BridgePointの入手とインストールについては、次の記事を参照するとよいでしょう。
後半の「BridgePointのインストール」を参照します。

https://qiita.com/kuboaki/items/adc2ee6bad2e8ab607ca

## BridgePointを起動する

初めて起動すると、次の記事に記載された現象に遭遇しますので、参照して対処しましょう。


https://qiita.com/kuboaki/items/9dc2fe818df2acbe75e5

対処が済めば、それ以降は問題なく起動できるようになります。

## `mcmc` を削除（または退避）する

BridgePointには、ビルド済みのモデルコンパイラー（バイナリーコンパイラー）とソースコード（スクリプト）のモデルコンパイラー（ソースコードコンパイラー）があります、
付随するバイナリーコンパイラーは、arm64のMacでは正常に動作しないそうです。
そこで、これを削除（または退避）します。そうしておくと、モデルコンパイラーとしてソースコードコンパイラーを使ってくれます。やや時間がかかるのですが、よほど大きなプロジェクトでもなければ、気になるほどの差はないでしょう。

Finderで、BridgePointのアイコンを右クリックして、ポップアップメニューから「パッケージの内容を表示」を選び、アプリケーションの內部フォルダを表示します。

`Contentes＞Eclipse＞tools＞mc＞bin` を開きます。
`mcmc`を削除、または名前を変更します。

![220606-0003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3221/d197d7ce-26c7-9d30-0da1-27da476b1300.png)

## 動作を確認する

導入作業が済んだら、既存のプロジェクトやWelcomeにあるサンプルなどで動作を確認しましょう。
tvOS Simurator のキー操作

よく忘れるのでメモ

## キー操作
上下左右 > 矢印キー
タップボタン > エンターキー
Menu > ESCキー
ホーム > Shift + Command + H

## Apple TV Remote (リモコン)の出し方

Window > Show Apple TV Remote
または
Shift + Command + R
Xib、Storyboardを作成する上でのノウハウ

# この記事の対象者

- Autolayout のチュートリアルや入門書を読んだけど、実務のレイアウト作成が作りづらいと感じている人
- iOS のUI作成のガイドラインを作成したい人
- 他の開発者が Autolayout をどう使っているか知りたい人

## 公式ドキュメント

[Auto Layout Guide
](https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html)

## Storyboardのノウハウ

- StoryboardにViewが多いとXcodeで開くときに時間がかかる
    - Storyboardは分割して使用しよう
    - 可能ならXibにしよう
    - SegueをStoryboard上で使うと動作が重くなるので、画面が少ないアプリ以外ではやめておこう
    - 分割すると、Storybaordで何をやっているかわからなくなるが、動作が重いデメリットは大きい
- UINavigationControllerが必要なときはStoryboardに配置しよう
    - コードでUINavigationControllerを制御するのは結構大変
- Storybaordはコードレビューや差分を見るのが難しいので、gitで同時に2人以上で開発するのは回避しよう

## View作成時のノウハウ

- UIStackView を使おう
    - `Content Hugging Priority`と`Content Compression Resistance Priority` の違いを理解しよう
    - Constraints だけで作られている、名前と住所が表示されいるコンテンツに、性別が加わると Constraints を作り直さなければならない、UIStackView を利用すれば UILabel を追加するだけ対応できる
    - UIStackView で複数のマージンを持ちたい場合は、UIView を追加して、 Margin View としたほうが楽で見やすい
- 名前を明示的に指定しよう、Constraints の関係がわかりやすくなる(SS)
    - Constraints に関連されている View が View という名前だとわかりにくい
- 色はAssetsに登録しよう(SS)
- UILabel の AttributeString を Xib で変更するとバグることがある
    - コードで変更するか、Xib をテキストファイルで開いて修正するしかない

## うまくいかないときは

- UIDebugViewでViewの構造を確かめる
- `hogeView?.translatesAutoresizingMaskIntoConstraints = false` になっているか?
- CAGradientLayerで透過しない
- CAGradientLayerをコード上で変更していないか?

## その他

- Autolayoutの配置がおかしいとシミュレーターで正常に見えても、実機でレイアウトが崩れていることがある
  - 特にUIScrollViewとUIStackViewを組み合わせたときに発生する
SVGを1文字でも最適化する

## SVGを1文字でも最適化してみます

今回 Twitter社の公式アイコン (Logo blue.svg)を例に説明してみますが、存在しない要素の最適化も含まれます。

https://about.twitter.com/en/who-we-are/brand-toolkit

## SVGOMGでまず最適化する

### Open SVG か Paste Makeup でSVGを開く

Open SVGはファイルを開く
Paste MakeupはSVGテキストを貼り付けて入力することができます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149448/94488589-5bae-1f14-73bf-3d4686c4e482.png)

Featuresより下の、「Remove xmlns以外」をすべてオンにします

Precision を左側にして、値を1か2のお好みの値にします

:::note info
0にしても構いませんが、埋め込まれているレイヤーの小数点以下がすべて消えますので、大幅に形が変わる可能性があります
:::

### 一度ダウンロードします

```twitter-optimized1.svg
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="enable-background:new 0 0 248 204" viewBox="0 0 248 204"><path d="m222 51.3.1 6.5c0 66.8-50.8 143.7-143.7 143.7A143 143 0 0 1 1 178.8a101.4 101.4 0 0 0 74.7-21 50.6 50.6 0 0 1-47.1-35 50.3 50.3 0 0 0 22.8-.8 50.5 50.5 0 0 1-40.5-49.5v-.7c7 4 14.8 6.1 22.9 6.3A50.6 50.6 0 0 1 18 10.7a143.3 143.3 0 0 0 104.1 52.8 50.5 50.5 0 0 1 86-46c11.4-2.3 22.2-6.5 32.1-12.3A50.7 50.7 0 0 1 218.1 33c10-1.2 19.8-3.9 29-8-6.7 10.2-15.3 19-25.2 26.2z" style="fill:#1d9bf0"/></svg>
```

### エディタで&lt;svg 要素から不要と思われるものを削除します

- xml:space="preserve"
- style="enable-background:new 0 0 248 204" 

今回これを削除しても、正常に表示されました。

```twitter-optimized2.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 248 204"><path d="m222 51.3.1 6.5c0 66.8-50.8 143.7-143.7 143.7A143 143 0 0 1 1 178.8a101.4 101.4 0 0 0 74.7-21 50.6 50.6 0 0 1-47.1-35 50.3 50.3 0 0 0 22.8-.8 50.5 50.5 0 0 1-40.5-49.5v-.7c7 4 14.8 6.1 22.9 6.3A50.6 50.6 0 0 1 18 10.7a143.3 143.3 0 0 0 104.1 52.8 50.5 50.5 0 0 1 86-46c11.4-2.3 22.2-6.5 32.1-12.3A50.7 50.7 0 0 1 218.1 33c10-1.2 19.8-3.9 29-8-6.7 10.2-15.3 19-25.2 26.2z" style="fill:#1d9bf0"/></svg>
```

### これ以外にも、以下の最適化が存在します。

#### &lt;defs&gt;、&lt;/defs&gt; の削除

&lt;g&gt;、&lt;/g&gt;が不要になる場合もあります

表示するだけならいらないような気がします

#### class名、ID名の短縮化

class="hogehoge1" とか長すぎますので、class="1" とかに最適化してみます。

## さいごに

ちりとつもれば山となります。

日ごろからのちょっぴりとした最適化が大きな成果につながると思います
【Linux】パーミッション　初心者のための超基本

環境
MacBook Air (M1,2020)
macOS Monterey


⚠️こちらは、Linuxに入門したばかりの初心者が投稿しております⚠️


先日SSH接続をした際に、秘密鍵のパーミッションを600に変更しました。
こんな感じ。

```
% chmod 600　ファイル名
```
はて・・・これは何の数字なのだろう？と思ったので
今回は、パーミッションについて簡単にまとめてみました！

<h1>アクセス権について</h1>

ファイルやディレクトリにはアクセス権が設定されており、以下の記号で表記します。

・読み取り権　= r (Read)
・書き込み権　= w (Write)
・実行権     = x (eXecute)

```zsh
#「読み取り権」「書き込み権」「実行権」がある場合は、下記の表記になります。
rwx
```

また、アクセス権は数値で表すことができます。

・読み取り権 (r) = 4
・書き込み権 (w) = 2
・実行権 (x) = 1

```zsh
#「読み取り権」「書き込み権」「実行権」がある場合は、7
 r   w   x
 4 + 2 + 1 = 7

#「読み取り権」「書き込み権」の場合は、6
 r   w   -
 4 + 2 + 0 = 6

#「読み取り権」のみ場合は、4
 r   -   -
 4 + 0 + 0 = 4
```
<h1>アクセス権の範囲</h1>

上記の3つのアクセス権は、以下のそれぞれに対して設定されます。

・所有者
・所有グループのユーザー
・その他のユーザー

つまり、パーミッションは「誰が何の権利を持っているか」を示しています。
```zsh
r   w   x     r   w   x    　  r   w   x
所有者の権利　　所有グループの権利  その他ユーザーの権利
```

<h1>パーミッションの例</h1>

```zsh
#すべてのユーザーが「読み」「書き」「実行」可能
rwxrwxrwx
 7  7  7

#すべてのユーザーが「読み」「書き」可能
rw-rw-rw-
 6  6  6

#すべてのユーザーが「読み」可能、所有者のみ「書き」可能
rw-r--r--
 6  4  4

#所有者のみ「読み」「書き」可能
rw-------
 6  0  0

```

※rootユーザーは、設定されているパーミッションにかかわらず
「読み」「書き」「実行」が可能です。

<h1>パーミッション変更のコマンド</h1>

パーミッションを変更するには、chmod(CHange MODe)コマンドを使います。
chmodコマンドを実行できるのは、変更対象のファイルの所有者とrootユーザーのみです。

```zsh
# test.txtファイルのパーミッションを600に設定
% chmod 600 test.txt

# パーミッションの確認
% ls -l test.txt

#結果
-rw-------  1 所有者  所有グループ  ファイルサイズ  最新更新日時 test.txt
```

<h1>まとめ</h1>
600というのは、所有者のみ「読み」「書き」可能という意味でしたね。

「Permission denied」が出ても落ち着いて・・・！
Python2 で Boto3 利用時に出力される PythonDeprecationWarning を抑制する

# Python2 で利用できる Boto3 の最終バージョン

Python で AWS を操作するライブラリとして [Boto3](https://aws.amazon.com/jp/sdk-for-python/) があります。
Boto3 を Python2 で利用する場合、最終バージョンは 1.17.112 になるようです。

https://github.com/boto/boto3/blob/develop/CHANGELOG.rst#1180

> 1.18.0
> ...
> feature:Python: Drop support for Python 2.7
> feature:Python: [botocore] Dropped support for Python 2.7

1.18.0 の一つ前 が 1.17.112 になります。

# 警告 "PythonDeprecationWarning" が出力されてしまう

Python2 で Boto3 1.17.112 を利用してみるとエラーなく実行できますが、PythonDeprecationWarning という警告も出力されます。

```python
import boto3 # v1.17.112

s3 = boto3.resource('s3')

for bucket in s3.buckets.all():
    print(bucket.name)

# ./lib/boto3/compat.py:86: PythonDeprecationWarning: Boto3 will no longer support Python 2.7 starting July 15, 2021. To continue receiving service updates, bug fixes, and security updates please upgrade to Python 3.6 or later. More information can be found here: https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-python-2-7-in-aws-sdk-for-python-and-aws-cli-v1/
#  warnings.warn(warning, PythonDeprecationWarning)
# bucket-1
# bucket-2
# ...
```

結果を見るだけなら警告は無視すればいいですが、別の処理に渡す場合は問題が生じそうです。
上の例では1〜2行目の警告文を削除してバケット名だけを渡すようにしないといけないでしょう。

# PythonDeprecationWarning を抑制する

warnings モジュールの `simplefilter()` を使って PythonDeprecationWarning を出力させないようにします。

```diff_python
import boto3
+ import warnings

+ warnings.resetwarnings()
+ warnings.simplefilter('ignore', boto3.exceptions.PythonDeprecationWarning)

s3 = boto3.resource('s3')

for bucket in s3.buckets.all():
    print(bucket.name)

# bucket-1
# bucket-2
# ...
```

`simplefilter()` の第二引数に抑制したい警告のカテゴリ（クラス）を指定します。
PythonDeprecationWarning は Boto3 独自の警告のため定義されたクラスも含めて指定してください。

# 参考

- [Pythonのwarningsで警告（Warning）を非表示、例外化](https://note.nkmk.me/python-warnings-ignore-warning/)
Vue初学者がSNSの紛い物を作ってみた

# 1. はじめに
　何かを勉強するときに、資料やチュートリアルを読んで知識をつけることはもちろん大事ですが、その身につけた知識を活用できないと意味がありません。ということで、今回Webアプリケーションを作成してみることにしました。<br>※Qiitaなどへの投稿は初めてなので拙い文章ですが、それでも読んでいただけると幸いです。
### アプリへのリンク
[ForActors](https://victorious-cliff-038858200.1.azurestaticapps.net)
現在アクセスできません🙇‍♂️


# 2. 用いた技術
```
フロントエンド：Vue.js、Vuetify、VueRouter、VueStore、VueLoading

バックエンド：Firebase、Firestore、Authentication、Azure Web Static App
```
# 3. 作成したアプリケーションの説明
　このアプリケーションは、役者を目指している友達が「オーディションの情報を仕入れづらい」と言っていたことがきっかけで作成しました。主な機能は以下の通りです。

### 主な機能
<dl>
    <dt>・全ユーザーの投稿したオーディション情報を閲覧</dt>
    <dd>Twitterのタイムラインのようにオーディション情報を閲覧することが可能</dd>
    <dd>お気に入りボタンを押すことで、プロフィールから閲覧可能</dd>
    <dt>・オーディション情報の投稿</dt>
    <dd>HOMEページの投稿ボタンからオーディション情報を投稿することが可能</dd>
    <dt>・ログイン、ログアウト機能</dt>
    <dd>リンクにアクセスするし、ログインページからログイン可能</dd>
    <dd>ログイン後、ヘッダーのログアウトボタンを押すことでログアウト可能</dd>
    <dt>・ユーザー検索機能</dt>
    <dd>検索ページからユーザー名を用いてユーザーのアカウントを検索可能</dd>
    <dd>他ユーザーをフォロー、メッセージを送るなどが可能</dd>
    <dd>他ユーザーの投稿したオーディション情報もしくはお気に入りに追加したオーディション情報を閲覧可能</dd>
    <dt>・プロフィールを閲覧、設定</dt>
    <dd>ユーザーのアイコン、名前、紹介文を編集可能</dd>
    <dd>今までの投稿を確認、削除可能とお気に入りの投稿確認</dd>
    <dt>・自分のフォロー、フォロワーの確認</dt>
    <dd>フォロー、フォロワーの数字を押すことでどのユーザーがフォロー、フォロワーなのか確認可能</dd>
    <dt>・他ユーザーとのメッセージ</dt>
    <dd>他ユーザーとメッセージのやりとりが可能</dd>
</dl>

# 4. UI説明
ログイン画面：
・GoogleアカウントとEmailでのログイン
・Emailによる新規アカウント作成
![LoginPage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534112/22e47064-2003-514a-b406-3fb56573c146.png)

ホーム画面：
・全ユーザーの投稿したオーディション情報の閲覧
・オーディション情報の投稿や、他のユーザーの投稿をお気に入り登録
・右上のログアウトボタンからログアウト
![HomePage.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534112/edd75061-0c24-0239-2efe-9215372c9687.gif)

検索画面：
・他のユーザーを名前から検索
・検索したユーザーをフォローする
・検索したユーザーとのメッセージルームに遷移
・検索したユーザーの投稿やお気に入りの閲覧
![SearchPage.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534112/a67406ab-1fce-7da2-9416-5b3b4b7fdbac.gif)

プロフィール画面：
・ユーザーの基本情報確認
・アイコン画像、名前、紹介文編集
・今までの投稿やお気に入りの削除
・フォローの取り消し
![ProfilePage.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534112/633314b2-98e6-3a6c-276b-30e4113344e7.gif)

メッセージ画面：
・他ユーザーとのメッセージのやりとり
![MessagePage.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534112/cfdd368f-6ab0-4bf1-5eeb-0b724f8e3dd3.gif)


# 5. 改善点
　改善点としては、メッセージを送った際のアイコンが保存されているため、送られてきたメッセージのアイコンと現在のアイコンに矛盾が生じてしまうことです。また、プロフィールでフォーロー、フォロワーを確認する際も同じことが起きてしまいます。この原因はFirestoreの構造にあると感じたので、一から見直して設計し直すことで改善しようと思います。

# 6. 最後に
　今回このアプリケーションを作成して、Vue.jsの扱い方や機能について大まかに理解できたと思います。しかし、思いつきで作成したこともあってER図もなく、DBの構造がしっかりしていないため中身が雑な作りとなってしまいました。まだまだ学ぶことは多いので、次にアプリケーションを作成する時にはしっかりとER図を作成して、バックエンドにも力を入れようと思います。

>ここまで読んでいただいた皆様、貴重なお時間をありがとうございます。もし、少しでも興味を持っていただけましたらこのアプリケーションを触ってみてください。
kubernetesについて、登場人物をまとめてみた。

## コンテナオーケストレーションとは？
Docker Swarm、Mesos、Kubernetesに代表される、複数のコンテナをうまく管理するための仕組み。
コンテナが動作するマシンが一つだと、マシンの故障とともに中で動くシステムもダウンしてしまうため、一つのアプリケーションを複数のコンテナに分けて、複数のマシン上で動作させたい。マシンごとのスペック格差も是正したい。こういった悩みを解決するのがコンテナオーケストレーションツール。

## Kubernetesとは
Googleによって開発された、コンテナ化したアプリケーションのデプロイ、スケーリング及び管理を行うための、オープンソースのコンテナオーケストレーションシステム。
...要するにDockerコンテナをうまいことやってくれる無料のシステム。

## Kubernetesが誕生した歴史

“Kubernetes”（クベルネテス）は、ギリシャ語で航海長または水先案内人を意味し、サイバネティクス（人工頭脳学）の語源でもある。Kubernetesは、当初Joe Beda、Brendan Burns、Craig McLuckieの3人によって開発が始まり、すぐにBrian GrantやTim Hockinなど、他のGoogleのエンジニアも参加するようになり、2014年中ごろにGoogleから初めて発表された。Kubernetesの開発や設計はGoogleのBorgシステムから強い影響を受けており、Borgのトップコントリビュータの多くが開発に参加している。Google内でのKubernetesのもともとのコードネームはProject Sevenであり、スター・トレックのキャラクターで、優しいBorgである、セブン・オブ・ナインの名前に由来する。Kubernetesのロゴの輪にある7つのスポークは、このコードネームに由来している。

Kubernetes v1.0は2015年7月21日（<font color="red">私の誕生日です!</font>）にリリースされた。Kubernetes v1.0のリリースと同時に、GoogleはLinux Foundationと共同でCloud Native Computing Foundation（CNCF）を設立し、Kubernetesを種となる技術として提供した。2018年3月6日には、KubernetesプロジェクトはGitHubにおけるコミット数で第9位に到達し、コントリビューター数とissue数では、Linuxカーネルプロジェクトに次いで第2位となった。




## 登場人物
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280830/fae7abc0-d19c-ab69-d396-3494ca3bd21b.png)


#### Node...
ノードはKubernetesではワーカーマシン。各ノードはマスターによって管理される。

#### pod... 
Kubernetes上のデプロイの最小単位。１つまたは複数のコンテナ。ネットワークやストレージを共有リソースとしてもつ。コンテナの実行方法に関する使用を持つ。



#### kube-proxy...
kube-proxyはクラスター内の各nodeで動作しているネットワークプロキシで、KubernetesのServiceコンセプトの一部を実装している。

#### kubelet...
ポッドによってデプロイされたコンテナがノードで実行されていることの面倒を見るコンポーネント。


#### Cluster...
特定のnamespaceに属さないリソースのこと。冗長化を担当する。

#### Master Node... 
Controll Planeとも。Kubernetesクラスタ内のリソースの構成と管理に使用するAPIを提供する。

#### Deployment...
ReplicaSetを管理するリソース。
ローリングアップデートやロールバック等アップデート機能（更新や元に戻す機能）を提供する。

#### Namespace
同一の物理クラスター上で、複数の仮想クラスターが動作するのをサポートするコンポーネント。

#### ReplicaSet...
指定したレプリカ数のpodを常に保証してくれるリソース。replicas(pod数), pod template, selector(対象podを特定する情報)というフィールドを持ち、コンテナ数を担保する特性上使用が推奨されない。（Deployまでやってくれないため。）

#### Scheduller...
コンテナの配置を管理する。新規に作成された各Podや他のスケジューリングされていないPodを稼働させるために最適なNodeを選択。

#### etcd...
一貫性、高可用性を持ったキーバリューストアで、Kubernetesの全てのクラスター情報の保存場所として利用される。

#### APIserver...
APIサーバーは、Kubernetes APIを外部に提供するKubernetesコントロールプレーンのコンポーネント。 APIサーバーはKubernetesコントロールプレーンのフロントエンド部分。各nodeに命令を発行する。

#### kubectl
Kubernetesで利用されるコマンドラインツール。Kubernetesクラスターを制御できる。

#### ConfigMap
機密性のないデータをキーと値のペアで保存し、podから参照できるようにするもの。コンテナイメージと固有の設定を切り離すことができる。


#### Secret
機密情報(パスワードやトークン等)を保存・管理し、podから参照するリソース。ファイルの書き方はConfigMapにかなり似ている。

#### Service
podの集合体を抽象化して公開したもの。podの集合体のDNS名を提供したり、負荷分散を担当する。
Mysql エラー bundle installができない

An error occurred while installing mysql2 (0.5.4), and Bundler
cannot continue.
Make sure that `gem install mysql2 -v '0.5.4' --source
'https://rubygems.org/'` succeeds before bundling.

上記エラー文

解決方法
$ sudo yum install mysql-devel
$ gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'
$ bundle install

参考サイト
https://qiita.com/kawara3782/items/7244a422b4446650320c
.NET MAUI のGraphicViewで描写テスト

「[.NET MAUI RC3を試してみる（後編）](https://qiita.com/hqf00342/items/db3633b389a785961803)」で `AbsoluteLayout` パネルの描写性能をテストしましたがあまりに悪かったので正規な方法として `GraphicView` での描写性能を確認してみました。

前回同様、ひたすらボールを書き続けてfpsを確認します。

# (参考) AbsoluteLayout の場合

最高60fps、100個で30fps、300個で10fpsでした。
![mauia.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54535/e11dbdbe-7ce5-2563-60f8-4a8f2238eb43.gif)


# MAUI で GraphicView 利用の場合

描写性能としては `AbusoluteLayout` の100倍ぐらいになります。1万個ぐらいは30fpsをキープ、3万個近くなると約10fpsとなりました。
（アップロードサイズ制限のため サイズ変更＋10fpsのアニメーションGIFです。）
![gv.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54535/98c9d90c-9260-6206-82de-ff93fb3b6574.gif)

## 参考：コード

主要な部分だけ抜粋します。
```xml:NewPage2.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns:local="clr-namespace:MauiApp1">
    <ContentPage.Resources>
        <local:GraphicsDrawable x:Key="drawable"/>
    </ContentPage.Resources>
    <StackLayout>
        <Button Text="Start" />
        <Slider x:Name="slider"/>
        <Label BindingContext="{x:Reference slider}" Text="{Binding Path=Value}" />
        <Label x:Name="fpslabel" />

        <GraphicsView x:Name="grahicsview" 
                      Drawable="{StaticResource drawable}"
                      WidthRequest="600" HeightRequest="400"/>
    </StackLayout>
</ContentPage>
```

```csharp:GraphicsDrawable.cs
internal class GraphicsDrawable : IDrawable
{
    public void Draw(ICanvas canvas, RectF dirtyRect)
    {
        //外枠の描写
        canvas.DrawRectangle(dirtyRect.Inflate(-1, -1));

        //円をすべて描写
        canvas.FillColor = Colors.Black;
        foreach (var ball in MyApp.BallList)
        {
            ball.UpdatePos();
            canvas.FillCircle(new Point(ball.X, ball.Y), 2.5d);
        }
    }
}
```

## 所感

- GraphicViewの場合、どういうわけか60fpsにならず30fps始まりです。画面の描写タイミングにTimerを使ったり、`CompositionTarget.Rendering` をタイミングに使ったりしたのですが変わらず。
- ボールは全て黒塗りとしましたが、ボール毎に色を変えたら途端に性能が出なくなりました（1万個で10fps）。色指定でこんなに性能が変わるのもどうかとは思います・・
- Windowsの場合、どうやら `Skia.GraphicView` ライブラリを使っていないかもしれません。AndroidやiOSではSkia版を使っていると思うのでSkiaの性能も見てみたいですね。
URI 設計標準

標準リスト

RFC
https://datatracker.ietf.org/doc/html/rfc7320
https://datatracker.ietf.org/doc/html/rfc8820
https://datatracker.ietf.org/doc/html/rfc3986

223 Best Practices URI Construction - Government Linked Data (GLD) Working Group Wiki
https://www.w3.org/2011/gld/wiki/223_Best_Practices_URI_Construction

[Guidelines for URI Design | CSS-Tricks](https://css-tricks.com/guidelines-for-uri-design/)


EU
D7.1.3 - Study on persistent URIs, with identification of best practices and recommendations on the topic for the MSs and the EC
https://joinup.ec.europa.eu/sites/default/files/document/2013-02/D7.1.3%20-%20Study%20on%20persistent%20URIs.pdf



Designing URI Sets for the UK Public Sector
https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/60975/designing-URI-sets-uk-public-sector.pdf


RFCは守るのは当然として、このような標準にも気を配ってほしい。
Point Free製のURL-ROUTINGを使ってディープリンクのルーティング書くとめちゃくちゃ便利でした

# Point Free製のURL-ROUTINGを使ってディープリンクのルーティング書くとめちゃくちゃ便利でした

<https://github.com/pointfreeco/swift-url-routing>

## 動機

使用してみて便利だったので記事にします。

DeepLinkで渡っていたURLをどう処理するかを、文字列をゴニョゴニョすることなく、
うまくルーティングすることができたので備忘録として残しておきます。

SwiftでiOSアプリ開発だけでなく、サーバーサイドにも使用できるそうです。

## ルートをenumで定義する

ルーティングをenumで定義していきます。

``` swift
enum AppRoute {
  case books
  case book(id: Int)
  case searchBooks(query: String, count: Int = 10)
}
```

URLごとに、どういうPathで渡ってきた場合、
どのcaseで返せばよいかを記述します。
パラメータとして渡される場合、どんな型で渡されるかも記述します。

例えば以下の２つ目の例では、数字が渡ってくることを
Digits()を通じてparseしています。

``` swift

import URLRouting

let appRouter = OneOf {
  // GET /books
  Route(.case(AppRoute.books))) {
    Path { "books" }
  }

  // GET /books/:id
  Route(.case(AppRoute.books(id:))) {
    Path { "books"; Digits() }
  }

  // GET /books/search?query=:query&count=:count
  Route(.case(AppRoute.searchBooks(query:count:))) {
    Path { "books"; "search" }
    Query {
      Field("query")
      Field("count", default: 10) { Digits() }
    }
  }
}
```

パラメータとして渡される値をどのようにParseするかは、
<https://github.com/pointfreeco/swift-parsing>
このPoint Free製のSwift-Parsingを使用しています。

## 渡ってきたURLをどのように処理するかを書く

``` swift
func handleDeepLink(url: URL) throws {
  switch try appRouter.match(url: url) {
  case .books:
    // navigate to books screen

  case let .book(id: id):
    // navigate to book with id

  case let .searchBooks(query: query, count: count):
    // navigate to search screen with query and count
  }
}
```

appRouterの関数で

``` swift
func match(url: URL)
```

にURLを渡すとenum AppRouteが返さるので、
ルートごとにどのような処理をするか書きます。

## Deeplinkの場合は、

ディープリンクの場合で例えば以下のようなURLがあるとき

`mydeeplink://foo/bar/3`

``` swift
  Route(.case(AppRoute.fooBar(id:))) {
    Path { "foo"; "bar"; Digits() }
  }
```

このようなRouterだと機能しません。

`/bar/3`
しか見ていないので。

つまり、hostを判定する必要があります。

以下、Swift-Parsing https://github.com/pointfreeco/swift-parsing
を拡張してHost名を判定するParseを作りました↓

``` swift
import Foundation
import URLRouting
import Parsing

struct Host: ParserPrinter {
  @usableFromInline
  let name: String

  @inlinable
  public init(_ name: String) {
    self.name = name
  }

  @inlinable
  public func parse(_ input: inout URLRequestData) throws {
    guard let host = input.host else { throw RoutingError() }
    try self.name.parse(host)
    input.host = nil
  }

  @inlinable
  public func print(_ output: (), into input: inout URLRequestData) {
    input.host = self.name
  }
}

@usableFromInline
struct RoutingError: Error {
  @usableFromInline
  init() {}
}
```

`mydeeplink://foo/bar/3`

``` swift
  Route(.case(AppRoute.fooBar(id:))) {
    Host("foo")
    Path {"bar"; Digits() }
  }
```

追加したHostを使って上記のように記述すればよいです。

## おわり

これのおかげで、文字列でゴニョゴニョする手間を省けるので便利でした！
指定した型に変換して返すことも、Swift Parse <https://github.com/pointfreeco/swift-parsing> を利用してParserを作れば良いみたいです。

## 余談

- URLRoutingを使ってjsonでリクエストとかも送れるみたいです。
<https://github.com/pointfreeco/isowords/blob/154141a0c83f8e1ce3cb922e47a8a95fa2d77f2c/Sources/ServerRouter/Router.swift>

- フリーランスでSwiftUI, ComposableArchitecture, Firestoreの組み合わせのお仕事あれば、ご紹介お願いします！
XAMPP のProFTPD が起動しない。。mac

# 初めに
つい最近MySQLDatabaseが起動しなくなりました、今度はProFTPDが起動しなくなりました。。。

正直、原因については理解できていないので、とりあえず直す一つの方法として参考にしてみてください。

## 解決方法
XAMPPアプリの「ServerEvents」を確認する。
今回でたエラー↓
```
2022-06-05 23:17:28,683 ~~~~~~~~~~~proftpd[0000]: warning: unable to determine IP address of '~~~~~~~~~~'
2022-06-05 23:17:28,683 ~~~~~~~~~~~proftpd[0000]: error: no valid servers configured
2022-06-05 23:17:28,684 ~~~~~~~~~~~proftpd[0000]: fatal: error processing configuration file '/Applications/XAMPP/xamppfiles/etc/proftpd.conf'
```

### [手順１]自分のPCのIPアドレスを調べる
ターミナルに下記を記述。
```
ifconfig
```

``en0``の部分の``inet``の横に書いてある数字をコピー
下記コードの場合``192.000.0.00``の部分
```
en0: flags=0000<~~~~~~~~~~~~~~~~> mtu 0000
	options=0000<~~~~~~~~~~~~~>
	ether ~~~~~~~~~~~~~~~~~~~~~
	inet6 ~~~~~~~~~~~~~~~~~~~~~
	inet 192.000.0.00 netmask ~~~~~~~~~~ broadcast ~~~~~~~~~~~

```

### [手順2] 設定ファイルに書き込み
**1:ターミナルに下記を記述**
```
sudo vi /../../private/etc/hosts
```
vimが起動します。
一番下に記述をするのですが、カーソールが使えないので注意です。

**[vim操作方法]**
キーボードの「K」で「上に移動」
キーボードの「J」で「下に移動」
キーボードの「L」で「右に移動」
キーボードの「H」で「左に移動」
キーボードの「I」で「書き込みモード」
キーボードの「esc」で「移動モード」

**2:vimの一番下に「IPアドレス」と「PC名」を記述**
```
//コピーしたIPアドレス　   エラーに出ていたPC名
192.○○○.○○○.○ PC名
```

PC名はXAMPPの「ServerEvents」に出ていたエラーの、``IP address of``から後ろの部分。
```
2022-06-05 23:17:28,683 ~~~~~~~~~~~proftpd[0000]: warning: unable to determine IP address of '~~~~~~~~~~'
```
最後に「esc」を押して、下記コマンドで、保存とvimの終了。
```
:wq
```

## 終わりに
参考になれば幸いです。
Chrome OSのlinuxログインシェルを変更する

## chrome OS で linuxを有効化する

色々なところで説明されているので割愛。
公式docs見たらできると思う。https://support.google.com/chromebook/answer/9145439?hl=ja

## linux用ターミナルが現れる
linuxを有効化するとbashのターミナルが出現する。
個人的にfishにしたい！※fishやらzshのインストールは各自でお願いします。
が、アイコン右クリックで設定とかあるんだけど、ここではログインシェルをいじれなかった。

## ログインシェルをコマンドから変更する
調べたところ、コマンドを打つことでログインシェルを変更できるととのことでやってみたらできた。

```shell
sudo chsh -s /usr/bin/fish ${USER}
```

zsh使う人とかも `/usr/bin/fish`の部分を適当なパスに置換すればいけると思います！

ログインシェル変更できないと思って、最初はgnome-terminal入れましたが純正でできるほうが嬉しいのでよかった！

## 参考

- https://www.reddit.com/r/Crostini/comments/9kscnr/changing_login_shell/
PythonでnextPageTokenのあるAPIを叩く


[Directory API](https://developers.google.com/admin-sdk/directory/v1/quickstart/python)を使おうとしたらnextPageTokenなるものが出てきて扱いに困ったのですが、わりと当たり前な存在らしいので自分用の備忘録として残しておきます。

# nextPageTokenについて
大量のデータを扱うAPIは取得上限が設けられており、1度に全てのデータを取ってくることができないようになっている。
そういったAPIは返り値にnextPageTokenというものがあり、これをリクエストパラメータに含むことで続きのデータを取得できるようになる。
続きのデータが無くなるとnextPageTokenも発行されなくなる。
```
例えば
データ取得上限が50のポケモンのデータを返すAPIがあったとすると…

リクエスト「ポケモンのデータを図鑑No順に全部くれ」
↓
レスポンス「ポケモンのデータ1~50とnextPageToken:Aをあげます」
↓
リクエスト「ポケモンのデータを図鑑No順に全部くれ + nextPageToken:A」
↓
レスポンス「ポケモンのデータ51~100とnextPageToken:Bをあげます」
↓
リクエスト「ポケモンのデータを図鑑No順に全部くれ + nextPageToken:B」
↓
繰り返す…

という感じ
```

# Pythonにおけるdo while構文の代替
データ取得と言えばループ。
「nextPageTokenが発行されなくなったらループを抜ける」という処理は、他の言語であればdo while構文（1回は必ず処理を実行し、whileの条件を満たす場合繰り返す）を使えば良いが、Pythonにはdo while構文がない。
do while構文の代替としては、while Trueとbreakを組み合わせることで実現ができた。

# 基本的な使い方
[このコード](https://github.com/googleworkspace/python-samples/blob/master/admin_sdk/directory/quickstart.py)の53行目以降の処理をnextPageToken使用verに書き換えてみました。
こんな感じで書けば全データを取ってくることができます。
```python:quickstart.py
# Call the Admin SDK Directory API
users = []
nextPageToken = ''

while True:
    results = service.users().list(
        customer='my_customer',
        maxResults=10,
        orderBy='email',
        pageToken=nextPageToken
    ).execute()
    users += results.get('users', [])
    nextPageToken = results.get('nextPageToken', [])
    # nextPageTokenが発行されなくなったら離脱
    if not nextPageToken:
        break
```

# おわりに
nextPageTokenもPythonのdo whileも自分が困ったところなのでこの記事に辿り着いた方のお役に立てればと思います。
あと、Pythonはわかりやすさ（読みやすさ）を追求してる言語っぽいのでdo whileが無いのも意外と理にかなってるのかもしれませんね…。


### 参考
+ [Directory API - Python Quickstart](https://developers.google.com/admin-sdk/directory/v1/quickstart/python)
+ [Admin SDK API PyDoc documentation](https://developers.google.com/resources/api-libraries/documentation/admin/directory_v1/python/latest/index.html)
batファイルから一時的に制限を解除してPowerShellスクリプトファイルを呼び出す


PowerShellスクリプトファイル(ps1ファイル)を実行する場合、実行ポリシーによる制限を解除する必要があります。

実行ポリシーの詳しい内容は以下サイトが大変参考になります。
[PowerShellの「実行ポリシー」とは何か？](https://mrkmyki.com/powershell%E3%81%AE%E3%80%8C%E5%AE%9F%E8%A1%8C%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%80%8D%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B%EF%BC%9F#:~:text=PowerShell%E3%81%A7%E3%81%AF%E6%82%AA%E6%84%8F%E3%81%AE%E3%81%82%E3%82%8B,%E5%AE%9F%E8%A1%8C%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%80%8D%E3%81%A8%E5%91%BC%E3%81%B3%E3%81%BE%E3%81%99%E3%80%82)


今回はサンプルとして、batファイルで指定して引数に対して、特定の文字列を追加したメッセージを表示するPowerShellスクリプトを用意しました。

```ruby:Hello.ps1
$input = $args[0]

$message = "ようこそ " + $input

write-host $message
```

```ruby:sample.bat
@echo off
setlocal

powershell -ExecutionPolicy Bypass -command .\Hello.ps1 "田中さん"

endlocal
pause
```

```ruby:結果
ようこそ 田中さん
```


実行ポリシーはデフォルトで「Restricted（全てのpsスクリプトの実行を禁止する）」になっていますが、
上記コマンドで実行ポリシーを「Bypass（全てのpsスクリプトの実行が可能）」に変更しています。
処理が完了すると、実行ポリシーは「Restricted」に戻ります。
[Angular]スマホで簡単にホットリロードする方法

## 扱う内容
自分も最近知ったのですが、Angularで作ったプロジェクトをスマホで検証しようとしたとき、いちいちビルドするの億劫だったりします。
その時に、このやり方を使えば、同じIPを共有している端末であれば、ライブでホットリードの環境が共有できます。

## やり方

### STEP 1 自分のIPアドレスを調べる
windowsであれば
```
ipconfig | findstr /r "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*"
```

と入力して、IPアドレスを調べます。

mac の場合は
```
ifconfig
```
で調べれるらしいです。（手元に端末が無い・・・）



### STEP 2 IPアドレスをhostに指定してコマンドを叩く
```
$ ng serve --host <PCのIPアドレス>
```

### STEP 3 下記のURLにアクセスする

```
http://<PCのIPアドレス>:4200
```

CONNECTION_REFUSEDと表示された場合は、ファイアウォールを無効にしましょう。
URLに無事アクセスできれば、違う端末でも同様に確認できるはずです。