OmniAICreator/Qiita-1.07M huggingface dataset:
ロングテキストエリアはFlowでは使えない？


【質問】
+ [Text messages cannot be longer than 255 characters without throwing salesforce flow error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000O9WLiSAN)

:::note
We have a "custom object" that represents a text message action, but salesforce throws a **STRING_TOO_LONG error** when we try to send a text message that exceeds 255 characters. However, in Object Manager, we made sure that the field that stores the message body has a data type of "Long Text Area(131072)." 

テキスト メッセージ アクションを表す「カスタム オブジェクト」がありますが、255 文字を超えるテキスト メッセージを送信しようとすると、Salesforce は **STRING_TOO_LONG エラー**をスローします。ただし、オブジェクト マネージャーでは、メッセージ本文を格納するフィールドのデータ型が「長いテキスト領域(131072)」であることを確認しました。
:::

調べてみると

+ [Long Text Areas in Flow](https://ideas.salesforce.com/s/idea/a0B8W00000J8A6cUAF/long-text-areas-in-flow)

:::note
While long text areas aren't supported in formula fields, you can use them as input for workflow actions or in process builder, e.g. to copy a long text area field to another record or to shorten it into a text field (see https://help.salesforce.com/s/articleView?id=000333937&type=1).

As Salesforce is migrating from workflows and process builder to flows, that feature needs to be supported in flows as well.

いテキスト領域は数式フィールドではサポートされていませんが、ワークフロー アクションやプロセス ビルダーの入力として使用できます。長いテキストエリア項目を別のレコードにコピーするか、テキスト項目に短縮します (https://help.salesforce.com/s/articleView?id=000333937&type=1 を参照)。

Salesforce はワークフローとプロセスビルダーからフローに移行しているため、その機能はフローでもサポートされる必要があります。

:::

+ [Allow long text area and rich text fields in Visual Workflow](https://ideas.salesforce.com/s/idea/a0B8W00000GdWCEUA3/allow-long-text-area-and-rich-text-fields-in-visual-workflow)

+ [Character Limit for URL Screen Inputs](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000J7W6ASAV)

:::note
If you're just collecting the URL to populate into a URL field on the resulting record, you should just be able to use a text input on the screen (instead of the URL input) and then you can add a length validation in the 'Validate Input' section.

結果のレコードの URL フィールドに入力する URL を収集しているだけの場合は、(URL 入力の代わりに) 画面上でテキスト入力を使用できるようにするだけでよく、その後、「」に長さの検証を追加できます。 「入力を検証」セクション。
:::

+ [The Service Appointment Flow throws an error when the Work Type name + Service Appointment Subject Exceeds the 255 character limit...](https://issues.salesforce.com/issue/a028c00000gAxq9AAC/the-service-appointment-flow-throws-an-error-when-the-work-type-name-service-appointment-subject-exceeds-the-255-character-limit)


+ [ロングテキストエリアの文字数カウントについて](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eqerS)

# Apexを使って回避する

+ [ケースから取引先責任者を作成するフローでロングテクストエリア内の文字を抽出したい](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bKwLE)

:::note
このアイデアを見る限りはロングテキスト項目は数式としてフローでは使えないみたいです。

https://ideas.salesforce.com/s/idea/a0B8W00000J8A6cUAF/long-text-areas-in-flow

Apexならロングテキスト項目が使えるので改行コードを区切り文字としてSprilt関数でList変数に格納できれば、処理は可能だと思います。
:::

# フローでも回避できる

+ [ロングテキストエリアの空白を判定する入力規則について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erKKhSAM)
Googleデジタルマーケティング＆Eコマース：検討ステージの戦略

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/84e33f4e-81cb-98a6-4546-f2ec06fd8b8b.png" width="800">

以前、ファネルの第２ステージである[検討の基礎][considerration]について紹介しました。

[considerration]: https://qiita.com/mapami/items/a0a31631e459461521f7

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f1784770-c58c-2bce-8d6f-7728cc262c3c.png" width="300">

# 検討を構築するためのマーケティング戦略

ファネルの検討ステージでは、製品やサービスに対する関心を高めます。潜在顧客はすでに製品やサービスについて知っており、さらに詳しく知る準備ができています。

### <font color="MediumBlue">USP（Unique selling proposition）</font>

これは、製品やサービスが競合より優れている理由を説明します。潜在顧客が製品やサービスを認識したら、USPを明確にし、頻繁に繰り返すようにします。

### <font color="MediumBlue">お客様の声</font>

これは、お客様が製品やサービスを利用した際の体験談を提供することです。うまく作られた体験談は、潜在顧客の信頼感を高めることができます。顧客は、自分が素晴らしい体験をし、問題が解決された顧客であることを想像する。体験談には、文章、音声、映像のいずれかがあります。

### <font color="MediumBlue">ケーススタディ</font>

これは、体験談と似ていますが、より踏み込んだ内容になっているのが特徴です。文章で書かれることが多いです。数ヶ月に及ぶプロジェクトがある場合、ケーススタディを使ってその経過を説明することができます。徹底したケーススタディは、潜在顧客の信頼を築きます。

### <font color="MediumBlue">リマーケティング広告</font>

これは、ブランドのWebサイトやソーシャルメディアの過去の購入者、購読者、訪問者に対して配信される広告のことです。このタイプの広告は、Eコマースでよく見られます。あなたもリマーケティング広告を経験したことがあるのではないでしょうか。
- 例えば、あるWebサイトでスニーカーを閲覧し、その後訪れた他のWebページやアプリでその靴の広告が表示されたことがあるかと思います。それがリマーケティングです。

### <font color="MediumBlue">ウェビナー</font>

これは、オンラインで提供されるプレゼンテーションのことで、通常は教育的なものです。ウェビナーは、潜在顧客を教育し、製品やサービスを宣伝するための素晴らしい方法です。ウェビナーの課題のひとつは、参加者を集めることです。顧客にとって魅力的で価値のあるものを提供することが大切です。

### <font color="MediumBlue">メールマーケティング</font>

これは、メールリストにプロモーションや教育用のメールを送信することです。潜在顧客がブランドを認知し、メールリストに登録すると、提供される製品やサービスについてもっと知りたいと思うようになります。また、まだ購入していない人には、お客様の声も効果的です。

### <font color="MediumBlue">ソーシャルメディア・マーケティング</font>

これは、検討ステージと認知ステージとでは若干異なります。検討ステージでは、潜在顧客はアカウントのフォロワーになっています。フォロワーに対して、様々なコンテンツをコンスタントに投稿し、ブランドへの関心を高めてもらいましょう。

:::note info
マーケティングでは、「セブンヒッツ理論」といって、潜在顧客が行動を起こすには、少なくとも7回メッセージを見なければならないとされています。ソーシャルメディアでは、このメッセージングを簡単に実行することができます。誰かのフィードに表示されるたびに、あなたのブランドをより身近に感じてもらうことができるのです。
:::
秋月のDS1307使用リアルタイムクロックで遊ぶK-15488




ＤＳ１３０７使用リアルタイムクロック（ＲＴＣ）モジュールキット
[AE-DS1307]
通販コード　K-15488
発売日　2020/10/07


![o_cop411.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/53319860-af9d-acf2-62a7-b4936218565b.jpeg)

回路図を確認の事

![o_cop468.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1ea44083-071f-01c4-0929-45720758f48f.jpeg)



RoHS2(改正RoHS) (EU)2015/863、10物質、付属品等を除く
信号伝達コネクター（ピンコネクター）　（オス）　（１０本入）
[A295-TM12548]
通販コード　C-13181
発売日　2018/03/20


![o_cop412.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/095aed88-df27-dc6b-fb12-1b553e82bb45.jpeg)



コネクタ用ハウジング　１Ｐ
[2226A-01]
通販コード　C-12150
発売日　2017/06/08


![o_cop413.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a75d66d1-16d7-13ed-5836-168672cc01df.jpeg)




![o_cop410.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f7599a3a-1474-6514-718a-7ede68742b5d.jpeg)



![o_cop414.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9ae6ab72-b6c2-32c3-76a4-82295a6c58cb.jpeg)





set_ds1307_uno_1

```c++



#include <Wire.h> //I2C library

#define ADDR    0x68  // 2進数 1101000

char    data_read[8]; //i2cバッファー

#define HH  5
#define MM  41

void setup()
{
  Wire.begin(); //uno

//i2c書き込み
  Wire.beginTransmission(ADDR);

  Wire.write((char) 0    ); //0 レジスターの位置は0
  Wire.write((char) 0    ); //1 秒
  Wire.write((char) ( MM /10)*16+( MM %10) ); //2 分
  Wire.write((char) ( HH /10)*16+( HH %10) ); //3 時

  Wire.write((char) 3    ); //4 曜日
  Wire.write((char) 1    ); //5 日
  Wire.write((char) 1    ); //6 月
  Wire.write((char) 0x20 ); //7 年

  Wire.endTransmission();

} //end setup

void loop()
{

} //loop



```


serial_ds1307_test3_uno_1



```c++




//serial_ds1307_test3_uno_1

#include <Wire.h>

//初期化
void setup() {

  //I2Cの初期化 UNO
  Wire.begin();

  //シリアルの初期化
  Serial.begin(9600);

} //setup


// デバイスアドレス(スレーブ)
#define ADDR    0x68    // 2進数 1101000

char data_read[16]; //データバッファー


//メインループ
void loop() {

  // レジスタのアドレスを先頭にする
  Wire.beginTransmission(ADDR);
    Wire.write(0x00);
  Wire.endTransmission();
  delay(1);

  // I2Cスレーブに8byteのレジスタデータを要求する
  Wire.requestFrom(ADDR, 8);

  // 8byteのデータを取得する
  for (int ii = 0; ii < 8; ii++) {
    while (Wire.available() == 0 ) {}
    data_read[ii] = Wire.read();
  } //for
  delay(1);

  //時分を表示形式に変換する
  char str1[16];
  str1[0] = '0' + (data_read[2] >> 4);    //時 上位
  str1[1] = '0' + (data_read[2] & 0xf);   //時 下位
  str1[2] = ':';
  str1[3] = '0' + (data_read[1] >> 4);    //分 上位
  str1[4] = '0' + (data_read[1] & 0xf);   //分 下位
  str1[5] =  0;

  // シリアルに文字列を送信する
  Serial.println(str1);

  delay(1000); // 1秒待つ

} //loop



```
Googleデジタルマーケティング＆Eコマース：認知ステージの戦略

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/84e33f4e-81cb-98a6-4546-f2ec06fd8b8b.png" width="800">

以前、ファネルの最初のステージである[「認知」の基礎][awareness]について紹介しました。

[awareness]: https://qiita.com/mapami/items/e205cb04e55a3d9572a9

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/61e36bc1-703d-e89d-368c-bb1f295dc96e.png" width="300">


# 認知度を高めるための戦略

デジタルマーケティング担当者であるあなたは、より多くの人に製品やサービスを認知してもらうための戦略を立て、実行することを任されています。さて、どうすればいいのでしょうか？


### <font color="MediumBlue">SEO(検索エンジン最適化）</font>

これは、Google検索やMicrosoft Bingなどの検索エンジンで、Webサイトの視認性を高めるために改善する作業です。潜在顧客が自分のペインポイントを解決するために検索するときのことを考えてみてください。あなたのWebサイトが検索の上位に表示されれば、あなたのビジネスを意識してくれるようになるのです。


### <font color="MediumBlue">SEM(サーチエンジン・マーケティング）</font>

これは、有料広告によって、検索エンジンでのWebサイトの視認性を高めることです。SEOと似ていますね。お客様がGoogleで検索したときに、検索結果の上位に表示されるのは素晴らしいことだと思いませんか？SEMは、ブランドをそこに到達させることができるのです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/525b9412-933c-f40f-2617-4e6caa6d85a9.png" width="600">

### <font color="MediumBlue">ソーシャルメディア広告</font>

これは、有料であることを除けば、ソーシャルメディア・マーケティングと似ています。広告の種類は、プラットフォームによって異なります。現在、認知度を高める一般的な有料の機会は、フォロワー以外の人のフィードに表示される広告です。あなたは、彼らの興味に基づいて、新しい潜在的な顧客をターゲットにすることができます。 

### <font color="MediumBlue">動画マーケティング</font>

これには様々な形態がありますが、認知度を高めるための一般的なものは、ソーシャルメディア広告と同様に、動画の前に再生されるYouTube広告です。以前にどのような動画を見たかによって、潜在顧客をターゲットにすることができます。

### <font color="MediumBlue">インフルエンサーマーケティング</font>

これは、多くのフォロワーを持つ人物やブランドと提携することです。インフルエンサー・マーケティングは、多くのフォロワーを持つ人物やブランドと提携し、そのフォロワーに製品やサービスを宣伝してもらう方法です。

インフルエンサーマーケティングのパートナーシップには、いくつかの種類があります。認知度を高めるためによく行われるのは、レビューです。
- 例えば、ブランドはインフルエンサーにお金を払って、自社の製品やサービスを試してもらうことができます。インフルエンサーは、その体験を詳しく説明します。そのレビューは、ビデオや写真、またはテキスト形式にすることができます。

インフルエンサーマーケティングを行う際は、インフルエンサーが関係性を開示することを忘れないでください。すべての規制ガイドラインに従いましょう。

### <font color="MediumBlue">コンテンツマーケティング</font>

これは、価値あるコンテンツを作成し、配布することに重点を置いたマーケティング手法です。
- 例えば、潜在顧客が読みたくなるようなダウンロード可能な電子書籍が挙げられます。
- また、教育用のWebページも考えられます。

コンテンツマーケティングは、SEOやSEMと結び付けられることが多いですが、価値あるコンテンツを作ることは、コンテンツマーケティングの最初のステップに過ぎないことを覚えておいてください。次は、そのコンテンツを潜在顧客の目に触れさせることです。
ユーザーのプロフィールページ③

<h1>プロフィールページに投稿した記事を表示</h1>
app/views/profiles/show.html.haml

    - current_user.articles.each do |article|
 記事の情報を全て取得する

app/views/articles/_article.html.haml
のコードをそのまま、コピーする

そうすると、プロフィールの下にそのまま記事が、表示されます　。

現時点では、同じコードを２回書いていることになる！

app/views/profiles/show.html.haml

    = render 'articles/article'
articleの中のarticlesを使うという意味

    = render 'articles/article', article: article
articleは、articleという値を渡してあげる

この状態でも良いが、articlesの中にarticleがあるので、articles以外で使っているは何か違和感💦

app/views/commons
フォルダーを作る
common:共通
app/views/commons/_article.html.haml
この中にarticleを持ってくる。
app/views/profiles/show.html.haml
commonsに変更

     = render 'commons/article', article: article
app/views/articles/index.html.haml
ここも変更

    = render 'commons/article', article: article

こういった部分テンプレートを活用していこう！！
Databricksのテーブルからクエリーとユーザーの洞察を得る

[View frequent queries and users of a table \| Databricks on AWS](https://docs.databricks.com/data/table-insights.html) [2023/3/8時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

Unity Catalogに登録されているテーブルにおいて、最近の高頻度クエリーやアクセス頻度の高いユーザーを参照するために、データエクスプローラの洞察タブを活用することができます。この洞察タブでは、過去30日間における高頻度クエリーや高頻度のユーザーアクセスがレポートされます。

この情報は以下のような質問の答えを得る役に立ちます:

- このデータを信頼できるのか？
- このデータの最も良い活用方法は？
- このデータに対する質問について答えてくれるユーザーは誰か？

:::note
**注意**
洞察タブに一覧されるクエリーとユーザーは、Databricks SQLで実行されたクエリーに限定されます。
:::

# 始める前に

洞察タブの頻出クエリー、ユーザーを参照するには以下の権限が必要です。

Unity Catalogでは:

- テーブルに対する`SELECT`権限。
- テーブルの親スキーマに対する`USE SCHEMA`権限。
- テーブルの親カタログに対する`USE CATALOG`権限。

メタストア管理者はこれらの権限をデフォルトで有しています。[Manage privileges in Unity Catalog](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/index.html)をご覧ください。

Databricks SQLでは:

- クエリーに対する`Can View`権限。参照権限を持たないクエリーを参照することはできません。[Query access control](https://docs.databricks.com/security/access-control/query-acl.html)をご覧ください。

# 洞察タブを表示する

1. Databricksワークスペースで、データエクスプローラを開くために![](https://docs.databricks.com/_images/data-icon.png)**Data**をクリックします。
1. 洞察を得たいテーブルを検索するか、テーブルにアクセスします。

    [Search for workspace assets](https://docs.databricks.com/search/index.html)や[Explore tables](https://docs.databricks.com/data/explore-tables.html)をご覧ください。

1. テーブルのページで、**洞察**タブをクリックします。

    過去30日間で、このテーブルに実行されたクエリーと、このテーブルにアクセスしたユーザーが頻度順に一覧され、最も頻度の高いものがトップに表示されます。

    ![](https://docs.databricks.com/_images/insights-tab.png)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
マクロの記録をしてみよう！

<h1>マクロの記録をしてみよう！</h1>
①適当に表のセルを選択

![スクリーンショット 2023-03-10 6.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/00072566-5e4d-ac7d-f4cd-04397cf22d8f.png)
②開発タブの左上付近にある、マクロの記録を選択

![スクリーンショット 2023-03-10 6.17.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/a000a72f-56cf-efc1-c3d1-972d5dca7122.png)
③マクロの名前を入力
今回は、一回押すとチェックがつき目立つようにしたいので、名前をチェックにしておきます👍
名前入力後、OKを選択

![スクリーンショット 2023-03-10 6.18.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/b108cc97-d6ef-aafb-f557-85036cadc0b3.png)
④ここからマクロの記録が開始されているので、間違えないように気をつけよう！（はじめにマクロの記録となっていた部分が、記録終了となっていれば、記録中）

ホームタブを押し、ボールド、斜体、アンダーバーを選択
背景色をオレンジにし、文字の大きさを26を選択

![スクリーンショット 2023-03-10 6.19.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/f05b8828-c77a-85b3-13cc-f678fb0dbccc.png)
⑤④が全てできたら、開発タブに戻り、記録終了を押す。
これで、④で選択した、変更内容がマクロで記録されたことになります。


![スクリーンショット 2023-03-10 6.19.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/c3941d2c-064e-da17-efbe-f579292ccaea.png)

⑥マクロを使ってみよう！
適当なセルを選択

![スクリーンショット 2023-03-10 6.20.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/cffb4674-fb72-c617-63dc-b747ef117e99.png)
⑦開発タブのマクロを選択
先ほど名前をつけたチェックを選択し、実行を押す

![スクリーンショット 2023-03-10 6.21.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/9ad6f646-1771-02d1-6c63-23747da727ef.png)
⑧先ほど選択したセルが、マクロに保存したことを実行してれます！
セルは、一つではなく、複数選択しても同じ結果が起こります。

![スクリーンショット 2023-03-10 6.21.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/d78ec740-d2ad-d226-8b35-40bf4ef87b14.png)

⑨⑥⑦の手順で、行うと選択したセル全てにチェックがつきましたね😆

![スクリーンショット 2023-03-10 6.21.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/93a25a82-fcea-0dca-50b4-1501ff73ccdc.png)
未経験エンジニアへそもそもプログラミングとは！

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
今回はプログラミングについて更に詳しく調べてみましょう！
![インスタスライド_202302282.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/f39614bc-4cc0-3518-21fd-78c7f1dc9510.gif)

# プログラミングとは
様々なプログラミング言語が存在する。

サイト、事業、サービスの内容によって適切な言語を選択する必要がある。

特にネットサービスでの利用シーンをベースに考える。

# 簡易サイト向け言語

PHP,JavaScript,python等の言語は、インタプリタ言語のため構築が容易。簡単な変更についても行い易い。

少しのサーバ資源（メモリ）で動き、パフォーマンスも良い。

# 高機能サイト向け言語

Java等の高機能言語は、クラスの利用により、再利用性が高められるので、長期的には生産性が高くなる。

パフォーマンスを上げるためには、多めのサーバ資源（メモリ）が必要となる

# プログラミング言語の色々
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/29838aa5-0475-8885-e2b4-086e3b78fc3e.png)
＊バージョンによって定義が変わったりします

# まとめ
ー様々なプログラミング言語が存在する。

ー簡易サイト向けのプログラミング言語や高機能サイト向けのプログラミング言語がある

ースクリプト型、コンパイル型、中間言語型、手続き型、オブジェクト指向型言語がある

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
AlmaLinux9やRockyLinux9等（バージョンは古くてもOK）に最新版のMariaDBをインストールする

# 概要

RedHatLinux系のOSに最新版のMariaDBのサーバーをインストールするための手順メモ。Ver10.7以降はセットアップ完了手順が少々異なるので備忘録にメモしておく。

# コマンドは一緒

`yum` や `dnf` で入れてしまっていた場合は `remove` すること。

```bash
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
```

`sudo` が必要かどうかは、環境によります。

# 普通にインストール

```bash
dnf install mariadb-server
```

インストール時にバージョンを確認して最新になっているか確認はしておこう

# mysql_secure_installation ... は存在しない

mariadb 10.7 以降は、`mysql_secure_installation` が存在しない。以下のコマンドで対処しよう

```bash
mariadb-secure-installation
```

アンダーバー(_)ではなくなり、ハイフン(-)になっている。また、`mysql` という文字列でもなくなっているので注意が必要だ

# 後はいつも通り

設定する内容などはあまり変わらないと思うので、ご自身の設定に合わせてどうぞ
Apacheのマルチインスタンス稼働

# はじめに
Webサーバを複数建てたいけど物理的なサーバを幾つも用意したくない
Apacheのマルチインスタンス化で解決すべ
ユニットファイルその他コピーしてどうにかならんか→なった
他のプロセスにも応用できそうなので備忘録
似たようなことやってるブログあったから(参考文献参照)Ubuntu22.10でやってみた
数日前に投稿したやつの改訂版

# 管理コマンド作成
> cd /usr/sbin/
cp apache2ctl apache3ctl
ln -s apache3ctl apachectl3
cp apache2 apache3

apache3ctlを開いて各行のapache2をapache3、apache2ctlをapache3ctlに書き換え(修正箇所多すぎるので省略)
sedでもいいだろうけどなんか怖いから僕は手動変更

# モジュール設定変更
cdしたついでにやっとく
>cp a2enmod a3enmod
ln -s a3enmod a3enconf

a3enmodの$basenameを以下の通り編集
このとき先程と同様に各行のapache2をapache3に書き換え
sedでもいいだろうけど(ry

```:/usr/sbin/a3enmod
$basename =~ /^a3(en|dis)(mod|site|conf)((?:-.+)?)$/
```
この後作成するユニットファイルにさっき貼ったシンボリックリンクapachectl3を参照させる

# ユニットファイル作成
> cp -a /lib/systemd/system/apache2.service /etc/systemd/system/apache3.service

ExecStartを書き換え
```/etc/systemd/system/apache3.service
ExecStart=/usr/sbin/apachectl3 start
ExecStop=/usr/sbin/apachectl3 graceful-stop
ExecReload=/usr/sbin/apachectl3 graceful
```

続いてメインの設定ファイルを配置する/etc/apache3等を作っていく

# 各種ファイル複製
環境によって違うかもしれんけどこの辺のコピー漏れとかあったらコメントで指摘してちょ
>cp -a /etc/apache2 /etc/apache3
cp -r /run/apache2 /run/apache3
cp -r /run/lock/apache2 /run/lock/apache3
cp -r /usr/lib/apache2 /usr/lib/apache3
cp /usr/share/bash-completion/completions/a2enconf /usr/share/bash-completion/completions/a3enconf
cp -r /usr/share/doc/apache2 /usr/share/doc/apache3
cp -r /var/lib/apache2 /var/lib/apache3
cp -r /var/log/apache2 /var/log/apache3
cp /etc/init.d/apache2 /etc/init.d/apache3

# 各種ファイル編集
/etc/init.d/apache3と環境変数ファイル（/etc/apache3/envvars）は編集箇所多すぎるので省略
sedでも(ry
他は以下の通り
```/etc/apache3/apache2.conf
ServerRoot "/etc/apache3"
```

```/etc/apache3/ports.conf
Listen 8080
```

```:/usr/share/bash-completion/completions/a3enconf
command ls /etc/apache3/$1 2>/dev/null
```

# リロード
>systemctl daemon-reload

apache2とapache3起動した後にss叩いてプロセスID分かれてれば成功

# 参考文献

https://natswell.com/techcolumn/2012/08/23/apacheを複数のプロセスで起動する方法/
https://tech-lab.sios.jp/archives/12738
https://neil-sk.hatenadiary.org/entry/20110602/1307024490
removeEventListenerの代わりにAbortSignalを使いましょう

# きっかけ
あまりこの手の初心者向け記事を見かけないので自分のメモも兼ねて書きます。
この記事はほぼ公式docsの焼きまわしなので、はず公式docsを貼ります。下にスクロールしていくと **「中断可能なリスナーの追加」** という項目が見つかるはずです。

https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener#%E4%B8%AD%E6%96%AD%E5%8F%AF%E8%83%BD%E3%81%AA%E3%83%AA%E3%82%B9%E3%83%8A%E3%83%BC%E3%81%AE%E8%BF%BD%E5%8A%A0


# なぜremoveEventListenerを使わないのか

まず特定のlistenerをremoveしたい場合、二度手間になる
```js
// わざわざ取り出して定義しないといけない
const fooListener = () => {
  // ...
}
document.addEventListener("keydown", fooListener)
document.removeEventListener("keydown", fooListener)
```

[公式docs](https://developer.mozilla.org/ja/docs/Web/API/EventTarget/removeEventListener)にも載っているように

> リスナーが capture フラグを設定したものと設定しないものの 2 つ登録されている場合、それぞれを別々に取り外す必要があります。キャプチャするリスナーを取り外しても、同じリスナーのキャプチャしないバージョンには影響しませんし、その逆も同様です。

2つ登録されている場合はさらにめんどくさくなります。

# AbortSignalを使いましょう

公式docsの例を丸コピしたものになりますが、AbortSignalを第三の引数に渡すと、後から`abort()`を呼ぶだけで特定のlistenerを取り除けます。
```js
// 中断可能なリスナーを table に追加
const controller = new AbortController();
const el = document.getElementById("outside");
el.addEventListener("click", modifyText, { signal: controller.signal } );

// t2 の内容を変更する関数
function modifyText() {
  const t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    t2.firstChild.nodeValue = "two";
  } else {
    t2.firstChild.nodeValue = "three";
    controller.abort(); // "three" になったらリスナーを削除
  }
}
```

古いブラウザーを対応しなければならない時の注意事項としては

>DOM 仕様書の古い版では、 addEventListener() の第 3 引数はキャプチャーを使用するかどうかを示す論理値でした。

まあすごく古いブラウザーではなければ気にすることはありません。

# 使用例

このままだとただの公式docsの焼き回しになるのでいくつかの例を出します。

たとえばshortcutを作りたいとき、keydownイベントとkeyupイベントを同時にlistenして、同時にremoveしたいはずです。この場合はAbortSignalを使うと有効的です。
```js
const shortcutController = new AbortController();
document.addEventListener(
  "keydown",
  (evt) => {
    // ...
  },
  { signal: shortcutController.signal }
);
document.addEventListener(
  "keyup",
  (evt) => {
    // ...
  },
  { signal: shortcutController.signal }
);

// ...ここで何かの処理を書く

// 処理が終わったらshortcutController.abortを呼ぶだけで
// 同時に2つのEventListenrをremoveすることができます
shortcutController.abort();
```

# 終わりに

やはり記事よりdocsをちゃんと読みましょう
記事は古いものもありますが、docsはいつも最新ですからね
複数のJDKを簡単に切り替える方法、見つかりました！SDKMAN!で手軽にJDKのバージョン管理ができます

https://sdkman.io/

# はじめに
JDKのバージョン管理において、複数のバージョンを簡単に切り替えられるツールがあることをご存知でしょうか？
今回は、**SDKMAN!** というツールを使用して、**JDKのバージョン管理を簡単かつスムーズに行う**方法を紹介します。
（今回はJDKを対象としておりますが、他のSDKも対象のようです。）

SDKMAN!を使うことで、手軽にJDKのバージョンをインストール、変更、管理することができます。
SDKMAN!のインストール方法から、JDKのインストール、プロジェクト内でのJDKの指定方法まで、詳しく説明していきます。

始めましょう！

:::note info
**執筆時の環境**
M1 MacBookAir
MacOS Ventura (13.2.1)
:::

# SDKMAN!をインストール
まず、SDKMAN!をインストールするために、ターミナルで以下のコマンドを実行します。
```sh
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
```

# JDKをインストール
## インストールできるJDKのリストを表示
次に、インストール可能なJDKのリストを表示するには、以下のコマンドを実行します。
```sh
sdk list java
```
※`.sdkman/etc/config` の sdkman_rosetta2_compatible を true にすると、Intel版互換のSDKも表示されるそうです。2023年3月現在、よっぽどのことがない限り false(デフォルトのまま) で良いと思います。

## 指定のJDKをインストール
表示されたリストから、インストールしたいJDKのIdentifier列の文字列を選択し、以下のコマンドを実行することで、JDKをインストールできます。
```
sdk install java [上記のリストで表示されたIdentifier列の文字列]
例) sdk install java 8.0.362-amzn
例) sdk install java 19.0.2-amzn
```
※２回目以降、デフォルトに設定するかを聞いてきます。

# JDKを変更
## デフォルトJDKを変更
デフォルトのJDKを変更するには、以下のコマンドを実行します。
```sh
sdk default java [Identifier]
例) sdk default java 8.0.362-amzn
例) sdk default java 19.0.2-amzn
```

## 起動しているターミナルのみJDKを変更
現在起動しているターミナルのみで使用するJDKを変更するには、以下のコマンドを実行します。
```sh
sdk use java [Identifier]
例) sdk use java 8.0.362-amzn
例) sdk use java 19.0.2-amzn
```

# プロジェクトでJDKを指定
プロジェクトごとに使用するJDKを指定するには、プロジェクトルートに `.sdkmanrc`ファイルを作成します。

## 初回のみ init
```sh
sdk env init
```

結果、 `.sdkmanrc` が作成されます。
その時点でのデフォルトが自動で記述されるぽいです。
```properties:.sdkmanrc
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=8.0.362-amzn
```

## `.sdkmanrc`があるプロジェクトをgit clone後
```sh
sdk env install
```

## `.sdkmanrc`の内容を使用
```
sdk env
```
※`.sdkman/etc/config` に `sdkman_auto_env=true`を書いておくと、プロジェクトディレクトリに移動した際に、自動的に.sdkmanrcで指定したJDKを使用するようになります。

# 他の使い方は公式のUsageを参照
SDKMAN!の他の使い方については、公式のUsageを参照することをおすすめします。
https://sdkman.io/usage

# おわりに
今回は、**SDKMAN!** を使用してJDKのバージョン管理を行う方法について紹介しました。
SDKMAN!を使うことで、手軽にJDKのバージョンを切り替えることができ、複数のプロジェクトを同時に進める際にも非常に便利です。
また、SDKMAN!を使用することで、必要なJDKのバージョンをすばやくインストールすることもできます。
この記事が、JDKのバージョン管理にお悩みの方々にとって、役立つ情報となることを願っています。
５分で紹介「プログラミングコンテスト攻略のためのアルゴリズムとデータ構造」

# はじめに
この記事は 
**「プログラミングコンテスト攻略のためのアルゴリズムとデータ構造」** を**５分**で**この本の魅力や大まかな内容**を理解することを目的とした記事です。

この記事で少しでも興味を持ってこの本を読むきっかけになれば幸いです。

<img width="300" alt="名称未設定のアートワーク 1 (1).jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921163/15ba9bda-b0aa-8b54-bcb9-ac7282435e9c.jpeg">

# 目次
**・概要
・個人的な感想
・参考文献**

# 概要

この本は**全479ページ、18章**で構成されています。

初めには**オンラインジャッチシステム**の使い方や、
環境構築を詳しく説明していて、
**プログラミング初心者の人**でも環境構築ができるように説明してあります。

読者の対象は**プログラミング初級者**に設定されていて、
内容は**体系的にアルゴリズムとデータ構造の基礎**を学ぶことができる内容になっています。

そして各章には**演習問題**が用意されて、
各問題の**制限時間**や**メモリ制限**、**正解率**もかかれています。

問題文の後には考察や解説の後に**解答例**が書かれており、
解答例は **C,C++** で書かれています。

アルゴリズムの説明には**図など**が使われており、
**視覚的にも理解すること**ができます。

さらに各問題にそれぞれ**必要スキル**と**前提スキル**が**アイコン**として書かれており、
**体系的な学習**ができるような工夫がされています。


# 個人的な感想
この本を読んで、
この本は**プログラミングコンテストに参加してみたい初級者**におすすめできる本だと思いました。

なぜなら初級者でも**オンラインジャッチ**を活用することで
本を読み知識を得るだけでなく、
**コードを実装して正しさをたしかめること**ができます。

**全479ページ**は初級者には長いのではないか
と感じる方もいるかもしれませんが、

**図やグラフ**を用いて説明されているため、
ページは多くとも**初級者**にも読みやすいようになっています。

さらに**グラフで視覚的に理解**し**考察**や**解説**を読むことで、
初級者でも体系的に学習できるようになっています。

しかし**プログラミング初心者**や
**C,C++を全く知らない人**にはおすすめできません。

この本は**C,C++の文法の説明**などはなく、

あくまで目的は**アルゴリズムとデータ構造の基礎を学ぶこと**なので、
**C,C++を知らない人**には**かなり難しい**とおもいます。




# 引用
>プログラミングコンテスト攻略のためのアルゴリズムとデータ構造 
著 渡部 有隆  協力 Ozy,秋葉 拓哉
2015/1/30


https://shopping.yahoo.co.jp/products/53f4349dee
【Python3】 気象庁が公開している潮位データを１年分まとめて読み込む

2022.3.11 ：【修正】サンプルプログラムにcsv出力を追加

## 背景

- 気象庁では潮位表として、全国各地の験潮所の観測データ(潮位,干満など)を公開しています。
- 観測データの参考：https://www.data.jma.go.jp/kaiyou/db/tide/suisan/index.php
- Web上から手に入り大変便利ですが、フォーマットに癖があり、利用する際に少し苦労しました。

## 実行環境
- Macbook(M1)
- Docker
- VsCode
- Python3

## 観測データの保存フォーマットについて
気象庁は公開している[データのフォーマット](https://www.data.jma.go.jp/kaiyou/db/tide/suisan/readme.html)を丁寧に解説してくれています。
実際に中のデータを見てみると、以下の通りになっています。
```
108117121120116109104102105114126137143144137123105 85 66 51 44 46 57 7515 116QN　220121123214599999999999999 6551022017 4499999999999999
```
- １～７２カラム目に１時間ごとの潮位データが、１時間ごとに３カラムで保存されています。
- ７３～７８カラム目に年月日が保存されています。yymmddです。
- ７９～８０カラム目に観測点の固有の識別番号が保存されています。
- ８１~１３６カラム目に満潮時刻・潮位と干潮時刻・潮位が保存されています。本記事では使いません。


この様にフォーマットに則って保存されていますが、利用する際にはいくつか注意点があります。

潮位の時刻データは１時間あたり３カラム必ず使用するため、観測潮位が２桁以下であった場合に左詰めでスペースが挿入されます。
また観測点の固有の識別番号にアルファベットが含まれています。
そのため数字として一括で読み取ることができません。

加えて、潮位の時刻データ以外にもデータが含まれているので、配列等に保管した際に欲しいデータの格納場所が飛び飛びになります。

## 解決策
一度データ全てを文字型として読み込み、それを３カラムごとに区切って配列に保管、スペース部分を削除します。
その後、潮位データのみを配列から取り出して配列に並べ直し解決しました。

サンプルプログラムを以下に示します。
(今回は実行結果を画像として保存しています。)

```
from pathlib import Path  # ファイル検索用
import re  # データ区切り用
import tqdm  # 進捗バー表示
import matplotlib.pyplot as plt  # グラフの描写
import numpy as np
import csv

tide_filepath = "Yokosuka-tide.csv"
tide_textdata = Path(tide_filepath).read_text()
tide_splittext = re.split("(...)", tide_textdata)[1::2]
tide_daycount = int(len(tide_splittext) / 45)
tide_data = [0] * 365 * 24

print(">>データの読み込み")
for i in tqdm.tqdm(range(tide_daycount)):
    for j in range(24):
        tide_data[i * 24 + j] = int(tide_splittext[i * 45 + j])

print(">>グラフの出力")
plt_x = np.arange(0, 365, 1 / 24)  # x軸：hour
plt_y = tide_data  # y軸：潮位データ
fig, ax = plt.subplots()
ax.plot(plt_x, plt_y, label="tide")
plt.xticks(np.arange(0, 365, 100))  # 横軸間隔の変更：day
ax.set_xlabel("day")
ax.set_ylabel("m")
ax.legend()
plt.savefig("tide.png")
print("save as tide.png")

print(">>CSVへの保存")
f = open("tide-out.csv", "w")
writer = csv.writer(f)
writer.writerow(tide_data)
f.close
print("save as tide-out.csv")
```

## 実行結果
今回は入力データとして、横須賀験潮所のデータを使用しています。
期間は2015年1月1日0時からの１時間潮位データです。
(この期間のデータには欠損がないため)

実行結果は下図の通りになります。
データ数が24h*365dayあるのでグラフがとんでもない密度になっていますが、正しく描写で出来ていることが確認できました。
(![tide.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3259514/502c8488-c2dd-969c-fb05-499e039574c5.png)
[Flutter]Flutter runコマンドではapiを叩けるのに実機環境に移すと叩けない場合の対処法



### 原因
「Flutter run」コマンドでは動作するのに、実機に移した場合に動かなくなる原因はさまざまですが、自分が遭遇したのは、Androidのネットワークに接続するための権限が原因でした。Androidアプリをビルドする際、アプリがAPIを使用する場合や外部サーバーにアクセスする場合には、ネットワークに接続するための権限が必要となります。
自分はawsの通信の際にこの事象に遭遇したのですが、とりあえず適当なapiにgetリクエストを送ってみようと思い、[シェークスピアapi](https://www.umayadia.com/Note/Note028WebAPISample.htm)を叩きレスポンスを確認したところ、Flutter run時にはシェークスピアの情報がjson形式で返ってきたのが、実機環境だとエラーを吐いたため、そもそも通信が行えてないことに気づきました。

### 解決法
ネットワークに接続する権限をandroid\app\src\main\AndroidManifest.xmlに記述

```xml:AndroidManifest.xml
<manifest xmlns:android=.....>
<!--ここから!--> 
    <uses-permission android:name="android.permission.INTERNET" /> 
<!--ここまで!-->
    <application android:name=......>
        <activity .....>
            .....
    </application>
</manifest>
```
これでandroidビルド時にもシェークスピアを叩けるようになりました！！

この際に「FLutter run」コマンドの詳細についてまとめた記事を書くので完成し次第、追記いたします。
Railsで中間テーブルを使ってできること

```Cannot have a has_many :through association 'Osusume#novels' which goes through 'Osusume#osusume_novels' before the through association is defined.
```
上記のエラーが出たんだけど、osusumeレコードから、osusume_novelsの中間テーブルを介してnovelsを取得するrubyのコードを教えて。

---
`以下、chatGPTの返答`

このエラーは、アソシエーションの定義順序が間違っていることを示しています。has_many :throughで中間テーブルを介して関連付けをする場合は、中間テーブルの定義よりも前に関連付けの定義を行う必要があります。

以下は、OsusumeモデルとNovelモデルの正しい関連付けの順序を示した例です。

```ruby
class Osusume < ApplicationRecord
  has_many :osusume_novels
  has_many :novels, through: :osusume_novels
end

class OsusumeNovel < ApplicationRecord
  belongs_to :osusume
  belongs_to :novel
end

class Novel < ApplicationRecord
  has_many :osusume_novels
  has_many :osusumes, through: :osusume_novels
end
```

このように定義すると、以下のようにして、osusumeレコードからnovelsを取得することができます。

```ruby
@osusume = Osusume.find(id) # idはおすすめのIDに置き換える
@novels = @osusume.novels
```
このコードでは、osusumeレコードを検索して@osusumeに代入し、@osusume.novelsを使用してosusume_novels中間テーブルを介して関連する小説を@novelsに代入しています。
勾配降下法をスクラッチで実装してみた(R)

## はじめに
勾配降下法をRで実装してみました。いざ調べてみると意外とRの参考記事がないので、簡単ではありますが初学者の方の参考になれば幸いです。誤り等ございましたらご指摘ください。

## 対象の式
今回は以下の式に対して最小値を計算してみます。
```math
5x^2-6xy+3y^2+6x-6y
```
## コード
~~~
rm(list =ls())

# 関数の定義
f = function(x, y) {
  return(5 * x^2 - 6 * x * y + 3 * y^2 + 6 * x - 6 * y)
}

df = function(x, y) {#fをx,yそれぞれで偏微分した値=傾き
  return(c(10 * x - 6 * y + 6, -6 * x + 6 * y - 6))
}

# 等高線図の作成
x = seq(-3, 3, length.out = 50)
y = seq(-3, 3, length.out = 50)
z = outer(x, y, f) # f関数をx,yの組み合わせに対して適用した結果をZとして保存

contour(x, y, z, main = "Contour plot of f(x, y)") #等高線図

# 勾配降下法の反復過程を可視化
search = function(x, y, f, df, alpha = 0.01, eps = 1e-6) {
  x0 = x #xの初期値
  y0 = y #yの初期値
  grad = df(x0, y0) #初期値でx,yそれぞれ偏微分したときの傾き⇒戻り値は配列の形
  
  path = data.frame(x = x0, y = y0)
  
  repeat {
    x_new = x - alpha * grad[1] # xの傾き*学習率alpha でxの値を更新
    y_new = y - alpha * grad[2] # yの傾き*学習率alpha でyの値を更新
    grad_new = df(x_new, y_new) # 更新後のx,yの値で改めて傾きを求める
    
    if(sum(grad_new ** 2) < eps ** 2){ #傾きの二乗和が閾値epsより低くなったら終了
      break
    }
    x = x_new #breakが走らなかった場合、x,y,gradを改めて設定して値の更新へ戻る
    y = y_new
    grad = grad_new
    
    path = rbind(path, data.frame(x = x, y = y)) #pathを対象に、更新後のdfを1行ずつ下に追加していく(履歴)
  }
  
  return(list(x = x, y = y, f = f(x, y), path = path))# 最終的なx,y,f,path(履歴)を出力
}

# 定義した関数の実行
result = search(3, 3, f, df) 

# 可視化
points(result$path$x, result$path$y, col = "blue", pch = 20)#履歴を青色でプロットする
points(result$x, result$y, col = "red", pch = 20) #最終結果を赤色でプロットする

# 最終結果の確認
result$x
result$y
result$f
~~~

## 出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1951021/6c522b69-893c-c0e9-0850-08bfdfa8d44c.png)
~~~
> result$x
[1] 3.503112e-07
> result$y
[1] 1
> result$f
[1] -3
~~~

結論としてx≒0 , y=1のときに最小値-3になることが分かりました。

データサイエンス関連のツイートをたまにしているのでよければフォロー(@nekobo_01)お願いします。お読み頂きありがとうございました。
CentOS 7にNVIDIAドライバをインストールしようとしてgccのバージョンでハマったお話

# 備忘録

## 結論
旧バージョンのgccをリネームで退避させ、新バージョンへのシンボリックリンクを貼ることで解決した。
```
# mv /usr/bin/gcc /usr/bin/gcc.bak &&  ln -s /usr/local/bin/gcc /usr/bin/gcc
# mv /usr/bin/gcc-ar /usr/bin/gcc-ar.bak &&  ln -s /usr/local/bin/gcc-ar /usr/bin/gcc-ar
# mv /usr/bin/gcc-ranlib /usr/bin/gcc-ranlib.bak &&  ln -s /usr/local/bin/gcc-ranlib /usr/bin/gcc-ranlib
```

## 何があったのか
NVIDIAドライバをインストール中、centos 7にデフォルトでインストールされているgcc 4.2.2が古すぎてエラーになってしまった。
ソースコードからgcc 12.2.0をインストールし、gcc -vでバージョンが上がっていることを確認したにもかかわらずドライバのインストールスクリプトはgcc 4.2.2を呼び出して同じエラーを吐き出すだけだった。

## どうしたのか
結論の通り、デフォルトで入っている/usr/bin以下のgcc関連実行ファイルを退避、/usr/local/bin以下にある新しいgccへのシンボリックリンクを貼った。
【AutoHotkey v1.1】マクロの一括起動と全終了

# 一括起動
指定したマクロを一括で起動するマクロ。

```
Array := ["マクロ1.ahk","マクロ2.ahk","マクロ3.ahk"]
For index, element in Array {
  Run, %element%
}
```
:::note info
一括起動した場合、マクロを複数起動するとタスクバーアイコンが複数並んでどのアイコンとマクロが対応しているかわからなくなるため、各マクロ毎にアイコンを変更させることによって区別できるようにしておきたい。

```
;アイコンの変更
menu, TRAY, Icon, img\\マクロx.png,,1
```
:::

# 全終了

起動しているマクロを全て終了するマクロ。

```
DetectHiddenWindows, On
SetTitleMatchMode,2
GroupAdd, Grp, ahk_class AutoHotkey , , , %A_ScriptName%
GroupClose, Grp, A
```
Pythonコース2周目の世界線3

2周目の3日目：今回は2周目の世界線最終回！！コース4とコース5をやっていくゾ😤


◎復習兼メモ◎

クラスは設計図、インスタンスはモノ(設計図と建築物みたいな感じか)

class MenuItem:←コロン忘れずに！！
　    ↑頭文字は大文字に

インスタンス.インスタンス変数名

クラスの中で定義した関数を「メソッド」という。第1引数に「self」を入れる。

戻り値は「return」

インデントの位置が…ちくしょうがあああああああ！！！！(自爆)

「__init__メソッドに引数を渡そう」が「引導を渡そう」に見えて草。


-----------------------------------------------------------

2周目終わったあああああああああああああああああ！！！！
最終問題めっちゃ答え見た😳すっげえ見た🌟
ここまで来て大体わかりましたって言ってるにんじゃわんこ気持ちよすぎだろ！！！
鳴らない言葉をもう一度描いて〜♪(唐突なワッカウェイ)

またまた業務でPDFを圧縮できるシステムとPDFを結合できるシステム作ったら楽じゃね？って思ってさっそく作りはじめたZE🌟
コードは書けてエラーも潰せたと思うんだけど、exe化させると他のパソコンでも使えるようになるってのを見つけてやってみた。


…ｯｽｩ〜〜〜〜〜〜〜…動かん(゜-゜)

落ち着け、まだ慌てるような時間じゃない👐
これできたら社内革命起きるかもしれんからもうちょっと調べて絶対完成させるゾ！！

こっちでも復習がてら作ってからGitHubにのせるZE🌟

次は3周目世界線にも突入していくぞい(σ・∀・)σ＜夢ならたーくさん見た♪
【TypeScript】API通信を型定義出来る最強ライブラリ！？　TypeScript製　HTTPクライアント　「aspida」とは

## aspida is 何
端的に言うと、aspidaとは API のリクエスト/レスポンスに型を付与するライブラリのことです！！

[aspidaのGithubのURL](https://github.com/aspida/aspida)

API通信に型がつけられるのは画期的ですね。


## aspidaを使えばどんな良いことがあるの？
最近のフロントエンド環境でREST APIリクエストを行う場合、axiosかfetchを使うことが多いかなと思います。
今回は型がつけられるメリットとして、axiosを使いながら例を出していきます。

#### その前に、そもそもaxiosって？
非同期のHTTP通信を簡単に実装することが出来る、Javascriptのライブラリのことです。
基本的なメソッドである、`get`,`post`,`delete`,`put`が用意されており便利です。
大体、Vue.jsを使ってる会社はこいつを使ってるなあという印象(前職も、現職も使ってる箇所があった)です。

#### aspidaを使わない場合
例を出していきます。
以下のようにaxiosで ```/blogs/:BlogID/?user={userId}``` をGETするケースを考えます。

``` ts
interface Blog {
  id: number 
  title: string 
}

const blogID = 1
const userId = 2
const { data } = await axios.get<Blog>(
  `/blog/${blogID}`,
  { params: { userId } }
)
```
axios.get<Blog>で型引数がBlog型であることがわかると思います。
しかし、上記はurlに文字列を使用しているため型的に安全ではありません。

上記では2箇所ほどミスがあります。

``` ts
interface Blog {
  id: number 
  title: string 
}

const blogID = 1
const userId = 2 
const { data } = await axios.get<Blog>(
  `/blog/${blogID}`,  // params: { user: userID } } が正しい
  { params: { userId } } // blogではなくblog"s"　タイプミス
)
```
axiosでは静的に上記のミスを検査することは不可能です。
axiosでGETする際のそもそもの問題点として
- `APIのパスをベタ打ちしているので、タイプミスに気づかない`
- `レスポンスの型がわからない。ジェネリクスを使わないとTypescriptでもanyになってしまう`

といったものが大きいですし、解消することができません。
レスポンスの型についてはジェネリクスを使用して定義をしていますが、そもそも**aspida**
を使ってしまえばライブラリとしてサポートしてくれるので楽です！

### 実際にaspidaを使ってみよう
では使っていきましょう。

```typescript:api/blogs/_blogId@number.ts
import { DefineMethods } from 'aspida'

type Blog = {
  id: number
  title: string
}

export type BlogInfo = DefineMethods<{
  get: {
    query: {
      user: number
    }
    resBody: Blog
  }
}>
```

上のような型定義をすることによって、/api以降のファイル名上をと含めて制約を作成することが出来ます。

- URLは `/blogs/:blogId`
- レスポンスはBlog型
- blogIdはnumber型
- Queryにnumber型のuserが必須

というHTTPクライアントが自動生成されます。
問題点で挙げた
- `APIのパスをベタ打ちしているので、タイプミスに気づかない`
- `レスポンスの型がわからない。ジェネリクスを使わないとTypescriptでもanyになってしまう`

について解決できますね！

https://github.com/aspida/aspida

導入方法については上記URLのREAD.mdのGetting Startedを確認してください！

それでは、リクエスト方法について説明します！

```ts
const blogId = 1
const userId = 2
const blog = await aspida.blogs._blogID(blogId).$get({ query: { user: userId } })
```

上記の場合、blogIDやqueryの型を間違えるとエディタ上でエラーになります。
これならidとtitleの入力ミスも起きませんし、blogsをblogのタイポが起きず、queryのプロパティも間違えることがありません。

aspidaを使うことによってジェネリクスも独自関数も使用することなく型安全なAPIリクエストを行うことが出来ます！！
因みにメソッドの$を消すとステータスコードやヘッダも取得できます。


## 最後に

API通信で型定義出来るのは画期的だなあと思い、まとめさせて頂きました。
REST APIの型の安全性を担保するといった面でGraphQLとライバル的関係になるのかなと勝手に思ってます。

いつか、GraphQLについても記事でまとめてaspidaとの比較もしてみます！！

最後まで見て頂いてありがとうございました！

## 参考 記事/レポジトリ
[HTTP通信をラクに実装できる「axios」の基本](https://webrandum.net/javascript-axios/)
[TypeScript製REST APIクライアント「aspida」](https://zenn.dev/solufa/articles/getting-started-with-aspida)
[aspidaのGithub](https://github.com/aspida/aspida)
SQLとExcelを主に使うアナリストのUS配列HHKBキーマップ

## 自己紹介
未経験から転職して3年の中年データアナリストです。  
転職直前は外食産業で財務経理のようなことしてました。
  
## 何の話
US配列HHKBキーマップ晒しです。以下の背景の私が使っています。  
・もともとタイピングが速い方ではなく、矢印キーに手を移動させると帰ってこれない。  
・SQL、ときどきPython使用。Excelに計算結果を貼り付けて加工しアウトプットにする。

## 環境・デバイス
OS：Windows  
キーボード：Happy Hacking Keyboard Professional HYBRID Type-S PD-KB800BS

## このようなキーマップ
### ・ニュートラル
![ニュートラル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124933/c879452e-0cc9-2dff-e9fb-1bf1aa033cea.png)
### ・FnキーON
![FnキーON](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124933/a363d367-631d-5bf7-1aa0-1bf947343292.png)

## どうしてこうなった
### ・ニュートラル  
1. ESC <- F4  
Alt + F4 でアプリケーションを次々と終わらせるを左手のみでやりたいため。ESCはすぐ押せなくてもいいからFnキーONで打てるようにしている。  
2. : <- Fn  
ホームポジションのまま、右手小指でFn切り替えたいため。:さんは使わない右Shiftさんへ異動  
3. 右winキー <- Appキー  
![Appキー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124933/bf3bbdaa-1ca3-2f93-4690-9906fad23ab1.png)
彼はAppキーっていうんだ。よろしゅうな。おおむねマウスの右クリックの動きをする。
コンテキストメニュー（っていうらしい）右クリックで出てくるアレをマウスに手を伸ばさず出したいため。Excelの特殊貼り付けのときとかセルの書式設定とかでAppキー＋アルファベットで実行したりする。  
4. 右Altキー　<- F2  
Excelのセル編集（追記・修正）をできるだけ速くやりたいため
### ・FnキーON  
1. 矢印キー周り  
よくある配置、ホームポジションから動かさずに矢印操作できる。Page UP/DOWNもよくある配置に。  
Home/Endもエディタで行の左右端に行くときやExcelのカーソル左上にそろえるときよく使うので、準じた位置にしたいが、小指固定のホームポジションから片手で無理なく押せるのがH/Nだったのでそのように配置。  
2. A <- Delete  
ホームポジションで文字を消したいが、暴発を防ぐため左右の手で組み合わせた操作にした。



## Qiita初投稿のきっかけ
「技術書」の読書術 https://www.amazon.co.jp/dp/4798171549/  
  
初心者は初心者の視点で情報発信すれば、それが独自性になる。  
と聞いてアウトプットする気になりました。感謝。
WEBサイト制作_小技『Google Map』

# 『Google Map』挿入
1- 挿入したい場所をGoogle MAPで開く。
2- 共有ボタンをクリック
3- 埋め込みをクリック
4- htmｌをコピー
5- VScodeに貼り付け
## 共有ボタンをクリック
![スクリーンショット 2023-03-09 23.51.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/4b5e112f-70c2-0dfe-e3c6-d44638c7feb0.png)
## 埋め込みをクリック
![スクリーンショット 2023-03-09 23.51.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/f2cffb11-ee58-edcc-6e63-2778d7a5106c.png)
## htmｌをコピー
![スクリーンショット 2023-03-09 23.51.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/3e39d7e4-b13f-b721-eb2f-72f038e643fa.png)
## VScodeに貼り付け
![スクリーンショット 2023-03-09 23.52.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/13d239d2-9525-8118-38c6-d03c44706466.png)
# Live
![スクリーンショット 2023-03-10 0.02.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/c3fb2ae9-ad74-690d-7a9d-ac443beb659f.png)
【Dev Containers】プロジェクト名の設定方法


## 設定方法
プロジェクトルートの`.env`に`COMPOSE_PROJECT_NAME`環境変数を記述することで設定できます。
以下のようにするとプロジェクト名は`sample-app`となります。
```.env
COMPOSE_PROJECT_NAME=sample-app
```
mapメソッドで2次元配列の要素を変換したい

### はじめに
業務で詰まったのでメモ

データベースから、記事一覧(Articlesテーブル)の情報をとってきて、
`タイトル(title)`と`出版日(published_at)`を2次元配列で返したい時の処理です。

`pluck`メソッドを使って以下のようにデータを取得して、指定したカラムのレコードの配列を取得できます。

``` ruby

article = Article.where(条件).pluck(:title, :published_at)

> [["article1", Thu, 31 Dec 2022], ["article2", Wed, 31 Mar 2023]]
```


### やりたいこと

* `Thu, 31 Dec 2022`(Date型)を`2022-12-31`(String型)に変換した配列を出力したい！ 
このように↓
`[["article1", "2022-12-31"], ["article2", "2023-3-31"]]`

*  具体的には、`article1`(配列[0]の配列の[0]の要素)はそのままで、
`"2022-12-31"`(配列[0]の配列の[1]の要素)を `Thu, 31 Dec 2022`から`"2022-12-31"`に変換した配列を出力したい。

### コード
```ruby
Article.where(条件).pluck(:title, :published_at).map { |a| [a[0], a[1].strftime('%Y-%m-%d')] }

> [["article1", "2022-12-31"], ["article2", "2023-3-31"]]
```
* mapメソッドをメソッドチェーンして一行で書けます(簡潔)
* `strftime('%Y-%m-%d')`メソッドを使うことで、文字列を指定のフォーマットで表示できます。
```ruby
.map { |a| [a[0], a[1].strftime('%Y-%m-%d')] }
```

### 終わりに。ChatGPTすごい

自分は最初、`{ |a| a[0], a[1].strftime('%Y-%m-%d') }`と書いていて、
[]がなかったため、SyntaxErrorになってました。

`each`で変換して配列にpushするしかないのか?って小一時間悩んでましたが、
なんとChatGPTに聞いたら一瞬でした。。。

ちなみにどんなふうに質問したかというと

```
Rubyのメソッドを使って
array = [["aaa", 1], ["bbb", 2]]
を
[["AAA", 1], ["BBB", 2]]
にしてください
```
と聞くと、なんと

```ruby
array = [["aaa", 1], ["bbb", 2]]

# mapメソッドを使用して、各要素の最初の文字列を大文字に変換します。
# 最初の文字列以外の要素はそのままにします。
result = array.map { |sub_array| [sub_array[0].upcase, sub_array[1]] }

p result #=> [["AAA", 1], ["BBB", 2]]
```
と返ってきました

変換前の配列と、変換後の配列を教えたら、ちゃんとコメント付きのコードを返してくれました(感動)
Logをテストごとにモックするのは大変なので、専用のルールを作ってみた

Androidのプロジェクトでユニットテストを書いているときに、テスト対象のメソッドの中で`Log.d`などを呼び出していると、以下のようなエラーが出る。

```shell
Method e in android.util.Log not mocked. See https://developer.android.com/training/testing/local-tests#mocking-dependencies for details.
java.lang.RuntimeException: Method e in android.util.Log not mocked. See https://developer.android.com/training/testing/local-tests#mocking-dependencies for details.
	at android.util.Log.e(Log.java)
```

これは、`Log`クラスがAndroidフレームワークに依存しているため、それをJVM上で動かすときに、モックを作成する必要があるということを意味している。

なので、`MockK`を使ってモックすることにする。おそらく次のようになるだろう。

```kotlin
@Before
fun setup() {
  mockkStatic(Log::class)
  every { Log.v(any(), any()) } returns 0
  every { Log.d(any(), any()) } returns 0
  every { Log.i(any(), any()) } returns 0
  every { Log.e(any(), any()) } returns 0
}
```

ただ、毎回これをテストごとに書くのはとても面倒。なのでルールとして作成してみた。

```kotlin
import android.util.Log
import io.mockk.every
import io.mockk.mockkStatic
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement

class MockLogRule: TestRule {
    override fun apply(base: Statement, description: Description): Statement {
        return object : Statement() {
            override fun evaluate() {
                mockkStatic(Log::class)
                every { Log.v(any(), any()) } returns 0
                every { Log.d(any(), any()) } returns 0
                every { Log.i(any(), any()) } returns 0
                every { Log.e(any(), any()) } returns 0

                try {
                    base.evaluate()
                } catch (e: Throwable) {
                    throw e
                }
            }
        }
    }
}
```

ルールを作成する際は、必ず`TestRule`を継承する必要があることを忘れてはいけない。
そして、`apply`メソッドをオーバーライドして、`Statement`を返す必要がある。

実際にテストで使う場合は、次のようになる。

```kotlin
class RepositoryTest {
  ...
  @get:Rule
  val mockLogRule = MockLogRule()

  @Test
  fun xxx_xxx_xxx() = testScope.runTest {
    ...
  }
}
```

これで、毎回`@Before`でモックを作成する必要がなくなったのでテストを書く際の効率化に繋がったと思う。

## 参考

https://stackoverflow.com/questions/36787449/how-to-mock-method-e-in-log
Firestoreでいいね機能を実装してみる

## 学ぶ
https://techblog.sgr-ksmt.dev/2019/12/31/160623/

これを読めばFirestoreでのリレーションもどきについてはおおむね理解できるが、RDBが恋しくてたまらない。

## 出来上がったカスタムhook
いいね状態を判定するためのRefを監視して、トグルするようにしている。

incrementメソッドを使用する場合、データを監視しているSubscribeが保留中の書き込みを反映しない設定にしている(snapshot.metadata.hasPendingWritesを弾いたり)と何故か更新を受け取れないようで、この設定を切る必要があった。なぜかはよくわからない。

また、[拡張機能の分散カウンタ](https://extensions.dev/extensions/firebase/firestore-counter)も試してみたが、batch処理に絡められないのと、エミュレーター上で動かすと権限エラーで使用できず苦しんだ。
かなりの数のリクエストを送ってみてもincrementで処理できていたためコストにリターンが見合っていないと考え、今回は使用しなかった。

```ts:likePost.ts
import { useFirestoreWriteBatch } from '@react-query-firebase/firestore';
import { doc, increment, writeBatch } from 'firebase/firestore';

import { db } from '@/config/firebase';
import { useFirestore } from '@/hooks/useFirestore';
import { useAuthContext } from '@/lib/auth';
import { timestampTemp } from '@/utils/constants';

import type { Post } from '../types';

export type LikePostDTO = {
  data: Post;
};

type UseLikePostOptions = LikePostDTO & {
  config?: {
    // ...
  };
};

export const useLikePost = ({ data }: UseLikePostOptions) => {
  const auth = useAuthContext();

  const batch = writeBatch(db);
  const LikePostBatch = useFirestoreWriteBatch(batch);

  const postRef = doc(db, 'users', data.author.path.split('/')[1], 'posts', data.id);
  const userRef = doc(db, 'users', auth?.user ? auth?.user?.uid : '_');
  const likedUserRef = doc(postRef, 'likedUsers', auth?.user ? auth?.user?.uid : '_');
  const likedPostRef = doc(userRef, 'likedPosts', data.id);

  const likedUserDoc = useFirestore<Post>(likedUserRef);
  const isLiked = !!likedUserDoc.data && !likedUserDoc.isLoading; // 読み込み済みでデータがあればいいね済み
  const canMutate = !likedUserDoc.isLoading; // 読み込み中はいいねできない

  const mutateToggle = () => {
    if (canMutate) {
      isLiked ? mutateUnLikeBatch() : mutateLikeBatch();
    }
  };

  const mutateLikeBatch = () => {
    // いいねをつけたユーザーのリストに自分を追加
    batch.set(likedUserRef, { ...timestampTemp });

    // 自分のいいねした投稿リストに追加
    batch.set(likedPostRef, {
      originRef: postRef,
      ...timestampTemp,
    });

    batch.update(postRef, { likeCount: increment(1) });

    LikePostBatch.mutate();
  };

  const mutateUnLikeBatch = () => {
    // いいねをつけたユーザーのリストから自分を削除
    batch.delete(likedUserRef);

    // 自分のいいねした投稿リストから削除
    batch.delete(likedPostRef);

    batch.update(postRef, { likeCount: increment(-1) });

    LikePostBatch.mutate();
  };

  return {
    ...LikePostBatch,
    mutateToggle,
    isLiked,
    canMutate,
  };
};
```
VBS 画像ファイルのサイズ（幅×高さ）取得 PNG&TIFF対応

# LoadPicture関数では失敗してしまう
JPEGだといけるのに、PNGだとエラーになってしまう。
「たかが縦横サイズだけなのに」と絶望しかけていたら、StackOverflowで海外の方が回答されていました！
しかも、ピクセル単位で取得してくれるので下手な計算も必要ありません。
[StackOverflow - Need to read width/height from graphics file with VBScript/ASP classic](https://stackoverflow.com/questions/57461786/need-to-read-width-height-from-graphics-file-with-vbscript-asp-classic)

# スクリプト
```vb
imgFilePath = "tmp.PNG" 'JPEG、TIFFにも使用できることを確認

' インスタンス作成
Set objImg = CreateObject("WIA.ImageFile")
' ファイルパス指定
objImg.LoadFile(imgFilePath)
' 幅x高さで表示
WScript.Echo(objImg.Width & "x" & objImg.Height & "(ピクセル)")
' インスタンス初期化
Set wia = Nothing

'### または ###
With CreateObject("WIA.imagefile")
    .LoadFile(imgFilePath)
    WScript.Echo(.Width & "x" & .Height & "(ピクセル)")
End With

'### 実行結果 ###
'1920x1080(ピクセル)
```

# 参考
[StackOverflow - Need to read width/height from graphics file with VBScript/ASP classic](https://stackoverflow.com/questions/57461786/need-to-read-width-height-from-graphics-file-with-vbscript-asp-classic)
[WIA.ImageFileオブジェクトについて（公式）](https://learn.microsoft.com/ja-jp/previous-versions/windows/desktop/wiaaut/-wiaaut-imagefile)
Azure DevOps と Excel を連携させる手順で個人的に詰まったので問題と解決のメモ

Azure DevOps のボードの操作を Excel から行いたく、以下のドキュメントを読みながら試そうとしていたのですが、「前提条件」の手順でいきなり詰まってしまいました。

https://learn.microsoft.com/ja-jp/azure/devops/boards/backlogs/office/track-work?view=azure-devops&tabs=open-excel

> Azure DevOps Office 統合プラグインを入手する唯一の方法は、最新エディションの Visual Studio または Azure DevOps Office Integration のいずれかをインストールすることです。 このプラグインでは、Excel から Azure DevOps への接続がサポートされています。

私の PC には既に最新のエディションの Visual Studio がインストールされていたのにも関わらず Excel には統合プラグインが見つからず、また Azure DevOps Office Integration を探そうともしていたのですが、公式ドキュメントに貼ってあったリンクから見つけることができず詰まってしまっていた。

https://visualstudio.microsoft.com/ja/downloads/

私の勘違いでこのドキュメントの説明自体は間違いではなかったのですが、他に詰まる人がいないように見つけた場所をメモします。

## 解決メモ1. 単に Visual Studio をインストールするだけではダメで、Visual Studio Installer から Azure DevOps Office Integration をインストールしないといけない

以下のように Visual Studio Installer の「個別のコンポーネント」から目的のプラグインをインストールできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180121/da2c5c2c-34a8-c016-6a0e-ad2a57d9cc64.png)

## 解決メモ2. Azure DevOps Office Integration のツールのインストーラーリンクはダウンロードページ下部の「その他のTools...」タブに隠れている

以下のスクショのところにあります。よく探せば見つけられると思うのですが、私は気づかずハマってしまいました...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180121/d6557d33-e9a8-dd48-d4a8-021b2d755675.png)

---

前提条件の手順で詰まってしまった以降は問題なく Excel と Azure DevOps を連携させることができました。非常に便利なので興味のある方はぜひ使っていただければと思います。
Mac bash Homebrewインストール

## 概要

- MacにHomebrewをインストールして`$ brew`コマンドを使えるようにする方法をまとめる。

## 方法

1. 下記にアクセスする。
    - [https://brew.sh/index_ja](https://brew.sh/index_ja)
1. 「インストール」の右下のコピーボタンを押下してインストールコマンドをコピーする。

    ![macOS（またはLinux）用パッケージマネージャー_—_Homebrew.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/6fcbd705-1a12-d9e1-80d3-d8981b9964ee.png)

1. コピーしたコマンドをMacのローカルのターミナルに貼り付けて実行する。
1. .bash_profileを開き下記の内容を追記する。

    ```.bash_profile
    export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH"
    ```

1. 下記コマンドを実行して.bash_profileを再読み込みする。

    ```bash
    source ~/.bash_profile
    ```

1. 下記コマンドを実行して正常にhomebrewのバージョンが帰ってきたらインストール完了

    ```bash
    brew
    ```