OmniAICreator/Qiita-1.07M huggingface dataset:
【 Java switch文の利点と注意点 と補足】　

現在『スッキリわかるJava 入門』でJavaを学習中です。
この投稿はそのアウトプットと備忘録になります。

## ■switch文
以下のようなif文（式A)があります。
式として問題はありませんが、同じ変数に対して繰り返し比較していて、
冗長でスッキリしていません。
このような`else if`が重複するとき`switch文`(式B)に置き換えてスッキリさせることができます。
```java
式A(冗長なif文)

public class App{
 public static void main(String[] args){
  System.out.println("あなたの運勢を占います");
  int fortune = new java.util.Random().nextInt(4) + 1;
  if (fortune == 1){
   System.out.println("大吉");
  } else if (fortune == 2){
   System.out.println("中吉");
  } else if (fortune == 3){
   System.out.println("吉");
  } else{
   System.out.prinln("凶");
 }
}
```
```java
式B(スッキリして見やすいswitch文)

public class App{
 public static void main(String[] args){
  System.out.println("あなたの運勢を占います");
  int fortune = new java.util.Random().nextInt(4) + 1;
  switch (fortune) {
   case 1:
    System.out.println("大吉");
    break;
   case 2:
    System.out.println("中吉");
    break;
   case 3:
    Syste,.out.println("吉");
    break;
   default:
    System.out.println("凶");
  }
 }
}
```

## ■利点
以上のようにswitch文を使うと、スッキリしていて見やすいコードになります。
## ■注意点
①switchの後に書く条件は(fortune == 1)などではなく(fortune)
②caseの後には「;」ではなく「:」
③case以降の処理の末尾にはbreak文を記述（書き忘れ注意）
## ■補足
①elseの代わりに「default:」を書くが、不要なら省略も可能
②break文を敢えて書かずに「fortuneの値が1か２なら...なら」という分岐を以下のように省略することが可能
```java
switch (fortune){
 case1:
 case2:
  System.out.println("いいね");
  break;
}
```



以上です。
GAS(Google Apps Script)のUrlFetchAppのリクエストbodyに配列をセットする

# 失敗するパターン

### オブジェクトの配列をそのままpayloadにセット
```ts
  const reqOptions = {
      method: 'post',
      payload: [{sample: 1}, {sample: 2}]
    }
  const res = UrlFetchApp.fetch(Config.API.URL, reqOptions);
```

### 単純なJSON.stringify
```ts
  const reqOptions = {
      method: 'post',
      payload: JSON.stringify([{sample: 1} {sample: 2}])
    }
  const res = UrlFetchApp.fetch('https://xxx', reqOptions);
 ```

# 成功するパターン

### `contentType: 'application/json'`　をセットする
```ts
  const reqOptions = {
      method: 'post',
      contentType: 'application/json', // これ！！！
      payload: JSON.stringify([{sample: 1} {sample: 2}])
    }
  const res = UrlFetchApp.fetch('https://xxx', reqOptions);
 ```
[Laravel8.x]APIResourceのwhenLoadedで初期値を設定する

APIResourceでリレーションの初期値の設定で割とハマったのでメモ。

# やりたかったこと

リレーション先のUserモデルが存在しない時に、Userモデルの空インスタンスをデフォルト値に設定したかった。
ただ、下記のソースだとwhenLoadedの第二引数($value)で無限ループが発生してしまう。

```php:❌ 　無限ループが発生する
new UserResource($this->whenLoaded('user', $this->user, new User()))
```


# 解決

whenLoadedの第二引数($value)にも、whenLoadedを指定することで解決しました。

```php:⭕ 　
new UserResource($this->whenLoaded('user', $this->whenLoaded('user'), new User()))
```
状態遷移テスト

# 状態遷移テストとは
状態遷移テストとは、設計仕様どおりにイベントによってソフトウェアの状態の変化することを確かめるテストのことを言います。そもそも「状態遷移」とは、ある「状態」から異なる状態に変化することを指します。ある状態が異なる状態に変化するきっかけをイベントと呼びます。

## 状態遷移テストを変える二つのツール「状態遷移図」と「状態遷移表」
-　状態遷移図
　状態遷移があるシステムの場合、必ず複数の状態を持っています。その状態がどのように遷移するのかを表現したものが「状態遷移図」です。この時、イベント（状態が遷移する条件）も記載しておくとわかりやすいです。一般的に、システムの状態や丸や四角で囲い、イベントを矢印で記載します。

- 状態遷移表
状態とイベントを表にしたものが「状態遷移表」です。
状態遷移表は、システムの状態とイベントをマトリクスで表現できるため、テストケースを抜け漏れなく抽出することができます。

## 要求分析モデリングのプロセス
ここからは実際に、仕様書から状態遷移表を作るまでのプロセスを、アラームを使います。
仕様書からイベントを抽出します。考えられる状態を抽出します。ここで一度、遷移漏れをチェックします。
<ストップウォッチの仕様>
スタート/ストップボタンを押すと、カウントが始まる。カウント中にスタート/ストップボタンを押すと、カウントが止まる。カウントが止まった状態で、もう一度、スタート/ストップボタンを押すと、カウントが再び始まる。リセットボタンを押すとカウントがゼロに戻る。
|イベント|アクション|備考
| :------------- | :------------: | -------------: 
|スタート/ストップボタン| カウントが止まっている場合、カウントスタート。カウントしている場合、カウントストップ。 |
|リセットボタン| カウントがストップし、カウントが0になる。 |
      
## 状態遷移テストのデメリット
状態遷移テストの問題点にテストケースを作るまでの手間が挙げられます。要求鵜分析モデリングのプロセスにも解説しましたが、仕様書からイベントを抽出->状態を抽出->遷移漏れをチェック->状態遷移図へ変換->テストケースの作成とかなり多くの工程が必要なため、それだけの多くの手間がかかっています。

## まとめ
- 状態遷移テストとは、複数の状態をもつシステムに対応して行うテスト
- システムが持つ状態とイベントを図にした「状態遷移図」と、それを表にまとめた「状態遷移表」
- 状態遷移テストは工程が多く、手間がかかる。
ドットインストールではじめてのJavaScriptをやってみた

# ドットインストール　はじめてのJavaScript編です
要点だけまとめてみたので、後で振り返り用としておきます

# JavaScriptを書いてみよう
- JavaScriptを書ける場所
    - Script タグの場合
        - body の中身を読み込んでから、それらの操作をする処理を書くことが多いので、　body の閉じタグの直前に書くのが一般的

- `'use strict';`
    - 厳密なエラーチェックをしてくださいね　と指定するためのキーワード
    - 最近の環境ではこれを付けるのが一般的

- `document.getElementById()`
    - getElementById
        - 任意のHTMLタグで指定したIDにマッチするドキュメント要素を取得するメソッド

- `.addEventListener();`
    - EventListener
        - 何かのイベントが起きたら、何らかの処理をしてね　という仕組み
        - 何らかの処理というのは()に記述する

- `function`
    - 処理の中身を定義するためのキーワード

- `.textContent`
    - テキストの中身という意味
    - `=` で繋げてテキストの中身を記述する
本日の基礎練習問題(22/3/15)

**問題**
正の整数を入力します。その整数が、
10の倍数（10,20,30...）からの差が2以内であるときはTrue
それ以外はFalse
と出力するメソッドを作りましょう。

出力例：
near_ten(12)→True
near_ten(17)→False
near_ten(19)→True

# 私の回答
```
def near_ten(num)
  quotient = num % 10
  if quotient <= 2 || quotient >= 8
    puts "True"
  else
    puts "False"
  end
end
```
# 解説
まずは引数に(num)を設定する
次に1の位を考える。10の倍数から差が2以内なので1の位が0,1,2,8,9が当てはまる。
quotientに1の位を代入する。
そしてif文で2以内または8以上と条件分岐を作成する。
当てはまる場合はTrue、当てはまらない場合はFalse

# 模範回答
```
def near_ten(num)
  quotient = num % 10
  if quotient <= 2 || quotient >= 8
    puts "True"
  else
    puts "False"
  end
end
```
# 模範解説
「10の倍数からの差」を考えるためには、一の位の値に着目します。すなわち、一の位が「0,1,2,8,9」のどれかであれば「10の倍数からの差が2以内」と判断することができます。

したがって、変数quotientに一の位の値を代入し、quotient <= 2 || quotient >= 8で「0,1,2,8,9」のどれかに当てはまるかどうかを確認しています。

# 感じたこと
1の位に着目できたのはよかった。しかし時間がかかりすぎたので明日は早く問題を解けるように意識したい。
PostgreSQLでソート順の入れ替えをSQL一発でできない

以下のようなテーブルがあります。
```sql:articlesテーブル
create table articles (
	article_id serial,
	sort_order integer not null,
	content text,
	PRIMARY KEY(article_id),
	UNIQUE(sort_order)
)
```
article_idが主キー。sort_orderにはユニーク制約が付いています。

そして、このテーブルには以下のようなレコードがあります。
```sql:articlesテーブルのレコード
insert into articles (sort_order, content) values (1, 'Aさんの記事です');
insert into articles (sort_order, content) values (2, 'Bさんの記事です');
```

UI上では、sort_orderの順に記事が並ぶものとします。

# 本題
ここで、Aさんの記事とBさんの記事の並び順を入れ替えたい場合、どのようなSQLを発行すればよいか？

一旦以下で書きました。
```SQL:sort_orderの入れ替え(動作しない)
update articles
set sort_order = 
  case sort_order 
	when 1 then 2
	when 2 then 1
	else sort_order
end
```
sort_orderが1のものを2にし、同時に2のものを1にしたいわけです。

ところが、以下のエラーが表示されます:persevere:
```
ERROR:  重複したキー値は一意性制約"articles_sort_order_key"違反となります
DETAIL:  キー (sort_order)=(2) はすでに存在します。
SQL 状態： 23505
```

SQLServerではできたのに！

PostgreSQLでは、内部的に二度にUPDATEが分かれているのでしょうか？

## 対応
ネットを検索した限りでは、1トランザクション内でsort_orderを一旦別の値にupdateして戻すやり方が多いようでした。以下のような形。
- `sort_order=1 のレコードを sort_order=-1 にUPDATE`
- `sort_order=2 のレコードを sort_order=1 にUPDATE`
- `sort_order=-1 のレコードを sort_order=2 にUPDATE`

このように1件ずつ更新していく方法です。
これだと確かに、一意誓約違反にならずにsort_orderの入れ替えができます。

しかし、SQLを3回実行している...
が、1回でできる方法は無さそうだ...

ということで、SQLの発行2回で入れ替えられる以下の方法をとることにしました。
- `sort_orderを更新したい値×(-1)でUPDATE`　※2件同時
- `sort_orderが負の数のものを正の数にUPDATE`　※2件同時

具体的には以下のSQL
```SQL:SQL1回目
update articles
set sort_order = 
  case sort_order 
	when 1 then 2*(-1)   -- 更新したい値*(-1)
	when 2 then 1*(-1)   -- 更新したい値*(-1)
	else sort_order
end
```

```SQL:SQL2回目
update articles
set sort_order = sort_order * (-1)
where sort_order < 0   -- 負の数のものを正の数にする
```

これでSQL2回でできました :hugging:

## 補足
- 本来、sort_orderは正の数しかとらないだろうに、unsigned型にしてないのか？
→ PostgreSQLにunsignedはありません。
- 負の数が入らないようcheck誓約を付けていないのか？
→ そこまでガチガチに誓約をかけていません。
　これは要件によりますね :rolling_eyes:

場合によりけりですが、参考になれば幸いです。
ありがとうございました:angel:
Slack Enterprise Grid の 開発用Sandbox を利用申請してみた

Enterprise Grid 対応の Slack アプリを作成するにあたり、開発環境がなくて困っていたところ、Slack に Sandbox 環境を申請できるとのことだったので申請してみました。

**参考ページ** 
[Testing your app on Enterprise Grid](https://api.slack.com/enterprise/grid/testing "Testing your app on Enterprise Grid") 

まずは申請フォームを送信します（上記参考ページ文中のあちこちにリンクが貼られています）
https://api.slack.com/go/sandbox

1. 名前、連絡用メールアドレス、会社名、会社のURLを入力します。
![１枚目のうえ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183487/c45d1b64-11c2-da3a-d68b-aea5841bccfd.png)
実際の業務では会社名と会社URLにも入力したのですが、今回は振り返り用に個人なので空白にしました。

2. 作成するアプリに関して入力します。
![１枚目のした.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183487/a5966370-c354-ce08-cb19-b622a0705871.png)
**「Are you building an app for your team's internal use or for distributing to other Slack teams?」**
作成するアプリは内部利用か、他のチームにも配布するか聞かれているんだと思います。
Internalが内部のみで、Distributingが配布で。
私は「Internal」にしました。
**「If you're building for distribution, is your app in the Slack app directory?」**
配布するアプリの場合、アプリは既にSlackアプリディレクトリにありますか？と聞かれているんだと思います。
私はまだ作成していなかったし配布するつもりもなかったので「Not Yet」にしました。
**「If "yes", please provide the App ID or URL」**
上記で「yes」と選択した場合に、アプリのIDかURLを入力するんだと思います。
私は「Not Yet」を選択していたので空白にしました。
3. ここまで入力したら「次へ」ボタンを押して、次のページにいきます。

6. Sandbox のプライマリーオーナーのメールアドレスを入力します。
![２ページ目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183487/46c0e068-c5ca-6cb1-bfe3-65913504f11b.png)
**「Org Owner Email Address」**
プライマリオーナーのアカウントは譲渡できないから、実際の人に紐づくメールアドレスじゃなくて、そういうメアドにしたほうがいいよって言われてるんだと思います。
今回は振り返り用で個人なので自分のメールアドレスにしました。
実際の業務ではGoogleグループを作ってそのメールアドレスにしました。

6. 下に同意事項があるので読んで、大丈夫なら「送信」ボタンを押します。

7. 受け付けたよ！って画面になります。
![３枚目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183487/a16f64e1-0a2e-b0b9-bc5a-ae47345451cd.png)
作成完了したらメールがくるはずなので、しばらく待ちます。

今、待っている最中なので、使い方の触りはまたあとで。
【備忘録】Ubuntu18.04でx11vncを使う

# はじめに
UbuntuでVNCをする方法を備忘録としてまとめておきます．
今更かもしれませんが，普段使う環境と異なり戸惑ったことをまとめておきます．
（Ubuntuデフォルトの画面を使いたくてx11vncをどうしても使いたかったという記事です）

## 環境
・Ubuntu Desktop 18.04.6 LTS
・CPUはIntel

# 問題点
①UbuntuデフォルトのVNC設定がバグってる！
VNCを使わないといけない状況になり，方法をググっていると，
Ubuntuの設定→画面共有→ONで簡単にできると出てきました．
(Ubuntu Desktopだからできる設定)
しかし，その設定にはバグがあり，ONにしてもすぐOFFになってしまいます(泣)
どうしてもこれが治らなかったので，手動でVNCを設定していこうと思います．

②モニターがないとVNCできない！
物理的にHDMIなどで出力していないとx11vncが使えないみたいです...


# 設定方法
https://qiita.com/chyonevvi/items/3d907464d11b2f056ef6
私は，以下の記事を参考に設定させていただきました．
とてもわかりやすくまとまっているので感謝です．

基本的には，参考にさせていただいた記事で設定が完了ですが，
問題点でも述べたように，実はx11vncはモニターがないと動かないのです．
簡単に説明すると，ディスプレイに映し出されたものを，複製してクライアントにも投げている仕組みなので，
モニターとの接続を切った（HDMIなどを抜いた）瞬間にvncができなくなってしまいます．
それをソフトウェア的にダミーのモニターを作って解決する方法をご紹介します．
（ハードウェア的に解決する方法もあり，「ダミーhdmiプラグ」などとググってみてください．）

早速，必要なパッケージを入れていきます．
(パッケージ名にubuntuのバージョンが入っているので，他のバージョンの場合は要確認)

```
$ sudo apt install xserver-xorg-video-dummy-hwe-18.04

Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 xserver-xorg-video-dummy-hwe-18.04 : Depends: xorg-video-abi-24
                                      Depends: xserver-xorg-core-hwe-18.04 (>= 2:1.18.99.901) but it is not going to be installed
```

上記のような返答が返ってきて，xserver-xorg-video-dummy-hwe-18.04を入れるには，
xserver-xorg-core-hwe-18.04を入れろとのことです．
[参考はこちら](https://askubuntu.com/questions/1155964/cannot-install-xorgxrdp-due-to-dependency-issues)


```
$ sudo apt install xserver-xorg-core-hwe-18.04
```

そして，もう一度xserver-xorg-video-dummy-hwe-18.04をインストールします．

```
$ sudo apt install xserver-xorg-video-dummy-hwe-18.04
```

無事にインストールできたら，ダミーモニターの設定をしていきます．


```/usr/share/X11/xorg.conf.d/20-dummy.conf
Section "Monitor"
Identifier "Monitor0"
HorizSync 5.0-200.0
VertRefresh 5.0-200.0
Modeline "1920x1080_60.00" 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -HSync +Vsync
EndSection
 
Section "Device"
Identifier "Card0"
Option "NoDDC" "true"
Option "IgnoreEDID" "true"
Driver "dummy"
EndSection
 
Section "Screen"
DefaultDepth 24
Identifier "Screen0"
Device "Card0"
Monitor "Monitor0"
    SubSection "Display"
    Depth 16
    Modes "1920x1080"
    EndSubSection
EndSection
```

解像度は，cvtコマンドで確認できます．
[参考はこちら](https://ameblo.jp/ekispresso/entry-11532367928.html)

次に，/etc/gdm3/custom.confにある```WaylandEnable=false```のコメントアウトを外します．

```/etc/gdm3/custom.conf
# Uncoment the line below to force the login screen to use Xorg
WaylandEnable=false
```

最後に，lightdmを再起動してあげると，VNC接続ができると思います．

```
sudo service lightdm restart
```
Micorosft Certified Trainer(MCT)になるまでの１か月の流れっ（2022-2023）

# ご挨拶
皆さんこんにちは！
某外資系企業で働く、エンジニアなのか、Sales担当なのか、なんなのかわからないKazuyaです👌
本日は、「MCT認定」を無事受けることができましたので、
そこまでの流れをば！

# 僕のベーススキル
・マルチ・ハイブリッドクラウド歴：３年くらい
・ほかのクラウドの資格：AWS Proが2つと、Google Proが1つ。
・PMP保有

# 流れ
な、、、長い道のりが。。。
嘘です。約１か月で取得しました。
といっても、基礎的なトレーニング（第三者に対する）の経験が僕はあったので、
そのおかげで申請がすんなりいったというだけです。

◆Azure資格取得
1. AZ-900受験
・これはもはや勢いだけで受けましたが、基本的な
2. AZ-400受験
・大体２時間くらい試験勉強を、Udemyやら、MS Learnのコンテンツやらでしました。
　で、当日受験申込して、自宅でPeasonVUEのOnVue試験を受験。合格～
3. AZ-303受験
・AZ-400と同じく、２～３時間くらい勉強。コンテンツは同じく。
　同じように勢いでOnVue受験で合格～
4. AZ-304受験（これが一番難易度高く感じた）
・AZ-303のための勉強内容が抜けちゃう前に、304の勉強もして受験。
　OnVue受験したけど１度不合格。ダメだった領域を再勉強して２４時間後に再受検して合格～
5. AI-900受験
・DevOpsとSolutionArchitectのExpertは取れたので、AI側もとりたいなと思い、
　AI-900を受験。同じような流れですがこちらは一発合格。
6. AI-102受験
・AI-900を受けてから1週間後くらいに知識が抜ける前に受験。
　これまた一発合格～

これで、MCTで必要な、技術系の証明は完了！（というか、この中のAZ-400か、AZ-303/304だけでもOK。ほかにも候補はあるので要確認）

◆MCTの申請
・講師経験の証明が必要になるので、トレノケートで２０万くらい払って証明するか、
　実際の講師経験（指導・育成経験）があるなら、それを承認してくれる上司などの情報を入れれば
　申請可能。
　僕は過去に、指導・育成経験が５年以上あったので、当時の指導育成業務を行っていた時の上司に連絡して、
　その方を指定して、経験証明依頼。
　→翌日には承認されましたとさ。

# MCTになると何がおいしいの？
・証明書が発行されます！（０円で）
・Azureなどなど様々なサービスの割引が受けられます！
・認定バッジをメールなどに表示することができます！

というところで、たどり着くと「認定トレーナーだぜぃ！」と名乗れるだけじゃなくて、
実用性のある割引サービスなどが受けられるというのも非常に有益ですので、
ぜひぜひトライしてみてください😊

それでは本日はこの辺で！

See you next time!
$a.util.toggleclassがコミュニティで機能していません


質問
[$a.util.toggleclass not working in community](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000EBrZs)

コンポーネントはアプリまたはコンテナからSLDSを継承します。この場合、彼らは自動的にsldを取得するカスタムテーマのNapiliコミュニティにいます。他のSLDSスタイリングクラスは問題なく機能しますが、slds-theme--shadeなど、機能していないクラスもあるようです。  

私は遊んでいますが、slds-theme_warningなどの他のテーマは正常に機能していますが、slds-theme_shadeは特に機能していないようです。その間にカスタムスタイリングを追加しましたが、誰かがこれについて洞察を持っているなら、私はそれをいただければ幸いです！

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_config_for_builder_theme_layout.htm
ASP.NET Web Form認証でログイン時にセッションIDを更新する

# きっかけ
セッションハイジャックへの対応策として「ログイン成功後に、新しくセッションを開始する」⇒ <b>「ログイン成功時に、以前のセッションを破棄し新しいセッションIDを割り振る」</b>という方法があるが、ではWeb Formでの認証時にはどのようなコーディングを行えばよいのかを調べたので、メモとして記事を書くことにした。


# 基本的な考え方
行うことは単純で

- ログイン前から存在するセッションを破棄する
- 新しいセッションIDを割り振る

の2点だけである。
ASP.NETは標準ではCookieにセッションIDを保持し、そのキーは<b>"ASP.NET_SessionId"</b>という事実があるので、それを考慮する。
ログイン成功後は、当初要求のあったページへのリダイレクトを行うとすると、リダイレクト処理の直前にこれらの処理を入れてあげるのがよいと思われる。

# 実装

Login成功後の処理をどこに記述するかは好みの問題があるが、ここでは単純にLogin.aspx(.cs)に記述するパターンを書いてみる。

```csharp:Login.aspx
protected override void Login_Click(object sender, EventArgs e)
{
    try
    {
        string userid = UserId.Value + string.Empty;
        string password = Password.Value + string.Empty;

        if (Authenticate(userid,password))
        {
            //認証OK
            HttpContext.Current.Session.Abandon();
            HttpContext.Current.Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", CreateSessionID()));

            FormsAuthentication.RedirectFromLoginPage(userid, false);
        }
        else 
        {
            //認証NG
            Msg.Text = ErrorMessage;
        }
    } catch (Exception ex) {
        // 例外処理
    }
}

private bool Authenticate(string userid, string password)
{
    // DBへの問い合わせなどを行う
}

private string CreateSessionID()
{
    // GUIDを用いてセッションIDを作成する
    return Guid.NewGuid().ToString();
}
```

ブラウザ(例えばEdge)のF12を押して開発ツールを起動し、アプリケーションタブを開いてもらうと確認できるが、ログインの前後で"ASP.NET_SessionId"キーを持つCookieの値が変わっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/8bed7020-1099-92a8-abea-15d3b50e93db.png)

# ログアウト処理
更新されたセッションIDはログインしている情報に紐づいていることを示しているので、ログアウトの処理などアプリケーションを抜ける処理を行う際にはセッションを破棄してあげる必要がある。
リッチテキスト内の画像を実行するレポート内で表示したい


2022/03/15時点ではちょと時間がないので、後程対応してみたい。

[リッチテキスト内の画像を実行するレポート内で表示したい](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FUGv8)

無事にできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ec6ea671-77b3-7acc-c267-6d08a7962bd7.png)
[備忘録]コーディングテスト対策で調べたもの一覧

## 前書き
どうも！絶賛就活中のグッピーです！
この度東証１部上場企業の自社開発と受託開発を行なっている会社様から内定をいただきました！！
これでメガベンチャーに安心して挑むことができます。
今回はそんなメガベンチャーに挑むのに必要なコーディングテスト対策のための備忘録です。
適宜編集しているので、よかったら覗いてみてください。復習になるかもしれないです。


## 調べたこと

### ビット演算
数字を二進数方式で表したものを操作するもの。普通の数値を2進数に変換するには以下のような操作が必要
```
a=1
a=bin(a)
print(a)
=>0b1
```

二進数の書き方は以下の通りです
```
0b1
=>1
0b101
=>5
```

0埋めをする場合以下のようになります。
```
0b0001
0b0101
```
負数は先頭にマイナスをつけて表現します
```
-0b0001
```
### 左シフトのやり方
左シフトとは、ビットの位置を左にずらす演算です。つまり累乗のことですね
また、右シフトはその反対です。右に一個ずらすことは-2乗、左は＋２乗ということです。
左シフトの場合<<の左側にシフトさせたい値、右側にシフト数を指定します。
右側シフトはその反対です
```
a=0b0001<<1
print(a)
=>2

a==0b0010>>1
print(a)
=>1
```

### 参照させていただいた記事
https://yu-nix.com/blog/2021/5/26/python-bit/
case assignment rules

[Case オブジェクトのまとめ に戻る](https://qiita.com/Keiji_otsubo/items/fb6fa038807750a5fc4c)


# グルーバルアクションではcase assignment rulesが起動しない

アイデアにあがっているようです。　回避策はApexトリガーを作って回避するようです。

[Enable Case Assignment Rules from Global Action](https://ideas.salesforce.com/s/idea/a0B8W00000Gdg8aUAB/enable-case-assignment-rules-from-global-action)

トリガーのサンプルが回答されています。

[Global action doesn’t activate the case assignment rules](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000A7tW1SAJ)

元の質問

[Assignment rule not firing from Global action "New case"](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FUmMjSAL)

# メッセージングセッションからケースを作成

+ [メッセージングセッションからケースを作成](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000FxVsj)
 メッセージングではケース自体はトリガーされないので、　「エージェント作業」レコードで別のレコードがフローをトリガーし、作業ステータスが「オープン」に更新されたとき（これは、エージェントがオムニチャネルウィジェットから作業を受け入れるとき）です。オムニチャネルでの作業を受け入れた所有者と一致するように、関連するケースを更新します（通常、ケースのステータスも同時に更新します）

# 特定のアドレスからきたものをキューに割り当てるという設定

+ [ケースの割り当てルールの一般的な使い方](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pex0RSAR)

英語ですが、同じような質問があって興味深い回答があります。
古い質問なので、プロセスビルダーを提案していますが、フローでも問題ないと思います。

電子メールメッセージはケースとは異なるオブジェクトであり、複数の電子メールを 1 つのケースにリンクさせることができるため、電子メールオブジェクトのフィールドに基づいてケース割り当てルールを作成することはできません。

できることは、ケースにカスタムフィールドを作成し、電子メールメッセージオブジェクトにプロセスビルダーを作成して、関連するケースレコードのカスタムフィールドを更新することです

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8faSSAR
【MEMO】Postgresでテーブルごとの変更履歴を取るトリガー

# Postgresでテーブルごとの履歴を取るトリガー

めもめも。
こちらを参考にした。
https://qiita.com/nishimura/items/aba93df97f02b571c3ce

1. 「schema.__tablename」に突っ込む
2. old_datasは１個前のデータ。変更のないUPDATEは履歴を取らない

``` SQL

CREATE FUNCTION define.insert_log()
    RETURNS trigger
    LANGUAGE 'plpgsql'
AS $BODY$
  DECLARE
    history_table NAME := TG_TABLE_SCHEMA || '.__' || TG_TABLE_NAME;
  BEGIN
    EXECUTE 'CREATE TABLE IF NOT EXISTS ' || history_table || '('
        || 'operated_user text NOT NULL,'
        || 'operated_type character(1) NOT NULL,'
        || 'operated_at timestamp without time zone NOT NULL,'
        || 'old_datas jsonb NOT NULL'
        || ')';
    IF (TG_OP = 'DELETE') THEN
      EXECUTE 'INSERT INTO ' || history_table ||
        ' SELECT USER, $1, NOW(), to_json($2)'
      USING 'd', OLD;
    ELSIF (TG_OP = 'UPDATE') THEN
      EXECUTE 'INSERT INTO ' || history_table ||
        ' SELECT USER, $1, NOW(), to_json($2) WHERE $2 != $3'
      USING 'u', OLD, NEW;
    ELSIF (TG_OP = 'INSERT') THEN
      EXECUTE 'INSERT INTO ' || history_table ||
        ' SELECT USER, $1, NOW(), ''{}'''
      USING 'c';
    END IF;
    RETURN NULL;
  END;
$BODY$;

```

あとはトリガーをセットするだけ。

``` SQL

CREATE TRIGGER add_test_table_log
    AFTER INSERT OR DELETE OR UPDATE 
    ON data.test_table
    FOR EACH ROW
    EXECUTE FUNCTION define.insert_log();

```

投稿する際に履歴テーブルを勝手に作ったら楽？
と思って足してみたけど、権限とか考えたら外すべきかも。

これで１個前に戻したい！いつ実行したっけ？？
という悩みが解決され、るといいなー。
React hooksでスクロールイベントの負荷を抑える

## はじめに

スクロールイベントを用いる実装では、イベントによる負荷が発生しますよね。
スクロールの高さを取得して、その高さによってなんらかのアクションをしたい時。

スクロールの高さはかなり細かく取ってくれるので、負荷が高いです。
1mmスクロール位置を動かしただけでスクロールイベントが発火するとか（言い過ぎかな）

パフォーマンス低下やバグの恐れがあるので、少しでも負荷を抑える実装が必要になります。

今回は、reacthooksの中でthrottleを使うやり方についてまとめます。

## throttle（lodashライブラリ）
lodashライブラリは、便利な関数がたっぷり収納されている有名な巨大ライブラリです。
JSのディープコピー問題を解決してくれる関数があったり。

その中に、**throttle**というのがあります。

今回はそちらを使用するのですが、**throttle**とは**イベント負荷を抑えることができる関数**です。

具体的には、指定した時間が過ぎるまでは次のイベントを発生しないようにしてくれます。
簡単に処理を間引いてくれるのです。便利！

間引くというとtimeoutを使って自力で書くこともできますが、面倒なのでライブラリを活用します。

throtttle以外に、debounceという同じくイベント負荷を抑える関数が存在します。
よく比較されます。
こちらは、「大量の処理をグループ化して処理の最後に一回だけ実行する」というもの。
使ったことないのですが、比較については色々な記事で紹介されています。

一部抜粋
[Debouncing and Throttling Explained Through Examples](https://css-tricks.com/debouncing-throttling-explained-examples/)
> Imagine you are in an elevator. The doors begin to close, and suddenly another person tries to get on. The elevator doesn’t begin its function to change floors, the doors open again. Now it happens again with another person. The elevator is delaying its function (moving floors), but optimizing its resources.

エレベーター無理矢理入ってくる人たまにいますね。


[throttleとdebounceの違い。覚え方も考えてみた](https://satoshimurata.com/throttle-debounce)

### インストールする

lodash丸ごとインストールすると容量が大きいので、個別でインストールします。

```
yarn add lodash.throttle
```

TS用のモジュールもインストール

```
yarn add @types/lodash.throttle
```

### イベントを間引く
実際の処理です。

```useSomething.ts

export const useSomething = () => {
  // 省略

  const someFunc = () => {

      const onScroll = () => {
        const currentPosition = Math.max(
          window.pageYOffset,
          document.documentElement.scrollTop,
          document.body.scrollTop
        )

        console.log('位置取得', currentPosition)

        if (currentPosition >= somePosition) {
          //　この位置に来たら何かしたい
        }
      }

      // スクロールイベントを0.4秒毎に間引く
      const throttledCount = throttle(onScroll, 400)
      document.addEventListener('scroll', throttledCount)
      return () => document.removeEventListener('scroll', throttledCount)
    }
  }

  useEffect(() => {
    someFunc()
  }, [])
  // 省略
}

```

あとは上記のカスタムhookをページやコンポーネントで呼び出します。


イベントを間引いてる様子をcodesandboxで作ったので、触ってみてください。

- console.logに位置取得の様子が表示されています。
- 比較の際は、use-scroll.tsで31行目の`normalScrollEvent()`のコメントアウトを外して、代わりに30行目の`throttledScrollEvent()`をコメントアウトしてください

https://codesandbox.io/s/throttledsukuroru-dx679v


## まとめ
パフォーマンスのためにもイベント負荷を意識するのは大事ですね。
以外に調べてみると、lodash×Reactの記事がなかったのですが、普段どのようなイベント負荷をしているのか是非コメント頂けると嬉しいです！

また、画面の遅延に影響するReactのstate/propsによる再レンダリングの負荷なども意識していきたいです。
なのでこの辺も知見が溜まったらまとめようかなと思います。

参考
[Using Throttling and Debouncing with React hooks](https://dev.to/pulkitnagpal/using-throttling-and-debouncing-with-react-hooks-57f1)
[カッコいいけど遅すぎる！ JSのスクロールイベントを改善するベストな方法](https://www.webprofessional.jp/throttle-scroll-events/)
[Lodashのファイルサイズを削減する方法](https://s8a.jp/javascript-lodash-reduce-file-size)
MGSDRVのMMLでの#allocの意味と使い方

MGSDRV用のMMLコンパイラMGSCは出力データサイズに制限があり、全トラックのデータの合計で約16KB以下にする必要があります。

MGSDRVではモード`#opll_mode`によってトラック数が変わりますので、デフォルトでは各トラックの最大サイズが次のように設定されます。

#### <a name="table1">表1 トラックの最大サイズのデフォルト</a>

|モード|トラック数|各トラックの最大サイズ|
|:-:|:-:|:-:|
|#opll_mode 0|18|903|
|#opll_mode 1|16|1016|

1トラックあたりの使用容量が上記のサイズを超えると`Track buffer full`エラーになってしまいます。こんな感じのエラーメッセージが出ます。

```
Track buffer full in 17
>> 1 cdefgab>c<cdefgab>c<cdefgab>c<cdefgab>c<cdefgab>c<cdefgab>c<
```

こうなってしまうともうお手上げかというとそうではなく、他のトラックにまだ空き容量がある場合、他のトラックのデータ最大サイズを減らして、別のトラックのデータサイズを増やすことができます。これを行うためのコマンドが#allocです[^1]。

[^1]: 今のコンピュータは、解析したMMLから自動的に各チャンネルのデータサイズを当たり前のように自動決定できますが、80年代のコンピュータはメモリに一切余裕がないため、こんなことも指定する必要があったのです...。


# #alloc の使い方

`#alloc トラック名 = 最大サイズ` という形式で指定します。最大サイズは16333[^2]まで指定できます。

[^2]: 数値上は16342まで指定できますが、トラックの合計容量が16333バイトを超えると`Object Too Big`エラーが出てコンパイルができなくなります。

例えば、トラック1の最大サイズを1500バイトにする場合は、

```
#alloc 1=1500
```

とします。複数指定することもできて、トラック1の最大サイズを1500バイト、トラックaの最大サイズを1200バイトにする場合は

```
#alloc 1=1500
#alloc a=1200
```

となります。また、まとめて1行にして

```
#alloc { 1=1500, a=1200 }
```

というような書き方もできます。

注意点としては、

- すべてのトラックの容量を合計して16333バイトを超えることはできません[^2]。
- #allocを書かなかったトラックは、
   - そのトラックのMMLを全く使っていなければ、トラックの最大サイズが0バイトとして扱われます。
   - そのトラックのMMLを使った場合は、<a href="#table1">表1</a>のバイト数が割当てられます。
- トラック番号0は音色データ用のトラックです。

# TIPS1:各トラックの使用量の確認方法

`#alloc` コマンドで最大サイズを決める場合は、各トラックがどの程度のサイズを使っているかを把握する必要があります。これは、コンパイル結果の画面から分かります。

例えば以下のデータをコンパイルしてみると、

```
#opll_mode 1
@e0 = {2,31,fn8.0=26}
@e1 = {3,0,f0}
@e2 = {0,0,fca}
1 l16v13 [[@1c4@0c4rv-3cv+3r8|c4]4 cccc]0
2 @2v12l16 [
2 o2 [ e8>e<e>>d<q2eq6d>e<<d>e<q2dq6db>>c&d<<e  ]2
2 o2 [ d8>d<d>>c<q2dq6c>d<<c>d<q2cq6ca>a+&>c<<d ]2 ]0
```

結果は、こんな感じになります。

```
MGSC MML compiler version 1.11
Copyright(c) 1992-94 by Ain

Compile complete

track :  0  ( 1016)  (   21)  (  995)
track :  1  ( 1016)  (   42)  (  974)
track :  2  ( 1016)  (  108)  (  908)
...
```

たぶん見てなんとなく分かると思いますが、（）で囲まれた数字が左から順に、そのトラックの最大サイズ、使用されたサイズ、空きサイズ、になります。

#alloc コマンドにどのぐらいの値を設定すれば良いかは、こちらのサイズを見ながら、合計が16333バイトを超えないように考えて設定していくことになります。

`Track buffer full` メッセージが出たタイミングでは、トラックがどのぐらいのサイズを使っているのか分かりません。エラーが出ている場合は、MMLを減らしてコンパイルが通るようにしてから確認する必要があります。

# TIPS2: エラーになる書き方

## 多重alloc 
同じトラックに対して2回以上 #alloc すると、2回目はエラーになります。

```
#opll_mode 1
#alloc { 1 = 1500 }
#alloc { 1 = 1200 }
```

これをコンパイルすると

```
Can't allocate in 3
>> #alloc { 1 = 1700 }
```

こうなります。

## MMLを書いたあとで alloc
トラックのMMLをひとつでも書いたあとで、そのトラックに対して #alloc を使うとエラーになります。

```
#opll_mode 1
1 o4v12cde
#alloc 1=1500
```

これをコンパイルすると、

```
Can't allocate in 2
>> #alloc { 1 = 1500 }
```

エラーになります。
借用スマホの返却時チェックリスト

## はじめに

会社などから借りているスマートフォンを返却するときのチェックリストを紹介します。

## 借用スマホの返却時チェックリスト

- [ ] 充電する
- [ ] スクリーンリーダー（iOS: VoiceOver, Android: TalkBack）をOFFにする
- [ ] 言語設定を戻す
- [ ] 日付を自動設定に戻す
- [ ] Webブラウザのシークレットタブをすべて閉じる  
Webブラウザはシークレットモードのみ使用すべき
- [ ] インストールしたアプリをすべてアンインストールする
- [ ] アプリから取得したファイルをすべて削除する  
通常はアプリをアンインストールしたら自動で消える
- [ ] ダウンロードしたファイル（APKファイルなど）をすべて削除する
- [ ] ダウンロードした画像（スクリーンショットなど）をすべて削除する
- [ ] QRコードリーダーの履歴をすべて削除する
- [ ] ログインしているアカウント（Googleなど）をすべてログアウトする
- [ ] 追加したWi-Fiのアクセスポイントをすべて削除する
- [ ] プッシュ通知をすべて削除する
- [ ] タスクをすべてキルする
- [ ] 電源を切る
- [ ] 画面と本体を拭く

## おわりに

これできれいな状態でスマホを返却できます :relaxed:
ちなみに「工場出荷状態にする」が問題なければそのほうが早いです笑
JavaScriptで作る、リロードごとに問題がシャッフルされるクイズ。

　JavaScriptでリロードごとに問題がシャッフルされるクイズを作った。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="GRyJKvL" data-user="m-kunugi" style="height: 00px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/m-kunugi/pen/GRyJKvL">
  Untitled</a> by mkunu (<a href="https://codepen.io/m-kunugi">@m-kunugi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


```quiz.html
<html>
<head>
  <title>損益計算書クイズ</title>
  <script type="text/javascript">
  // 配列（問題と答えの選択肢）
  var array1 = [['販売手数料', 0], ['広告宣伝費', 0],
                ['受取利息', 1],
                ['支払利息', 2],
                ['固定資産売却益', 3],
                ['固定資産売却損', 4]];
  function answer(){
    for (const element of array1) {
      var choices = document.getElementsByName(element[0]) ;
      if(choices[element[1]].checked) document.getElementById('color'+ element[0]).style.color="blue"
      else document.getElementById('color'+ element[0]).style.color="red"
    }
  }
  </script>

</head>
<body>
  損益計算書クイズ
  （リロードするとランダムに表示されます。）
  <form name="f">
    <!--答え合わせのボタンの配置-->
    <input type="button" value="答え合わせ" onclick="answer()">
    <div id="order_list">
  <script type="text/javascript">
  var d1 = document.getElementById('order_list');
  // 配列をシャッフル　https://teratail.com/questions/81199
  function arrayShuffle (array) {
    var k, t, len;
    len = array.length;
    if (len < 2) {
      return array;
    }
    while (len) {
      k = Math.floor(Math.random() * len--);
      t = array[k];
      array[k] = array[len];
      array[len] = t;
    }
    return array;
    }
  arrayShuffle(array1);
  
  for (const element of array1) { // 問題の作成
    d1.insertAdjacentHTML('afterend', '<div class="order">\
      <b><p id="color'+ element[0] +'">\
      '+ element[0] +'</b><br>\
      <input type="radio" name="'+ element[0] +'" > 販売費及び一般管理費\
      <input type="radio" name="'+ element[0] +'" > 営業外収益\
      <input type="radio" name="'+ element[0] +'" > 営業外費用\
      <input type="radio" name="'+ element[0] +'" > 特別利益\
      <input type="radio" name="'+ element[0] +'" > 特別損失\
    </p></div>');
  }
  </script>
    </div>
    <!--答え合わせのボタンの配置-->
    <input type="button" value="答え合わせ" onclick="answer()">
  </form>
</body>
</html>
```

# 参考サイト
ラジオボタン式クイズの作り方
http://www2.kuma.u-tokai.ac.jp/~kfuji/hp/JavaScript/index.html

配列シャッフルの仕方
https://teratail.com/questions/81199
GitHubとHerokuを連携してDjangoアプリをデプロイする（2022.3.15）

<h1>背景</h1>
先日は単にあるファイルをGitHubに上げるだけの記事を書きました。せっかくなら、GitHubに上げた物をインターネットから見れるようにもしたいです。なんならアプリを作ってインターネットから使えるようにしたいって事です。<br>
なお、説明や用語の使い方が間違っている事がありましたら、優しく教えて頂けると嬉しいです。その割に説明はいろいろ飛ばしているので、初心者には向かないものになっています。ただ、大雑把にどのようにするかは分かると思いますので取っ掛かりになれば幸いです。<br>
<br>
前回の投稿<br>

[GitHubにpushする（2022.3.11）](https://qiita.com/tan0ry0shiny/items/5cf257f47807d828252c)
<h1>目的</h1>
簡単なDjangoアプリをGitHub経由でHerokuサーバーからデプロイします。
<h1>方法</h1>
ローカルではVScodeを使って作っていきます。リモートリポジトリとしてGitHubを使い、リモートサーバーとしてHerokuを使いたいです。全て無料で行いたいです。
<h2>準備</h2>

1. GitHubとHerokuとローカルにそれぞれアプリ用のリポジトリを作ります。名前はghrtestにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/788d4eee-589b-3e1c-27a2-2a876c368164.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/8818da7f-557e-c58d-125a-a715de506b73.png)

1. HerokuからGitHubに連携します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/62d0d6da-75a2-64e8-479c-e0296c6c56f9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/9dca41dd-7310-3efc-c52d-f17863554af6.png)


これで、ローカル(PC)とリモート(GitHub)、リモートサーバー(Heroku)の環境が出来ました。後は、ローカルでアプリを作って、リモートに上げるだけです。
<h2>Djangoアプリを作る</h2>
詳細は参考1にお任せします。これが出来ると次の様な物が出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/674b6acd-380e-94c0-c171-671fa03fae47.png)


<h2>staticファイルを作る</h2>
こちらは参考2にお任せします。GitHub経由の場合、「heroku config:set DISABLE_COLLECTSTATIC=1」をどうすれば良いか分からなかったので、使う事はないのですがstaticファイルを作りました。

<h2>GitHub経由でHerokuにデプロイする</h2>
GitHubに上げるだけでHerokuにも連携はされるみたいです。ただ、そのままアプリを起動するとエラーになります。これは手動でデプロイする事で解決出来ました。

具体的には
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/7a172bbc-6ee5-7c8e-7b07-5fccb9d33bdc.png)
アプリを起動するとこの状態になります。この時、Herokuに戻り、マニュアルでデプロイする事で解決します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/598fe1ff-7665-5d12-6157-7685b2fb98bf.png)

赤丸部をクリックするとデプロイが始まり、次の様になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/59c3679c-de1c-3309-b45c-01da7ebaa285.png)

確認のため、赤丸部の「View」をクリックします。
<h1>結果</h1>
無事、インターネットから見れるようになりました。赤丸部がローカルを意味する「127.0.0.1 8000」から「ghrtest.herokuapp.com」になっている事を確認出来ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/b66f60c2-fdaf-54bf-d5d6-ece81e6ecfcf.png)

<h1>考察</h1>
連携はしているので、自動で更新されると思っていましたが、やり方が悪いせいか手動で更新しています。これで問題ないのでしばらくはこれで我慢しようと思います。
<h1>課題</h1>
次回はデータベースを使ったり、データベースもpostgreやMySQLを使いたいと考えています。具体的にはメモアプリを作りたいと思います。staticファイルもtemplatesファイルと同じアプリフォルダの直下に作るようにしたいです。
<h1>参考</h1>

1. [とりあえず秒速でDjangoでホームページを作ってHerokuで公開するやつ（Windows対応）](https://qiita.com/hibit/items/d9b2ed158ac3b0ff7b64)
1. [Djangoで作る初めてのウェブアプリケーション（番外編）herokuデプロイ](https://note.com/takuya814/n/n209dd3c95496)

<h1>次回記事</h1>

[デプロイするDjangoアプリ（メモアプリ）にCSSを反映させる（2022.3.19）](https://qiita.com/tan0ry0shiny/items/7dce5df9da62599bcd3d)
【データモデル】テーブルを書き込み可能にしてみる

[Sharperlight](https://sharperlight.jp/)の使用において、「お客様のデータソースには一切変更を加えない」ということが基本です。
しかしながらお客様からデータソースへの書き込みをご要望されるケースが多々あります。
そのご要望にお応えするため、書き込み機能も備わっています。しかし初期設定ではその機能はオフになっています。
書き込み機能にはセキュリティの観点から様々なレベルでの設定が存在します。
今回の記事では、最下層の設定であるテーブルに対する書き込みオプションの許可設定をみていきます。
## 書き込み許可の設定
対象となるデータモデルにおいて、テーブルが書き込み許可を持つ必要があります。
[Sharperlight](https://sharperlight.jp/)アプリケーションメニューから**スタジオ**を選択します。
![Qiita Common - Menu Studio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/1b55012d-05f8-2f39-06d0-80ba4638ddef.png)
**スタジオ**が起動したら、対象となるデータモデルを開きます。
![2022-03-15 Figure 01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e9dac242-21ce-912d-c682-10d7cc6bd397.png)
データモデルが読み込まれたら、➀テーブルタブに移動、➁テーブル階層表示から書き込み許可を与えたいテーブルを選択します。
中央の領域に選択したテーブルの詳細が表示されるので、➂テーブル名を選択するとテーブルの属性一覧が右側の領域に表示されます。
➃**Allow Table Writeback**(テーブルの書き込み許可)属性を**TRUE**(真)に設定します。
![2022-03-15 Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/9ebc03d6-10e6-9bf3-27db-a4c5e949f0b7.png)
テーブルのアイコンがオレンジに変化することを確認します。書き込みが許可されたテーブルを意味します。
![2022-03-15 Figure 03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0f50a033-962e-cd46-8b4f-0ba14fd1e52a.png)
これで今回の設定は終了です。データモデルの変更を保存して、**スタジオ**を閉めます。
運転中のSharperlightサービスやその他の開いているSharperlightアプリケーションを全て閉じます。
Sharperlightサービスを開始したり、Sharperlightアプリケーションを再度開くことでデータモデルへの変更が反映されます。
## 書き込み許可を与えられたテーブルの確認
Sharperlightサービスが再起動された後、Sharperlightのインデックスページを開きます。
URLは、**http://{YourServerName}/mdService1Rest/Index**です。
ページ左側のメニューから**書き戻し**を選択します。
プロンプトの製品コードで先ほど変更したデータモデルを選択します。[送信]ボタンを押すと書き込み許可を与えたテーブルの一覧が表示されます。今回は一つのみです。
![2022-03-15 Figure 04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/7ebd7276-cf07-a8d8-5edb-df0067c40540.png)
このテーブルに関してはSharperlightの書き込み機能を利用して、データを挿入したり更新したりすることが可能になります。

:postbox:[Sharperlight](https://sharperlight.jp/)
git リポジトリにアクティブな変更が多いため、 git 機能の一部のみが有効になります。のMACでの対処法

# 原因：恐らくuserの階層でgit initしたことが原因
対策方法

1. ユーザーのファインダーに行く（個々の名前が出ています）

ファインダーの中で

Command + Shift + .

を押して隠しファイルを表示し

.gitファイルを削除すると直る

![スクリーンショット 2022-03-15 11.46.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246495/b177c0c4-413c-87e0-903f-523c6c214592.png)

参考：[The git repository
 at ‘c:\Users\(username)’ has too many active changes, only a subset of Git features will be enabled](https://discuss.codecademy.com/t/the-git-repository-at-c-users-username-has-too-many-active-changes-only-a-subset-of-git-features-will-be-enabled/572848)



翻訳：

macをお使いの方へ

ファインダーを開いて左の「お気に入り」バーにユーザー名が表示されていない場合は、画面上部のアップルロゴの横にある「ファインダー」→「環境設定」→「これらの項目をサイドバーに表示」のユーザー名のボックスにチェックを入れてください。

ファインダーに戻ると、左の「お気に入り」バーにあなたの名前が表示されているはずです。あなたのユーザー名をクリックします。隠しフォルダを表示するには、Command + Shift + .(を押します（そう、文字通りピリオドを押す必要があります）。グレーになった ".git" フォルダーが見えるはずです。そのフォルダをゴミ箱に移動してください。
【MEMO】PostgresでUPDATE前後のデータを比較する

# PostgresでUPDATE前後のデータを比較する方法

めもめも。
WITH句にUPDATEをつっこむ。

``` SQL

DROP TABLE IF EXISTS test_table;
CREATE TEMP TABLE test_table (
	test_id int,
	test_name text
);
INSERT INTO test_table VALUES(1, 'a');
INSERT INTO test_table VALUES(2, 'b');
INSERT INTO test_table VALUES(3, 'c');
INSERT INTO test_table VALUES(4, 'd');

/* ここから */

WITH afters AS (
  UPDATE test_table SET test_name = 'UPDATED'
  WHERE test_id >= 3
  RETURNING test_id, test_name
)
SELECT
  befores.test_name AS "old",
  afters.test_name  AS "new"
FROM test_table AS befores
INNER JOIN afters
  ON befores.test_id = afters.test_id;

```
Azure App Service チュートリアル

AzureのAppServiceを触ってみたので勉強メモ兼ねて記載します。

## App Service
Webアプリケーションの実行環境を提供
### WebApps
WindowsサーバでいうIISのようなもの。
アプリの実行環境を提供
### AppServiceプラン
課金対象。仮想マシンのようなもの。AWSでいうとEC2のインスタンス？

ACU（Azure Compute Unit） = AppServiceプランのスペック
もっとも小さいスペックを100（標準）として、
200は2倍、400は4倍　のような感じで見る。

# 実際に作ってみる

AppServiceの作成
![webapp0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/86aa8f0f-89a6-0793-0f9f-381420cf2191.png)

リソースグループは適当な名前で新規作成
名前は一意な名前にする必要があるので注意（Azure全体で一意）
ランタイムは、今回はHTMLを動かすだけなのでASP.NETを選択
リージョンは東日本リージョンを選択
Windowsプランも適当な名前で新規作成
![webapp1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/5b55e1f7-465c-4c32-d65d-98ae81a517da.png)

継続的デプロイは無効化
![webapp2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/ffa3c696-b311-90f6-f51f-3db9c98b896d.png)

Application Insightsは今回は利用しない
![webapp3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/8ba0415f-3cc9-67c9-0f77-9e715aa90c5a.png)

作成をクリックし、少し待つと作成完了！
![webapp4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/574b89b5-7224-56fe-6c2e-c58cf30b21ab.png)

# HTMLをデプロイする

### Kudo（くーどぅ）

AppServiceはリモートデスクトップで接続できないが、Kudoを使えばエクスプローラー操作ができたり、コマンドラインからの操作を実行できる。

また、Kudoを使えばGitを使ってWebAppsでデプロイできる（こっちがメインの使い方？）が今回は使用しない。

AzurePortalから「高度なツール」を選択 → 移動をクリック
![webapp5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/de70f256-01dd-893d-1cf2-911c4d6326eb.png)

「Debug console」から「CDM」または「PowerShell」を選択
※今回はCMDを選択
![webapp6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/2506c948-6171-72c7-d710-df28710d86b0.png)

下記のパスに移動し事前に作成していたHTMLファイルを格納（ドラッグ＆ドロップが可能）
\home\site\wwwroot
![webapp7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/690313c9-4c1d-81a4-36dd-b0b340c85d22.png)

下記のURLにアクセスすると、デプロイされたWebAppsにアクセスできる。
格納したindex.htmlが見えたら成功。

[https://{リソース名}.azurewebsites.net/]
![webapp8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99895/43dc8452-0ee5-336f-fb7e-6e13e7baaf90.png)


App Service のチュートリアルは以上。
MyNetアップデート履歴

# MyNetとは
私が作成した深層学習モジュールです。
この記事にアップデート履歴を記録していくので、バージョン情報が違った際に参考にしてください。

https://github.com/TTaisei/MyNet

# 1
## 1.0
### 1.0.0
ミスにより動きません。
### 1.0.1
ミスを修正し、動くようにしました。
## 1.1
GitHubの操作が不慣れなため、新しいブランチを作成してしまいました。
### 1.1.0
Matrixクラスにappendメソッドを追加。
### 1.1.1
MatrixクラスにArrayList<ArrayList<Double>>を引数にとれるコンストラクタを追加。
### 1.1.2
Matrixクラスのdivメソッドを修正。
## 1.2
### 1.2.0
Optimizerクラス及びGradientDescentクラスにそれぞれログ出力を行うfitメソッドを追加。
### 1.2.1
1.2.0で追加したfitメソッドを変更。学習経過をプロンプト上へ出力するメソッドと、ファイル出力するメソッドに完全に分けた。
### 1.2.2
1.2.0で追加したfitメソッドを変更。動作に変更はない。
### 1.2.3
1.2.2のエラー修正。
### 1.2.4
Optimizerクラスのfitメソッドで、トレーニングデータと確認データの量が違った際に起こるエラーを改善。
# 2
## 2.0
### 2.0.0
フォルダ名`MyNet`を`myNet`に変更．
QMK薙刀式　Remapで配列の変更案

この記事は後日まとめ直しする予定です
現状時点では、この案の成果物は何もありません。

## 暫定的な何か
薙刀式　　　　1 薙刀式の入力中はレイヤー1のまま
単打　　　　　6
シフト単打　　7
編集モード縦　8 縦の編集モードのみで使用する
編集モード横　9 横の編集モードのみで使用する

6789のレイヤーを変更レイヤーと呼ぶとしよう。
変更レイヤーは出力文字を変更用データ配列として利用する
変更レイヤーはRemap(外部操作)を利用することで容易に
変更可能なメモリ配列として扱うプログラムの一案


従来のプログラム修正とファームウェア作成し
マイコンに書き込む作業が無くなり、
1つや2つキーの変更を何度でも気軽に行える

初めは変更レイヤーのキー全てKC_NOで設定しておく。
プログラムの0リセットにあたる

KC_NOのキーは変更データ無し扱いとして
この場合はプログラム側の文字出力になる

変更レイヤーに設定するカスタムキーのデータ規則の
ついて書く前に変更レイヤーの有効、無効機能について
まとめておく。

一時的に変更前の状態に戻したい場合に
仮にESCキーの位置と決める
その位置に
1のキー　カスタムキーコードで変更する　
0のキー　全てしないプログラム側で文字出力する
を設定することで変更レイヤーの動作を切り替える。　

プログラム的には1キーで変更レイヤーを使い
それ以外の全てのキーがプログラム側を使うように
プログミングする。

## カスタムキーのデータ規則
### 単打とシフト単打

### 編集モード縦　横






## ここまでまとめた
## この下　メモ書きのまま

QMK薙刀式をRemap対応する方法に書いていたのが
長くなりすぎたので別記事に分けました

Remapの物理キーの配列を変える　入力キー側
論理配列　文字出力側　にも　Remapの
カスタムキー機能を使って変更可能にする案に
なります

## 2022/03/15 アイディアのメモ追加
Remapのさらなる活用方法の提案

配列の出力文字を変えたいと思っても
現状はプログラムを変更してファームウェアを
入れ直す工程が必要となる

単打とシフト+単打の出力文字を仮にレイヤー8,9に
定義する方法はどうだろう
キー定義を文字変換テーブルとして利用する

keyboard_quantizer rev4は10レイヤー分
あるので薙刀式に3レイヤー分を使っても
まだ余るはず。

Aのキーを　レイヤーを分けて定義すると
1 NG_A  0x5F5A 
8 ろ     0x308D または ro 0x726F
9 せ     0x305B または se 0x7364

ユニコードの先頭0x30が0のキャラコードとかぶるが
2バイトと1バイトで判別が付くので問題無し
0は0x0030となり0x00は出力無しのスルー動作させる
ユニコードはひらがなの範囲のみを想定している
それ以外は無効かASCIIとして扱う。


ユニコードで文字を直接出力か
ASCIIコードのローマ字の出力を想定している
この仕組みなら配列を変更するたびに
プログラム修正とコンパイルなどをしないで済む

変更したい文字があってもRemapの
カスタムキーの書き換えだけで出力文字が
変更できるので便利になる

編集モードはマクロ利用で変更できるのかな
レイヤー移動無しのマクロキーを押すような
プログラムを想定している
M0からM15の16個分　30キー分には足りないが
BSとかはそのまま定義すればなんとかなるかも

薙刀式　　　1 薙刀式の入力中はレイヤー1のまま
単打　　　　7 出力文字変換テーブルとして利用のみ
シフト単打　8 出力文字変換テーブルとして利用のみ
編集モード　9 マクロキーを含むテーブルとして利用

789のレイヤーには移動はしない
789はデータ参照して文字出力を行う
実験的にやってみようかな

## スルー動作をする
31 3レイヤー分をRemapで全て設定するのも
大変だから変更箇所だけにしよう
789のレイヤーの変換キーテーブルに
KC_NOが設定されて箇所は元のままの
出力文字を出すとしよう　

## 変換テーブルごとの有効　無効の設定
全て元のままに戻したい場合は
仮にESCキーに割り当てるとして
変換テーブルの有効、無効を設定機能を取り入れる

~~例えば　有効はoキー　無効はfキーで切り替えする
のは分かりづらいかな~~

やっぱり1,0キーでいいか
ファンクションキーに分かりやすくなる表示として
“1:on 0:off”と1キーづつ並べておけば分かるかな
誤入力の防止のために薙刀の31キー以外は無効にして
6789レイヤーはキー入力をさせないようにする。

もちろん、これらもプログラムをする
編集モード　縦横を別にした方が良さそう

薙刀式　　　　1 薙刀式の入力中はレイヤー1のまま
単打　　　　　6
シフト単打　　7
編集モード縦　8 縦　編集モードのみで使用する
編集モード横　9 横　編集モードのみで使用する

6789のそれぞれのESCキーに有効　無効を設定
暫定としてこれで進める。
他にいい方法があったら変更する
ローカルPCからリモートPCへファイルを送る方法

## 本記事概要
本記事では、ローカルPCのMacからリモートPCのLinuxへ、ローカルPCでZIPに圧縮したファイルを、データ転送の通信を暗号化して転送し、その後解凍する方法について記載しています。

## 学べること
1.ローカルPCからリモートPCへファイル転送する方法
2.ファイルの圧縮と解凍の方法

## 前提
リモートPCへssh接続ができる
　本記事では、リモートPCであるLinux（IPアドレス：152.126.41.70、ユーザー名：root）へ転送します。

## 本編
### SSLでリモートPCに接続
1. ローカルPCのMacのターミナルを開きます。
2. `ssh ユーザー名@IPアドレス`でリモートPCにssh接続を実施します。
```:コマンド
ssh root@152.126.41.70
```
その後Passwordを入力し、ssh接続が出来たことを確認してください。

### 転送するフォルダを圧縮
ローカルPCのデスクトップにある、textフォルダを「text.zip」へ圧縮します。
1.ターミナルの作業ディレクトリを、`cd`コマンドを用いて、textフォルダがあるデスクトップへ移動します。
```:コマンド
cd /Users/XXXXXX/Desktop
```
2.`zip -r [作成するZIP] [圧縮するディレクトリ]`でtextフォルダをZIPに圧縮します。
```:コマンド
zip -r text.zip text/
```

```　:結果例
 adding: text/ (stored 0%)
  adding: text/text3 (deflated 28%)
  adding: text/text2 (deflated 28%)
  adding: text/text1 (deflated 28%)
```
3.`ls`でデスクトップにzipができたことを確認します。
```:コマンド
 ls text.zip
```
```:結果例
text.zip
```
zipファイルがデスクトップにできたことが確認できました。
### ローカルPCからリモートPCにファイルを転送
1.`scp [転送するファイル名] [リモートPCのユーザ名]@[IPアドレス]:[転送先のディレクトリ]`でローカルPCからリモートPCのrootディレクトリにファイルを転送します。その際にリモートPCのパスワードを求められるので、入力してください。
```:コマンド
scp /Users/XXXXXX/Desktop/text.zip root@152.126.41.70:/root
```
```:実行例
text.zip                                      100%  949     5.3KB/s   00:00    
```
### リモートPCでZIPファイルを解凍
1.`unzip [解凍したいzipファイル]`でZIPファイルを解凍することができます。
```:コマンド
unzip text.zip
```
```:結果例
Archive:  text.zip
   creating: text/
  inflating: text/text3              
  inflating: text/text2              
  inflating: text/text1              
```
以上で、ローカルPCからリモートPCにディレクトリを転送することができました。

## 注意点
ローカルPC、リモートPCで`zip`、`unzip`を実行した際に、
```
unzip: コマンドが見つかりません
```
の結果が返ってきた場合、
```
yum list installed | grep zip
```
を実行して、`zip`がインストールされているのか確認することができます。
`コマンドが見つかりません`と返ってきた場合は、以下のコマンドで`zip`、`unzip`をインストールしてください。
```
sudo yum install zip unzip
```
## 終わりに
本記事では、ローカルPCからリモートPCへ、ファイルを転送する方法について記載しました。
Sass（TypeError: this.getOptions is not a function）

### エラー

```
TypeError: this.getOptions is not a function
```

### 環境
```
Node.js v16
nuxt.js v2.15
node-sass v5.0
```

nuxt.js 初期の設定で `<style lang="scss">` を使おうとすると出る。

### 解決方法

`sass-loader`のバージョンを下げる
```
npm install -D sass-loader@10.1.1
yarn add -D sass-loader@10.1.1
```

### そもそも
`node-sass` が古いようで、みんな. `sass(dart sass)`使ってるらしい。

### 参考記事
https://amg-solution.jp/blog/25614

https://qiita.com/n0bisuke/items/123a69ba5940f11404aa
macOS Monterey 12.3「python2.7廃止」への対応

[macOS Monterey 12.3 Release Notes](https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes) より

>Python
Deprecations
Python 2.7 was removed from macOS in this update. Developers should use Python 3 or an alternative language instead. (39795874)


python2.7が廃止になったことに伴って、デフォルトのzsh上でpythonコマンドが使えなくなったため、pyenvを導入してpython環境を構築した。

```zsh:zsh
# formulaeの最新バージョンを取得して、pyenvをインストールする。
% brew update
% brew install pyenv
# pyenvのpath読み込みとpyenvのcompletionを有効化するようにzsh起動時の設定をする。
% echo 'eval "$(pyenv init --path)"' >> ~/.zprofile
% echo 'eval "$(pyenv init -)"' >> ~/.zshrc
#brewコマンド実行時にpyenvのpathを読み込むようにzsh起動時の設定をする。
% vim ~/.zshrc
```

```zsh:~/.zshrc
# 最終行に追加する。
alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'
```

```zsh:zsh
# zshの設定ファイルを再読み込みする。
% source ~/.zprofile 
% source ~/.zsh
# pythonのインストール可能なバージョンを確認する。
% pyenv install --list
# python2系とpython3系の最新版をインストールする。
% pyenv install 2.7.18
% pyenv install 3.10.2
# インストールしたバージョンをglobalに設定する。
% pyenv global 2.7.18 3.10.2 # 2系を先に書くこと。
# インストールしたコマンドがglobalに効いていることを確認する。
% python --version
Python 2.7.18
% python3 --version
Python 3.10.2
```

参考
[pyenv](https://github.com/pyenv/pyenv#command-reference)
Python - Conda仮想環境の構築方法


本稿では、Windows環境でAnacnda又はMinocodaを使ったPython仮想環境の構築方法を簡潔にご紹介します（Macもほぼ同じ、違いは文中で説明）。こちらの[ozaki_physicsさんの記事](https://qiita.com/ozaki_physics/items/985188feb92570e5b82d)はより詳しいので必要に応じてご参照ください。

### Anaconda又はMinicondaのインストール
Condaもpipもpythonのバージョンとパッケージを管理しますが、両者のグローバル環境での共存・競合がややこしいのでAnaconda又はMinicondaをインストールするときは少し慎重になる必要があります。現在pipを使っていて、仮想環境を構築したい場合は、このためだけにAnaconda又はMinicondaをインストールせず、pipを使うpyenv + venvなどの別の方法を検討した方がいいと思います（Windowsの方は[こちらの私の記事](https://yoheiko.com/?p=2899)を参照）。なおグローバル環境（root環境）でいずれか一方のみを使うと決めれば、仮想環境ではなんらかの事情によりcondaとpipが共存したとしても問題にならないような気がします（ご意見伺えれば幸いです）。

### 現在の環境の確認
これまで仮想環境を作成していなければ、（root）のみが表示されます。

```python
$ conda info -e
```

### 新たな仮想環境の構築
envnameの部分に任意の仮想環境の名称を、pythonに続く等号の左側に特定のpythonのバージョンを指定します。指定がないと最新のものがインストールされると思います。これで（root）とは異なる環境ができます。
```python
$ conda create -n envname python=3.9.6
```

### 仮想環境のActivate
続いて作った仮想環境に入ります。この操作により、シェルの冒頭の（root）の部分が、（envname）に変わったと思います。macの場合は下段にように頭にsourceを付けます。
（base）が表示されるも、activate envnameでは動かない場合は、activateの前にcondaを付けると動くことがあります。

```python
$ activate envname
$ source activate envname
```

### 仮想環境にインストールされたライブラリーの確認
仮想環境に入った状態で、下記上段を記述するか、仮想環境の外では下段のコードで環境を指定して確認できます。

```python
$ conda list
$ conda list -n envname
```

### 仮想環境へのライブラリーの追加インストール
envnameの部分には仮想環境の名称を、pkgnameの部分にはインストールしたいパッケージの名称を記述します。

```python
$ conda install -n envname pkgname
```

### 仮想環境内でのpythonの実行
Anaconda promptの表示が（envname）となっていれば、当該仮想環境の内側にいますので、この状態で（root）と同じようにpythonが実行可能です。例えば、main.pyを今作った仮想環境内で実行したい場合は下記の通りです。（envname）の部分は冒頭の表示ですので、記入頂く必要はありません。また、同時に複数のAnaconda Promptを立て、それぞれ別の仮想環境をActivateすることにより、同一のサーバ内で異なる環境下にあるプログラムも実行可能です。

```python
(envname) $ python main.py
```
### Conda仮想環境内でのjupyter notebookの実行
Conda仮想環境でjupyter notebookを実行したい場合、ipykernelをグローバルに（ここはグローバルではなく仮想環境の内側だったかもしれません）インストールの上、下記のコードを実行するだけで設定が完了します。右のenvnameの部分はcondaで作成した仮想環境の名称を記入します。jupyter notebookを立ち上げた後、右上「new」をクリックすると、追加した仮想環境内でjupyter notebookを動かすことが可能です。

```python
$ ipython kernel install --user --name=envname
```
 


### 仮想環境内から抜ける（Deactivateする）方法
処理が完了したら仮想環境から抜けて終わります。下記上段はwindowsでの方法、下段はmacです。Windowsでは2021年頃から、頭にcondaを付けるようになりました（付けない方法はdepreciated）。なお、そのままAnaconda Promptを落としても、次にAnaconda Promptを立ち上げたときは仮想環境から抜けてrootに戻っています。

```pythono
$ conda deactivate
$ source deactivate
```

### 仮想環境を削除する方法
不要な仮想環境は、下記のコマンドで簡単に削除することも可能です。
```pythono
$ conda remove -n envname --all
```

### 複数のシェルの立ち上げに関する不安定な挙動
既に仮想環境で動いているフォルダに対して、別の新たにシェルを立ち上げ、同一の仮想環境を適用させようとするとうまく行かないことがあります。同じ仮想環境ではあるもの、同じフォルダに対する複数環境の競合が回避されている可能性があります。この場合は、conda内の履歴に別のものを挟む趣旨で、別の仮のフォルダで、一度仮想環境を立ち上げてから、該当のフォルダに戻って同様に仮想環境の立ち上げを試みるとうまく行くことがありました（失敗することの方が多い）。また起動の順番は1. （base）のdeacivate、2.conda info -eの表示、3.activate envnameの順番がよく、無関係に思えますが、管理者権限でシェルを実行するとうまく行くことがありました。

### ダブルクリックで実行する方法
Conda仮想環境にあるpythonのファイル（.pyファイル）をダブルクリックで実行することもできます。具体的な設定方法については、私のYoheiKoブログでのこちらの記事「[Pythonファイルの実行方法、ダブルクリックでの実行方法](https://yoheiko.com/blog/python%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e3%83%80%e3%83%96%e3%83%ab%e3%82%af%e3%83%aa%e3%83%83%e3%82%af%e3%81%a7%e3%81%ae%e5%ae%9f%e8%a1%8c%e6%96%b9%e6%b3%95/)」で詳しく解説していますので、ご関心ある方はご覧になってみてください。

今日も最後まで読んで頂きありがとうございました。
Python 複数のEventを扱いたいとき悩んだ時に見るコード例 (30秒で読めます)

２つのタスクを別のスレッドで実行し、各スレッドでキューに値を入れてEventをセットする。メインスレッドは５秒間処理を行わず、その間、サブスレッドがキューに値をいれる。q1の要素数が0じゃなければpopし、q2の要素が3以上ならpopする。

```python
import threading
import time
from collections import deque
import random


class MyEvent():
    def __init__(self) -> None:
        self.event1 = threading.Event()
        self.event2 = threading.Event()


class MyDeque():
    def __init__(self) -> None:
        self.q1 = deque([])
        self.q2 = deque([])


def pop_q1(event: MyEvent, q: MyDeque):
    # 要素数0じゃなければ実行
    if q.q1:
        print('main_thread pop_q1', q.q1.popleft())
        event.event1.clear()


def pop_q2(event: MyEvent, q: MyDeque):
    # 要素数3以上なら実行
    if len(q.q2) >= 3:
        print('main_thread pop_q2', q.q2.popleft())
        event.event2.clear()


def is_wait_event(event: MyEvent):
    return True if event.event1.is_set() or event.event2.is_set() else False


def main_thread(event: MyEvent, q: MyDeque):
    begin = time.time()
    while True:
        try:
            if is_wait_event(event):
                pop_q1(event, q)
                pop_q2(event, q)
            time.sleep(0.01)
        except KeyboardInterrupt as e:
            print(e)


def task1(event: MyEvent, q: MyDeque):
    while True:
        # キューへ追加したらeventセット　
        time.sleep(random.random())
        q.q1.append('q1_elem')
        print(f'task1 append elems: {len(q.q1)}')
        event.event1.set()
        time.sleep(random.random())


def task2(event: MyEvent, q: MyDeque):
    while True:
        # キューへ追加したらeventセット　
        time.sleep(random.random())
        q.q2.append('q2_elem')
        print(f'task2 append elems: {len(q.q2)}')
        event.event2.set()
        time.sleep(random.random())


my_q = MyDeque()
my_event = MyEvent()
target_list = [task1, task2]
for target in target_list:
    th = threading.Thread(target=target, args=(my_event, my_q,), daemon=True)
    th.start()
# 5秒間スリープしてスレッドの処理を行わせる
time.sleep(5)
main_thread(my_event, my_q)

```

```:実行結果
task1 append th1 1
th1
task2 append th2 1
task1 append th1 1th1

task1 append th1 1th1

task2 append th2 2
```