OmniAICreator/Qiita-1.07M huggingface dataset:
【Django】同名でsquashmigrationsしたらshowmigrationsから消えてしまったとき

## 環境
```
$ python -V                              
Python 3.9.1
$ python -m django --version
3.1.5
```

## 起こった問題
こういうマイグレーションがあるとします。

```bash
$ python manage.py showmigrations
user
 [X] 0001_initial
 [X] 0002_user_name
 [X] 0003_auto_20220214_1200
```

`squashmigrations`を使って0002と0003をまとめます。
このとき、`--squashed-name`オプションでまとめた後のファイル名を指定します。

```bash
$ python manage.py squashmigrations user 0002 0003 --squashed-name user_name
Will squash the following migrations:
 - 0002_user_name
 - 0003_auto_20220214_1200
Do you wish to proceed? [yN] y
Optimizing...
  No optimizations possible.
Created new squashed migration /app/user/migrations/0002_user_name.py
  You should commit this migration but leave the old ones in place;
  the new migration will be used for new installs. Once you are sure
  all instances of the codebase have applied the migrations you squashed,
  you can delete them.
```

この後、`showmigrations`でマイグレーションを確認してみると、なんと`user`アプリのマイグレーションが全て消えてしまっています。

```
$ python manage.py showmigrations
user
 (no migrations)
```

`migrate`してみても、何も適用されません。`--fake`をつけても同様。

## 原因
消えてしまったマイグレーションは、単にDjangoから認識されなくなったというだけで、ファイル自体は残っています。
squash後のファイルの中身を見てみましょう。

```0002_user_name.py
# Generated by Django 3.1.5 on 2022-02-14 06:56

from django.db import migrations, models


class Migration(migrations.Migration):

    replaces = [('user', '0002_user_name'), ('user', '0003_auto_20220214_1200')]

    dependencies = [
        ('user', '0001_initial'),
    ]

    operations = [
      # 割愛
    ]
```

`squashmigrations`で作られたマイグレーションには、`replace`属性が追加されます。
この属性で、どのマイグレーションをまとめて作られたのかがわかるようになっていて、このリストにあるマイグレーションは無視されます。

ここが今回の問題の原因です。
`replaces`に含まれるマイグレーションと自分の名前が同じなので（自分を無視する？）、依存関係がぐちゃぐちゃになってしまったようです。

## こう直す
`replaces`属性を削除することで解消しました。
その場合、残った`0003_auto_20220214_1200.py`が実行されるようになるので、こちらも削除しておくこと。

## 参考
[マイグレーション | Django ドキュメント | Django](https://docs.djangoproject.com/ja/3.1/topics/migrations/)
[Django マイグレーション完全に理解した (基礎編) 🍏 - くろのて](https://note.crohaco.net/2018/django-migration/)
40 代おっさん GASの権限と許可‼

## 本記事ついて

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

## スクリプトの共有と権限

GASはクラウドにスクリプトが存在している。
どのユーザーが該当のスクリプトの編集や実行についての権限をもっているのか明確に定められている。

スクリプトの権限レベルは3段階に分かれている
オーナー
編集者
閲覧者

### 実際に付与してみる、

スプレッドシートの右上に共有と緑色のボタンがあるのでクリック

ユーザーやグループと共有画面に来ますので

![ユーザーやグループと共有.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/9b40c6c6-877b-346a-215d-0f4571443b31.png)

黒塗り　自分のアカウント
赤枠　　ユーザー名または相手のメールアドレスを入れる

完了を押してください。

![送信画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/936c71e5-6abd-0e96-21ae-37145f5da6d7.png)

必要であればメッセージを入れて送信を押してください。
メールが届いていると思うので一応確認を！！

## 参考資料

<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>
PowerAutomateのJSONファイルを読み取ると内部サーバーエラー

PowerAutomateでフローからファイル入出力するときの形式として、SharePointリストやExcelファイルよりもJSONファイルに優位性があることがあります。
これは例えばフローAのある処理の結果を利用してフローBが別のある処理を実行するような場合です。

JSONファイルの優位性は：

* 読み書きが高速
* 書き込み中の「中途半端な状態」で参照されるリスクがない
* 日時データの表現（シリアル vs. ISO8601）に関する難しさがない
* 日時データのタイムゾーンに関する難しさがない
* 配列でもマップでも取り扱える
* レコードを構成するデータをカラム（列）毎にアクションの入力欄に設定する面倒がない

──といったところ。

# Problem

ところで、JSONファイルの内容を読み取るために「ファイル コンテンツの取得」ないし「パスによるファイル コンテンツの取得」アクションを使用していると、次のようなエラーが発生してしまうことがあります：

> InternalServerError. 内部サーバー エラーが発生しました。追跡 ID は、'3f1bf9e6-6b4b-4fc5-bceb-625ad746183a' です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/9e15a671-8eb7-0156-cc4b-825b763dab53.png)


# Solution

「内部サーバーエラー」では原因がまったくわからないわけですが、私が遭遇した事例ではあれこれ試した結果、以下の条件（AND）が満たされた場合にエラーとなることがわかりました：

1. JSONのルート・レベルが配列（`[...]`）
1. アクションの「コンテンツタイプの推論」が「はい」（`true`）

ルート・レベルをオブジェクト（`{"foo": [...]}`）にするか、「コンテンツタイプの推論」を「いいえ」（`false`）にすると、このエラーは発生しなくなります。

「コンテンツタイプの推論」を「いいえ」（`false`）にすると当然拡張子によるコンテンツタイプの推論が行われなくなるので、アクションの出力形式は「JSON形式のデータを内容とする文字列」となります（`"[...]"`）。
このためフローの後続アクションでオブジェクトとして利用する場合は、`json(...)`関数でデシリアライズを行う必要があります。
【Rails】 Webpacker::Manifest::MissingEntryError in

## エラーの内容
Webpacker::Manifest::MissingEntryError in ooo#xxx
![スクリーンショット 2022-02-14 16.12.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687433/ef6ce708-e2c5-7447-3bac-7f9c51477ba5.png)

## 原因
webpackでコンパイルしていないことです。このため、webpackでコンパイルすれば解決します。

## 解決方法
```sh
$ rails webpacker:install
```

# 上記のコマンドで以下のログが出たら
```
Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/
Exiting!
```

以下のコマンドをしてやる

```sh
$ npm install --global yarn

# installの確認
$ yarn --version
$ rails webpacker:install
```
## 参考
- https://prograshi.com/framework/rails/webpackermanifestmissingentryerror/
- https://discuss.rubyonrails.org/t/i-cant-solved-webpacker-missingentryerror/79604
【反変性・共変性】とあるList<子クラス>をobjectに突っ込み、あとで親クラスとしてforeachしたい

## 背景
若干ハマったけど解決できたのでメモがてら共有させていただきます。

## 環境
OS: Windows 10 Pro
IDE: Visual Studio 2017 Enterprise Version 15.9.40
Target Framework: .NET Framework 4.7

## 概要
親クラス(Parent)を継承した複数の子クラス(Child1~3)のListをポリモーフィズム的に処理したく、
保持用クラス(Hoji)のobject型変数(obj)に突っ込んで、List<Hoji>として保持しておいた。
その後、List<Hoji>をforeachで反復処理しようとした際に、objからforeachで列挙可能な形に変換するのにちょっと躓いた話。

## コード
```C#:定義
// 親クラス
class Parent
{
    public string Name { get; set; }
}

// 子クラス(1~3)
class Child1 : Parent { }
class Child2 : Parent { }
class Child3 : Parent { }

// 保持クラス
class Hoji
{
    public object obj { get; set; }
}
```

```C#:準備
// 各子クラスに要素を持たせる。
List<Child1> childList1 = new List<Child1>
{
    new Child1 { Name = "aaa" },
    new Child1 { Name = "bbb" },
    new Child1 { Name = "ccc" }
};

List<Child2> childList2 = new List<Child2>
{
    new Child2 { Name = "あああ" },
    new Child2 { Name = "いいい" },
    new Child2 { Name = "ううう" }
};

List<Child3> childList3 = new List<Child3>
{
    new Child3 { Name = "111" },
    new Child3 { Name = "222" },
    new Child3 { Name = "333" }
};

// 保持用リストに格納
List<Hoji> hojiList = new List<Hoji>
{
    new Hoji { obj = childList1 },
    new Hoji { obj = childList2 },
    new Hoji { obj = childList3 },
};
```

```C#:処理
// こうしようとした
foreach (var hoji in hojiList)
{
    foreach (var child in hoji.obj as List<Parent>)
    {
        Console.WriteLine(child.Name);
            // ⇒ System.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません。
    }
}

// こうすればできた
foreach (var hoji in hojiList)
{
    foreach (var child in hoji.obj as IEnumerable<Parent>)
    {
        Console.WriteLine(child.Name);
            // ⇒  "aaa"
            //    "bbb"
            //    "ccc"
            //    "あああ"
            //    "いいい"
            //    "ううう"
            //    "111"
            //    "222"
            //    "333"
    }
}
```

## 感想
正直、なんでできるのかまで調べる余裕がなくてわかってません。
いろいろ試した結果、IEnumerableでできたってことは遅延評価が関わってるのかなーってとこで止まってます。
気が向いた方は教えていただけると幸いです。

## 追記(2022-02-15)
@htsign さんからのコメントで
[反変性・共変性](https://ufcpp.net/study/csharp/sp4_variance.html) の問題だと判明しました！
【Mapbox Style Specification】Sourcesと Layers の概念説明

## Mapbox Style Specificationとは
[Mapbox Style Specification] (https://docs.mapbox.com/mapbox-gl-js/style-spec/)を 簡単に言うと、Mapboxを用いてマップのスタイリングをする際のJSON オブジェクトやそのプロパティ等の書き方について記載したルールブックのことです。

![スクリーンショット 2022-02-14 15.18.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467847/5dbfc719-c498-91b4-bd97-fb310ae145bf.png)


[Mapbox Studio](https://www.mapbox.jp/mapbox-studio)を用いてGUIでマップデザインをすることも可能ですが、Mapbox Style Specificationは以下の人を対象に作られています。

```
- Mapbox Studio を使用せず、マップスタイルを行いたい上級デザイナーやカートグラファーの方

- Mapbox GL JS または Mapbox Maps SDK for Android のスタイル関連機能を使用するエンジニア

- Mapbox スタイルを生成または処理するソフトウェアエンジニア
```

Mapbox Style Specificationには様々なオブジェクトが用意されており、その中でも[Sources](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/)と [Layers]( https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/)の概念の理解は大変重要になってきます。

今回は、 数あるオブジェクトの中でもsources と layers に絞って説明をしていきます。

## Sourcesとは
Sourcesでは、**"マップに描画したい素材を指定する"**という作業を行います。
基本的な記述方法は以下の通りです。

```
 sources: {
"任意のソース名": {
    "type": "タイプ名", // 使用する素材の種別をここに記載
    "tiles": [
        "http://a.example.com/tiles/{z}/{x}/{y}.pbf",
        "http://b.example.com/tiles/{z}/{x}/{y}.pbf"
    ] 
   "url": "http://api.example.com/tilejson.json"

　　　　　// "tiles"もしくは"url"どちらかを用いて記述すること。
  //　　"tiles"と"url"両方記載してはダメ🙅
},
},
```
> **type** で指定できるもの

"type" では指定する素材の種別を記述する必要があります。
"type"で指定できる種別はvector, raster, raster-dem, geojson, image, video です。
つまり、Mapboxを用いて地図コンテンツを作る場合は、使用する素材を上記のフォーマットに修正してあげる必要があります。シェープファイル等は使えないので注意しましょう。

複数の素材を重ねてレイヤー式に地図を描画する場合はSourcesで、すべての素材を指定してあげる必要があります。
ここで、指定を行わない素材は地図に描画することができないので注意しましょう。

上記のコード例は最低限の記載となっています。
より細かいオブジェクトや記載方法等は[こちら](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/)を参考にしてみてください。

## Layersとは
Sourcesでマップに描画したい素材の指定をおこないました。Layersではその素材を**どのような順番で並べるか（レイヤーにするか）**を決めていきます。

基本的な記述方法は以下の通りです。

```
"layers": [
  {
    "id": "レイヤー1", //任意のID名をつける
    "source": "任意のソース名", //使用する素材のSourcesで決めたソース名を記述
    "source-layer": "water", //使用する素材がベクトルタイルなら記述が必須。それ以外なら記述する必要はなし。
    "type": "fill", // 
  },
 {
    "id": "レイヤー2", //任意のID名をつける
    "source": "任意のソース名2", 
    "type": "fill", // 
  },
]
```
"layers"では後に記述するものほど、高レイヤーとして表示されます。
つまり、上記の例だと "レイヤー1" が下になり "レイヤー2" が上に表示されるマップとなります。

![レイヤー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467847/ed47ee84-4b54-bb69-0357-2297d10a0d82.png)


"source-layer"は使用する素材がベクトルタイルで合った時のみ記述します。raster, raster-dem, geojson, image, video の場合は記述する必要はありません。

Layersの"type"では "fill", "line", "symbol", "circle", "heatmap", "fill-extrusion", "raster", "hillshade", "background", "sky"を指定することができます。

"source"で記述した素材が"fill", "line", "symbol", "circle", "heatmap", "fill-extrusion", "raster", "hillshade", "background"のどれに当たるのかをここで指定してあげましょう。

各typeの詳細は以下の通りです。
![スクリーンショット 2022-02-14 16.01.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467847/15fcbdc2-f65d-7192-f08d-c28b91bd03eb.png)

## まとめ
描画に必要な素材を**Sources** で記述し、素材の並べ順を**Layers**で記述する。

文頭で書いたとおり、Style Specificationには様々なオブジェクトが用意されています。SourcesとLayersの理解ができた方は、これ以外の様々なオブジェクトに挑戦してみましょう！
2か月でCCNAを取得するための勉強法

# はじめに
2021年4月下旬にネットワークエンジニアの登竜門的な資格である「CCNA（Cisco Certified Network Associate）200-301」を取得しました。
CCNAに向けた勉強を始めたのは2021年3月からだったので、**2か月間**で取得できました。
その時どのような勉強をしたのか最近聞かれることが多くなってきたので、備忘録的にまとめたいと思います。
# 試験概要
約100問、120分です。合格ボーダーは公には発表されていませんが、8割5分くらいとれればまず合格と言われており、試験終了後すぐに合否がわかります。私は1000点中890点くらいでした。
CCNAには有効期限があり、3年経つまでに試験を受け直さないと失効します。その代わり資格を持っているということは最新の知識を持っていることの証明になります。
# 受験方法
[ピアソンVUE](https://www.pearsonvue.co.jp/Clients/Cisco.aspx)から自分の受けたい日に試験予約をして、最寄りのテストセンターで受験しました。
# 試験形式
選択問題、ドラッグアンドドロップ問題が出題されます。
※私の場合は上記の問題だけでしたが、試験改定前（2020年2月以前）の試験では他にも入力問題、シナリオ問題、シミュレーション問題というのも出題されていたみたいです。これらの問題の廃止が公式に発表されているわけではないので、念のため対策は必要かと思います。
# 勉強方法
横に、試験時の点数890点を母数として、その勉強のおかげで何点くらい獲得できたかを記載します（イメージです）。
※なお、①は基礎的な内容であるため得点を記載していません。
①[1週間でCCNAの基礎が学べる本](#1週間でCCNAの基礎が学べる本) 
②[トレノケート株式会社の研修](#トレノケート株式会社の研修) ー 445点獲得！(50%)
③[Ping-t](#Ping-t) ー 267点獲得！(30%)
④[CCNAイージス](#CCNAイージス) ー 133点獲得！(15%)
⑤[シスコ技術者認定教科書](#シスコ技術者認定教科書) ー 45点獲得！(5%)
### 学習の流れ
3月上旬：①1週間でCCNAの基礎が学べる本
3月下旬：②の研修
4月上旬：③～⑤を駆使して試験範囲全て網羅＋GNS3で仮想ネットワーク構築（詳細は後述）
4月下旬：ひたすら③Ping-t → 試験
### 1週間でCCNAの基礎が学べる本
まず、ネットワーク初心者の方は[1週間でCCNAの基礎が学べる本 第3版](https://www.amazon.co.jp/1%E9%80%B1%E9%96%93%E3%81%A7CCNA%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8C%E5%AD%A6%E3%81%B9%E3%82%8B%E6%9C%AC-%E7%AC%AC3%E7%89%88-%E4%B8%80%E9%80%B1%E9%96%93-%E5%AE%AE%E7%94%B0-%E3%81%8B%E3%81%8A%E3%82%8A/dp/4295010731/ref=pd_lpo_2?pd_rd_i=4295010731&psc=1)という書籍が参考になると思います。
私の場合は、この内容をノートにまとめてから以降の勉強を始めました。
### トレノケート株式会社の研修
[トレノケート株式会社](https://www.trainocate.co.jp/)の「Implementing and Administering Cisco Solutions (CCNA) v1」という5日間の研修を受けました。
わかりやすい解説でよく理解できました。ただ、本研修ではCCNAの全ての試験範囲をカバーしていなかったので、その部分については自分で勉強しました。
### Ping-t
[Ping-t](https://ping-t.com/)というWeb問題集です。問題量、解説ともに大ボリュームであるため、非常に役立ちました。
問題は無料会員だと400問、有料会員になると800問以上解くことができます。私の場合は有料会員になり、全ての問題を1回以上正解してから挑みました。
### CCNAイージス
[CCNAイージス](https://www.infraexpert.com/info/ccnaz7.html)というWebテキストです。基本から応用まで広い分野の技術について詳しく解説がなされているので、わからない概念はこのWebサイトを見て理解しました。
難しい分野も掲載されていますが、CCNAだけでなくCCNP（CCNAの次にとるような資格試験）の範囲もカバーしているので、CCNAをとるためだけであれば全ての分野を理解しなくても大丈夫です。
### シスコ技術者認定教科書
[シスコ技術者認定教科書 CCNA 完全合格テキスト&問題集[対応試験]200-301](https://www.amazon.co.jp/%E3%82%B7%E3%82%B9%E3%82%B3%E6%8A%80%E8%A1%93%E8%80%85%E8%AA%8D%E5%AE%9A%E6%95%99%E7%A7%91%E6%9B%B8-CCNA-%E5%AE%8C%E5%85%A8%E5%90%88%E6%A0%BC%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E5%AF%BE%E5%BF%9C%E8%A9%A6%E9%A8%93-200-301/dp/4798165778)というテキスト兼問題集です。CCNAイージスと併用して、①の研修でカバーされていない範囲の勉強に役立ちました。
# 受験に向けた注意点、アドバイス
・試験問題は英語を直訳したような文章が見られ、そもそも何を聞かれているのか意味が分からない場合があります（Cisco語と言われています）。私の場合は分かりにくいところはありましたが聞いていたほどではなく、Cisco語のせいで失点した問題はなかったと思います。
・学んだ内容をノートにまとめていくのがオススメです。そうすれば知識の定着が早まりますし、現場に帰ったときも参考になります。
・設定コマンドについて問われることが多いので、実際にルータやスイッチのコンソールから設定をする経験が必要です。実機を触るのが難しければ[GNS3](https://www.gns3.com/)などのソフトウェアを使って下さい。私の場合は、実機も仮想も両方やりました。
具体的に設定した例としては、以下の通りです。
ネットワーク疎通、VLAN、CDP、STP、HSRP、ルーティングプロトコル、WAN、ACL、DHCP、NAT、リンクアグリゲーション、ポートセキュリティなど。
# おわりに
ネットワークに関するスキルは、全てのエンジニアに必要なものだと思います。実際、仕事をしていて資格を取得しておいて良かったと思う場面も多いです。
ネットワークの基礎を身につけるのには最適な資格だと思いますので、ぜひ頑張って取得してください。
ansible-playbook を check 無しで叩いた場合の保険 

## 概要
テストのつもりで ansible-playbook を叩いたところ、
オプションの `--check` を付け忘れ、うっかり適用してしまった！

という事故を防ぐための小技を紹介します。

### 対象とする読者
+ Ansible で自動化を進めている方
+ ansible-playbook の本番適用時に確認 STEP を入れたい方
+ 自分のメモ用

### ansible-playbook とは？
Ansible は構築管理ツールの一種で、
サーバの自動構築などを行う事が可能です。

これを使うためには、python と yaml をベースにした、
独特な文法でコードを記述する必要があります。

ansible-playbook は Ansible の適用作業を行うための CUI コマンドです。


## 詳細
### 解説
ansible-playbook での本番適用時に
確認文言を出す＆意図しない実行なら終了させる仕組みです。

具体的には、pause モジュールで適用を中断し、
よくある「適用しますか」的な確認文言を出します。

これに "yes" という文言で応えた場合のみ、後続の処理を継続。
それ以外の文言なら、fail モジュールで強制終了する、という仕組みです。


### コード例
```
# check 無しで実行した場合は確認文を出す
- name: confirm running
  pause:
    prompt: >-
      適用するなら yes, 終了するなら yes 以外を入力してください
      ◆ check mode ではありません！
  register: result1
  when: not ansible_check_mode

# 確認に対する入力が yes 以外なら終了する
- name: abort running
  fail:
    msg: "Task is aborted"
  when: (not ansible_check_mode) and (result1.user_input != 'yes')
  run_once: yes
```


### あとがき
私の現場では Ansible が日常的に使われています。
適用のチェックを行う場合、
本来なら検証環境でやるべきなのでしょうが、
本番環境でチェックした方が、環境差異の確認もできて何かと都合が良いのです。

しかし、当然本番環境なので、コマンド入力を誤れば、
前述の通り うっかり 適用してしまいます。
（人間だもの、コピペでもミスはあるんです）

これを防ぐ方法はないものか、と考え、
この方法を作りました。

考えれば、もっといい方法はあるかもしれません。
40 代おっさん GASのスクリプトエディタの機能をまとめて見た‼

## 本記事ついて

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

## スクリプトエディタの機能

### 候補の表示

GASでは大・小文字を区別されるため、エラーに注意

Ctrl+spaceで候補が出る

### 検索

Ctrl+Fで検索バーを表示
バーにキーワードを入れるとハイライトされる。
Enterで次に、shift+Enterで前に移動

### 置換

Ctrl+H

などなど色々あるみたいです、

## ログとデバック

### 実行ログ

実行をすると下に実行ログが出る

左側サイドバーにある三本線を押すと実行数が見れる。

## デバック

実行のとなりにデバックがある。
ブレイクポイントを設置するとそこまでデバックしてくれる。

### デバッカ
再開　デバック実行を再開
ステップオーバー　一行ずつ実行、呼び出した関数では一時停止しない
ステップ員　一行ずつ実行、呼び出した関数でも一時停止する
ステップアウト　現在の関数の最期まで実行

## 参考資料

<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>
VSCodeで.twilioserverlessrcをJSON5と認識させる

JSON5 syntax機能拡張を入れて
https://marketplace.visualstudio.com/items?itemName=mrmlnc.vscode-json5

設定にこう書けばOK

```json:settings.json
{
  "files.associations": {
    ".twilioserverlessrc": "json5"
  }
}
```

以上 :smile: 

参考: https://qiita.com/mobilebiz/items/0b599d31b64e62873c7a
【Azure】Linux系VMのログイン用パスワードが忘れてしまった時

#シリアルコンソール
Azureでは、シリアルコンソール方法で、VMに接続できる仕組みがあります。
シリアルコンソールについて：

https://docs.microsoft.com/ja-jp/troubleshoot/azure/virtual-machines/serial-console-overview

#VMのパスワードが忘れてしまった時
もしVMのパスワードが忘れてしまった場合は、下記の方法で、VM内のローカルカウントユーザーのパスワードをリセットすることができます。
前提はAzure Cliが利用できることです。

```
az vm user update \
  --resource-group myResourceGroup \
  --name myVM \
  --username azureuser \
  --password myNewPassword
```

https://docs.microsoft.com/ja-jp/azure/virtual-machines/extensions/vmaccess#reset-password

#VM諸設定によりSSHで入れない時
例えはsshdのconfigファイル編集により、失敗してしまい、sshできない場合は、シリアルコンソール経由して、シリアルコンソールでまずsudo権限を持つユーザーを作成し、その後シリアルコンソール上で色々編集できます。

管理者権限を持つユーザーの作成

```
az vm user update \
  --resource-group myResourceGroup \
  --name myVM \
  --username myNewUser \
  --ssh-key-value ~/.ssh/id_rsa.pub
```

その後、上記で作成したユーザーからシリアルコンソールでいろいろ操作できればと思います。

操作後に、一時的に作成したユーザーの削除を忘れずに

```
az vm user delete \
  --resource-group myResourceGroup \
  --name myVM \
  --username myNewUser
```

参考URL：

https://docs.microsoft.com/ja-jp/azure/virtual-machines/extensions/vmaccess#reset-password
Salesforceのフローで起きたUNABLE_TO_LOCK_ROWをループ処理で解決してみた

# この記事はなに？
Salesforceのフローにて、レコードを更新する処理を走らせた際に、`UNABLE_TO_LOCK_ROW`のエラーが発生したため、その原因と対処方法を記載した記事になります。

# 元々どんな処理を組んでいたか

スケジュールトリガフローにて、デイリーでキャンペーンメンバーのレコードを起点に、リードとキャンペーンメンバーのレコードを更新する処理を組んでいました。(イメージ画像は、わかりやすくするために簡略化しています)
![スクリーンショット 2022-02-14 14.59.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311026/20f9073e-7be8-1027-b8c6-b198aab9a26c.png)


# エラー内容と発生原因

公式のヘルプによると、

> UNABLE_TO_LOCK_ROW エラーは、更新処理Aが更新処理を実行しようとした対象レコードが別の更新処理Bから更新処理を実行中であり、データの整合性を保つ為にロックされているために更新処理 A がロックの解放を待機する状態となり、待機時間の上限値を超過して待機してしまった際に発生するエラーとなります。

と書かれています。
今回の事例だと、リードとキャンペーンメンバーが1:Nの関係になっており、キャンペーンメンバーAがリードAを更新している途中で、キャンペーンメンバーBもリードAを更新しようとしてエラーが発生していました。(このエラーが起きるまで、レコードの更新処理は1レコードずつ処理されると思っていたのですが、実は並列で実行されていることを知りました)

# 対処方法

最初に更新対象のキャンペーンメンバーのコレクションを作った上で、ループ処理で1レコードずつ処理する方式に変更しました。
![スクリーンショット 2022-02-14 15.09.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311026/23f9d5ac-099a-36ff-1476-12a37e1470a7.png)

これにより、同時にリードが更新されることがなくなったため、無事`UNABLE_TO_LOCK_ROW`のエラーを解決することができました。

# 補足情報

当初、トリガーの起点オブジェクトをリードにすれば解決できると思っていたのですが、キャンペーンメンバーは特殊なオブジェクトのようで、他のオブジェクトからの参照はできない仕様になっていたため、リードを起点にすることを断念しました。
[公式リファレンス](https://help.salesforce.com/s/articleView?id=sf.overview_of_custom_object_relationships.htm&type=5)

# おわりに

ここまで読んでくださりありがとうございました。
今回のエラー対応を通して、レコード更新の仕組みとループ処理の使い所を理解することができました。
フローは便利なのですが、如何せん処理部分がブラックボックス化されていたり、リファレンスの日本語が難解だったりと躓く箇所がいくつもあるので、今後も新しい発見があれば記事に起こしていこうと思います。
CURLコマンドを使ってfreee APIにアクセスする



# アクセストークンの取得方法

これが　先ほどのauthorization code　を取得する方法みたい。

アクセストークンを取得するためには、「Webアプリ認証用URL」（https://accounts.secure.freee.co.jp/public_api/authorize?client_id=${お客様のClient ID}&redirect_uri=${お客様のコールバックURI}&response_type=code）にて認証コード（Authorization code）を取得し、それを用いたhttpリクエストを送る必要があります。認証コードの有効期間は10分です。

はまった。${}は要らんみたい。

```
https://accounts.secure.freee.co.jp/public_api/authorize?client_id=898546c46ca42gh6960e1a6579327e629706050978yx83961a1c46be3cec5f78&redirect_uri=urn:trgf:wg:oauth:2.0:oob&response_type=code
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fd9ac5fb-6502-e975-31c6-3d2dc4cd85f0.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e78c1479-dd02-1779-9670-4295bd547a5e.png)


使ったCURLコマンド
```
curl -s -S --compressed -tlsv1.2 https://accounts.secure.freee.co.jp/public_api/token -i -X POST -H 'Content-Type:application/x-www-form-urlencoded' -d 'grant_type=authorization_code' -d 'client_id=898546c46ca42gh6960e1a6579327e629706050978yx83961a1c46be3cec5f78' -d 'client_secret=58b557e2e6577d4b627a7a217bc7856891f3d586cd38ec0502cebfe7c4730fc7'   -d 'code=c173f5exc8e5208320ddfa86db66c973dba895fcbcdd704265c036f1b52e6rf9' -d 'redirect_uri=urn:trgf:wg:oauth:2.0:oob'
```


無事アクセストークンが取れました。

```
{"access_token":"xYzxccb3f155c9ab924f7232f449703d94777d22d1dcb3039908d501b3bb85853","token_type":"bearer","expires_in":86399,"refresh_token":"xced554043f399093315f61d5af11771716c41bf678a60035203ed709267d93","scope":"default_read accounting:account_items:read accounting:companies:read accounting:deals:read accounting:docs:read","created_at":1644818713}
```

# freee APIを使ってアクセスしてみます。

アクセストークンを使って実際にデータを取ってみよう。

```
curl -s -S --compressed -tlsv1.2 https://api.freee.co.jp/api/1/companies -i -X GET   -H 'Authorization:Bearer xYzxccb3f155c9ab924f7232f449703d94777d22d1dcb3039908d501b3bb85853' -H 'Content-Type:application/json'
```

結果です。jsonだ。Content-Type:application/xml としたけど変化なし。

```
{"companies":[{"id":1588789,"name":"","name_kana":"","display_name":"〇電機株式会社","role":"admin"},{"id":2014076,"name":"","name_kana":"","display_name":"〇電機株式会社2","role":"admin"},{"id":2080611,"name":null,"name_kana":null,"display_name":"△プラン: 開発用テスト環境","role":"admin"}]}
```

注意)ここでの例は本物に似せた実際とは違うIdを使っています。

# エラーメッセージ。

+ {"error":"unsupported_grant_type","error_description":"この認可グラントのタイプは認可サーバではサポートされていません。"}
${}があったためだ...


+ {"error":"invalid_grant","error_description":"指定された認可グラントは不正か、有効期限切れか、無効か、リ ダイレクトURIが異なるか、もしくは別のクライアントに適用されています。"}

まだ有効である時に　先ほどのauthorization codeを使ってサクセストークンを取得しようとしたからかな？

# アクセストークン等の自動取得(変数に）するための予行演習。

jqを使ってname形式に変換できればいいんですがね。

なんかごちゃごちゃしていますが、以下のようにすれば変数として使えそうです。

```
| jq . | sed -e 's/"//g' | sed -e 's/://g' | sed -e 's/,//g' | sed -e 's/{//g' | sed -e 's/}//g' | sed '/^$/d' | sed -e 's/^[ \t]*//' |
cat > $tmp-loginInfo

access_token=$(nameread access_token $tmp-loginInfo)
```

# 以前の設定のままで接続してみると

{"message":"アクセスする権限がありません","code":"expired_access_token"}

さすがですねぇ、トークンの再作成が必要です。
【Project Euler】Problem 87: 素数のべき乗の和

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 87. 素数のべき乗の和

原文 [Problem 87: Prime power triples](https://projecteuler.net/problem=87)


**問題の要約：素数の2乗・3乗・4乗の和で表せる数が$5*10^7$未満でいくつあるか求めよ**

50未満では以下の4個だけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/c97cca7f-d007-4457-50c9-62238a1d98b8.png)


単純に全探索します。同じような処理が繰り返されるので再帰関数で実装しました。重複を除くためにセットを使っています。

```python 
import sympy
def countPPT(ppt, pw, PPTmax):
  if pw == 1:
    if ppt < PPTmax: 
      pptSet.add(ppt)
    return 
  for p in Primes:
    ppt1 = ppt+p**pw 
    if ppt1 >= PPTmax: break
    countPPT(ppt1,pw-1, PPTmax)
  return 

PPTmax, pptSet = 5*10**7, set({})
Primes = list(sympy.primerange(2,int(PPTmax**(1/2))))

countPPT(0, 4, PPTmax)
print(f"Answer: {len(pptSet)}")
```

（開発環境：Google Colab）
chart.jsのstepSizeはプロパティ名の小文字・大文字に注意

##chart.jsの目盛り数が設定できない問題
chart.jsで5目盛りのレーダーチャートを作ろうとしてstepSizeプロパティをいじりまくるのだけれども、なぜか5目盛りにならない。目盛り量がすごいことになった状態のままうんともすんともいわない。
![スクリーンショット 2022-02-14 14.56.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324551/07c2d79d-f418-078f-f303-50076c2df3b5.png)


##原因
めちゃくちゃ初歩的な原因でした。**プロパティ名を正規表現「stepSize」にしていなかった**ことが原因。
それまで「StepSize」と頭文字を大文字にしてしまっていたために設定できていなかったようですー。


```
options: {
    scale: {
      ticks: {
        label: false,
        min: 0,
        max: 5,
        stepSize: 1,
        showLabelBackdrop: false,
        fontSize: 0,
        color: '#eee',
      },
        gridLines: { 
            display: true,
            borderWidth: 2,
            color: "#ddd"
        }
    },
    scales: {
      xAxes: [{
         display: true,
         stacked: false,
         gridLines: {
            display: false
         },

      }]
    },
    legend: {
        display: false
    },
    tooltips: {
        enabled: false
    }
}
```

以上のoptions記述で解決！
![スクリーンショット 2022-02-14 15.07.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324551/7899d293-df07-5b6b-233a-144b4dec8ae4.png)


私はなかなかこれに気づかずハマっていたので、同じ悩みをもった方のもとに届きますように。

##参考リンク
- chart.js 公式サイト：https://www.chartjs.org
- レーダーチャートのプロパティ設定に参考にしたサイト：http://www.kogures.com/hitoshi/javascript/chartjs/radar.html
Javaのstringについて

#　stringとはなんでしょうか
　　まずstring本質とはcharアレイです、例えば

```java
String a = "hello";
```

実はと以下のコッド同じです

```java
char[] b = {'h','e','l','l','o'};
```
#stringと他のタイプの変換

　　ここはintを例にして　文法は以下です

```java
//int toString: string.valueof(int)
     String abc = String.valueOf(200);

 //String to int:     integer.parseint(string)
     int bcd = Integer.parseInt("200");
```
#string tools of date
  これはJava.util.dateというの内容を引用する、とscanner同じです。

```java
    java.util.Date now = new java.util.Date();
    //フォマード制定したいなら：
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy年mm月dd日hh点mm分ss秒");
	String date = sdf.format(now);
	System.out.println(date);
```

もしstringをdateにtransformしたいなら：

```java
	 String date1 ="2022年1月1日13时10分50秒";
	 SimpleDateFormat qwe = new SimpleDateFormat("yyyy年mm月dd日hh点mm分ss秒");
	 java.util.Date datea = qwe.parse(date1); //can get the type of date form string
	 System.out.println(datea);
```

#stringnの比較

```java
     String a ="abc";
	 String b ="bcd";
	 a.equals(b); //aとｂのコンテンツは同じならtrue 違うならfalse 
	 a.equalsIgnoreCase(b);//アルファベットの大文字と小文字を無視する
	 a.compareTo(b);// aとb比較する
	 a.isEmpty();//stringはスペースですか　スペースならtrue 違うならfalse 
	 a.contains(b);//aにbがあるかどうか あるならtrue 違うならfalse
	 a.startsWith(a);//string aで始まるかどうか 同じならtrue 違うならfalse
	 a.endsWith(b);//a はbで始まるかどうか 同じならtrue 違うならfalse
```

#stringの他のツール
```java
	//スペースを削除
     String aad = new String("i love u");
	 System.out.println(aad.trim());

	//大文字になる
	 aad.toUpperCase(); 

	 //小文字になる
     aad.toLowerCase();  

     //starindex endindexコンテンツの取り切り
	 aad.substring(1,2);

     //コンテンツの変化
	 aad.replace("i", "I");

	 //split() コンテンツの分割　例えば：
	 String asf ="i love you";
	 String[] splited = asf.split("");//get ["i","love","you"]
```


#最後stringbufferについて
stringとはfinalの不可変化な量です　だからそのコンテンツは変化しません、それは新たな値を生成です。
例えば：

```java
String a = "i love u"
String b = a.trim();//そこaの値は変化しません　新たな値を生成でした。
```
多くの値が生成されるとカートンや性能低下の問題になります
だからstringbufferを使いです

```java
//時間を記録：
long begin = System.currentTimeMillis();//1970年1月1日から現在まで
long end =System.currentTimeMillis();
long spendtime = end - begin;
```

stringbufferについてツール：
append//内容の追加
delete//内容の削除
replace//内容を変える
reverse//内容逆になる
to string//stringタイプになる

```java
    StringBuffer sb=new StringBuffer();
	sb.append("hello").append("world").append("java");
	System.out.println(sb);
	sb.delete(0, 5);
	System.out.println(sb);
	sb.replace( 0, 5, "lalala");
	System.out.println(sb);
	sb.reverse();
	System.out.println(sb);
	sb.toString();
```

#以上です　ありがとうございます
M1Mac + Pyenv + Pyenv-Virtualenvでの'pyenv install'時エラー

# 前提
- Mac M1Max
- Pyenv + Virtualenvを利用していて、ある日pyenv installができなくなった

# エラー内容
pyenvで新しいPythonをインストールしようとすると、下記のようなエラーが出る。
アーキテクチャ絡み？M1のせい？

```bash
$ pyenv install 3.7.12

Last 10 log lines:
  "_libintl_textdomain", referenced from:
      _PyIntl_textdomain in libpython3.7m.a(_localemodule.o)
      _PyIntl_textdomain in libpython3.7m.a(_localemodule.o)
ld: symbol(s) not found for architecture x86_64
ld: symbol(s) not found for architecture x86_64
clang: clangerror: : linker command failed with exit code 1 (use -v to see invocation)error: 
linker command failed with exit code 1 (use -v to see invocation)
make: *** [Programs/_testembed] Error 1
make: *** Waiting for unfinished jobs....
make: *** [python.exe] Error 1
```

# 対処法
いろいろなサイトに転がっていた、下記対処法が効きそう。
必要ないものもあるかも。誰か教えてください。

## binutilsのアンインストール
そもそも私の環境では入っていなかった。

```bash
$ brew uninstall binutils
Error: No such keg: /opt/homebrew/Cellar/binutils
```

## XcodeのCommand Line Toolsの設定
1. xcodeを起動
1. Preferenceをクリック  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204712/b9b6c06d-86a0-b619-55c7-b660d25c3ce6.png", width=300>
1. Locationsタブを選択  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204712/702132cc-22a0-eb8d-b9f3-39a0cb3bcbf4.png", width=300>
1. Command Line Toolsが選択されていない場合は、選択する  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204712/59822d56-f3c2-fff1-036c-8a757c692ef8.png", width=300>

## Pyenvの再インストール
上だけでは治らなかったので、再インストール。キャッシュの削除などは不要。

```bash
brew uninstall pyenv-virtualenv
brew uninstall pyenv
brew install pyenv
brew install pyenv-virtualenv
```

## 実行
```bash
$ pyenv install 3.7.12
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Installing Python-3.7.12...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.7.12 to /Users/<USER NAME>/.pyenv/versions/3.7.12
```
動いた！
Azure Portal 用のブックマーク (テナント、ユーザー指定)

Azure で複数の AAD のテナントを所有している場合、Azure ポータルでテナント、ユーザーを切り替えることが結構手間になります。
そのため、ブックマークとして URL 内にテナント、ユーザー名を指定する方法が無いか模索していたところ、以下の URL で動作を確認できました。

```
https://portal.azure.com/<テナント名>?loginHint=<ユーザー名>#home
```

すでにログイン済みのユーザーであれば認証なしで切り替わりますし、ログインしていない場合は認証画面にリダイレクトされます。
たまに既存の接続かキャッシュの影響かはわかりませんが、うまく切り替わらない時がありますが、もう一度ブックマークをクリックすれば大抵うまく切り替わります。

環境によってはうまく動作しない可能性もありますが、一度試してみる価値はあるかと思います。
<font color="Red">なお、ブックマークのアイコンが既定のアイコンに変わってしまうので、アイコン重視の方にはお勧めしません。</front>

### ブックマークの編集方法

Azure ポータルを開きログイン後、対象の URL をブックマークに追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/8e35bb18-5bbf-a49b-4ef4-4a1540f56807.png)

追加したブックマークを右クリックして、"Edit" を押し、URL に "＜テナント名＞?loginHint=<ユーザー名>" の部分を追加して保存ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/69788926-e7e9-780d-158c-09cc32544e28.png)

完成したブックマークをクリックしてみると指定したテナントに指定したユーザーでログインするはずです。テナント、ユーザー毎にブックマークを用意しておけばポータル作業を効率化できると思います。

LoginHint 自体は Microsoft ID プラットフォーム (AAD 等) の認証で使えるパラーメーターのようなので、Office 365 や Power Platform 等の他のサービスでも使えるかもしれません。

https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code

|パラメーター	|必須/省略可能	|説明|
|---|---|---|
|login_hint	|省略可能	|このパラメーターを使用すると、ユーザー名が事前にわかっている場合、ユーザーに代わって事前に、サインイン ページのユーザー名および電子メール アドレス フィールドに入力することができます。 多くの場合、アプリでは、以前のサインインから login_hint を抽出した後の再認証時にこのパラメーターを使用します。
CP4DのWatson Studioからのデータアクセス関連記事まとめ

CP4DのWatson Studioからのデータアクセス関連の記事をいくつか書いたのでまとめました。

#プロジェクト・データ・アセットの管理
[Waston StudioからICOSデータにアクセス](https://qiita.com/kawada2017/items/0e2f9cc3a03b3e88719b)
[Watson StudioからSQLQueryへのアクセス](https://qiita.com/kawada2017/items/4a03974a49c67ee6e887)
[Watson StudioからSQLQueryの実行結果のICOSバケットへのアクセス](https://qiita.com/kawada2017/items/31a7b03e84bb14fd2c9b)
[Watson Studio on CP4Dでプロジェクトのアセットをダウンロードする](https://qiita.com/kawada2017/items/8de36be35adb8c0c2f07)

#Jupyterからのデータ読み書き
[ibm_watson_studio_libでCP4DのProjectのファイル・データ資産の読込、登録を行う](https://qiita.com/kawada2017/items/35061650af47d2128e38)
[CP4DのWatson StudioのJupyterからSQLAlchemyでDb2を操作する](https://qiita.com/kawada2017/items/e547b2ebb9aa45aa78d0)
[CP4DのWatson StudioのJupyterからICOSを操作する](https://qiita.com/kawada2017/items/261b73df274119dbf4db)
[Watson StudioのJupyter notebookからSQL Queryへのクエリー実行](https://qiita.com/kawada2017/items/7de86e5739fd5e4d1d8f)

#ModelerFlowからのデータ読み書き
[ModelerFlowでICOSのCSVを読んでICOSに書き込む](https://qiita.com/kawada2017/items/c26567eb01485f968fc0)
[ModelerFlowでICOSのCSVを読んでDb2WHに書き込む](https://qiita.com/kawada2017/items/79d6cf650288d771774b)
can't find node.js binary "deno": path does not exist.

# VSCodeで `can't find node.js binary "deno": path does not exist.` エラー対処

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403148/0bb264f9-d11c-b366-afb9-3b0052264ca0.png)
全文

```text
can't find node.js binary "deno": path does not exist. Make sure Node.js is installed and in your PATH, or set the "runtimeExecutable" in your launch.json
```

## 発生した問題
`deno`をインストールして`deno -V`でバージョンが返ってくるのに`"runtimeExecutable": "deno"`でPATHがないと怒られる。

## 環境
os: windows 11
version: 21H2

## 手続き
一応インストール済みか確認する

```shell
deno -V
> deno 1.18.2
```

`deno`がどこにインストールされているのかを確認する

```shell
where.exe deno
> C:\Users\<ユーザー名>\.deno\bin\deno.exe
```

vscodeに戻って`launch.json`を開く

```json:launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "request": "launch",
            "name": "main.ts",
            "type": "pwa-node",
            "program": "${workspaceFolder}/main.ts",
            "cwd": "${workspaceFolder}",
            //先ほど確認したパスに'\'を増やして記述
            "runtimeExecutable": "C:\\Users\\<ユーザ名>\\.deno\\bin\\deno.exe",
            "runtimeArgs": [
                "run",
                "--inspect",
                "--allow-read",
                "--allow-net"
            ],
            "attachSimplePort": 9229
        }
    ]
}
```

これで治りました。
重複しているレコードの内、最も古いレコードだけを残すSQL

# 背景
登録時の重複チェックがうまく効いてなかったのか、同じ内容のレコードが複数登録されてしまっていて、
重複しているレコードのうち登録が一番古いレコードだけを残したかった際に実行したSQL。
※ここでは「最も古いレコード = idが一番若いレコード」として書いてます。

### 実行したSQL

```
DELETE FROM `[table_name]` WHERE id NOT IN (SELECT min_id FROM (SELECT min(table1.id) AS min_id FROM `[table_name]` AS table1 GROUP BY table1.[column]) AS table2);
```
[table_name]に対象のテーブル名、[column]に重複が確認できるカラム名を入れて実行すれば、idが一番若いレコード以外のレコードが削除されます。

SELECT文の中の「min(table1.id)」の箇所を変えてあげれば、id以外のカラムでもできます。

そもそもそんなレコードが作られる際にちゃんと対策しとけよと思いますが、何かしらの要因で重複してしまった際の対応策として。。。
GitHubにホスティングしたPHPパッケージをComposerで使う

### これはなに

packagist.orgに公開せずに、Composerから使う方法のメモ

### パッケージを作成する

composer.jsonを配置します。

```
$ composer init
```

こんな風になる。versionプロパティはなくてOK。

```json:composer.json
{
    "name": "GitHubユーザー名/リポジトリ名",
    "description": "パッケージの説明",
    "autoload": {
        "psr-4": {
            "ベンダー名\\パッケージ名\\": "src/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}
```

```php:src/クラス.php
<?php

namespace \ベンダー名\パッケージ名\クラス

class クラス
{
    （なにか処理）
}

```

### リリースする

`git push` した後にタグを打つことで、パッケージ利用側はタグをバージョンとして指定して依存に追加できるようになります。

```
$ git tag 1.0.0
$ git push origin 1.0.0
```

タグをプッシュしなくてもバージョンを
`dev-ブランチ名`として依存に加えることもできます。

### 作成したパッケージを読み込む

作成したパッケージを利用するプロジェクト側の設定をしていきます。

composerがリポジトリを解決できるようにrepositoriesプロパティを追加します。
コマンドを実行し、composer.jsonにrepositoriesプロパティを追加できます。直接composer.jsonを書き換えても動作します。


```bash
$ composer config repositories.GitHubユーザー名/リポジトリ名 vcs git@github.com/GitHubユーザー名/リポジトリ名.git`
```

こうなる

```json:composer.json
"repositories": [
    {
        "type": "vcs",
        "url": "git@github.com:GitHubユーザー名/リポジトリ名.git"
    }
]
```

※ 試していないけどプライベートリポジトリの場合のurlの形式について
SSHのものなら鍵、HTTPSのものなら`personal access tokens`でアクセスできるらしい。（それはそうか）

バージョンを指定して依存に加えます。

```bash
$ composer require GitHubユーザー名/リポジトリ名:1.0.0
```
Web技術 まとめ

##HTTPとは
**「Hyper Text Transfer Protocol」**の略。WebサーバーとWebブラウザの間で、Web情報をやり取りするための通信規則。
情報のやり取りは常に、クライアントが要求を出し、サーバーが応答を返す。1つのリクエストには１つのレスポンスを返すルールになっており、どちらかが多くなることはない。

##HTTPとHTTPSの違い
HTTPとHTTPSの違いは、**通信が暗号化されているか暗号化されていないか**の違い。
HTTPSは**「Hyper Text Transfer Protocol Secure」**の略で、HTTPで通信を安全に行うための仕組み。
WebブラウザとWebサーバーで、ネットバンキング、クレジットカード決済、個人情報登録を行うようなケースでHTTPSが利用される。
【第７回】Confluent Platformのデモをためしてみる（Confluent Replicator編）

###概要
今回は、[第一回](https://qiita.com/Alex-hiro/items/0209b2faec9c00cf3ca1)で構築したConfluentのクラスタを利用しConfluent Control CenterにログインしてConfluent Replicator部分を確認してみたいと思います。

###Confluent Control Centerにログイン
１.以下のURLでWebブラウザからコンフルエントコントロールセンターのGUIにアクセスします。

```sh
http://localhost:9021
````

Confluent Replicator は、コピー元 Kafka クラスターからコピー先 Kafka クラスターにデータをコピーします。コピー元とコピー先のクラスターは通常、異なるクラスターですが、このサンプルでは、コピー元とコピー先の Kafka クラスターは同じです。他のコンポーネントと同様に、Confluent Replicator にもセキュリティが構成されています。

１.Confluent Control Center(以下CCC) で、Replicator のステータスとスループットを表示します。
![スクリーンショット 2021-12-24 16.13.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/943c81d7-6605-6a7d-b759-825f0de03f24.png)

2.CCCのメニューにある「Consumers」を選択し、Confluent Replicator のスループットとレイテンシをモニタリングします。Replicator は Kafka Connect ソースコネクターであり対応するコンシューマーグループはconnect-replicator です。
![スクリーンショット 2021-12-24 16.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/0f428f80-c632-08e3-7b9e-c8ab517716ec.png)

３.Replicatorのコンシューマーラグを表示します。
![スクリーンショット 2021-12-24 16.26.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/406fb4d8-f1e4-7273-f308-fa0c8fe920e5.png)

４.Replicator の消費メトリクスを表示します。
![スクリーンショット 2021-12-24 16.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/f1aa79b9-f4aa-0b8b-1ace-da8d9a7faa7b.png)

５.CCCのメニューにある「Connect」を選択し、Settingsで右上の一時停止アイコンを押し、有効になるまで10秒間待ってReplicatorコネクターを一時停止します。これで、関連するコンシューマーグループの消費が停止します。
![スクリーンショット 2021-12-24 16.32.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/5ae404d1-f8f4-efdd-f406-5af61468cba6.png)

６.「connect-replicator」コンシューマーグループの消費が停止したのをCCCで確認します。
![スクリーンショット 2021-12-24 16.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/8185edcf-1a73-3b95-363b-08f6e52f3c41.png)

７.5.で一時停止したReplicatorコネクターを再起動します。
８.「connect-replicator」コンシューマーグループが消費を再開したことを確認します。ここでは以下の確認ができます。
　・コンシューマーグループ「connect-replicator」が動作していなかった時間があるにもかかわらず、すべてのメッセージが配信済みとして表示されます。
　・レイテンシはピークに達した後、徐々に減少します。これは生成したタイムスタンプに対して相対的であるためです。




今回も最後までお読み頂きありがとうございました！
DockerでTideways

# これはなに

Docker上で動くWordPressに、PHPのプロファイリングツールであるTidewaysをインストールした時のメモ。

WordPressの独自テーマプロジェクトのことを書いているが、(読み替えれば:innocent:)通常のPHPプロジェクトでも同じようにインストールできるはず。

# 背景

PHPゴリゴリのWordPress独自テンプレートのパフォーマンスチューニングをする機会があった。

プロファイラを使ってボトルネックを調査しようと思いツールを調べたところ、PHPではTidewaysというものがメジャーなもよう。

Docker上で動くWordPressでTidewaysのレポートを出力できたので、方法をメモしていく。

# ポイント

- グラフを出力するためにgraphvizをインストール
- xhprofをビルド
- `/var/www`にtidewaysの管理画面（[xhprof-html](https://github.com/sters/xhprof-html)）をホスト

# 使い方

### 1. 解析したいPHPコードを次のコードで囲む

```php
tideways_xhprof_enable();

// ここに解析したいメインの処理

$data = tideways_xhprof_disable();
$filename = '/tmp/xhprof/' . intval(microtime(true)) . mt_rand(1, 10000) . '.xhprof';
file_put_contents($filename, serialize($data));
```

### 2. PHPを実行し、解析ファイルを作成する

(1)のPHPを実行すると、`/tmp/xhprof`に解析ファイルが生成できる。

### 3. xhprof-htmlで可視化する

ホストしたxhprof-htmlにアクセスし、(2)で作成したxhprofファイルを選択してパフォーマンスを確認

↓からアクセスできる
http://localhost:8000/xhprof/?dir=/tmp/xhprof

# 構築方法

WordPressの独自テーマプロジェクトのため、
direnvでテーマのディレクトリへのパスを設定した。

```.envrc
export THEME_REPO=~/path/to/my-theme
```

```yml:docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    platform: linux/x86_64
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    build:
      dockerfile: wordpress/Dockerfile
    platform: linux/x86_64
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DEBUG: true
    volumes:
      - ${THEME_REPO}:/var/www/html/wp-content/themes/my-theme

volumes:
    db_data:
```

すごい雑だがtidewaysのインストールをDockerfileにて定義している。

```Dockerfile
FROM wordpress:latest

RUN apt-get update && apt-get install wget git graphviz -y
RUN cd /tmp && git clone https://github.com/tideways/php-xhprof-extension
RUN cd /tmp/php-xhprof-extension && phpize && ./configure && make && make install
RUN echo 'extension=tideways_xhprof.so' >> /usr/local/etc/php/conf.d/tideways.ini
RUN echo 'tideways.auto_prepend_library=0' >> /usr/local/etc/php/conf.d/tideways.ini
RUN mkdir /tmp/xhprof && chmod 777 /tmp/xhprof/

COPY wordpress/xhprof-html.conf /etc/apache2/conf-enabled/xhprof-html.conf
RUN cd /var/www && git clone https://github.com/sters/xhprof-html.git
```

WordPressの公式イメージに同梱しているApacheにのっかって管理画面をホストしているけど、Nginxに読み替えてOK。

↓ホスト用のApache設定ファイル

```xhprof-html.conf
<IfModule alias_module>
    Alias /xhprof /var/www/xhprof-html
</IfModule>
```
react-admin で firestore 使う時の react-admin-firebase での filter と rule の書き方

## TL;DR
- react-admin-firebase 使った時、firestore.rules と permanent filter を合わせる書き方

## dataProvider

```typescript
import { initializeApp } from "firebase/app";
import { FirebaseAuthProvider, FirebaseDataProvider, RAFirebaseOptions } from "react-admin-firebase";

const firebaseConfig = { ... };
const app = initializeApp(firebaseConfig);

const options: RAFirebaseOptions = {
  disableMeta: false,
  renameMetaFields: {
    created_at: "created_at",
    created_by: "created_by",
    updated_at: "updated_at",
    updated_by: "updated_by",
  },
  dontAddIdFieldToDoc: false,
  associateUsersById: false,
};

const authProvider = FirebaseAuthProvider(firebaseConfig, options);
const dataProvider = FirebaseDataProvider(firebaseConfig, options);
```

## list
```typescript
import firebase from "firebase/compat/app";
import { ResourceComponentProps } from "react-admin";
type CollectionReference = firebase.firestore.CollectionReference;

const list = (props: ResourceComponentProps) => (
  <List {...props}
    filter={{
      collectionQuery: (cr: CollectionReference) =>
        cr.where("created_by", "==", props.permissions.user_id),
    }}
  >
    <Datagrid>
      ...
    </Datagrid>
  </List>
);
```

## firestore

```firestore.rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    match /posts/{post} {
      allow get: if request.auth != null;
      allow list: if request.auth != null && resource.data.created_by == request.auth.uid;
    }

  }
}
```

参考
https://github.com/benwinding/react-admin-firebase/pull/39
Emacs 保存時、休憩後（放置後の再スタート）にプチフリーズする

たぶん原因はこれ。
昔も同じ原因にたどり着いた記憶が薄っすら思い出されます。
バージョンコントロールを無効にしましょう！
ひとまずやっつけで対応したコードをここに置いてゆきます！幸運を！

## ありがとうありがとう
### Emacs で勝手に vc-follow-link が実行されて辛い - あらびき日記 https://abicky.net/2014/06/07/175130/
### Emacsでファイルのオープン・保存が遅い https://blog.rainyman.jp/nest/?p=1117
### esup.el : Emacs起動が遅い原因を探れ！init-loader.el対応コードあり http://emacs.rubikitch.com/esup/
### Mac アクティビティモニタで[歯車]→[プロセスのサンプルを収集]
## init.el
```emacs-lisp:init.el抜粋
;; You can also configure builtin package via leaf!
(leaf cus-start
  :doc "define customization properties of builtins"
  :tag "builtin" "internal"
  :preface
  (defun c/redraw-frame nil
    (interactive)
    (redraw-frame))
  :bind (("<M-escape> <escape>" . c/redraw-frame))
  :custom (;; (debug-on-error . t)        ;; エラー時に有効にする。エラー内容表示
       ;; (init-file-debug . t)
       (c-tab-always-indent . t)
       (case-fold-search . t)               ;; 検索時に大文字と小文字の区別をしない nil:する t:しない
・・・
       ;; Emacs で勝手に vc-follow-link が実行されて辛い - あらびき日記 https://abicky.net/2014/06/07/175130/
       ;; [vc-follow-link が勝手に実行されて辛い時]
       ;; vc-find-file-hook では Git などでバージョン管理されていないファイルを開こうとした時に、その
       ;; ファイル自体や親ディレクトリがシンボリックリンクだった場合にリンクを辿ろうとします。っで、
       ;; 既にリンク先のファイルを開いていたら無条件でリンクを辿る仕様になっていて、「既にリンク先の
       ;; ファイルを開いているかどうか」の判定がバグっています。
       ;; (get-file-buffer
       ;;  (abbreviate-file-name
       ;;   (file-chase-links buffer-file-name)))
       ;; 対策:
       ;;   * vc-follow-symlinks を nil にしてリンクを辿らないようにする
       ;;   * vc-handled-backends を nil にして vc を実質無効にする
       ;;   * vc-find-file-hook の around advice を作成するなり、同名の関数を定義するなりして (file-chase-links buffer-file-name) を buffer-file-truename に変更する
       ;;
       (vc-follow-symlinks . nil)           ;; シンボリックリンクを開くときの質問省略、リンク先を開く
       (vc-handled-backends . nil)          ;; vc を実質無効にする
       )
  :config
  (defalias 'yes-or-no-p 'y-or-n-p)
  ;;(keyboard-translate ?\C-h ?\C-?)
  (define-key query-replace-map [return] 'act)
  (define-key query-replace-map [?\C-m] 'act)
  ;; Emacsのバージョンコントロール(vc)を無効にする
  (setq vc-handled-backends())
  )

```
Windows10のcurlからSlack APIのfiles.uploadで日本語の改行付きテキストをポストする。

Windows 10のCURLを用いて、Slack APIの files.upload にファイルをアップロードする必要があり、文字化けのせいでドン詰まりした。

検索に検索を重ねたが、参考にはなれど直接の回答にはなってなかったので、備忘録を兼ねてポスト。

curl.exe
　-F “file=@C:\Temp\TEST.test”
　-F “initial_comment=<C:\Temp\initial_comment.txt”
　-F “channels=XXXXXXXXXXX”
　-H “Authorization: Bearer xoxb-XXXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXXXXXXXXXXXX”
　https://slack.com/api/files.upload

パスの前に＜をつけると、ファイルの中身だけ取り出して渡すことができる。

上のコマンドが入ったBatファイルをUTF8 BOM無しで作成して、
initial_comment.txt も同様にUTF8 BOM無しで作成する。

当然だが、initial_comment.txt の中身は投稿したい文章本文。改行もちゃんとSlack上に反映される。



 

追記

今更だけど、cmdでなくPowershellで作ったらテキストBOM有りUTF8で行けんじゃないかと思いだした。試してないけど
nginxでContent-Security-Policyヘッダを入れる

Content-Security-Policyヘッダを入れなさいと偉い人からお達しが出たので調べて追加してみました。
初耳だったので調べたところ、特定の攻撃に対する効果軽減のために設定するヘッダのようです。

```
コンテンツセキュリティポリシー (CSP) は、クロスサイトスクリプティング (XSS) やデータインジェクション攻撃など
のような、特定の種類の攻撃を検知し、影響を軽減するために追加できるセキュリティレイヤーです。これらの攻撃は
データの窃取からサイトの改ざん、マルウェアの拡散に至るまで、様々な目的に用いられます。
```

https://developer.mozilla.org/ja/docs/Web/HTTP/CSP

サイトのページから外部リソースにアクセスする対象を予め列挙しておいて、それ以外へのアクセスは許可しない。という対応でクロスサイトスクリプティングは回避するみたいですね。
上記のサイトには記載がありますが、いまいち読み取れなかったので試行錯誤しながらお試ししてみました。

今回はnginxなので、nginxの構文で記載しています。

```nginx
 add_header Content-Security-Policy "default-src 'self'";
```

この記載だと、自身のサイト以外のリソース（サブドメインもだめ）の読み込みはしない。という設定。
外部のjavascriptもdata:で始まる画像イメージも読み込めません。
今回は、特定の外部リソース（フォントとかJavascript）も読み込みたいし、data:から始まる画像も表示するのでこんな設定にしました。

```nginx
 add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' data: tekitouna-font.com *.subdomain.thissite.co.jp *.googleapis.com *.googletagmanager.com *.google.com";
```

サイト側で利用するリソースが増えたらまたnginxの設定を変更しないといけない。。。
めんどくさいなぁ
Laravel KitでGUIからArtisanコマンドを打とう

# はじめに
GUIでArtitanコマンド、Tinkerを動かせるツールを見つけたので紹介。
ターミナルやコマンドプロンプトを立ち上げることなく開発出来るのが売りなツールです。

# 目次
1. [導入](#導入)
1. [Artisan](#Artisan)
1. [Tinker](#Tinker)

<!-- 各チャプター -->
<a id="#導入"></a>
# 導入
<a href="https://github.com/tmdh/laravel-kit">公式(リポジトリ)</a>から
Windowsの人は``Download the setup file (.exe)``をクリックしてexeファイルをダウンロード。
Macの人はbrewで導入。``brew install laravel-kit``

<a id="#Artisan"></a>
# Artisan
インストールしたLaravel Kitを開くとトップが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/12b289a1-1a7b-6133-a9e7-260dfd08dcbc.png)
トップのOpen project...をクリックするか、ナビゲーションバーの``Project > Open Project``からLaravelプロジェクトを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/6b2a6474-75b0-4d9a-9af7-fda905a8920a.png)
Artisanコマンドを打ちに行くかTinkerを使いにいくかが表示されますが、左のサイドメニューでいつでも行き来出来るのであまり気にしなくて大丈夫です。

まずは``Go to Artisan``をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/676d44f5-39dc-4b2b-c279-9b8feb9b9aa3.png)

画面上右から3番目の``Serve``ボタンをクリックすると``php artisan serve``コマンドが走りサーバーが立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/57648fdf-c721-3bc5-c104-508ec388e4de.png)

画面左のArtisan項目にコマンドがズラリと並んでいます。試しに``make:model``をクリックしてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/d5d3fbac-e9d3-5f72-a3cf-c863dddf176d.png)
オプションが沢山表示されてます。``name``にモデル名を入れ、``migration``と``seed``にチェックを入れると画面下にコマンドが組み立てられて表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/e0d693f0-0caa-e614-66bd-bff79b10cf7e.png)
画面右上``Run``コマンドをクリックする事で組み立てられたArtisanコマンドが実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/d70bd9ac-2c28-73ab-b97b-86fb3caff164.png)

<a id="#Tinker"></a>
# Tinker

左サイドメニュー``</>``のようなアイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/46b32922-0957-e01b-7286-460cbb6f395e.png)
名言、格言をランダムで出力してくれるメソッドがデフォルトでセットされていますが無視して消しちゃって大丈夫です。
出力したいプログラムを書いて画面下の``Tinker``ボタンをクリックすると右側に内容が表示されます。
画面左下の``Auto Tinker``にチェックを入れるとリアルタイムに反映されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/993da187-e94b-5e16-5ef9-c3ff773044ba.png)

# おわりに
一通りのArtisanコマンドがあるので知らないコマンドを知れたり、
ちょっとしたコマンド辞書代わりにも使えるので初学者の方など良いかもしれません。