OmniAICreator/Qiita-1.07M huggingface dataset:
あなたと私の見ている色は同じだろうか？

あすけんの [@sato-shin](https://twitter.com/sankakuButton) です。
哲学的なタイトルですが「カラープロファイルには気をつけようぜ」というお話です。

## はじめに
印刷した画像と、ディスプレイでみた画像を比較して「なんか違う」と思ったことはないでしょうか？
これは表現できる色域の違いから来ています。

色域？カラープロファイル？と思った人のためにざっくり説明を書いておきます。
正確な表現ではないですが、大体合っているはず。

* 色域:表現できる色の範囲
    * 印刷物の場合は、プリンターやインク・トナーの性能に依存する
    * ディスプレイの場合は、ディスプレイの性能に依存する
* カラープロファイル:表現物(印刷物やディスプレイ）によって、色が異ならないように補正する設定・仕組み

実際に体感して見てみましょう。

## 右と左の色は同じですか？

**ブラウザによっては補正がかかるので、画像をクリック・タップして、生画像を見てください。**
![スクリーンショット 2021-12-23 0.25.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46792/db3df5ba-2607-7f7c-bbc5-360e8d9f66aa.png)

この画像はXcodeのカラーアセットで以下のように設定しました。

* どちらも `#00FF00` に設定
* カラープロファイルは左は `sRGB`、 右は `Display P3` に設定

**あなたが見えている2つの色は同じですか？異なりますか？**

私の環境＆私の目では違う色に見えますし、Macにプリインストールされている「Color Digital Meter」を使ってみると、違う色として表現されています。
この違いを産んでいるのが色域やカラープロファイルになります。
（利用している環境によって表現できない色（色域）があるので一緒に見えたり、色覚異常を持っている方にとっては一緒に見える可能性もあります）

利用者のディスプレイの性能は開発者側からは変更することができません。
よって、私たち開発者が特に気にすべきことはデバイス毎に色が異ならないようカラープロファイルに気をつけることです。

## iOS開発で特に気をつけたいカラープロフファイルの種類

* sRGB: MSとHPが策定した。最も一般的なカラープロファイル。WebブラウザとかiOSのデフォルト
* Display P3: Appleが策定した。sRGBより表現できる色域が広い。iPhone7のディスプレイからこの色域を正確に表現ができるようになった
* Adobe RGB: Adobeが策定した。sRGBより表現できる色域が広い。**Xcodeで現状は設定できない**

基本的には、グラフィックにとても気を遣うサービス以外ではsRGBを使うことをオススメします。
なぜかというと、sRGBは1996年に策定されており、現在普及しているほぼ全てのデバイスで同じように表示できるからです。

## 開発者として確認すること

これまで「カラープロファイルは気にしてなかったよ」という方は、
まずは、使っているデザインツール(Figma, sketchなど)の設定と一致しているか確認してみてください。
Xcodeのカラーアセットで、どのカラープロファイルが使われているかはここを確認すればOKです。

![スクリーンショット 2021-12-23 1.23.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46792/4abdd306-b081-2c3f-ccd1-ec70cdff540d.png)

分からないときは、担当のデザイナーさんとお話しする場合にはカラープロファイルは何使ってる？って雑談してみてください。

`Adobe RGB` は現状ではXcodeで設定ができないので、特にUIデザインの成果物がAdobe系列（.aiや.psなど）のファイルだった場合にはAdobe RGBかどうかの確認は必須です。

## さいごに

カラープロファイルを気をつけることで、デバイス毎の差異を最小限にすることができますので、ぜひ実践してみてください。

色の世界はとても奥が深いです。
色に興味が湧いた人はカラープロファイルや色域などのキーワードでググってみたり、
[Apple HIG の Color のページ](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/) を読んだりしてみてください。
【必読】笠松競馬場 12/30(木) 第3レース完全攻略マニュアル【water】

## はじめに
12/30(木)笠松競馬場第3レースの必勝法!?それは…

## python

第1引数にはレースの頭数、第2引数には好きなワードを入れて実行しよう！すると… 

~~~python
import sys
import random

args = sys.argv

uma = 1
umatachi = int(args[1])
umas =[]

while uma <= umatachi:
    umas.append(uma)
    uma += 1

print(args[1]+'頭立て')

random.seed(args[2]) 
random.shuffle(umas) 

print(str(umas[0])+'-'+str(umas[1])+'-'+str(umas[2])) 
~~~

## 実行結果
おぼろげながら浮かんできたんです、数字が。

~~~console
python tsun.py 10 やざわ
10頭立て
8-7-5
~~~

## ちなみに
seed値に神聖三文字を入れて実行した結果は以下となる。真理に辿り着け。3連単に1万突っ込め。

~~~console
10頭立て
7-5-9
~~~

## ちゃんとするなら
"人気"とかパラメータ持ってウェイトをかけたりするかああああ
運動不足を解消！筋トレガチャアプリを作りました

## 全リモートワーカーの困りごと
それは筋トレが続かないことだッ！

## 改善策
なかやまきんに君の筋トレ動画にランダムで遷移するアプリを作りました。
「する！」を押下すると、自宅でできる筋トレ動画27種類のどれかに遷移します。

■ URL：https://matt-note.github.io/kintore-gacha/
■ GitHub：https://github.com/matt-note/kintore-gacha
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288331/ca2be5e1-9cdd-43ed-066e-ecf6b7c29245.png)




## 着想
旅ガチャやホテルガチャといったサービスが出てきたことで、○○ガチャおもしろいなーと思い、「筋トレのガチャがあったら面白いのではないか。健康向上に役立つのではないか」と思い、制作に着手しました。

## 制作
制作、、といっても、あらかじめJSONにURLを定義しておいて、ランダムにそのリンクを生成するだけのショボいクソアプリです。

### 工夫した点① JSONをファイルにせず、べた書きにした
普段JavaScriptを書いていないので、ローカルのJSONファイル取得にfetch API使うかーと思っていたのですが、そもそも使ったことないし、ネットワークアクセスの時間が発生するし、エラーハンドリングもしなきゃだし、、と思っていたところ、「べた書きで全部解決するやん」と思い浮かび、この作りとして工数削減に寄与しました。

### 工夫した点② 背景画像をランダムで表示するようにした
背景画像をランダムで表示しようとしたのですが、普通にこれをやろうとすると、ブラウザのキャッシュから取得してしまうため、毎回アクセスするたびに毎回異なる背景画像を設定することができませんでした。
この解決策は下記のように背景画像をクエリ文字列付きで取得するようにすることでした。クエリ文字列は以前のものと違うのなら何でも良いので、アクセス時刻をクエリ文字列に設定する作りとしました。

```javascript
let randomIndex = Math.floor(Math.random() * BG_IMAGES.length);
document.body.style.backgroundImage = "url(" + DIR_PREFIX + BG_IMAGES[randomIndex] + "?" + new Date().toISOString() + ")";
```

## 終わりに
皆様の筋トレ時間が3分でも増えたなら望外の喜びです。最初は筋トレ動画も全部見ようとせず、適当なところで辞めるのを何回か続けていくというのでも良い気がします。では、最後に皆様の健康を願いまして、、、パワー！

## これで筋トレが続～～かないッ！
平日は仕事で疲れてるし、休日は休みたいしで、筋トレもしたいけど続きませんでしたッ！ ヤーッ！！

### 参考
- 動画: [ザ・きんにくTV 【The Muscle TV】](https://www.youtube.com/channel/UCOUu8YlbaPz0W2TyFTZHvjA)
- フォント: [しょかきうたげ（無料版）](https://booth.pm/ja/items/1492419)
- 画像: [マッスルプラス](https://freephotomuscle.com/)
【Linux】コマンド一覧

## はじめに
　本記事は、プログラミングの学習を始めて1ヶ月の初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

### Linuxコマンド一覧


```

 cd 移動したいフォルダ名   # ディレクトリ（フォルダ）移動

 ls   # フォルダの内容をリスト形式で表示する

 mv (移動元ファイル名/フォルダ名) (移動先ディレクトリのパス)　  # ファイルを移動

 cp (移動元ファイル名/フォルダ名) (移動先ファイル名/フォルダ名)　　　　# ファイルやフォルダをコピーする

 mkdir フォルダ名    # フォルダを作成する　

 touch ファイル名   # ファイルを作成する

 rmdir フォルダ名   # 空のフォルダを削除する

 rm ファイル名/フォルダ名   # ファイルやフォルダを削除する

 pwd    # 現在いるディレクトリを表示する

　find / -name ファイル名   # ファイルの検索

 cat ファイル名   # ファイルの内容を表示する

 diff 旧ファイル名 新ファイル名   # ファイルとファイルの内容の違いを表示する

 grep "検索したい文字" * ファイル名   # 指定した文字列がテキスト内に存在した場合その行を抽出する

 chmod 権限ファイル名   # ファイルやフォルダのアクセス権限を変更する

 chown 変更したいユーザー名   # 変更したいファイル名ファイルやフォルダのオーナーやグループを変更する

 history   # コマンドの履歴を表示する

 ln リンク元ファイル名　リンク先ファイル名/フォルダ名   # ファイルやフォルダにリンクを設定する

 man コマンド   # 指定したコマンドのマニュアルを表示する

 apropos キーワード   # manページの内容を検索する

 less ファイル名   # テキストファイルを閲覧する

 more ファイル名   # ファイルをページ単位で閲覧する


```
Rubyで配列処理

## each

単純な繰り返し処理

```sample.rb
numbers = [1,2,3,4]
sum = 0
numbers.each do |num|
  sum += num
end
p sum # => 10
```

## delete_if
配列を回し、各要素を評価。評価した結果、Trueだった要素を配列から削除する

```sample.rb
# delete_if : 真を返すものを配列から削除する
numbers.delete_if do |num|
  num.odd? # 奇数の場合、真
end
p numbers # => [2, 4]
```

## map
配列を回し各要素に対してブロック内の処理を実行。**新しい配列**を返す。
※Javaのstreamに似ている。
※元の配列には何の影響も与えない

```sample.rb
new_numbers = numbers.map { |num| num * 10 } # 各要素にブロック内の処理を行い、新しい配列を生成する
p new_numbers # => [20, 40]
p numbers # => [2, 4]
```

## select
配列を回し各要素を評価。評価した結果、**Trueだった要素のみの配列を新たに**返す

```
numbers = [1,2,3,4,5,6,7,8,9]
new_numbers = numbers.select { |num| num.even? } # 真になった要素のみの新しい配列を生成
p new_numbers # => [2, 4, 6, 8]
```

## reject
select の逆の挙動

```sample.rb
new_numbers = numbers.reject { |num| num.even? } # 真になった要素を取り除いた新しい配列を生成
p new_numbers # => [1, 3, 5, 7, 9]
```

## find
配列を回し、各要素を評価し、Trueになった最初の要素のみ返す

```sample.rb
new_numbers = new_numbers.find { |num| num % 3 == 0 } # 真になった最初の要素を返す
p new_numbers # => 3
```

## inject

```sample.rb
new_numbers =  numbers.inject(100) { |result, num| result + num }
p new_numbers # 100+1+2+3+4+5+6+7+8+9 = 145
```
Chakra UIで作るポケモン図鑑

これは [エキサイトホールディングス Advent Calendar 2021](https://qiita.com/advent-calendar/2021/excite-hd) 23日目の記事です。
## はじめに
iXIT株式会社の小長谷です。
2021年11月に[ポケットモンスターのシリーズ最新作](https://www.pokemon.co.jp/ex/bdsp/ja/)が発売されましたね！
なのでポケモン図鑑を作ってみたいなと思い、TypeScriptでポケモン図鑑を作ってみました。
今回はその際に利用したAPI、UIライブラリの紹介をしたいと思います。
## 完成サイト
見た目は以下のようになっています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297796/48cfdf77-d6cf-8918-3505-094ad3f7c5db.gif" width="60%">

以下のサイトでぜひご覧ください！
https://pokedex-ts-flame.vercel.app/
ソースコードは以下になります。
https://github.com/kngy0306/pokedex-ts
## 使用言語など
- TypeScript
- React
- Chakra UI


## ポケモンAPIについて
ポケモンのデータはすべて[PokeAPI](https://pokeapi.co/)から取得しています。
PokeAPIからはポケモンの名前、図鑑番号など様々なデータを取得することが可能です。

今回作成したものは、シンオウ地方という地域に生息するポケモンのみを表示しているので、図鑑番号を387番から493番に絞ってデータを取得しています。

## Chakra UIについて
[Chakra UI](https://chakra-ui.com/)は、ReactのUIコンポーネントライブラリで、様々なコンポーネントが用意されています。その中で今回の開発に使用したコンポーネントを紹介します！

#### SimpleGrid
ポケモンの表示は、画面サイズによって列数を変えるようにしました。[SimpleGrid](https://chakra-ui.com/docs/layout/simple-grid)というコンポーネントを利用して簡単に作成することができました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297796/a198c56b-5f81-9a24-81ca-d5bcd7877b01.png" width="80%">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297796/740c0cd3-06b1-e349-975e-2eabc708bbb1.png" width="80%">


#### Modal Dialog
このサイトではポケモンをクリックすると、モーダルでポケモンの詳細を表示するようにしています。ドキュメントのサンプルを参考にアレンジしました。こちらは[Modal Dialog](https://chakra-ui.com/docs/overlay/modal)というコンポーネントを使用しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533114/85600444-7178-5977-f57c-0fc2d51a5e93.jpeg" width="80%">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533114/eb6cc379-10c1-1f5a-f5a5-47666b793638.jpeg" width="80%">

## 最後に
ポケモン図鑑をChakra UIフル活用で作成してみました。
ドキュメントには実際の挙動と、そのコードがすぐ下に記載されているのでとても便利です。ほとんどCSSを書くことなく見た目を作ることができるので、とてもおすすめです！

アドベントカレンダーはまだまだ続きます！お楽しみに！
[Django REST Framework] APIViewを使ったときのurls.pyの書き方

# APIViewを使ったときのurls.pyの書き方


# 結論
ViewSetとAPIViewだとurlの定義方法が違うので注意しましょうという話

```urls.py
router = routers.SimpleRouter()
router.register(r'users', UserViewSet) # ViewSet
router.register(r'accounts', AccountViewSet) # ViewSet

urlpatterns = [
    path('forgot-password/', SampleView.as_view()), # APIView
]

urlpatterns += router.urls
```






# 過程
APIViewは任意のエンドポイントを定義したいときに使うViewクラスで例えばPOSTだと以下のように書く。

```views.py
class SampleView(APIView):
    def post(self, request, *args, **kwargs):
        serializer = SampleSerializer(data=request.data)
        serializer.is_valid(raise_exceptions=True)  
        serializer.save()
        return Response(serializer.data)
```

これに対してViewSetはモデルに足してCURDを全部定義してくれるViewクラスである。

```views.py
class SampleModelViewSet(viewsets.ModelViewSet): 
    queryset = TestModel.objects.all()
    serializer_class = TestModelSerializer
```

この２つでurlsの書き方が違うというところが罠。


#　参考文献
- [DRF公式ドキュメント](https://www.django-rest-framework.org/api-guide/routers/)
ChakraUIのいろんな方法で真ん中寄せする

[KDDI Engineer&Designer Advent Calendar 2021](https://qiita.com/advent-calendar/2021/engineer-designer)の25日目の記事です。最終日なのに小粒なネタを投稿します。

今までMaterialUI(MUI)を使っていたのですが最近ReactでChakraUIを始めてみました。
レイアウトを組む方法が様々な方法があるため、「縦方向＆横方向で真ん中寄せ」をいろんな方法で書いてみました。
何故真ん中に寄るのか説明しながらそれぞれのコンポーネントの特徴を説明していきたいと思います。
真ん中寄せ生活の参考にしてもらえると幸いです。

# 真ん中に置くコンポーネント
以下のコンポーネントを真ん中に置く想定で説明していきます。

```TypeScript
const RectBox :React.FC = () => (
  <Box bg='gray.500' boxSize={100} />
)

```
以下の例1~6すべてにおいて、以下が表示されます。
![スクリーンショット 2021-12-23 0.45.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149986/cb471b02-8584-f6c9-4958-0f81c37cda12.png)


## 例１.Boxで

```TypeScript
<Box h={200} display='flex' justifyContent='center' alignItems='center' bg='gray.100'>
   <RectBox />
</Box>
```

Boxにhを指定することで高さを指定しています。
あんまりChakraUIっぽい書き方じゃないです。MaterialUIを使っていたときはこうやって書いていました。
```display='flex'```がついている状態で```justifyContent='center'```をつけると縦方向に真ん中寄せ```alignItems='center'```をつけると横方向に真ん中寄せします。

参考：

https://chakra-ui.com/docs/layout/box

## 例2.Centerで真ん中寄せ
```TypeScript
<Box h={200} bg='gray.100'>
   <Center h='100%'>
     <RectBox />
   </Center>
</Box>
```

この例では、```<Center>```を使って真ん中寄せができます。alignもjustifyも指定不要です。ただし、```h='100%'```をつけないと高さがないため上に張り付いてしまいます。高さを明示的に書く必要があります。

参考：

https://chakra-ui.com/docs/layout/center

## 3.Flexで真ん中寄せ
```TypeScript
<Flex h={200} justify='center' align='center' bg='gray.100' >
  <RectBox />
</Flex>
```

Flexを使っていますが、例１とやっていることは近いかもしれません。
```justify```で```justifyContent```と同じ、```align```で```alignItems```と同じ意味になります。
Boxでは```justify```と```align```は省略の意味で使えないので要注意です。

参考：

https://chakra-ui.com/docs/layout/flex#usage

## 4.Flex & Spacerで長さ調整
```TypeScript
<Flex h={200} align='center' bg='gray.100' >
   <Spacer />
   <RectBox />
   <Spacer />
</Flex>
```
Spacerをいれることで両端を調整します。縦方向は```align='center'```で調整してます

参考：

https://chakra-ui.com/docs/layout/flex#using-the-spacer

## 5.HStack
```TypeScript
<HStack h={200} justify='center' bg='gray.100'>
   　<RectBox />
</HStack>
```
HStackを使うと水平方向(Horizontal)、つまり横方向に積み上げることができます。
（敢えてHStackを持ってきましたが、今回のように１個だけ置くなら使わないでしょう）

## 6.VStack
```TypeScript
<VStack h={200} justify='center' bg='gray.100'>
    <RectBox />
</VStack>
```
VStackを使うと垂直方向(Vertical)、つなり縦方向に積み上げることができます。Flexの時は、水平方向に積むため```align='center'```で縦方向が中央になりましたが、VStackは垂直方向に積むため```justify='center'```にする必要があります。

（敢えてHStackを持ってきましたが、今回のように１個だけ置くなら使わないでしょう）

参考：

https://chakra-ui.com/docs/layout/stack

### あれ？真ん中に寄らないな？と思ったら
 
- justifyとalign逆になってないか確認しましょう justifyは主軸方向、alignは交差軸方向
- heightを書かないと高さ方向は寄せてくれない
【Laravel5系】外部キーを2つ持つテーブルのリレーション

#やりたかったこと
ツイッタークローンのアプリを作成中。
ユーザのフォロー・フォロワーの管理をするfollowsTableから、ログイン中のユーザのフォロー人数、フォロワー人数がほしい。

#マイグレーション
usersのidをずっと「increments」にしててmigrateでエラーになってた。
→followsの「unsignedBigInteger」に合わせたら解消した。（合ってるのかな？）

 - usersTable

```create_users_table.php
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->unsignedBigInteger('id')->autoIncrement();
            $table->string('username',255);
            $table->string('mail',255);
            $table->string('password',255);
            $table->timestamps();
        });
    }
```

 - followsTable

```create_follows_table
class CreateFollowsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('follows', function (Blueprint $table) {
            $table->increments('id')->autoIncrement();
            $table->unsignedBigInteger('follow_id');
            $table->unsignedBigInteger('follower_id');
            $table->timestamp('created_at')->useCurrent();

            $table->foreign('follow_id')
            ->references('id')
            ->on('users');

            $table->foreign('follower_id')
            ->references('id')
            ->on('users');

            $table->unique(['follow_id', 'follower_id']);
        });
    }
```

#モデル
Eloquentのリレーションを組む。
自分はusers対followsは多対多だと思っています。

 - User.php

```User.php
class User extends Authenticatable
{

   // 一部省略

    public function followUsers(){
        return $this->belongsToMany('App\User', 'follows', 'follow_id', 'follower_id');
    }
    public function followerUsers(){
        return $this->belongsToMany('App\User', 'follows', 'follower_id', 'follow_id');
    }
```

#コントローラ
ログインしているユーザの情報から、モデルで作ったfunctionを呼び出す。

```HomeController.php
class HomeController extends Controller
{
    //
    public function index(){
        $user = Auth::user();

        //ログインユーザのフォローしている人数
        $follow = $user->followUsers;
        $followCount = $follow->count();

        //ログインユーザのフォローされている人数
        $follower = $user->followerUsers;
        $followerCount = $follower->count();

        return view('posts.index',compact('user', 'followCount', 'followerCount'));
    }
```

#ビュー
コントローラで渡した変数をぶちこむ。

```home.blade.php

<p>{{ $user->username }}さんの</p>
<p>フォロー数</p>
<p>{{ $followCount }}名</p>
<p>フォロワー数</p>
<p>{{ $followerCount }}名</p>
```

#まとめ
まだまだ初学者ですが、欲しかったデータを持ってこれて感動したので初投稿しました。
もし指摘やもっといい方法があれば教えて下さい！
開発生産性を上げる、プログラムの抽象化とは【エンジニアになるために、コンピューターサイエンスの基礎を学ぶ　01】

本記事は、投稿者が勉強したことをアウトプットするために書いたものです。記事の内容が間違っている可能性がございますことをご了承ください。また、記事の知識はそのすべてを網羅しているわけではありません。参考文献を最後に乗せていますので、完璧に学びたい方はそちらを参考に。

#抽象化とは何ぞや
抽象化とは、思考における手法のひとつで、対象から注目すべき要素を重点的に抜き出して他は捨て去る方法である。
>引用：[Wikipedia「抽象化」](https://ja.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E5%8C%96)

<br>
なるほどなるほど。
<br>
もっと簡単に言うとおそらく、**一番大事なところだけに注目して、他はとりあえずほっとく**という事なのでしょう。
そして最も気になるのは、この抽象化という思想がなぜプログラミングにおいて重要なのかという点です。
<br>
#抽象化はなぜプログラムで重要なのか
取り敢えず下記のコードを見てみましょう。
（投稿者が現時点で一番学んでいるのがJavaScriptなので、それで書いています。）

```JavaScript
function drawsquare() {
    let ctx = document.getElementById('cvs').getContext('2d');
    ctx.fillStyle="red";
    ctx.fillRect(10, 10, 100, 100);
}
```
<br>
これがどういったことをしているコードか分かりますでしょうか？
すでにある程度JavaScriptを学んでいる方や、ほかのプログラミング言語をやっている方なら分かるかもしれません。
<br>
でも、ほかの多くの人には分からないと思います。
<br>
ですが、最初の行の`drawsquare()`を見れば、何をしたいかなんとなく分かります。
「drawsquare」を直訳すると「正方形を描く」です。
<br>
**ああこれは正方形を描きたいプログラムなんだな、と分かります。**
**これが抽象化です。**
<br>
**「一番大事なところだけに注目して、他はとりあえずほっとく」**、です！
<br>
全てのコードを読まなくても、最初の一行を読むだけ。
それで何をするためのコードなのか瞬時に理解できます。
<br>
#理解しやすいプログラムは生産性を上げるということ
プログラムというものは一回書いて終わりというものではありません。
<br>
アップデートを行うためにコードを書き足したり書き換えたり。
必要なくなったコードを削除したり。
それらと整合性を保つためにプログラムの他の部分を書き換えたり。
<br>
頻繁にファイルを開いて、プログラムを読みます。
プログラマーは基本チームで開発するので、他人が書いたコードも読みます。
<br>
二つのコードを見比べてみてください。
もし初めて見るプログラムだったとき、どちらの方が理解しやすいでしょうか。
<br>
・ひとつ目のコード

```JavaScript
function 関数名() {

//数百行～数千行のひたすら長いコード
//   ~
//   ~
//   ~
//   ~
//   ~

}
```

・ふたつ目のコード

```JavaScript
function 関数名() {

  function わかりやすい名前() {
  //数十行程度のコード
  //   ~
  }

  function わかりやすい名前() {
  //数十行程度のコード
  //   ~
  }

  function わかりやすい名前() {
  //数十行程度のコード
  //   ~
  }

  //   ~
  //   ~
  //   ~

}
```

<br>
ふたつ目の様に機能ごとに詳しく分割してあるコードの方が遥かに分かりやすいはずです。
<br>
プログラムの抽象化は、こういったコードの分割にも使用できます。
これをすることで、コードの読みやすさがさらにアップすることでしょう。
<br>
#抽象化すればプログラムの中身が分からなくても何とかなる
**もう一つ、プログラムの抽象化による恩恵があります。
それは、プログラムの中身を理解できなくてもその使い方を簡単に理解できるという事です。**
<br>
JavaScriptを書くときにお世話になるコードがいくつもあります。
これはその一部なのですが……

```JavaScript
Math.floor(数値を入れる);  //数値の小数点以下を切り下げて整数にする
Math.ceil(数値を入れる);   //数値の小数点以下を切り上げて整数にする
Math.random();            //0 以上 1 未満の疑似乱数を取得する
```

<br>
これらのコードは、この一行を入れるだけでその機能通りの数値をポンと出してくれます。
<br>
プログラムを少しかじった方なら分かると思いますが、
**プログラムとは非常に単純な命令を多く組み合わせることで、複雑な機能を作ることができるものです。**
<br>
この三つのコードも、私たちの知らない裏で複雑かつ大量のコードが動いているはずです。
でも、私たちはこの一行を描くだけでこの機能を活用できます。
**このプログラムの中身が分からなくても。**
<br>
英単語の意味も非常に分かりやすいですよね。
それぞれMath.floor（数学.床）、Math.ceil（数学.天井）、Math.random（数学.ランダム）です。
<br>
これこそ抽象化の思考そのものである、
**一番大事なところ（プログラムの機能）だけに注目して、他（プログラムの中身）はとりあえずほっとく**なのです。
<br>
#参考文献
Webアプリケーションサービス：[Recursion](https://recursionist.io/)
Facebook社のガチエンジニアが作った、日本語でコンピューターサイエンスを学べるサービス。

<br>
<br>
Power BIレポートをつくるときに気をつけること 初級

# はじめに

https://qiita.com/hanaseleb/items/bfd9ce5f46f0a0e2058f

アドベントカレンダーで上記の記事をかきました。
オープンデータをAPIで取得してきて、日本の都道府県別の人口推移をプロットするという内容でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/dc53fec9-1b18-37e1-819c-a71f9161c956.png)

# レポートをつくるときに気をつけること

### 変わらないデータを再取り込みするのは無駄

コミュニティで

>当面変化のないデータを再取り込みするのは無駄ですよ

とご指摘いただきました。

つまりこのレポートの作成過程においては、

**都道府県データ**

のことを指します。

日本の47都道府県についてはたしかにおそらく当面は変化することはないはずなのに、このレポートにおいてはデータの更新のたびに47都道府県を再読み込みする形式になっています。
API連携で都道府県データを取るときにコケることもあるでしょうし、リソースをわずかかもしれませんが使いますし、更新時間も少しは伸びてしまいます。毎日、毎月、この作業を繰り返すことになるので、たしかに無駄です。

# 解決方法①

:::note
2022/01/22 記事更新しました。
「読み込みを有効にする」のチェックを外すのではなく、「レポートの更新に含める」のチェックを外すべきでした。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/2b256575-9419-e77f-dc46-6eb1fd1f7416.png)

#### **レポートの更新に含める** のチェックを外す。

これでQueryの更新がはしらなくなるので、リソースをくう心配はなくなります。

# 解決方法②

手入力。です。

47都道府県はほぼ普遍ということも考えると、手入力しちゃうのが早いかもしれません。

このテーブルの作成はEXCELからコピー＆ペーストも可能なので、この場合はそれがはやいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/d3204a45-7a5b-f05e-b541-8bd59cbf0241.png)

# まとめ

奥が深い。
情報セキュリティマネジメント試験受験レポート

##はじめに
　12月に情報セキュリティマネジメント試験を受験し、合格基準点を突破しました。正直Qiitaに書くほどの話でもないように思うのですが、ほかの資格に比べて比較的受験レポートが少ないように思いましたのでケーススタディとして残しておこうと思います。もしよければ参考にしてください。

##バックグラウンド
　私自身のスペックとしては

* 非IT系学部→非IT理系院卒のなんちゃって理系
* IT？系に1年弱勤務→現教員（非情報教科担当）
* Rは業務で使える程度、Pythonは頑張れば仕事効率化に使えなくもない程度
* ネットワーク・セキュリティの知識はほぼ一般人並
* 11月にITパスポート合格（得点は70％前後）

といったところでしょうか。少なくとも情報セキュリティ分野については**ITパスポートに通る程度の知識はある一般人**、という認識で十分かと思います。

##なんで受けたの？

　**A.生徒がITパスポートほしいって言ってたから**

　たとえ教えるにしても資格を持ってないやつに教えられるのは気分が良くないだろうと思いITパスポートに合格→ついでだからもう一つ上も取っておこうと思い受験、という流れです。王道の基本情報技術者を取るという案もあったのですが、流石に業務をこなしつつ3週間で絶対受かるレベルに持っていけるか不安だったため、比較的簡単とされる情報セキュリティマネジメントを選択しました。

##勉強方法

####午前問題

* とりあえず書籍で勉強してみる（3時間）

[令和04年 情報セキュリティマネジメント合格教本](https://www.amazon.co.jp/E4-BB-A4-E5-92-8C04-E5-B9-B4-E6-83-85-E5-A0-B1-E3-82-BB-E3-82-AD-E3-83-A5-E3-83-AA-E3-83-86-E3-82/dp/4297124114/ref=dp_ob_title_bk)
正直最新版の書籍であればなんでもよかったのですが、ひととおり知識を入れるべくこちらの本を買って2/3ぐらい流し読みしました。

* 過去問演習（15−20時間）

[情報セキュリティマネジメント試験ドットコム](https://www.sg-siken.com/)
ITパスポートに引き続きお世話になりました。最初は6割届かない程度の正答率だったのですが、受験寸前にはおそらく70-80％ぐらい正解できるレベルまで達していた気がします。記録によると解いた問題数は約400問でした。

####午後問題

* 過去問演習（1−2時間）

当時多忙だったこともあり、前日まではほぼなにもせず当日に4問程度過去問を解いて臨みました。終わってから今にして思うと、もう少し問題を解いておいてもよかったかなと感じています。問題形式に癖があるので初見で行くよりはある程度雰囲気を知っておくことをおすすめします。

##受験時の感想

私は午前試験を13:00〜、午後試験を15:00〜で同日受験しました。

####午前問題

　受験票に記されていた開始時間より15分程度早く入室でき、そのまま問題を解いていって構わないとのアナウンス。特につっかえることもなく25分程度で解き終わって退室しました。過去問そのままの問題もあったほか、懸念だった略語は元の英単語が括弧付きで書いてあったのである程度手応えはあった気がします。

　退室後5分ほどでスコア通知が届き、合格基準点突破でほっと一息。息抜きにカラオケ（舐めてんの？）＆食事を済ませ午後試験に備えました。

####午後問題

　午前問題同様開始時間よりかなり前に入室し、問題解答を開始できました（ひょっとすると会場特有？）。出題形式としてはほぼ過去問と同様でしたが、大問によってはなかなか難しく、かなり悩まされました。とはいえ解答自体は45分程度でできたので、こちらもある程度手応えはあったように思います。

　結果退室後5分程度でスコア通知が届き合格基準点突破。それほど力を入れて勉強したわけではなかったとはいえ、おもわずガッツポーズ。市街地の真ん中でスマホ画面を眺めながら喜ぶ不審者と化してしまいました。

##結果・考察もどき

　午前が74点、午後が72点とともに基準点からある程度余裕を持っての合格となりました。勉強時間に換算するとせいぜい20時間程度だったように思いますので、上々の結果だと思います。

　午前は最大の主眼となるテクノロジ系が66%とやや不安の残る結果でしたが、マネジメントとストラテジは80％前後正答できていましたので、**ITパスポートの知識があればテクノロジ以外の知識は上積み不要と言える**と思います。

　午前は1問が満点、ほか2問が60％弱という正答率でした。事前学習がわずかであっても午前問題を突破できれば、知識面は問題ないという証左になったかと思います。むしろ重要なのは読解力と情報を精査し判断する能力だと感じました。イメージとしては共通（センター）試験の資料問題や国語・英語長文問題を解く感覚にむしろ近いように思います。**知識量はもちろんですが、日頃から資料を読み解く技術をつけておくことが合格への近道**なのではないでしょうか。

　また、現状情報セキュリティマネジメント試験と基本情報技術者試験はCBTとなって以降の過去問題が公開されていませんが、過去問演習による学習が十分に有効であると判明したのは今後基本情報を受ける上でもよかったと思います。

##合格してよかったこと

　まだ二週間でいいも悪いもクソもないだろという話なのですが、最大の利点はやはり自信の面かと思います。合格直後にICTに関して組織内研修を行う機会があったのですが、**「俺は国家資格保持者様だぞ」**という強い気持ちを持って研修に臨むことができました。~~裏を返すと今の職場ではほかに活かせることがあるか微妙なのですが~~

##今後について

　2022年4月の応用情報技術者試験＆6月の基本情報技術者試験をターゲットにします。並行して基本情報の問題も触れていたのですが、半年あれば余裕を持って合格点まで持っていけると感じたのでもう一つ上のランクを狙う意図です。（よい）結果が出ましたら報告したいと思いますので、またよろしくおねがいします。
日常から学ぶ 気づきの法則

Jira のバックログにおいて、
もう見返さないであろうストーリーとかタスクチケットを、ときどき却下しまくって、
小さな業務改善気分を味わっています

今回、少し思い切った断捨離にトライしました

最近追加したストーリーとタスク以外の過去数年分のチケット 135個 を、
チームメンバー全員に1週間ほど目を通し確認してもらった後に、
135チケットすべてを却下して**バックログ断捨離**を実行しようと思い立ちました


# ふと思いついたこと

ところで削除対象の 135 チケットっていまのバックログのリスト全体のどのくらいの割合だ？

ぜんぶで 462 チケットあって 135 チケット削除したら 327 チケットになる、
ということは、135 チケットは現在のチケット全体の 29.2 %を占める．．．
リスト画面の項目が 3割 も減ったら、画面のパフォーマンス向上するかもな．．．

よし、測ってみよう ♪

# パフォーマンス計測

Chrome ＞ Dev Tool ＞ Lighthouse ＞ Performance にて、
チケット3割削除の前後の、5回の計速値の平均で、数値が向上するかどうか確認しました

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46880/43146bac-2d07-8089-f172-5cc1cf48f6a0.png)

計測結果値を眺めてみて、
メンバーにとって業務影響が最もイメージしやすい項目として、

- Time to Interactive ：  UI全体が操作可能になるまでの時間

による比較をしてみようと思いました

## 削除前と後のTTI（Time to Interactive）の比較

Jira のバックログ一覧画面をリロードして、
Lighthouse の Performance を実行する作業を前後とも5回ずつ繰り返しました

| | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | 平均 | 改善 |
|:--|:--|:--|:--|:--|:--|:--|:--|
| before | 7.4 | 12.8 | 9.7 | 9.6 | 9.6 | 9.82 ||
| after | 7.4 | 7.4 | 7.4 | 7.9 | 8.2 | 7.66 | **2.16 s** |

ページのロード時に、**画面が使えるようになる時間**が、
9秒から7秒になり、**2秒改善** という結果になりました

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46880/739a21cf-fc67-87b2-4dce-2f17282d3776.png)


# 得られた効果

チームメンバーにアンケートを取って平均を出したところ、
この Jira の バックログ 画面の1日のロード回数は 4.85 回となりました
シンプルに 1日 4回ロードしてると仮定しますと．．．


## 時間

年間 200営業日 で
15人 のメンバー が
1日 平均4回 画面ロード する場合に
表示速度が 毎回 2秒短くなると
チーム全体で年間 6.7時間

つまり、Jira 操作に費やしている時間を 6.7時間 削減できた、ということです

チーム全員で、**いままで捨てていた年間 6.7時間** を取り返せたことになります


## 効率

上述の計算の通り、チケットは 29.2 %削減できました

画面スクロールや目視での検索において、
無駄が3割ほど削減し、作業効率が向上できました
集中を阻害する要因も削減できたと言ってよいでしょう


# 所感

何気ない日常の作業について、
面白がって進められる方法を模索したり、
自身がほぼ事務的に行っているような業務の価値を再確認し、
効果があれば可視化して、
こうして自慢気にアウトプットして ｗ より楽しんでみたり

こんな風に仕事ができている自分っていま、
大丈夫そうだな ｗ って実感しました


# 考察

ともあれ、
実は以上のような取り組みを実践することは、
自身の目標評価サイクルを回す時や、
プロダクトの分析やデータサイエンスの解法を導き出す時など、
いろいろな場面でプロセスを生み出す時の作業と似ているところがあります

埋もれている法則性を見つけ出すことや、
まだ調べられてないことを調査し可視化しようとする動機と好奇心を持つことの価値、は
とくにデータサイエンスを進める際にも大切なポイントになります

ですので、事業プロダクトについても、
常日頃から上記のようなスタンスで、
没頭し面白がりながら好奇心と行動量を高い水準で維持しておくことで、
新しい指標や効果、価値を発見する確率を上げることができそうだ、
と感じた取り組みでした



# まとめ

- 何気ない**日常を面白がる素材**はすぐ手元に転がっている
- 日常を**面白がれる**と**活力**が湧く
- 埋もれた**価値**を**再発見**しわかりやすい指標で**可視化**するスキルは有用である
- **没頭**し**面白がり**ながら**好奇心**と**行動量**を維持することで、**気づきの確率は上げられる**
RailsのActiveRecordのcount、length、sizeメソッドの違い

# はじめに
いよいよダットのターンです！たまにはRailsについて書かずHTMLかJavascriptばかりの記事を投稿したので今回はRailsのメソッドについて説明させていただきます。:pray:
開発者としてはこれらのメソッドを触ったことがあるはずですね。風通はこの三つの中に勝手に選んでどっちでも使って無事で計算されるので大丈夫と思いましたが、実はそうでしょうか？実際は場合によって返った結果も変わって実行する時間も異なる可能性があります。さっそくですが、始めましょう！

# 概要
この記事はこれらのメソッドがRubyに使われる時を気にしないでActiveRecordに使用する時だけ中心してください。結局、アソシエーションの中に幾つのレコードがあるか教えてくれますが、内部の処理がちょっと違います。
例えば、このモーデルとリレーションがあります。

```ruby:app/models/post.rb
class Post
  has_many :comments, dependent: :destroy
end

```

```ruby:app/models/comment.rb
class Post
  belongs_to :post
end

```
### post.comments.count

SQLのCOUNTのクエリを実行して結果からエレメントを数えます。この`count`の前に条件を絞ってサブセットのエレメント数を数えることもできます。

```terminal
$ post.comments.count
(1.0ms)  SELECT COUNT(*) FROM `comments` WHERE `comments`.`post_id` = 1
=> 3

$ post.comments.where(author: 'dat').count
(1.0ms)  SELECT COUNT(*) FROM `comments` WHERE `comments`.`post_id` = 1 AND `comments`.`author` = `dat`
=> 1
```
尚、リレーションに`counter_cache: true`を使用したら`count`は新しいクエリを実行せず、すぐにキャッシュの値を返るようになります。
カウンターキャッシュはこの記事に書いてありませんが[これ](https://blog.appsignal.com/2018/06/19/activerecords-counter-cache.html)は参考になるかと思っています。:rolling_eyes:
### post.comments.length
この場合はアソシエーションのコンテンツをロードしてロードされたエレメントを数えます。このメソッドはアソシエーションが既にロードされたらもう一度クエリを実行しません。

```terminal
$ post.comments.length # クエリが実行される
Comment Load (1.1ms)  SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` = 1
=> 5

$ post.comments.length # もう一度実行するとクエリが実行されなくてすぐに返す
=> 5
```

### post.comment.size
これは以上の二つのメソッドを合わせるものです。もしコレクションが既にロードされたら`length`メソッドのようにすぐに結果を返します。逆だったら`count`メソッドのようにクエリを実行して結果を返します。ザッと見るとこのメソッドが全部自動的に適当な方法を選んで実行するのでもっとも良いメソッドかなと思う人もいますね。しかし、特別なケースによって意外と間違った結果を返す場合もあります。具体的な例を出そうと思ってます。

```terminal
$ posts = Post.all
Post Load (1.7ms)  SELECT `posts`.* FROM `posts`
$ posts.length
=> 3
$ posts.size
=> 3
$ post.count
(1.0ms)  SELECT COUNT(*) FROM `posts`
=> 3
```
以上の例を見るとコレクションが既にロードされたら`count`は無駄なクエリを実行しまったとわかります。だが、ロードされたコレクションが変更したらどうなりますか。:thinking_face:

```terminal
$ posts = Post.all
Post Load (1.7ms)  SELECT `posts`.* FROM `posts`
$ Post.last.destroy!
=> # 消されたエレメントを返す
$ posts.length
=> 3
$ posts.size
=> 3
$ post.count
(1.0ms)  SELECT COUNT(*) FROM `posts`
=> 2
```
つまり、新しいクエリを実行しないと変更があるかどうか分からなくて間違った結果を返してしまいました。なので、この場合は`count`しか使えません。

# 結論（TLDR)
- クエリから取ったデータをもう使わなかったら、`count`を利用すると良い
- クエリから取ったデータを既に使ったか使う可能性があったら、`length`を利用すると良い
- Railsに任せたかったら`size`を利用することもできる。しかし、意外と間違った結果が返される可能性があるのでよく分析してから`size`を代わりに適当な`count`か`length`を使用したら良い :ok_hand: 

# 終わりに
これは自分が実装したときどっちの方がいいのか悩んで調べた内容からまとめておいたのです。具体的な説明とか他の例を見たい方は以下の記事でも参考になると思います。ここまで読んで頂いて感謝いたします。:bow:

- https://web.archive.org/web/20100210204319/http://blog.hasmanythrough.com/2008/2/27/count-length-size
- https://medium.com/ruby-daily/comparing-count-length-and-size-in-ruby-on-rails-e061840bc19e
- https://stackoverflow.com/questions/6083219/activerecord-size-vs-count
【Apigee】KeyValueMapから値取る方法

Apigeeの仕様については、公式のドキュメントやYoutubeにアップされている説明動画がたくさんあるのでありがたいです。
ただ謎に細かいところでつまずいたりしたので一応メモ。

# KVM (KeyValueMap) とは
キーと値のセット。
Apigee内で使用可能なConfig値のようなイメージ。
認証情報やターゲットURLなど、プログラムの変更とは関わらない変更が生じる場合に使用。

環境毎に別の値を設定可能。例えば同じ名称のKVMをprodとtestに作成しておけば、APIプロキシがデプロイされている環境のKVMをApigeeは取得してくれる。
[※公式の説明動画](https://www.youtube.com/watch?v=l1OqKOlSqo8)

# KVMの設定
サイドバーの [Admin] ⇒ [Environment] ⇒ [Key Value Maps]
に現在設定済みのKVMが一覧表示される。
※UIは頻繁に変わってるっぽい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364867/688bbfb0-8721-6d80-7478-9f7a98de2ce8.png)

###手順（画面ポチポチ）
KeyValueMapは、こんなイメージ↓で作成される。

```
KVM1
 |_ key:value
 |_ key:value

KVM2
 |_ key:value
 |_ key:value
 |_ key:value
```
1. 画面右上の「+ Key value map」押下で出るダイアログで作成するKVMの名前を入力
2. 暗号化するかどうか選択（チェックボックス）して、Add
3. 作ったKVMを選択
4. keyとvalueの組み合わせを入力していく

# KVMの取得

1. ポリシー「Key Value Map Operations」を選択
2. 取得対象のKVM名を指定

```
<KeyValueMapOperations async="false" continueOnError="false" enabled="true" name="Key-Value-Map-Operations-GetConfig" mapIdentifier="Config">
～～～～～～中略～～～～～～～
    <Get assignTo="private.httpTargetUrl">
        <Key>
            <Parameter>HTTPTargetUrl</Parameter>
        </Key>
    </Get>
```
・KeyValueMapOperationsタグのmapIdentifier属性で、KVM名を指定
・Keyタグ内で対象のkey文字列を指定
・GetタグのassignTo属性で、取得した値を格納する変数名を指定
※この際、暗号化済みの値を取得する場合は「private.」を使用する必要があります（上記の例）。

これで、後続のポリシー内でKVM値が参照可能になります。
上記の例だと「private.httpTargetUrl」を指定することで取得できます。

```
context.getVariable("private.httpTargetUrl")
```
[※KeyValueMapOperationsポリシーで使う各種属性の詳細はこちら（公式サイト）](https://docs.apigee.com/api-platform/reference/policies/key-value-map-operations-policy?hl=ja)
DialogFlow CXのスロット充填について

![スクリーンショット 2021-12-22 203721.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342677/5deaabc5-0525-46f1-daf6-764a43c017a8.png)

#はじめに

はじめまして、SE1年目のmochinokiです。
本記事は[NI+C Advent Calendar 2021](https://qiita.com/advent-calendar/2021/niandc_teamgcp)の23日目として執筆したものです。
よろしければ合わせてご覧ください。

#DialogFlow CXとは？
DialogFlow CXとはGoogleのドキュメントを見ると
>
Dialogflow CX エージェントは、エンドユーザーとの同時会話を処理する仮想エージェントです。これは、人間の言語のニュアンスを理解する自然言語理解モジュールです。Dialogflow は、会話中のエンドユーザーのテキストまたは音声をアプリやサービスが理解できる構造化データに変換します。Dialogflow エージェントは、システムに必要な種類の会話が処理されるように設計および構築されます。

ちょっと何言ってるかよくわからないですね・・・
要約するとチャットボット作成ツールみたいなニュアンスでとらえてもらえばOKです。

真面目な話としては
DialogFlow ES(旧DialogFlow)の新バージョンとして、2020年9月より公開されたサービスとなります。
DialogFlow ESとの違いは、コールセンターなどの複雑で大規模なサービスでの利用を想定して作られたという点ですね。
![スクリーンショット 2021-12-22 203721.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342677/af47fac3-2f6b-d592-f692-4ecd9d3680d3.png)

詳細については以下、公式のドキュメントから確認お願いします。
https://cloud.google.com/dialogflow/docs?hl=ja


#DialogFlowCXのスロット充填
では本記事の本題、DialogFlow CXでのスロット充填に入っていこうかと思います。

この記事を開いてくれるような奇特な方は既にDialogFlowを触ったことのある方が大半だと思うので、
どうやってDialogFlowを動かすのかなどの説明は割愛させていただきます。

まず結論としましてはDialogFlow CXにDialogFlow ESのようなスロット充填機能はありません。
これだけ聞くと誤解を招くので、補足しますと下記画像の様なGUIでの操作ができないといった形です。
![intent-parameters-required.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342677/912aa0fd-02c0-072b-cc90-80f63b26e853.png)


ではどうやってスロット充填機能を作るのかといった点につきましては、
フォームパラメータの定義を用いて行います。
https://cloud.google.com/dialogflow/cx/docs/concept/parameter#form-ref

以下のフォームパラメータを使用することで、定義されたパラメータをすべて満たすまで
ページ遷移が発生しなくなり、Dialoflow ESのスロットが再現できるようになります。

```
$page.params.status="FINAL
```
![スクリーンショット 2021-12-22 232812.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342677/7bc4c8fb-c705-3088-fc2f-105a94d5ffee.png)

また、ページのパラメータ設定で、Requiredを設定することにより特定のパラメータを満たすまでは
会話を続けることが可能になります。
![スクリーンショット 2021-12-22 231526.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342677/b447866a-c3bc-b7ce-7a62-10dcdfa455de.png)


最後に上記のものを組み合わせた会話フローをちょっと見せます。
![スクリーンショット 2021-12-22 231744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342677/514e02a9-163b-3d17-8478-d93faa2511cf.png)
内容としては`Start`から要素を取得していき、足りない部分はDialoflow ESのスロット充填の様に
`search1`,`search2`で要素を満たすまでチャットを継続していきます。
要素の収集が完了すると`result`部分で集めた文言からチェックを行いオペレーターに振り分け、
もしくはセッションを終了するという一連の流れとなっております。
構造は非常に簡単なので、是非作成にチャレンジしてみてください！







#おわりに
いかがだったでしょうか。
簡単にではありますが、Dialoflow CXのスロット充填をご紹介させていただきました。

私個人の正直な感想としては、DialogFlow CXは少し使いづらいかなあという感じがしますね。
私自分の調査不足もあるのですが、サービスについて公式ドキュメントや動画を見たのですが
DialogFlow CX関連は少なかった印象がありました。

また、DialogFlow ESでは使えてたスロット充填が使えないのもエンジニア力の低い自分にとっては
なかなか難しかったですね。

しかし公式のサンプルを見ると、使いこなせればかなり自由に作れるのではないかとワクワクします。
まだまだ出たばかりのサービスなので、これからQiitaなどでナレッジが溜まっていくことを期待したいと思います。最後までご覧いただきありがとうございました。
![スクリーンショット 2021-12-23 001722.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342677/7ad804c4-3f62-415f-9c73-c985148e7cb5.png)
C言語 構造体と共用体の違い

#始めに
この記事はC言語を始めて1年弱の初心者が気になったことをまとめて書いたものです。あまり参考にならないと思いますがご了承ください。誤字・脱字、内容の間違いなどがあればご指摘ください。

初投稿なので拙い文章ではありますがよろしくお願いします。
#構造体・共用体について
そもそも構造体・共用体とは何か、自分なりにまとめてみました。
###1.構造体
構造体とは、簡単に言えば**「データ型が異なる複数のデータをまとめて格納できるデータ型」**というものです。
複数のデータをまとめるという点は配列と同じですが、**「中に格納するデータのデータ型が違っても格納できる」**という特徴があります。
#####構造体の定義・変数宣言
```
struct 構造体名             例)struct DATE_DATA
{　　　　　　　　　　　　　　　　　{
    メンバ宣言1;                   int year;   
    メンバ宣言2;                   int month;
    メンバ宣言3;                   int day;
        ︙　　　　　　　　　　   };
};

struct 構造体名 構造体変数名;    struct DATE_DATA x;
```
構造体の定義・変数宣言は上記の通りです。typedefを使って定義することもできますが、今回は割愛させていただきます。

構造体を定義すると、メンバの数とデータ型のサイズに応じてメモリ内に連続して記憶領域が確保されます。なので構造体のメンバが増えれば増えるほど構造体は大きくなります。
###2.共用体
次に共用体ですが、データ型が異なる複数のデータを扱うという点では構造体と同様です。
違う点として、**「複数のデータ型を同じ記憶領域で使い分ける」**という点が挙げられます。
#####共用体の定義・変数宣言
```
union 共用体名              例) union DATE_DATA
{　　　　　　　　　　　　　　　　   {
    メンバ宣言1;                    int year;   
    メンバ宣言2;                    int month;
    メンバ宣言3;                    int day;
        ︙　　　　　　　　　　　　  };
};

union　共用体名 共用体変数名;     union DATE_DATA x;
```
共用体の定義・変数宣言は上記の通りです。構造体と同様にtypedefを使って定義することもできますが、これも割愛させていただきます。

共用体を定義すると、その共用体のメンバの中で最も大きいデータ型の大きさの記憶領域が割り当てられます。
#構造体と共用体の違い
大きな違いとして、**「使用した時の動作の違い」**が挙げられます。
構造体ではデータ型の異なる複数のデータを同時に代入することができますが、共用体ではそれぞれのメンバが同じ記憶領域を使用するので2つ目のデータが代入された時点で1つ目に代入されたデータが上書きされます。そのため構造体のように同時に複数のデータを代入することができません。
もう一つの違いとして、**「定義した時に割り当てられる記憶領域の大きさ」**が挙げられます。
例えばメンバ内で`char x;` `short y;` `int z;`の3つを宣言したとすると、構造体に割り当てられる記憶領域の大きさは`char型の1バイト`・`short型の2バイト`・`int型の4バイト`の合計`7バイト`の記憶領域が割り当てられます。
対して共用体では、メンバ内で宣言されたものの中で一番大きいデータ型の大きさの記憶領域を割り当てるので、割り当てられる記憶領域は`4バイト`となります。
#それぞれのメリット・デメリット
違いを踏まえたうえでそれぞれのメリットとデメリットをまとめてみました。

||メリット|デメリット|
|:-|:-:|:-:|
|構<br>造<br>体|それぞれデータ型の異なるメンバに複数のデータを同時に代入することができる|メンバの数が増えると増えた分多くのメモリを消費してしまう|
|共<br>用<br>体|メンバの数を増やしても割り当てられる領域は一番大きいデータ型のものだけなのでメモリの消費を抑えることができる|対応したメンバは存在するがそれぞれデータ型の違う値を複数同時に代入することができない|
#まとめ
違いを簡潔にまとめると、
#####構造体
* いろんなデータ型の値を複数同時に扱うことができる
* メンバが増えるとそれに伴ってメモリの消費も増える

#####共用体
* いろんなデータ型の値を複数扱うことはできるが同時に扱うことはできない
* メンバが増えても一番大きいデータ型の大きさのメモリの消費だけで済む

その時の状況に応じて使い分けるのが一番ですが、慣れないうちは構造体で事足りると思います。
#終わりに
今回、C言語を一通り学習したうえで気になったことを簡単にまとめてみました。
まだまだ分からないことも多く手探り状態ですが、もっといろんなコードを書いて慣れていこうと思います。

最後まで読んでいただき、ありがとうございました。
VimからGitHub Copilotを使う

はろー、バクダンくんだよ。
この記事は[Vim Advent Calendar 2021](https://qiita.com/advent-calendar/2021/vim)の23日目の記事だよ。


# ｺﾋﾟﾛｯﾄ

[GitHub Copilot](https://copilot.github.com/)（以下、ｺﾋﾟﾛｯﾄ[^1]）はGitHubが開発中のAIプログラミング支援システムです。ソースコードのコンテキストを理解し、ちょこちょこっと関数の說明コメントを書くだけで関数まるごとサジェストしてくれちゃったりするんだとかで、気になっている人も多いと思います。

初めはほぼVSCodeでしか使えませんでしたが、今はIntelliJ IDEAでも使える他、VimやNeovimでも[copilot.vim](https://github.com/github/copilot.vim)というプラグインを介して使えるようになっています。
このことを紹介している記事がそういえばQiitaに無いようなので、今日の記事としましょ。

[^1]: 正しい発音は「コパイロット」です

# 注意

とても便利に見えるｺﾋﾟﾛｯﾄですが、今はまだテクニカルプレビューの段階です。ここに書いてあることが今も通用するとは限りません。
また、間違いや脆弱性を含むコードがサジェストされたり、学習に使われたGPLのコードがサジェストに紛れ込むのではないかといった懸念もあります。
利用は自己責任で、参考のために試用するに留めるようにしましょう。


# copilot.vim

[copilot.vim](https://github.com/github/copilot.vim)は、vim-fugitiveやvim-surroundで有名なアノTim Pope氏がGitHub公式で開発中のNeovimプラグインです。Node.jsでGitHubと通信し、Neovim上にサジェストしてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42867/95fddcbf-5093-812b-c5a7-5517760ab9a7.png)

こちらのプラグイン、READMEには "it requires Neovim 0.6" と書いてありますが、実はそれ以前のNeovimやVimでも一応使うことができます。
ただし、Neovim 0.6のvirtual lines機能（↑のようにバッファの行間にテキストを表示する機能）が無いので、代わりにプレビューウィンドウにサジェストを表示する形になります。
なんにせよNode.jsは必要なのでインストールしておいてください。


## セットアップ

あなたのお好きな方法でcopilot.vimをVim/Neovimプラグインとしてインストールしましょう。インストールしたら、Vim/Neovimを起動して `:Copilot setup` コマンドを実行します。すると8桁のコードが表示され、ブラウザが開いてコードの入力を求められるので、コードを入力してcopilot.vimをGitHubアカウントと連携すれば準備OKです。


## 使い方

Neovim 0.6以降の場合は、適当なファイルを開いて編集を始めれば勝手にｺﾋﾟﾛｯﾄがサジェストしてくれるので、Tabキーで確定できます。

Vimやバージョン0.6未満のNeovimの場合は、適当なファイルを開いたら `:Copilot split` コマンド[^2]を実行しましょう。すると、サジェストを表示するためのプレビューウィンドウが開きます。
その状態でインサートモードに入って編集を始めると、プレビューウィンドウにサジェストが表示されるので、Tabキーを押すとサジェストされていたコードが入力されるハズです。
コーディングのお供にしたり、[ｺﾋﾟﾛｯﾄとお話](https://youtu.be/L6Nr1uc80pY)したりして楽しみましょう。

注意点として、今のところMarkdownやYAMLなど一部のファイルタイプではデフォルトでサジェストが無効化されています。有効化したい場合はそのバッファで`:let b:copilot_enabled = 1` したり、辞書 `g:copilot_filetypes` にキーを追加したりすれば有効化できるようです。

[^2]: `:Copilot open` でも可


# ちなみに

僕は拾った杖を振り上げたところVimのバッファが割れたので、そこにｺﾋﾟﾛｯﾄを通してNeovimと遜色ない表示をさせています。そのうち詳しく書くかもかも。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42867/589fac29-522a-3674-f444-489ca9989bc6.png)
オフショア開発でBacklogを使ってマネジメントしてみた話

## はじめに
今まで参画したプロジェクトで何回かオフショア開発(主にベトナムなど)に携わった事があり、その中で感じた課題感や知見を書いていきます。

## Backlogを使ってオフショア開発ってどうなの？
- 結論としては問題なくマネジメントできると思います。  
ただ、現在の対応言語が日本語と英語だけになっているようです。

参考記事
https://backlog.com/ja/product-updates/announcement/close-multi-language/

ちなみに言語設定はプロフィールページから変更できます。
![スクリーンショット 2021-12-22 23.33.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85181/dd964288-b556-b96d-fbe8-1228ad814f8c.png)


## オフショア開発でマネジメントをやった際の課題感
### 課題1.タスクをチケットに日本語で起票した際にベトナムの通訳の方に毎回、翻訳して頂くのが大変。  
- 具体的には通訳の方も必ずしもエンジニア出身ではないので、間違った翻訳が行われたりする事がある。  
また、通訳の方が休んでしまい、チケットに書いてある仕様が読めず、作業が進まないなどの事もあった。

### 改善策
- ここは通訳通すと間違った伝わり方しそうだなと思った技術的な細かい話は自分で英語で伝える。  
- 通訳の人の持ちタスクも最低限、把握してどの翻訳を優先してやってもらうか多少、タスク管理もしてあげる。  
Backlogに自動翻訳機能があったら、より嬉しいなとかも思ってます(笑)

### 課題2. 日本人の「よしなにやっておいて下さい」が上手く通じない
- 「よしなにやる」これがどういうイメージかと言うと、日本ではざっくり、仕様を説明して、あとは聞きながら進めて下さいと指示するシュチュエーションもまあまあ、あるかなと思っています。    
その中で、開発者の人は今ある情報で少しずつ不明点を聞きながら進めたり、開発した後に最低限、テストを書いたり、デグレの確認をする。   
これが「よしなにやる」だと思っています。
(日本人同士だから上手くいく部分もあると思います)   
ただ、オフショア開発且つ、初めて開発するメンバーだとこれが中々、上手くいかないです。

### 改善策
- 根気強くタスクのチケットを細かく書き続けると、徐々に日本のよしなにやっておいてが通じるようになってきました。  
例えば、開発の流れ、テストケースの洗い出し、デグレの確認方法など。これらをチケットに明記して、細かく説明を繰り返すとお互いの「よしなにやる」のレベル感が合うようになってきました。

### 課題3.海外の方と完全リモートワークは壁を感じる
- コロナ禍になって、いきなりオンラインで海外の方と仕事するのは難しいと感じました。  
理由としては、仕事において仲が良い方が質問や相談がしやすい雰囲気になると思っています。
また、海外の方は国によっては、リアルコミュニケーションをけっこう大切にしている印象で、コロナ禍でなければ、必ず現地で顔合わせをやるべきだなと感じました。

### 改善策
- ここはまだ具体的な改善策が思いついておらず、模索中です...！

### 課題4.日本と海外で祝日が違うのが辛い
- 時差はそこまで課題には感じなかったのですが、祝日が違うのが地味にキツかったです。
例えば、日本が連休の時にベトナム側は平日だった場合に仕事の連絡が来たりしました。

### 改善策
- 日本が連休の時はこっちが休みに入る前に多めにタスクを振っておく。  
ただ、沢山お願いしてたとしても、タスクの不明点などで少しは連絡が来てしまったりもあります。  
そうなると、休みだけど、なんだかんだで、Slackは気にしてないといけなくて、なかなか、心が休まりませんでした。  
また、ベトナム側が連休の場合、それも含めてスケジュールに余裕持って引いておかないと悲惨なことになります。汗

以上がオフショア開発でBacklogを使ってマネジメントしてみた話でした！  
もっと、書きたい事もありましたので、今度、時間取って書こうかと思います(笑)  

Backlogの話、あまり書けなかった。汗
業務を通じての学びと成長

## 初めに
この記事は<a href="https://qiita.com/advent-calendar/2021/mynavi">マイナビ Advent Calendar 2021</a>の24日目の記事となります。

最近格段と冷え込んできましたね。クリスマスイブをいかがお過ごしでしょうか？:santa:
本記事は***最近学んだこと***と***エンジニアとして必要なスキルだと思うこと***
について共有させていただければと思います！！
## ※注意事項
・完全に自分の偏見についてまとめたものです。その点についてはご容赦いただき読んでいただけると幸いです。
・自分自身まだまだ言語化や表現することが苦手であり課題です。お手柔らかに読んでいただけると幸いです。

##　うまく整理して言語化できる力
本当に大切だと思っています。
自分は頭の中で整理して伝える力。特に

:::note alert
・　聞かれたことに対して結論ファーストの答えで返すようにする。
・　できる。できない。わからないをはっきりと伝える。
・　内容の部分もなるべく「多分」「おそらく」などは極力減らす。
・　詰まりそうな部分があればこちらの方から提案を含め質問させてもらう。
:::
を意識してコミュニケーションを図るようにしています。　← 自分もできるように努力しています...!:runner_tone3:
正直本当に難しいことだとは思っていますが
大切だと考える理由として
***自分のやったことや考え対してフィードバックやアドバイスの機会を作ることができる***からです。
それくらいの価値があると考えています。

###　例としての会話
***相手への伝え方に対して全く意識していない自分***
![スライド1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543281/5b96b12e-c9a3-102f-0ae0-07841c274102.png)

***伝え方を意識している自分***
![スライド2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543281/68b5a8be-63dd-683d-0c84-e729f19f84b9.png)

例が少しわかりづらくなっているようでしたら申し訳ありません。。。
このような感じで意識することで相手が理解しやすいだけではなく、
現在の状況や提案をすることでプロダクトを
自分の知見でだけではなく相手の意見も知ることができるようになり、
自分の視野が広がるだけではなく意見を汲み取ることで
***成長することができるようになるチャンスを作ることができる***と思っています。

可能であれば、
***手で仕草をしながら表現***をするや***実際に画面を見てもらって説明***するなどできると尚いいと思います。
さらに、整理して言語化することを***質問する側の時でも意識***したら相手は汲み取りやすいと思います:hatching_chick:

## チームメンバーに配慮する力
チーム開発で意識することは本当にたくさんあると思います。
相手に対してのリスペクトを払うことや情報を共有すること、目標を決めることなど様々なあると思います。
そんな中でも今回は***共有***という部分で一つ大切だと最近思ったこと１つを紹介したいと思います。

### GitHubでのプルリクエストのドキュメントの配慮
チーム開発をしている時に利用することが多いGitHub
その中でもブランチを切って、
developmentブランチやmainブランチに対してプルリスクエストを投げることが多いと思います。
自分も少なからず今までプルリクエストを投げてはレビューしていただきました。

ある時自分は***データ設計そのものを変更して実装するタスク***を実装してプルリクエストを投げました。
その時にレビューしていただくときに自分は
***具体的にどこの部分の変更が大きかったか***と***変更をどのように検証していただくか***を記載していませんでした。
今考えると自分の経験として

```
実装したのは自分だからわかっていて当然だが、
他のメンバーからしたらコード含め大幅に変更されているので実際にサーバー立てて動かした時に
どう振る舞いが変更されたかわからないだろう
```
と一番に思います。

しかしこの時にアドバイスをいただき

:::note warn
・知らない人でもわかるようにその手順を記述できる方が望ましいこと
・もっと誰でもわかりやすいようなドキュメンを書くことを意識すること
・必要な要件などは全て記述すること
:::
などを教えていただきました。
　→ 本当に自分の学びと相手の立場になって考えること。
そして自分だったらどう思うかなどを考えることができました。

結果として具体的に、
### 例としてのドキュメント

:::note info
テストしていただく部分

下準備
1. xxxコマンドを実行してローカルサーバを立ててください！
2. localhost:3000/admin/xxx から管理者ログインを行い、xxxファイルを編集したので新しくお部屋を作成して検証してください！
　＜－　お部屋の数は２つ以上だと望ましいです。

いざ検証！

1. xxx画面からパスワードを入力してログインしてください！
2. ログイン後に実際に処理を行なってみてください！
3. 以上でゲーム画面での操作は完了です。
4. 最後に、そのときに表示されているxxxとoooの部分を確認して一致していれば検証完了です。
...
:::
のように
***実際にコマンド名などを書いてレビュー側の方に実行していただき、フィードバックをもらう***という部分が効率化でき、
***自分の要件もれ***や***フィードバックでのより良いアイデア***をより双方理解しやすくいただけるようになったと思います。
このように***やったことを振り返りそれをまとめる力***の重要性や***相手の立場になって考えること***を学べました。

## まとめ
***相手の求めることを汲み取んで落とし込むことができる***できるかどうか大切だと感じます。
毎日学ぶことがたくさんありますがそれ以上に自分自身の新しい知見が溜まっていくことや
心から開発を楽しんで取り組むことができていること。
ひとえに様々な人の助けの上で成り立っているのだろうと考えており、皆さんに感謝しております。
自分自身これからも日々精進していきます:sunrise_over_mountains:

ここまでご清聴していただきありがとうございました！
また、機会があればどんどん知見をアウトプットしていきたいです。
TouchDesignerでasyncioを使った非同期処理について

こんにちは。ちょうど今年の2月までは制作会社でTouchDeisgnerやUnity,UE4などのコンテンツ制作をしておりました。フリーランスになってからTouchDeisgnerの仕事をする機会は減りましたが、[去年](https://qiita.com/sndmtk/items/385930acdc5a568f5a12)に引き続き今年も何か投稿しようということで、以前に[TouchDesigner forum](https://forum.derivative.ca/t/using-asyncio-module-in-touchdesigner/190487)で投稿したasyncioの使い方について説明したいと思います。思いのほかフォーラムでレスポンスをいただいたのでみなさんのお役に立てればと思います。

# はじめに

TouchDesignerはシングルスレッドで動作するため、待機処理やI/Oバウンドな処理をpythonで実行するとTouchDesignerのプロセスは停止します。

次のようなコードを Textport または text DAT で実行してみると、指定秒数が経過するまでTouchDesignerは停止します。

``` python
import time
time.sleep(1)
```

HTTPによるPOSTも同様に処理が完了するまでTouchDesignerは停止したままです。

``` python
import requests
requests.post('<https://derivative.ca/>')
```

TouchDesignerのオペレーターにはtimer CHOPやWeb DATのような便利な機能がいくつかありますが、これらの機能をPythonで実現するためには非同期処理が必要になります。

## マルチスレッドによる非同期処理

Pythonでマルチスレッドというと`threading`, `concurrent.futures`, `asyncio`といったライブラリがあります。中でもasyncioは**シングルスレッドで動作するためTouchDesignerとの連携が簡単**です。（一概にthreadingやconcurrent.futuresが適していないという訳ではないです）

ということで次のようなコードを実行したところまんまとTouchDesignerがフリーズしました..

``` python
import time
import asyncio

async def test():
    await asyncio.sleep(1)
    print('hello world')

asyncio.run(test())
```

どうやらは`asyncio.run()`を実行すると内部的では`run_until_complete()`を呼び出しており、asyncioのイベントループは実行された処理が完了するまでブロックするようです。

そこで`loop_create_task()`からTaskを生成し、`call_soon(event_loop.stop())`と`run_forever()`を毎フレーム実行することで、「フレーム毎にイベントループを起動してちょっと仕事したら停止する」みたいに繰り返すことでブロックを回避できるようです。。

（このあたりの説明はわからなくても使えます）

# [TDAsyncIO.tox](https://github.com/sndmtk/TouchDesigner-asyncio)

ということでそれらをまとめてtoxにしたものがこれです。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216025/93434375-9d11-34c3-a0cb-781d695bcc39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216025/93434375-9d11-34c3-a0cb-781d695bcc39.png)

使い方は簡単でこんな感じです

``` python
import asyncio

async def test():
    await asyncio.sleep(3)
    print('hello world')

# Run coroutine
coroutines = [test()]
op.TDAsyncIO.Run(coroutines)

# Cancel all tasks
op.TDAsyncIO.Cancel()

```

グローバルショートカットを設定しているので`op.TDAsyncIO`からメソッドを呼べます。

- `op.TDAsyncIO.Run()`の引数にコルーチンのリストを渡すだけです。
- `op.TDAsyncIO.Cancel()`からすべてのタスクを停止します。

githubのtest.toeにはその他の使い方(subprocessやrequestsと合わせて使う方法)についても簡単なサンプルを置いてあります。
ぜひサーバーと連携する際などは試しに使ってもらえればと思います。

# まとめ

- TouchDesignerのプロセスを停止することなくasyncioが実行できるtoxを作りました
- サーバーとの連携が必要な処理を実行したいときに便利です
- メインスレッドで実行されているためtd Moduleを使えます

ちなみに非同期処理と記載がありますがasyncioではCPUバウンドな処理を高速化することは期待できません。CPUバウンドな処理については[Engine COMP](https://docs.derivative.ca/Engine_COMP) や [刻みTD](https://qiita.com/shks/items/656186c5127869bfbe84) などのようにプロセスを分離することを推奨します。
アプリ内バナー広告の実装(SwiftUI)

#GoogleAdMobの実装
アプリ内広告の種類はいくつかありますが、今回はGoogleAdMobのバナー広告を選択しました。
作成済みのアプリ（以下のQiita記事リンクに詳細）に組み込みます。
>[天気図リンクアプリ](https://qiita.com/PearlEarringMinion/items/ae5790123e2f57c7dd48)

また、AdMobの広告の種類は以下の通りです。
![スクリーンショット 2021-12-23 0.09.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261100/d775d2bf-4430-4625-d59a-87a817b84b56.png)
>https://support.google.com/admob/answer/6128738?hl=ja より画像引用

###AdMobの登録とキーの取得
省略します

###フレームワーク(Google-Mobile-Ads-SDK)のインストール
cocoapodsを使用したフレームワークのインストールに失敗しました。
M1マックを使用していることに原因がありそうですが、解決法が見つからなかったので手動でサイトから直接ダウンロードして、
手動でフレームワーク放り込むことで上手くいきました。

放り込む場所(`Gneral`の`Frameworks,Libraries,and Embeded Content`)
![D491A63B-DFC8-4CFF-A016-E34B762A9AFA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261100/162885a9-d961-5a69-bec6-d89970323f8c.jpeg)

デフォルトで`Embed`になっていますので`Do Not Embed`にします

###Infomtion Property Listにkeyを追加
![BC610AC0-649C-46EC-81A5-5C6CBC397684_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261100/166beefe-875a-5133-7f1d-5daa7446cc65.jpeg)



###コードの記述
フレームワークのインポート

```swift:ContentView.swift
    import GoogleMobileAds 
```

初期化

```swift:AppDelegate.swift
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        GADMobileAds.sharedInstance().start(completionHandler: nil)
        return true
    }
```

`AppDelegate.swift`にある`func applicarion`内の`//Override point for...`以下に
`GADMobileAds.sharedInstance().start(completionHandler: nil)`を記述します。





続いて`struct ContentView: View {}`内に広告を定義します。


```swift:ContentView.swift
//Admobの実装
struct AdView: UIViewRepresentable {
    func makeUIView(context: Context) -> GADBannerView {
        let banner = GADBannerView(adSize: kGADAdSizeBanner)
        // 下記はテスト専用広告ユニットID（バナー広告）。
        banner.adUnitID = "ca-app-pub-3940256099942544/2934735716"
        banner.rootViewController = UIApplication.shared.windows.first?.rootViewController
        banner.load(GADRequest())
        return banner
    }

    func updateUIView(_ uiView: GADBannerView, context: Context) {
    }
}
```

続いて、`var body: some View {}`内にAdView()を追加します。
これで広告の実装が完成です。


```swift:ContentView.swift
AdView().frame(width: 320, height: 50)
```

![792C84B3-956B-4BAE-9A1B-105E65D00B32.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261100/61b5e608-43ee-b987-fc3b-c37a920283ca.jpeg)

今回は`NavigationView`の上に配置しました。
本番用の広告IDを使用して、もしタップしてしまうとペナルティをくらいますのでご注意下さい。
アダルトサイトの相互リンクに自分のサイトも乗っかろうとして止めた

この記事は [驚異のFANZA女優検索](https://fanza-actress-bust-search.azurewebsites.net/) Advent Calendar 2021 の 23日目の記事です。

#他の有名サイトからリンクをはってもらう
昨日[収益](https://qiita.com/fabsabsfabsabs/items/219f739d29ad24dd2bb0)の話を書いた。正直思っている以上に収益は上がっていない。もちろん収益が上がれば嬉しい。とはいえ、そういう施策ばかりを考えるのも違うと思う。。PVを上げるのにもっとも効果がありそうな方法を考えると、既に人気があるアダルトサイトからリンクを貼ってもらうことかと思った。

#相互リンクを歓迎しているサイトを探す
ただアダルトサイトリンク集などでググっても有益な情報が出ない。最初は良い思い付きかと思って乗り気で調べていたが、調べるうちにどんどんやる気がなくなってきた。何が分からないって相互リンクの貼り方だ。そういうサイトはちょくちょくあって相互リンク歓迎と書いてあったりもするが、実際にはリンク切れになっているのが多数だったり、肝心の方法がページをみても書いてなかったりするケースが多いのだ。今ではもう古くなったようなサイトばかりが目立ってやる気が削がれてきた。

#よさげなサイトなのがあったので、相手のパーツを貼ってみた
その中では一つ良さげなサイトを見つけたのでそこと相互リンクをしようとした。そこは仕組みがかなりしっかり出来ていたので、まずは相手方が指定しているブログパーツみたいなものを実際に自分のページに置いてみた。ところが、これが、また、なんというか品がない。デザインセンスもないし、内容もダサいと感じてしまった。これを置いて思い出したが、一昔前のエロ系のページって左右にゴテゴテと大量にリンクが貼ってあって、そこをいくらクリックしていっても、目的の映像が見れない罠みたいなサイトが一杯あったなと思った。

#相互リンクは相手の価値観を自分のサイトに反映する行為
自分のページを作る際、自分なりにデザインやレイアウトをこだわって作った。DMMのアフィリエイトリンクも邪魔にならない最低限の表示に制限した。にも拘わらずここで相互リンクをするために相手指定のデザインを追加するのがどうしても嫌だった。もちろんそれが恰好良かったり必要最低限なものだったりすれば、話は別だ。今回はむしろお願いする立場に近いので、最悪ダサくなければ許せるかと思っていた。しかし、もうどうしようもなくダサいと思ってしまったので、それを自分のサイトに置くのは本当に本当に無理だった。

#というわけで止めた
ここまで書いて、正直、妥協してリンクを貼った所で、PVが劇的に上がることもないような気がしてきた。最初にアダルトサイトに相互リンクの仕組みを考えた人はやっぱりすごいと思う。ただ後からそれに乗っかっても、得られるものはどんどん少なくなっていると思う。ましてやもう時代的に廃れてきている方法論では、もしかしたらほんのちょっとPVが上がることはあるかもしれないが、それに見合うだけの価値が相互リンクにはないなと思ってしまった。というわけで、驚異のFANZA女優検索はDMM以外のアダルトページ特有の謎の縦に長い、要素に辿り着けないようなリンクは置かないことをここに誓います。
１０倍に伸びた登録者数によるSQLリクエストの負荷対策について

皆さんこんにちは、べリョ・トムと申します。

去年コロナ禍の最初の数ヶ月で、貴社では負荷の増加という影響を受けましたのでしょうか?
弊社では、２０１８年にリリースされ、農業者向けに求人掲示板サイトを運営していて、２０２１年４月で農業界において人手不足という状況が発生して、そのプロジェクトがテレビに流されました。

それによって、１日で合計３万人の登録者数が３０万人になって、その負荷に準備していなかったインフラやコードとしては、とんでもない負荷を背負うことができました。チームと負荷を複数のサーバーに分散してから、メールの送信率も調整し始めて、データベースのサーバを含めて、全てのサーバーのスペックを上げたことで、中止なし可用性を守ることができました。
その後の数週はプロダクトのあらゆる非効率性の部分を改善していくことにしました。

そこに、もっと大きな改善はマッチングアルゴリズムの性能でした。
マッチングアルゴリズムとは、仕事の案件に添う人を提案するアルゴリズムで、機能としてはプラダクトの中心でした。開発の初めから作られたもので、簡単な形で作られて、機能に積められてきたものだから、技術的負債を作っていったのですね。

その機能の性能を探ることで、下記の問題を分かりました：

-  リクエストから直接、必要だけの結果を返さず、大量の結果を返して、PHPで色んなスコアーを計算して整理されていました
-  その整理から、二十位以内だけにある結果をページに表示
-  大量のデータをPHPに送って、計算、整理するのが時間がかかる
-  リクエストが大きすぎて、ロジックが複雑になって、コードが更新しづらかった
-  JOINでの絞り込みが増えていたため、データベースの設計には不適切になっていた

そして下記のようにリファクトリングしました：

-  Materialized Viewでデータを簡単にまとめて
-  一件に関するリレーションのIDを配列に保管して、旧リクエストの複数のJOINを減らすことができる
-  インデックスの配列として扱うことで、PHPで計算されていたマッチングスコアーがSQL直接に計算するのができる

その改善のおかげで、数十秒以上の処理時間が数百ミリ秒だけになりました。SQLのリクエストも省略することができ、アルゴリズムを一つの場所だけに統括することで、コードが読みやすくなって、スコアの複数の機能を分かりやすくようになりました。先に来る機能の変化や追加も安くするようになりました。
Materialized ViewによるRAMの消費の増加を観察しなかったので、本番環境に安全にリリースしました。

皆さんも似たような経験を生きたのでしょうか？共感できたらぜひ教えてください。
又、日本語での初めての記事としてどうでしたか？感想があれば幸いです。:blush:

今、バックエンドやフルスタックエンジニアとして日本に働くために就職中ですので、興味があればぜひ声をかけて下さい：https://www.linkedin.com/in/tom-berriot-ba689110a/