OmniAICreator/Qiita-1.07M huggingface dataset:
【Spring Data JPA】主キーが重複した複数のデータをsaveAll()で登録すると・・・

現在参画している案件でJava使い、開発を行っています。
そこでsaveAll()を用いてデータを登録する機会がありました。
しかし、実際にテストで動かしてみると3件データを登録できるはずがなぜか1件しか登録が出来ていなかったのです。



#原因
テスト自体は通るのですが、エラーで落ちてはいない・・・
なぜ登録できなかったのか、それは**重複した主キーを複数のデータに登録していたから**です。
実は開発中のAPIの仕様が曖昧なところがあり、""(空文字)で指定しておいてくださいと指示を受け、主キーに全て空文字を登録するようなロジックを作成していたことが原因でした。
(そもそも主キーに空文字を登録する時点で気づくべきだった・・・)

しかしここで、また1つ疑問が浮かびました。
なぜ、**重複した主キーなのにデータを登録できているんだろう？？？(しかもなぜか1件だけ)**
その答えはsaveAll()の仕様にありました。



#saveAll()の仕様
どうやらsaveAll()は
**①登録する際に重複する主キーがなかったら登録(insert)**
**②登録する際に重複する主キーがあったら更新(update)**
という仕様になっているようです・・・

↓saveAll()を掘り下げてる記事↓
https://hosochin.com/2020/08/16/post-589/



#解決策
**①複合キーを使う**
・複合キーとは2つ以上のキーをもつテーブルのことです。
例）

```Person.java

@Entity
@Data
@Table(name="person")
@IdClass(value=PersonKey.class)
public class Person implements Serializable {

  @Id
  @Column(name="person_id")
  private Integer personId;

  @Id
  @Column(name="employment_date")
  private String employmentDate;

  @Column(name="age")
  private Integer age;

  @Column(name="gender")
  private String gender;

  @Column(name="person_name")
  private String person_name;

  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  public static class PersonKey implements Serializable {
    private Integer personId;
    private String employmentDate;
  }
}
```

①@IdClassでPrimaryKeyを定義したクラスを指定します
②@IdClassで指定したクラスに、@Idを付与しているカラムを定義します。

以上で複合キーの完成です。
これでどちらかが""(空文字)であっても、もう片方が違う値なら登録されます。

**②そもそも重複するようなロジックにしない。**
これに尽きます。
(そもそも""(空文字)指定の前提がおかしいような・・・？？)

#終わり
以上、saveAll()や複合キーについてまとめてみました。
saveAll()が登録の他に更新も行うことは、この問題が起きるまでまったく知りませんでした。
皆様もsaveAll()を使うときはお気を付けてください。
**意図せず更新をかけてしまう可能性もありますので・・・**
Spark: データフレームの操作



```python
tmp = [[1, '2012/01/05', '岡野 徹'],
[2, '2012/1/0', '庄野 弘一'],
[3, '2012/01/3', '若山 みどり'],
[4, '2012/1/19', '岡野 徹']]

from pyspark.sql.types import *
schema = StructType([
   StructField("id", IntegerType(), True),
   StructField("date", StringType(), True),
   StructField("name", StringType(), True)]
)
df = spark.createDataFrame(tmp, schema=schema)

```


```python
from typing import List
import pyspark
import re

def get_particular_type_columns(_type: pyspark.sql.types.StringType) -> List:
    stringcol_list = []
    for col in range(len(df.schema)):
        if type(df.schema[col].dataType) == _type:
            stringcol_list.append((df.schema[col].name))
            
    return stringcol_list
```


```python
pattern = re.compile(r'[0-9]{4}/[0-9]{1}/[0-9]{1}|[0-9]{4}/[0-9]{2}/[0-9]{2}|[0-9]{4}/[0-9]{2}/[0-9]{1}|[0-9]{4}/[0-9]{1}/[0-9]{2}')
tablename_list = ['df']

col_dict = {}
for tablename in tablename_list:
    col_list = get_particular_type_columns(_type=pyspark.sql.types.StringType)
    col_dict[f'{tablename}'] = col_list
    
print(col_dict)

out_dict = {}
for tablename in tablename_list:
    
    # print(','.join(stringcol_dict[f'{table}']))
    selected_col = ','.join(col_dict[f'{tablename}'])
    
    # df = spark.sql(f'''
    # select {selected_col}
    # from {table}
    # limit 10
    # ''')
    
    collection = df.collect()
    
    # 10レコードに対して正規表現マッチを行ってマッチしたレコードをリストに追加していく
    out_record = []
    for record in collection:
        for value in record:
            if type(pattern.match(str(value))) == re.Match:  # 外す
                # print(value)
                out_record.append(record)
    
    out_dict[f'{tablename}'] = out_record

print('out_record\n',out_record)    
print('out_dict\n',out_dict)    

# print(f'table name:{tablename}')
# print(selected_col)
```

    {'df': ['date', 'name']}
    out_record
     [Row(id=1, date='2012/01/05', name='岡野 徹'), Row(id=2, date='2012/1/0', name='庄野 弘一'), Row(id=3, date='2012/01/3', name='若山 みどり'), Row(id=4, date='2012/1/19', name='岡野 徹')]
    out_dict
     {'df': [Row(id=1, date='2012/01/05', name='岡野 徹'), Row(id=2, date='2012/1/0', name='庄野 弘一'), Row(id=3, date='2012/01/3', name='若山 みどり'), Row(id=4, date='2012/1/19', name='岡野 徹')]}
IAMのスイッチロールを設定してみる

#初めに
AWSを勉強していて、スイッチロールという概念が出てきました。
詳しく調べてみると、複数アカウントで作業をしている際にアカウントの切り替えを楽にしてくれる仕組みとのこと。
いまいちピンとこなかったので、実際に設定してみて理解しようと思います。

#やりたいこと
・スイッチロールを設定し、**Account01**から**Account02**に切り替えを行う。

#設定
実際に設定を行ってみます。

###①Account02側の設定（IAMロールの用意）
Account02にログインし、IAMのコンソールから、[ロール] > [ロールの作成]をクリックします。
そして、信頼されたエンティティタイプで[AWSアカウント]を選択し、ロールを使用できるアカウントの識別子の入力欄にAccount01のアカウントID(12桁)を入力して[次へ]をクリックします。
![WS000004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/6d9e8c9d-3ffc-d590-5387-35de035c3240.jpeg)

許可を追加にて、Account01に対してのアクセスを許可するポリシーを選択します。
（本記事では[AdministratorAccess]を選択しています）
そして、[次へ]をクリックします。
![WS000005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/4cd7ae4e-d00f-6556-20db-7e9531c968b1.jpeg)

ロール名の入力を行います。
（本記事では「SwitchRoleDemo」としています）
![WS000006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/c6381e2a-1f0d-5ed0-2577-9ac485f39d4d.jpeg)

画面をスクロールし、[ロールを作成]をクリックすれば、Account02側での設定は完了です。
![WS000007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/8bb6aeaa-090c-22fc-3d6e-215b50c6754b.jpeg)

###②Account01側の設定（ロールの切り替え）
Account01にログインし、右上のアカウント名をクリックした後、[ロールの切り替え]をクリックします。
![WS000010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/07c7277d-8446-44ec-dac0-cd75193b2064.jpeg)

遷移先の画面にて、[ロールの切り替え]をクリックします。
![WS000011.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/85fe43be-da4d-f440-fa10-772218dcc134.jpeg)

ロールの切り替え画面にて、Account02のアカウントID及び、Accont02で作成したロール名を入力して[ロールの切り替え]をクリックします。
![WS000015.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/2a4e6b89-a32b-6460-4c84-c82c53b6402b.jpeg)

これにより、右上のアカウント名がAccont02で作成したロール名に切り替わり、Account02側のリソースに対して操作を行うことが出来るようになります。以上で設定は完了です。
![WS000016.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/dde0d296-f54a-ee87-7f30-0df989b9a8fc.jpeg)

なお次回からは、ロール履歴にて即座に切り替えを行うことが可能となります。
![WS000018.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/06adb18d-b8cb-3697-1183-178527e6ce74.jpeg)

#最後に
実際に設定してみることにより、アカウントのログアウト・ログイン操作を行わずに別のアカウントへ移動できるのが、スイッチロールだと理解できました。
確かにこれらの操作が省けるだけでも、だいぶ時間短縮になるからなあ・・・。
（特にMFAを設定している場合などは）
Terraform/GCP google_project_serviceに指定する値

## やりたかったこと
terraformで、google_project_serviceは以下のような形で使用するが、serviceに指定する値がどういうものがあるのか知りたかった

```tf
resource "google_project_service" "project" {
  project = "your-project-id"
  service = "iam.googleapis.com"

  timeouts {
    create = "30m"
    update = "40m"
  }

  disable_dependent_services = true
}
```

## 結論
`gcloud services list` のコマンドで表示できる。この記事執筆時点での自分の環境では以下が列挙された。

```
appengine.googleapis.com              App Engine Admin API
artifactregistry.googleapis.com       Artifact Registry API
bigquery.googleapis.com               BigQuery API
bigquerystorage.googleapis.com        BigQuery Storage API
cloudapis.googleapis.com              Google Cloud APIs
cloudasset.googleapis.com             Cloud Asset API
cloudbuild.googleapis.com             Cloud Build API
clouddebugger.googleapis.com          Cloud Debugger API
cloudfunctions.googleapis.com         Cloud Functions API
cloudresourcemanager.googleapis.com   Cloud Resource Manager API
cloudtrace.googleapis.com             Cloud Trace API
compute.googleapis.com                Compute Engine API
containeranalysis.googleapis.com      Container Analysis API
containerregistry.googleapis.com      Container Registry API
datastore.googleapis.com              Cloud Datastore API
dns.googleapis.com                    Cloud DNS API
eventarc.googleapis.com               Eventarc API
fcm.googleapis.com                    Firebase Cloud Messaging API
firebase.googleapis.com               Firebase Management API
firebasedynamiclinks.googleapis.com   Firebase Dynamic Links API
firebasehosting.googleapis.com        Firebase Hosting API
firebaseinstallations.googleapis.com  Firebase Installations API
firebaseremoteconfig.googleapis.com   Firebase Remote Config API
firebaserules.googleapis.com          Firebase Rules API
firestore.googleapis.com              Cloud Firestore API
googlecloudmessaging.googleapis.com   Cloud Messaging
iam.googleapis.com                    Identity and Access Management (IAM) API
iamcredentials.googleapis.com         IAM Service Account Credentials API
iap.googleapis.com                    Cloud Identity-Aware Proxy API
identitytoolkit.googleapis.com        Identity Toolkit API
logging.googleapis.com                Cloud Logging API
monitoring.googleapis.com             Cloud Monitoring API
oslogin.googleapis.com                Cloud OS Login API
pubsub.googleapis.com                 Cloud Pub/Sub API
run.googleapis.com                    Cloud Run Admin API
runtimeconfig.googleapis.com          Cloud Runtime Configuration API
securetoken.googleapis.com            Token Service API
servicemanagement.googleapis.com      Service Management API
serviceusage.googleapis.com           Service Usage API
source.googleapis.com                 Legacy Cloud Source Repositories API
sql-component.googleapis.com          Cloud SQL
sqladmin.googleapis.com               Cloud SQL Admin API
storage-api.googleapis.com            Google Cloud Storage JSON API
storage-component.googleapis.com      Cloud Storage
storage.googleapis.com                Cloud Storage API
testing.googleapis.com                Cloud Testing API
```
GraphAPI: Teams に貼り付けた画像の取得

# 背景
Teams での内容を Share に保存するって話が会社であった。
Teams に添付したものではなく、貼り付けの場合、単純に取得出来ないってことだったので調査してみた

# 結論
- [Graph Explorer](https://developer.microsoft.com/en-us/graph/graph-explorer) でなら取得は出来た。
- Power Automate ~~だとそのまま権限不足なのでアプリ登録してカスタムコネクターで、かな？~~
    - v1.0 だとダメだったけど、beta なら hostedContents/{contentId} までは問題なし
    - hostedContents では、Content が取得出来ない為・・結局ダメかな・・
- とりあえずそこまでする気はないので、おしまい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/0faefd8b-7e59-d4db-7d7d-c8a55626c09b.png)

# 取得方法
1. hostedContents で ID を取得<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/4a0d1a2d-6786-0beb-01d5-f63c26c7fceb.png)
1. ID を使って、$value で完了<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7f6d57cc-46d3-ef58-2bbb-99821048f3e2.png)

```uri:sampleUrl
https://graph.microsoft.com/v1.0/teams/{teamId}/channels/{channelId}/messages/{messageId}/hostedContents/{contentId}/$value
```

# hostedContents では Cntent が null なので・・あきらめ
/$value でなら取得可能だけど、Automate じゃ取得は無理。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/bdee2e19-abc4-8584-ce55-c31a48d19070.png)

Teams Action で Post したら表示ぐらいならできる？と思ったけど HTML も Adaptive Card でもダメでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/9e8af985-5687-5761-f946-15f4b397c496.png)


# 参考

https://docs.microsoft.com/en-us/graph/api/chatmessagehostedcontent-get?view=graph-rest-1.0&tabs=http

以下を元に Document 作ってる？（この辺よくわからず）

https://github.com/microsoftgraph/microsoft-graph-docs/blob/main/api-reference/v1.0/api/chatmessagehostedcontent-get.md

https://github.com/MicrosoftDocs/msteams-docs/issues/1561


# あとがき
Power BI のカスタムコネクターでなら取得して表示は可能そう・・・でも使い道が思いつかない
SvelteとSupabaseでアプリ作成

##　はじめに
- 最近流行りのフレームワークを使用し、メモアプリを作成した。
- シンプルな構造で、初学者でも学びやすい。
- 認証機能を追加し、ログイン・ログアウトまで実装した。
- 本記事ではSvelteとSupabaseでアプリ作成・データベース接続までを記事にした。

## 環境
- Mac　11.5.2（2020）
- node v17.2.0

## 問題点
- 編集機能がないため、メモを登録した後削除することしかできない。

## 開発
```sh
mkdir アプリ名
npm init svelte@next アプリ名
- Which Svelte app template?: demo app
- Use TypeScript?: No
- Add ESLint for code linting?: No
- Add prettier for code formatting?: No
cd アプリ名
npm i 
npm run dev
```
## Supabase
### Supabaseとは
- Webの管理画面からDBを作成・管理できるプラットフォーム。
- https://app.supabase.com/

### 使い方
- 登録後orサインイン後、'New project'ボタンをクリック
- Name:○○
- Database Password:　○○
- Region: Nprtheast Asia(Tokyo)
- Princing Plan: Free - $0/month
- 問題なければ'Create new project'ボタンをクリック

### 接続
```sh
touch .env
```
```
<* .env *>
VITE_PUBLIC_SUPABASE_URL=supabase_url
VITE_PUBLIC_SUPABASE_KEY=public_anon_key
```

### Supabase 管理画面
- Setting → APIへ
- supabase_url: Config → URLをコピー
- public_anon_key: Project API keys → 'anon' 'public'をコピー
- .envに貼付

## 参考記事
https://github.com/Kamekure-Maisuke/sva-sample
[Kamekure-Maisuke/sva-sample]

## さいごに
### Supabase 作成したprojectを削除する方法
- 【歯車マーク】Settingsへ
- Delete Projectを選択。
- Are you absolutely sure?：(Type the project name in here):Project Nameを入力。
- I understand, delete this projectを選択。
Terraform CloudでExecution Modeを切り替える

## やりたかったこと
- [terraform cloud](https://cloud.hashicorp.com/products/terraform) で、Execution ModeをRemoteで管理しているが、動作確認のため、Execution Modeを一時的にLocalにしたかった。
- 何かリスクとか副作用がないか心配だった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152020/d42cfb7c-8d8a-7dc7-6e2e-51f9d6670b14.png)


## 結論

- **特に副作用はないっぽいので、適当に切り替えてよし！**
- ただRemote実行時はTerraform Cloud側のvariablesの定義を参照しているので、いきなりLocalにしても、未定義の変数参照したりして、動かない可能性はある
40 代おっさん GASのクラスへのメソッド定義とプロトタイプについて学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## クラスのメソッドの定義

構文

```javascript
メソッド(仮引数1, 仮引数2, ...){
  //処理
}
```

クラスのメソッド定義内でもthisを用いることができる

お試し

```javascript
function toshiki() {
  class Person {
    constructor(name, age) {
      this.name = name;
      this.age  = age;
    }
  

    greet() {
      console.log(`こんにちは、私は${this.name}君です。`);
    }

    isChild() {
      return this.age <= 18;
    }
  }
  const p1 = new Person('利樹', 4);
  p1.greet();
  console.log(p1.isChild());
}
```

＊アロー関数はメソッドの定義には不向き
アロー関数内でthisを使用した場合、外側のスコープでのthisの定義に従うという特性があるので注意！！

## プロトタイプ

クラスから生成されたインスタンスはプロパティとメソッドを持つから、新たなインスタンスを生成するごとに、データを保存するための領域が必要となる。
しかしメソッドはすべてのインスタンスに共通で良いわけだから、インスタンスが複製されて、その分のメモリ容量を確保されればもったいない。

この問題を解決するのがプロトタイプと言う仕組み

どのクラスもprototypeプロパティと言うプロパティをもっている。
そこにメンバーを追加できます。
そのクラスをもとに生成されたインスタンスから参照することが出来る仕組みになっている。

クラスのprototypeプロパティに定義されたメソッドをプロトタイプメソッドよ呼び。
class文何に定義されたメソッドはプロトタイプメソッドになる。

## インスタンスのメソッドの変更

メンバーの変更が可能というなら、メソッドも変更が可能ということになるが
まずはこちらを

```javascript
function toshiki() {
  class Person {
    constructor(name, age) {
      this.name = name;
      this.age  = age;
    }
  

    greet() {
      console.log(`こんにちは、私は${this.name}君です。`);
    }

    isChild() {
      return this.age <= 18;
    }
  }
  const p1 = new Person('利樹', 4);

  p1.greet = function() {
    console.log(`${this.name}はかわいいです。`);
  };
  p1.greet();
  console.log(Person.prototype.greet.toString());
  console.log(p1.greet.toString());
}
```

コンソールログは
22:40:38	情報	利樹はかわいいです。
22:40:38	情報	greet() {
      console.log(`こんにちは、私は${this.name}君です。`);
    }
22:40:38	情報	function() {
    console.log(`${this.name}はかわいいです。`);
  }
になっていたのだが
二つとも異なるものになっている。
つまりこれは、生成されたインスタンスへの変更は、インスタンスのメソッドを直接的に変更したもので、クラスのprototypeプロパティには変更を与えていないことになっています。
ここを注意してください。

## 参考資料

<https://www.amazon.co.jp/s?k=google+apps+script+%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80&adgrpid=110264232688&gclid=CjwKCAiA9aKQBhBREiwAyGP5lSl7AJJLCvOEHb4wQgMlyqW1fll5X8GDTT_Rkd1_soUAyIPMXQr26hoClHEQAvD_BwE&hvadid=553833563682&hvdev=c&hvlocphy=1009076&hvnetw=g&hvqmt=b&hvrand=4378489642044417389&hvtargid=kwd-594191211348&hydadcr=4106_13159878&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_2x1owglv0s_b_p52>
アプリの新規作成~ GitHubへの反映まで

目的
-


1. コマンドでアプリケーションを作成する
-

```
% cd ~/projects
% rails _6.0.0_ new reizoko-app -d mysql
```

 ここで、database.ymlの「encoding: utf8mb4」を「encoding: utf8」へ変更する。

```
% cd reizoko-app
% rails db:create
```

2. GitHubで管理する
-

GitHubで管理するために、新規アプリケーションのリポジトリを作成する。

① GitHub Desktopを用いてローカルリポジトリを作成する
② first commitというコミットメッセージでcommitする
③ アプリケーションと同名のリモートリポジトリを作成する 
(publicにすると、他社がコードレビューできる。「Keep this private」のチェックを外すとできる。）
④ pushする
date-io/dayjsで"TypeError: utils.getYearText is not a function"が発生した場合の対処

# はじめに
Material-UI Pikcersとdate-io/dayjsを使って月名選択の機能を作っていたら、本現象が発生。
その解決方法をメモ

# 発生状況
Material-uiのDatePickerコンポーネントを使うにあたって、その親にMuiPickersUtilProviderを定義する必要がある。
このpropsに、日付管理用のライブラリをして、date-io/dayjsを指定してビルドすると以下のエラーが発生した。

```
TypeError: utils.getYearText is not a function
```

# 解決方法
以下のmaterial-ui-pickerの導入に、material-ui-pickerのv3を使う場合は、data-ioはv1.xを使うように書いてあった。
<https://material-ui-pickers.dev/getting-started/installation#peer-library>
date-io/dayjsの1.xを使う事で解決した。

```
yarn add @date-io/dayjs@1.x
```

npmの場合は以下の通り

```
npm install @date-io/dayjs@1.x
```
"100TB"のファイルサーバにあるファイルを断捨離するために(5) ～ツール作成実践編②～

# はじめに
前回は、ZiDOMA dataで取得したCSVファイルをPythonで読み込む、
Excelを開く、保存する部分の実際の実装方法を紹介しました。

今回は、CSVファイルから読み込んだデータをpandasを使って
分析レポート用に集計した際に使用した主な関数をご紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/770141/bce0b1f8-ce64-08a8-a054-d2d1d1bbbcb9.png)

# "pandas" とは
Pythonでデータ分析を効率的に行うためのライブラリで、以下の作業を容易に行うことができます。

 * (大量な)データの読み込みや並び替え
 * データ分析
 * グラフ化

また、pandasを利用して処理を進めると、非常に高速に処理を行うことができます。

以下では、主に使用した関数をご紹介します。

# 1. データを読み込む

```read_csv.py
# pandasライブラリを使いますよという宣言
import pandas as pd
# CSVライブラリを使いますよという宣言(前回紹介)
import glob

# 読み込んだCSVのデータを"list_file_summary"に格納します
file_summary = glob.glob('data/csv/*_グラフデータ_*.csv')

# CSVファイルからデータ読み込むときの各列項目名
columns_summary = ['グラフタイプ', 'タイトル', 'サイズ', 'カウント', '対象ディレクトリ']

# pandasにデータを入れる箱を用意
df_import_summary = []

# "df_import_summary" に取り込んだデータを以下のルールで取り込むと指定する
for file_s in file_summary:
    df_import_summary = pd.read_csv(file_s, index_col=None, header=0, usecols=columns_summary, encoding='cp932', engine="python")

# file_s読み込んだCSVのデータファイルを1つずつ処理を行う繰り返し処理用に定義
# index_col→CSVファイル内にインデックスが含まれないことを指定する
# header→ヘッダー(データのタイトル)が何行目にあるのか指定する(最初の行は0行目)
# usecols→特定の列のみ取り込む場合は列を指定する(列を指定する場合は、列番号、もしくは列名を指定)
# encoding→文字を指定しておかないと文字化けする場合がある(例えば、Windows環境の場合)
```

# 2. クエリを作成する

```pd_query.py
import pandas as pd

# 1.のcolumns_summaryにあった'グラフタイプ' が "合計" の場合のデータ抽出を行います。
df_file_cover = df_import_summary.query('グラフタイプ == ("合計")')
```

# 3. データをソートする(並べ替え)

```pd_sort.py
import pandas as pd

# 1.のcolumns_summaryにあった'グラフタイプ' が "ファイル所有者" の場合でデータを抽出し、
# ファイルサイズで降順並べ替えたうえで、Top50件に絞ります。
df_file_owner = df_import_summary.query('グラフタイプ == ("ファイル所有者")').sort_values("サイズ", ascending=False).head(50)

# デフォルトは "昇順"なので、どの値を基準にソートするかを指定する
# (ランキングのように降順にする場合は "ascending=False")
# head(50)で50件に絞り込みが可能
```

# 4. Excelに書き込む

```wr_excel.py
import pandas as pd
# Excelライブラリを使いますよという宣言(前回紹介)
import openpyxl

# 書き込み先のシート名を指定する
sheet_file_owner = ExcelBook['シート名']

#ファイルサイズをByteからMBへ再計算
file_size = df_file_owner_fix.iat[y, x] / 1024 / 1024

# 例：2行目、1列目にファイルサイズを入力
sheet_file_owner.cell(row=2, column=1).value = file_size

# エクセルファイルを保存(参考:前回の記事)
ExcelBook.save(ファイル名)

# 整理したデータを表として記載するときはfor文を使用して処理を繰り返します。
```

# さいごに

実際に私自身が作成した際、今回ご紹介した関数を使って作りました。
取り込んだデータを計算したり、並べ替えをするだけで
様々な観点での集計レポートができるようになります。
また、今回はご紹介していませんが、取り込んだデータを使って
グラフを作成することもできますので、いろいろと試される方の参考になれば幸いです。

# 関連記事:
"100TB"のファイルサーバにあるファイルを断捨離するために(1)
https://qiita.com/karin_to/items/8a375f41de0e4f754cfb

"100TB"のファイルサーバにあるファイルを断捨離するために(2)
https://qiita.com/karin_to/items/7e1dab963e0dc0ba2e9b

"100TB"のファイルサーバにあるファイルを断捨離するために(3)
https://qiita.com/karin_to/items/a2ee0d8332f1151b3b87

"100TB"のファイルサーバにあるファイルを断捨離するために(4)
https://qiita.com/karin_to/items/2731295a4d0a8d40e590
Windows11で発生したVBEの全角/半角カタカナ オートコレクト問題をNLSのバージョン変更で対応

Access利用者です。Windows11に移行したらVBEのオートコレクトにやられた話です。
数年前に、[Qiita](https://qiita.com/tfukumori/items/e73cc61529c573966e94)とか[MSDN](https://social.msdn.microsoft.com/Forums/sqlserver/fr-FR/4e6223e2-34d0-4a5f-bb61-109bc28040b6/windows-10-1249612540124721251912531-2004-201973847712391?forum=officesupportteamja)、[はてなブログ](https://mitomoha.hatenablog.com/entry/2020/11/17/010334)で言及されるNLSのバージョンによる問題で困ったことがありました。
(例)使っているデータベースに、フィールド名に半角カタカナを使ったテーブルと全角カタカナを使ったテーブルが存在しています。

    テーブルA
     フィールド名1
     フィールド名2

    テーブルB
     ﾌｨｰﾙﾄﾞ名1
     ﾌｨｰﾙﾄﾞ名2
VBAの記述をしていると"rs!フィールド名1"がオートコレクトにより"rs!ﾌｨｰﾙﾄﾞ名1"などになってしまう事があります。
NLS 6.2の時には問題では無かったのですが、NLS 6.3で全角カタカナと半角カタカナを区別するようになったため、VBAも全角半角を正しく記述する必要があります。
Windows10のときは"rs![フィールド名1]"、"rs2![ﾌｨｰﾙﾄﾞ名1]"のように[括弧で囲む](https://gotan.club/2016/09/16/access%E3%81%AEvba%E3%81%A7%E5%8D%8A%E8%A7%92%E3%81%8C%E5%8B%9D%E6%89%8B%E3%81%AB%E5%85%A8%E8%A7%92%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%95%E3%82%8C%E3%81%A6%E5%9B%B0%E3%81%A3%E3%81%9F%E5%A0%B4%E5%90%88/)ことで、オートコレクトの対象外にする事が出来ていました。

---
ところが、Windows11にしたところ、"[ ]"で括ってもオートコレクトされてしまうようになりました。また、最適化やインポートでも半角が全角(またはその逆)に変わってしまいます。
厄介なことに、開発機(Windows11)では問題なく動作するのに、実行機(Windows10)たちはエラーで動きません。
仕方が無いので、AccdbをWindows10のPCに持っていって手直しをするハメになりました。
後輩R君のアドバイスでNLSのバージョンを下げたら、今のところWindows10(202H)当時のように[かっこで括る方法](https://gotan.club/2016/09/16/access%E3%81%AEvba%E3%81%A7%E5%8D%8A%E8%A7%92%E3%81%8C%E5%8B%9D%E6%89%8B%E3%81%AB%E5%85%A8%E8%A7%92%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%95%E3%82%8C%E3%81%A6%E5%9B%B0%E3%81%A3%E3%81%9F%E5%A0%B4%E5%90%88/)が有効になりました。

---
変更するレジストリキー

    コンピューター\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Sorting\Versions
(既定)の値が"00060403"(NLS 6.4)になっているので"00060305"(NLS 6.3)に変更します。
社内のPCが全てWindows11になれば不要になる対処ですね。
DOTWeenでToUniTaskを使う時にOperationCanceledExceptionが呼ばれない場合がある話

# 初めに
``` C#
await tweener.ToUniTask(cancellationToken:cancellationToken);
```
のようなコードを書いたらcancellationTokenのキャンセル時にOperationCanceledExceptionが発生しませんでした。どうやら引数によって発生の有無が変わるようなので挙動を調べました。

# 環境
- Unity2020.3.19f1
- UniTask 2.2.5

# Tween.ToUniTaskのOperationCanceledException発生の有無
UniTask+DOTWeenでキャンセル処理をしたい場合、ToUniTaskメソッドでcancellationTokenを指定しますが、下のようなコードだと移動中にcancellationTokenがキャンセルされてもOperationCanceledExceptionが呼ばれず、以降の行が実行されて"Done"が出力されます。

``` C#
public class Hoge : MonoBehaviour
{
    private CancellationTokenSource _cancellationTokenSource;
    
    async void Start()
    {
        _cancellationTokenSource = new CancellationTokenSource();
        
        MoveTask(cancellationToken:_cancellationTokenSource.Token).Forget();
        // 1秒後にキャンセル
        await UniTask.Delay(1000, cancellationToken: _cancellationTokenSource.Token);
        _cancellationTokenSource.Cancel();
    }

    private async UniTask MoveTask(CancellationToken cancellationToken)
    {        
        try
        {
            Tweener tweener = transform.DOMove(new Vector3(2, 3, 4), 3);
            await tweener.ToUniTask(cancellationToken:cancellationToken);
        
            Debug.Log("Done");
        }
        catch (OperationCanceledException e)
        {
            Debug.Log(e);
            throw;
        }
    }
}
```
DOTWeenのToUniTaskの引数にはキャンセル時の挙動を決めるtweenCancelBehaviour引数があり、その引数によってOperationCanceledException発生の有無が変わります。

| tweenCancelBehaviour引数 | OperationCanceledExceptionの発生 |
|:-:|:-:|
| Kill(デフォルト) | なし |
| Complete  |  なし |
| CancelAwait | あり  |
| CompleteAndCancelAwait  | あり  |
| CompleteWithSeqeunceCallback  | なし |
| KillAndCancelAwait  | あり  |
| KillWithCompleteCallback | なし |
| CompleteWithSeqeunceCallbackAndCancelAwait | あり  |
| KillWithCompleteCallbackAndCancelAwait| あり  |

例えば下のコードのようにTweenCancelBehaviour.Completeを指定すると、cancellationTokenのキャンセル時にTweenが終了時の状態になり、OperationCanceledExceptionは発生しません。

``` C#
public class Hoge : MonoBehaviour
{
    private CancellationTokenSource _cancellationTokenSource;
    
    async void Start()
    {
        _cancellationTokenSource = new CancellationTokenSource();
        
        MoveTask(cancellationToken:_cancellationTokenSource.Token).Forget();
        // 1秒後にキャンセル
        await UniTask.Delay(1000, cancellationToken: _cancellationTokenSource.Token);
        _cancellationTokenSource.Cancel();
    }

    private async UniTask MoveTask(CancellationToken cancellationToken)
    {        
        try
        {
            Tweener tweener = transform.DOMove(new Vector3(2, 3, 4), 3);
            await tweener.ToUniTask(tweenCancelBehaviour:TweenCancelBehaviour.Complete, cancellationToken:cancellationToken);
        
            Debug.Log("Done");
        }
        catch (OperationCanceledException e)
        {
            Debug.Log(e);
            throw;
        }
    }
}
```
ページ移動するブックマークレット

##動機
- 最下部までスクロールしないでもページをめくりたい
- URL末尾の「/5/」や「?page=5」を「6」にしたり「4」にしたり、入力したり
- 各種サイトの「隣のページ／エントリ／ユーザー」も見たい

##二種類
1. 1ページすすむ・もどる
1. 1ページすすむ・もどる + 任意のページ入力


##コード

#####1. 1ページすすむ・もどる

ブックマーク用

```javascript:
javascript:(()=>{const url=location.href;const res=url.match(/(\=|\/|\?)(\d{1,10})\/?$/)??!1;if(res){const n=parseInt(res[2],10);const tg=confirm('【OK】: next page\nor 【Cancel】: prev page')?n+1:n-1;let newUrl=url.replace(res[0],res[0].replace(n,tg));window.location.href=newUrl}else{alert('not work on this page.')}})()
```

全体

```javascript:
  function turn1page()
  {
    const url = location.href;
    const res = url.match( /(\=|\/|\?)(\d{1,10})\/?$/ ) ?? false;
    if( res ) {
      const n = parseInt(res[2], 10);
      const tg = confirm('【OK】: next page\nor 【Cancel】: prev page') ? n+1 : n-1;
      let newUrl = url.replace( res[0] , res[0].replace( n, tg ) );
      window.location.href = newUrl;
    } else {
      alert( 'not work on this page.' );
    }
  }
```

- - -
#####2.　1ページすすむ・もどる + 任意のページ入力


ブックマーク用

```javascript:
javascript:(()=>{const url=location.href;const res=url.match(/(\=|\/|\?)(\d{1,10})\/?$/)??!1;if(res){const n=parseInt(res[2],10);let tg=confirm(%27【OK】: Next Page\nor 【Cancel】: Input%27)?(n+1):window.prompt(%27【 Input page num! 】\n\nor 【Cancel】: Previous Page%27)??(n-1);let newUrl=url.replace(res[0],res[0].replace(n,encodeURIComponent(tg)));window.location.href=newUrl}else{alert(%27not work on this page.%27)}})()
```

全体

```javascript:
  function turnPageWithInput()
  {
    const url = location.href;
    const res = url.match( /(\=|\/|\?)(\d{1,10})\/?$/ ) ?? false;
    if( res ) {
      const n = parseInt(res[2], 10);
      let tg = confirm( '【OK】: Next Page\nor 【Cancel】: Input' ) ? (n+1) :
        window.prompt( '【 Input page num! 】\n\nor 【Cancel】: Previous Page' ) ?? (n-1);
      let newUrl = url.replace( res[0] , res[0].replace( n, encodeURIComponent(tg) ) );
      window.location.href = newUrl;
    } else {
      alert( 'not work on this page.' );
    }
  }
```
- - -

####利用方法

https://qiita.com/aqril_1132/items/b5f9040ccb8cbc705d04

:::note info
Android版Chromeはブックマーク欄のタップでは動作しないため、自分でつけたブクマ名「いどう」等をアドレスバーに手入力し、サジェスト表示された当該ブクマをタップすると動きます
:::

- - -

読んで下さってありがとうございます:melon:
AWS 認定 高度なネットワーキング – 専門知識(AWS Certified Advanced Networking - Specialty)に合格したので勉強方法を書いておく

AWS 認定 高度なネットワーキング – 専門知識(AWS Certified Advanced Networking - Specialty)に合格したので、勉強方法を備忘として書いておきます。参考になれば幸いです。

職業：現在インフラエンジニア6年目でAWSをメインに設計構築をするようになって、2年くらい。
最近はもっぱらオンプレミスからAWSへの移行などのコンサルをやることが多いです。
AWSをやる前は、VMwareやWindows、Linuxなどいろいろやってましたが、
今では、AWSが得意！と言えるくらいになってます。

他のAWS関連の資格：
　ソリューションアーキテクトアソシエイト(SAA)(2018年取得)
　SysOpsアドミニストレータアソシエイト(SOA)(2019年取得)
　ソリューションアーキテクトプロフェッショナル(SAP)(2020年取得)
　セキュリティ – 専門知識（SCS）(2021年取得)
　デベロッパーアソシエイト（DVA）(2021年取得)
　クラウドプラクティショナー（CLF）(2021年取得)
　DevOpsプロフェッショナル (DOP）(2021年取得）
　データベース - 専門知識 (DBS) (2021年取得)
※記載現在全資格を取得しているのですが、資格取得時の状態です。（サボっていてすみません・・・）
　
https://qiita.com/Regryp/items/0645fb976655262e9229

https://qiita.com/Regryp/items/2066ffca878e1726aa3c

https://qiita.com/Regryp/items/19f85ca4aec1940ca106

https://qiita.com/Regryp/items/228936a4c991ad925254

https://qiita.com/Regryp/items/fe5981bbd5585beb4864

勉強期間:１ヶ月くらい
私の場合、集中して長時間時間を取るということが苦手で、ほぼ毎日３０分〜４０分程度の時間をとってやっていました。

# 試験について
他の方々が難しいと言われていることが多かったため、かなり難しいのかなと思っていたのですが、それほど難しくなかった印象でした。ネットワークにあまり触れたことのないアプリメインの方には難しいかもですが、それほどネットワークに触れて来なかった基盤エンジニアにとってはそれほどでもといった印象です。
また、試験問題を見て感じましたが、少し出題されるアーキテクチャが古いのかなといった印象を受けました。最新のアーキテクチャでは別のソリューションがあるのにと思ったケースが多々あったので、試験自体アップデートされていないのかもしれません。
※最近アップデートされたベータ試験が始まり、２０２２年７月には切り替わるみたいです。旧試験で対策をされている場合はお早めに

# 試験までに何をやるか
### 1.「AWS 認定試験に備える」を参照する
これは基本です。どの試験にも共通しますが、出題範囲、見るべきドキュメント、トレーニングが列挙されています。
基本的に私の勉強方法は以下URLのリンク先を潰していくことがメインとなります。
学習のヒントとして、出題範囲や、参考とするドキュメントなど事細かにリンクが載っていますので、
最初に見ることをおすすめします。

https://aws.amazon.com/jp/certification/certification-prep/

### 2.試験ガイド、サンプル問題を読む
出題される分野、配分、問題の形式をしっかり読みましょう。
配分は以下のとおりです。

分野 1:  ハイブリッド IT ネットワークアーキテクチャの大規な設計および実装 24%
分野 2: AWS ネットワークの設計と実装 28％
分野 3: AWS タスクのオートメーション　8%
分野 4: アプリケーションサービスとのネットワーク統合の構成 14%
分野 5: セキュリティとコンプライアンスの設計と実装 12%
分野 6: ネットワークの管理、最適化、トラブルシューティング　14%

[試験ガイド](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-advnetworking-spec/AWS-Certified-Advanced-Networking-Specialty_Exam-Guide.pdf)
[サンプル問題](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-advnetworking-spec/AWS-Certified-Advanced-Networking-Specialty_Sample-Questions.pdf)

### 3.試験対策本を読む
以下の本を購入しました。一応オフィシャルなガイドみたいです。
中身を読みたくてというよりは、付属している練習問題がみたくて買いました。
https://www.amazon.co.jp/dp/1119439833/ref=cm_sw_r_tw_dp_9RQW8JA8YFPJHQTSR65T


### 4.問題集を解く
aws WEB問題集で学習しようのサイトにて、ANSの問題を2周しました。
やはり、問題集を解くことが一番ためになります。試験で求められる知識をチェックできる、間違えた問題から苦手な分野、深堀りすべきドキュメントが参照できるというところがあるので、一番おすすめです。

https://aws.koiwaclub.com/

Udemyの問題集も購入して解いて見ました。
※セールのときに購入するのがおすすめです。

https://www.udemy.com/course/aws-certified-advanced-networking-specialty-practice-test-g/

以下の無料で公開されているQUIZもちょろっとやりました。
https://www.examtopics.com/exams/amazon/ans-c00/




### 5.ホワイトペーパー、よくある質問、BlackBeltを見る
全体的に苦手な分野を軽く目を通すレベルでよいかなと思います。
私の場合、DirectConnectのBlackBelt、よくある質問を軽く眺めました。

https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/#management-admin

# 最後に
ネットワークちょっとやってたとか、インフラやってるよ〜的な方にはちょうどよい難易度だと思いました。
おすすめです。
attr_writter, attr_reader, attr_accessorについて

まず、この３つのメソッド話題のときに理解していないといけないのはインスタンス変数です。
インスタンス変数とはその名の通り、インスタンスを格納している変数です。(説明になってないので、[こちら](https://qiita.com/wangqijiangjun/items/787c956dab02e516eab9)の記事をご覧ください。)

インスタンス変数というのはクラス外からは参照できないんです。
実際にコードを書いていきます。
```
class User
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
p user.name
=> NoMethodError (undefined method `name' for #<User:0x00000235aa72df80 @name="John">)
```

上のコードを見ていただくと分かるのですが、インスタンス変数はクラス外部からは参照できないんです。

## attr_reader
そこで、クラス外からインスタンス変数を参照したい時に、読みとり専用のメソッドを定義する必要があります。
```
class User
  def initialize(name)
    @name = name
  end

  def name #読み取り用のメソッド
    @name
  end
end

user = User.new("John")
p user.name
=> "John"
```
このように書くことで、Johnという値が出力されました。
でも、この書き方だと参照するインスタンス変数が増えるほど、読み取り専用のメソッドを追加で書いていかなきゃいけないので非常にめんどくさいですね。

そこで登場するのが**attr_reader**です。前置き長くなってしまいましたね笑
これを使うと、以下のように書けます。

```
class User
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
p user.name
=> "John"
```
attr_readerはゲッターメソッドを１行で定義できるので、可読性が上がりますね！

## attr_writter
ここまで読んだ方で勘の良い方はattr_writterの役割は分かるかもしれませんね。
このメソッドの役割は書き込み専用のメソッドを定義できるというところです。現状だと読み込みはできるのですが、nameの値を変更できないんです。実際にエラーを吐かせてみましょう

```
class User
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
user.name = 'Taro'
=> NoMethodError (undefined method `name=' for #<User:0x00000235aaabdc40 @name="John">)
```
現状だと値の変更ができないんです。そこで値の書き込み、もっといえば値の変更や作成をする役割を果たすのが、**attr_writer**です。
実際に書いてみましょう

```
class User
  attr_reader :name
  attr_writer :name
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
user.name = 'Taro'
=> "Taro"
```
上手く動きました！

## attr_accessor
今まで紹介してきた、attr_readerとattr_writerの両方をこなすメソッドが**attr_accessor**です。
「いや、早く言えよ！」って感じですよね笑
２つのメソッドがフュージョンした感じですね
```
class User
  attr_accessor :name
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
user.name = 'Taro'
=> "Taro"
```

attr_readerは、それだけを使うことでインスタンス変数に格納する値を変えたくないときに使えるかもしれないですね。

以上です。何か間違いがございましたら、ご教示いただけますと幸いです。

【参考資料】

https://pikawaka.com/ruby/attr_reader

https://pikawaka.com/ruby/attr_writer

https://pikawaka.com/ruby/attr_accessor
Kotlinx.html

# (日記) Kotlin/JS と HTML についてメモ

# 環境
- Kotlin: 1.6.10

# Project
- IntelliJ > Gradle > Kotlin/JS for browser
- Sources: https://github.com/kyoya-p/samples/tree/master/2022/KotlinJs2022

# Build/Run
```bash
gradlew browserDevelopmentRun
```

# HTML-DSLのサンプル
[build.gradle.kts](https://github.com/kyoya-p/samples/blob/2ccf73191eeb1d19ea76d5c791cdd27cc06b69ea/2022/KotlinJs2022/build.gradle.kts#L15)
[Main.kt](https://github.com/kyoya-p/samples/blob/2ccf73191eeb1d19ea76d5c791cdd27cc06b69ea/2022/KotlinJs2022/src/main/kotlin/Main.kt#L7-L10)

# (その後) kotlinx.html　応用
https://qiita.com/shokkaa/items/15eb53db7914513189a4

# 参照
[Kotlinx.html](https://github.com/Kotlin/kotlinx.html)
[DOM trees](https://github.com/kotlin/kotlinx.html/wiki/DOM-trees)
【filemaker】スクリプトトリガを発火させたのは何か特定したい

## やりたい事

スクリプトトリガが発火したとき、ユーザー操作によって発火したか他のスクリプトのステップにより発火したかを区別したい。
`Get ( コールスタック )`があれば嬉しいが、無い。
`Get ( スクリプト名 )`だと今まさに実行中のスクリプト名しか取れない。

## 解決策

スクリプトトリガ設定時、スクリプト引数に`Get ( スクリプト名 )`を設定する。

## 解説
スクリプト内部でトリガが発火した場合、引数としてそのスクリプト名が渡されるし、ユーザー操作により発火したなら空であるから

```
If [ IsEmpty ( Get ( スクリプト引数 ) ) ]
  # ユーザー操作による発火時の動き
Else
  # スクリプトステップによる発火時の動き
End If
```

とすれば、うまく処理を分ける事ができる。

## より具体的な使用場面

⌘+F などで検索モードに切り替えた時には何か処理をしたいが、[スクリプトステップ 検索実行]などの時には何もしないでほしい。

この場合、レイアウトのスクリプトトリガである"OnModeEnter"にスクリプトを仕込めば、検索モード切り替えの時にスクリプト実行できる。しかし、[検索実行]や[対象レコードの絞り込み]など、直感的にはウインドウモードの切り替えが発生しなさそうなタイミングでもトリガが発火してしまう。

このような場合、上記のように引数に`Get ( スクリプト引数 )`を渡せばユーザー操作とスクリプトステップを区別し、確実にユーザー操作時のみ処理を実行させることができる。

## まとめ

スクリプトトリガを既存のレイアウトに新たに仕込む時、既存のスクリプトと競合して意図しない動きをしてしまうことは多い。
上記の対策である程度回避できる。
dashでheatmapにtext表示ができなかったので最新のplotly.jsを取り込む

# 3行で
stackoverflowみて、解決したのでメモ（2022/02/17現在）。
* 公式サンプルに従ってもheatmapに文字を表示できない
* 原因はdash2.0.0に同梱されているplotly.jsでは命令がサポートされていないこと
* [external_scripts](https://dash.plotly.com/external-resources)で新しいバージョンを読み込ませてやればOK

# サンプル
[GitHub](https://github.com/plotly/plotly.js/)や[公式サイト](https://plotly.com/javascript/getting-started/)で最新バージョンを確認して、ソースコードに埋め込む。

```
app = dash.Dash(
    __name__,
    meta_tags=[{"name": "viewport", "content": "width=device-width"}],
    external_scripts=["https://cdn.plot.ly/plotly-2.9.0.min.js"],
)
app.title = "Dash sample"
server = app.server
```

# 参考
ここで書いてある内容そのままです
* [How to show text on a heatmap with Plotly? - stackoverflow](https://stackoverflow.com/questions/70512660/how-to-show-text-on-a-heatmap-with-plotly)
GoogleSpreadSheetの値をBigQueryで呼び出す

勉強会で参考になったのでその備忘録として

# 目的
SpreadSheetをBigQueryで呼び出す

# 手順

#### SpreadSeheetの準備
こんな感じのSpreadSheetを用意する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/f4018ed9-223e-f424-2e23-bdecedcc0696.png)


#### BigQueryの準備
BigQueryのコンソール上から、DataSetまで作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/4601250b-c504-5c6d-61b3-cfbc4c14d783.png)

#### SpreadSheetのリンクをコピーする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/3d69eee6-33eb-c98a-f341-0cf44a16bdc2.png)


## BigQuery側でテーブルの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/eecd5035-a625-5cd7-6602-d3bb24390512.png)

#### テーブル作成その1
ソース : ドライブ
ドライブｎURIを選択 : SpreadSheetのリンク
ファイル形式 : Googleスプレッドシート
シート範囲 : 任意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/bb6b91b7-5ae3-6069-c709-d674a8be55bb.png)

#### テーブル作成その2
送信先　：プロジェクト名
データセット　：データセット名
テーブル　：任意
テーブルタイプ　：外部テーブル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/bcf15c31-a5f8-4b1f-5939-df11648a6788.png)

#### テーブル作成その3
自動検出　：ON
スキップするヘッダ : 1
あとはチェックなしで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/a40753da-c196-17b3-2a07-6f621d09b3ee.png)

--> テーブルを作成をクリック

####　確認
テーブルが作成されていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/ef219145-5df6-8f21-92b3-966ad11e7e13.png)

#### テーブルの中身を確認
SpreadSheetの中身が表示されることを確認できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/f1fc0183-8ca1-a9e8-c063-e76aa3df1dcb.png)

#### 補足
SpreadSheetで値を追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/45de71ca-7703-80a0-66df-cb96e8615e1e.png)

Select文で追加された項目も表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143249/e95025c9-a115-2f17-a8ed-c05d250fd6be.png)
初心者でもわかる関数型インターフェース（UnaryOperator編）

##はじめに
皆さんはUnaryOperatorについてご存知でしょうか。UnaryOperatorを使用すれば、一律の処理をキュッとまとめることが出来ます。例えば、リストの文字列を全て大文字にするなど使い方次第で色々なことが出来ます。JavaGoldの試験の出題範囲でもあります。そんな、UnaryOperatorについて解説していきます。

##UnaryOperatorとは
UnaryOperatorとは、１つの値を処理して同じ型の処理を戻す処理を表す関数型インターフェースです。例えば、String型の引数を受け取ったら、戻り値もString型の処理を戻すというイメージです。UnaryOperatorは、Funcitionインターフェースのサブクラスで、抽象メソッドであるapplyメソッドを実装しています。それでは、サンプルコードを通して、使い方を解説していきます。

##どのように使うの？
以下のコードは、String型の引数を受け取ってその引数に変数strを加える処理です。
そしてapplyメソッドを使用して、UnaryOperatorで実装した処理を呼び出します。

```Sample.java
public class Sample {
	public static void main(String[] args) {
		String str = "さん、こんにちは";
		UnaryOperator <String> s = x -> x.concat(str);
		System.out.println(s.apply("佐藤"));
	}
}
```

##BinaryOperatorとは
UnaryOperatorでは1つの引数を受け取っていたのに対して、BinaryOperatorは2つの引数を受け取って、引数と同じ型の処理を戻します。

##どのように使うの?
OperatorFactoryクラスで、addメソッドとminusメソッドを作成しています。
このように、処理をまとめておくと再利用性が高くなります。

```OperatorFactory.java
import java.util.function.BinaryOperator;

public class OperatorFactory {
	public static BinaryOperator<Integer> add(){
		return (a,b) -> a+b;
	}

	public static BinaryOperator<Integer> minus(){
		return (a,b) -> a-b;
	}
}
```
OperatorFactoryで作成したaddメソッドを変数opに代入して、applyメソッドで呼び出しています。

```Sample.java
import java.util.function.BinaryOperator;

public class Sample {
	public static void main(String[] args) {
		BinaryOperator<Integer> op = OperatorFactory.add();
		System.out.println(op.apply(10,20));
	}
}
```
##まとめ
UnaryOperatorとは、１つの値を処理して同じ型の処理を戻す関数型インターフェース
BinaryOperatorは2つの引数を受け取って、引数と同じ型の処理を戻す関数型インターフェース
今度こそmacOSで文字化けしないZIPファイルを作る

macOSでOS標準の機能で、適当にZIPファイルを作ってメールした場合、Windowsで開くとかなりの確率で文字化けしています。

文字化けしないためには、コマンドラインでZIPファイル作ると良いみたいです。以下のコマンドは、dataというフォルダを圧縮して、hoge.zipというファイルに圧縮します。

```bash
7z -r a hoge.zip data
```

# p7-zip をインストール

7-zipがインストールされていなければ、以下のコマンドでインストールします。

```bash
brew install p7zip
```

# メモ

なお、zipコマンドでは同様に文字化けしました。

# 圧縮ツールのオプションすぐに忘れる

すぐに圧縮オプションを忘れてしまうので、シェルスクリプト作っておきますか。たぶん、毎回検索するので、使わない可能性大ですが。。。

```bash:mkzip.sh
#!/bin/bash
TARGET=$(basename $1)
7z -r a $TARGET.zip $1
```
Eloquentを使ったLIKE検索機能の作り方

#はじめに
検索結果をモデルコレクションで欲しいためクエリビルダではなくEloquentを使う必要があったのですが、調べるとクエリビルダのものしかヒットしなかったため、今回記事にします。初学者なため瑕疵や不備があると思うので、ツッコミやより良い方法があればどんどんお願いします

#環境
Laravel 8.79.0
PHP 8.1.1

#検索機能
```php:PostController.php
    public function search(Request $request)
    {
        // searchが検索ワードが入力されたフォーム部品 requiredは入力必須のバリデーション項目
        $request->validate(['search' => 'required']);
        // 検索ワード取得
        $search = $request->search;
        // 全角スペースを半角に変換
        $spaceConversion = mb_convert_kana($search, 's');
        // スペースやカンマ区切りで検索ワードを配列に格納
        $wordArraySearched = preg_split('/[\s,]+/', $spaceConversion, -1, PREG_SPLIT_NO_EMPTY);
        // 一つ目の検索ワードをwhereで抽出
        $query = Post::where("title", "LIKE", "%" . $wordArraySearched[0] . "%");
        // 二つ以上検索ワードがあれば抽出
        if (count($wordArraySearched) > 1) {
            for ($i = 1; $i < count($wordArraySearched); $i++) {
                $query->Where("body", "LIKE", "%" . $wordArraySearched[$i] . "%");
            }
        }
        // 検索結果取得
        $posts = $query->get();
    }
```

#参考
リンク内のクエリビルダによる検索機能を参考にし、一部変更しました

https://takuma-it.com/laravel-keyword-search/
vim-fzfを使う

## リポジトリ
https://github.com/junegunn/fzf.vim

## 内容
- nvimの場合、`config/nvim/init.vim`に定義する
- nnoremap
    - ノーマルモードのときのキーマップ

```vimscript

" Plugins
  Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
  Plug 'junegunn/fzf.vim'

" fzf settings
nnoremap <silent> ,f :Files<CR>
nnoremap <silent> ,F :GFiles?<CR>
nnoremap <silent> ,b :Buffers<CR>
nnoremap <silent> ,l :BLines<CR>
nnoremap <silent> ,h :History<CR>
nnoremap <silent> ,m :Mark<CR>
```
poweshellのawk

# awkの場合
test.csvの2番目の項目を表示する。これはこれでなかなか便利

```
awk -F, '{print $2}' test.csv
```

# powershellの場合
csvの項目がa,b,cだった場合

```
import-csv test.csv|select b
```

なあるほどなあ

# csvにheaderが付いていない場合、a,b,cをheaderにする
```
import-csv -h ("a".."c") test.csv|select b
```
【Laravel】エックスサーバーにデプロイするには（メモ）

https://kaiblo.com/%e3%80%90laravel%e3%80%91%e3%82%a8%e3%83%83%e3%82%af%e3%82%b9%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e3%81%ab%e3%83%87%e3%83%97%e3%83%ad%e3%82%a4%e3%81%99%e3%82%8b%e3%81%ab%e3%81%af%ef%bc%88%e3%83%a1/

こちらに移動しました。
【SpringBoot】画像表示する2つの方法（2/2）

#SpringBoot2で画像表示
今回は二つ目の画像表示方法を書いていきます。
<strong>②画像データをBase64に変換しimgタグに直接埋め込む方法。</strong>

今回の画像表示の方が前回のやり方よりもシンプルなので実装しやすいと思います。
一つ目の画像表示についてはこちらから↓
[SpringBoot2で画像表示する2つの方法（1/2）](https://qiita.com/nmaolks/items/985096d22d39c122b0fd)
##全体の流れ
①サーバサイドで画像をバイト列に変換しその後、Base64に変換
②HTMLのimgタグのsrc属性にBase64文字列を埋め込む
##各ファイルを作成
####controllerを作成する
画像ファイルをバイト列に変換後、Base64に変換してます。
下記文字列を追加し画面にデータを渡してます。
`data:image/png;base64,`

```java:ImageController.java
@Controller
public class ImageController {
	@GetMapping("/getImage")
	public String getImage(Model model){
		File fileImg = new File("img/testimg.png");
		try {
			byte[] byteImg = Files.readAllBytes(fileImg.toPath());
			String base64Data = Base64.getEncoder().encodeToString(byteImg);
			model.addAttribute("base64Data","data:image/png;base64,"+base64Data);
		}catch(IOException e) {
			return null;
		}
		return "image";
	}
}
```
####htmlを作成する
`<th:src>`にControllerから受け取ったキーをセット

```java:image.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<title>画像表示</title>
</head>
<body>
	<p>画像表示</p>
	<img th:src="${base64Data}">
</body>
</html>
```
VIMとVscodeでファイルを同期する方法

# VIMとVscodeでファイルを同期する方法


<!-- vim-markdown-toc GFM -->

* [はじめに](#はじめに)
* [同期設定を行う](#同期設定を行う)
  * [Vscode側の設定を行う](#vscode側の設定を行う)
  * [VIMの設定を行う](#vimの設定を行う)
* [参考資料](#参考資料)

<!-- vim-markdown-toc -->

## はじめに

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">VimとVscodeをシームレスに行き来できるようになると快適です。</p>&mdash; あだもふ (@adamof_engineer) <a href="https://twitter.com/adamof_engineer/status/1494274689967214596?ref_src=twsrc%5Etfw">February 17, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

VIMとVscodeの両方を使用した感想として、

- VIM：編集に強い
  - モード変更というVIM特有の機能のおかげで高速で編集することが可能(ただし英語に限る)
- Vscode：新規作成、グラフィカル表示、に強い
  - 1からコードを書く、あるいはコードを追加する場合などに補完する機能が優秀
  - 視覚的にわかりやすくなる機能が豊富

という印象があります。

そんなVIMとVSCodeの両方をいいとこ取りして使いたい。

その場合、同じファイルをVIMとVscodeの両方で開くことになると思います。
けれども、例えばVIMで編集した内容をVscodeに即座に反映してくれないと、使い勝手がかなり悪い。

その問題を解決する方法を見つけたので、ご紹介したいを思います。

想定読者：

- Vscodeを使っているけれどVIMも使いたい。またはその逆。

前提条件：

- VscodeとVIMの両方の設定をいじることができる。
- ファイルを自動保存しても構わない

動作確認：

- [動作を動画で確認する](https://www.loom.com/share/a0065bf4a79a4bf4a4ca1b7142aec956?sharedAppSource=personal_library)

それではVIMとVscodeでファイルを同期する方法について説明します。

## 同期設定を行う
### Vscode側の設定を行う

Vscodeの自動保存を有効にしましょう。

[VSCode | エディターの自動保存の設定](https://www.javadrive.jp/vscode/setting/index2.html)

私は”After Delay” で設定し、1秒毎に保存するようにしています。

Vscode側はこれでOKです。

### VIMの設定を行う

Vimrcファイルに以下を追加してください。

```vim
augroup vimrc
  au!
  autocmd InsertLeave,TextChanged * silent! write
  autocmd FocusGained,BufEnter * :silent! !
augroup END
set autoread
set autowrite
set autowriteall
```

これでOKです。

VIMの設定は、かなり細かく設定することができます。
自分の好みに合わせて変えてください。

## 参考資料

[How does Vim's autoread work? - Stack Overflow](https://stackoverflow.com/questions/2490227/how-does-vims-autoread-work)
windows10のping

# 基本
eth0は有線
wlan0無線

#

https://tarufu.info/windows-ping-response/
https://atmarkit.itmedia.co.jp/ait/articles/1712/21/news018.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/97047a1b-609e-f27b-b4f5-ad3556fd28fd.png)

# windows10 パブリックとプライベートの切替
https://pc.jpita.jp/index.php?QBlog-20200409-1#:~:text=%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%A8%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%92%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88%E3%82%8B%E6%96%B9%E6%B3%95&text=%E6%8E%A5%E7%B6%9A%E6%B8%88%E3%81%BF%E3%81%AE%5B%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%5D%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3,%E3%81%A8%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF%E3%82%92%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88%E3%81%BE%E3%81%99%E3%80%82

# ping受信設定


ファイルとプリンターの共有（エコー要求 - ICMPv4 受信 を設定して、右クリックから「有効化」する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/1d6f4e77-be6e-2f0f-23cb-7b211c1df6b8.png)
bareリポジトリをnon-bareリポジトリに変える

# bareリポジトリとは
https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository

- bareリポジトリは、公開されたリポジトリを管理する人が扱うもの
- 管理ファイルが`リポジトリ名.git`に入っている
    - 普通の（non-bareな）リポジトリなら`.git`という隠しディレクトリになってる
- 他のソースファイルとかはない（チェックアウトされてない）

bareリポジトリを`.git`に改名して`git config core.bare false`すると普通のnon-bareリポジトリになるので`checkout`などの操作ができるみたいです。

# bashでの操作
```bash:bareリポジトリを取ってきてnon-bareにする
git clone --bare <URL等>/foo.git
# foo.git というディレクトリ（bareなリポジトリ）が手に入る
mv foo.git .git
git config core.bare false
```
`foo.git`のディレクトリ名を`.git`にして、configでnon-bareにするだけです。

## 補足
```bash:bareリポジトリを取ってきてnon-bareにする（コメント付き）
git clone --bare <URL等>/foo.git
# ここで git status すると以下のエラー (ここで実行するなら".git"という名でないと認識されないので)
#   fatal: not a git repository (or any of the parent directories): .git
mv foo.git .git
# ここで git status すると以下のエラー (bareで実行すべきでないので)
#   fatal: this operation must be run in a work tree
git config core.bare false
git status
# 成功(checkout等をしてないので全ファイルを削除したという旨の結果が出る)
```

# 使う場面
gitの仕組みが気になった時？
他にはあまりないと思う。non-bareなものが欲しければ普通にcloneすればいいはず。
ただ、bareだと使用できるコマンドに制限があるので「手元になぜかbareなリポジトリだけあって色々調べたい」という場面なら試していいかもしれない。
と思ったけど`git clone <ローカルのパス>`でそのリポジトリをクローンすればいいだけな気もする。

# 参考
https://qnighy.hatenablog.com/entry/2017/02/25/154752

https://qiita.com/devzooiiooz/items/56a02342d9d65d79f6c3

https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-%E9%85%8D%E7%AE%A1%EF%BC%88Plumbing%EF%BC%89%E3%81%A8%E7%A3%81%E5%99%A8%EF%BC%88Porcelain%EF%BC%89
GitHub Actionsで複数のPHPのバージョンとOSでまとめてPHPUnitを動かしてみる

PHPのライブラリなどを開発しているとPHP7.4 / 8.0 / 8.1 on Linux / macOS / Windowsのように複数の環境の組み合わせでテストを実行したい事があると思います。
手元でこれらの環境を作って毎回テストするのはあまりにも効率が悪いので、今回はGitHub Actionsを使って複数の環境でまとめてテストを実行できるようにしてみました。

## 用意するもの
- 手元でPHPUnitが動くようになっているプロジェクト
- GitHubのレポジトリ(publicでもprivateでもよい)
- `composer.json`が存在して`composer install`で必要なライブラリが揃う状態になっているプロジェクト

## GitHub Actionsの設定を入れる
`.github/workflows/phpunit.yml` に以下のYAMLファイルを配置します。おしまい！

**とても簡単ですね。**

今回は、Ubuntu(Linux)とWindowsとmacOSでPHP7.4と8.0と8.1を動かす設定を入れてみます。

```yml:.github/workflows/phpunit.yml
name: tests
on:
  push:
    branches:
      - main
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
jobs:
  phpunit:
    name: PHPUnit (PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }})
    runs-on: ${{ matrix.operating-system }}
    strategy:
      fail-fast: false
      matrix:
        operating-system: [ ubuntu-latest, windows-latest, macos-latest ]
        php-versions: [ '7.4', '8.0', '8.1' ]
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      # Docs: https://github.com/shivammathur/setup-php
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
          extensions: mbstring, dom, fileinfo, simplexml
          coverage: xdebug

      - name: Get composer cache directory
        id: composer-cache
        run: echo "::set-output name=dir::$(composer config cache-files-dir)"

      - name: Cache composer dependencies
        uses: actions/cache@v2
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: ${{ runner.os }}-composer-

      - name: Install Composer dependencies
        run: composer install --no-progress --prefer-dist --optimize-autoloader

      - name: Test with PHPUnit
        run: vendor/bin/phpunit --testdox --colors=always
```

実際に動かしてみると、このような形で実行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41743/dc6da605-bf60-d142-cdb9-1485566e1e30.png)

## さいごに
Public Repositoryの場合はActionsを無料で使用する事ができますが、Privateの場合は無料枠を超える場合は追加で課金が必要なので注意が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41743/0fd28d90-dc34-c761-b7d3-9c309ec2e4c9.png)

https://github.com/settings/billing から見ることが出来るので、使いすぎてないかよく見ておきましょう！(特にこのように複数環境で同時に実行する場合は)

ちなみに、macOSとWindows環境は少々割高(クォータの消費時間はWindowsの場合は2倍で、macOSの場合は10倍でカウントなので)使いすぎには注意が必要です。
javascript64_構造関数（クラス）

構造関数：
構造関数はオブジェクトを作る時に専用の関数です。
構造関数は普通の関数ですが、最初のアルファベット文字は大文字です。

構造関数と普通の関数について、呼び出し方に違いがあります。
例：　function Person(){
     }
構造関数の呼び出し方：
     var per = new Person();
普通関数の呼び出し方：
　　 var per = Person();

構造関数実行の流れ：
1. 新しいオブジェクトを作成します
2. 新しく作ったオブジェクトを関数のthisに設定します.
   構造関数の中にthisで新しいオブジェクトを引用することができます。
   (例：per を　thisに設定します）。
3. 関数の処理を実行します。
4. 新しく作ったオブジェクトを戻り値として返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/81c95c53-6c45-c2c0-c267-0244a18b06f1.png)
引数と設置し、代入することはできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/e00af2f6-2266-36e8-a07a-faa718e02b9b.png)

同じ構造関数を使用し作られたオブジェクトは、インスタンスと呼びます。構造関数のことをクラスと言います。

instanceofを使って、インスタンスはクラスに属しているかをチェックすることができます。
構文：　インスタンス instanceof クラス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/c124675c-1973-3982-8013-342028aea529.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/32c08228-bd92-e38b-d304-4849ce44f5db.png)
必ず覚えておくこと：
構造関数で呼び出す時、thisは新しく作ったオブジェクトです！！
関数で呼び出す時、thisはwindowです。
メソッドで呼び出す時、thisを使った対象はthisになります。