OmniAICreator/Qiita-1.07M huggingface dataset:
PowerShellでフォルダの中身のスクリーンショットを取得したい

エビデンスでフォルダの中身のキャプチャをうん百枚と取る必要があるので作りました。


## 目次
リンク|説明
:--|:--
[フォルダ構成](#フォルダ構成)|フォルダの構成。batファイルについては[こちら](https://qiita.com/sakekasunuts/items/d80ecae428866f9acdaa)
[実際のコード](#実際のコード)|前半部分は[ここ](https://qiita.com/sakekasunuts/items/ad5998edb61e3e9207bf)を見てね
[取得結果](#取得結果)|取得するとこんな感じになるよ


## フォルダ構成[↑](#目次)
フォルダ構成はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/f18dbc1a-c6da-2f4e-8250-1344a6705e4b.png)
target.txtにキャプチャ取得したいディレクトリが入ってる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/a9d0ece0-678f-7b4f-aa00-526fae6095cf.png)

## 実際のコード[↑](#目次)
日時・ログファイル定義 ～ スクリプト開始　の詳細は↓のページを見てね
[PowerShellのスクリプトテンプレート](https://qiita.com/sakekasunuts/items/ad5998edb61e3e9207bf)

#キャプチャ取得 から画面キャプチャ処理をしてるよ

```PowerShell:hoge.ps1
#実行前にディスプレイの比率を100％にすること。
#※倍率が高いとスクリーンショット取得時に画面が見切れてしまうことがある。

#==============日時・ログファイル定義==============
$Date = Get-Date -Format yyyy_MM_dd
$Time = Get-Date -Format HH_mm_ss
$Now = $Date + "_" + $Time
$Name_ps1 = [System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath)
$Log_Ps1 = "$PSScriptRoot\log\" + "$Name_ps1" + "_" + "$Now" + "_" + "$env:COMPUTERNAME" + "_"  + "$env:USERNAME" + ".log"

#==============スクリプト終了定義==============
Function Finish_Ps1{
    Write-Host (Get-Date -Format HH_mm_ss) "`t**********スクリプトを終了します**********"
    Stop-Transcript
    Exit
}

#==============スクリプト開始==============
Start-Transcript $Log_Ps1
Write-Host (Get-Date -Format HH_mm_ss) "`t**********スクリプトを開始します**********"
Write-Host ""

#==============キャプチャ取得==============
Write-Host (Get-Date -Format HH_mm_ss) "`t▼▼▼▼▼▼▼▼▼▼ScreenShot取得処理を開始します▼▼▼▼▼▼▼▼▼▼"
$Array_dir = Get-Content "$PSScriptRoot\target.txt"

foreach($i in $Array_dir){
    $i | ii
    Start-Sleep 2

    #画面定義
    [void][reflection.assembly]::loadwithpartialname("system.windows.forms")
    $MyScreenshot = [System.Windows.Forms.SystemInformation]::VirtualScreen
    $WID = $MyScreenshot.Width
    $HEI = $MyScreenshot.Height
    $LEFT = $MyScreenshot.Left
    $TOP = $MyScreenshot.Top

    #オブジェクト作成し、コピーする
    $MyBitmap = New-Object System.Drawing.Bitmap $WID, $HEI
    $MyDrawing = [System.Drawing.Graphics]::FromImage($MyBitmap)
    $MyDrawing.CopyFromScreen($LEFT, $TOP, 0, 0, $MyBitmap.Size)

    #bmpファイルを保存
    $MyFile = "$PSScriptRoot\log\" + (Get-Date -Format HH_mm_ss) + ".bmp"
    $MyBitmap.Save($MyFile)
}

Write-Host (Get-Date -Format HH_mm_ss) "`t▲▲▲▲▲▲▲▲▲▲ScreenShot取得処理を終了します▲▲▲▲▲▲▲▲▲▲"
Write-Host ""

#==============スクリプト終了==============
Finish_Ps1
```

## 取得結果[↑](#目次)
こんな感じでbmpファイルがlogフォルダにポコポコと取得される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/e3fb785b-45b8-3532-926c-cd7ec3fd0df3.png)
中身はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/68cfc5fb-c75e-5d91-1710-55a4b9204364.png)

####  参考にしたサイト[↑](#目次)
* [パワーシェル - スクリーンショットを撮る](https://techexpert.tips/ja/powershell-ja/%E3%83%91%E3%83%AF%E3%83%BC%E3%82%B7%E3%82%A7%E3%83%AB-%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%82%92%E6%92%AE%E3%82%8B/)
【初級】pythonを使ってみる

記載日：2022/11/13
Ubuntuでpythonを実行してみます。初心者用。


#### 目標（5分）
pythonプロジェクトを用意し、実行する。

#### 環境
OS : Ubuntu22.04
VSCodeインストール済。
pythonインストール済。
（私の環境ではpyenvをインストールしたので、python使える状況。）
※pyenvのインストール方法は[こちら](https://qiita.com/middle_aged_rookie_programmer/items/0eb574e92a52c923e7ec)

#### 作業
#### 0.プロジェクトフォルダ作成（1分）
プロジェクトフォルダを作る場所へ移動する。
例えば、デスクトップに作る場合、ターミナルを開いて以下コマンドを実行する。
”python-test”フォルダができる。
~~~command
cd ~/Desktop
mkdir python-test
~~~
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1381309/7c7bdabd-891e-dc6d-6efe-6d147c86ccf9.png" width=80%>

以降はVSCodeで作業する。以下コマンドでVSCodeを起動する。
~~~command
code .
~~~


#### １.プロジェクトファイル作成（1分）
プロジェクトフォルダ内にプロジェクトファイル（メインファイル）を作る。
VSCodeのNewFileボタンで”main.py”ファイルを作る。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1381309/a6c60d8c-b63a-69d1-28b9-257932a423c3.png" width=80%>


#### ２.コード記述（3分）
main.pyに以下コードを記述する。
main()：メイン関数。
if __name__=="__main__"：コマンドラインからのみ実行を許す。
~~~python
import datetime

def main():
    today=datetime.date.today()
    print(today, "Hello Python World!")

if __name__=="__main__":
    main()
~~~


#### ３.プロジェクト実行
ターミナルを開き、プロジェクトフォルダ内へ移動して、main.pyを実行する。
”[今日の年月日] Hello Python World!”と出力され、pythonを使えたことが分かる。
~~~command
cd ~/Desktop/python-test
python main.py
~~~
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1381309/78008d35-42dd-2e21-b8c1-51fb14d50ade.png" width=80%>


#### 参考にさせて頂いたサイト
・'if \_\_name\_\_=="\_\_main\_\_"'について詳しく知る。
https://note.nkmk.me/python-if-name-main/
Intersection Observer API(範囲の指定応用)

# Intersection Observer API(範囲の応用)
thresholdを書いているところに追加する。
種類は大きく分けて２種類
1.root:null
    →nullがデフォルト。細かく指定できる。％の
2.rootmargin:'0 0 0'
   →marginをつける時と同じようにして書く。

ex)
```Javascript
  const target = document.querySelector('img');

  function callback(entries) {
    console.log(entries[0]);

    if (!entries[0].isIntersecting) {
      return;
    }

    entries[0].target.classList.add('appear');
  }

  const options = {
    threshold: 1,
    rootMargin: '0px 0px -100px',
  };

  const observer = new IntersectionObserver(callback, options);

  observer.observe(target);
```
Vercelにデプロイ時のビルドエラー[ModuleNotFoundError: Module not found: Error: Can't resolve 'xxx' in '/vercel/path0/components']

## 内容

Next.jsプロジェクトをVercelにデプロイ時のビルドで、ModuleNotFoundエラーが発生したため、解決した手段を記述。
Next.jsプロジェクトをVercelにデプロイする手順の記事は[こちら](#https://qiita.com/tarian/items/dffaf2dc8c3b3e393e5f)にまとめています。

## 目次
- [エラー内容](#エラー内容)
- [エラー原因](#エラー原因)
- [解決手順](#解決手順)

## エラー内容

Vercelデプロイ時のエラー文
```plaintext
ModuleNotFoundError: Module not found: Error: Can't resolve 'xxx' in '/vercel/path0/components'
```
どうやらモジュールが見つからないらしいが、コードを見返してもファイルを参照する相対パスなどに誤りが見受けられない。

## エラー原因

[Vercelの公式サイト](#https://vercel.com/guides/how-do-i-resolve-a-module-not-found-error)によると、

> (概要のみ)
Vercelのデプロイメントでは大文字と小文字を区別するファイルシステムを使用している。
ローカルマシンでファイル名の大文字小文字を変更すると、Git はそれぞれの静的import文の変更だけを拾ってしまう可能性がある。

つまり、ローカルでファイル名を `component.tsx ⇒ Component.tsx`などに変更すると、Gitの設定によっては（というか多分デフォルトで）ファイル名の大文字小文字の変更が反映されない。
したがってVercelにデプロイするGitHubのリモートリポジトリでは、誤ったファイル名のままとなっているため、生じたエラーと考えられる。

## 解決手順

### 結論

リモートリポジトリの`pages/`, `components/` その他可能性のあるディレクトリを削除し、再push。
私の場合は最終的にはこの方法で解決に至りました。

### 手順１：プロジェクト全体をバックアップ

ファイル名の大文字小文字を変更した可能性のあるディレクトリをリモートリポジトリから削除するため、復元するためにプロジェクト全体のコピーを作成しバックアップ。

```bash
cp -r project/ project-back/
```

### 手順２：gitから削除し、push

```bash
git rm -r pages/
git rm -r components/
git push
```
これでローカルとリモートリポジトリから削除

### 手順３：バックアップファイルから削除したディレクトリをコピーし復元、再push

```bash
cp -r project-back/pages/ project/pages/
cp -r project-back/components/ project/components/
git add .
git commit -m "message"
git push
```

これで再push時に自動デプロイが走り、ビルドを無事passすることができました。

以上
Intersection Observer API(targetの情報)

# Intersection Observer API(targetの情報)
```Javascript
 const target = document.querySelector('img');

  function callback(entries) {
    console.log(entries[0]);
  }

  const options = {
    threshold: 0.2,
  };

  const observer = new IntersectionObserver(callback, options);

  observer.observe(target);
```
・functionの引数を設定することで情報を受け取ることができる。
・引数は配列扱いになり、con~()で配列のように受け取る。

【中身】
・intersectionRatioはrootが何%交差しているか。
・isIntersectingは交差しているか。真偽値

# 実践(rootに交差したらふわっと出てくる)
cssでは、、、
```Javascript
img {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .3s, transform .3s;
}

img.appear {
  opacity: 1;
  transform: translateY(0);
}
```

JSは上と一緒である。
次に、JSとCSSと関連付ける。

```Javascript
 const target = document.querySelector('img');

  function callback(entries) {
    console.log(entries[0]);

    if (!entries[0].isIntersecting) {
      return;
    }

    entries[0].target.classList.add('appear');

    // if (entries[0].isIntersecting) {
    //   entries[0].target.classList.add('appear');
    // } else {
    //   entries[0].target.classList.remove('appear');
    // }
  }

  const options = {
    threshold: 0.2,
  };

  const observer = new IntersectionObserver(callback, options);

  observer.observe(target);
```

・intersecting()は交差した時に、tureかfalseかを判断する。
・ifの上はtureの時、下はfalseの時。
・交差終わる時にはアニメーション取りたくない。
    if()のelseを消すか、!をつけてlfalseにする。
    falseだったらすぐにreturnする。→何もしないで返す。
Elixirのバイナリデータパターンマッチ

この記事は[「Elixir Advent Calendar 2022その1」](https://qiita.com/advent-calendar/2022/elixir)2日目の記事です．

## はじめに
本記事は以下のElixir特集のパターンマッチの章でページ数の関係上削られたので、こちらで供養します

https://www.amazon.co.jp/WEB-DB-PRESS-Vol-131-%E5%90%89%E5%B7%9D/dp/4297131110

　バイナリデータのパターンマッチについて紹介します。

## 基本的な使い方

　バイナリデータは、ビットストリングを表す`<<>>`記号の内側で、セグメントごとにパターンマッチを行うことができます。

```elixir
iex> a = "abc"
"abc"
iex> <<b, c, d>> = a
"abc"
iex> {b, c, d}
{97, 98, 99}
```

　`bits`や`binary-size`修飾子を使用して、残りすべてのビットや指定したビット数にマッチさせることができます。

```elixir
iex> a = "abc"
"abc"
iex> <<b, c::bits>> = a
"abc"
iex> b
97
iex> c
"bc"
```

```elixir
iex> a = "abcde"
"abcde"
iex> <<b::binary-size(2), c::binary-size(3)>> = a
"abcde"
iex> b
"ab"
iex> c
"cde
```

　範囲外をマッチさせようとするとマッチエラーになります。

```elixir
iex> a = "abcde"
"abcde"
iex> <<b::binary-size(2), c::binary-size(4)>> = a
** (MatchError) no match of right hand side value: "abcde"
```

## 実践的な使い方

　バイナリデータ画像のヘッダのバイナリから、画像形式を判別する関数を実装します。実行する前に、IExを実行するフォルダにPNG形式の画像を`image.png`として保存しておいてください。

```elixir
iex> defmodule WebDB.Binary do
...>   def mime(<<0x89, "PNG", _::bits>>), do: "png"
...>   def mime(<<"GIF", 0x38, _::bits>>), do: "gif"
...>   def mime(<<0xFF, 0xD8, _::bits>>), do: "jpg"
...>   def mime(_), do: "unsupported file"
...> end
{:module, WebDB.Binary, <<（省略）>>, {:mime, 1}}
iex> {:ok, file} = File.read("image.png")
iex> WebDB.Binary.mime(file)
"png"
iex> WebDB.Binary.mime(1)   
"unsupported file"
```

# 最後に
バイナリデータのパターンマッチマッチについていくつか例を紹介してきました
このパターンマッチはセンサーデータでも有用なのでいろいろ試してみてください

https://qiita.com/the_haigo/items/a941f769ed1e60e382eb#nmeagps-log-parser

バイナリデータ以外のパターンマッチはWebDBPressの方で記事になっていますので是非買って読んでみてください

https://www.amazon.co.jp/WEB-DB-PRESS-Vol-131-%E5%90%89%E5%B7%9D/dp/4297131110

本記事は以上になりますありがとうございました
Jupyter lab上でジョイスティックF710を使おう。

ポイントは、ビデオをダミーにします。
jetson nanoではバージョンによって入らない場合もあるかもしれない。
必要なライブラリをインストールしてバージョンを下げてトライします。
以上。

ビルドに必要なライブラリは依存関係でうまくインストールできない場合があります。

```bash
sudo apt update
```

依存関係を修正

```bash
sudo apt --fix-broken install
```

pygameに必要なライブラリをインストール

```bash
sudo apt install -y libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev
```

```bash
sudo apt install -y python3-dev python3-pip build-essential libffi-dev
```

pipアップグレード

```bash
/home/pi/env/bin/python3 -m pip install --upgrade pip
```

pygameインストール

```bash
pip3 install pygame
```

```python
import time         
import pygame
import os
from IPython.display import clear_output

#Displayをオフ
os.environ["SDL_VIDEODRIVER"] = "dummy"


pygame.init()
joy = pygame.joystick.Joystick(0)
joy.init()
time.sleep(0.5)

try:
    while True:
        leftStick = int( joy.get_axis(1)*-1023 )
        righSstick = int( joy.get_axis(3)*-1023 )
        button0 = joy.get_button(0)
        button1 = joy.get_button(1)
        button2 = joy.get_button(2)
        button3 = joy.get_button(3)
        pygame.event.pump()

        print("left=%d  right=%d"%(leftStick, righSstick))

        if button0 == 1:
            print("Button_A")
        elif button1 == 1:
            print("Button_B")
        elif button2 == 1:
            print("Button_X")
        elif button3 == 1:
            print("Button_Y")

        time.sleep(0.01)
        clear_output(True)

except( KeyboardInterrupt, SystemExit):
    print( "Ctr + D pushed. EXIT！" )
    
```
深層学習を学ぶ - 活性化関数編

# 1.この記事で分かる事
- 活性化関数とは
- よく出てくる活性化関数の数式及びその特徴や使用目的と、Pythonによるスクラッチ実装
  - ステップ関数
  - シグモイド関数
  - ソフトマックス関数
  - tanh関数
  - ReLU関数
# 2.活性化関数とは
活性化関数の特徴は、①**非線形な関数**で、②**微分可能**な関数という事が特徴。
①については、NN内において非線形な変換を行うため。
②については、勾配計算の際に微分可能である必要がある。

# 3.よく出てくる活性化関数

## ステップ関数(階段回数)
### 特徴
- 標準形
```math
step(x)=\left\{\begin{array}{l1}
1&(a \geq 0)\\
0&(a \lt 0)
\end{array}\right.\\
```
- 閾値(上記のコードでは**a**)以上なら１
- 閾値未満なら０という非常にシンプルな関数
- 閾値 aはハイパーパラメータ
### 深層学習における問題点
- 微分できない
- 閾値を超えないと常に0なので、勾配消失が起こりがち


```python:step 関数
def step(a,x):
   if x >= a: #閾値a以上なら、1を返す
      return 1
   else:      #他は全て0
      return 0
```
step関数の図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208224/b8ba5fca-8d19-ef3b-eaaf-d440d2b23a88.png)


## シグモイド関数
### 特徴
- 標準形
```math
sigmoid(x)=\frac{1}{1 + e^{-ax}}
```

- 微分形
```math
sigmoid(x)をf(x)としたとき、f'(x)= (1-f(x))f(x)となる
```
- 値域が0～1の範囲で、**確率の出力に類似している**
- a は基本的に1のハイパーパラメータ
### 深層学習における問題点
- 勾配消失が起こりやすい事 

```python:sigmoid 関数
import numpy as np

def sigmoid(a,x):#以下のグラフではa=1としている
    return 1 / (1 + np.exe(-a*x))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208224/0e6f7d5b-e0e8-9296-59c9-349de252a3fb.png)

### 補足
- シグモイド関数とロジスティック関数が混同する事が多いので気になる方は以下のページへ
→[シグモイド関数とロジスティック関数の違い](https://kenichia.hatenablog.com/entry/2017/03/04/122551)
- シグモイド関数の微分も大事なので、一度実際に計算する事をお勧めします。
→[シグモイド関数の微分の解答](https://qiita.com/yosshi4486/items/d111272edeba0984cef2)

## tanh関数
### 特徴
- 標準形
```math
tanh(x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}}
```
- 微分形
```math
tanh(x)をf(x)としたとき、f(x)'= (1-f(x))^2となる
```
- 値域が-1～1の範囲。
- a は基本的に1のハイパーパラメータ
### 深層学習における問題点
- 勾配消失が起こりやすい事 

```python:tanh 関数
import numpy as np

def tanh(x):
    return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208224/805cee2d-593c-9bbe-bf2d-af5dd42c819f.png)


## softmax関数
### 特徴
- 標準形
```math
y_i=\frac{e^{x_i}}{\sum_{k=1}^{n}e^{x_k}}
```
- 微分形
```math
\frac{∂y_i }{∂x_j }=\left\{\begin{array}{l1}
y_i(1-y_j)&(i=j)\\
-y_jy_i&(i\neq j)
\end{array}\right.\\
```

- 値域が0～1の範囲
### 深層学習における問題点
- 勾配消失が起こりやすい事 
- オーバーフロー対策が必要になる場合がある

```python:softmax 関数
import numpy as np

def softmax(x):
    x = x.T
    x = x - np.max(x, axis=0) #オーバーフロー対策で最大値を引いている。
    x = np.exp(x) / np.sum(np.exp(x), axis=0)
    return x.T
```

x = np.array([1, 2, 3, 4, 5, 6]) として、上記の関数を適用すると以下の図のようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208224/b4ba9cab-e7a8-5f36-d36e-e836284245f9.png)



### 補足
モデルの蒸留に使われる**温度付きソフトマックス関数**(元の式のexpの乗数の分母に、温度パラメータTを付けたソフトマックス関数のこと)→詳しくは[こちらのページ](https://qiita.com/nkriskeeic/items/db3b4b5e835e63a7f243)

## ReLU関数
### 特徴
- 0より上の入力をそのまま扱うことで、上記の関数の勾配消失問題を解決したこと
### 深層学習における問題点
- 0以下の部分において、勾配消失が起こりやすい事 

```math
ReLU(x) = max(0,x)
```

```python:ReLU
import numpy as np

def ReLU(x):
  return np.maximum(0,x)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208224/36b56211-f1e5-f369-9d13-64d3ae618970.png)
Next.jsプロジェクトをVercelにデプロイする

## 内容

Next.jsで作成したプロジェクトをVercelにデプロイする方法についてまとめ。
Next.jsのプロジェクトは既にGitHubにpush済、Vercelのサインアップは既に完了している前提で進めます。

## 目次
- [デプロイ手順](#デプロイ手順)
- [サブドメインの変更](#サブドメインの変更)
- [環境変数の追加・編集](#環境変数の追加・編集)
- [トラブルシューティング](#トラブルシューティング)
- [その後の運用](#その後の運用)

## デプロイ手順
### Vercelのプロジェクトを作成

[Vercelのダッシュボード](#https://vercel.com/dashboard) > Add New... > Project を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/21ea1127-128d-cdd9-2577-683d69aa3f05.png)

### GitHubにVercelからのリポジトリへのアクセスを許可

GitHubの画面が開くので、アクセスを許可
すべてのリポジトリへのアクセスを許可する場合は「All　repositories」を選択。
選択したリポジトリへのアクセスのみ許可する場合は「Only select repositories」を選択。


### GitHubのリポジトリを選択

Continue with GitHub
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/993a9dad-1f52-b87e-aff6-2752b9fe67db.png)

対象のリポジトリを選択 > Import
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/3aec8c76-7166-5be6-11cf-c470ddb54d0b.png)

### 環境変数など必要な設定を入力

プロジェクト名、環境変数、その他必要な設定を入力し > Deploy
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/c2d6536e-6cdd-020e-75b8-b49c2bbca939.png)


### 公開されたサイトを確認

問題なくデプロイが完了すると、「Congratulations!」と表示される。
「Go　to Dashboard」をクリックし、ダッシュボードへ進む。

プロジェクトの管理画面が開かれ、右上の「Visit」をクリックすると、公開されたサイトを確認できる。
下には公開されたURLが表示されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/faa1f580-90c6-3b79-97d6-154f99f84c53.png)

## サブドメインの変更

サイトのURL `~.vercel.app`はサブドメインの部分を変更することができる。

プロジェクト上部「setting」タブ > Domains > 現在のドメインの右側「Edit」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/28b175d2-b190-6175-e9f0-f9bcbc9136f3.png)

※ 自分が所有しているドメインを追加し、設定することもできる

所有しているドメインを入力 > ADD
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/6b9003ce-07ad-333d-2aa8-9949883d11e6.png)

## 環境変数の追加・編集

プロジェクト上部「setting」タブ > Environment Variables
から新しい環境変数を追加・既存環境変数の編集をする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/e6d49620-796f-9bad-4500-66f6a8d590cf.png)

## トラブルシューティング

Vercelへのデプロイ時にエラー解決で小一時間はまったため、その時のエラー対応を別記事にまとめております。
[記事はこちら（ModuleNotFoundErrorの解決）](#https://qiita.com/tarian/items/f666bf5e8daf5e31a0de)

## その後の運用

プロジェクトのソースコードを変更したとき、修正箇所をcommit ⇒ pushしてGitHubのリモートリポジトリに反映させるだけで、VercelではGitHubリポジトリの変化に反応し自動デプロイ処理が走る。
デプロイ処理が完了するとサイトに変更が反映される。

以上
Intersection Observer API（ターゲットが交差する％）

# Intersection Observer API
ある要素がスクロールして、特定の領域に入ったら、どれだけ交差しているか調べる。
領域：root
要素：target
割合：Intersection Ratio

ex)imgが一つある。それが画面に入ってくる。
```Javascript
 const target = document.querySelector('img');

  function callback() {
    console.log('fired!');
  }

  const observer = new IntersectionObserver(callback);

  observer.observe(target);
```
・observer()は（）を監視して。
・new IntersectionObserver()は、IntersectionObserverは()の仕事をする。
・これらの処理は監視が始まった時、０％の時(最初と最後)の計三回ある。
→じゃあ％を指定したい時はどうするの？→threshold
# %の指定
```Javascript
const target = document.querySelector('img');

  function callback() {
    console.log('fired!');
  }

  const options = {
    threshold: [0.2, 0.8],
  };

  const observer = new IntersectionObserver(callback, options);

  observer.observe(target);
```
・第二引数を渡してあげればよい。
・20%と80%のの時が追加される。
ffmpeg で GIF アニメーション作り 手順書

動画ファイルから GIF アニメーションを作るのを、ffmpeg のみで完結させます。

「コマンドの履歴まっさらでオプション忘れた」なんて時のメモ用に。

# 1. 動画の下ごしらえ

動画がフル HD であるなどの場合、そのまま GIF にしてしまうと膨大なサイズになってしまいます。そこで、ある程度ダウンスケールするなどの下ごしらえを行います。

## 時間切り取り

```sh
ffmpeg -ss START -to END -i "input.mp4" "output.mp4"
```

例: `-ss 0:02 -to 0:04`

`-ss` で開始時間、`-to` で終了時間を指定。

## 映像切り取り (トリミング, クロップ)

```sh
ffmpeg -i "input.mp4" -vf "crop=W:H:X:Y" "output.mp4"
```

例: `crop=400:300:80:70`

`W:H` に出力の横:縦サイズ、`X:Y` に切り取り矩形の左上端の座標を指定。

## 解像度変更 (スケール)

```sh
ffmpeg -i "input.mp4" -vf "scale=W:H" "output.mp4"
```

例: `scale=640:-1`

1辺の解像度を指定し、縦横比を維持してもう 1辺を指定したい場合、`-1` を指定することで自動で解像度が決められます。

以下のページで、詳しい例と共に解説されています。

https://trac.ffmpeg.org/wiki/Scaling

## フレームレート変更

```sh
ffmpeg -i "input.mp4" -vf "fps=F" "output.mp4"
```

例: `fps=20`

:::note warn
用途にもよりますが、60fps はややオーバー。体感的には 30fps が上限かと思います。
:::

## 備考 - 複数の効果を用いるには

```sh
ffmpeg -ss START -to END -i "input.mp4" -vf "crop=W:H:X:Y,scale=W:H,fps=F" "output.mp4"
```

`-vf` の後の項目をコンマ `,` 区切りで連続で書きます。(時間切り取りは `-vf` と別のオプション)

ビデオフィルタ `-vf` は、左から指定した順に適用されます。上の例では、トリミング後にスケール、最後にフレームレート変更という順で処理が行われます。

# 2. GIF に変換する

```sh
ffmpeg -i out.mp4 -vf "palettegen=stats_mode=diff" pal.png
ffmpeg -i out.mp4 -i pal.png -lavfi "paletteuse" out.gif
```

初めに 256色パレットを生成、その後にパレットを使用して動画から GIF を作成します。

:::note
GIF の仕様で、1画像 (正確には 1レイヤごと) に 256色しか使用することができません。これは、GIF が昔のフォーマットであることの名残です。
:::

# 3. 後片付け

以上の手順における中間ファイルを削除します。

```sh
rm pal.png out.mp4
```

:::note
中間ファイルを作らずに進める方法もありますが、オプションを簡潔にするため中間ファイルを通すことにしました。中間ファイル無しで進めるには、本記事末尾に貼った記事を参照してみてください。
:::

# ちなみに

趣旨から離れるのであえて省きましたが、GIF の作成手順は他にもいくつかあります。キレイさを犠牲に最も手軽に作るなら、出力の拡張子を `.gif` にしてやるだけでも OK です。

```sh
ffmpeg -i out.mp4 out.gif
```

こちらの記事で、実例と共に様々な最適化の試みをしてくださっています。高みを目指してチューニングしたい方は、試してみると良いかもしれません。

https://qiita.com/yusuga/items/ba7b5c2cac3f2928f040
Advent Calendar 2022 現状と課題

Advent Calendar 2022の過去との比較をしてみる。

合計が多い順にならべた。数字が整列していないと、思考のさまたげになる可能性があるから。　
今年の数で並べる方法と、合計の数で並べる方法の２種類が考えられる。　
合計の方が、数が大きく、おおきい数で並べる方が、統計屋さんらしいかもしれない。
　
全体の傾向はわかっていて、今年の課題だけを考えるのであれば、
今年の多い順にならべることに意味はある。


|分類|15|16|17|18|19|20|21|22|合計|21/22|22/21|
|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|
|Organization |78|145|198|245|308|289|310|215|1788|1.44|0.69|
|プログラミング言語 |57|78|89|84|79|91|63|51|592|1.23|0.8|
|その他 |25|61|63|60|78|80|89|70|526|1.27|0.78|
|ライブラリ・フレームワーク |54|54|61|69|63|52|51|33|437|1.54|0.64|
|サービス・アプリケーション |32|41|40|48|67|68|83|56|435|1.48|0.67|
|DevOps・インフラ・SRE|11|10|19|38|43|30|30|25|206|1.2|0.83|
|Webテクノロジー|25|27|40|26|19|20|23|18|198|1.27|0.78|
|IoT・ハードウェア |16|13|19|34|29|34|30|15|190|2|0.5|
|科学・理論 |12|19|22|22|31|21|22|9|158|2.44|0.4|
|ネイティブアプリ |11|17|13|13|13|13|7|6|93|1.16|0.85|
|データベース・DWH |16|13|9| |11|9|10|11|79|0.9|1.1|
|プレゼント | | | |8|7|19|12|24|70|0.5|2|
|エディタ  |7|12|10|5|12|7|8|3|64|2.66|0.37|
|OS|10|8|6|5|8|11|8|5|61|1.6|0.62|
|未設定 |23|1|0|7|0|0|2|12|45|0.16|6|
|Qiita主催 | | | | | | |6|2|8|3|0.33|
|合計|377|499|589|664|768|744|754|555|4950|1.35|0.73|


実際の開始まで、あと半月あり、昨年比、0.73であれば、まだいけるかもしれない。　

2021が2020より減ったのは、プログラミング言語で28減ったのが大きいだろう。

比率でいえば、ネイティブアプリが減っている。　

今年残念なのは、プレゼントが表より２つ減ることがまず最初にある。　

一番右の数字が、0.78未満のものは、増やすといいかもしれない。　

常に、データを示して、説明する訓練をしていると、データを示さずに、何かものを言うのがおかしいなって感じるようになるかもしれない。
Slack Appで「このアプリへのメッセージ送信はオフにされています」と表示される

# はじめに
こんにちは、ユーゴです。
今回は、Slack Appを作っていた際に出会った問題を紹介します。3分あれば解決できるのに、どこのサイトでも解決策が紹介されていなかったので、手助けになれば幸いです。

# 問題
Slack AppにDMを送り付けたいが、テキストボックスの欄が「このアプリへのメッセージ送信はオフにされています」と表示されてメッセージを入力できない。DMを送れない。
![スクリーンショット 2022-11-13 22.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/8dc9d163-4358-33c2-2187-5774a9d9dd95.png)

# 解決策
Slack Appの管理ページから、「App Home > Show Tabs」の項目を探し、「Allow users to send Slash commands and messages from the messages tab」の欄にチェックを入れる。
![スクリーンショット 2022-11-13 22.19.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/c2ec8153-1bca-edfc-874f-9b1ef3dd8fd9.png)

# 結果
メッセージを入力するテキストボックスが表示された。
![スクリーンショット 2022-11-13 22.20.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/852e12ab-dddc-6bcb-cb2a-45495726e987.png)

# まとめ
いかがだったでしょうか。
今回は、簡単なのになかなか答えに辿り着けない内容を紹介しました。

このようにUnity、GAS、Slack Appなどのプログラミングに関して、初歩的な内容から上級者的な内容まで幅広く取り扱っていきます。
気に入っていただけましたら、いいね・フォローの方、よろしくお願いいたします。
【MAC】 QTを動かしてみる(メモ)

# Qtとは
いろんなOS(クロスプラットフォーム)で動くGUIツール。
QtはGPLライセンスらしいので，商用はできないみたい。
C++で開発して，アプリケーションを作るために導入

# Qtのインストール
以下のURLからダウンロード。

https://www.qt.io/download-qt-installer?hsCtaTracking=99d9dd4f-5681-48d2-b096-470725510d34%7C074ddad0-fdef-4e53-8aa8-5e8a876d6ab4

# 使い方
以下を参考にしました。基本的に同じです。
[Macで、Qt5をbrew installしてサクッと起動する。](https://www.webcyou.com/?p=10581)

GUIにボタンを3つ作りたいと思います。
まずは，以下のcppを作成して

` qmake -project `
を実行。

```C:hello.cpp
#include <QtWidgets/QApplication>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
	QWidget* window = new QWidget;
	QPushButton* buttonA = new QPushButton("Button A");
	QPushButton* buttonB = new QPushButton("Button B");
	QPushButton* buttonC = new QPushButton("Button C");
	QHBoxLayout* layout = new QHBoxLayout;

	layout->addWidget(buttonA);
	layout->addWidget(buttonB);
	layout->addWidget(buttonC);

	window->setLayout(layout);
	window->show();	

    return app.exec();
}

```

その後，
`qmake hello.pro QT+=widgets`
を実行する。するとMakefileが出来上がるので，
`make`
を実行すると``.app``ができる。

`.app`をクリックするとGUIが描画される。
![t.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580278/9098e8ae-7958-249b-c6ac-b86c18233b7c.png)


# 参考
https://tomokiit.hatenablog.jp/entry/QtEnvironment

https://www.webcyou.com/?p=10581
【Python2.7】csvで空行なしで書き出す方法

# はじめに

Pythonに`csv`というcsvの読み書きをするライブラリがあります。
しかし普通に`writer.writerow()`を使って書き込むと、書き込む行と行の間が1行空いてしまうという問題があります。ちなみに原因は`CRLF`問題です。

|ヘッダー|
|:---|
|一行目のデータ|
|空白|
|二行目のデータ|
|空白|
|三行目のデータ|

**Python3**ではこれに対する解決策は`newline=""`を指定することで解決できるといろいろなサイトで解説されています。

しかし、**Python2.7ではこれは動きません。**

解決法を見つけたので共有します。




# Python2.7での解決法

Python2.7では、以下のように`lineterminator="\n"`を指定することで改行文字を指定して回避することができます。



```Python
import csv
    with open('test.csv', 'w') as f:
        writer = csv.writer(f,  lineterminator="\n")
        writer.writerows(text)
```
こちらのドキュメントを参考にしました。

https://docs.python.org/ja/2.7/library/csv.html#dialects-and-formatting-parameters




# 最後に

今回はPython2.7でcsvで1行空く問題の解決法について記事を書きました。
使用している環境がPython2だと、ネットで調べてもほとんどPython3なので動かなくて大変です。
今後もPythonのバージョン違いで記事がないものは積極的に記事を書いていこうと思います。




# Python3での対象法


https://qiita.com/ryokurta256/items/defc553f5165c88eac95

https://qiita.com/ikura1/items/17e6dd19f98145afc2eb

https://docs.python.org/ja/3/library/csv.html#id3
【シェルスクリプト】バージョン情報から数字だけを取得する方法

## 取得方法

以下のように実行するとバージョン表記部分のみ取得できます。  

```zsh
$ git --version
git version 2.38.1

$ git --version | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+"
2.38.1
```

- `-E`  
  拡張正規表現を使用する。  

- `-o`  
  一致した文字列のみ出力する。  

- `[0-9]+`  
  0から9が1回以上繰り返される。
【kotlin】遅延させる方法

# はじめに
今回はコルーチン内で処理を遅延させる方法を記事にします！

参考にしたページも併せて載せておきます

[kotlinx.coroutines1.6.4](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/delay.html)

[kotlin公式](https://developer.android.com/kotlin/coroutines/test?hl=ja)


# delay
やり方は使用しているCoroutineScope内で

delay(）というsuspend関数を呼び出し引数にLongで遅れさせたい秒数を記述します
```
val textView: TextView = findViewById(R.id.text_view)

suspend fun delayDisplayText() = withContext(Dispatchers.IO) {
            delay(1000L)
            textView.text = "Hello World!"
    }
```
スレッドをブロックせずにコルーチンを一定時間遅らせ、指定時間後に再開します
1000Lで１秒遅れさせます

また、この一時停止機能は、キャンセルすることが可能で　Jobがキャンセルまたは完了した場合、その時点で遅延がキャンセルされます。

# おわりに
今回はコルーチンの中のdelayについて記事にしました
コルーチンは使えると便利なものが多い反面、コードが難しくなりがちだったり 知識が必要になりますね
今後もコルーチンについての記事が上がるかもしれません
自分の知識の備忘録として記事にしていますが、誰かの参考になれば幸いです
組み合わせテストとテストツールの使い方

組み合わせテストと組み合わせテストツール（pict）について簡単に説明します。

## 組み合わせテスト
複数の入力条件を組み合わせてテストすること。

## 二因子間網羅

全ての組み合わせをテストするのが理想だが、限らた時間の中全てのテストを行うのは不可能である。
そこでテストの質を落とさずに、テストケースを考える為に二因子間網羅を使用する。

二因子間網羅を理解する上で、因子と水準を知っておく必要があります。
因子は、入力項目です。
水準は、因子がとりうる値です。

例は以下の通りです。
|  因子  |  水準  |
| ---- | ---- |
|  OS  |  Windows、Mac  |
|  言語  |  c#、Java  |


二因子間網羅は、二つの因子の組み合わせを網羅することです。
二因子間網羅は以下の表になります。

|  | 因子1 | 因子2 | 因子3 |
|:-:|:-:|:-:|:-:|
| 1  | 1  | 1  | 1  |
| 2  | 1  | 2  | 2  |
| 3  | 2  | 1  | 2  |
| 4  | 2  | 2  | 1  |

[因子1,因子2],[因子1,因子3],[因子2,因子3]のどの組み合わせをとっても、[1,1],[1,2],[2,1],[2,2]の4つの組が網羅されます。
全網羅だと8パターンですが、二因子間網羅により4パターンに削減することが出来ます。

## 直交表とペアワイズ法
- 共通すること：二因子間網羅である
- 直交表の特徴：
    - 均衡を意識するため、ペアの回数が均一になる。
    - ペアワイズ法より組み合わせが多くなる。
- ペアワイズ法
    - 均衡を意識しないので、ペアの回数が均一にならない。
    - 直交表よりも組み合わせが少ない。
  

## pictの使い方
因子と水準が大きくなると、自分で組み合わせを考えるのは大変になると思います。
一般的には組み込みテストツールを使って、組み合わせを考えます。

エクセルで使える[PictMaster](https://ameblo.jp/pictmaster)というツールがあるのですが、自分の環境ではマクロが起動しなかったのでpictを紹介します。

pictは[こちら](https://github.com/microsoft/pict)から利用できます。

基本的な使いかたは以下の通りです。
```pict.txt
因子名:水準1,水準2,水準3
```
以下のコマンドで実行出来ます。
```
./pict.exe qiita.txt
```

以下の組み合わせを実行します。
```qiita.txt
OS:Windows,Mac
Language:Java,PHP,Ruby
DB:SQLServer,MySQL
```
半角スペース区切りで出力されます。
```qiita-result.txt
OS	Language	DB
Mac	PHP	MySQL
Windows	Java	SQLServer
Mac	Ruby	SQLServer
Mac	Java	MySQL
Windows	PHP	SQLServer
Windows	Ruby	MySQL
```

制約を加えることも出来ます。
例えば、「Macの時はSQLServerを使用しない」との制約を加えた時は以下の通りになります。
```qiita.txt
OS:Windows,Mac
Language:Java,PHP,Ruby
DB:SQLServer,MySQL

# 制約
if [OS] = "Mac"
    then [DB] <> "SQLServer";
```


## おわりに
もし間違いがありましたら、編集リクエスト又はコメントお願いします。

## 参考文献
- [組み合わせの技法](https://gihyo.jp/dev/feature/01/sp-test/0001)
- [PICTの機能説明と使用例 （中編）](https://gihyo.jp/dev/feature/01/sp-test/0004)
- [ソフトウェアのテスト技法](https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E5%AD%A6%E3%81%B6%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E6%8A%80%E6%B3%95-%E3%83%AA%E3%83%BC-%E3%82%B3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%B3%E3%83%89-ebook/dp/B00HE8082Q/ref=sr_1_2?keywords=%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E6%8A%80%E6%B3%95&qid=1668342109&qu=eyJxc2MiOiIyLjA0IiwicXNhIjoiMS40NiIsInFzcCI6IjEuNDIifQ%3D%3D&sprefix=%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%83%86%E3%82%B9%E3%83%88%2Caps%2C231&sr=8-2)
React webアプリをCloud Runで実行する

ReactアプリをCloud Runで実行する必要があったので方法を調べました。

# Cloud Runとは
コンテナイメージを上げておけばそのイメージをいい感じにスケールアップしながら使ってくれる便利な機能。
AWSでいえばECSのようなものですかね。

# GCPのプロジェクト作成とCloud Runのサービス作成
1. GCPプロジェクトを作成します
2. Cloud Runを有効化します
3. Cloud Runサービスを作成します
4. コンテナイメージのURLを指定します(作成方法は後述)
5. Cloud Runサービスの作成を完了します

# コンテナイメージの保存場所
1. Artifact Registryを作成します 
2. GCR.io Repositoryを作成します。
   こんなURLが割り当てられます `gcr.io/YOUR_PROJECT_ID/gcr.io`
3. コンテナイメージをpushします(方法は後述)

# コンテナイメージのpush
```
# ローカルでreactをビルドします
cd PROJECT_ROOT
npm run build

# 一度だけ gcpのレジストリのurlとかをdockerに認識させます
gcloud auth configure-docker

# gcp環境にpushするのに認証が必要です
gcloud auth login

# ビルドされたreactを含むコンテナイメージを作成しRegistoryにpushします
## Intel Macの場合
### ビルド
docker build -f docker_cloudrun/Dockerfile --tag　gcr.io/YOUR_PROJECT_ID/gcr.io/reactcloudrun:latest .
### プッシュ
docker push gcr.io/YOUR_PROJECT_ID/gcr.io/reactcloudrun:latest

## M1 Macの場合ビルドとプッシュは同時に行う
docker buildx build --no-cache --push --platform=linux/amd64 -f docker_cloudrun/Dockerfile --tag gcr.io/YOUR_PROJECT_ID/gcr.io/reactcloudrun:latest .

これはGCPの実行環境のアーキテクチャがM1のものと違うからbuildxを使う必要があるという認識です。buildxで作成したマルチプラットフォームのイメージはローカルに作成できないので、直接pushする必要があると理解しました。
```

# Dockerfile
nginxで任意のディレクトリを表示すればよいだけなのでシンプルです。
```
FROM nginx:1.23
# PORTを8080で待ち受けるようにしたconfをコピー
COPY docker_cloudrun/default.conf /etc/nginx/conf.d/default.conf
# ビルドされたreactのディレクトリをnginxの公開ディレクトリとしてコピー
COPY build /usr/share/nginx/html
```

# 検証用プロジェクト
今回検証に使ったプロジェクトはGithubで公開しています。
https://github.com/sekitaka/react-cloud-run-example

# 注意
## ポート番号
Cloud Runの内部のコンテナが待ち受けるポートはデフォルトで8080なので、作成するイメージを8080に合わせる必要があります。ドキュメントではPORT環境変数から取得して動くようにしてねと書いてはありました。
スクラム開発のバックログ作成（簡潔版）

# はじめに

私は日本の大手企業において、POをしており、モダンオフショアでスクラム開発を行っています。

今回局所的なテーマ「バックログ」について、整理してみました。

:::note info
ここでは、新しい旅行アプリを構築することをサンプルにしています。
:::


# 1. ユーザーストーリー

POはバックログを作るために、最初にユーザーストーリーが必要です。テンプレートは次の通りです。

> AS A [user]
> ユーザー/役割として
>
> I WANT [function]
> 機能/性能ができる
>
> SO THAT [value]
> それにより価値がもたらされる

それでは、ユーザーストーリーを記述してみます。
- 旅行者として、過去の旅行履歴に基づいて、提案をもらうことができる。そうすれば、計画を立てやすくなる。
- 旅行者として、ローケーションで検索できる。そうすれば、目的地を見つけやすくなる。
- 旅行者として、価格で検索できる。そうすれば、予算内で目的地を見つけやすくなる。
- 旅行者として、幾つかの旅行オプションを知ることができる。そうすれば、多くの選択肢を持てる。
- 旅行者として、交通機関を予約できる。そうれば、一つのアプリケーションですべての調整を完結できる。
- 旅行者として、レンタカーを予約できる。そうすれば、一つのアプリケーションですべての調整を完結できる。
- 旅行者として、プロモーションを見ることができる。そうすれば、オファーを活用できる。
- 航空エージェントとして、旅行者のために、航空TICKETの予約を簡単にできるようにする。そうすれば、乗客をわたしたちの航空機に惹きつけられる。
- ホテルエージェントとして、ゲストのために宿泊を簡単に予約できるようにする。そうすれば、ゲストを私達のホテルに惹きつけられる。

ユーザーストーリーは、最初ユーザーストーリーマッピングなどを使って、整理するとよいです。またステークホルダーや開発チームも一緒に参加してもらうとよいです。（実際にはうまくできていませんが・・・）

# 2. 受け入れ条件

ユーザーストーリー毎に、開発チームの開発基準となる、受け入れ条件を追加します。

ビヘイビア駆動開発 (BDD)のテンプレートを使うと便利です。

> GIVEN
> 前提・初期コンテキスト
>
> WHEN
> シナリオをトリガーする条件
>
> THEN
> 期待される結果

- ユーザーストーリー：旅行者として、過去の旅行履歴に基づいて、提案をもらうことができる。そうすれば、計画を立てやすくなる。

        GIVEN:　ユーザーはユーザープロファイルを見ている
        WHEN:　ユーザーは旅行検索ページを開く
        THEN:　ユーザーは検索履歴に旅行提案を見る


# 3.優先順位

そして、優先順位を付けます。これはPOの重要な役割の一つです。

# 4.ストーリーポイント

開発チームは、最初のスプリントを見積もりします。そのため、過去のデータはありません。

ベロシティは過去のデータに基づいています。ベロシティとは、1つのスプリントでどれだけのストーリーポイントを完成させることができるかを見積もることです。


もし、過去データがないのであれば、当然、他の基準が必要です。アジャイルの世界では、いくつかの初期基準を与えてくれます。

たとえば、1人のチームメンバーが2週間のスプリントで約8ポイントを与えてくれるとします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/8fc218c3-2fda-ee98-7a7d-819fa2ee38b2.jpeg" width="200">


もし、メンバー数が4人なら、4×8で40ポイントです。2週間のスプリントで40のストーリーポイントを作成することになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/70ac818d-c245-f954-49d3-cd194d791741.jpeg" width="500">



そして次のスプリント、スプリント2では、40がうまくいった場合、その数字を使うことになります。しかし、ベロシティが何であれ、スプリント1で完了したストーリーポイントの数は、スプリント2で使用する過去のデータです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c6b04823-49c2-f8cd-e508-b1d3d9f76908.jpeg" width="６00">
Pycaretを使用し10行でKaggleのTitanic挑戦（Accuracy=0.78229）

# Introduction
Pycaretを使用してサクッとKaggleに挑戦する．
今回は二値分類のTitanicコンペに参加した．

# パッケージインポート
```py
import pandas as pd
import pycaret
from pycaret.classification import *
```

# 実行した10行のコード
今回はチューニング前のgbcの精度が良かったためそれを最終モデルとして採用した．
```py
# データの読込
data_train = pd.read_csv('csv_data/train.csv', index_col=0)
data_test = pd.read_csv('csv_data/test.csv', index_col=0)

# データの前処理
exp = setup(data = data_train, target='Survived', session_id=1)

# モデル比較
best_model = compare_models()

# モデル作成
gbc = create_model('gbc')

# モデルチューニング
tuned_gbc = tune_model(gbc)

# 最終モデル作成
final_gbc = finalize_model(best_model)

# テストデータで予測
test_predict = predict_model(final_gbc, data=data_test)

# 提出用csvデータ出力
data_submit = test_predict['Label'].rename('Survived')
data_submit.to_csv('csv_write/submit_20221113_pycaret_3.csv')
```

# 結果
Accuracy=0.78229
2666位/14474チーム　上位20%以内（2022/11/13時点）


![20221113.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/931058/bb11305c-5ac5-65f7-8e98-c6cef1d55f34.png)

# Conclusion
非常に簡単にそこそこの結果が出せたと思う．
Pycaretには様々な前処理方法が用意されているため，今後Pycaretだけ使用してどこまで精度が改善するか検証してみようと思う．
Tips: 保守性を高めるため、クラス内でインスタンス変数を使うときに意識していること

## この記事は何
僕はクラス内でインスタンス変数を使うとき、保守性の高いコードを書くうえでいくつか意識をしていることがあります。
意識していることの紹介と、なぜそれを意識しているのかを紹介します。

## 基本方針
まず初めに、意識していることを紹介する前に、クラスをどのような考えで作っているかを紹介します。
僕はクラスを以下のような考えで実装しています。
もちろんどれも例外はあるので、「できるだけそのようになる」ということを意識しているというつもりで読んでいただけると嬉しいです。

- イミュータブルである
- メソッドの返り値はコンストラクタで受け取った値だけで決まる
- クラス内部の実装が変更に対して閉じている

Open-Closedの原則と、参照透過性が高く、安全に使いやすいクラスを作ることを意識しているため、上記のような部分を意識しています。

今回は、上記のような実装を実現するため、特にインスタンス変数を使うときに意識していることを紹介ます。

## 1. インスタンス変数は初期化を行なった後には値を変更しない
インスタンス変数は基本的に一度値を入れたら変更をしないようにしています。
インスタンス変数の値を変える場合は、何かしらの状態変化が起こっていることが大半だと思います。
そして状態が変わっている場合、そのインスタンス変数を参照しているメソッドの返り値も変わる可能性が高いです。
そのようなクラスになっていると、クラスを参照する側からは現在どのような状態になっているかを常に意識をして実装を行う必要があり、実装ミスを誘発しやすくなると考えています。

## 2. setterメソッドを外部に公開しない
1の考え方に従っていれば結果的にそうなるかもしれませんが、基本的にsetterメソッドは外部に公開しないようにしています。

setterメソッドはインスタンス内部の状態を外部から直接変えることができてしまう処理です。
また、setterで値を変える場合は、インスタンスを違う目的の処理に使いまわそうとしている場合が大半だと思います。
その場合はsetterメソッドでインスタンス変数を上書きするのではなく、インスタンスを生成し直す実装で代替するようにしています。

## 3. クラス内部ではgetterメソッドを経由して値の参照を行う
メソッドの実装など、クラス内部でインスタンス変数を参照する場合は、直接インスタンス変数を参照するのではなく、getterメソッドを介して参照するようにしています。
このようにすることで、インスタンス変数で受け取る値のインターフェースなどが変わった場合も、Getterメソッドの修正をするだけで内部の処理の修正を行うことができ、内部処理の変更をできるだけ小さく抑えることができると考えています。

## サンプルコード
あげた３つの要素を含めたクラスのイメージをRubyで作ってみました。
もちろん全てのクラスをこのように実装することはできないと思いますが、できるだけ紹介した内容を意識した実装を行うようにしています。

```rb
class Sample
  private attr_reader :foo # 内部での参照用にgetterメソッドを定義する

  def initialize(foo)
    @foo = foo # @fooはコンストラクタでの初期化以外では代入しない
  end

  def bar
    @bar ||= foo.baz # 変数を直接参照しない。@barはこのメソッド内で一度だけ値が代入される
  end
end
```

## 最後に
最後までお読みいただきありがとうございました。
Devトークも公開しているので、もし直接話してみたい、と感じていただけた方はぜひDevトークの方も「話したい」を押していただけると嬉しいです！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/27
デジタル庁公開のデザインをhtml/cssに落とし込んでみた。

# はじめに

デジタル庁が公開したデザインシステムがよさそうなデザインでしたので、適当に遊ぼうかと思いました。
html/cssで公開してくれればすぐに使いやすいと思ったんですが、どうやらFigmaでしか配っていない。。
ということでhtml/cssに落とし込んでみました。

https://www.digital.go.jp/policies/servicedesign/designsystem/

## 注意事項

- 趣味程度に作ったものを、使いたい人がいればどうぞというものです。
- 細かい部分は間違っていることもあるかと思います。(ラジオボタン難しかったので、何とか再現した感じです。)
- 自分用に目的もなくつくっていましたので、命名等のポリシーもめちゃくちゃです。許してください。
- 大変つかれましたので、厳しいコメントは受け付けません。
- 気が向いたら、もう少しきれいにするかもしれません。

## ソースコード
以下、に載せています。

https://github.com/arakiyahoo/SampleDAWebUI.git



## 完成概要
ページとしてはこんな感じ
![_C__Development_HTML_work_mypassword_webui_mypassword.html (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1909955/1da95ccb-1903-9188-135a-4fb2e4c749ba.png)
パワーワードをバトルさせるアプリをレベルアップしてみた～Ver2～ #JavaScript #WebSpeechAPI

### 1.先日作成したアプリをレベルアップしたい
先日、パワーワードをバトルさせ勝敗を決定するアプリ **『ぱわーわーどばとる』** を作成しました。
結構いろんな方に見ていただいて、私が作成したQiita記事の中では一番参照されています。
せっかくなので、作成したアプリをレベルアップすることにしました。

※前回作成したアプリの詳細はリンク先を参照いただけると嬉しいです。
 **【前回記事リンク】**

https://qiita.com/kana87/items/18de38997edf64c09086

### 2.「ぱわーわーどあぷり」とは
レベルアップしたアプリはリンク先にて公開しています。

https://prismatic-cheesecake-e864d4.netlify.app

https://twitter.com/AYE7WvdouqRwaNp/status/1591748261815410689?s=20&t=HvFkkSNphhE0v8o-8rpoHw

### 3.アプリの利用ガイド
1.入力欄にバトルさせたいパワーワードを入力する
2.「たたかわせる」を押下する
3.ボタンの下にパワーワード力を計算して表示する
4.どちらが勝利したか、勝敗判定結果を表示する

### 4.前回からの変更点
###### 1.パワーワード力の計算方法の変更
**1-1.文字列の多い方に合わせて文字数調整**
前回作成したアプリは、文字数の多いワードが有利になるルールでした。
入力した文字数の差分を算出し、**差分×ランダム数(100~1000)を加算する** ことで、
同じワードを戦わせても異なる結果が出るようにしました。

**1-2.Googleの検索結果数(totalResults)を加算**
「よく検索されているワード＝パワーがある」とし、「Custom Search API」を使用し、
検索結果数(totalResults)を加算しました。
そのため、 **Google検索されているワードが有利** になります。

※「Custom Search API」は1日に100クエリまで呼び出し可能なため、このアプリは1日50回まで使用できます。
###### 2.勝者を読み上げる機能を追加
Web Speech APIを利用し、判定結果を音声で読み上げる機能を追加しました。
「たたかわせる」ボタンを押下し、勝敗を表示した後、「しょうしゃは？」ボタンを押下すると
判定結果を読み上げます。
読み上げる声は背景にあわせて女性の声を選択しました。
結果読み上げ機能を追加することで、ゲーム実況ぽい雰囲気が出ていると思います。

###### 3.「もしかして、あきた？」機能の追加
バトルだけだとあきちゃうよという方向けに、**「もしかして、あきた？」機能**を追加しました。
「もしかして、あきた？」ボタンを押下すると、ボタンの下に英語で暇つぶし案を提示してくれます。
(DeepLAPIで日本語に翻訳したかったのですが、登録がうまくいきませんでした。)
こちらの機能は利用回数の制限がないので、**暇つぶしを見つけたい方にもオススメ**です。

###### 4.背景および背景アニメーションの変更
アプリ名に「ばとる」とつけているので、バトルっぽい背景に変更しました。
これから戦う雰囲気の女性のイラストと、炎がちらついている演出に変更しました。
前回のアニメ演出は「Anime.js」を使用していましたが、今回のアニメ演出はJavaScriptのみを使用しています。

### 5.環境
Netlify
CodePen
Bootstrap
<font color="Red">★Web Speech API
★axios</font>
※★がついてい箇所が今回のアプリ構築で追加使用しました。
### 6.プログラム
前回と同様に今回作成したアプリもCodePenでソースコードを公開しています。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="BaVRgXe" data-user="kanakiku" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kanakiku/pen/BaVRgXe">
  パワーワードアプリ②</a> by kana_xedge (<a href="https://codepen.io/kanakiku">@kanakiku</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

###### 1.苦戦したところ
①「勝敗結果」の音声読み上げ機能
　音声読み上げ機能をVue.jsを使って構築しようとしたのですが、Vue.jsで処理を組むと上手くいかず、
　通常のJavaScriptのサンプルコードを探して作成しました。
②API戻り値の取得方法
APIの戻り値の値をどう扱っていいか分からず苦戦しました。
```JavaScript
 //ひとつめの検索件数を取得
  const res = await axios.get("https://www.googleapis.com/customsearch/v1?", {（略）
```

APIを下記のように呼び出しているので```res```から値を取得すればいいのではと思い、
開発を進めましたが上手く値が取得できず、

```JavaScript
     .then(function (response) {
      const date = response.data;
      wpoint = wpoint + date.queries.request[0].totalResults;
    });
```
と記述したところ、上手く検索結果の値を取得・加算することができました。

###### 2.まとめ
今回は、以前作成した「ぱわーわーどあぷり」のレベルアップした記事を作成しました。
ひとつのアプリを改良することで、JavaScript・HTML・CSSに関する知識とスキルを深められたと思います。
また、どうしたらゲーム性が出るのか、自身の持っているスキルでどこまでできるのか考えるのは大変でしたが、とても楽しかったです。
また、機会があったら「画像」や「動画」を追加できないか考えたいと思います。
【GitHooks】GitHooksの設定内容をチームで共有する。

## 概要
過去2回にわたってGitHooksを使った事例を紹介しました。
[【Git Hooks】コミット時にコミットメッセージの自動チェックを行う。【commit-msg】](https://qiita.com/MasaoSasaki/items/f10ab4cd54e228fb436f)
[【GitHooks】mainブランチへのコミットを禁止する。【pre-commit】](https://qiita.com/MasaoSasaki/items/431a7f103780a01757b5)

これらの設定は個人のローカル環境で設定するものですが、Hooksの設定をチーム内にも共有しルール化することができます。

## Git Hooksとは
Git Hooksとはgitに標準で備わっている機能の一つで、`git commit`や`git push`が実行された際に、スクリプトを実行することができ、そのスクリプトの実行結果によってコマンドを通すかどうかを自動的に判断させることができます。
[8.3 Git のカスタマイズ - Git フック](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF)

実行されるスクリプトファイルは以下の場所に置かれています。
```
$ ls .git/hooks
applypatch-msg.sample     post-update.sample        pre-merge-commit.sample   pre-receive.sample        update.sample
commit-msg.sample         pre-applypatch.sample     pre-push.sample           prepare-commit-msg.sample
fsmonitor-watchman.sample pre-commit.sample         pre-rebase.sample         push-to-checkout.sample
```
これらのファイル名は予約されていて、gitコマンドが実行されたときに任意のタイミングでそれぞれのスクリプトが動作することになっています。
デフォルトでは全てのファイルの拡張子が`.sample`となっているため、どのスクリプトファイルも動作していませんが、拡張子`.sample`を取り除くと、gitコマンドのそれぞれのタイミングでファイルに記述されているスクリプトが実行されます。
(シェルスクリプトの拡張子`.sh`は不要です。)

## 実装
### 共有するGitHooksの作成
1. 今回はリポジトリルート(.envや.gitignoreが置かれている階層です。)に.githooksディレクトリを作成します。
`$ mkdir /.githooks`

2. さらに概要のところで紹介したcommit-msg, pre-pushファイルを.githooksディレクトリ内に作成します。
`$ touch .githooks/commit-msg; touch .githooks/pre-push`
各Hooksスクリプトの内容については概要の記事をご参照ください。

3. Hooksスクリプトファイルに実行権を付与します。
`$ chmod a+x .githooks/*`

### GitHooks参照先の変更
GitHooksの参照先デフォルトパスは`.git/hooks`となっているため、このパスを先ほど作成した.githooksディレクトリに変更することで、リポジトリ内で共有されているHooksスクリプトを使えるようになります。
GitHooksの参照先を変更するコマンドは`git config`コマンドの`core.hooksPath`で変更を行うことができます。

```
.githooksを参照するコマンド
$ git config --local core.hooksPath .githooks

デフォルトに戻すコマンド
$ git config --local core.hooksPath .git/hooks

現在の参照先を確認するコマンド
$ git config --local --list
...(省略)
core.hookspath=.githooks
...
```

上記のコマンドで設定を変更することで、チーム内で共有されたHooksスクリプトを利用できるようになります。
プロジェクトに参加するメンバーは最初に上記のコマンドを実行する必要がありますが、以後はプロジェクト内で作られGit管理されているHooksスクリプトが適用されますので、Hooksスクリプト自体のメンテナンス性も上がります。

## 参考
[【Git Hooks】コミット時にコミットメッセージの自動チェックを行う。【commit-msg】](https://qiita.com/MasaoSasaki/items/f10ab4cd54e228fb436f)
[【GitHooks】mainブランチへのコミットを禁止する。【pre-commit】](https://qiita.com/MasaoSasaki/items/431a7f103780a01757b5)
[sample-codes/githooks/ - GitHub](https://github.com/MasaoSasaki/sample-codes/tree/githooks/main/githooks)
Railsのアクション内で実行される「redirect_to」にて、クエリストリングを渡す方法

## バージョン

- Rails 6.1.7
- ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]

## 状況

controller内の処理にて、リダイレクトするときにクエリストリングが渡したい。

```ruby
class SessionController < ApplicationController
  def create
    # ... 処理

    redirect_to xxx_url # ここでクエリパラメータを渡したい
  end
end
```

## 結論

上記のように`xxx_url`を使った場合、キーワード引数として値を渡してもうまく反映されない。


```ruby
class SessionController < ApplicationController
  def create
    # ... 処理

    redirect_to xxx_url, hogehoge: "fugafuga"
    # もちろんこんな形でも無理
    # redirect_to xxx_url, params: { hogehoge: "fugafuga" }
  end
end
```

なので、controllerとactionを指定してあげる形で記述する

```ruby
class SessionController < ApplicationController
  def create
    # ... 処理

    # topicコントローラーのnewへとリダイレクトしたい場合
    redirect_to controller: "topic", action: "new", hogehoge: "fugafuga"
  end
end
```

当たり前かもしれないですが、同じcontroller内の別actionにリダイレクトしたい場合は、controllerの指定は不要です。
PHP laravel 新規作成方法まとめ

Dockerでの新規作成方法まとめの自分用メモ
# PHP
```shell
docker run -p 4000:80 -v ${PWD}:/var/www/html -d php:apache
```
参考：https://gray-code.com/blog/php-on-docker/
mysqlもつける場合: https://and-engineer.com/articles/Ybx0hREAACEAgRY9

# laravel sail
```shell
curl -s https://laravel.build/<YOUR_PROJECT_NAME> |bash
```
とか
```shell
curl -s "https://laravel.build/<YOUR_PROJECT_NAME>?PHP=81" |bash
```
参考: [Amazon プロフェッショナルWebプログラミング Laravel〈最新Laravel 9対応〉](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%ABWeb%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Laravel%E3%80%88%E6%9C%80%E6%96%B0Laravel-9%E5%AF%BE%E5%BF%9C%E3%80%89-%E4%B9%85%E4%BF%9D%E7%94%B0-%E8%B3%A2%E4%BA%8C%E6%9C%97/dp/4295202835/ref=pd_vtp_sccl_3_2/356-7831410-4963024?pd_rd_w=hCNkl&content-id=amzn1.sym.cbb45385-7b99-44b7-a528-bff5ddaa153d&pf_rd_p=cbb45385-7b99-44b7-a528-bff5ddaa153d&pf_rd_r=C996M7JT6Y79QTFYV5RE&pd_rd_wg=pFFH3&pd_rd_r=598fdf4b-b6c5-46de-a76e-f89afe69b053&pd_rd_i=4295202835&psc=1)

# laravel docker
参考: https://www.engilaboo.com/laravel-nginx-docker/
参考の手順で、と言うかdocker/Dockerfile以外参考見ればいける
* docker/Dockerfile
```dockerfile
FROM php:8.0-fpm 
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get install -y \
    git \
    zlib1g-dev \
    libzip-dev \
    unzip \
&& docker-php-ext-install pdo_mysql zip

```
* docker-compose.yaml
```dockerfile
version: "3.8"
services:
  app:
    build: ./docker
    volumes:
      - ./app:/var/www/app
  nginx:
    image: nginx
    ports:
      - 8083:80
    volumes:
      - ./app:/var/www/app
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf

  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    ports:
      - 3306:3306

```
* docker/nginx/default.conf
```conf
server {
    listen 80;
    root /var/www/app/public;
    index index.php;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        fastcgi_pass app:9000; 
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
```
作成して
appフォルダ作成して
```
docker compose up -d
```
ESLintの@typescript-eslint/no-misused-promisesで怒られた時の対処法

React（TypeScript)にESLintを導入して、クリックイベントなどで非同期処理を入れた際に
@typescript-eslint/no-misused-promises
が現れました。

こちら、なぜこんな指摘が出るのかも含めて対処法を残します。

※こちらはTypescriptのESLintを導入してないケースでは注意されないと思います。

## 結論
### ◆Async/Await と .then() を使い分けよう

## なぜ指摘されるのか？
例えばデータをフェッチしてくる下記コードをクリックイベントで実行しようとして
![スクリーンショット 2022-11-13 19.08.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295930/29603b1e-abe4-c738-7af5-2904376109d4.png)

ESLintが、{reload}の箇所で「ここはPromiseあかんで」と指摘します　
![スクリーンショット 2022-11-13 19.11.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295930/0e198346-b024-aab6-ce3c-cd2fa3c67d04.png)

なぜなら、
![スクリーンショット 2022-11-13 19.22.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295930/3addb475-8b8a-13ce-6d68-ffc021b763f3.png)
イベントハンドラにはvoidを返す関数を入れるように定義されているから。

Promise<void>はあくまでプロミスを返しているため
ESLintのチェックに引っかかります。

## Q.ではどうするか？
### A. ならば.then()だ
![スクリーンショット 2022-11-13 19.32.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295930/5f495d6d-f4bf-e0e4-06e5-70e44cad0bcd.png)
voidを返す形にすれば指摘も消えます。
それにこれくらいなら可読性の影響もないと判断しています。
![スクリーンショット 2022-11-13 19.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295930/23228ee6-ffb3-1611-f73e-c6ef8d5dd848.png)

ちなみに.catch()のなかにalert()入れてる件は、今回は見逃してください。

いちおう関数コンポーネント内の定義なのでギリOKかと思いますが、
alert()を使うならこの関数ではstringを返して
クリックイベント関数の返り値をvoid型にするのが良い気がしています。



[こちら](https://github.com/react-hook-form/react-hook-form/discussions/8020)のディスカッションでも討論されてましたが、void演算子をつける案やラッパーを作った方もいました。

## まとめ
個人的には、サーバーレスを使うと相手の関数自体がPromiseを返すこともあるため、
可読性がいいからと、一つ覚えのAsync/Awaitにならず
状況に応して.then()を使える柔軟さを身に付けておいた方が良いと思いました。
IEモードで開発者ツール使用

# 概要
IEモードのEdgeの場合、下記のようになり開発者ツールを使用できない。
これではCSSの確認などが難しいため、
開発者ツールを使用する方法を説明します。
※対して難しい内容ではないが、備忘として残す目的で記事を書いています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33640/defb0993-131d-b461-810f-6dd323403c14.png)

# 参考ページ
https://learn.microsoft.com/ja-jp/microsoft-edge/devtools-guide-chromium/ie-mode/

# 開発者ツール起動
Windowsキー　＋　rキー　を押す。
↓
下記を入力してOKボタンを押下
```
%systemroot%\system32\f12\IEChooser.exe
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33640/12428e8c-afbb-6d33-6777-2a3c10f7c791.png)

※要するに、
```
C:\Windows\System32\F12\IEChooser.exe
```
を実行するということですね。

# 使用方法
IEChooser.exeを起動すると下記の画面が表示される。
使用したいページを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33640/ea973722-ddc0-94ea-c2b4-34d1a62a0951.png)

すると下記の画面が表示されるので後は、普段使用している通り操作することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33640/93917bd3-379e-5db4-3da9-2a97d06e85c8.png)
Google Keepの一覧を取得するPythonスクリプト

## 概要
gkeepapiを使いKeepのオブジェクトを取得する方法について調査した。
理由はGoogleKeepは一覧性が乏しく、タイトルとノートの一覧を取得しかった。

## gkeepapiとは
Google非公式のAPI。Pythonで記述しKeepの情報を取得できる。認証はgpsoauthのライブラリを利用している。
公式ではエンタープライズ向けのみで一般ユーザーへAPIを提供していない。

- [Google Keep APIのドキュメント](https://developers.google.com/keep/api)
- [gkeepapiのドキュメント](https://gkeepapi.readthedocs.io/en/latest/#setting-note-content)
- [GitHubリポジトリ](https://github.com/kiwiz/gkeepapi)


## 準備
```
pip install gkeepapi
```

## コード
```python:
import gkeepapi
import json

# Googleアカウント情報(Gmailアドレスとパスワード)の指定 
credential_path = 'C:\\xxxxxxxxxxx\\gcredential.json'
credential = json.load(open(credential_path))
email = credential["email"]
password = credential["password"] # ドキュメントではアカウントの二段階認証を有効にし、アプリパスワードの設定を推奨

# インスタンスの生成
keep = gkeepapi.Keep()

# 認証
keep.login(email, password)

# ノートの取得(ノートの作成順に)
gnotes = sorted(keep.all(), key=lambda x: x.timestamps.created)

# コンソールへ表示
for gnote in gnotes:
    print("Created timestamps: " + gnote.timestamps.created.strftime('%Y-%m-%d %H:%M:%S'))
    print("id   : " + gnote.id)
    print("Title: " + gnote.title)
    print("Text : " + gnote.text)
    print("-------------------------------")

```
```json:gcredential.json
{
    "email": "user@gmail.com",
    "password": "password"
}
```

## 備忘
少し気になる点や調査不足の備忘
- プライバシーポリシーがドキュメントに不明記で、セキュリティ面の問題がないか気になる。
- ログイン失敗時に警告が来ない理由が不明。UIからのログインでは、失敗時にGoogleからの警告メールやプッシュ通知が来るので、APIでも同じく警告が来るのではと考えていた。
- gpsoauthなどのOAuth認証についての理解が浅く勉強が必要と感じた。
SourceTreeで2つ以上のプロジェクトを1つにまとめる方法

## 概要
特に、記事にするまでもないと思いますが、備忘録として便利機能について投稿します。
SourceTreeを使っていて、2つ以上のアプリのウィンドウを稼働すること、ありますよね？
そんな場合に、個々のウィンドウを開かなくていいように1つのウィンドウに2つ以上のアプリのウィンドウをタブによる切り替えで表示を切り替えすることができます！

## 使用方法
①SourceTreeで、いくつかのウィンドウを開く
以下の画面で、1つのウィンドウにまとめたいプロジェクトをいくつか選択して開いておきます。
![938f7e9e1c008e127b1cadf7dfb3cfa8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2630898/50b08a36-faab-b1fc-4d9d-84c59b098db6.png)


②開いたリポジトリを開いた状態で、メニューバーからウィンドウを選択する
その名の通り、メニューバーにあるウィンドウを選択します。
![メニューバー](https://gyazo.com/ed375927acbd95dd3840f9ce2e878ded.png)


③ウィンドウの選択肢にある、「すべてのウィンドウを結合」を選択する
Gyazoの使用上写真を撮れなかったのですが、②でメニューバーを選択すれば、真ん中から下あたりに「すべてのウィンドウを結合」という選択肢があるので、こちらを選択すると1つのウィンドウで、複数のウィンドウをタブの切り替えによって表示を切り替えできるようになります。

## さいごに
最近、勤務先でも効率を上げるための仕事術をプレゼンし合う時間があったので、こういう投稿もしてみようと思い、投稿してみました。
最近は、ChromeのショートカットキーかXCodeのショートカットを極めたいなと思って、慣れているところです。
こういう些細なことでも効率化して、仕事を爆速で終わらしていきたいものですね！