OmniAICreator/Qiita-1.07M huggingface dataset:
cfn-linterでCloudformationのフォーマットチェックをためす

# はじめに

こんにちはあるいはこんばんは。みなさんはCloudFormationを使っていらっしゃいますか？私はふだんTerraformを使うことが多く、Cloudformationを勉強中です。勉強中ですとやはり、Linterや静的解析ツールに色々教えてもらいたくなります。
今回は、CloudformationのLinter、cfn-lintを試してみます。

https://github.com/aws-cloudformation/cfn-lint

cfn-lintのLinter規則は以下をご覧ください。

https://github.com/aws-cloudformation/cfn-lint/blob/main/docs/rules.md


# 実際にやってみる

CloudFormationテンプレートのサンプルはこちらです。

```yml
Resources:
  MyVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: MyVPC

  MySubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: MySubnet

  MySecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: My security group
      VpcId: !Ref MyVPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0

  MyEC2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: ami-0abcdef1234567890  # Replace with your AMI ID
      InstanceType: t2.micro
      SubnetId: !Ref MySubnet
      SecurityGroupIds:
        - !Ref MySecurityGroup
      KeyName: my-key-pair  # Replace with your key pair name
```

では、上記に色々フォーマットエラーを仕込んでみましょう。

(1)存在しないTypeにタイポしてみます。

```diff_yaml
-   Type: 'AWS::EC2::VPC'
+   Type: 'AWS::EC2::VPCC'
```

(1)指摘できました
```sh
E3001 Invalid or unsupported Type AWS::EC2::VPCC for resource MyVPC in us-east-1
cfn.yaml:3:5

E3008 Property "VpcId" can Ref to resources of types [AWS::EC2::VPC] at Resources/MySubnet/Properties/VpcId/Ref
cfn.yaml:15:7

E3008 Property "VpcId" can Ref to resources of types [AWS::EC2::VPC] at Resources/MySecurityGroup/Properties/VpcId/Ref
cfn.yaml:26:7
```

(2)subnetのIP範囲を、VPCを超えたものにしてみます。

```diff_yaml
-     CidrBlock: 10.0.1.0/24
+     CidrBlock: 10.0.0.0/8
```

(2)指摘できました。指摘の言い方がちょっと異なりますが。
```sh
E3031 CidrBlock contains invalid characters (Pattern: x.x.x.x/y) at Resources/MySubnet/Properties/CidrBlock
cfn.yaml:16:7
```

(3)存在しないプロトコルにタイポしてみます
```diff_yaml
-       - IpProtocol: tcp
+       - IpProtocol: tcpp
```
(3)残念！！見つけられませんでした。ここから先は、静的解析ツールが必要かもしれません。

# まとめ

今回は、cfn-lintを試してみました。細かな静的解析までいかずとも、コードを書く上でかなり助けてくれそうです。

参考にしたwebサイト https://aws.amazon.com/jp/blogs/news/git-pre-commit-validation-of-aws-cloudformation-templates-with-cfn-lint/

- AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
- Terraform は、HashiCorp, Inc. の米国およびその他の国における商標または登録商標です。
- その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。
Vue + Viteでビルド時に特定の属性を削除してビルドする方法

# 目的

Webアプリケーションの開発においてテスト目的に付与した属性をプロダクションビルド時に剥がしたい場合があるかもしれません。
たとえば`testing-library/vue` [testing-library](https://testing-library.com/docs/vue-testing-library/intro)を用いてユニットテストを行なっていて、`v-for`で展開した配列の要素を`data-testid`で別個取得できるように配列のIDを渡していたりする場合、あまり露出したくないなどあるかもしれません。
そういった場合のTipsです。

## Vite Config

Viteでの開発やビルドの設定を行う `vite.config.ts`ファイルでvueのプラグインの設定を調節します。

```ts:vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig(({ mode }) => ({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          nodeTransforms: [
            (node) => {
              if (mode === 'production') {
                if (node.type === 1) {
                  for (let i = 0; i < node.props.length; i++) {
                    if (node.props[i].name === 'data-testid') {
                      node.props.splice(i, 1);
                      i--;
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }),
  ]
})
```

## 何をしているか

`vue`のビルドのために提供されているプラグインである`@vitejs/plugin-vue`はオプションを引数として渡すことができます。

[@vitejs/plugin-vue](https://www.npmjs.com/package/@vitejs/plugin-vue)
このオプションは`vue`のコアプラグインのDefinition fileを参照しています (@vue/compiler-sfc)
https://github.com/vuejs/core

その中でビルドするノードのタイプが1、HTML要素(ELEMENT)である場合にそのノードのpropsが6、HTML属性(ATTRIBUTE)である場合にその名称が`data-testid`であれば削除しています。

これら一連の処理をビルドのモードが`production`の場合にのみ行うようにしています。

ちなみにモードは`vite build --mode production`で渡すことができます。
渡していない場合は`undefined`になります。
Vision API Product Searchを利用した視覚的類似商品推薦の効果

## はじめに

TRiCERA ART（ https://www.tricera.net/ja/ ）には2024年4月が現在10万2,000点もの作品が掲載されています。

素晴らしい作品が多く掲載されているのはいいことですが、作品数が多すぎるが故に回遊を続けたけ結果好みのアートが見つからず離脱をしてしまうという現象が起きてしまいます。

そこで我々プロダクトチームは日夜ユーザーの検索体験を向上させるためにはどうすればいいか模索し、開発を繰り返しています！

その試行錯誤の中で生まれた一つの機能がTRiCERA ARTの作品詳細ページ下部にある「あなたにおすすめのアート作品」になります。

このエリア自体は以前からあったのですが、表示される作品はメディウムが同じ作品をランダムに出すという簡単なロジックで、あまりCTRが多くないことが課題でした。
そこで改善の仮説として、視覚的に類似度が高い作品が表示されることでよりCTRが高くなるのではないかと検討が重ねられ、Vision API Product Searchを活用して機能を実装することが決まりました。

![スクリーンショット 2023-11-27 19.51.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771181/4012cc95-7f30-80cb-9365-5b0cd51c82c4.png)

![スクリーンショット 2023-11-27 19.52.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771181/d6e491c1-8d41-dc12-a743-976ca04f1675.png)

## なぜVision API Product Searchなのか

Vision API Product SearchはGoogle Cloudで提供されている、視覚的に類似した作品群をランク付きリストで返却してくれるサービスです。

このサービスを選んだ理由としては、「あなたにおすすめのアート作品」に表示したかった作品毎の類似画像の情報を手軽に取得することがでるからです。

Vision API Product Searchで画像の類似度を取得する際に使用されるモデルはGoogleが既に用意してくれているため、こちらで用意する必要はありません！
導入はざっくり書いてしまえば、インポート用のCSVをしてデータを流し込み、Google Cloudが提供している各言語用のクライアントライブラリで画像を渡すだけです。

検索体験向上を目的とした開発を繰り返す中で、素早く実装してユーザーの反応を見ることは非常に重要で、TRiCERAのプロダクトチームの開発リソース状況とこのサービスでできることが非常にマッチしていました。

また、この機能開発当時Gogoleのスタートアップ支援プログラムに選ばれていたことで、Google Cloudのクレジットが無料で利用できたことも要因の一つです。
Google Cloudの粋な計らいに本当に感謝したいです。

## **機能の効果の分析**

リリース後、ページセッション数が平均で約1.5倍に増加し、ページセッションの増加に伴い、平均セッション時間も向上しました。これは、ユーザーがサイト上で過ごす時間が長くなり、より多くの作品を見て回るようになったことを意味しています。

この変化は、ユーザーが自分の好みに合った作品を見つけやすくなったこと、また、新たな発見をする機会が増えたことに起因しています。視覚的な類似性に基づく推薦システムは、ユーザーが知らない新しい作家やスタイルに出会う機会を提供し、その結果、ユーザーがサイト上での探索を続ける動機付けを強化しました。

## まとめ

「あなたにおすすめのアート作品」機能は、Google CloudのVision API Product Searchを活用することで、ユーザーの検索体験を大幅に向上させることに成功しました。
この機能は、ユーザーがサイト上でより多くの時間を過ごし、新たな作品との出会いを楽しむきっかけを提供しています。今後も、TRiCERAのプロダクトチームはユーザーの検索体験をさらに向上させるために、新たな技術とアイデアを積極的に取り入れていきます！
論文管理にZoteroとObsidianを活用し始めました

## ZoteroとObsidianで何ができるのか？

皆さんは論文管理をどのように行なっていますか？

私はこれまで、ブックマークをフォルダごとにまとめる、という悪行を行ってきました。

しかし最近、カレンダー、メモ、Todo全てobsidainでまとめるようになりました。
これに伴い、論文もobsidianでまとめてしまいたい！　と考え今回の行動に至りました。

# 本記事の内容

本記事では、obsidianとZoteroの連携の方法を簡単に紹介します。
この連携に関する日本語の記事が少なかったためです。
大筋は英語のこちらの記事を参考にして下さい。
https://medium.com/@alexandraphelan/an-updated-academic-workflow-zotero-obsidian-cffef080addd　

日本語で進める上で詰まったところのみ記述させて頂きます。

# 私が詰まった最大にして唯一の問題　
![スクリーンショット 2024-04-16 14.23.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631067/893911a5-c8c0-538b-f57f-b1eb5126843e.png)

私が行いたかったのは、Zoteroに追加した論文をobsidianでも閲覧し、メモを残すことです。
そのため、プラグインを使って論文の内容をobsidianに追加します。
その際必要なのが
「import Formats」　の設定です。

ここで論文やその画像をobsidianのどこに出力するのか設定します。
最も重要なのは、「Bilbiography Style」です。
ここではご自身がよく読む論文のスタイルを選択する必要があります。
さらに、obsidianで指定する　Bilbiography Style　と、Zoteroの「環境設定」　「エクスポート」の中にある「アイテムのフォーマット」こちらをきちんと揃える必要があります！

これさえ上手くいけば、あとは大丈夫です。
![スクリーンショット 2024-04-16 14.28.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631067/328d4553-01c6-4ec0-3d8a-691ed565164a.png)

#　まとめ
ZoteroとObsidianを活用して、論文の内容をまとめることができるようになりました。
また、テンプレートに通称「落合フォーマット」を導入したりすれば、より論文の内容を血肉にできることと思います。

ここまで、ご覧頂きありがとうございました。

# 参考文献
https://garden.matsuuratomoya.com/%E8%AB%96%E6%96%87%E3%81%AE%E7%AE%A1%E7%90%86

https://medium.com/@alexandraphelan/an-updated-academic-workflow-zotero-obsidian-cffef080addd

https://www.hosimitu.com/2024/04/1322-23191.php
element in your flow has validation error



+ [Getting Flow Error : element in your flow has validation error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8h5HSAR)

:::note
Well, I found the issue and able to proceed further in my flow.

For anyone else if facing same issue, please check all variable for error.

In my case I have defined one variable which has some error, though I was not using this avriable anywhere in my flow but I have not deleted also (my bad), due to that it was throwing error when trying to use apex action.

Once I deleted errorneous variable its staretd working.

さて、問題が見つかり、フローをさらに進めることができました。

他の人も同じ問題に直面している場合は、すべての変数にエラーがないか確認してください。

私の場合、エラーのある変数を 1 つ定義しましたが、フロー内のどこにもこの変数を使用していませんでしたが、削除もしていませんでした（悪い）。これは、apex アクションを使用しようとするとエラーがスローされていたためです。

エラーのある変数を削除すると、started が機能します。
:::
（JSPsych不要）生PHPと生JavaScriptで書く心理実験刺激入門

# JSPsych?そんなもの知りません（でした）

生PHPと生JavaScriptを習得した方にとっては、ライブラリに頼らない方が早く心理実験刺激を作成できるのではないでしょうか？
また、JSPsychを使ってみたものの、痒いところに手が届かないと感じてた方もいらっしゃるかと思います。

そんな人のために、生PHPと生JavaScriptで作成した心理実験刺激の例を作成しました。
自由にご活用ください。

取り上げているのは、映像刺激に対する評価実験です。
後輩ちゃんが不要なファイルをあげたりあげなかったりしていますが、お気になさらず。

https://github.com/Hoboki/russell-evaluation

PHP7系が入っていれば動作しますが、今回は簡単にMacOSでのDockerを用いた環境構築について説明します。

1. Docker Desktopのインストール
    https://docs.docker.com/get-docker/

1. コードの引用、コンテナ立ち上げ
    Terminalで以下を実行
    ```bash
    cd ~/Documents
    git clone https://github.com/Hoboki/russell-evaluation.git
    cd ~/Documents/russell-evaluation
    docker-compose up -d
    ```
    
1. README.mdに従って*.example*を.exampleなしのファイルにコピー

1. ブラウザで`localhost:8000`を検索。被験者のログインページが出てきたら成功！

# JSPsychを使わないことのデメリット
今のところ思いつかないので、思いつき次第更新します！（コメント待ってます）
CICDとは？〜jenkinsのサイトを参考に〜

# 経緯
以前[Jenkinsとgithub actionsの違い](https://qiita.com/ponponnsan/items/94284c9764f63ba6fa7f)について調べていたところ、CICDの説明が[ここ](https://cloudbees.techmatrix.jp/jenkins/)のサイトにわかりやすーく書かれていたため、自分の学習も含め、改めてCICDとは何かまとめてみようと思いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159060/990fd1d3-bb66-e4b7-f4a0-f2ad023e401b.png)

# CICD(継続的インテグレーション/継続的デリバリー&デプロイ)
ソフトウェアのリリーススピード向上を目的としたソフトウェア開発の手法です。頻繁にビルドやテストを実行します。

一般的には、コードがgithubなどにコミットされたタイミングで、ビルドプロセスやリリースプロセスを自動実行するように構成します。

コミットされるたびに実行されるため、エラーがあればすぐコミットした開発者にフィードバックされ、影響範囲の小さいうちにバグの発見と修正が可能となります。

自動でプロセスが実行されるため、人手によるミスや、操作のばらつきが少なくなります。

# CI(継続的インテグレーション)
開発者が書いた新しいコード(開発ブランチ)とメインブランチを頻繁に統合するプロセスです。

githubのmergeがそれにあたります。

一回のコミットでの変化量を小さくして頻繁にマージすれば、問題の発見が早くなりますし、対処も楽になります。

これは切るチケットの範囲も適切か問われてきますね。

問題発見の余分な負担を小さくするために、自動化されたテストを行います。

# CD(継続的デリバリー)
CIを延長して、単体テストだけでなく、結合テストなども自動的に行い、新しい変更がリリース可能であることを保証するプロセスです。

このプロセスを経た成果物はいつでも本番環境にデプロイすることができます。

CDが行う代表的なものは以下のとおりです。
- リリースノートの作成
- ソフトウェアのパッケージング
- テスト環境へのデプロイ
- 機能要件、非機能要件の充足を確認する包括的なテスト

## 継続的デプロイメント
CDをさらに延長して、リリース可能であることを保証されたソフトウェアを実際に本番環境にデプロイするプロセスです。

このプロセスでは確実にデプロイが実行されるように配慮された実行環境のリソースを構築、設定、管理し、万が一の時は、アプリケーションの状態を元に戻すことが自動的に行われます。

# 最後に
結構雰囲気で使っていたCICD、調べてみれば

**適切なチケットを切って、gitのコミット、マージからテスト、ビルド、デプロイまでを自動で行おう！楽しよう！** というものでした。

適切なチケットを切るのが一番難しいんですけどね笑

この記事がお役に立てれば幸いです！！

# 参考文献

https://cloudbees.techmatrix.jp/jenkins/
XCodeで謎エラー error: accessing build database "/Users/…/XCBuildData/build.db": no more rows available

## XCodeで謎エラー

その名の通り、XCode15.3で謎エラー発生。
Mac使いの人にはなじみがあるものなのかもしれないけど、ググっても解決方法出てこなかったからメモ代わりに記事を書いておく

`error: accessing build database "/Users/…/XCBuildData/build.db": no more rows available`

が出て、突然XCodeがビルド通らなくなった。
それまでは全然普通に通ってたのに、何回か cordova platform rm ios と add ios を繰り返すうちに、余計に……。
うちのアプリ、Cordovaやさかい、#Cordovaつらい 案件かと思ったけど、そうでもなかった。

XCode上部メニューの
Product > Clean Build Folder

これで直った。
誰かの訳に立てば。
Experience Cloud コミュニティユーザーは Experience Cloud 上で Chatter グループを共有できますが、Salesforce 内部の Chatter グループは共有できないと思います。



+ [Adding community user to a new public group receiving and getting internal error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bLIGl)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f6825e22-c037-59f3-f394-45eb94e7bba6.png)

I think Experience Cloud community users can share Chatter groups on Experience Cloud, but not Salesforce internal Chatter groups.

I think the specifications are probably the same for public groups.

Experience Cloud コミュニティユーザーは Experience Cloud 上で Chatter グループを共有できますが、Salesforce 内部の Chatter グループは共有できないと思います。


おそらく公開グループでも仕様は同じだと思います。


Community Groups (Chatter) cannot share across internal and external users (Lightning Experience, Experience/Community Cloud). Public Groups are primarily designed for internal user licenses (role-based licenses) so Customer Community Plus (CC+) and Partner Community (PC) licenses will work, but Customer Community (CC) does not.

コミュニティグループ (Chatter) は、内部ユーザと外部ユーザ (Lightning Experience、Experience/Community Cloud) 間で共有できません。パブリック グループは主に内部ユーザー ライセンス (役割ベースのライセンス) 用に設計されているため、カスタマー コミュニティ プラス (CC+) およびパートナー コミュニティ (PC) ライセンスは機能しますが、カスタマー コミュニティ (CC) は機能しません。

You can only add role-based licensed users to public groups. So if your user has a Customer Community or Customer Community Login (or some other non-role-based license), you cannot add them to public groups.

ロールベースのライセンスを付与されたユーザーのみをパブリック グループに追加できます。したがって、ユーザーがカスタマー コミュニティまたはカスタマー コミュニティ ログイン (またはその他の非ロールベースのライセンス) を持っている場合、そのユーザーをパブリック グループに追加することはできません。

You will need to do the following:

1. Create the chatter group in the community
2. Ensure the internal users are members of the community AND that chatter group
3. Have the internal users switch over to the community, navigate to the chatter group
4. Make a post to that chatter group from within the community, and ensure the visibility is not set to Internal ([Organization Name] only), I think it would be set to All Users with Access or something similar.

# 類似

+ [I am trying to add a partner user to a group on our Salesforce for him to view files attached to records.It comes up with a insufficient access rights on cross-reference id.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bLS6PSAW)

# 回避策

+ [カスタマーユーザーとChatterグループについて](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ajuTz)

:::note
エクスペリエンスクラウドとは関係なく、顧客のメールアドレスを用いてChatter専用ユーザーを作りChatterグループに招待できる機能です
:::
Azure DevOpsのWikiでページ内リンク

https://learn.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#links

セクション名が

```markdown
# Secion Name
```

だった場合、英文字を小文字に、空白を`-`にする

```
[Secion Name](#section-name)
```

---

セクション名にピリオドを含んでいる場合

```markdown
# 1. はじめに
```

は、`%`＋ピリオドのhex表記

```markdown
[はじめに](#1%2e-はじめに)
```

になる。
ピリオド以外の記号も（たぶん）同様の扱い。
レポート UIからエラーの判断を行う

[レポートのまとめに戻る](https://qiita.com/Keiji_otsubo/items/9c883d1e4bf0df549a2a)

+ [レポート、ダッシュボードを開いた時のエラー](https://qiita.com/Keiji_otsubo/items/acfb1e49d3ece31a0e82)

+ [レポートにてグルーピングを行った際の行の表示の制御方法](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bLKe3)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f9adf98b-c9a8-517b-430a-405386fbf532.png)

:::note
内容を見た限りですが、

レポートタイプは子レコードの有無を問わない作りになっている
Forecast項目は子レコードの項目になっている
という場合に同じような動作になるので、この作りになっているのではないかと思います。

上記の場合であれば、クロス条件で「子レコードが関連する親レコード」を追加すると目的の状態になるかと思われます。


+ クロス条件の設定をしても変化はなかったのですが、レポートタイプの設定で 少なくとも 1 つの関連レコードが存在する に変更したところ希望の表示となりました。
:::


# ブラウザの問題

+ [レポートを開いても一部ユーザーのみ演算子がうまく表示されない事象が起きています。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007akSmn)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/017cce2d-594e-29ba-b2e5-b4190a289e2a.png)

+ [ダッシュボード検索条件／次の値の間が表示されない](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epoyySAA)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/86fb5997-e90e-22e5-935b-45daacab3485.png)

:::note
キャッシュクリア、シークレットウィンドウでは状況変わらずだったのですが、
ログインし直したら出現しました。。
:::

# 項目がないというエラー

+ [項目を選択して挿入をクリックすると、項目のAPI参照名＋:sumなどの値が関数に挿入されます。検証をすると、その値は正しくないと出てきます。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ig672)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/13a6baaf-bf20-3d75-93ba-87a67961c020.png)

:::note
エラーメッセージが誤解を招きますね。実際にはSUMという関数が無いと思います。

以下の場合だったら AMOUNT:SUM というように　項目名の後に:SUMが続く形になると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4fa9f793-30fe-a5d3-871c-22d1981f7704.png)
:::
Flutter環境構築のためのCocoaPods・Rubyのダウンロード

Flutterでアプリを実際に動かしたいが、runしてもchromeアプリさえ表示されない。そのためにCocoaPodsというモジュールのインストールが必要だったのだが、2時間ほど手こずったのでメモを残しておく。

# cocoapodsのインストール、でもできない
公式サイトを参考に、CocoaPodsのダウンロードを試みる。

https://guides.cocoapods.org/using/getting-started.html

```sh
sudo gem install cocoapods
```

しかし、cocoapodsがインストールできない。
Rubyがダウンロードできていないとダメなようです。

## Rubyのインストール

[ruby install](https://gorails.com/setup/macos/14-sonoma)のサイトを参考にしながらRubyをインストール。

```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

```sh
cd
git clone https://github.com/excid3/asdf.git ~/.asdf
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.zshrc
echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.zshrc
echo 'legacy_version_file = yes' >> ~/.asdfrc
exec $SHELL
```
ASDFというバージョンマネージャーを使用して、ruby 3.3.0をダウンロード。
```sh
asdf install ruby 3.3.0
asdf global ruby 3.3.0

# Update to the latest Rubygems version
gem update --system
```
ここでエラーが表示されました。
エラーメッセージからyaml.h ファイルが見つからないことが原因で psych 拡張モジュールが構築できていないようです。

### yaml ライブラリのインストール
```sh
brew install libyaml
```

以下の通りダウンロードができました。
```sh
libyaml 0.2.5 is already installed and up-to-date.
```

続いてRubyのインストールに再挑戦。
```sh
asdf install ruby 3.3.0
```

正しくダウンロードできているか、Rubyの場所とバージョンを確認。無事ダウンロードできているようです。
```sh
which ruby
#=> /Users/username/.asdf/shims/ruby/3.3.0
```
しかし、rubyのバージョンを確認すると、別のバージョンが表示されました。2年ほど前にダウンロードしていますね。
```sh
ruby -v
#=> ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.x86_64-darwin23]
```
以下のコマンドで使用するrubyのバージョンを指定します。
```sh
rbenv global 3.3.0
```
## rbenvのインストール
まだrbenvをインストールをしていなかったので、インストールと初期化を以下で行いました。
```sh
# ダウンロード
brew install rbenv
# 初期化
eval "$(rbenv init -)"
```
ダウンロードできるRubyのバージョン一覧を表示
```sh
rbenv install -l
```
rbenvでRuby最新版をダウロード
```sh
rbenv install 3.3.0
```
以下のようにバージョンを確認すると、無事最新版の3.3.0に更新されていました。
```sh
ruby -v
#=> ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin23]
```

そして待ちに待ったcocoapodsのインストールへ！

# 【再挑戦】 cocoapodsのインストール
```sh
sudo gem install cocoapods
```
無事インストールが終了しました。
再びFlutter doctorを実行。
```sh
flutter doctor
```

あれ、まだエラーが、、
```sh
# Xcodeのコマンドラインツールをインストールする
sudo xcode-select --install
# Xcodeを選択する
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
# 初回起動時にXcodeが必要な追加のセットアップを行う
sudo xcodebuild -runFirstLaunch
```
以下のように無事Xcodeとの接続ができました。
```sh
flutter doctor
#=>[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
```
まだMacOSやAndroidでは使用できませんが、runするコットでChrome上では無事表示されるようになりました！
```dart
import 'package:flutter/material.dart';

void main() {
  const print_helloworld = MaterialApp(
    home: Scaffold(
      body: Center(
        child: Text('Hello, world'),
      ),
    ),
  );
  runApp(print_helloworld);
}

```


## 【追記】CocoaPodsが正しくプロジェクトに設定できていない時
### 1. 上記の方法でcocoapodsをインストール
### 2. podsの初期化

プロジェクトディレクトリの中のmacosディレクトリへ移動。

```sh
cd path/to/your/flutter/project/macos
pod install
```

### 3.0 プロジェクトのクリーン
```sh
cd path/to/your/flutter/project
flutter clean
flutter pub get
flutter run
```
javascriptフレームワークの環境構築

##### この記事では主にHomebrewを使用した環境構築方法になります。

#### node.jsの環境構築
```
# node.jsのバージョン管理のためのnodebrewをインストール
$ brew install nodebrew

# nodebrewのバージョン確認
$ nodebrew -v

# node.jsのインストール
$ nodebrew install-binary stable


## 下記のようなエラーが出た時は、、、、
Fetching: https://nodejs.org/dist/v20.3.0/node-v20.3.0-darwin-arm64.tar.gz
Warning: Failed to create the file
Warning: /Users/username/.nodebrew/src/v20.3.0/node-v20.3.0-darwin-arm64.tar.gz
Warning: : No such file or directory

# エラーの場合は下記のコードを実行後に最インストール
$ mkdir -p ~/.nodebrew/src

# インストール確認
$ nodebrew ls

$ node -v
```

#### Vue.jsの環境構築

```
# vueのインストール
$ npm install vue@3

#Vue.jsを用いた新しいプロジェクトを作成
$ npm init vue@3

#この時、以下のように表示されたら y を入力して追加のパッケージをインストールしましょう。
$ npm init vue@3
Need to install the following packages:
  create-vue@3.7.0
Ok to proceed? (y)

# プロジェクト設定が必要（各プロジェクトごとに変更する。以下は筆者の場合）

    Project name: … プロジェクト名
    Add TypeScript? … No
    Add JSX Support? … No
    Add Vue Router for Single Page Application development? … No
    Add Pinia for state management? … No
    Add Vitest for Unit Testing? … No
    Add an End-to-End Testing Solution? › No
    Add ESLint for code quality? … Yes
    Add Prettier for code formatting? … Yes

# 下記のコマンドをそれぞれ実行
$ cd frontend
$ npm install

# npm run 系のコマンドは、 package.json に記述されたコマンドを実行するコマンドです。
# npm run format は、コードのフォーマットを行うコマンドです。
$ npm run format
$ npm run dev

# 以下コマンドでサーバー実行
npm run dev
```



## ボーナスチャプター

#### ruby on railsの環境構築

- 筆者が現在取り組んでいるプロジェクトでバックエンドをrailsをしようするので、環境構築手順をついでにメモしておく
- rbenvをしようするのでそのインストールも済ませておく

```
# rubyのインストール（バージョンはプロジェクトに応じて）
$ rbenv install 3.1.4

# インストールできるバージョンの確認ができる
$ rbenv install -l

#バージョンを固定する
$ rbenv local 3.1.4

# rubyのバージョン確認
$ ruby -v

もしもrubyのバージョンが切り替わらない時はpathが通ってない可能性がある。
rdenvのrubyではなくてシステムでデフォルトで入っているrubyが呼ばれているかも、、

# 確認方法(/usr/bin/rubyの場合はシステムデフォのrubyが呼ばれている)
which ruby

.zshrcのファイルを変更して対応しました
export PATH="~/.rbenv/shims:/usr/local/bin:$PATH"
eval "$(rbenv init -)"
# 変更を反映
$ source ~/.zshrc

```
これでうまくいったようです。


#### Railsのインストール

 さてここからRailsをインストールしていくわけですが、その前にRailsのことを少しおさらいしましょう

 [参考文献]： [Gemfile?bundler?Rails開発するなら理解しておきたいgem管理の基礎知識](https://nishinatoshiharu.com/fundamental-gem-knowledge/)

```:ターミナル
# gemのインストール
$ gem install bundler -v "2.3.15"

# gemfileの作成
$ bundle init
```

```ruby:Gemfile
# railsのインストールしたいバージョンを指定
source 'https://rubygems.org'

gem 'rails', '~> 7.0.5'

```

```:ターミナル
# bundleのインストール先を指定（まとめやすくするため）
$ bundle config set path '.bundle'

# Bundle complete!が出れば成功
$ bundle install
```

インストールした Gem をコマンドで使用する際は、bundle exec を付ける必要があるので注意してください。


[参考文献]： [bundle execって必要なの?](https://qiita.com/d0ne1s/items/fa2dafcee02e963fe997)


```
$ bundle exec rails -v

# 筆者はフロントエンドは Vue.js を使用しているため、Rails の役割は API サーバーとしてのみ使用します。そのため--api オプションを付けて実行しています。
$ bundle exec rails new アプリ名 --api --skip-bundle --skip-test


# Rails プロジェクトに必要な Gem のインストール
$ cd backend
$ bundle install

# サーバー起動
$ bundle exec rails s
```


自分用のメモみたいなものなので書き方が雑になりました。
あー、キュビズム作品の定量的な特徴知りてぇーー

# はじめに

今回使用したGoogle Colabのリンクは[こちら](https://drive.google.com/file/d/1K2kKQ6wJcERnzMMC_hIxTey_y3wR5dfQ/view?usp=sharing)

皆さんは、キュビズム（Cubism）という芸術運動と、その運動の中で使用された絵画の表現手法を知っているでしょうか？
キュビズムとは[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A5%E3%83%93%E3%82%B9%E3%83%A0)によると、
>キュビズム（仏: Cubisme; 英: Cubism「キュビズム、キュービズム」、立体派）は、20世紀初頭にパブロ・ピカソとジョルジュ・ブラックによって創始され、多くの追随者を生んだ現代美術の大きな動向である。多様な角度から見た物の形を一つの画面に収めるなど、様々な視覚的実験を推し進めた。

とのことです。
キュビズムの絵画は幾何学的な模様を多く含む、特徴的な見た目をしています（図1）。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666665/43f16b01-99a3-f85d-1e1e-fca94e2999e1.jpeg
" />

図１　ゲルニカ, パプロ・ピカソ

この記事ではみなさんが「明日までにキュビズムの画像を検知しなくちゃ！」という場面に遭遇したときに[^1]、どうやって普通の絵画とキュビズムの絵画を識別するのか、また、キュビズムの絵画にはどのような特徴があるのかを考えていこうと思います。

# 実践

今回、下記のように普通の絵画とキュビズムの絵画を5枚ずつ解析に使用しました（図2）。解析を簡単にするために、前処理として画像のサイズを全て正方形に揃え、グレースケールに変更しました[^2]。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666665/7de0dd27-8cbc-0ad5-230b-354d3431f814.png" />

図2　使用した絵画の画像データ（上段：普通の絵画、下段：キュビズムの絵画）

さて、画像の解析をしようとなったら、とりあえず画像をフーリエ変換して、空間周波数を見てみましょう。
空間周波数が何かについては、[このサイト](https://www.clg.niigata-u.ac.jp/~medimg/practice_medical_imaging/imgproc_scion/5fourier/index.htm)などを参考にしてください。

図3が空間周波数成分の強度を可視化したものです。キュビズムの画像ではやや低周波数の強度が弱いように見えますが、人目ではそこまで顕著ではなさそうですかね。
図4は、各絵画の平均パワースペクトラムを可視化したものです。こちらは少し特徴的で、下段のキュビズムの絵画のほうが中心から離れた領域（高周波数領域）でも明るく、輪郭や端が多く含まれていることが推測できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666665/7135ee3d-6e75-dfe2-0be6-8171fc9513b5.png" />

図3　各絵画の空間周波数成分の強度

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666665/c1aca9f3-c426-1fe5-9073-b71aa3f1c800.png" />

図4　各絵画の平均パワースペクトラム

全体の傾向を調べるために、空間周波数を低周波、中周波、高周波の3つの帯域にわけ、普通の絵画全体とキュビズム絵画全体での傾向を調べてみました（図5）。やはりキュビズム画像は中周波や高周波成分にも多少強度が出ています。これはピクセル間の急激な変化（輪郭や端）の多さが反映されているのかと思われます。一方、普通の絵画では低周波成分が幅広い強度で出ていますね。こちらは逆に、ピクセル間の滑らかな変化が多いことが反映されているのでしょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666665/871d65cc-ce3a-6c01-ad4e-54543400e0b8.png" />

 図5　普通の絵画とキュビズムの絵画での周波数帯域ごとの強度の分布


さて、人の目なんて対して信用できないものなので、機械学習の力を借りましょう（機械学習と聞くとCNNやTransformerなどの深層学習を思い浮かべる人も多いかもしれませんが、今回は~~データをたくさん集めるのが面倒なので~~解釈性を高めるために古典的な手法を使います）。

空間周波数から[kmeans](https://qiita.com/g-k/items/0d5d22a12a4507ecbf11)クラスタリングを行い、その結果を2次元の[主成分空間](https://qiita.com/NoriakiOshita/items/460247bb57c22973a5f0)に射影した結果が図6です。

**はい、機械学習でも全然誤分類起こしてますね。**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666665/f46e20a9-ec67-0fd0-fb9d-2fc75bfc8f9f.png" />

図6　空間周波数によるkmeasクラスタリング結果の主成分空間上での可視化

# まとめ
キュビズム画像のほうが高空間周波数成分の強度が強い傾向があることがわかりましたが、案外きれいなクラスタリングはできませんでした。正直余裕で違いが出ると思っていましたが、意外と難しかったですね。

もしかしたら次回、
**あー、深層学習でのキュビズム分類してぇーー**
という続編を作るかもしれません[^3]。ご覧いただきありがとうございました。


[^1]:人生には思いもよらない場面に遭遇するときがあります。
[^2]:「サイズや色を変えたら画像の特徴も変わるでしょ？」というロジカルハラスメントはお控えください。
[^3]:絵画の学習データ作成には[このあたり](https://qiita.com/dzbt_dzbt/items/10168ee503645e105faf)が使えそうです。
ChromeでのSubmit二度押し防止対策　苦肉の策

# Chrome固有の問題
こちらの記事に詳しく書かれているのですが，ChromeだとWindows版もAndroid版もButtonタグにdisabledをつけてしまうと，submit後であってもPOST送信されなくなってしまいます。

https://qiita.com/limithand/items/bcec6d519c2a2a45e9c2

上の記事に「解決済み」とあった方法も，うまく動かなかったため，試行錯誤の上，このようにして動かしてみました。

```javascript:hoge.js
var btnLock = 0;

function on_submitonce(){
    let targetButtons = Array.from(document.querySelectorAll('.btn_once'));
    if(btnLock !== 0){
        window.alert("2度押しは無効です");

        let i = 0;

        targetButtons.forEach(function () {
            targetButtons[i].disabled = true;
            i++;
        });

        return false;   //ロックされていたらキャンセル
    } else {
        btnLock++;
        let i = 0;

        targetButtons.forEach(function () {
            targetButtons[i].classList.add("disabled");
            i++;
        });
    }
}

document.getElementById('form').addEventListener( 'submit', on_submitonce );
```

```html:foo.html
<form id="form" .....>
..
..
<button type="submit" class="btn_once">
</form>
```

初回のボタン押下で，Bootstrapのdisabledクラスをaddして対応。当然，見た目が変わってもsubmitはできてしまします。
そこで，2度目に押下されたときは disabledをつけてPOST送信されないようにしてます。

もう少しスマートなコードにできたらいいのですが…。
「タネ カ アトゥイ アヌカㇻ ルウェ ヘ アン」をアイヌ語Universal Dependenciesで解析する

[昨日の記事](https://qiita.com/KoichiYasuoka/items/966ec19eeaabc69a9440)の例文に対応する「タネ カ アトゥイ アヌカㇻ ルウェ ヘ アン」を、[deberta-base-ainu-ud-goeswith](https://huggingface.co/KoichiYasuoka/deberta-base-ainu-ud-goeswith)の助けを借りて、アイヌ語Universal Dependenciesで解析してみた。Google Colaboratoryだとこんな感じ。

```
!pip install transformers deplacy
from transformers import pipeline
nlp=pipeline("universal-dependencies","KoichiYasuoka/deberta-base-ainu-ud-goeswith",trust_remote_code=True,aggregation_strategy="simple")
doc=nlp("タネ カ アトゥイ アヌカㇻ ルウェ ヘ アン")
import deplacy
deplacy.serve(doc,port=None)
```

私(安岡孝一)の手元では、以下の結果が出力された。

```
# text = タネ カ アトゥイ アヌカㇻ ルウェ ヘ アン
1	タネ	tane	ADV	副詞	_	5	advmod	_	_
2	カ	ka	ADP	副助詞	_	1	case	_	_
3	アトゥイ	atowi	NOUN	名詞	_	5	obj	_	_
4	ア	a=	PART	人称接辞	_	5	nsubj	_	SpaceAfter=No
5	ヌカㇻ	nukar	VERB	他動詞	_	6	acl	_	_
6	ルウェ	ruwe	NOUN	形式名詞	_	8	nsubj	_	_
7	ヘ	he	ADP	副助詞	_	6	case	_	_
8	アン	an	VERB	自動詞	_	0	root	_	SpaceAfter=No
```

![ain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/cf0ba323-7987-b8ee-786a-fbeb7e3d1296.png)

「アトゥイ」のLEMMAが間違っている(atowiではなくatuyが正しい)ものの、その点を除いては、品詞付与も係り受け解析も完璧だ。ただ、私が見る限り、この例文においては、アイヌ語とイテリメン語でかなり言語構造が違う。北千島アイヌ語と南部イテリメン語の間では言語接触があったらしい(cf. 村山七郎『北千島アイヌ語』吉川弘文館、1971年3月)が、残念ながらその痕跡は、少なくともこの例文には見当たらない。その点からすると、アイヌ語Universal Dependenciesの知識は、現時点では、イテリメン語への転用は難しそうである。
[Google Slides API(V1)] Javaでプレゼンテーション内のページのサムネイル画像を取得する

Google Slides API V1(Java)を使用して、
プレゼンテーション内のページのサムネイル画像を取得する方法
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Slides API(V1)] JavaでSlides APIを使う](https://qiita.com/doran/items/9c0917d03d394bf0d3d7)
を参照ください。
:::

|No|||目次|
|---|---|---|---|
|1|||[サムネイル画像を取得](#1-サムネイル画像を取得)|
||1||[スコープ](#11-スコープ)|
||2||[実行](#12-実行)|
||3||[レスポンスの内容](#13-レスポンスの内容)|

## 1. サムネイル画像を取得
プレゼンテーション内のページのサムネイル画像を取得します。

### 1.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
SlidesScopes.DRIVE
SlidesScopes.DRIVE_FILE
SlidesScopes.DRIVE_READONLY
SlidesScopes.PRESENTATIONS
SlidesScopes.PRESENTATIONS_READONLY
```
[⧉[Google Slides API(V1)] JavaでSlides APIを使う(2.2. Slidesインスタンスを取得)](https://qiita.com/doran/items/9c0917d03d394bf0d3d7#22-slidesインスタンスを取得)
でスコープを指定してください。

### 1.2. 実行

```java
public static void main(String[] args) throws Exception{
    Slides slides = getSlides();
    Slides.Presentations presentations = slides.presentations();
    Slides.Presentations.Pages pages = presentations.pages();
    
    Slides.Presentations.Pages.GetThumbnail get = pages.getThumbnail("プレゼンテーションID", "ページID");
    
    Thumbnail res = get.execute();
    System.out.println(res);
}
```
#### 1.2.1. HTTPリクエスト
GET:　https:\//slides.googleapis.com/v1/presentations/{プレゼンテーションID}/pages/{ページID}/thumbnail
が実行されます。

#### 1.2.2. クエリパラメータ
クエリパラメータはありません。

### 1.3. レスポンスの内容
#### Thumbnail
|メソッド|戻り値|説明|
|---|---|---|
|getWidth|Integer|サムネイル画像の幅（ピクセル単位）|
|getHeight|Integer|サムネイル画像の高さ（ピクセル単位）|
|getContentUrl|String|サムネイル画像URL|

<br>
<br>
おしまい。。
SupabaseでCountを取る

```javascript
supabase().
    select('count(*)')
    .from('hoge')
    .then((res) => {
        console.log(res)
    })
```
こんな感じでいけるだろうと書いてみるとSELECT句がおかしいよーというエラーを吐かれた。少し調べてみると、selectの引数にオプションを渡せることがわかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3746801/e3202360-f8ce-f3c7-c6f4-2ccee79831c0.png)
https://supabase.com/docs/reference/javascript/select

`count`を指定するとどの様に算出するかを決められる。
- exact: 計算は遅いけど正確な値を算出
- planned: おおよその値だがpostgresの統計情報を使って速く算出
- estimated: 少数であればexactとして機能、量が多くなるとplannedとして機能

`head`を`true`にするとresultに`data`を含まない。（実装していてわかったが、dataの代わりにcountが出現する。）

今回の用途としてはページングの際の最大量を取りたいので`exact`を指定して正確な値を取得。レコード自体は別のクエリで取得するため`head`は`true`を設定。

```javascript
supabase().
    select('*', {count: 'exact', head: true})
    .from('hoge')
    .then((result) => {
        console.log(result.count)
    })
```

こんな感じでCountが取れましたとさ。
Unityでandroidビルドを行う【2024年4月】

# Androidにswitchする
#### File - Build Settings をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/804bf874-45c7-0748-3a95-a13437e2d9a9.png)

#### Androidを選択してSwitch platformをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/a8c70d92-7424-af73-56a6-a2b06b7e9d0d.png)

# package名などを決める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/b043bb40-a3f0-b1cc-ed17-766869f358cd.png)

#### キーを作成してパスワードを入力する
Publishing Settingsの下の方
作成したキーはなくさないように保存してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/3a08b85c-5ee6-7acb-44cf-032d05d36e22.png)

# apk作成
#### buildボタンをクリックして名前を付けて保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/7b38f560-69fb-f76c-04b1-1a56b0ed8bd6.png)

apk作成後は、実機にいれて動作確認して問題なければGoogle Playの作業を行います

# ビルド時のエラー
```
Resource 'integer/google_play_services_version' not found in AndroidManifest.xml:42,
(See the Console for details)
```


google_play_services_versionが不要になったので、マニュフェストに記載さている
google_play_services_versionのmateの行の部分を削除
C:\(インストールした場所)\Assets\Plugins\AndroidAndroidManifest.xml
Accessでフォルダ単位でCSVを指定した期間でインポートする方法

```vb
Function ImportCSVFromFolder()
    Dim folderPath As String
    Dim csvFile As String
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim strSQL As String
    Dim startDate As Date
    Dim endDate As Date

    ' フォルダパスと期間を設定
    folderPath = "C:\path\to\your\csv\"
    startDate = #2023/01/01#
    endDate = #2023/12/31#

    ' フォルダ内のすべてのCSVファイルをループ
    csvFile = Dir(folderPath & "*.csv")
    Do While csvFile <> ""
        ' 接続文字列とSQLクエリ
        Set conn = New ADODB.Connection
        conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & folderPath & ";Extended Properties='text;HDR=YES;FMT=Delimited';"
        strSQL = "SELECT * FROM [" & csvFile & "] WHERE DateColumn >= #" & Format(startDate, "yyyy-mm-dd") & "# AND DateColumn <= #" & Format(endDate, "yyyy-mm-dd") & "#"

        ' レコードセットを開く
        Set rs = New ADODB.Recordset
        rs.Open strSQL, conn, adOpenStatic, adLockReadOnly

        ' Accessのテーブルにデータを挿入
        Do While Not rs.EOF
            DoCmd.RunSQL "INSERT INTO YourTable (DateColumn, OtherColumn) VALUES (#" & Format(rs!DateColumn, "yyyy/mm/dd") & "#, '" & rs!OtherColumn & "')"
            rs.MoveNext
        Loop

        ' クリーンアップ
        rs.Close
        Set rs = Nothing
        conn.Close
        Set conn = Nothing

        ' 次のファイルへ
        csvFile = Dir
    Loop
End Function
```
グループ化して操作を加える pandas

#複数のIDを有するdataframeがあり、時系列になっています。
経過の中にはそれぞれのIDに対し”開始”、”終了”といったイベント（経過）が記録されています。今各IDで開始から終了までの血圧を取り出したいどうすればよいでしょうか？まず、groupbyでグループ化し、それをdataframeにもどし…、わかりません(´;ω;｀)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426068/f48b3f17-9ff7-e26a-a8cd-d5d1135ff2e9.png)
ID	経過	血圧
1		90
1	開始	100
1		90
1		60
1	終了	70
1		90
2		100
2	開始	80
2		90
2		100
2		110
2	終了	90
2		80
3		120
3		110
3	開始	90
3		90
3	終了	110
3		120
3		90
3		130
access vbaでcsvを指定した期間でインポートする方法

```vb
Function ImportCSVData()
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim strSQL As String
    Dim startDate As Date
    Dim endDate As Date
    Dim pathCSV As String

    ' CSVファイルのパスと期間を設定
    pathCSV = "C:\path\to\your\csv\"
    startDate = #2023/01/01#
    endDate = #2023/12/31#

    ' 接続文字列とSQLクエリ
    Set conn = New ADODB.Connection
    conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathCSV & ";Extended Properties='text;HDR=YES;FMT=Delimited';"
    strSQL = "SELECT * FROM [yourfile.csv] WHERE DateColumn >= #" & Format(startDate, "yyyy-mm-dd") & "# AND DateColumn <= #" & Format(endDate, "yyyy-mm-dd") & "#"

    ' レコードセットを開く
    Set rs = New ADODB.Recordset
    rs.Open strSQL, conn, adOpenStatic, adLockReadOnly

    ' Accessのテーブルにデータを挿入
    Do While Not rs.EOF
        DoCmd.RunSQL "INSERT INTO YourTable (DateColumn, OtherColumn) VALUES (#" & Format(rs!DateColumn, "yyyy/mm/dd") & "#, '" & rs!OtherColumn & "')"
        rs.MoveNext
    Loop

    ' クリーンアップ
    rs.Close
    Set rs = Nothing
    conn.Close
    Set conn = Nothing
End Function
```
cscの作法 その493

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
comboboxの値で、DataGridViewに、フィルターをかけよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5b6c9c90-030a-2082-6263-ae382da2513d.png)


# サンプルコード

```

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Data;

class form1: Form {
	ComboBox comboBox1;
	DataTable dt;
	DataGridView gd0;
	form1() {
		Text = "select";
		ClientSize = new Size(400, 300);
		comboBox1 = new ComboBox();
		comboBox1.Location = new Point(120, 10);
		comboBox1.Size = new Size(100, 25);
		comboBox1.Items.Add("");
		comboBox1.Items.Add("赤");
		comboBox1.Items.Add("黄");
		comboBox1.Items.Add("紫");
		comboBox1.Items.Add("橙");
		comboBox1.Items.Add("緑");
		comboBox1.SelectedIndex = 0;
		comboBox1.SelectedValueChanged += comboBox1_SelectedIndexChanged;
		dt = new DataTable();
		dt.Columns.Add("id", typeof(int));
		dt.Columns.Add("Iro", typeof(string));
		dt.Columns.Add("Name", typeof(string));
		dt.Rows.Add(1, "赤", "りんご");
		dt.Rows.Add(2, "黄", "バナナ");
		dt.Rows.Add(3, "黄", "レモン");
		dt.Rows.Add(4, "赤", "トマト");
		dt.Rows.Add(5, "紫", "ぶどう");
		dt.Rows.Add(6, "橙", "みかん");
		dt.Rows.Add(7, "橙", "柿");
		dt.Rows.Add(8, "緑", "めろん");
		gd0 = new DataGridView();
		gd0.Location = new Point(20, 40);
		gd0.Size = new Size(350, 250);
		gd0.DataSource = dt;
		Controls.AddRange(new Control[] {
			comboBox1,
			gd0
		});
	}
	private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
		string str = "Iro = '" + comboBox1.SelectedItem.ToString() + "'";
		DataTable _newFilteredDataTable = dt.Select(str).CopyToDataTable();
		gd0.DataSource = _newFilteredDataTable;
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

以上。
Github Actions超入門

# はじめに

なんとなくgithubを使っていると、リポジトリの上の方にいるこいつ。
![actions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/70352a01-6896-1fe7-292a-8f86953b553b.png)

いつも目につくけど、一体なんなんだろう？

そう思いながら放置してきた方に向けたGithub Actionsの入門です。


## GitHub Actionsとは
GitHub Actionsは、Githubが提供しているワークフロー自動化ツールです。Githubのユーザーであればすぐに利用できます。

詳細はこちら...

https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions

色々書いてありますが、要はテストとかを自動でできちゃいます！という便利なものです。
なんだか難しそうですが...実は簡単に使えてしまうわけです。


## 前提

- Githubに登録しており、基本的な設定が完了している

今回は簡単なPythonのプログラムを例として用いるので、ローカルでPythonが実行できることが望ましいです。（実行結果などは下記で紹介していますのでPythonの実行環境がなくても問題はないです！）

## 手順

### 1. プログラムを用意する

まずはリポジトリを作成しましょう。
main.pyを作成します。

```python:main.py
import sys

def main():
    if len(sys.argv) > 1 and sys.argv[1] == "bye":
        print("Good Bye...")
    else:
        print("Hello World")

if __name__ == "__main__":
    main()

```

今回は上記のプログラムを例として扱います。
実行するとこんな感じです。

```bash
$ python main.py
Hello World

$ python main.py bye
Good Bye...

```

そのまま実行すると`Hello World`を出力し、引数で`bye`を指定すると`Good Bye...`を出力します。
とんでもなく雑ですが許してください。
動作が確認できたら保存してpushしておきます。


### 2. Actionsの設定をする

リポジトリの**Actions**に移動します。
![acsionspave.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/777f898f-d946-05cd-516e-65cc3515e3b2.png)

何やらいっぱいありますが、とりあえず全部無視して**set up a workflow yourself**をクリックします。

![yaml.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/1d2db728-0f05-fc27-bd65-bbfe1dd5bb10.png)

エディタが立ち上がりました！
下記のコードをコピペします。

```yaml:main.yml
name: Python application test

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python 3.x
      uses: actions/setup-python@v3
      with:
        python-version: '3.x'

    - name: Test with default argument
      run: python main.py

    - name: Test with argument 'bye'
      run: python main.py bye


```

**Commit change**しちゃいましょう！

ではActionsのタブに戻って見てみましょう！

何やら動いてますね。
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/806e3ff3-2b22-2f40-efc9-380f05cb78b8.png)

**Create main.yml**に行ってみます。
![build.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/252d1046-56c4-93bd-7361-b1b08e71cb9a.png)

**build**をクリックして...

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/7f4e1abe-7e89-a975-5670-c92ddcc8ce88.png)

Testの部分を開いてみると上手く実行できていますね！

これであなたはもうGithub Acionsを使えるようになってしまいました...

はい、とまあこんな感じで簡単な流れの紹介でした。
もっと興味がある方は、最初の方で紹介した公式のリファレンスを見ていただくのがいいかなと思います。
ブラウザ上で表示しているFigmaファイルをデスクトップアプリで開く

1.ブラウザFigmaの左上アイコンクリック
2.「デスクトップアプリで開く」をクリック
※ブラウザによっては「デスクトップアプリで開く」が表示されないので注意（Braveとか）

以前はURLコピペで開けたのにできなくなっていた。

:::note info
基本設定の中に「リンクをデスクトップアプリで開く」がある。
これにチェックを入れておけば常にアプリで開ける。
※この項目はブラウザ上でのみ表示される。
:::
【CISCO】Wirwesharkを使ったパケットキャプチャー設定について

# はじめに
通信障害やパケットエラーが発生した際にNW機器でパケットキャプチャーを取得する場面が時々あります。
NW機器でパケットキャプチャーを取得する方法はいくつかありますが、ここではにCatalystスイッチにミラーリング機能を実装し、WIRESHARKを使ったパケットキャプチャーの方法について記載いたします。
※ミラーリング機能：特定のインターフェースのデータをコピーして、別のインターフェース(ミラーポート)に流す機能。
# 前提
・パケットキャプチャーの取得対象の機器はCISCO機を想定
・PCにWIRESHARKをインストール済みであること
・NW機器のミラーポートにPCが接続されていること
# 構成
<img width="500" alt="IAM" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/e82c7f68-ca1f-e4eb-1c3d-b241c8b61fd3.png">

# やりたいこと
・Fa0/24のインターフェースのパケットをコピーしてFa0/12に流し、WIRESHARKが入っているPCでパケットキャプチャーする
※この構成の場合Fa0/12がミラーポートになります。
# CISCO機側の設定
入力コマンド
```
　Catalyst(config)# monitor session 1 source interface FastEthernet 0/24
　Catalyst(config)# monitor session 1 destination interface FastEthernet 0/12
```
■コマンドの説明
monitor session 番号：この番号を合わせることでsourceインターフェースで受信したトラフィックデータをdestinationインターフェースにコピーして流すことができます。
source interface：トラフィックデータをコピーしたいインタフェース
destination interface：コピーしたトラフィックデータを送るインターフェース(WIRESHARKが入ったPCを接続するインターフェース)
※source interfaceとdestination interfaceの設定を逆にしてしまわないように注意してください。

設定完了後show monitorコマンドなどで設定を確認してください。

# WIRESHARK側の設定
WIRESHARKを起動します
PC側の接続しているインターフェースを選択します
<img width="500" alt="IAM" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/ba1b2116-7e0e-4e9e-0026-b209d4deb230.png">
※インターフェースでトラフィックを受信できていると、インターフェースの右側に波形が出ます
対象のインターフェースをダブルクリックします。
するとそのインターフェースで受信しているトラフィックのパケットキャプチャー画面が出てきます
<img width="500" alt="IAM" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/22db0551-edc9-1f0e-c81a-52bd67302962.png">

パケットキャプチャーを停止するには、メニューから停止を選択します。
<img width="400" alt="IAM" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/d8032726-d6b4-66d2-bf82-a5505daf34bd.png">

パケットキャプチャーを再開するには、メニューから開始を選択します。
<img width="400" alt="IAM" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/2b9c0f74-0e08-eca3-b60f-6a1d9d293874.png">
パケットキャプチャー再開時にそれまでキャプチャしたパケットを保存するか聞かれます。
保存してから再開することも、保存せずに再開することも可能です。

※初回起動時は時刻表示が最初に流れたパケットからの経過時間になっていますので
必要に応じて「日時」などの表示に変更してください。

メニューから、表示→時刻表示形式を選択して変更ができます
<img width="500" alt="IAM" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/bbc6c112-c8ae-5467-5643-1cdec01f75be.png">

# まとめ
WIRESHARKでのパケットキャプチャーの取得方法について簡単にまとめました。
この記事では対象のインターフェースの全てのトラフィックを取得していますが、monitor sessionコマンドのオプションで、TX(送信)のみ、RX(受信)のみなどの特定の方向のトラフィックだけを取得することも可能です。
WIRRESHARKでは取得したパケットキャプチャーログから特定のデータをフィルターする機能や、パケットの流れを表示するフローグラフの機能などもありますので、別の機会で記載したいと思います。
【OpenAI Japan始動】と関連情報。


　どうも、カーブミラーです。

　今回は、OpenAIが、日本に支部を作った、という話と関連する情報についてです。APIやUIについてもあります。

:::note info
本記事は、ニュースだけで、
ChatGPTを使っておりません。
あしからず。
:::

　昨日（2024/04/15）の
　　15時に下記がポストされました。
[OpenAI アカウントによるポスト](https://twitter.com/OpenAI/status/1779754674242892014?t=HX6bialXcqFSClIjLiSd4A&s=19)

　それと同時に
　　OpenAI東京支社にて
　　　会見が開かれました。

　OpenAI Japan 始動
　・東京に新オフィス（アジア初）
　・日本市場に特化した
　　　GPT-4カスタムモデルの
　　　　提供を開始
　・日本語最適化モデルは
　　　既存モデルより
　　　　最大3倍の速度で動作
　　　　コスト効率も47％向上
　・すでに一部の企業に提供
　・なお、このモデルは
　　　数ヶ月以内に、APIで提供される。
[OpenAI 公式ブログ](https://openai.com/blog/introducing-openai-japan)
***
　OpenAIとは
　　関係なさそうで
　　　ある話です。

　Adobeが
　　ビデオ編集ツール「Premiere Pro」
　　　に生成AIを統合することを発表

　Fireflyシリーズに加わり、
　　OpenAI「Sora」、
　　「Runway」、
　　「Pika」も
　　　Premiere Proで
　　　　利用可能になるそうです。
　　　　　すぐに、ではないでしょう。

[利用者のポスト](https://x.com/shota7180/status/1779968261125554223?t=f7xgAjQJNpjHoLAj1wwJGw&s=03)
***
[OpenAIからバッチAPI登場](https://x.com/super_bonochin/status/1779969254202437792?t=_9TMXfpNlfZ2o21S0GgdIA&s=03)

　こちらは
　　バッチ処理を
　　　できるAPIのようです。

　ふつうは
　　ホールを投げたら
　　　相手が返してくれるでしょ。
　　　　これが今までのAPI。

　バッチ処理は
　　ボールを投げたら
　　　すぐには返らず、
　　　　相手が仕事の合間に
　　　　　返してくれる感じ、と
　　　　　　言えばいいかな。

　即応性を
　　求めないので、
　　　GPT-4のサーバー側の負担が
　　　　減ったところで
　　　　　こちらの仕事を
　　　　　　してくれるので、
　　　　　　　その分、安価に
　　　　　　　　なります。

　で、返ってくるのは
　　一日以内だそうで、
　　　その代わりに、
　　　　価格が半額だとか。
　　　　　
　私は今のところ、
　　開発側にまわるつもりは
　　　ないので、使いませんけどw
***
　次に、ChatGPTのWeb版の
　　UIが変更されました。

　これまで、
　　出力のあとに
　　　音声、コピー、リジェネ、バッド
　　　　の四つのボタンが
　　　　　出てきました。

　そのボタンが
　　なくなりました。
![Screenshot_20240416-074855.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/ef8a1338-4fb7-dec1-022c-3ca56a2e70c5.png)

　安心してください。

　出力をタップすれば
　　出てきます。
　　　隠れているだけです。

　パソコンの場合は
　　クリックになるのでしょうか？

　ひと手間、
　　掛かるのはちょっと。

　それに
　　出力が終わったのかどうか、が
　　　わかりにくいです。
***
　最後に
　　OpenAI Japanは、
　　　人材を求めています。
[人材募集のポスト](https://x.com/shoty_k2/status/1780029892199084102?t=i5w3s6byG3Qrf4RuXreI0Q&s=03)

　やりたい人、頑張れ！
tmux上でvimを開いた時の文字色が変

## tmux上でvimを開くと文字が非常に見づらい。

### vimを普通に開いた時
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124451/36d9ea2a-9ab5-3f39-1a23-c8abc80ea2c3.png" width="400">

### tmux上でvimを開いた時
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124451/40e2fa84-af46-7c16-178f-f5b1b7afcfd7.png" width="400">

明らかに見にくいのである。

## 解決方法
vimrcの設定を変える。
```
# ~/.vimrc
colorscheme elflord
```

### 結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124451/3dd9965e-a96c-d1c4-bc3e-ffc8a1ad79b0.png" width="400">
AWS Certified Solutions Architect – Associate 認定試験に合格した後、何をしているか

AWS-SAA(AWS Certified Solutions Architect – Associate) 認定試験に合格した後、何をしているかといえば、次の3つのことをしています。

1\. AWS-SAA の問題集を寝る前に解く
2\. AWS-SAA 講習動画で紹介されたハンズオンの復習
3\. AWS-SAP (AWS Certified Solutions Architect - Professional) 認定試験の試験問題を解く

SAA の問題集を解いているのは、記憶の定着を狙っています。問題集を7周するまで継続する予定です。

ハンズオンの復習は、特に試験問題に専念して後回ししたものが多数残っていて、今でも不安を感じるからです。実務では二度と使わないサービスもあるかもしれませんが、選択肢として経験があれば、他のサービスとの取捨選択が可能になるでしょう。

SAP は早い段階で取っておいたほうがいいと肌身で感じました。なぜならAWS の相談を持ち掛けてくる相手はSAA の範囲内に絞って要件を出してくるわけではないからです。SAP の試験は難問ぞろいですが、用語に関してはSAA の範囲も含まれる分、問題文を読むことや知らないサービスを調べる難易度がSAA のころに比べて下がっています。

### AWS-SAP を取得した後は何をするか？
専門分野のAssociate、 Professional を取得したいです。
フォルダにあるcsvファイルをテーブルにインポートする

```vb
Sub ImportCSVFiles()
    Dim strPath As String
    Dim strFile As String
    Dim strTempTable As String
    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    Dim strSQL As String

    ' 初期設定
    strPath = "C:\YourFolderPath\"  ' CSVファイルが存在するフォルダパス
    strTempTable = "TempTable"       ' 一時テーブル名
    Set db = CurrentDb()

    ' CSVファイルを探す
    strFile = Dir(strPath & "*.csv")

    Do While strFile <> ""
        ' CSVファイルを一時テーブルにインポート
        DoCmd.TransferText TransferType:=acImportDelim, _
                           TableName:=strTempTable, _
                           FileName:=strPath & strFile, _
                           HasFieldNames:=True

        ' レコードセットを開く
        strSQL = "SELECT * FROM " & strTempTable
        Set rst = db.OpenRecordset(strSQL, dbOpenDynaset)

        ' ファイル名を追加しながら本テーブルにデータを挿入
        Do While Not rst.EOF
            strSQL = "INSERT INTO YourTableName (FileName, Field1, Field2, Field3) " & _
                     "VALUES ('" & strFile & "', '" & rst!Field1 & "', '" & rst!Field2 & "', '" & rst!Field3 & "')"
            db.Execute strSQL
            rst.MoveNext
        Loop

        rst.Close

        ' 一時テーブルのデータをクリア
        db.Execute "DELETE * FROM " & strTempTable

        ' 次のファイルを検索
        strFile = Dir()
    Loop

    ' オブジェクトのクリーンアップ
    Set rst = Nothing
    Set db = Nothing
End Sub
```
サーバーサイドのデバッグはサーバーサイドで

Next.jsにてAPIでエラーが出ていた。
クライアントにエラーが出たら返すようにしていたが、400 エラーというバッドリクエストぐらいしか詳細がわからなかった。

しかし、サーバーサイド側にて`console.log()`でエラーを出すとDBが外部制約によるエラーを出していることがわかった。

つまり、クライアント側のみでエラーを確認するようにすると、得られる情報の粒度がかなり変わってくる。

クライアント側に出すエラー　= エンドユーザーへ見せたいもの
サーバーサイド側で出すエラー　＝ 開発者が把握したいもの

というのを指針に`trycatch`などを記述していくことにする。
どの粒度でエラーを吐くべきか、何をクライアントにどこまで返せばいいのか迷っていたので
上記を一旦の　指針とする。
cscの作法 その492

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
datatableが、DataGridViewで、CRUD実装されている事を確認せよ。

# 方針
- コンソールにプリントアウトする。

# create
最下行に、四郎を追加。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/86b7e682-60ed-40d0-e3c9-0029cfb11e74.png)


# read

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/16e56cb3-d5c6-516b-8bfc-0ca29a294273.png)

# update

太郎を３０に変更。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/86d4ad70-7d67-80a5-10cf-c5f8c373ddb3.png)

# delete

次郎をdeleteキーで削除。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/119c23d4-7f6a-1afe-eab3-50d0478f303d.png)

# サンプルコード

```

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Data;

class form1: Form {
	DataTable dt;
	form1() {
		Text = "CRUD";
		ClientSize = new Size(400, 300);
		dt = new DataTable();
		dt.Columns.Add("id", typeof(int));
		dt.Columns.Add("Name", typeof(string));
		dt.Columns.Add("Age", typeof(int));
		dt.Rows.Add(1, "太郎", 20);
		dt.Rows.Add(2, "次郎", 15);
		dt.Rows.Add(3, "三郎", 10);
		DataGridView gd0 = new DataGridView();
		gd0.Location = new Point(20, 40);
		gd0.Size = new Size(350, 250);
		gd0.DataSource = dt;
		Button btn1 = new Button();
		btn1.Location = new Point(150, 10);
		btn1.Text = "確認";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1,
			gd0
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		for (int i = 0; i < dt.Rows.Count; i++)
		{
			DataRow row = dt.Rows[i];
			Console.WriteLine("id: {0}, Name: {1}, Age: {2}", row["id"], row["Name"], row["Age"]);
		}
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

以上。