OmniAICreator/Qiita-1.07M huggingface dataset:
LaravelのマイグレーションでSyntax error or access violation: 1235が出たとき

# はじめに
業務でLaravelを使ったWebアプリケーションを開発しているとき、ローカルでは問題なかったのにテスト環境にデプロイ後マイグレーションコマンドを実行した際にエラーが発生し、その解決に手間取ったので備忘録的にメモしておきます。

環境は以下の通り。
```txt
PHP 8.0.28
Laravel 7.30.6
MySql 8.0.32 (Azure Database for MySQL)
```

# 本題
## マイグレーションの内容
```php:migration.php
public function up()
{
    Schema::table('table_name', function (Blueprint $table) {
        $table->unsignedInteger('hoge')
            ->default(0)
            ->after('fuga');
    });
}
```
何の変哲もない、数値型のカラムを1つ追加するだけのマイグレーションです。

## エラー内容
```txt
Syntax error or access violation: 1235 This version of MySQL doesn't yet support 'existing primary key drop without adding a new primary key.
In @@sql_generate_invisible_primary_key=ON mode table should have a primary key. Please add a new primary key to be able to drop existing primary key.
```

「新しいプライマリキーを追加しないと既存のプライマリキーは削除出来ないよ」みたいな内容なんですが、心当たりなし。。。

## 原因
- MySQLの`sql_generate_invisible_primary_key`がONになっていたから

こちらはデフォルトではOFFなんですが、Azure Database for MySQLではデフォルトでONになっているようです。
これをONにしたからどう、OFFにしたからどうというのは割愛しますが、要は「見えない主キーを使うかどうか」みたいな設定なようです。
ちょっと前までは似たようなマイグレーションも通っていたので割と最近の話なんですかね？

## 対策
マイグレーションの前に、一時的に設定を無効にする記述を追加します。
```php:fix_migration.php
public function up()
{
    DB::statement('SET SESSION sql_generate_invisible_primary_key = 0');
    Schema::table('table_name', function (Blueprint $table) {
        $table->unsignedInteger('hoge')
            ->default(0)
            ->after('fuga');
    });
}
```

これでOK。

# 参考
https://dev.mysql.com/doc/refman/8.0/en/create-table-gipks.html

https://github.com/laravel/framework/discussions/48522

https://github.com/laravel/framework/issues/33238
Flutter 画面遷移について


## Navigatorを使って画面遷移をする
Flutterにおいて画面遷移をする方法はいくつかありますが、今回は基本的なNavigato Widgetを使用した画面遷移の方法についてまとめてみます。

### Navigatorとは？
Navigatorとは、Flutterにおける画面遷移を実現してくれるWidgetになります。

以下のように遷移したい画面を指定することで画面遷移をすることができます。
```
Navigator.push(context, MaterialPageRoute(builder: (context) => <遷移したい画面>));
```

以下の記述をすれば前の画面に戻る場合が出来ます。
```
Navigator.pop(context);
```

以下の例では、main.dartを書き換えて画面中央にボタンを表示し、ボタンを押した時にの画面へ遷移できるようにしています。
また、遷移先の画面でボタンが押されたら元の画面に戻るようにもしています。

```
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text("次の画面へ"),
          onPressed: () {
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => NextPage()));
          },
        ),
      ),
    );
  }
}

class NextPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Next Page'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text("前の画面に戻る"),
          onPressed: () {
            // ここにボタンを押した時に呼ばれるコードを書く
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}
```


ElevatedButton WidgetのonPressed()にNavigatorを設定します。
これでボタンが押されたNavigatorが動作します。
onPressed()にはボタンを押した時の処理を書きます。
今回はNextPage()に画面遷移する処理を、書いています。
```
  child: ElevatedButton(
     child: Text("次の画面へ"),
        onPressed: () {
            // ここにボタンを押した時に呼ばれるコードを書く
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => NextPage()));
        },
    ),
```

遷移先のNextPage()にも同じように、ElevatedButton WidgetのonPressedにNavigatorを設定しました。
これにより、一つ前の画面であるMyHomePage()に戻ることができます。
```
  child: ElevatedButton(
     child: Text("前の画面に戻る"),
        onPressed: () {
            Navigator.pop(context);
        },
    ),
```

### まとめ
今回は画面遷移について簡単にまとめてみました。
非常に簡単に画面遷移させることができました。
最後までご覧いただきありがとうございました！
通知設定2

AlarmManagerはAndroidアプリケーションでタイマーやアラームのような予定されたタスクを管理するためのクラスです。以下はAlarmManagerの基本的な使い方です：

1. AlarmManagerのインスタンスを取得:

```java
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
```

2. PendingIntentを作成:

タイマーのタスクを実行するためにPendingIntentを作成します。これには、アラームが発生したときに実行されるコード（Intent）が含まれます。

```java
Intent intent = new Intent(this, YourReceiver.class); // YourReceiverはアラームが発生したときに呼び出されるクラス
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
```

3. アラームを設定:

アラームを設定するには、AlarmManagerにアラームの種類（単発または繰り返し）、発生時刻、およびPendingIntentを指定します。

```java
// 単発アラームの場合
alarmManager.set(AlarmManager.RTC, triggerTime, pendingIntent);

// 繰り返しアラームの場合
alarmManager.setRepeating(AlarmManager.RTC, triggerTime, interval, pendingIntent);
```

4. アラームのキャンセル:

アラームをキャンセルする場合は、PendingIntentを使用してAlarmManagerから削除します。

```java
alarmManager.cancel(pendingIntent);
```

これで、AlarmManagerを使用してアラームを設定し、タスクをスケジュールし、必要に応じてキャンセルできるようになります。アラームがトリガーされたときに指定されたPendingIntentが発動し、指定されたアクションが実行されます。
postgresqlのtimezoneを変更する方法

## 目標

Postgresqlのタイムゾーンを`JST`に変更する備忘録です。

## 手順

1. `psql`で接続
1. タイムゾーンの確認
1. タイムゾーンの変更
1. タイムゾーンの確認

### 接続

```bash
psql -h ホスト名 -p ポート番号 -U ロール名 -d データベース名
```
で接続できます。

### タイムゾーンの確認

```sql
show timezone;
```

### タイムゾーンの変更

```sql
SET timezone TO 'Asia/Tokyo';
```

再び、タイムゾーンの確認をして変更されていることを確認して作業終了です。
Curlを使用したデバッグ方法メモ

よく使いそうなものをリストアップしていく。

リクエスト時にホスト名を指定する。

```terminal
$ curl -sIXGET http://*.*.*.* -H "host: example.com" --insecure
```

オプション

* `-s`, `--silent`: サイレントモード。進行状況メーターやエラー メッセージを表示しない。
* `-I`, `--head`: ヘッダーのみを取得。
* `-X`, `--request <method>`: リクエストに使用するメソッドを変更する。デフォルトはGET。なので、[-XGETは無意味らしい](https://stackoverflow.com/questions/8498371/curl-get-and-x-get)。
* `-H`, `--header \<header/@file\>`: 送信される情報に含める追加のヘッダーを指定する。
* `-k`, `--insecure`: 検証ステップをスキップし、チェックせずに続行する。
* `-L`, `--location`: Locationヘッダにより要求したページが異なるロケーションに移動した場合、新しい場所でリクエストをやり直す。
* `-S`, `--show-error`: -s, --silentとともに使用すると、curlが失敗した場合にエラーメッセージが表示される。
* `-D`, `--dump-header`: 受け取ったプロトコルヘッダを指定したファイルに書き込む。ヘッダーを受信しない場合、このオプションを使用すると空のファイルが作成される。


参考：DNSレコードを変更せずにカスタムドメインでのアクセスをデバッグする方法

https://acquia.my.site.com/s/article/360004175973-Using-an-etc-hosts-file-for-custom-domains-during-development
(テスト) 通知設定

通知

▼Notificasion
役割➞メッセージやイベントを通知でアプリケーション外でユーザーが情報にアクセスできるようにする。
特徴➞ステータスバーや、通知トレイに表示される。リアルタイムで通知。通知の中身をカスタマイズ可能りユーザーインタラクション。
使用例➞
通知チャンネルを作成する
ID、チャンネル名、重要度の設定を組み込んだ
通知チャンネルの元を用意
通知マネージャーを使って通知チャンネル登録
通知の作成
NotificationCompat.Builder(this, "my_channel_id")
contextとIDを設定して
セットを使ってアイコンや、メッセージを設定
通知の送信

val notificationId = 1 // 通知の一意なID
with(NotificationManagerCompat.from(this)) {
    notify(notificationId, notificationBuilder.build())
}
Emotionで'css' does not exist on typeというエラーがでる

# はじめに

最近React100本ノックという企画を初めてEmotionを使い始めました
そこで遭遇した問題をまとめます

# 問題

```tsx
import { css } from "@emotion/react";
import { useState } from "react";

function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <div
        css={css`
          display: flex;
```

このようなコードを書くと`css`で以下のエラーがVSCodeででました

```
Type '{ children: Element[]; css: SerializedStyles; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
  Property 'css' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.ts(2322)
```

# 解決方法

```tsx
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
```

このようにすることでエラーを回避しました

# おわりに

根本的な解決まではできていませんが、そこに時間をかけるほどの価値はなさそうだったのでこのような対応をしてみました
laravelタグ付け機能

拡張しやすいように作成していく


DBテーブルを作成

# Tagname

```
id,name,created_at,updated_at
```

# Tag
```
id,foreign_key,model,tagname_id,created_at,updated_at
```

# User

```
id,name,created_at,updated_at
```

`テーブル完成OK`

それぞれのモデルを作成して関連付け

```Tagname.php
public function tag(){
    return $this->hasMany('App\Models\Tag')
        ->orderBy('updated_at', 'desc');
}
```

```Tag.php
public function tagname()
{
    return $this->belongsTo('App\Models\Tagname');
}

public function user()
{
    return $this
        ->belongsTo('App\Models\User','foreign_key')
        ->orderBy('updated_at', 'desc');
}
```

```User.php
public function tags(){
    return $this->hasMany('App\Models\Tag','foreign_key')
        ->where('model', 'User')
        ->orderBy('updated_at', 'desc');
}
```

# タグのIDから、関連ユーザーも検索

```hoge.php
$limit = 2;
$res = Tagname::query()
    ->with(
        [
            'tag.user','tag' => function ($q) { $q->where('model', 'User'); }
        ]
    )
    ->where('id',105)
    ->orderBy('id', 'desc')
    ->paginate($limit);//paginateで統一しておくか。件数指定

    foreach ($res as $v) {
        echo "タグ名" . $v->name."<br>";
        foreach ($v->tag as $s) {
            if(!empty($s->user->name)){
                echo $s->user->name;
            }
        }
    }

//出力
//タグ名体験談
//かな
//ちゃんあみ
```

# ユーザーから、関連付けられているタグも取得

```hoge.php
$limit = 2;
$res = User::query()//単数形 User
        ->with('tags.tagname')
        ->orderBy('id', 'desc')
        ->paginate($limit);//paginateで統一しておくか。件数指定


foreach ($res as $v) {
    echo $v->name."<br>";
    foreach ($v->tags as $s) {
        echo "タグ : " . $s->tagname->name."<br>";
    }
}

dd($res);

//ちゃんあみ
//タグ : お知らせ
//タグ : 体験談
//hideki
```


# タグ付け

ユーザーの登録時、変更時に、今までのタグを一旦すべて削除してから新規追加する。

```hoge.php
$user_id = 296640923;
$model = 'User';

$tags = [
    'ウェブショップ',
    'お知らせ',
    '体験談'
];

$tagname_ids = [];

foreach ($tags as $v) {
    $tag = Tagname::query()//単数形 User
        ->where('name',$v)
        ->first();//最初の
    if($tag){
        //あればタグのIDを取得
        $tagname_ids[] = $tag['id'];
    } else {
        //なければ新規保存
        $model = new Tagname;
        $model->name = trim($v);
        $model->save();
        $tagname_ids[] = $model->id;
    }

}


$now =  Carbon::now();


$data = [];
foreach ($tagname_ids as $v) {

    $data[] = [
        'id' => null,
        'foreign_key' => $user_id,
        'model' => $model,
        'tagname_id' => $v,
        'created_at' => $now,
        'updated_at' => $now
    ];

}

$data = array_values($data);

Tag::query()
    ->where('foreign_key',$user_id)
    ->where('model',$model)
    ->delete();//削除


Tag::upsert($data, ['id']);//idを軸にすべてのフィールドを更新
```
Anti-Affinityについて

# Anti-Affinityってそもそも何？
k8s上で特定のPodが存在していないNodeへスケジューリングする機能。Pod topology spread constraintsの代わりとして使えないこともない。
Antiという接頭詞がついていることからわかるようにAffinityも存在する。

## Affinity
特定のPodが存在するNodeへ、該当のPodをスケジューリングする。

## Anti-Affinity
Pod Affinityの逆で、特定のPodが存在していないNodeへスケジューリングをする。
### requiredDuringSchedulingIgnoredDuringExecution 
Pod配置の必須条件。条件に合わない場合、絶対にスケジューリングされない。
### preferredDuringSchedulingIgnoredDuringExecution
Pod配置の優先条件。条件に合わない場合、他に合うNodeがなければ、スケジューリングされる。これを利用する。

https://qiita.com/Esfahan/items/a673317a29ca407e5ae7

# 何故Pod topology spread constraintsの代わりとして利用できるのか
というより先にPod topology spread constraintsの説明をするのが先だと思うが、AZ分散するようなk8s構成を取ろうとする場合、各AZに配置されたNodeに適切に分散するということであれば同じことだからである。
https://zenn.dev/tmrekk/articles/07f30b09c26b50

# 設定例
## cert-managerの場合
以下のhelmを利用した場合を示す。
https://artifacthub.io/packages/helm/cert-manager/cert-manager
```
affinity: {}
```
を以下のように設定する。
values.yamlに設定することになる。
```
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - cert-manager
        topologyKey: kubernetes.io/hostname
```
Cloud Vision APIをReactで呼び出す

どうもTABEです。

ReactからCloudVisionAPI呼び出す方法を調査しなくてはいけなかった為
それを備忘録として残します。


まずは

### Reactプロジェクトのセットアップ

以下のコマンドをサンプルのReactプロジェクトを作成したい場所で実行
```
npx create-react-app my-vision-app
cd my-vision-app
```


### 次にgoogle cloudのセットアップ
コード自体は簡単なのですが、ここで結構詰まりました。。。
私は以下を参考にして、設定しました。
https://dev.classmethod.jp/articles/google-cloud_vision-api/

### サンプルコード

App.jsの中身を以下に書き換えます。

```react.js
import './App.css';
import React, { useState } from 'react';
import axios from 'axios';

function App() {
  const [image, setImage] = useState('');
  const [result, setResult] = useState(null);

  const handleChange = (e) => {
    setImage(e.target.value);
  };

  const handleSubmit = async () => {
    const API_KEY = process.env.REACT_APP_YOUR_GOOGLE_CLOUD_VISION_API_KEY;
    console.log(process.env);
    const url = `https://vision.googleapis.com/v1/images:annotate?key=${API_KEY}`;

    const request = {
      requests: [
        {
          image: {
            source: {
              imageUri: image,
            },
          },
          features: [
            {
              type: 'LABEL_DETECTION',
              "maxResults":1
            },
            {
              type: 'TEXT_DETECTION',
              maxResults: 10
            },  
          ],
        },
      ],
    };

    try {
      const response = await axios.post(url, request);
      setResult(response.data);
    } catch (error) {
      console.error('Error calling the Vision API', error);
      setResult(null);
    }
  };
  return (
    <div>
      <h1>Google Cloud Vision API with React</h1>
      <input type="text" value={image} onChange={handleChange} placeholder="Image URL" />
      <button onClick={handleSubmit}>Analyze Image</button>
      {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
    </div>
  );
}
export default App;

```

.envファイルにAPIキーを設定することを忘れずに！

```.env
REACT_APP_YOUR_GOOGLE_CLOUD_VISION_API_KEY=xxxxxxx
```
xxxxxにGoogle Cloudで取得したAPIキーを入力してください。

### 動作確認
ネットのどこかから取得した、画像のURLを貼り付けて（URLが.jpegや.pdfの様なファイルを参照しているものにしてください。）Analyze Imageボタンを押して

以下の様にJson形式でレスポンスが表示できれば成功です！

![スクリーンショット 2023-10-24 17.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/904276/df9748c0-8b4f-bee1-3d72-0b48c96aaf5e.png)

サンプルで使ったものが、無料の素材でなかった為、テキストの部分は抜けていますが
画像のテキストもちゃんと取得できていました！

### Google Cloudの設定でいくつかのエラー


#### ①Cloud Vision API has not been used in project xxxxx before or it is disabled. Enable it by visiting 

プロジェクトで「Cloud Vision API」が有効化されていなかった。
「Vision AI API」という方を選択していました。。。。ボンミスです。

#### ②This API method requires billing to be enabled. Please enable billing on project xxxx by visiting

請求の設定をしていなくエラーになりました。
請求の設定を忘れずに！！

上記のエラーを出すには、レスポンスにエラーが入ってきた時に
以下を仕込んでおけば出せると思います。
``` 
console.error('Error response data:', error.response.data);
```

以上です。
ありがとうございました！
＜備忘録＞mpremote : MicroPython remote control

# mpremote

「MicroPython remote control」というだけに、多彩な機能を有している。
使い方は、公式マニュアを参照。

https://docs.micropython.org/en/latest/reference/mpremote.html

https://micropython-docs-ja.readthedocs.io/ja/latest/reference/mpremote.html

```terminal:基本的な使い方
$ mpremote connect PORT repl
（終了は Ctrl+[ ）

$ mpremote connect PORT run $HOME/Downloads/test.py

$ mpremote connect PORT cat boot.py
$ mpremote connect PORT cp $HOME/Downloads/test.py :/test.py
```

<br/><br/><br/>

## 経緯

久ぶりに`ESP32`で`Micropython`を使おうとして、`Micropython`の`firmware`は`esptool`でサクッと入れられたのだが、ファイルを転送するために使うコマンド名が思い出せず、1時間ぐらいネットをググりまくり、やっとコマンド名を見つけたので、ここに備忘録としてまとめておく。


<br/><br/><br/>

# ampy（2023.10.29追記）

[adafruit-ampy](https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy)も機能は少なめだが、お手軽に使える。

AMPY_PORT環境変数にセットしておくとportが省略できるところが良い。

```terminal
export AMPY_PORT=/dev/cu.wchusbserial53250003491
```

```terminal:基本的な使い方
$ export AMPY_PORT=/dev/cu.wchusbserial53250003491

$ ampy ls
```

ちゃんとした公式マニュアルが見つからなかったので、下記サイトが参考になる。

https://ambidata.io/blog/2018/03/15/ampy/

https://blog.goediy.com/?p=335
springの画像処理


## springとhtmlを使用して画像の表示、保存、格納がしたい


やりたいこと
1. 選択された画像のオリジナルネームにし、DBに格納　　　結果：OK

1. 選択された画像を指定のパスに保存　　　　　　　　　　 結果：OK

1. １番２番で行った値をもとにHTMLで表示　　　　　　　 結果：NG



※以下は現時点での進捗です。

新規で写真追加の場合
```ruby:newphoto.html
<form id="uploadForm">
            <tr>
                <input type="file" id="fileUpload" name="facePhoto" onchange="uploadImage()">
            </tr>
        </form>
<script>
    function uploadImage() {
        var formData = new FormData(document.getElementById('uploadForm'));
        fetch('/uploadpicture', { method: 'POST', body: formData })}
</script>
```

```ruby:Controller.java
@PostMapping("/uploadpicture")
	public void uploadImage(@RequestParam("facePhoto") MultipartFile multipartFile) throws Exception {
		byte[] bytes = multipartFile.getBytes();
		String pathfile = multipartFile.getOriginalFilename();
		Path path = Paths.get("C:\\Users\\name\\OneDrive\\デスクトップ\\facePhoto", pathfile );
		session.setAttribute("pathfile", pathfile);
		Files.write(path, bytes);
	}

@PostMapping("/nuwphoto") //こちらには他の値もありますが今回関係ないので省略//
        facephoto = (String) session.getAttribute("pathfile");
		session.removeAttribute("pathfile");
		if (facephoto != null && !facephoto.isEmpty()) {
			filePath = facephoto;
		} else {
			filePath = null;
		}
    Photo.save(new Photo(filePath)
```

```ruby:photo.html
   <form id="uploadForm">
              <img th:src="'/img/' + ${indiv2.facePhoto}" width="80px" height="80px" >
    </form>

    <script>
        function uploadImage() {
            var formData = new FormData(document.getElementById('uploadForm'));
            fetch('/uploadphoto', { method: 'POST', body: formData })
        }
    </script>
```

流れ
1. newphoto.htmlで画像を選択し、選択された画像をuploadpictureに送る

1. Controller.javaで選択された画像を指定のフォルダーに格納＆オリジナルネームを作成後DBに格納

1. photo.htmlで指定した画像を表示（<img th:src="'/facePhoto/' + ＄｛indiv2.facePhoto}"））indiv2は関連したDBの値を引っ張ってきてますので ${indiv2.facePhoto}の中身にはオリジナルネームが入っております。


##エラー
画像の格納、オリジナルネームの保存はできておりますが、表示の部分がアイコンだけになってしまいます。

考えられる理由：指定しているファイルパスが"C:\\Users\\name\\OneDrive\\デスクトップ\\facePhoto"がデスクトップのため、
今回はアプリを重くしないためプロジェクトの外に作りました
Salesforce: 標準オブジェクト・カスタムオブジェクト・リレーション

## はじめに
Salesforceは、企業の営業やマーケティング活動をサポートするクラウドベースのプラットフォームです。この記事では、Salesforceの基本用語である「標準オブジェクト」「カスタムオブジェクト」「リレーション」について、初心者にもわかるように例を交えて解説します。

## 1. 標準オブジェクトとは？
標準オブジェクトとは、Salesforceに最初から用意されているデータの型のことを指します。

**例:** あなたが新しいスマートフォンを購入したとき、電話帳やカメラ、メッセージなどの基本的なアプリが最初からインストールされていますよね？これらのアプリは、スマートフォンの「標準アプリ」と考えることができます。同様に、Salesforceには「取引先」「商談」「リード」などの基本的なデータ型が最初から用意されており、これを「標準オブジェクト」と呼びます。

## 2. カスタムオブジェクトとは？
カスタムオブジェクトは、ユーザーがSalesforceに独自に追加するデータの型のことを指します。

**例:** スマートフォンのアプリストアから、自分の趣味や仕事に合わせて新しいアプリをダウンロードすることができます。このダウンロードしたアプリは「カスタムアプリ」と考えることができます。同様に、Salesforceでは、標準オブジェクトだけでは足りない情報を管理するために、独自のデータ型を作成することができ、これを「カスタムオブジェクト」と呼びます。

## 3. リレーションとは？
リレーションは、Salesforce内の異なるオブジェクト間の関連性を示すものです。

**例:** あなたのスマートフォンの電話帳には、友人や家族の連絡先が保存されています。そして、ギャラリーアプリには、その友人や家族との思い出の写真が保存されているかもしれません。このとき、電話帳の連絡先とギャラリーの写真との間に「関連性」があると考えることができます。Salesforceでも、例えば「取引先」と「商談」のように、異なるオブジェクト間に関連性を持たせることができ、これを「リレーション」と呼びます。

## まとめ
Salesforceを使用する上で、これらの基本用語の理解は非常に重要です。日常生活の例を思い浮かべながら、Salesforceの世界を探索してみてください。


## 参考文献

https://qiita.com/Takaa/items/508ffb49496dbd0ebff6
Macのシステムデータ

Macのシステムデータが容量の半分以上を占めるという、エラい状況が長く続いていたが。。。
やっと原因っぽいのがわかった・・・

__.DocumentRevisions-V100__

がめちゃくちゃ容量食ってる！
こいつなんだろ・・・消しちゃって良いのかなぁ・・・
なんか、オートセーブのデータらしい。

自分の環境では消しても問題なくmacは動いてて、空き容量もかなり増えた。
が、何に使われていたデータかは不明なので、削除は自己責任で・・・
（Sketchは、使ってないんだよなぁ・・・
Eclipseの設定

# はじめに
SESにてエンジニアとしての道を進み始め、Javaの研修をしていますが、このJavaのIDEであるEclipseが無性に見にくい。ということで、自分なりに見やすくなってきたと思うので備忘録的に記事にしておきます。

# フォントの変更
Windows版のデフォルトフォントである「Courier New」は読みにくいので、新たにプログラミング用フォントである「Ricty Diminished Discord」を入れます。

## プログラミング用フォントRicty Diminishedのインストール

1. [Ricty Diminished](https://github.com/edihbrandon/RictyDiminished)のgithubに移動

1. 「code」をクリックし、下のほうにある「Download ZIP」をクリックして、ZIPファイルをダウンロード

    ![qiita01_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1585457/a95fac7e-d6bd-963b-ffbb-8caa3a68fe1d.png)
1. ダウンロードしたZIPファイルを解凍する。解凍したファイルは以下の通り。
    ![スクリーンショット 2023-10-24 152846.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1585457/200f8742-0c87-1ed1-26e1-3f6149030327.png)

1. 解答したファイルの中の拡張子が「.ttf」のファイルを開いて、左上のほうにある「インストール」をクリックするとインストールが開始される
1. 必要なフォントをインストール（著者はすべてインストールしました） 

## Eclipseでフォントを変更する
1. Eclipseの[ウインドウ]->[設定]から設定ウインドウを開く
    ![qiita01_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1585457/4898eeb1-2372-83fe-7c14-072fdbc104ab.png)
    ![qiita01_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1585457/0921dff3-c38f-738c-86ed-8c1eb31ab5da.png)

1. [一般]->[外観]->[色とフォント]に移動して、[テキスト・フォント]を[編集]する。今回は「Ricty Diminished Discord」のサイズ「12」
    ![qiita01_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1585457/ba440115-4ca3-7c68-5882-bc08286c5d7d.png)

これで、かなり見やすくなったと思います。<br>
![qiita01_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1585457/249dd77b-fa32-1abc-8bd3-ca4a83767688.png)


# アイコンのサイズ変更
Eclipseの初期設定だと、アイコンがかなり小さく見にくいのでアイコンを大きくします。
アイコンのサイズは、先ほどの設定ウインドウでは変更できないので、設定ファイルから変更。

設定ファイル「eclipse.ini」はEclipseのexeファイルが置いてあるディレクトリ内にあると思うので、探し出して編集し、以下の3行を追記。

```
-Dswt.enable.autoScale=true
-Dswt.autoScale=120
-Dswt.autoScale.method=smooth
```

今回はアイコンのサイズを120％にしています。
上記を追記し、保存してからEclipseを再起動するとアイコンが大きくなります。

# まとめ
今回は初めての記事ということで、Eclipseの設定の記事を書きました。これからエンジニアとしてより精進して、より良い記事を書いていきたいと思っています。
ここまで読んでいただいて誠にありがとうございました。

# 参考サイト
https://ex1.m-yabe.com/archives/5893
https://qiita.com/naohiro2g/items/dde897c0b510391182e0
mrbgemsのメソッドの引数

mrubyの拡張のmebgemsをCで書いた場合のメソッドの引数は以下のようなパターンがあります。

# 無し

```ruby
mrb_define_method(mrb, bsdspi, "getclk", mrb_bsdspi_getclk, MRB_ARGS_NONE());
```

# 固定引数

```ruby
mrb_define_method(mrb, bsdspi, "setclk", mrb_bsdspi_setclk, MRB_ARGS_REQ(1));
```

関数では以下のようにして引数を拾います。

```ruby
mrb_get_args(mrb, "i", &val);
```

複数の型が引数になる場合は、型をチェックして処理します。以下はintかarrayが引数になる処理です。

```ruby
  mrb_get_args(mrb, "o", &arg);
  if (mrb_type(arg) == MRB_TT_INTEGER) {
    arr = mrb_ary_new(mrb);
    mrb_ary_push(mrb, arr, mrb_fixnum_value(mrb_integer(arg)));
  } else {
    arr = arg;
  }
```

# 可変引数

必須な引数と、オプションの引数が有る場合

```ruby
mrb_define_method(mrb, bsdiic, "read", mrb_bsdiic_read, MRB_ARGS_ARG(2, 1));
```

これは以下のように拾います。

```ruby
mrb_get_args(mrb, "ii|i", &addr, &len, &opt);
```

引数の数はmrb_get_argc(mrb)で確認できます。

オプションの引数のみの場合はMRB_ARGS_OPT(n)で指定できるようです。

# 完全可変引数

MRB_ARGS_ANY()で指定して、配列として受け取れます。

# キーワード引数

MRB_ARGS_KEY()で指定して使えるようですが、未確認です。
やはり for は遅い...

「やはり for は遅い...」とは言っても，かなりの計算量でも実際の所要時間は微々たるものであるから，「どちらにしましょう」というような問題ではない（ことのほうが多い？）。

それにしても，1回目の実行時間に precompile の時間が含まれるのは仕方ないとはいえ，うざい。

[パッケージの使用](https://qiita.com/iikaiki/items/785535a4c4a67062ce0c) にあったプログラムで，`for` と `@.` を使う場合の速度を見てみた。

## 計算の準備

```julia
using DifferentialEquations
using OrdinaryDiffEq

f(u, p, t) = 1.01*u
u0 = 1/2
tspan = (0.0, 1.0)
prob = ODEProblem(f, u0, tspan)
sol = solve(prob, Tsit5())
nt = 500000
time = range(0.0, stop=1.0, length=nt);
```

## for を使う場合

```julia
@time begin
    tolsum = 0
    for i = 1:nt
      tolsum += abs(0.5*exp(1.01time[i] - sol(time[i]))/sol(time[i]))
    end
    println(tolsum/nt)
end

#=
0.43430654234310617
初回:  0.287376 seconds (7.62 M allocations: 130.864 MiB, 11.72% gc time, 19.01% compilation time)
2回目: 0.155388 seconds (7.50 M allocations: 122.056 MiB, 12.63% gc time)
=#
```

## @. を使う場合

```julia
using Statistics
@time mean(@. abs(0.5*exp(1.01time - sol(time))/sol(time)))

#=
0.43430654234310745
初回:  0.221519 seconds (453.79 k allocations: 34.439 MiB, 3.28% gc time, 89.64% compilation time)
2回目: 0.034055 seconds (18 allocations: 3.826 MiB)
=#
```

## ついでに

同じ計算を2回以上しない。

```julia
using Statistics
@time begin
    soltime = sol.(time)
    mean(@. abs(0.5*exp(1.01time - soltime)/soltime))
end

#=
0.43430654234310745
初回:  0.104983 seconds (354.28 k allocations: 31.687 MiB, 88.32% compilation time)
2回目: 0.027302 seconds (19 allocations: 7.631 MiB, 40.48% gc time)
=#
```
【Windows】ローカルPCにvenvでpythonの環境構築

以下の理由で、ローカルPC（Windows）上にvenvでpythonの環境構築をしました。
- openaiやlangchainなどのパッケージをcondaで管理するのが複雑だったため
- ネットワークの関係でDockerが使用できないため

詰まった箇所があったのでメモです。

### 環境
- OS: windows11
- python: 3.10.11

### やりたいこと
- pythonをローカルPC（windows）で実行
  - バージョン管理ツール（asdfなど）やパッケージ管理ツール（conda, poetry）を使用しない
  - pipを使いたい

### 手順
1. 以下から、python3（任意のバージョン）のWindows用インストーラーをダウンロード
https://www.python.org/downloads/

:::message
- 仮想環境の作成は、バージョン3.5から`pyvenv`ではなく`venv`が推奨されている
:::

---

2. インストーラーを起動し、pythonをインストール
![](https://storage.googleapis.com/zenn-user-upload/a161bf643143-20231024.png)
:::message
- `Add Python 3.x to PATH`にチェックを入れ、パスを通す
:::

---

3. Windows PowerShellで確認
```log
$ python -V 

Python 3.10.11
```

---

4. 任意のディレクトリで環境を作成
○○○に任意の環境名を入れる。

```log
$ mkdir xxx
$ cd xxx
$ python -m venv ○○○
```

---

5. 作成した環境のアクティベート
下記を実行後、プロンプトの先頭に`(.○○○)`が表示されていればアクティベート成功

```log
$ Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
$ .○○○/Scripts/Activate.ps1
```

:::message
- スクリプトを実行するためにPowerShellでは`$ Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force`を実行する必要がある
:::

--- 
#### 以下メモ

- パッケージのインストール
アクティベートしている環境で任意のパッケージのインストール

```log
$ pip install xxx
```

---

- 現環境にpipでインストールされたパッケージをrequirement.txtに出力

```log
$ pip freeze > requirements.txt
```

:::message
- `pip install -r requirements.txt`で環境間でパッケージを共有できるようになる
:::


---

- デアクティベート

```log
$ deactivate
```

### 感想
- venvでの環境構築はシンプルでわかりやすかった。ローカルではvenvを使用し、pythonのバージョン管理やパッケージの管理は必要になったタイミングで導入すると理解しやすいと感じた。

### 参考
https://docs.python.org/ja/3/library/venv.html
https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e
https://www.python.jp/install/windows/venv.html
https://note.nkmk.me/python-pip-install-requirements/#requirementstxt
画像のファイル形式をコマンドで一括変換

# 目的
画像の拡張子を`.png`や`.jpg`などに相互変換できるようにしたい。 備忘録。

# 環境
シェル：zsh

# 事前準備
Homebrewで必要なコマンドをインストール。
```zsh
brew install imagemagick
```

# 方法
例としてiPhoneで撮った拡張子`.heic`の複数枚の写真を`.png`に一括変換してみる。

## 1枚のみ変換する場合
`convert`コマンドを使用。
- 例.) `result.heic`を`result.png`に変換する。
```zsh
convert result.heic result.png
```

## 複数枚を一括変換する場合
`mogrify`コマンドを使用。こっちは`-format`オプションが必要。
- 例.) 全ての`.heic`ファイルを`.png`形式に変換する。
```zsh
mogrify -format png *.heic
```

## 蛇足
変換元の`.heic`ファイルをディレクトリから全て削除。
```zsh
rm *.heic
```
ImageMagickでもっとできることは沢山あるけど今の所これだけしか使ってない、何かあったら追記します。

# 参考
- [ImageMagick公式サイト(英語)](https://imagemagick.org/script/index.php)
- [ImageMagick日本語ガイド](https://imagemagick.biz/)
AndroidStudio: Coroutine の使い方

こちらのプログラムを AndroidStudio で実行して見ました。
[Kotlin: Coroutine の使い方](https://qiita.com/ekzemplaro/items/c594de59e70addc08e03)

## 環境設定

```kts:app/build.gradle.kts
（省略）
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
（省略）
```

## プログラム

```kt:MainActivity.kt
package com.example.oct2402

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // main_proc を非同期で呼び出すために CoroutineScope を作成
        CoroutineScope(Dispatchers.Main).launch {
            main_proc()
        }
    }

    // main_proc を非同期関数に変更
    suspend fun main_proc() = coroutineScope {
        val aa = 10
        val bb = 20
        var cc = 0
        var dd = 0

        // バックグラウンドスレッドで計算を行う
        launch(IO) {
            delay(1000)
            println("Kotlin Coroutines World!")
            cc = aa + bb
            dd = aa - bb
            println("PP: cc = $cc\t\tdd = $dd")
        }

        // メインスレッドで "こんにちは" を表示
        println("こんにちは")

        println("QQ: cc = $cc\t\tdd = $dd")
    }
}
```

## 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/be34d8df-64d1-a154-9751-faac26dea69f.png)

```text
15:41:20.237  I  こんにちは
15:41:20.238  I  QQ: cc = 0		dd = 0
15:41:21.242  I  Kotlin Coroutines World!
15:41:21.242  I  PP: cc = 30		dd = -10
```
【Vue.js】vue-gtagでカスタムイベントをトラッキングしよう【GoogleAnalytics】 

# はじめに
突然の質問ですが、Google Analytics(以下GA)を使用して特定のイベントの発火回数や状態をカウントする際、どのように計測していますか？

私は以前、Google Tag Manager(以下GTM)を使用していました。
しかし、GTMでは変数やタグ、トリガーの設定、プレビューなど、コンソール上での操作が多く必要で、設定完了までにかなりの時間を費やすことがありました。

そのため、最近は`vue-gtag`を使用しています。
これにより、カスタムイベントの設定をより簡潔に行えるようになりました。

そこで今回は実際に行っている`vue-gtag`を使用したカスタムイベントの設定手順についてまとめました。

# vue-gtagとは
vue-gtag は Vue.js のアプリケーションで Google Analytics の新しいライブラリである gtag.js を簡単に導入・統合するためにラッパーライブラリです。
Vue のSPA特有のルーティングを考慮しており、ページ遷移やイベントトラッキングを簡単に操作できるようになります。

https://matteo-gabriele.gitbook.io/vue-gtag/


# この記事のゴール
カスタムイベントを作成してGAに反映させること

# 実装手順
今回はViteで構築したVue3の環境を使用します.

1. GAアカウントとプロパティ、データストリームの作成
2. 測定IDとGoogleタグの取得
3. vue-gtagのインストールと有効化
4. カスタムイベント設定
5. アナリティクスコンソールで確認

応用編 パラメータ付きカスタムイベントを設定する

### 1. GAアカウントとプロパティ、データストリームの作成
[こちら](https://marketingplatform.google.com/about/analytics/
)のリンクにアクセスしてGAアカウントとプロパティを作成します。
次に、公開可能なURLとストリーム名を入力します。
上記を作成した後データストリームの作成を行います。

![スクリーンショット 2023-10-24 1.09.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739783/93aad9e3-5da7-4324-9d20-08512915daa1.png)


### 2.測定IDとGoogleタグの取得
左下の歯車マークから設定画面に遷移し、ストリーム詳細画面を確認します。
以下の2つをコピーしておきましょう。
- **G-から始まる測定ID**
![アナリティクス (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739783/f2ce8983-4179-6bc7-c5f6-8e44636401ce.png)

- **Googleタグ**
`タグ実装手順を表示する`ボタンを押下後、表示されます
![アナリティクス (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739783/b3090cf9-3318-54e7-bf9d-81bbf67bf6a6.png)

これでGAコンソール上での設定は完了です。
### 3. vue-gtagのインストールと有効化

`index.html`のheadタグ直後に先程コピーした`Googleタグ`を貼り付けます。

   yarn または npm を使用して、`vue-gtag` をダウンロードします

```
yarn add vue-gtag
```

ダウンロードが完了したらmain.tsにて`vue-gtag`の有効化を行います。
下記のように記述することで、Vueインスタンス作成時に`VueGtag`プラグイン渡すことで`vue-gtag`が利用可能となります。
`hoge`には先程コピーした測定IDを貼り付けます
```
import { createApp } from 'vue'
import App from '@/App.vue'
import router from '@/router'
import VueGTag from 'vue-gtag'
const app = createApp(App)
app.use(
  VueGTag,
  {
    config: {
      id: '{ hoge }'
    }
  },
  router
)

app.use(router)
app.mount('#app')
```
`vue-gtag`読み込み時に`router`インスタンスを渡すことによって、ユーザーが`Vue Router`を使用してページを移動するたびに自動的にページビューのイベントがGAに送信されるようになります。

初期設定はこれで完了です。

### 4.カスタムイベント設定

コンポーネントやモジュール内でvue-gtagの`eventメソッド`を読み込みます。
```
import { event } from 'vue-gtag'
```

次にeventメソッドをトリガーとなる処理の中に設定します。
```
const clickHogeBtn = () => {
  //event('イベント名')
  event('clicked hoge btn')
}
```

上記の設定を行うことでclickHogeBtn関数が発火するごとに**clicked hoge btnイベント**がGAに送信されるようになります。

### 5.アナリティクスコンソールで確認
最後に設定内容の反映確認をGAコンソールにて行います。
これまでの変更内容をデータストリームに登録済みのサイトに反映したら実際にサイト上で設定済みをイベントを発火させます。

イベントの発火後、GAコンソールの左メニューバーからレポートを選択して、**リアルタイムレポート**を確認しましょう。

設定済みのイベント名が表示されることを確認できたら完了です！

![アナリティクス-リアルタイムの概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739783/d13b7f6d-c8a5-9905-eee9-d922dad8231e.png)

### おわりに
これまでの手順を通して簡単にカスタムのイベントの設定を行うことができました。
GTMを使用して設定する場合と比べて大幅に実装時間を短縮できたかと思います。

GAでは様々な値を計測することが可能なので、また次回の記事でまとめようと思います。
Linuxめも_viで検索したいぽよ篇

## はじめに
タイトルそのまま。
一応CLI使いこなせる人かっこいいなあ〜！と思ってはいる

## 検索したい時は
`/`の後にキーワードを入力する。

で、この後がキモ
- キーワードがヒットした位置から、
    - 下にモリモリ検索する時は`n`
    - 上にぐんぐん行きたいときは`N`

からの、
- 大文字小文字を区別したくない時は/の後ろに`\c`
    - macのJISキーボードでバックスラッシュはoption ¥て入力するw

です！！！

## 復習
### カーソルの移動
- 次の単語の移動：w　#ハイフンは1単語としてカウントする
    - 現在または前の単語の先頭に移動：b
    - 現在または次の単語の末尾に移動：e

### 行の中での移動

- 行頭：0
- 行末：$
- 最終行への移動：G

### 全行の削除
- :%dでどーんと消える
- ddで1行まるごと消える

## おわりに
毎回忘れるのでめもでした。
簡単ですが以上です:v:
Rummagene: 遺伝子セットから論文内の遺伝子セットを検索するWebツール

# Rummageneとは
[Rummagene](https://rummagene.com/)は遺伝子セットを入力して、PMCの論文内にある遺伝子セット(Supplementary_tableなど)を検索できるWebツールです。
またPubMed Central (PMC)はNBCIが管理する生物学のジャーナルのオンラインアーカイブです。オープンアクセスですので、自由に閲覧が可能です。

一般に、遺伝子セットから直接論文を検索することは難しいです。また、ある論文とどの程度遺伝子が類似しているのか、その$P$値はいくらか計算するには膨大な手間がかかります。

[Rummagene](https://rummagene.com/)は500万本以上の論文を読み込んでおり、遺伝子セットからPMC内の論文に収録された遺伝子の類似度や$P$値を計算することができます。また論文単位ではなく、論文内のSupplementary data単位での類似度も計算してくれます。[Rummagene](https://rummagene.com/)は論文をタームとするEnrichment解析だと思ってよいでしょう。

:::note warn
注意
プレリリース版がある場合、二重に遺伝子セットを抽出してしまう場合があるそうです。(2023/10/23 確認)
:::

# Rummageneの使い方

[Rummagene](https://rummagene.com/)にアクセスすると、下の画像のような画面が出てきます。

![2023-10-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527309/41f270ca-35db-372e-02a8-8bf4714ad779.png)

オレンジ色の枠のところに、改行区切りで遺伝子を入力しましょう。遺伝子はEntrez gene symbolにしましょう(ABCA1など)。もしくは、緑色のボタンからテキストファイルで遺伝子を入力することができます。

遺伝子を入れ終わったら、水色の**SUBMIT**ボタンを押して解析を始めましょう。今回はexampleの遺伝子セットを入力しました。しばらく待機した後、下の画像のような結果が出てきます。

![2023-10-24 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527309/c39fb021-95fe-b32f-f706-7ed82de8d1a6.png)

それぞれ論文のIDとタイトル、ヒットした表や$P$値などが記されています。Paper行にあるPMC……をクリックすれば、論文のページに飛べます。Supporting Table行のファイル名を押せば遺伝子表をダウンロードできます。ほかにもOverlapをクリックすれば重複した遺伝子を得られるなど、このページだけで完結できて便利です。
また補正$P$値の順に並んでおり、遺伝子セットがより似ている順に並んでいると思ってよいでしょう。$P$値はフィッシャーの正確確率検定で計算され、BH法で補正されています。

また表の右上にある検索を使えば論文のタイトルで結果にフィルターをかけることができます。例えば、新型コロナウイルス関連について知りたいとき、[ **COVID-19** ]と検索すれば、

![2023-10-24 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527309/0105c7c7-989f-1f0c-55de-668e39d7a6c1.png)

COVID-19がタイトルに含まれる論文のみ表示されました。Rummageneでは大量のタームが手に入るので、適宜検索して結果を絞りましょう。

# その他のRummageneで出来ること

サイト右上にあるAboutに行くと、GraphQL API経由でWeb APIが公開されています。大量の解析結果をダウンロードしたいときは、APIを使いましょう。

またAboutの左にあるDownloadからはRummageneのデータセットがgmt形式で配布されています。ファイルのサイズはかなり大きいですが、GSEAやclusterProfilerなど外部ツールでRummageneを利用できます。

# 参考文献

Daniel J. B. Clarke, Giacomo B. Marino, Eden Z. Deng, Zhuorui Xie, John Erol Evangelista, Avi Ma’ayan. 
Rummagene: Mining Gene Sets from Supporting Materials of PMC Publications
*bioRxiv* 2023.10.03.560783; doi: https://doi.org/10.1101/2023.10.03.560783
【ネットワーク】初心者のためのネットワークの基礎知識についてまとめてみた

## 概要
今回は初心者向けにネットワークの基礎知識についてまとめました。
ネットワークやネットワークトポロジについて説明します。

# ネットワークとは
ネットワークとは、パソコンやネットワーク機器といった複数の要素がケーブルなどで接続されていて、
相互通信できる状態になっているものを指します。
ネットワークを構成する要素を**ノード**、ノードとノードを結ぶ線を**リンク**、リンク上のデータの流れを**フロー**と言います。

# ネットワークの種類
ネットワークには大きく分けてLAN、WAN、インターネットの３つに分類されます。
この３種類について説明します。

### LAN
LANとは、家庭またはビルといった1つの建物の範囲で利用されるネットワークです。

### WAN
WANとは、本社と支部といった距離の離れたLANとLANを接続するネットワークです。

### インターネット
インターネットとは、複数のネットワークを接続した世界規模の大きなネットワークのとこです。
インターネットの接続には、家庭用のPCや企業内のLANなどから**インターネットサービスプロバイダ**を介して接続します。

# ネットワークトポロジ
ネットワークトポロジとは端末やネットワーク機器をどのように接続しているのか、
その接続形態のことです。

### バス型
基幹となるケーブルに各ノードを接続する形態です。
バスに障害が発生するとノード間の通信ができなくなります。
![スクリーンショット 2023-10-24 14.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/6bf98861-524f-685a-0adc-2f393d458b20.png)


### リング型
隣接するノードをリング状に接続する形態です。
１か所で障害が発生すると全体に影響が出ます。
![スクリーンショット 2023-10-24 14.46.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/0c0f16b7-cb62-1367-bf79-4bf23759099e.png)

### スター型
中央の集線装置に各ノードを接続する形態です。
現在の主流の形態です。
![スクリーンショット 2023-10-24 14.50.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/2191794b-b8a0-d7c2-4e03-8c2d41c3d428.png)

### メッシュ型
ノード間をそれぞれ接続する形態です。
どこか一か所で障害が起きても、他のノードを経由して通信ができるため、障害に強い形態となっています。
下記の画像のように、全てのノードが互いに接続されているものを**フルメッシュ**と言います。
![スクリーンショット 2023-10-24 14.57.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/d53d51d1-c9d4-72fc-4fa8-8b556fee07a7.png)

### ハイブリット型
上記の紹介した、ネットワークトポロジを複数組み合わせた接続形態です。

# 最後に
以上となります。
続きは下記の記事となりますので是非、見てください。

https://qiita.com/nakamura_slj/items/4d10e529f771225d2844
~Pマーククイズ~デザイン定義書

## Pマーククイズアプリデザイン定義書

### カラー設定
使用したカラーは以下のものです。
![app-pallate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3578112/42c4643b-c6b7-b4c4-f994-b813b115901c.png)


全ての画面デザインは以下のXD共有URLに収めてあります。
https://xd.adobe.com/view/f727613e-227e-4045-8248-d43a2281d2e9-a274/?fullscreen
※Adobe XDのリンクはAdobeの契約が切れたら見えなくなる可能性もあります。


### 意識したポイント
・見やすいカラー
・使いやすいボタン
・綺麗な余白
・シンプルなフォント

#### カラー
色に関してはまず、Pマーク公式サイトを参考にし、公式のカラー設定が青紫だったのでそれをベースにしました。

今回はPマークと言われた時に感じる硬いイメージをなくしてほしいと言われたのでもう一つの提案でオレンジをベースとしたデザインも提案しました。結局は青色ベースのものが採用されました。

青色に合う色でポップな感じを出せるのは黄色だと思い次に使用している青色に合う黄色を探して決めました。青色と黄色の組み合わせは確かにポップな感じを出し、硬いイメージをなくします。

しかし、これだと少し派手すぎると感じました。もう少しトーンの低い黄色を使うか、違う色にするかとなったときにベージュを使うことにしました。

普段から派手さを収めたい時にベージュやグレーを使っているので今回もそうしてみました。
黄色もなかなか色的にあっていたのでボタンの色として使用することにしました。

問題の正解・不正解の色に関しては赤色はベースにしている青色の補色を使いました。
不正解用の色に関しては赤色の彩度・明度が高いのでそれに合わせて色を決めました。
同じような彩度・明度を使うと違和感が少ないためです。

結果ページの背景に関しては最初は薄いグレーを使っていたが他のデザイナーさんにみてもらった時に色をメインの色に合わせるとより良くなると言われそのようにしました。


色に関しては大体こんな感じです。

色に関してのツールやサイトは以下のサイトを参考にしました。
https://xd.adobe.com/view/f727613e-227e-4045-8248-d43a2281d2e9-a274/?fullscreen


#### ボタン
ボタンの最小縦幅を55pxで今回はやりました。
大体推薦されている最小縦幅が50pxなのでそれより少し余裕を持たせた感じです。

同じ機能を持ったボタンは同じ色にする。似ているような機能を持ったボタンは同じようなスタイルにすることを意識しました。

今回使用したボタンは以下のものです。
![buttons-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3578112/8cc2a50f-e659-af6e-03e9-6a4824e0ab86.png)

#### 余白
私の苦手な部分でもある余白、今回はデザインを作るときに見つけた記事に従って余白のルールを決めました。

その記事は残念ながら見つけれなかったです。端末からの横の最低余白が15px、縦が25pxにしてあります。

それ以外の画面内の最低余白は横が10px縦が15pxというルールを一応決めてから制作をやり始めました。

#### フォント
フォントは基本的なシンプルなものを意識しました。

今回はヒラギノ角ゴシックを使用しました。みんなが見慣れているシンプルなフォントを使用することによって伝わりやすさを意識しました。

唯一違うフォントを使ったのがスクリーンショットの一枚目です。

![app-store.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3578112/e3a0fa7f-5b9f-e9fc-be70-90d5ba18bf6e.png)


ここではもう少しポップな感じにし、他の文字との違いをつけたかったので違う
フォントを使用しました。

### 感想
アプリデザインに限らずデザインを作っていく時に使う道具やルールを決めておくと便利です。

意識するポイントは制作する人によって変わってきますが、私の場合は色と余白を重要視します。

今回のデザインでは他のデザイナーのアドバイスや他のかたのアドバイスを頂きながらデザインを完成させました。
手伝っていただいた方々には感謝の気持ちでいっぱいです。




アプリダウンロードはこちら→
https://apps.apple.com/jp/app/pmark/id6462645147?ign-itscg=30200&ign-itsct=apps_box_link

サポートサイトはこちら→
https://apps.qualias.jp/

クオリアシステムズHPはこちら→
https://qualias.jp/

ご覧戴き、ありがとうございました!!
【Unity】GetAxisを使うとキャラの動きがヌルヌルする

改善
-

↓ を開く
Edit → Project Settings → Input Manager → Axes → Horizontal と Vertical
（編集 → プロジェクト設定 → Input Manager → 軸 → 水平 と 垂直）

↓ の二つを15くらいにする
Gravity（重力）
Sensitivity（感度）　


---
あるいは、GetAxisRaw(スムージングなしのGetAxis)を使う
AWS Copilot CLIで環境を作成していくときにExpiredTokenExceptionで詰まった話

AWS Copilot CLIを使用することで、サクッとECSへデプロイできるということで使用してみてが、予想外に詰まった箇所があったので備忘録。

# ExpiredTokenException: The security token included in the request is expired

`copilot init`や`copilot app init`を実行するとタイトルのエラーが発生する。

環境変数に別の資格情報が設定されている場合があると発生することがあるため、
下記のコードを打って、リセットすると解消する。

``` bash
unset AWS_SESSION_TOKEN AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY

```
【Swift】オプショナルバインディング-改めて整理

# 目次
[1.オプショナルバインディングとは？](#1-オプショナルバインディングとは？)
[2.シャドーイング](#2-シャドーイング)
[3.実例](#3-実例)
[4.終わりに](#4-終わりに)

# 1. オプショナルバインディングとは？
Swiftでは厄介なことにnillを意識しないと、アプリがクラッシュしてしまったりと意図しないシステムエラーが起きてしまいます。(逆にこのことを利用する開発手法もありますが、、)
そんな、オプショナル型をアンラップする正当な手法のひとつが<u>***オプショナルバインディング***</u>です

# 2. シャドーイング
`if let ~`や`guard let ~`の２つの記法で記述する方法を***シャードーイング***と言います。

# 3. 実例
- if let~ 構文
~~~swift:IF-Let構文
let a: Int? = 1

if let a = a {
    // アンラップ対象がnillでないときの処理
    print("aはnillではないです！")
} else {
    // アンラップ対象がnillのときの処理
    print("Error- aはnillです")
}

print(type(of: a))
~~~
`出力結果: Optional Int`


- Guard let構文
:::note info
Tip
現場ではこちらを多用している印象です！
:::
~~~swift:Guard let構文
let a: Int? = 1

guard let a = a else {
    // アンラップ対象がnillのときの処理
    print("Error- aはnillです")
} 

print(type(of: a))
~~~
`出力結果: Int`
つまり、Guard-Let構文を通過した変数はnillでなくなっているんです。

# 4. 終わりに
If-Let構文とGuard-Let構文の違いはその記述方法と、これらの処理通過後の変数の型です。
開発現場では、ややGuard-Let構文に軍配が上がっていますが、お好みで。

今回も本記事を最後まで読んでいただいてありがとうございました。
目指せ脱初学者で頑張っていきましょう〜♪
【SwiftUI】Lottieを使ってアニメーションを簡単に実装してみた

# Lottieとは
アニメーションを記述したjsonファイルをプロジェクトに追加して呼び出すだけで簡単にアニメーションを実装できるライブラリです。アニメーションのjsonファイルは無料でダウンロードできるので気軽に実装できます。
#### LottieFiles
ここからダウンロードできます

https://lottiefiles.com/featured

#### Lottieのライブラリのリポジトリ

https://github.com/airbnb/lottie-ios


# LottieViewを定義する
Lottieを導入したら、まずLottieViewを定義してViewで呼び出せるようにします。

::: note info
少し前の記事で`let animationView = AnimationView().animation.named(name)`と宣言されている場合がありますが、動かないようなので`LottieAnimationView(name: String)`で宣言しています。(バージョンが更新された際に仕様が変更されたのかもしれません)
:::
```Swift:LottieView.swift
import Lottie
import SwiftUI

struct LottieView: UIViewRepresentable {
    
    var name: String
    let loopMode: LottieLoopMode
    
    func makeUIView(context: UIViewRepresentableContext<LottieView>) -> UIView {
        let view = UIView(frame: .zero)
        
        let animationView = LottieAnimationView(name: name)
        animationView.contentMode = .scaleAspectFit
        animationView.loopMode = loopMode
        animationView.play{ (finished) in
            
        }
        
        animationView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(animationView)
        NSLayoutConstraint.activate([
            animationView.heightAnchor.constraint(equalTo: view.heightAnchor),
            animationView.widthAnchor.constraint(equalTo: view.widthAnchor)
        ])
        
        return view
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {
        
    }
}
```
今回はloopModeだけをView側で変更できるようにしています。loopModeには以下の5種類があります。
```Swift
/// Defines animation loop behavior
public enum LottieLoopMode {
  /// Animation is played once then stops.
  case playOnce
  /// Animation will loop from beginning to end until stopped.
  case loop
  /// Animation will play forward, then backwards and loop until stopped.
  case autoReverse
  /// Animation will loop from beginning to end up to defined amount of times.
  case `repeat`(Float)
  /// Animation will play forward, then backwards a defined amount of times.
  case repeatBackwards(Float)
}
```
Viewで呼び出す際は非常にシンプルで`.frame`で大きさも指定できます。
```Swift
LottieView(name: "sample", loopMode: .playOnce)              
    .frame(width: 200, height: 200)
```
# 最後に
Lottieを使うことで簡単に高度なアニメーションを実装することができました。ちなみにAdobeのソフトでアニメーションを制作してjsonファイルとして出力すればオリジナルのアニメーションを制作することができるそうです。

# 参考リンク
https://lottiefiles.com/featured

https://github.com/airbnb/lottie-ios

https://medium.com/@ckinetandrii/how-to-add-lottie-animation-in-swiftui-de39fe0c7018
【Tableau】「値を使用した表示状態の制御」の活用

### はじめに
　Tableauダッシュボードの表現を広げる機能である、「値を使用した表示状態の制御」(動的ゾーン表示)を活用したダッシュボードを紹介します。
　「値を使用した表示状態の制御」では、ダッシュボードに置かれたシートなどのオブジェクトを自動的に表示または非表示にすることができます。

:::note
作成したダッシュボードは[こちら](https://public.tableau.com/views/WOW2023_41_16980351239520/sheet0?:language=ja-JP&publish=yes&:display_count=n&:origin=viz_share_link)から見ることができます。
:::

### 活用方法
「値を使用した表示状態の制御」の活用方法は以下の通りです。
1. 表示を切り替えたいシート数分のリストを持つパラメータを作成します（定数であればリストのデータ型は問いません）
2. リストそれぞれに対応する判定を作成します
3. ダッシュボードにて該当のシートを選択します
4. レイアウトタブから「値を使用して表示を制御」にチェックをつけ、プルダウンから該当のパラメータ判定を選択します

<details><summary>画像付き手順</summary>
1. 表示を切り替えたいシート数分のリストを持つパラメータを作成します（定数であればリストのデータ型は問いません）

![画像13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/adb78a1e-2001-ec73-1ef1-c6e34a0a4e61.png)

2\. リストそれぞれに対応する判定を作成します

![画像11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/1aabfa80-6d2d-0d4c-a46e-82e8d3ce3eaf.png)

3\. ダッシュボードにて該当のシートを選択します
4\. レイアウトタブから「値を使用して表示を制御」にチェックをつけ、プルダウンから該当のパラメータ判定を選択します

![画像12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/d4b4afe1-fdc1-dfd5-3bc3-ac944e0d7706.png)

</details>

　上記手順ののち、パラメータの選択を切り替えるとシートの表示も切り替わるようになります。

### 参考
* [#WOW2023 | Week 41 | Can you build a flexible tabular display?](https://workout-wednesday.com/2023w41tab/)
* [Tableauヘルプ / Tableau Cloudヘルプ / Web上でのビューの作成と操作 / Dynamic Zone Visibilityの使用](https://help.tableau.com/current/online/ja-jp/dynamic_zone_visibility.htm)
【Tableau】ツールヒント内Vizの活用

### はじめに
　ビジュアライゼーションの表現を広げる機能である、ツールヒント内Vizを活用したビジュアライゼーションを紹介します。
　ツールヒント内Vizでは、マークにカーソルを合わせると表示されるツールヒントにビジュアライゼーションを埋め込むことができます。

:::note
作成したビジュアライゼーションは[こちら](https://public.tableau.com/views/WOW2023_31_16980346498090/1?:language=ja-JP&publish=yes&:display_count=n&:origin=viz_share_link)から見ることができます。
:::

### 活用方法
ツールヒント内Vizの活用方法は以下の通りです。
1. ツールヒント内に埋め込みたいビジュアライゼーションのシートを作成します
2. 元となるシートのマークカード「ツールヒント」から「挿入」で作成したシートを選択します
3. ツールヒントの編集で表示する大きさやフィルターを掛ける対象を編集します

<details><summary>画像付き手順</summary>
1. ツールヒント内に埋め込みたいビジュアライゼーションのシートを作成します

![画像14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/32ee3519-1f43-be2c-7a67-15536652a2b7.png)

2\. 元となるシートのマークカード「ツールヒント」から「挿入」で作成したシートを選択します

![画像10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/6512ed6f-7695-17df-8691-d80335790955.png)

3\. ツールヒントの編集で表示する大きさやフィルターを掛ける対象を編集します

![画像15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/5cc4eeb0-c81f-a9f9-950b-6710e59f750e.png)

</details>

　上記手順ののち、マークにカーソルを合わせるとツールヒント内Vizが反映されるようになります。

![画像16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/2fadb4e0-6ebc-2ce5-37dd-da0e489f51ba.png)

　今回作成したビジュアライゼーションでは、ネストされたLOD表現も活用しています。
　[こちら](https://qiita.com/PVPJsYOKww74838/items/b74413f88d6ca13a3510)の記事も併せてご覧ください。

### 参考
* [#WOW2023 W31: Can you find the most popular sub-category by sales per state?](https://workout-wednesday.com/2023w31tab/)
* [Tableauヘルプ / Tableau DesktopとWeb作成のヘルプ /.../ インサイトの紹介 / ツールヒント内でビューを作成する(ツールヒント内Viz)](https://help.tableau.com/current/pro/desktop/ja-jp/viz_in_tooltip.htm)
【Tableau】ネストされたLOD表現の活用

### はじめに
　ビジュアライゼーションの表現を広げる機能である、LOD表現(詳細レベル表現)を活用したビジュアライゼーションを紹介します。
　LOD表現では、計算したい粒度をコントロールすることができます。

:::note info
作成したビジュアライゼーションは[こちら](https://public.tableau.com/views/WOW2023_31_16980346498090/1?:language=ja-JP&publish=yes&:display_count=n&:origin=viz_share_link)から見ることができます。
:::

### 活用方法
ネストされたLOD表現を利用している今回のビジュアライゼーションの考え方は以下の通りです。
1. 各都道府県において、サブカテゴリごとの売り上げはどれくらいか
2. 都道府県ごとに最も売れたサブカテゴリの売り上げはどれくらいか
3. 上記に該当するサブカテゴリは何か
4. 上記のサブカテゴリが最も売れた都道府県の数はどれくらいか

<details><summary>画像付き手順</summary>
1. 各都道府県において、サブカテゴリごとの売り上げはどれくらいか

![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/1ade052d-0d32-5e93-943f-78d22ea77267.png)

![画像5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/8e8c3286-5155-1786-4a4b-d838a913417e.png)

2\. 都道府県ごとに最も売れたサブカテゴリの売り上げはどれくらいか

![画像6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/6e45a4b4-4840-b120-2018-a5d8fa4ced9b.png)

![画像7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/8e07239b-4790-6bed-dced-ed5aa1614d18.png)


3\. 上記に該当するサブカテゴリは何か

![画像8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/ed1452dc-f8ea-46de-7dae-ae409cd26a78.png)


4\. 上記のサブカテゴリが最も売れた都道府県の数はどれくらいか

![画像9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/b0f4bf07-58f2-9473-02af-2ccc2fda88c2.png)

</details>
	
　今回作成したビジュアライゼーションでは、ツールヒント内Vizも活用しています。
　[こちら](https://qiita.com/PVPJsYOKww74838/items/76ed50332a5b7c451a64)の記事も併せてご覧ください。

### 参考
* [#WOW2023 W31: Can you find the most popular sub-category by sales per state?](https://workout-wednesday.com/2023w31tab/)
* [Tableauヘルプ / Tableau DesktopとWeb作成のヘルプ /.../ 計算フィールドの作成 / 詳細レベル表現](https://help.tableau.com/current/pro/desktop/ja-jp/calculations_calculatedfields_lod.htm)
【Tableau】「イメージの役割」の活用

### はじめに

　Tableauバージョン2022.4で追加された新機能、「イメージの役割」を活用したビジュアライゼーションを紹介します。
　「イメージの役割」では、Web画像のURLから画像をワークシートに動的に追加することができます。

:::note info 
作成したビジュアライゼーションは[こちら](https://public.tableau.com/views/WOW2023_1/sheet0?:language=ja-JP&publish=yes&:display_count=n&:origin=viz_share_link)から見ることができます。
:::

### 活用方法
「イメージの役割」の活用方法は以下の通りです。
1. Web画像のURLが要素となっているディメンションフィールドを準備します
2. 1 のフィールドを右クリックし、「イメージの役割」→「URL」を選択します
3. アイコンが画像アイコンに変わります

<details><summary>画像付き手順</summary>
1. Web画像のURLが要素となっているディメンションフィールドを準備します

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/619ac165-1baa-fc68-af1e-4d7b0a95d806.png)

2\. 1 のフィールドを右クリックし、「イメージの役割」→「URL」を選択します
3\. アイコンが画像アイコンに変わります

![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/a41efb49-b2d5-9e99-74cf-419edfc65056.png)

</details>

　上記手順ののち、ビジュアライゼーションに該当フィールドを追加すると自動で画像表示されるようになります。

![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583156/5a20693a-ed60-5a63-6f3d-ab8a6326134a.png)


### 参考
* [#WOW2023 Week 1: Can you use Image Role & Dynamic Zone Visibility?](https://workout-wednesday.com/2023w1tab/)	　
* [Tableauヘルプ / Tableau DesktopとWeb作成のヘルプ / グラフの構築とデータの分析 / Web画像をワークシートに動的に追加する](https://help.tableau.com/current/pro/desktop/ja-jp/image_role.htm)