OmniAICreator/Qiita-1.07M huggingface dataset:
SwiftUI で List の height を中身に合わせて動的に変化させる

**追記：** NavigationView の中だと上手くいかない場合がありました。

---

SwiftUI で List の高さを中身に合わせて変える方法です。
下の画像の様に、 List の高さを中身と同じにします。（グレーの部分は List の背景です。）

**高さ設定前**
![スクリーンショット 2021-07-23 午前4.50.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/cfa5e951-d3d6-e599-2c32-e11cd38c13d9.png)

↓

**高さ設定後**
![スクリーンショット 2021-07-23 午前4.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/2b228060-9747-f088-778a-35f26d857d69.png)

List と同じ様に表示される（高さが同じになる） VStack を作成して、その高さを List に設定しています。


```swift
import SwiftUI
import Combine

struct Item: Identifiable {
    var id = UUID()
    var name:String
}

class ViewModel: ObservableObject {
    var items:[Item] = { (0..<2).map { i in Item(name: "item\(i)") } }()

    @Published var listHidden = true
    var listHeight:CGFloat = 0

    var publisher = PassthroughSubject<Bool, Never>()
    
    func setHeight(_ height: CGFloat) {
        listHeight = height
        // 5. List を表示
        listHidden = false
    }
}


struct MyView: View {
    @ObservedObject var viewModel = ViewModel()

    init() {
        // 分かりやすい用に List の背景色を付けます
        UITableView.appearance().backgroundColor = UIColor.lightGray
    }

    var body: some View {

        // 1. VStack の方が表示される
        if viewModel.listHidden {
            ZStack {
                VStack(spacing: 0) {
                    ForEach(viewModel.items) { item in
                        Row(item: item)
                    }
                }
                .background(
                    GeometryReader { geo in
                        Color.white
                            // 4. viewModel の listHeight に高さをセット
                            .onReceive(viewModel.publisher) { _ in
                                viewModel.setHeight(geo.size.height)
                            }
                    }
                )
                // 2. VStack が見えないようにする
                Color.white
            }
            // 3. 表示したら publisher から通知
            .onAppear { viewModel.publisher.send(true) }

        // 6. 表示される
        } else {
            List {
                ForEach(viewModel.items) { item in
                    Row(item: item)
                }
            }
            // 7. 高さを設定
            .frame(height: viewModel.listHeight)
        }
    }
}

struct Row: View {
    var item:Item
    var body: some View {
        Text(item.name)
            .listRowInsets(.init()) // 余白を消しておく
            .padding()
            .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
            .background(Color.orange)
    }
}

struct MyView_Previews: PreviewProvider {
    static var previews: some View {
        MyView()
    }
}

```

---

**バージョン**
Swift 5.4
EmbulkでAmazon Athenaから入力する 

[embulk-input-athena](https://rubygems.org/gems/embulk-input-athena)では弊社の要件に合わなかったので、参考にさせて頂きつつ、[embulk-input-jdbc]()でやってみました。

## 前準備
### JDBCドライバをダウンロードする
Athena用JDBCドライバをダウンロードし、Embulkから参照可能な場所に保存しておきます。

```bash
wget -P /path/to/ https://s3.amazonaws.com/athena-downloads/drivers/JDBC/SimbaAthenaJDBC-2.0.21.1000/AthenaJDBC42.jar
```

## 設定ファイルを書く
Embulkの設定ファイルに、Athenaからの入力設定を記述します。

```yaml
# vim /path/to/_in_athena.yml.liquid
in:
  type: jdbc
  # ダウンロードしたJDBCドライバのパス
  driver_path: /path/to/AthenaJDBC42.jar
  # JDBCドライバのクラス名
  driver_class: com.simba.athena.jdbc.Driver
  # JDBC URL (接続情報)
  # AwsRegion        AWSリージョン
  # User             AWSアクセスキー
  # Password         AWSシークレットアクセスキー
  # WorkGroup        Athenaのワークグープ名 AWSコンソール->Athena->ワークグループで確認
  url: jdbc:awsathena://AwsRegion={{AWS_DEFAULT_REGION}};User={{AWS_ACCESS_KEY_ID}};Password={{AWS_SECRET_ACCESS_KEY}};WorkGroup={{ATHENA_WORK_GROUP}}
  query: |
    SELECT
      *
    FROM (
      SELECT
       *, row_number() over (PARTITION BY id ORDER BY updated_at DESC) AS rn
      FROM {{DB_NAME}}.{{TABLE_NAME}}
    )
    WHERE rn = 1
```

## 参考

- [JDBC ドライバーのインストールおよび設定ガイド(pdf)](https://s3.amazonaws.com/athena-downloads/drivers/JDBC/SimbaAthenaJDBC-2.0.21.1000/docs/Simba+Athena+JDBC+Connector+Install+and+Configuration+Guide.pdf)
 - JDBCドライバの公式ガイドです。JDBC URLのオプションは上記の限りだけではないので、調べてみれば多様な要件に対応できるかもしれません。

## その他
- embulk-input-athenaを採用しなかった理由
 - カラムの指定がrequiredであるため、全カラムまるごと転送したいという要件に合いませんでした。
2021/07/21開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[Kubernetes Meetup Tokyo #43](https://k8sjp.connpass.com/event/217089/)|[Kubernetes Meetup Tokyo](https://k8sjp.connpass.com/)|423||
|:two:|[第9回ザッピングセミナー](https://zappingseminar.connpass.com/event/216876/)|[ザッピングセミナー](https://zappingseminar.connpass.com/)|422|500|
|:three:|[Shopifyキャッチアップ会！Sections EverywhereとDawnの特徴を知ろう！](https://tokyofreelance.connpass.com/event/220035/)|[東京フリーランス](https://tokyofreelance.connpass.com/)|268|500|
|:four:|[エンジニアの勉強法ハックLT- vol.5 #studyhacklt](https://rakus.connpass.com/event/216412/)|[ラクス](https://rakus.connpass.com/)|228|240|
|:five:|[Future Tech Night #14～認証認可（IDaaS）勉強会～](https://future.connpass.com/event/218520/)|[フューチャー](https://future.connpass.com/)|190|200|
Linuxコマンド - ユーザ・グループの確認/追加/削除

## この記事について
* この記事で、Linux上でのユーザやグループの追加・削除コマンドの紹介を行います。
* 「ユーザやグループとは何」というような概念的は部分は記載しておりません。  
ユーザやグループの概念的な部分は以下のサイトを参照
    * [【初心者でもわかる！】Linuxのユーザとは？](https://eng-entrance.com/linux-user-what)
    * [【初心者向け】Linuxのグループとは？ ざっくりの説明](https://eng-entrance.com/linux-user-group)

## 対象読者
* Linuxでユーザ管理やグループ管理（ユーザやグループの確認・追加・削除）を行いたい方

## 環境
utunbu 20.04.1

## 確認
### ユーザ一覧

```
cat /etc/passwd
```

### グループ一覧

```
cat /etc/group
```

### 指定ユーザが所属するグループ一覧

```
groups ユーザ名
```
例： `testuser` ユーザは `testgroup` と `testgroup2` の2つのグループに属する

```
ubuntu@example:/$ groups testuser
testuser : testgroup testgroup2
```

## 追加
### ユーザ

```
sudo adduser ユーザ名
```
例： `testuser` というユーザ名で新規ユーザを追加

```
ubuntu@example:/$ sudo adduser testuser
[sudo] password for ubuntu:
Adding user `testuser' ...
Adding new group `testuser' (1002) ...
Adding new user `testuser' (1002) with group `testuser' ...
Creating home directory `/home/testuser' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for testuser
Enter the new value, or press ENTER for the default
        Full Name []: testuser
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []: none
Is the information correct? [Y/n] y
```

### グループ

```
sudo groupadd グループ名
```
例：`testgroup` というグループ名で新規グループを追加

```
ubuntu@example:/$ sudo groupadd testgroup
```

### 指定ユーザが所属するグループの追加（と変更）
* 主グループの変更

    ```
    sudo usermod -g グループ名 ユーザ名
    ```
    例： `testuser` ユーザの主グループを `testgroup` グループに変更

    ```
    ubuntu@example:/$ sudo usermod -g testgroup testuser
    ```

* 副グループの追加

    ```
    sudo usermod -aG グループ名 ユーザ名
    ```
    例： `testuser` ユーザの副グループに `testgroup2` グループを追加

    ```
    ubuntu@example:/$ sudo usermod -aG testgroup2 testuser
    ```
    ※ 後述する `gpasswd` でも特定ユーザにグループ追加ができる模様
    （[linux ユーザをグループに追加・削除する gpasswd 編](https://takuya-1st.hatenablog.jp/entry/2016/07/22/165742)）

* 副グループの変更

    ```
    sudo usermod -G グループ名 ユーザ名
    ```
    例： `testuser` ユーザの副グループを `testgroup3` グループに変更

    ```
    ubuntu@example:/$ sudo usermod -G testgroup3 testuser
    ```

## 削除
### ユーザ

```
userdel -r ユーザ名
```
`-r` によって、削除対象のユーザの `home` ディレクトリも削除する
例： `testuser` ユーザを削除

```
userdel -r testuser
```

### グループ

```
groupdel グループ名
```
**あるユーザが属している副グループも削除されてしまう**ため、グループの削除時は他ユーザが属していないことの確認を行うと良い。
例： `testgroup2` グループを削除

```
groupdel testgroup2
```


### 指定ユーザが所属するグループの削除
* 主グループから削除
    どのユーザも必ず何らかのグループの属するため、主グループからの削除は行えない

* 副グループから削除

    ```
    sudo gpasswd -d ユーザ名 グループ名
    ```
    例： `testuser` ユーザを `testgroup2` グループから削除

    ```
    ubuntu@example:/$ sudo gpasswd -d testuser testgroup2
    Removing user testuser from group testgroup2
    ```

## 参考
* [groupadd - 新規グループの作成 - Linuxコマンド](https://webkaru.net/linux/groupadd-command/)
* [usermodコマンドについて詳しくまとめました 【Linuxコマンド集】](https://eng-entrance.com/linux-command-usermod)
* [ユーザーをグループから削除（追放）するCentOS7](https://adan.jp.net/blog/programing/1788)
* [linux ユーザをグループに追加・削除する gpasswd 編](https://takuya-1st.hatenablog.jp/entry/2016/07/22/165742)
JenkinsでGitHubからUnityビルドと結果を通知自動化メモ

新しく、記事を下のリンク先に移行しましたので、よろしかったら、参考になってください。

[JenkinsでGitHubからUnityビルドと結果を通知自動化](https://fanblogs.jp/3apes/archive/9/0)
文系エンジニア（志望）の振り返り-at coder

##1.qiitaアカウント設立の目的と投稿理由

様々なところで、「エンジニアたるものアウトプットが必須」とのご意見をいただいたため。
また、自分の学習内容のメモとしても利用。
初心者であるため、これまでの学習内容で詰まりがちであった内容を整理のため。
ひとまず、当記事ではatcoderの[初心者問題]('https://atcoder.jp/contests/abs/tasks')のB問題のコードを掲載


##2.学習内容、投稿コンテンツについて
現在はpythonの学習と並行して、統計学の学習を行っている。投稿としては主としてその辺。見られることはあまり想定していない。

##3 atcoderについて
役に立たないとの声も多いが、初心者〜初級者の間の人間の学習コンテンツとしては最適であるように感じる

### ABC081B - Shift only

```
n=int(input())
a=list(map(int,input().split()))
count=0

flag = True
while flag:
    for i in a:
        if i%2 !=0:
            flag=False
            break
```


### ABC081B Shift only

```
A=int(input())
B=int(input())
C=int(input())
X=int(input())
count=0
for a in range(A+1):
    for b in range(B+1):
        for c in range(C+1):
            if 500*a+100*b+50*c==X:
                count +=1
print(count)
```


### ABC083B Some Sums

```
n,a,b=input().split()
count=0
for i in range(int(n)+1):
    i_s=str(i)
    array=list(map(int,i_s))
    sum_n=sum(array)
    if int(a)<=sum_n<=int(b):
        count += i
    else:
        pass
print(count)
```


##ABC088B Card Game for Two

```
n=int(input())
list_b=sorted(list(map(int,input().split())),reverse=True)

count_a=0
count_b=0

for i in range(0,n,2):
    count_a += list_b[i]
for t in range(1,n,2):
    count_b += list_b[t]

print(count_a-count_b)
```


###ABC085B Kagami Mochi

```
N, Y = map(int,input().split())
for x in range(N+1):
    for y in range(N-x+1):
        if 10000*x + 5000*y + 1000*(N-x-y) == Y:
            print(x,y,N-x-y)
            exit()
print(-1,-1,-1)
```

総評
とりあえずクリアはしたけれど、これでいいのか？というものが多い。
クリスタで出力したPhotoshopカラースウォッチファイル(.aco)の仕様メモ


初投稿です。結構雑なメモですが需要があれば。

# 経緯と注意点
筆者はクリスタユーザーで、カラーセット（Photoshopのカラースウォッチのようなもの）を色々カスタマイズしようとしていたのですが、クリスタのカラーセットファイル(.cls)の仕様がわからなかったので、Photoshopスウォッチファイル形式(.aco)で入出力を行うことにしました。
その際、[仕様書（英語）](https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/)を読んだり、VSCodeでバイナリファイルを見たりして分かったことをまとめたものがこちらです。

つまり、**クリスタから書き出されたacoファイルしか見ていないので、Photoshopで書き出したものとは異なる点があるかもしれない**です。そこだけご注意を！

# 全体の構造
|長さ(byte)|項目|値|エディタ上(例)|
|:----:|:----:|:----:|:----:|
|2|バージョン(1)|1に固定|00 01|
|2|ファイル内の色の数n|範囲は不明*|00 80|
|n×10|色データ|下の表参照|略|
|2|バージョン(2)|2に固定|00 02|
|2|ファイル内の色の数n|範囲は不明*|00 80|
|n×(10+任意)|色データ+色名(Unicode文字列**)|下の表参照|略|
\*実験してません。0色でクリスタから出力しようとしたらできませんって言われちゃった
**クリスタのカラーセットでは色名を付けられないので、ここがどうなってるのかは詳しくわかりませんでした。
仕様書曰く
"UTF-16のユニット数(=文字数＋終端文字1ユニット分？)を表す4byte＋文字数×2byte＋終端文字2byte"
になるらしいです。実際、クリスタからの出力ファイルだと、この部分は全部の色で

```
00 00 00 01 00 00
// 前半4byteはユニット数(=1)、後半2byteは終端文字
```

になっていて、仕様に即しているのがわかります。

## 色データ
|長さ(byte)|項目|値|エディタ上(例)|
|:----:|:----:|:----:|:----:|
|2|色の表現形式(IDで指定)|0|1|2|7|8|00 00|
|8|上の表現形式で表現された各色のデータ。<br> 8byteすべてに値が入らないときは、残りの値は定義されず0になる。|IDによる|FF FF FF FF FF FF 00 00<br>(RGB(255,255,255)の真っ白)|

## 表現形式ID
|ID|形式|色データパラメータ|エディタ上(例)|
|:---:|:---:|:---:|:---:|
|0|RGB<br>(Red, Green, Blue, 00 00)<br>すべてunsigned 16-bit|それぞれ[0,65535]|00 00 FC FC ED ED D5 D5 00 00|
|1|HSB<br>(hue, saturation, brightness, 00 00)<br>すべてunsigned 16-bit|それぞれ[0,65535]||
|2|CMYK<br>(cyan, magenta, yellow, black)<br>すべてunsigned 16-bit|それぞれ[0,65535]| |
|7|Lab<br>(lightness, a chrominance, b chrominance, 00 00)<br>すべて16-bit|[0,10000],[-12800,12700],[-12800,12700]| |
|8|Grayscale<br>(grayscale, 残り全部00)<br>その名の通りグレースケール|[0,10000]| |
- 他にもIDと形式は存在するが、詳細はあまり公開されていない。(仕様書にちょっと書いてあります)
- クリスタではバージョン1と2ともにRGB形式で書き出されるみたいです。
- Photoshopではどうなのかわかりませんが、普通は色のパラメータって8bitの範囲[0,255]で扱うのでなんらかの変換が必要かも（クリスタの出力では8bitの値が2回繰り返されている）

# そのほか
- クリスタ→ACO形式だと透明色はRGB(0,0,0)の値になるっぽい？→読み込んでみたら透明色は全部黒になってました
- クリスタはバージョン2のほうのみを読んでるっぽい（バイナリファイルをバージョン2のほうだけ変えたらバージョン2に即した色になった）
- RGBの各2byteの値は1byteの0~255の繰り返しだが、どちらも同じ値じゃないと読み込んだ時おかしくなったのでちゃんと繰り返して書いておく必要がありそう。
- 16進数カラーコードとカラーセットファイルの変換ツールとかはすぐ作れそうですね

# 参考
ここに書いてある半分は仕様書の一部を訳したものなので、こちらも見てみてください！

https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1055819
GCP の global と multi-region と region と zone

- global
    - 
 global resource の例は、HTTPSs load balancer, VPC network
- multi-region
    - `Americas`内, `Europe`内, `Asia Pacific`内の3つがある
- region
    - region内なら、往復のnetwork latency は (95th percentile で) 1 millisecond未満
    - regionalに設定できるものの例は、GKE cluster, DataStore
    - `東京`とか
- zone
    - =データセンターと考えていい
GitHub Actionsを使ってDokkaで出力したドキュメントをGitHub Pagesにデプロイする

## 目的

タイトル通りです。

Dokkaについて詳しく知りたい方は↓へどうぞ。
http://kotlin.github.io/dokka/1.5.0/

## 準備

### Gradle

``` build.gradle.kts
plugins {
    id("org.jetbrains.dokka") version dokkaVersion
}

repositories {
    mavenCentral()
}

// ビルド先のディレクトリを指定します。なくても大丈夫です。
tasks.getByName<org.jetbrains.dokka.gradle.DokkaTask>("dokkaHtml") {
  outputDirectory.set(buildDir.resolve("dokkaHtmlOutput"))
}

```

``` build.properties
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
```

Dokkaはメタスペースを大量に消費して最悪の場合`OutOfMemory`が発生するので、程よく調整してください。

### ワークフロー

https://github.com/peaceiris/actions-gh-pages

こちらを用いてデプロイします。

``` ..github/workflows/deploy_gh_pages.yml
name: 'Deploy Document to GitHub Pages'

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: 'ubuntu-20.04'
    steps:
      - uses: actions/checkout@v2
# ドキュメントのビルド
      - name: Build Document
        run: ./gradlew dokkaHtml
# デプロイ
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./build/dokkaHtmlOutput
```

## 結果

`main`ブランチにプッシュするとCIが回ります。

サンプルはこちら

https://uramnoil.github.io/Serverist/backend/index.html

## まとめ

GitHub Actionsを使ってDokkaで生成したドキュメントをGitHub Pagesにデプロイする方法でした。

ローカルでのDokkaのビルドでOOMが発生してたので、戦々恐々としながらも作ったワークフローをGitHub Actionsで回してみたものの、案の定こけていました。
GitHub Actionsのvmoptionsを変更する方法が見当たらず、Dokka側で最適化されるのを待つしかないのかと半ば絶望してました。

それ以外はよそ様のActionsを使ったりと色々と楽をしていたら拍子抜けするくらいすぐにデプロイできたのでなかなか楽しかったです。
Amazon Linux 2 (aarch64)にimagick(ImageMagick)をインストール

# インストールした環境

AWS､EC2のt4gインスタンスです｡

```bash
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
Linux hostname 4.14.232-177.418.amzn2.aarch64 #1 SMP Tue Jun 15 20:58:11 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux
```

# 手順

- ImageMagickをソースコードからインストール
- imagickをインストール

# ImageMagickをインストール

現時点(2021/07/23)では､ARM(aarch64)用のrpmは用意されていないのでソースコードからインストールします｡

ソースコードインストール手順は公式サイトに従います｡
｢tarボールをダウンロード｣する記事が多いですが､現在は`git clone`で取得するのが正規の手順のようです｡

[ImageMagick - Install from Source](https://imagemagick.org/script/install-source.php)


最初にライブラリインストール

```
sudo yum install fftw3 gcc libwebp libwebp-devel
```

ソースコードからインストール

```
cd /usr/local/src
git clone https://github.com/ImageMagick/ImageMagick.git ImageMagick-7.1.0
cd ImageMagick-7.1.0
./configure
make
make install
```

バージョン確認

```
/usr/local/bin/convert --version

Version: ImageMagick 7.1.0-5 Q16 aarch64 2021-07-18 https://imagemagick.org
･･･
```

# imagickをインストール

```bash
yum install php-pear
pecl install imagick
```

インストール確認

```bash
pecl list | grep imagick

imagick 3.5.0   stable
```

php.ini に以下を追加

```ini:/etc/php.ini
extension=imagick.so
```

サーバ再起動(ApacheとFPMの場合）

```bash
systemctl restart php-fpm
systemctl restart httpd.service
```

PHPモジュールとして認識されたか確認

```bash
php -m | grep imagick

imagick
```
変数にリストを代入したが元リストの演算影響を受けてしまう

<h1>リストを代入したリストの値が元リストの演算影響を受けてしまう</h1>
元のリスト```old_list```を汚さずに処理をしたく思い、下のように別の変数```new_list```に代入した。
```remove```による要素削除を```new_list```に施したところ、```old_list```の要素も消えていた...


```python:test.py
old_list = [1, 2, 3]
new_list = old_list
new_list.remove(2)

print(old_list)
#[1, 3] 
print(new_list)
#[1, 3]
```

<h1>解決策</h1>```copy()```を使い、値渡しをする

```python:solution.py
old_list = [1, 2, 3]
new_list = old_list.copy()　#値渡し
new_list.remove(2)

print(old_list)
#[1, 2, 3] 
print(new_list)
#[1, 3]
```
Easy SaveとAssembly Definitionの注意点

#はじめに
UnityにはAssembly DefinitionというC#のビルドファイルを分割して出力できる機能があります。
詳細は「[Unity Assembly Definition 完全に理解した](https://qiita.com/toRisouP/items/d206af3029c7d80326ed)」を参照してください。

[Easy Save](https://assetstore.unity.com/packages/tools/utilities/easy-save-the-complete-save-data-serialization-asset-768?aid=1101lGoY&utm_source=aff)はUnityで簡単にセーブ・ロード・暗号化が実装できるアセットです。

さて、現在Assembly Definitionを切りまくっている自分のUnity ProjectでEasy Saveを活用していた所、幾つかハマりポイントを発見したので共有します。


一般的なエラーはKanさんのブログを参照してください
[Easy Saveを使ってるうちに遭遇するかもしれない、いくつかのエラーとその対処法【Unity】【アセット】【Easy Save】【トラブルシューティング】](https://kan-kikuchi.hatenablog.com/entry/Easy_Save_Error)

# Easy SaveにAssembly Definitionを追加する
Easy Saveは標準ではAssembly Definitionを追加していないため、Assembly Definitionを切っているアセンブリ内でEasy Saveの機能を追加するには、自分でAssembly Definitionを追加しなければなりません。

それでは、`Assets/Plugins/EasySave3/Scripts`内に`ES3`という名称でAssembly Definitionファイルを作成します。`Assets/Plugins/EasySave3/Editor`内には`ES3.Editor`という名称でAssembly Definitionファイルを作成し、Assembly Definition ReferencesにES3.asmdefを追加しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281560/a04ea805-f471-aa06-afb0-ea5da7036056.png)

しかしこのままだと、どんな型の値を保存しようとしても
`ES3Type for primitive could not be found, but the type list has been initialised and is not empty. Please contact Easy Save developers on mail@moodkie.com
`
というエラーが出てしまいます。
このエラーを解決するには、`Assets/Plugins/EasySave3/Resources/ES3/ES3Defaults.asset`を選択し、Assembly Namesに今回追加したAssembly Definitionファイルの名前（今回はES3）を追加しないといけません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281560/77151e97-9239-68da-6a45-5284fbaed58e.png)


# 保存済みの型のnamespaceかAssembly Definitionファイルを改名する
Easy Saveでは値のセーブ時に、stringのkeyだけでなくnamespaceとアセンブリ名も使用しています。
そのため、既にセーブしてあるクラスや構造体のnamespaceやアセンブリ名（Assembly Definitionファイル名）を変えた場合、keyは一致するがnamespaceかAssembly Definitionファイルが異なるため
`System.InvalidOperationException: Trying to load data of type 保存対象の型, but data contained in file is type of`というエラーが発生して、読み込み処理ができなくなります。

この場合はes3ファイルを直接書き換えるか、作り直す必要があります。
debianでkea dhcp serverを利用する

#kea
dhcpサーバとしてはiscの[dhcp server](https://www.isc.org/dhcp/)が有名ですが、新しいdhcpサーバとして[kea](https://www.isc.org/kea/)が開発されています。

## debianへのインストール
debianの公式パッケージにもkeaは含まれていますが、より新しいバージョンを利用したい場合はiscのリポジトリを追加して利用します。

詳しい方法については、すでに記事[「パッケージからISC Kea DHCP サーバのインストール方法」](https://qiita.com/akiyoshi_tomita/items/8e85d8f96a91b02e28cb)があるので、そちらを参照してください。

また、こちらの環境では[「Kea DHCPでAct-Act(load-balancing)のHA構成を組む」](https://qiita.com/jp7fkf/items/969f784daff69940cbf4)の記事を参考に2台のkeaでHA構成(Act-Act)にしています。

### systemd用の起動ファイル修正
mariadbにdhcpの情報を保存するようにしたら、インストールしたままでは、再起動時にisc-kea-dhcp-serverが正常に起動しなくなっていた。詳しく調べると、どうやらsystemdで起動する際にmariadbが起動する前にkeaが起動すると、異常終了してしまう。

systemdの設定ファイルで起動の依存関係を記述することで回避しようとしたがうまくいかなかった。
`/lib/systemd/system/isc-kea-dhcp4-server.service`の\[Unit\]セクションに

```
[Unit]
...
After=mariadb.target
```

を追加してみた。これでうまくいくと思ったが、実際にリブートすると異常終了している。そこで\[Service\]セクションの`ExecStart`を修正してmariadbのソケットが生成されるまでkeaの起動を待つようにした。

```
[Service]
...
ExecStart=/usr/bin/bash -c "while [ ! -S /var/run/mysqld/mysqld.sock ]; do sleep 1; done;/usr/sbin/kea-dhcp4 -c /etc/kea/kea-dhcp4.conf"
```

これで再起動してもkeaが正常に稼働してることを確認できた。

### DBの更新
apt upgrade
すると、うまく起動しなくなった。keaのlogを確認すると

```
2021-08-06 12:11:36.699 ERROR [kea-dhcp4.dhcp4/63609.140537304271296] DHCP4_INIT_FAIL failed to initialize Kea server: configuration error using file '/etc/kea/kea-dhcp4.conf': Unable to open database: MySQL schema version mismatch: need version: 10.0 found version: 9.6
```

というエラーが記録されており、どうやらデータベースのschemaが更新された模様。

```
kea-admin db-upgrade mysql -u kea -n kea -p
```

を実行してデータベースを更新し、restartすると無事に起動した。
firebaseのdatabaseに追加ができない原因

#firebaseのdatabeseに追加処理する実装を忘れないための備忘録

##オブジェクトの中がundefined
```js
const booksRef = firebase.database().ref('books')

methods: {
  addBooks(e) {
    const bookData = {
      title: e.title,
      image: e.image,

      //undefinedの原因
      discription: e.discription,

      id: this.books.length,
      readDate: '',
      memo: '',
      learn: '',
      important: '',
      examples: '',
      different: '',
      userId: this.$store.state.userId,
      }
      booksRef.push(bookData)
```

##discription: e.discriptionを削除

```js
discription: e.discription
```
オブジェクトの中がundefindなプロパティがあると追加処理ができない。
今回のケースではdiscription: e.discriptionがundefinedのためfirebaseのdatabeseに要素を格納できずにいましたが、削除したことでfirebaseのdatabaseに格納できました。
h5pyとnumpyの使い方

# はじめに
ここでは、h5pyの3.6.0で確認を行った。また、`google colab`で動かして確認した。

## 元データの作成

```python
import h5py
import numpy as np

expression_matrix =  np.random.rand(20000, 8)
sample_name = ['sample_' + str(x + 1) for x in range(8)]
```
## 書き込みの例

```python
out_file = './h5pysample.h5'

outfh = h5py.File(out_file, 'w')
outfh.create_dataset('expmat', data = expression_matrix)
outfh.create_dataset('sample_name', data = sample_name)
outfh.flush()
outfh.close()
```
## 読み出しの例
フォーマットとして出てくる`<f8`は、little-endian floating point 8byte(64bit)の意味である。Numpyのデータフォーマットに従っている。


```python
in_file = './h5pysample.h5'

infh = h5py.File(in_file, 'r')
print(infh.keys())
## <KeysViewHDF5 ['expmat', 'sample_name']

print(infh['expmat'])
## <HDF5 dataset "expmat": shape (20000, 8), type "<f8">

print(infh['expmat'][::])

expression_matrix_2 = np.array(infh['expmat'])
sample_name_2 = list(infh['sample_name'])

infh.close()
```

## 検索

HDF5データの検索で、テーブルリストに該当名称があるかないかは、`grep`で検索できる。上でいうところの`expmat`等で存在するテーブルを確認することが出来る。

# 参考資料

- [HDF5 for Python](https://docs.h5py.org/en/stable/index.html)
   - [Datasets](https://docs.h5py.org/en/stable/high/dataset.html)
- [バイナリーデータファイルのフォーマット HDF を扱う Python ライブラリー](https://bi.biopapyrus.jp/python/module/h5py.html) 
   - h5py 2.xの時点の記事である。(現在は、h5py 3.xとなっている)　参考にしたが、`Datasets`オブジェクトでは`.value`が動かない。このため`[::]`等を使う。説明は、[3.0のリリースノート](https://docs.h5py.org/en/stable/whatsnew/3.0.html)に記載されている。
- [The HDF Group](https://www.hdfgroup.org/)
  - [DESIGN SPECIFICATIONS](https://portal.hdfgroup.org/display/HDF5/Design+Specifications) 
- numpy
  - [`Data types`](https://numpy.org/doc/stable/user/basics.types.html) 
  - [`Data type objects (dtype)`](https://numpy.org/doc/stable/reference/arrays.dtypes.html)

# ソースコード

- [from ._hl.files import File](https://github.com/h5py/h5py/blob/3.6.0/h5py/__init__.py#L60-L65)
  - [class File(Group)](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/files.py#L261-L558)
     - [class Group(HLObject, MutableMappingHDF5)](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/group.py#L29-L625)
         - [def create_dataset](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/group.py#L69-L151) 
             - [def make_new_dset](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/dataset.py#L40-L147) 
         - [class MutableMappingHDF5(MappingHDF5, MutableMapping)](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/base.py#L470-L478)
             - [class MappingHDF5(Mapping)](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/base.py#L444-L467)
                 - [def keys](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/base.py#L453-L455) 
                     - [class KeysViewHDF5(KeysView)](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/base.py#L384-L391)  
- [from ._hl.dataset import Dataset](https://github.com/h5py/h5py/blob/3.6.0/h5py/__init__.py#L67)
  - [class Dataset(HLObject)](https://github.com/h5py/h5py/blob/3.6.0/h5py/_hl/dataset.py#L343-L1085)
Flutterでシンプルな枠付きの吹き出しを使いたかったのでパッケージを作った

# 経緯
業務で**枠付きの吹き出し**を使いたかったが、いい感じのパッケージがなかったので（パクって）作った
パッケージを使っていたんですがIssueなどに作成者が反応していないので、勝手にパクってパッケージ化しました。


# さっさと使い方人向け
https://pub.dev/packages/speech_balloon

ここでパッケージを公開しています。バグやリクエストはIssueまでおねがいします。

こんな感じで使えます
![example1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256196/0274a690-5a47-261a-f1a4-e634ed6bdff9.png)

# 簡単な使い方
### 画像の左上の吹き出しの場合
```dart
SpeechBalloon(
  nipLocation: NipLocation.bottom, // 向きを設定デフォルトは下です
  color: Colors.white, // 中身の色これはデフォルトで白になっています
  borderColor: Colors.red, // 境界線のカラーです、これを指定すると境界線の設定が有効になります
  nipHeight: 10.0 // 棘の部分の長さを指定出来ますデフォルトは１０ポイントです
  borderRadius: 2 // 四隅の丸みを設定しますデフォルトは2です
  // offset:  基本的に指定しなくてもいいですが、場合によってはずれてしまうのでその時は指定してください
  // innerBorderRadius: 基本的に指定しなくてもいいです、場合によってはずれてしまうのでその時は指定してください
  child: Icon(
    Icons.favorite,
    color: Colors.red,
  ),
)
```

### 画像の右下の丸の吹き出しの場合
```dart
SpeechBalloon(
  nipLocation: NipLocation.bottom,
  borderColor: Colors.green,
  height: 60, // マルなので同じheightとwidth
  width: 60,
  borderRadius: 40,
  offset: Offset(0, -1), // 棘の位置がずれてしまったのでoffsetで位置を修正してあげる
  child: Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Icon(
        Icons.people,
        color: Colors.green,
      ),
      Text(
        '11',
        style: TextStyle(color: Colors.green),
      ),
    ],
  ),
)
```

以上です下記からは公開の仕方などを書いていきます。

# Flutterでパッケージを作成する
この手の記事は無限にあると思うので、未来の私に向けて書いておきます。
https://flutter.dev/docs/development/packages-and-plugins/developing-packages
基本的なことはこの公式の記事に書いています

まず作成の際のcreateのコマンドのplatromsにはandroidとiosの指定を入れておきましょう

```
flutter create --org com.example --template=plugin --platforms=android,ios -a kotlin -i swift hello
```
これを入れずに作成した方は、後からでも追加できます

```
flutter create --template=plugin --platforms=android .
```
みたいな感じで

`-a` でAndroid `-i`でiosの言語を指定できます
これをしておくことでpubの`Support multiple platforms`の点数を上げることが出来ます（多分）

# 作ったパッケージを公開する

```
flutter pub publish
```

で公開できますが、**一度公開すると永久に削除出来ない**ので注意してください
使ってる方が使えなくなった、とかが無い様にらしいです。

あと`pubspec.yaml`には、`homepage`タグとか登録しましょう多分警告で出ると思うけど。

# パッケージのバージョンアップをする
同じく

```
flutter pub publish
```
でバージョンアップすることができます
この場合は`pubspec.yaml`のバージョンも上げておく必要があります。
Xcode ビルドファイルの保存先

xcodeでビルドし生成したファイルがどこに保存されているか分からなかったので調べてみました。

```md:保存先
/Users/{ userName }/Library/Developer/Xcode/DerivedData/{ productName }/Build/Products/{ Debug or Release}
```

上記のディレクトリ配下にビルドファイルが保存されています。

Products/配下の`Debug`,`Release`ですがXcodeでのビルド方法の指定によって変わります(デフォルトだとDebugビルドが指定されているはずです。)

ビルド方法の切り替えはXcode画面上部のプロジェクト名をクリックし、表示されたプルダウン内の「Edit Scheme...」を選択します。
![スクリーンショット 2021-07-22 23.54.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264641/923b1cb2-6943-d99d-cfdf-f09b41ab8b5e.png)
表示された設定の「Build Configuratior」を確認します。ここで選択されている値が現行のビルド方法です。(添付画像の場合はDebugビルドが指定されています)
![スクリーンショット 2021-07-22 23.54.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264641/7b0369cf-3cd9-334e-ab57-fb8604784b5a.png)
こちらの値を`Release`に設定すれば`Products/Release`にビルドファイルが生成されます。
ahkファイルを.exeにコンパイルする時にハマったこと

## 結論
コンテキストメニューからコンパイルせず、コマンドラインからコンパイルしたら行けました

``` cmd.exe
C:\Program Files\AutoHotkey\Compiler>Ahk2Exe.exe /in C:\Users\***\hoge.ahk
```

## 経緯
- まず普通にAutoHotKeyをインストール（https://www.autohotkey.com/）
- （Windows環境）作っておいたahkファイルをエクスプローラーでコンテキストメニューからコンパイルし、起動はするものの動いてない...
- 上記の方法で無事動いてやりたかったことが実現できました:smiley:
【ハンズオン1】基本的なブログサービスを構築する（シングル構成）

##今回の記事について
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com

隅から隅まで細かい説明はしません。
自分が構築して大事だと思った部分だけ記述します。

##環境
macOS Big Sur バージョン１１.２.２

##今回やること
・基本的な２つのAZにまたがる冗長構成の環境作成
・EC２へwordpressをインストール
・RDS作成
・publicIPにアクセスし、wordpress起動

##構成図

![hands-on1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1650745/a8f4adc3-2142-5b70-2132-d1f262f632b3.png)

##土台の環境作成
**・VPC作成**

**・サブネット作成**
パブリックサブネット＊２
プライベートサブネット*２
＊AZにそれぞれ１組ずつ作成

**・IGW（インターネットゲートウェイ）作成し、VPCにアタッチ**
**・パブリックサブネットのルートテーブルにIGW（インターネットゲートウェイ）を追加する**
**・ルートテーブルにパブリックサブネットを関連づける**
**・プライベートサブネット用のルートテーブル作成＆サブネットの関連付け**

##EC2作成（wordpressのインストール）
＊セキュリティグループ（ssh, http許可）

**ログインし、以下のコードを実行**
＊`sudo su -`でrootユーザーに切り替える

```
yum -y update

amazon-linux-extras install php7.2 -y
yum -y install mysql httpd php-mbstring php-xml gd php-gd

systemctl enable httpd.service
systemctl start httpd.service

wget http://ja.wordpress.org/latest-ja.tar.gz ~/
tar zxvf ~/latest-ja.tar.gz
cp -r ~/wordpress/* /var/www/html/
chown apache:apache -R /var/www/html
```


##RDS作成

**・サブネットグループ作成**
先ほど作成したそれぞれのAZのプライベートサブネットを指定

**・RDSデータベース作成**

↓以下設定項目
・データベース作成方法を選択：標準作成
・エンジンのオプション：mysql
・テンプレート：開発/テスト（無料利用枠でもOK）　＊用途に応じて

・DB インスタンス識別子：デフォルト（database-1）でOK
・マスターユーザー名：任意
・マスターパスワード:任意
＊wordpressインストール時に必要なので覚えておく

・DB インスタンスクラス：t2.microでOK（用途に応じて）

・VPC：作成したVPCを指定
・サブネットグループ：作成したサブネットグループを指定
・パブリックアクセス：なし
・VPC セキュリティグループ（RDS用）：新規作成

・最初のデータベース名：wordpress
（任意で良いのかわからないけど、とりあえずwordpress）
＊後にwordpressの設定項目で入力する

**追記：**最近ではセキュリティ対策として、データベース名も推測されない名称を指定するケースも出てきてる。wordpress以外のランダムなデータベース名を設定するのも対策としてあり。

他デフォルトのままでOK

データベースの作成ボタンを押す

##RDSのセキュリティグループの設定
先ほど新規作成したRDSセキュリティグループの画面にいき、EC2のセキュリティグループからの許可を設定

![スクリーンショット 2021-07-22 20.34.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1650745/6d7c47cb-192a-2672-b6a0-6847674cbe6e.png)

＊注意点
EC2SGを設定しようとすると
You may not specify a referenced group id for an existing IPv4 CIDR rule.
というエラーが出て設定できない場合がある

解決策：一旦デフォルトのルールを削除して、新しく追加すれば設定できる

以下の記事を参照

https://dev.classmethod.jp/articles/aws-you-may-not-specify-a-referenced-group-id-for/

##wordpressの初期設定

EC2のパブリックIPをブラウザに貼り付けて接続

すると、wordpressの初期設定画面が開かれる

![スクリーンショット 2021-07-22 20.47.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1650745/25079da6-f1cc-fe6a-3335-3408485ad84e.png)

さあ、始めましょう！をクリック

**初期設定項目を設定**

データベース名：wordpress

ユーザー名：（RDSで設定した値）

パスワード：（RDSで設定した値）

データベースのホスト名：（RDSのエンドポイント）

テーブル接頭辞：wp_（デフォルトでOK）

**記入できたら送信⇨インストール実行**
すると以下の画面に移る

![スクリーンショット 2021-07-22 20.57.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1650745/c218137d-c17e-dbb9-a8dd-8b09f3142f3a.png)

**各項目を記入し、wordpressをインストールして完了**
（任意の設定）

**ユーザー名、パスワードを入力し、ログインできればOK**


##補足　エラー体験談
・wordpressのインストールが完了し、ログインできた。
しかし、RDSの設定を間違えたことに気づき作り直したら、データベース接続エラーになった

**解決策**
EC2を作り直して再びwordpressインストールしたら解決した。

おそらく元々のwordpressのキャッシュに最初に作成したRDSの情報があって、その情報と噛み合わないことが原因だったと思う。

**追記：**/var/www/html配下にあるディレクトリを一旦削除し、ダウンロードしたWordpressを再度展開および/var/www/html 配下に設置してみるのも解決手法の１つ

##次回の記事

https://qiita.com/wanidrums/private/9f08a6c6e62328f34cfa
EC2にDocker


教材
-
https://www.youtube.com/watch?v=HvrIPQ77xRY



前提
-
VPCとサブネットは作成済み
sshでEC2ログイン出来るところまで
EC2はポートHTTP80番を全開で受け付ける
ssh用の22番もマイIPだけ受け付ける（作業用）

Windows10 テラターム

完成形
-
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178985/2a9ffca5-6a47-4304-e0e0-53c099839b5a.png)


作業
-

①EC2にログインします

②sudo -y yum update

③sudo -y yum install docker

④ sudo service docker start
起動

⑤sudo docker info
起動確認

⑥mkdir hallodocker
作業ディレクトリを作って移動

⑦vi hello.html
表示するhtmlを作成 保存

⑧vi Dockerfile
イメージをつくるためにDockerfileを作成
※今回はnginxをインストールする

FROM nginx
COPY ./hello.html /user/share/nginx/html/

⑨sudo docker build -t hello-docker-ec2 

⑩sudo docker run --rm -d -p 80:80　hello-docker-ec2
※コンテナ停止したらコンテナ消す
ブラウザから80番で待つ
名前をつける

⑪　sudo docker ps
※確認

※間違ったときは
docker stop コンテナID
としてコンテナ削除する
⑨からやり直す

⑫ブラウザにEC2のIPアドレスでアクセスできる
http://EC2のIP/hello.hIP/

所感
-
ファイルを作り間違えない
パスを間違えない
Salesforce FlowでChatterで特定のユーザに@メンションしたい場合

# やりたいこと
`Flow`を使って、商談が受注/クローズした際に、その商談に対して特定のユーザ（例えばマネージャなどに）毎回メンションしたい

# やり方
[ユーザまたはプロファイルの Salesforce ID を特定する](https://help.salesforce.com/articleView?id=000312782&language=ja&mode=1&type=1)
に従って、メンションしたいユーザIDを取得する。
あとは`Flow`の`アクション`を`レコードトリガーフロー`につなげて下記の通りにするだけ。
これで`レコードトリガーフロー`に指定した商談クローズ時に、対象商談のChatterにメンション付きで`aaa`が投稿されます。

### レコードトリガーフローのオブジェクト設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484310/3feefd19-471a-c0fa-3715-a11bda5b8d6d.png)

### アクション設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484310/c9b4f754-7d4d-f085-161b-90d23e0d92a8.png)

`xxxxxxxxxxxxxxx`にはもちろんユーザIDが入ります。
色々やったけど、単純に`@[xxxxxxxxxxxxxxx]`の`[]`を入れるだけで良かったオチです。

### 注意点
- このメンション方法は、上記アクションであれば動作しますが、直接 `FeddItem` オブジェクトにレコード作成する場合は動作しません  
- また、Community Userからレコード作成時などにレコードトリガで内部ユーザにChatterメンションはエラーが発生し、通知できない仕様になっています
AWSグループの作り方

# はじめに
AWSのグループを作る方法もメモしておく。
あと、権限の付け方によってどんな画面表示になるのかも併せて検証してみようと思う

# 手順
1. ユーザ（権限なし）を作成する
1. グループを作成する
1. グループに権限を付与する
1. メンバーをグループに割り当てる


## 1. ユーザ（権限なし）を作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/d1b64c97-caf8-cf7a-df9b-3ec7aa4769e7.png)

グループの権限によってアクセス許可がどう変わるのかが見たいので
あえて何も選択せずにユーザを作る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/e588d357-188c-a27b-49d9-300e47e47561.png)

アクセス権限無いよ、の警告が来る。
想定の範囲内。よしよし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/e01e7d72-0f4a-d78c-e9bc-1c433576cff5.png)

ユーザ完成。一覧にjigenができた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/4cff0ed1-1e7c-5f7d-4b6f-bf47aa73a0f5.png)

# 2. グループを作成する
IAM画面にて「ユーザーグループ」へクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/3a7535a9-c2e0-aaa3-df16-2810bc4ddea4.png)

[グループを作成]クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/3330bb50-1d14-f27d-801f-6e2e55d6e89d.png)

# 3. グループに権限を付与する
# 4. メンバーをグループに割り当てる

グループ作成画面に到着。
以下、入力して[グループを作成]クリック。
ユーザグループ名：operator
ユーザーをグループに追加："jigen"を選択
アクセス許可ポリシーをアタッチ："AmazonS3FullAccess"を選択（※）
※S3をフィルタ窓に入力してEnter押したらうまいことフィルタリングしてくれたので見つけやすかった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/1b00ffec-4941-bfd4-d936-3f6ebcd3e530.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/b321ddd2-2e4a-3e06-9548-0455ae919468.png)

完成！クリックした瞬間にできあがった。はやー。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/91cfd8e9-8e98-65f1-7878-8d28382f4512.png)

早速、"operator"リンクをクリックして内容を確認。
ちゃんとjigenがセットされてる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/48663ac9-1a0e-c1c2-b266-7ae150979cff.png)

# jigenがS3にアクセスできるか確認する
とりあえずログインはできた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/d7cdff43-0ee3-2cf6-52d3-1428955ca756.png)

S3リンクへクリック。問題なく表示できた！成功ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/d4e468b8-c076-04af-650c-a9f765493dc2.png)



### 余談：何のアクセス権限をもたない状態だとどんな画面表示になるのか？
ログインしてみる。ログイン自体は問題ないようだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/169541d8-ebb0-113a-4d09-3ba42b7a0379.png)

EC2へ行ってみる。リソース状況が何も確認できない…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/e3699047-6617-8c5c-76b1-e7f51fae4edf.png)

無理矢理「インスタンス（実行中）」のリンクへ行くも
↓↓の画面のようになり権限的に無理、とのこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/a1222a4f-8c42-7a38-d83e-0e7bca7f1936.png)

S3に行ってみる。こちらも同様の理由でNGっぽい。
なるほどなるほど。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/5feed145-783b-55b4-3006-f8bec87b16b7.png)
BtoBPF API Response JSONをVBAでパーサー


[BtoBPF API responce JSONをVBAでパーサー | 備忘録　(。・_・。)ノ](https://ameblo.jp/ak09z/entry-12687968674.html?fbclid=IwAR2jZWESa3Sp6Ul3ZCusAd8e9icA2D9Zv2_5C-8q3aa8AyYhPIV4vTWdXls)
より抜粋

```vb
Option Explicit
Private Sub VBA_JSON_TEST()
Dim Parse As Object
Dim i As Long
Dim j As Long
Dim strJson As String
    strJson = ""
    For i = 1 To Worksheets(1).Range("A1").End(xlDown).Row
        strJson = strJson & Worksheets(1).Cells(i, 1)
    Next i
    Set Parse = JsonConverter.ParseJson(strJson)
    Debug.Print Parse("result")
    Debug.Print Parse("jounal_frees")("jnl_free_code1")
    For i = 1 To Parse("invdata").Count
        Debug.Print Parse("invdata")(i)("inv_no")
        For j = 1 To Parse("invdata")(i)("banks").Count
            Debug.Print Parse("invdata")(i)("banks")(j)("depositor_name")
        Next j
        For j = 1 To Parse("invdata")(i)("details").Count
            Debug.Print Parse("invdata")(i)("details")(j)("item_aut_amount_d")
        Next j
    Next i
    Set Parse = Nothing
End Sub
```
Cloud9でRails6の開発環境構築（rails sするまで）

Cloud9でRails6の開発環境を構築した際、少し苦労したので以下備忘録として。

## Railsをインストール
Rails6を使いたかったので```gem search rails```でバージョンを確認してインストール。

```
gem install rails -v 6.1.4
```

Rails6からwebpackerが標準になったことにより、Railsアプリの開発環境にyarnのインストールが必要になっているので、以下の記事を参考にNode.js, yarn, webpackerを順にインストールしていきます。
https://qiita.com/yamori/items/974e4775eb1d21aa7889
https://qiita.com/pharma_tech3/items/2ab578eb5b07ff0ca296

## Node.js, yarn, webpackerをインストール
まずHomebrewを入れようと思ったのですが```npm -v```で確認したらnpmはすでに入っていたので割愛。
 
次にyarnをインストールします。

```
npm install -g yarn
yarn -v
```

## アプリケーション作成
```rails new```でアプリケーションを作成して、cdしてからwebpackをインストールします。

```
rails webpacker:install
```

とりあえず```rails s```してみたのですが、ブラウザからアクセスすることができませんでした。

## リクエストを許可するホストを設定
Rails6で**DNSリバインディング攻撃からの保護**機能が追加されているので、許可するホストを自分で設定します。

```config/environments/development.rb
回避方法１：　ホワイトリストに許可したいhostを追加したい場合
config.hosts << "許可したいホスト名"

回避方法２：　ホワイトリスト全体をクリアしたい場合
config.hosts.clear
```
回避方法2の場合全てのリクエストが通過してしまうので、回避方法1の設定を追記します。

ここでもう一度```rails s```してプレビューしてみると、今度は以下のように怒られました。

```
Your version of SQLite (3.7.17) is too old. Active Record supports SQLite >= 3.8.
```

## SQLite3をアップデート

Rails6ではSQLite3.8以上が必要なので、ダウンロードページなどでバージョン情報を確認して、
homeへcdして以下を実行します。

```
wget https://www.sqlite.org/2021/sqlite-autoconf-3360000.tar.gz
tar xzvf sqlite-autoconf-3360000.tar.gz
cd sqlite-autoconf-3360000
```

念のため```which sqlite3```で確認してから、もとから入っているsqliteと競合しないように /opt/sqlite/sqlite3 でビルドしてインストールしていきます。

```
./configure --prefix=/opt/sqlite/sqlite3
make
sudo make install

/opt/sqlite/sqlite3/bin/sqlite3 --version
```

Railsアプリ直下へcdして作業ディレクトリにsqlite3のgemを入れ直します。

```
gem uninstall sqlite3

gem install sqlite3 -- --with-sqlite3-include=/opt/sqlite/sqlite3/include \ --with-sqlite3-lib=/opt/sqlite/sqlite3/lib
```

不要なファイルは削除しておきます。

```
rm sqlite-autoconf-3310100.tar.gz
rm -rf ./sqlite-autoconf-3310100
```

以下の記事を参考にパスを通しておきます。
https://qiita.com/Taku3939/items/76356f46f53946962d2e

```
echo 'export PATH=/opt/sqlite/sqlite3/bin:"$PATH"' >> ~/.bashrc
```

ここまでやって作業ディレクトリのsqlite3が更新できたことを確認できました。

```
sqlite3 --version
3.36.0
```

しかし、まだ```rails s```してもちゃんと動いてくれません。

以下を参考にもう一度gemを入れ直してみます。
https://mebee.info/2021/01/13/post-27973/

```
gem uninstall sqlite3

gem install sqlite3 -- --with-sqlite3-include=/opt/sqlite/sqlite3/include --with-sqlite3-lib=/opt/sqlite/sqlite3/lib
```

起動時に大量のwarningは大量に出るものの、なんとか```rails s```はできるようになりました。

## Warningの解消

Gemを入れ直してから_already initialized_というwarningが大量に出るようになってしまったので、最後にこれも解消しておきます。
１行ずつエラーメッセーを確認して、Gemの読み込みで怒られている場合は必要に応じて以下を実行します。

```
gem uninstall etc
gem uninstall forwardable
```

ここまででやっと問題なく```rails s```できるようになりました！
AWSユーザの作り方

# はじめに
AWSのアカウントを作る機会があったこともあって
簡単な手順を残す

# やり方
TOP画面からIAMをクリックして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/2cc1158a-61bb-ad8d-a126-0e03d9c85f13.png)

左ペインの「ユーザ」クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/796eae08-717c-e866-7e0c-c31422b72479.png)

[ユーザーを追加]クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/d1c15b68-ec98-58e8-132e-d3091ffcdf78.png)

ユーザ登録画面で必要事項を入力。。。
ユーザ名：watyanabe164
アクセスの種類："AWSマネジメントコンソールへのアクセス"　←このアカウントでAPI使う予定はないのでコンソールへのアクセスのみとした
コンソールのパスワード：＊＊＊
パスワードのリセットが必要：チェックなし
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/01a0c45d-f57e-a196-fd3b-7f3998a38501.png)

”アクセス許可の設定”では、
　[既存のポリシーを直接アタッチ]をクリックして
　AdministratorAccess　をチェック。
定義を見たところ、あらゆるリソースへのあらゆるアクションを許可、するようだ。
Administrator権限を付与するわけだから当然といえば当然。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/7ec393a2-c82b-726b-2ba6-60fdebd5cfd6.png)

タグは特に設定なし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/4b891225-f8a9-1192-38f3-bd7db07e54e8.png)

ここで確認画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/8e4ea778-56d8-f87a-42c6-b88b065764c0.png)

数秒程度で作成完了。簡単だ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/24c3825b-1db7-3892-5794-a040a241d1fe.png)

出来上がりを確認。
ちゃんとユーザ一覧にwatyanabe164ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/cee1572c-f1d2-a217-5510-5f5be8a8362c.png)


## オマケ：そのほかのアクセス許可の設定を見てみる。
### AmazonEC2FullAccess
ec2とelasticloadbalancingなど、EC2とそれに関連する機能の利用が許可されてるようだ。Actionを一つずつ定義しているので、他のサービスは利用できないって感じなのかなと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/29e78eff-b177-c39d-9873-581726c0dfad.png)

### AmazonEC2ReadOnlyAccwss
AmazonEC2FullAccessと比較して、機能から更に出来ること絞っているようだ。細かい。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/8714e5bf-9ab2-8326-178f-b62b02e95d9c.png)
タップしたUICollectionViewのCellの上だけにViewを表示する

# こんな感じです
<img width="150" alt="962F3E1A-6D0B-4D06-9E7C-A3C3E2FBE89C_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/87f7f19d-2ce0-b1eb-cff2-445b1849eab9.jpeg">
[UISliderとCollectionViewの簡単復習App](https://qiita.com/HiroUrata/items/ae190ddbecfd929e6b09)で作ったアプリに思いつきで機能を追加しただけです。

#　コードと簡単解説

* タップしたCellの上に表示するViewの作成

```Swift:CellOnView
import Foundation
import UIKit

class CellOnView{
    
    let cellOnView = UIView()
    
}

extension CellOnView{
    
    func createCellOnView(cellPointX:CGFloat,cellPointY:CGFloat,cellWidth:CGFloat,cellHeight:CGFloat,targetView:UIView){
        
        cellOnView.frame = CGRect(x: cellPointX, y: cellPointY, width: cellWidth, height:cellHeight)
        
        cellOnView.backgroundColor = .systemGreen
        
        targetView.addSubview(cellOnView)
    
    }
}
```

* `cellOnView.createCellOnView(~~~省略~~~,targetView:UIView)`でUIViewを必要としているので,タップしたCellをUIViewとしてselectCellに入れています

```Swift:ViewController
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            
        let selectCell = collectionView.cellForItem(at: indexPath)! as UIView
        
        cellOnView.createCellOnView(cellPointX: selectCell.bounds.minX, cellPointY: selectCell.bounds.minY, cellWidth: selectCell.frame.size.width, cellHeight: selectCell.frame.size.height, targetView: selectCell)
            
    }
```

# 終わり
休憩中に思いつきでやってみたことについて書きました。(役立つかは微妙ですね)
ご指摘や質問などありましたら、喜んで受け付けてます。
TypescriptでOptional chainingを使用した箇所がJestのCoverageに反映されない場合

# 現象
以下のようにOptional chainingを使用してオブジェクトを読み込んだ箇所が、

```Typescript
    result.userId = response?.userId;
    result.todoId = response?.todoId;
    result.title = response?.title;
```

テストを通しているはずなのにJestのCoverageに反映されない

```Jest
------------------------|---------|----------|---------|---------|-------------------
File                    | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------------------|---------|----------|---------|---------|-------------------
All files               |   98.01 |    93.18 |   97.62 |      98 |                   
 lambda/domains         |     100 |      100 |     100 |     100 |                   
  todoUseCase.ts        |     100 |      100 |     100 |     100 | 103-105 <-消えてくれない    
略      
------------------------|---------|----------|---------|---------|-------------------
```

# 解消法
[こちらのIssue](https://github.com/istanbuljs/istanbuljs/issues/516)に書いてある方法を試したところ解消しました

tsconfig.jsonのcompilerOptions.targetを「ES2020」に設定

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
  }
}
```
Laravelのmigrationでtimestamp型がInvalid default value for ''エラー

以下のマイグレーションファイルを作成し実行した。

```
public function up()
{
  Schema::create('events', function (Blueprint $table) {
    $table->id();
    $table->string('name', 255);
    $table->timestamp('start_datetime');
    $table->timestamp('end_datetime');
    $table->timestamps();
  });
}
```

すると、以下のエラーが発生した。
ちなみにこのSQLをDBに直接実行すると正常にテーブル作成が完了する。
なのでSQLのエラーと言うよりLaravelのエラー。

```
SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'end_datetime' (SQL: create table `events` (`id` bigint unsigned not null auto_increment primary key,`name` varchar(255) not null, `start_datetime` timestamp not null, `end_datetime` timestamp not null, `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')
```

で、解決方法としてはtimestampはデフォルト値を設定するか、Null許容にする必要があるらしい。

```
public function up()
{
  Schema::create('events', function (Blueprint $table) {
    $table->id();
    $table->string('name', 255);
    $table->timestamp('start_datetime')->default(DB::raw('CURRENT_TIMESTAMP'));
    $table->timestamp('end_datetime')->default(DB::raw('CURRENT_TIMESTAMP'));
    $table->timestamps();
  });
}
```

ドキュメントには特に記載なかったので、↓を参考に。

https://stackoverflow.com/questions/50156519/eloquent-invalid-default-value-with-timestamps
cakephp4 リレーション先のデータ取得・表示

Every Qiita #20
のんびり独学初学者の毎日投稿チャレンジ 20日目
今回は・・・
cakephpでリレーション先のテーブルデータを取得した時の備忘録です。

###modelでリレーションを設定する
公式チュートリアルの例に倣ってusersテーブルとarticlesテーブルで1対多のリレーションを設定してみます。
外部キーはuser_idです。

```php:UsersTable.php
public function initialize(array $config): void
{
  parent::initialize($config)
  $this->hasMany('Articles',[
       'foreignKey'=>'user_id',
       'dependent'=>true,
     ]//foreignKeyはデフォルトで`テーブル名_id`
}
```

```php:ArticlesTable.php
public function initialize(array $config): void
{
  parent::initialize($config)
  $this->belongsTo('Users',['foreignKey'=>'user_id']//foreignKeyはデフォルトで`テーブル名_id`
}
```
今回は外部キーがuser_idですので省略可能です。テーブル名_id以外でキーを設定する場合は任意で設定してください。
`'dependent'`をtrueに設定することで、再帰的にモデルを削除することができます。今回は特定のuserが削除されると、それに関連するarticlesも削除されます。

###controllerでリレーション先のテーブルも取得する
今回はgetメソッドオプションの`contain`を使って取得します。
***一意のuser情報と関連するarticlesを一覧表示するためのクエリを設定します。***

```php:UsersController.php
public function view($id = null)
{
  $user = $this->Users->get($id, ['contain' => ['Articles']]);
  $this->set(compact('user'));
}
```
これでuserと関連するarticlesが取得できました。
viewで表示する時はforeachを使って表示します。

```php:Users/view.php
foreach($user->articles as $article){
  echo $article->articlesテーブルの任意カラム
}
```
リレーション先のモデル名は大文字頭文字ですが、viewでは小文字ですので注意が必要です。
JSON 配列の中身をPowerQueryで分析する

# なぜ？
- Power Automate で SharePoint を操作するなら Rest API が便利なことが多い
- SharePoint Rest API の情報は （自分には） MS Doc だけでは難しい[^HardtoUnserdatand]
- 実行結果から解析して利用出来ると楽

ってことで配列要素をデータ分析したいんだけど・・
- VS Code などの JSON Editor では集計は出来ない。
- Linq Pad には Driver がない・・Pro 版買えば色々やれそうなんですが・・

無償で、簡単に、JSON 配列分析ってなると、Power Query かなってのが現状です。

# 分析結果例
[SiteUser](https://docs.microsoft.com/en-us/dotnet/api/microsoft.sharepoint.spweb.siteusers?view=sharepoint-server) の取得結果はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/ce03b90a-3f97-33cf-5406-540f54b4acfa.png)
で、Power Query での分析結果（今回は Power BIだけど、Excel のでも OK）
こんな感じで配列を見える化してくれるので、あとは大量に取得した一覧情報を分析して処理方法を考えましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/45b31fec-cd35-3da5-007d-e647239df45f.png)

# では、実際のやり方
1. Text Editor で、解析したい JSON を複写して保存する。（自分は解析・編集も便利な VS Code を利用）
1. Power Query エディターで、JSON File を選択するだけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/d74c1af3-6021-9a7a-f6fe-e00c9dc04794.png)
1. そうするとこんな感じでサクッと表示してくれるので超絶便利。あとは煮るなり焼くなり
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/45b31fec-cd35-3da5-007d-e647239df45f.png)

# ほんとにやりたかったこと
- Linq Pad の拡張UIでJSON解析をしつつ、選択した配列を Linq で集計・分析

とはいえ・・Power Queryのほうが分析するのは楽だなぁとやってみて思ったのでした🤔


[^HardtoUnserdatand]: あくまでも自分には・・なんですけどね。なんかコツがあれば知りたい
RDLのデータセットのフィルターでOrを使用する方法

#はじめに
SSRS(SQL Server Reporting Services)を使用している方がどのくらいいるのかわからないのですが、何か問題が起きたときに、なかなか解決方法が見つからないことが多いです。
.Net FrameworkでWPF開発をしていた時に、レポートを作るのに、Microsoft Reporting Service(RDLC)を使っていました。
ところが、.Net5で開発をしようとすると、Microsoft Reportは使えないことがわかりました。
記事執筆時点では、MicrosoftがMictosoft Reportは未対応だったようで、何か代替案はないかと探していくうちに、SQL Serverであれば、SSRS(RDL)が使えることがわかりました。使い方や開発方法は、ほぼMicrosoft Reportと同じでした。

#課題
さて、今回のタイトルにあるフィルターについてですが、データセットを作成後、パラメータでデータを絞り込めるようにしようとしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/d4f1d5e0-dd79-2e9b-f813-f52a6305b56d.png)

この図にあるのですが、UsageDateFromというのはNullを許容した日付で、UsageDateToという同じくNull許容した日付がほかにあります。
これをServiceDateというパラメータで絞り込みをしています。
日付範囲を指定して、

```
UsageDateFrom <= ServiceDate <= UsageDateTo
```
というよう感じにしたいわけです。
要するに、いつから、いつまで提供したサービスを表示したいというような感じです。

ところが、まだサービスが終了していない場合、UsageDateToはNullになっています。
つまり、クエリとして書くと

```
UsageDateFrom <= ServiceDate And (UsageDateTo Is Null Or UsageDateTo >= ServiceDate)
```
といった感じになります。

ところが、フィルターは、上からAndで結合されてしまうため、Or条件を付加する方法がわかりませんでした。
いろいろと試行錯誤した結果、ようやく一つの解決方法がわかったのでご紹介させていただきます。

#解決
フィルターは「式」「演算子」「値」「データタイプ」で構成されていますが、「式」と「値」にさまざまな式を入力することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/d980d240-dcd1-c95b-f23f-a932ee45ae42.png)
これらを駆使してOrを実現していきます。

```
UsageDateFrom <= ServiceDate
```
の部分は以下のようにすでに設定して済み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/00bd9396-e7ad-1a3f-19ca-49d989932a1c.png)

次が問題となる箇所です

```
UsageDateTo Is Null Or UsageDateTo >= ServiceDate
```
まずは式のfxをクリックして以下のように記述します。Or ではなくOrElseとするのが肝かな。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/aa93b948-f610-f6c0-aca0-c181d54fee7b.png)
そして、ここがポイント！
データタイプをブールにします。そして値をTrueにすることで実現できました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/d929c3d7-8ade-c9e2-7276-a25f88fe90f3.png)

SSRSを使用している方がどのくらいいるのかわかりませんが、Power BIでもRDLフォーマットは使用できるので、学んでおいても損はないかなと思います。