OmniAICreator/Qiita-1.07M huggingface dataset:
ScalaのZIOやZQueryについて日々の知見

## 概要
SalaのZIOやZQueryで出てくる色んな方や日々の発見について自分用のメモした記事です。
随時更新していければと思います。

## 型について
### ZIOのChunk型について

ZIOは、Scala向けの効率的で安全な非同期プログラミングライブラリで、Chunk型はその中で使用されるデータ構造の1つです。

Chunkは、メモリの塊を表現する不変のデータ構造で、大量のデータを効率的に処理するために設計されています。
Chunkは、リストや配列などの他のデータ構造と同様に、複数の要素を保持できますが、一般的には連続するメモリ領域に要素を格納することで高速なデータアクセスを可能にします。

**Chunkは、特にZIOの並列処理や非同期I/O処理において、高速なデータの読み書きや変換を可能にするために使用されます。**
また、Chunkは不変であるため、同期やロックなどの同期の必要性を減らし、並列処理をより簡単に実現できます。

例えば、以下のようにChunkを使用して、大量のデータを並列で処理することができます。

```.scala
import zio._
import zio.stream._

val data: Chunk[Int] = Chunk(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

val processed: Task[Chunk[Int]] =
  ZStream.fromChunk(data)
    .mapMPar(4)(i => Task(i * 2))
    .runCollect
```

この例では、Chunkに格納された整数のリストを4つの並列タスクで2倍に変換し、最終的に処理された整数のリストを収集しています。

### ZQueryのバッチ処理：　DataSource.fromFunctionBatchedMについて
DataSource.fromFunctionBatchedMは、ZIO-Queryのデータソース構築用の関数の1つであり、
効率的なバッチ読み込みを可能にする方法を提供します。
この関数は、バッチ単位で要素を読み込む関数を提供することで、バッチ処理を可能にするデータソースを構築します。

DataSource.fromFunctionBatchedMを使用してデータソースを構築するには、まず、各要素の識別子と、バッチ単位で要素を読み込む関数を定義する必要があります。

たとえば、以下のような識別子と関数を持つデータソースを定義することができます。

```.scala
  case class User(id: Long, name: String)

  val users = List(
    User(1L, "Alice"),
    User(2L, "Bob"),
    User(3L, "Charlie"),
    User(4L, "David"),
    User(5L, "Eve"),
  )

  def loadUsers(ids: Chunk[Long]): Task[Chunk[User]] = Task {
    ids.flatMap(id => users.find(_.id == id))
  }
```

loadUsersは、Chunk[Long]の識別子のバッチを受け取り、その識別子に対応する要素のバッチを返すタスクを返す関数です。
この関数は、usersリストから、識別子に対応する要素を検索して返します。

DataSource.fromFunctionBatchedMを使用して、
上記のloadUsers関数からバッチ処理可能なデータソースを構築するには、以下のようにします。

```.scala
  case class UserRequest(id: Long) extends Request[Throwable, User]
  val usersDataSource: DataSource[Any, UserRequest] =
    DataSource.fromFunctionBatchedM("Users") { ids: Chunk[UserRequest] =>
      for {
        users <- loadUsers(ids.map(_.id))
      } yield {
        users
      }
    }.batchN(1000)

```
DataSource.fromFunctionBatchedMの第1引数は、データソースの名前を示す文字列です。
第2引数は、バッチ単位で要素を読み込む関数です。この関数は、Chunk[Long]の識別子のバッチを受け取り、その識別子に対応する要素のバッチを含むマップを返します。


このデータソースを使用して、ZQueryを構築することができます。
たとえば、以下のように、usersDataSourceを使用して、ユーザーのIDに対応するユーザー名を取得するクエリを定義することができます。

```.scala
  val userNameQuery: ZQuery[Any, Throwable, Set[User]] =
    ZQuery.foreachPar(List(1L, 2L, 3L, 4L, 5L).toSet)(x => ZQuery.fromRequest(UserRequest(x))(usersDataSource))
```

このクエリは、ZQuery.foreachParを使用して、ユーザーIDのセットを取得し、
それぞれのIDに対応するユーザーの名前をデータソースから取得します。
ZQuery.foreachParは、ユーザーIDのセットをバッチに分割し、並列でデータソースから要素を取得するため、効率的なバッチ読み込みが行われます。

userNameQueryを実行するには、ZIO環境を提供する必要があります。
たとえば、以下のようにして、ZIO Appを使用して実行できます。

```.scala
object Example extends App {
  override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = {
    val program = for {
      userNames <- userNameQuery.provideLayer(Blocking.live).run
      _ <- console.putStrLn(userNames.toString)
    } yield ()

    program.exitCode
  }
}
```
この例では、provideLayerメソッドを使用して、Blockingレイヤーを提供し、ZQueryを実行します。console.putStrLnを使用して、ユーザー名のマップを標準出力に出力します。
AZ-500（Microsoft Azure Security Technologies)受験の記録

# はじめに
近頃、関わるAzure案件で、色々なセキュリティ対策や業界基準に沿った対応を検討することが多くなってきました。
自身でAzureセキュリティを再学習する際に、ちょうどよいので１つの目標としてAzure Security Engineer Associate(AZ-500)の資格取得を目指しました。
この受験を振り返り、学習したことを記載します。今後この資格の取得を考えている方の参考になれば幸いです。



# Azure Security Engineer Associate(AZ-500) とは
この資格に求められる役割
*Azure セキュリティ エンジニアは、エンドツーエンドのインフラストラクチャの一部として、Azure、マルチクラウド、ハイブリッド環境でのリソースのセキュリティを実装、管理、監視します。*

以下、出題範囲です。
- ID とアクセスの管理
- ネットワークのセキュリティ保護
- コンピューティング、ストレージ、データベースのセキュリティ保護
- セキュリティ オペレーションの管理


公式情報・最新情報は以下をご参照。

https://learn.microsoft.com/ja-jp/certifications/exams/az-500

# 勉強方法

1. 「[試験 AZ-500: Microsoft Azure セキュリティ テクノロジ](https://learn.microsoft.com/ja-jp/certifications/exams/az-500)のラーニングパス」を一読。4つのラーニングパスがあり、各パスで規定の時間は6時間程度。
ポイント：対象範囲と知識の習得。サービス・機能・特徴に焦点をあてて理解に努める。
2. 「[Udemy：AZ-500 Microsoft Azure Security Exam Certification 2022](https://www.udemy.com/course/exam-azure-2/)」の演習問題を解く。
ポイント：わからない問題は演習の解説をみる。ネットで検索やラーニングパスの該当箇所で復習

1はざっと読んでいきそれぞれラーニングパスで2時間くらい × 4コース。2は3時間×2演習問題　くらいで実施（演習問題の解説を理解するのに時間をかけました）。


# 受験
- テストセンターでの受験を選択しました。
- 問題は3つか4つの選択肢から選ぶ形式が多い。後半にシナリオ問題がありました。
- 1時間程度で解き終わり、見直す時間は十分にありました。

# 結果、振り返り
受験後すぐに結果が出ます。797点で合格でした(合格点は700/1000点)。

以下振り返りです。
- ある程度Azure環境に触れている方なら、Microsot Learnで出題範囲の知識をアップデートすれば回答できる問題も多い印象です。
- 使用した問題集は、同じ問題がでるというわけではないですが、出題ポイントを把握でき、覚えた知識で回答できる問題が多いように感じました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2563999/64081d2e-d7a5-72db-6f9a-77da08a14d79.png)

引き続き、クラウド環境のセキュリティの学習をして、次は[Cybersecurity Architect Expert(SC100)](https://learn.microsoft.com/ja-jp/certifications/cybersecurity-architect-expert/)を目指そうかなと思います。
JSON schema diagram for SPDX v2.3

## Motivation

The SPDX community has published [the specifications](https://spdx.github.io/spdx-spec/v2.3/) and [some examples of SPDX document](https://github.com/spdx/spdx-examples), but understanding the structure of SPDX document and how each item relates is a little difficult.  
In very near future, when we must consider about SBOM automation, I think it is very important to understand not only the specifications but also the working SPDX Document, so I want to illustrate its architecture.  

## What is this?

Split ["a236284 on Jan 21" version of the JSON schema for SPDX v2.3](https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json) published on github and transcribed it into a UML diagram using [PlantUML](https://plantuml.com/en/json). And JSON files used to create them have been committed [here](https://github.com/OpenChain-Project/OpenChain-JWG/tree/master/subgroups/sbom-sg/outcomes/SBOM/SPDXv2.3/jsonschema).
I hope this helps you understand SPDX document.

## Overview  

![SPDX-JSON-schema-overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/cdd74ec0-e631-3727-ea82-dfe0c1f8e62b.png)

## annotations  

![SPDX-JSON-schema-annotations.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/60ab84f8-4342-c735-9e44-7232557da751.png)

## creationInfo  

![SPDX-JSON-schema-creationInfo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/200b767d-942f-2e54-0a40-cba82b52c240.png)

## externalDocumentRefs

![SPDX-JSON-schema-externalDocumentRefs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/bb5e2ced-146d-f3bd-8cd3-d4e6d027d792.png)

## hasExtractedLicensingInfos  

![SPDX-JSON-schema-hasExtractedLicensingInfos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/239271a6-0ba1-65cc-28ce-bc6e96043aeb.png)

## revieweds  

![SPDX-JSON-schema-reviewds.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/518f7532-f5f4-3438-35ba-487342310341.png)

## documentDescribes  

![SPDX-JSON-schema-documentDescribes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/6e9ed7bb-a060-96ec-4cf5-d8525972e7a2.png)

## packages  

![SPDX-JSON-schema-packages.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/724f1caa-7690-11fc-37c5-9cf43414069b.png)

## files  

![SPDX-JSON-schema-files.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/bb23d1a9-7b79-d4cb-b9bf-40c8e22b62a0.png)

## snippets  

![SPDX-JSON-schema-snippets.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/0f26c90a-0321-5106-9382-ed5adac7f361.png)

## relationships  

![SPDX-JSON-schema-relationships.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114349/f77040a5-1ff0-5130-49c8-5350d25ed7ea.png)
Jitsi meet　インストール

以下でSSL更新
sudo /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh

https://tutorialcrawler.com/ubuntu-debian/ubuntu%E3%81%ABjitsi-meet%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/

インストール参考
https://blog.masato-nike.net/post/2020-05-01-web-meeting-2/
iPhoneのGoogleChromeアプリで開いているタブを、macOSのGoogleChromeに共有することができると思うのですが、タブが大量(数十個くらい)もあってひとつひとつ共有するのが面倒な場合に、効率よく共有する方法はありますか?

はい、効率的にiPhoneのGoogle Chromeアプリで開いているタブをmacOSのGoogle Chromeに共有する方法があります。

以下の手順に従ってください。

1.  まず、iPhoneとmacOSの両方で、Google Chromeを起動しておく必要があります。
2.  次に、iPhoneのGoogle Chromeアプリで共有したいタブを開きます。
3.  タブを開いたら、iPhoneのGoogle Chromeアプリの右下隅にある「タブ一覧」アイコンをタップします。
4.  タブ一覧画面で、共有したいタブを長押ししてください。
5.  長押しすると、タブが選択状態になり、タブ上に「共有」というボタンが表示されます。このボタンをタップして、共有メニューを表示します。
6.  共有メニューで、macOSのGoogle Chromeを選択してください。
7.  選択すると、macOSのGoogle Chromeでタブが開かれます。

この方法で、複数のタブをまとめて共有することができます。ただし、共有するタブの数が多い場合は、1つ1つのタブを共有するよりも時間がかかることがあります。また、共有するタブの数が多い場合は、macOSのGoogle Chromeがクラッシュする可能性があるので、注意してください。
関連付けで追加されるメソッド

## 4.1.1 belongs_toで追加されるメソッド
belongs_to関連付けを宣言したクラスでは、以下の8つのメソッドが自動的に利用できるようになります。
* association
.
.
.

### 4.1.1.1 association
associationメソッドは、```関連付けられたオブジェクト```を返します。関連付けられたオブジェクトがない場合はnilを返します。
```rb
@author = @book.author
```

## 4.3.1 has_manyで追加されるメソッド
has_many関連付けを宣言したクラスでは、以下の17のメソッドが自動的に利用できるようになります。
* collection
.
.
.

上のメソッド名のcollectionの部分はプレースホルダなので、has_manyの第1引数として渡されるものの名前で読み替えてください。また、collection_singularの部分は名前を単数形にして読み替えてください。

.
.
.
### 4.3.1.1 collection
collectionメソッドは、関連付けられた```すべてのオブジェクトのリレーションを返します```。関連付けられたオブジェクトがない場合は、空のリレーションを1つ返します。
```rb
@books = @author.books
```

# 出典
https://railsguides.jp/association_basics.html#%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%81%AE%E8%A9%B3%E7%B4%B0%E3%81%AA%E5%8F%82%E7%85%A7:~:text=writer.first_name%0A%3D%3E%20true-,4%20%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%81%AE%E8%A9%B3%E7%B4%B0%E3%81%AA%E5%8F%82%E7%85%A7,-%E6%9C%AC%E3%82%BB%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A7%E3%81%AF

# 感想
複数か単数かで間違えないようにしよう。
【M5Stick】天気予報が雨の時、傘を持つように促す装置を作った[天気の戸締まり]

# 天気の戸締まりとは
新○監督の天気○子とす○めの戸締まりを合体したイメージで名付けました。
先日作成した"[鍵を閉め忘れたらLINEに通知するシステム(通称:自宅警備員)](https://qiita.com/nih/items/6135769d6572f07a5789)"の機能追加版です。
鍵の閉め忘れをLINE通知するのはもちろん、天気予報が雨の時、ドアを開けた際ブザーで傘を持つように促します。

# 必要なもの
- M5StickCPlus
- [磁気ドアスイッチ](https://ssci.to/7390) x2
- [LINENotify](https://notify-bot.line.me/ja/)のToken x1
- [OpenWeatherMap](https://openweathermap.org)のToken x1

# 作り方
[GitHubリポジトリ](https://github.com/11104/Weathering_Tojimari)のプログラムの
12~17行目にWiFi情報とLINENotifyのToken,openWeatherのTokenを書き込んでください。
鍵用の磁気スイッチは16番pin、鍵用の磁気スイッチ2番pinを使用します。


# 所感
[前回](https://qiita.com/nih/items/6135769d6572f07a5789)はM5Stackでしたが、今回はM5Stickで作成したため配線と工夫すれば装置がコンパクトになりそうです。




↓実際の動作(予報が雨の場合)
<iframe width="200" height="400" src="https://www.youtube.com/embed/_xXk4dWurT4" title="【M5Stick】天気予報が雨の時、傘を持つように促す装置を作った[天気の戸締まり]" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# 参考記事
- [ESP32でAPIを使って現在の天気を取得してみた](https://wak-tech.com/archives/797)(OpenWeatherのToken取得方法など)
Cannot run migrations because another migration process is currently running.

# Cannot run migrations because another migration process is currently running.
```
**********@mbp ****** % rails db:migrate                          
rails aborted!
ActiveRecord::ConcurrentMigrationError: 

Cannot run migrations because another migration process is currently running.
```
## 訳
別のマイグレーションプロセスが実行中のため、マイグレーションを実行できない
出典　deepL

## 検索
https://qiita.com/kskinaba/items/4da04bc5ba5d6f90419d

### 気づき
MySQLの処理中のマイグレーションを削除すればいいらしい。

## KILLとは？
13.7.8.4 KILL Statement
```
KILL [CONNECTION | QUERY] processlist_id
```
>Each connection to mysqld runs in a separate thread. You can kill a thread with the KILL processlist_id statement.
>Thread processlist identifiers can be determined from the ID column of the INFORMATION_SCHEMA PROCESSLIST table, the Id column of SHOW PROCESSLIST output, and the PROCESSLIST_ID column of the Performance Schema threads table. The value for the current thread is returned by the CONNECTION_ID() function.

## 出典
https://dev.mysql.com/doc/refman/8.0/en/kill.html

## 訳
mysqldへの各接続は、別々のスレッドで実行されます。KILL processlist_idステートメントでスレッドを強制終了することができます。
スレッドプロセスリストの識別子は、INFORMATION_SCHEMA PROCESSLISTテーブルのID列、SHOW PROCESSLIST出力のId列、Performance Schema threadsテーブルのPROCESSLIST_ID列から求めることができます。現在のスレッドの値は、CONNECTION_ID()関数によって返されます。
出典　deepL

## CONNECTION_ID()とは？
```
CONNECTION_ID()
```
>Returns the connection ID (thread ID) for the connection. Every connection has an ID that is unique among the set of currently connected clients.
## 出典
https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_connection-id:~:text=%2D%3E%20%27latin1_swedish_ci%27-,CONNECTION_ID(),ID%20that%20is%20unique%20among%20the%20set%20of%20currently%20connected%20clients.,-The%20value%20returned

CONNECTION_ID関数を使用することで、現在接続中の自分の接続IDを調べることができます。

## 出典
http://db.yulib.com/mysql/000056.html#:~:text=CONNECTION_ID%E9%96%A2%E6%95%B0%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%A7%E3%80%81%E7%8F%BE%E5%9C%A8%E6%8E%A5%E7%B6%9A%E4%B8%AD%E3%81%AE%E8%87%AA%E5%88%86%E3%81%AE%E6%8E%A5%E7%B6%9AID%E3%82%92%E8%AA%BF%E3%81%B9%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

# 感想
```migration process is currently running.```で
プロセスが実行中であると判断するのか。

それから```SHOW PROCESSLIST;```で現在の実行中のプロセスを```KILL```でIDを指定して、強制終了させるのか。
もっと理解しないといけないようだ。
Ruby の twitter gem で Twitter API の確認をする

App で API v2 を使えるかどうか知りたいときがある

## 前提

- twitter app が standalone app だと API v1.1対応
- app が project app だと API v1.1 / v2 対応

### v2 対応じゃない

```ruby
> require 'twitter'
> client = Twitter::REST::Client.new(
  access_token: "...",
  access_token_secret: "...",
  consumer_key: "...",
  consumer_secret: "...",
)
> client.send(:perform_get, '/1.1/account/verify_credentials.json')[:screen_name]
"..."
> client.send(:perform_get, '/2/users/me')
lib/twitter/rest/request.rb:97:in `fail_or_return_response_body': Twitter::Error::Forbidden (Twitter::Error::Forbidden)
```

### v2 対応

```ruby
> require 'twitter'
> client = Twitter::REST::Client.new(
  access_token: "...",
  access_token_secret: "...",
  consumer_key: "...",
  consumer_secret: "...",
)
> client.send(:perform_get, '/1.1/account/verify_credentials.json')[:screen_name]
"..."
> client.send(:perform_get, '/2/users/me')[:data][:username]
"..."
```

## まとめ

リクエストすればいいんだけど，設定がアプリに入っているので，
コンソールでやった方がいいとかの場合には使えるかも？
RailwayのCLIの仕様が変わったので一応のメモ

Railway.appのCLIがアップデートされて仕様が変わったので、スクリプト上であれこれ操作する場合に認証などが変わったっぽい。今までGithub Actionsで動いていたスクリプトが途端に動かなくなったので、RailwayのDiscordコミュニティで教えて貰ったものを備忘録的に書いておく。

今までは

```yaml
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Use Node 18
        uses: actions/setup-node@v1
        with:
          node-version: 18.x

      - name: Install packages
        run: yarn install --frozen-lockfile

      - name: Install Railway
        run: npm i -g @railway/cli

      - name: Deploy
        run: railway up
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
```

といった感じで``RAILWAY_TOKEN``をGithubの環境変数に設定してやり、Node.jsとyarnをインストールし、RailwayCLIをインストールさせてやればrailwayのコマンドが使えたが、これだけだと"No linked project found"とエラーメッセージが出るようになってしまった。

要するにプロジェクトとちゃんとリンクをつけろと言ってるので

```yaml
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Use Node 18
        uses: actions/setup-node@v1
        with:
          node-version: 18.x

      - name: Install packages
        run: yarn install --frozen-lockfile

      - name: Install Railway
        run: npm i -g @railway/cli

      - name: Link Railway Project
        run: railway link --environment ${{ secrets.ENVIRONMENT_NAME }} ${{ secrets.PROJECT_UUID }}
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}

      - name: Link Railway Service
        run: railway service ${{ secrets.SERVICE_UUID }}
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}

      - name: Deploy
        run: railway up
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
```

と``ENVIRONMENT_NAME``と``PROJECT_UUID``と``SERVICE_UUID``を環境変数として設定してやればちゃんと動くことが確認できた。やったぜ。

ENVIRONMENT_NAMEはprojectのページの歯車アイコンのProject SettingsのEnrironments項目から、Project Environmentsの名前を入れる。PROJECT_UUIDはプロジェクトページのアドレスの/project/のページの次の文字列、SERVICE_UUIDは各サービスページのアドレスの/service/の次の文字列が該当するIDって感じだった。
Discordの開発者モードを有効にする方法【備忘録】

# 説明
1. Discord左メニュー下の`歯車`を押す。
1. `詳細設定`
1. `開発者モード` を `ON`

> 歯車 → 詳細設定 → 開発者モード
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102978/493c1fb6-5456-532a-fbfb-329c01e734a5.png)


以上。


## おまけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102978/28d8c6bf-277a-4d51-3f03-06115ebd3ea1.png)


```shell
$ 勇者がdiscordの開発者モードを有効にする壮大なSF小説を1000文字程度で制作してください。
```

勇者であるアリシアは、魔王を倒し、世界を救った後、新しい挑戦に立ち向かうことにした。彼女は、オンラインコミュニティの一員であるDiscordを改善することを決意しました。

ある日、アリシアはDiscordの開発者モードを有効にすることを思いつきました。それは、Discordをより効率的に管理できるようになり、他のユーザーとのコミュニケーションを改善するための強力なツールを提供することができます。

しかし、彼女は開発者モードを有効にするにはDiscordの深い部分にアクセスする必要があることを知っていました。彼女は、開発者モードを有効にするための膨大な知識を学ぶ必要があったため、新たな冒険に出かけることになりました。

彼女は、Discordの仕組みや言語を熟知する開発者達と協力し、開発者モードを有効にする方法を学びました。彼女は長い時間を費やし、数々の試練を乗り越えなければなりませんでしたが、最終的に成功しました。

開発者モードを有効にしたアリシアは、Discordの全ての機能にアクセスし、サーバーを管理し、ロールや権限を設定することができました。また、ユーザーとのコミュニケーションを改善するための新しい機能を開発することもできました。

彼女は、Discordの開発者モードを有効にすることで、より効率的なコミュニケーションを実現し、多くの人々にとって利益をもたらしました。彼女の冒険は、Discordの歴史に刻まれ、多くの人々の助けとなりました。
go言語でwindowローカル環境の別のフォルダーのファイルの関数を呼び出す方法

go言語で別フォルダーの関数を呼ぶ時、依存関係でハマったので纏めます
今回はtestフォルダーのtest.goを呼ぶ簡単な構成で説明します

## ファイル構成
```
gotest
∟test
　∟test.go
∟main.go
```

## main.goのsrcの中身
```golang
package main

import (
	"fmt"

	"gotest/test"
)

func main() {
	fmt.Println("test")
	test.GetTest()
}

```

## test.goのsrcの中身

```golang
package test

import (
	"fmt"
)

func GetTest() {
	fmt.Println("test2")
}
```

## modの初期化やpackageの取得
```sh
// modの初期化
$ go mod init gotest

// フォルダー移動
$ cd test

// modの初期化
$ go mod init gotest/test

// 上階層に移動
$ cd ..

// testフォルダーのpackageをローカルの相対パスに変更
$ go mod edit -replace=gotest/test=./test

// packageを取得
$ go get gotest/test

// main.goを実行
$ go run main.go
```

## 実行され下記のように出力される
```
test
test2
```

go言語を勉強しはじめた時にハマりやすいポイントなので参考にして頂ければと思います
Path Planningを最適制御問題として解く

Path Planningは、各点でのコスト関数の和がなるべく小さくなるように、かつ、終端の点がなるべく目標地点に近くなるように、経路を決める問題である。また、移動体の物理上の構造を考慮するという制約も付く(e.g.急激に方向転換をすることは不可能)。これを制御工学の言葉で言うと、

* 各点$x_i$でのコスト関数$\to$ステージコスト関数$L(x_i)$
* ホライズンの終端の点が目標点に近いかどうか$\to$終端コスト関数$\phi(x_f)$
* プラントの物理的構造を考慮する。

なので、ここでは、Path Planningを制御工学の最適制御問題として解いてみる。

## プラント
Path Planningのアルゴリズムをいくつか見てみると、移動物体の速度が考慮されておらず、経路を決める際に打たれる点はそれぞれ等距離ずつ離れている。

ということで、プラントから速度と時間の概念を除き(あるいは、プラントの速度は一定であると仮定する)、 **時間$t$ではなくて経路長$s$による状態方程式** を作る。

まずは、状態$x$を以下のように定義する。
```math
x(s)=[x_1(s) ~ x_2(s) ~ \theta(s)]^\mathrm T
```
$x_1,~ x_2$はプラントの位置座標、$\theta$はプラントが今向いている角度である。

次に、状態方程式を示す。通常の、時間による状態方程式とは以下のような式だが、
```math
\frac{d}{dt}x(t)=f(x(t),u(t))
```
今回は以下のような式とする。ただし、$s$は経路長である。
```math
\frac{d}{ds}x(s)=f(x(s),u(s))
```
つまり、$f(x,u)$は、プラントが単位経路進むと状態$x$がどのくらい変わるのかを表した関数となり、具体的には
```math
f(x(s),u(s))=[\cos(\theta(s)) ~ \sin(\theta(s)) ~ u(s)]^\mathrm{T}
```
とする。なお、$u(s)$は入力であり、プラントの向きを変える角速度に対応する。

という訳で、時間の次元が存在しない状態空間を仮定した。

## 問題設定
![x0.xf.obstacles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/0352a1be-5dc0-bb63-1c94-51c7de306de4.png)
上の図のような環境を考える。

プラントの初期状態を$x_0=[0 ~ 0 ~ 0]^\mathrm T$(黄の+点)とし、目標状態を$x^{goal}=[15 ~ 0 ~ 0]^\mathrm T$(紫の*点)とする。

$x_0$から$x_f$の間にはいくつかの障害物(黒い円2つ)があり、これを避けながら$x_0\to x_f$と移動するための最適な入力$u(s)$を求める。

なお、離散時間系で解くこととし、時間刻みならぬ **距離刻み** を$\Delta s=0.2$、ホライズンを$h=100$とした。

## コスト関数
コスト関数には、ステージコスト関数$L(x(s))$と終端コスト関数$\phi(x(s_f))$の2種類がある。

### ステージコスト関数
状態$(x_1,~ x_2,~ \theta)$がもしも障害物に入っていたら、ステージコスト関数$L(x)$を課すこととする。

その障害物の中心座標を$(x_1^o,~ x_2^o)$とすると、ステージコスト関数$L(x)$に対する状態$x$の微分を

```math
\frac{dL(x)}{dx}=[G\frac{x_1^o-x_1}{d} ~ G\frac{x_2^o-x_2}{d} ~ 0]^\mathrm T
```

とする。なお、$d$は状態と障害物の中心の距離$|(x_1^o,~x_2^o)-(x_1,~x_2)|$、$G$は勾配の強さを決める定数$G=3$である。

これは、今の位置から障害物の中心に向かう単位ベクトルに$G$をかけたものである。つまり、コスト関数$L(x)$の形状は、障害物の中心が最も標高が高い円錐である。

なお、2つ以上の障害物が重なっていることはない。

### 終端コスト関数
終端コスト関数は以下のように定義される。
```math
\phi(x)=\frac{W}{2}(x_1-x_1^{goal})^2+(x_2-x_2^{goal})
```
ただし、$W$は重みを表す定数であり、$W=0.1$である。また、終端コスト関数の状態に対する微分は
```math
\frac{d\phi(x)}{dx}=[W(x_1-x_1^{goal}) ~ W(x_2-x_2^{goal}) ~ 0]^\mathrm T
```
である。ここから分かるように、角度はコストの対象としないこととした。つまり、プラントが目標座標$(x_1^{goal},~ x_2^{goal})$に到達すれば、その時の角度$\theta$は何でもOKということ。

## 実験結果
入力$u(s)$の初期値を$u(s)=0$としたので、最初は以下のようなPath(青線)となった。

![initial.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/6ff4ca19-b3b2-cc88-decf-38b5d82cbc2f.png)

障害物にモロ当たってる。。

ここで、$u(s)$を最適化すると・・・

![final.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/00492c85-24f1-d652-7f2a-57338ed4afd3.png)

障害物を避けながら、うまく目標地点まで到達できた。

## 振り返り
* ちょうどホライズンの終端で目標地点に到着するようなPathになっているが、もうちょい近道できると思う。このような少し回り道なPathが作られてしまった原因としては、状態$x$と目標地点$x^{goal}$の距離のコストが終端コスト関数でしか与えられていなかったためであると考えられる。なるべく短い道のりで、かつ、障害物を避けるようなPath Planningをしたいのであれば、状態$x$と目標地点$x^{goal}$の距離のコストをステージコスト関数にも載せるべきだと考えられる。
* 今回は入力$u(s)$に制約条件を付けなかったが、制約条件を付けてやってみても面白く実用的かもしれない。
* これと似たPath Planningの手法としてDWAというものがあるが、DWAとこのアルゴリズムの長短がそれぞれ何なのかを検討した方がいいね。
* このアルゴリズムを、実際にプラントを動かしながら逐次行っていくことによって、モデル予測制御のようなことができるのでは？

## 勾配法の実装
今回は最適化を勾配法で実施したが、この実装を示す。

```
... 工事中 ...
```
ChatGPTの履歴が消える問題への対処（Cookieクリア）

# 3/21追記

今度は､一部環境でなくChatGPT全体（?）の問題として発生した模様です｡後述したCookieクリアでも解消されません｡

[![Image from Gyazo](https://i.gyazo.com/9104b4d95fb7edbdb449a429b72a885b.png)](https://gyazo.com/9104b4d95fb7edbdb449a429b72a885b)

> We continue to roll out restoration of ChatGPT service. Users are
not able to retrieve conversation history at this time. We are
working to restore this feature.

> ChatGPTのサービス復旧に向けて、引き続き展開中です。ユーザーの皆様は現在、会話履歴を取得することができません。私たちはこの機能を復活させるために活動しています。


# 結論

単に｢画面再読み込み｣したり｢ログイン→ログアウト｣するだけで解決する場合もあるようですが､私の場合は､それらは効果ありませんでした｡

Cookie削除したら解決しました｡以下はChromeの場合

[![Image from Gyazo](https://i.gyazo.com/19206ebbcfe22f5a7eed596875d6acc3.png)](https://gyazo.com/19206ebbcfe22f5a7eed596875d6acc3)

表示されたのを全て削除します｡

[![Image from Gyazo](https://i.gyazo.com/f4ca5f646e2f0861d7f9dab797b25fc7.png)](https://gyazo.com/f4ca5f646e2f0861d7f9dab797b25fc7)


# 元ネタ

OpenAIのフォーラムのある人のコメントにありました｡阿鼻叫喚です｡笑

[All previous ChatGPT history gone? - ChatGPT - OpenAI API Community Forum](https://community.openai.com/t/all-previous-chatgpt-history-gone/87964/228)

# 余談

ChatGPT､まじ､凄い｡
超有能なアシスタント｡
劇的に生産性あがりました｡

将棋棋士にAIが欠かせなくなったのと同じで､プログラマにもChat GPT Plusは必須ですね｡
(Plusにしてから10日ほど経過しましたが､応答の遅延･エラーはゼロです）

｢将棋AIの指し手を理解するには高い棋力が必要｣と言われるのと同様に､Chat GPTも相応のプログラミング能力が求められますね｡

やりたいことを言語化できるスキルと､Chat GPTの回答を理解して業務に使えるように最適化したり非機能部分を肉付けできなければ使いこなせない｡
ということで､仕事を失うことは当面なさそう｡笑

[![Image from Gyazo](https://i.gyazo.com/6bc4c7ef9b2331200119f655ebf54882.png)](https://gyazo.com/6bc4c7ef9b2331200119f655ebf54882)
データベースを基本からまとめてみた【A5:SQL Mk-2　SQLのエクスポートとインポート】

## エクスポートとは
あるアプリケーションで作成したデータを、他のアプリケーションでも利用できる形式でファイルを保存する機能である。



## インポートとは
あるアプリケーションで作成したデータを、使用中のアプリケーションでも利用できる形式に変換して取り込むことを指す。

## 参考サイト
[IT用語辞典バイナリ＜パソコン用語・コンピュータ辞書＞](https://www.sophia-it.com/content/%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88)
[【A5:SQL Mk-2】CSVのインポート・エクスポート方法](https://yu-report.com/entry/a5csv/)
ディレクトリ内のテキストファイルで特定の文言を含むファイルを抽出するコマンド（Windows PowerShell）

# 概要
特に外向けに難しいことを発信しようとしたわけでもなく、今後もたまに使いそうだと思った、ファイルの一括削除＠Windowsローカル環境のコマンドレットを備忘しておきます、その２。

# 指定ディレクトリ内で、特定の文言を含むテキストファイルを抽出する

## ファイルパスを出す

こういう感じ。

```sh
Get-ChildItem -Path "（ディレクトリパス）" -Filter *.txt -Recurse | ForEach-Object {
    if (Select-String -Path $_.FullName -Pattern "（検索したい文字列）") {
        Write-Output $_.FullName
    }
}
```

## ファイルパスだけでなく、該当行の記述も出す

こういう感じ。

```sh
Get-ChildItem -Path "（ディレクトリパス）" -Filter *.txt -Recurse | ForEach-Object {
    $matches = Select-String -Path $_.FullName -Pattern "（検索したい文字列）"
    if ($matches) {
        Write-Output "File: $($_.FullName)"
        $matches | ForEach-Object {
            Write-Output "Line: $($_.LineNumber): $($_.Line)"
        }
    }
}
```

## 複数の文字列でも検索できるようにする
こういう感じ

```sh
$searchStrings = '文字列１', '文字列２', '文字列３', '文字列４', '文字列５'

Get-ChildItem 'C:\target_directory\*.txt' -Recurse | ForEach-Object {
    $filePath = $_.FullName
    $content = Get-Content $filePath

    foreach($searchString in $searchStrings) {
        $lineNumber = 0

        foreach($line in $content) {
            $lineNumber++
            if($line -match $searchString) {
                Write-Host "File: $filePath"
                Write-Host "Line #${lineNumber}: $line"
            }
        }
    }
}

```

# 終わり

大量のログファイルの中から、指定の文言があるかを調べるときに便利デスネ。
ChatGPT, Whisper, Cognitive Serviceを使って会議の議事録作成アプリを作ってみた

# はじめに

最近公開されたChatGPTとWhisperを用いて以前作成した会議の議事録作成アプリ、会議の音声データから要約文を作成するアプリの改良版を作ってみました。また実際開発していてそれぞれのAPIのオプションについての記事も投稿したので以下のリンクからご覧ください

https://qiita.com/murasso/private/ef3797e174bd0172184e

# 目次

- 会議の議事録作成アプリを作成に至った経緯
- 以前のアプリの構成
- 改良版アプリの構成

# 会議の議事録作成アプリを作成に至った経緯

会議は多くの場合、情報共有や意思決定のための重要な場ですが、時間が限られているため、参加者が話した内容を全て把握することは難しいことがあります。特に長時間の会議や多人数の参加者がいる場合は、その課題はより深刻となります。そこで、会議の音声データから自動で要約を行うアプリを作ることで、参加者が話した内容を短時間で把握することができ、参加していない人たちにも会議の内容を把握してもらえます。また、会議に限らず、講義やインタビューなど、様々な場面で活用が期待されます。

# 以前のアプリの構成

以下のような構成で以前作成しました。



![diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1453705/efaaf10b-5ece-cc5d-a430-56222884b92b.png)


## cognitive serviceとは

cognitive serviceとは、Microsoft社が提供するクラウド上のAPI（Application Programming Interface）群で、自然言語処理、音声認識、画像認識、機械翻訳、感情分析などの人工知能技術を利用して、アプリケーションの開発やビジネスの業務改善を支援するものです。

## text-davinci-003とは

text-davinci-003とは、OpenAIが提供する自然言語処理のための言語モデルの1つで、自然言語での文章生成や翻訳、文章の質問応答など、様々なNLPタスクに使用することができます。特に、高度な文章生成や文章要約、文章の類似性判定などのタスクに優れた性能を発揮します。

### 改善点

- 音声データはwavフォーマットのみ対応
- 音声データの長さ分、処理時間がかかってしまう

# 改良版アプリの構成

改良版の構成は以下の通り

![diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1453705/c591d05b-cb9b-9abc-c00c-010f8e18f6a5.png)


## Whisperとは
Whisperとは、自動音声認識（ASR）システムであり、インターネット上から収集された680,000時間の多言語でマルチタスクな監視データに基づいてトレーニングされています。この多様なデータセットにより、Whisperはアクセント、バックグラウンドノイズ、テクニカル言語に対してより頑健になり、複数の言語でのトランスクリプションや翻訳を可能にする多言語対応のASRシステムとなっています。

##gpt-3.5-turboとは
gpt-3.5-torboとは、既存の「GPT-3.5」よりもGPT-3モデルより10倍安く、価格は1,000トークンあたり0.002ドルです。
また、チャット以外の多くのユースケースに最適なモデルです。プロンプトにわずかな調整を加えるだけで、text-davinci-003 から gpt-3.5-turbo に移行することができます。

### 特徴

- 音声データフォーマットは、mp3, m4a, wav対応可能
- 処理時間を1/36に短縮

また開発するにあたってそれぞれのAPIに様々なオプションがあったので、別の記事でそれぞれのオプションの仕様についてまとめてみました。


実際作成したアプリのコードは、githubに乗せています

https://github.com/soumurata/meeting_notes_app
Gazebo Ignitionという名前が変更になったことについての整理

# Ignitionという名前は廃止となりました。

https://community.gazebosim.org/t/a-new-era-for-gazebo/1356


それに伴い、Fortress(2021)->Garden(2022)にかけて、
Ignition GazeboからGazeboという名前への変更が行われています。

そもそもで利用されていないのに、更に混乱させるような状況が起きています。

Fortressで作ったものがGardenで使えないということが起きているので
一旦整理します。

1. Fuel(ModelとかWorldの共有サイト)のURLが変わった

Fortress:　fuel.ignitionrobotics.org
Garden:　fuel.gazebosim.org

Fortressで、GardenのURLを利用するとエラーになり、
Gardenで、FortressのURLを利用するとエラーになります。
なので、Fuelのサイトで、利用するときも、それがどのバージョンで作られたかを考慮しながら
利用する必要があります。

https://app.gazebosim.org/dashboard

2.HumbleはFortressを利用している前提で作られている
ROSPackageも移行期であり、Package名をIgnition->gzへの変更を行いつつあります。
HumbleはGardenもFortressも利用できると書いていますが、まだ完全にGardenに対応しきれていないフシが見られるので、利用しないほうがよいかと思います。


https://github.com/gazebosim/ros_gz/tree/humble


以上思考の整理でした。
AWSのアカウント作成方法(備忘録)

# AWSのアカウント作成

初めてなのでテストとして投稿します。
AWSのアカウント作成ですが、公式に手順があったのでそちらを参考にしてアカウントを作成します。

https://aws.amazon.com/jp/register-flow/?sc_icampaign=acq_aws_takeover-abandoner_jp&sc_ichannel=ha&sc_icontent=awssm-1524&sc_iplace=hero&trk=ha_awssm-1524&refid=94c18984-27d1-4395-8dae-cdbf523f1ae5

作成後ログインできることを確認しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680920/c978ef55-2b39-998e-a6fa-ff035eaabe87.png)
AccessのVBAでテキストボックス内文字列の一部選択や全選択

# 一部選択

下記のような名前のテキストボックスとボタンを用意。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/38e77d7f-b88f-f616-fcea-250d4f7927b3.png)

```vb:先頭3文字を選択するサンプル
Option Compare Database
Option Explicit

Private Sub btn_1_Click()
    
    'フォーカスあてる。
    Me.txt_1.SetFocus
    
    '最初の1文字目も選択に含める時は0。
    Me.txt_1.SelStart = 0
    
    '3文字分選択。
    Me.txt_1.SelLength = 3
    
End Sub
```

実行結果。

全角半角まわり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a8d722f2-bfe5-cfad-c423-b6893de58f0c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e02bbe29-e55b-2a59-0584-e94a9327dd9d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1ecca046-ce4c-fcbf-e2fb-9e5410b08e16.png)

テキストボックスの文字数 < VBAで指定した文字数 の場合、例外にならず全選択になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c2d66cc1-f8b2-fde3-52f0-dca741d80a29.png)


# 全選択

テキストボックスやボタンは一部選択と同じなので省略。

```vb:全選択するサンプル
Option Compare Database
Option Explicit

Private Sub btn_1_Click()
    
    'フォーカスあてる。
    Me.txt_1.SetFocus
    
    '最初の1文字目も選択に含める時は0。
    Me.txt_1.SelStart = 0
    
    '末尾まで選択。
    '何も入力していない場合『Me.txt_1.Value』はNULLとなり、
    'Len()に通すと例外になる為、Nz()をかませる。
    Me.txt_1.SelLength = Len(Nz(Me.txt_1.Value, ""))
    
End Sub
```
# SelLengthに0を指定した場合

例外にならない。
何も選択されないだけ。

# SelLengthに負の値を指定した場合

例外になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/2e7a2264-e6f3-fc8f-f72d-17329adadafd.png)

# 参考サイトさん

https://learn.microsoft.com/ja-jp/office/vba/api/access.textbox.sellength

https://ameblo.jp/bb-jp/entry-10107408522.html

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2673
Microsoft Access for Microsoft 365 MSO (バージョン 2301 ビルド 16.0.16026.20196) 32 ビット
Browserlessを試してみた

# 概要

https://www.browserless.io/

> Browserless is a web-service that allows for remote programs to connect, pilot, and execute headless browser tasks — all inside of docker.

> Browserlessは、リモートプログラムがDocker内でヘッドレスブラウザタスクを接続、操作、実行することができるWebサービスです。

Playwrightとも連携できるらしい。

# 起動する

```sh
docker run -p 3000:3000 browserless/chrome
```

# コンソールにアクセス

http://localhost:3000/

右上の実行ボタンを押すと実行される。

![CleanShot 2023-03-14 at 10.43.37.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7565/1669638f-e7d2-60c1-63bf-e925ad02c0f5.gif)
【マジ？】ChatGPT でスクレイピングのコード聞いたら、普通に使えた

つい昨日、スクレイピングの記事を書きました。

https://qiita.com/yNavS4Ki/items/3c043962a1dae583db0f

ChatGPT でコーディングできることは、いろんな記事を読んでいたので、同じ内容を実際に確認してみました。

## ChatGPT に聞いてみた

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157574/c8b6ec8b-841b-5e9d-ff04-3450f9857699.png">

想像以上に、普通に回答がもらえたのでビビりました。
とは言ってもそのままでは動作しませんでした。。どうやら CSS セレクターが違うようです。

`.yrnwTitle` という CSS セレクターを、実際に記事で利用した CSS セレクターに変更すると、普通に動作しました。。

ただ、自分で作った記事とは別のライブラリを使っていたので、記事で実際に利用した Colly を使ってもらった場合も教えてもらいました。

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157574/a7b426e2-db7a-2dc0-1ef4-f42a71e694f4.png">


これも CSS セレクターを修正するだけで、動作しました。。

## これからは、"修正" がメインで開発することになりそう

ここまで普通に動作するのであれば、ゼロ知識のものに関しては、

- 「やりたいこと」を説明してコード書いてもらう
- ライブラリなどは公式見ながら理解し、必要箇所を修正

という流れの方が、必要最低限の知識でより早く開発ができそうです。
"Done is better than perfect" というように、完璧さを求めすぎて何もできないよりかは、失敗や間違いを修正しながら仕上げていくことができるので、こっちの方が早く成長しそうです。
【Debian系】APTツールを使用した高度なパッケージ管理

# 目的
APTツールを理解する！

# APTツールとは
Adbanced Packaging Toolの略。
高度なパッケージ管理機能を提供する。
ネットワーク経由で最新のパッケージの取得ができる。

# 主なリポジトリ
|リポジトリ|説明|
|:--|:--|
|/etc/apt/sources.list|パッケージの取得元|

# コマンド
|コマンド|説明|
|:--|:--|
|apt-get|パッケージのインストールアンインストールがメイン|
|apt-cache|パッケージの情報の検索・参照などを行う|
|apt|apt-getコマンドとapt-cacheコマンドを統合したコマンド|

# apt-getコマンド
APTツールで使用するコマンド。
アプリケーションの依存関係を調整しながらパッケージのインストール、アップグレードなどを行う。
インターネットで最新パッケージを入手してインストールと依存関係の解決ができる。

### apt-getコマンドのオプション
|オプション|説明|
|:--|:--|
|-d|インストールせずにダウンロードのみ行う（/var/cache/apt/archivesに保存）
|-s|システムを変更せずに動作をシュミレートする|
|--purge|設定ファイルを含めて、パッケージを削除する（removeコマンドと一緒に指定する）|

### apt-getコマンドのサブコマンド
|サブコマンド|説明|
|:--|:--|
|clean|ダウンロードしたパッケージファイルを削除する|
|dist-upgrade|ディストリビューションを最新版にアップグレード|
|install|指定したパッケージをインストール、またはアップデート|
|remove|指定したパッケージをアンインストール（設定ファイルは残す）|
|update|パッケージのデータベースを最新にする|
|upgrade|システムの全パッケージを最新版にアップグレードする|

# apt-cacheコマンド
パッケージの情報の検索・参照などを行うコマンド。

### apt-cacheコマンドのサブコマンド
|サブコマンド|説明|
|:--|:--|
|search キーワード|キーワードを含むパッケージを検索|
|show パッケージ名|指定したパッケージ情報の表示|
|showpkg パッケージ名|指定したパッケージに依存しているパッケージを”含めた”情報の表示|
|depends パッケージ名|指定したパッケージが依存しているパッケージの一覧を表示|

# 終わり
コマンドのオプションとサブコマンドがあるんですね〜。
使いながら覚えていこうと思います。
【Debian系】dpkgコマンドを使用したパッケージ管理

# 目的
dpkgコマンドを使用したDebianパッケージ管理を覚えたい！

# パッケージとは
Linuxでは、ソフトウェアをパッケージという単位で管理する。
パッケージは関連ファイルを全てまとめたバイナリとして提供される。
そのため、元のプログラムの改変には向いておらず、提供されているものを素早く利用したり、アップデートやインストール後に発生する”管理”を楽にします。

# Linuxのパッケージ
Linuxのパッケージは大きく分けて２種類。
・Debian形式
・RPM形式

今回はDebianパッケージのお勉強をします！

# Debianパッケージ
|方式名|説明|拡張子|
|:--|:--|:--|
|Debian形式|Debian GNU/LinuxやUbuntu等のDebian系ディストリビューションで使用|.deb|

# リポジトリ
|リポジトリ名|説明|
|:--|:--|
|/etc/dpkg/dpkg.cfg|dpkgツールの設定ファイル|


# dpkgコマンド
dpkgコマンドは、Debianパッケージを管理するコマンド。
「d」はDebianの意味。
「pkg」はパッケージの意味。

できることは
・パッケージのインストール
・パッケージの削除
・パッケージのアップデート
・パッケージの情報確認
などなど。

### dpkgコマンドの主なオプション
|オプション|説明|
|:--|:--|
|-i(--install)|パッケージをインストール|
|-r(--remove)|設定ファイルを除くすべてのファイルを削除|
|-P(--purge)|設定ファイルを含むすべてのファイルを削除|
|-l(--list)|インストール済みパッケージの一覧を表示する|
|-L(--listfiles)|指定したパッケージからインストールされたファイル一覧表示|
|-s(--status)|パッケージ情報を表示する|
|-S(--search)|指定したファイルがどのパッケージからインストールされたか表示|
|-C(--audit)|インストールが完了していない(不完全)パッケージの表示|
|-E|同バージョンがインストールされていたらインストールを行わない|
|-G|新バージョンが既にインストールされていればインストールを行わない|
|-R|パッケージファイルを再帰的に検索し、パッケージをまとめてインストール|

※注意すべきオプション「-r」「-P」
2つは設定ファイルを削除するかしないかの違いにあります。
・設定ファイルを残しておき、以前の設定で動作させたい→「-r」
・確実に必要のないパッケージだから消したい→「-P」

# dpkgツールコマンド
|コマンド|説明|
|:--|:--|
|dpkg-reconfigure|インストール済みのパッケージを再設定する|

# 最後に
Debianパッケージの管理コマンド「dpkg」はこれで完璧！？

[apt-getについてまとめたものはこちら](https://qiita.com/tanamoru/items/181285180f53d27ad4d8)
Yahoo!リアルタイム検索を CLI 化

## きっかけ

下記の単なるわがままから CLI を作成することにしました。 

- トレンドを即座に知りたい
- ただ、ブラウザ立ち上げる面倒さや、他の情報が入るのがイヤ
- Colly ライブラリを使ってみたい

↓↓↓↓↓ https://search.yahoo.co.jp/realtime の出力結果

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157574/861c202a-3013-2763-4294-c4e8e5f99617.jpeg">

## まず、スクレイピングしていいか確認

`https://search.yahoo.co.jp/realtime` をスクレイピングしていいのかを確認。

https://search.yahoo.co.jp/robots.txt

```
User-agent: *
Disallow: /assistapi
Disallow: /bin
Disallow: /legacy
Disallow: /language
Disallow: /upyjt
Disallow: /combo
Disallow: /r/
Disallow: /search/psp?
Disallow: /search/msie?
Disallow: /web/save_pref
```

リストにないので、問題なさそうです。

## 該当箇所あたりの HTML 覗く

`https://search.yahoo.co.jp/realtime` にアクセスして、HTML を見ます。

![Screenshot 2023-03-12 at 15.15.02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157574/ec86d852-2806-3a98-9949-2e902445742d.jpeg)

リスト要素を特定できそうな要素を確認していきます。

- `section` タグのクラスに `Trend_container` を含む要素
- `a` タグ に `data-c-params` 属性を持つ要素
- その `a` タグ配下の `h1` のテキスト

が欲しい情報ですね。

## Go で書いてみる

```go
package main

import (
	"fmt"
	"log"

	"github.com/gocolly/colly/v2"
)

type Trend struct {
	Item string
	Link string
}

func main() {
	url := "https://search.yahoo.co.jp/realtime"

	var trends []Trend

	c := colly.NewCollector()

	cssSelector := "section[class^=Trend_container] a[data-cl-params]"
	c.OnHTML(cssSelector, func(e *colly.HTMLElement) {
		trend := Trend{
			Item: e.DOM.Find("h1").Text(),
			Link: e.Attr("href"),
		}
		trends = append(trends, trend)
	})

	c.Visit(url)

	for i := range trends {
		fmt.Println(trends[i].Item, trend[i].Link)
	}
}
```

- `section` タグのクラスに `Trend_container` を含む要素 → `section[class^=Trend_container]`
    - `^` をつけることで、Trend _container で始まる」という意味になる
    - この後ろに続く文字列が変わりそうだったので、変わらなさそうな先頭の一部分だけを指定
- `a` タグ に `data-c-params` 属性を持つ要素 → `a[data-c-params]`
    - 他にも属性はありますが、なんとなくこれを選択
- `section[class^=Trend_container] a[data-cl-params]` と並べることで、`section` タグ配下の `a` タグとしている
- その `a` タグ配下の `h1` のテキスト
    - ここまでくると `h1` は一つしかないので 

あとは go build でバイナリ化すれば、いつでも欲しい情報が取得できます。

## まとめ

思った以上に Colly ライブラリ簡単に使えますね。
欲しい情報が間違いなく取得できるように CSS セレクタ の指定が間違えなければ、ちゃちゃっと作れますね。
gitのcherrypickでマージコミットを選択する方法

# 初めに
今回はgitでcherry-pickをする対象がマージコミットだったときの解決策を紹介します
### 本文
まず、マージコミットをcherry-pickしようとすると下記のようになります
```terminal
git cherry-pick コミットID
error: commit コミットID is a merge but no -m option was given
```
`-m`オプションつけてねと言われるので下記のようにすると成功します
```terminal
git cherry-pick -m 1 コミットID
```
`-m`の後の数字は１から選択可能でこの数字は`git log`をしたときの`merge`ヘッダ表示順になります
### 最後に
下記の記事を参考に書かせていただきました。
https://qiita.com/awakia/items/5fad0c454ddc7b478ff1
自分の備忘録用ではありますが、どなたかのお役に立てれば幸いです
postgres11.3コンテナでリポジトリ迷子になったので対策

# 状況
ある日を境にpostgresコンテナがbuildエラーとなってしまった
# 原因
postgres11のリポジトリの場所が変更になったみたい。
# 対策
```diff_docker
FROM postgres:11.3
+ RUN rm /etc/apt/sources.list.d/pgdg.list
+ RUN echo "deb http://archive.debian.org/debian stretch main contrib non-free" > /etc/apt/sources.list
+ RUN apt-get update && apt-get -y install apt-transport-https
+ RUN echo "deb [ signed-by=/usr/local/share/keyrings/postgres.gpg.asc ] https://apt-archive.postgresql.org/pub/repos/apt/ stretch-pgdg main 11" >/etc/apt/sources.list.d/pgdg.list
RUN apt-get update
RUN apt-get install python3 python3-pip  unzip -y
RUN pip3 install --upgrade pip
- RUN apt-get install pgadmin3 -y
+ RUN apt-get install pgadmin3 -y --allow-unauthenticated
```
# 結び
pgadmin3は推奨しません
docker build時にcmakeでエラー吐かれたときの対策

# 状況
Dockerfileをbuildしようとしたとき、apt-get install の中でcmakeを内包しているところでエラーが出てしまった。
# 環境
NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.3 LTS"
VERSION_ID="18.04"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
# Dockerfile
``` docker
FROM tensorflow/tensorflow:2.6.0-gpu

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    python3-dev \
    python3-pip \
    rm -rf /var/lib/apt/lists/*

ENV TZ Asia/Tokyo

RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
RUN apt-get install kitware-archive-keyring && rm /etc/apt/trusted.gpg.d/kitware.gpg
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6AF7F09730B3F0A4
RUN apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main"
RUN apt-get update
RUN apt-get install -y cmake
```
# 結び
dockerfile難しい
SwiftUIの状態変数とは何か

Rubyから学習を始めた身としては衝撃でした
## ざっくり結論
SwiftUIにおいてビューの状態を保持するために使用される変数
ビュー内で値が変更されると自動的に再描画される

## 解説
https://blog.code-candy.com/swiftui_state/

より引用
>@StateはSwiftUIの大きな特徴であるデータバインディングという仕組みの１つです。
データとViewを紐付けることでデータの更新時に自動的にViewも更新されるという連動的な仕組みがデータバインディングの特徴です。
また、@Stateが付与されたプロパティは”状態変数“とも呼ばれます。

@stateを用いて状態変数を定義することで、その中の値が変わった際に、自動的にviewに反映される

## 使い方
状態変数を`@State`で指定すれば良い
先の引用元にも事例は載っていますが、他にも以下のような使い方が出来る
```.swift
struct ContentView: View {
    //状態変数textを定義
    @State var text = "Hello, World!"
    
    var body: some View {
        VStack {
            Text(text)
                .font(.largeTitle)

            //Buttonを押すことで、テキストメッセージがHello, SwiftUI!に変わる
            Button("Change Text") {
                self.text = "Hello, SwiftUI!"
            }
        }
    }
}
```

```.swift
struct ContentView: View {
    //Boolean型の状態変数isOnを定義
    @State private var isOn = false
    
    var body: some View {
        VStack {
            //isOnがtrueの場合は "ON"、falseの場合は "OFF" と表示
            Text(isOn ? "ON" : "OFF")
                .font(.title)
            //タップされるたびに「isOn」の値が反転、false => true, true => false
            Button("Toggle") {
                self.isOn.toggle()
            }
        }
    }
}
```

## 参照
https://developer.apple.com/documentation/swiftui/state/

https://blog.code-candy.com/swiftui_state/
初めての投稿

<h1>自己紹介</h1>

<p>現在、27歳です。</p>
<p>私は、1月から独学でプログラミングを学習し始めました。<br>昨年まで、小学校教員をしていました。<br>現在は無職で、プログラミングスクールに通っています。</p>
<p>2024年の4月を目処に、就職を目指しています。</p>
<p>現在、ProgateでHTML・CSS・JavaScriptの学習を一通り終えており、実践として既存ホームページの再現コーディングを複数行っています。</p>

<p>まだまだ知識も浅く、上手く情報発信できないとは思いますが<br>
優しい目で見守って頂けると幸いです。よろしくお願いします。</p>

<h1>Qiitaを利用しようと思ったきっかけ</h1>

<p>皆さんの投稿を見て情報を得るだけでなく、自身の情報を発信することで
<br>就職活動のアピールポイントになればと思い、Qiitaを利用し始めました。
<p>また、質問機能があるので
<br>自分で考え、調べてもどうしても分からなかったことについては
<br>こちらで質問させて頂けたらと思います。
</p>

<h1>プログラミングを始めて、感動したこと</h1>

<h2>（1）Emmet機能</h2>

<p>今までは、HTMLに用いるタグなどを全て直接入力していたのですが
<br>VScodeでEmmet機能があるということを知ってから、コーティングがとても快適になりました。
<p>JavaScriptなどでプログラミングを行う際も、これに似た機能を使用できたらいいな、と思うので<br>
VScodeの拡張機能などにそのようなものがないか、調べてみようと思います。</p>

<h2>（2）入力したものが画面に反映される楽しさ</h2>
<p>今までPCで作業をするといったら、WordやExcel、Powerpointなどを操作する程度で
<br>プログラミングとは無縁の生活を送ってきました。</p>
<p>真っ白の状態から、英数字や記号を入力して
<br>PCに指示を出して自分の思った通りの字や色、動きをつくっていくのは
<br>私にはとてもクリエイティブに思えます。
<br>これをずっと続けていられたら、どんなに幸せだろうと感じています。</p>
<p>仕事となると、納期に追われる、クライアントの要望と自分の思いに相違が生じる等の要因があり
<br>なかなか楽しむ余裕がなくなってしまうのだろうとは思うのですが
<br>それでも、私はプログラミングを仕事にしたいと考えています。
</p>

<h1>投稿頻度について</h1>
<p>まずは、週一を目標に投稿していきたいと思います。
<br>投稿するネタを集められるよう、毎日プログラミングの学習や情報収集を行っていけたらと思います。</p>

<p>ご覧いただき、ありがとうございました。</p>

<footer>RYMO</footer>
APIって結局何してるの？

# APIをIT知らない人に説明できないことに気づいた
社内でプログラミング経験があまりない人に対して、Go言語のトレーニングを行えるコンテンツ作成に取り組んでいます。
その中でAPIを作ってもらうのですが、ITについてまだ詳しくない人にAPIをうまく説明できないことに気づきました。
色々と考えてみた結果、APIはSNSでのやり取りに似ているのではないか、と思い記事化してみました。

# なぜAPIが必要なのか？
Wikipedia先生によるとAPIというのは、、、([アプリケーションプログラミングインタフェース](https://ja.wikipedia.org/wiki/アプリケーションプログラミングインタフェース))

> APIは各種システム／サービスがそのシステム／サービスを利用するアプリケーションに対して公開するインタフェースである。

例えば、自作の日記アプリに天気予報機能を実装したい際に、天気予報のアルゴリズムを自分で書くのは大変です。
しかし、自分で天気予報アルゴリズムを書く代わりに、「今日の天気を教えてください」というリクエストを送ったら今日の天気を返してくれる天気予報APIを使えば簡単に天気予報機能を実装できます。

「各種システム/サービス」が「天気予報サービス」で、「利用するアプリケーション」が「自作の日記アプリ」です。
「天気予報サービス」をを利用するために公開しているのが「天気予報API」ということになります。
この天気予報APIは今回のような自作の日記アプリだけではなく、SNSアプリやブログ、研究ログアプリなどでも使用されるかもしれません。

このように、天気予報APIは色々なアプリケーションに対してそのサービスを提供する必要があります。
天気を予測するアルゴリズムをそれらのアプリケーションに組み込むのは現実的ではないため、日記アプリから「今日の天気を教えてください」とうリクエストを天気予報APIに対して送るような形式で天気情報を得ます。


# APIを使うときのイメージ

クライアントとAPIとのやりとりはSNSでのやりとりと似ていて、SNSでのやりとりができるようになる要素を準備してあげるとAPIを作ることができます。

まず、日記アプリは天気を知りたいので、天気に詳しそうな天気予報APIとSNSでつながります。
そして、日記アプリは天気予報APIに「天気を教えて欲しい」とメッセージを送り、天気予報APIは日記アプリに天気を教えます。
天気予報APIは几帳面なので、指定した文章で天気予報をお願いしないと天気を教えてくれません。
そのため、天気予報APIが指定した形式で天気予報の依頼をします。

つまり、まずはやり取りを行うための場(SNSでつながる、通信できるようにする)を作ります。
SNSでつながれば、あとは天気予報APIが答えやすいようにメッセージを送るだけです。
これらのルールを難しく言ったのが、プロトコルとかバリデーションと言ったものになります。

そのため、APIを1から作りたいときは、「APIとクライアントがやりとりを行える場の用意」、「どんな質問が来るのかを想定して、それに沿った回答を用意」するとよいということになります。
これらがHTTP通信だったり、リクエストとレスポンスと呼ばれているものです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045261/bf4c1146-c8e8-4206-82f6-874d334e147e.png)


# まとめ
APIとクライアント(APIを使いたいアプリ)のやり取りは、SNSにおけるやりとりと似ている。
クライアントはまずAPIとやりとりを行うための場に接続する必要がある。
APIは几帳面なので、クライアントはAPIが指定する書式で欲しい情報をリクエストする必要がある。。
APIはクライアントからのリクエストに答えられるように、想定していたリクエストに沿ったレスポンスを返せるように準備しておく。
uniqueな型を作成するutility type (Branded)

## はじめに
idが複数ある時に、型でどのidなのか区別できるようにしたい。
その解決策メモ

## 問題点

```typescript
type PrivateID = string;
type PublicID = string;

const privateID: PrivateID = "1";
const publicID: PrivateID = "1";

const func = (id: PrivateID) => {}
func(publicID) // ok

const PrivateIDArray = [privateID]
PrivateIDArray.includes(publicID) // ok
```

## 解決策
Branded typeを作成
```typescript
type Branded<T, U> = T & { __brand: U }
type PrivateID = Branded<string, "PRIVATE_ID">
type PublicID = Branded<string, "PUBLIC_ID">

const privateID = "1" as PrivateID;
const publicID = "1" as PublicID;

const func = (id: PrivateID) => {}
func(publicID) // error

const PrivateIDArray = [privateID]
PrivateIDArray.includes(publicID) // error
```

## おまけ
```typescript
// 普通に書いても良さそう
type ID = string & "ID"

// リテラル型のみにすると他の型全てと区別できそう (stringやnumberのメソッドが使えなくなる)
type ID = "ID"
const id = 1 as unknown as ID

// 関数
type Branded<T, U> = T & { __brand: U }
const applyBrand = <T, U extends string>(value: T) => {
  return value as Branded<T, U>
}
const id = applyBrand<string, "ID">("1")
```

## 結論
アサーション必須!!?😊
Googleデジタルマーケティング＆Eコマース：キャンペーンのためのソーシャルメディア・プラットフォームを選択する

# はじめに

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

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

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/24ea32fb-2fb3-bdb2-462a-4ffc4d60a96f.png" width="800">

# ソーシャルメディア・プラットフォームを慎重に選択する理由

- 適切なプラットフォームは、ターゲットオーディエンスにリーチするのに役立ちます。製品やサービスに興味を持つ可能性の高い人々が集まるプラットフォームに投稿することで、より多くのトラフィックをウェブサイトに誘導することができます。
- 売上やトラフィックを増やす可能性の高いプラットフォームに集中して時間とお金を費やすことができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/4dbaa796-4dbb-9fbb-3664-dca1ca414c00.png" width="600">

# ソーシャルメディア・プラットフォームを選択するための戦術

### 各プラットフォームの仕組み

それぞれのプラットフォームがどのように機能し、人々がどのようにコミュニケーションしているかを理解するために、時間をかけて勉強してください。

#### Twitter

リアルタイムの情報に重点を置いています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/b4e62189-8b24-dcd3-7a14-ea6294732d9f.png" width="500">

メッセージの文字数も、他の多くのソーシャルメディアとは異なり、文字制限されています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/497591bc-aa93-4d3a-7790-b4479c63bf6b.png" width="500">

そのため、Twitterは速報性を重視し、非常に短いコンテンツを投稿し、リアルタイムで人々と直接対話するのに適しています。

### ターゲットとするオーディエンス

ターゲットとするオーディエンスは、どのソーシャルメディアプラットフォームで最もアクティブに活動しているのでしょうか？ターゲットオーディエンスを定義するために行った調査は、ここでも役に立つはずです。

- **Facebook**は、他のどのプラットフォームよりもアクティブなユーザーを抱えているかもしれません。
- しかし、ターゲット層が25歳以下であれば、**TikTok**のような若い層を取り込むプラットフォームにもっと力を入れた方がいいかもしれません。

### ゴール

ソーシャルメディア・キャンペーンのゴールについて考えてみましょう。あなたのビジネスの全体的なゴールと一致させる必要があります。

- ブランドの認知度を上げたいのか？
- リードを生み出したいのか？
- コミュニティのエンゲージメントを高めたいのか？

プラットフォームによって利点が異なり、これらのゴールを達成するのに適している場合があります。

- **LinkedIn**は、プロフェッショナルが履歴書を掲載し、仕事を探し、専門知識を共有し、互いにネットワークを築くことができるプラットフォームです。ブランドの権威を高めることを目標の1つとする場合、LinkedInを選択することができます。

### 自社

プラットフォームを選ぶ際には、自社についても考慮する必要があります。

- 製品やサービス
- ブランドのアイデンティティ
- ビジネスの種類

など、すべてを考慮して決定する必要があります。

- 美術品販売会社は、**Instagram**のような視覚的なチャンネルに集中するのがよいでしょう。
- 教育用ビデオを制作する企業であれば、**YouTube**のようなビデオベースのプラットフォームを選択することもできます。

### 競合他社

競合他社がどのようなプラットフォームを使っているのかにも注目しましょう。

- 彼らはどこに投稿しているのか？
- 最も多くのエンゲージメントを獲得しているのは、どのようなものでしょうか？

競合他社が特定のチャネルで優れたパフォーマンスを発揮している場合、貴社もそのチャネルで優れたパフォーマンスを発揮する可能性が高くなります。

同様に、競合他社が特定のチャネルでエンゲージメントに問題を抱えている場合、貴社も同じタイプの課題に直面する可能性があります。

### リソース

ソーシャルメディア・マーケティング・キャンペーンは、一種のコミットメントです。時間、お金、エネルギーを投資する必要があります。

- あなたが利用したいすべてのプラットフォームを管理するために利用できる人は何人いますか？
- 各プラットフォームにどれだけの時間を割くことができますか？
- すべてのプラットフォームで広告を出すための予算はどのくらいですか？

企業規模が異なれば、予算やマーケティングチームの規模も異なるでしょう。ですから、ソーシャルメディア・プラットフォームを選択する際に、利用可能なリソースを明確に理解することは有益です。
Adobe Character Animator CCの使い方　【自分で描いた絵を動かしてみた】

どうもYumaです。

Adobeコンプリートプランを購入して一ヶ月ほど経ちました。
PhotoshopとIllustratorを使うために買ったAdobeですが、せっかく買ったのだから違うソフトも使ってみたい。

ということで前々から興味があった**Adobe Character Animator CC**を使ってみました。
先に感想を言うとめちゃ楽しかったです。

この記事では簡単な使い方(顔を作って動かす)を説明していきます。

`2018年に書いた記事のため、一部古い箇所があると思います。最新の使い方をご確認ください。`

## まずはソフトをダウンロード

Character AnimatorはAdobe商品なので購入しないと使用することができません。
もし購入していない場合は購入しましょう。

## Character Animator CCを開く

手に入れたら早速使っていきましょう!
開いた画面はこのようになっています。
![１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280199/9cf5bc2b-4a1b-d1db-4a7f-391451976da8.jpeg)

今回作成するのは顔だけなので赤枠で囲っている所をクリックします。
![２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280199/bbbf885c-254d-ef21-7657-64bafba2eca7.jpeg)


そうすると自動的にPhotoshopへ移動します。
![３.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280199/681d3909-f415-62f0-c787-18208e11bce6.jpeg)

## Photoshop(Illustrator)で絵を描く

無事にPhotoshop(Illustrator)を開いたら、早速絵を描いていきます。
自分が動かしたいキャラクターを作成していきます。
丁寧なことに「目」「口」「輪郭」などのレイヤーと下書きが用意されているので、レイヤー通りに作成していけば楽に作れます。

そして実際に僕が作ったキャラクターはこちら(絵下手なのは無視して下さい...)
作り終えた後は保存をしてPhotoshopを閉じましょう。閉じたらCharacter Animatorの画面に戻り、画面上では先ほど描いた絵が表示されています。
![４.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280199/37c679c9-e926-44e2-9215-a542d71a6621.jpeg)


これで描いた絵が動くまでの準備が完了。
実際に動いている様子がこちら。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Cm36MSPY0Y0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


これにて自分で作った絵を動かす作業は終了です。思ってたより簡単でしたでよね？Adobe製品は偉大です...。

## まとめ

お疲れ様です。
この記事ではCharacter Animatorを使って自分で描いた絵を動かす方法について書きました。
このソフトを使えば作ったキャラクターでyoutubeデビュー、またアニメーションを作ってみたりなど様々なことができます。

~~面白そうなのでyoutuberに挑戦してみようかなと密かに考えております。~~
↑実際にyoutubeに投稿してみたところ、かなり大変だったため諦めました...。
youtuberの方達スゴイ。

では！
nested_attributesを使用したつもりになっていて、 ActiveModel::UnknownAttributeError:が出てしまっていた。

あたりまえなのですが、
`accepts_nested_attributes_for`を使用するときは、モデルに定義してあげないといけません。

本当に当たり前。
ただ、大きなファイルをいじっている時など書いたつもりになっていることがあると思います。

なので、nested_attributesを使う場合などは、
もう一度モデルに

```
accepts_nested_attributes_for :user_profile, allow_destroy: true
```
などが定義されていることを確認してください。
Xcode13からXcode14へのアップグレードに伴う変更点と不具合

# Xcode13からXcode14へのアップグレードに伴う変更点と不具合

Xcode13からXcode14へのアップグレードに伴って、以下のような変更点や不具合が確認されています。

## 不具合

- ビルド時に「Segmentation fault: 11」というエラーが発生することがあります。この場合、プロジェクトをクリーンしてから再ビルドすることで解決する場合があります。
- ビルド時に「fatal error: 'XXX.h' file not found」というエラーが発生することがあります。この場合、ヘッダーファイルが正しくインポートされているかを確認する必要があります。
- ビルド時に「No such module 'XXX'」というエラーが発生することがあります。この場合、プロジェクトの設定を確認して、必要なフレームワークが正しく追加されているかを確認する必要があります。

## 変更点

- Xcode14では、Swiftのバージョンが5.5にアップデートされています。
- Xcode14では、シミュレータの性能が向上しています。
- Xcode14では、ビルド時のパフォーマンスが向上しています。

以上が、Xcode13からXcode14へのアップグレードに伴う変更点と不具合の一部です。アップグレード前には、事前にバックアップを取ることをおすすめします。