OmniAICreator/Qiita-1.07M huggingface dataset:
Dockerのメモ

## 想定読者
- Docker、名前だけ聞いたことある
- コンテナ、箱？
- クジラのマーク見たことある
- etc


## Dockerとは

https://ja.wikipedia.org/wiki/Docker

、、開発~リリースまでの効率を上げるものなのは分かった。

**コンテナ仮想化**がキーワードであり、核技術らしい。


参考記事を読んで、まとめると以下。

- ゲストOS不要
- 早い
- コピーが可能なため、新たな環境構築が楽。
- 複数のコンテナを管理する連携ツールは、**Kubernetes**

参考

https://www.mtioutput.com/entry/it/whatis-docker

https://www.dx-digital-business-sherpa.jp/blog/containerized-virtualization#:~:text=%E4%BB%AE%E6%83%B3%E5%8C%96%E6%8A%80%E8%A1%93%E3%81%AE1,%E5%BF%85%E8%A6%81%E3%81%A8%E3%81%97%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82


## いざ入門

案ずるより売るが易し秋元、という事でget started

https://chigusa-web.com/blog/windows%E3%81%ABdocker%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6python%E7%92%B0%E5%A2%83%E3%82%92%E6%A7%8B%E7%AF%89/


フォルダの共有の部分だけうまく動かなかった。

windows側とコンテナ側でフォルダの共有が可能。


https://and-engineer.com/articles/YaSPjRIAACAAkhMI


なるほど、簡単に仮想環境を構築することが出来る！(今更)

docker hub からmysql, ubuntu等の環境を手軽にインストールできる!


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/1c9e91f5-ec30-c182-48ed-4f5fc8fbfe3c.png)


## 次やる

日本語→英語見る

https://youtu.be/lZD1MIHwMBY

https://youtu.be/3c-iBn73dDE
Tomcatをコマンドラインで操作するのに必要なこと

主にホットリロード目的。
大抵のサイトには

```
http://localhost:8080/manager/text/relaod?path=<your_path>
```

を叩けと書いてあります。ちなみにGETです。
Basic認証がかかっているなら

```
curl -XGET -u <user>:<password> http://localhost:8080/manager/text/relaod?path=<your_path>
```

こんな感じです。
しかし私の場合403になってしまい、なぜ…と思っていたら tomcat-users.xml にユーザーの追加が必要でした。

```
<role rolename="manager-script"/>
<user password="<password>" roles="manager-script" username="<username>"/>
```

こんな具合に。
manager-guiのロールがいるならそれとは別に記載する必要がありますよ。
言語の壁を打ち破る：GPT with 多言語インデックス

## この記事を読むと嬉しいこと

言語の壁を越えた、グローバルAIを作れます！
= GPTに英語と日本語、中国語、フランス語…の情報をまとめてインプットし、質問に答えさせることが出来ます！

```python

"""「Harry Potter（英語）」と「ぼっち・ざ・ろっく！」の情報をまとめて与えた後で質問をした時の回答"""

# before
index.query("ハリーの学校では、何を教えている？日本語で答えて")
# -> ハリーの学校では、何を教えているかは不明です。

# after
index.query("ハリーの学校では、何を教えている？日本語で答えて")
# -> ハリーの学校では、魔法と魔法使いの学問を教えています。


```

## 背景・課題

今大人気のGPTに、外部情報を繋ぐ[GPT Index](https://github.com/jerryjliu/gpt_index)が物凄い勢いで使われています。一方で、この仕組みを無邪気に使おうとすると、OpenAIに課金しまくることになり、お財布が。。

https://github.com/jerryjliu/gpt_index

その解決策として、[oshizoさん](https://note.com/oshizo/n/n137aaa2c29d4)、[npakaさん](https://note.com/npaka/n/nee11eb7e620e)がインデックス作成をローカルで行うことで、課金を抑える方法を公開してくださっています。この方法は非常に有益なのですが、日本語特化モデルのため、言語が異なる場合はインデックスも異なるつくりになってしまいます。例えば、英語文献Indexに対して日本語で質問（あるいはその逆）をしても、適切に答えが返せません。

日本語情報は、インターネット全体の中で3%を切ると言われています。英語に恨みはありませんが、AIに教えを乞うために英語を勉強するというのは、[我々の思い描いた未来](https://ja.wikipedia.org/wiki/%E3%81%BB%E3%82%93%E3%82%84%E3%81%8F%E3%82%B3%E3%83%B3%E3%83%8B%E3%83%A3%E3%82%AF)とは異なります。


## やり方

[PullRequest](https://github.com/hwchase17/langchain/pull/796)通しておいたので、誰でも、すぐに使えます！

https://github.com/yakigac/universal_sentence_encoder_gpt_index/blob/main/test_use_for_gpt_index.ipynb
```python
import os
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

from langchain.embeddings import TensorflowHubEmbeddings
from gpt_index import LangchainEmbedding, GPTSimpleVectorIndex, SimpleDirectoryReader, PromptHelper

# 埋め込みモデルの準備
embed_model = LangchainEmbedding(TensorflowHubEmbeddings())


# インデックスの作成
documents = SimpleDirectoryReader('data').load_data()

index = GPTSimpleVectorIndex(
    documents=documents,
    prompt_helper=PromptHelper(
        max_input_size=4000,  # LLM入力の最大トークン数
        num_output=256,  # LLM出力のトークン数
        chunk_size_limit=500,  # チャンクのトークン数
        max_chunk_overlap=0,  # チャンクオーバーラップの最大トークン数
        separator="。"  # セパレータ
    ),
    embed_model=embed_model  # 埋め込みモデル
)

print(index.query("ハリーの学校では、何を教えている？日本語で答えて"))

```

## （興味ある人用）どうやって解決したのか？

GPT Indexから、GoogleがTensorflowHubで公開しているモデル郡を使えるようにしました。その中でデフォルトに設定している[universal-sentence-encoder-multilingual](https://tfhub.dev/google/universal-sentence-encoder-multilingual/3)モデルは複数の言語（なんと16言語！）において、同じ意味の言葉が同じベクトルになるように訓練されたモデルです。

GPT Indexでは、人間が辞書やグーグル検索でそれっぽい話を探しながら読むのと同じように、
1. 文章の塊ごとに意味ベクトルを計算しておき
1. 質問から作ったベクトルに一番近いベクトルを探し
1. その文章の塊をGPT等に補足情報として与えて質問に答える

ということをしています。そのため、目的に応じたモデルを与えてあげることで検索がしやすくなり、冒頭の結果を出すことができるようになっています。（なので私がやったことは、ただ凄い人の成果と別の凄い人の成果を繋いだだけなのでした。）

最後まで読んでいただき、ありがとうございました！
Salescloud Consultant 学習メモ①

<h4>１．セキュリティー</h4>
<strong>組織の共有設定</strong>: 所有しないレコードへの基本的なアクセスレベルを決める設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/1cce9d5e-016a-0683-49fa-2bf63d20169a.png)
デフォルト内部アクセス権：社内ユーザのアクセス権限
デフォルト外部アクセス権：顧客、パートナーのアクセス権限

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/be9937f6-392c-6910-cfe8-85843e088fcc.png)


<strong>ロール階層</strong>：上司と部下の関係ー上司と部下の階層を構築し、上司が部下のアクセス権を継承
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/9f76cebe-c900-441f-73ef-f58e1f66fdcc.png)

<strong>共有ルール（所有者ベース）</strong>：部門、特定のグループ間でレコードのアクセスを拡張する
<strong>共有ルール（条件ベース）</strong>：条件に一致するレコードを対象に特定ロールやグループにアクセス権を拡張
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/3426a719-bb57-422a-c62a-5119b425dce9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/ab72e005-af28-8c5b-cbe7-131f2d1cf17a.png)


<strong>手動共有</strong>：レコードの所有者が自由にアクセス権を拡張



<strong>チーム（取引先、商談）</strong>：レコード所有者に関連する固定メンバーに自動的にアクセス権を付与する

GDPR：個人データ保護に関する法律
GDPRに重点を置きたい
→組織の共有設定を非公開


<h4>2．レコードタイプ</h4>
ビジネスプロセス（進捗管理）
リード　→　リードプロセス
商談　→　セールスプロセス
ケース　→　サポートプロセス

ビジネスプロセス作成（先）ー＞レコードタイプ作成（後）

<h4>3．自動化</h4>
ワークフローとプロセスビルダーのアクション

・ワークフロー：ToDo、メールアラート、項目自動更新、アウトバウンドメッセージ
・プロセスビルダー：レコード作成・更新、メール送信、Chatter投稿、カスタム通知送信、アクションの使用、承認申請、フローの起動、Apexの呼び出し、Quipの更新

割り当てルール→リード、ケースのみ


<h4>4.承認プロセス</h4>
各レコードに関する承認処理を自動化
複数ステップを登録し、条件によって異なる承認者設定が可能

<h4>5.メールテンプレート</h4>
Classicメールテンプレート：自動化で使われるメールテンプレート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/a9a492b3-af40-190c-fd84-b26073cec638.png)

Lightningメールテンプレート：ユーザが個人で使うメールテンプレート
プログラミング初心者向けのインプットとアウトプットの話

プログラミング初心者の方に向けて、今回は学習の方法について書いていこうと思います。

## はじめに

**「早くプログラミングできるようになりたい...」**

と思っている初心者の方は多いです。
私も新人1年目の頃は、もっとできるようになりたいと思いながらプログラミングをしていました。
今思い返すと、もっと早く身に付けることができたと思っています。

というのも、学習のスタイル自体が未熟だったからです。。
学習のスタイルで習得の速さは、変わります。
なので、今回は初心者向けの学習のためにインプットとアウトプットについて書いています。

ちなみに、インプットとアウトプットの割合は、3:7くらいです。
アウトプットのほうが大事です。
しかし、インプットもちゃんとしていく必要があります。

では、本編です。

## インプットとアウトプットの割合は、3:7

**インプットとアウトプットの割合は、アウトプットのほうが大きいです。**

「ゴンドラ猫」という実験を知っているでしょうか？
詳しくは割愛しますが、自らが動くことで認識や理解ができるようになるお話です。
つまり、アウトプットすることが、脳の理解に繋がっています。

プログラミングの本を読んだり、動画を見るのも当然大事です。
しかし、**実際にコードを書いて動かしてみることほど自分の成長になることはありません。**

### 毎日インプットの時間を作ること

1時間でも良いです。
まず、毎日インプットの時間を作りましょう。

アウトプットが大事と紹介してきましたが、そもそもインプットをしなければアウトプットはできません。
そして、最初慣れないうちは、どうしてもインプットからも距離を取ってしまいます。

なので、まずは毎日インプットの時間を作ることが、最初にやるべきステップです。
たとえ、わからなかったり、内容が頭に入ってこなくても毎日やっていると、だんだんと分かるようになってきます。
**毎日1時間インプットしていると、1週間もするとかなり感覚が変わってきます。**

### おすすめのインプットはYouTube

YouTubeをオススメします。
最初だけですがね...（笑）

やはり慣れていない間は、本や記事を読むよりもYouTubeのような動画で勉強するほうが、ハードルが低いです。
**ある程度コードを見るのに慣れてきたら、本のほうが良いです。**
その時その時に合わせて必要な情報を調べやすいですし、参考になるところを見ながらコードを書けますからね。

### さいごに

まとめると、

:::note info
* インプットとアウトプットの割合は、3:7
* アウトプットが、一番の理解になる
* インプットは、毎日1時間は作る
:::

毎日やると、習得も早いですよ。
タスクをたくさん定義して作業を効率化させてみるぞい！

# はじめに

**package.json**の**scripts**にスクリプトを設定してVSCodeで実行するみたいに、Android Studioでも特定の処理をスクリプトとしてまとめたい！

そんなときに、**build.gradle**にはタスクという機能があることを知りました。

今回は、Ktorプロジェクトの**build.gradle.kts**にタスクを定義した時の内容を忘備録としてまとめました。

# 実行するロジックの定義

**scripts**パッケージに、ファイルを作成します。名前は**InsertUserTask.kt**にしましょう。

そして、ファイル内で`main()`を定義して、実行したロジックを記述します。
もちろん、プロジェクト内の他のクラスにもアクセス可能です。

ここでは、`infrastructure`パッケージからデータベース関連のクラスを取得しています。

```kotlin
@file:JvmName("InsertUserTask")

package com.takagimeow.myapplication.scripts

import com.takagimeow.myapplication.infrastructure.database.dao.DatabaseFactory
import com.takagimeow.myapplication.infrastructure.database.dao.impl.UserDAOFacadeImpl
import org.mindrot.jbcrypt.BCrypt

suspend fun main(args: Array<String>) {
    val dbUsername = "..."
    val dbPassword = "..."
    val email = "..."
    val password = "..."
    val name = "..."
    DatabaseFactory.init(
        user = dbUsername,
        password = dbPassword
    )
    val dao = UserDAOFacadeImpl()
    val hashed = BCrypt.hashpw(password, BCrypt.gensalt())
    dao.addNewUser(
        email,
        hashed,
        name,
    )
}
```

# タスクの定義

**build.gradle.kts**にて、`tasks.register()`を呼び出して、タスクを定義します。第一引数にはタスク名。第二引数には`JavaExec::class`を渡します。これにより、`register()`に渡したラムダで受け取れる`this`は`JavaExec::class`型を表します。

```kotlin
tasks.register("InsertUserTask", JavaExec::class) {
    main = "com.takagimeow.myapplication.scripts.InsertUserTask"
    classpath = sourceSets["main"].runtimeClasspath
}
```

## java.lang.ClassNotFoundExceptionエラーが出る場合

次のようなエラーが出る場合があります。

```shell
> Task :InsertUserTask FAILED
エラー: メイン・クラスcom.takagimeow.myapplication.scripts.InsertUserTaskを検出およびロードできませんでした
原因: java.lang.ClassNotFoundException: com.takagimeow.myapplication.scripts.InsertUserTask
```

ネット上の記事を探すと、**build.gradle**での定義方法がたくさん掲載されていて、`classpath = sourceSets.main.runtimeClasspath`で`classpath`を設定するようにしていますが、**build.gradle.kts**ではできません。

**build.gradle.kts**では、`classpath = sourceSets["main"].runtimeClasspath`で　`classpath`に対して設定を行います。

私の場合は、`sourceSets["main"].runtimeClasspath`を使わなかった場合に上記のエラーが発生しました。

# 実行方法

IntelliJ IDEAの**gradle**ウィンドウを開きます。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/b062455c-2059-aaf7-ebb7-30f67a742a33.png)

再生ボタンのようなアイコンをクリックします。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/baf6b6e1-cf93-06d8-c8ae-9898cbe8b8b6.png)

自分が定義したタスク名をクリックして、タスクを実行します。

コンソールから実行する場合は`./gradlew`を使います。

```shell
$ ./gradlew HelloTask
```

# まとめ

Kotlinでスクリプト感覚でデータベースへのシード処理などをかけるのはとても便利ですね！
それ専用にプロジェクトを作成したりなどしなくても良いので、積極的にタスクを定義していこうと思います。


# 参考にした記事

https://stackoverflow.com/questions/51810254/execute-javaexec-task-using-gradle-kotlin-dsl

http://gradle.monochromeroad.com/docs/userguide/tutorial_using_tasks.html

https://stackoverflow.com/questions/39576170/proper-way-to-run-kotlin-application-from-gradle-task

https://nnao45.hatenadiary.com/entry/2019/12/09/104542

http://gradle.monochromeroad.com/docs/userguide/custom_tasks.html

https://takusan.negitoro.dev/posts/android_gradle_to_kts/
最近のイラスト系画像生成AI調べてみた


こちらのきじを読んだ

https://taron88wordpress.net/2023/01/08/stable-diffusionmodel/


漫画に使えそうなモデル

実写系
- 公式配布モデルの**stable-diffusion-2-1**はグレースケールしたら背景の生成が手早く出来そう

イラスト系
- 適性が高いモデルは倫理的にグレーなのが多い....!
    - NovelAIは有料なので、**Waifu Diffusion**を使ってキャラクターの生成が出来そう。



ひとまず公式配布のSDとWDを動かしてみます。


追記それより先にDreamBooth動かしてみます


## DreamBooth調べた


参考リンク

こちらの記事を参考にgoogle colabで動かしてみた。

http://cedro3.com/ai/dream-booth/








InstanceとClass Promptの調整はこちらを参考に

https://dolls.tokyo/about_breambooth_instanceprompt/
UnityでPlayModeTestを導入したらVS上でのみエラー

一人で数時間結構ハマってしまったのでメモ。

# 概要
- UnityでPlayModeのテストを書いた
- Unity上では実行可能で正常にテストできた
- VisualStudio上では[UnityTest]のAttributeが見つからないエラー

# 結論
Unity上で以下を実行でエラーが消えた

- Edit >
    - Preferences >
        - ExternalTools >
            - Regenerate Project files

要はUnityから外部ツールに渡しているファイル(参照?)に漏れがあった？ということと理解。UnityとVisualStudioで挙動に差が見られた場合はこれを一度やってみると良いのかもしれない。

# 現象

- EditModeの`[Test]`は問題なかった。
- PlayModeの`[UnityTest]`で以下のエラーがでた

```
型または名前空間の名前 'UnityTestAttribute' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)
```

# やったこと

以下ハマったログなので、役には立たないメモ。いつかまた新しいprojectを作ってハマるであろう自分の為に推論過程をメモ。

- 最初はVisualStudioのパッケージ(?)の問題かとおもい、VisualStudioからNuGetで何かインストールすんのかと思って調べていた。
- `[UnityTest]`は`[Test]`と同じく、`using NUnit.Framework`由来かと思ったが、ドキュメントを追うと、`using UnityEngine.TestTools` の方から来てるらしい (多分)
- NUnitは参照できてる。using時点でエラーは出ていない。ならVisualStudioではなくUnityの方の問題では？
- アセンブリ参照とやらを調べた結果以下の記事にたどり着く
    - [Unityでアセンブリ参照の仕方が分からない](https://teratail.com/questions/302850)
    - (まじ神。ありがとうございますmm)
- 記事の通り、`Regenerate Project files`して VisualStudioを再読み込みでエラーが消えた。

# 所管
- モックだからと言い聞かせていたが、いい加減コード量が増えてきたのでテストをちゃんとすることにした
- Unity独学で進めているけど、開発に戸惑う時間が多い
- 聞ける人を得るためにも、企業かチームに属するべきか。。。
新卒2年目エンジニアが設計の入門書を3冊読んでみた

# はじめに

僕はWebアプリケーションエンジニアとして新卒入社してからもうすぐ2年になります。フロントエンドやバックエンドの開発経験を通じて、求められた要件を満たす実装はある程度できるようになってきました。ですが、それが **良い設計** かどうかはまだ自分だけでは判断できない部分があり、課題に感じていました。以前「オブジェクト指向設計実践ガイド」を読んだことがあるのですが、途中で断念し、設計に対して苦手意識がありました。そこで、もしかしたら前提となる背景や知識が足りないのでは？と思い、もっと基礎的な「設計の入門書」を読んでみることにしました。

実際に読んだのは以下の3冊です。

- リーダブルコード
- プリンシプルオブプログラミング
- 良いコード/悪いコードで学ぶ設計入門

これらの本を読むことで、良い設計・良いコードとは何なのか、そしてそれを実現するためには何を意識する必要があるかといった設計の入門的な重要な概念について学ぶことができたので紹介します。それぞれの本について、概要と感想を少しずつ書いていきます。

# 1. リーダブルコード

https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655

この本はエンジニアなら一度は聞いたことがあるであろうくらい有名な本だと思います。僕が通っていた大学の研究室にも置いてあり、少し読んだことはありましたが、全部通して読んだことはなかったので、これを機に読んでみました。

この本のテーマは本のタイトルの通り、「読みやすいコード」です。変数名の付け方や、ロジックの書き方、データ構造など、どうしたら読みやすくなるのかそれぞれ書かれています。サンプルコードなどもわかりやすく、読みやすい本だと思いました。また、仕事で開発をするようになった今だからこそ「読みやすいコード」の重要性が共感でき、とても参考になりました。

1.5 節のタイトル「でもやるんだよ」がお気に入りです。

# 2. プリンシプルオブプログラミング

https://www.amazon.co.jp/%E3%83%97%E3%83%AA%E3%83%B3%E3%82%B7%E3%83%97%E3%83%AB-%E3%82%AA%E3%83%96-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B03%E5%B9%B4%E7%9B%AE%E3%81%BE%E3%81%A7%E3%81%AB%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%91%E3%81%9F%E3%81%84%E4%B8%80%E7%94%9F%E5%BD%B9%E7%AB%8B%E3%81%A4101%E3%81%AE%E5%8E%9F%E7%90%86%E5%8E%9F%E5%89%87-%E4%B8%8A%E7%94%B0-%E5%8B%B2/dp/4798046140

この本のサブタイトルは「3年目までに身につけたい一生役立つ101の原理原則」となっており、もうすぐ3年目になる自分にぴったりだと思い、読んでみることにしました。この本はプログラミングにおいて重要な様々な原則（プリンシプル）について、それはどんな原則か、なぜ必要なのか、どうすればそれをじつげんできるのか、をそれぞれ簡潔に記載されている本です。DRYのような有名な原則から、UNIX思考、プログラマの3大美徳など、様々な原則が書かれています。

まだ一通り軽く読んだだけなので、これからまた少しずつ読み返し、普段の開発業務に活かしていけるようになりたいと思いました。

# 3. 良いコード/悪いコードで学ぶ設計入門

https://www.amazon.co.jp/%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89-%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80-%E2%80%95%E4%BF%9D%E5%AE%88%E3%81%97%E3%82%84%E3%81%99%E3%81%84-%E6%88%90%E9%95%B7%E3%81%97%E7%B6%9A%E3%81%91%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-%E4%BB%99%E5%A1%B2/dp/4297127830

最後に読んだのは「ミノ駆動本」とも呼ばれるこの本です。著者は Qiita でも有名な ミノ駆動さん(`@MinoDriven`) です。悪いコードがどんな悪影響を及ぼし、それを防ぐためにどうすればいいか、Javaで書かれたサンプルコードを中心に書かれている本です。

ミノ駆動さんの Twitter で投稿されている「クソコード動画」シリーズの解説が途中で出てきたり、クラスの例として「魔法によるヒットポイント回復をカプセル化したクラス」のようなゲームを題材とした説明が書かれていて、わかりやすく、読んでいて楽しかったです。

https://twitter.com/MinoDriven/status/1380773721032433674

# おわりに

3冊を読み、コードの読みやすさ、変更しやすさなど、チーム開発での重要さを改めてすることができました。これから「読みやすい」「変更しやすい」コードを書くためのより具体的なテクニックとして、「オブジェクト指向設計」や「ドメイン駆動設計」、「クリーンアーキテクチャ」等を学んでいきたいと思います。

また、今回紹介した3冊は、僕のように「いきなりオブジェクト指向実践ガイドは難しい...」という方でも読みやすく、さらにそこから発展していけると思うので、これから設計の勉強をしていきたいと考えている方におすすめしたいです。
【Linux】一度に複数のファイルを作成する方法


## 複数ファイルを扱う方法
以下のように`{}`で括り、`,`で区切ることで複数ファイルを扱うことができます。
```
{file1,file2}
```

### `touch`コマンド
```
$ touch {index.html,style.css}
```

### `mkdir`コマンド
```
$ mkdir {dir1,dir2}
$ touch {dir1/index.html,dir2/style.css}
```
Lottie-iOS 4.0.0以降でアニメーションがうまく表示されない時の対処法

## この記事を書くきっかけ
先日、Lottieで3Dレイヤーを含むアニメーションファイルに対応したPRがマージされており、ちょうど3Dレイヤーを含むアニメーションを使用したいためアップデートを行いました。
アップデート後にアニメーションを確認してみると、一部のアニメーションで座標がずれたり、レイヤーの色が真っ黒になってしまうなどの問題がありLottieのissueや検証などを含め解決法を模索しました。

https://github.com/airbnb/lottie-ios/pull/1930
## Lottie-iOS 4.0.0の主な変更内容
- Lottie 3.4.0 から対応されているCore Animationがデフォルトで有効になる
- RenderingEngineOptionのデフォルト値が`.automatic`になる
- DecodingStrategy.dictionaryBasedがデフォルトで有効になる
- AppleのフレームワークとのコンフリクトがあるためAnimationViewなどがRenameされている
- BackgroundBehaviorのデフォルトが`pause` ではなく `.pauseAndRestore`に変更されている
- dotLottieのファイル形式をサポート

https://github.com/airbnb/lottie-ios/releases/tag/4.0.0
## 結局何が原因だったのか
直接的な原因としては2つめの変更点である
**RenderingEngineOptionのデフォルト値が.automaticになる**という部分が原因でした。
元々のデフォルト値は`.mainThread`だったので`.automatic`になり内部的に`.coreAnimation`が選択されてしまっているようでした。

ちなみに`.automatic`の挙動についてはCoreAnimationに対応しているJsonかどうかで決まっているようです。
```swift
public init(
    renderingEngine: RenderingEngineOption = .automatic, // ここが該当部分
    decodingStrategy: DecodingStrategy = .dictionaryBased,
    colorSpace: CGColorSpace = CGColorSpaceCreateDeviceRGB())
  {
    self.renderingEngine = renderingEngine
    self.decodingStrategy = decodingStrategy
    self.colorSpace = colorSpace
  }
```
## 解決方法
一番簡単な解決方法はinitで`renderingEngine`を`.mainThread`に変更する方法です。
（ちなみに公式もmainThreadに指定する解決方法を提案していました。)

```swift
let animationView = LottieAnimationView(configuration: .init(renderingEngine: .mainThread))
```
LottieAnimationViewを生成する際にconfigurationを指定します。
現状はconfigurationがletのため変更できずinitの際に指定する方法が一番妥当だと思いました。

#### Xibで使っている場合の対処法
LottieAnimationViewをXibで作っている場合は、現状のAnimationViewをUIViewに変更しそのViewに対してLottieAnimationViewをaddSubviewするのが手っ取り早いと思います。

複数画面の場合は大変だと思うので、今回のように3Dレイヤーを含むアニメーションを使いたいなど、特にこだわりがなければ4.0.0以前のバージョンを使うのが良さそうです。


## 参考文献
- Lottie-iOS Release 4.0.0
https://github.com/airbnb/lottie-ios/releases/tag/4.0.0
- Animation looks differently with different rendering mode #1876
https://github.com/airbnb/lottie-ios/issues/1876
Nuxt3 .envで環境変数を設定

# はじめに
フロントエンドでも実行環境に応じて設定値を変えたい場合があります。
例えば、よくあるのがAPIのオリジンです。
APIのオリジンを本番環境では`https://api.XXX.com`、開発環境では`http://localhost:8080`にしたい場合です。
Nuxt3では設定情報をpublic/privateで区別し、privateな設定はサーバーサイドでのみ参照可能となるセキュリティ面も配慮されています。

# 概要
`.env`に環境変数を定義して、`nuxt.config.ts`で読み込み、`useRuntimeConfig()`や`$config`で参照するイメージです。

# 手順
## 1. `.env`の設置
Nuxt3のプロジェクトルート直下に`.env`を設置します。
環境変数を定義する場合は`NUXT_`または`NITRO_`のプレフィックスをつけてください。
```.env
NUXT_API_KEY=XXXX1234
NUXT_PUBLIC_API_URL=http://localhost:8080
```

## 2. runtimeConfig(環境変数の読み込み)設定
`nuxt.config.ts`にて`runtimeConfig`ブロックを定義します。

```ts:nuxt.config.ts
export default defineNuxtConfig({

    runtimeConfig: {
        apiKey: '',
        public: {
            apiUrl: '',
        }
    },

});
```

### privateとpublic
private：`runtimeConfig`直下に定義した場合は、サーバーサイドからのみ参照できます。
public：`public`ブロック内で定義した場合は、サーバーサイド、クライアントサイド双方から参照可能です。

### .envとの関連(dotenvサポート)
`.env`で`NUXT_API_KEY`と定義している場合、`runtimeConfig.apiKey`は上書きされます。
`.env`で`NUXT_PUBLIC_API_URL`と定義している場合、`runtimeConfig.public.apiUrl`は上書きされます。
ただし、dotenvサポートが有効なのはビルド時のみなのでご注意ください。

## 3. コンポーネント側で呼び出す

Nuxtが提供するuseRuntimeConfig Composableを利用して、Runtime Configを取得します。
Nuxt3のAuto Importの対象なのでimport文の記述は不要です。

```js
const runtimeConfig = useRuntimeConfig();

console.log(runtimeConfig.apiKey); // 結果： XXXX1234
console.log(runtimeConfig.public.apiUrl); // 結果： http://localhost:8080
```

なお、publicに定義した設定については`this.$config.public`でも参照可能です。

# さいごに
環境変数の定義を必要とする場面は多いと思います。
SSRができるNuxt3ならではの注意点もありますが、publicとprivateを上手く使い分けてもらえたらと思います。

# 参考
- [Runtime Config](https://nuxt.com/docs/guide/going-further/runtime-config)
- [Nuxt3入門(第5回) - アプリケーションの設定情報を管理する](https://developer.mamezou-tech.com/nuxt/nuxt3-app-configuration/)
- [Nuxt3のruntimeConfigで環境変数を設定する](https://debug-life.net/entry/4140)
nginx起動時に転送先が名前解決できなくてもエラーにしない方法

# 概要
nginxは、起動時に転送先の名前解決を行います。
名前解決ができない場合、正常に起動しません。

しかし、proxy_passが複数設定されている場合、そのうちの1つでも名前解決できない（起動していない）とnginxが起動しないのは不便です。
locationの書き方を工夫することで、この状況を回避することができます。

# 回避方法
## 変数を使用する
proxy_passで設定する値に変数を使用します。
これにより、nginxは起動時に名前解決を行いません。

## resolverを使用する
変数を使用する場合、resolverの使用も必要になります。

dockerの場合、resolverの値は
`127.0.0.11`
です。

GKEの場合は
`kube-dns.kube-system.svc.cluster.local`
です。

## 記述例

```
 location /myservice-1 {
    resolver kube-dns.kube-system.svc.cluster.local;
    set $path http://myservice-1.namespace.svc.cluster.local:8888; 
    proxy_pass $path;     
 }
```

# 参考
https://sandro-keil.de/blog/let-nginx-start-if-upstream-host-is-unavailable-or-down/
https://serverfault.com/questions/876308/kubernetes-dns-resolver-in-nginx
https://www.nginx.com/blog/dns-service-discovery-nginx-plus/
Java 基礎知識① オブジェクト指向と変数宣言(データ型)について

## Javaとは
サーバーサイド言語の一つで、大規模開発に使用されることが多い言語です。
オブジェクト指向に対応している言語であり、プログラミングの基礎が詰め込まれた言語になります。

## オブジェクト指向とは
簡単にいうとソースコードを部品化して、プログラムを組み立てやすくする考え方です。
Javaでは機能ごとのソースコードをクラスごとに分けて、実装や保守などをしやすくなります。
大規模開発では必須の開発方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/f998ec95-7eba-4bcf-6570-477e658cc3c2.png)
この画像では、剣、敵、銃を部品化してクラス別のファイルで管理をしています。
こうすることで、例えば剣の攻撃力を上げる修正が入っても、剣クラスの内容だけ修正すれば良いので管理もしやすくなりますし、実装もしやすくなるのです。




## Javaプログラムの基本構造
Javaプログラムを動かすMainクラスは以下のようになります。

```Main.java
public class Main{
  public static void main(String[] args){
    System.out.println("hello!");
  }
}
```
出力結果
```
hello!
```
このような感じです。

## Javaの変数宣言方法とデータ型
Javaの変数の宣言方法と使用頻度は以下の表にまとめました。

|分類|型名|格納するデータ|変数宣言の例|利用頻度|
|:--:|:---:|:--:|:---:|:---:|
|整数|byte|とても小さな整数|byte glasses(所持するメガネの本数)|△|
|整数|short|小さな整数|short age(年齢)|△|
|整数|int|普通の整数|int salary(給与額)|◎|
|整数|long|大きな整数|long worldPeople(世界の人口)|△|
|少数|float|少しあいまいでもよい少数|float weight(体重)|△|
|少数|double|普通の少数|double pi(円周率)|○|
|真偽値|boolean|trueかfalse|boolean isError(エラーか否か)|○|
|文字|char|1つの文字|char initial(イニシャル1文字)|△|
|文字列|String|文字の並び|String name(自分の名前)|◎|

この中でもよく使うのが、int型、String型。
この二つを覚えておけばどうにかなる。
宣言方法は以下のような感じ。
```java
int age = 11;
String name = "sato"
```
このような感じで変数は宣言をします。
画像から動画を生成 OpenCV


```python
import sys
import cv2
import os

video_dir = "videos"
video_list = os.listdir(video_dir)

codec = cv2.VideoWriter_fourcc(*'mp4v')
# video = cv2.VideoWriter(filepath, codec, CLIP_FPS, (w, h))
# encoder(for mp4)
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
# output file name, encoder, fps, size(fit to image size)
out_file_name = 'video.mp4'
video = cv2.VideoWriter(out_file_name,fourcc, 20.0, (1280, 720))


for frame in video_list:
    # hoge0000.png, hoge0001.png,..., hoge0090.png
    img = cv2.imread(os.path.join(video_dir,frame))

    # can't read image, escape
    if img is None:
        print("can't read")
        break

    # add
    video.write(img)

video.release()
print('written')
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

機械学習、ARアプリ（Web/iOS）を作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
Ruby12

# 問題
ターミナルから数字を入力して、数字に応じて以下のように出力するプログラムを書いてください。

・10以下なら10以下の数字です
・10より大きい数値なら10より大きい数字です
・10以下でかつ0以下なら0以下の数字です

```Ruby:雛形（ソースコードを追記すること）
input = gets.to_i
```

<br>
<br>
<br>

# 模範解答

```Ruby:模範解答
input = gets.to_i

if input <= 0
  puts "0以下の数字です"
elsif input <= 10
  puts "10以下の数字です"
else
  puts "10より大きい数字です"
end
```

# 【解説】
### ①ターミナルから数値を入力する書き方
ターミナルから数値を入力するにはgetsというメソッドを使います。
このgetsメソッドを使って入力した値は全て文字列になるため、getsの値をto_iメソッドを使って数値に変換します。

### ②条件分岐の書き方
条件分岐はif文を使います。今回は3つのパターンで分岐するためelsifとelseも使います。

```Ruby:記述例
if 条件1
  # 条件1のときの処理
elsif 条件2
  # 条件2のときの処理
else
  # 条件3のときの処理
end
```

今回の条件は数値の比較です。比較には<や==などの比較演算子を使います。
今回は10以下や0以下という比較なので、<=を使います。=を付けた場合は以下や以上という意味になります。

3つの条件のうちどの条件から記載するかが難しい部分です。
if文は先に書いた条件から判断していきます。そのため上の条件に当てはまったら、たとえ下の条件に当てはまっても、下の条件の処理はスルーされます。

かつ、と条件に記載されていても１０以下かつ０は、シンプルに考えて０以下の数字という条件になります。

・10以下なら10以下の数字です
・10より大きい数値なら10より大きい数字です
・10以下でかつ0以下なら0以下の数字です

よって、この中で優先処理が高いのは３つめの条件です。
０以下の数字、１０以下の数字、１０より大きい数字の順に処理をしていく記述をします。

&&（かつ）を使いそうになりますが、条件を整理するとシンプルな条件式に整理する事ができます。
Java(spring)のメール送信について (2パターン実装してみた)

実務の中で初めて触れたjavaのメール送信について、簡単に備忘録として書き残しておこうと思います。

メール送信に困っている方の参考にもなれば嬉しいです。

## 利用するメールサーバー等の設定

今回は、springを利用しているので、ymlファイルを利用しています。
また、Gmailのサーバーを利用してGmailからメール送信します。

※ springを利用していない方はpropertyファイルに記載が必要になります。

```yml:
spring:
  mail:
    host: smtp.gmail.com
    port: 587
    username: ユーザー名
    password: パスワード
    properties:
      mail:
        smtp:
          auth: true
          starttls.enable: true
```

<password:>
gmailにログインする時のパスワードではないので、注意が必要。

<auth:>
送信依頼をしてきたメールサーバが正規のクライアントかどうかを認証して確認してくれる設定。

<starttls.enable:>
TLS通信で安全な接続を行ってくれる設定。
<br>

上記の設定が終われば、いよいよメール送信です。

## メール送信①:SimpleMailMessageを利用
簡単なメール送信(添付ファイルや特殊な文字エンコーディング以外)で利用できます。

実装は本当にシンプルで、タイトルや本文を設定して、MailSenderクラスのsendメソッドで送信するだけです。

```java:
import lombok.RequiredArgsConstructor;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;


@Service
@RequiredArgsConstructor
public class MailSenderService {

    private final MailSender mailSender;

    public void sendMail() {
            var mailInfo = new SimpleMailMessage();
            mailInfo.setSubject("javaの実装練習です");
            mailInfo.setText("お元気ですかテストです");
            mailInfo.setTo("xxxx@xxxx");
            mailInfo.setFrom("xxxx@gmail.com");

            mailSender.send(mailInfo);

    }
}

```


## メール送信②:JavaMailを利用

 MimeMessageHelperを利用してMimeMessageを作成
MimeMessageHelperを利用せず、MimeMessageだけで作成も可能
 → SimpleMailMessageを超える内容が充実したメール送信がしたい時に利用


```java:
package com.example.demo.Service;

import lombok.RequiredArgsConstructor;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;


@Service
@RequiredArgsConstructor
public class MailSenderService {

    private final JavaMailSender javaMailSender;

    public void javaMailSender() {
        // 新しいメッセージを作成
        var message = javaMailSender.createMimeMessage();
        try {
            var messageHelper = new MimeMessageHelper(message, true);
            messageHelper.setFrom("xxxx@gmail.com");
            messageHelper.setTo("xxxx@xxxx");
            messageHelper.setText("お元気ですかテストです。JavaMail利用です",
                    "<span style='color: red'>赤文字出力</span><br>段落下げた");
            messageHelper.setSubject("タイトルですよ");

            javaMailSender.send(message);
        } catch(MessagingException e) {
            throw new RuntimeException("メッセージの設定に失敗しました", e);
        }
    }
}
```
messageHelper.setTextメソッドの第二引数にhtmlを設定できたり、
addAttachmentメソッドでPDFやファイルを設定できたりするので、
SimpleMailMessageよりもできることが増えるイメージです。


```java:
new MimeMessageHelper(message, true);
```
インスタンス化する際の第二引数にtrueを入れないと添付ファイルを設定できないっぽいです。
(マルチパートモードをonにしないといけない)


PDFファイルの生成処理の実装ができたら、それをメールに添付して送信するみたいな実装をこれからやっていこうと思います。
TwitterAPIを有料版に移行する方法【ツイッターAPI有料化】

ツイッターAPIの有料化が始まります。Herokuより移行期間が短いです。APIが使えなくなる前に対処しましょう

https://twitter.com/TwitterDev/status/1621026986784337922

# Twitter Developerを開く

https://developer.twitter.com/

# `Developer Portal`を押す
![Screenshot from 2023-02-02 22-10-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/7e4edd72-3f71-6630-c317-24073591dc74.png)

# `Billing`を押す
![Screenshot from 2023-02-02 22-12-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/8a2507ed-a815-250e-160e-442a83e3d756.png)

# `②Credit card info`を押す
![Screenshot from 2023-02-02 22-12-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/53517f31-e798-53cc-5f55-3d20f56ef74b.png)

# `Add new payment method`を押す
![Screenshot from 2023-02-02 22-12-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/e6fb2700-2ae1-2153-4b85-3c149c961134.png)

# クレカと住所を入れて、`Save payment method`を連打
![Screenshot from 2023-02-02 22-13-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/8adae92d-bf80-d588-875d-0ec98071580c.png)

クレカと住所がない人はバンドルカードがオススメです

# クレカが登録されたか確認
![Screenshot from 2023-02-02 22-17-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/b89360ae-82b7-c76f-2abe-bec8f402cf33.png)

いかがだったでしょうか(👊
【初心者の勉強記録】MAMPを使わずに、Laravel上でphpMyAdminを使えるようにしました。



## 前書き

私はphpMyAdminをもう使い慣れたので、どのようにDocker環境でphpMyAdminを立ち上がるかを紹介します。

PHPの学習をしていた段階で、実はMAMPが愛用でしたが、今回の転職ポートフォリオを作成し始めた段階でDockerのみで実装してみようと思います。

## 接続方法
Laravelのプロジェクトを一旦インストールした後、次にDBの接続と.envの初期設定を行います。

この方法は非常に初心者フレンドリーだと思います。Docker初心者の私でも使えるくらいおすすめしたいです。

参考したYoutube動画はこちらです→*[Setting up a New Laravel Application and phpMyAdmin using Docker](https://www.youtube.com/watch?v=AGg8UJoQGWk)*

~~（英語の動画ですが、英語が得意な方は直接参考にしてみてください）~~

簡単にいうと、ステップは以下のようになります：

①プロジェクトファイルの**docker-compose.yml**を開きます。

②seleniumとnetworksの間にphpMyAdminの設定を記述します。

```docker:docker-compose.yml
# .envファイルの「DB_HOST」とサービス名を合わせる
	phpmyadmin:　
        depends_on:
            - mysql
        image: phpmyadmin/phpmyadmin
        environment:　
            - PMA_HOST=mysql
            - PMA_PORT=3306
			# mysqlサービス名とポート番号を指定。3306で指定しましょう。
        networks:
            - sail
        ports:
            - 8001:80
```

記述の場所はこの辺りです。

![Screen Shot 2023-02-02 at 22.15.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/816933/e94c6727-b833-79b9-baa4-6924d8814eae.png)

上記の記述が完成できたら、一旦Laravel Sailで起動し、localhost:8001へアクセスしてみます。

すると、ログイン画面が出てきましたー！わーい！

![Screen Shot 2023-02-02 at 21.57.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/816933/8f44ce3f-809a-6218-1ab2-6e9295881abc.png)

ちなみに、私のユーザ名とパスワードは`DB_USERNAME=sail`　`DB_PASSWORD=password`　なので、そのまま入力しても構いません。

ログインできたらマイグレーション作業ができると思います。

以上。接続作業は終わります。
エンジニアインターン10日目

今日はpythonを使ってスクレイピングをした。Beautifulsoupを使ってDOM要素を取り、得た情報を配列に渡して、DBに保存する仕組みだった。複数のページからスクレイピングをしたかったため、urlを配列に渡して、ページごとに正しい値を取るようにした。lambda上でtestをしてエラーを解決しながら進めた。やはり、初心者だと、エラーを解決するのに時間がかかってしまったり、工夫がまだまだ足りていない。そこで、先輩エンジニアに質問することでエラーに対する工夫の仕方や考え方などを教えていただくことができる。自分で検索して探すことももちろん大切であるが、いつでも質問できて、改善させてくれるような環境を持つこともとても大切であると考えた。そろそろインターンを初めて1か月を立とうとしている自分にもタスクに対する責任感も出てきて、日々成長した姿を証明していきたいと思う。しかし、まだまだ分からないことの方が多い。失敗を恐れず、チャレンジを辞めずに成長していきたい。
Twitterと連携しているアプリを安全に移行する方法【ツイッターAPI有料化】

ツイッターAPIの有料化が始まります。Herokuより移行期間が短いです。ログインできなくなる前に対処しましょう

https://twitter.com/TwitterDev/status/1621026986784337922

# `もっと見る`を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/30933e2c-eafc-64e9-4e68-c07473d6003e.png)

# `設定とプライバシー`を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/8a131ffc-63c0-a6b2-bf86-d21005752e87.png)


# `セキュリティとアカウントアクセス` > `アプリとセッション`を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/3fbce126-28af-91e6-4a73-1079c8efb38a.png)

# `連携しているアプリ`を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/e661cb05-d02d-9310-789f-5496de73b9d2.png)

# `連携しているアプリ`を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/65d371e4-8ee7-5951-903c-ec720aa11387.png)

# `アプリの許可を取り消す`を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/0efc0778-1904-6428-2950-e9ae1140dd6f.png)

# 他のIDプロバイダーで認証する
ただflatにするだけでない？flatMapの便利な使用法

## 概要
`flatMap`はES2019で追加された機能で比較的新しい配列を操作するメソッドです。
MDNを見ると使用例に以下のようなものがあります。

``` javascript
const arr1 = [1, 2, [3], [4, 5], 6, []];

const flattened = arr1.flatMap(num => num);

console.log(flattened);
// Expected output: Array [1, 2, 3, 4, 5, 6]
```

これだけ見るとただmapをflatにしただけであまり使い道がないように思いました。

しかし実際に使うと便利な場面が多々あるので紹介したいと思います。

## 要素の抽出

例えばユーザーの名前とペットの名前が書かれた配列があるとします。
ペットを飼っていない人もいるのでpetは定義されていないこともあります。
ここからpetの名前の配列を取り出す操作を考えたいと思います。
```javascript
const users = [
    { name: 'user1', pet: 'pochi' }, 
    { name: 'user2', pet: 'tama' }, 
    { name: 'user3' }
];
// ここから [ 'pochi', 'tama' ]という配列が欲しい
```

この時従来であれば次のように記述します。
```javascript
const pets = users.filter((user) => user.pet).map((user) => user.pet);
```
この書き方だと2回同じようなことを書かなければならず、わかりにくさがあります。

一方でflatMapを使うと以下のように記載できます。
```javascript
users.flatMap((user) => user?.pet || [])
```
このようにobjectの配列から要素を抽出したいときに
flatMapを使うことでより簡潔に使うことができます。

## 要素を増やす

例えば、商品と金額のオブジェクトのリストが与えられるとします。
ここで商品がスマートフォンがあれば無料で保護シートをつけるという処理をしたいと考えます。
この時、表示の問題でただ末尾に保護シートを追加するのではなくスマートフォンの後に保護シートを追加したいとします。

``` javascript
const cart = [
    { name: '本', price: 1000 },
    { name: 'スマートフォン', price: 30000 },
    { name: '電池', price: 200 },
];
// ここから下記のような配列が欲しい
// const cart = [
//     { name: '本', price: 1000 },
//     { name: 'スマートフォン', price: 30000 },
//     { name: '保護シート', price: 0 },
//     { name: '電池', price: 200 },
// ];
```

この時従来であれば次のように記述します。
```javascript
const newCart = carts.reduce((newCart, item) => {
    newCart.push(item);
    if (item.name === 'スマートフォン') {
        newCart.push({ name: '保護シート', price: 0 });
    }
    return newCart;
}, []);

```

reduceを使うことで記載しましたが若干コードの長さや可読性が気になります。


flatMapを使うことで以下のように記載できます。

``` javascript
const newCart = cart.flatMap((item) =>
    item.name === 'スマートフォン' ? 
       [item, { name: '保護シート', price: 0 }] : item
);
```
かなり簡潔に記載することができました。

## まとめ
flatMapはただflatにするだけでなく
要素を増やしたり抽出したりしたい時に使える
とても便利なメソッドです！
MUI(Material UI)のDataGridで特定の行にstyleを追加する方法【React】

ReactのUIフレームワークであるMUI(Material UI)のDataGridにて、特定の行にだけstyleを設定する方法を解説していきます。
指定のセルが入力されている時に行(row)の色を変えるなどの実装に役立つかと思います。

https://mui.com/x/react-data-grid/

## React・MUI(DataGrid)の実際のコード

```tsx
import { Container } from '@mui/material'
import { DataGrid, GridColDef, GridRowParams } from '@mui/x-data-grid'

const Home = () => {
  const columns: GridColDef[] = [
    { field: 'id', headerName: 'ID' },
    { field: 'name', headerName: 'NAME' },
    {
      field: 'email',
      headerName: 'E-MAIL'
    }
  ]

  const rows = [
    {
      id: 1,
      name: 'Taro',
      email: 'test1@gmail.com'
    },
    {
      id: 2,
      name: 'Ken',
      email: 'test2@gmail.com'
    },
    {
      id: 3,
      name: 'Yui',
      email: 'test3@gmail.com'
    }
  ]

  return (
    <Container>
      <DataGrid
        columns={columns}
        rows={rows}
        checkboxSelection
        // クラスを設定しておく
        sx={{
          '& .rows-active': {
            background: '#2C7CFF !important'
          }
        }}
        // 特定の条件でclassを返す
        getRowClassName={(params: GridRowParams) => {
          if (params.id === 2) {
            return 'rows-active'
          }
          return ''
        }}
      />
    </Container>
  )
}

export default Home
```

DataGridの`getRowClassName`で特定の行にのみ`class`を設定することができます。
その`class`にstyleを当てておくことで、特定の行(row)にのみstyleを当てることが可能です。
上記の例では、idが2の行のみ背景が変化するようにしています。（※`getRowClassName`の引数には行の情報が入ってきます。）

![mui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/d5aec8ce-e4d3-ca1c-6ef7-47d6325c5280.png)

## 参考
https://mui.com/x/react-data-grid/style/#striped-rows
未経験からデータアナリストへ転職する為には？


# 目的と期間

目的は、データアナリスト、データサイエンティスト職種へ転職することです。
期間としては、私の場合、未経験かつ異業界でしたので約1年間の準備を行ってきました。

# 必要なスキルとそれを裏付ける方法

* プログラミング開発経験／データ分析経験　
・ポートフォリオの作成　・・・　各種スクール
・kaggle　https://www.kaggle.com/

* 機械学習・プログラミング
・Python3エンジニア認定基礎試験　
・Python3エンジニア認定データ分析試験　
　https://cbt.odyssey-com.co.jp/pythonic-exam.html

* ロジカルシンキング　

* コミュニケーション能力　

* 業界知識

* 数学（微分積分／線形代数／確率統計）　
・統計検定2級　https://www.toukei-kentei.jp/exam/grade2/

* コンピュータサイエンス
・基本情報技術者試験　https://www.jitec.ipa.go.jp/1_11seido/cbt_sg_fe.html
・G検定　https://www.jdla.org/certificate/general/

* 創意工夫／インプット／アウトプット／自己研鑽

# 未経験からの学習ロードマップ

## 1．プログラミング言語に関する基礎理解（約2ヶ月：1・2月）
　
Progateにて有料プラン含めて3周（SQL、Python）　https://prog-8.com/

## 2.Python、データサイエンスに関する基礎理解（約2ヶ月：3・4月）

書籍
* 「AIデータ分析プロジェクト」
* 「これからのデータサイエンス」

Udemy
* 「現役シリコンバレーエンジニアが教えるPython3入門＋応用＋アメリカ
　　　のシリコンバレー流コードスタイル」　

## 3.機械学習に関する基礎理解（約2ヶ月：5・6月）
書籍
* 「ディープラーニングG検定」

学習サイト
* 筑波大学オープンウェア（機械学習・データベース概論）受講　※無料
https://ocw.tsukuba.ac.jp/course/systeminformation/machine_learning/

## 4.データ分析の経験を積む（約2ヶ月：7・8月）

書籍
* 「東京大学のデータサイエンティスト育成講座」
* 「pandasライブラリ活用入門」

Udemy
* 「ゼロから始めるデータ分析　ビジネスケースで学ぶPythonデータサイエンス入門」

学習サイト
* 総務省統計局社会人データサイエンス　入門・実践　受講　
https://gacco.org/stat-japan/
　　　
## 5.統計検定2級の資格取得（約2ヶ月：9・10月）

統計Web　
　https://bellcurve.jp/statistics/course/

書籍
* 「統計学が最強の学問である」
* 「統計検定２級過去問」

## 6.Python3エンジニア認定データ分析試験の資格取得（約1ヶ月：11月）

書籍
* 「Pythonによる新しいデータ分析の教科書」

学習サイト
* PRIME STUDY「Python3エンジニア認定データ分析模擬試験」※無料　
　https://study.prime-strategy.co.jp/

## 7.転職活動（約1ヶ月～：12月～）
* 書類作成
* 転職エージェント活用
* 面接対策

# ポートフォリオ

実務におけるビジネス課題発見をはじめ、データ分析まで一貫して行いました。転職前の会社で個人的に分析してみるのも良い経験になるかもしれないですね。

# 終わりに

求人側に共通する求めるスキルをどう証明するかが重要だと思いますので、計画的に職務経歴書に盛り込めると、実際の面接の際に辻妻の合う話が出来ると思います。また、未経験で求められているところはポテンシャルの部分も大きいと個人的に思いますので、今の業務の中で得られている経験や知識が次の仕事でどのように活かすことが出来るかキャリアの棚卸をしておくことも大切だと思います。
Djangoでプロジェクトを作成しローカルサーバーを起動してみた

## 背景
2023年にエンジニアとして1円でも良いので仕事を取りたいという気持ちがありますが、どこから手をつければ良いのか分からない中でDjangoを扱えるようにがんばっています。毎日少しずつでも良いので学んだことや解決したことを蓄積していければと思っています。暖かい目で見守っていただければ嬉しいです。

そもそもマークダウンの書式が分からない…[こちら](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)や[こちら](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)を見ながら。

## やったこと
まずはプロジェクト作成
```python:terminal(PJT作成したいフォルダ)
% django-admin startproject mysite
```
おまじないとして：
```python:
% cd mysite
% python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK
```
この状態でローカルサーバーを動かせる
```python:
% python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
February 02, 2023 - 21:10:31
Django version 3.2.12, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
```
おめでとうございます！
![スクリーンショット 2023-02-02 21.41.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224055/66cf02f1-6fcc-7560-019b-94fd15623391.png)

## 気づき
実はQiitaに書くかなり前にこの作業は終わっていた(当たり前)のだけど、プロジェクトを作っては躓いて進めなくなったり、違うことをやりたくなることも多く、ゼロからプロジェクトを作成することが少なくないため、まとめてみました。
次はアプリをつくり、モデルからDBを作成、管理サイトまでまとめようと思っています。
[React]コンポーネントをpdf出力させる

Reactのコンポーネントをそのままpdf表示したいときあると思います。
動的なuiをそのまま変換できるので便利。

次の手順で進める。
1.componentをcanvasに変換
2.canvasをpdfに変換

# 1. package install
```
$ npm i html2canvas jspdf
```

# 2. pdf表示ロジック
```tsx:usePdf
import html2canvas from 'html2canvas'
import { jsPDF } from 'jspdf'
import { useRef } from 'react'

const usePdf = () => {
  const targetRef = useRef<HTMLDivElement>(null)

  const pdfOpenHandler = () => {
    if (targetRef.current === null) return

    html2canvas(targetRef.current).then((canvas) => {
      const pdf = new jsPDF({ format: 'a4' })
      pdf.addImage(canvas, 'canvas', 15, 10, canvas.width / 18, canvas.height / 18)
      window.open(pdf.output('bloburl'))
    })
  }

  return {
    targetRef,
    pdfOpenHandler,
  }
}

export default usePdf
```

## 解説
targetRefにはReact componentが入る想定です。
##### componentをcanvasに変換
```tsx
html2canvas(targetRef.current)
```

##### canvasをjspdfに突っ込む
```tsx
const pdf = new jsPDF({ format: 'a4' })
pdf.addImage(canvas, 'canvas', 15, 10, canvas.width / 18, canvas.height / 18)
```
pdf.addImage(引数)
canvas： pngや他のフォーマットでもいけます。
'canvas': ファイルフォーマット
15: xの始点
10: yの始点
canvas.width / 18： 横幅(canvas.widthだと長すぎるので割ってます)
canvas.height / 18: 縦幅

#### pdfを表示
```tsx
window.open(pdf.output('bloburl'))
```
ちなみにwindow使わず
`pdf.output('dataurlnewwindow')`でも開きますがabout:blankで開くのでなんとなくやめました。

ダウンロードしたい場合は
`pdf.save(faile名)`

# 3. UIにセット
```tsx:page.tsx
const page = () = {
  const {targetRef, pdfOpenHandler} = usePdf()

  return (
    <>
      <Component ref={targetRef}>
      <Button onClick={pdfOpenHandler}>pdfで開く</Button>
    </>
  )
}
```



# 参考
https://zenn.dev/k_kazukiiiiii/articles/8938bb1bd33985
【Java】「文字の出力」　――サンプルコード

備忘録として、他の言語に慣れすぎて書き方を忘れた人に。

```java:Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
```

```:実行結果
Hello World!
```

mainの書き方もご参考に。
Colabで、selenium使おうとしたらエラー出た時のメモ（2023.01

これベースにやればいける
- https://teratail.com/questions/szqt1qg23qdcc8
- https://github.com/kaliiiiiiiiii/Selenium-Profiles/issues/10#issuecomment-1387618009


colabのUbuntuバージョンが変わったみたいで、それに伴って出てる模様。
pyminizipでcompress_multipleを使わずに複数のファイルをまとめる方法

#### 概要
pyminizipを使って圧縮ファイルにパスワードを付ける時、
複数のファイルをまとめるならcompress_multipleを使うけれども、
イテレートしながらファイルをまとめたい時のやり方。

#### 方法
- pyminizip.compressでパスワード付きのzipファイルを作成してから、zipfile.ZipFileの追記モードでファイルを追加していくとできる。

```python
import zipfile
from pathlib import Path

import pyminizip


class ZipFileProcessor:

    @staticmethod
    def init_zipfile_with_password(zip_file_name: str, file_name: str, password: str) -> None:
        pyminizip.compress(file_name, '', zip_file_name, password, zipfile.ZIP_DEFLATED)

    def process_zipfile(self, zip_file_name: str, file_name: str, password: str) -> None:
        if not Path(zip_file_name).exists():
            self.init_zipfile_with_password(zip_file_name, file_name, password)
            return

        with zipfile.ZipFile(zip_file_name, 'a') as zip_file:
            zip_file.write(
                file_name,
                compress_type=zipfile.ZIP_DEFLATED
            )
```
Visual Studioでの行全体の入力候補をOFFにする

本当に世の中はどんどん便利になっている。
その最たるものが<strong>補完機能</strong>だと勝手に思ってます。
プロパティやメソッドを入力するにも、頭の数文字を打ち込むだけで良い。めちゃくちゃ便利。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118844/e0185398-c5d9-a65c-a39e-0f67917a4626.png)

ただ本当にありがたいんですが、個人的に迷惑な設定がこれ。
改行すると次の行に入力しそうな候補が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118844/e6976525-502a-8103-ffee-7aa8849e06eb.png)

インデントをそろえるためにTabを押したりすると、この候補が入力される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118844/5a77d55e-a896-ab8f-0ea7-55e824b372fa.png)

変数inputNameから予測しているのは良いけれど、正直この候補をそのまま使うことがあまりない、、、
しかもその度にEscを押すのもダルい、、、、

### 行全体の入力候補の表示を無効にする。
「ツール」の「オプション」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118844/43de15c6-8ea9-d10d-b8b6-e6f4f971397d.png)

左側の一覧から「IntelliCode」にある「詳細設定」を選択して、「行全体の入力候補を新しい行に表示する」のチェックを外す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118844/9b071457-7b9d-e0d2-9660-70e3e1ab6053.png)


これで改行時に候補が出てくることがなくなります。
setodaNoteCTF - Mx.Flag 150

# 問題

https://ctf.setodanote.net/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ba017aab-4793-9bd0-7461-2b0b51bd75f3.png)

# 解いてみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/7dcf82bb-d79e-4411-de93-dd59d64f644a.png)

ソースを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/81708c35-7986-aabe-b373-20f6c19161da.png)

faviconとcssが一つずつあるだけ。
faviconを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f7bcbe67-64c9-603f-2c7f-9fd3a024f432.png)

これは怪しいですね。

curlでダウンロードしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/93f5b264-0425-0a38-be65-defefaf13e32.png)

ダウンロードしたファイルを見ることはできません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/1830e8c3-36a3-d032-2414-0c88c56d4927.png)

Bzで見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/398f0c95-09ec-35e8-fef1-a67903d8aa2c.png)

フラグありました。
Makefileの使い方

# はじめに
チーム開発をする際に事前にセットアップを行わないといけないことがあり、Makefileを使用したので記録しておきます。

今回の例ではStableDiffusionのモデルをsetup.pyで生成しています。

https://qiita.com/SNQ-2001/items/2d33dc535cf106189f75

# 書き方
```Makefile
.PHONY: setup
setup:
	pip3 install huggingface_hub
	python3 setup.py
	open sample.xcodeproj
```

# 実行方法
```:コマンド
make setup
```

# おわり
`.PHONY`を追加することで複数定義することができます。
FizzBuzz問題のちょっと改良版


いつもならifでi%3==0 %% i%5==0を入れてから
3で割り切れる場合と5で割り切れる場合を判定したが
今回は3でも5でも割り切れる場合を記述せずに両方を判定するコードを記述する。

```java
//今回はelse ifを使わずif使う。
//3で割り切れる場合でも次の条件判定if(5で割り切れるかどうか)がスキップされないので、else ifで15入れなくてよい
public class Main {
    public static void main(String[] args) throws Exception {
        String output;//println使わずに出力するメンバ変数を決めておく。
        for (int i = 1; i <= 30; i++){
            output="";//初期値
            if (i%3==0) {
                output="Fizz";
            }
            if (i%5==0){
                output=output+"Buzz";//3でも割り切れる場合、output+"Buzz"のoutputに"Fizz"が代入される
            } 
            output=String.valueOf(i)+":"+output;
            System.out.println(output);
        }
    }
}
/*出力された値
1:
2:
3:Fizz
4:
5:Buzz
6:Fizz
7:
8:
9:Fizz
10:Buzz
11:
12:Fizz
13:
14:
15:FizzBuzz
16:
17:
18:Fizz
19:
20:Buzz
21:Fizz
22:
23:
24:Fizz
25:Buzz
26:
27:Fizz
28:
29:
30:FizzBuzz
*/
```
for文, 拡張for文, イテレータの３種類の方法を使用してArrayListの中身を順に取り出してみた。

# １．はじめに
ラーメンの提供している姿をみていたらArrayListのことを思い出してしまった。
JavaのArrayListクラスに慣れるために３つの方法を使用して中身を順に取り出す練習をすることにした。
ArrayListクラスは実務でも非常に多く使用されており、平然と使えるようにならないといけない。

# ２．３種類の方法
<details><summary>for文</summary>

一般的な繰り返し方法。__変化式を記述できるのが特徴__
```java
for (int i; i < リスト変数.size(); i++){
  // 変数iがリスト変数の要素数未満の場合に繰り返す処理
  ...
}
```
</details>
<details><summary>拡張for文</summary>

for文を可読性の高いものにした方法。**すべての要素を順番に処理していくのが特徴**
```java
for (リスト要素の型 i : リスト変数){
  // リスト変数の要素数まで繰り返す処理
  ...
}
```
</details>
<details><summary>イテレータ</summary>

for文を可読性の高いものにした方法。**hasNext()やnext()を使用して次の要素が存在するかを判定しながら処理していくのが特徴**
```java
Iterator<リスト要素の型> i = リスト変数.iterator();
while (i.hasNext()){
  // リスト変数の要素数まで繰り返す処理
  String str = i.next();
  ...
}
```
</details>

## 2.1　for文
for文を利用しての実行は下記のようなものになった。
```java:RamenFor.java
import java.util.ArrayList;

public class HelloRamen {
	public static void main(String[] args) {
		ArrayList<String> noodles = new ArrayList<String>();
				
		noodles.add("とんこつ");
		noodles.add("しょうゆ");
		noodles.add("しお");
		
		for (int i = 0; i < noodles.size(); i++) {
			System.out.println(noodles.get(i));
		}
	}
}
```


## 2.2　拡張for文
拡張for文を利用しての実行は下記のようなものになった。
```java:RamenExpansion.java
import java.util.ArrayList;
import java.util.Iterator;

public class HelloRamen {
	public static void main(String[] args) {
		ArrayList<String> noodles = new ArrayList<String>();
				
		noodles.add("とんこつ");
		noodles.add("しょうゆ");
		noodles.add("しお");
		
		Iterator<String> i = noodles.iterator();
		while (i.hasNext()){
		  String str = i.next();
		  System.out.println(str);
		}
	}
}
```


## 2.3　
拡張for文を利用しての実行は下記のようなものになった。
```java:RamenExpansion.java
import java.util.ArrayList;

public class HelloRamen {
	public static void main(String[] args) {
		ArrayList<String> noodles = new ArrayList<String>();
		
		noodles.add("とんこつ");
		noodles.add("しょうゆ");
		noodles.add("しお");
		
		for (String noodle : noodles) {
			System.out.println(noodle);
		}
 		
	}
}
```


# ３．結果
`結果`
```java
とんこつ
しょうゆ
しお
```


# まとめ
今回はArrayListクラスで基本的な取り出しを練習した。
これを実務でも応用することによって、データの取り出しをスムーズなものにしようと思う。
[ユキのIT教室](https://yuki-itclass.com/ "ユキのIT教室ホームページ")

https://yuki-itclass.com/
Kotlin Collection

```
import org.junit.Test
import org.junit.Assert.*
import kotlin.math.pow
class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
        val nums = listOf(10, 20, 100, 5)
       //1. check true of false
        assert(nums.any()) // true if nums is not empty
        assert(nums.any{it > 99})
        assertFalse(nums.all { it > 99 })
        assert(nums.none{it > 101})
        // 2. filter
        assertEquals(listOf(10,5), nums.filter { it <= 10 })
        assertEquals(listOf(20,100), nums.filterNot { it <= 10 })
        // 3. map
        val ints : List<Double?> = listOf(2.0,null, 3.0)
        assertEquals(listOf(4.0, null, 9.0), ints.map { it?.pow(2) })
        assertEquals(listOf(4.0, 9.0), ints.mapNotNull { it?.pow(2) })
        //4. group
        assertEquals(mapOf("odd" to listOf(1,3), "even" to listOf(2,4)),
            listOf(1,2,3,4).groupBy { when {it % 2 == 1 ->"odd" else -> "even"} })
    }
}
```