OmniAICreator/Qiita-1.07M huggingface dataset:
今ある日付から、締日を求める数式


[Answersで回答する時に使う情報のまとめに戻る](https://qiita.com/Keiji_otsubo/items/9e6e0e946826133eddc7)

考え方を忘れないように残しておきます。

For example, if an Achievement Date falls within 1st April - 30th June, then the Payment Date returned is the 5th of August;  if it falls within 1st July - 30th September, then the Payment Date is 5th November; if it falls within 1st October - 31st December,  Payment Date is 5th Feb; and if it falls within 1st Jan - 31st March, then Payment date is 5th May.  

たとえば、達成日が4月1日から6月30日までの場合、返される支払い日は8月5日です。 7月1日から9月30日までの場合、支払い日は11月5日です。 10月1日から12月31日までの場合、支払い日は2月5日です。 1月1日から3月31日までの場合、支払い日は5月5日です。

元の日付から年だけをうまく使って式をつくります。

```
IF( AND(fHCM2__Achievement_Date__c >= DATE(YEAR(fHCM2__Achievement_Date__c),1,1) ,fHCM2__Achievement_Date__c <= DATE(YEAR(fHCM2__Achievement_Date__c),3,30) ),DATE(YEAR(TODAY()),5,5),
IF( AND(fHCM2__Achievement_Date__c >= DATE(YEAR(fHCM2__Achievement_Date__c),4,1) ,fHCM2__Achievement_Date__c <= DATE(YEAR(fHCM2__Achievement_Date__c),6,30) ),DATE(YEAR(fHCM2__Achievement_Date__c),8,5),
IF( AND(fHCM2__Achievement_Date__c >= DATE(YEAR(fHCM2__Achievement_Date__c),7,1) ,fHCM2__Achievement_Date__c <= DATE(YEAR(fHCM2__Achievement_Date__c),9,30) ),DATE(YEAR(fHCM2__Achievement_Date__c),11,5),
IF( AND(fHCM2__Achievement_Date__c >= DATE(YEAR(fHCM2__Achievement_Date__c),10,1) ,fHCM2__Achievement_Date__c <= DATE(YEAR(fHCM2__Achievement_Date__c),12,31) ),DATE(YEAR(fHCM2__Achievement_Date__c) + 1,2,5),
NULL))))
```

[Date Formula that returns a date based on a business qrt](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Bs17b)

# 今日の日付に基づいて四半期の開始日を計算するための数式

[今日の日付に基づいて四半期の開始日を計算するための数式](https://qiita.com/Keiji_otsubo/items/a5c79a0d01abe5435c4a)


# 前日17時～当日17時までに登録した活動レポートを当日17時にメールで配信したい。

+ [レポートの設定および通知機能について教えてください。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Tr1z5)

DATETIMEVALUEで生成した時間がGMTなので、日本時間に調整するところがポイント

```
AND( 
CreatedDate  >= DATETIMEVALUE(TEXT(TODAY()-1) & " 17:00:00") -9/24,
CreatedDate  <  DATETIMEVALUE(TEXT(TODAY() ) & " 17:00:00") -9/24
)
```

# 次の営業日のチェックボックスをトリガーすることです。（つまり、今日が金曜日で予約日が月曜日なので、今日チェックボックスをオンにする必要があります。

+ [Checkbox formula to only populate if appointment date is tomorrow (WEEKDAYS only)](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000PX25m)

:::note
TODAY() +
CASE(WEEKDAY( TODAY() ),
6,3,
7,2,
1) = appointment_date__c
:::
【Python】正規表現メモ

Sphinx拡張で使おうと思っている正規表現のメモ。
思い付く限りのパターンを試して、問題ないことを確認したサンプル。

#サンプル

```python
#!/usr/bin/python

import re

regex = re.compile(r'([ 　]*)((.*?)\|)*([^_]*)((_)([0-9a-z]*)?)?')
ps = []
ss = [
    "読み１|用語１",
    "読み２|用語２_120a3",
    "読み３|用語３_",
    "読み４|用語４_120a3あいうえお",
    "読み５|用語５_あいうえお",
    "用語６",
    "用語７_120a3",
    "用語８_",
    "用語９_120a3あいうえお",
    "用語Ａ_あいうえお",
    "  読み１|用語１",
    "  読み２|用語２_120a3",
    "  読み３|用語３_",
    "  読み４|用語４_120a3あいうえお",
    "  読み５|用語５_あいうえお",
    "  用語６",
    "  用語７_120a3",
    "  用語８_",
    "  用語９_120a3あいうえお",
    "  用語Ａ_あいうえお",
    " 　読み１|用語１",
    " 　読み２|用語２_120a3",
    " 　読み３|用語３_",
    " 　読み４|用語４_120a3あいうえお",
    " 　読み５|用語５_あいうえお",
    " 　用語６",
    " 　用語７_120a3",
    " 　用語８_",
    " 　用語９_120a3あいうえお",
    " 　用語Ａ_あいうえお",
]

for s in ss:
    p = regex.match(s)
    print(p.groups())
```

#以上
Python仮想環境作成

# 環境

* VS Code(ターミナルGit Bash)
* Python3.9.1


# 仮想環境作成

アプリ作成するフォルダに移動
env: 任意

```
python -m venv env
```

# アクティブ化

### windows

```
source env/Scripts/activate
```

### Mac

```
source env/bin/activate
```

# VS Codeインタープリンタ選択
コマンドパレットで「Python: Select Interpreter」入力し、
作成した仮想環境のPythonを選択
Nuxt.jsでFirebaseセットアップ


Nuxt.jsでFirestoreを使う。FirebaseはWeb v9(Beta)版だと上手くいかなかったので今回はWeb v8版でいきます。2021年9月時点でv9(Beta)版はかなり新しい。

公式ドキュメントはこちら↓

https://firebase.google.com/docs/firestore/quickstart?authuser=0#web-v8

## 各種インストール

```
npm install firebase@8.10.0
```

```
npm install @nuxtjs/firebase@7.6.1
```

envファイルを作成して環境変数セットするためにdotenvを用います。

```
npm install @nuxtjs/dotenv
```

## 実際のコード

```js:nuxt.config.js

require('dotenv').config()


modules: [
    '@nuxtjs/dotenv',
    [
      '@nuxtjs/firebase',
      {
        config: {
          apiKey: process.env.API_KEY,
          authDomain: process.env.AUTH_DOMAIN,
          projectId: process.env.PROJECT_ID,
          storageBucket: process.env.STORAGE_BUCKET,
          messagingSenderId: process.env.MESSAGING_SENDER_ID,
          appId: process.env.APP_ID,
          measurementId: process.env.MEASUREMENT_ID
        },
        services: {
          auth: true,
          firestore: true,
          storage: true
        }
      }
    ]
  ],

```

## envファイルの記述

```:.env
API_KEY=
AUTH_DOMAIN=
PROJECT_ID=
STORAGE_BUCKET=
MESSAGING_SENDER_ID=
APP_ID=
MEASUREMENT_ID=
```

# Vue.jsの場合

セットアップはこちらが参考になりました。

https://qiita.com/app_js/items/69f9862f7f46fe06b795
Magit infoファイル 翻訳

"It’s Magit!  The magical Git client"

キミもマジットを使ってマジシャンになろう！

- マジット(FAQ Magitの読み方は？ 参照)

- マジシャン(Getting Started 参照)

# 更新
2022/08/25 本家(712be463)を取り込んで翻訳を更新 Magit v3.3.0-git 用になりました。パーシャルチェックアウトの記述が充実したのと、マウスサポートについて簡単に追記されています(マウスサポート関連のLisp関数等については Magit-section参照)

2021/12/09 本家(1eb183e7)を取り込んで翻訳を更新。magit v3.3.0 用になりました。文書の変更は、バージョン番号書き換えと、一部文言修正、外部参照URL変更程度の軽微な修正のみです。

2021/09/25 本家(2049fd6f)を取り込んで翻訳を更新。magit v3.2.1-64-g8771401d4+1 用になりました。magit-bundleあたりはこれからの追記っぽい感じです。

# 使い方

https://github.com/kuma35/magit-docs-ja

のブランチ docs-ja より、

docs/docs-ja フォルダの

- magit.ja.info
- magit-section.ja.info
- dir

を持ってきて、それだけをフォルダに入れる。例えば ~/work/magit-docs-ja/docs/docs-ja

init.elに書き加える

(add-to-list 'Info-directory-list "~/work/magit-docs-ja/docs/docs-ja")

あなたの info の先頭に Magit(ja) とか現れる

# htmlを生成

上記リポジトリを手元にcloneしてくる。
docs/docs-ja フォルダで make html

# 注意

翻訳開始時点での Magitバージョンが 3.2.1 (de1dc8e7) でしたので更新する文書ももそれ以降のものだけになるかと思います。

ノード名の一部を翻訳してしまいましたので、外部からの参照に失敗するかもしれません。

html生成物はチェックとかしてないです。

# 翻訳手順
git switch docs-ja

cd docs-ja

make info

すると、poファイルが無い場合は生成し、
原文ファイルが更新されていればpoファイルを更新します(下記参照) 原文ファイルに更新が無い場合は make info しても poファイルはいじりません。
# 翻訳更新手順

本家から(masterに)fetchなりpullしてきます。ドキュメント以外いじってないので、docsフォルダ以外は競合は発生しないと思います。
docs-jaブランチへマージします。(git switch docs-ja; git merge master)
そしたら make infoを実行すると自動で po ファイルの更新行います。 --previous オプション付きなので、原文変更になった部分は、前の文がコメントとして入り、 fuzzy 扱いになります。 po ファイルを開いて fuzzy や obsolute や untranslated を潰してやれば更新完了です。


##持続的開発目標
流行りの SDGs です 持続的翻訳です。 巷の翻訳は大変ありがたいのですが、それを更に更新していく方法が分かりません。

あわよくばだれかが肩代わりしてくれると嬉しいななんて思います。

こちらさんを参考にさせてもらってます。

https://qiita.com/ayatakesi/items/a8a6a9bb2df6c4511185



# 翻訳の流れ(仕組み)

po4aとsedとawkを使ってpoファイルに落とし込んだあとEmacsのpo-modeで行います。

## 前処理

ソースのmagit.texiファイルはそのままではpo4aでエラーになるため加工してからpo4aに食わせます。sed-outフォルダ。

変更点は `@ifhtml` で囲った中で更に `@html` で囲ってる部分で、po4aではこの部分で警告がでます。 `@ifhtml` の中では html なのは自明で省略してもいいと判ったので単純に `@ifhtml` の中の `@html` を削っています。

## 翻訳作業

翻訳。poフォルダ

### 翻訳中の確認作業は
M-x compile で

cd ~/work/magit-docs-ja/Documentation/docs-ja ; make info

起動時に一度打ち込めばあとは補完でいけますのでEmacs起動のたびに打ってますが、めんどくさかったらshellスクリプトにするなどしてください。

### infoファイル更新時挙動

そのinfoファイルを呼び出すところから、全体メニュー(?)まで一旦戻らないと新しいinfoファイルの読み込みをしてくれないようです。その場で更新するには ```M-x revert-buffer``` です。

## 後処理

そして翻訳後 po4a-translate で生成した magit.ja.texi は削除しちゃダメな改行を削除とかしやがる(info生成でエラーになる)のでこれを個別に修正しておきます。translate-rawフォルダ

なぜかpoに変換すると


``` text
@documentencoding UTF-8 @documentlanguage en
```

と一行にしてしまいます。これを改行入れて

``` texinfo
@documentencoding UTF-8
@documentlanguage en
```

とするだけです。



## info生成

翻訳後のファイルが Document/docs-ja/magit.ja.texi と magit-section.ja.texi です。

これを info に変換したのが magit.ja.info と magit-section.ja.info です。同時に dir ファイルも生成されます。

info生成時になんとなく桁数80を指定しています。必要に応じて適宜変更して下さい。
deferの即時評価

Go言語の勉強を始めたのですが、deferで引っかかってしまった部分があったのでまとめまてみました。


>defer ステートメントは、 defer へ渡した関数の実行を、呼び出し元の関数の終わり(returnする)まで遅延させるものです。

>defer へ渡した関数の引数は、すぐに評価されますが、その関数自体は呼び出し元の関数がreturnするまで実行されません。

引用元：[A Tour of Go](https://go-tour-jp.appspot.com/flowcontrol/12)

上記の通りdeferを使うことで、呼び出している関数がreturnするまで処理の実行を遅らせることができます。
例えばファイルを閉じたりチャネルをクローズするのに使われます。
<br>

```go:サンプルコード
func main() {
	file, _ := os.Open("./example.txt")
	defer file.Close()
	data := make([]byte, 100)
	file.Read(data)
	fmt.Println(string(data))
}
```
<br>
<br>

そして引っかかってしまった部分は

```go:
func main() {
	var fruit string = "Orange"
	defer fmt.Println(fruit)
	fruit = "Apple"
}
```

結果：`Orange`

Appleが帰ってくると予想していたので、？？？となってしまいました。
実は引用文の2行目に非常に重要なことが書かれています。
>defer へ渡した関数の引数は、すぐに評価されますが、その関数自体は呼び出し元の関数がreturnするまで実行されません。

つまりdeferへ渡した関数の引数は、deferが評価された時点で値が保持されてしまうということです。だからdeferの評価後に変数fruitの値を変更しても、deferでの実行には反映されていなかったのです。


他にもdeferを使ってpanicからrecoverするとき、

```go:panic/recover
func main() {
	defer func() {
	s := recover()
	fmt.Println(s,"ok")
	}()
	panic("panic!!!")
}
```
これだとrecoverできてokが出力されますが、

```go:panic/recover
func main() {
	panic("panic!!!")	
	defer func() {
	s := recover()
	fmt.Println(s,"ok")
	}()
}
```

このようにpanicをdeferより前に書いてしまうとそのままプログラムが終了してしまいます。
Windows 365 情報まとめ

Windows 365 に関する情報をこちらにまとめていきます

# Microsoft 公式

https://docs.microsoft.com/ja-jp/windows-365/

https://docs.microsoft.com/ja-jp/microsoft-365/admin/setup/get-started-windows-365-business?view=o365-worldwide

https://techcommunity.microsoft.com/t5/windows-it-pro-blog/bg-p/Windows10Blog/label-name/Windows%20365


# Zenn 本
https://zenn.dev/takuyaot/books/60c3ced87ba86f

https://zenn.dev/takuyaot/books/507584243171c2

# その他

https://www.slideshare.net/takuyaot/it-windows-windows-365-249784610

# 動画
https://youtu.be/qKG8r1NERl4
Filecoin mining のメモ(lotus miner)

## 背景

chia plot, GPU マイニング, 機械学習やレイトレなどで性能良い SSD, GPU が余っている.
chia plot が終わったりとか, 機械学習プロジェクトが終わったとかで HW が遊体していてもったいなので活用方法を考えたい.

Filecoin mining を考えてみます.

https://docs.filecoin.io/mine/

ただし日本で合法的にできるかは要確認.

## 種類

* Storage miners : ストレージの保存に責任を負う
* Retrieval miners : ファイルの提供(retrieval)を quick に行うのに責任を負う
* Repair miners : 実装はこれから

Storage miners : ストレージ領域を提供するほどリワードがもらえる

データは 32 GiB のセクタ(sector)単位で sealing(暗号化とか?)して保存される.

Retrieval miners : データの流通チャネルみたいなもの. ファイル転送の帯域を低遅延で提供するほどリワードがもらえる
  

## HW cost

とりあえず mem 256 GB, SSD, GPU あればいいっぽそう.
SSD, GPU は GPU mining, chia plot のを流用を想定(= 調達コストゼロ)

### mobo, CPU

x299, x399 がメモリ 256 GB 対応のがあって, 中古で 1.5 ~ 2 万円(CPU も 1950X などレベルが中古で 2 万円くらい)でよいのですが, すでにディスコンであまり出回っていない印象があります.

### メモリ

DDR4 non-ECC 256 GB で 15~20 万円くらい.

### ネットワーク

インターネットは 300 GB/day の転送量が必要っぽい.

300 GB / 24 hours / 60 mins / 60 secs * 1024 = 32 Mbps くらいの回線があればいいかも.

内部ネットワークも高速である必要がある. 10 GbE or InfiniBand(40 Gbp or more)がよさそうか.

## 収益予測

https://nad128668.medium.com/filecoin-mining-system-financial-analysis-259fad2dd79a

https://medium.com/6block/top-mining-pool-6block-shares-its-filecoin-mining-hardware-specs-205fbb270ac1

## TODO

* [ ] Filecoin mining を日本で合法的に行えるか(個人/法人), 法令などを確認する.
  * データの hosting は懸念点があるが, sealing だけとか, retrieval だけなどはいけるか?
Mediapipeを使ってみた

# Mediapipeで顔認識をする話

## インストール
まずはmediapipeのインストールから。pipインストールでok。

````
pip install mediapipe
````

### MediaPipeでできること
- 顔検出 
- 顔認識
- 虹彩の追跡
- 手、上半身、全身の骨格推定
- 髪のセグメンテーション
- 物体検出
- トラッキング
- 立体的な物体検出
- KNIFT

今回行うのは上記の中にある顔検出です。

## コード

```` python
import mediapipe
import cv2 
import numpy 
import mediapipe as mp
import math
import matplotlib.pyplot as plt

mp_drawing = mp.solutions.drawing_utils 

img = cv2.imread('顔検出したい画像のpath')
mp_face_detection = mp.solutions.face_detection

face_detection=mp_face_detection.FaceDetection(min_detection_confidence=0.1, model_selection=1) 
results = face_detection.process(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

DESIRED_HEIGHT = 480
DESIRED_WIDTH = 480
def resize_and_show(image):
    h,w = image.shape[:2]
    if h < w:
        img = cv2.resize(image, (DESIRED_WIDTH, math.floor(h/(w/DESIRED_WIDTH))))
    else:
        img = cv2.resize(image, (math.floor(w/(h/DESIRED_HEIGHT)), DESIRED_HEIGHT))
    img=cv2.cv2.cvtColor(img, cv2.COLOR_BGR2RGB)    
    plt.imshow(img)
annotated= img.copy()
for detection in results.detections:
    annotated_image=mp_drawing.draw_detection(annotated, detection)
    resize_and_show(annotated)
````
このコードの実行時間は0.2321150302886963でした。なかなかの速度だと思います。
実行結果
![out.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1157150/00ea50f5-8b17-6260-4d7c-e016169934b0.jpeg)

## 色々試したい
pip install ではなくgit cloneをしてコードを取得して現在遊んでいます。
顔の座標が入力されて矩形を書いているのがここの[関数](https://github.com/google/mediapipe/blob/137e1cc7630524ea1c3a9b120985285fe43c8a3f/mediapipe/python/solutions/drawing_utils.py#L69)なので、この関数をいじって顔にモザイクをかけようとしています。
簡単にできるのですが、動画で試したらエラーが出たので、うまく動いたらだします。
[備忘録] Rust で Arduino Uno の L チカをするまで

## ファームウェアの実装

ruduino SDK　を使えばファームウェアはシュッと書ける
https://github.com/avr-rust/ruduino

Arduino Uno は atmega328p なのでそのファイルを参照する。
https://github.com/avr-rust/ruduino/blob/master/src/cores/atmega328p.rs

Pin Mapping は以下のページにある。例えば digital pin の 5 番は PD5 なのでファイル内でそれを探せば良い。
https://www.arduino.cc/en/Hacking/PinMapping168

## ビルド環境の準備

AVR-Rust というものを使う。これで cargo コマンドで AVR のビルド環境が構築できる。
https://www.avr-rust.com/

インストールは以下を参照
https://book.avr-rust.com/002.1-installing-required-third-party-tools.html

AVR 向けの tool chain は nightly にしかないので以下のようにして nightly ビルドの環境を整える必要がある。

``` sh
$ rustup update
$ rustup toolchain install nightly
$ rustup component add rust-src --toolchain nightly
$ rustup override set nightly
```

Arduino Uno (atmega328p) はビルトインのターゲットに存在しないので avr-atmega328p.json という名前でファイルを作りカスタムターゲットを用意する。

```json
{
  "arch": "avr",
  "cpu": "atmega328p",
  "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
  "env": "",
  "executables": true,
  "linker": "avr-gcc",
  "linker-flavor": "gcc",
  "linker-is-gnu": true,
  "llvm-target": "avr-unknown-unknown",
  "no-compiler-rt": true,
  "os": "unknown",
  "position-independent-executables": false,
  "exe-suffix": ".elf",
  "eh-frame-header": false,
  "pre-link-args": {
    "gcc": ["-mmcu=atmega328p"]
  },
  "late-link-args": {
    "gcc": ["-lgcc", "-lc"]
  },
  "target-c-int-width": "16",
  "target-endian": "little",
  "target-pointer-width": "16",
  "vendor": "unknown"
}
```

ここまで進めると以下のようにビルドができるようになる。 `target/avr-atmega328p/release/{Cargo.toml の name}.elf` に実行ファイルが生成される。

```sh
$ export AVR_CPU_FREQUENCY_HZ=16000000
$ cargo build -Z build-std=core --target avr-atmega328p.json --release
```

ファームウェアの書き込みは以下のコマンドでできる。

```sh
$ sudo avrdude -p m328p -c arduino -P {Arduino が接続されているポート} -U flash:w:{実行ファイルへのパス}:e
```
むずむずしたJavaコード

# むずむずしたJavaコード
普段Javaをつかった開発に従事させていただいてますが、
読む機会のあったコードの中で、おこがましいですが
「ううう、こう書いてもいいのでは」とむずむずすることがありました。

今回はそういったむずっとくるコードを改善するコードを記載できればと思います。

## foreach
```java
class Member {
   private String name;
   private int age;
   // ...AllConfigConstructor,getter,setter
}

List<Member> members = List.of(
        new Member("Tom", 21)
        , new Member("Gomez", 19)
        , new Member("Ame", 10));

Map<String, Member> teens = new HashMap<>();
members.stream().forEach(member -> {
    if (member.getAge() < 20 && member.getAge() > 9) {
        teens.put(member.getName(), member);
    }
});
```

foreachで条件合致するオブジェクトはmapに詰めるといった記述をみました。
streamのなにをしたいかが読める感じが好きなのに、
foreach内でいろいろやられると命令的に読む内容が増える。ううう。（例は簡単ですが）


filterとCollectorsつかって書き直すならこんな感じかと。

```java
Map<String, Member> teens = members.stream()
        .filter(member -> member.getAge() < 20 && member.getAge() > 9)
        .collect(Collectors.toMap(Member::getName , Function.identity()));
```

条件分岐は別で考えたい。filterで中身を整えたあとにmapに変換したい。
newの初期化も消える。

## Optional.isPresent()

ラップオブジェクトでNullPointerException回避のためにも
よくつかっているのですが、isPresentとかifPresentとか使い分けがなかなか難しい。
ううう。

```java

Optional<Member> opMember = Optional.ofNullable(member).filter(m -> m.getAge() > 50);
if (opMember.isPresent()) {
    execute(opMember.get().getAge());
}
```

とか

```java
Optional<Member> opMember = Optional.ofNullable(member).filter(m -> m.getAge() > 50);
String target;
if (opMember.isPresent()) {
    target = opMember.getName();
} else {
    target = null;
}
// ...
```
Optional.isPresent()で判定して、値があるならなにかしらの
処理をする、もしくは値を取り出す記述を見ました。
Optionalはもっと便利につかえるはず。

```java
Optional.ofNullable(member)
        .filter(m -> m.getAge() > 50)
        .ifPresent(m -> execute(m.getAge()));
```

戻りがないならifPresentにConsumerとして渡してあげられるし

```java
String seniorMemberName
        = Optional.ofNullable(member)
        .filter(m -> m.getAge() > 50)
        .map(Member::getName)
        .orElse(null);
```

Optionalもmapメソッドをもってて
空っぽであれば空のOptionalを返してくれるので便利。
if文をかかなくていいし。


ちょっとした使い方覚えるとif文とか書かなくてよくなるので
やっぱりJavadoc見たりした方がいいですね。

小さな現場からは以上です。

※上記の改善側にもむずむずする方もいらっしゃるとは思います。
その時はご指摘いただけると幸いです。
題材が少なすぎてどうにもならんかもですが。
【Ubuntu(WSL2上)】Linuxコマンド チートシート

#基本

https://eng-entrance.com/linux-what-is-command


#◆ファイル閲覧
→`cat`コマンド

https://eng-entrance.com/linux_command_cat

#◆cdでディレクトリ移動後、元の「Ubuntuユーザー名<span>@</span>MyComputer:~$」に戻りたい
現在のユーザーのホームディレクトリへの移動
→`$ cd`または`$ cd ~`

https://eng-entrance.com/linux-command-cd#i-6

#◆IPアドレス確認

|ip addr show|IPv4とIPv6アドレスを表示|
|:--|:--|

#◆WSL環境で起動したUbuntuを終了する方法
$ `exit`

https://okwave.jp/qa/q9888762.html

#◆一時的に別のユーザに替わる
`su`

https://codezine.jp/unixdic/w/su

#◆sudoコマンドとsuコマンドの違い

|コマンド|説明|
|:--|:--|:--|
|sudo|他のユーザの権限でプログラムを実行するコマンド。<br>一般的には root 権限で一度だけプログラムを実行する場合に使用。|
|su|他のユーザにスイッチする管理系のコマンド。<br>原則的には「rootのパスワードを知っている」且つ「rootにスイッチすることが許可されている」必要あり。|

http://tooljp.com/windows/chigai/html/Linux/sudo-su-chigai.html

https://atmarkit.itmedia.co.jp/ait/articles/1611/28/news036.html
プライベート関数とは

#プライベート関数とは
- スクリプトファイルに次々と関数を宣言していくと、エディタのプルダウンに多数の関数名が列挙されていき見づらくなってしまう。
- 表示させたくない関数は、関数名の最後にアンダースコアを付与することでプルダウンに表示されなくなる。
- ただし、プロジェクト内からの呼び出しは引き続き可能。


```GAS:構文.gs
function 関数名_() {
    //処理
}
```

#エディタで実際の挙動を確認してみる

##プライベート関数を使わなかった場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2024964/ba5a186b-26a9-be37-80e1-c811c5285e83.png)

##プライベート関数を使う場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2024964/1e5765bf-93bf-6aae-002f-53027662a663.png)
【VSCode】チートシート

◆ターミナルで「vi ファイルパス」→テキストファイルが開く→ターミナルに戻りたい
・エディタ→ターミナル
↓これがヒントになるか？

https://forest.watch.impress.co.jp/docs/news/1337121.html



・ターミナル→エディタ
ショートカットキー＝`Ctrl+1`
もし左右に分けて2つファイルを開いており、右側へ移動したければ`Ctrl+2`

https://qiita.com/Shun141/items/fbed88abd4518f6d4039#%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E3%81%AE%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88%E3%82%AD%E3%83%BC
HerokuのSendgridを利用してDjangoで楽々メール送信の巻

##<Djangoでメールを送信したいですか？>

もしもアプリにメール送信機能がある場合にはメールの設定が正確かどうか確認してください。
Gmailで送信する場合もあればSendGridを利用して送信するかもしれません。
私はSendGridを利用しましたので今回はSendGridの設定を例にご紹介します。

SendGridの利用方法ですがまずはアカウントの作成とHerokuのAdd-onに追加する作業を行ってください。
（ちなみに私はアカウントの取得に数日かかりました...）

SendGridをDjangoで利用する場合おそらくAPIキーを利用する方法が公式の推奨法かと思います。
APIキーの発行については公式で優しく解説してくれていますのでここでは割愛させていただきます。
https://sendgrid.kke.co.jp/docs/Tutorials/A_Transaction_Mail/manage_api_key.html


いきなりですが最終的にこの形になります。

```python:settings.py
#メール設定
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' #メール送信しますよ
DEFAULT_FROM_EMAIL = 'hoge@app.com' #送信者のアドレスです。自由に決められます。
#SendGrid設定
EMAIL_HOST = 'smtp.sendgrid.net'
EMAIL_HOST_USER = 'apikey'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
```
おそらくこの形が最新版ではないかと思います。
ちなみにAPI_KEYはもちろんHerokuの環境変数に隠しますので
```settings.py```の最終行で

```python:settings.py
if not DEBUG:
    SECRET_KEY = os.environ['SECRET_KEY']
    EMAIL_HOST_PASSWORD = os.environ['SENDGRID_API_KEY'] #追加
    import django_heroku
    django_heroku.settings(locals())
```
本番環境時には```django_heroku```でSendGridのAPI_KEYを読みます。

ちなみにDB編でもご紹介しましたがherokuの環境変数の設定は

```
$ heroku config:set SENDGRID_API_KEY='あなたのAPIキー'
```
で行ってくださいね。

SendGridのAPIを利用したメール送信は非常に楽です。また独自ドメインを用意する手間も省けますのでメール機能に時間を取られたくない開発者にはとてもおすすめです。
ですが設定がこのように若干ですが複雑なのでよく確認してください。

ちなみに私は超が付くほど頭が悪いので全然すんなり設定できませんでしたよ。
Julia でOpenAI Gym

## OpenAI Gym

[OpenAI Gym](https://gym.openai.com/)は、強化学習の環境を提供するフレームワークで、Pythonに対して提供されている。

サンプルプログラムは以下の用な感じ。`CartPole-v1`で環境を指定している。この場合はいわゆる倒立振子だ。

``` Python
import gym
env = gym.make("CartPole-v1")
observation = env.reset()
for _ in range(1000):
  env.render()
  action = env.action_space.sample() # your agent here (this takes random actions)
  observation, reward, done, info = env.step(action)

  if done:
    observation = env.reset()
env.close()
```

これを実行すると下のような図が表示されてアニメーションされる。この例では`env.action_space.sample()`で`action`を決めている。本来はこの部分で状態に応じた`action`を生成するように学習する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412142/9831ce25-60b1-c8c4-40a1-9cd5cf9aa7ca.png)

OpenAI GymのインストールにはOpenGLをインストールする必要があったりしてそれなりに面倒。

## PyCall

Gymに限らず、PythonのライブラリをJuliaから利用することができる。それには[PyCall](https://github.com/JuliaPy/PyCall.jl)を用いる。

パッケージのインストールはいつもどおりパッケージマネージャで`add`すればいいのだが、このパッケージの場合は事前に環境変数で利用するPythonインタプリタを指定しておくことが重要。デフォルトだと、Juliaが自前でかかえるConda内のPython担ってしまうらしく面倒。

``` Julia
julia> ENV["PYTHON"]="/Users/nakada/.pyenv/shims/python"
```
とかしておいてから、

``` Julia
(@v1.6) pkg> add PyCall
```
とすればいい。結構時間がかかる。また、インストールしたら一度インタプリタを再起動するようにドキュメントには書かれている。

## Julia で OpenAI Gym

インストールできてしまうと、あとは意外に簡単で、下のコードで動かす事ができた。

``` Julia
gym = pyimport("gym")

env = gym.make("CartPole-v1")
observation = env.reset()
for _ in 1:1000
    env.render()
    action = env.action_space.sample()
    observation, reward, done, info = env.step(action)

    if done 
        observation = env.reset()
    end
end
env.close()
```

かなりPythonっぽい文法に見えるが、Juliaのコードである。上のコードと見比べるとほぼそのままであることがわかる。よくできてるなー。

## 問題点
- なんか遅い。Pythonで実行するとランダムな制御なのであっという間に失敗するのだが、どういうわけか、失敗していないように見える。表示がおそすぎて、初期状態がずっと見えているだけなのかもしれない。
- 窓がクローズされない。うまく停止できていないっぽい。

とにかく動くには動いたので色々試してみよう。
BigQueryへExportしたFirestoreの情報をDataPortalで閲覧する際にハマったこと

# この記事について
FirestoreのデータをBigQueryに流し
DataPortalで閲覧したい場合にハマったことについての記事です。

関連知識まわり
[Export Collections to BigQuery](https://firebase.google.com/products/extensions/firestore-bigquery-export?hl=ja)
[データポータルを使用して BigQuery データを可視化する](https://cloud.google.com/bigquery/docs/visualize-data-studio?hl=ja)
[google/re2](https://github.com/google/re2/wiki/Syntax)
# ハマったこと
dataに含まれる指定のkeyに紐づくvalueを取得すること。

## ExportされたFirestoreのデータがBigQueryでどのように保存されるか

CollectionからBigQueryへExportされるテーブルのスキーマは以下になります。
Firestore上のDocumentはdataにjson形式で型はStringで格納されています。
![スクリーンショット 2021-09-14 23.57.04（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/f00349ae-3c35-d90d-cefe-ffecbe8b4aef.png)

例としてBigQueryへ流す対象のCollectionに含まれるDocumentの内容は以下とします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/e8c1205a-2d79-5c9b-9298-eee0a6c38e0a.png" width="350">
このDocument情報はBigQuery上ではdataFieldに保存されます。

```json
{"defense": 250,"name": "スライム","power": 200}
```

powerだけを取得したい場合Queryを作る場合以下で済むんですが・・・

```sql
SELECT JSON_EXTRACT(data, '$.power') FROM table_name
```
## DataPortal上でも同じことをしてみた・・・
Queryと同じようにDataPortal上でdataからpowerを抽出し新しくFieldを追加しようとするもJSON_EXTRACTはサポートされてない・・・
![スクリーンショット 2021-09-14 23.51.50（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/651c07bd-f13a-7577-3e8c-4bfbb561e199.png)

## 解決法

DataPortalでサポートされている関数の一つである[REGEXP_EXTRACT](https://support.google.com/datastudio/answer/7050487?hl=ja)を使いdataから正規表現で指定Keyである"power"のvalueを取得する。
![スクリーンショット 2021-09-14 23.55.47（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/d5dff385-4416-8861-3e68-a32cddb49c50.png)

REGEXP_EXTRACTはBigQueryでもサポートされているのでQueryを書くと以下になります。

```sql
SELECT REGEXP_EXTRACT(data,'"power":+([^,]+)') FROM table_name
```

# 最後に
今回はハマったことに対してサポートしてる関数を使用し正規表現で指定のkeyに紐づくvalueを取得したんですがもっと簡単な方法あるぞ！とご存じの方いらっしゃいましたらぜひご共有ください:v:
【Golang】mapに複数のキーを設定する

個人的に感動的に便利だったので、書いておきます。

## コード

mapのキーにstructを設定すると出来ます。
複数のキーで一つの値を持っておきたい時に便利です

```go
package main

import (
	"fmt"
)

type key struct {
	key1 string
	key2 string
}

func main() {
	m := map[key]string{
		key{
			key1: "hoge_key1",
			key2: "hoge_key2",
		}: "hoge",
	}
	
	fmt.Println(m)
}
// 結果：map[{hoge_key1 hoge_key2}:hoge]
```
Microsoft Teamsで投稿に「いいね」をしていないひとに対してスケジュール実行でメンションする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/01f2b8e8-e426-9669-b707-bcf63f59decd.png)

<font color="Red">2021/10/21 更新：
・「GitHubからフローをダウンロードするときの注意点」を追記しました。</font>

チームやプロジェクトのメンバーに対して提出物の依頼をしたりお知らせを周知したりする際に、完了/未完了をチェックする場面があります。

こういった完了/未完了をMicrosoft Teamsを使って管理する方法のひとつとして、「完了したひとはスレッドに返信してください」というやりかたがあります。

少人数のメンバーであれば返信を使った管理でも問題ないですが、人数が多くなってくると完了までに大きく時間がとられますし、抜け漏れが起きる場合があります。

【返信を使って完了/未完了を管理する流れ】
提出物の依頼をする
↓
完了したひとが返信する
↓
メンバーの一覧と返信したメンバーを見て、未返信のひとに催促する
↓
催促されて完了したひとが返信する
↓
また、メンバーの一覧と返信したメンバーを見て、未返信のひとに催促する
↓
（全員が完了するまで繰り返し。。。）

この手間を削減するひとつの方法として、「いいね」を使って完了/未完了のチェックを行うフローを作ってみました。

#フロー図
フロー全体の流れは下図の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/abe803c3-e7b9-fc76-7ba4-636392e12fba.png)

#使い方
まずは準備を行います。チェックを行いたい対象メンバー全員のメールアドレスを定義します。この設定は初回のみ行います。2回目以降は実施不要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/471a5e77-d371-8c13-ecce-0c3b831f0b20.png)

それではメンションのスケジュールをセットします。まずは、チェックを行う対象の本文を投稿をします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/9f4a800a-146c-63c1-1ad5-fa450b0fd40b.png)

次に、「…」をクリックして「そのほかの操作」-「提出状況をチェック」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/262cfc5d-0f25-1eac-870e-fb8afe40d592.png)

チェック実行の設定画面が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/cc488962-656b-afa6-b74e-2380deff7104.png)

「日時を指定する」を選択して、時間を指定します。日付はカレンダー形式で指定します。時間（HH:mm)は30分刻みでドロップダウンから選択します。「未完了者にメンションする」のチェックをオンにします。

ここまで入力が完了したら、「submit」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/1282a5c2-6147-8fff-be3c-4df3c2f3d503.png)

スケジュール実行がセットされた旨が自動で返信されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/648468bd-7a8e-6ba5-21ce-94ab95eb1ad2.png)

チェック対象のメンバーは、依頼事項が完了したら「いいね」を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/3936fcef-f2e9-cc7a-13ec-dc9d88624f9d.png)

指定した時間になるとフローが自動で投稿を行います。「いいね」をしたひととその時間が表形式で投稿されます。いいねをしていないひとには自動でメンションが行われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/319f7f14-fcc5-652b-66db-9d1d7314882f.png)


このフローをエクスポートしたファイルをGitHubにアップロードしました。活用していただけると幸いです。

https://github.com/wataruf01/Microsoft365/tree/main/PowerAutomate_Flow/MentionToPeopleWhoHaveNotDoLike

#【2021/10/21 追記】GitHubからフローをダウンロードするときの注意点
GitHubからフローのエクスポートファイルをダウンロードするときに、ダウンロードのやり方によってはzipファイルが破損してしまうようです。

下図の通り、「Download」ボタンをクリックして保存したzipファイルであれば正常にインポートができるようです。もし、インポートに失敗した場合はこちらの方法でダウンロードをやり直してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/a2cfee39-25de-f733-c5d5-30a114085357.png)
ABC151 C - Welcome to AtCoder から学んだ

https://atcoder.jp/contests/abc151/tasks/abc151_c

![abc151_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/ff0b239e-7046-9716-a71e-8e8295932952.png)

うーん、いけそう。

![abc151_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/1b1d19a6-b379-5532-7371-0343c58b4447.png)

だが、しかし wa.

```WelcomToAtcoder_r0.py
N,M = map(int,input().split())
 
memo = [False]*N
wa = 0
for _ in range(M):
    p,S = input().split()
    p = int(p)-1
    if not memo[p] and S == "WA":#AC未 get 問題で wa なら インクリメント
        wa += 1
    elif S == "AC":#AC なら memo を ture.AC は後で true の数を数えればいい。
        memo[p] = True
ac = memo.count(True)
print("{} {}".format(ac,wa))
```

なぜ wa なのか分からなかったから、
テストケースを確認した。

https://www.dropbox.com/sh/nx3tnilzqz7df8a/AAAYlTq2tiEHl5hsESw6-yfLa?dl=0

愕然とした。
問題文には **AC を初めて出すまでの WA の数**とある。
前述の記述では**一個も AC が無い場合、WA の数を無限に数える**のではないだろうか？

```WelcomToAtcoder_r1.py
N,M = map(int,input().split())

memo = [False]*N
wa = [0]*N
for _ in range(M):
    p,S = input().split()
    p = int(p)-1
    if not memo[p] and S == "WA":
        wa[p] += 1
    elif S == "AC":
        memo[p] = True
        
WA = 0
AC = memo.count(True)
for i in range(N):
    if memo[i]:#正解するまでの WA をカウント
        WA += wa[i]
print("{} {}".format(AC,WA))
```

***
再チャレンジ、ちゃんと理解してるかな。

問題文を読んで頭に浮かんだのは
以下のエッジケース。

```edge_case.py
2 5
1 WA
1 AC
2 WA
2 WA
2 WA
```

AC が出るまでの WA カウントが正常にできるパターンと、
AC が出ずに WA が続くパターンの混在。
対策としては、各 N 問ずつ WA をメモするリストと、
AC を True / False でメモするリストを併用して管理する必要がある。

```abc151c.py
N,M = map(int,input().split())
AC_memo = [False]*N                       #AC をメモ
WA_memo = [[] for _ in range(N)]          #WA をメモ

for _ in range(M):
    p,s = input().split()
    p = int(p)
    if not AC_memo[p-1] and s == "WA":    #未AC かつ WA なら WA としてメモ
        WA_memo[p-1].append("WA")
    elif not AC_memo[p-1] and s == "AC":  #未AC かつ AC なら AC としてメモ
        AC_memo[p-1] = True

AC = AC_memo.count(True)                  #ACは簡単。True を数えるだけ
WA = 0
for i in range(N):                        #i番目の問題で WA 数をカウントしたい
    if AC_memo[i] and len(WA_memo[i]) > 0:#条件として AC_memo[i] が True である必要がある
        WA += len(WA_memo[i])

print(AC,WA)
```

よかった。書き方にはスマートさが足りないが
ポイントを突くことが出来て、無事 AC.
GLSLからHLSLへ変換する方法



ShadertoyのGLSLのソースコードをHLSLへ変換するShaderManというツールがあるのですが、結構癖があるので説明します。

使い方などは以下にやり方が載っているのでそれを参考にしましょう。

https://github.com/smkplus/ShaderMan

## ドキュメントが古い

Open ShaderMan from Tools\ShaderManと書かれていますが、実際には2021年現在はWindow\ShaderMan です。

## エディタの癖が強い

コピへして、スクロールしようとすると、Macのマジックパッドなどでスクロールできず、矢印キー下（↓）で進んでいくと、下のコードへ辿り着けると言う仕様になっており、最初文字数制限で下にいけないのかと思ってしまうくらい、非常にわかりにくいUIです。

![スクリーンショット 2021-09-14 23.37.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1771055/2f71b1fb-8243-8472-f885-bc79a7487ed9.png)


## 構文を少しでも違うと、変なエラーが出る

例えば、Shadertoyでよくある以下のようなメイン関数で

```HLSL
void mainImage( out vec4 fragColor, in vec2 fragCoord )
```

`in` を抜いた状態でconvertを走らせると、以下のようなバグが起こります。

```
i.uvfi.uvri.uvai.uvgi.uvCi.uvoi.uvli.uvoi.uvri.uv
i.uvfi.uvri.uvai.uvgi.uvCi.uvoi.uvli.uvoi.uvri.uv
<省略>
```


## 変更しないといけないコード

``` HLSL
iFrame -> Time.y
tex2Dlod(_MainTex, uv, x) -> tex2Dlod(_MainTex, float4(uv, x, 0))
```
ID&PASS LINE bot

ブログ記事は[こちら](https://cyrus.tokyo/blog/idpass-line-bot "ID&PASS LINE BOT")
[こちら](https://qiita.com/kro/items/67f7510b36945eb9689b "PythonでLine botを作ってみた")を参考にさせていただきました。

```python
from flask import Flask, request, abort
import pandas as pd

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import os


app = Flask(__name__)

#環境変数取得
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    csv_path = './tecom_idpass.csv'
    student_number = event.message.text
    is_number = False
    reply_text = ""

    try:
        student_number = int(student_number)
        if student_number >= 5000 and student_number <= 5111:
            is_number = True
        else:
            reply_text = "整理番号が無効です。\n5001〜5111を入力してください。"
    except:
        reply_text = "整理番号が無効です。\n5001〜5111を入力してください。"

    if is_number:
        try:
            df = pd.read_csv(csv_path, encoding="shift-jis")
            data = df[df.number == student_number]
            name = data['name'].item()
        except:
            reply_text = "エラーが発生しました。"
        else:
            try:
                id = str(int(data['id'].item()))
                password = str(int(data['password'].item())).zfill(5)
                is_success = True
                reply_text = f"{student_number}\n{name}さん\n\n初期ID\n{id}\n\nパスワード\n{password}"
            except:
                reply_text = f"{student_number}\n{name}さん\n\nデータがありません。"

    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=reply_text))


if __name__ == "__main__":
#    app.run()
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

```
初学者の時に疑問だったこと!  guard let x = y else { return }編

#今回の内容

* 学習を始めてまだ１ヶ月くらいの時によく理解出来なかった`guard let x = y else { return }`について、自分なりに解説していきます。

#コードと簡単解説

*　いきなりですが`guard let x = y else { return }`について、自分が学習する中で得た答えは、未計画な`nil`が引き起こす`エラー`を回避する為に使用しています。

##例コード１
* 下記のコードの場合,`変数y`が`nil`で無い時に`print(x)`を働かすことができます。

* 実際に下記のコードを動かすと、`print(x)`は働きません。
 * 理由は、 `変数y`を宣言する時に`String?`で宣言をしています。
 * `var y:String?`の様に`?`を書いて宣言すると、値には`nil`が入ってしまいます。
 * なので`print(x)`を働かすには`guard let x = y else { return }`の処理より前に、`変数y`が`nil`では無い状態にしないといけません。

```Swift:

    var y:String?

    override func viewDidLoad() {
          super.viewDidLoad() 

          guard let x = y else { return }

          print(x)
}
```

##例コード2

* 下記のコードの場合,`変数y`が宣言時に`nil`を値として持っています。
* ですが、`guard let x = y else { return }`の処理の前で、`"Not nil"`を`変数y`に入れています。
* よって`変数y`の値が`nil`では無い状態になったので`print(x)`を働かすことができます。

```Swift:

    var y:String?

    override func viewDidLoad() {
          super.viewDidLoad() 

          y = "Not nil"

          guard let x = y else { return }

          print(x)  
}
```

#終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
【個人開発】タイピングゲーム「じゅげ〜む」を作ってみた

# はじめに
Vue.jsの勉強をかねて、タイピングゲームを作ってみました。
制作期間は5日。
意外と時間をかけてしまいました。

[https://flamboyant-beaver-eb2250.netlify.app](https://flamboyant-beaver-eb2250.netlify.app/)

[![Image from Gyazo](https://i.gyazo.com/014144e13b57dcd8e59787fd0a75e9ca.png)](https://gyazo.com/014144e13b57dcd8e59787fd0a75e9ca)

# 使用技術
フレームワーク：Vue.js
UIフレームワーク：Vuetify
ライブラリ：vue-confetti

# デプロイ
netlify

# 作ってみての感想
コンポーネントについての理解の甘さを実感し、次はコンポーネントをしっかりと活用したアプリケーションを作成してみたいと思います。
デザインがちょっと物足りなさがあるので、今後バージョンアップするかもしれません。

# おわりに
暇な時間のお供に是非ご活用ください。
作ってみてなんですが、私はまだ一度もクリアしてません。
PHPでselectBox作ってみた

##PHPでselectBox作ってみた

タイトル通りです。

```php
<?php

$busho_list = array("営業部","経理部","製造部","開発部",);
$select_option = 2;

$select_box = "<select name='busho'>";
foreach($busho_list as $key => $busho){

    $selected = "";
    if($key === $select_option){
        $selected = "selected";
    }
    $select_box .= "<option value='{$key}' {$selected}>{$busho}</option>";
}
$select_box .= "</select>";

echo $select_box;

```

変数$select_optionにデータベースから取得した値を代入することでデフォルトの選択を動的に変更することができます。

$busho_list自体もマスタなどから取得すれば選択項目も動的に作ることができますね♪

部署みたいに会社によって大きく異なる要素はPHPで動的に作ってあげることで、どんなに部署が増えてもHTMLを修正することなく選択肢を追加することができました。
ハードウェアキー とは

## 勉強前イメージ

HWで何か鍵をする？
あんまりイメージついてないけどMACアドレス指定とか・・？

## 調査

### ハードウェアキーとは

ソフトウェアの利用制御で使用される、
USBデバイスなどのハードウェアのことを指します。
PCであればUSBデバイス等で、モバイル端末であればボタンのことを指します。

主に不正アクセス等を防止する目的で使用され
端末にデバイスを接続しないとソフトウェアを使用できない仕組みになっています。
なので、ハードウェアをキーとして扱うのでハードウェアキーになります。

### ハードウェアキーのメリデメ

- メリット
	- ハードウェアに情報を格納するので、ディスクのクラッシュなどから退避出来る
	- ハードウェアキーをPCと別で管理することでセキュリティを向上することが出来る
- デメリット
	- ソフトウェアを使用するにはハードウェアは必要になり、持ち歩く必要がある
	- ハードウェアの費用も掛かる可能性がある
	- 無くす可能性がある

## 勉強後イメージ

ハード的に「これがないと動かないようにする」ってやつか
結構持ち歩きがあればキーの管理はめんどくさいけど、
PCをなくした際などのセキュリティの向上を図ることが出来る・・・・

## 参考

- [ハードウェアキー](https://www.sophia-it.com/content/%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%AD%E3%83%BC)
Android + Kotlin での HTTP リクエストの方法

## はじめに

Firebase Authentication の ID トークンを HTTP ヘッダに付与したり、独自データと JSON 文字列間の変換を行ったりすることはよくあるのですが、頻繁に使う割に忘れるので記事として残します。

## 環境

build.gradle は次のような内容になっています。

```groove
plugins {
    ...
    id 'org.jetbrains.kotlin.plugin.serialization' version '1.5.21'
    id 'com.google.gms.google-services'
}

dependencies {
    ...
    implementation "androidx.navigation:navigation-compose:2.4.0-alpha06"
    implementation platform('com.google.firebase:firebase-bom:28.4.0')
    implementation 'com.google.firebase:firebase-auth-ktx'
    implementation 'com.squareup.okhttp3:okhttp:4.9.0'
}
```

## 実装

* POST で送信
* Firebase Authentication の ID トークンを HTTP ヘッダに付与
* Firebase Authentication の認証が終えていない場合は例外を投げる
* Serializable なクラスのインスタンスを JSON 文字列にエンコード
* API サーバーから受け取った JSON 文字列をクラスのインスタンスにデコード

上記の仕様を持つ `request` 関数は次のようになります。

```kotlin
val API_PREFIX = "http://192.168.1.100:3000/api"
val json = Json { ignoreUnknownKeys = true }

@OptIn(ExperimentalSerializationApi::class)
inline fun <reified T, reified S> request(path: String, post: T): S {
  val user = FirebaseAuth.getInstance().currentUser
  require(user != null)
  val idToken = Tasks.await(user.getIdToken(true)).token
  require(idToken != null)

  val client = OkHttpClient()
  val req = Request.Builder().apply {
    addHeader("Authorization", "Bearer $idToken")
    url("${API_PREFIX}${path}")
    post(json.encodeToString(post).toRequestBody("application/json".toMediaType()))
  }.build()

  client.newCall(req).execute().use {
    val str = it.body?.string()
    require(str != null)
    return json.decodeFromString(str)
  }
}
```

正直なところ、`inline` や `reified` を使う理由がよくわかりません。コンパイルエラーを直していくと上記のコードになりました。

## 使用例

次のように使用します。Kotlin の型推論により、戻り値の型を `request` 関数で指定する必要がなくて素晴らしいです。

```kotlin
@Serializable
data class ListUsersRequest(
  val offset: Int,
  val pageSize: Int,
)

@Serializable
data class User(val id: Int, val name: String)

fun listUsers(req: ListUsersRequest): List<User> {
  return request("/users/list", req)
}
```

この関数は Jetpack Compose の Composable から使うことを想定しています。ボタンがクリックされたときなどです。その箇所のコードは次のようになります。

```kotlin
var users by remember { mutableStateOf<List<User>>(emptyList()) }
var ajax by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val handleClick = {
  scope.launch(Dispatchers.IO) { 
    try {
      ajax = true
      val req = ListUsersRequest(0, 20)
      val res = listUsers(req)
      users = res
    } catch (e: Exception) {
      // TODO: ここで Snackbar などを使ってエラー内容をユーザーに伝える
      Log.e("ERROR", e.toString())
      return@launch
    } finally {
      ajax = false
    }
  }
  Unit
}
Button(onClick = handleClick, enabled = !ajax) {
  Text("click me!")
}
```

## おわりに

HTTP リクエストを行うライブラリを公式が用意してくれると嬉しいのですが、ないですかね？
初心者がDjangoでHerokuにデプロイした際のserver error 500解決策 DB編

私自身初めてHerokuでアプリをデプロイした際にこのserver error 500に非常に悩みましたので投稿させていただきます。

まずは基本ですが開発環境（ローカルで）全てのページが正常に動作するか確認してください。
当然遷移先のページがないような場合でもserver error 500と表示されます。

それでも改善しない場合は以下の記述が正確かどうか確認してみてください。

確認するポイントとしては
・データベースの接続
・メールの設定（メール送信をする場合は）
・ALLOWED_HOSTSの設定
・staticの設定

上記の箇所が主なつまずきポイントだと思います。１つずつ正確に記述してください。

今回は１つ目のデータベースの接続について解説していきます。

##<データベースの接続は本当に問題ないですか？>
私のエラーは主にここが原因でした。
postgreSQLでもMySQLでも共通ですがHerokuのデータベースの設定には
```dj_database_url```
を使用するかと思います。こいつが結構重要なのにあまり詳しい情報が載っていないように思いました。
まずこいつはなにをするためにあるのかというと
Herokuの環境変数に設定してある```DATABASE_URL```からあなたが設定したDBのURLを持ってきてそれを設定の形に反映してくれます。つまり

```python:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
        'OPTIONS': '',
    }
}
```
これを書いているのと同義ということです。

余談ですが
```DATABASE_URL```の確認方法は

```
$ heroku config
```

使用するデータベースを変更する場合には

```
$ heroku config:set DATABASE_URL='データベースのURL'
```

ちなみになんでわざわざ環境変数に入れるの？っと私は馬鹿なので思いました。
これはデータベースの情報を外に漏らさないためですね！settings.pyをgitにプッシュしないわけにはいきませんからね。

そして記述例ですが

```python:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
        'OPTIONS': {'sql_mode': 'STRICT_TRANS_TABLES',}
    }
}
db_from_env = dj_database_url.config()#ここのカッコの中身はOPTIONSにあたります
DATABASES['default'].update(db_from_env)
```
これはあくまで私の記述方法になりますが、上で設定した項目```DATABASES['default']```
に対して
```DATABASE_URL```の情報を持ってきて上書きしている状態になります。
ちなみによくサイトに落ちている以下の記述をそのままコピペするとserver errorになります。

```python:settings.py
import dj_database_url

DATABASES['default'] = dj_database_url.config(conn_max_age=600, ssl_require=True)
```
このコードは```OPTIONS```にあたるカッコ内にも問題があります。
```conn_max_age=600```というのは60秒までしかデータベースに接続しないよ!という意味です。
（私はこれでserver error 500が出ていました。なぜか時間をおくと切断される！！となっていました。）
なので```conn_max_age```を任意の数値に設定してください。記述なし、または```CONN_MAX_AGE```なら切断はされません。
```ssl_require```も場合によってはFalseにする必要があるかと思います。


データベースの設定は確実に行ってください。
デプロイで一番大切なのは根気ではなく１つ１つを正確にすることだと身をもって学ばされました。
頭の悪い私にもできたので皆さんなら楽勝なはずです。最後まで諦めないで頑張ってください。
ABC155 C - Poll から学んだ

https://atcoder.jp/contests/abc155/tasks/abc155_c

![abc155_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/7c67b8a5-43e0-545e-b772-1fc780ccd5bd.png)

何か辞書で行けないかな？
とりあえずサンプルを見てみる

![abc155_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/1e197bfc-c281-6aee-5d9b-9d4522915c18.png)

辞書で各要素をカウント。
=> 最大値を取り出して
=> 辞書順に最大値に合うものを print する。

辞書を key / item で一回ずつソートすれば行けるんじゃね？

=> 最大値を取り出して ...item でソート
=> 辞書順に最大値に合うものを print する。...key を辞書順でソート

調べたらスグに出てきた、神。

https://www.headboost.jp/python-how-to-sort-dict

早速かいてみる。

```Poll.py
N = int(input())
dic = {}

for _ in range(N):#O(n)
    s = input()
    if s not in dic:
        dic[s] = 0
    dic[s] += 1

#item についてソート。
lis = sorted(dic.items(),key=lambda t:t[1])#O(nlogn)
ref = lis[-1][1]#最大値とりだし

#key を辞書順に並び替え
lis = sorted(dic.items(),key=lambda t:t[0])#O(nlogn)
print(lis)

for a,b in lis:#O(n)
    if b == ref:
        print(a)
```

計算量はトータル O(n) x 2set + O(nlogn) x 2set だから、
8*10^5 っと言ったところだろうか。
一応通った。
Basic operation of NIO Buffer classes

There are 4 internal indicators (capacity, limit, position, remaining) in Buffer classes, example below shows the change of these indicators.

```java
import java.nio.Buffer;
import java.nio.ByteBuffer;

public class BufferTest {

	public static void main(String[] args) {
		ByteBuffer buf = ByteBuffer.allocate(8);
		System.out.println("[new buf]");
		printBufferInfo(buf);

		buf.put((byte) 1).put((byte) 2).put((byte) 3);
		System.out.println("[put 3 elements]");
		printBufferInfo(buf);

		for (int i = 0; i < buf.position(); i++)
			System.out.println(buf.get(i));
		System.out.println("[get 3 elements by index]");
		printBufferInfo(buf);

		buf.flip();
		System.out.println("[flip]");
		printBufferInfo(buf);

		for (int i = 0; i < 2; i++)
			System.out.println(buf.get());
		System.out.println("[get 2 elements]");
		printBufferInfo(buf);

		buf.compact();
		System.out.println("[compat]");
		printBufferInfo(buf);

		buf.put((byte) 4);
		System.out.println("[put 1 element]");
		printBufferInfo(buf);

		buf.clear();
		System.out.println("[clear]");
		printBufferInfo(buf);
	}

	public static void printBufferInfo(Buffer buf) {
		System.out.println("Capacity: " + buf.capacity());
		System.out.println("Limit: " + buf.limit());
		System.out.println("Position: " + buf.position());
		System.out.println("Remaining: " + buf.remaining());
	}

}
```

The output is

```
[new buf]
Capacity: 8
Limit: 8
Position: 0
Remaining: 8
[put 3 elements]
Capacity: 8
Limit: 8
Position: 3
Remaining: 5
1
2
3
[get 3 elements by index]
Capacity: 8
Limit: 8
Position: 3
Remaining: 5
[flip]
Capacity: 8
Limit: 3
Position: 0
Remaining: 3
1
2
[get 2 elements]
Capacity: 8
Limit: 3
Position: 2
Remaining: 1
[compat]
Capacity: 8
Limit: 8
Position: 1
Remaining: 7
[put 1 element]
Capacity: 8
Limit: 8
Position: 2
Remaining: 6
[clear]
Capacity: 8
Limit: 8
Position: 0
Remaining: 8

```
myCobot Pi sshで記録再生動作実現までの手順

##はじめに
myCobot Piは動作を記録再生することができる。

<iframe width="560" height="315" src="https://www.youtube.com/embed/YN1fOaXNg68?start=193" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

こちらの動画のmyCobotはM5版なので記録再生は本体スイッチを使って簡単に行えているが、
myCobot Piにはそれがないため、自分で記録再生をできるようにする必要がある。
そこまでの手順を備忘録的に残す。

## ssh経由によるアクセス
HDMIでPCモニター等に映像を写し、USBマウス・キーボードによる操作でもよいが、、
ssh経由でmyCobot Piにアクセスも可能なので、できるようにしておくと楽。
無線でアクセスしたい場合は通常のRaspberryPiと同様に設定をしておく。
最初のコマンドはいつもと同じ。

```
ssh pi@raspberrypi.local
```

次のパスワードはお馴染みの`raspberry`ではなく、`pi`になっている。
アクセスできれば成功。

## 記録再生動作のソースコード

myCobot Pi公式マニュアルにはチュートリアルサンプルが紹介されているが、
この中には残念ながら記録再生動作をさせるものはない。
https://www.elephantrobotics.com/docs/myCobot-en/1-introduction/6-raspberry_mycobot/

記録再生動作のプログラムはElephant Roboticsのgithubの方に公開されている。
https://github.com/elephantrobotics/pymycobot/tree/main/demo

この中の`drag_trial_teaching.py`が記録再生動作のソースコードになる。
実行すると以下のようなことを聞かれる。

```
1 : /dev/ttyAMA0 - ttyAMA0

Please input 1 - 1 to choice:
```

ここは接続するCOMポートの選択で、1から1までの中から選べと聞かれている。
今は1番の`/dev/ttyAMA0`しかないため、1と入力。
入力すると、次はボーレートを聞かれる。

```
Please input baud(default:115200):
```

ここで注意なのが、`default:115200`を入れてはいけないということで、myCobot Piでは`115200`を入れて実行するとうまく動作しない。
前述のmyCobot Piチュートリアルサンプルではボーレートは`1000000`が使われているのでこれを入力。
最後にデバッグモードを使うか聞かれる。

```
Wether DEBUG mode[Y/n]:
```

Yとかにして動かしてもよく分からないバイナリデータが流れるだけなので、普通にnでいい。
上記ポートとボーレートが変えることはまずないはずなので、setup()を使わず、ソースコードに


```
port = /dev/ttyAMA0
baud = 1000000
mc = MyCobot(port, baud)
```

と直接入力してしまうのがいい。

実行するとコマンド入力画面になる。

```
 q: quit
 r: start record
 c: stop record
 p: play once
 P: loop play / stop loop play
 s: save to local
 l: load from local
 f: release mycobot
----------------------------------
```

表示されている通り、rで記録開始、cで記録終了、pで再生、Pでループ再生、sで動作保存、lで動作読込、fでサーボオフ、qで終了。
基本的には動作を作成する場合はr→c→p→fを繰り返して望む動作を作成。記録後に保存したい時にsを使う流れになる。
Windows Server 2012にOffice2019はインストールできない

##はじめに
PCには64bit版のOfficeがインストールされており、
とあるExcelマクロは32bitを想定して作られている。
よってこのPCではマクロが動かせない。（いろいろとエラーが出る。）
ということで、２つの手段を検討してみました。

**検討１．PCに32bitと64bitのOfficeが共存させる**

**検討２．仮想サーバに32bit版のOfficeを入れて、リモートデスクトップ接続して、そこでマクロを動かす**


##検討１．
これについてはMicrosoftが公式に「できない」と謳っていたため、早々に諦めました。
（最初っからこれは無理だと思ってましたので、想定内。）

##検討２．
WindowsServerにOffice入れるだけでしょ？簡単簡単！と思っていたら、想定外のところでハマってしまったので少しまとめます。

##やったこと
早速Office2019ライセンスを購入し、インストーラをダウンロードしてWindows Server 2012上で実行したところ、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980545/7818427f-d276-1119-6291-2d2a977f6645.png)

こんなメッセージが出てインストールできませんでした。
**Office2019をインストールするには、Win10が必要**みたいです。

じゃあOffice2016をインストールすればいいかと思い、インストーラをネットから探してこようとしましたが、これがなかなか見つからない。
インストーラは誰でもダウンロードできるだろうとたかをくくっていた私が甘かったです。
購入したOfficeライセンスと紐づけているMicrosoftアカウントでサインインしないとダウンロードできません。

幸いにも以前Office2016を購入したときのアカウントが残っていたので、そのアカウントでサインインして2016のインストーラを無事にダウンロードできました。

気を取り直してサーバにOfficeのインストールをすべく再チャレンジ。結果インストールはすんなりできましたが、**ライセンス認証が通りません。**
上位バージョンのOfficeライセンスがあれば下位バージョンのOfficeはライセンスが通るとばかり思っていたんですが、**これも大きな間違いでした。**

ということで、最後の手段です。
Office2016が入ってるPCを2019へアップグレードし、空いた2016ライセンスをWindows Serverで使うというところてん式で事なきを得ました。

##おわりに
ただ単にOfficeをインストールするだけの作業に丸一日費やしてしまいました。
確認不足や思い込みが招いた悲劇？でした。
PC98シリーズの起動音をハードウェア実装する

RaspberryPIの起動音が寂しいのでarduinoで作りました。
なんでもいいからUSBにつなげておくと通電時に一回だけ鳴ります。
<iframe width="560" height="315" src="https://www.youtube.com/embed/sX_OqmscHF4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

【準備】
arduinoの2番ピンとGNDにスピーカーをつなげろ。

【コード】

```C:pc98.ino
#define SPEAKER_PIN     2       // スピーカー接続ピン
#define TONE_HIGT       2000    // 高音周波数
#define TONE_LOW        1000    // 低音周波数
#define DELAY           100     // 待ち時間(ms)
#define OFF             0       // 再生まだ
#define ON              1       // 再生済み

int flg = OFF;  // 再生フラグ

void setup() {

}

void loop() {
        if(flg == OFF){                         // 再生済み？
                tone(SPEAKER_PIN, TONE_HIGT);   // 高音再生
                delay(DELAY);                   // 待ち
                tone(SPEAKER_PIN, TONE_LOW);    // 低音再生
                delay(DELAY);                   // 待ち
                noTone(SPEAKER_PIN);            // 再生停止
                flg = ON;                       // 再生済みにする
        }
}
```

コンパイルしてローディングすれば動くはず。
知らねえけど。
機種によって音と長さが微妙に違うので、調べて各機種の起動音を再現しましょう。

オワリ
dockerでphpのサーバーを立てる

カレントディレクトリにphpファイルを置く。

```index.php
<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
 <?php echo '<p>Hello World</p>'; ?> 
 </body>
</html>
```

apacheが含まれているdockerコンテナを動かす。

```
docker run -it --rm --name php -p 80:80 -v $PWD:/var/www/html php:apache
```

サーバーが立つ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396969/05423136-a2ba-c02e-45c7-9243910d854c.png)
ViteをVue+Amplifyプロジェクトに導入する時に困ったこと&解決策

# はじめに
Viteとは、vue-cliと比較して高速で動作するビルドツールです。
筆者はVue.jsとAmplifyを利用したプロジェクトを作成しているのですが、プロジェクトが大きくなるとともにビルド時間が掛かるようになってしまい、困っていました。そこで試しにviteを入れてビルド時間を短縮できるか試すことにしました。

# 困ったことと解決策
1. viteがそもそも動作しない
amplifyモジュールが古い場合にviteを入れたことで起動しないようです。
モジュールのアップデートを実行しましょう。

1. viteと相性が悪いモジュールが存在する
筆者の環境ではある1つのモジュールが動作しなかっため、アンインストールしました。

1. 起動後にエラーが発生する
筆者の環境では、コンソール上に`Uncaught ReferenceError: global is not defined`
というエラーが発生しました。

[こちらのStackOverflow](https://stackoverflow.com/questions/66912795/in-vite-vue3-ts-project-aws-amplify-failed-to-resolve-components)を参考に解決しました。
index.htmlに下記のコードを追加すると解決します。

```
<script>
  var global = global || window;
  var Buffer = Buffer || [];
  var process = process || {
    env: { DEBUG: undefined },
    version: []
  };
</script>
```

# 感想＆まとめ
vite導入前は数分かかっていた起動が数秒に短縮されました。予想以上に早く、非常に可能性を感じました。
ただ、viteを導入する過程でモジュールの置き換えが必要になったことや、動作させるために準備が必要なことから、今回の導入は見送ることにしました。