OmniAICreator/Qiita-1.07M huggingface dataset:
IPv6で接続されたHTTPクライアントのIPv4アドレスを確認する方法

[確認くん(IPv6/HTTP2 対応版)](https://ipchecker.berdysh.net/BookMark/ "確認くん(IPv6/HTTP2 対応版)")



REMOTE_ADDR には IPv6 しか入って来ないのでIPv4のアドレスを取得する為にもう一本の新しいセッションを張る必要がある。

別セッションでもまたIPv6が使われてしまわないように、DNSにIPv4専用にAレコードのみを記載したサブドメインを用意。

```
# host -a ipv4.berdysh.net

Trying "ipv4.berdysh.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47657
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
;ipv4.berdysh.net.              IN      ANY

;; ANSWER SECTION:
ipv4.berdysh.net.       3600    IN      A       160.16.79.241
```

同様にIPv6専用のAAAAのみのレコードをDNSを登録
```
# host -a ipv6.berdysh.net

Trying "ipv6.berdysh.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26972
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
;ipv6.berdysh.net.              IN      ANY

;; ANSWER SECTION:
ipv6.berdysh.net.       3600    IN      AAAA    2001:e42:102:1515:160:16:79:241
```

javascript から IPv4専用のURLを呼び出す
```
    fetch('https://ipv4.berdysh.net/IpChecker/', {
        method: 'get',
        headers: { 'Origin': 'https://ipchecker.berdysh.net' }
    })
    .then(function (data) {
        return data.json() ;
    }).then(function (json){
        console.log(json) ;
    }) ;
```

JSONでIPv4のアドレスを応答する

```
{
    "REMOTE_ADDR": "*.*.*.*"
}
```

javascript の fetch を使う場合接続先のドメインが異なるとセキュリティエラーになってしまうので、CORS を設定する必要がある。

```
Uncaught (in promise) TypeError: Failed to fetch
    at EvCheck ((index):72:5)
    at EvLoad ((index):86:5)
    at window.onload ((index):90:5)
berdysh.net/:1 Access to fetch at 'https://ipv4.berdysh.net/IpChecker/' from origin 'https://berdysh.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
ipv4.berdysh.net/IpChecker/:1          Failed to load resource: net::ERR_FAILED
```

サーバー側はPHPで記述
```
header('Access-Control-Allow-Origin: *') ;
header('Content-Type: application/json; charset=utf-8') ;
```

この方法だと、DNS の設定権限でワイルドカード証明書が必要になってしまう。


フリーのAPIを使う方法もありそうだが、それは次回に試してみます。

https://qiita.com/kazu_wsx/items/790a31409524d3b4e7fd
Bigqueryにおける日付操作(備忘録)

EXTRACT関数を用いることにより、スキーマがDATEの場合に簡単に操作をすることが可能

今回の場合は、customerテーブルで年ごとのcustomerの数を数えています。
DAYやMONTHも可能

```sql
SELECT 
  EXTRACT(YEAR FROM birth_day) AS birth_year, 
  EXTRACT(MONTH FROM birth_day) AS birth_month,
  -- EXTRACT(DAY FROM birth_day) AS birth_day,
  COUNT(*) AS count,
FROM `100_knock.customer`
GROUP BY birth_year,birth_month
ORDER BY birth_year
```
実行結果
![スクリーンショット 2023-08-25 11.28.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/984e8a49-b8cc-3663-c960-435fcb6b3381.png)
k8sへのDatadog導入

Datadogの導入手順です

環境、ツール
・GKE（standard）
・Kustomize

今回は新規にnamespaceをつくります
```namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: datadog
```

External Secret Operatorを使ったので下記のようにしてSecretを作成します。
```secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: datadog-secret-es
spec:
  secretStoreRef:
    kind: ClusterSecretStore
    name: gcp-cluster-secret-store
  target:
    name: datadog-secret
    creationPolicy: Owner
  dataFrom:
    - extract:
        key: datadog-key
```

Datadog AgentのデプロイにはDatadog Operatorを使いました。 https://docs.datadoghq.com/ja/containers/kubernetes/installation/?tab=operator （ちなみにGKE Autopilotだとうまくいかなかったため、こちらの方法になるかと思います https://docs.datadoghq.com/ja/containers/kubernetes/installation/?tab=helm）

```kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: datadog
resources:
  - namespace.yaml
  - secret.yaml
helmCharts:
  - name: datadog-operator
    repo: https://helm.datadoghq.com
    version: v1.0.3
    releaseName: datadog-operator
    namespace: datadog
```

DatadogAgentをデプロイします。
spec.featuresでオプションを設定できます。
```datadog-agent.yaml
kind: DatadogAgent
apiVersion: datadoghq.com/v2alpha1
metadata:
  name: datadog
  namespace: datadog
spec:
  global:
    site: ap1.datadoghq.com
    credentials:
      apiSecret:
        secretName: datadog-secret
        keyName: api-key
      appSecret:
        secretName: datadog-secret
        keyName: app-key
  override:
    clusterAgent:
      image:
        name: gcr.io/datadoghq/cluster-agent:7.46.0
    nodeAgent:
      image:
        name: gcr.io/datadoghq/agent:7.46.0
  features:
    logCollection:
      enabled: true
      containerCollectAll: true
    apm:
      enabled: true
      hostPortConfig:
        enabled: true
    admissionController:
      enabled: true
      mutateUnlabelled: false
    kubeStateMetricsCore:
      enabled: true
```

APM（分散トレーシング）は別途設定が必要です。Datadog Admission Controllerを有効にしてDeploymentを下記のようにします。
```deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: example
    tags.datadoghq.com/env: 'prod'
    tags.datadoghq.com/service: 'example'
    tags.datadoghq.com/version: '0.0'
  name: example
spec:
  selector:
    matchLabels:
      app: example
  template:
    metadata:
      labels:
        app: example
        tags.datadoghq.com/env: 'prod'
        tags.datadoghq.com/service: 'example'
        tags.datadoghq.com/version: '0.0'
        admission.datadoghq.com/enabled: 'true'
      annotations:
        admission.datadoghq.com/js-lib.version: v4.7.0
    spec:
      containers:
        - name: example
          image: ghcr.io/org/example
      imagePullSecrets:
        - name: ghcr-secret
```
Podでinit containerが起動していることが確認できます。
![スクリーンショット 2023-08-09 8.17.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2333388/ce06cc98-8b9a-714f-272e-8a9bbb7709e2.png)
![スクリーンショット 2023-08-09 8.18.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2333388/7350fffe-a586-99c9-a5c6-a3a00be66571.png)
計算が終わったらLINEに通知が行くようにした方法

計算機で長めの計算を流すときに、それが終わったら（正常終了でもエラーでも）LINEで通知を受け取ることができる方法を試してみた。
参考にしたのは[こちら](https://tech-drive.net/raspi/2018071101/)。
なお、ぼそっとつぶやいたら即座にやり方を調べて提案してくれたAさんにも感謝したい。

# LINE Notifyのトークン発行
[LINE Notify](https://notify-bot.line.me/ja/)を友だち追加。
同じページでログイン。
右上の名前からマイページ。
トークンを発行。

# コマンド
## メッセージを即座に送りたい
計算機に打つコマンドは以下の通り。
~~~
curl -X POST -H 'Authorization: Bearer トークン' -F 'message=メッセージ' https://notify-api.line.me/api/notify
~~~
トークンには発行したものを、メッセージは日本語でもOK。

## 計算が終わったらメッセージを受け取りたい

他にもやり方はありそうだが、とりあえず使えそうなものは以下のコマンド。
~~~
(nohup time ./test >./out.log 2>./err.log </dev/null; curl -X POST -H 'Authorization: Bearer トークン' -F 'message=test終わったよ' https://notify-api.line.me/api/notify) &
~~~
jQuery3以降では $(function () {}内で $(window).on('load', function(){}); は使えない

# はじめに
jQueryの`$(window).on ('load')`が上手く動かない。
具体的には、リストデータを遅延読み込みする際に画面読み込み時だけ上手く動かず、条件検索や件数表示を変えたときの処理はきちんと動く。

### 改善前のソースコード
```
$(function () {
    $(window).on('load', function(){
    	// ここでAjax通信を行う。
    });
}
```
これがそもそもダメだった。
`$(function () {} `で`$(window).on('load', function(){});`を囲うことは **jQuery3以降では完全にアウト**とのこと。
# 解決策
```
$(window).on('load', function(){
    // ここでAjax通信を行う。
});
```
`$(function () {} `の外に出すだけ。

ただ、開発によっては思わぬ事故を防ぐために関数定義のたびに`$(function () {}`で囲うのをちょいちょい見ます。
少なくとも、`$(window).on('load', function(){});`に限っては`$(function () {} `の中で定義するのはやめておいた方が良さそう。

# 参考文献
https://wemo.tech/109
【Jenkins】WindowsにJenkinsをインストール

# Jenkinsをインストール
1,https://www.jenkins.io/からダウンロードします。
2,下記の手順で設定を行います。

ダウンロードしたjenkins.msiを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/633fd5b3-3f23-fa2d-08c3-05f861e4239b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/e9aff839-8abd-2b7b-4b07-7ac094c0510e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/52f8c351-8d23-1229-50c3-f127c95a6c90.png)

ローカルで使用する場合は「Run Service as LocalSystem」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/165f1ccd-ee9f-6c73-1d5a-89ea958f22d6.png)
ポート番号を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/e54e35ca-03aa-3993-3ff1-8fb5d7f9c56b.png)
Javaが必要な為、インストールしていない場合は
https://www.java.com/ja/download/ie_manual.jsp
からインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/504fcf62-8c83-d99f-7ef9-afa5625c7948.png)
作業のなかでJava（JRE or JDK）のホームディレクトリを記載する必要がある
必要とされるJavaのバージョンはJenkinsのバージョンによって違う
 私の時は11か17を求められた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/384671db-9b9f-f3f9-9e32-c8a1df63a3a4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/8168e2af-e083-b7b9-1b9a-9deb36a81545.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/8b9f89b1-eb0c-8c42-71da-dcd95d427f5f.png)

インストール後にFinishをクリックし、Jenkinsを起動する

自動的にブラウザでJenkinsが起動するらしいが、自分の環境ではしなかった
起動しない時は http://localhost:8080 にアクセスすれば良い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/b08562c4-8f0f-2881-2605-760b6d3936e6.png)
C:\ProgramData\Jenkins\.jenkins\secretsのフォルダが作成されますので
secretsフォルダのinitialAdminPasswordを確認して入力します。
次にカスタマイズの設定がありますが、どちらでも問題ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/07e09242-8288-de5a-f17c-874622d51ee9.png)
プラグインは、特に要望がない限りはInstall suggested pluginsで良いと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/e02ae82d-415f-5131-08b0-d21602f2cebc.png)
管理者ユーザーの作成を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/cdad50e4-1c79-2eaf-1be6-df2f40a3ed24.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/dd67087e-8146-96fa-a2c5-6bff05490e06.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/2c8a7449-9979-3f15-7f04-f1d6a5cad2ef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/05865587-1c3e-4451-1c46-91f8bb760a74.png)
ゲーム学科に入って

<p>どうも<br>地方の普通科高校からゲーム学科に入った理系大学生です！</p>
<p><br>ゲーム業界に行きたい中高生は今や多いと思うので、参考までに…

<h1> 周りのやる気 </h1>
<p> 基本的には、普通の大学生と同様殆ど何もしない怠け者が大半を締めていますが…一応専門職目指しているだけあってその割合は体感6.7割ではないでしょうか？<br>なお、学年によってやる気ある人が多かったり少なかったりします。<br>やる気がある人は1年生の頃から個人プロジェクトを組んだり、AtCoderにて入茶したり、Unityを1日8時間やってたりします！

<h1> 就職先など </h1>
<p>就職率はほぼ100%ですが…ゲーム業界に行く人は1割で通常のIT企業等に入る人が7割、その他が1.5割、残りの0.5割は不明といった配分になっているそうです。<br>また、大抵は学部卒で就職しますが…偶に院進する人もいます。
<br>人数等は私の学科は1学年200人程います。
<br>また、カプコンやコナミ、バンダイナムコ等出身の先生がいるので毎年何人かはその辺りの企業に内定しています。

<h1> 私のプロフィールなど </h1>
<p>現在大学2年生で冒頭でも書いた様に地方の普通科高校出身です。（高校時代の文理選択は理系）<br>ゲームプログラマ志望としてゲーム学科に入りましたが…それまでにプログラミングの経験は殆ど無いです。<br>資格としては、B1の6月にITパスポート、B2の7月に基本情報技術者試験を習得してます。<br>プログラミングに関しては…プログラミング言語はJavaScript、C#、C++、C、PHP、Pythonが使え、AtCoderはB問題全てやC問題の1番簡単な物は解けますので…実力的には標準以上といった所だと思います。
<br>元々数学や物理が好きで1年生のときはそれらのノートを取ったり証明を見たりしていました。すると…いつの間にか将来の夢が組み込みエンジニアに変わってました（笑）
<br>ゲームに使いますというとどんなテーマでも通るらしいので…卒業研究は、圏論か組み込みソフトウェアをやろうと思ってます！</p>
<h1> ゲームクリエイターになるには </h1>
<p>基本的にとにかく作品を作りまくった末、どれを企業に送ろうかな？という状態になる事をおすすめします。それと理論より制作を意識すると色々作れると思います。理論から入らなければ…とすると私の様に理論大好きマンや思想強すぎマンになってしまうので（笑）
<br>あと、競技プログラミングはとても役に立つと思うので…有効活用すると良いかもしれません（具体的にはAtCoderにて茶色、Paizaにて最高ランクであるSくらいの実力があると凄く良い）
<br>資格に関しては情報やパソコンの基礎ができてないと感じるなら是非ITパスポートを取るべきだと思います！基本情報技術者試験は余裕が少しあれば取っておくと少し加点にはなるかと思います。</p>

<h1>授業について</h1>
<p>基本は他の情報系や工学系、理工学系に比べて実験などはほとんど無いためレポートや課題も1週間分まとめてやっても長くて4時間で終わり、テストもオンラインだったり何回でもできたりするので殆どの授業は真面目にやると最大評価を貰えます。ただゲーム学科なので…芸術的な感性を重視される授業もあるため真面目なだけではトップは取れない様になってます。<br>これは、大学によると思いますが…先生達はいつでも研究室に遊びに来てね！といった感じなので…気軽に高度な話を聞けます。<br>他にはプロジェクト系の授業が多いので…同学科の人と話し合う事が多いです。

<h1>まとめ</h1>
<ul>
<li>ゲーム学科は普通の大学生同様怠けて遊んでいる者が多い</li>
<li>ゲーム業界に行くべくゲーム学科を目指す人はとにかくゲームを作りまくること</li>
<li>高校の情報の教科書を読んでよくわからない場合はITパスポートを取ること</li>
<li>グループワークにて話し合う授業が多い</li>
<li>単位は他の学科よりも取りやすい傾向にある</li>
</ul>
PHPのfloor関数で誤差が出たのでBC Math 関数で対応した話

# 環境
- php:8.1

# 対象
- floor関数を使って誤差が出てしまった人


# 原因
以下に記載されていますが、浮動小数点の精度が計算結果に誤差を生じさせるようです。
https://www.php.net/manual/ja/language.types.float.php
```php:Controller.php
$result =floor((0.1+0.7)*10);

echo $result; // 7になる
```


# 対応
BC Math 関数を使用して対応します。
```php:Controller.php
$number = (0.1+0.7)*10;  

$result = (int)(bcdiv((string)$number, '1', 0));

echo $result;  // 正しい結果の８になる
```
CASE文を使って縦持ちから横持ちデータに（備忘録）

# 1.CASE句の特徴

CASE句は縦持ちデータを横持ちにすることを得意としています。
ExcelでいうIF文という解釈で大丈夫だと思います

# 2.コードの全体像
今回のケースとして、年齢、男性の合計、女性の合計、そのほかの合計
をカラムとして、取得したいとします。

まずは、コードの全体像です。

```sql
WITH gender_age_group as (
SELECT gender_cd , age , sum(amount) amount
FROM `100_knock.receipt` r
JOIN `100_knock.customer` c
ON r.customer_id = c.customer_id
GROUP BY c.gender_cd ,c.age
)

SELECT
  age,
  COALESCE(sum(CASE WHEN gender_cd=0 THEN amount END),0) male,
  COALESCE(sum(CASE WHEN gender_cd=1 THEN amount END),0) female,
  COALESCE(sum(CASE WHEN gender_cd=9 THEN amount END),0) unknown
FROM gender_age_group
GROUP BY age,gender_cd
ORDER BY age
```

まずは、WITH句の中から確認していきます

```sql
SELECT gender_cd , age , sum(amount) amount
FROM `100_knock.receipt` r
JOIN `100_knock.customer` c
ON r.customer_id = c.customer_id
GROUP BY c.gender_cd ,c.age
```
これは至って簡単で、customerテーブルとtransactionデータであるreceiptテーブルを結合しています。

結合した後は、性別と年齢ごとにグルーピングを行なってそれぞれの合計金額を取得しています。

結果が以下の通り
![スクリーンショット 2023-08-25 10.38.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/752af398-4c01-fbff-f5ff-e53bce19ae2e.png)

上の結果をWITH句でサブクエリとします
これから、横持ちデータに変えていきたいと思います。
CASE句を使うことでうまくいきます

ですが、まずは年齢ごとにということなので先にGROUP BYでageごとに集計します

### 意識すべき点

その後に、CASEを使っています。
gender_cdが0で既に年齢でグルーピングしているので、実際にはデータは1つしかないので、sumを用いる必要性は？と僕は思いましたが、
今回の場合は、1つですが、サブクエリの持っているデータによっては2つ以上になりうるので、ここではsumを使わないとエラーが起きてしまいます。

このままだと、欠損値が現れる可能性があるので、
COALESCEで欠損値保管を行なっています。

```sql
SELECT
  age,
  COALESCE(sum(CASE WHEN gender_cd=0 THEN amount END),0) male,
  COALESCE(sum(CASE WHEN gender_cd=1 THEN amount END),0) female,
  COALESCE(sum(CASE WHEN gender_cd=9 THEN amount END),0) unknown
FROM gender_age_group
-- GROUP BY age
ORDER BY age
```
【旧EnPiT】創造力実践プログラムに参加してみた【会津大・日大工学部】

今回は旧EnPiTこと、創造力実践プログラムに参加してきたので紹介する。

結論から言うと、**まだ就職先が不明という方は参加すべき**だと思っている。逆にもう就活で手一杯な場合はかなりハードスケジュールとなるので少し考えるべき。基本的にはおすすめという形だが、なぜそう思ったのかを以下の記事としてまとめたので見ていってほしい。

## 創造力実践プログラムのカリキュラム
- 創造力開発スタジオ
- 開発プロジェクト入門
- 開発プロジェクト実践

必修なのはこの３つ。私は会津大学でなく、同じく福島の郡山にある日大工学部に所属するものだが、この半年だけは会津大生という名目も背負っている。

詳しい流れは面倒なので[会津大学の公式サイト](https://u-aizu.ac.jp/enpit/)をご覧ください。2023/08/25現在では去年のデータだが、流れは多分一緒。下記では要約した説明のみ記載している。

### 創造力開発スタジオ

8/15~8/18は、創造力開発スタジオが実施された。その名の通り、**アイデアを提案するフェーズ**だ。私のところでは、**地方創生や異文化理解の意味合い**が強くあり、実際にその地方（今年度は**福島県喜多方市**）に訪れて現地調査をした。

### 開発プロジェクト入門

8/21~8/24は開発プロジェクト入門が実施された。次は、**開発の環境構築や実践**を行った。今回は**Java EE**と**MySQL**の環境をローカルのPCに構築して、それまで考えたアイデアを元に簡単なWebアプリケーションを作成した。

### 開発プロジェクト実践

10月~2月は開発プロジェクト実践が実施される。実際にシステムを作成してデプロイまで実施する、はずだった。

## 全てに共通して

### 時間が切羽詰まってる

全てに共通して言えることは、**本当に時間がない**ということ。常にフルで頭を回転させないといけないため、体力がえぐられる。9:00~17:00のカリキュラムだが、当然これで足りるわけもなく、その後残って話し合ったり、夜にミーティングを実施したり。人によっては睡眠時間１時間という人もいたくらい。

### アイデア出しが地獄だった
次に、私たちが出すアイデアは、ほぼ100%講師からツッコミが来る。

- そのシステムを導入してどんなメリットがあるか
- 地域の何を実現したいのか
- 現状のアプリケーションでいけるのでは
- もっと独創的なアイデアでいい

特に、**地域の何を実現したいのか**、というところでかなりダメ出しを食らった。途中から手段が目的になっていて、私自身は「またか」と嘆いているくらい。

講師側の中には70代くらいの年配の方もいたが、その方のほうがいいアイデアを出せていたりして、結構きつかった。若い人ほど自由な発想ができると思っていたが、実際は知識のほうが重要だったりする。

また、その方が仰ってたのは、**会社に頼む**。こんなにもシンプルで大きな影響が与えられるのは私でも天才的だと感じたくらい。まだまだ私たちは思考が硬いと痛感した限り。

### アイデアは掛け算
今回の中で、アイデアは`0→1`というより、`1→1.2`, `1→1.14`という事が多い。
`0→1`はアイデアと言うより必然的な事象。マズローの5段階欲求で言う生理的欲求。

実際求められているのは`1→0`を防いだり、`1→1.2`として、地域をより良くするアイデアだ。
そうなったとき言われたことが、**アイデアは掛け算だ**、ということ。

既存のアイデア1つでは、既にやっていること、これに更に掛け算することで、地域独自のアイデアとなる。

### 自分の欲求に偏りすぎた

これは私自身のことだが、私は地方創生というより、自分が実現したい、というアイデアばかり思いついてしまい、チームに対して的はずれな回答をすることがあった。

当然それでは地域に何を実現したいかが不明である。ただ正直私自身は、**この地方はオワコンだ**。と、心の奥底で思ってたため、もう他人にアイデア出しを委ねる他なかった。

### チームに助けられた

この活動は4人のグループを作成してそこで議論をする形だが、今回参加メンバーが8人だけだったので、特に戦闘意識もなく、一瞬でお酒を飲める仲に。

### アプリ開発もJava EE

あと、開発プロジェクト入門では、WebアプリケーションをJava EE（表現あっているか不明だが、xhtmlのファイルが出てくるやつ）でやった。講師は敢えて難しい状態でやらせることでチームの団結的なものを促進させる、という狙いがあったらしい。

まあ構築は相当困難を極め、一人ひとり状況も違かったが、最終的には全員コンプリートすることができた。一応Webアプリケーションも軽くは作ることができた。Java特有のオブジェクト指向は曲者だと感じた。MySQLのデータベースに触れるのにSQL文が一切表示されない、Next.jsで言うPrisma的な立ち位置。

開発プロジェクト入門では**あくまでプロトタイプ**なので、**プレゼンをする際どういった経緯で開発するか**、という方が重要で、技術的なアプローチはここまででは詳しくされることはない。


## 今回の気づき

ここからは私の感想になるため適当に見てほしい。

まず、上記の繰り返しになるが、**アイデアを出すことは本当に難しい**。特に私自身は途中からやる気を無くしていたため、もしかしたら自らアイデアを出すことが苦手なのかもしれない。
逆に、**コーディングになって一気にモチベーションが上がった**ため、コーディングの作業は好き、なのかもしれない。

### アイデアは本当に重要

でもやはり、自分のプロジェクトに落とし込むとき、アイデアの構成は重要だと感じた。特に、「**何のために作るか**」「**新たにイチから作る必要はあるのか**」と必死にQ&Aを繰り返して、ようやくコーディングに踏み込む、ということが必要なんだ。

まあ今回のプログラムで分かったが、これをやるのは本当にキツい。上記の項目を考えると、最悪何も作れなくなる。だからこそ、アイデアをともに共有したり、深掘ってくれる仲間を作るのも一つの手だな、と思う。

## 最後に

まだ最後まで実施していないので、今の段階の結論、まあ最初の方にも述べたが、**参加すべきだよ**。

今後の個人、そしてチームでのプロジェクトに強く生きていく。一番はアイデア。その次にコーディング、という流れというのが深く感じることができた。

ということで私の３年の夏季休業は８月後期からゴリゴリ忙しいものになって、私は幸せである。このモチベのまま個人のプロジェクトやしゅーかつを頑張りたいなー。
ガバナンスアーキテクチャ①

# 前置き
前の記事でルールの存在理由についてや向き合い方について記述しました。
この記事では、そのルールの設計についての考察記事を書きたいと思います。
以下では、ルールや規定、ガバナンスといったワードが飛び交いますが、
すべてここでは同じ意味を指すものだと考えていただけたらと思います。
途中出てくるTOC制約理論についての説明は、ネットに沢山情報があるので割愛します。

# 前提
いまからお話しするガバナンスアーキテクチャの前に前提となる
重要な設計原則である、リスコフの置換原則についてまず簡単に記載します。

この原則は簡潔に言うと、上位概念を意味継承した下位の概念は
必ず上位概念の規約を満たさなくてはいけない　というものです。

## 具体例①
まず例として、社内規定を例に出します。
下図では、わが社の組織構造と対応付けて社内規定の構造図を描きました。
<img width="600" alt="ガバナンス.png (19.0 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/25/135213/bf885601-255a-44c1-910d-1b6df70ec5b2.png">

わが社の部門すべてに共通する全社規定。各部門ごと固有の規定。
これら各部門ごとの規定は、上位の全社規定を満たすように設計されていなくてはならない。

## 具体例②
これを１つの社だけではなく、もっと広い意味でのガバナンスの構造として考えてみます。
ここではIT業界全般のルールについて考えてみます。

法律で定められている法令規定。
これに下位の組織とかが違反したら法律違反として訴えられますよね？
これはまさにガバナンス面でのリスコフの置換原則違反を表していると考えられます。
<img width="481.5" alt="規定構造.png (16.7 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/25/135213/0fad39ad-bf11-4270-822d-52238a731c46.png">


図で言うと、
法令規定をリスコフの置換原則満たすように継承する形でソフトウェア業界規定が存在し、
さらにそれをリスコフの置換原則満たすように継承する形でわが社規定が存在する。

逆に原則違反をしていると、先にも述べたように業界全体で統制をはかるのが難しくなると考えられます。

なんでも自由勝手にルールを設けるのではなく、
この【リスコフの置換原則をみたすように】という制約によって全体としての統制をはかりやすくする。

# ゼロからガバナンスの構築
ここでは例として予約管理ができるITシステムが導入される飲食店ビジネスを考えてみます。
まず絶対的な制約として考えられるのは、食品衛生法などの飲食店である限り
必ず厳守しなくてはならない法律がありますね。
暗黙的には、コロナ渦騒動中の各テーブルの飛沫よけなんかも
飲食店業界の法的というか社会情勢的制約と言えますが、これは暗黙的なので今回は無視します。
あとは予約の際の個人情報の保護法なんかも上げられますね。

まずこれらはそもそもの前提の制約として最初に定義できるものだと考えられます。

次にやることは、そのビジネス特有のルールの設計。
あくまでもその特有ルールも上記で述べたようにリスコフの置換原則を満たすように設計。

されそのビジネス特有のルールを考えるために必要なのが、リスク分析です。
ルールの存在意義については、前の記事ですでにリスク回避or軽減のためと記載したのでここでは省きます。

## 食品リソース観点
たとえばクリスマスなどの繁忙期シーズンでは飲食店、
特にチキンなどが在庫不足になることや、注文してから配達にかかる時間が長時間にわたるなど、
本来であれば喜ぶべき注文がたくさん来るというのが
キャパオーバーして、市場の要求量＞＞生産能力　という物理制約が発生している状態です。

でもだからと言って、
年がら年中チキンを大量に生産すればそれはそれで、
生産能力＞＞市場の要求量　という市場制約の現象が起きてしまい、
食材や梱包パッケージなどの物資の無駄遣いを生んでしまいます。

つまり、物資の無駄を最大限減らし　
かつ　在庫切れになって売上UPのチャンスを逃さないためには、
当たり前ですが　生産能力＝市場の要求量　に近い状態を目指さないといけません。

## ヒト系リソース観点
これは同様にヒト系リソース観点でも言えますね。
繁忙期に生産する人が足りないとエンドユーザを待たせるだけでなく、
１人あたりの作業がちょうぜつ忙しくなるのでミスも増えやすい。
そのため普段の繁忙期に比べて人数を増やさなくてはいけませんね。
ここでやってはいけないのが、思考停止して１年中一律の人数にしてしまうこと。
繫忙期には人が足らず、閑散期には逆に人が多すぎてコストの無駄遣いが起きます。

## 方針制約
TOC制約理論では、上記の物理制約および市場制約は、ほとんどの場合はその真因として
方針制約、つまり組織のガバナンスがボトルネックとなって起きる表面的現象と言われています。
そのため、繁忙期には普段よりも倍のヒト系リソースや、食品リソースを投入することで
リスク緩和ができるように食品の仕入れ管理や在庫管理や、スタッフのシフト管理を行うなどの方針設計が重要となります。


## アーキテクチャ管理などの例
アーキテクチャの統制が取れなくなるリスクなどが考えられます。
これは非常にハイリスクであり、
かつ指数関数的に２次リスク３次リスクと脅威度合いが跳ね上がっていくと考えられますので、避けなくてはならないリスクです。

変更の際のリスクに対応しなかったことで、結果として統制が取れなくなる
という因果関係が考えられますね。
変更時のリスクとは、たとえば以下が考えられます。
①どこが変更されるべきかの特定に時間がかかる
②変更時の他への影響範囲の調査にも時間がかかる
③変更者によって予期せぬ設計方針を崩すような変更が加えられる可能性
④その結果本来追加で考えられるべき品質特性の観点が抜け落ちた状態で更新される可能性
⑤変更されたけども、やっぱり元に戻したいとなった際に、
どこを変えたのか？ブラックボックス化していて迅速に元に戻せないリスク

ここで⑤について考えたら、Ver管理の番号管理を全体で統制かけるといった
全社アーキテクチャ規定として制約をかけることでリスクの軽減がはかれます。

たとえばVerの管理番号の構造をトレーサビリティマップと対応付けることです。
最上位目標 . Capability . Operational . Services . Function
の順番で　どこに変更が加えられたのか、管理番号見たら一発で分かるようにするなどです。

# まとめ
以上のような経営リスクをどの程度抑えたいのかによって、ルールの仕組みづくりも当然変わってきますね。
法という前提の制約にさえのっとっていれば、各ビジネスでどのようにルールを設計しても
OKというのがリスコフの置換原則を満たしたうえでの真の多様性と言えると感じます。
次回はガバナンスのリアーキテクティングについて記述します。
特定ディレクトリで使用するpyenv環境を自動的に切り替える (bash/zsh)

bashとzshで設定の仕方が若干異なったので整理しました。詳細は下記の元記事を参照してください。

- https://dev.classmethod.jp/articles/how-to-auto-conda-activate/
- https://qiita.com/noraworld/items/4062e8dd3ccffecb4801#prompt_command-%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92-precmd-%E3%81%AB%E7%A7%BB%E8%A1%8C%E3%81%99%E3%82%8B

# bash/zsh共通

切り替えたいディレクトリで、当該環境をactivateし、その環境名を`.environment.yaml`に書き出す。

```
conda config --set auto_activate_base false
conda activate hogehoge
conda env export > .environment.yaml
```

# zshの場合

`~/.zshrc`に下記を書き込む。

```
# Auto activate conda environments
function conda_auto_env() {
  if [ -e ".environment.yaml" ]; then
    ENV_NAME=`head -n 1 .environment.yaml | cut -f2 -d ' '`
    # Check if you are already in the environment
    if [[ $CONDA_PREFIX != *$ENV_NAME* ]]; then
      # Try to activate environment
      conda activate $ENV_NAME &>/dev/null
    fi
  fi
}
precmd() {
   conda_auto_env
}
```

# bashの場合

`~/.bashrc`に下記を書き込む。

```
# Auto activate conda environments
function conda_auto_env() {
  if [ -e ".environment.yaml" ]; then
    ENV_NAME=$(head -n 1 .environment.yaml | cut -f2 -d ' ')
    # Check if you are already in the environment
    if [[ $CONDA_PREFIX != *$ENV_NAME* ]]; then
      # Try to activate environment
      source activate $ENV_NAME &>/dev/null
    fi
  fi
}

export PROMPT_COMMAND="conda_auto_env;$PROMPT_COMMAND"
```
paiza.ioでelixir その248

# 概要
paiza.ioでelixirやってみた。
文字列を連結したい。

# サンプルコード

```

Enum.reduce(["a\n", "b\n", "c\n"], "", fn v, acc -> 
	acc = acc <> v
end)
|> IO.inspect


```

# 実行結果

```
"a\nb\nc\n"

```

# 成果物

https://paiza.io/projects/A3usAn0uTS5VxhZxvKEIyg


以上。
推論できるAI～2023年8月号の日経サイエンスに「数学する脳とAI」を読んで～

# 数学する脳とAI
2023年8月号の[日経サイエンスに「数学する脳とAI」](https://www.amazon.co.jp/%E6%97%A5%E7%B5%8C%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B92023%E5%B9%B48%E6%9C%88%E5%8F%B7-%E7%89%B9%E9%9B%86%EF%BC%9A%E6%95%B0%E5%AD%A6%E3%81%99%E3%82%8B%E8%84%B3%E3%81%A8AI%EF%BC%8F%E6%A0%B8%E8%9E%8D%E5%90%88%E3%81%AE%E7%8F%BE%E5%9C%A8%E5%9C%B0-%E6%97%A5%E7%B5%8C%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9%E7%B7%A8%E9%9B%86%E9%83%A8/dp/B0C6NL4DHH)という特集記事が掲載されているのを読みました。
そこには、[「Logical Tasks for Measuring Extrapolation and Rule Comprehension」](https://arxiv.org/abs/2211.07727)という論文が紹介されています。
この論文では、研究用の小規模な Transformer に、500～1500 の範囲の数を2つ足すような足し算を学ばせたあと、学習の範囲外を含む 0～2500 の範囲の数字を使った足し算を解かせたところ、学習していない計算については殆ど不正解だったという結果を紹介しています。
人間にとっては、計算と会話は全く異なるタスクですが、LLM では地続きの同じ作業に見えているのではないかと著者は考察しています。つまり、LLM は足し算を「直感的」に解いており、足し算の背後にある「規則性」（たとえば桁上りといった規則）の抽出は苦手としていると見ています。実際、LLM が間違った足し算では桁上り（繰り上がり計算）ができていないケースが多かったと報告しています。
こうして、今の AI（ Transformer をベースとした LLM ）は数学を理解していない（足し算の規則性すらきちんと把握していない）と結論付けており、今後「推論できるAI」を目指すことの重要性を説いていました。

## コンテキスト内学習（In-context learning）

そんな推論ができないと思われている今の AI ですが、コンテキスト内学習（In-context learning）によって、つまり、プロンプト内でタスクの指示内容を工夫することで推論能力を高めることができることが知られています。具体的には、命令内容の前に、ルールや手順を言葉で与えるのが効果的とのことです。有名なのは「Let's think step by step」ですね。実際、足し算の計算方法やアルゴリズムをコンテキスト内学習で言葉で教えてから実際の問題を解かせることで正答率が上がったという研究もあるそうです。

## グローバル・ワークスペースを持つ AI

推論できる AI を目指して、ヒトの脳をヒントにした「グローバル・ワークスペース」という新しい AI の概念があるそうです。
特定の機能に特化した複数のニューラルネットワークがあり、まとめ役になるニューラルネットワークが情報の集約を行って、必要に応じてそれらのニューラルネットワークに指示を出すというモジュール型の考え方だそうです。

## GPT4もグローバル・ワークスペースを持つ AI ？

当初、GPT4のパラメータ数は１兆を超えるとまことしやかに言われていましたが、実は、GPT3.5クラス（パラメータ数 2,200億）の LLM を８つ連結し、[それらの調整役をする LLM がそれらに指示を出しているとの説があります](https://ainow.ai/2023/08/08/274257/)。GPT4のアーキテクチャは非公開なので、本当のところはわかりませんが、もしそれが事実とすれば、これってグローバル・ワークスペースを持つ AI ですよね。

## CoT (Chain of Thought)

推論機能を高めると言えば CoT (Chain of Thought) もそうですね。
実は今の LLM には特定の機能に特化したモジュール構造が既に生まれており、CoT によってそのモジュールをステップ・バイ・ステップに呼び出すことを人間が指示してやることによって論理的な推論を実現しているのではないかと妄想しています。
ですが、今の LLM には調整役のモジュールがない。だから、ゼロ・ショットではうまく推論ができない。問題は、その推論機能を駆動する調整役のモジュールをどうやってデータから学習するかということです。

## 創発

私は LLM の「創発」によってこの推論の問題が解決するのではないかと思ってましたが、「Logical Tasks for Measuring Extrapolation and Rule Comprehension」の著者は、「大規模言語モデルの規模を大きくするだけで解決する問題ではありません」と言ってます。私は、「創発」現象は、潜在空間におけるトークンの状態ベクトルの質が極度に向上した結果、これまで解けなかったタスクが解けるようになるのではないかと考えています。しかし、こと推論においては、トークンの「質の向上」だけでは解決しませんよね。論理はトークンに宿るものではなく、もっとメタな概念ですものね。

## グローバル・ワークスペース再考

LLM のモジュール化と言えば、Plugin もある意味そうですよね。
たとえば ChatGPT用 Wolframプラグイン を利用すれば数学の問題が正確に解けるようになります。ですが、プラグインはあくまでもその目的に応じて人間が開発し、必要に応じて人手によって導入（設定）するものであって、LLM がデータから学習して実現するものではありません。推論する AI にとって重要なことは、機械が自動的にデータから学習して利用できるようになることです。人が介在すると、どうしても「漏れ（機能の過不足）」や「想定外」な事態が発生します。
LAG関数(備忘録)

# 1.LAG関数の特徴
LAG関数とは、ウィンドウ関数と呼ばれている
ある日の前日の売上などを同じ行に追加して、比較できるようになります。

今回の場合は、トランザクションデータを使っており、日々蓄積されるデータになっております。

# 2.記述の手順
まずは、
GROUP BYを使って、日の集計を行います。
その後に、 LAG関数で前日のデータを取得してくるのですが、
その前に、データを並び替える必要があります。
OVERとORDER　BYを使ってどの値でソートするのかを決めます。
今回の場合は、日付で一個前のデータがほしいので、ORDER BYには
sales_ymdにします。

3日前までのデータを取得したいので、LAGの値を１〜３で用意します。

記述したコードがこちら
```sql
WITH sales_total_day AS (
SELECT
sales_ymd,
sum(amount) amount
FROM
`100_knock.receipt`
GROUP BY
sales_ymd
)

SELECT
sales_ymd,
amount ,
LAG(sales_ymd ,1) OVER(ORDER BY sales_ymd) sales_ymd_1agoa,
LAG(amount ,1) OVER(ORDER BY sales_ymd) amount_1ago,
LAG(sales_ymd ,2) OVER(ORDER BY sales_ymd) sales_ymd_2ago,
LAG(amount ,2) OVER(ORDER BY sales_ymd) amount_2ago,
LAG(sales_ymd ,3) OVER(ORDER BY sales_ymd) sales_ymd_3ago,
LAG(amount ,3) OVER(ORDER BY sales_ymd) amount_3ago
FROM
sales_total_day
```
cscの作法 その432

# 概要
cscの作法、調べてみた。
ListBox使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4c01aae5-2261-503e-821b-3272552f8839.png)

# サンプルコード

```


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

namespace App
{
	public class Form1: Form {
		private Label label;
		ListBox list;
		public Form1() {
			this.Text = "ListBox";
			this.Width = 300;
			this.Height = 200;
			setupControls();
		}
		public void setupControls() {
			label = new Label();
			label.Text = "type text:";
			label.Font = new Font("Geneva", 12, FontStyle.Regular);
			label.Height = 30;
			label.Width = 300;
			this.Controls.Add(label);
			list = new ListBox();
			list.Width = 100;
			list.Height = 100;
			list.Left = 50;
			list.Top = 50;
			list.SelectionMode = SelectionMode.MultiExtended;
			list.Items.Add("Hello");
			list.Items.Add("Welcome");
			list.Items.Add("Bye!");
			list.SelectedValueChanged += list_changed;
			this.Controls.Add(list);
		}
		private void list_changed(object sender, System.EventArgs e) {
			string res = "selected: ";
			foreach(string obj in list.SelectedItems)
			{
				res += obj + " ";
			}
			label.Text = res;
		}
		[STAThread]
		public static void Main(string[] args) {
			Application.Run(new Form1());
		}
	}
}




```

以上。
getByRoleの参照と、アクセシブルネームの確認方法

## getByRoleはHTMLのロールと同じ

`Testing Library` の `getByRole` は、 `HTML要素のロール`を参照します。
必要に応じて公式を参照しましょう。

## 例
button は暗黙的に button というロールを持っています

```html
// わざわざroleを指定しなくてよい
<button role="button">ボタン</button>

// divにも反映できる(理由があれば)
<div role="button">~~~</div>
```

#### 注意

input のロールは、type 属性名称がロール名称に一致するとは限らない。

```html
<input tyle="text">     // role="textbox"
<input tyle="checkbox"> // role="checkbox"
<input tyle="radio">    // role="radio"
<input tyle="number">   // role="spinbutton"
```

## h 属性の絞り込み方法

h 属性は `headigロール` を持っています。
h1~h6 まで、すべで heading で同じとなっています。
なので、 `h 属性が複数存在する` ページの場合、`screen.getByRole("heading")` とすると失敗してしまいます。(screen.getByAllRole("heading)は成功する)

```html
// 両方ともheading
<h1>見出し1</h1> // role="heading"
<h2>見出し2</h2> // role="heading"
```

これを見分けるためには、`level` を使用する

```js
screen.getByRole("heading" , {level:1}) // h1が取れる
screen.getByRole("heading" , {level:2}) // h2が取れる

// 何かしらの理由でh属性を使えない場合、このように指定する
<div role="heading" aria-level="1">見出し</div> 
```

## アクセシブルネーム

Accessible Name は HTML の `name属性とは関係ありません`。
スクリーンリーダーで読み上げられるテキストを示します。

```html
// アクセシブルネームは 送信
<button>送信</button> 

// アクセシブルネームは送信
<button><img alt="送信" src="画像.png"></button>

// アクセシブルネームがない！必ず指定しよう
<button><img src="画像.png"></button> 
```

アクセシブルネームは様々な要因が絡んで決定されるので、下記を読んでまずは確認しましょう。
(算出の仕様はこちら : [Accessible Name and Description Computation 1.2](https://www.w3.org/TR/accname-1.2/))

## ロール名、アクセシブルネーム名を確認する

慣れないうちは、なにがアクセシブルネームになるのかわかりません。。
ただ、確認する方法が主に2つの方法があります。

- ブラウザの拡張機能を使用する
- テストコード上で確認する

### ブラウザの開発者ツールを使用する

Chromeの拡張機能を使用すれば、簡単に確認できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129861/ccfa69fc-f7a4-d4f4-1fdf-760f0ad1565e.png" width=400>

### テストコード上で確認する

```jsx
// 実装
export const Form = ({ title, handleOnSubmit }) => {
  return (
    <form onSubmit={(event) => {~処理~}}>
      <h2>タイトル</h2>
      <p>{title}</p>
      <button>決定</button>
    </form>
  );
};

// test
test('logRoles: アクセシブルネームを確認する', () => {
  const { container } = render(<Form title='リスト' />);
  logRoles(container);
});
```

テスト結果は下記となり、アクセシブルネームが確認できた。
![スクリーンショット 2023-08-25 9.09.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129861/3b69ac59-c126-6276-bccc-622a2a7edb90.png)

`logRoles`を使い、アクセシブルネームを確認しつつテストコードへ反映させていくのがよさそう。

---



参照
AccessibleRichInternetApplications(WAIARIA)
https://www.w3.org/TR/waiaria1.2/

WAIARIAロール
https://developer.mozilla.org/ja/docs/Web/Accessibility/ARIA/Roles

a11yとテストを同時に改善する話
https://zenn.dev/takepepe/articles/improve-a11y-and-testing
PhpStormでWordPressのコードスタイルを設定【Code Style】

設定(`Ctrl + Alt + S`)から、`Editor > Code Style > PHP`に行き`Set from...`からWordPressを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3127414/c0e9ed6f-86cb-2b71-d0fc-d337d764ef44.png)


`Ctrl + Alt + L`でフォーマット整形( Reformat Code )できます。

https://www.jetbrains.com/help/phpstorm/wordpress-aware-coding-assistance.html#configuring-wordpress-code-style
【flutter】Columnを左寄せするには？

こんにちは。
今回は、Columnを左寄せする方法を紹介します。

# 方法
![スクリーンショット 2023-08-13 20.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/ce57fee2-1687-ea40-8538-b4c8b9db94e0.png)

Columnを左寄せするには、crossAxisAlignmentにCrossAxisAlignment.startを指定します。


# 使用例
```dart
@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.pink, //背景の色を選択
          title: const Text("Flutter!!!!"), //タイトルを表示
        ),
        body: const Column(
          crossAxisAlignment: CrossAxisAlignment.start, //これをつける
          children: [
            Text(
              "太文字",
              style: TextStyle(fontWeight: FontWeight.bold), //太文字
            ),
            Text(
              "文字色ピンク",
              style: TextStyle(color: Colors.pink), //文字色ピンク
            ),
          ],
        ));
  }
}

```

# 実行例
![スクリーンショット 2023-08-25 9.17.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/0590dd58-0d0a-8e3b-3722-ac162ff3d9c0.png)
非エンジニア向けにもわかるよう「依存」を解説する

エンジニアリングにおいて、「依存」は重要な概念です。

たとえば『Clean Architecture』では、設計やコンポーネントの原則のなかに「依存」をテーマにするものもあるように、依存に対する理解は不可欠と言えるでしょう。

このエントリでは他の職種の人にも「依存」の重要性を知ってもらうため、「持ち家と賃貸」を例に挙げて、**エンジニアリング関連の言葉を使わずに「依存」を説明する**ようなテキストを書いてみました。

ぜひ5分ぐらい時間を確保して読んでいただければと思います。

## 言葉の意味を考える

まず「依存」とは、どのような意味でしょうか。

Weblio辞書を引くと「他に頼って存在、または生活すること。[^1]」と書いてあります。

つまりは「**自身以外のものを必要とすること**」と言えるでしょうか。

### 身近な「依存」

たとえば私たちは家に住んでいます。

そして「家は必要だ」と考えるとき「**私は家に依存する**」と表現できます。

「依存」というと「依存症」というような強烈なイメージのみ持つかもしれませんが、いたるところに依存はあります。

依存していない人は存在しません。

**どんなものにも依存関係はあります**。

## 依存することによって何が起きるか？

つぎに「**依存することによって何が起きるか？**」を考えてみましょう。

自分なりに説明すると、

「**依存先の変更の影響を依存元は受ける**」

と言えるでしょうか。エンジニアにとっては、この意味合いがとても重要です。

### 依存先の変更の影響を依存元は受ける

さきほど「私は家に依存する」と書きました。

「私は家に依存する」ということは、「**家の変更があると私も影響を受ける**」ということです。

- 素敵なソファーをリビングに置いたけれど、引っ越したら置き場所に困ってしまった
- 隣に越してきた人がうるさくて寝れない

みたいな例は一度はあるはずです。[^2]

## 依存には強弱がある

そのままさらに「依存」の解像度を上げてみましょう。それは、

「**依存には強弱(度合い)がある」**

ということです。つまり**強い依存と弱い依存があります**。

### 強い依存

「強い依存」とは「**依存先を変更できないものに対する依存**」です。

たとえばあなたが持ち家を持っている場合、そう簡単には他の持ち家に変えることはできないでしょう。

この場合「**私は持ち家に強く依存している**」と表現できます。

「依存症」と呼ばれるものもこれに該当するでしょうか。「私はアルコールに強く依存している」つまり「アルコールという依存先を変更できない(やめられない)」わけですね。

### 弱い依存

一方で「弱い依存」は「**依存先を容易に変更できる依存**」です。

持ち家に対応させるなら、賃貸が正しい例でしょうか。来年違う家に住んでいるかもしれません。「**私は賃貸に弱く依存している**」わけです。

## 依存の度合いは変化するしコントロールもできる

最後に。依存をきちんと把握できると、いずれは依存をコントロールできるようになります。

### 変更が起きないものには強く依存する

たとえば持ち家を持っている人は、どうせ家の変更はないでしょうから、オーダーメイドされた本棚を設置したり、キッチンにさまざまな調理家電を置いたりしても構いません。

つまり「**変更が起きないものには強く依存する**」作戦をとっているわけです。

### 変更が起きやすいものには弱く依存する

しかし賃貸でこれをやるとどうでしょう。

その本棚は次の家には収まりきらず、まな板を置くスペースもないキッチンになるかもしれません。

言い換えれば「**変更が起きやすいものには弱く依存する**」必要があります。賃貸に変更が起きないことは考えられません。

繰り返し、ここで重要なのは、依存の度合いはある程度コントロールできるものだということです。

持ち家に住んでいたとしても「いつ地震で壊れるかわからない」と考えるのであれば、その人は「依存を弱める」戦略をとれます。

## エンジニアがなぜ「依存」を重要視しているのか

エンジニアも日々いろいろな「依存」をコントロール、とくに**弱く依存するように**工夫しています。

なぜか。それは「**刻々と変わっていく状況に対応するため**」です。

ビジネスやエンジニアリングの現場は、持ち家とは違って、死ぬまで一生変わらないことが有り得ません。

### オンプレミスからクラウドへ

最近ではもう当たり前になってきた「クラウド」は、その主な例でしょう。

自社のサービスが動くサーバの実物が社内に置かれているとき、そのサーバは用意に交換できないため「自社サービスはサーバに強く依存している」ことになります。

当然サーバの変更はモロに受けます（サービスの停止）。

これをクラウドに変えると、サーバは（上記例と比較して）変更容易なものになります。

いまあるスペックのサーバで満足できなければ、依存先を別のスペックのサーバに切り替えればいいだけです。「弱く依存している」と言えるでしょう。[^3]

## まとめ

本エントリのポイントをまとめなおすと、次の通りです。

- 依存とは、自身以外のものを必要とすること
- どんなものにも依存関係はある
- 依存先の変更の影響を依存元は受ける
- 依存には強弱の度合いがある
  - 変わらないものには強く依存する
  - よく変わるものには弱く依存する
- エンジニアリングにおいては「よく変わるもの」が多いので、弱く依存できるような工夫をしている

この記事が好評であれば、もうひとつだけ「**依存関係は逆転できる**」というテーマも書いてみようと思います。

またここまで読んでいただいた方は「強く依存しているもの」や「弱く依存しているもの」の実例を教えていただけたら幸いです。


[^1]: [依存(いそん)の意味や読み方 Weblio 辞書](https://www.weblio.jp/content/%E4%BE%9D%E5%AD%98)

[^2]: 正確を期するのであれば、「ソファーは家に依存する」「私は隣人に依存する」と説明すべきでしょう。このエントリではおおまかに理解できれば良いと思うため、ここに書いておきます。

[^3]: これを「依存していない」と表現しても間違いではないと思います。
【Python】イテレータ・ジェネレータからN件ずつ取得する方法

# はじめに
みずほリサーチ＆テクノロジーズの@fujineです。

リストや辞書のように、要素を１つずつ取得可能なオブジェクトのことを、Pythonでは[イテラブルオブジェクト](https://docs.python.org/ja/3/glossary.html#term-iterable)と呼びます。

for文にイテラブルオブジェクトを使用すると、以下のように1件ずつ取得できます。
```py
[i for i in range(5)]  # 0, 1, 2, 3, 4
```
これを、例えば`N=2`とした場合に
```
(0, 1), (2, 3), (4,)
```
のようにN件ずつ取得する方法を本記事で模索していきます。

# 検証環境
Python3.9で検証していきます。
使用するデータは、イテラブルオブジェクトである`iterable`と、同じ値を生成するジェネレータの`generator`の2種類です。
一度に取得する要素数は`N=2`とします。
```py
iterable = [0, 1, 2, 3, 4]
generator = (i for i in iterable)
N = 2
```

# ①スライスを使う
インデックスで取得範囲を指定する方法です。最も直感的な実装であり、他のプログラミング言語でもよく用いられます。

```py
def niter_slice(iterable, n):
    return [iterable[i:i+n] for i in range(0, len(iterable), n)]

niter_slice(iterable, N)
# [[0, 1], [2, 3], [4]]
```

ただし、ジェネレータにこの方法は使えません。ジェネレータは通常`__len__()`をサポートしていないため、以下のようにエラーとなってしまいます。

```py
niter_slice(generator, N)
# TypeError: object of type 'generator' has no len()
```

# ②whileループを使う
whileループを使ったパターンです。①よりもコード量は増えてしまいましたが、ジェネレータにも適用できる点がメリットです。
```py
def niter_while(iterable, n):
    res = []
    it = iter(iterable)
    is_stop = False
    while not is_stop:
        chunk = []
        for _ in range(n):
            try:
                chunk.append(next(it))
            except StopIteration:
                is_stop = True
        if chunk:
            yield chunk

list(niter_while(iterable, N))
# [[0, 1], [2, 3], [4]]

list(niter_while(generator, N))
#[[0, 1], [2, 3], [4]]
```

# ③more-itertools.chunkedを使う
[more-itertools]()を使うと、標準ライブラリの[itertools](https://docs.python.org/ja/3/library/itertools.html)よりも高度で多様なイテラブル関数を利用できます。

以下コマンドでインストールします。
```
pip install more-itertools
```

[more_itertools.chunked](https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.chunked)でN件ずつ取得します。ジェネレータにも適用でき、コードもかなりシンプルです！
```py
import more_itertools

list(more_itertools.chunked(iterable, N))
# [[0, 1], [2, 3], [4]]

list(more_itertools.chunked(generator, N))
# [[0, 1], [2, 3], [4]]
```

# ④Numpy.array_splitを使う
取得後のデータを[Numpy](https://numpy.org)の配列にするのであれば、[Numpy.array_split](https://numpy.org/doc/stable/reference/generated/numpy.array_split.html)が便利です。

以下コマンドでインストールします。
```
pip install numpy
```

`array_split`の第2引数には、分割サイズではなく分割数を指定します。分割結果は`numpy.ndarray`型として取得されます。

```py
import numpy as np

np.array_split(iterable, len(iterable) // N + 1)
# [array([0, 1]), array([2, 3]), array([4])]
```

残念ながらジェネレータには適用できません。
```py
np.array_split(generator, 3)
# TypeError: object of type 'generator' has no len()
```

# まとめ
色々と模索した結果、汎用性や使い勝手の点では`more_itertools`がとても優秀でした。N件取得以外にも様々なイテレーション機能が充実しているようですので、改めて記事化したいと思います。

https://more-itertools.readthedocs.io/en/stable/
【Python】enumerateのようにアルファベットを循環的に生成したい

# はじめに
みずほリサーチ＆テクノロジーズの@fujineです。

`for`文などでイテラブルの要素を取得する際、連番のインデックスも同時に生成する方法として、組み込み関数である[enumerate](https://docs.python.org/ja/3/library/functions.html#enumerate)がよく使用されます。
```py
data = "abcdefg"
res = [(i, d) for i, d in enumerate(data)]
print(res)
```

```
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g')]
```

**このインデックスを、連番ではなくアルファベットで生成したい**というのが本記事の趣旨です。なお、整数と違いアルファベットの個数は有限のため、循環的に生成する必要があります。

この方法を応用すれば、アルファベットに限らず任意のイテラブルを`enumerate`のように扱うことができるようになります。

検証環境はPython3.9です。

# アルファベット版のenumerate
enumerateのアルファベット版は、標準ライブラリの[itertools](https://docs.python.org/ja/3/library/itertools.html)と[string](https://docs.python.org/ja/3/library/string.html)を使用します。

30個の連番にアルファベットを付与するコードと実行結果は以下の通りです。
```py
import itertools
import string

index = itertools.cycle(string.ascii_uppercase)
res = [(i, x) for i, x in zip(index, range(30))]

print(res)
```

```
[('A', 0), ('B', 1), ('C', 2), ...（中略）..., ('Y', 24), ('Z', 25), ('A', 26), ('B', 27), ('C', 28), ('D', 29)]
```

このコードは、以下仕組みで動いています。
- [ascii_uppercase](https://docs.python.org/ja/3/library/string.html#string.ascii_uppercase)は、英大文字（`A..Z`）の文字列
- [itertools.cycle](https://docs.python.org/ja/3/library/itertools.html#itertools.cycle)にて、イテラブルの要素を循環的に取得
- [zip](https://docs.python.org/ja/3/library/functions.html#zip)関数に複数のイテラブルを指定した場合、「短い方のイテラブルが先に終了した場合はzipも終了する」という特徴を活用

`ascii_uppercase`を[ascii_letters](https://docs.python.org/ja/3/library/string.html#string.ascii_letters)（英小文字+英大文字）にすれば、26+26=52文字と更に長い文字群も生成できます。

# アルファベット+数字を組み合わせたenumerate
次に、`A0`、`A1`、...、`A9`、`B0`、`B1`、...、`Z9`のように、アルファベットと数字を組み合わせたインデックスを生成してみます。

```py
index = itertools.cycle(product(string.ascii_uppercase, string.digits)) 
res = [(f'{a}{n}', x) for (a, n), x in zip(index, range(30))]

print(res)
```

```
[('A0', 0), ('A1', 1), ('A2', 2), ...(中略)..., ('A9', 9), ('B0', 10), ('B1', 11), ...(中略)..., ('C9', 29)]
```

仕組みは、`ascii_uppercase`（`A..Z`の英大文字）と`digits`(0..9の数字)の2つのイテラブルを、[itertools.product](https://docs.python.org/ja/3/library/itertools.html#itertools.product)で組合せ生成しています。

# まとめ
今回は小ネタとして、enumerateのようにアルファベットを循環生成する方法をご紹介しました。
「イテラブルの要素を順番にグルーピングしたい」というシーンで活用できれば幸いです。
「Code Llama」Metaが開発したコーディング補助AIを無償公開

## 初めに
2023 年 8 月 24 日、MetaAI は、テキスト プロンプトを使用してコードを生成できる大規模言語モデル (LLM) である Code Llama をリリースしました。 Code Llama は、コード タスクに関する公的に利用可能な LLM の最先端のものであり、現在の開発者にとってワークフローをより高速かつ効率的にし、コードを学習している人々の参入障壁を下げる可能性があります。

![image.png](https://scontent-nrt1-1.xx.fbcdn.net/v/t39.8562-6/369634634_298372716122486_560769700771259146_n.gif?_nc_cat=110&ccb=1-7&_nc_sid=6825c5&_nc_ohc=A7xtUs6ybWgAX8BKT4L&_nc_oc=AQm1936qRzic5WLEDxrET-Md9fEw70c8OjtsEoPOepXmLdp72D9N83RTedhSOBiB2xM&_nc_ht=scontent-nrt1-1.xx&oh=00_AfB9IgOeOvkmV5IlYBm4pg5LQS-lzQnf-0ZZRLfyyrL4bg&oe=64ECDA4B)

## 概要：

- 「Code Llama」は、コードおよび自然言語のプロンプトからコードとコードに関する自然言語を生成する能力を持つ最新のLLM（言語モデル）です。
- 「Code Llama」は、研究および商用利用のために無料で提供されています。
- 「Code Llama」は、Llama 2をベースに構築されており、次の3つのモデルが利用可能です：
  - 基本となるコードモデル、「Code Llama」；
  - Pythonに特化した「Code Llama - Python」；
  - 自然言語の指示を理解するために微調整された「Code Llama - Instruct」。
- 独自のベンチマークテストによると、「Code Llama」は、コードタスクにおいて最先端の公開されているLLMを凌駕しました。
- 「Code Llama」は、コードや自然言語のプロンプトから（例：「フィボナッチ数列を出力する関数を書いてください。」など）コードやコードに関する自然言語を生成することができます。また、コードの補完やデバッグにも使用できます。このツールは、Python、C++、Java、PHP、Typescript（Javascript）、C#、Bashなど、今日最も人気のある言語をサポートしています。

利用申請：
https://ai.meta.com/resources/models-and-libraries/llama-downloads/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225269/22945008-e594-3b05-6631-f08381fc75eb.png)

申請後、すぐに返信のメールが届きます。メールでモデルの利用方法を教えます。

## モデルのダウンロード方法：

1. GitHubのCode Llamaリポジトリを訪問し、README内の指示に従ってdownload.shスク プトを実行してください。
2. 固有のカスタムURLが求められる際には、以下を挿入してください：
○○○
3. ダウンロードするモデルの重みを選択してください。

提供された固有のカスタムURLは、モデルのダウンロードに24時間間有効であり、複数回リクエストを送信することができます。

## モデル

以下のモデルが利用可能です：

CodeLlama-7b
CodeLlama-13b
CodeLlama-34b
CodeLlama-7b-Python
CodeLlama-13b-Python
CodeLlama-34b-Python
CodeLlama-7b-Instruct
CodeLlama-13b-Instruct
CodeLlama-34b-Instruct


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225269/ca1aebf2-efed-27cd-1e59-d0e8527f7723.png)


## モデル評価の結果

「Code Llama」の性能を既存のソリューションと比較するために、2つの人気のあるコーディングベンチマーク、HumanEvalとMostly Basic Python Programming（MBPP）を使用しました。HumanEvalは、モデルがドックストリングに基づいてコードを補完する能力をテストし、MBPPはモデルが説明に基づいてコードを記述する能力をテストします。

私たちのベンチマークテストによれば、「Code Llama」はオープンソースのコード専用LLMよりも優れたパフォーマンスを示し、Llama 2をも凌駕しました。たとえば、「Code Llama 34B」は、HumanEvalで53.7%、MBPPで56.2%というスコアを獲得し、他の最先端のオープンソリューションと比較して最も高い成績を収め、ChatGPTと同等の結果を示しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225269/cecdd075-01bd-6ad0-00c9-455206357eb7.png)


参照：
記事：https://ai.meta.com/blog/code-llama-large-language-model-coding/
論文：https://ai.meta.com/research/publications/code-llama-open-foundation-models-for-code/
Github: https://github.com/facebookresearch/codellama
Huggingface: https://huggingface.co/codellama
cscの作法 その431

# 概要
cscの作法、調べてみた。
FlowLayoutPanel使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/86f144e1-cef7-45e6-1f4f-40ce4925ac51.png)

# サンプルコード

```

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace App
{
	public partial class Form1: Form {
		public Form1() {
			ClientSize = new Size(100, 500);
			FlowLayoutPanel FlowLayoutPanel1 = new FlowLayoutPanel();
			FlowLayoutPanel1.Dock = DockStyle.Fill;
			FlowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
			FlowLayoutPanel1.AutoScroll = true;
			FlowLayoutPanel1.AutoSize = true;
			FlowLayoutPanel1.WrapContents  = true;
			this.Controls.Add(FlowLayoutPanel1);
			for (int i = 1; i <= 15; i++)
			{
				Button button = new Button();
				button.Text = i.ToString();
				//button.Dock = DockStyle.Fill;
				//button.Left = 50;
				button.AutoSize = true;
				button.Margin = new Padding(20, 10, 5, 0);
				button.Click += new EventHandler(btn_Click);
				FlowLayoutPanel1.Controls.Add(button);
			}
		}
		private void btn_Click(object sender, EventArgs e) {
			Console.WriteLine("ok");
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
[Node.js] Packeage.jsonにあるSemVerの表記まとめ

# Semantic Versioningとは
- パッケージ等ソフトウェアにバージョンを振るための手法
- SemVer(センバー)とも略される
- packeage.jsonなどパッケージを管理するファイルで使用されている
- Semantic　「意味論」

# 書き方
Semantic Versioningの例
```
3.2.4
6.2.0
```
左から「メジャーバージョン.マイナーバージョン.パッチバージョン」

#### メジャーバージョン(Major)
後方置換性がない変更の時に上がる数字
後方置換性とは旧製品に対して互換性を持っている新製品の性質。つまりメジャーバージョンが違うパッケージに変更すると、以前のように動かない可能性がある。

#### マイナーバージョン(Minor)
後方置換性がある変更の時に上がる数字

#### パッチバージョン(Patch)
バグ修正の時に上がる数字

# バージョン表記の記号
パッケージのバージョン名の前の記号の意味
#### ^(キャレット)
0でないメジャーバージョンを固定し、マイナー、パッチバージョンは指定されたバージョン以上のパッケージを使用
例
```
# 1.2.3以上2.0.0未満のパッケージのバージョンを使用
^1.2.3

# 0.13.0以上0.14.0未満のパッケージのバージョンを使用
^0.13.0
```

#### ~(チルダ)
一番右のバージョンを上げる
例
```
# 1.2.3以上1.3.0未満
~1.2.3

# 1.2以上1.3未満
~1.2

# 1.0.0以上2.0.0未満
~1
```


# 参考にさせていただいた記事
- [Semantic Versioning](https://qiita.com/usamik26/items/c8911219b610101e69a9)
- [nodejsのsemverまとめ](https://blog.orz.at/2021/07/24/semver/)
cscの作法 その430

# 概要
cscの作法、調べてみた。
CheckBox使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/2886ee2a-5c14-b8c0-f958-985b959f23ab.png)

# サンプルコード

```
using System;
using System.Drawing;
using System.Windows.Forms;

namespace App
{
	public class Form1: Form {
		private Label label;
		CheckBox check0;
		CheckBox check1;
		public Form1() {
			Text = "CheckBox";
			this.Width = 300;
			this.Height = 200;
			setupControls();
		}
		public void setupControls() {
			label = new Label();
			label.Text = "type text:";
			label.Font = new Font("Geneva", 12, FontStyle.Regular);
			label.Height = 30;
			label.Width = 300;
			this.Controls.Add(label);
			check0 = new CheckBox();
			check0.Text = "check box0";
			check0.Top = 50;
			check0.Left = 50;
			check0.CheckedChanged += check0_changed;
			this.Controls.Add(check0);
			check1 = new CheckBox();
			check1.Text = "check box1";
			check1.Top = 90;
			check1.Left = 50;
			check1.CheckedChanged += check1_changed;
			this.Controls.Add(check1);
		}
		private void check0_changed(object sender, System.EventArgs e) {
			label.Text = "checked0: " + check0.CheckState + "(" + check0.Checked + ")";
		}
		private void check1_changed(object sender, System.EventArgs e) {
			label.Text = "checked1: " + check1.CheckState + "(" + check1.Checked + ")";
		}
		[STAThread]
		public static void Main() {
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			Application.Run(new Form1());
		}
	}
}





```

以上。
firestoreの書き込みクエリを実行したときにValue for argument "refOrQuery" must be a DocumentReference, Query, or AggregateQueryと言われるエラーへの解決策

こんにちは。[virapture株式会社](https://virapture.com)でCEOしながら[ラグナロク株式会社](https://ragna-rock.com)でもCKOとして働いている[@mogmet](https://twitter.com/mogmet)です。

本日はトラブルシュート記事です。

firestoreを使ったupdateやcreateなどのunit testを実行していたら下記のエラーが発生しました。

> Value for argument "refOrQuery" must be a DocumentReference, Query, or AggregateQuery.

この解決策の備忘録です。

## 結論

使っているパッケージのバージョンを合わせる

## 原因

本来は下記の部分らへんで一致したらreturnするようになっているのですが、なぜかすべての条件を素通りしてエラーになっていました。

https://github.com/googleapis/nodejs-firestore/blob/main/dev/src/transaction.ts#L148

そこで調べたところ、monorepo構成をとっているプロジェクトだったのですが、package.jsonに記載しているfirebase-adminのバージョンが違う状態で実行していたためこのエラーが出ているようでした。

## 解決方法

package.jsonに記載しているfirebase-adminのバージョンをあわせたら治りました！

## まとめ

パッケージのバージョンを上げるときは一斉に上げるようにしよう！

最後に、スノボの楽しく滑るコツを掴める [cotsume](https://cotsume.page.link/blog) というアプリを作ってます！よかったらDLしてみてね！

https://cotsume.page.link/blog

また、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！

https://online.1nite-jinro.com/link/blog

他にも[Camecon](https://camecon.me/)や[Offcha](https://offcha.com/)、問い合わせ対応が簡単にできる[CSmart](https://csmart.jp/lp)、フリーランスのコミュニティの[NextFreelance](https://next-freelance.net/)といったサービスも作ってるのでよかったら使ってね！

https://camecon.me/

https://offcha.com/

https://csmart.jp/lp

https://next-freelance.net/

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

https://virapture.com/

ラグナロクでもエンジニアやデザイナーのメンバーを募集しています！！楽しくぶち上げたい人はぜひお話ししましょう！！

https://ragna-rock.com
cscの作法 その429

# 概要
cscの作法、調べてみた。
Dataset使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/42c4e2d6-4296-bdac-4e9d-ac93668e4302.png)


# サンプルコード

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

class form1: Form {
	form1() {
		Text = "Dataset";
		ClientSize = new Size(400, 400);
		Label la1 = new Label();
		la1.Location = new Point(50, 10);
		la1.Text = "test";
		Button btn1 = new Button();
		btn1.Location = new Point(50, 50);
		btn1.Text = "test";
		btn1.Click += btn1_Click;
		TextBox bo1 = new TextBox();
		bo1.Location = new Point(50, 90);
		bo1.Text = "test de su";
		DataGridView gd0 = new DataGridView();
		gd0.Location = new Point(50, 130);
		Controls.AddRange(new Control[] {
			la1,
			btn1,
			bo1,
			gd0
		});
		using (SQLiteConnection conn = new SQLiteConnection("Data Source=db0.sqlite"))
		{
			conn.Open();
			using (var command = conn.CreateCommand())
			{
				command.CommandText = "CREATE TABLE IF NOT EXISTS diary(text TEXT NOT NULL, date TEXT NOT NULL)";
				command.ExecuteNonQuery();
			}
			conn.Close();
		}
		using (SQLiteConnection conn = new SQLiteConnection("Data Source=db0.sqlite"))
		{
			conn.Open();
			using (DataSet dataSet = new DataSet())
			{
				String sql = "SELECT date, text From diary ORDER BY date DESC LIMIT 1000";
				SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(sql, conn);
				dataAdapter.Fill(dataSet);
				gd0.DataSource = dataSet.Tables[0];
			}
			conn.Close();
		}
	}
	void btn1_Click(object sender, System.EventArgs e) {
		using (SQLiteConnection conn = new SQLiteConnection("Data Source=db0.sqlite"))
		{
			conn.Open();
			using (DataSet dataSet = new DataSet())
			{
				String sql = String.Format("INSERT INTO diary(date , text) VALUES('{0}', '{1}')", DateTime.Now, "test de su");
				SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(sql, conn);
				dataAdapter.Fill(dataSet);
				MessageBox.Show("登録しました。");
			}
			conn.Close();
		}
	}
	[STAThread]
	public static void Main() {
		Application.EnableVisualStyles();
		Application.SetCompatibleTextRenderingDefault(false);
		Application.Run(new form1());
	}
}




```

以上。