OmniAICreator/Qiita-1.07M huggingface dataset:
Vue Routerでparamsとqueryの取得方法

#Vue Routerでparamsとqueryの取得方法



##params

```
https//localkhost:3000/users/1
→ this.$route.params.id
```


##query(クエリ)
```
localhost:8080/example?itemId=1234
→ this.$route.query.itemId
```
「?」+「変数名」=「変数の値」がqueryパラメータとなる
この例では「itemId」が変数名、「1234」が変数の値となる

queryパラメータ内に「?」を複数付けた場合、正しい動きをしない可能性があるので注意
ffmpegで"Decoder (codec none) not found for input stream #0:0"となったとき

## 環境

- ubuntu 20.04

## 問題

```bash
$ ffmpeg -i input.avi output.mp4
ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
#中略
Stream mapping:
  Stream #0:0 -> #0:0 (? (?) -> hevc (libx265))
Decoder (codec none) not found for input stream #0:0
```

## 解決

ffmpegをversion 4.3以上にすれば解決するみたいです。
ffmpegのアップデート方法は以下を参考にしました。

- https://ubuntuhandbook.org/index.php/2021/05/install-ffmpeg-4-4-ppa-ubuntu-20-04-21-04/

## 参考

- https://www.fixes.pub/program/701318.html
【Python3】PC開きすぎ防止ソフトを作ってみた

最近、PCを見続けることが多くなり、視力が悪くなったと感じた。
そのため、以下のようなPC開きすぎ防止ソフトを作った。



#1.目標
PCを開いてから1時間以内にスリープする。
また、作業時間をGUI上に表示する


#2.仕様
言語:Python3.9
のちにpyinstallerでexeに。
OS:Windows10

#3.実装時注意点
threadingでスリープ処理と作業経過時間表示処理を分けること。

#4.実装方法とコード



```Python:sleeping.py
import ctypes
import datetime
import tkinter as tk
import time
from tkinter import messagebox
import threading
import sys
from tkinter import ttk

#初期設定
dt = datetime.datetime.now()
print("開始時間: "+str(dt.hour)+":"+str(dt.minute)+":"+str(dt.second))
funsu = 0
flag = True

#スリープ判定
def sleep_checker():
    #8時以前と22時以降の場合何もしない
    if dt.hour >= 22 or dt.hour <8:
        pass
    else:
        time.sleep(3600)
        ctypes.windll.PowrProf.SetSuspendState(0, 1, 0)
        sys.exit()

#経過時間表示
def show_window():
    
    #GUI設定
    root = tk.Tk()
    status = tk.StringVar()
    status.set("")
    root.title("実行監視プログラム")
    root.geometry("450x180")
    work_label=tk.Label(text="作業開始から",font=('',35),wraplength=400,anchor="center")
    work_label.pack()
    status_label=tk.Label(textvariable=status,font=('',45),wraplength=400,anchor="center")
    status_label.pack()
    
    
    # ---設定項目---
    def check_time():
        global funsu,flag
        dt_now = datetime.datetime.now()
        sabun = dt_now - dt
        
        #秒数計算
        if sabun.seconds == 1:
            flag = False
        if (sabun.seconds%60) == 0 and flag == False:
            funsu = funsu+1
        else:
            pass
        
        if funsu <1:
            status.set(str(sabun.seconds)+"秒経過")
        elif funsu == 59:
            status.set("残り1分で作業を終了してください")
        elif funsu == 60:
            root.destroy()
        else:
            status.set(str(funsu)+"分"+str(sabun.seconds%60)+"秒経過")

        #1秒ごと繰り返し
        root.after(1000,check_time)
    check_time()
    root.mainloop()

thread1 = threading.Thread(target=sleep_checker)
thread2 = threading.Thread(target=show_window)
thread1.start()
thread2.start()
thread1.join()
thread2.join()

```

以下に動作時のスクリーンショットを載せる
![スクリーンショット 2021-10-04 214547.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702737/9170e6de-98a2-1135-3e18-0b65d5aa527a.png)





#5.考察
sleepの処理でてこずるかと思ったが案外早くできた。
スリープ後に処理が落ちていないことがあり、スリープから復帰しても再スリープするということがあった。
対策として、Pythonのプログラムを強制終了させる手段として、sys.exit()をスリープさせた後に組み込んだ。

#6.参考サイト



https://pashango-p.hatenadiary.org/entry/20110417/1303019127

Windowsをスリープさせる処理を参考にさせていただきました。



https://qiita.com/tchnkmr/items/b05f321fa315bbce4f77

Pythonにおけるスレッド処理について記載されています。参考にさせていただきました。



https://genchan.net/it/programming/python/4250/

.pyファイルの.exe化の方法についてはこちらのサイトを参考にさせていただきました。
PowerAutomate: SharePoint Lists で Filter Query を使えば 5000件越えても問題なし

# 概要

Get Items コネクタで 5000件超えてたらどうなるの？って言われてちょっと調べた記録

# 準備
5000件問題が20000になったとかの話もあってまだ実体験してないので、とりあえず20000件突っ込んだListを用意

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/fab691dd-af44-9873-6a95-c5cf6925c221.png)
フィルターしやすいように、Details に ID の一位を突っ込んでおく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/1eccdac9-094b-b382-8be9-c92aef6b6500.png)


# 5000 件超えのエラーの確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/d52c6d70-91e6-7cb1-3a15-7968669a93ed.png)

5000 件までなら普通に取得出来てしまう・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/860075b4-e8ee-b5dc-693b-d9ea0d55be97.png)

## 記述ミス
ここ、default=all といいつつ、100 ってのはいい加減なんとか直らないかな・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/d9484448-3dd5-7d2e-3216-ec8f3a107b81.png)

# Filte Query でエラーが消えるか確認

20001 / 10 となる Filter 設定したら、普通に問題無しで取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/81aed4a2-c2e9-b3f0-469e-28673faa2747.png)

# 結論

取得量も減るし、出来る限り Filter Query を定義するのは大切ですね。
使ってないと、Editor さんも注意してくれますしね。

https://social.technet.microsoft.com/wiki/contents/articles/35796.sharepoint-2013-using-rest-api-for-selecting-filtering-sorting-and-pagination-in-sharepoint-list.aspx
Angular: 特定の 要素までスクロールさせる

いくつか方法があります。

## `viewportScroller.scrollToAnchor`

特定のIDを持つ要素までスクロールします。

コンポーネントでは次のように記述します。

```typescript
/* 省略 ... */

    constructor(private viewportScroller: ViewportScroller) {
    }

    sampleMethod() {
        this.viewportScroller.scrollToAnchor('specific_id')
    }

/* 省略 ... */
```

```html
<div id="specific_id"></div>
```

## ViewChild

`scrollToAnchor` は即座にスクロールしてくれるのですが、 ユーザからすると一瞬で画面が変わることになり、なにが起きたのか理解できなくなることがあります。

スムーズにスクロールする方法のひとつに、 `ViewChild` を使う方法があります。
`ViewChild` を使ってHTMLの要素をコードから使えるようにしておきます。
スクロールは HTML の要素が持つメソッドを使って行います。

```typescript
/* 省略 ... */

    @ViewChild('specific') specificElement: ElementRef | undefined

    sampleMethod() {
      this.specificElement?.nativeElement.scrollIntoView({
        behavior: "smooth", block: "start", inline: "nearest"
      })
    }

/* 省略 ... */
```

```html
<div #specific></div>
```

たとえば次のように、条件変更と同時に要素が出現する場合には、 `setTimeout` を使うとうまくスクロールできます。

```typescript
/* 省略 ... */

    sampleMethod() {
      this.flag = true
      setTimeout(
        () => {
          this.specificElement?.nativeElement.scrollIntoView({
            behavior: "smooth", block: "start", inline: "nearest"
          })
        },
        100
      )
    }

/* 省略 ... */
```

```html
<div *ngIf="flag">
    <div #specific></div>
</div>
```
ESP32 で arduino-CAN ライブラリを使うと通信速度が半分になる問題と解決策

## 問題
　ESP32でCAN通信を扱う際、Arduino IDE で開発している場合は、[arduino-CAN](https://github.com/sandeepmistry/arduino-CAN) というライブラリを使うことが多いと思います。この **arduino-CAN ライブラリ を使って ESP32 でCAN通信を行うと、なぜか通信速度が指定値の半分になる** という問題に遭遇することがあります。

### 問題が発生しているハードウェア
- [ESP32-DevkitC-32E (ESP32-WROOM-32E開発ボード)](https://akizukidenshi.com/catalog/g/gM-15673/)
- [CANトランシーバ MCP2562FD-E/P](https://akizukidenshi.com/catalog/g/gI-14383/)

[ESP32でCAN通信をする](https://siroyantech.hatenablog.com/entry/2021/01/31/150751) を参考に結線しています。ただし、私の環境では都合により`RX`を`32`、`TX`を`33`としています。

### 問題が発生しているコード
　arduino-CAN の[サンプルコード](https://github.com/sandeepmistry/arduino-CAN/blob/master/examples/CANSender/CANSender.ino) `examples/CANSender` そのものなので省略します。


## 原因
　以下のページに、この問題に関する議論がありました。
https://github.com/sandeepmistry/arduino-CAN/issues/62

　チップバージョンがRev2以上のESP32では、CAN通信に関係する、とあるレジスタビットの役割が「通信速度を半分にする」という意味に変更されたそうです。変更前の仕様に従って書かれている arduino-CAN ライブラリは、このビット値を`1`にセットしてしまうため、通信速度が`CAN.begin(baudrate)`で指定した`baudrate`の半分になってしまうのです。

## 解決策
　単純に、送りたい速度の2倍を指定して`begin` すれば、送ることはできます。

　しかし、1 Mbps で通信したい場合や、根本的な解決を求める場合、`setup()`内で `CAN.begin(baudrate)`の後に以下のように追記します。

```C
  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
  // 以下2行を追記
  volatile uint32_t* pREG_IER = (volatile uint32_t*)0x3ff6b010;
  *pREG_IER &= ~(uint8_t)0x10;
```

（詳しい人向け）
CAN割込み関連のレジスタ `REG_IER` （ESP32 の公式マニュアルでいう `TWAI_INT_ENA_REG` `0x3ff6b010`） の bit 4 の役割が、"Wake-up interrupt" から "divide BRP by 2" に変更されたそうです。`CAN.begin(baudrate)`のソースコードでこのレジスタに`0xff`を書き込んでいるため、当該bitが`1`となり、速度が半分になります。そこで、`begin`した後に当該ビットに0を書き込んでいます。

## おわりに
　複数のプロジェクトで立て続けにこの問題に遭遇し頭を抱えておりました。しかも、ESP32 Technical Reference Manual にもこの仕様変更が反映されていない（執筆時点での最新版v4.5, 2021/7/21）ため原因特定に時間がかかりました。かなりニッチな話題ですが、1度ハマると迷宮入りしそうなポイントに見えます。
[Ruby] 自作クラスを比較可能にする方法

## :ledger: はじめに：自作クラスで比較したいケース
自作クラスを簡単に比較したいケースがあると思います。
例えば、身長を格納するHeightクラスを作成したとします。
インスタンス化するときの式はこのようになります。

`taro_height = Height.new(180)`

そして、他の人と身長を比較したいケースが出てきたとします。

`hanako_height = Height.new(158)`

タロウさんとハナコさんの身長を簡単に比べるためには以下が出来ると嬉しいですよね。

`taro_height > hanako_height`

しかし、これを実現するにはモジュールのインポートと独自の実装が必要になります。
今回はテスト科目の点数を持つScoreクラスをサンプルコードとして扱っていき、比較可能にする方法を解説します。

## :ledger:自作クラスはそのままでは比較できない
まず、単純に自作クラスを作成して比較しようとしてみます。
サンプルコードをご覧ください。

```rb
class Score
    def initialize(math, english, physics)
        @math = math
        @english = english
        @physics = physics
    end
end

score_noby = Score.new(30, 45, 50)
score_ace = Score.new(98, 95, 94)

puts score_noby < score_ace # undefined method `<'
puts score_noby > score_ace # undefined method `>'
puts score_noby == score_ace # false (Objectクラスの実装によりオブジェクトIDで比較される)

```

もちろん、このままでは比較演算子が使えません。
このままだとそのクラスの何を比較するのか、全く分からないですよね。
これを解消するには、Comparableモジュールをインクルードし、<=>メソッドを定義する必要があります。

## :ledger: 比較する対象をきめる必要がある
比較する対象はテストの合計点としましょう。
そして、<=>メソッドを定義します。サンプルコードをご覧ください。

```ruby
class Score
    include Comparable # Comparableモジュールのインクルード
    attr_reader :math, :english, :physics

    def initialize(math, english, physics)
        @math = math
        @english = english
        @physics = physics
    end

    def <=>(other)
        if other.is_a?(Score)
            @math + @english + @physics <=> other.math + other.english + other.physics
        else
            nil
        end
    end
end

score_noby = Score.new(30, 45, 50)
score_ace = Score.new(98, 95, 94)

puts score_noby < score_ace # > true
puts score_noby > score_ace # > false
puts score_noby == score_ace # > false
```

*nobyはのび太、aceは出木杉君の英名です。
ABC190 C - Bowls and Dishes から学んだ

https://atcoder.jp/contests/abc190/tasks/abc190_c

![abc190_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/de758cc7-4009-1508-b710-58cb643bd3a4.png)
![abc190_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/8142cf19-9a85-896f-be4c-8f0b8f733a1b.png)
![abc190_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/4c516677-7f51-1fe4-8b4f-30cf5ababfc6.png)
![abc190_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/8e555f6c-afdf-92b3-305a-a149dbf4971b.png)
![abc190_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/eda42a5d-a662-dda8-b554-eb1bd9ba807c.png)

とりあえず、全探索で思いつくまま書いた。

```BowlsAndDishes_r1.py
N,M = map(int,input().split())
dish = []
 
for i in range(M):
    a,b = map(int,input().split())
    dish.append([a,b])
 
K = int(input())
lis = []
for _ in range(K):
    c,d = map(int,input().split())
    lis.append([c,d])
 
from itertools import product
ans = 0
for x in product([0,1],repeat=K):
    nums = []
    cnt = 0
    x = list(x)
    #print(x)
    for k in range(K):
        nums.append(lis[k][x[k]])
    nums = set(nums)#<= ココをlist にすると確実に TLE になるので注意
    for a,b in dish:
        if a in nums and b in nums:
            cnt +=1
        ans = max(ans,cnt)
print(ans)
```

ビット全探索を使ってみた。
ただ、これでも TLE となったが、こんな感じだった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/5b26fe2f-23ee-aee4-92d8-7b0f721f846f.png)

TLE でコケルときって、もっと沢山こけるべ。
じゃあ、pypy + def の合わせ技でどうだべ。

```BowlsAndDishes_r2.py
def solv():
    N,M = map(int,input().split())
    dish = []

    for i in range(M):
        a,b = map(int,input().split())
        dish.append([a,b])

    K = int(input())
    lis = []
    for _ in range(K):
        c,d = map(int,input().split())
        lis.append([c,d])

    from itertools import product
    ans = 0
    for x in product([0,1],repeat=K):
        nums = []
        cnt = 0
        x = list(x)
        for k in range(K):
            nums.append(lis[k][x[k]])
        nums = set(nums)

        for a,b in dish:
            if a in nums and b in nums:
                cnt +=1
        ans = max(ans,cnt)
    print(ans)

solv()
```

通った。

***

過去の記述は忘れた状態で再チャレンジ。
K 人が置いた組み合わせは True or False として
memo することにした。

あとは両方のお皿において True になっている組み合わせを
カウントするだけ。

```abc190c.py
N,M = map(int,input().split())
dish = []
for _ in range(M):
    a,b = map(int,input().split())
    dish.append([a,b])
K = int(input())
select = []
for _ in range(K):
    c,d = map(int,input().split())
    select.append([c,d])

ans = 0
from itertools import product
for num in product([0,1],repeat=K):#O(2^K)
    num = list(num)
    memo = [False] * 101
    cnt = 0
    for i in range(K):#O(K)
        memo[select[i][num[i]]] = True
    for j in range(M):#O(M)
        if memo[dish[j][0]] and memo[dish[j][1]]:
            cnt += 1
    ans = max(ans,cnt)
print(ans)
#O(2^K*(K+M))
```

これなら 10^6 オーダーなので python でも
普通に間に合う。
Xcode13におけるSwift Package Managerを使ったNCMB Swift SDKのインストールについて

## 問題

Xcode13からSwift Packagesのインストールが変わっています。これまではFileメニューのPackagesに、Add Package Dependency...があったのですが、それがなくなりました。

![ScreenShot_ 2021-10-04 18.33.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/50d51ae0-e90a-eb6a-8923-fc0b652bb629.png)

## 解決策

新しい方法は、プロジェクトを開いて、Package Dependenciesの中にある + アイコンをクリックします。

![ScreenShot__2021-10-04_18_35_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/20d0f49e-5afc-1ecd-4602-04a3dbc7ebd6.png)

パッケージ名が色々と出てくるので、左上のURL入力欄にて下記のURLを入力します。

![ScreenShot__2021-10-04_18_35_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/d49802de-0551-0388-5b1e-ab922a8705cb.png)


```
https://github.com/NIFCLOUD-mbaas/ncmb_swift
```

そうすると ncmb_swift が出てくるので、右下にある Add Package ボタンを押します。

![ScreenShot__2021-10-04_18_35_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/2f45f740-a1ab-7b04-946b-5cf2ce40f69d.png)


確認ダイアログはそのままで、Add Package ボタンを押します。

![ScreenShot_ 2021-10-04 18.35.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/d83394e7-4e7a-fa6b-b804-bb39a6001a83.png)


これでインストール完了です。

![ScreenShot_ 2021-10-04 18.35.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/e7b5a8c6-a65e-da9d-0c79-eb42413e1728.png)


## まとめ

これまでと全く異なるフローでのインストールになるので、機能を探すのに時間がかかりました。Swift Package Managerを利用する際には注意してください。

[イントロダクション \(Swift\) : クイックスタート \| ニフクラ mobile backend](https://mbaas.nifcloud.com/doc/current/introduction/quickstart_swift.html)
railsチュートリアル第七章 debuggerメソッド

###debuggerメソッド
アプリケーションの振る舞いを理解するために```debug```メソッドが役に立つことを学びました。
しかし、もっと````直接的にデバッグする方法```もあります。
それが```byebug gem```による```debugger```メソッドです。
debuggerメソッドを実際にアプリケーションに差し込んで確かめてみましょう。

####debuggerをUsersコントローラに差し込む
app/controllers/users_controller.rb

```rb
class UsersController < ApplicationController
  
  def show
    @user = User.find(params[:id])
    # データベースからユーザー情報を取り出す
    debugger
    # rails sにデバックが表示される
  end
  
  def new
  end
end
```
debuggerメソッドを差し込んだら、ブラウザから /users/1 にアクセスし、Railsサーバーを立ち上げたターミナルを見てみましょう。```byebugプロンプトが表示```されているはずです。

```
[3, 12] in /home/ubuntu/environment/sample_app/app/controllers/users_controller.rb
    3:   def show
    4:     @user = User.find(params[:id])
    5:     # データベースからユーザー情報を取り出す
    6:     debugger
    7:     # rails sにデバックが表示される
=>  8:   end
    9:   
   10:   def new
   11:   end
   12: end
```
このプロンプトでは```Railsコンソールのようにコマンド```を呼び出すことができて、アプリケーションの```debuggerが呼び出された瞬間の状態を確認```することができます。

```
(byebug) @user.name
"Michael Hartl"
(byebug) @user.email
"michael@example.com"
(byebug) params[:id]
"1"
```
なお、```Ctrl-D```を押すとプロンプトから抜け出すことができます。
また、```デバッグが終わったらshowアクション内のdebuggerの行を削除```してしまいましょう。

####debuggerをUsersコントローラーから取り外す

```rb
class UsersController < ApplicationController
  
  def show
    @user = User.find(params[:id])
    # データベースからユーザー情報を取り出す
  end
  
  def new
  end
end
```
今後Railsアプリケーションの中で```よく分からない挙動があったら、上のようにdebuggerを差し込んで調べてみましょう```。
トラブルが起こっていそうなコードの```近くに差し込むのがコツ```です。
byebug gemを使ってシステムの状態を調査することは、アプリケーション内のエラーを追跡したりデバッグするときに非常に強力なツールになります。

###演習
1.showアクションの中にdebuggerを差し込み（リスト 7.6）、ブラウザから /users/1 にアクセスしてみましょう。その後コンソールに移り、putsメソッドを使ってparamsハッシュの中身をYAML形式で表示してみましょう。ヒント: 7.1.1.1の演習を参考にしてください。その演習ではdebugメソッドで表示したデバッグ情報を、どのようにしてYAML形式で表示していたでしょうか?

```
(byebug) a = params
<ActionController::Parameters {"controller"=>"users", "action"=>"show", "id"=>"1"} permitted: false>
(byebug) puts a.to_yaml
--- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  controller: users
  action: show
  id: '1'
permitted: false
nil
```

2.newアクションの中にdebuggerを差し込み、/users/new にアクセスしてみましょう。@userの内容はどのようになっているでしょうか? 確認してみてください。

```
(byebug) @users
nil
```
多分newメソッドに@userがないからだと思う。
コマンドプロンプトにおけるC言語プログラムの作成

windowsを立ち上げ、コマンドプロンプトを開く。
メモ帳でC言語のコードを書く。
任意のフォルダに保存して拡張子を.txtから.cに変更。（ソースファイルの作成完了）
コマンドプロンプトでcdやcd ..(上の階層に移動)コマンドを使い、
ソースファイルを保存したフォルダに移動。(後半へ続く)
slackをtwitter化したい第3回

ちょっとごたごたがあって更新が滞った。
今日はお酒を飲みながら slack <-> heroku(nodejs) でwss通信ができるか試してみる。

## herokuの登録
適当に登録。
登録後いきなり unauth とか出てきて草
初めてgoogle 認証システムなるものを使った。訳も分からずずっとQRコード読み込めねえと思っていた。あほ
使い方わからなくて心が折れそう

なんとか node.js getting started をやってやる気を持ち直す

## やる気をなくす
events api 事態が ws 使うと思ってたけど違うのね、さらに socket mode にしないといけないと。
今のコンディションでは無理なので次回に続く
if文による条件分岐（Ruby）

**基礎編**
-
まずは、基本的な書き方から紹介します。

```
if  <条件式>　　then
  　<文>
end
```
<条件式>が真（falseとnil以外）なのか偽（falseとnil）なのかを判断して、真のときに、<文>を実行します。
実際に書いていきます。

```
number = 5
if number == 5
  puts ('5です')
end
```
説明すると、

1. numberに5を代入します
1. もし、numberが5だったら、'5です'と表示してください

こんな感じになります。このコードを実行すると、真と判断され、'5です'と表示されます。
また、<条件式>が偽と判断されると、<文>は実行されません。

**応用編**
-
さらに細かく条件を指定したいときは、ifの中にelsifやelseを加えることで指定することが出来ます。

```
if <条件式１> then
  <条件式１>の結果が真のときに実行したい処理 
elsif <条件式２> then
  <条件式１>の結果が偽で、かつ<条件式２>の結果が真のときに実行したい処理
elsif <条件式３> then
  <条件式１>　<条件式２>の結果が偽で、かつ<条件式３>の結果が真のときに実行したい処理
else
  全ての<条件式>の結果が偽のときに、実行したい処理
end
```
こちらも先ほどと同じように、thenは省略可能です。
もう少しわかりやすくなるように実際に書いていきます。

```
number = 35
if number == 20
  puts('20です')
elsif number > 30
  puts('30より大きい')
elsif number < 10
  puts('10より小さい')
else
  puts('それ以外')
end
```
説明すると、

1. numberに35を代入します
1. もし、numberが20だったら、'20です'と表示してください
1. もし、numberが30より大きかったら、'30より大きい'と表示してください
1. もし、numberが10より小さかったら、'10より小さい'と表示してください
1. どれにも当てはまらない場合は、'それ以外'と表示してください


このように書いてみました。今回は、35を代入しているので、'30より大きい'と表示されます。
最初のnumberに代入している数字を変えると、実行結果も変わってきます。

**最後に**
-
簡単な内容ですが、数字を変えたり、コードを少し変えたりすると、面白いかもしれません。
最後まで読んで頂きありがとうございました。
Mojave に brew 経由で Python3 をインストールする 私の場合

# Thanks to
https://qiita.com/takeruw/items/3540c1c618d5459195ad

# はじめに

ESP-IDFではいろいろ必要な場面があって、
`python --version` で3系となるのが目的なのだが、どうもうまくいかない。
他のマシンで公式からpkgでインストールしたときはうまくいったのだが、いろいろ使い倒したマシンなので、偶然である可能性もある。

# 作業環境

macOS Mojave 10.14.6
昨日クリーンインストールした。
`brew install python` だけでは切り替わらなかった。
とか、完全にクリーンインストール直後ではないのでご容赦ください。

# うまくいった手順

- `echo $SHELL` で bash であることを確認
- `env` で確認すると、`/usr/local/bin` が重複している。気持ちが悪いので1個だけにする。
- brewでインストールしたpythonは一旦削除 
- `brew uninstall python@3.9`
- `brew install pyenv` 実行
- `export PATH="$HOME/.pyenv/shims:$PATH` を `.bash_profile` に記載
- 以下を順に実行

```bash
pyenv install 3.9.7
pyenv global 3.9.7
```

# 最後に

さて、もう一度 esp-idf 構築からやり直してみます。
Marpでスライド作成

# Marpについて

Marpは，Markdownからプレゼンテーションスライドを作成してくれるツールです．Marpには，VSCode上で動かす「Marp for VS Code」，CLIベースでMarpを様々な形式に変換したり，プレゼンモードを起動したりする「Marp CLI」，reveal.jsのようにHTMLフレームワークとして動く「Marpit」があります．この中でも「Marp for VSCode」と「Marp CLI」を組み合わせたプレゼン作成が簡単かつ拡張性があるため，この記事では主にこの二つを扱います．
## うれしさ
- Markdownという簡単な記法
- テキストベースなので，Gitで管理が可能
- TeX数式対応（[KaTeX](https://katex.org)）
- Emoji対応 😎
- 様々な形式に変換可能（pdf, pptx, html）


## かなしさ
- 細かなレイアウトはCSSで調整が必要
- 文字の色，フォントサイズはhtmlタグで記述
- アニメーション非対応

# Marp for VSCodeの導入
[Marp for VS Code](https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode)をVSCodeにインストール後，Markdownファイル（.md）を作成し以下を記述．これだけでMarpが使えます．

```markdown
---
marp: true
---
```

VSCodeの右上にアイコンが増え，それぞれ以下のようなボタンとなっています．今，プレビューボタンを押すと白いスライドが一枚表示されます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228086/adee1a3a-4e58-122c-47f3-e9fa403d0e53.png)

## VSCodeの設定

フォントサイズやフォントの色を変える際や音声の埋め込みをする際にはHTMLタグを用いる必要がありますが，デフォルトではVSCodeのプレビューにHTML要素が反映されません．従って，有効に設定する必要があります．VSCodeの「設定」から，「marp html」などと検索すると**Marp: Enable HTML**という項目が出てくるので:ballot_box_with_check:を入れます．これで，HTMLがプレビューに反映されます．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228086/7dda986c-846c-35c1-056e-7bc49eb35d5f.png)

## Marpの機能説明・使用方法

実際にMarpを用いて機能及び使用方法を説明しています．
サンプルコード及びスライドを置いておきます．

https://gist.github.com/ioComk/1a8e85cefe00cac48747e04f577740a1

https://www.slideshare.net/RuiWatanabe3/marp-250365802

# Marp CLIの導入

VSCode上でもMarpをpdfやpptxに変換することができますが，画像の埋め込みやHTMLタグの反映が難しいため，Marp CLIを用いて生成する方が楽です．

Marp CLIはnpmパッケージとして公開されており，まずはNode.jsをインストールする必要があります．npmはNode Packaged Modulesの略称で，パッケージ管理ツールです．Pythonでいうところのpipで，Web系でよく使うツールです．今はあまり深入りせずにMarpに集中しましょう．

## Node.jsの導入

[https://nodejs.org/ja/download/](https://nodejs.org/ja/download/) から，対応するインストーラをDLしてインスコしてください．
導入が完了したら，ターミナルに`npm`と入力しなんか出てきたらOKです．

## Marp CLIのインストール

ターミナルに以下のコマンドを打つことで，Marp CLIをインストールできます．インストール完了後`marp`と打ちなんか出てきたら導入完了です．

```bash
npm install -g @marp-team/marp-cli
```

[https://github.com/marp-team/marp-cli#global-installation](https://github.com/marp-team/marp-cli#global-installation)

# Marp CLIの使用方法

## スライド生成

Marp CLIを用いてpdfを生成します．

```bash
marp --pdf <file_name>.md --html --allow-local-files --image-scale 2
```

`--pdf`のオプションが生成するファイル形式となっており，pptxを生成したい場合は，`--pptx`のようになります．
あとは，ファイル名を指定することで生成できますが，htmlタグを使用している場合は`--html`が必要となります．また，`--allow-local-files`で画像（音声）の埋め込みを行っています．
pptxを生成する場合は`--image-scale`オプションで2に指定してあげないとジャギります．

## プレゼンモードの起動

スライド生成と同様にpreviewオプション`-p`をつけてあげるだけです．

```bash
marp -p <file_name>.md --html --allow-local-files --image-scale 2
```

また，ローカルホストを立ち上げるserverモード`-s`もありますが，使いどころは限られそうです．

# おわり

以上がMarpの基本的な説明です．CSSを用いたカスタムテーマの作成については別記事に書く予定です．
RailsアプリでS3に画像をアップロードするとWe're sorry ~が表示される時の解決方法

# はじめに
EC2+Nginx+Unicorn+MysqlでRails6アプリを構築し、S3に画像をアップロードすると「we're sorry, but something went wrong.」が表示されました。ちなみに、S3を確認すると画像は保存されています。少し前までは正常に動作していたのですが・・・
結構悩んだのですが、あっけなく解決しました。

## 動作環境
・Rails 6.0.4
・Unicorn 6.0.0 
・Nginx 1.20.1
・Mysql 8.0.26
・AWS S3

## 解決方法
原因は、IAMユーザー内の設定が、知らぬ間に変わっていた事でした。(変えた記憶ない・・・)

まず、S3へのアクセス権限を付与しているIAMユーザーを選択します
![スクリーンショット 2021-10-04 20.07.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863548/7e5902e6-6914-92d1-2490-8eefeed14cf5.png)
アクセス権限のポリシーを見ると・・・
![スクリーンショット 2021-10-01 21.29.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863548/92b8a968-24d6-890a-b1db-ec17500774a9.png)
S3への権限しか付与した記憶しかなかったのですが、なんだかよくわからないポリシーが付与されています・・・

私の場合、これを削除したら問題なく動作しました!
どうやら、この「AWSCompromisedKeyQuarantineV2」というポリシーは、特定のアクションを制限するポリシーのようです。私の場合、EC2への書き込み、S3への書き込み・アクセス等が制限されていました。自動的に適用されるポリシーなのでしょうか・・・
rails serverを実施したときに、pumaについて、mach-o, but wrong architecture

#書いた理由
備忘メモ
何度も同じことが起こるので

#起こったこと

rails tutorialを進める過程で
`rails s`
を実行したとき、コケる

```
/Users/username/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `require': dlopen(/Users/username/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/puma-3.9.1/lib/puma/puma_http11.bundle, 9): no suitable image found.  Did find: (LoadError)
/Users/username/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/puma-3.9.1/lib/puma/puma_http11.bundle: mach-o, but wrong architecture
/Users/username/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/puma-3.9.1/lib/puma/puma_http11.bundle: mach-o, but wrong architecture - /Users/username/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/puma-3.9.1/lib/puma/puma_http11.bundle
```

※pythonの環境設定をしたら起こったりした…。なぜ…。

#解決したこと
ターミナルでpumaの再インストール
`gem uninstall puma && gem install puma`

ターミナルで
`bundle update`と`bundle install`

※VSCodeのターミナルだとうまく行かない

#思ったこと
何か、シェルの設定とかrbenvの使い方とかそのへんで間違っているような気がしてならない。
文字列から数字だけを取り出すor消す

いつもググってた
ttp://djcase.jp/app/mywiki/post/172
に有った記事のコピーです
どうもサイトがなくなってしまったようで・・(泣)


#文字列から数字だけを取り出すor消す
##数字のみを「消す」場合

```
$target = 'アッカリーン0120はーい！0930';
$target = preg_replace("/[0-9]/", "", $target);
echo $target;
```

上記の結果は

```
アッカリーンはーい！
```

正規表現を使って置換できるpreg_replaceを使用。[0-9]は「0から9までの数字」という意味。

$targetに対して「0から9までの数字」を空文字で置換(=消す)している。

preg_replace関数について
https://www.php.net/manual/ja/function.preg-replace.php

##数字のみを「取り出す」場合

```
$target = 'アッカリーン0120はーい！0930';
$target = preg_replace("/[^0-9]/", "", $target);
echo $target;
```

上記の結果は

```
01200930
```

[0-9]は「0から9までの数字」だったが^が付く事で否定になる。

$targetに対して「0から9までの数字」以外を空文字で置換(=消す)している。

preg_replace関数について
https://www.php.net/manual/ja/function.preg-replace.php
TypeScriptでisNonNullable関数の型の書き方に注意


結論： 返り値型に `NonNullable` を使いましょう。

```ts
const isNonNullableNg = <T>(value: T | undefined | null): value is T =>
  value !== undefined && value !== null;

const isNonNullableOk = <T>(value: T): value is NonNullable<T> =>
  value !== undefined && value !== null;

const array0 = [undefined, null].filter(isNonNullableNg);
// (null | undefined)[] 型になってしまう

const array1 = [undefined, null].filter(isNonNullableOk);
// ちゃんと never[] 型になる
```

---

標準ライブラリの `NonNullable` の定義を参考までに載せておきます。

```ts
// lib.es5.d.ts

/**
 * Exclude null and undefined from T
 */
type NonNullable<T> = T extends null | undefined ? never : T;

```
2021年Spring設定備忘録

初期設定はたまにしかしないから、よく忘れる。

# Database作る
仮にdebian系でPostgreSQLを使うものとする。

```
sudo apt install postgresql
sudo -u postgres psql
CREATE DATABASE demodb;
ALTER ROLE postgres WITH PASSWORD 'postgres';
```

マイグレーションツールを使うにしてもデータベースの設定は自分でやる。

# STSを持ってきて展開する
Spring Tool Suite を https://spring.io/tools からダウンロード。
/optあたりに置くのがよいかも。

# STSを起動してプロジェクトを作る
File -> New -> Spring Starter Project
デフォルトは Maven だけど Gradle のほうが好きだ。
Jar ではなく War を選ぶとよいかも。
ミニマムだと依存関係は以下のようなものか。

- JDBC API
- Spring Data JPA
- Flyway Migration
- PostgreSQL Driver
- Spring Web

```application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/demodb
spring.datasource.username=postgres
spring.datasource.password=postgres
```

仮にこんなテーブルが欲しいとする。

```src/main/resources/db/migration/V1__Items.sql:
CREATE TABLE Items (
       id serial,
       name varchar(15)
);
```

```src/main/java/com/example/demo/ItemEntity.java
package com.example.demo;

import javax.persistence.*;

@Entity
@Table(name = "Items")
public class ItemEntity {

	@Id
    @GeneratedValue
    private int id;

    @Column(nullable = false)
    private String name;
}
```

GETとPOSTだけでも実装してみる。

```src/main/java/com/example/demo/ItemRepository.java
package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ItemRepository extends JpaRepository<ItemEntity, Integer> {
}
```

```src/main/java/com/example/demo/ItemService.java
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class ItemService {

	@Autowired
    ItemRepository repository;

    public ItemEntity postItem(ItemEntity item) {
        return repository.save(item);
    }

    public List<ItemEntity> getItem() {
        return repository.findAll();
    }
}
```

```src/main/java/com/example/demo/ItemController.java
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("items")
public class ItemController {

    @Autowired
    ItemService service;

    @RequestMapping(method = RequestMethod.POST)
    ItemEntity postItem(@RequestBody ItemEntity item) {
        return service.postItem(item);
    }

    @RequestMapping(method = RequestMethod.GET)
    List<ItemEntity> getItem() {
        return service.getItem();
    }
}
```

# とりあえずアプリを実行する
プロジェクトを選んで Run -> Run As -> Spring Boot App するとマイグレーションが実行されてテーブルが出来る。
【GAS】Google Apps Scriptでスプレッドシートの最終行にデータを書き込む２つの方法

　今回は、Google Apps Scriptでスプレッドシートの最終行にレコードを追加する方法を解説していきたいと思います。
#appendRowメソッドでシートの最終行にレコードを追加する
　appendRow() メソッドによってスプレッドシートでデータが入力されている行の一つ下に行を追加してデータを書き込みます。
以下の書式で、カッコに渡す引数は1次元配列である必要があります。

```
Sheetオブジェクト.appendRow(配列)
```
例えば、appendRowメソッドを使ってデータを追加するスクリプトは、以下のように書くことができます。

```
function appendRecords(){
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.appendRow(['イチゴ','ブドウ',ミカン]);
}
```

appendRow() は Sheetクラスのメソッドであるので、上記のようなSheetクラスの作成の方法以外でも問題なく動作します。

この方法では行がない場合でも新しく下に挿入して書き込みをしてくれます。

#pushメソッドで配列に要素を追加する
 配列の最後に任意の要素を追加する場合は、Array（配列）オブジェクトの組み込みメソッドとして用意されているpushメソッドを使用します。

```
var Array = 配列データ;

Array.push( 追加する要素 );
```
今回サンプルとして使用する二次元配列はこちらです。

```
function productLists(){
  var sheet = SpreadsheetApp.getActiveSheet();
  //二次元配列
  var values = [
                   ["イチゴ","100円"],
                   ["ブドウ","150円"],
                   ["ミカン","200円"]
               ];  
}
```
二次元配列valuesの中に一次元配列が3つ入っています。

スプレッドシートで表すと下記のようなイメージです。
![gas3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/e8a4cd2b-2fee-0ee8-cfbe-e3a71bc89db6.png)

pushを使用すると配列の末尾に要素を追加することができます。

括弧内に一次元配列["リンゴ", "250円"]を入力することで、二次元配列valuesの末尾に一次元配列["リンゴ", "250円"]を追加することが出来ます。

```
function productLists(){
  var sheet = SpreadsheetApp.getActiveSheet();
  //二次元配列
  var values = [
                   ["イチゴ","100円"],
                   ["ブドウ","150円"],
                   ["ミカン","200円"]
               ];  
  //二次元配列の末尾に一次元配列を追加する
  values.push(["リンゴ", "250円"]);
  
  sheet.getRange(2, 1, values.length, values[0].length).setValues(values);
}
```
setValuesメソッドを実行する場合には、getRangeで配列を書き出す範囲を指定する必要がありますので、以下のように行数と列数を取得しています。

行数: valuesの要素数(=レコード数)
列数: values[0](=見出しレコード)の要素数

実行結果は下記になります。
![gas4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/2dd323cb-9e45-85c2-244b-10a5d1ae0a2e.png)


#まとめ
Google Apps Scriptで配列を使ってスプレットシートにレコードを追加する方法について解説しました。今回はシートの最終行に配列を追加するappendRowメソッドと配列に要素を追加するpushメソッドを使いました。
ABC213 C - Reorder Cards が解けて歓喜

https://atcoder.jp/contests/abc213/tasks/abc213_c

![abc213_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/0917c7b0-87ef-a4d8-3177-b3b3285db10e.png)
![abc213_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/096de8fb-14aa-4643-52c2-4ee481921d15.png)
![abc213_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/8cb27342-4954-d236-e10d-f037a8b36a73.png)
![abc213_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/a69f12b1-9c81-aad2-93fa-f9d1651ca1fa.png)

眺めてて思ったが、行列とか関係なくね？
**それぞれの要素(A1,B1...An,Bn)を小さい順に 1,2,3...N とナンバリングしなおせって問題では？**
あとはデータの形式が [A1,B1],[A2,B2],[A3,B3]... になってるから行列のようにも見えるが
冒頭のイメージがあれば [A1,B1] とかはタダのデータ構造でしかない。。

```ReorderCards_r0.py
H,W,N = map(int,input().split())
h = []
w = []
for _ in range(N):
    a,b = map(int,input().split())
    h.append(a)
    w.append(b)
 
h_ = sorted(h)#小さい順に並べ替え
w_ = sorted(w)#同上

#以下、辞書で小さい順に格納した key に i+1 と値を埋め込む
dich={}
dicw={}
for i in range(N):
    dich[h_[i]] = i+1
    dicw[w_[i]] = i+1

#冒頭の h, w を一個ずつ辞書に代入して前述の i+1 の順番を取り出した
for a,b in zip(h,w):
    print("{} {}".format(dich[a],dicw[b]))
```

しかし、見事に WA。
例えば、 [1,2] , [1,3] が与えられたとする。
冒頭の記述だと、

**[1,2]** を **[1,1]**
**[1,3]** を **[2,2]**

と認識してしまう。
望ましいのは

**[1,2]** を **[1,1]**
**[1,3]** を **[1,2]**

だ。また、for 文で回す場合は、一個飛ばした場合は、
次の数値が飛ばした値になるから、飛ばした分だけ詰めなければならない。

```ReorderCards_r1.py
H,W,N = map(int,input().split())
h = []
w = []
for _ in range(N):
    a,b = map(int,input().split())
    h.append(a)
    w.append(b)
 
h_ = sorted(h)
w_ = sorted(w)
 
dich={}
cnth=0#行の重複をカウント
dicw={}
cntw=0#列の重複をカウント
for i in range(N):
    if h_[i] not in dich:
        dich[h_[i]] = i+1-cnth # 飛ばした分を詰めて辞書に記録
    else:
        cnth += 1              # 飛ばした回数をカウント
 
    if w_[i] not in dicw:
        dicw[w_[i]] = i+1-cntw # 飛ばした分を詰めて辞書に記録
    else:
        cntw += 1              # 飛ばした回数をカウント
 
for a,b in zip(h,w):
    print("{} {}".format(dich[a],dicw[b]))
```

うん! 説明下手,俺。

解けなかった問題が解けるようになった喜びは半端ない。。
Anacondaを使わずにFaceSwapを使う話

##初めに
初めてのQiitaの為、至らぬ点が多々あるとは思います

不完全だとは思いますが一旦公開します
markdownの記法にも不馴れな為、見づらいかもしれません
適当に修正していきます

#本題
[faceswap](https://github.com/deepfakes/faceswap)(https://github.com/deepfakes/faceswap)
を実行するにあたってAnacondaをインストールしてほしくなかった為
Anacondaを使わない方法を模索した

失敗について記述すると冗長になるので要点のみ纏めます

faceswapの詳細、Pythonのインストール等については他の方が書いているものが相当数あるので割愛

####環境
OS: Windows10
CPU: Ryzen 3700X
GPU: RTX3070
Python 3.8.6



####1,公式ドキュメントに従ってgit clone
```console:cmd
git clone --depth 1 https://github.com/deepfakes/faceswap.git
```

####2,依存関係ライブラリのインストール
```console:cmd
pip install -r requirements_xxx.txt
```
xxxには適宜、cpu,nvidia,amdを入れてください
cpu: Intel製CPUで学習させたい方
nvidia: Nvidia製GPUで学習させたい方
amd: AMD製GPUで学習させたい方　※別途PlaidMLが必要になります

#####2.2 GUIを使えるようにする
```console:cmd
pip install tk
```


####3,起動
```console:cmd
python faceswap.py -h
↓GUIを使いたい場合↓
python faceswap.py gui
```
【Chrome94】#tab-hover-card-imagesの設定値を勝手に書き替えられた

Chrome バグ セキュリティ

Chrome91から全員[#tab-hover-card-imagesをDisabled](https://qiita.com/rana_kualu/items/c0c1730805387ae1b2be)にしていると思いますが、Chrome94にアップデートしたら勝手に`Enabled small full width show delay`に書き換えられました。
クソが。

この調子だと、そのうちセキュリティ設定も勝手に緩めてきそうですね。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/67c9617f-d25f-d7fa-82e7-73c16d31da1b.png)
Formsアンケートの未回答者に個別にリマインドメールをするワークフロー

###割り込みによる集中力途切れを減らしませんか？
自分宛の通知はすぐ見るようにしているのですが、たいていは回答や確認を終えているアンケートやお知らせのリマインドなので「終わっていない人に案内してくれよ…」と思うことがままあります。

発信する人からすれば、「メーリングリストで通知を出す」「全員をメンションにすれば簡単にリマインドが終わる」「私の担当しているこの案内は重要だ」、ということかと思います。ですが回答率・開封率をあげたいのであれば未回答者にだけ送る方がヘイトは減りますし、割り込み通知が減ることで各自が自身の作業により集中して取り組むことができるのではないでしょうか。


###制約、前提事項
- 在籍企業は400名程度ですが、全員を対象にまだ動作はさせていません。
- リマインダー用ワークフローは処理時間がどうしてもかかります(1分以上)。最大の処理時間の実測はできていません。
- Office365を利用しています。

###用意するもの
 - Formsのアンケートやクイズ
 - 社員一覧（Excel）
    - 社員名
    - メールアドレス
    - ステータス
    - リマインド通知日付
 - Power Automateのワークフロー２本
    - Formsで回答したらステータスを「回答済み」にする
    - 未回答者にリマインドを通知する
 
###参考にしたブログ

|参考にしたこと|記事URL|
|---|---|
|リマインダー用フローのロジックについて|よーよんさん<br>[Power AutomateでのFormsアンケートリマインダー作成方法](https://yo-yon.hatenablog.com/entry/powerautomate20201114)<br>|
|リマインダー用フローのロジックについて<br>＋実行時間がアクションによって変わる等のTips|（上記ブログ内で引用）Yellow11さん<br>[Do untilを使い、ExcelやSharePointリストのデータ取得数制限を回避して全件取得する](https://qiita.com/Yellow11/items/97e3a142c7510c8378eb)|
|「JSONの解析」アクションの使い方|ミムさん<br>[【業務効率向上】PowerAutomateのアクション「JSONの解析」の使い方](https://mimulife.com/power_automate_json_-analysis/)|
|Forms側の設定について|渡邊正和さん（ソフトバンクテクノロジー）<br>[Power Automate で Forms アンケートのリマインドを（半）自動化>１．アンケートの作成](https://www.softbanktech.co.jp/special/blog/cloud_blog/2020/0003/)|

###参考ブログからの変更点
1. よーよんさんのブログではなにかしらのデータ操作コネクタで取得したらしい動的コンテンツ、`User`が唐突に出てくる<br>→　「JSONの解析」アクションを利用して`メールアドレス`を取得する
 
2. 以下のアクション順に変更
　「変数（アレイ）の設定」アクションのアウトプットを「作成」アクションに設定　→
　　**「JSONの解析」アクション（追加）**　→　「アレイのフィルター処理」アクション

3. アダプティブカードのアクションを　「メールを送信する(V2)」アクションに変更
TWT とは

## 勉強前イメージ

wifi6のときに見たけど、
通信の必要ないときは通信をスリープモードにするってやつだった気がするけど
詳細は知らない

## 調査

### TWT とは

Target Wake Time の略で、Wi-Fi6で導入された省電力の機能になります。
以前はアクセスポイントと端末は同期していなかったのでスリープモード入ったことがわからず
端末に一斉にトリガーを投げるため端末が起きてしまい電力を使用していましたが、
TWTのパワーセーブ機能では、アクセスポイントと端末が同期してスケジュール化、
また端末ごとに起動タイミングをずらし、電力の消化を抑えます。

### TWTの対応

wifi6から技術的に導入されたので、
wifi5には非対応になります。

IoT向けの無線LANの規格である `IEEE 802.11ah(Wi-fi HaLow)` ではすでに導入されていました。

### スマートフォンの対応確認

スマートフォンでWi-Fi6 = IEEE 802.11ax が対応しているは
仕様を見れば確認できますが、例にiphoneを見てみると以下になります。
詳細は [こちら](https://support.apple.com/ja-jp/guide/deployment-reference-ios/apd1c22e481c/web) から確認できますが、
iPhone12シリーズ、iPhone11シリーズは対応していますが
iPhoneXシリーズには対応していないことが確認できます。

![iPhoneのWi-Fi仕様の詳細 - Apple サポート - Google Chrome 202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a227fc96-7b72-2b26-e2e9-e4ad7d3e2d43.png)

なので、wifi6に対応させるにはルーターと端末、どちらも見る必要があります。

## 勉強後イメージ

元々アクセスポイントと同期してなかったからわからなかったけど、
同期するようになったから出来るようになった機能ってことかな？
最近出たスマホは対応してそう。

## 参考

- [第20回　Wi-Fi6 = IEEE 802.11ax　その2](https://www.wlan-business.org/archives/25022)
- [iPhoneのWi-Fi仕様の詳細](https://support.apple.com/ja-jp/guide/deployment-reference-ios/apd1c22e481c/web)
自宅のネットワークの情報を調べる

# 前提
Windows 10 Home

# 手順
1. コマンドプロンプトを起動する
1. ipconfig と入力して Enter
1. 情報が表示される
    
```
   C:\Users\\(user)>ipconfig
   Windows IP 構成
   Wireless LAN adapter Wi-Fi:
   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: (IPv6のIP)
   IPv4 アドレス . . . . . . . . . . . .: 192.168.11.8
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .: 192.168.11.1
```
サブネットマスクが「255.255.255.0」の場合、8bit x 3 = 24bit 分がマスクされているので、PC等に割り当てられるIPは 192.168.11.1 ～ 192.168.11.254 となる。
固定IPを割り振る場合は、上記の範囲から未使用のものを選ぶことになる
Spine Skeletonの画像を切り替える方法(Unity)

# はじめに
Spineでボーンは共通でスキンのみを変えたいときがあるので、その方法のメモです。
(SpineUnityRunTimeのバージョンは4.0です)

# スキン画像でSpineアトラス用の画像プリセットを適用する
通常通りに画像を追加した場合、アセットをTextureとして取得できなくなっていたので解決方法を書きます。
(Unityは2Dプロジェクトで、何かしらの設定が間違っていたかもしれません)

Spineマニュアル通りに各種データを追加した場合の画像は正しい設定で追加されるようです。

こちらから設定をプリセットとして保存して、
![Screen Shot 2021-10-04 at 18.53.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188476/fbb5ab45-245b-7efe-0d88-63d22d0e4fbc.png)

追加した画像も同じボタンからプリセットを適用することができます。

設定を同じにすることで、問題なく画像を使用できました。

# SkeletonAnimationの場合
こちらは2Dワールド空間でスケルトンを表示する場合に使用するコンポーネントです。
以下の拡張メソッドを定義し、

```csharp
public static class SpineExtension {
    
    public static void SetAtlasTexture(this SkeletonAnimation skeletonAnimation, string materialName, Texture texture) {
        foreach (var atlas in skeletonAnimation.skeletonDataAsset.atlasAssets) {
            foreach (var mat in atlas.Materials) {
                if (mat.name == materialName) {
                    var newMat = new Material(mat) {
                        mainTexture = texture
                    };
                    skeletonAnimation.CustomMaterialOverride[mat] = newMat;
                }
            }
        }
    }

}

```

呼び出すときは

```csharp
[SerializeField] SkeletonAnimation _skeletonAnimation;

var texture = Resources.Load<Texture>("chara2");
_skeletonAnimation.SetAtlasTexture("chara_Material", texture);
```

でスキンを変えることができました。

# SkeletonGraphicの場合
こちらはUiCanvas上でスケルトンを表示したいときに使用するコンポーネントです。

## アトラスが一つの場合
この場合はOverrideTextureプロパティで新しいテクスチャをセットすれば大丈夫かと思います。

```csharp
skeletonGraphic.OverrideTexture = texture;
```

## アトラスが複数ある場合
### Multiple CanvasRenderersにチェックを入れる
![Screen Shot 2021-10-04 at 18.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188476/901cc1e8-f369-f88d-d984-02196e4c79ff.png)

### 拡張関数を実装

```csharp
public static class SpineExtension {

    public static void SetAtlasTexture(this SkeletonGraphic skeletonGraphic, string materialName, Texture texture) {
        skeletonGraphic.allowMultipleCanvasRenderers = true;
        skeletonGraphic.OverrideTexture = texture;
        foreach (var atlas in skeletonGraphic.skeletonDataAsset.atlasAssets) {
            foreach (var mat in atlas.Materials) {
                if (mat.name == materialName) {
                    skeletonGraphic.CustomTextureOverride[mat.mainTexture] = texture;
                }
            }
        }
    }

}
```

呼び出し時

```csharp
[SerializeField] SkeletonGraphic _skeletonGraphic;

var texture = Resources.Load<Texture>("chara2");
_skeletonGraphic.SetAtlasTexture("chara_Material", texture);
```
VSCodeでGitリポジトリが認識されないとき

# 概要
* VSCode Version 1.60.2 (Windows x64)で、リモート計算機 (CentOS7)に置いてあるGitリポジトリを開いたら、Gitリポジトリとして認識されなかった。
    * コミット履歴やブランチ一覧などが全く表示されないなど。
* リモート計算機にGitの最新版(ver 2.33.0)をインストールしてパスを通し、リモート計算機中のVSCodeサーバープロセスをすべて殺し、再度接続したところ、Gitリポジトリとして認識されるようになった。
* 原因はCentOS7のデフォルト(システム)のGitバージョンが古すぎたため(ver 1.8.3.1)と考えられる。
「指定の金額に対してどの硬貨を何枚出すのかを、....」を参考にvbaソルバーでやってみた。

オリジナル

https://qiita.com/dl_from_scratch/items/dddf11257e79dba1932a

#出す硬貨の数を最小にしたい場合

```vb
Const myMoney = 73
Const myMethod = "GRG Nonlinear"
Sub aaakeisan()
    ActiveSheet.Cells.Clear
MsgBox myMoney & "円で出す硬貨の数を最小にしたい。"
    Range("A1") = myMoney
    Range("A2") = 50
    Range("A3") = 10
    Range("A4") = 5
    Range("A5") = 1
    Range("A6").Formula = "=A2*B2+A3*B3+A4*B4+A5*B5-A1"
    Range("B6").Formula = "=SUM(B2:B5)"
    Dim ws As Worksheet: Set ws = ActiveSheet
    SolverReset
    SolverOk setCell:=ws.Range("A6"), _
                   MaxMinVal:=3, _
                   ByChange:=ws.Range("B2:B5"), _
                   EngineDesc:=myMethod
    SolverAdd cellRef:=Range("B2:B5"), relation:=4, FormulaText:="integer"
    SolverOptions AssumeNonNeg:=False
    SolverSolve UserFinish:=True
End Sub
'結果
'50円 B2=1枚
'10円 B3=2枚
' 5円 B4=0枚
' 1円 B5=3枚
```

#出す硬貨の数を最大にしたい場合
勉強中
Jupyter lab使ったあとにMacを再起動するとカーネルパニックが起きる件

Intel MacのMac miniでJupyter Labを使ったあとに再起動しようとすると，再起動が止まり，最終的にカーネルパニックを起こす状態でした。

実際の問題はiPythonを起動して，exitしただけで再現します。再起動するとカーネルパニック起こします。

https://github.com/ipython/ipython/issues/12083

症状的には上記と同じ状態です。
上記にOSアップデートしたら直ったとあったので，CatalinaをBig Surにしました。やっぱり起きます。
Pythonの環境はAnacondaでもpyenvで入れた3.9.4でも発生しました。

# 多分解決した方法

+ gcc等の環境を一旦削除します。（Xcode版がはじめ入っていたので，Xcodeを削除）
+ Command Line Toolsを再インストール。
+ Gccでclang version 12.0.0だったのが12.0.5に変化します。

この状態で，ipython起動したあとでもMacの再起動が普通にできます。

Gccの現状。

``` bash
$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
```
「A file with the name “GoogleService-Info (n).plist” already exists. To save the file, either provide a different name, or move aside or delete the existing file, and try again.」と出た

xcodeのディレクトリ内に、FirebaseからダウンロードしたGoogleService-info.(n番目)plistを挿入し、番号を削除した際に、タイトルに書いてあるエラーが出てしまった場合、自分の場合は、そのplistを一旦削除し、それをまたxcodeに挿入することで、番号を削除してもエラーが出ずに無事解決しました。

見にくくてすみません、ぜひお試しあれ。
ConoHa WingでSSH設定したらプライベートキーを鍵して！と怒られた

#基本環境
`macOS Big Sur 11.6`

#conoha wingでの操作
###ssh keyを作成
１）サーバー管理
２）SSH
３）＋　SSH Key

![スクリーンショット 2021-10-04 17.58.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/e4ee6161-51ce-d5c9-c9ce-1d86c50467fb.png)

１）自動生成を選択
２）ネームタグに自分にわかりやすい任意の文字列
３）保存
![スクリーンショット 2021-10-04 18.08.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/b3e33a94-5830-bd04-93bc-1865f1b96082.png)

###プライベートキーをダウンロード
ローカルにプライベートキーを保存するフォルダを用意
（フォルダ名にスペース入れない）

ConoHa Wingからダウンロード
![スクリーンショット 2021-10-04 18.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/1f935c11-0f6b-7fbb-e595-22fd96977395.png)

###接続情報を確認

![スクリーンショット 2021-10-04 18.19.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/47fe8c44-cff2-bf6e-da24-1378865662f7.png)

#macターミナル
`vim ~/.ssh/config`にSSH情報を記載

```:vim&nbsp;~/.ssh/config
Host 任意の呼び出し名
HostName ホスト名
Port ポート番号
IdentityFile プライベートキーのローカルパス
User ユーザー名
```

ローカルパスはMac上でファイルを右クリック後`option`で表示

#思わぬエラー

```
ssh 任意の呼び出し名

Permissions 0644 for '＜プライベートキーのローカルパス＞' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "＜プライベートキーのローカルパス＞": bad permissions
```

プライベートキーをしまってあるフォルダをちゃんと鍵してよ！と怒られた

鍵をする

```
chmod -R 600 ＜ローカルパス＞
```

SHHに繋がった

***
#参考記事
`https://qiita.com/ucan-lab/items/21d62f1beaa8007c4ca9`
【Flutter】form以外の部分をタップしたときにキーボードを隠す

備忘録として残します。
キーボードやform以外をタッチした時に、キーボードを消したい時の書き方です。
``FocusScope``を使ってキーボードをunfocusします！

```dart
// InkWellでつつみこみーーー
InkWell(
  onTap: () => FocusScope.of(context).unfocus(),
  child: SingleChildScrollView(
    child: Form(),
  ),
)

```

参考記事
https://dev-yakuza.posstree.com/flutter/widget/textfield/

間違いがあれば、コメントしていただけると嬉しいです！！
ある日、太郎はシャローコピーの呪いにかけられた💀

JavaScriptで以下のようなことがおきます.

```jsx
const arr = [{ name: 'taro', age: 28 }];
const newArr = [...arr];
newArr[0].name = 'HAGE'; // 新しく作った配列の要素の一部を変更しているつもりでも
console.log(arr); // 元の配列を見てみると
// 結果
[{ name: 'HAGE', age: 28 }]; // 書き換わってしまっている！
```

シャローコピーの呪いにかかったようなので解き方を書きます.

# Take1（前提知識）

俺の名は太郎.どこにでもいる成人男性である.

スペックはこんな感じだ.

```jsx
const iamTaro = {
  name: 'Taro',
  gender: 'male',
  age: 28,
};
```

そんなある日,魔の手が彼に襲いかかる.

```jsx
const taro2sei = iamTaro;

taro2sei.age = 97;
```

太郎は朝目覚めるとなんだか体が重くなっていた.

やっとのおもいで洗面所につき,鏡を見ると,おじいちゃんになっていた.

太郎:「なんでえええええええええ！！！？？？？？」

```jsx
console.log(iamTaro);
```

このときの太郎のスペック

```jsx
{
  name: 'Taro',
  gender: 'male',
  age: 97, // 書き換わってしまっている！！！
}
```

## 内部的に新しいデータが作成されているかどうかの違い？

今回の原因は以下の行で新しい変数が作られたように見えるが,参照元を代入しただけの状態で,内部的に使用されるデータ自体は新しく作成されたことになっていないようだ.

```jsx
const taro2sei = iamTaro;
```

そのため,`taro2sei`を書き換えると参照元である`iamTaro`の内部的なデータも書き換わってしまったのである.

こんな時に使用するのがシャローコピー（浅いコピー）である.参照元から値を渡して,内部的にも新しい変数が作成されるので,新しく作成した変数を変更しても,参照元のデータを書き換えることはない.

```jsx
const taro2sei = { ...iamTaro };
```

あるいは,

```jsx
const taro2sei = Object.assign({}, iamTaro)
```

と書けば,太郎はおじいちゃんにならずに住む.

また,配列の場合のシャローコピーは書き方が割と豊富でこんな感じである.

```jsx
const names = ['Taro', 'Zico', 'Sanji'];

const newNames1 = names; // 参照元の代入
const newNames2 = [...names]; // シャローコピー
const newNames3 = Array.from(names); // シャローコピー
const newNames4 = names.map((item) => item); // シャローコピー
const newNames5 = names.concat(); // シャローコピー
```

まぁとにかくスプレッド構文で新しい変数を作れば,参照元に影響されることはなさそうである（これが大きな間違いであることはまだ,知る由もなかった）

太郎:「なんだそんなことか.よかったー.」

# Take2（本題）

俺の名は太郎.どこにでもいる三兄弟の長男だ.

スペックはこんな感じ.

```jsx
const ippanPeoples = [
  { name: 'Taro', gender: 'male', age: 28 },
  { name: 'Zico', gender: 'female', age: 52 },
  { name: 'Sanji', gender: 'male', age: 21 },
];
```

そんなある日,魔の手が彼に襲いかかる.

```jsx
const newIppanPeoples = [...ippanPeoples]; // しっかりとスプレッド構文で

newIppanPeoples[0].gender = 'female';
```

太郎は朝目覚めるとなんだか胸の辺りが膨らんでいることに気がつく.

恐る恐る洗面所に向かい,鏡を見ると,アラサー女性になっていた.

太郎:「どうしてなのよおおおおおおおおお！！！？？？？？？？」

```jsx
console.log(ippanPeoples);
```

このときの太郎兄弟のスペック

```jsx
[
  { name: 'Taro', gender: 'female', age: 28 }, // genderが書きkw
  { name: 'Zico', gender: 'female', age: 68 },
  { name: 'Sanji', gender: 'male', age: 21 }
]
```

## ネストされた配列やオブジェクトはディープコピーで

残念ながら,ネストされている配列やオブジェクトに対してはシャローコピー（浅いコピー）ではその名の通り,ネスト深くまで内部的にデータが新規作成されていない様子.

```jsx
const newIppanPeoples = JSON.parse(JSON.stringify(ippanPeoples));
```

JSONになったものを戻すことによって,ネストされたデータに関しても内部的に新しく作成されるのである.これをディープコピー（深いコピー）と言う.

太郎:「 ス マ ー ト じ ゃ な い ね . 」

※用語に関しては多少あいまいです.
モデル駆動型のPower Appsのナビの消し方

## 背景

はじめてPower Appsを使う人に対して、「目の前にあるのはアプリですか？開発環境ではないですか？」という質問がありますでしょうか？

以下は僕の練習用アプリのスクリーンショットです。
上部のパープルのナビゲーションはアプリ自体と関係ないと思います。ほぼアプリ間の切り替えとか、Microsoftアカウント情報とか、システム設定などシステムラベルの機能です。エンドユーザにはまったく気にしない機能だから、カスタムメニューを使いたいと考えています。もし、非表示できれば嬉しいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/f2cbbb07-99a9-6385-597e-702fecee5200.png)

## 試したこと

グーグルしますと、「アプリ起動用のURLに`&hidenavBar=true`をつけると取り除くことができます。」というような回答が多いですけど、試した結果は残念でした。エラーが出てしまった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/51bc6a32-cf97-59cc-d54f-73b1bc7292a0.png)

もうちょっと英語のブログ([How to hide the purple Power Apps navigation bar at runtime
](http://powerappsguide.com/blog/post/hide-navigation-bar))を拝見しましたが、この解決策はモデル駆動型(MDA)に適用していないようです。（キャンバスアプリのみできそう）
一応キャンバスアプリを作成して、やってみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/e0886eb9-6b52-22fc-fc27-16999bff78c3.png)

ナビが非表示のコントロールパラメータをつけると、できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/0cbdfcca-6026-fca1-8374-513401a732e2.png)


## 解決方法

いくつかの英語記事を読んだ後、解決方法を見つけました。
下記のAPIをコピーして、右クリックの検証コンソールに貼り付けて、`Enter`キーを押す。
もちろん、4行目の`AppUniqueName`を自分のアプリ名に置き換えることが必要です。

```js
fetch(window.origin + "/api/data/v9.1/SaveSettingValue()", {
    method: "POST",
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ AppUniqueName: "Your App Unique Name", SettingName: "HideNavbar", Value: "true" })
})
```

AppUniqueNameはここで入手できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/11f4ceb1-d76d-a34b-8faa-7336d356ae15.png)

実行した後、アプリを再公開して、完成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/e325a7d2-8dc4-3768-82ec-2e5af6c621a1.png)

消した後、スッキリしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/9e3f50c9-8fd1-ee5f-c101-5d71014b755c.png)

## 参照サイト

https://xrmtricks.com/2021/09/21/how-to-display-a-power-apps-canvas-application-in-full-screen-without-the-title-bar/