OmniAICreator/Qiita-1.07M huggingface dataset:
【Lerna】PR中のコードをGithub Packagesにcanary releaseする

Lernaで管理しているmonorepoのパッケージをPR中でも実際のアプリケーションで動作確認したかったので、canary releaseできるようにGithub Actionsを作成したのでメモ。

```yml
name: Canary Release
on:
  issue_comment:
    types: [created]

jobs:
  canary-release:
    name: canary-release
    runs-on: ubuntu-latest
    if: |
      github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/canary-release')
    steps:
      - name: checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: '0'

      - name: setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 16.x
          registry-url: 'https://npm.pkg.github.com'
          scope: '@<scope_package>'
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Cache dependencies
        uses: actions/cache@v3
        with:
          path: ./node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install packages
        run: yarn install --frozen-lockfile

      - name: Publish
        run: yarn lerna publish --canary --preid next --dist-tag next --force-publish='*' --no-push --no-git-tag-version --yes --registry=https://npm.pkg.github.com
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '🎉 Canary Release. You can install canary version via `npm install package@next`'
            })
```

PRに `/canary-release`とコメントするとcanary releaseを公開します。

![スクリーンショット 2022-12-27 16.33.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349238/41936285-9c19-e7b1-9a20-ab865a7e345f.png)


## 参考
[monorepoでPR中のコードをnpmパッケージとしてcanary releaseするGitHub Actions](https://zenn.dev/azu/articles/29e1465875d57d)
[lerna/commands/publish at main · lerna/lerna](https://github.com/lerna/lerna/tree/main/commands/publish#--canary)
テキストファイル内の重複行をソートせずに削除

テキストファイルの重複行を削除する際、`sort tmp.txt | uniq` だと当然ソートされてしまう。
**ソートせずに**順番は保ったまま重複行を削除したい場合は awk を利用すると楽。
基本の形は `awk '!a[$0]++ {print}'`
!a[$0]++ の部分を変えることで一部が重複している行を対象にしたり、重複回数で絞れたりできる。
 
```
# 重複行削除
cat tmp.txt | awk '!a[$0]++ {print}'

# 重複している行のみ出力
cat tmp.txt | awk 'a[$0]++ == 1 {print}'

# 2 列目が重複している行を削除
cat tmp.txt | awk '!a[$2]++ {print}'

# 3 回目以降の重複は削除
cat tmp.txt | awk '++a[$0] < 3 {print}'
```

# 動作

```sh
$ cat tmp.txt
hoge 100
fuga 200
foo  200
foo  200
foo  200
foo  200
fuga 200
foo  200

$ cat tmp.txt | awk '!a[$0]++ {print}'
hoge 100
fuga 200
foo  200

$ cat tmp.txt | awk 'a[$0]++ == 1 {print}'
foo  200
fuga 200

$ cat tmp.txt | awk '!a[$2]++ {print}'
hoge 100
fuga 200

$ cat tmp.txt | awk '++a[$0] < 3 {print}'
hoge 100
fuga 200
foo  200
foo  200
fuga 200
```

# 解説

`!a[$0]++` の部分について、\\$0 (行全体) の値が初出の場合は a[\\$0] = 0 となる。
awk では 0 は false 扱いされるので結果として `!a[$0] == !0 == true` となり出力される。
2 回目以降は後置インクリメントされているので a[\\$0] = 1, a[\\$0] = 2... となり、0 以外の数字は true 扱いされるので `!a[$0] == !X == false` (X は 1 以上の整数) となり無視される。

なので `a[$0]++ == 1` とすれば 2 回目に出現した行のみ true となるし、`!a[$2]++` とすれば 2 列目だけを見て重複判定するし、`++a[$0] < 3` とすれば 3 回目以降の重複が無視される。(最後だけ前置インクリメントにしているのはその方が主観的に分かりやすく感じたため)
jsonをTypedDictのクラスに変換してくれるサービス

**apiから帰ってくる内容をTypedDictにしたい！
でもめんどい**

というときに使えるのが

https://pytyper.dev/

左にjsonを入れるだけで右にTypedDictのクラスにしてくれるのだ！！！

例えばこれを入力すれば

```json
{
  "emojis": [
    {
      "id": 1,
      "name": "thumbsup",
      "alias": ["+1"]
    },
    {
      "id": 2,
      "name": "thumbsdown",
      "alias": ["-1"]
    },
    {
      "id": 100,
      "name": "100"
    }
  ]
}
```
こんな感じにしてくれる
```python
from typing import List, Union

from typing_extensions import TypedDict


class EmojisItem0(TypedDict):
    id: int
    name: str
    alias: List[str]


class EmojisItem2(TypedDict):
    id: int
    name: str


class Root(TypedDict):
    emojis: List[Union[EmojisItem0, EmojisItem2]]
```

この場合のaliasがあるのとないのをNotRequiredでやってくれないけど、それ以外はいい感じに変換してくれる
App ServiceのJobsが文字化け・表示されない時の対処法

# 目次
1. はじめに
2. 対処方法
3. 最後に


# はじめに
FoundryのApp Serviceには、
APIなどの処理を自動実行するためのCronに似たJobsという機能があります。

Jobsでは、自動実行したい処理を選択して、
週1や月1などスケジュールを設定することができますが、
Chromeではうまく表示されないことがあります。（2022/12/27時点）
![スクリーンショット_0004-12-27_15_40_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/ee8c164e-e892-ea4e-317a-9f25c6c278b9.png)

今回は、Jobsを表示させるための対処法についてご紹介したいと思います。

Jobsって何？という方は以下の記事に概要を書いていますので、
こちらもご参考ください👀

https://qiita.com/Kony_Team/items/f557535f52c4e96c6cb1 


# 対処方法
早速対処法を紹介します！

## Safariで開く
Chromeではなく、Safariで開いてみましょう。

JobsのURLをSafariにコピペし、
自身のアカウントでログインするとJobsの画面が見れるようになるかと思います。

大体はこの方法で解決できます👌
![スクリーンショット_0004-12-27_15_42_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/0e62f1b9-88a5-b9df-12e9-487f82680ca3.png)

画面が表示されたら通常通りJobsの設定を行ってください。

## 言語設定を英語に変更 
大体の場合は上記の対処法でうまくいきますが、
Safariの最新バージョンを使っている場合、Safariでも画面がうまく表示されないことがあります。

その場合は、ブラウザの言語設定を英語にしてみましょう。

英語に変更するとChromeでもSafariでも画面を見ることができるようになります。

ブラウザに応じた言語設定の変更方法はこちらをご参照ください。

https://staku.designbits.jp/mac-browser-accept-language/

言語変更後も変わらない場合は、
言語設定変更後に端末を再起動すると表示されるようになります。


Chrome
![Screen_Shot_0004-12-27_at_15_53_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/115e2614-f7f3-6c01-380e-403b54ddb102.png)

Safari
![Screen_Shot_0004-12-27_at_15_57_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/da2d0133-9b86-20b1-50f6-174e3912c3ce.png)

ChromeとSafariどちらも正常に表示されるようになりましたね👌

# 最後に
今回はJobsの設定画面が見れない時の対処法についてご紹介しました。
困った時は参考にしてみてくださいね！
fish-shellでdevboxを動かすのはNixOSのプラグイン入れればいけた

いけた

### fishのプラグインのインストール

[GitHub \- lilyball/nix\-env\.fish: Nix environment setup for the fish shell](https://github.com/lilyball/nix-env.fish)

```
fisher install lilyball/nix-env.fish
```
NSAttributedStringと絵文字でなんで文字化けになる？

# 背景
超久しぶりに文字列と戦ったのでここで残しておきたい！
みんなも文字のカウントいつ何を使えばいいか思い出してみましょう

例のこちら文字列値がある
```swift
@Binding var text: String
```

でその文字列に超えた制限だけハイライトをしたいな〜と思ったあなたへ、文字のみであればtext.countでも全然十分！
ただ、multibyte絵文字含めてしまうとどう計算すればいいのでしょうか？

# text.count
上記の書いた通りに文字しか想定していない場合はこれだけでいける！

```swift
        let text = "Hi my name is Adam!"

        print(text.count) // 24

        let textView = UITextView()
        textView.frame = CGRect(x: 150, y: 200, width: 200, height: 50)
        let attributedText = NSMutableAttributedString(string: text)
        
        attributedText.addAttributes(
            [.font: UIFont.systemFont(ofSize: 18),
             .foregroundColor: UIColor.gray],
            range: .init(location: 0, length: text.count)
        )
        
        if text.count > 5 {
            attributedText.addAttributes(
                [.backgroundColor: UIColor.red],
                range: .init(location: 0, length: text.count)
            )
        }
```

こんな結果が出ます
![Screen Shot 2022-12-27 at 15.40.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147278/db645d40-5248-b429-8839-7cbfa2bb8d56.png)

でも次は絵文字使ってみましょう
```swift
let text = "Hi 🗿 my name is Adam😉😉😉!"
```

![Screen Shot 2022-12-27 at 15.41.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147278/2546ba7d-1b07-1e2f-844e-84ca81e3c718.png)

`text.count`だと24が出ますが、`NSAttributedString`の`Range`だと計算ロジックと違う
それで絵文字の途中まで`attribute`をかけているから文字化けしている

# text.utf16.count
[UTF-16](https://ja.wikipedia.org/wiki/UTF-16)を使ってみましょう

```swift
        let text = "Hi 🗿 my name is Adam😉😉😉!"
        
        print(text.count) // 24
        print(text.utf16.count) // 28

        let textView = UITextView()
        textView.frame = CGRect(x: 150, y: 200, width: 200, height: 50)
        let attributedText = NSMutableAttributedString(string: text)
        
        attributedText.addAttributes(
            [.font: UIFont.systemFont(ofSize: 18),
             .foregroundColor: UIColor.gray],
            range: .init(location: 0, length: text.utf16.count)
        )
        
        if text.utf16.count > 5 {
            attributedText.addAttributes(
                [.backgroundColor: UIColor.red],
                range: .init(location: 0, length: text.utf16.count)
            )
        }
        
        textView.attributedText = attributedText
```

これでは思い通りの結果になる！やった〜
![Screen Shot 2022-12-27 at 15.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147278/ec35bdec-b0ab-fda0-eec7-cba62ac82eac.png)

# Summary
しばらく使っていないと忘れやすい！ので誰か役に立ったら嬉しい！
もし絵文字＋NSAttributedStringを一緒に使うんだったらUTF-16を使いましょう！！
# C++ でプロパティーを実現する方法パート2

改めてプロパティーをC++で実現する方法を考えてみました。 clang ではメンバーのアドレス/オフセットが静的に扱えないので empty base optimization(EBO) で実現する形にしました。 型は分かれますが醜悪なマクロを使いません。
    
```c++
#include <iostream>
#include <type_traits>
#include <string>

template<class T>
struct PropertyUtil {
    // empty base
    PropertyUtil(const PropertyUtil&) = delete;
    PropertyUtil(PropertyUtil&&) = delete;
    PropertyUtil& operator=(const PropertyUtil&) = delete;
    PropertyUtil& operator=(PropertyUtil&&) = delete;

protected:
    PropertyUtil() {}

    constexpr auto operator->() noexcept -> T* {
        return reinterpret_cast<T*>(this);
    }

    constexpr auto operator->() const noexcept -> const T* {
        return reinterpret_cast<const T*>(this);
    }
};

template<typename T>
struct FooProperty {
    // empty base
    FooProperty() {}
    FooProperty(const FooProperty&) {};
    FooProperty(FooProperty&&) {};
    FooProperty& operator=(const FooProperty&) {};
    FooProperty& operator=(FooProperty&&) {};

    [[no_unique_address]] struct : PropertyUtil<T> {
        operator int() noexcept {
            return this[0]->value_;
        }
        auto operator=(int n) noexcept -> int {
            this[0]->value_ = n;
            return n;
        }
    } value;
};
struct Dummy {};
static_assert(std::is_empty<FooProperty<Dummy>>::value);

struct Foo : FooProperty<Foo> {
private: 
    int value_ = 123;
    friend struct FooProperty<Foo>;  
    friend int main();
};

int main()
{
    auto a = Foo();
    //auto _ = a;
    std::cout << a.value << std::endl;
    a.value = 256;
    std::cout << a.value << std::endl;   
}
```
[Rails,Javascript]RailsのviewでJavaScriptを用いて一定時間後に指定したページへ飛ぶ

チーム開発で活用した技術アウトプット投稿
## 目的
- 特定ページを訪れた際、一定時間後指定したページへリダイレクトする

## 開発環境
- Ruby 3.1.2
- Rails 6.1.7

## 基本的な書き方
指定したいページに下記`script`を記述

```.js
<script>
  const action = function() {
    window.location.href = '/';
  }
  const time =  5*1000;
  setTimeout(action,time);
</script>
```
- `action`内の`window.location.href = 'URL';`で遷移先を指定
- `time`内の5*1000で秒数を指定(ミリ秒で指定する。1000 = 1秒)
- `setTimeout`で`time`に指定した時間経過後に`action`を実行

## 問題点
この記述をしたページから違うページに飛んだ場合でも実行されてしまう
※指摘してくれたチームメイトに感謝

例)Aboutページに指定している、指定先はトップページ、移動時間は５秒後とする
- Aboutページにアクセス
- 5秒以内に他のページ、例えば商品ページに移動
- **５秒立つとトップページに飛ばされてしまう**

**→つまりキャンセル処理が必要であるということ**

## キャンセル処理
`setTimeout`のキャンセルには`clearTimeout()`を使用する
今回はヘッダーにあるリンクを押して移動した場合はキャンセル処理を走らせたかったため以下の様に記述

```.js
  const action = function() {
    window.location.href = '/';
  }
  const time =  5*1000;
  let timer = setTimeout(action,time);
  
 function stopTimer() {
   clearTimeout(timer);
  }
```
##### 変更点
- 変数`timer`に`setTimeout`処理を代入
- `function stopTimer() {}`に`clearTimeout(timer);`を指定
そして押下時にキャンセル処理を走らせたい部分に追加の記述を行う

```_header.html.erb
　　　　　　　〜略〜
<ul class="navbar-nav ml-auto">
  <li class="mr-2" onclick="stopTimer()">
    <%= link_to my_page_customers_path, class: 'nav-link text-dark btn btn-outline-secondary me-2' do %>
      マイページ
    <% end %>
   〜以下略〜
```
**`class`で指定している`onclick="stopTimer()"`が追加部分**
`onclick`は押すことで指定している変数の内容を実行する、つまり`stopTimer()`が実行される
`stopTimer()`は`clearTimeout(timer);`の処理を指定しているので、リダイレクトがキャンセルされるという流れ
## 参考
https://developer.mozilla.org/ja/docs/Web/API/setTimeout

https://developer.mozilla.org/ja/docs/Web/API/clearTimeout

https://www.javadrive.jp/javascript/event/index2.html
WindowsでUIから終了できないプロセスをコマンド経由で強制終了

# 概要

問題起きてるプロセスを停止したい。
でも、タスクマネージャーで下記ように操作しても、プロセス停止できない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b24f5ee5-441d-0967-1261-cfa72bd5bda8.png)

下記のようなダイアログが出る。
> プロセスを終了できません
> 操作を完了できませんでした。
> アクセスが拒否されました。

# コマンド経由で強制停止

## まずプロセスIDを調べる

コマンドプロンプト開いて下記。

```bat:タスク一覧表示コマンド
tasklist
```

『PID』の列がプロセスID。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b113cadf-508d-bd13-0ebe-43a293739fe4.png)

タスク一覧を一旦テキストで出力しておくのがおススメ。
（『検索』『作業前と作業後の比較』『エビデンス』の用途に使えるので）
```bat:タスク一覧をtxtに書き出しコマンド
tasklist > tasklist.txt
```

大体、コマンドプロンプト起動すると ```C:\Users\ユーザー名``` が起点フォルダーになっている。
その場合、txtはそのフォルダーに出力される。

## プロセスIDを指定してタスク強制終了コマンド

コマンドプロンプトを管理者権限で開いて下記。

```bat
taskkill /f /pid プロセスID
```

誤って別の重要なプロセスを停止してしまわないように注意！
落ち着いて『本当にこのプロセスIDでいいか』を再度確認してからコマンド流そう！

# 参考サイトさん

https://did2memo.net/2016/01/12/windows-unable-to-terminate-process/

http://webmemonote.com/diary/taskkill/

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2364
コードレビューを単純に導入するだけでは問題が起きた話💔 - HRT（ハート）の精神を大切にしよう🤗

# はじめに
HRTをチーム内に浸透させることでコードレビューがうまく回るようになった、実体験に基づくお話しです。

# 背景
少人数かつベンチャーだったこともあり、コードレビューの文化がありませんでした。
人によってコードがバラバラで、知識の共有もできていませんでした。
そこでコードレビューを提案し、導入することにしました。
ただ、これまでのバックグラウンドの違いもあり、議論が終わらなかったり、命令口調だったりで以下のような問題が起きました😭
💔 チーム内の雰囲気が悪くなってしまった
💔 レビューが終わらずタスクの進捗が悪くなってしまった

そこで導入したのが**HRT**と**ラベル**です。
今回はHRTについてお伝えします🤗

ラベルについては以下の記事を見ていただけると嬉しいです。
[コードレビューを単純に導入するだけでは問題が起きた話 - ラベルバッチをつけよう！](https://qiita.com/miyuc/items/623d34d6f9d38a14bdf0)

# HRT（ハート）とは？

**HRTの原則**は以下の3つです。

```
1. 謙虚(Humility)
2. 尊敬(Respect)
3. 信頼(Trust)
```

詳しく見ていきます。

- **謙虚(Humility)**
世界の中心は君ではない。君は全知全能ではないし、絶対に正しいわけでもない。常に自分を改善していこう。

- **尊敬(Respect)**
一緒に働く人のことを心から思いやろう。相手を一人の人間として扱い、その能力や功績を高く評価しよう。

- **信頼(Trust)**
自分以外の人は有能であり、正しいことをすると信じよう。そうすれば、仕事を任せることができる。

この3つの精神が欠けていると人間関係の衝突が生まれます。
『Team Geek』では下記のように言い切っています。

> あらゆる人間関係の衝突は、謙虚・尊敬・信頼の欠如によるものだ


以下、レビューでの具体的なやりとりが書かれていて面白かったです。
🗒[アンチパターンから学ぶHRTなコードレビュー](https://blog.toshimaru.net/hrt-review/)

# なぜHRTなレビューが必要なのか？

全てはの**チームの心理的安全性を確保するため**です。
心理的安全性とは
「対人関係においてリスクのある行動をしてもこのチームでは安全であるという、チームメンバーによって共有された考え」
のことで、Googleの調査でハイパフォーマンスなチームにとって心理的安全性は極めて重要だと言うことが証明されています。
🗒[「効果的なチームとは何か」を知る](https://rework.withgoogle.com/jp/guides/understanding-team-effectiveness/#foster-psychological-safety)

HRTの精神が根付いているチームは心理的安全性の高いチームと言って良いでしょう。

# どうやってチームに浸透させたか

すごく普通のことですが、以下のことを行いました。

- チームでHRTについて話す場を設ける
- 自分から率先してHRTの精神で相手に接する
- 不定期で自分の反省をチームのチャンネルに投稿する

# 実際にどう変わったのか

コードレビュー時もそうですが、チームのチャンネルでも技術的な会話が増え、お互いのことを知るようになりました。
そうすることで相手を尊重しながらコードを良くしていこうという流れができてきました。
結果として、人間関係が改善し、レビューにかける時間も減って、うまく回るようになりました。
相手を批判するのではなく、どうしたらシステムを良くしていけるか、という意識で会話できるようになって、心理的安全性の高いチームになったと思います。

# 感想

HRTは自分にとってもチームにとっても大事な要素です。
チームとして生産性を上げていきたいのであれば必ず必要な考え方だと実感しました。

# 参考

以下の記事を参考させていただきました。
とても参考になる情報をありがとうございました😃

📕『Team Geek』

https://blog.toshimaru.net/hrt-review/

https://rework.withgoogle.com/jp/guides/understanding-team-effectiveness/#foster-psychological-safety
PyOpenGL入門 GPGPU・エフェクト編をリリースしました

# はじめに

PyOpenGL入門 基礎編の続編である「GPGPU・エフェクト編」をリリースしました。PDFの電子書籍です。
以下のBOOTHサイトで購入出来ます。

[PyOpenGL入門_GPGPU・エフェクト編(BOOTH)](https://mainichipython.booth.pm/items/4411663)

以下のYouTube動画では本の内容を一部立ち読みできます。

[PyOpenGL入門 GPGPU・エフェクト編をリリースしました(YouTube)](https://www.youtube.com/watch?v=JS9-FtHswqQ)

# 対象読者

- OpenGL の基礎を習得していて GPGPU やエフェクト処理を勉強したい
- OpenGL の GPGPU やエフェクト処理は知っているが、PyOpenGL でも動かしてみたい
- Unity などのエフェクト処理に応用するため、エフェクト処理の基礎を勉強したい

# 執筆動機

元々、基礎編を書き終えた時点で続編の執筆は決まっていました。
OpenGLはゲームプログラミングに応用したくて勉強しましたので、OpenGLの基礎的な理解だけでなくエフェクト処理の理解も勉強したい内容の内の１つでした。
GPGPUはエフェクト処理に必要なため合わせて一緒に載せています。

# 書籍内容

内容としては、そのままなのですが、GPGPUとエフェクト処理の基本を解説する事です。
出来るだけ簡単なサンプルで基本を解説したつもりです。
内容的には難しい分野なので、基本と言ってもシェーダコードを理解するのは大変かもしれません。
少なくとも基礎編くらいの内容は理解しておいた方が良いと思います。

GPGPUとしては、OpenGLでシェーダでアトリビュート変数以外の方法でデータをやり取りする方法は、全てではないとしても重要な手法としては本書で大体カバー出来たかなと思います。
あとは、エフェクトの基本的な考え方を身に付けてしまえば、応用のための基礎力は身に付くと思います。

今回のOpenGL入門シリーズは、ある意味では自分のリファレンス用として執筆したという意味合いもありますので、ゲームプログラミングへの応用方法も今後は模索していきたいと思っています。

# おわりに

執筆途中で体調不良になってしまい書き残した項目はありますが、とりあえずOpenGL入門は本作で完結したつもりです。
書き残した項目も余裕が出来たら改訂版として追記したいと思います。
既に購入された方は無料で改訂版をダウンロード出来るようにするつもりです。

あくまでも予定ですが、次回作は実践的な内容として、OpenGLを利用した2Dゲームグラフィックエンジン開発をやりたいと思っています。
電子書籍かYouTubeなどの方法で公開したいと思います。
エンジニアに必要な基礎能力について

# はじめに
昨今 it エンジニアの不足が不足しています。
ただ数が不足しているだけでなく能力の面でも要求されることが増えています。
プログラミング能力以前の基礎能力についてまとめました。エンジニアにとって必要な基礎能力は何なのでしょうか？
本記事では、簡潔に必要な基礎能力についてまとめています。

# 必要な基礎能力
1. 外向性
1. 想像力
1. 不透明なものに対する忍耐力
1. コミュニケーション能力
1. 構成力

外向性
人脈を築いたり、取引先と良好な関係を築くために有効なのだと思います。
鍛える方法としては寝る前に、自分が行った外交的だった行動を思い出すようにすればいいと思います。このようにすれば自分に対してのイメージが少し変わるのではないでしょうか？

想像力
この能力は計画を立てたり、システムを設計したりする時に役立つと思います。

不透明なものに対する忍耐力
なかなかうまくいかない時のストレス管理が求められると思います。動いたり歌ったり愚痴をこぼしたりと言う外に出すようなストレス発散がいいと思います。

コミュニケーション能力
この能力はチームでシステム開発を進めるエンジニアにとって必要不可欠ではないでしょうか？
この能力を鍛えるために、友人と話すときに、コミュニケーションのテクニックを試してみるのもいいかもしれません。

構成力
システムを構築するためにはこの力が必要不可欠だと思います。
この能力を育成するために、計画を立てるといいと思います。

# 参考文献
SE のための仕事術心得ノート
【jQuery】validate()　をclass名を使って実装

classを使ったバリデートの実装とメッセージの出力をまとめました。
wordpressや外部のサービスを使って自動形成されるフォームを使用したときに、idやnameが自動生成で指定出来ない時などにクラスを使ったバリデートの実装が使えます。

```html
<html>
<head>
</head>
<body>
<form>
<select namae="kakegami" class="select_kakegami">
    <option value="のし有り">のし有り<option/>
    <option value="のし不要">のし不要<option/>
</select>
<input type="text" class="input_naire" />
<input type="submit" />
</form>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
<script>
$(function(){
    $('.input_naire').rules("add",{
        required:{
            depends: function (element){
                return $('.select_kakegami option[value!="のし不要"]').is(':selected'); 
           }
        },
        message: {
            required: "のしをご希望の場合は必ず入力してください。";
        }
    });
});
</script>
</body>
</html>
```
Hydraのconfig nameを動的に設定・取得

## 想定するファイル構成
```bash
├── conf
│   ├── transformer.json
│   └── lightgbm.json
│
├── main.py
```

## config nameの動的な設定
```bash
python main.py --config-name=transformer train.cuda=0 ...
```

## config nameの取得
```python
from omegaconf import DictConfig
from hydra.core.hydra_config import HydraConfig


@hydra.main(version_base=None, config_path="conf", config_name=None)
def main(cfg: DictConfig):
    CONF_NAME = HydraConfig.get().job.config_name

```
【AWS】AppSync GraphQLのクエリfilter検索条件

AppSyncのGraphQL検索条件のfilter条件をまとめてみます。

# filter
|operator|description|
|--|--|
|eq|指定した値と一致する(=)|
|ne|指定した値と一致しない(!=)|
|gt|指定した値より大きい(>)|
|ge|指定した値以上(>=)|
|lt|指定した値より小さい(<)|
|le|指定した値以下(<=)|
|between|指定した1つ目の値よりも大きく、2つめの値よりも小さい|
|contains|指定した値が含まれる|
|notContains|指定した値が含まれない|
|beginsWith|指定した値で先頭一致|
|and|すべての条件を満たす|
|or|いずれかの条件を満たす|
|not|指定した条件を満たさない|

```js
input ModelStringInput {
	ne: String
	eq: String
	le: String
	lt: String
	ge: String
	gt: String
	contains: String
	notContains: String
	between: [String]
	beginsWith: String
	attributeExists: Boolean
	attributeType: ModelAttributeTypes
	size: ModelSizeInput
}
```

# 使用例
```js
let filter = {
      or: [{ priority: {eq:1} },
           { priority: {eq:2} }]
  };
await API.graphql({ query: listProducts, variables: { filter: filter}}));
```

```js
let filter = {
  number: { ge: 1, le: 100 },
}
```

```js
let filter = { 
  createdAt: { between: ["2022-01-01", "2022-12-31"] },
}
```

# 参考
https://docs.amplify.aws/lib/graphqlapi/query-data/q/platform/js/

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html
PythonでDALL·E 2 APIを使う方法と、結果のURLだけのリストを取得する方法

# 課題

Djangoの中で画像を生成するAPIを使いたいと思っていた所、DALL·E 2 APIを見つけました。
その使い方だけでなく、結果のURLだけのリストを取得する方法まで載ってるサイトが見つかりにくかったので、共有させていただきます。

# PythonでDALL·E 2 APIを使う方法と、出力結果のURLだけのリストを取得する方法

```python:views.py
# "pip3 install openai"などで、openaiをあらかじめインストールしておく。
#google colaboratoryを使う際には、"! pip3 install openai"でインストール

import os
import openai
openai.api_key = "ご自身のAPIキー"

#引数を基に画像を生成し、そのURLのリストを返す
def Get_Image_URL(English_Summary):
    # 戻り値を複数返すためのリストの箱を作る
    URL_List = []
    # リストの中身をリセット
    URL_List.clear()
    # 生成する画像の数を指定
    Number_of_Images = 2

    dalle = openai.Image.create(
        #promptに、画像を生成するキーワードを入れる。
        prompt=English_Summary,
        n=Number_of_Images,
        size="1024x1024"
    )
    #画像のURL生成した画像の枚数分
    for i in range(Number_of_Images):
        # dalleAPIからの結果を取得（辞書型）
        IMG_URL_Dict = dalle["data"][i].values()
        # 辞書型からリスト型へ変換
        IMG_URL_List = list(IMG_URL_Dict)
        # 変換したURLの中身を、URL_Listに追加
        URL_List.append(IMG_URL_List[0])

    return URL_List

#画像を生成するキーワードをtranslation_resultsに入れる。
translation_results="今日はとても幸せな気分です。"

#translation_resultsを引数にして、英訳した要約を基に、画像生成のURLを取得する。
result_urls = Get_Image_URL(translation_results)
print(result_urls)
```

```:出力結果
['https://oaidalleapiprodscus.blob.core.windows.net/private/org-b04fDiF1M7SyzWhEfy5pBFhj/user-TgC89wwC9hwu05oNpVHtsNgc/img-EobSx0odM3g0Z64bdK6xGWxl.png?st=2022-12-27T04%3A21%3A16Z&se=2022-12-27T06%3A21%3A16Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-12-27T03%3A19%3A35Z&ske=2022-12-28T03%3A19%3A35Z&sks=b&skv=2021-08-06&sig=V7qK7auw5EhuoOjkIh2jkIkerXf6OMdYEbPCfTWTtjk%3D', 'https://oaidalleapiprodscus.blob.core.windows.net/private/org-b04fDiF1M7SyzWhEfy5pBFhj/user-TgC89wwC9hwu05oNpVHtsNgc/img-pi5D2k01hanPIz5zZ0bS6s8Q.png?st=2022-12-27T04%3A21%3A16Z&se=2022-12-27T06%3A21%3A16Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-12-27T03%3A19%3A35Z&ske=2022-12-28T03%3A19%3A35Z&sks=b&skv=2021-08-06&sig=JbW6jvu4a5lXsWXEnTjWvy51WQdfxFogwKvR4dz7oco%3D']
```

これで、URLのみのリストを取得できました。

このリストの内容をtemplateに送れるようにすることで、生成した画像の一覧を表示するWEBサービスを作ることができます。

リストの内容をtemplateに表示させる方法は以下のサイトで解説されているので、よろしければごらん下さい！

[Djangoテンプレートでできるforループの全て]([https://itc.tokyo/django/django-for/](https://itc.tokyo/django/django-for/)  "Djangoテンプレートでできるforループの全て")

またDALL·E 2 APIのAPIキーを取得する方法については、以下の動画がとても分かりやすかったです！

[How to use DALL·E 2 API in Python](https://www.youtube.com/watch?v=S7tOW-xkhjY "How to use DALL·E 2 API in Python - AI Photo Generation for Beginners")

# 最後に

DALL·E 2 APIで、結果のURLだけのリストを取得する方法が見つかりにかったため、出来るようになるまでにまあまあ時間がかかりました。
なので、これが皆さんの参考になれば幸いです！

最後までお読みいただき、ありがとうございました！
ファインチューニング（感情分析）したLUKEを公開しました（たった２ステップで完結！LUKEでの感情分析）

こんにちにゃんです。
水色桜（みずいろさくら）です。
今回はLUKEをファインチューニングして、Hugging Faceにアップしたので、そのモデルのデモの様子などについて書いていこうと思います。
作成したモデルは[こちらのサイト（Hugging Face）](https://huggingface.co/Mizuiro-sakura/Luke_finetuned_sentiment_analysis)にアップしてあります。
コピペして使えるコード（ディレクトリ名は適宜変更してください）も添えてあるのでぜひ使ってみてください。
本記事を使えば、環境構築（pythonなどのインストール）を除けば、**たった2ステップ**でLUKEで感情分析が行えるようになります。

# 環境
torch 1.12.1
transformers 4.24.0
Python 3.9.13
sentencepiece 0.1.97


__transformersのバージョンが古すぎるとMLukeTokenizerが入ってないので注意してください。__

# LUKE

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2847349/251b4d44-ab82-ecc9-e85e-81f3827db713.png)

2020年4月当時、5つのタスクで世界最高精度を達成した新しい言語モデル。
日本語バージョンのLUKEは執筆現在（2022年12月）も4つのタスクで最高スコアを有しています。RoBERTaを元として構成され、entity-aware self-attentionという独自のメカニズムを用いています。LUKEに関して詳しくは下記記事をご覧ください。

https://qiita.com/Mizuiro__sakura/items/9ccbd655501e78df5cc6

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2847349/cff01f3a-bc09-c16c-a84a-55b62161c01d.png)

# モデルの作成方法

東京工業大学、乾・鈴木研究室の公開している[日本語評価極性辞書](http://www.cl.ecei.tohoku.ac.jp/Open_Resources-Japanese_Sentiment_Polarity_Dictionary.html)を用いて、夏目漱石さんの文章（こころ、三四郎、ぼっちゃん、etc）に対してポジティブ・ネガティブのタグ付けを行い、教師データとしました。この教師データをもとに、下記記事と同様の方法でファインチューニングを行い、モデルを作成しました。詳しくは下記の拙著をご覧ください。（分類数を48から2に減らしただけです）

https://qiita.com/Mizuiro__sakura/items/785e0769d47f25d11bc3

# モデルのデモ（たった2ステップで完結！）
**追記：短い文章においても精度が高くなるようにモデルを改訂しました（2022年12月27日17時30分）**

**ステップ１**
[このサイト(Hugging Face)](https://huggingface.co/Mizuiro-sakura/Luke_finetuned_sentiment_analysis)から、My_luke_model_pn.pthをダウンロードし、任意のディレクトリにおいてください。
**ステップ２**
その後下記のコードをコピペして、modelを置いたディレクトリを入力してください。あとは実行すれば、感情分析が行えます。

<details><summary>model_exe.py</summary>

```python: model_exe.py
import torch
from transformers import MLukeTokenizer
from torch import nn 

tokenizer = MLukeTokenizer.from_pretrained('studio-ousia/luke-japanese-base-lite')
# この部分を変更してください（modelを置いた場所）
model = torch.load('C:\\[modelのあるディレクトリ]\\My_luke_model_pn.pth')

text=input()
# トークン化します
encoded_dict = tokenizer.encode_plus(
                        text,                     
                        return_attention_mask = True,   # Attention maksの作成
                        return_tensors = 'pt',     #  Pytorch tensorsで返す
                )

pre = model(encoded_dict['input_ids'], token_type_ids=None, attention_mask=encoded_dict['attention_mask'])
SOFTMAX=nn.Softmax(dim=0)
num=SOFTMAX(pre.logits[0])
if num[1]>0.5:
    print(str(num[1]))
    print('ポジティブ')
else:
    print(str(num[1]))
    print('ネガティブ')
```

</details>

```ruby:モデル実行の様子
今日はいろいろな乗り物に乗れて楽しかった
tensor(0.9881, grad_fn=<SelectBackward0>)
ポジティブ
今日は雨が降ってどこにも出かけられなくて最悪だった
tensor(0.0776, grad_fn=<SelectBackward0>)
ネガティブ
```

# 終わりに

世界最高精度を達成したことで今話題のLUKEですが、とっつきづらいと感じている方も多いのではないでしょうか？
そこで、今回は**たった2ステップ**で感情分析を行えるようにしてみました。
（個人作成のため企業さんが公開しているモデルほど精度は高くなく、申し訳ないです（スーパーコンピュータが欲しい…>_<））
これを機に、ぜひLUKEを触ってみてください。
素晴らしい技術なので、もっと多くの方にLUKEを知ってほしいと切に願っています。
では、ばいにゃん～。

# 参考
著者である山田先生には感謝いたします

https://arxiv.org/abs/2010.01057
PL-900：Power Appsの関数の利用

この投稿はMicrosoft PL-900の受験に向けた勉強資料をMS Learnページを参考にして作っています。
一発合格に向けて頑張りましょう！

※　今回は日本語のタイトルを変えてみました。
[Power Appsでの関数の開始方法][MS-Learn]

[MS-Learn]: https://learn.microsoft.com/ja-jp/training/modules/build-app-solution/4-get-started-functions-power-apps

## Power Appsの関数の利用
Power Appsの関数の中で一部を紹介する
* フィルター (Filter)
    * データソースから返ってきた行を指定した特定の日付範囲、設定値、ユーザーなどで絞り込む機能
    * ギャラリーやテーブルのデータでよく使われている
* 一致(Match)
    * 値が特定のパターンに従っているかどうか確認できる
    * この関数が適用されている箇所でメールアドレスを入力する場合、メールアドレスの形式が間違っているなど、問題がある場合、警告を表示することができる
    * 条件フォーマットに適している
* Distinct
    * データのリストから一意の値を返す機能
    * 有効な値のみドロップダウンに表示するなどで使える
* Math関数
    * Sum, Average, Atan, Sinなど、さまざまな計算式が用意されている

詳細な情報は以下をご参照ください

[Power Appsの関数一覧について][MS-Learn1]

[MS-Learn1]: https://learn.microsoft.com/ja-jp/power-platform/power-fx/formula-reference#s

[式の使用の詳細について][MS-Learn2]

[MS-Learn2]: https://learn.microsoft.com/ja-jp/training/paths/use-basic-formulas-powerapps-canvas-app/
これだけは知っておきたいLinuxコマンド(超基礎編)

# コマンドとは何か？

コマンドとは、コンピュータに対する命令のことです。
ブラウザのアイコンとかをクリックすると、ブラウザが起動しますが、
あれも内部的にはコンピュータに対してブラウザを起動させる命令となっています。

コマンドも基本的にはそれと同様ですが、
命令を行う場所が、GUI(グラフィカルな部分。普段見ている画面)から
CUI(コマンドライン、ターミナルなどの黒い画面)に変わるようなイメージです。

コマンドを実行するには、terminalというアプリが必要ですが、
普段GUIで作業していたことなどは、実はCUIのterminalからでも
行うことができます。

そうした、様々な命令を行うものがコマンドで、
コマンドには色々種類があるという感じです。

# lsコマンド

まず、1つ目に紹介するコマンドは、
おそらく一番使う機会が多いであろう、
lsコマンドです。

カレントディレクトリ内のファイルやディレクトリを表示します。
カレントディレクトリとは、ユーザが現在作業中のディレクトリのことを指します。

```
$ ls
Desktop          Downloads        Movies           Pictures         Public
Documents        Library          Music            Project          index.html
```

# pwdコマンド

カレントディレクトリの絶対パスを表示します。

```
$ pwd
/Users/user1
```

# cdコマンド

これもlsと同じぐらい使う機会が多いコマンドで、
change directoryの略でcdです。
ディレクトリを変更するという名称そのまんまで、
カレントディレクトリを変更したいときに使います。

```
$ pwd
/Users/user1/desktop
$ cd
$ pwd
/Users/user1
$ cd /Users/user1/Downloads
$ pwd
/Users/user1/Downloads
```

# sourceコマンド

引数に与えられたファイルに書かれたコマンドを現在のシェルで実行するコマンドです。
.zshrcなど、シェルの設定ファイルをターミナルを再起動させずに適用したいときや、
シェルスクリプトを実行したいときなどに使います。

```:test.sh
#!/bin/bash
echo 'testシェルスクリプトです'
```
```
$ ls
test.sh
$ source test.sh
testシェルスクリプトです
```

# cpコマンド

こちらはコピーコマンドです。
ファイルやディレクトリをコピーできます。

```
$ ls
test.sh
$ cp test.sh test1.sh
$ ls
test.sh test1.sh
```

# mkdirコマンド

ディレクトリを作成するコマンドです。

```
$ ls
test.sh
$ mkdir test
$ ls
test.sh test
```

# rmコマンド

ファイルやディレクトリを削除するコマンドです。

```
$ ls
test.sh test
$ rm test.sh
$ ls
test
```

# touchコマンド

ファイルのタイムスタンプを更新するコマンドなのですが、
引数で指定したファイルが存在しない場合、その空ファイルを作成するという副次効果が
あるので、その用途で使われることが多いです。(というか私はその用途以外で使ったことがありません。)

```
$ ls
test
$ touch test.sh
$ ls
test test.sh
```

# catコマンド

ファイルの内容を表示するコマンドです。
vimとかでいちいち開くのが面倒なときに、
サクッと中身を確認したいときとかに使います。

```
$ ls
test.sh
$ cat test.sh
#!/bin/bash
echo 'testシェルスクリプトです'
```

ちなみにcatは、パイプやリダイレクトといったシェルの機能をフル活用して、
catエディタみたいな使い方をしている方もいるそうです。

お使いのエディタはなんですか？って聞かれたら、
一度でいいからcatですって答えたいですね。

# grepコマンド

grepは、独学のときに使うことがなく、
実務に入ってから使うようになるコマンドの筆頭ともいえるもので、
簡単に言うと、ファイルやテキストなどの検索をするコマンドです。

grepは奥が深いので、
ここでは概要しか紹介しませんが、
気になる人は、grepの詳細解説の記事も御覧ください。

下記は、binという文字列をtest.shファイルから検索しています。

```
$ ls
test.sh
$ grep 'bin' test.sh
#!/bin/bash
```

実務でよく使うパターンとしては、
メソッドや関数がどのへんで呼ばれているか目星をつけたりする際に
使用されることが多い気がします。

例えば下記は、srcディレクトリ配下のすべてを検索対象として、
fetchApiFuncという文字列を検索します。

```
$ grep 'fetchApiFunc' src/*
```

これ以外にもよく使うコマンドをあげてみる

本記事では、代表的なコマンドと、
使い方の例を掲載したが、
各コマンドには、オプションも存在するため、
それらも合わせて知っておく必要がある。
(覚えることが多いですね)

加えて、まだまだ重要なコマンドは、
残っていて、ぱっと思いつく限りでも、

- ping
- dig
- curl
- mv
- less
- chmod
- which

などがある。

コマンドってたくさんあるなー
【データ基盤構築/BigQuery】少数点付きの数値の計算をする時は、NUMERIC型に変換してから計算しないと誤差が出てしまう

# 今回の課題
BigQueryにて、離脱率や直帰率などの○○率数値の計算する際に、
INT64やFLOAT型のまま割り算をすると、正確の数値が出なかった。

理由は、BigQueryで**少数点以下が発生する数値**の計算をする際は、
NUMERIC型に変換して計算をしなければ、誤差が発生してしまうためだった。
(詳しくは、[NUMERICの不思議](https://queuery.com/docs/bigquery-data-types-numeric/#numeric-%E3%81%AE%E4%B8%8D%E6%80%9D%E8%AD%B0)参照)

## 解決策
少数点が発生する数値をNUMERICに変換したうえで、計算を行った。
これで正確な数値を算出できる。
```SQL
select
    cast(exits as numeric) / cast(pageviews as numeric) as exits_rates -- 離脱数÷PV数=離脱率
    , cast(bounces as numeric) / cast(pagevies as numeric) as bounces_rates -- 直帰数÷PV数=直帰率
from
    `テーブル名`
```
また、〇〇率数値におかしな数値が無いか、ざっと確認しておくと尚良い。
シンプルに、0〜100％の間の数値になっているか確認するのでも良い。

例えば、下記のクエリでデータが抽出されない（COUNTの結果が０になる）ことを確認するなど行う。
```SQL
with master as (
    select
        cast(exits as numeric) / cast(pageviews as numeric) as exits_rates-- 離脱数÷PV数=離脱率
        , cast(bounces as numeric) / cast(pagevies as numeric) as bounces_rates -- 直帰数÷PV数=直帰率
    from
        `テーブル名`
)
select
    count(*)
from
    master
where
    1=1
    and exits_rates < 0
    and exits_rates > 100
    and bounces_rates < 0
    and bounces_rates > 100
```

**【参考】**
・[(SQLite)Select句で計算をした場合に少数にする方法](https://3ryupg.hatenablog.com/entry/2018/03/09/200000)
・[[SQL]割合を計算するときの定石(割られる数をCASTする)](http://kei0310.info/?p=381)
・[NUMERICの不思議](https://queuery.com/docs/bigquery-data-types-numeric/#numeric-%E3%81%AE%E4%B8%8D%E6%80%9D%E8%AD%B0)
チケット管理の改善Tips その弐

こんちは。
新幹線の中で食べる一番好きな食べ物はカツサンドの[とよしー](https://twitter.com/_toyo_sea_)です。

昨日、[チケット管理の改善Tips その壱](https://qiita.com/toyosea/items/f417bc2d37fc2b9c92f1)を紹介しました。
今日はTipsのその弐を紹介したいと思います。

## 背景
自チームでもっているチケットは、改善要望/バグなど比較的軽微なものが多いです。
そのため、新入社員のオンボーディングのタスクとしてピックしたり、協力していただいているパートナーさんにアサインするケースが多い状況です。
その状況でどうなったかというと、
「手頃なタスクをください」
「手が空いたのでタスクがあればください」
という非同期的な依頼が頻発するようになりました。
そこで、それらの依頼に応えるように自チームのメンバーの1人がタスクの斡旋をしていたというわけです。

加えて、自チームのメンバーがタスクの斡旋をするとしても、
チケット一覧で着手可能かどうかの判別がつきづらかったため、斡旋に時間的なコストがかかっていたこともありました。
自チームのメンバーは本来進めていくべき開発作業も持っていたので、なかなか作業に集中しにくい環境になっていたと思います。

## 課題
- タスクの斡旋の非同期的な依頼が自チームに来るため開発作業に集中できない
- チケットが着手可能か判別がつきづらいためタスクを渡しにくい

## やったこと
タスクの状態を示す【Ready】【Not Ready】を定義しました。

【Ready】は完了条件が設定されていて着手可能であること
【Not Ready】は完了条件が設定されていない / 仕様の確認が必要 / デザイナーの作業が必要 / CSの確認が必要... など準備が整っていない状態であること
を意味しています。

この【Ready】【Not Ready】のprefixをチケットのタイトルの冒頭につける運用にしました。

> 例： 【Ready】 〇〇のCSVをアップロードしようとするとエラーメッセージが出てアップロードできない


ちなみに既存のチケットに関しては、棚卸しのタイミングで【Ready】か【Not Ready】かをまとめて精査しました。
新規で起票されるチケットに関してもテンプレートに【Not Ready】を付与しておくことで、状態がわからないタスクを作らせない運用にしました。


## 結果
- 依頼人がチケット一覧をみて着手可能かまだ着手すべきでないかの状態が分かるようになりました
- そのため、タスクが欲しい人が自主的にピックするようになったため、斡旋業をする時間がほぼなくなりました

## まとめ
今回はチケットが着手可能かどうかを示す点について紹介しました。

その弐のTipsをまとめながら気づいたことなのですが、
組織の中にいる人たちが自律的に動くためには、対象のものを「どういう状態であるのか」と定義することは結構大事なことなのではないかと思いました。
飽くまで経験則ではありますが、逆のケースで考えてみると「これはいまどういう状態なのかわからない」ものって、なんとなく忌避したり、後回しになりやすい。
となると、「どういう状態であるのか」をマメに定義することは、透明性をあげることにつながるのではないか...。

今後、課題とぶち当たったときに「状態を示すことで改善されるか」はひとつの思考のツールとして持っておこうと思います。

それではまた。
Google Cloud 認定試験のトラブル対処法

## GCP認定試験で困ったこと
先日、GCPの認定試験の遠隔監視オンライン試験を申し込んだ。色々と困ったことがあり、ググったのだが日本語での情報量が少なかったので、他に困った人が出てきた時のために備忘として残しておくこととする。

## DevOps Engineer等のProfessional資格を受験する場合
Security Engineer, Solution Architect, Developper, Google Workspace Administrator, Data Engineer以外のProfessional資格は、2022年12月の現時点では日本語では受験できない。

## 英語で受験する場合
日本語用のアカウントとは別に英語用のアカウントを作成する必要がある。

英語用アカウント作成はこちら

https://webassessor.com/googlecloud

日本語用アカウント作成はこちら

https://webassessor.com/googlecloudjp

## KRYTERIONのアカウント名を間違えた場合
氏名の登録が誤っているとそもそも試験の受験ができない。特に英語の場合、ヘボン式かどうかで氏名の表記が揺れており、アカウント登録時の氏名と身分証明書の表記が一致しないために受験できないという話を見聞きする。
KRYTERION上でパッと変更できれば良いのだが、氏名の箇所はグレーアウトされて、ロックされているために簡単に情報の変更ができないのである。それはKRYTERIONの管轄ではなく、Google Cloudなどの各テストスポンサーの管轄であるためである。
変更が必要な場合は、以下のリンクより3点の情報を添えて、登録情報の変更依頼を出す。

- Legal First Name
- Legal Last Name
- Registered email address

https://support.google.com/a/contact/certification?hl=en

https://support.google.com/cloud-certification/answer/9907450

## 遠隔試験する場合
AWS認定試験と比較すると、テストセンターでのオンサイト試験も遠隔試験もスケジュールが全然空いてないので注意が必要。2、3週間前には余裕を持って、申し込みする必要がある。ただし、遠隔試験の場合は直前の数時間から数日前は急にスケジュールが空くことがあるので、そこを狙うのもあり。

受験する部屋を綺麗にしておく必要がある。物が何もない状態である必要があり、机の上もデスクトップとマウスのみにすること。置き物も禁止。

## Secure Browserが起動しない場合
英語でググると情報が多い。Macの人は「System Preferences」から「Siri」関連のサービスの停止、「Users & Groups」からログインユーザーの「Login items」の設定を外し、起動時にアプリケーションが不用意に立ち上がらないようにした上で、Macの再起動を行う。そのほか、Lockdown Browser OEM（Secure Browser）が起動する際の警告メッセージを確認し、「Activity Monitor」で一つひとつ対象のデーモンを停止していく。karabinerを使ってる場合も止める必要がある。基本的に常駐アプリも全て止めないとSecure Browserは起動しない。

## 試験が開始しない場合
試験開始前の身分証明書、試験環境の確認時点でローディングバーがクルクル回り続けて、1時間程度待ったが、何も進展はなかった。その日の試験は諦めた。KRYTERIONのスケジュール済みの試験のステータスを確認したところ、SUSPENDになっていたため、サポートに問い合わせたところ、リスケができた。試験開始時に問題がある場合は、下記のリンクより、サポートに問い合わせるのが良い。

https://kryterion.force.com/support/s/contactsupport?language=en_US

https://www.kryterion.com/frequently-asked-questions/

## 備考
AWSやピアソンビューに慣れてしまっているせいなのか、Google Cloudが提携しているKRYTERIONが提供するテストサービスは分かりづらく感じる。Salesforceの試験もKRYTERIONが代行しているようなので、慣れている人は慣れているのかもしれない。上記に記載した通り、Google Cloud向けのKRYTERIONのアカウント名を変更したくてググっても、Salesforce向けの情報ばかりが出てくるので、解決策を探すのが簡単ではなかった。

AWSの3時間という長丁場は疲れる。AWSと比較して、GCPはプロフェッショナルレベルの資格も2時間で終わるのが良い。
PHPの定数のサンプルプログラム

PHPで定数のサンプルプログラムを実装しました。
全体のプログラムです

```html
<!-- 定数のWORKプログラム作成 -->
<!-- 新規作成 2022/12/27 -->
<!-- Program name work35a.php -->
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WORK35A</title>
  <style>
    .test1 {
      color:#F00;
      font-weight:bold;
    }
  </style>  
</head>
<body>
  <?php
      define('TEAM_NAME','really?Madrid');
      define('ADD',10);

      function echo_team($person){
        echo "<p>チーム名は<span class=test1>" . TEAM_NAME . "</span>です</p>";
        echo "<p>現在所属人数は" . $person . "人で、来月" . ($person + ADD) . "人になります。</p>";
      }

      echo_team(30);

  ?>
</body>
</html>
```

```PHP
<?php
      // チーム名を定義する。
      define('TEAM_NAME','really?Madrid');
      // 加わる人数を定義する
      define('ADD',10);

      // チームに関する関数 
      function echo_team($person){
        echo "<p>チーム名は<span class=test1>" . TEAM_NAME . "</span>です</p>";
        echo "<p>現在所属人数は" . $person . "人で、来月" . ($person + ADD) . "人になります。</p>";
      }
      // 関数の呼び出し
      echo_team(30);

  ?>
```

```PHP
define(変数名,変数の値);
```
で定義します。
Magento2 に韓国語をインストールする

読めないけど、デモをする必要があるため韓国語をインストールします。インストール方法の[Originalはこちら](https://github.com/mageplaza/magento-2-korean-language-pack)。

magentoがインストールしてあるパスに移って
```
composer require mageplaza/magento-2-korean-language-pack:dev-master mageplaza/module-smtp 
```

そのあとにIndex, Cacheを更新します。
```
php bin/magento setup:static-content:deploy -f ko_KR
php bin/magento indexer:reindex
php bin/magento cache:clean
php bin/magento cache:flush
```

終わったら、Magento Admin 画面より ```Store - Configuration - General ```を選択し、```Locale options - Locale```を変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56044/1075acd0-6eb7-e955-da13-eeee45c93419.png)

韓国語で表示されるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56044/92e3d3bc-0890-445e-8bf7-a9cd65583d37.png)
【Mysql】DELETE文とDROP文

# 【Mysql】DELETE文とDROP文

## 基本構文
### テーブル内のレコードの削除
```sql
DELETE FROM テーブル名;
```

### 特定のレコードの削除
```sql
DELETE FROM テーブル名 WHERE 条件式;
```
※条件式には「id = 0001」のような条件を記載します。


### テーブルごと削除
```sql
DROP TABLE テーブル名;
```
テストの区分と力の入れどころ

自分がWebアプリのサーバーエンジニアとして単体テスト・結合テストのコードを書くにあたって、そもそもの前提として「テストの区分」って自分の中でどんな認識だっけ？をアウトプットしておこうと思って記事化。

# 1. テストの区分
## ①単体テスト(ユニットテスト)
- 関数・メソッドについて、別の部品(クラス・関数・メソッド)の影響を受けることのないテストコードを記述してテストすること
    - テスト対象の内部に含まれる別の部品はモック化するなどして実際の実装の影響を受けないようにしてテストコードを書く。
    - テストケースは、「関数・メソッドのコメント」に基づく「ブラックボックステスト」を基本とし、「コメント」に載っていない詳細仕様の部分については、「ホワイトボックステスト」にする
    - その部品単体がちゃんと動いているかをチェックするだけであり、アプリが仕様通りか？について担保されるわけではない。
    - 内部で他の関数・メソッドをたくさん呼び出すようなものには向かない(別部品をモック化してテストOKだったとしても、そいつらの占める割合多いせいでテストの存在価値が低い)
    - アプリの実装によく使うようなライブラリの関数・メソッドに向く

## ②結合テスト(統合テスト)
- 部品同士を組み合わせ、想定している動作をしているかのテスト。「部品」同士の粒度は様々であり、この言葉がカバーする範囲は広く曖昧。
    - アプリ内に含まれる関数・メソッドのテストであれば、その中に含まれる小さな関数・メソッド群の影響も考慮(=モックを使わない)したものになるだろうし、その中でもAPIのテストであれば、DBとの連携(マスタデータ、ユーザーデータの状態も考慮)も考慮したものになるだろうし。
    - APIの実行方法をとっても、実際にクライアントアプリ側から叩いてのテストもあれば、APIを叩いたときの開始地点である関数・メソッドを直接実行してのテストもある。

## ③E2Eテスト
- 本番に近い状態でアプリを操作するテスト。ユーザー目線でのテスト
- 製品としての品質の担保をするための一番重要なテスト。


# 2. 各テストの力の入れ具合
それぞれの区分でどんだけテストすればいいんだよっていう話だが、過去の経験的に以下のような形になると思ってる。

※サーバーエンジニア/クライアントエンジニア/QAエンジニアのチームではっきりシステムがわかれているWebアプリ開発現場を想定


## ①E2Eテスト
※システム内部を知ってるサーバーエンジニアが担当するとどうしてもユーザー目線が損なわれることがあるので、基本的に第三者(QAエンジニアとか)が担当するのが妥当。

- 製品としての品質を担保するもっとも重要なテストであるため、手を抜くべきではない。
- 以下を確認する。
    1. アプリが仕様書通りであるか(状態に応じた画面構成、画面遷移)
       ※テストケースは「条件・期待結果」をわかりやすく記述して、関係各所(ディレクター・クライアントエンジニア・サーバーエンジニア)でレビューして認識に齟齬がないことまで確認しておく
        仕様書で語られてない部分は仕様書について責任を持つ人(だいたいディレクターじゃね)に仕様を確認する
    2. ユーザー体験として違和感がないか、親切であるか

## ②結合テスト
- API実行
    - サーバーチームが責任を持つシステムとして、想定してる仕様が満たせているか？をチェックできるので最も力をかけるべき。
    - 理想としてはすべての状態を考慮したテストケースがここにまとまっていれば、内部のロジックを変更しても、全体の動きとしての想定に食い違いがないかに気付ける。
    - 細かな状況は内部で呼ばれてる関数・メソッド単位でチェックしてもいいんじゃない？という意見も出やすいが、個人的には内部で呼んでいる関数・メソッドの仕様が変わったり削除されないという保証もなく、この状況でのテストってどこで担保されてんだよ・・・・ってなりがち
- その他関数・メソッド
    - 再利用されるような関数・メソッドは、その動作の信頼性を担保できるのでテストを実装する価値がある。
    - やろうと思ったらキリがないので、API実行レベルでのテストを実装した上で余裕があったらって感じ。
    - ・・・が、仕様変更やコードレビュー指摘で対象の関数・メソッド自体が不要になっちゃったり、大きく構造が変わった場合の再コーディングのコストや精神的ダメージがデカいため、そんなに力をかけるべきではない。もっともコスパ悪いのは「unexported, privateなサブルーチン」であり、テストコード実装してる現場は多くないんじゃないだろうか。

- サーバーxクライアントのつなぎこみ: 主要な動作くらいはちゃんと手動でクライアントアプリ経由でテストし、E2Eテストしてもらうレベルには仕上がってることを担保しておく。

## ③単体テスト
- ライブラリ
    - 便利関数系はモックを使う箇所が少ないだろうし、相性がいい。
    - 実際にアプリケーションコードで使っているものはちゃんとテストコードを書いておいた方がいい。特に外部ライブラリは、自分たちのアプリの要件を満たす動作をしているかという受け入れ検証の意味も込めて。



# 3. 結論
・・・・っていうか自分の認識では、結合テストと単体テストの違いって不純物が紛れているかどうかなだけだと気づいた
で、テストコードがんばって記述する価値があるのは、

```
API実行 >= ライブラリ > その他関数・メソッド(public) > > > > > > > > > その他関数・メソッド(private)
```

っていう認識。
Google検索結果のWebクローリング - ちゃちゃっと半自動化

# 伝えたいこと
Googleの検索結果からリンク先のURL文字列だけをちゃちゃっと抽出する方法です。
ブラウザの開発者ツールと`sessionStorage`を使います。

## 背景
いまだHTTPで動いている日本のWebサイトのURL(FQDNレベル)を収集したかった。
Google Dorksにて **intitle:"index of" inurl:http after:2010 inurl:jp**
このように検索した。１ページにおよそ検索結果が10サイトぐらい出てくる。
ここからURLを一つ一つ手動でコピペするのはかなりめんどくさい。
真っ先に考えることはAPIを使うことであるが、すぐには用意がなかった。
Seleniumなどブラウザ動作をエミュレートするプログラミングをしようと考えるが10分以内に終えたかった。
短期間にアクセスしすぎると、Google検索結果にてbot検知のGoogle reCAPTCHAが発動する懸念もある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646242/832f8be7-c4da-d82a-5c65-af5c2f0cfde4.png)

## 方法
ブラウザの開発者ツールにて少量のJavaScriptと'sessionStorage'で10分でURL 120個ぐらいを収集した。


%1. ブラウザの開発者ツールを開く（Safariの例）
%2. JavaScriptコンソールのタブに移動
%3. sessionStorageの初期化
```
sessionStorage.clear()
```
%4. sessionStorageに検索結果のURLリストを登録するために以下のJavaScriptをコンソールに入力して実行(Enter)
　　　(DOMのプロパティは今後Googleにて変更になる可能性があることに留意)

```
document.querySelectorAll("cite").forEach(
  function(currentValue,currentIndex) {
    sessionStorage.setItem(Number(location.href.match(/&start=(\d+)&/)[1])+currentIndex,currentValue.textContent);
  },
);
````
%5. 次のページボタンを手動で押す

%6. %4を再度実行

%7. %5と%6を繰り返す

%8. sessionStorageに登録したURLリストをJavaScriptコンソールにダンプ。200は適当に必要十分以上のバッファ値で、検索結果の総数より多い値を入力する。最下部"参考"のリンク先ではブラウザ開発者ツールの中でsessionStorageをテーブル表示する方法を紹介している。
```
var urls = []
for (let i = 0; i < 200; i++) {
  urls.push(sessionStorage.getItem(i));
}
console.log(urls);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646242/e342d675-34ce-e985-64ae-cb7d7a2548c4.png)

この方法ならGoogle reCAPTCHAが表示されても手動で突破すればよい。
reCAPTCHAの入力と次のページめくり、JavaScriptコンソールへの4の実行は手動である半自動オペレーション。

%9. JavaScriptコンソールから結果をConsole.txtにExport（Safariの場合、Array出力部分を右クリックし上から4番目の"Save Selected"を選択）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646242/cb196519-504f-6cce-9448-b6ee3cf6a986.png)

%10. 結果の加工
```
cat Console.txt | grep http | sed -e 's/ › /\//g' | cut -d" " -f2- | sort | uniq |  sed -e 's/"//g'
````

## まとめ
使い回すのであればPowerAutomateやSeleniumなどでクローリングの型化をするのが好ましいが
プログラミングの実行環境がすぐにインストールできない端末で即興でWeb Hackingをするには、
やはりブラウザ開発者ツールは便利！

## 参考
https://b-risk.jp/blog/2021/07/sessionstorage/#sessionStorage

以上です。ご一読ありがとうございました。
ご参考になれば幸いです。
PL-900：キャンバス アプリを構築する

この投稿はMicrosoft PL-900の受験に向けた勉強資料をMS Learnページを参考にして作っています。
一発合格に向けて頑張りましょう！

今回のセクションでは実習するのがメインとなっています。そのため、以下の参考ページのリンクからきれいにまとめている内容を基に各自でPower Appsを用いたアプリの構築ができると思いますのでご確認ください。


[キャンバス アプリを構築する][MS-Learn]

[MS-Learn]: https://learn.microsoft.com/ja-jp/training/modules/build-app-solution/3-build-canvas-app


* 基本的なPower Appsでの作成順はこちら
1\. Power Appsによって満たすことができる業務上のニーズを特定する
2\. Power Appsの必要なデータに接続する
3\. コントロール、ボタン、および使いやすいインターフェイスを使用してアプリを設計し、エンドユーザーがデータを操作して業務上のニーズを満たすことを可能にする
4\. アプリとテストの機能を保存して公開する
5\. 問題がなければ、アプリをエンド ユーザーと共有し、より優れた業務プロセスを提供する
VSCodeを用いた開発 コーディング統一 メモ

※メモです

# あらすじ

環境はVSCode + typescript + npm
なるべくVSCode側で通知を出してもらうことで開発ルールの統一をしたいし、ケアレスミスをなくしたい

## 何をなくしたいか

- タイポ
- 命名規則逸脱
- 好ましくない実装
- 実装があっているかという開発者の不安

## 拡張機能構成

- Code Spell Checker
- ESLint
- prettier

## 開発者に意識してもらうこと

- VSCodeの「問題」タブを定期的に気にしてもらう
- ESLintで出たエラーはまず公式ドキュメントを見てなぜダメかやどう直せばいいかを学んでいただく
- コミット前やプッシュ前にeslintコマンドを実施してもらう(あるいはCIで開発フローに組み込む)

## できなかったこと(調査中)

- ファイル名の命名規則チェック
PythonでDeePL APIの英訳結果を、文字列（str）型として受け取る方法

# 課題
DeePLのAPIを使って英訳し、その結果を使って他のAPIを呼び出そうとしていました。
しかしDeePLの英訳結果を文字列として受け取れてないことが原因で、以下のようなエラーが出てしまいました。
```python:エラーメッセージ
--> 179         raise TypeError(f'Object of type {o.__class__.__name__} '
    180                         f'is not JSON serializable')
    181 

TypeError: Object of type TextResult is not JSON serializable
```

DeePLの英訳結果を文字列として受け取るための方法を探すのに苦労したので、共有させていただきます。
またこれは、翻訳結果を文字列として受け取る際にも使える方法なので、参考にしていただけると幸いです。

# 結論
英訳結果に、「.text」メソッドを使用する

# 解決する前のコード
出力結果より、英訳の結果を入れたtranslation_resultsのタイプが、
```<class 'deepl.translator.TextResult'>```になっている事が分かります。

```python:解決する前のコード
# deepLの認証コードと設定
deepL_auth_key = "ご自身のAPIキー"
translator = deepl.Translator(deepL_auth_key)

#英訳するもののリストを用意
result =[ "私は今日も、元気です。","おはよう"] 

#リスト型からひとつずつ取得して、それぞれを英訳し、文字列型として取得する
for i in result:
    # EN-USに翻訳
    translation_results = translator.translate_text(
        i, target_lang="EN-US")
    print(translation_results)
    print("型のタイプは、")
    print(type(translation_results))
    print("-----------------")
```

```出力結果
I am fine today, too.
型のタイプは、
<class 'deepl.translator.TextResult'>
-----------------
Good morning.
型のタイプは、
<class 'deepl.translator.TextResult'>
-----------------
```

# 解決した後のコード
英訳の結果を入れたtranslation_resultsに.textを追加しました。
これにより、英訳した結果が```<class 'str'>```のように、文字列（str）型として受け取れています。

```python:解決した後のコード
# deepLの認証コードと設定
deepL_auth_key = "ご自身のAPIキー"
translator = deepl.Translator(deepL_auth_key)

#英訳するもののリストを用意
result =[ "私は今日も、元気です。","おはよう"] 

#リスト型からひとつずつ取得して、それぞれを英訳し、文字列型として取得する
for i in result:
    # EN-USに翻訳
    translation_results = translator.translate_text(
        i, target_lang="EN-US")
    print(translation_results.text)
    print("型のタイプは、")
    print(type(translation_results.text))
    print("-----------------")
```

```出力結果
I am fine today, too.
型のタイプは、
<class 'str'>
-----------------
Good morning.
型のタイプは、
<class 'str'>
-----------------
```

# 参考にしたサイト
[BeautifulSoupでスクレイピング。データをJsonに出力すると「TypeError: Object of type Tag is not JSON serializable」](https://awesome03.com/2021/01/05/beautifulsoup%E3%81%A7%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E3%80%82%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92json%E3%81%AB%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B%E3%81%A8%E3%80%8Ctyp/ "BeautifulSoupでスクレイピング。データをJsonに出力すると「TypeError: Object of type Tag is not JSON serializable」")

# 最後に
```TypeError: Object of type TextResult is not JSON serializable```
のエラーが出てしまった際には、「.textメソッドを使って、文字列として受け取れるようにしてみる」というのをお試し下さい！

最後までお読みいただき、ありがとうございました！
SOQLでカスタムオブジェクトのキープレフィックスと名前空間プレフィックス

AppExchange配下のカスタムオブジェクトも含めて一覧を作りたいって話があり、
調べた方法をメモとして残しておく。
もっと簡単な方法があるのかもしれないけど・・・。

```
SELECT MasterLabel, 
       KeyPrefix, 
       DeveloperName, 
       QualifiedApiName, 
       NamespacePrefix 
  FROM EntityDefinition 
 WHERE IsCustomSetting = false 
   and QualifiedApiName like '%__c' 
 Order by MasterLabel
```

EntityDefinitionの詳細は↓
https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/tooling_api_objects_entitydefinition.htm
Rubocopのバージョンアップ作業 2023

[Rubocopのバージョンアップ作業](https://qiita.com/drafts/e41bceece33e000e0b53)の改訂版です。

Rubocopは頻繁にルールが改定されれるため、バージョンアップの際には設定やソースコードを見直さなければなりません。

だいたい２週間に１回は行う作業なので、スムーズに作業できるよう手順を書き出しておきます。

Rubocopは、バージョン毎に新しいCop（Lintのルール）が追加されたりCopの名前が変わったりします。そのためバージョンアップ後には、大抵は設定やソースコードを見直さなければなりません。

[だいたい２週間に１回は行う作業](https://github.com/rubocop-hq/rubocop/releases)なので、スムーズに作業できるよう手順を書き出しておきます。

# 0. 事前準備

Rubocopのバージョンアップ前に以下を済ませましょう。

- ユニットテストが整備されていること
- 現バージョンの `rubocop` を実行して通ること
- gitツリー上に変更したファイルが無いこと（`git status` で確認できる）
- 適切なgitブランチがチェックアウトされていること（`git branch` で確認できる）

# 1. バージョンアップ

rubocop や関連ライブラリのバージョンを上げます。

```shell
# 例
bundle update rubocop rubocop-performance rubocop-rails
```

# 2. `rubocop --autocorrect`で自動修正

コードの問題点を修正します。

```shell
bundle exec rubocop --autocorrect spec/
```

`rubocop` には自動修正オプションが２種類あります。

- `rubocop --autocorrect`はスペースの使い方など比較的安全な修正のみを行います。
- `rubocop --autocorrect-all`はより野心的な修正を行います。

また、テストコードのみを自動修正するか、本体のコードまで自動修正してしまうかという、選択もあります。プロジェクトのテスト体制に応じて塩梅します。

# 3. 設定ファイルを修正する

以下のようなCop名が変更された事によるエラーが出ることがあるので、`.rubocop.yml`を修正します。

```
Error: The `Layout/FirstParameterIndentation` cop has been renamed to `Layout/IndentFirstArgument`.
```

# 4. `.rubocop_todo.yml` を再生成する

`rubocop --regenerate-todo` で再生成します。

```
bundle exec rubocop --regenerate-todo --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp
```

なお以下のオプションを使うと `git diff` が読みやすくなります：

- `--no-exclude-limit`: 問題のファイルが多くても全ファイル名が`.rubocop_todo.yml`に出力されます。
- `--no-offense-counts`: 問題点の出現数を出力しない
- `--no-auto-gen-timestamp`: 生成日時を出力しない

# 5. `rubocop` を実行する

問題点が見つからないことを確認します。

```
bundle exec rubocop # => 問題が指摘されない
```

問題点が見つかったら、修正します。

# 6. コードレビュー＆テスト

通常のコードレビュー・テストを行います。
Windows10で完全シャットダウン設定

# 概要

シャットダウンは『高速スタートアップ』と『完全シャットダウン』の2種類ある。

『高速スタートアップ』は起動が早い。
その理由は『起動時の状態を保持』しているから。
（要は完全に電源を切ってはいない）

『完全シャットダウン』は起動が遅い。
そのかわり、PCをクリーンな状態で起動できるメリットがある。

# やり方

## 1回だけ完全シャットダウン

Shift押しながらシャットダウン押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/49b3bf49-812e-e1a4-76b7-06c993cfa917.png)

## 常に完全シャットダウン設定

『高速スタートアップを有効にする』のチェック外す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/73811518-3449-2566-1c66-ac9a3bf6b5b8.png)

こんな感じで『高速スタートアップを有効にする』自体が表示されていない場合は…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1979b542-dff1-5629-988d-06dc8bce9c5f.png)

コマンドプロンプトを管理者権限で開いて下記コマンド
```bat
powercfg /h on
```

# bat化したい時は

https://qiita.com/waokitsune/items/04f36b76409edf8f56a8

# 蛇足



# 参考サイトさん

https://pcmanabu.com/complete-shutdown/

https://itojisan.xyz/trouble/12711/

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2364
【Unity】 Time.time / Time.deltaTime / Time.timeScale 違い

# はじめに
Time関係の変数を使う時にいつも何を使えば良いのか混乱するのでまとめておきました。

# それぞれの意味
Time.time：
__ゲーム開始時__ から __現在までの経過時間__（秒）を表す。
プレイ時間を表す時に使う。

Time.deltaTime：
__前回のフレーム__ からの __経過時間__（秒）を表す。

Time.timeScale:
現実世界とUnity内の時間があるとすると、__Unity内の時間経過__ 表す。
初期値=１であり、1の時に現実世界の時間と等しい。
0=止まる　0.5=1/2倍速　2=2倍速

# 的した場面(一例)
Time.time：
長い時間を計測したい場合
ゲーム開始時からの経過時間を取得したい場合

Time.deltaTime：
処理を時間単位で行いたい場合
一時停止をしたい場合
短めの時間を計測したい場合(Time.timeでも良いがdeltaTimeの方が記述が簡単)

Time.timeScale:
スローモーションにしたい場合
クイックモーションにしたい場合