OmniAICreator/Qiita-1.07M huggingface dataset:
ABC220Dを解いた

筆者はAtCoderのレート600弱の茶色コーダ

[AtCoder Problems](https://kenkoooo.com/atcoder/)に以下の問題をおすすめされたので解いてみる。

https://atcoder.jp/contests/abc220/tasks/abc220_d

# 実装

難しく考えすぎて、解説をみてしまったが、
それぞれの操作した結果を使って配るDPするだけでいいようだ

```python
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

class ModInt:
    def __init__(self, x, mod = 998244353):
        self.mod = mod
        self.x = x.x if isinstance(x, ModInt) else x % self.mod
    __str__ = lambda self:str(self.x)
    __repr__ = __str__
    __int__ = lambda self: self.x
    __index__ = __int__
    __add__ = lambda self, other: ModInt(self.x + ModInt(other).x)
    __sub__ = lambda self, other: ModInt(self.x - ModInt(other).x)
    __mul__ = lambda self, other: ModInt(self.x * ModInt(other).x)
    __pow__ = lambda self, other: ModInt(pow(self.x, ModInt(other).x, self.mod))
    __truediv__ = lambda self, other: ModInt(self.x * pow(ModInt(other).x, self.mod - 2, self.mod))
    __floordiv__ = lambda self, other: ModInt(self.x // ModInt(other).x)
    __lt__ = lambda self, other: self.x < ModInt(other).x
    __gt__ = lambda self, other: self.x > ModInt(other).x
    __le__ = lambda self, other: self.x <= ModInt(other).x
    __ge__ = lambda self, other: self.x >= ModInt(other).x
    __eq__ = lambda self, other: self.x == ModInt(other).x
    __ne__ = lambda self, other: self.x!= ModInt(other).x

class mint(ModInt):
    pass

def main():
    N = rI()
    A = rLI()
    
    dp = [[mint(0)] * (10) for _ in range(N)]
    
    dp[0][A[0]] += 1
    
    for i in range(1,N):
        for j in range(10):
            a = A[i]
            dp[i][(j+a)%10] += dp[i-1][j] # F
            dp[i][(j*a)%10] += dp[i-1][j] # G
    for k in range(10):
        print(dp[N-1][k])
if __name__ == '__main__':
    main()

```

# まとめ

ABC220Dを解いた。実装には各操作に対して配るDPを実行した。

# 感想

単純の式の演算をするのだから配るDPをすれば良いという発想はなかなか出なかった。
DP頑張りたいと思ってる身でこのような問題がすぐに解けないのはさらなる精進が必要なようだ。
AsciiDocで書いてVivliostyleで組版する

2025/02/12 追記

Vivliostyle CLIで[VFM以外のunified Processorを使用できるように拡張](https://github.com/vivliostyle/vivliostyle-cli/pull/526)されたため、現在ではそちらを利用したほうがシームレスに行えます。

https://github.com/u1f992/asciidoc-parse-as-hast


<details>
<summary>過去の情報</summary>

ある程度詳細を指定してHTMLを出力できるマークアップ言語であれば何でもVivliostyleによるCSS組版フローに組み込めます。一例として、AsciiDocで書いてVivliostyleで組版する手順を紹介します。

[AsciiDoctor](https://asciidoctor.org/)ではAsciiDocから直接PDFを出力することもできますが、HTMLを出力してVivliostyleを通せばさらに詳細な組版を行うこともできます。

```
> cmd /c ver
Microsoft Windows [Version 10.0.22631.3737]

> wsl tree .
.
├── Makefile
├── manuscript.adoc
├── manuscript.pdf
└── style.css

0 directories, 5 files
```

AsciiDocter、Vivliostyle CLIの他に、[watchdog](https://github.com/gorakhargosh/watchdog/)に付属するwatchmedoを使用しています。pipxでインストールしておくのがよいでしょう。

```Makefile:Makefile
MANUSCRIPT=manuscript
STYLESHEET=style.css

ifeq ($(OS),Windows_NT)
    ifeq ($(SHELL),/bin/sh)
        # MSYS2 make
        RM=rm -f
        BACKGROUND_PREVIEW=vivliostyle preview $(MANUSCRIPT).html &
	else
        # GnuWin32 make
        RM=del /Q
		# Press ctrl+c once (or twice), then y followed by enter to quit.
        BACKGROUND_PREVIEW=powershell -Command "Start-Process -FilePath vivliostyle.cmd -ArgumentList 'preview $(MANUSCRIPT).html' -NoNewWindow"
    endif
else
    RM=rm -f
    BACKGROUND_PREVIEW=vivliostyle preview $(MANUSCRIPT).html &
endif

.PHONY: all build-html build preview watch clean

all: build

$(MANUSCRIPT).html: $(MANUSCRIPT).adoc
	asciidoctor \
	    --verbose \
	    --attribute stylesheet=$(STYLESHEET) \
	    --attribute last-update-label! \
	    --attribute lang=ja \
	    $<

$(MANUSCRIPT).pdf: $(MANUSCRIPT).html
	vivliostyle build $< --output $@

build-html: $(MANUSCRIPT).html
build: $(MANUSCRIPT).pdf

preview: $(MANUSCRIPT).html
	$(BACKGROUND_PREVIEW)
	watchmedo shell-command \
	    --drop \
	    --patterns="*.adoc" \
	    --command="make build-html" \
	    .

clean:
	$(RM) $(MANUSCRIPT).html $(MANUSCRIPT).pdf
```

`make preview`を立ち上げておけば、おおもとのAsciiDocの変更に応じてVivliostyleのプレビューが更新されます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1550728/1dd93755-f19f-9fa8-fd9a-cf04a8fa71fb.gif)

GnuWin32 makeでのプレビューのバックグラウンド実行についてよい方法を知っていたら教えてください。

</details>
Linuxでtimezone変更


:::note warn
タイムゾーンを変更すると、ログファイルやスケジュールされたタスクに影響を与える可能性があるため、変更は慎重に行いましょう。
:::

## システムのタイムゾーン情報を表示
```shell
$ ls -l /etc/localtime
lrwxrwxrwx 1 root root 25 Mar  6  2023 /etc/localtime -> ../usr/share/zoneinfo/UTC

$ date
Wed Jul  3 06:57:54 UTC 2024
```
## 方法1: timedatectl コマンドを使用してタイムゾーンを変更する

```shell
$ sudo timedatectl set-timezone <タイムゾーン>
# 日本標準時 (JST) に変更する場合
$ sudo timedatectl set-timezone Asia/Tokyo
```

## 方法2: シンボリックリンクを上書きする
```shell
# JSTに変更
$ sudo ln -sf /usr/share/zoneinfo/Japan /etc/localtime

# 確認
$ ls -l /etc/localtime
lrwxrwxrwx 1 root root 25 Jul  3 15:59 /etc/localtime -> /usr/share/zoneinfo/Japan

$ date
2024年  7月  3日 水曜日 15:59:14 JST
```


## その他
### 現在のタイムゾーンやシステムクロックの状態を確認する
```shell
$ timedatectl
      Local time: Wed 2024-07-03 21:50:21 JST
  Universal time: Wed 2024-07-03 12:50:21 UTC
        RTC time: Wed 2024-07-03 12:50:22
       Time zone: Japan (JST, +0900)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a
```

:::note warn
cronを使っている場合、タイムゾーンを変更後にcronの再起動が必要.
```
$ sudo service crond restart
```
:::

## 参考

https://zenn.dev/mtmatma/articles/7d561577f1fc46

https://qiita.com/tkkrr/items/4a17b989e51392f2c649
Scala 3のQuote Types Patternsを使ってみる

# 概要

Scala 3では、コンパイル時の型情報を利用して柔軟で型安全なコードを書くための「[Quote Types Patterns](https://docs.scala-lang.org/scala3/guides/macros/quotes.html#quote-types-patterns)」が導入されました。
この記事では、この機能を使って型に基づいた分岐を行う方法を紹介します。

# サンプルコード

今回は、型に応じて異なるメッセージを返す関数を作成します。以下の2つのファイルを使用します：

### QuoteTypeTest.scala

このファイルでは、型に基づいてメッセージを返す`quoteTypeTest`関数を定義します。

```scala
import scala.quoted.{Expr, Quotes, Type}

object QuoteTypeTest {
  inline def quoteTypeTest[T]: String = ${ impl[T] }

  def impl[T: Type](using ctx: Quotes): Expr[String] = {
    import ctx.reflect._
    val typeRepr = TypeRepr.of[T]

    typeRepr.asType match
      case '[Int] => '{"整数型"}
      case '[List[a]] => '{"リスト型"}
  }
}
```

このコードでは、`impl`関数内で型`T`の情報を取得し、パターンマッチングを行います。`'[Int]`の場合には「整数型」、`'[List[a]]`の場合には「リスト型」を返します。

### Main.scala

このファイルでは、`QuoteTypeTest.quoteTypeTest`関数を呼び出し、その結果を表示します。

```scala
@main
def main(): Unit =
  println(QuoteTypeTest.quoteTypeTest[Int]) // 整数型
  println(QuoteTypeTest.quoteTypeTest[List[Boolean]]) // リスト型
```

このコードを実行すると、`quoteTypeTest[Int]`は「整数型」、`quoteTypeTest[List[Boolean]]`は「リスト型」と表示されます。

## まとめ

Scala 3のQuote Types Patternsを使うことで、型に基づいた柔軟で型安全なコードをコンパイル時に生成できます。
今回の例では、型に応じたメッセージを返す簡単な関数を作成しました。
raspiのpythonを3.8にする

importlib.metadata
が3.8から使えるということでraspiのバージョンを上げました。

3.7.3 -> 3.8

Raspberry Pi OS (Raspbian Buster)は、デフォルトでPython 3.8は提供されていない（？）
Python 3.8を手動でインストールする。

```
$ sudo apt update
$ sudo apt install -y \
    build-essential \
    libssl-dev \
    zlib1g-dev \
    libncurses5-dev \
    libncursesw5-dev \
    libreadline-dev \
    libsqlite3-dev \
    libgdbm-dev \
    libdb5.3-dev \
    libbz2-dev \
    libexpat1-dev \
    liblzma-dev \
    tk-dev \
    libffi-dev \
    libgdbm-compat-dev \
    wget


$ cd /usr/src
$ sudo wget https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz
$ sudo tar xzf Python-3.8.0.tgz

$ python3.8 --version
->
Python 3.8.0

めんどくさいのでシンボリックリンクを作成

$ sudo ln -sf /usr/local/bin/python3.8 /usr/bin/python
$ ls -l /usr/local/bin/python3.8 /usr/bin/python
lrwxrwxrwx 1 root root       24  7月  3 21:39 /usr/bin/python -> /usr/local/bin/python3.8
-rwxr-xr-x 1 root root 15283956  7月  3 20:43 /usr/local/bin/python3.8

$ python --version
Python 3.8.0

$ cd [ソースがある場所へ]
$ python -m venv .venv
$ source .venv/bin/activate

$ pip install gpiozero

->
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting gpiozero
  Using cached https://files.pythonhosted.org/packages/b3/b5/64b461f496134218886a18cbfa40def2b9b1c152c10c71efa992f07952e0/gpiozero-2.0-py3-none-any.whl
Collecting colorzero (from gpiozero)
  Using cached https://files.pythonhosted.org/packages/7e/a6/ddd0f130e44a7593ac6c55aa93f6e256d2270fd88e9d1b64ab7f22ab8fde/colorzero-2.0-py2.py3-none-any.whl
Requirement already satisfied: setuptools in /home/pi/.venv/lib/python3.7/site-packages (from colorzero->gpiozero) (40.8.0)
Installing collected packages: colorzero, gpiozero
Successfully installed colorzero-2.0 gpiozero-2.0
```

成功
Rubyでデザインパターン (6) Prototypeパターン

## この記事は何
デザインパターンについて、Rubyでどのような使い方ができるかをまとめた記事です。
デザインパターン自体の解説は詳しく行いません。

## Prototypeパターンとは
Prototypeパターンとは, オブジェクトを複製することで新しいインスタンスを生成するデザインパターンです。

詳しくはこちらをご覧ください。

https://qiita.com/shoheiyokoyama/items/61826e158b3c4a259065

## Rubyでのコード例
以下のように`module`を用いてインターフェースの定義を行なっていきます。

```rb
module Prototype
  def create_clone
    clone()
  end
end

class ConcreatePrototype1
  include Prototype

  def call
    "Prototype1"
  end
end

class ConcreatePrototype2
  include Prototype

  def call
    "Prototype2"
  end
end

class PrototypeManager
  def initialize
    @prototypes = {}
  end

  def register(key, instance)
    @prototypes[key] = instance
  end

  def get_clone(key)
    prototype = @prototypes[key]
    prototype && prototype.create_clone
  end
end

manager = PrototypeManager.new
manager.register(:prototype1, ConcreatePrototype1.new)
manager.register(:prototype2, ConcreatePrototype2.new)

prototype1 = manager.get_clone(:prototype1)
puts prototype1.call

prototype2 = manager.get_clone(:prototype2)
puts prototype2.call
```

```:実行結果
Prototype1
Prototype2
```

## どのような時に使えるか
Prototypeパターンはインスタンス生成のコストが大きいインスタンスを複数用意する場合などに有効なデザインパターンです。
以下のように最初のインスタンス生成に時間はかかりますが、Prototypeパターンを適用することではじめ以外のインスタンスの作成は高速化することが可能です。

```rb
module Prototype
  def create_clone
    clone()
  end
end

class HeavyInitializer
  include Prototype

  attr_accessor :name

  def initialize
    sleep(4)
    puts 'Initialized'
    @name = nil
  end
end

class PrototypeManager
  def initialize
    @prototypes = {}
  end

  def register(key, instance)
    @prototypes[key] = instance
  end

  def get_clone(key)
    prototype = @prototypes[key]
    prototype && prototype.create_clone
  end
end

manager = PrototypeManager.new
manager.register(:heavy_initializer, HeavyInitializer.new)

instances = []
10.times do |i|
  instance = manager.get_clone(:heavy_initializer)
  instance.name = "Name #{i}"
  instances << instance
end

puts instances.map(&:name)

```

```:実行結果
Initialized
Name 0
Name 1
Name 2
Name 3
Name 4
Name 5
Name 6
Name 7
Name 8
Name 9
```
git switch と git checkout って何が違うの？

# はじめに
こんにちは、H×Hのセンリツ大好きエンジニアです。（同担OKです😉）
「新しいブランチを作成し、現在のブランチを新しいブランチに切り替える」という動作を行いたい場合、`git checkout -b <new branch>`と`git switch -c <new branch>`があると思います。

。。。これってどう使い分ければいいの？って思ったので調べました🤔

# git checkoutとは
ブランチの切り替えもありますが、**ブランチの切り替え以外にも多くの用途があるコマンド**です。

1. ブランチの切り替え
```
git checkout <branch name>
```
2. コミットやタグの切り替え
```
git checkout <commit-hash> or <tag>
```
3. ファイルの復元
```
git checkout -- <file>
```

大体こんなもんかなと思います。
checkoutって言っても、何をするのか具体的な挙動って想像しにくいですよね😮‍💨

それと同じ話が挙がった故に、後述する`git switch`と作業ディレクトリの変更を元に戻すためのコマンドである`git restore`が誕生しました！

# git switch
`git switch`コマンドは、**ブランチの切り替えに特化したコマンド**です。
`git checkout`のブランチ切り替え機能を簡潔にしたものになります。

用途としては、先ほど冒頭で出したようなブランチの切り替えメインです。
1. ブランチの切り替え
```
git switch <branch name>
```

これのみです。🫣
出来ることがシンプルなので、分かりやすいですね！

# 使い分け
「ブランチの切り替え」を行う時にはもう`git switch`でいいんじゃないかなと思います！👍
その方が意図が分かりやすいので。

それ以外、例えば「特定のコミットの状態に戻す」や「ファイルを復元する」と言った処理では`git switch`は使えませんので、`git checkout`になるかな〜と。

ただ、状態を戻すという処理は`git restore`というコマンドで行えるので実際の所`git checkout`は多用すべきでは無い気がしています。

#### これからは、git switch と git restore を使おう！

# おわりに
普段何気なく使っていた両者の違いについて触れてみました。
`git checkout`のように、色々なことが出来てしまうとミスが起こりやすいので、なるべくは決められた動作しか出来ないものを使った方が安全ですね😎

最後までご覧いただきありがとうございました！
以上、センリツでした。🤓
本を安く買うコツ

# はじめに
私は、読書が好きです📚
ビジネス書、自己啓発本、エンジニア向けの技術書などなどなんでもござれです💡
ただ、本って結構お高いですよね・・・

ということで、**本を安く買うコツ**をご紹介します。

# 裁断本　を狙う
私の結論は、**裁断本**です！

こんな感じ

https://jp.mercari.com/search?keyword=Python%E3%80%80%E8%A3%81%E6%96%AD%E3%80%80%E3%83%99%E3%82%A4%E3%82%BA&status=sold_out%7Ctrading

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091004/96fc69a3-0b57-7269-a311-9956a6a6baf5.png)

引用元：メルカリ

この本は、Amazonだと定価3,080円ですが、2000円以下で出品されることが多く、お安く購入できますね！

# 裁断本の扱い方
## 穴あけ＆２穴リングファイル
こんなリングファイルを１つ購入します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091004/e1ef8a11-eb09-75d6-fc5a-4e1329608e4c.png)

引用元：https://amzn.asia/d/0iDB70Qm

あとは、パンチで本に２穴あければ、完成で✨

**分厚い技術書を　通勤時でも厳選して持ち運べるので、裁断済は意外と便利です！**



## スキャンして、PDFにして読む
これは、個人用のスキャナが手元にある方むけです。

※決して会社の業務用複合機でスキャンしてはいけません・・・
　裁断の状態が悪いと詰まって、最悪複合機を壊す可能性があります。
　本もびりびりになります👹

※メルカリで販売している方は、スキャンすると物は不要になるので、安く販売しているようです。


# 終わりに
今回は、メルカリ等のフリマサイトを使って、本を安く買うコツをご紹介しました。
裁断本の存在は意外と知られていません・・・。

ぜひ、お試しください💡
スライドデザインの超基礎【PowerPoint】

### このページについて
うちの会社の同僚・後輩が作るパワーポイントの資料がクソ過ぎるので，最低限守ってほしいことをまとめた．

理系脳だと，「必要な情報が揃っていればデザインなんて気にしなくてもOKでしょ」という考えに陥りがちですが，それではダメです．

"相手がよく考えて，その結果理解できる．"のでは良い資料とは言えないのです．

スライドデザインの優れている資料の方が，説明が伝わりやすいのです．

つまり，より短い時間で報告などを終えることが出来て効率的なのです．

### フォントの選択
フォントは読みやすさに影響します．
日本語では「游ゴシック」や「Meiryo UI」，英数字では「Segoe UI」や「Times New Roman」を選ぶのが良いです．

### 文字の色
赤・緑・青などの原色は強すぎるため避け、薄めた色を使いましょう．
（黄色とかシアン，マゼンタも主張が強いので避けた方がベター．）
基本の文字色は黒よりも少し薄い灰色が適しています。また、3色以内の配色を心掛けましょう．

### 配色の法則
「70:25:5の法則」を守りましょう．
背景色は70％程度、メインカラーは25％程度、特に強調したい箇所に使うアクセントカラーは5％程度の比率で使用するのがベター．

### スライドサイズ
特に理由がない限り，16:9で作成しましょう．

### 各ページの情報量
1ページに情報を詰め込み過ぎないようにしましょう．
あと，各ページで「タイトル」と「結論」を書くように心がけましょう．
「結論」はタイトルとイコールの関係になるようにしてください．

### 目次とページ数
目次とページ数の表示はプレゼンテーションの整理に役立ちます．

ロジカルな構成を確認するために目次を作成する習慣をつけましょう．

終わりの見えないプレゼンは地獄です．終わりの見えるプレゼンを心がけましょう．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3700895/d8be47ce-0fa2-b46f-a1e6-9c3348d48eaf.png)
https://www.tiktok.com/@reiwanotora/video/7251528937686273298


### 参考にさせてもらったページ
https://studio.virtual-planner.com/powerpoint-color/
250円で買えるコスパの良い要件定義の本

## 高コスパの本

250円で買えるコスパの良い要件定義の本があります。（※2024年7月3日現在）

[「要件定義って食べれるの？」](https://amzn.asia/d/0fEARKfN)です。

要件定義の本質が詰まっています。

この本の素晴らしいところ
* 図とイラストがわかりやすい
* 要件定義がなぜ難しいのか（Why）を平易に説明している
* その上で、どうすればいいか(How)を説明している
* 短くてすぐに読める
* 安い

この本を読んで、私は要件定義の解像度が上がりました。

## 1冊目は短い方がいい

何を学ぶときでも、1冊目の書籍はわかりやすいだけでなく、短い方が良いと考えます。

挫折を感じにくく、達成感を得やすいためです。

要件定義の分野では、書籍「要件定義って食べれるの？」が1冊目としておすすめできます。

要件定義を学ぶ方の参考になれば幸いです。
LeetCode挑戦日記：Day26

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 394. Decode String

エンコードされた文字列が与えられたとき、そのデコードされた文字列を返してください。

エンコード規則は次の通りです：`k[encoded_string]`。
ここで、角括弧の中の`encoded_string`が正確に`k`回繰り返されます。
`k`は正の整数であることが保証されています。

入力文字列は常に有効であると仮定してかまいません。
余分な空白文字はなく、角括弧も正しく形成されています。
また、元のデータに数字は含まれておらず、数字は繰り返し回数`k`のためだけに使用されます。
例えば、`3a`や`2[4]`のような入力はありません。

テストケースは、出力の長さが`10^5`を超えないように生成されます。

## 素直に解いてみる

### 考え方

1. `s`の先頭から1文字ずつ確認する
1. `'['`が来たときにそれまでの数字と文字列をstackに入れる
1. `']'`が来たときにstackから情報を取り出し、デコードする

### コーディング

```typescript
function decodeString(s: string): string {
    const stack: { k: number, prefixString: string }[] = [];

    let kString = '';
    let encodedString = '';

    for (let i = 0; i < s.length; i++) {
        const char = s.charAt(i);
        if (('0' <= char) && (char <= '9')) {
            kString += char;
        } else if (char === '[') {
            stack.push({ k: Number(kString), prefixString: encodedString });
            kString = '';
            encodedString = ''
        } else if (char === ']') {
            const record = stack.pop();
            let str = '';
            for (let j = 0; j < record.k; j++) {
                str += encodedString;
            }
            encodedString = record.prefixString + str;
        } else {
            encodedString += char;
        }
    }

    return encodedString;
};
```

### 結果

Runtime：54ms
Beats 74.58%

Memory：50.21MB
Beats 62.03%
DRY原則とは

# DRY原則
- 「DRY」とは「Don’t Repeat Yourself」の略
- 「ソフトウェア開発全体において情報を重複させない」という考え方
- DBスキーマ、テスト計画、ビルドシステム、ドキュメントなどが対象
- 「ソースコードは重複させない」と誤認されることが多いが、
それは「OAOO（Once And Only Once）原則」に近いものとなる

 # 参考記事
 - https://www.artima.com/articles/orthogonality-and-the-dry-principle
 - https://qiita.com/yatmsu/items/b4a84c4ae78fd67a364c
スクラムフェス大阪2024@栃木トラックに現地参加してきた！

2024年6月21日～22日の間開催されたスクラムフェス大阪2024に栃木トラックに現地参加してきました！  
参加した感想を残します。

◇目次
[参加した背景](#参加した背景)
[目的](#目的)
[聴いた講演](#聴いた講演)
[参加した感想](#参加した感想)
[最後に](#最後に)


<a id="参加した背景"></a>
#### ◇参加した背景  
・スクラムフェス栃木実行委員の方と一緒に会場探しを手伝ったため（元々9月の三河の会場探しを手伝ったことが始まり）
・チームメンバー、ステークホルダー、上司との関係性をもっとよくしたいと思ったため
・いろんな人と交流して、心の栄養補給をしたかったため

<a id="目的"></a>
#### ◇目的  
・自分のモチベーションアップの種を得る
・仕事への還元できる何かを得る（今年の業務に活かす）
・チームについての学びを得る

<a id="聴いた講演"></a>
#### ◇聴いた講演  
・[Minoru YOKOMICHI - Keynote: 「出世」を目指そう、 もとい、マネジングアップしよう](https://confengine.com/conferences/scrum-fest-osaka-2024/proposal/20204/keynote)  
・[Yasunobu Kawaguchi - (続き) サービス運用はボールを落とさない競技 : 2009年DevOpsDays の誕生と私の身の回りの話](https://confengine.com/conferences/scrum-fest-osaka-2024/proposal/20115/2009devopsdays)  
・[Taku Fujii - スプリントゴールで価値を駆動しよう](https://confengine.com/conferences/scrum-fest-osaka-2024/proposal/20109)  
・[Keisuke Wada - 感情知性を高めて、達人アジャイルコーチ・スクラムマスターになろう！](https://confengine.com/conferences/scrum-fest-osaka-2024/proposal/20060)  
・[Masafumi Takarada - 苦境からのManagement Transformation！アジャイルな組織になっていく道筋のひとつとしての「カオスインジェクション」の探求、そして（泥くさい）実践](https://confengine.com/conferences/scrum-fest-osaka-2024/proposal/19931/management-transformation)  

<a id="参加した感想"></a>
#### ◇参加した感想  
・1日目  
仕事中だったので、オンラインから参加しました。
タイムリーに、上司との関係性にすごく悩んでいたので、見直すいいきっかけになりました。
上司が忙しく、こちらからの積極的なコミュニケーションを怠ったいたことに気づかされました。
スクラムフェス大阪明けの月曜日に、さっそく上司に話しかけて、コミュニケーションをとってみました。
これからも、少しづつ関係性が良くなるように、自分から動いていこうと思います。
また、Managing UpのコースがUdemy(Business)にあったので、受講しています。（英語なので少しづつ・・・）

・2日目  
午前中のDevOpsDaysの話から、スプリントゴールで価値について考えることの重要性、思いやりのコーチング、苦境をエントロピーに組織改善をする話と、とても内容の濃い一日でした。
特に、スプリントゴールの設定は、所属しているスクラムチームでの、スプリントゴールの設定とスプリントレビューの微妙なアンマッチ感があるよねとPOと話していたので、とても勉強になりました。自分たちのスクラムチームも、使ったものの価値があるかどうかをスプリントレビューで、ステークホルダーと話したいんだというのを認識し、チームメンバーで共感できたのがとてもよかったです。  
思いやりのコーチングは、仕事の提案資料を作る際に、問題があり、こんなことができない、これを解決しないと、市場競争力がなくなるのような、煽る感じの提案をしてしまうことが多かったです。反省しなければと思いました。
目指したい姿を共有して、成長するにはどんなことを達成していけばいいか、を一緒に考えられるようにマインドセットを入れ替えます。（スクラムチームの仕事とは別件、）  

打ち上げの飲み会が楽しかったです！  
餃子づくしでした（笑）  
製造業あるあるが、意外とIT業界の人にとっては新鮮で面白いようで、酒の肴になってよかったです！

<a id="最後に"></a>
#### ◇最後に  
とても良い学びをたくさん得られました。上司との関係性やスクラムイベントの考え方の転換、思いやりのコーチングは、現在の自分の置かれている状況において、とても心に刺さる内容でした。  
まずは、1%のカイゼンができるように、働きかけていきたいと思います。

後日、製造業アジャイルの話を教えてもらって、お邪魔したら、**すじもん**の話で盛り上がっていました。  
すじもんのメタファーと日々の関係性のカイゼンで、上司とチームが気持ちよく仕事できるように頑張ります！
【備忘録】棒グラフに個別データを重ねるやつ （その２）：geom_bar + geom_point + geom_line

# はじめに
<!-- 発端や概要を記載 -->

[前回の続き](https://qiita.com/yshk_psy/items/b6458f95fd9a5ce40557)です。. . . って1年以上前かよ。



最近実験心理学系の論文で流行っている棒グラフに個別データを載せるやつ。
完成形はこんな感じ↓


![Rplot.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737734/0fbe35ce-424a-4585-8dca-8eb753dfab0b.jpeg)



<code>geom_bar</code>で棒グラフ, <code>geom_point</code>と<code>geom_line</code>で個人データを描きます。



# 目次
<!-- タイトルとアンカー名を編集 -->
1. [下準備](#下準備)
1. [平均と標準偏差を出す](#平均と標準偏差を出す)
1. [グラフを描画](#グラフを描画)
1. [終わりに](#終わりに)



<!-- 各チャプター -->
<a id="#下準備"></a>
# 下準備
今回使うデータです。
この<code>df</code>というデータは個人プロット (<code>geom_point</code>と<code>geom_line</code>) で使います。

```r
id <- rep(seq(1, 10, 1), 4)
A <- c(rep('a1', 20), rep('a2', 20))
B <- rep(c(rep('b1', 10), rep('b2', 10)), 2)

a1b1 <- c(rnorm(10, mean=5, sd=5))
a1b2 <- c(rnorm(10, mean=15, sd=5))
a2b1 <- c(rnorm(10, mean=10, sd=5))
a2b2 <- c(rnorm(10, mean=-10, sd=5))

df <- data.frame(id, A, B, Value  = c(a1b1, a1b2, a2b1, a2b2))


#データの出力
df
```

<a id="#平均と標準偏差を出す"></a>
# 平均と標準誤差を出す
今回使うデータの平均と標準誤差を出します。
この<code>SummaryData</code>というデータは棒グラフ (<code>geom_bar</code>) で使います。


```r
library(tidyverse)

SummaryData <- df %>% 
  group_by(A, B) %>%
  dplyr::summarise(mean_Value = mean(Value),
                   se_Value = sd(Value)/sqrt(n()))

#計算結果の出力
SummaryData 

```

<a id="#グラフを描画"></a>
# グラフを描画

棒グラフとエラーバーでは<code>data=SummaryData</code>, 個別プロットでは<code>data=df</code>という感じに描画に使用するデータを指定します。

```r
gColor=c("darkorange", "yellow")

ggplot() + 
  geom_bar(data = SummaryData, aes(x = B, y = mean_Value, fill = B), position = position_dodge(), stat = "identity", alpha = .3, 
           color = "black", size = 0.7) +
  geom_line(data = df, aes(x = B, y = Value, color = B, group = id), stat = "identity", alpha = .3, color = "grey40") +
  geom_point(data = df, aes(x = B, y = Value, color = B, group = id), shape = 1, stat = "identity", alpha = .3, color = "grey10") +
  geom_errorbar(data = SummaryData, aes(x = B, y = mean_Value, ymax = mean_Value + se_Value, ymin = mean_Value - se_Value), 
                width = 0.3, position = position_dodge(0.9), stat = "identity", color = "black") +
  scale_fill_manual(values = gColor) +
  facet_wrap(~ A) +
  coord_cartesian(ylim = c(-60, 60))

  
```



<a id="#終わりに"></a>
# 終わりに
論文で報告する時は注釈に

<b>「ラインプロットは個別値、エラーバーは標準誤差を表す」</b>

を忘れずに。
PHP/JavaScriptで相互に動作する暗号復号関数

## 概要
任意のパスワードと暗号化したいテキストのみでPHPとJavaScriptで相互に暗号←→復号できる関数を示します。

## PHP
```encrypt.php
function encrypt(string $plaintext, string $passphrase) :string
    {
        $cipher = "aes-256-cbc";
        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
        $key = hash('sha256', $passphrase, true);
        $encrypted = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
        $encrypted = base64_encode($iv . $encrypted);
        return $encrypted;
    }
```

```decrypt.php
    function resvDecrypt(string $encryptedText, string $passphrase) :string
    {
        $cipher = "aes-256-cbc";
        $key = hash('sha256', $passphrase, true);
        $ivLength = openssl_cipher_iv_length($cipher);
        $data = base64_decode($encryptedText);
        $iv = substr($data, 0, $ivLength);
        $encrypted = substr($data, $ivLength);

        $decrypted = openssl_decrypt($encrypted, $cipher, $key, OPENSSL_RAW_DATA, $iv);
        return $decrypted;
    }
```

## JavaScript
JavaScriptはcrypto-jsライブラリを使用します。

[crypto-js](https://github.com/brix/crypto-js)

```encrypt.js
import CryptoJS from 'crypto-js';

function encrypt(message, passphrase) {
    const key = CryptoJS.SHA256(passphrase);
    const iv = CryptoJS.lib.WordArray.random(16);
    const encrypted = CryptoJS.AES.encrypt(message, key, {
        iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    const encryptedMessage = iv.concat(encrypted.ciphertext).toString(CryptoJS.enc.Base64);
    return encryptedMessage;
}
```

```decrypt.js
import CryptoJS from 'crypto-js';

function decrypt(encryptedText, passphrase) {
    const encryptedBytes = CryptoJS.enc.Base64.parse(encryptedText);
    const iv = CryptoJS.lib.WordArray.create(encryptedBytes.words.slice(0, 4));
    const ciphertext = CryptoJS.lib.WordArray.create(encryptedBytes.words.slice(4));
    const key = CryptoJS.SHA256(passphrase);
    const decrypted = CryptoJS.AES.decrypt(
        { ciphertext },
        key,
        {
            iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }
    );

    return decrypted.toString(CryptoJS.enc.Utf8);
}
```
Intune Cloud PKI 失敗談（消せなくなる）

# はじめに
今回は、**失敗談** です。
同じことにならない様に注意してください。

Intune には、アドオン サービス というものがありますが、その中で Cloud PKI という機能の検証をしている中で、サポートリクエスト する羽目になりました。

**Intune アドオン については こちらで解説しています**

https://qiita.com/carol0226/items/6529a423573ed246305f

# 背景
Cloud PKI には、以下の２パターンの仕組みがあります。
① Intune が 証明機関 (CA) となり、**ルート証明書** と **発行元証明書** を発行する機能
　→　Entra ID の証明書認証などで利用可能
② 外部の証明機関 (CA) の下位 CA として、**発行元証明書** を発行する機能 (BYOCA と言う)
　→　RADIUS , VPN , Wifi の認証を行うためには、こちらが必要

上記の CA から発行された証明書があれば、どちらも、Intune の機能を使って、SCEP 証明書 を発行することが出来るようになります。

SCEP 証明書 というのは、クライアントが Intune から SCEP証明書プロファイルを受け取ったあと、証明書要求 (CSR) を 証明機関 (この場合は Cloud PKI) に対して発行し、それをもとに、動的に クライアント証明書をデバイスに発行する仕組みです。

# 注意すべき点
以下の公開情報に **既知の問題** として、最大６つの CA を作成できますと説明されており、
さらに、以下の注意書きがあります。

:::note alert
管理センターには、Intune テナントから **CA を削除または無効にする方法はありません。**
これらのアクションの提供に積極的に取り組んでいます。
利用可能になるまでは、CA を削除する Intune サポート要求を行うことをお勧めします。
:::

**公開情報：既知の問題と制限事項**
https://learn.microsoft.com/ja-jp/mem/intune/protect/microsoft-cloud-pki-overview#known-issues-and-limitations

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/aed2d2ce-412c-48f4-674c-92521fd86f42.png)

# ハマった点
もう、上記の注意点を見ただけで、書かなくても判ると思いますが、上限まで CA を作ってしまい、それを消せなくなりました。

CA を作成してしまうと、それを編集する事も出来ないため、作成に失敗すると ゴミ になってしまいます。

一応、言い訳すると、① の 仕組みは 正常に機能させることができました。
１回目に失敗して、２回目に作成成功。なお ルート CA と 発行元 CA で ２つ消費します。

そのあと、私は WiFi の認証で使いたかったので ② の BYOCA の作成に取り組みました。
そこで、うまく成功させることができず、残り３つ分の枠を消費してしまい、それ以上 検証することができなくなりました。

# 不要な CA 削除までの流れ
サポートに問い合わせたところ、CA の削除は 海外の部署で対応をするため、５営業日ほど掛かるとのことでした。基本的には、「Cloud PKI の CA を消したいです」と言えば、提示すべき情報や手順を示していただけます。

**参考：削除依頼時に提示すべき情報**
削除のためには、削除する CA がある テナント から サポートリクエストの起票が必須です。
そして、テナント名 (xxx.onmicrosoft.com) もテキストで明記します。

これは、誤って 他人の CA を消したり、他者が悪意で サポートリクエストを起票し 他社テナントの CA を削除してしまうようなことを抑止する目的もあるのだと思います。

さらに、ポータルを 英語モード に切替えた上で、以下のような画面キャプチャを提出する必要があります。

**CA の一覧画面**
消したい CA を 以下のように明示する必要アリ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/2a20bb7a-bb22-fae0-b6e7-ceaaf7bcd2ee.png)

**CA ごとの詳細画面**
さらに、CA ごとに 詳細ページ も提示する必要があります。
赤線部に、CA ごとのユニークな ID が表示されているので、それを必ず含める。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/8f29d915-c9d0-af2c-7e1a-1dcb1f0cdd24.png)

これで、削除申告を行う事で、手続きに入って頂けます。
受付していただいてから、**５営業日** 程度 待つ必要があるとのことです。

Cloud PKI で 失敗を重ねたら こういう待ち時間が発生するということを 前もって知っておいていただくと、計画的に対応いただけるかと思います。

それにしても、これ 早く GUI から削除できるようにして欲しいです。

# 結果報告
対応頂き、無事にキレイさっぱり消えました！
結果的には、想定通り 5 営業日目に連絡が来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/7db97e33-0b39-67ce-e9f1-81c285f993cf.png)

今週末に、Cloud PKI の検証を進めたいと思います。
Build mysql2 for Rails error: ld: library not found for -lzstd

Error:

```
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lzstd
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1
```

How to fix:

```bash
bundle config --local build.mysql2 "--with-opt-dir="$(brew --prefix zstd)" --with-ldflags=-L"$(brew --prefix zstd)"/lib"
sudo bundle install

```
reduce関数を使ってオブジェクト配列の中身をマージする

# 結論
```ts: マージ関数
const reduceSameProducts = (Orders: Order[]) => {
  return Orders.reduce<Order[]>((acc, currentOrder) => {
    // ここはマージする条件
    if (acc[acc.length-1] &&
        acc[acc.length-1].name === currentOrder.name
    ) {
      // マージする処理
      const processedOrder: Order = {
        ...acc[acc.length-1],
        quantity: acc[acc.length-1].quantity + currentOrder.quantity,
      }
      return [processedOrder]
    } else {
      // マージ対象ではなかったらスキップ
      acc.push(currentOrder);
      return acc;
    }
  }, []);
}
```

# 解説
以下の`Order`データオブジェクトを想定します。
```ts:Order
type Order = {
  name: string;
  price: number;
  quantity: number;
}
```

そして以下のような`Order[]`があったとします。

```ts:Order[]
const orders: Order[] = [
  { name: 'トマト', price: 100, quantity: 1 },
  { name: 'トマト', price: 100, quantity: 2 },
  { name: 'マンゴー', price: 200, quantity: 1 },
  { name: 'イチゴ', price: 250, quantity: 3 }
];
```
トマトが被っていますね。
これを以下のようにマージしたい。
```ts:マージ
[
  { name: 'トマト', price: 100, quantity: 3 },
  { name: 'マンゴー', price: 200, quantity: 1 },
  { name: 'イチゴ', price: 250, quantity: 3 }
];
```
トマトの個数をまとめました。
しかしこれをまとめるのが意外と難しい。
現在の要素と一つ前の要素を比較してゴニョゴニョする必要がありそうです。
`reduce` が使えそうです。

最初の要素は空配列にします。

```ts:最初
type Order = {
  name: string;     // 商品名
  price: number;    // 値段
  quantity: number; // 個数
}

const orders: Order[] = [
  { name: 'トマト', price: 100, quantity: 1 },
  { name: 'トマト', price: 100, quantity: 2 },
  { name: 'マンゴー', price: 200, quantity: 1 },
  { name: 'イチゴ', price: 250, quantity: 3 }
];

const reduceSameProducts = (Orders: Order[]) => {
  return Orders.reduce<Order[]>((acc, currentOrder) => {}, []);
}
```

`acc` は `accumulator` です。前回の
```ts
(acc, currentOrder) => {}
```
の呼び出し結果です。
商品名が一致しているかどうかで処理を変更するので、そうでない場合は現在の値をそのまま結果に突っ込む必要があります。
ここで以下のように処理を書きます。

```ts:ステップ1
const reduceSameProducts = (Orders: Order[]) => {
  return Orders.reduce<Order[]>((acc, currentOrder) => {
    // ここはマージする条件
    if (acc[acc.length-1] &&
        acc[acc.length-1].name === currentOrder.name
    ) {
      
    } else {
      // マージ対象ではなかったらスキップ
      acc.push(currentOrder);
      return acc;
    }
  }, []);
}
```
`acc[acc.length-1]` は、1回目の時に `undefined`になるため、そこの条件分岐のために入れています。
`acc[acc.length-1].name === currentOrder.name` は一つ前の結果と比べるための条件です。
マージする条件は以下でも可です。
```ts
const existingOrder = acc.find(order => order.name === currentOrder.name);
```

そして実際のマージ処理です。
一つ前の結果（現在の値でもいいです）の処理しないプロパティを展開して、対象のプロパティを処理します。
```ts
const processedOrder: Order = {
    ...acc[acc.length-1],
    quantity: acc[acc.length-1].quantity + currentOrder.quantity,
  }
```

こうすることで、以下のように値が変わります。
```ts:結果
[{
  "name": "トマト",
  "price": 100,
  "quantity": 3
}, {
  "name": "マンゴー",
  "price": 200,
  "quantity": 1
}, {
  "name": "イチゴ",
  "price": 250,
  "quantity": 3
}] 
```

# おわりに
もっといいやり方があったら教えてください。
ITパスポート 企業統治と内部統制

・レピュテーションリスク
企業の評判が下がるリスク

・コーポレートガバナンス（企業統治）
企業経営が健全に行われているかどうかを、外部から監督・監視する仕組み

・コンプライアンス（法令遵守）
法律を遵守して企業活動を行うこと
法律以外にも各種ガイドラインや社内規則、社会通念、慣習、倫理、道徳なども含まれる

・内部統制
企業自らが、健全な企業活動を継続するための体制を整備・運用する仕組み
・モニタリング
内部統制が有効に機能していることを継続的に監視・評価する

・IT統制
情報システムを活用した内部統制
・業務処理統制
業務個別の情報システムにおける統制活動
・全般統制
それぞれの業務処理統制が有効に機能することを保証する統制活動

・職務分掌
業務における不正や誤りが発生するリスクを減らすために、仕事の役割分担や仕事の権限を明確にすること

・監査
企業経営や組織運営を行っていく上で発生する各種のリスクへの対策が、適切に整備・運用されているかを評価すること
企業内部の監査部門が行う内部監査と外部の第三者機関に依頼して行う外部監査に分類できる
会計監査、業務監査、情報セキュリティ監査、システム監査などがある

・会計監査人
会社の計算書類（貸借対照表や損益計算書など）を会計監査する
Flutterでじゃんけんを実装する(Step3:テストの実装)

## はじめに
前回の続きです。テストコードを実装していきます。
テストは開発の基本なので、ここら辺は手厚く実施していきたいです。
特にロジック周りは手厚めにやると、経験上吉です。

https://qiita.com/koji0705/items/57614dc08a809c96f861

## ソースコード
```dart:test/main_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_first_app/main.dart'; // アプリのエントリーポイントをインポート

void main() {
  testWidgets('じゃんけんゲームのテスト', (WidgetTester tester) async {
    // アプリをビルドしてテスト環境にアタッチ
    await tester.pumpWidget(MyApp());

    // グーのボタンを見つける
    final guButtonFinder = find.text('グー');
    final chokiButtonFinder = find.text('チョキ');
    final paButtonFinder = find.text('パー');

    // グーのボタンが存在するか確認
    expect(guButtonFinder, findsOneWidget);
    expect(chokiButtonFinder, findsOneWidget);
    expect(paButtonFinder, findsOneWidget);

    // グーのボタンをタップ
    await tester.tap(guButtonFinder);
    await tester.pump(); // ステートの変更を反映

    // コンピュータの手と結果が表示されるか確認
    expect(find.byType(Text), findsWidgets); // いくつかのTextウィジェットが存在するはず

    // コンピュータの手と結果を確認
    final computerChoiceFinder = find.textContaining('コンピュータの手:');
    final resultFinder = find.textContaining('結果:');
    expect(computerChoiceFinder, findsOneWidget);
    expect(resultFinder, findsOneWidget);

    // 他のボタンでも同様のテストを行う
    await tester.tap(chokiButtonFinder);
    await tester.pump();
    expect(computerChoiceFinder, findsOneWidget);
    expect(resultFinder, findsOneWidget);

    await tester.tap(paButtonFinder);
    await tester.pump();
    expect(computerChoiceFinder, findsOneWidget);
    expect(resultFinder, findsOneWidget);
  });
}
```

```dart:test/janken_game_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:my_first_app/game_logic.dart'; // パッケージ名を修正

void main() {
  group('JankenGame', () {
    JankenGame? game;

    setUp(() {
      game = JankenGame();
    });

    test('初期状態の確認', () {
      expect(game?.userChoice, '');
      expect(game?.computerChoice, '');
      expect(game?.result, '');
    });

    test('ユーザーがグーを選択した場合', () {
      game?.playGame('グー');

      expect(game?.userChoice, 'グー');
      expect(game?.choices, contains(game?.computerChoice));
      expect(['勝ち', '負け', '引き分け'], contains(game?.result));
    });

    test('ユーザーがチョキを選択した場合', () {
      game?.playGame('チョキ');

      expect(game?.userChoice, 'チョキ');
      expect(game?.choices, contains(game?.computerChoice));
      expect(['勝ち', '負け', '引き分け'], contains(game?.result));
    });

    test('ユーザーがパーを選択した場合', () {
      game?.playGame('パー');

      expect(game?.userChoice, 'パー');
      expect(game?.choices, contains(game?.computerChoice));
      expect(['勝ち', '負け', '引き分け'], contains(game?.result));
    });
  });
}
```
集中力こそ全てのパワー

* 集中力がある人はIQが高い人より長生きする
* 集中力がある人はIQが高い人より年収が高い傾向にある
* 集中力がある人はメンタル面も含め、病気になりにくい
* 集中力がある人は幸せ指数が高くなりやすい
Python＋openCVでクロマキー合成した動画を生成してみた

# はじめに
私事ですが、友人がYoutubeに動画投稿をしており、度々グリーンバックの動画と背景画像を送り付けてきて、「編集お願い!」と言ってきます。
まあまあな頻度なので勉強もかねてプログラムにしてみようと思いました。
内容が気になる方はリポジトリを下に載せておくので覗いてみてください。

Python + poetryの環境で開発を行ったので、git cloneしてきて`poetry install`を実行すればプログラムを動かせるはずです。

# 主な処理

```
def create_frame(input_frame):
    # コントラスト調整
    contrast_image = cv2.convertScaleAbs(input_frame, alpha=contrast_adjustment_value, beta=0)

    # クロマキー処理と二値化
    hsv_chroma_key_color = cv2.cvtColor(chroma_key_color, cv2.COLOR_BGR2HSV)
    lower_green = np.array([hsv_chroma_key_color[0][0][0] - chroma_key_threshold, 50, 50])
    upper_green = np.array([hsv_chroma_key_color[0][0][0] + chroma_key_threshold, 255, 255])
    hsv_image = cv2.cvtColor(contrast_image, cv2.COLOR_BGR2HSV)
    chroma_key_image = cv2.inRange(hsv_image, lower_green, upper_green)
    mask_image = cv2.bitwise_not(chroma_key_image)

    # ノイズ除去
    transparent_image = cv2.cvtColor(input_frame, cv2.COLOR_BGR2BGRA) # RGBA形式に変換
    transparent_image[:, :, 3] = mask_image # アルファチャンネルにマスク画像を設定
    
    # 背景画像に重ねる
    foreground = transparent_image[:, :, :3]
    alpha = transparent_image[:, :, 3:] / 255.0
    background = back.copy()

    output_frame = cv2.convertScaleAbs(background * (1 - alpha) + foreground * alpha)

    return output_frame
```
このプログラムの主となる、画像処理部分が上にあるコードです。
動画を1フレームずつ取ってきて、画像処理しています。

まず最初にコントラストを調整します。
画像処理は専門外なので、理由はよくわかっていませんが画像処理の精度をよくするためらしいです。

次に指定した色の箇所を白に、それ以外の箇所を黒にする二値化処理を行っています。
lower_greenやupper_greenは透過する色の閾値を決めています。
`mask_image`が二値化処理が済んだ画像になります。

次に`transparnet_image`=透過画像を作成します。BGR形式からアルファチャンネルを含むBGRA形式に変換して、アルファチャンネルにmask_imageを設定します。
これで、指定した色の箇所が透過されます。

最後に背景画像と合成して終了です。

ほとんどOpenCVが関数を用意してくれているので、そんなに時間をかけずにコードを書くことができました。

# サンプル

<iframe width="560" height="315" src="https://www.youtube.com/embed/UTfQh9h0MjY?si=l6vDJsKpNFS0PFGl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

やや縁が残っていますが、友人はこれくらいなら許容してくれます。

# リポジトリ

実行速度が遅いので、できるならば速くしたいと思っています。
良い方法があれば、プルリクやコメントしていただけると嬉しいです。

https://github.com/IamSBStakumi/Chroma_key_Movie_Creator
Flutterでじゃんけんアプリをつくる(Step2:ロジックを分離)

## はじめに
前回までの続きです。ロジックとUI部分が同一クラス内に記載されていたので、分離しました。

https://qiita.com/koji0705/items/ccb982312f9effc8a043

## 実装
```dart:lib/main.dart
import 'package:flutter/material.dart';
import 'package:my_first_app/game_logic.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: JankenApp(),
    );
  }
}

class JankenApp extends StatefulWidget {
  @override
  _JankenAppState createState() => _JankenAppState();
}

class _JankenAppState extends State<JankenApp> {
  JankenGame game = JankenGame();

  void _playGame(String choice) {
    setState(() {
      game.playGame(choice);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('じゃんけんゲーム'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'コンピュータの手: ${game.computerChoice}',
              style: TextStyle(fontSize: 20),
            ),
            Text(
              '結果: ${game.result}',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                ElevatedButton(
                  onPressed: () => _playGame('グー'),
                  child: Text('グー'),
                ),
                ElevatedButton(
                  onPressed: () => _playGame('チョキ'),
                  child: Text('チョキ'),
                ),
                ElevatedButton(
                  onPressed: () => _playGame('パー'),
                  child: Text('パー'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
```

```dart:lib/game_logic.dart
import 'dart:math';

class JankenGame {
  final List<String> choices = ['グー', 'チョキ', 'パー'];
  final Random random = Random();

  String userChoice = '';
  String computerChoice = '';
  String result = '';

  void playGame(String choice) {
    userChoice = choice;
    computerChoice = choices[random.nextInt(3)];

    if (userChoice == computerChoice) {
      result = '引き分け';
    } else if ((userChoice == 'グー' && computerChoice == 'チョキ') ||
        (userChoice == 'チョキ' && computerChoice == 'パー') ||
        (userChoice == 'パー' && computerChoice == 'グー')) {
      result = '勝ち';
    } else {
      result = '負け';
    }
  }
}

```
3D地図ツール　CESIUMをマスターする ver1

色々なものを開発するのに３つのSが必要と考えてます。

　　・シミュレーション (Simulation)：
　　　　現実の状況を仮想的に再現し、計画や戦略の有効性を検証すること。
　　・スケジュール (Schedule)：
　　　　効率的に時間を管理し、目標達成に向けた計画を立てること。
　　・シェルパ (Sherpa)：
　　　　ガイドやサポーターとして他人を助け、共に目標に向かって進むこと。

あらゆるモノづくりにおいてもです。
その中で最重要課題は物流（ロジスティック）と考えます。
物を運ぶのは、ほんの数メートル先に移動することから世界各国への運搬
長距離は運送会社や公共交通機関の仕事として地方を見ていて思うことは半径5Kmの物流と考えてました。

あるときものづくり仲間と話す機会があり話してみるとそれなら
国土交通省が進めるPLATEAUはどうかとアドバイスをもらいました。
PLATEAU Hack Challenge 2024 for ルーキーに参加して
なんとなく理解できました。
そこで3D地図ツールCESIUM.comをしり紹介されているサンプルを再現できれば良いかなと
思い学習を始めました。

学ぶうちにおおむねやるべきことを理解できたが
思ったように動かないので一度ここに簡単にまとめておく

## やりたいことの流れ

再現したこと自動運転バスのシュミレーションサイトを作る
下記のサイトを任意の場所で好きな車のアイコンを動かせるようにする

https://sandcastle.cesium.com/?src=Multi-part%20CZML.html&label=CZML

### ファイル構成
 記載しているJavaScriptを調べてみるとCZMLというファイルを作り
　アイコンはGLBファイルをCZMLファイル内で設定する

### CZMLファイル
使い方などのガイドはこちらを参照
https://github.com/AnalyticalGraphicsInc/czml-writer/wiki/CZML-Guide

どのような形が描画できるか、色の設定、表示位置など参考にするとよい

### glbファイル
glbファイルはCADやblenderでエクスポートして作ることができます。
今回iPhoneアプリ　３Dスナップを使って３Dスキャンを行いUSDZファイルを作り
変換サイト　https://products.groupdocs.app/ja/conversion/usdz-to-obj　に
ファイルをアップロードしてglbに変換するように設定してファイル化しました。

## 現状のつまづき

サンプルサイトを見てどのようにしたらよいか理解できましたが
URL付きのglbファイルだと認識しない
どうすればよいか対策中です。

## やりたいこと

現在のつまづきを対策してやりたいことを
書いておきます。

１．任意のglbファイルを描画できるようにする
２．経路線を簡単に描画できるようになるため
　　地図上でクリックした座標を取得し線描画のプログラムを行うこと
３．CZMLファイルを簡単に作れるツール
　　※ExcelRPAでつくる原型をブラッシュアップする
４．cesium.comで再現すること
５．unity上で描画
６．cesium.comとunityの連携

## 最後に

全体を見るには地図上で行うcesium.com
建物の中など詳細部分は緯度経度情報が無くても問題ないので
unity上で行う、そしてそれぞれ連携して流れを作る

今回現状見えてることをまとめてみました。
引き続き目標達成に向けて行っていきます。
【Xcode】Content Hugging PriorityとContent Compression Resistance Priority

毎回忘れるのでメモ

# Content Hugging Priority
- ハグ（抱きしめる・元のサイズからの大きくなりにくさ）の優先度
    - コンテンツを抱きしめて引き伸ばさないイメージ
- 値が大きいほど引き伸ばされない、値が低いほど引き伸ばされる
- UISwitchなど引き伸ばされたら明らかにおかしいものはDefaultで高くなっている

# Content Compression Resistance Priority
- Compression Resistance（圧縮抵抗）の優先度
- 値が大きいほどViewが元のサイズより小さくならない、値が小さいほど元のサイズより小さくなる
Flutterでじゃんけんアプリを作る

## はじめに
表題通り、Flutterでじゃんけんアプリを作成します。
初めてFlutterに触るような状態に近いので、hands-on的に少しづつ進めていきます！！

## 成果物
![じゃんけん.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/cb57e825-4d63-f90e-f899-71d3027e7b81.gif)


## ソースコード
```dart:main.dart
import 'package:flutter/material.dart';
import 'dart:math';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: JankenApp(),
    );
  }
}

class JankenApp extends StatefulWidget {
  @override
  _JankenAppState createState() => _JankenAppState();
}

class _JankenAppState extends State<JankenApp> {
  String _userChoice = '';
  String _computerChoice = '';
  String _result = '';

  void _playGame(String choice) {
    final choices = ['グー', 'チョキ', 'パー'];
    final random = Random();
    _userChoice = choice;
    _computerChoice = choices[random.nextInt(3)];

    if (_userChoice == _computerChoice) {
      _result = '引き分け';
    } else if ((_userChoice == 'グー' && _computerChoice == 'チョキ') ||
        (_userChoice == 'チョキ' && _computerChoice == 'パー') ||
        (_userChoice == 'パー' && _computerChoice == 'グー')) {
      _result = '勝ち';
    } else {
      _result = '負け';
    }

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('じゃんけんゲーム'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'コンピュータの手: $_computerChoice',
              style: TextStyle(fontSize: 20),
            ),
            Text(
              '結果: $_result',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                ElevatedButton(
                  onPressed: () => _playGame('グー'),
                  child: Text('グー'),
                ),
                ElevatedButton(
                  onPressed: () => _playGame('チョキ'),
                  child: Text('チョキ'),
                ),
                ElevatedButton(
                  onPressed: () => _playGame('パー'),
                  child: Text('パー'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

```
ITパスポート 標準化

・標準化
物やサービスなどにおいて共通の基準や規格を決めること

・デファクトスタンダード
市場のシェアなどによって広く使用されるようになり、その結果として事実上の業界標準になったもの
・フォーラム標準
業界団体（フォーラム）が策定する標準規格

・ISO
電気分野を除く、工業や技術に関する国際規格
ISO9000（品質マネジメントシステム）
ISO14000（環境マネジメントシステム）
ISO20000（ITサービスマネジメント）
ISO26000（組織の社会的責任）
ISO27000（情報セキュリティマネジメントシステム）
ISO38500（ITガバナンス）

・JIS
産業製品に関する国内規格

・IEEE
電気工学・電子工学に関する規格
IEEE802.3（有線LAN）
IEEE802.11（無線LAN）

・ITU
電気通信技術に関する規格
【Drupal】リリースしました。Views Pager Token

## はじめに
この度、DrupalCommunityにModuleProjectを公開してみました🎉🎉

https://www.drupal.org/project/views_pager_token

本記事では、モジュールの使用方法についてお話します。

## どんなモジュールなの？
ViewsのPagerの設定に関するモジュールです。

Pagerの表示件数設定って、`<input type="number" />`です。なので、文字を入れることってできないですよね。
そこの設定項目でToken入力を有効にするモジュールです。

「運用面で活躍すること間違いなし！」と思って開発しました。

## 出番は？
いまいちしっくりこないですかね。

運用していく中で、一覧の表示件数を「3件」→「5件」に変えたい。とかそういうことって比較的あると思います。
- おすすめ記事ブロックの表示件数を「増やしたい or 減らしたい」とか

運用のことを考えていただきたんです。
Viewsの設定等は Config として管理されるため、Git等でConfigを管理している場合、運用であまり解放しない設定箇所ですよね。（例外はありますが、開発中のみの解放って認識をしています）

※ 場合によっては、`Views UI`モジュールごと無効にする運用もありだとか。→ 確かに安全。

そこで活躍するのが、今回のモジュールです。**Token使えるので。**
``hook``だったり、ViewsのPluginを都度実装する必要がなくなりますよ 👌

## 導入はどうするの？
特別な依存ライブラリ等はありません。
慣れてる方はいつも通りインストールしてください。

1. ソースコードをプロジェクトにインストール
    ```shell-session
    composer require 'drupal/views_pager_token:^1.0'
    ```
2. アプリ内で有効化
    ```shell-session
    drush en views_pager_token
    ```

## 設定画面
ViewsのPager設定画面を開くと、「Display a specified number of items (Available Token)」という選択肢が出てきます。そちらを選択してください。

選択後、Option項目の設定画面を開くと、表示件数を指定できるように作っています。
ここで Token 使えます。

![スクリーンショット 2024-06-30 19.30.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/90881266-fcd6-c514-6f6d-be9ecb5804c3.png)

こんな感じ。

## まだ強みをお伝えできていないと思います...
Token機能を標準で搭載しているあのモジュールと相性抜群ですよね。

ConfigPages!!

私の一押しです。（ConfigPagesは、正直かなり使い込んでいます。機会があれば記事書きます）

![スクリーンショット 2024-07-02 13.43.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/711eb0e3-4a8f-dba6-c182-c1c68c71d035.png)

ConfigPagesを利用すると、簡単にこの5件って数字をTokenで拾えますよね。

## 今後の開発・メンテナンス
現在は、「表示件数を指定」のみTokenを対応させています。
「フルページャー」の「10, 20, 30, 50」等もTokenで設定できるように、開発を進めているところです。

## まとめ
気が向いたら使っていただければ幸いです。

また、気になる所があれば Issue の起票をいただければ大変ありがたいなと思います。
もちろん、本記事のコメントでも大歓迎です 🤲
セキュリティクイズ

T企業で働く皆さん、サイバーセキュリティの基礎知識はどれほど自信がありますか？
どれだけ最新の技術を駆使していても、基本を押さえていなければ大きなリスクにさらされます。

このクイズでは、日々の業務に必要不可欠な基本的なセキュリティ知識を再確認できます。
基本的なセキュリティに関する問題に挑戦して、あなたの知識を再確認しましょう。


# IT系の会社向けセキュリティクイズ

## 問題 1
**パスワードの管理方法として最も安全なのはどれですか？**
- A. 同じパスワードをすべてのサイトで使用する
- B. メモ帳に書き留める
- C. パスワードマネージャーを使用する
- D. 誕生日や名前をパスワードにする

<details><summary>正解と解説</summary>

**正解: C. パスワードマネージャーを使用する**
- **解説:** パスワードマネージャーは複雑で一意のパスワードを生成し、安全に保管するため、セキュリティを強化します。
</details>

## 問題 2
**フィッシングメールの特徴として最も適切なものはどれですか？**
- A. 常に信頼できる送信者から来る
- B. 緊急性を強調し、個人情報を要求する
- C. 添付ファイルが含まれていない
- D. 送信者のアドレスが正確である

<details><summary>正解と解説</summary>

**正解: B. 緊急性を強調し、個人情報を要求する**
- **解説:** フィッシングメールはしばしば緊急性を強調し、迅速な対応を促して個人情報を盗む手法を取ります。

</details>

## 問題 3
**二要素認証（2FA）の目的は何ですか？**
- A. パスワードを短くするため
- B. アカウントのセキュリティを強化するため
- C. アカウントを共有しやすくするため
- D. パスワードを覚えやすくするため

<details><summary>正解と解説</summary>

**正解: B. アカウントのセキュリティを強化するため**
- **解説:** 二要素認証は、パスワードに加えて追加の認証手段を要求することで、アカウントのセキュリティを強化します。

</details>

## 問題 4
**暗号化の主な目的は何ですか？**
- A. データの圧縮
- B. データの可読性を向上させる
- C. データの機密性を保護する
- D. データのバックアップを作成する

<details><summary>正解と解説</summary>

**正解: C. データの機密性を保護する**
- **解説:** 暗号化は、データを暗号化することで、未許可のアクセスから保護し、機密性を保ちます。

</details>

## 問題 5
**強力なパスワードの特徴はどれですか？**
- A. 8文字未満の長さ
- B. 単純な言葉やフレーズ
- C. 大文字、小文字、数字、記号を含む
- D. 短いが覚えやすい

<details><summary>正解と解説</summary>

**正解: C. 大文字、小文字、数字、記号を含む**
- **解説:** 強力なパスワードは、大文字、小文字、数字、記号を含むことで推測されにくくなります。

</details>

## 問題 6
**セキュリティパッチの適用が重要な理由は何ですか？**
- A. ソフトウェアのインターフェースを改善するため
- B. 新機能を追加するため
- C. 既知の脆弱性を修正するため
- D. ユーザーの使いやすさを向上させるため

<details><summary>正解と解説</summary>

**正解: C. 既知の脆弱性を修正するため**
- **解説:** セキュリティパッチは、既知の脆弱性を修正し、システムを保護するために重要です。

</details>

## 問題 7
**VPNの主な利点は何ですか？**
- A. インターネットの速度を向上させる
- B. IPアドレスを隠す
- C. ウイルスから保護する
- D. データを暗号化して安全に通信する

<details><summary>正解と解説</summary>

**正解: D. データを暗号化して安全に通信する**
- **解説:** VPNは、データを暗号化して安全に通信するため、セキュリティとプライバシーを保護します。

</details>

## 問題 8
**ソーシャルエンジニアリング攻撃の例として最も適切なものはどれですか？**
- A. ソフトウェアのバグを悪用する
- B. マルウェアをインストールする
- C. 人を騙して機密情報を提供させる
- D. ファイヤウォールを無効にする

<details><summary>正解と解説</summary>

**正解: C. 人を騙して機密情報を提供させる**
- **解説:** ソーシャルエンジニアリングは、人間の心理を悪用して機密情報を取得する攻撃手法です。
</details>

## 問題 9
**HTTPSプロトコルの利点は何ですか？**
- A. ウェブサイトの表示速度を向上させる
- B. データの信頼性を向上させる
- C. データの盗聴や改ざんを防ぐ
- D. ウェブサイトのデザインを改善する

<details><summary>正解と解説</summary>

**正解: C. データの盗聴や改ざんを防ぐ**
- **解説:** HTTPSは、データを暗号化して通信することで、盗聴や改ざんから保護します。
</details>

## 問題 10
**エンドポイントセキュリティとは何ですか？**
- A. サーバーのみを保護するセキュリティ
- B. ネットワーク全体を監視するセキュリティ
- C. 個々のデバイス（PC、スマートフォンなど）を保護するセキュリティ
- D. データベースを暗号化するセキュリティ

<details><summary>正解と解説</summary>

**正解: C. 個々のデバイス（PC、スマートフォンなど）を保護するセキュリティ**
- **解説:** エンドポイントセキュリティは、PCやスマートフォンなどの個々のデバイスを保護するためのセキュリティ対策です。
</details>
【Mac】Safariでショートカットキーを使用してページ翻訳する方法

## 設定方法

MacのSafariでショートカットキーを使用してページ翻訳するには以下の手順を実行します。

システム設定のキーボード > キーボードショートカットを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/3208222d-1572-e992-2738-cddbd913ff59.png)

アプリのショートカットを選択し、「+」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/5adce011-592a-aef4-bfed-cbf39f3b343c.png)

開いたウィンドウで以下のとおり入力（キーボードショートカットは任意のキー）し、「完了」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/92cc0c8b-c446-e721-d1e4-bebee6dbc198.png)

Safariのメニューバーで　表示 > 翻訳　を表示し、先ほど設定したショートカットキーが表示されていれば完了です。今回の設定では`⌘ + J`を押下するとページが日本語に翻訳されます。

![スクリーンショット 2024-07-03 20.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/fd9a42e8-df52-5a08-4844-25eff845bf9e.png)

## 参考

https://support.apple.com/ja-jp/guide/mac-help/mchlp2271/mac
【Glide Wiki】リリース記事まとめ

# はじめに
NoCodeアプリケーション開発サービス「Glide」解説記事一覧です。
無料プランで設定・実装可能な内容をまとめます。

:::note info
順次、記事公開予定です。
:::

# 記事一覧

## Columns
- [Image Column, Date & Time Column, URL Column ](https://qiita.com/riina_hoiz_nocode/items/7ade0ba08b8a69a66ad1)
- `近日公開` Text Column, Number Column, Boolean Column
- `近日公開` Row ID Column, Rich Text Column, Email Column, Phone Number Column


## Components
- `順次公開`

## Actions
- `順次公開`

# 執筆者紹介

https://qiita.com/riina_hoiz_nocode

https://qiita.com/riina_hoiz

- `順次追加予定`

# 参考
- Glide公式ページ：https://www.glideapps.com/
- Glide Docs：https://www.glideapps.com/docs