OmniAICreator/Qiita-1.07M huggingface dataset:
WSLでGhidra環境構築

# 0.Ghidraとは？
Ghidraは、米国家安全保障局（NSA)が公開しているリバースエンジニアリングツールです。
環境
- Windows11
- WSL2-Ubuntu22.04.2
# 1.Ghidraのインストール


まずJRE(Java Runtime Environment)とJDK(Java Development Kit)が入っているか確認してください。
```
$ java -version
$ javac -version
```
ない場合
```
$ sudo apt-get install openjdk-17-jre
$ sudo apt install openjdk-17-jdk
```
次にghidraをインストールします。

https://github.com/NationalSecurityAgency/ghidra/releases

最新版はここから確認してください。ここではインストールガイドが充実しているver10.2.3をインストールします。
```
$ wget https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_10.2.3_build/ghidra_10.2.3_PUBLIC_20230208.zip
$ unzip ghidra_10.2.3_PUBLIC_20230208.zip 
$ cd ghidra_10.2.3_PUBLIC/
$ ./ghidraRun
```
これで無事GUIが起動するはずです

# 3.ghidraRunが何も表示されないとき
自分も別端末でGhidraを入れようとしたときこのような状態になりました。
対処法
```
$ cd support/
$ ./ghidraDebug
```
これでエラーが出力されるはずです。自分の場合はopenjdkのバージョンが19で17が必要だ的なことが書かれていました。上記のコマンドでバージョン17をインストールした後以下のコマンドでバージョンを選択できます
```
$ sudo update-alternatives --config java
```
再度ghidraRunを実行してみてください。無事動くようになっているはずです
【Python】JSONファイル内のエントリ数（キーと値のペアの数）を一瞬でカウントする方法

# 概要
* Pythonを使用してJSONファイル内のエントリ数を数える方法を紹介します。

## サンプルコード

* JSONファイルを読み込んでから`len()`関数を使用してエントリ数を数えます。

```count-entry.py 
import json

# JSONファイルを読み込む
with open('data.json') as file:
    data = json.load(file)

# エントリ数を取得
entry_count = len(data)
print("エントリ数:", entry_count)
```

* `len`は、辞書だけでなく、リストや集合といった型にも使えます。データ構造の要素数を取得するために使用される組み込む関数です。勿論、文字列の要素数（文字数）を指定することもできます。
* 結果は以下のように返ってきます。

```terminal
$ python count-entry.py 
エントリ数: 3
```

### エントリ数とは？
* ちなみに以下のようなJSONデータの場合、「エントリ数」は3になります。

```json
{
    "name": "John",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "New York"
    }
}
```

* エントリは、JSONデータ内の1つの単位を指します。
* エントリ数は、JSONデータ内の直接的なキーと値のペアの数を指します（or配列の要素）。
    * ネストされたオブジェクトや配列の要素は、それぞれ独立したエントリとして数えられます。
    * 上記の場合、`street`や`city`は、`address`オブジェクト内のキーと値のペアとして計算されます。
【Laravel migration】テーブルの編集2（カラムの編集）

# Laravelのマイグレーション
データベースの作成や編集、削除などを管理する方法として、PHPフレームワークのLaravelには「マイグレーション」というものが備わっています。
本記事では、マイグレーションで生成されたテーブルを編集する方法（カラムの編集）について書きます。

カラムの追加・削除については、下の記事をご参照ください。

https://qiita.com/Takahiro_Nago/items/5c00894e63279632ce19

# 開発環境
XAMPP
MySQL 5.2
Laravel 10.1
php 8.1

# 1. カラムの編集の前に
カラムの編集を行う場合、Composerパッケージマネージャを使い、doctrine/dbalパッケージをインストールする必要があります。
コマンドは以下の通り。
```
composer require doctrine/dbal
```

# 2. マイグレーションファイルの作成
カラムを編集するマイグレーションファイルを作成します。
下の例では、既存postsテーブルの既存titleカラムを編集しようとしています。
```
$ php artisan make:migration change_title_of_posts_table
```

database/migrationsディレクトリ内に以下のマイグレーションファイルが生成されます。
```2023_06_08_131653_change_title_of_posts_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        //
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        //
    }
};
```


新しく生成されたマイグレーションファイルの「up」に変更の内容、「down」に変更を基に戻す内容をそれぞれ挿入します。なぜかSchemaも生成されていないので、Schemaも書きます。
下の図ではtitleカラムをnullableに変更しています。downはnullable(false)にしてあげればOKです。
最後のchengeを忘れないこと。
```2023_06_08_131653_change_title_of_posts_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->string('title')->nullable(true)->change();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->string('title')->nullable(false)->change();
        });
    }
};
```

最後にマイグレーションを実行すれば、カラムの編集完了です。
```
php artisan migrate
```
Jenkinsを2.409にバージョンアップしたらエラー(Bad Message 400: reason: Duplicate Host Header)が出るようになった

先日、Jenkinsを 2.379から 2.409にバージョンアップしたら、エラーが出て接続できなくなった環境がありました。

```
Bad Message 400
reason: Duplicate Host Header
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/f366c311-c1e0-5186-148c-b36f4bea851f.png)

# エラーの原因

対象の環境は、HTTPS接続のために Nginxリバースプロキシを使用していましたが、Nginxの設定ファイルに誤りがありました。

```
$ cat /etc/nginx/sites-available/default | grep Host
        proxy_set_header   Host   $http_host;
        proxy_set_header   Host   $host;
```

分かればエラーメッセージの通りだったのですが・・・Host Headerの設定が2つありそれが原因でエラーになっていました。
2.379まではこの設定でも問題なく動いていたので何故このタイミングで顕在化したのかは不明ですが、片方を削除して問題解消しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/49b0b8d4-8776-5c48-2041-c1ab6034c8a4.png)
GitHub Desktopを使ってGitLabにコミットする

### TL; DR
- GitLabでレポジトリのHttpsクローンURLをコピー
- GitHub DesktopでURLからローカルレポジトリを作成
- コミットするとGitLabに反映される

### こちらの文章について
GitHub Desktopを使ってGitLabにコミットする方法が思ったより簡単だったのでそれの紹介。

### 前提条件
- GitHub・GitLabアカウント所持
- GitLabでレポジトリを作成している

### 方法
まず初めに、ローカルで作業したいレポジトリのHttpsクローンのURLを取得します。
(GitLabでの作業)
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/15ea8159-013d-78f2-a009-20cde9aaabdc.png)
続いて、これをGitHub Desktopにてクローンします。
(GitHub Desktopでの作業)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/c10f6982-3669-bf55-6294-900ec90a3185.png)
上側のリボンの**File**を選択して、上から三番目**Clone a repository**を選択すると下のような画面が出てきます。
出てきたら上側に先ほどコピーしたURLを、下側はローカルのお好きな場所を選択してください。
これで完了です。

### コミットしてみる
では、実際にコミットしてみましょう。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/7965845e-e690-2322-f8f7-24cefdac7ad9.png)
今回は**readme**という名前でコミットしてみます。
(はじめてコミットするときはGitLabのユーザー名とパスワードを求められると思います。)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/3c39e494-1cc2-d34e-0c05-a2712113d4c6.png)
GitLab側で見てみると、しっかり**readme**という名前でコミットされているのが分かります。

### まとめ
GitHub DesktopはコマンドでGitを使わなくて済むので楽です。
このようにGitLabでも利用できるので皆さんもぜひお試しください。

### 参考文献
https://www.slideshare.net/sagardash2/gitlab-with-github-desktop-98160868

参考にさせていただきました。ありがとうございます。
【Rspec】before と let! を使ってSystem Specを書いてみた (データ作成日時降順表示のテスト)

# はじめに
　
プログラミングスクールにてRuby on Railsを学習している者です。
この記事では、System Specの書き方で疑問に思った点と自分なりの解釈をまとめます。

初学者（学習期間１ヶ月）のため、初歩的な内容です。
誤った記述があるかもしれませんが、ご指摘いただけますと幸いです。
よろしくお願いいたします。


 # 前提
タスク管理アプリの一覧画面にて、タスク登録日時の降順表示（最新のものが上にくる）に切り替えた際のテストコードです。


<br>
task_spec.rb

```ruby
require 'rails_helper'
RSpec.describe 'タスク管理機能', type: :system do
  let!(:task) {FactoryBot.create(:task, name: 'aaa')}
  describe '一覧表示機能' do
    before do
      task1 = FactoryBot.create(:task, name: 'bbb')
      task2 = FactoryBot.create(:task, name: 'ccc')
      visit tasks_path
    end
    context '一覧画面に遷移した場合' do
      it '作成済みのタスク一覧が表示される' do
        expect(page).to have_content 'bbb'
        expect(page).to have_content 'ccc'
      end
    end
    context 'タスクが作成日時の降順に並んでいる場合' do
      it '新しいタスクが一番上に表示される' do
        expect(page.text).to match(/#{task2.name}[\s\S]*#{task1.name}/)
      end
    end
  end
end
```


factories/tasks.rb
```ruby
FactoryBot.define do
  factory :task do
    name { 'test_name' }
    detail { 'test_detail' }
  end
end
```

 # エラー発生

上記のコードを実行すると、**it '新しいタスクが一番上に表示される' do**　の部分で task1 って何？taskのことですか？　とエラーが出ました。
```
Failure/Error: expect(page.text).to match(/#{task2.name}[\s\S]*#{task1.name}/)
NameError:
       undefined local variable or method `task1' for #<RSpec::ExampleGroups::Nested::Nested_2::Nested_2 "新しいタスクが一番上に表示される" (./spec/system/task_spec.rb:29)>
       Did you mean?  task
```

しかし、**it '作成済みのタスク一覧が表示される' do**　のテストはパスしているため、
beforeの部分のcreateは成功しているはずです。
では、なぜtask1が定義されていないと怒られてしまうのでしょう？

それもそのはず。インスタンス変数でないと、メソッド外で呼び出せません。
下記の通り、beforeの定義の際に、データを**インスタンス変数**に代入することで、テスト成功。


```ruby
before do
      @task1 = FactoryBot.create(:task, name: 'bbb')
      @task2 = FactoryBot.create(:task, name: 'ccc')
      visit tasks_path
end
```

# さらに疑問に思ったこと

先ほどのエラーメッセージでtask1じゃなくて、taskじゃないですか？と言われておりました。

```
Failure/Error: expect(page.text).to match(/#{task2.name}[\s\S]*#{task1.name}/)
NameError:
       undefined local variable or method `task1' for #<RSpec::ExampleGroups::Nested::Nested_2::Nested_2 "新しいタスクが一番上に表示される" (./spec/system/task_spec.rb:29)>
       Did you mean?  task
```

このtaskって何？逆にそのtaskはどこに存在しているのでしょう？

# 自分なりの解釈
自分で書いたコードなのに自信がありません。
let!で定義している変数taskのことでしょうか。


```ruby
let!(:task) {FactoryBot.create(:task, name: 'aaa')}
```

試しに binding.irb で確認した所、taskにはname'aaa'のデータが入っていました。
let!で定義した変数はインスタンス変数としてどこでも使えるのですね。
@はついてないけど・・・・・。



# おまけ

今回のコードでは、

let! で name'aaa'　のデータを作成
↓
before　で　name'bbb'　のデータを作成
↓
before　で　name'ccc'　のデータを作成
<br>
この順番でデータが作成されました。
ということは、なんとなくイメージ被りしているlet!とbeforeですが、let!のほうが実行順位が高いんですね。いや、let!のほうがネストの浅いところに記述しているので当然・・・？
今後もう少しコードを動かして考えてみようと思います。

<br>
<br>
※コードの中に不要なlet!が存在しており気持ち悪く感じられた方がいらっしゃいましたら申し訳ございません。let!は今回記載していない別の機能でのみ必要でしたが、エラー文に関係していたためコードを残しました。



## 参考にさせていただいた記事
[使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」](https://qiita.com/jnchito/items/42193d066bd61c740612)
[【Rspec】system testで並び順をテストする](https://qiita.com/kensuke_kumaki/items/bb09d5c61e13fc50fd6d)
[【Rspec】letとlet!、beforeの違い](https://qiita.com/mmaumtjgj/items/e149b506ee7cd5c2a96d)
[RSpec letとlet!とbeforeの実行されるタイミング.](https://note.com/izuha0/n/nd3a633eddf9c)


ありがとうございました。
自分用メモ

cloudformationの書き方調べるのがめんどくさい時は

とりあえず手動でリソース作る
↓
Former2にRead権限IAM渡す
↓
Former2で既存リソースから読み込んでGenerate

注意点は手動で作る時は勝手に色々作ってくれる(CloudWatchLogグループとか)けどFormer2は関連分を勝手に読み込んでくれるわけじゃない

RDS関係をgenerateするとこんな感じ
``` yaml
AWSTemplateFormatVersion: "2010-09-09"
Metadata:
  Generator: "former2"
Description: ""
Resources:
  RDSDBInstance:
    Type: "AWS::RDS::DBInstance"
    Properties:
      DBInstanceIdentifier: "db-ident-1"
      AllocatedStorage: 400
      DBInstanceClass: "db.t3.micro"
      Engine: "postgres"
      MasterUsername: "postgres"
      MasterUserPassword: "REPLACEME"
      PreferredBackupWindow: "03:15-03:45"
      BackupRetentionPeriod: 7
      AvailabilityZone: !Sub "${AWS::Region}c"
      PreferredMaintenanceWindow: "mon:06:18-mon:06:48"
      MultiAZ: true
      EngineVersion: "14.5"
      AutoMinorVersionUpgrade: true
      LicenseModel: "postgresql-license"
      Iops: 13000
      PubliclyAccessible: false
      StorageType: "gp3"
      Port: 30000
      StorageEncrypted: true
      KmsKeyId: !Sub "arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/ごにょごにょ"
      CopyTagsToSnapshot: true
      MonitoringInterval: 60
      EnableIAMDatabaseAuthentication: false
      EnablePerformanceInsights: true
      PerformanceInsightsKMSKeyId: !Sub "arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/ごにょごにょ"
      PerformanceInsightsRetentionPeriod: 7
      DeletionProtection: true
      DBSubnetGroupName: "default-vpc-ごにょごにょ"
      VPCSecurityGroups: 
      - !Ref EC2SecurityGroup
      - "sg-ごにょごにょ"
      DBParameterGroupName: !Ref RDSDBParameterGroup
      OptionGroupName: "default:postgres-14"
      MonitoringRoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/rds-monitoring-role"
      EnableCloudwatchLogsExports: 
      - "postgresql"
      - "upgrade"
      CACertificateIdentifier: "rds-ca-2019"
      Tags: 
      - 
        Key: "devops-guru-default"
        Value: "db-ident-1"

  RDSDBSubnetGroup:
    Type: "AWS::RDS::DBSubnetGroup"
    Properties:
      DBSubnetGroupDescription: "my-rds-subnet"
      DBSubnetGroupName: "my-rds-subnet"
      SubnetIds: 
      - "subnet-ごにょごにょ"
      - "subnet-ごにょごにょ"
      - "subnet-ごにょごにょ"

  RDSDBParameterGroup:
    Type: "AWS::RDS::DBParameterGroup"
    Properties:
      DBClusterParameterGroupName: "post14-param"
      Description: "post14-param"
      Family: "postgres14"
      Parameters: 
        idle_session_timeout: "400000"

  EC2SecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "myssh created"
      GroupName: "myssh"
      VpcId: "vpc-ごにょごにょ"
      SecurityGroupIngress: 
      - 
        CidrIp: "0.0.0.0/0"
        FromPort: 10022
        IpProtocol: "tcp"
        ToPort: 10022
      SecurityGroupEgress: 
      - 
        CidrIp: "0.0.0.0/0"
        IpProtocol: "-1"

  LogsLogGroup:
    Type: "AWS::Logs::LogGroup"
    Properties:
      LogGroupName: !Sub "/aws/rds/instance/${RDSDBInstance}/postgresql"

  LogsLogStream:
    Type: "AWS::Logs::LogStream"
    Properties:
      LogGroupName: !Sub "/aws/rds/instance/${RDSDBInstance}/postgresql"
      LogStreamName: !Sub "${RDSDBInstance}.0"
```
PowerAutomate: decodeBase64(非推奨)ではなく、base64ToStringを使う

# 背景
decode 関数が二つあってあれ？って思って動作差異を調べたら差なんてなくて、
単に非推奨だったことがわかったので、その記録

Action 一覧には、Deprecated という記載はない（詳細には記載有り）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/ab0de859-53da-af61-35f9-bfe26315a0c9.png)

英語版でも同様
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/aaaf7cc9-34ae-2c04-9d38-bc97326db8f8.png)

[サイトURLの英語・日本語変換](https://qiita.com/baku2san/items/ac02be7157d62f4b78da#%E3%82%B5%E3%82%A4%E3%83%88url%E3%81%AE%E8%8B%B1%E8%AA%9E%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%A4%89%E6%8F%9B) はこれ利用すると便利

# decodeBase64 は非推奨
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/8de626d1-5d8e-21ed-0e73-00046b696c60.png)

[decodeBase64](https://learn.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#decodebase64-deprecated)

# base64ToString

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/49b023c3-fa82-d1c4-24d8-9edc7130516a.png)

[base64ToString](https://learn.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#base64tostring)
【Material-UI】ふわっとMaterial-UIに触れてみる

## お手軽に今風な画面を作りたい
その昔、htmlとcssだけでめっちゃ頑張ってカッコイイ画面を作っていました。
しかしある人は言いました。
🙅‍♀️「`デザインに統一なくね？`」
🤦‍♀️「`毎回似たようなcss描きまくるのダルくね？`」

そこでいつの間にか生まれた概念`マテリアルデザイン`と
その`コンポーネントライブラリ`です。

https://m3.material.io/

とくにReactのためにあるものが`Material-UI`であり
公式がとても見やすく、簡単に綺麗なUIが作れるうえ、カスタムも十分にできます。
やすっぽい言葉より実際に見た方が早いので、早速実践してみましょう。

とその前に...

## バージョンについて
Material-UIのv4とv5の間に大きな溝があります。
綺麗にまとめてくださいってる方の記事を貼っておきます。公式は[こちら](https://mui.com/core/)

v4

https://zenn.dev/yumemi_inc/articles/2020-09-24-react-material-ui?redirected=1

v5

https://zenn.dev/yumemi_inc/articles/2021-09-26-material-ui-v5

また、v5からブランド名が`Material-UI`から`MUI`に変わりました。よって
この記事のタグにも一応どっちもつけてみましたし、なにより
npm installするものが変わり、ソース中でのimport文も変わってしまいます。

```v4.
npm install @material-ui/core @material-ui/icons
```
```v5だとこんな感じがおすすめされている.
npm install @mui/lab @mui/material @emotion/react @emotion/styled
npm install @mui/icons-material
```
🌾[公式](https://mui.com/)の`Get Started`を参考にしています

## さっそく実践
それではいい感じの画面を作ってみましょう。Reactの導入等はここではスキップします。
codepenで5秒で作ってみたものがこちら。
`0.5x`押すと見やすいです。
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="eYPRdey" data-user="serna37" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/serna37/pen/eYPRdey">
  Untitled</a> by serna37 (<a href="https://codepen.io/serna37">@serna37</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

muiの[`Card`](https://mui.com/material-ui/react-card/)とかと[`Typography`](https://mui.com/material-ui/api/typography/)を使ってみました。
文字通りカード型のやつを画面上に置いてくれます。勝手にレスポンシブ対応してくれます。
さて、MUI公式を見ながら使い方のデモを確認してゆき、多くのコンポーネントを取り入れることができますが
公式はとっても見やすいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453310/4f03f90c-3f5c-e21c-8db8-7258f507b183.png)

---
サンプルのソースも↓のボタン押せばすぐに見れますし
sandboxで公開してくれているので、その場でちょっと変更してお試しができちゃいます。
服屋で試着する感覚に近いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453310/6d5544a6-21da-7eda-c3d8-2d874d316865.png)


MUIは基本的に細かいcss事情を考えなくて良い、あらかじめ、ある程度作られた
みんながどうせコレよく使ってるでしょ！ってパーツをめっちゃ持ってます。
なんてありがたい。

## コード共有サイトで試す
コード共有サイトについては趣旨とズレるので細かくは触れませんが、以下を参考にすると良いです。
[・CodeSandbox](https://qiita.com/nishiurahiroki/items/279041447ef1415804c2)
[・StackBlitz](https://qiita.com/tkiryu/items/46f64a09f23bed248e12)
[・CodePen](https://qiita.com/fumu238/items/f73274aa1a188eb15794)

とにかく即座にフロント言語を試してみましょうということです。

MUIのCDNでの入れ方は[こちら](https://mui.com/material-ui/getting-started/installation/#cdn)にあります。
```これいれるだけです.
https://unpkg.com/@mui/material@latest/umd/material-ui.development.js
```

とりあえず触ってみたいだけの方は、前述のCodePenで試してみたり
以下のように公式MUIに溢れているsandbox(や、stackblitz)で試すと良いでしょう

Cardの例であれば[こちら](https://codesandbox.io/s/ezrs93?file=/demo.tsx)からいけます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453310/991edec9-46e8-f3db-716c-0977803e4ec9.png)
【OfficeScriptsコード】ユーザーのメールアドレスを取得してWebエクセルにフィルターを設定する

# 【やりたいこと】
* 複数名で共有しているExce on the Web（以下、エクセル）のテーブルで、閲覧者が1クリックで自分のデータのみ表示できるようにしたい

<table>
  <caption>サンプルテーブル名「T果物購入履歴」</caption>
  <thead>
    <tr>
      <th>氏名</th> <th>メールアドレス</th> <th>果物購入日</th> <th>購入品名</th>
    </tr>
  </thead>
  <tr>
    <td>ホゲ太郎</td> <td>hogetarou@hogehoge</td> <td>2023/6/1</td> <td>りんご</td>
  </tr>
  <tr>
    <td>ホゲ花子</td> <td>hogehanako@hogehoge</td> <td>2023/6/2</td> <td>イチゴ</td>
  </tr>
<tr>
    <td>ホゲ太郎</td> <td>hogetarou@hogehoge</td> <td>2023/6/4</td> <td>みかん</td>
  </tr>
  <tr>
    <td>ホゲ花子</td> <td>hogehanako@hogehoge</td> <td>2023/6/6</td> <td>ぶどう</td>
  </tr>
</table>


ホゲ花子さんがエクセルを開いてボタンをクリックしたら、ホゲ花子さんの行のみが表示されるのが理想
<table>
  <thead>
    <tr>
      <th>氏名</th> <th>メールアドレス</th> <th>果物購入日</th> <th>購入品名</th>
    </tr>
  </thead>
  <tr>
    <td>ホゲ花子</td> <td>hogehanako@hogehoge</td> <td>2023/6/2</td> <td>イチゴ</td>
  </tr>
  <tr>
    <td>ホゲ花子</td> <td>hogehanako@hogehoge</td> <td>2023/6/6</td> <td>ぶどう</td>
  </tr>
</table>

# 【コード】
```
function main(workbook: ExcelScript.Workbook) {

  // 作業用のシートを新規作成（後で消します）
  const sheetName = "wk"
  workbook.addWorksheet(sheetName);
  const sheet = workbook.getWorksheet(sheetName);
  
  // 作業用シートにコメントを追加してユーザーの情報を取得する
  const cell = sheet.getRange("A1");
  const comment = sheet.addComment(cell, "");
  const name = comment.getAuthorName();
  const email = comment.getAuthorEmail();
   
　// 取得情報出力
  console.log(name)
  console.log(email)

  // 作業用シートを削除
  workbook.getWorksheet(sheetName).delete();

  // ここからフィルター操作　★対象のテーブル名を設定してください★
  const tableName ="T果物購入履歴"
  const dataTable = workbook.getTable(tableName);

  // 事前にフィルターをクリアしておく
  dataTable.getAutoFilter().clearCriteria();

  // 指定の列に取得した情報でフィルターを設定　★対象列名を設定してください★
  const columnName ="メールアドレス"
  dataTable.getColumnByName(columnName).getFilter().applyValuesFilter([email]);

}
```
あとはコード実行用ボタンをシートに配置して完了です！

https://learn.microsoft.com/ja-jp/office/dev/scripts/develop/script-buttons

# 【補足】
* 作業用のシートを作成している理由
既存シート上でコメント追加→削除をすると、既にコメントが入力されていた場合、そちらが消えてしまう懸念があったため


# 【諦めたこと】
（方法が分かれば実装したかった）
* 次の人が開いた時にフィルター設定がクリアされ、全データが表示されるようにしたい
（「フィルターをクリアする」ボタンを付けるくらいしか思いつかなかった）
* むしろ開いた時点で自分のデータのみ表示するようにしたい
（VBAのWorkbook.Openイベント的な。PowerAutomateと連携すれば方法あるのかも？）

# 【使用シーン】
全社的なデータがあって、それを各担当者にチェックしてもらうといった時にユーザーが使いやすいはず

項目数が大量でメールアドレスや氏名の列が右端にあったりするテーブルだと、まず列を探してフィルターを設定して・・・というのが地味に負担だったりしません？
ユーザー側からすると、簡単に自分のデータのみ表示できるのは便利かな、と思いコードを書いてみました（コピペですが）。

# 【注意点】
* 作業用シートの名前は既存のシート名と重複しないようにしてください。同名シートが既に存在するとエラーが発生します。
* エクセルでコメントが入力された際に通知を受け取る設定にしている場合、コードが実行されるたびに通知が来ます。
* コード初回実行時、実行権限の確認ダイアログが表示されるかも。「許可」を選択すれば問題なく実行開始されます。


# 【参考にしたサイト】
ありがとうございました。

https://qiita.com/uttne/items/060011431ef027382ba4
FarmRPG　Unity Preserving Scene State Part1-2 まとめ

# 参考
Section 10

https://www.udemy.com/course/unity-2d-game-developer-course-farming-rpg/learn/lecture/19849494#content


# 一覧

## Part1 　Stateの作成と保存
![0616.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/281a3104-e767-0b54-055c-37b96aee2d2c.gif)

https://qiita.com/RYA234/items/f754ada6ebf5faca55a6

## Part2 　保存したStateから復元する

![0619.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/311164c7-857c-0cfb-9b7f-2ddff1cb4871.gif)


参考　実装前の様子　シーンを再読み込みすると取ったアイテムが再生成される。これを改善したい。

![0622.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/32aa868d-c32a-dbe5-5aa4-b73e15094d55.gif)

https://qiita.com/RYA234/items/a6b573ec4d02a563793b
Nginxでリバプロを構築し、URLpathで振り分ける

## 目的

前回やった様にtraefikでも出来るのだが、周りがNginxを使っているのでnginxで対応しなければならない場合が出てきた。

## Docker-compose
一部抜粋
```docker-compose.yml
version: '3'

services:
  reverse-proxy:
    image: nginx
    volumes:
      - ./reverse-proxy/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 80:80


  reveal-docker:
    build: .
    container_name: "reveal-docker"
    volumes:
      - ./md:/etc/reveal/md/
    tty: true

  ul7:
    build: .
    container_name: "ul7"
    volumes:
      - ./ul7:/etc/reveal/md/
    tty: true

```

## nginx.conf
```nginx.conf
events {
    worker_connections  16;
}
http {
    server {
        listen 80;
        server_name localhost;

        location /reveal-docker {
            proxy_pass http://reveal-docker:8000/;
            proxy_redirect off;
        }

        location /ul7 {
            proxy_pass http://ul7:8000/;
            proxy_redirect off;
        }

        location /ship {
            proxy_pass http://ship:8000/;
            proxy_redirect off;
        }

        location /codimd {
            proxy_pass http://codimd:3000/;
            proxy_redirect off;
        }

        location /chinenlabweb {
            proxy_pass http://chinenlabweb:80/;
            proxy_redirect off;
        }


    }
}
```
Elixirの対話モードでパイプ演算子の動作を確認してみた

# 概要
Elixirの対話モードでパイプ演算子の動作を確認してみました。以下のページを参考にしました。

https://elixirschool.com/ja/lessons/basics/pipe_operator

# 対話モードで実行
以下のコマンドを実行しました。
```
$ iex
Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]

Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> "Elixir rocks" |> String.split()
["Elixir", "rocks"]
iex(2)> "Elixir rocks" |> String.upcase() |> String.split()
["ELIXIR", "ROCKS"]
iex(3)> "elixir" |> String.ends_with?("ixir")
true
iex(4)> "elixir" |> String.ends_with? "ixir"
warning: parentheses are required when piping into a function call. For example:

    foo 1 |> bar 2 |> baz 3

is ambiguous and should be written as

    foo(1) |> bar(2) |> baz(3)

Ambiguous pipe found at:
  iex:4

true
iex(5)> 
```

# まとめ
何かの役に立てばと。
rails authenticate_user!の使い方

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/eb19c596-97ed-c0cf-a32c-a496cd22ba54.png)

１：authenticate_user!とは
①deviseのメソッドである。
②ユーザーがログインしているかどうかを確認し、ログインしていない場合はユーザーをログインページにリダイレクトする。

２：使い方の一例
before_action :authenticate_user!, except: [:show, :index]

上記のコードの意味：すべてのアクションが実行される前に、ユーザーがログインしているかを確認する。ただし、show・indexアクションが呼び出された場合は、除くという意味となります。
（例：Twitterはログインしていなくても、ツイートの一覧、ツイートの詳細は見ることができる）
【Python】JEPXスポット市場価格データの《時刻コード：1~48》を《時刻表記：0:00~23:30》に変換する

# 目的
「時刻コード30のコマ」より、具体的な時刻「14:30のコマ」のほうが圧倒的に分かりやすいので、表を整備したりグラフに可視化することを想定して、時刻コードを時刻表記に変換したい。

# ゴール
以下のように、時刻コードをそれぞれ該当する時刻表記に変換したカラムをデータフレームに追加する。
>1⇨0:00、2⇨0:30、3⇨1:00、………、46⇨22:30、47⇨23:00、48⇨23:30

# 実践
```python
import pandas as pd
import datetime
from datetime import datetime as dt
from datetime import timedelta
```
[JEPXのHP](https://www.jepx.jp/electricpower/market-data/spot/)からダウンロードしたスポット価格データを読込み

```python
# スポット市場価格データ読込み
spot = pd.read_csv("spot_summary_2023.csv", encoding="shift-jis")
display(spot)
```
![スクリーンショット 2023-06-08 19.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1493633/24cee501-a8f6-b476-6a26-240bd66c6921.png)

48コマの時刻コードと時刻とを照合する辞書を作成
```python
# 1~48の"時刻コード"リスト作成
code_list = list(range(1,49))

# 0:00~23:30の時刻リスト作成（2000年1月1日はダミー）
t = dt(2000,1,1,0,0)
end = dt(2000,1,2,0,0)
delta = datetime.timedelta(minutes=30)
time = []
while t < end:
    time.append(t.strftime("%H:%M"))
    t = t + delta

# 時刻コードと時刻とを対照する辞書を作成
time_dict = dict(zip(code_list, time))
print(time_dict)
```
![図1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1493633/74f3d030-30b3-05fa-d8c1-844a10d1dd09.jpeg)

```python
# "時刻コード"カラムを時刻列に変換
spot["時刻"] = spot["時刻コード"].map(time_dict)

# 
display(spot[["受渡日","時刻コード","時刻","エリアプライス東京(円/kWh)"]])
```
![スクリーンショット 2023-06-08 19.42.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1493633/b19d4fbb-8fdf-ab0e-29e3-4bbc5a6a5282.png)
変換された！
aws cliを使用する際にアカウントを使い分けている場合のterraform

# 目的
・aws cliで以下のようなconfigファイルでアカウントを出し分けている場合の書き方を示しておく

~/.aws/config
```
[default]
region=
output=

[profile terraform]
region=ap-northeast-1
output=json
```

# 環境
・terraform: 1.2.9
・aws-cli: 2.11.25

# 方法

main.tf
```
provider "aws" {
  profile = var.aws_profile
  region  = "ap-northeast-1"
  default_tags {
    tags = {
      terraform-managed = "true"
    }
  }
}
```

valiables.tf
```
variable "aws_profile" { default = "terraform"}
```

後は通常通りコマンドをたたいていけば問題ないです。
```
$> terrafrom init
$> terraform plan
...
```
Flask × GoogleCloudStorageでWebアプリ作成

FlaskとGoogleCloudStorageを使って画像を表示する簡単なWebアプリを作成しました。
## GoogleCloudStorageとは
GoogleCloudStorageとは動画や画像などのオブジェクトを保存することができるサービスのことです。
## GoogleCloudStorageの使用方法
* GCPのコンソールでプロジェクトを作成します。
* 左上のナビゲーションメニュー＞IAMと管理＞サービスアカウントを開きます。上部にある「+CREATE SERVICE ACCOUNT」でサービスアカウントを作成します。
* サービスアカウントを作成したら開いて上部の「キー」を開いて「鍵を追加」の所で鍵を作成します。この鍵はあとで使用します。この鍵はwebアプリのプロジェクトと同じ場所に保存します。
* ナビゲーションメニュー＞Cloud Storage＞バケットを開きます。上部の「+作成」でバケットを作成します。このバケットに画像や動画などのオブジェクトが保存されます。※公開アクセスの所が「インターネットに公開」になってないと、あとでFlaskで画像を表示することができません。
## Webアプリ作成
ここからはFlaskを使ってwebアプリを作っていきます。
始めに、HTMLで画像をアップロードできるようにします。
```
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="../static/css/style.css">
  <title>home</title>
</head>
<body>
  <h1>画像選択</h1>
  <form action="/upload" method="POST" enctype="multipart/form-data">
    <input type="file" name="image">
    <input type="submit" value="アップロード">
  </form>
</body>
</html>
```
次に、画像を表示できるようにします。
```
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="../static/css/style.css">
  <title>upload</title>
</head>
<body>
  <img class="image" src="{{image}}" alt="Image">
</body>
</html>
```
最後にpythonでバックエンドの部分を書いていきます。
```
import os
from flask import Flask, render_template, request
from datetime import datetime
from google.cloud import storage

app = Flask(__name__)

service_account_key = 'key'
bucket_name = 'bucket'

key = os.path.join(app.root_path, service_account_key)
client = storage.Client.from_service_account_json(key)
bucket = client.get_bucket(bucket_name)

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def upload():
    if 'image' in request.files:
        file = request.files['image']
        if file.filename != '':

            blob = bucket.blob(file.filename)
            blob.upload_from_string(file.read(), content_type=file.content_type)

    objects = list(bucket.list_blobs())
    
    new_file = max(objects, key=lambda x: x.time_created)

    image_url = f'https://storage.googleapis.com/{bucket_name}/{new_file.name}'   

    return render_template('upload.html', image=image_url, name='-')

if __name__ == '__main__':
    app.run(debug=True)
```
* service_account_keyには先ほど作成、保存しておいたサービスアカウントの鍵のパスを書きます。
* bucket_nameには先ほど作成したバケットの名前を書きます。
```
service_account_key = './path/鍵のpath'
bucket_name = 'バケットの名前'
```
## 大変だったこと
GoogleCloudPlatform(GCP)を使用したのは、このWebアプリを本番環境でもちゃんと使えるようにしたいと思ったからです。しかし、GCPを使うにしても、そもそも使い方が分からなかったのでそこを理解するのが一番大変でした。
## Webアプリ完成
「ファイルを選択」を押して画像を選択し、「アップロード」を押します。
![home - Google Chrome 2023_06_08 17_56_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3073852/b3710cb3-a372-67d5-ecb7-7c0f3b127c0f.png)
すると以下のように画像が表示されます。
![home - Google Chrome 2023_06_08 17_57_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3073852/088b4eaf-962b-837a-a0f5-942b2e7e0a60.png)
RaspberryPi4から無線LANでRapberryPiPicoWに適当なコマンドを送って適当な返事を返すコード

[前回の記事](https://qiita.com/pinkych24/items/a98ff518869d24201b28)でRaspberryPi4で立てた無線LANを使ってホスト側のRaspberryPi4からPicoWへ適当なコマンドを送ってPicoWから適当な返事を返すコードを書いた
UECSを使いたかったんだけど素人にはCのサンプルコードをPythonで書き直すスキルがなかったのでできる範囲で適当に作った。

PicoWで実行するコード
```python
import network,socket,machine,time
from picozero import pico_temp_sensor,pico_led

ssid = 'NameOfNetwork'
password = 'AardvarkBadgerHedgehog'

def connect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid,password)
    while wlan.isconnected()==False:
        print("Waiting for connection")
        time.sleep(5)
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')
    return ip

def open_socket(ip):
    address = (ip,8080)
    connection = socket.socket()
    connection.bind(address)
    connection.listen(1)
    return connection

def serve(connection):
    pico_led.on()
    while True:
        client = connection.accept()[0]
        request = client.recv(1024)
        try:
            request = request.decode()
            if request=="Hello!":
                response = "Hello world!"
            elif request=="temp?":
                temp = pico_temp_sensor.temp
                response = "Current temperture is "+str(round(temp,2))+"°C"
            elif request=="time?":
                response = "Current time is "+str(time.time())
            else:
                response = "pardon?"
        except:
            response = "Failed recieving a message"
        print(request)
        client.send(response.encode('utf-8'))
        client.close()

try:
    ip = connect()
    connection = open_socket(ip)
    serve(connection)
except KeyboardInterrupt:
    machine.reset()
```

RaspberryPi4側で実行するコード
```python
import socket,time,datetime,os
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

def send_message(ip,port,mes):
    with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
        s.connect((ip,port))
        s.sendall(mes.encode('utf-8'))
        buf = s.recv(1024)
        return buf

try:
    ip = '192.168.4.20'
    port = 8080
    while True:
        try:
            buf = send_message(path,ip,port,"Hello!")
            buf = buf.decode().strip("()")
            print(buf)
            time.sleep(1)

            buf = main(path,ip,port,"temp?")
            buf = buf.decode().strip("()")
            print(buf)
            time.sleep(1)

            buf = main(path,ip,port,"time?")
            buf = buf.decode().strip("()")
            print(buf)
            time.sleep(1)
            
            buf = main(path,ip,port,"WTF!!!")
            buf = buf.decode().strip("()")
            print(buf)
            time.sleep(1)

        except:
            dt_now = datetime.datetime.now()
            dt_now = dt_now.strftime("%Y-%m-%d_%H:%M:%S")
            print(dt_now,"error, try again.")
            time.sleep(1)
            pass
except KeyboardInterrupt:
    pass
```
通信プロトコル的なものが無法地帯となっているけど独立したネットワークなので気にしない…。登録済のMACしか接続できないようにしているのでよほどのことがなければ事故もおこらないはず。多分。
受信したコマンドに応じて実行する関数を変えれば測定ノードから環境情報を取得して制御ノードでモーターの制御みたいなこともできる。
「Firebase Dynamic Links を使っても アプリへ直接遷移できない！」となった時の対処法

## 対象となる人
- Firebase上での Firebase Dynamic Links の設定を終えている人
- Firebase Dynamic Links を使ったアプリ遷移ができていない人
    - アプリインストール済みにも関わらず`AppStoreに遷移してしまう`人


## 対処法

私は以下 1〜2 の手順で確認/変更を行い無事アプリ遷移できるようになりました。

#### 1: 「iOS 自己診断ツール」を用いて Firebase Dynamic Links の設定に不備がないか確認

[iOS 自己診断ツール](https://firebase.google.com/docs/dynamic-links/debug?hl=ja)は、Firebaseが提供しているデバッグのプログラムで、Firebase Dynamic Links に関して検出されたエラーを含むデバッグ情報が標準出力に出力されます。

診断用のプログラムは以下の通りです。`1行でOK`

```hoge.swift
DynamicLinks.performDiagnostics(completion: nil)
```

<br><br>

🙆‍♂️ アプリへ直接遷移`可能`な場合の診断結果

```
---- Firebase Dynamic Links diagnostic output start ----
Firebase Dynamic Links framework version 10.10.0
System information: OS iOS, OS version 16.0, model iPhone
Current date 2023-06-08 08:33:17 +0000
Device locale en-JP (raw en_JP), timezone Asia/Tokyo
ERROR: UIApplication delegate <sampleApp.AppDelegate: ----------> does not implements selector application:openURL:options:. FDL depends on this implementation to retrieve pending dynamic link.
	Specified custom URL scheme is -------------- and Info.plist contains such scheme in CFBundleURLTypes key.
	AppID Prefix: ------, Team ID: ------, AppId Prefix equal to Team ID: YES
performDiagnostic detected 1 ERRORS.
---- Firebase Dynamic Links diagnostic output end ----
```

<br>

❌ アプリへ直接遷移`できない`な場合の診断結果

```diff
---- Firebase Dynamic Links diagnostic output start ----
Firebase Dynamic Links framework version 10.10.0
System information: OS iOS, OS version 16.0, model iPhone
Current date 2023-06-08 08:47:29 +0000
Device locale en-JP (raw en_JP), timezone Asia/Tokyo
ERROR: UIApplication delegate <sampleApp.AppDelegate: ----------> does not implements selector application:openURL:options:. FDL depends on this implementation to retrieve pending dynamic link.
+ ERROR: Specified custom URL scheme is ---------- but Info.plist do not contain such scheme in CFBundleURLTypes key.
	AppID Prefix: ------, Team ID: ------, AppId Prefix equal to Team ID: YES
performDiagnostic detected 2 ERRORS.
---- Firebase Dynamic Links diagnostic output end ----
```

`Info.plist do not contain such scheme in CFBundleURLTypes key` : URLTypes の設定が行われてませんよ


#### 2: URLTypeを設定

`TARGETS` > `Info` > `URL Types` > `+`

<img width = 80% src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764557/4769305a-b37f-a138-9bc7-ac77dd62a240.png">

※ Identifier: 任意
※ URL Schemes: アプリごと設定される **Bundle ID**。(確認 : `TARGETS` > `General` > `Identify` > `Bundle Identigy`)


#### 3: 2までで解決しない場合

以下2つの動画を見て、設定を見直す。

https://www.youtube.com/watch?v=KLBjAg6HvG0

https://www.youtube.com/watch?v=fsFHoC4ReUA



**疑問や気になったことがある場合は、コメントお願いします 🙏**
第一週目を終えて

第一週目を、本日第二週の木曜日に終了しました。初めてで上手くいかない事ばかりで、相当苦戦しましたが、ようやく終わりました。今回分かった事は、HTLMは、骨組みで、CSSは、デコレーションだという事です。まだまだ理解していない事だらけでまた、予習が必要だと思いました。また、色々苦戦続きでしたが、とても楽しかったです。最後に、これまで支えてくれた皆様本当に、ありがとうございました。これからも宜しくお願いします。![uploading...0]()
Power Apps で、GroupBy 関数を利用して合計値を計算する


# はじめに

例えば、以下のような SharePoint リストで何かしらの管理をしているケースにおいて、Power Apps で、種類2ごとの合計値を計算して表示したいようなケースがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/c68d8589-b24d-86c6-9745-c125cdc2a2aa.png)

Power Apps 側では、以下のように、コンボボックスで種類1をフィルターし、種類2ごとの合計値を表示するイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/afe2e5f3-8b90-9c4f-8b28-5d296c918606.png)

このように、アプリ側で合計した値を表示したいといったニーズもあると思うので、こちらの実装について説明します。

# 実装

コンボボックスを配置し、`[Items]`プロパティに、SharePoint リストの選択肢の情報を入れます。今回は、フォームコントロールから流用し、`Choices([@契約].種類1)`を入れます。

:::note
ギャラリーのフィルターは、以下の記事も参考にしてください。
:::
https://qiita.com/Takashi_Masumori/items/777c37b57ddecbf05d12#%E9%81%B8%E6%8A%9E%E8%82%A2%E5%88%97%E3%81%A7%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%83%BC


`[OnChange]`プロパティの式は以下のような感じです。


```
ClearCollect(
    colTempContract,
    ForAll(
        Filter(
            契約,
            Type.Value = ComboBox1.Selected.Value
        ),
        {
            Type2: Type2.Value,
            Quantity: Number
        }
    )
);
ClearCollect(
    colContract,
    ForAll(
        GroupBy(
            colTempContract,
            "Type2",
            "GroupedResults"
        ),
        {
            Type2: Type2,
            Total: Sum(
                GroupedResults,
                'Quantity'
            )
        }
    )
)
```

少し長いですが、GroupBy を利用するところがポイントになります。こちらについては、以下のページも参考にしていただけたらと思います。最初はピンとこない人もいると思いますが、こういったシナリオがあった際にもしかしたら利用するかも、みたいな感じで思い出していただけたらと思います。

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-groupby

今回のケースですと、一旦、`colTempContract`は以下のようになります。ここから、Type2 をベースにグループ化していく感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/20613302-44d0-dde1-77f6-b7e3dbc8df50.png)

GroupBy 関数により、以下のような仮想的なテーブルが作成される感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/0a55a997-2fea-0da9-d266-fd08d9115245.png)

そして、ForAll で行ごとに処理していき、Sum 関数 (合計を出力する関数) で、今回は、GroupedResult がテーブルになるため、そのテーブルから、Quantity 列の情報で合計を出力する感じになります。具体的には、1 行目の処理、2 行目の処理で以下の合計値を計算しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/52828f31-b63a-97b5-b62e-0cd93cd5e568.png)

結果として以下のようなテーブルが出来上がるため、こちらをギャラリーで表示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/044725e8-12bd-e6db-17ec-c3d2c8d13068.png)


そのため、ギャラリーの`[Items]`プロパティは、上記で作成した、`colContract`とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/0581a3db-2cc5-c205-98cc-cd1c866dd02c.png)

# まとめ

今回は、契約関連の情報を集約する SharePoint リストを例に、Power Apps で、GroupBy 関数を利用して、契約種類ごとの合計値を計算する方法について説明しました。GroupBy 関数を利用することでアプリの利用者への情報の見せ方を工夫することが出来るため、参考にしていただけると幸いです。
Db2 for i ってやっぱスゴくない？（スペックの話）

ここにDb2 for i のテーブルのスペックが書いてあります。

https://www.ibm.com/docs/ja/i/7.5?topic=concepts-database-file-sizes

1レコードの最大バイト数	32 766 バイト
レコードの最大フィールドの数	8 000 フィールド　　＊1
ファイル内のキー・フィールドの数	120 フィールド　＊1
テーブル・ビューのキーの最大サイズ	32 768 文字
1テーブルの最大レコード数	4 294 967 288 レコード
1テーブルの最大バイト数	1.7 テラバイト         ＊1
1テーブルに対して作成可能な論理ファイル（ビュー）の最大数	3686 ファイル
文字タイプのカラムまたは DBCSタイプの最大サイズ	32 766 バイト
ゾーン 10 進またはパック 10 進タイプのカラムの最大サイズ	63 桁

地味にすごいと思います。。

※上記マニュアルページには
----------------------
通常、 IBM i データベース・ファイルは、オペレーティング・システムで許可されている最大サイズに達するまで拡張できます。 オペレーティング・システムは、通常一度にすべてのファイル・スペースを 割り振ることはしません。 むしろ、ファイルの大きさに応じて追加スペースを割り振ります。 このような自動的に記憶域を割り振る方法により、適切 なパフォーマンスと効率的な補助記憶域スペースが最良の組み合わせで管理されます

----------------------
と書かれていますが、かんたんにいうと他のRDBMSのように表スペースは存在せず（理由：RDBMSはマイクロコード層で動作するのでDB専用のストレージ領域を定義する必要が無い、OSレベルのストレージ管理で動作するから）、テーブルのサイズが増加していくと物理ストレージやLUNに分散されて順次拡張されていきます。またテーブル最大サイズも論理的には制限がない、ということになります。（通常は物理的なストレージサイズで上限が規定される）

※わりと最近遇った話
・メインフレームのCOBOL,データベース資産を移行したい案件でやっぱりデータベースのカラム数（たしか1,000以上）,レコード件数（億件以上のテーブル多数）,スキーマ数数百以上,などなどでオープン系DBだとかなりきついと（実質無理と）。Db2 for iだと上記は割とフツーです。
私が知ってる事例ですと1コアで億件テーブル処理してるユーザーはぜんぜん普通です。スキーマ数=数百問題なし（設計上は1000-2000スキーマ以上で設計）などなどです。

*1 Db2 for i は複数メンバーといって、カラムレイアウトを複数作成してそれぞれのレイアウトに属するレコードごとに、メンバーとして扱うことが出来ます。（マルチメンバー構成、普通にカラムレイアウトが1つしかないのはシングルメンバー構成）。この値はシングルメンバーの最大数です。
[Terraform]EC2のAMIが更新されてリソースが削除&再作成されてしまいそうになった

### 背景
terraformでAWS上で展開するためのコードを記載中に、変更を加えていないのにも関わらず既にあるEC2インスタンスが削除&再作成(Destroy& Recreate)されそうになってしまった。

```bash
# 他のリソースのコードを書き換えた後にterraform planを実行
@ terraform % terraform plan
Terraform will perform the following actions:

  # aws_instance.app_server must be replaced
-/+ resource "aws_instance" "app_server" {
      ~ ami = "ami-07c2a88388bb80eb0" -> "ami-0d739893974bd27d0" # forces replacement
(以下略)
Plan: 1 to add, 0 to change, 1 to destroy.
```

## 発生原因
1, AWSの仕様でEC2インスタンスのAMIが変更されていた。
![スクリーンショット 2023-06-08 17.02.55 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706294/78585a7a-1ddd-540c-262c-c1104267839b.png)

:::note alert
赤線で引いた部分が最初のリソース作成時と現在で変更が加えられていた。
(これからも同じようなことは定期的にありそう)
:::

　

2, EC2インスタンスのAMI情報をdataブロック(data.tf)から取得していたが、そのdataブロックが最新のAMIを取得する設定になっていたため。
```hcl:data.tf
data "aws_ami" "ami" {
  most_recent = true #ここがtrueになっていたため常に最新のAMI情報を取得
  owners      = ["self", "amazon"]
```

```hcl:ec2.tf
# --------------------------
# create EC2 instance
# --------------------------
resource "aws_instance" "ec2" {
  ami                         = data.aws_ami.ami.id #data.tfから値を取得
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.public_subnet_1a.id
  associate_public_ip_address = true
```
3, 結果として、現在のリソースとterraform側で管理している情報に差異が生じ、`terraform plan`の時に削除&再作成が出てきてしまった。

## 対処法
`lifecycle`ブロックの`ignore changes`を使用して、特定の項目をterraformの管理外として設定する。
```hcl:ec2.tf
resource "aws_instance" "ec2" {
  ami                         = data.aws_ami.ami.id #data.tfから値を取得
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.public_subnet_1a.id
  associate_public_ip_address = true

↓↓↓ 以下を追加

lifecycle {
    ignore_changes = [
      ami,
    ]
  }
```

## 解決
```bash
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
```

## 補足
最初に参考にしたサイトで""をつけて使用したところ以下のようなエラーが出ました。teraformのver. 0.11以前については必要だったが、現在は必要がないみたい。

```hcl
Warning: Quoted references are deprecated
│ 
│   on appserver.tf line 66, in resource "aws_instance" "ec2":
│   66:       "ami",
│ 
│ In this context, references are expected literally rather than in quotes. Terraform 0.11 and earlier required quotes, but quoted
│ references are now deprecated and will be removed in a future version of Terraform. Remove the quotes surrounding this reference
│ to silence this warning.
```

## 参考
https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#ignore_changes

tfsteteファイルを手動で変更してできないか試したが、この方法ではエラー解消はできなかった。
[tfsteate手動編集](https://qiita.com/moaikids/items/d11dee96c8d68262098b)
【Flutter】紙の端が折れたようなContainerを作る


## 環境
* Android Studio： Flamingo　2022.2.1
* Flutter: 3.7.12

## 考え方
* Containerの右下に切り抜きを作る → Clipperをつかう
* めくれた感じをつくる ＝ 右下に小さいContainerを重ねる → Stackをつかう

## 完成イメージ
![Screenshot_20230608-164310.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827233/043f371d-eae4-3694-fbbd-544c7f9e9bd3.png)



### コード

<details><summary>サンプルコード</summary>

```dart
import 'package:flutter/material.dart';

/// 折れたところのサイズを設定する
const _clipSize = Size(40, 40);

class OretaContainerPage extends StatefulWidget {
  const OretaContainerPage({super.key});

  @override
  State<StatefulWidget> createState() => _OretaContainerState();
}

class _OretaContainerState extends State<StatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('紙の端が折れたようなContainer')),
      body: _createContainer(),
    );
  }

  Widget _createContainer() {
    // Positionedで右下にめくれたようなUIを配置する

    return Padding(
      padding: const EdgeInsets.all(8),
      child: ClipPath(
        clipBehavior: Clip.antiAlias,
        clipper: PaperClipper(),
        child: Stack(
          children: [
            Container(
              width: double.infinity,
              height: 200,
              color: Colors.blue.shade100,
            ),
            Positioned(
              bottom: 0,
              right: 0,
              child: Container(
                width: _clipSize.width,
                height: _clipSize.height,
                color: Colors.blue.shade300,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

/// 角折れを表現するためのClipper
class PaperClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    // 折れてるところだけを切り抜く
    final path = Path();
    path.lineTo(0, 0); // Start
    path.lineTo(size.width, 0); // 右上
    path.lineTo(size.width, size.height - _clipSize.height); // 折れてるところ
    path.lineTo(size.width - _clipSize.width, size.height); // 折れてるところ
    path.lineTo(0, size.height); // End
    path.close();
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return false;
  }
}

```
</details>


ここのコードには載せてませんが、
Materialで影とかつけたりしたらいい感じのUIになると思います。


【6/9 追記】
ClipしたUIに影をつけるのは、Materialでくくるだけではダメな模様。
→ stackoverflowに質問あった。
https://stackoverflow.com/questions/54753355/how-to-make-suitable-border-and-shadow-for-a-widget-created-by-customclipper

### 補足

* CustomClipperの、getPath()の繋げ方のイメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827233/68b66964-b331-df06-de7d-c4c672e690d3.png)


## 参考サイト

* Clipperの使い方

https://www.woolha.com/tutorials/flutter-using-clipper-examples


---

この紙の端が折れたUI、って正式名称はなんて名前なんでしょうか？
めくれてる、とか？

ググってもでてこなくて、自力でつくりました…

そもそも自力でつくるものではないのでしょうか？　そういうプラグインがある？？ :thinking: 
UIに詳しい方、教えてください。

### 【2023/7/3　追記】

> この紙の端が折れたUI、って正式名称はなんて名前なんでしょうか？


 <b>「[ドッグイア](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%83%E3%82%B0%E3%82%A4%E3%82%A2)」</b>というらしいです。 :dog2:
フローを実行した場所（GPS）を条件に出社か在宅勤務かを判別する【PowerAutomate】

## はじめに
私は出社するか在宅勤務するかの報告をPowerAutomateを使って自動化していて、
その判別に位置情報を利用しています。

簡単なフローではありますが見てください。

## 設定方法
### トリガー
「＋作成」を選択し、「インスタント クラウド フロー」を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/f5b0e05f-bdc1-ebed-2988-2bce3cf9ea73.png)

ダイアログが表示されたら、「手動でフローをトリガーします」を選択してください。
その後、「作成」ボタンを押してください。
ちなみにフロー名は入力してもしなくても大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/8507bc40-d4b4-402c-465b-daf00f92664c.png)

### 位置情報の取得
「＋新しいステップ」から「変数を初期化する」アクションを選択します。
※検索バーで「変数」と入力すると候補が出てきます

次に「変数を初期化する」アクションに以下の内容を入力します。
名前：Location（任意の名前で大丈夫です）
種類：文字列
値：市区町村

:::note info
位置情報のずれでフローが誤作動を起こすのが嫌だったので、「市区町村」を設定しています。
（市区町村なら範囲が広いので、ずれは起こりにくそう…という考えです）
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/cef91e2a-4155-e3c5-d109-43b2fa679bde.png)

### 判別条件
「市区町村」の値は英文字で返ってきます。
例えば私の会社は中央区にあるので「Chuo Ward」になります。
東京23区の場合：○○ Ward
市の場合：○○ City

また位置情報が会社付近の場合：出社、それ以外の場合：在宅勤務　と判定したいので
条件式は「Location」が「Chuo Ward」に等しくない　に設定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/074a32b3-75be-b5dc-5fd8-e2b79c5b99a9.png)

## フローの実行
### フローのテスト
フローを保存してテストを手動実行すると、PCの位置情報が確認できると思います。

### スマートフォンから実行
私の場合はスマートフォンに「PowerAutomate」のアプリをインストールしていて、アプリ内からフローを実行しています。
そうすると、フローを実行したときのスマートフォンの位置情報を利用することができます。

## おわりに
位置情報には他にも「完全なアドレス」（住所のことです）や「緯度・経度」などがあります。
用途に合わせてどの種類の位置情報を使うか選定すれば、もっと色々なことが出来ると思います。
例：「完全なアドレス」を使用して、どの会社のどの支店に訪問しているかを共有する
bitmapファイルのヘッダ解析


```python
import struct

def parse_bmp_header(file_path):
    with open(file_path, 'rb') as f:
        # ファイルヘッダの解析
        file_header = f.read(14)
        (file_type, file_size, _, _, data_offset) = struct.unpack('<2sIHHI', file_header)
        
        print('ファイルタイプ:', file_type.decode())
        print('ファイルサイズ(byte):', file_size)
        print('データオフセット(byte):', data_offset)

        image_header = f.read(40)
        (header_size, width, height, planes, bit_depth, compression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, ClrUsed, _) \
        = struct.unpack('<IiiHHIIIIII', image_header)
        
        print('ヘッダサイズ(byte):', header_size)
        print('画像幅:', width)
        print('画像高さ:', height)
        print('プレーンの数:', planes)
        print('ピクセルあたりの色数:', bit_depth)
        print('圧縮形式:0で圧縮なし', compression)
        print('ビットマップビットのサイズ:', biSizeImage)
        print('水平解像度:', biXPelsPerMeter)
        print('垂直解像度:', biYPelsPerMeter)
        print('カラーテーブルエントリ数:', ClrUsed)
        

parse_bmp_header('example.bmp')
基本的なGo其の物についてお浚い

## 概要
Goがどういったプログラミング言語なのか、初学者向けに、なるべくわかりやすくまとめるよう努め記述させて頂きます。

## Goの特徴
### 高水準言語
高水準言語とは、**人間が理解しやすい言語**を指します。Python, C/C++, Javaなども高水準言語の一例です。もちろん、高水準言語の反対である低水準言語もあり、これには機械語やアセンブリ言語が含まれます。

:::note info
**人間が理解しやすい言語**
:::

### 静的型付け言語
静的型付け言語とは、**変数の型を事前に宣言する必要がある言語**を指します。Goは実行前に型をチェックします。他の静的型付け言語としては、C/C++, C#, Javaなどがあります。

:::note info
**変数の型を事前に宣言する言語**
:::

### 波括弧による文のグルーピング
Goでは**文のグルーピングは波括弧 {} で行われます**。これは、例えばPythonのようにインデントを使用しないということを意味します。

:::note info
**文のグルーピングは波括弧で行われる**
:::

### パッケージシステムによる再利用
Goでは、よく使う処理や型を整理、管理したいときに、パッケージシステムを利用することで**汎用性のあるコードを再利用することが可能**です。

:::note info
**汎用性のあるコードを再利用できる**
:::

### コンパイラ型言語
コンパイラ型言語とは、**ソースコードを一度機械語に変換し、その後その機械語のプログラムを実行する方式**のことを指します。そのため、Goでは事前にコンパイルが必要です。反対に、PythonやRubyのようなインタープリタ型言語はプログラムの命令を一つずつ解釈しながら実行します。

コンパイラ型言語の利点としては、プログラムが一度コンパイルされると高速に実行できるという点があります。一方で、コードの変更を反映させるためには都度コンパイルを行う必要があります。

:::note info
- **コンパイルが必要**
- **一度コンパイルすると高速に実行できる**
:::

## この記事のシリーズ
- [基本的なPython其の物についてお浚い](https://qiita.com/kimascript/items/6dcb0bc4fc427e8f3833)
生成AI　～目次～


# GAN

https://qiita.com/momo10/items/46e842beada6910c3836

# VAE

https://qiita.com/momo10/items/608761dc291b95b46b2a
# 拡散モデル

https://qiita.com/momo10/items/e19aaf66cc7088ef3da3
【React】React-selectでEnterを押すと、リロードされてしまう

<h2>症状</h2>
React-selectを使用して、そのコンポーネント上にカーソルがある状態でEnterを押すと、リロードされてしまう事象がありました。

以下がソースです。

```react:react-select
export default function MUIAnimatedMultiSelect({ placeholederText, setCity, city, onkeyPress }) {
  const classes = useStyles();

  function handleChange(value) {
    setCity(value);
  }

return (
    <Fragment>
      <form className={classes.root} noValidate autoComplete="off">
        <InputLabel id="demo-simple-select-helper-label">提供地域</InputLabel>
        <Select
          labelId="demo-simple-select-label"
          id="demo-simple-select"
          label="提供地域"
          options={options}
          placeholder={placeholederText}
          defaultValue={{ label: city, value: city }}
          onChange={(event) => { handleChange(event.value) }}
          variant="outlined"
          onKeyDown={(event) => {
            event.preventDefault();
            if (event.key === 'Enter') {
              event.preventDefault();
              onkeyPress(event)
            }
          }
          }
        >
        </Select>
      </form>
    </Fragment>
  );
}
```


<h2>解決方法</h2>
MUIとは違い、react-selectではonKeyDownではなく、onKeyPressに対応しているようです。
onKeyPressに変更して、event.preventDefault();を挿入することで解決しました。

```react:react-select
        <Select
          onKeyDown={(event) => {
            event.preventDefault();
            if (event.key === 'Enter') {
              event.preventDefault();
              onkeyPress(event)
            }
          })
        }
        >
        </Select>
```

<h2>参考</h2>

https://react-select.com/props