OmniAICreator/Qiita-1.07M huggingface dataset:
正規表現で記号が入った文字をチェックするには



#### お問い合わせなどの入力フォームで名前に記号などの文字が入っているかチェックしたい

記号が入っている名前はいたずらの可能性がある

正規表現で記号かどうかチェック

`[^!"#$%&'()\*\+\-\.,\/:;<=>?@\[\\\]^_`{|}~]+`


でもこういうのもチェックしたい

`①②③㌢〒♡♢`

記号や機種依存文字を全部書いてもいいが、大変なので、いっそのこと許可する文字以外だったらNGにする
ひらがな、英数字、漢字、句読点、空白
`^[ぁ-んァ-ヶーa-zA-Z0-9一-龠０-９ー、。\n\r]+$/u`

でもそうすると名前で使われている機種依存文字もNGになってしまう。

こういうやつ
`謹祐神﨑謁逸敏﨏㘴隆晴𠮷海朗都羽㤗㟢﨑々猪猪隆繁飼祥塚悅悊惞惕愠`

今回はmysqlに登録してある正規表現に一致したらNGみたいな処理を使おうとしたが、限界なので、php側でチェックすることにした。

こんなやり方がある！

PHPで機種依存文字をチェック（https://mgng.mugbum.info/60）

> mb_convert_encoding を使って UTF-8 → SJIS (SJIS-winじゃないよ) 変換すると、機種依存文字が「?」になるので、あとは元文字列とバイト数比較すればいいだけ。一応以下スクリプト実行して「OK!」表示されることを確認。

```
function check($s){
  return strlen($s) !== strlen(mb_convert_encoding(mb_convert_encoding($s,'SJIS','UTF-8'),'UTF-8','SJIS'));
}
```

なるほどおおおお
xmlのshapeタグって意外と自由度が高いっていう話 part1

# 初めに
今回からxmlの`shape`タグで使えるものをシリーズ化して紹介していこうと思います。
トップバッターは最も使われているであろう要素である`corners`です。

## 本文
こちらは、その名の通り角丸にすることができます。
`dp`を値として渡し、渡した値が角丸の半径になります。
`corners`と言っても要素として一括で角丸を指定する`radius`と各種四隅ごとに設定できる`topLeftRadius`等があります。
こちらを使用することで下記の様なViewを作れます

```xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white"/>
    <corners android:radius="12dp"/>
</shape>
```
![スクリーンショット 2022-03-31 17.19.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638092/3278e4dc-ea46-d2b6-19ce-eeba929b42d0.png)

注意点として、xmlでいじってる際は長方形に引き伸ばされた形がレビューとして表示されているので、実際に使用する画面で見て見ない限りは期待通りの見た目になっているかどうかわからないという点です。

## 最後に
今回から始まった`shape`タグで作れるViewシリーズですが、次回は`stroke`あたりを紹介しようかなと思っています。
次の記事が投稿でき次第こちらにも次の記事にもシリーズの導線を置いていこうと思うので、どなたかの力になれれば幸いです。
Ubuntu 20.04.4 LTS(Server版)で固定IPの設定

`Ubuntu 20.04.4 LTS`はインストール時にIPの設定を行う。DHCPサーバからIPを取得する設定にしたが、後から固定IPにする必要が生じたため、その際に設定した方法をメモする。

# 状況
* VMware Workstation上にUbuntu 20.04.4 LTSのサーバ版をインストール
* 初期設定でDHCPサーバからIPを取得するように設定
* 自宅のWAN側グローバルIPアドレスに届いたHTTPリクエストを今回の仮想サーバ(Ubuntu 20.04.4 LTS)にポートフォワーディングをしたいのだが、その際アドレスが動いてしまっては困るため、固定IPの設定を行いたい


# 使用した方法
1. 現在のネットワーク設定ファイルを無効化
1. 目的の設定を記述した新規設定ファイルを`/etc/netplan/`に配置
1. 新規設定ファイルを有効化

# 手順
## 1. ネットワーク設定ファイルの無効化

`Ubuntu 20.04.4 LTS`のサーバ版をインストールすると、ネットワーク設定ファイルが`/etc/netplan/00-installer-config.yaml`に設置されるので、catコマンドで内容を確認。
```00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      dhcp4: true
  version: 2
```
上記4行目の「ens33」はネットワークインターフェース名であり、新たに設定ファイルを作成する際に必要となるため、メモしておくとよい。また、ens33のタブに`dhcp4: true`の記載からDHCPサーバからIPを取得していることが確認できる。

この設定ファイルを無効化するには、設定ファイルを削除するかファイル名を変更する。今回はファイル名を変更して無効化する方法を使用した。

```
~$ sudo mv 00-installer-config.yaml 00-installer-config.yaml.disabled
```

:::note warn
cdコマンドで対象のファイルがある場所へ移動してからコマンドを実行
:::

## 2. 新しい設定ファイルを作成 

sudoeditコマンドを使用し、`99-netcfg.yaml`という設定ファイルを新規作成して内容を記述する。
```
~$ sudoedit 99-netcfg.yaml 
```

以下は自分が記述した固定IPの設定例である。

```99-netcfg.yaml
network:
  version: 2
    ethernets:
      ens33:                           // ネットワークインターフェース名 
        addresses: [192.168.1.159/24]  // IPアドレス(CIDR記法)
        gateway4: 192.168.1.1          // ゲートウェイ
        nameservers:
          addresses: [192.168.1.1]     // DNSサーバ
          search: []
        optional: true
```

## 3. 設定を反映させる
2.で作成した設定を反映させるには以下のコマンドを実行する。

```
~$ sudo netplan apply
```

何も出力されなければ正常に反映されている。
再起動を行い、ip aコマンドなどでIPが固定されているかを確認するとよい。

## 補足：`/etc/netplan/`に設定ファイル(YAML)が複数ある場合

設定ファイルが複数ある場合には、**ファイル名の辞書順で設定がマージ**される。
設定項目が重複する場合、ファイル名の辞書順で上書きされていく。`00-...yaml`, `10-...yaml`, `20-...yaml`とあった場合、`20-...yaml`の設定が反映されることになる。
Qiitaで自己紹介文を書いたら怒られた話

# 自己紹介
はじめまして。
株式会社オムニバスワンダーラボに勤めている坂本晴輝と申します。
東京から沖縄に移住し、現在ぴかぴか1年生のエンジニアです。
# Qiitaを始めた経緯
エンジニアを繋ぐIT勉強会支援サイトconnpassで小島優介(kojimadev)さんが主催されているオンラインLT大会でエンジニア1,2年目の方々が堂々と発表している姿に圧倒的な差を感じ、発信活動を始めてみようと思いました。

小島優介さんがLTでもご使用されたQiita記事↓

https://qiita.com/kojimadev/items/f4a6539e4fbc641c6fa0

LT大会のyoutubeのリンク↓

https://youtu.be/8UZoqQmcxU4

# 最後に
自身の備忘録を含め、新人エンジニアの方やプログラミング初心者の方に少しでも参考になるような記事を書けたら良いなと思っています。
未熟者ではありますが、これから宜しくお願い致します。

※追記：この投稿をした後、Qiitaの先人の方にコメントでご指摘頂きました。
Qiitaのコミュニティガイドラインにも投稿すべきではない部類に記載がありますので、
これから記事を書いてみようかなと思った投稿初心者の方はくれぐれもお気をつけください。
最小二乗法の三次元版

最小二乗法の三次元版っていうのを scikit-learn でやってみました。

```python
# データセットの取得
from sklearn.datasets import load_iris

dataset = load_iris()
X = dataset.data[50:100, [0, 1]]
Y = dataset.data[50:100, 2]
```


```python
# 最小二乗法による線形回帰
from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X, Y)
```




    LinearRegression()




```python
# 三次元プロット
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(X[:, 0], X[:, 1], Y)

plot = np.array([
                 [X.min(axis=0)[0], X.min(axis=0)[1]], 
                 [X.max(axis=0)[0], X.max(axis=0)[1]]
                 ])

ax.plot(plot[:, 0], plot[:, 1], model.predict(plot))

ax.set_xlabel('X0')
ax.set_ylabel('X1')
ax.set_zlabel('Y')

plt.show()
```


    
![最小二乗法の三次元版_2_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/2b872663-b312-8879-8aa2-c75fb6c1f5fe.png)

こんな感じで合ってますか。
M1 Pro MacBookProでWordPress（docker-compose）を使ってみました

# 目次
- 始めに
- ローカル環境
- 構築手順
# 始めに
最近自分用のブログ・勉強メモ帳を作りたいと思って、使えるツールやフレームワークを調べてみました。
HexoとWordPressを考えましたが、持つ機能を考えた上で、ローカル環境にDockerを使ってWordPressサイトを構築することにしました。
# ローカル環境
- MacBookPro 14"(2021) 10 Core CPU, 14 Core GPU
- Docker Desktop 4.5.0
# 構築手順
## 1.作業フォルダーを構築する
```bash
$ mkdir ./WordPressProject
$ cd WordPressProject
```
## 2.docker-compose.ymlファイルを作成する
作業フォルダーにdocker-compose.ymlのファイルを作成して、下記の設定を入れます。
```yaml
version: '3'

services:
   db:
     platform: linux_x86_64
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: root
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:
```
`platform`を明示的に書いていることを注意してください。
M1 ProチップはARM CPUなのでデフォルトの`platform`値が`arm64`になります。`x86_64`に設定しないと、構築時に下記のエラーメッセージが出てしまいます。
```
ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries
```
## 3.プロジェクトを構築する
作業フォルダーで下記のコマンドを実行する
```bash
docker-compose up -d
```
無事構築出来た後、ブラウザーで`http://localhost:8000`にアクセスしてWordPressのセットアップ画面が見れます。
設定や投稿はブラウザーで完成できます。
# 参考資料
https://zenn.dev/persona/articles/50f87da99c92af
https://qiita.com/jizya/items/38f15271903de629d1ab
春から大学生（情報・工学）の方へ～プログラミング入門番外編～（他学部などでのプログラミングの授業）

# 第１回
https://qiita.com/HaaSAtC/items/490d066bdbec8441a2f6

# はじめに
情報・工学系以外の学部でもプログラミングの授業はあります。
その中でも私が見聞きしたもの、実際に受けたものなどを学部ごとにあげていきたいと思います。

# 経済系学部
データ分析を行うので、Pythonの授業があります。一応Excelでも簡単な分析はできますが、論文に使うような高度な分析だとPythonやR言語を使うのでしょう。

# 芸術学部
私が受けたものだと、JavaScript言語でお絵かきやアニメーションを作るものがありました。（p5.js: https://p5js.org/）

# その他
Webプログラミングや、大学によってはAndroidアプリ開発の授業などもある（近畿大学）とかなんとか…
ZIG SIM PROとTouchDesignerでNDI飛ばす時の覚書

# 使用したデバイス
　iPhone 12 pro
　iOS 14.2.1

# NDIが上手く接続できないとき
　Firewallが有効になっていないかチェックする

# ZIG SIM のdepthとdisparity
　深度情報はRGBAのアルファチャンネルに入ってる。

　Camera → FRONT
　Depth Type → DEPTH
　遠くが白(255)、近くが黒(0)
　なんだけど1mくらいしか見えない。32bitでとって8bitで送信してる？

　Camera → FRONT
　Depth Type → DISPARITY
　遠くが黒(0)、近くが白(255)
　結構遠くまで見える

　Camera → REAR
　Depth Type → DEPTH
　遠くが白(255)、近くが黒(0)
　超広角カメラと広角カメラで差視を取ってるっぽい
　1mくらいしか見えない。32bitでとって8bitで送信してる？

　Camera → FRONT
　Depth Type → DISPARITY
　遠くが黒(0)、近くが白(255)
　超広角カメラと広角カメラで差視を取ってるっぽい
　結構遠くまで見える

　背面のライダーは指で隠した状態でも動くので、
　**背面のLiDARは使われていない(と思う)** →　ZIG CAMを使おう

# 座標系がなんか合わない
　TouchDesignerの座標系は **右手系、up軸y**
　オペレーターのwindowなどは**左下が原点となる**
　また、上記に示す通り使用する設定によっては**z軸が反転する**ので注意

# iPhone(iPad)のカメラ行列は？
以下を参考にswiftアプリ内からも取得できるが、

https://qiita.com/shirahama_x/items/e489f12d60e2e3e90498

以下の参考リンクのように、推定することもできる。(記事内のcalc_K)

https://dev.classmethod.jp/articles/convert-coords-screen-to-space/

ただし、これは本来レンズに固有のパラメータではあるが、スマホのカメラのように、オートフォーカスなどでリアルタイムにレンズの特性が変化するようなデバイスは、本来は常時算出することが望ましい。

# デバイスが変わったらなんか挙動が違う
　iPhoneとiPad、各世代で微妙に配置やスペックが違っていたりする

　https://www.itmedia.co.jp/mobile/articles/2011/20/news031.html
　https://xtech.nikkei.com/atcl/nxt/column/18/01459/102800001/

　レンズについてはここが詳しい

　https://xn--35mm-y27hg92j.com/cameras/apple/iphone12promax/

# NDIは各チャンネル8bitしか送れない?
(2020年あたりの情報)

https://support.newtek.com/hc/en-us/articles/218109667-NDI-Encoding-Decoding
https://forums.newtek.com/threads/10bit-ndi-options.162178/

```
NDIは常に内部的には16ビットですが、YUV 8ビットフォーマットを使用したオンランプとオフランプによって人為的に制限されています。
理論的にはNDIに16ビット（つまり10ビット）を入出力する方法がありますが、まだ全てのプラットフォームで完全に実装されているわけではありません。
つまり、機能は提供されつつありますが、まだ完全には提供されていないのです。

例えばSienna NDI Signal Generatorは長い間テストストリームとして10ビット（または16ビット）をサポートしてきましたが、NDI SDKが全てのプラットフォームで16ビットを完全にサポートし、主要ベンダーがソフトウェアをアップデートしてサポートするまで、おそらく私たちはもう少し待つ必要があります。

そうすれば、10ビット以上のワークフローをエンドツーエンドできちんとサポートできるようになります。
```
Vue.js Tips

# Vue.jsの豆知識

* JSはケパブケースではなくキャメルケースで記述する
例） ❌test-code ⭕️testCode

* computedは　returnで値を返す
* computedはデータの変更がない限り一回のみの実行
* documentのvmはビューインスタンス(``let hoge = new Vue({})``　の``hoge``のこと
* computedより複雑な処理はwatchを使える
* フォームのバリデーションは自作で作ると誤りや漏れが生じやすいため[VeeValidate](https://vee-validate.logaretm.com/v3 "VeeValidate")等を使うと良い。
* v-modelの書き方について２種類使い分けられる[v-model ２種類](https://jp.vuejs.org/v2/guide/components.html#%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%A7-v-model-%E3%82%92%E4%BD%BF%E3%81%86 "")
* Vue CLI のファイルは package.jsonで記述の内容がnode_modulesの中に格納されている。
* distフォルダには本番環境にアップする際、コンパイルした内容が格納される(webpack等使用時）：　```npm run build```を実行しコンパイルするとdistフォルダが作成される。
* gitにはdistやnode_modulesは不要（package.jsonは必要）
* ```v-bind:value = 'hoge'```　は ```:value = 'hoge'```で省略可能
* ```v-on:input = 'fuga'```は ```@input = 'fuga'```で省略可能
spread sheet を活用したVCT JPまとめ(失敗編)

VALORANT Champions Tour stage1の日本予選が終了しました。

大学のサークルにて大会に出る機会が増え、日本のメタを追うために個人的なまとめをしていました。
しかし、今まで使用していた表ではとても効率が悪いため、記述方法を一新。
今回の記事では、過去に使用していたプログラムと、その問題点をまとめます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321297/27aa63f9-f1fe-9c69-3686-a436b81095bf.png)

これは去年作成したspreadsheetで
**1行**をイベント名
**2行**を対戦相手
**3行**をMap名
**4~21行**をキャラクター名とし
ピックされたキャラは**1**　
ピックしていないキャラは**0**
と手動で入力しました。

[前回の記事](https://qiita.com/kir1n/items/0585c9657eeaa92b49e7)で紹介した方法を用いて、pythonに読み込んだ後以下のプログラムでピック率の計算を行いました。
```py
worksheet_len = [ pd.DataFrame((workbook.get_worksheet(j)).get_all_values()) for j in range( len( worksheet_list ) ) ]
list_len = [worksheet_len[p].iloc[1].to_list() for p in range( len( worksheet_list ))]
#ilocのところに求めたい行を入れる
ave = 0
for j in list_len :#すべてのワークシートの1行目がJに入る
    int_list = [ int(k) for k in j ]#jの中身をｋ
    ave += np.mean( int_list )#シートの枚数分回して合計の平均値
ave_fin = ave/ len( list_len )
print(ave_fin)
```
その後、別のスプレッドシートに書き出す。
```py
workbook = gc.open_by_key('')#スプレッドシートのトークン
worksheet = workbook.get_worksheet(0)
worksheet.update_cell(19, 2, ave_fin)#入力セル指定
```
:::note info
もちろん、同じシートに書き出すことも可能
:::

出力結果は以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321297/328f8081-c490-5c55-8bbf-8642134504ed.png)

<d1>
 <dt>生じた問題点</dt>
 <dd>1.入力が面倒な上に効率が悪い</dd>
 <dd>2.Mapやキャラの絞り込みが難しい</dd>
 <dd>3.キャラが追加された際、プログラムの大幅修正が必要</dd>
 <dd>4.これ以上の情報を得られない</dd>

**1** について
　行がずれたことを確認しにくい。
　プログラムをキャラの回数だけ実行しなければならない。
　連続で実行しようとしてもspreadsheet側にはじかれる。
　1列目に文字を入れているとエラーが出て計算ができないために、計算段階で1列目を消す必要がある。
**2**について
　キャラのピック率を計算することとマップを絞り込むことの両立が技術的に不可能だった。
　このマップだけについて見たい！を簡単に作れない。
**3**について
VALORANTは2~3か月に1回ほどのペースでキャラ(エージェント)が追加されるが、そうなった際に以前使っていたシートを利用することができない。
入力ミスを防ぐためにロールごと分けていたが、もしデュエリストが追加されると後の行が1段ずつずれる。

:::note warn
補足
ここにおけるロールは
デュエリスト,センチネル,イニシエーター,コントローラー
であり、順に上からまとめていた。
:::

**4**について
この表では、だれが何を使ったのかが記述されておらず、競技シーンの一番大事(だと勝手に思っている)な個性を生かしたピックが一切読み取れない。
拡張性もなく、何か追加で知りたい情報があったとしても同一のシート上で計算する要素を増やせない。

以上のように、一度作ってみたはいいものの、実用性もなく、没となった。
この程度の情報であれば、すでにインターネットにもっとわかりやすい形で情報があるので、
そちらを利用したほうがよいだろう。
[Drupal]リビジョン周りのチートシート

※随時更新予定

## NIDから最新のリビジョンIDを取得する
```php
$vid = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->getLatestRevisionId($nid);
```

## リビジョンIDからリビジョンをロードする
```php
$node = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadRevision($vid);
```

## ノード保存時に新しいリビジョンを作成する
`$node->setNewRevision(TRUE)`にした場合、リビジョンユーザーと更新日時、リビジョンログメッセージ等のプロパティの値を明示的に値をセットしないと前のリビジョンの値が使われるので注意.
ちなみにContent ModerationとWorkflowsモジュールでワークフローを実装している場合は、デフォルトで`$node->setNewRevision(TRUE);`がセットされるので、リビジョンが勝手に増えてもびっくりしないように...
```php
$node->setNewRevision(TRUE);
$node->setRevisionUser($user);
$node->setRevisionCreationTime($timestamp);
$node->setRevisionLogMessage($message);
$node->save();
```

## 最新リビジョンかどうかをチェックする
```php
// 最新リビジョンの場合はTRUE.
$node->isLatestRevision();
```

## デフォルトリビジョンかどうかをチェックする
```php
$node->isDefaultRevision();
```
【C#】LINQのクエリ結果に対して複数回反復処理をしない


タイトルの通りです。レビューで指摘されたことの備忘録として書きます。

## なぜLINQのクエリ結果に複数回反復処理をしてはいけないのか

反復処理の回数だけクエリが実行されてしまうため。

LINQはクエリ結果が必要になったときに初めて実行される(遅延評価)。
しかし、クエリ結果に対して複数回反復処理を行うと反復回数＝必要になったときのため、クエリが無駄に実行されてしまう。

## 例
```C#
static void Main(string[] args)
{
    var a = Enumerable.Range(0, 5).Select(x => DisplayEvenNum(x));

    foreach (var n in a);
    foreach (var n in a);
}

static int DisplayEvenNum(int n)
{
    if(n % 2 == 0)
    {
        Console.Write(n);
    }

    return n;
}

//結果
//024024

//aを呼び出すたびにDisplayEvenNumが実行されてしまう
```

## 対処方法  

クエリ結果を即時評価する。

具体的にはクエリ結果に対して`ToList`か`ToArray`メソッドを使い、リストor配列を作成することで1度だけ評価されるようにする。

## 例
```C#
static void Main(string[] args)
{
    var a = Enumerable.Range(0, 5).Select(x => DisplayEvenNum(x)).ToList();//.ToList()で即時評価する

    foreach (var n in a);
    foreach (var n in a);
}

static int DisplayEvenNum(int n)
{
    if(n % 2 == 0)
    {
        Console.Write(n);
    }

    return n;
}

//結果
//024
```

## 参考  
- [プログラミングC# 第8版](https://www.amazon.co.jp/dp/4873119367)
- [[雑記] LINQ と遅延評価](https://ufcpp.net/study/csharp/sp3_lazylist.html#delay)
[Laravel]単体テスト（テストケース使用、自動テスト）

# 概要
Laravel のテスト作成時、
全部テストされるのがめんどくさかった

- グループで指定したメゾットだけテストする
- ファイルテストする(class)

## 環境
- laravel@8
- Docker
- TestCase(phpunit)

## テスト環境の構築まだな方↓↓
【公式】テストの作成
https://readouble.com/laravel/8.x/ja/testing.html

## グループテストする
テストしたいメゾットのコメントに下記内容を記載
- ``@test``
- ``@group groupName``

※ ``groupName``はグループ名になる
※ TestCaseサンプルコードを記載してるので参照

```bash:
$ php artisan test --group=testing

// ↓　Docker環境の方
$ docker-compose exec app php artisan test --group=testing
```

## ファイルテストする(class)
``XXXTest``には``class``名
※ 同じ名前のclassもテスト処理する
```bash:bash:Feature/Auth/Login/ConstructTest.php
$ php artisan test --filter ConstructTest

// ↓　Docker環境の方
$ docker-compose exec app php artisan test --filter ConstructTest
```

## TestCaseサンプルコード
```php:Feature/Auth/Login/AuthenticatedTest.php

namespace Tests\Feature\Auth\Login;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

//　　　↓　classテスト
class AuthenticatedTest extends TestCase
{
    /**
     * A basic feature test example.
     * 
     * @test　←　グループテスト
     * @group testing　←　グループテスト
     * 
     * @return void
     */
    public function test_example()
    {
        $response = $this->get('/login');

        $response->assertStatus(200);
    }
}

```
Tableau（タブロー）の表計算関数:LOOKUPの使い方


今回、Tableauの自己学習を行い、自分の振り返りを兼ねて拙い文ですがまとめてみました。



**使用環境**
・Tableau Public（無料）

**使用データ**
・サンプル　-　スパーストア

**初期画面**
![スクリーンショット 2022-03-31 16.17.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/a212759c-d11b-62a7-1bdf-e8b82eb3d702.png)




今回使用環境の準備、サンプルデータの準備の方法に関しては省略させていただきます。

## LOOKUP関数とはそもそも何？

Tableau社公式サイトのヘルプによると
>LOOKUP(expression,[offset])
>現在の行からの相対オフセットとして指定されたターゲット行にある式の値を返します。
>パーティション内の最初/最後の行に相対的なターゲットには、オフセット定義の一部として >FIRST() + n と LAST() - n を使用してください。
>offset を省略した場合は、比較対象行をフィールド メニューで設定できます。
>この関数は、ターゲット行を特定できない場合は、NULL を返します。

となっております。

参考サイト（Tableauヘルプ）:
https://help.tableau.com/current/pro/desktop/ja-jp/functions_functions_tablecalculation.htm

いまいちわかったようで、わからないような形になったので、

実際に実行環境で動かしてみます。

# 実行環境

**目標：表形式で昨年の売上データをLOOKUPで持ってくる。**


今回使用する項目としては、
・オーダー日（年）
・売上




##### 1,各年の売上データの表の作成

行にオーダー日、売上をドラッグし、2018年〜2021年の各年の売上表作成。
![スクリーンショット 2022-03-31 14.08.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/140818fc-dee9-5e13-34ba-3ff3a8e71ec6.png)


##### 2,LOOKUPを使用して、昨年の売上データ作成

| オーダー日| 売上 | 昨年売上 |
|:-:|:-:|:-:|
|2018年   |2018年の売上 |2017年の売上   |
|2019年   |2019年の売上   |2018年の売上   |
|2020年   |2019年の売上   |2019年の売上   |
|2021年   |2019年の売上   |2020年の売上   |

LOOKUPを使用し、一番右列を作成する。

**手順１:**
・計算フィールドの作成をサイドバー部分（データが並んでいるところ）の一番上左の▼で計算フィールドの作成。
もしくは、ツールバーの分析→計算フィールドの作成でも可能です。

![スクリーンショット 2022-03-31 14.31.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/ea82ddf8-4fa3-b3de-8714-c8203b0898d5.png)

**手順2:**
・下記画像のように記入。


![スクリーンショット 2022-03-31 14.32.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/5d4834b4-74d3-b9b9-5043-2db259059cb4.png)

**手順3:**
・作成した、昨年売上を行にドラッグ。

![スクリーンショット 2022-03-31 14.40.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/2a79a9d8-54af-f99b-6829-184ace0a21b7.png)


このように、LOOKUPを使用し売上データを(-1)下にずらす事で、昨年の売上を持ってくることができます。

*2018年の昨年売上は、売上のデータが2018年〜2019年の売上データ4行を下にずらしておりデータとして存在しないことからNULLという表記となってます。

これを利用し各月の昨年売上の比較も作成する事ができます。

![スクリーンショット 2022-03-31 15.00.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/71577663-269f-61a8-ddb7-a2519e1fdab0.png)


## まとめ

正確な理解では、ないかもしれませんが

まとめると

LOOKUP(X,Y)とおいて
X:表で動かしたいデータ
Y:どれくらい動かすのか

こういった認識で使っていけば、LOOKUPを使用して表計算する事ができると思います。
recsys-pythonを進めていく(第3章から終わりまで)

# 参考文献とか
1. https://recsyslab.github.io/recsys-python/
2. https://techbookfest.org/product/5547509835366400?productVariantID=5739222210183168
3. https://note.nkmk.me
4. https://qiita.com/nyantacos/items/fc45bd584fcade57c267

# 前回の記事
https://qiita.com/yaminabeworks/items/7afe7d849fa29b8ce92d

# やったこと
- google colabで参考文献1.の第13章までをすべて解いた。
  - こまめに進捗を投稿しようとしたが、やる気のあるうちに問題を解きたかったので後回しになった。
- 以下の場所に解答した.ipynbファイルを配置したので、見ていってくださると大変ありがたいです。
  - https://github.com/yaminabeworks/qiitakiji/blob/main/numpyknock_recsys.ipynb

# 感想
- 終わったけどあまりわかっていないもやもや感もある。
  - 特に第10章の決定木と第13章の評価に関する部分はなかなか難しいという気持ち。
  - 前者は`NumPy`を前提にスクラッチでアンサンブル学習する本があり、後者も一応実装付きではないけど本はあったはず。
    - 次にやる、この記事に関連することの欄に書いておく。
  - `np.nan`の扱いがしんどい第6章あたりで辞めたくなった。
    - 進捗をいちいち報告されてくれた友人には励まされたので感謝。
    - `np.nan`ではない比較できる部分のみを抽出するという処理がつらかった。
      - `NumPy`の型の問題もありそう。 
  - `jax`や`Julia`に書き直す機会があればやってみたいなという気持ち。
- 参考文献4.には大変助けられた。全作業時間の5分の1くらいは`np.argsort`に躓いたせいだと思うので本当に救世主でした。ありがとうございました。

# 次にやる、この記事に関連すること
以下の書籍のどちらか
1. https://www.c-r.com/book/detail/1316
2. https://www.coronasha.co.jp/np/isbn/9784339024968/
  - https://www.morikita.co.jp/books/mid/081861 を読んでからにしたいから、たぶん1.から。

いずれにせよ、情報検索の分野に触れていきたいという強い気持ち。

# 次にやる、必ずしもこの記事と関連しないこと
- ベイズ統計学
  -ちょっと時間かかりそう 
- 線形回帰モデル→一般化、機械学習の解釈モデルへの拡張を追っていく。
  - ステップを踏んで実装した過程などを記録していけるといいなの気持ち。
Shopifyの公式チュートリアル起動時点で詰まった時の備忘録

2022年3月時点でのShopifyチュートリアルで詰まった人（というより筆者が詰まってしまったところ）向け記事。
https://shopify.dev/apps/getting-started/create

いざ`shopify app serve`を起動してみると以下エラーが出ていた人向け。
そもそもShopifyがなんなのかとか、チュートリアルに明記されていることは省略する。

> X Couldn't verify your store. If you don't have a development store set up, please create one in your Partners dashboard and run `shopify app connect`.

>X An unexpected error occured.
        To submit an issue include the stack trace.
        To print the stack trace, add the environment variable SHOPIFY_CLI_STACKTRACE=1.

# 確認すべきこと
## そもそもRequirementsに書かれてることやってる？

>You've created a Partner account and a development store.
You understand how apps fit into Shopify and the different types of apps you can build.
You've installed the latest versions of Node.js and npm.

パートナーアカウント作ったり開発用ストア作ったり。

## ngrokに登録してる？

ngrokはローカルWebサーバのポートを伝えるとインターネットへデフォルトHTTPSで公開してくれるツールである（すごい）。

> Shopify CLI uses ngrok to create a tunnel that allows your app to be accessed using a unique HTTPS URL, which is mandatory when creating an app.

> You need to create an ngrok account and auth token to run shopify app tunnel auth. To learn more about creating an auth token, refer to ngrok’s documentation.

では、` shopify app tunnel auth <token>` にあるトークンはどこにあるのか？

ngrokに登録したあと、`https://dashboard.ngrok.com/get-started/your-authtoken`にてトークンが発行されているのでそれを使う。
つまり発行されているのが`hogehoge`だとすれば`shopify app tunnel auth hogehoge`とすればいい。

## .envに書かれている項目にSHOPはある？

`SHOP=hogehoge`みたいに書かれていなければ、SHOP情報が抜けている。

`shopify login --store <STORE NAME>`のように入力し、.envに覚えさせる。
【IBM Application Gateway】フェイルオーバー動作について

# はじめに
IBM Security Verify にバンドルされている IBM Application GatewayをOpenshiftにデプロイして、フェイルオーバー動作について確認してみました。

フェイルオーバーの設定は大きく3つあります。

https://docs.verify.ibm.com/gateway/docs/tasks-failover

①IDプロバイダーからのシングルサインオン
Application Gatewayのセッションがなくなった場合に、IDプロバイダーにアクセス/IDプロバイダーのセッションが残っている場合は、新しくApplication Gatewayのセッションをを確立するパターン。

![qiita(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/96bd9f47-8bef-f260-eac3-8a4c102d78b9.png)

②JWEフェイルオーバーCookieの利用
フェイルオーバーCookieを利用して、IDプロバイダーにアクセスすることなくフェイルオーバーするパターン。

![qiita(2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/406ffe4a-3fb6-7fdb-5a25-9c00baa4143c.png)


③Redisサーバーを使用した分散セッション
Redisサーバーにセッション情報を保存し、このセッション情報を他のIAGインスタンスで使用するパターン。


# ①IDプロバイダーからのシングルサインオンのパターン
デフォルトはこちらの動作です。

動作確認で利用したyamlファイルの一部です。
server/failoverは指定なしで動作確認しました。
https://docs.verify.ibm.com/gateway/docs/yaml-server-failover

また、identity:で、Application GatewayのIDプロバイダーとして、Security Verifyを指定しました。

```demo-sso.yaml
server:
  ssl:
    front_end:
      certificate: "@secret_files/iag.certkey.pem"
  local_applications:
    cred_viewer:
      path_segment: "cred-viewer"
      enable_html: true
～～割愛～～
identity:
  oidc:
    discovery_endpoint: https://<tenant>.verify.ibm.com/oidc/endpoint/default/.well-known/openid-configuration
    client_id: <OIDC_CLIENT_ID>
    client_secret: <S_OIDC_CLIENT_SECRET>
～～割愛～～
```





Application GatewayのPodを再作成した場合、トレースログの通り一度 IDプロバイダーとして設定したSecurity Verifyにアクセスしていました。

![qiita(3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/39c6d0aa-813e-9d3c-7099-7f2d1ebb4ebf.png)


# ②JWEフェイルオーバーCookieの利用

動作確認で利用したyamlファイルの一部です。
server/failoverを設定し、jwtというCookie名にしました。
https://docs.verify.ibm.com/gateway/docs/yaml-server-failover

```demo-sso.yaml
server:
  failover:
    key: "@oct-512-bit.bin"
    cookie_name: jwt
    domain_cookie: false

  ssl:
    front_end:
      certificate: "@secret_files/iag.certkey.pem"
  local_applications:
    cred_viewer:
      path_segment: "cred-viewer"
      enable_html: true
～～割愛～～
identity:
  oidc:
    discovery_endpoint: https://<tenant>.verify.ibm.com/oidc/endpoint/default/.well-known/openid-configuration
    client_id: <OIDC_CLIENT_ID>
    client_secret: <S_OIDC_CLIENT_SECRET>
～～割愛～～
```

Application Gatewayにアクセスすると、Cookieにjwtが表示されました。
![qiita(4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/640edd02-e8fb-4655-5980-eaf020ed47cc.png)


Podを再作成した後に、アプリケーションにアクセスすると、IDプロバイダーとして設定したSecurity Verifyへのアクセスは発生しませんでした。
![qiita(5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/42df0e9d-5f28-8b2a-e6b0-cec1535618bd.png)


# 最後に
IBM Applicatio Gatewayのフェイルオーバーについて確認しました。
Redisサーバーを使用した分散セッションは試せたらご紹介します。

4/5追記
[【IBM Application Gateway】Redisサーバーを使用したセッション保持について](https://qiita.com/fitz/items/53a2fecb58085b8a6372)
StreamlitでWEBアプリケーション開発～基本的な使い方を学ぶ～

# はじめに

この記事では、[Streamlit](https://www.streamlit.io/) を使ってWEBアプリケーションを作成するための手順を大まかに解説します。
Streamlitを使うことで、Pythonを使って非常に簡単にWEBアプリケーションを作成することができます。
今回はコードを実際に動かして、Streamlitの基本的な使い方を学ぶことを目的とします。
使用したコードは [こちら](https://github.com/masachika-kamada/streamlit_qiita) のリポジトリにあります。

# 開発環境作成

1) [Anaconda](https://www.anaconda.com/products/individual)とお好みのエディタをインストール
2) Anaconda Promptで（仮想環境を作成して）Streamlit をインストール

```terminal
pip install streamlit
```

# Streamlitを使ってみる

ひとまずSteamlitを使ってみましょう。
以下のプログラムをコピペして保存したら、```streamlit run basic_usage.py```で実行してみましょう。
（プログラムと同じ階層に画像ファイルを配置）
すると、[このページ](https://share.streamlit.io/masachika-kamada/streamlit_qiita/basic_usage.py)と同じように表示されると思います。

```python:basic_usage.py
import streamlit as st
import numpy as np
import pandas as pd
from PIL import Image


"""
## [Streamlit](https://docs.streamlit.io/)ではマークダウンを使用できます
###この記法の詳細は[こちら](https://docs.streamlit.io/library/api-reference/write-magic/magic)
他にも[API reference](https://docs.streamlit.io/library/api-reference)に色んな機能が載っています
```python
print("hello world!")
"""

st.title("st.titleでも文字を表示できます")

# data frameを表形式で表示
df = pd.DataFrame({
    "名称": ["東京タワー", "スカイツリー", "エッフェル塔", "自由の女神"],
    "高さ[m]": [333, 634, 300, 93]
}).astype(str)
st.table(df)

# data frameを棒グラフで表示
df = pd.DataFrame(
    np.random.rand(20, 3),
    columns=["a", "b", "c"]
)
st.bar_chart(df)

# map上へのプロット
df = pd.DataFrame(
    np.random.rand(50, 2) / [80, 80] + [36.95, 138.78],
    columns=["lat", "lon"]
)
st.map(df)

# 画像の表示
img = Image.open("landscape.jpg")
st.image(img, caption="スキー場", use_column_width=True)
```

# ウィジェットを使ってみる

次はウィジェットを使ってWEBアプリケーションを作成してみましょう。
ウィジェットを使うことで、欲しい機能をサクッと作ることができます。
以下のプログラムをコピペして保存したら、```streamlit run input_widgets.py```で実行してみましょう。
すると、[このページ](https://share.streamlit.io/masachika-kamada/streamlit_qiita/input_widgets.py)と同じように表示されると思います。
詳しくは[こちら](https://docs.streamlit.io/library/api-reference/widgets)を参照してください。

```python: input_widgets.py
import streamlit as st

# ボタン
# (True/Falseで値が入ってくるのでif文で)
if st.button('ためになった'):
    st.write('LGTMを押そう！')
else:
    st.write('ストックしておこう…')

# チェックボックス
if st.checkbox('こんにちは'):
    st.write('こんにちは！')

# セレクトボックス
option = st.selectbox(
    '好きなSNSは？',
    ('Twitter', 'Instagram', 'LINE', 'Qiita'))
st.write('あなたの選択:', option)

# スライダー
values = st.slider(
    '数字の範囲を選んでください',
    0.0, 100.0, (25.0, 75.0))
st.write('Values:', values)

# テキスト入力
title = st.text_input('好きな映画を教えてください')
st.write('あなたが好きな映画は', title, "ですね！")
```

# 最後に

Streamlitの基本的な使い方を紹介しました。
[公式ドキュメント](https://docs.streamlit.io/)を参照して使えそうな機能を試してみると良いかもしれません。
画像サイズがでかくなってることに気づかずAWSのコストで有り金溶かした顔になった話

期末なので、今期有り金溶かした話をば

## アウトバウントコストがやばい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143313/04757e7e-eeea-c14f-4780-effcc9ee3854.png)

円安の影響もやばいですが、今回はその話とは別です。
上記の画像を見てもらうと分かる通り、11月-12月のコストが跳ねました。

アウトバウンドのデータ通信量です。
コストが1.X倍になっていました。

## やばくなった根本原因

* SVGのファイルサイズが原因です
  * とある画像(png)をsvg形式のものに変更した
  * そのsvgが800KB程度あった
  * 以前までは10KB程度だった
  * **80倍**の容量の差だった

ちょっと計算してみましょう。
※実際にかかったコストではなく概算です。
※0.114USD/GBで計算します
※簡単にするためにGiB計算はしていません

```
800kBの場合
800,000(B) * 1,000,000,000(リクエスト/月) = 800(TB/月)
800,000(GB/月) * 0.114(USD/GB) = 91,200(USD/月)

10kBの場合
10,000(B) * 1,000,000,000(リクエスト/月) = 10(TB/月)
10,000(GB/月) * 0.114(USD/GB) = 1,140(USD/月)

差額：91,200(USD/月) - 1,140(USD/月) = 90,060(USD/月)
```

いかがでしたか？有り金が溶けますね。

## どう解決したのか

* もともとsvgに向いていないものをsvgにしてしまっていたので、pngに戻しました。

## どういう状況だったの？(Q＆A)

* なぜ気づくのに遅れたの？
  * コストの予実管理を1か月毎に行っており、確認するタイミングで気づきました
* なんで1か月の間確認してなかったの？
  * 毎日どのくらいコストがかかってるかslackに出しているけど、確認はほぼ形骸化していました
* AWSのコスト異常検知設定していなかったの？
  * 検証用に私のところにだけメールが来るよう設定していました
  * しかし閾値が高くて引っかかりませんでした
* なんで異常検知をちゃんと調整していなかったの？
  * 他の業務優先してて忘れてました
* 画像ファイル大きいのに気づく人いなかったの？
  * いなかったですねぇ・・・
* チェック機構みたいなの無かったの？
  * 少なくともこれが起きるまでは無くても問題なく、特に入れようとする人もいなかったので入ってませんでした
* なんでSVGファイルにしたの？
  * SVGファイルのメリットを享受したかったからです
* SVGファイルがなんでそんな大きいの？
  * 画像のグラデーションが影響していました
* CloudFront通せばもっと安く済んだんじゃないの？
  * とある仕様の問題でCloudFrontを通せない状態にあります

## どうすればよかったか

いろいろ対策案はあると思いますが

* AWSの異常検知を導入する
* CDパイプラインにチェック機構を設ける
* slack通知が文字列だけで視覚情報としての差分が出てなかったため、日々の動向をグラフにして出力する
* 大きいファイルを返すとコストに影響するということをナレッジとして共有する

## まとめ

* 定期的に有り金溶かした顔してる気がする・・・
ImageJ と cellpose を使って、細胞画像の輝度値を測定する。（３）


# 目的
顕微鏡撮影した細胞画像から、細胞膜領域と細胞質基質領域の範囲を選び、その平均輝度値を求めたい！

使用するアプリケーションは、以下の通りです。
- Fiji (ImageJ)　　　　　        
-画像解析ソフト
- anaconda 　　　　　　　　　　　　　　
-Python を動かすところ
- cellpose					　　　　　　　　　　　　　　　**←今回は、これのインストール！**
-Python で書かれた細胞画像の分節化に特化した、deep-leaning に基づくアルゴリズム

上記アプリケーション（プラグインを含む）のインストールや、解析に必要なマクロを記録していきます。

### PC の環境
Windows 10

# この記事の範囲
cellpose のインストール

cellpose は、Python 3 で書かれた、deep-leaning に基づいた細胞画像の分節化（Segmentation）用アルゴリズムです。
インストールをする前に、Web 上で手軽に性能を試すことができます。
以下のリンクに行き、お手持ちの写真をドラッグ&ドロップをすると Segmentation の結果が見られます。
[cellpose の Web インターフェイス](https://www.cellpose.org/)

cellpose を動かす方法は、いくつか用意されています。
私は、クリックすることで条件を変えることができ、結果をすぐ確認することができる、GUI バージョンを使用しています。
よって、以下には cellpose の GUI をインストールする方法を記載します。


# cellpose のインストール

cellpose のインストール方法ならびに動かし方の詳細は、Github に説明があります。
私も、この Github の記事に従ってインストールしました。

[Github での cellpose のページ](https://github.com/mouseland/cellpose)

### cellpose のインストール方法

1. Anaconda prompt を開きます。
Anaconda のインストール方法は、下のリンクにあります。
[ImageJ と Cellpose を使って、細胞画像の輝度値を測定する。（２）](https://qiita.com/Naka24-sun/items/df672b12e2daa016e8cb)

2.  cellpose を動かす環境を作ります。
Anaconda prompt に以下のコマンドを入力。
`conda create --name cellpose python=3.8`

3.  環境をスタートさせます。Anaconda prompt に以下を入力。
`conda activate cellpose`

4. cellpose をインストールします。今回は、GUI も含めた全部入りをインストール。
Anaconda prompt に以下を入力。
`python -m pip install cellpose[all]`

5. cellpose を最新バージョンにアップデートします。
　　cellpose は、時々アップデートが入り小さなバグを直してくれます。
　　私も、数か月前までは GPU を使おうとするとエラーが出ていたのですが、
　　アップデートをすると直っていました！
　　（ GPU を使う方法は、[Github](https://github.com/mouseland/cellpose) に記載しています。少し使ってみましたが、
　　CPU とGPU で結果が若干異なります。計算時間は、GPU の方が圧倒的に短いです）
Anaconda prompt に以下を入力。
`python -m pip install cellpose --upgrade`

6. 細菌など複雑な形状の Segmentation もできる Omnipose というアルゴリズムも追加します。
この操作は、省略しても大丈夫です。Anaconda prompt に以下を入力。
`pip install omnipose`

### cellpose の起動

Anaconda prompt に以下の2行のコマンドを入力すると、cellpose [GUI] が起動します。

`conda activate cellpose`
↑このコマンドは、上記のインストール直後だと不要です。ただし、一度Anaconda prompt を閉じた後は、毎回このコマンドによって、環境をスタートさせる必要があります。

`python -m cellpose`

cellpose のGUI が立ち上がります。

次回、cellpose で細胞画像の Segmentaion を行っていきます。



以上！
【VSCode】ターミナル上でのFileNotFoundError

# 事象
VSCodeでPythonスクリプトを実行/デバッグ中、ファイルの読み込み操作エラー（**FileNotFoundError**）に出くわした。

### 実行環境
- Windows10
- Visual Studio Code 1.65.2
- Python 3.9.12

# 原因
**VSCodeターミナルのカレントディレクトリが、実行/デバッグ対象のPythonスクリプトが置かれているフォルダと一致していなかった**ため、相対パスによるファイルの参照ができていなかった。

# 対処
VSCode上で**適切なプロジェクトフォルダ（Pythonスクリプトが配置されているフォルダ）を開く**ことで、ターミナルのカレントディレクトリを対応させる。
1. [File(ファイル)]→[Open Folder...(フォルダーを開く)]からPythonスクリプトの配置されているフォルダを開く
2. エクスプローラー（左サイドバー）からPythonスクリプトを選択して実行/デバッグする
Windowsのスタートアップで毎日使うツールを自動立ち上げ

PCを立ち上げたときに毎回絶対に開くアプリってありますよね？
そういったアプリはWindowsのスタートアップで起動時に自動で立ち上げを行うとちょっと幸せになれます。

## 設定方法
##### ①「win + R」を押してファイル名を指定して実行を開く 
##### ②「shell:startup」と入力してOK
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602965/27e27a4e-0f37-f381-2dd8-704b4a2a75c0.png)
##### ③スタートアップのフォルダが起動するのでアプリのショートカットを登録
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602965/9b59fe3a-2547-6c7f-f962-b86d85344fd9.png)
フォルダのファイルパス
`C:\Users\ユーザー名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`
##### ④動作確認のためPCを再起動
##### ⑤登録したAPPが起動
先程のフォルダに追加したアプリが起動しているはずです。
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602965/bbbd4500-7d52-4cad-793c-0297dab5f66a.png)

## 勝手にスタートアップに登録されたアプリの無効化
PCメーカーが最初から入れているアプリやアプリをインストールしたら勝手にスタートアップに入れられていることがあります。
特にメーカー独自のソフトウェアやお試し版のセキュリティソフトのポップアップはほぼウイルスだと思ってます。
そういったアプリはタスクマネージャーのスタートアップで無効にしましょう。
##### ①win + shift + escでタスクマネジャー起動
##### ②スタートアップタブに移動
##### ③無効にしたいアプリケーションを選択して「無効にする」をクリック
Visual Studioで簡易電卓を作ってみた

# はじめに
C#の勉強としてVisual Studio 2022で下記画像の簡易電卓を作ってみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415520/fde2abbd-3bd7-d1d5-2ad5-16d3cb84ab4d.png)

## 環境
- OS : Windows 10
- Visual Studio 2022



## 作成した電卓の機能
::: note info
基本機能
- 四則演算は可能
- ACを押すまでは続けて計算できる。
:::

::: note alert
注意点
- 小数点の入力は不可
- $2+2+2=6$ のように続けて計算がしたいときは、$2+2=4+2=6$ のように$=$を毎回入力しなければならない。
:::

# 作る

## 画面の作成
下記画像のようにテキストボックスとボタンを配置し、テキストボックスのプロパティからReadOnlyをTrueに変更とボタンとテキストボックスの(Name)とTextの変更を行う。
![2022-03-31 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415520/8022ebb5-f1e1-8e55-0546-b79c4d0b3820.png)

## コード編

## 数字ボタン
現在表示されているTextにそのまま数字を足すとはじめに表示させている $0$ が残ってしまいます。
そのままTextに数字を足した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415520/51e5de28-2829-822f-cc2b-1bef3e6f8eff.png)
なので、$0$ を消すために一度decimal型にしています。
decimal型にする処理を入れた場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415520/cdcf81a2-6ae2-d193-7825-c9ff4396567a.png)

```C#:btnNum_Click.C#
//数字ボタンを押したとき
private void btnNum_Click(object sender, EventArgs e){
    Button btn = (Button)sender;
    decimal inputNum = decimal.Parse(txtResult.Text + btn.Text);

    txtResult.Text = inputNum.ToString();
}
```

## 四則演算の記号ボタンを押したとき
メソッド間で値の受け渡しをするために、btnOpe_Click()メソッドの外側で、`string型のOper`と`decimal型のMem1`を定義しています。
四則演算の記号ボタンを押したときにstring型の変数Operにそれぞれ押した記号の文字を入れることで押したボタンの計算をできるようにしています。
```C#:btnOpe_Click
//+,-,×,÷を押したとき
private void btnOpe_Click(object sender, EventArgs e)
 {
     Button btn = (Button)sender;

     if(btn.Text == "÷")
     {
         Oper = "÷";
     }
     else if(btn.Text == "×")
     {
         Oper = "×";
     }
     else if(btn.Text == "-")
     {
         Oper = "-";
     }
     else if(btn.Text == "+")
     {
         Oper = "+";
     }

     Mem1 = decimal.Parse(txtResult.Text);//一つ目の項
     txtResult.Text = "0";
 }
```

## イコールボタンを押したとき
現在表示されているTextを2つ目の項として保存します。
`string型の変数Oper`にある文字の情報で計算方法が変わるようになっています。
```C#:btnEqu_Click
private void btnEq_Click(object sender, EventArgs e)//イコールボタンを押したとき
 {
     decimal Mem2 = decimal.Parse(txtResult.Text);//二つ目の項
     decimal CalcResult = 0m;

     if(Oper == "÷")
     {
         CalcResult = Mem1 / Mem2;
     }
     else if(Oper == "×")
     {
         CalcResult = Mem1 * Mem2;
     }
     else if (Oper == "-")
     {
         CalcResult = Mem1 - Mem2;
     }
     else if (Oper == "+")
     {
         CalcResult = Mem1 + Mem2;
     }
     txtResult.Text = CalcResult.ToString();
 }
```

## オールクリアボタンを押したとき
```C#:btnAC_Click
private void buttonAC_Click(object sender, EventArgs e)
 {
     //初期化
     txtResult.Text = "0";
     Mem1 = 0m;
     Oper = null;
 }
```
# 動作確認

実際に動作を確認してみます。
下のようにしっかり動作する簡易電卓が作成できました。
![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415520/42d4160d-c792-a64d-9b84-f6b49eeef7aa.gif)

# おわりに

C#を勉強し始めたばかりの初心者でわからないことばかりですがこれから頑張っていこうと思います。
最後まで読んでいただきありがとうございました！
【kintone カスタマイズ】　印刷画面の全ての罫線を非表示にする

## 印刷画面の全ての罫線を非表示にする
kintoneの罫線は「フィールドコード」を持ち合わせていないため、DOM操作による非表示が必要になります。 下記のコードではラベルに付与されるクラス名からラベル要素を全て取得し、その後非表示する処理を行っています。

```javascript:js
(function () {
    "use strict";
    // 印刷画面が表示されたときに動作
    kintone.events.on('app.record.print.show', function(event) {
        //罫線の非表示('control-hr-field-gaia ')
        let hrs = document.getElementsByClassName('control-hr-field-gaia ');
        for (let i = 0; i < hrs.length; i++) {
            let hr = hrs[i];
            let parent = hr.parentNode;
            hr.style.display = 'none';
            parent.style.display = 'none';
        }
    });
})();
```
[ラベルの非表示はこちらをご覧ください](https://qiita.com/yamamotoooooooooo/items/c3a83ac070a8f69c27fc)
【kintone カスタマイズ】　印刷画面の全てのラベルを非表示にする

## 印刷画面の全てのラベルを非表示にする
kintoneのラベルは「フィールドコード」を持ち合わせていないため、DOM操作による非表示が必要になります。 下記のコードではラベルに付与されるクラス名からラベル要素を全て取得し、その後非表示する処理を行っています。

```javascript:js
(function () {
    "use strict";
    // 印刷画面が表示されたときに動作
    kintone.events.on('app.record.print.show', function(event) {
        //ラベルの非表示('control-label-field-gaia')
        let labels = document.getElementsByClassName('control-label-field-gaia ');
        for (let i = 0; i < labels.length; i++) {
            let label = labels[i];
            let parent = label.parentNode;
            label.style.display = 'none';
            parent.style.display = 'none';
        }
        return event;
    });
})();

```
[罫線の非表示はこちらをご覧ください](https://qiita.com/yamamotoooooooooo/items/f048b21290e3514e5979)
[Oracle] [SQL] 実行～DBへのデータ登録まで

# 実行時に使用　SQLPlusとは
　Oracle Databeseに付属しているソフト
　SQLを実行するためのユーティリティーソフトで、クライアントツールとして標準装備されている

## 起動方法
　　sqlplus　ユーザー名/パスワード@接続文字列

## 実行方法
　　@ファイルパス

## SQLおすすめの書き方
　　1. FROM テーブル名　＋　結合するテーブルから書いていく　（設計書をみて）
 2. WHERE区の中の抽出条件を書く　（設計書をみて）
　　3. 最後にSELECT句を書く
　　＊最後に；
　　　　　　 COMMIT；
　　　　　　 QUIT
       を忘れない様に


```sql:test1.sql
  TRUNCATE TABLE test --testテーブルをTRUNCATEする
  INSERT INTO test (
    bg --番号
   ,id --ID
   ,start --開始日
   ,end  --終了日
   ,kingaku --金額
   ,biko --備考
   ,cd --コード
  )
  SELECT
    '0'|| col002 AS bg --番号の先頭に0を付ける
    ,cnvt(col005) AS id -- ファンクションでidを変換
    ,substr(col006,1,10) AS start --開始日を切り取り　
    ,substr(col006,1,10) AS end -- 終了日を切り取り
    ,CASE
       WHEN col014 = '2' THEN col011
       ELSE NULL
      END AS kingaku
     ,col026 AS biko
     ,'1' AS cd --1を固定でセット
   FROM
     testtest
   WHERE
    col005 IN (SELECT DISTINCT col001 FROM tes WHERE col013 IS NOT NULL) --副問い合わせ
    AND ((substr(col007,1,10) >= '2018/04/01') OR col0007 IS NULL) 
    ;
    COMMIT;
    QUIT
```

# データを格納する時に使用　SQLLoaderとは
　大量のデータを高速にテーブルへ格納するためのOracle Database付属ツール
　CSVファイルを元にまとめてデータを取り込むことが可能
　直接テーブルにデータを書き込み高速に処理できることが特長


## 使用の流れ
　　テーブルの作成⇒CSVファイルの作成⇒制御ファイル（.ctl）で読み込み
　　
### テーブルの作成方法

```sql:create.sql
　　　CREATE TABLE テーブル名(
         カラム名　型,
         カラム名　型,--ex col001 VARCHAR2(400)
      )
       --COMMENT ON COLUMN テーブル名.カラム名　IS '';
       --でテーブルのヘッダーに任意の名前を付けることができる
```
　　
### 制御ファイルの役割
　　　制御ファイルの役割は投入元のCSVファイルと投入先のテーブルのマッピング
　　　　
### 制御ファイルの書き方
```sql:test.ctl
   OPTIONS(SKIP=1)
   Load data
    infile 'ファイルパス' 
    badfile 'ファイルパス'
    truncate into table テーブル名
   FIELDS TERMINATED BY ","OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS
          (
           カラム名,
           カラム名
           )
```

## 起動方法
　　sqlloader
　ユーザー名/パスワード@接続文字列

## 実行方法
　　@ファイルパス（コントロールファイル）
【rails6 + webpaker】yarnでblumaを入れて使ってみる

## はじめに
blumaを使う予定の人向けに作成します。
jsはサクッと作ったものなので、運用には向いてないかも

## 環境
- ruby:3.0.0
- rails:6.1.5
- Webpacker : 5.4.3
## 手順
#### 1. まずはインストール
yarnを使ってインストールします。
```console:コマンド
yarn add bulma
```

#### 2. CSSの読み込み
下記を追記します。
blumaのファイルの場所は違う可能性あるので、確認してください。
```javascript:app/javascript/packs/application.js
import 'bulma/css/bulma.min'

```
#### 3. 使ってみる
##### 3-1 サンプル作成
サンプルでコントローラーとビュー作ります。
```console:コマンド
rails g controller home index
```
##### 3-2 blumaを使ってview作成
メッセージを表示させます。
```erb:app/views/home/index.html.erb
<div class="section" id="message-modal">
  <article class="message">
    <div class="message-header">
      <p>ようこそ</p>
      <button class="delete" aria-label="delete" id="close"></button>
    </div>
    <div class="message-body">
    ここにメッセージを書くよ〜！
    </div>
  </article>
</div>
```
##### 3-3 起動確認
こんな感じで適用されていればOK！

![スクリーンショット 2022-03-31 14.33.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358130/08282da3-7b1e-e4d1-fef3-64e9af6a8281.png)

#### 4. javascriptを書いてみる
##### 4-1 jsファイルの作成
```javascript:app/javascript/javascripts/application.js
document.addEventListener('DOMContentLoaded', () => {

  // 閉じるボタンを取得します。
  const $close = document.getElementById('close');
  // ボタンのクリックイベントを追加します。
  $close.addEventListener('click', () => {
    // 閉じます。
    const $modal = document.getElementById('message-modal');
    $modal.classList.add('is-hidden');
  });
});

```
##### 4-2 読み込み
javascriptをアプリ全体に反映させるために追記します。書いた後はwebpakkerを再起動してね
```javascript:app/javascript/packs/application.js
import '../javascripts/application.js'
```

##### 4-3 起動確認
やったね！
[![Image from Gyazo](https://i.gyazo.com/be0b2718a84452390e0285dde2a6053c.gif)](https://gyazo.com/be0b2718a84452390e0285dde2a6053c)
Obsidianとのマリアージュその1｜Alfredのスニペットで日時を入力する

## はじめに

超絶便利ツール[Obsidian](https://obsidian.md)。さらに便利に使うコツをご紹介します。

### 背景

Obsidian単体でもきわめて便利ですが、ほかのツールと組み合わせるとさらに便利になります。毎日のように使ってきて、熟れてきたやりかたは、誰かのお役に立てるのではないかとおもいました。


## Alfredと組み合わせる

<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masatora_bd5/20220331/20220331141007.png" width=80%>


[Alfred](https://www.alfredapp.com)は、macOS用の作業効率化ツールです。有料版（パワーパック）は34ユーロもしくは59ユーロですが、このツールにピンと来る人なら元が取れるとおもいます。わたしにとっては、過去最高級のコスパでした。

Alfredにはたくさんの機能がありますが、そのなかでもObsidianとのマリアージュが最高の`スニペット`のご紹介です。


## 常用しているスニペット

さまざまなスニペットを登録していますが、そのなかでも日時入力にしぼってご紹介します。

`Keyword`列に書かれている文字をタイプすると、`Snippet`が発動され、現在時刻にもとづいて文字列が展開されます。

`Keyword`は好きに設定できますが、誤発射を防ぐため、`!`を冒頭につけることにしています。


| Keyword | Snippet                          | 展開例                    | 用途       |
| ------- | -------------------------------- | ------------------------- | ---------- |
| !td     | {date:yyMMdd_}                   | 220331_                   | ファイル名 |
| !yy     | {date:YYYY-MM-dd（EE）}          | 2022-03-31（木）          | 文中適宜   |
| !dt     | ({date:yyyy-MM-dd} {time:HH:mm}) | (2022-03-31 08:17)        | 文中適宜   | 
| !##     | ## {cursor}<br>{snippet:!dt}     | ## <br>(2022-03-31 08:19) | 見出し           |

### !td → {date:yyMMdd_} →　220331_ 

ファイル名の冒頭に日付を入れています。`220330_課題の定義について_rev02`とかですね。

ファイル名に日付を入れなくても、「ファイルに更新日時や作成日時が記録されるじゃないか」という見解もあります。ところが、更新日時や作成日時は、意図とは違うところで書き換わってしまいます。明示的にファイル名に入れることで、ファイルの前後関係で迷うことが少なくなります。

### !yy → {date:YYYY-MM-dd（EE）} 　→　2022-03-31（木） 

日付＋曜日がサクッと入るとうれしい状況はよくあります。たとえば提案書やレポートに記載する日付とかですね。Obsidianのデイリーノートのタイトルも、この日付形式にしているので、デイリーノートへのリンクをさくっと作れるというメリットもあります。


### !dt → ({date:yyyy-MM-dd} {time:HH:mm}) → (2022-03-31 08:17) 

文中に適宜日付を入れています。ある程度入力したら、日時を入れるようにしています。長年メモを書き溜めていて、いちばん重要な付帯情報は「それを書いた日時」だとおもっています。

メモを書いた背景や状況を、克明にメモしておくのは大変ですが、スニペットで日時を入れておくことはかんたんです。日時がわかれば、メモの背景をかなり推測できます。たとえば「夜中の2時にメモしているから、だいぶ行き詰まっていたんだな」とかですね。

近いところでは、LINEのトーク履歴が「あとから見ても使える」のは、タイムスタンプが押されているからですよね。とにかく「文中でタイムスタンプは押しまくる」はメモ取りの原則ではないかとおもいます。


### !## → ## {cursor} {snippet:!dt} → ## (2022-03-31 08:19)

ところが、タイムスタンプを押すのも面倒になってきました。Obsidianでメモを取っていると、ほとんどかならず見出しを書きますから、そのときにタイムスタンプを押すようにし始めました。単純なアイディアですが、無意識のうちにタイムスタンプが押されていて、これは相当便利です。

<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masatora_bd5/20220331/20220331143738.png" width=50%>


## おわりに

Obsidianをさらに便利にする、Alfredのスニペットとのマリアージュをご紹介しました。

長年メモを取っていると、「日時情報至上主義者」になっていきます。手入力はめんどうくさいですが、自動化すればかんたんです。日付をかんたんに入力できれば、メモの価値が上がります（あるいは価値の低いメモを見分けることが容易になります）。

スニペットツールはいろいろあるので、Alfredである必要はありませんが、ほかにも便利ツールが揃っているので、Alfredをつかって損はないとおもいます。

それではハッピーObsidianライフを！


### 参考リンク

[Obsidian｜使いかたとコツ（目次）](https://qiita.com/hann-solo/items/ac8fa75394813e8adcf4)


### 環境

ここで書いていることは、下記のバージョンで実施しました。

- Alfred 4.6.4
- Obsidian 0.14.2
- macOS Monterey 12.2.1
- MacBook Pro (14-inch, 2021)
文系出身で数学が嫌いなプログラミング未経験の私が一年間エンジニアとして働いてみて思う「一年目にやるべき」こと

# はじめに
もうすぐ4月ですね。
文系出身、プログラミング全くの未経験だった私がエンジニアとして働き始めてから
1年が経とうとしています。

「未経験だけど春からエンジニアとしてやっていけるのだろうか？」
「プログラミングに興味があるけど文系だしな...」
「一年目に意識した方が良いことってなんだろう...？」

と不安なあなたに、私が思う **エンジニア一年目にやるべきこと** を紹介しようと思います。
(私の主観なので一意見として参考にして頂ければと思います)

# この記事の対象読者
* これから新卒でエンジニアになる予定の人
* エンジニアに転職しようと思っている人
* エンジニアに興味がある人　など

# 一年目にやるべきこと 3選
### 1. 自分で調べる力をつける
最初はとにかくわからないことが多いです。(というか何もわかりません)
環境構築、コードの書き方、ロジックの組み方など、次から次へとわからないことが押し寄せてきます。
でも不安になることはありません。
なぜなら最初からすべてを知っている人間は誰一人としていないからです。
なんでも知っている先輩も同じ道を通ってきたに違いありません。

なので、エンジニア一年目は「わからない」「知らない」を恥じずに
とにかく**調べる癖をつけて情報収集をし、知識を増やしましょう**。
私は業務中に調べたことをメモしておいたり、参考にした記事をブックマークバーのフォルダに保存しています。後で復習したい時に便利なのでおすすめです。

そして「**調べ方を学ぶ**」という点でもこれは大切になります。
特にエラーが発生し、解決方法がわからずに詰まってしまった時には
**エラーコードをそのまま調べる**と問題解決につながることが多いです。
「なんだかエラーが出ているけど、どこでエラーが出ているのかがわからない...」
なんて事態を避けるためにどこでエラーが発生しているのか **ログを確認する**ことも大切ですね。

また、**公式ドキュメントを見る**癖をつけておくのが良いでしょう。
最初のうちは情報量が多くて読みづらいと感じると思いますが
公式ドキュメントには大抵の答えが載っているので、全てを理解しようとして読まずとも
公式ドキュメントを見る癖をつけておくのが良いです。
英語が読めなければ翻訳サイトを駆使して、英語のドキュメントも臆さずに読むと
知識の深掘りになり、より理解を深めることができます。
***
### 2. 自分に合う思考方法を知る
「どのように考えたら物事を理解しやすいのだろうか？」
と、あなたは自分の思考方法について考えたことがありますか？
私は社会人になって初めて考えました。
そして、**人によって思考・理解の仕方は全く異なる**ということを知りました。

簡単に例を挙げるだけでも
* 言葉で理解するのが得意な人
* 文字で理解するのが得意な人
* 図で理解するのが得意な人
* 読みながら/書きながら/言葉にしながら 理解するのが得意な人　などなど

人の思考方法は様々です。
自分に合った方法で考えるのが一番効率良く理解ができ、学びになると思うので
まずは自分に合う思考方法について考えてみましょう。
自分に合う方法がわからなければ、一通り色々な方法を試してみるのが良いと思います。

ちなみに、私は**図を書きながら考える**ことが一番自分に合っていたので
ノートやiPadを活用して思考を整理したりロジックを考えたりしていました。
プログラミングを勉強する際もただがむしゃらに勉強するよりも自分に合った学習方法について考え、
その方法で学習するのが良いと思います。

***
### 3. 質問の仕方を工夫する
例えばわからないことがあったとします。
先輩にただ
「わかりません。教えてください。」
と言っても、何がわからなくて何を知りたいのかがわからず先輩も困ってしまうことでしょう。
仮に先輩が1から100まですべてを完璧に説明してくれたとして、それをあなたは理解できるでしょうか？
わからない単語が次から次へと出てきて
「問題解決するどころかわからないことが増えてしまった...」
なんてことになりかねません。

なので質問をする時には、

**「自分がどこでつまづいて何がわからないのか」**
**「自分がわかっている(と思っている)こと」**
（↑これが間違っていることもよくある。でもめげない。）

をパソコンなりノートなりにまとめて質問に行くと良いです。
これをすると、説明を聞きながらメモを取ったり分からないことがあればその場で質問しやすくなります。最後に「自分が理解したこと」や「今からやるべきこと」を確認するとスムーズに仕事に取り掛かれます。

また、これを続けていると自分の得意分野や苦手分野がなんとなくわかるようになってきます。
私はロジックの組み立てに苦手意識があったので、最近はロジックの組み立てにも臆せず挑戦するようにして苦手を克服しようとしています。

# 終わりに

自分の全く知らない世界に飛び込むのは不安なことも沢山ありますが
伸び代だらけなので何をしても学びになるし自分の成長を感じられる機会が多いです。

日々の業務で「文系で良かった！」と思うことは正直ないですが
全然文系でもエンジニアになれます。これは自信を持って言えます。
~~一年前にはMacの使い方さえ全くわからなかった私ですが、~~
一年で「エンジニアらしくなったね」と周りの人に言ってもらえるくらいには成長できたので
たとえ「自分には向いてないんじゃないか...」と思っても興味があったら挑戦してみるのも良いと思います。私と一緒に頑張りましょう！

最後まで記事を読んで頂き、ありがとうございました。
AWS EC2 → S3接続の最低条件（個人メモ）

# 概要

- EC2からS3にアクセスする際の最低限の条件とやらないといけないことをまとめておく

# すみません

- おそらく他にも方法があり、条件があると思います。ベストプラクティスではないですが、かなりEC2とS3の接続で詰まったのでまとめさせてください。

# 最低条件

- S3にアクセスできる権限を持ったIAMユーザーのアクセスキーとシークレットアクセスキーがEC2に`$ aws configure`コマンドで登録されていること。
- S3にアクセスできる権限を含んだIAMロールがEC２に設定されていること。

# 参考文献

- [https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-instance-access-s3-bucket/](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-instance-access-s3-bucket/)
[ Ryzen CPU & Windows ] VMwareにmacOSをいれる!

# 手順
1. vmware workstation をインストール
2. unlockerでvmwareの制限を解除
3. 仮想vmxファイルを編集
4. 仮想環境を実行
5. ドライブを初期化する
6. OSをインストール
7. VMware Toolsインストール
8. ※ usbが認識されない時

# 1. vmware workstation をインストール
https://www.vmware.com/in/products/workstation-pro/workstation-pro-evaluation.html


# 2. unlockerでvmwareの制限を解除
https://github.com/paolo-projects/unlocker/releases/

- unlocker.zipを解凍
- ウィルスソフトを停止

```: cmdで管理者モードで実行
$ cd unlocker
$ win-install.cmd
```

# 3. 仮想vmxファイルを編集

仮想環境を保存したディレクトリへ移動して.vmxファイルに以下を追記

```仮想環境名.vmx
smc.version = "0"
cpuid.0.eax = "0000:0000:0000:0000:0000:0000:0000:1011"
cpuid.0.ebx = "0111:0101:0110:1110:0110:0101:0100:0111"
cpuid.0.ecx = "0110:1100:0110:0101:0111:0100:0110:1110"
cpuid.0.edx = "0100:1001:0110:0101:0110:1110:0110:1001"
cpuid.1.eax = "0000:0000:0000:0001:0000:0110:0111:0001"
cpuid.1.ebx = "0000:0010:0000:0001:0000:1000:0000:0000"
cpuid.1.ecx = "1000:0010:1001:1000:0010:0010:0000:0011"
cpuid.1.edx = "0000:0111:1000:1011:1111:1011:1111:1111"
smbios.reflectHost = "TRUE"
hw.model = "MacBookPro14,3"
board-id = "Mac-551B86E5744E2388"
```

# 4.  仮想環境を実行

仮想環境を実行する

# 5. ドライブを初期化する

ユーティリティーを開く　→　名前がVMWareから始まるドライブを消去

# 6. OSをインストール

macOSインストーラーを実行

# 7. VMware Toolsインストール

設定のcd/dvdでunlocker/tools/darwin.isoを指定して仮想環境のmac上でインストールする

これにより、usb等のデバイスが認識されるようになる

# 8. ※ usbが認識されない時

windows管理ツール > サービス > VMware USB Arbitration Service > プロパティ > サービスの状態　＞ 開始にする
【GAS + Slackbot】毎朝担当を通知する当番botをつくる

## はじめに

弊チームでは、朝会の司会を持ち回りでやっています。
しかし、当番の人が司会担当であることをちょくちょく忘れるので、Slackbotを作ってみました。
本記事ではその作り方を紹介します。

## 1. Botの用意
以下の記事を参考に、Botを用意してください。
https://qiita.com/k_ued/private/07978ede29a67be761bb

## 2. ユーザー情報をまとめる

スプレッドシートに当番にあたるユーザー情報をまとめます。
必要なデータは「ユーザー名」「ユーザーID」の2つです。
以下のようにまとめます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429691/762c987f-d3ab-0cb6-6dea-c46e90475645.png)

## 3. スプレッドシートで当番を取得するGASを書く
「次の当番はだれか」を保持する必要があるため、D1セルにポインタを保持しています。
最初の1回目が誰かを示しておく必要があるため、ちょっとだけGSSを編集する必要があります。

### GSS

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429691/5807441a-74ee-1a12-a82f-e3c1dfa91352.png)

### コード
```
const GSS_ID = "スプレッドシートID";
const GSS_SHEET = "sheetA";
const POINTER_CELL = "D1";
const NUMBER_OF_PERSON = 3;

/**
 * GSSから当番を取得する
 */
function getDutyUser() {
  // シート取得
  const book = SpreadsheetApp.openById(GSS_ID);
  const sheet = book.getSheetByName(GSS_SHEET);

  // ポインタ取得
  const pCell = sheet.getRange(POINTER_CELL);
  const p = pCell.getValue();

  // ユーザー取得
  const dutyUser = sheet.getRange(p, 1, p, 2).getValues();

  // ポインタ追加
  pCell.setValue((p % NUMBER_OF_PERSON) + 1);

  return {
    name: dutyUser[0][0],
    id: dutyUser[0][1]
  }
}
```
GSSの操作については以下の記事を参考にしてください。
https://qiita.com/k_ued/items/90e088368c2c653b75f3

## 4. メッセージを投稿するGASを書く

### ライブラリの追加
SlackAPI用のライブラリを入れます。
GASを開き、左のメニューから「ライブラリ」の＋ボタンを押下します。

スクリプトIDに以下の値をコピペし、検索したのち、追加します。
`1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq`

### コード
```
function postSlackbot() {
  // ボットのトークンを設定
  const token = "xoxb-XXX";
  const slackApp = SlackApp.create(token);

  const dutyUser = getDutyUser();

  // 投稿先
  const channelId = "#hogehoge";
  // 投稿するメッセージ
  const message = `<@${dutyUser.id}> 今日の担当は${dutyUser.name}さんです。`

  // postMessageメソッドでボット投稿
  slackApp.postMessage(channelId, message);
}
```

## 5. GASのトリガーを設定

あとは好きな曜日、時間に投稿されるようトリガーを設定するだけです。
トリガーは左のメニューから設定できます。

![2022-03-31_14h26_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429691/184578e9-7ab9-1418-0dcf-7a67e8a16f03.png)

トリガータブを開いたら、右下の「トリガーを追加」ボタンを押下します。
すると、ダイアログが開かれるので、以下のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429691/7f5d6e5f-43a6-683c-9450-5f5025c8136d.png)

大事なのは以下の2点です。そのほかのメニューについてはお好みのものを選択してください。
- 実行する関数に[postSlackbot]を設定する
- 実行するデプロイに[Head]を選択する

## 注意事項

- 「平日だけ通知する」としたい場合は、トリガーを5つ設定する必要があります。
- 現状、当番の入れ替えやスキップ機能が備わっていません。今後追加していく予定です。