OmniAICreator/Qiita-1.07M huggingface dataset:
LinqでのSelectとWhereとの違い

C#のLinqでのSelectとWhereの違いについてみてみます。

1、Select
「Select」は、リストや配列の各要素を順番に処理するイメージです。
例えば、以下の通りです。

```
using System;
using System.Linq;
using System.Collections.Generic;
public class Sample {
    
    static public void Main () {
        
        int[] numbers = new int[]{1, 2, 3, 4, 5};
        
        // 各数値を３倍する
        IEnumerable<int> it = numbers.Select(item => item * 3);
        
        foreach(int item in it) {
            Console.WriteLine(item);
        }
        
    }
}

//出力結果
3
6
9
12
15
```


2、Where
「Where」は、条件に合致したデータを抽出するイメージです。
例えば、以下の通りです。

```
using System;
using System.Linq;
using System.Collections.Generic;
public class Sample {
    
    static public void Main () {
        
        int[] numbers = new int[]{1, 2, 3, 4, 5};
        
        // 偶数のみを抽出する
        IEnumerable<int> it = numbers.Where(item => item % 2 == 0);
        
        foreach(int item in it) {
            Console.WriteLine(item);
        }
        
    }
}

//出力結果
2
4
```

3、Selectのおまけ
Selectは各要素が条件を満たしているかの判定する機能もあります。
```
using System;
using System.Linq;

//trueかflaseの判定 
class Program
{
    static void Main(string[] args)
    {
        int[] numbers = new int[] {1,2,3,4,5,6};
        //4の倍数かどうかを判定する
        var olds = numbers.Select(x => x % 4 == 0);
        foreach(var old in olds)
        {
            Console.WriteLine(old);
        }
    }
}

//出力結果
False
False
False
True
False
False

```



参照記事
https://symfoware.blog.fc2.com/blog-entry-1928.html
https://csharpprogram.com/category/c/linqpractice/
キーボードとマウスの往復を少なくしたい！

右手がキーボードとマウスを行き来する時間を合算すると、人の一生ぐらいの長さがあるとされています。
ここでは、キーボードとマウスの行き来を軽減するショートカットキーを紹介します。
便利なのをご存知の場合コメントください。

- [ファイルエクスプローラー編](#ファイルエクスプローラー編)
    - [ファイルエクスプローラーを起動したい](#)
    - [特定のパスをコピーしたので開きたい](#特定のパスをコピーしたので開きたい)
- [ブラウジング編](#ブラウジング編)
    - [Googleで検索窓にフォーカスしたい](#Googleで検索窓にフォーカスしたい)
- [全般編](#全般編)
    - [今選んでるウィンドウをスクショをコピーしたい](#今選んでるウィンドウをスクショをコピーしたい)
    - [ウィンドウを移動したい、綺麗に置きたい](#ウィンドウを移動したい、綺麗に置きたい)
    - [ウィンドウ閉じたい](#ウィンドウ閉じたい)
    - [コピーしたものを何個も保持したい](#コピーしたものを何個も保持したい)
    - [さっきフォーカスのあったウィンドウにフォーカス当てたい](#さっきフォーカスのあったウィンドウにフォーカス当てたい)


## ファイルエクスプローラー編
ファイルエクスプローラーを起動したい
Ctrl+E

### ファイルエクスプローラーのパスの欄を選択したい
Alt+D

### 特定のパスをコピーしたので開きたい
Windows+R
Ctrl+V
Enter

## ブラウジング編
### Googleで検索窓にフォーカスしたい
/


## 全般編
### 今選んでるウィンドウをスクショをコピーしたい
Alt+ScreenShot

### ウィンドウを移動したい、綺麗に置きたい
Windows + ↑ ↓ ← →

### ウィンドウ閉じたい
Alt + F4

### コピーしたものを何個も保持したい
Windows + V ↑や↓で選んでエンター

### さっきフォーカスのあったウィンドウにフォーカス当てたい
Alt + Tab
類似機能にWindows + Tabがあるんですが、この用途においてはAlt側を勧めます。
なぜならアニメーションがなく爆速だからです。（左Alt Tab、右Win Tab）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109589/3091d921-f398-0b21-4cc2-e073bd3c377c.gif" width="400" height=456px > <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109589/6560083e-ffd3-0cce-c9f0-64df76e9ef4c.gif" width=400 height=456px >

いったん以上
エンジニアが Sales Operations に取り組むとどうなるか

まずは自己紹介から始めようと思いますが、私自身がはじめてプログラムに触れたのは小学校４年生のことでした。Perlをさわっていましたが、まだ4でオブジェクト指向っぽくない感じが全盛で、とほほのwww入門が最大のリファレンスだったみたいな時代。
今３７歳なので、2８年前（！！）のことです。

それから新卒でもエンジニアの道に進みました。職業エンジニア歴は１５年になるでしょう。
当時はIT土方（土方も建築用語ですね）と呼ばれ、エンジニア３5歳定年説が大きく謳われていた時代、なりたくない職種ランキング上位だったことを思うと、今のエンジニア全盛期には隔世の感があります。
テスターのような仕事から始まり、ウォーターフォール開発も経験して、エンジニアリーダー、PM、POなども経験しました。

[１０年前にQiitaのハッカソンでファンキー賞を頂いたこともあります](https://blog.qiita.com/33699635640-2/)。ファンキーってなんだ？とか、Qiitaってもう１０年以上経つのかーとか感慨深いです。賞の特典がQiitaへの入社パスになっていて、当時ファンキーなエンジニア集めたい良い会社なんだなと思いました。

さて、このような私ですが最近は **Sales Operations** の改善に取り組んでいます。
もう少しエンジニアに馴染みのある書き方をすると **SalesOps** です。DevOpsのセールス版です。
セールスオペレーションと言うとピンとこない部分もあると思いますが、CRMシステムを入れようとか、マーケティングオートメーション（MA）を組もうとか、セールストークや資料はどうしようかなど、セールスメンバーが効率的に動きやすいインフラを整えたり、最適なファネルになるための人員配置や採用などの人事面などが含まれます。

SalesOpsという職種は日本では、一部の外資系やSaaSを提供する企業で導入され始めたばかりで、まだ世の中では認知されていない職種です。
キャリアパスとしては、戦略コンサルやセールスマネージャーから、SalesOpsになるケースが多いようです。

さて、当社ではSalesOpsを専任でたてたいと思っているものの、現状では私がファンクションの多くを担い、残りの一部はチームの兼務によって実現しています。

SalesOpsのキャリアパスを考えても、これまでも、これからも、セールスプロセスにエンジニアが関わることは少ないと思うので、そこで得られた知見を共有してみたいと思います。

今回はエンジニアがSalesOpsに取り組んだときの成果に着目して、メリットについてご紹介したいと思います。

# 得られた成果
## 安く良いものを組み合わせて使える
当社でもCRMやMAツールを導入していますが、導入をするにあたって世の中に流通しているサービスの情報収集を行いました。
その中で、おそらく日本ではCTOの設置がIT企業以外では進んでいないことや、ジョブ型採用でないこともあると思いますが、ユーザー側がITスキルをあまり持っていない前提で、そこに対するラーニングやトレーニングのコストがプライシング（初期費用や月額が高い）に反映されているのかなというプロダクトが多い印象を受けました。また、複数のプロダクトを組み合わせる方法だと複雑度が上がって、上記コストが更にかかってくるためオールインワンサービスのニーズが高いという仮説を持ちました。

一方、海外ではフリーミアムモデルで良質なSaaSが提供されていて、同種のサービスであっても日本とは違った料金体系となっているケースが見られます。
このあたりは、かなり考察が進んでる分野ですが、いわゆるジョブ型採用によってIT人材が組織に取り込まれている成果だと思います。
※ここで言う海外はほとんど北米を指します

海外では複数のSaaSを「どのように組み合わせるか？」のノウハウの共有が盛んに行われています。SaaSを統合（Integration）して利用しているためです。SaaS同士がオフィシャルにAPI連携を行っているケースもありますが、ZapierのようにN対Nでの連携をするための専用のプラットフォームまであります。
それぞれ強みのあるサービスを組み合わせて使っているので、ハイレベルなことが実現可能になっています。

一方、日本ではオールインワンが好まれる印象で、Zapierと言って分かる人はまだまだ少ないです。

エンジニアがSalesOpsに関わると、海外と同じことが実現できます。
つまり、フリーミアムで品質の高いSaaSを組み合わせて使えます。
（弊社のサービスもZapierに対応している数少ない日本のサービスのうちの一つです。）

日本は人口わずか1.2億人のアジアの小国ということもあり、日本語対応が甘い海外SaaSも多くあるので、選択肢は限られますが、UTF-8のおかげで文字化け等の致命的に使えないケースは少なくなってきています。

グローバリゼーションの中で、ITスキルや言語の壁によって、日本のビジネスで利用されるサービスがガラパゴス化していくことは避けたいなと感じています。

弊社でも、ほとんど日本で導入実績がないと思われるSaaSも含め複数組み合わせて利用しています。

SaaSを利用しなくても、スプレッドシートとGAS等で様々なことに柔軟に対応できるのもエンジニアの強みです。

## リスト操作（文字列操作）が得意
営業活動の中で、複数の経路から入ってきた顧客情報をマージする機会が数多く発生します。
適切にマージを行い、商談記録をしっかり残すことが中長期では求められてきます。
そこで正規表現による文字列置換や、機械的にマージを行うためのルールの発見やスクリプトの実装を行うことで、非エンジニアと比べると圧倒的な生産性を実現できます。

## KPI抽出
エンジニアは自然現象を構造化する職業なので、営業プロセスを構造化して捉えて、自動的データを取得して様々な角度から分析することは造作もない仕事です。
営業ファネルの中でどこがボトルネックになっているかを発見したり、リスクアラート、スコアリングなどを行って、問題を瞬時に特定します。

## スケーラブルな商流の設計
お客様と契約が発生するための証跡の残し方や、初回ログインやその後のステップメールの送信、カスタマーサクセスを交えたオンボーディングまでのUX設計など、エンジニアリングがわかっているからこそ、システムと人が連動した、生産性が高く、必要十分でお客様の負担が少ない状態を実現できます。
カスタマージャーニーの考え方は営業プロセスでもそのまま使えて、効果も高いのでおすすめです。

# まとめ
以上のような取り組みを行った結果、弊社では営業プロセスのを通してクライアントの顧客体験を高めつつ、営業につきもののいろいろな事務作業を排除して、営業がお客様とのコミュニケーションに集中できる環境を実現することができました。
SalesOpsは、セールスに浸透させていくプロジェクト管理能力も求められるものの、エンジニアの強みを多く発揮できる職種だと感じました。

そんな弊社は、工務店・住宅会社の営業プロセスの改善をテクノロジーの力でサポートして、同時にお施主様の顧客体験を高めるサービスを提供しています。
工務店・住宅会社の方でSalesOpsにご興味をお持ちの方は、お力になれると思うのでぜひお声掛けください。
Capistrano + Unicornでデプロイが反映されない時

Capistrano + Unicornの環境で構築すると、デプロイした内容が反映されない時がある。
ググってみると「stop → startすれば直るよ」と書いてある記事をよく見かけるが、それだと無停止デプロイできないし本番で使えないだろ、と思って原因を調べてみた。

# 原因

capistranoはデプロイ日時１４桁のディレクトリを作成して、そこに新しいリソースをチェックアウトし、参紹ディレクトリを切り替える仕組みだが、これが古いディレクトリのままになっていた。
ページ内で `__dir__` で現在のファイルのディレクトリパスを画面上に出すようにしたら、デプロイ後もデプロイ前のディレクトリになっていた。

`capistrano/current` のリンク先は正常に変わっていたので、**変わったリンク先を見てくれていないのが原因**と判明。

# 対策

## working_directoryを絶対パスに変更

unicorn.rbの設定方法の記事をみると、大抵の記事が以下のように書いてある。

```config/unicorn.rb
app_path = File.expand_path('../../../', __FILE__)
working_directory "#{app_path}/current"
```

相対パスで書いてあり、環境に依存しない書き方で大変便利なのだが、これだとcapistranoの日時ディレクトリがworking_directoryに設定され、USR2シグナルの再起動では読み込み直されないもよう（もちろんHUPシグナルでも）。

なので、この**working_directoryをROOTからの絶対パスで書くようにした**。

## serviceの起動方法を変更

serviceの起動時も `config/unicorn.rb`　を相対パスで書いていた。
そのためか、serviceで起動したunicornはデプロイが反映されなかった。

```unicorn.bash
cd $APP_ROOT && /usr/local/rbenv/shims/bundle exec unicorn -E $RAILS_ENV -c config/unicorn.rb -D
```

これも **`config/unicorn.rb`　のパスをROOTからの絶対パスで書くようにした**。

```unicorn.bash
cd $APP_ROOT && /usr/local/rbenv/shims/bundle exec unicorn -E $RAILS_ENV -c ${APP_ROOT}config/unicorn.rb -D
```

# 結論

Capistrano + Pumaでこの現象になったことないので、Capistrano使うときはUnicorn使わない方が良いと思う。
Floating VueでTooltipを作る

Vue3でtooltipやdropdownを作成できるライブラリFloating Vueを使う機会があり
マニュアル通りだと動かず困っていたところ、
<a fref="">cogor</a>さんが助けてくれたので使い方のメモ書きを共有します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/3cfb61d3-56d6-e3f1-4725-32bd5f4a5819.png)

https://floating-vue.starpad.dev/

```Vue.js/Tooltip.vue
<template>
  <div class="flex items-start">
    <Tooltip :placement="placement" :triggers="[trigger]" :theme="tooltipStyle">
      <a>Sponsor me</a>
      <template #popper>
        Help me fund my Open Source work!
      </template>
    </Tooltip>
  </div>
</template>

<script lang="ts" setup>
import type { PropType } from 'vue'
import type { TooltipPlacement, TooltipStyle, TooltipTrigger } from './types'
import { Tooltip } from 'floating-vue'
import 'floating-vue/dist/style.css'

const props = defineProps({
    placement: {
      type: String as PropType<TooltipPlacement>,
      default: "top"
    },
    tooltipStyle: {
      type: String as PropType<TooltipStyle>,
      default: "tooltip-dark",
    },
    trigger: {
      type: String as PropType<TooltipTrigger>,
      default: "hover"
    }
})
</script>
```
GithubActionsでSwaggerドキュメントを自動更新して、PRへコメントをつける

# はじめに
いくつかのプロジェクトにてSwaggerを利用した、API仕様書の運用をしています。
エンドポイントの追加・変更などがあった場合に、ドキュメントの更新を忘れがちなので、github上でPRを作成した際に、swaggerドキュメント生成のためのコマンドを自動実行し、差分があった場合はPR上にコメントするようなフローを作成しました。

使用言語及びライブラリは以下。
https://github.com/swaggo/gin-swagger
```
	github.com/swaggo/gin-swagger v1.3.3
	github.com/swaggo/swag v1.7.8
```

前提として、`Dockerfile`や`Makefile`等でSwaggerドキュメントの生成ができている状態とします。
(各種ライブラリなどで設定方法・実行方法は違うと思うので、Swaggerの設定部分については割愛します。)

# 実行ファイル

全体の設定ファイルです。以下で一つ一つ見ていきます。
PRのオープン・プッシュのイベントでトリガーされます。

```pr_pushed.yml
name: pr_pushed

on:
  pull_request:
    types: [opened, synchronize]
    branches: [develop]

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.ref }}

      - name: exec swagg
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          make swag

          if ! git diff --exit-code --quiet
          then
            git config --global user.name "${GITHUB_ACTOR}"
            git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"

            git add .
            git commit -m "regenerated swagger by github actions"

            git push

            gh pr comment ${{ github.head_ref }} -b "swagger が更新されました"
          fi
```

## checkout
```
- uses: actions/checkout@v3
  with:
    ref: ${{ github.event.pull_request.head.ref }}
```
最終的に、PRのブランチに対して、pushを行うためcheckoutブランチを`ref`で指定します。
（余談ですが指定なしの場合は、デフォルトブランチが指定されるそうです。）
```
# The branch, tag or SHA to checkout. When checking out the repository that
# triggered a workflow, this defaults to the reference or SHA for that event.
# Otherwise, uses the default branch.
ref: ''
```

## 差分を検知
```
if ! git diff --exit-code --quiet
```
Swaggerドキュメント更新を実施後、差分が無い場合は、commit時にエラーになるため、`git diff --exit-code --quiet`によって、制御します。`--exit-code`により、差分があれば処理が終了するため、否定系`!`をつけておきます。

## commitとpush
```
git config --global user.name "${GITHUB_ACTOR}"
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"

git add .
git commit -m "regenerated swagger by github actions"

git push
```

通常と同じ流れで`commit`して`push`。
`GITHUB_ACTOR`はPRを行ったユーザーとなるので、userに設定することで、自動的にcommitログにも追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457889/14228ddd-ec70-9f06-522d-6d1cb262f594.png)

## コメント
```
gh pr comment ${{ github.head_ref }} -b "swagger が更新されました"
```
PRへのコメントに対しては、[githubCLI](https://cli.github.com/)が使用できるので、そちらを利用します。
`GH_TOKEN`という名称で、値は`secrets.GITHUB_TOKEN`を使用します。別途PAT(PersonalAccessToken)も使用できそうです。
対象のブランチは `github.head_ref`を使用して特定します。
※こちらはPullRequestEventでしか取得できないので、他のイベントの場合は注意。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457889/27092851-e6c2-98cb-8153-5aee3f90f9fb.png)


# 参考
https://dev.classmethod.jp/articles/how-to-get-a-ref-branch-within-a-workflow-execution-in-github-actions/
https://cli.github.com/manual/gh_pr_comment
https://github.com/actions/checkout
https://yoshiori.hatenablog.com/entry/2021/12/08/220839
https://zenn.dev/lollipop_onl/articles/eoz-gha-push-diffs
エンジニアインターン１年生と大学４年生の両立

私は2022年の4月から現在まで[Catallaxy](https://catallaxy.me/)という会社でエンジニアインターン生として勤務している大学４年生の学生です。

こちらの記事は金属加工プラットフォームを開発・運用する[Catallaxy](https://catallaxy.me/)の[Catallaxy Advent Calendar 2022](https://qiita.com/advent-calendar/2022/catallaxy)の12/7の記事となります。

https://qiita.com/organizations/catallaxy-dev


今回は、エンジニアを目指す１大学生の活動をこれからエンジニアインターンを検討されている方やあるいはそれに近しい方に向けて発信できればと思います。

# 自身について
私はインターン生として入社したのは2022年の4月からで、開発経験でいうと他の学部卒のエンジニア志望の同級生よりも数年出遅れている状態でエンジニア1年生を迎えることになりました。

また、技術レベルについては、開発ではReactやTypeScriptを使っているのですが、自分はJavaScriptさえ書いたことがない状態で入社しました。。。

ちなみに大学では（ざっくり言うと）物理学を専攻しています。

以下、時系列に沿ってインターンと大学側の活動記録を羅列しました。

## 春頃
- 全体的なコードの理解・基本文法を抑えるのに精いっぱい
- 業務というか勉強
- 10:00出勤・16:00退勤
- 研究室から受験休みをもらい学校には行かなくてよかった

## 院試直前
- だんだんフロントエンドのタスクが少しずつこなせるように
- 周りが受験勉強をガチ化
- 10:00出勤・16:00退勤
- 出勤後夕方から勉強
- 入試直前の3週間は受験に専念

## 秋頃
- バックエンドのタスクもするように
- バックエンドにも少しずつなれてくる
- フロントエンド・バックエンド両方からむタスクができるように
- 10:00出勤・18:00退勤
- 夜から研究室で研究


## 冬頃（現在）
- フロントエンド・バックエンド両方からむタスクを行う
- 個人開発やらなきゃなあってなる
- 10:00出勤・18:00退勤
- 夜から研究室で研究

# 最後に
以上、ここ半年強の自分の主な活動記録を羅列しました。
開発に参加するようになってから、本当に見違えるようにスキルを身に着けたと思います。

なので開発インターンに興味はあるがなんとなく踏みとどまっている方がいれば、迷わず行動すべきだと思います。

未経験・大学４年生でも十分成長の余地があることを知ったので、これからも新しいことにどんどん挑戦していこうと思います！
Qiitaとnoteの両方に記事を書き始めて感じたことの覚書き

　Qiitaの更新が滞ってましたが、その間、noteに記事を書いてました。今のところ、なるべく理系っぽい記事はQiitaに、文系っぽい記事はnoteに書こうと思ってます。で、両方を比較して考えたことをメモしておきたいと思いました。個人的雑感として、以下4点、仕様の違いを挙げておきたいと思います。

## README.md vs GUI

　Qiitaはマークダウンで書きます。GitHubにREADME.mdを書く時と同じイメージですよね。記事を書く画面も、Visual Studio Codeで2画面分割でREADME.mdを書くのと同じようなユーザー体験になってます。でも、noteは分割されていない1画面で書くんすよ。なんというか、GUIによるブログ記入サービスみたいなイメージで、最初少し書きにくかったです。これはプログラミングができない人にも手広く書かせるためだと思います。なので、本当にシンプルな文しか書いていないライト層はあちらの方が多いです。誤解の無いように言っておくと、noteでもTeX記法で数式が書けるし(2021年末以降)、あっちにもガチな理系の人もいます。ただ、個人的には、数式を書くならQiitaかなーと思っています。

## 「いいね(LGTM)」vs「スキ!」

　Qiitaは、「いいね」してくれるのは基本的にユーザーのみです。本当にコードを書いている人が、「いいね」を押してくれたということで、重みを感じて嬉しくなります。エンジニアのコミュニティ感が出ている反面、コード読めない奴は口出すな、的な何かも感じますが・・・。個人的には、Qiitaの「いいね」の方が嬉しいです。はい。

　一方、noteは「スキ！」という名称で、非ユーザーでも押せます。匿名で別口から複数回押してもカウントアップできてしまうので、その重みはQiitaとnoteで全然違います。noteでは、他の人の記事のハートをクリックすると、うち何名が実ユーザーなのか分かるので、内訳を知りたい人はそれをクリックしてね、という仕様になっています。これもライト層まで幅広くリーチするための戦略かもしれません。

　あと、同じハートマークでも、言い方が違いますよね。言いにくいんですが、noteの「スキ！」ってちょっと恥ずかしくないですか。やはりライト層を狙ってのものでしょうか。当方、既婚のオッサンですので・・・。一方、Qiitaの方は、少し前に「LGTM」から「いいね」に言い方を戻しましたね。その公式の説明を見つけたので貼っておきます。「LGTM」だとあまりにコードレビュー感があるからということのようですが・・・。ヘヴィー層に寄りすぎたので少しライト層まで戻したというイメージでしょうか。僕のような中途半端な文系SEはその方が安心かもです。

https://blog.qiita.com/lgtm-to-like/


## 目次の自動表示について

　Qiitaでは、目次が自動で右ペインに出るようになりましたね。こちらでは皆、けっこうしっかり見出しを定義して書いていて、エンジニア的な<b>「TL;DR」の文化</b>を感じます。対して、noteの目次機能は、2022/11/25時点、<b>デフォルトでは非表示</b>なんです。そして、文の構造を気にしないでダラダラと書いている人も多い印象です。最初記事を書いたときに、自動で目次が出なかったので、僕は少し不便に感じました。noteとしては、思いついたことを構造を気にせず気軽に書いてね、という意図かもしれず、ここもやはり、ライト層向けのポイントなのかもしれません。

## 変更履歴の扱いの違い

　一番驚いたのはコレです。変更履歴。2022/8/17、noteにも変更履歴の機能が追加されたんですが、個人の編集画面で見られるだけで、非公開なんですよ。編集履歴を読者に伝えたいときには、自分で追記する必要があります。これだから文系は。どーせすぐ政治的事情で何かを書き換えて隠そうとするんですよ。よくないですよ。そういうの。まあ、これはつまり、単にライト層向けの仕様というよりは、それだけ政治的にデリケートなことを書く人も沢山いるから、ということかもしれませんね。逆に、現時点、Qiitaの編集履歴は基本的に全公開ですよね。GitHubと一緒で、オープンソースコミュニティの透明性へのコダワリみたいなものを感じて大好きです。スキ！

https://note.com/info/n/n962cf4a3e97a

## おまけ(宣伝)

　以上4点、微妙な仕様の違いから、ターゲット層の違いを感じたという話でした。

　最後に僕のnoteのリンクを貼っておきます。あちらでは中年以上の人をターゲットにした陰鬱な長文を書いています。なんか、久々にそういう文章を書いたらメチャクチャ疲れました。なのに<b>全然PVが増えない</b>ので、良かったらアクセスしてあげてください。

https://note.com/b3qp/m/m3edf7fa74d95
構築隔日記(9) Advent Calendar 2022 進捗報告(13)

残念ながら、今日をもって、この 構築隔日記は中断せざるを得ないかもしれない。　

Qiitaが過去の記事の手直しをすると、その日は投稿できなくなるという仕様がなかなか変更にならない。　

他のSNSでも、計算機が自動入力して編集している場合に、編集禁止にするサービスはいろいろある。　

それらの判断基準は、どう考えてもおかしいと思い、過去に２社に応募した。　

どちらも書類審査で落ちた。　

システム側に直してもらおうという気持ちは基本的にない。　

直すのなら、自分でシステムは直したい。そこで応募した。　

入れなければ、社外取締役はどうかなって思いました。

社外取締役はいかがでしょう

https://qiita.com/kaizen_nagoya/items/a77a81da08b17194699f

それはさておき、せっかくAdventCalendarの記事を書き始めたのに、これでは所定の記事が書けない。　

１日１０記事しか書けないかもしれない。　

新規投稿ができない場合でも、下書きは投稿できる。　

下書きの予備は、以前は１０だった。今はいくつか確かめてない。　

いずれにしても２０はないような気がする。　

昨日、新規投稿ができなくなり、どうしようかと思っていた。

今朝、新規投稿ができるように戻り、新たに下書きを１１個作っておいた。

夕方、下書きを編集して投稿した後、１舜だけ新規投稿ができた。１記事分。　

都合１１記事、今日、AdventCalendar2022に投稿した。　

この記事は、一般投稿にしよう。
Pythonで中学方程式の計算

Pythonで中学 数学の「方程式の計算」をする方法を紹介します。レベルは「中1」です。

## はじめに

Pythonがインストールしてあり、使い方を知っていることが前提です。

また、Pythonでの基本的な計算方法を知っておくことが前提です。
こちらの記事を参考にしてください。

https://qiita.com/akiba_burari/items/5bb4c083b30768a33aa1

## 必要なもの

Pythonが使えるデバイス。
パソコン、ラズパイ、タブレット、スマホなど。

※自分はChromebookのLinuxを使っています。

## sympyをインストールする

方程式の計算でも文字式と同様にPythonライブラリ「sympy」を使います。

最新版をインストールしましょう。

```
pip3 install sympy==1.9
```

sympyをインストールするには、Pythonがすでにインストールされていることが前提です。
インストールできない人は以下の方法でインストールできるかもしれません。※Linuxの場合です。

```
sudo apt-get install python-pip
sudo pip install sympy
```
## 方程式 一般的な解き方

このような問題があったとします。

### Q 次の方程式を解きなさい。

### 10x=4-6x

Pythonで解くには右辺の方をゼロにする必要があります。

したがって、次のように書き換えます。

10x-4+6x=0

これをもとにコードを書いていきます。※コピペして自分のファイルに保存してください。

```
import sympy 

x = sympy.Symbol('x') 
y = sympy.Symbol('y') 

print(sympy.solve(10*x-4+6*x, x)) #10x-4+6x=0
#出力結果[1/4]   答え　4分の1
```

## 問題点

しかし、この方法では、自分で「移項」させなければならず、非常に面倒くさいです。

よく考えてみると、左辺にあるものを右辺に移す際には、「すべてマイナスをかけてやればよい」ので、

コードに中にそれを書き込んで、自動で計算するプログラムにします。

## 工夫したやり方

自分で移項しないで方程式の問題を解いてみます。

### Q 次の方程式を解きなさい。

### 10x=4-6x

※コピペして自分のファイルに保存してください。

```
import sympy 

x = sympy.Symbol('x') 
y = sympy.Symbol('y') 

expr1=10*x #左辺
expr2=-(4-6*x)　#右辺 マイナスをかける

print(sympy.solve(expr1+expr2, x)) #xの値を出す
#出力結果[1/4]   答え　4分の1
```

## かっこのある方程式

工夫したやり方で「かっこのある方程式」を解いてみます。

### Q 次の方程式を解きなさい。

### 7x-6=3(x-4)

```
import sympy 

x = sympy.Symbol('x') 
y = sympy.Symbol('y') 

expr1=7*x-6
expr2=-(3*(x-4))

print(sympy.solve(expr1+expr2, x)) 
#出力結果 [-3/2]       答え　-2分の3
```

## 最後に

sympyについて調べていくと、「2次方程式」や「連立方程式」のコードもありました。

気になる人はコピペして試してみてください。


### 2次方程式

```
import sympy 

x = sympy.Symbol('x') 
y = sympy.Symbol('y') 

print(sympy.solve(x**2 - 3 * x + 2)) #xの2乗 -3x +2
# [1, 2]
```



### 連立方程式

```
import sympy 

x = sympy.Symbol('x')  
y = sympy.Symbol('y') 

expr1 = 3 * x + 5 * y - 29     #3x+5y-29
expr2 = x + y - 7 

print(sympy.solve([expr1, expr2]))
# {x: 3, y: 4}
```

## 関連記事

【超基礎編】Pythonで中学 数学の問題を自動作成する方法 - Qiita 

https://qiita.com/akiba_burari/items/f8a11cf0533b889e0af3

Pythonで中学 比例の計算・グラフを描く方法 - Qiita 

https://qiita.com/akiba_burari/items/954f832b408fef353aa3

Pythonで中学 文字式の計算 - Qiita 

https://qiita.com/akiba_burari/items/55ddae0c065fdccdef16

Python で計算する準備　足し算・引き算・掛け算・割り算・分数・累乗 - Qiita

 https://qiita.com/akiba_burari/items/5bb4c083b30768a33aa1
特定条件のみに呼応するプログラム作成

# 問題
今日の曜日を表示するコードをDateクラスを使用して記述してください。

ただし、金曜日だった場合だけ以下のように表示の内容を変えてください。

（出力内容）
「今日は月曜日」
「今日は金曜日だ ！！！」
![スクリーンショット 2022-11-25 19.43.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/20ca1f1c-a235-e6b7-fb4c-cd00f87acd57.png)

# 解答
![スクリーンショット 2022-11-25 19.44.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/d8b0f9a7-4c84-7eb7-d128-b710a6d78657.png)
　
　
　
# 解説
（1行目）Dateクラスをライブラリから呼び出す。

（3行目）wdayメソッドを用いて曜日を
　0（日曜日）から6（土曜日）の整数にしたときの
「今日」の値を取得する。

（4行目）配列daysを定義し、
　日曜日（0番）〜土曜日（6番目）まで文字列を格納する。

（6〜10行目）dayの値が5（金曜日）か否かで条件分岐させる。
　例えば、今日が金曜日だった場合はday=5となり、
　daysの5番目の値である金曜日が出力されるようになる。

# 反省
自分で考察する事ができなかったので、考察するだけの知識を
身につける事ができていないです。
次回は今回の知識を活かしプログラムできるよう挑戦します。
ruby in1to10　真偽値

# 問題
　
以下の条件を満たすin1to10メソッドを実装しよう
・第1引数のnumが1以上かつ10以下の範囲であればTrueを出力する
・第二引数のoutside_modeがTrueの場合は、
　第一引数numが条件範囲外でもTrueを出力する
・それ以外はFalseを出力する

~~~RUBY
  def in1to10(num, outside_mode)
    #ここに条件式を記述する
  end

# 呼び出し例
in1to10(5,false)
in1to10(11,false)
in1to10(11,true)
~~~

出力例
```
in1to10(5,false)→True
in1to10(11,false)→False
in1to10(11,true)→True
```
　
# 解答
![スクリーンショット 2022-11-25 19.05.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/87860168-d1d7-1a1b-a80d-b5e9d3ed8797.png)
　
　
　
# 考察

　if文を用いて第1引数のnumの条件式が合っている場合はTrueを出力する。
　次にelsifの条件式で第1引数がfalseの条件(numが1以下と仮定義)の場合でもoutside_modeがTrueとなる場合はTrueと出力することを定義
　最後にどちらもfalseの場合、elseを用いてfalseを出力するように記述した。
　
　
　
　
# 模範解答
![スクリーンショット 2022-11-25 19.14.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/ad2c31c3-338c-9ac2-9707-d1963b16d033.png)
　
　
　
# 解説
2行目では、論理演算子&&と||を用いて条件式を記述している。
###### (num >= 1 && num <= 10)|| outside_modeとは、
numが1以上かつnumが10以下、またはoutside_modeがtrueの場合を意味している。
それ以外(else)であればfalseと出力される条件を示している。

問題文の出力例の条件を当てはめていく。
![スクリーンショット 2022-11-25 19.20.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/d5f59632-f54a-da1c-c068-73920b818280.png)
　num=5の時点で(num >= 1 && num <= 10)の条件に
　当てはまっているので出力結果は「True」と出力される。

![スクリーンショット 2022-11-25 19.22.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/d48373c5-8c3b-0fad-2ce7-18dddfe9121d.png)
num = 11により numの条件式には当てはまらない。かつoutside_modeがfalseのため出力結果は「false」と出力される。

![スクリーンショット 2022-11-25 19.23.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/bbba6189-f40b-0eb1-6cb4-d24c19a6ddb9.png)
　num = 11のためnumの条件式には当てはまらない。
　しかしoutside_modeがtrueのため、「True」と出力される。
　
　
　
　
　
# 反省
まず、trueの場合とfalseの場合と大きく分類する必要があった。
その上で論理演算子を使用して条件式を定義していく事が必要であった。

aもbもtrueの場合にてtrue　は「　a && b 」

aかbのどちらかがtrueの場合は「a || b 」

rubyの論理演算子では左辺から右辺に条件式を評価する。
全体の評価が確定したらその時点で残りの評価は行われない。

「a && b 」においてaがfalseの時点で全体がfalseなので終了する。

「a || b 」においてaがtrueの時点で全体がtrueなので終了する。


今後は以上の要点を踏まえて記述していく。
Twitter Cardがロードはされるがプレビューが表示されなかった話

## Twitterカードのロードは成功するが、画像は表示されない

[TwitterのCard Validator](https://cards-dev.twitter.com/validator)で該当サイトを入力に入れると、Card loaded successfullyとは、表示されるものの、該当サイトをTwitterに投稿しても、プレビューは表示されないという問題に遭遇した。

```
INFO:  Page fetched successfully
INFO:  20 metatags were found
INFO:  twitter:card = summary tag found
INFO:  Card loaded successfully
```

## 拡張子を変更する

カードの画像の拡張子がjpegだったことが問題だった模様。画像のフォーマットを変更して、拡張子をpngに変更すると、問題なく表示された。

## サポートされているフォーマットはJPG, PNG, WEBP, GIF

[Twitter Developer Platform](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/summary-card-with-large-image)によれば、サポートされている画像のフォーマットはJPG, PNG, WEBP, GIFのみ。jpegとjpgは機能面では同じものと認識しているが、拡張子がjpgではなくjpegだったために弾かれたのだろうか...
class名やid名指定でaddEventListenerを処理させる方法

class名やid名の指定の仕方によっては、戻り値が変わってきます。（配列とかHTMLCollectionとかNodeListとか）今回はどんな形であっても、addEventListenerで処理させる方法をまとめます。

### document.getElementByIdの場合
~~~ JavaScript
const btn =document.getElementById("btn");

  btn.addEventListener('mouseenter', function() {
    //処理内容
});
~~~
`document.getElementById`の場合、途中の処理を必要とせず、直接記述できます。
### document.querySelectorAllの場合

~~~ JavaScript
const btn = document.querySelectorAll(".btn");

  btn.forEach(function(btn) {
  btn.addEventListener('mouseenter', function() {
    //処理内容
});
~~~
`querySelectorAll`の場合すべてのクラスに処理をかける必要があります。なので、forEach文で繰り返し処理を使って、配列の全てに処理をかけます。
### document.getElementsByClassNameの場合
~~~ JavaScript
const btn =document.getElementsByClassName("btn");
const btns = Array.from(btn);

btns.forEach(function(btn) {
  btn.addEventListener("click", function() {
  // 処理内容
});

~~~
`getElementsByClassName`の取得した場合戻り値は`HTMLCollection`になります。これは配列ではないので、`arry.from`メソッドで配列にします。そうすれば、あとは上記と同じような処理で動作します。

よくある指定方法をまとめました。
クラス指定する時は`querySelectorAll`が楽なのかな。
まだ`addEventListener`を満足に使いこなせていないです。なんかいいまとめサイトとかないかな。

### 参考記事

https://paralux.co.jp/blog/1177

https://logical-studio.com/develop/frontend/20191213-js-class-addeventlistener/

https://qiita.com/minhee/items/36da49954b0d6da48b77
[Hubspot] コンタクトのメモが記入された時にslack通知する


ワークフローで実現していきます

まずメモというのは、コンタクトページにおける、これです
![スクリーンショット 2022-11-25 18.47.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/9b70858a-e01f-1080-3e88-1deba044c8b8.png)

弊社ではよく使っています。

このメモが記入された時に読みたいというメンバーがいたので、slackに通知するようにしていきます。


# 作りかた
まずメモはコンタクトに紐づくものなので、コンタクト基点のワークフローを組んでいきます
[コンタクトベースのワークフローをテストする](https://knowledge.hubspot.com/ja/workflows/test-your-contact-based-workflow)

![スクリーンショット 2022-11-25 18.51.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/89c0596a-cc25-fc30-6cf1-b4d041a16d9e.png)

メモはアクティビティーに含まれるので「アクテビティーのプロパティ」を選択して

![スクリーンショット 2022-11-25 18.53.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/e34f8d90-c681-50e6-253a-bd1ea7ac2f7c.png)

「メモ本文」に値があるを条件にします

あとはSlackの設定をして完成です
![スクリーンショット 2022-11-25 18.55.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/0861ca56-26f3-66d1-b8f3-5b3218a630de.png)


こんな感じで通知が来ます

![スクリーンショット 2022-11-25 18.56.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/20b0979e-6116-4972-f899-fb3c08ae9ab8.png)

# まとめ
ワークフローでslack通知の紹介をしました。よくある通知系ワークフローですね。
コンタクトのメモをフックできるのは結構偉大だったので取り上げました


# 最後に
弊社では、一緒に働いてくれるエンジニアを募集しています。
↓最新技術や自社開発に興味のある方はこちらから↓
[Wantedly - スタジオアンビルト株式会社](https://www.wantedly.com/companies/studiounbuilt)

こんなWebサービスを作っています。
・[マドリー](https://madree.jp/)
・[Studio Unbuilt](https://www.studiounbuilt.com/)
Laravelのクエリビルダでjoinする

Laravelのクエリビルダでjoinするのに少しはまってしまったのでメモ。

以下の記載をしてみて、`toSql()`をしてSQLエディタに貼り付けると問題なく動くが、
Laravel上だとうまく動かない。。。

```php
->leftJoin('table1', function ($join) use ('table2') {
                $join->on("table1.columnA", '=', "table2.columnA");
                $join->where("table1.columnB", '=', "table2.columnB");
            })
```

何が問題だったかというと、`table2.columnB`が文字列として扱われてしまっていた。
それを解決するには`where`ではなく、`whereColumn`を使用する必要があるとのこと。

```php
->leftJoin('table1', function ($join) use ('table2') {
                $join->on("table1.columnA", '=', "table2.columnA");
                $join->whereColumn("table1.columnB", '=', "table2.columnB");
            })
```

単純な話ですがこれで無事に取得できました。
times　合計値

〜要件定義〜
・timesメソッドの繰り返し処理を使用して合計値を導き出すこと
　
　
　

〜問題〜
・1〜10の数値を順番に足し合わせる
・足し算の合計値がターミナルに出力される

sum = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
↑足し算のみのプログラムはNGで、ループ処理を用いて実装する事
　
　
　


〜解答〜
![スクリーンショット 2022-11-25 18.35.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/e8394e84-1db6-351c-6dd0-104904ad3652.png)
　
　
　


〜解説〜

このプログラムの考え方
①合計値を保存しておく変数sumを定義しておく
②変数sumに1〜10の数値を順番に足していく
③順番に足していく処理をtimes文に繰り返しで置き換える
④変数sumの値をターミナルで出力
　
　
　①合計値を保存しておく変数sumを定義しておく
　　1に2を足し、その結果に3を足し、その結果に4を足し・・・と
　　『その結果』を保存しておく変数が必要となる。
　　その為、sum=0にて変数sumを定義しておく必要がある。
　　まだ何も足していない状態なので、変数には0を代入しておく。

　
　
　
　　②変数sumに1〜10の数値を順番に足していく
![スクリーンショット 2022-11-25 18.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/35d2019a-6dfa-51be-d206-0853010d23a7.png)
　　1〜10を順に足しておくプログラムを記述していく。
　　↑上記は自己代入演算子を使用。

　　※コードが非常に長く、かつ同じ処理が続いている為
　　　times文を用いて効率的なコードに書き換える。
　
　
　
　
　③順番に足していく処理をtimes文に繰り返しで置き換える
　

　　times文を用いて何度も行っている処理をまとめる。
　　今回の例では『sum += 数値』の部分が当てはまる。
![スクリーンショット 2022-11-25 18.44.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929112/8e500b0a-f860-f441-9e29-8e9ce7d5d5ff.png)
　　↑上記の処理となる。
　　数値の部分は繰り返す毎に1回目は1、2回目は2、3回目は3のように数値が変化することが予測される。つまり繰り返しの回数を同じになる。
　　変数iの中に繰り返しの回数が数値として自動で代入される。

　　iの数値は0となるため、i + 1と記述する。
　
　
　
　　結果を保存する変数を定義する事を学ぶことができた。
[Hubspot] コンタクトリスト利用ケース


公式の使い方説明は[リストを作成して使用する](https://knowledge.hubspot.com/ja/lists/create-active-or-static-lists?KBOpenTab)から参照ください

公式ドキュメントにリスト自体の使い方は十二分に載っているので
ここでは、実際の利用ケースを紹介します。

# 「障害で影響を受けたリストを出して」
今は復旧しましたが、システム不具合の影響を受けたユーザがいそうなので
対象のコンタクトリストを出す必要になりました

不具合によってデータ欠損が起きているようなので
それを条件にして静的リストを作成します

[コンタクト]　-> [リスト]　
名前と静的リストを選択

![スクリーンショット 2022-11-25 17.48.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/389b2f84-a5b5-b4ff-1314-a9dd45b4f7d3.png)

今回は郵便番号が取れなかった(仮定)として、条件このようにします

あとは「リストの保存」をしすると、対象のコンタクトのリストが作成されます。
処理に時間がかかる場合があるので気長に待ちましょう。

最後にリストページのURLを依頼者に渡して完了。簡単。

# 「メルマガでサイト流入したユーザを出して」
トラキングコードがサイト内に埋め込まれている
＆ メルマガのリンクに utm_campaign のパラメータが付与されていたら
特定可能です

リストの条件としては以下の感じになります

![スクリーンショット 2022-11-25 17.59.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/9026ea66-da29-de4b-06cf-07c4784a320e.png)

Hubspot経由でないEメールにおけるURLのutm_campaign パラメータは
「他キャンペーン」に分類されます
([オリジナルソースおよび最新ソースのプロパティーについて](https://knowledge.hubspot.com/ja/contacts/understand-source-properties))

また、最新のソースドリルダウンにパラメータの値が入るので、ここでは「mailmaga」として絞り込みをします

こうして出力されたリストは、同じくURLを依頼者に渡して終了です

一点注意なのは、”最新”のソースなので、次のメルマガリンクを踏んでしまったら、変更されてしまう値です。
また、これまでのソース歴に対して検索をかけることはできません
静的リストを利用することをお勧めします

# 「LINE返信がない人を出してほしい」
LINEと連携していて、
自動応答の返信はしたが、自由入力の返信を頂けていない人をリストに出します
(LINEの連携にはLittle Helpを利用していますが、それについては別記事で)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/9b2e9e7f-07e3-bc2e-6fac-e26fa1f1e7e4.png" width="397px">

返信メッセージは「LINE Last Reply Message _ 1」のプロパティに入るので
これが不明であることを条件にし
かつ、自動応答のメッセージに対して回答したことも条件にします

自動応答には返信をしたけど、自由入力で離脱したということが分かり
リマインド対象リストとしても活用できます

# まとめ
実際の利用ケースに沿ってリストを使う場面を紹介しました

コンタクト一覧では検索する条件の種類が少し乏しいので、
ゴリゴリ検索をかけてリストを出したい、誰かと結果を共有したいときにコンタクトリストは便利です。
また、リストをベースとしたグラフ化や自動化もできるので、
まずコンタクトに対して何か処理をしたいときは、私はリスト作成からするようにしています、おススメです.

# 最後に
弊社では、一緒に働いてくれるエンジニアを募集しています。
↓最新技術や自社開発に興味のある方はこちらから↓
[Wantedly - スタジオアンビルト株式会社](https://www.wantedly.com/companies/studiounbuilt)

こんなWebサービスを作っています。
・[マドリー](https://madree.jp/)
・[Studio Unbuilt](https://www.studiounbuilt.com/)
UdonでVRCのメニューを開いているか検知する

# 方法
UdonでVRChatのメニューは本来取れませんが、クイックメニューなどのUIにはレイが当たるようにするためのコライダーがあり、Physics.OverlapSphereなどのレイキャスト系のメソッドで取得できます。
ただし、IsValidでfalseになり、それ自体のデータは取ることができず、「そこにある」ということだけわかります。
それで取得したコライダーの数でメニューが表示されていることがわかります。

:::note warn
**注意**
この方法は2025/01/11時点での方法です。
この方法はVRChatのアップデートで利用できなくなる可能性があります。
:::

# コード
```csharp
int intUI;
VRCPlayerApi localPlayer;

private void Start()
{
    localPlayer = Networking.LocalPlayer;
}

private void LateUpdate()
{
    intUI = Physics.OverlapSphere(localPlayer.GetPosition(), 10F, 524288).Length;
    if (intUI == 11 || intUI == 12 || intUI == 13 || intUI == 14 || intUI == 15 || intUI == 16 || intUI == 17 || intUI == 18 || intUI == 19)
    {
        // クイックメニューが表示されている
        Debug.Log("クイックメニューが表示されています。");
    }
    else if (intUI == 8 || intUI == 9 || intUI == 18 || intUI == 19 || intUI == 20)
    {
        // メインメニューが表示されている
        Debug.Log("メインメニューが表示されています。");
    }
}
```
PCゲームにおけるテスト観点について考えてみた

# はじめに
皆さんこんにちは！

今年もアドベントカレンダーの時期がやってきました！

今年はどんな記事を書こうか考えていたのですが、いま動いている案件でモバイル→PC展開を目指すプロジェクトがあり、出すにあたってどういうテストが必要なのかを考える時間が多かったので、そこでの気づきなどを記事にしようと思います。
これからPCゲームをテストする方に向けて、少しでも参考になれば幸いです。


# モバイルとPCの違い
当然のことながらハードが違うのでテストの要件も変わってきます。

例えば、PCだと基本的にはキーボードとマウスでプレイするのでキーコンフィグの実装やマウス操作などモバイルとは違ったテストが必要になってきます。
場合によってはコントローラー対応も入ってくることがあります。

そのほかにも、CPU、GPU、RAMなどの組み合わせ次第ではモバイル以上にスペックが多種多様になるので、多端末検証をどこまで担保するかも重要になってきます。

例えばCPUだとIntelとAMDに大きく分かれ、コア数、スレッド数、クロック数など世代によって違いますし、GPUやRAMも機器によってスペックが様々です。
（なので、どれとどれを組み合わせてテストするかは開発サイドと相談しながら進めていくのが吉）
![image (75).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541094/cb292d50-b4e1-0de7-226d-c5095e48dc6a.png)


次はどういうテストが必要なのか、テスト観点をまとめたので例を記したいと思います。


# PCゲームのテスト観点
あくまでも一例ですので参考程度にしていただければと思います。

## ゲーム操作周り
基本的にゲーム操作は各デバイスの動作確認がメインになってくると思います。
キーボードは各配列ごとの確認だったり、コントローラによる動作確認、マウスだとボタンやホイール、マウスを動かしたときの確認が必要です。
基本的には仕様として定めた要件通りに動くかの確認（WASDやスティック操作でキャラが動くか）がメインで、特にキーボード周りだとキー配列が変更できるかも確認が必要になってきます。
他にも純正機器かどうか、接続状態が有線/無線など、パターンがいくつも存在するのでどこまで担保するのかは開発側と相談する必要があります。

![image (72).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541094/c0a9cae0-188c-7910-0505-b87daca3b12f.png)


## PF間の引継ぎ
モバイルからPCに展開する場合、PCと併用するユーザーが多いので、PF間で正常にデータの引継ぎができるかが重要になってきます。
要件によってさまざまかもしれませんが、基本的にはモバイルとPCの相互でデータの引継ぎができるか、引継ぎ後に問題なくゲームをプレイできるかのテストが必要です。
また、引継ぎ後の元の端末ではどういう動作をしているのが正しいのか、各PF特有の機能で引継ぎやアカウントを切り替えたときの挙動も確認が必要になります。
（先述した通り、モバイルとPCを併用するユーザーが多いので、どちらのPFでもプレイできるかのテストが必要になります）

![image (73).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541094/468a4c09-898e-e571-9cd2-85ec47ed5d95.png)


## 課金検証
ここは言わずもがなですが、モバイルとPCだと決済手段が別の場合が多いのと、返金などの障害発生リスクが高いためPC版でも必須の項目になります。
テスト観点としては、モバイル版とそこまで大きく変わる部分はないと思いますが、
PC特有の観点もあるので確認する際はしっかり押さえておきたい部分になります。
※PCだと決済手段が豊富にあるため（paypal、stripeなど）

![image (74).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541094/3ff734ad-03de-5882-ba05-fe5a0a9da654.png)




# 最後に
少しではありますが、PC版検証におけるテスト観点を書き連ねてみました。
モバイルゲームのQA一辺倒だった私にとってはいろいろな発見があったのでとても勉強になりました。
これから同じ境遇の方がこの記事を読んでテストする時の参考になればと思っています。


それでは、みなさんよいクリスマスを:xmas-tree::xmas-wreath1::xmas-wreath2:
QlikView：データ圧縮の仕組み Symbol Tables and Bit-Stuffed Pointers

# はじめに
先日ふと気になり、QlikViewのデータ構造が列指向なのか調べてみました。
その際に見つけた記事について、自分なりにまとめてみました。

出典：[Symbol Tables and Bit-Stuffed Pointers - Qlik Community - 1475369](https://community.qlik.com/t5/Design/Symbol-Tables-and-Bit-Stuffed-Pointers/ba-p/1475369)

結論からいうと、QlikViewは厳密には列指向ではなく独自のデータ構造となっているようです。
ただ内容としては、列ごとで圧縮する構造など、列指向とほぼ同じという印象でした。

# そもそも行指向・列指向とは
行指向・列指向とは、データを格納・取得・管理するための構造のことです。
一般的にECサイトなどの業務システムで使用されるデータベースでは、行指向（行ストア）の構造が使われます。
一方、データ分析のためのデータマートやDWHでは、列指向（列ストア・カラムナー）の構造が使われます。
それぞれの特徴は次のとおりです。

* 行指向
	* ECサイトなどの業務システム向けの仕組み
	* 行ごとにデータが格納される
	* 取得したいカラム以外のすべてのカラムも読み込まれてしまう
	* 行を素早く特定できる

* 列指向
	* DWHなどの分析システム向けの仕組み
	* 列ごとにデータが格納される
	* 必要なカラムのみ読み込むことができる
	* 行単位の処理は不向き

![行指向と列指向の違い](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/c681f474-9e1c-eb11-5284-7fbbc03b60e8.png)

列指向は列ごとに圧縮するため、同一のデータが多いほどデータ圧縮の効果は高くなります。

![列指向の圧縮](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/7a762a7c-3ab5-232b-f315-5450308e973f.png)

# QlikViewのデータ構造について
ここから本題です。
まずQlikViewは、ロードしたデータを2つのテーブルタイプに変換します。
データテーブルとシンボルテーブルです。
シンボルテーブルは、ロードしたテーブルのカラムの数だけ作成されます。
たとえば3つのカラムからなるテーブルをロードした場合、Qlikのエンジンは1つのデータテーブルと3つのシンボルテーブルへ変換します。

![テーブルタイプ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/4debf601-94f6-eefc-d61c-d0bce6555c5d.png)

## データテーブル（Data table）
データテーブルは、ロードしたテーブルと同じ数の行、同じ数の列で構成されます。
テーブルにはポインターのみを保持しており、データそのものは含まれていません。
しかし、ポインターを使ってシンボルテーブルから値を検索するため、情報が失われることはありません。

![データテーブル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/5a482c99-25c1-ec93-b0b6-eb0f24215bde.png)

## シンボルテーブル（Symbol tables）

シンボルテーブルは、ポインターとデータの値（テキストや数値）の2つのカラムを保持しています。
データの値は一意になっており重複はありません。
シンボルテーブルは、データテーブルから値を検索するためのテーブルです。

![シンボルテーブル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/7a7454ab-c935-8413-d9ff-7004ad941733.png)

## ビットスタッフドポインター（bit-stuffed pointers）
データテーブルとシンボルテーブルをつなぐポインターをビットスタッフドポインター（bit-stuffed pointers）といいます。
このポインターは、データ値を表現するのに必要最低限なビット数だけで構成されています。
たとえばある列に4種類の値があった場合、4つの値を表現するのに必要なビット数は次の表のように2ビットであるため、データテーブルが非常に小さくなります。

| Pointer | 性別 |
|:--|:--|
| 00 | 男 |
| 01 | 女 |
| 10 | その他 |
| 11 | 未回答 |


# 最適化の例
シンボルテーブルとビットスタッフドポインターという構造によって、Qlikはデータを圧縮できます。
Qlik Senseについても同じエンジンを使っているため、QlikViewとQlik Senseのどちらも同様です。
この構造には、次のような特徴があります。

* ポインターの長さは、シンボルテーブルのサイズに影響する
* 列内の一意な値の数は、ポインターの長さだけではなく、シンボルテーブルの行数にも影響する

Qlikを最適化するための例を紹介します。

## Autonumber()を使用する
たとえば、表示する必要のない長い連結された複合キーがあった際には、Autonumber()を使用するとデータを最適化できます。
ポインター自体が連番の情報をもつため、シンボルは不要になりシンボールテーブルのサイズをゼロにできます。

## 列を複数に分解する
秒単位でデータを保持しているタイムスタンプの列があった際に、時間を15秒間隔や1分単位で丸めると、一意の件数を減らすことができるため、データサイズを縮小できます。
また、日と時間の2つの列に分割しても一意の件数を減らすことができます。
一意の値が10万種類を超えるようなら、2つの列に分割することを検討する必要があります。

# さいごに
今回参考にした記事が載っている「[QlikView Design blog](https://community.qlik.com/t5/Design/bg-p/qlik-design-blog)」には、他にもQlikに関する情報がたくさんありそうでした。
今回Qlikの内部構造について調べてみましたが、日本語の記事はほとんど見つけらなかったので、頑張って英語の記事を読んでみようと思いました。
LGTMのGIFを簡単に貼れるChrome拡張をつくったよ

# 作ったもの

**ランダムで良い感じのLGTMのGIF画像を貼り付けられます**。
↓こんな感じです!!:heart_eyes:

![EZTMのデモGIF](https://user-images.githubusercontent.com/53589952/203290886-3e8a7d8b-a0c2-4113-bc0c-967893a8cadf.gif)


ストアページ

https://chrome.google.com/webstore/detail/eztm/pilidjngjpaijlblpfdncckldgecngak

# なぜ作ったか

最近LGTMするときに、LGTMのGIFを付けるのにハマってました。
GIF画像は https://www.lgtmgifs.com/ のようなページから毎回コピペしてたんですが、
絶妙にめんどくさかったです。笑
それを解決するためにつくりました!


# ソースコード

簡単なアプリなので、正直JavaScriptだけでもいいのですが、
TypeScriptが好きなのでTypeScriptで書きました。
webpackとmanifest.jsonのくだりが少々面倒でした。

ソースコードは公開してあります。


https://github.com/kakudenbuzo/eztm

### 工夫した点

強いて言うなら、カーソルが当たっている箇所にGIF画像のマークダウンが挿入されるようにしたことです。
カーソル位置は`document.activeElement.selectionStart`で取得しました。

# 今後の課題

### 1. GIF画像の種類が少ない
現状、10枚分のGIF画像のURLがソースコードにべた書きとなっている。
それについて以下を検討しました。
- ユーザが任意でGIFを追加できる仕組み
    - →ユーザの手間が増えるので当分はこの機能は入れない予定
  
- **開発者側(私)がもっとGif画像を用意しておく**
    - **→これでいこうと思います!目標100枚!**

### 2. 使い方が分かりにくい
現状、目に見えるボタンが設置されるわけでもなく、

- 右クリックでコンテキストメニューを開いて「Insert LGTM gif」をクリックする
- または、ショートカットコマンド(shift + cmd + v)をする

のいずれかを行わないと機能が使えない。

はじめて使うユーザだと、使い方が分からない可能性があるので分かりやすくする工夫が必要かもしれない。

### 3. 機能のトリガーをもっとよくできそう
   
ユーザが特別な操作を行わなくても、欲しいタイミングでLGTM画像が自動で張り付けられれば、
もっと便利になると思います。
具体的なトリガーの案としては以下のような感じでしょうか？ 
- コメントにLGTMと入力したとき
- Approveをクリックしたとき


# おわりに

**LGTMのGIFは気持ちがアゲアゲになるのでオススメです！**
気になった人はぜひEZTM使ってみてください。
フィードバックなども大歓迎です!コメントにお願いします!!
今後もアップデートしていく予定です:ok_hand_tone5:

↓ストアページ

https://chrome.google.com/webstore/detail/eztm/pilidjngjpaijlblpfdncckldgecngak
JSのプラグイン「Swiper」を使ってみた

# はじめに

今回の記事では、JavaScriptのSwiperというライブラリについて

実際に使ってみた感想も踏まえて解説したいと思います。

結論から言うと、かなり簡単に時間をかけずに実装ができます。

# JavaScriptの無料実践学習

とにかく手を動かしながらJavaScriptの学習を始められるサイトです。

また、忍者CODEでは有料コンテンツも用意されており、更にスキルを伸ばしたい方には低コストで学習できるサービスです。

https://ninjacode.work/


https://koga.ninjacode.site/?ni=q_2

# Swiperとは？使用に至った理由

私はWebアプリを制作する中で、トップページは印象に残りやすい動きのあるものがいいなと考えておりました。

検索をしているとjQueryを使った実装が多く、これまでjQueryを触ったことがなかった私にとっては学習コストがかかってしまうため、

ほかの方法を探していたところjQueryが不要な「Swiper」にたどり着きました。

# Swiperを導入することで可能なこと

- スライドをループさせる
- スライドのスピードを変更できる
- スライドの自動再生
- スクロールバーの表示
- スライドにページネーションを付けられる
- スライドにホバーした時にズームインする
※他にもいろいろあります

# Swiperの導入手順

手順は2つだけです。

- ファイルの読み込み
- HTMLとJSのコーディング

### ファイルの読み込み

ファイルを読み込む方法は2パターンあり、CDNでSwiperを読み込む方法と、NPMなどからダウンロードしてローカル環境に設置してから読み込む方法があります。

手っ取り早く利用するのであれば、CDNから読み込む方法がおすすめです。

CDNの場合、公式サイトの最新版のCDNを読み込んでください。
```HTML:HTML
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.css"
/>

<script src="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.js"></script>
```

### HTML・CSS・JSのコーディング
```HTML:HTML
<!-- スライダーのコンテナ -->
<div class="swiper">
  <!-- 必要に応じたwrapper -->
  <div class="swiper-wrapper">
    <!-- スライド -->
    <div class="swiper-slide">Slide 1</div>
    <div class="swiper-slide">Slide 2</div>
    <div class="swiper-slide">Slide 3</div>
    ...
  </div>
  <!-- 必要に応じてページネーション -->
  <div class="swiper-pagination"></div>

  <!-- 必要に応じてナビボタン -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>

  <!-- 必要に応じてスクロールバー -->
  <div class="swiper-scrollbar"></div>
</div>
```

```CSS:CSS
.swiper--wrapper {
  /* wrapperのサイズを調整 */
  width: 100%;
  height: 300px;
}

.swiper-slide {
  /* スライドのサイズを調整、中身のテキスト配置調整、背景色 */
  color: #ffffff;
  width: 100%;
  height: 100%;
  text-align: center;
  line-height: 300px;
}

.swiper-slide:nth-child(3n + 1) {
  /*1、4、7、3n+1枚目の背景色 */
  background-color: #de4439;
}

.swiper-slide:nth-child(3n + 2) {
  /*2、5、8、3n+2枚目の背景色 */
  background-color: #fcd500;
}

.swiper-slide:nth-child(3n + 3) {
  /*3、6、9、3n+3枚目の背景色 */
  background-color: #53c638;
}
```

```JavaScript:JavaScript
const swiper = new Swiper(".swiper", {
  // ページネーションが必要なら追加
  pagination: {
    el: ".swiper-pagination"
  },
  // ナビボタンが必要なら追加
  navigation: {
    nextEl: ".swiper-button-next",
    prevEl: ".swiper-button-prev"
  }
});
```
新卒1年目がストレージ用語をまとめてみた 第2回：ストレージ機能編


## この記事について
この記事では、私（新卒1年目）のように最近IT業界に参入された方が読んで、
「この単語はこんな感じの意味合い」ぐらいに理解を深めていただけれるよう書いています。
もちろんスキルアップのために詳しい勉強は必要になってきますが、「本格的な勉強の前に軽く理解したい」「ちょっと度忘れした」、
みたいな時に本記事を活用していただけたら幸いです。
理解しやすいようかなり砕けた言葉遣いで書いております。
今回は第２回目ということで、ストレージに一般的に搭載されている機能についてフォーカスしていきます。

## ストレージ効率化機能
#### 重複排除(デ・デュプリケーション)
データをストレージ装置に格納・バックアップする際、重複するデータブロックを1つだけ格納することでストレージの消費容量を削減する技術です。
皆さんも身に覚えあると思いますが、一部書き換えただけのデータ、ファイル名が異なるだけのデータとか保存しちゃうことありますよね？
これらデータを指定バイト数で精査し、既に格納されたデータと重複しているデータは新たに書き込みを行わないように動作します。
↓こんな感じで、内容はそんなに変わらないファイル群の差分だけ保管することで、容量使用を抑えられます。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504005/62c7c03f-06ab-3825-af2d-65bc722a68c9.png)

#### データ圧縮
「符号化」と呼ばれる、データをある法則（アルゴリズム）で計算して変換することで、
元のデータの内容を損なわずにデータのサイズを減らす方法です。


#### ストレージ仮想化
仮想的にストレージを管理することで、物理的な制限に捉われない使い方です。
複数のストレージを仮想的に一つのストレージとして管理することもできたり、
逆に一つのストレージを仮想的に複数のストレージとして分割して使うことも可能です。

#### （VMware）
仮想化という観点から、サーバ仮想化の技術についてご紹介します。
VMwareという会社が提供している、vShpereという商品があります。
1台のサーバ上に複数台の仮想サーバを稼動して、
WindowsやLinuxなど複数のオペレーティングシステムを同時に実行するソフトウェアです。
vSphere上で動作する仮想サーバはそれぞれ独立したサーバとして認識され、
物理サーバが複数台ある環境と同等の操作が可能になります。
この独立したサーバ群が仮想化されたストレージを利用するので、
ストレージとは切っても切れない関係にあります。


## データ保護機能
#### バックアップ
最近は企業で利用するデータのほとんどが、デジタルデータとして保存されています。
しかし、人為的なミス、コンピュータ・ウイルス、機器類の故障、事故、天災などが原因で、データを一瞬にして失う可能性があります。
コンピュータに保存されたデータやプログラムを破損やコンピュータ・ウイルス感染から守るために
別の記憶装置に保管したり、データを復元できる形(後に紹介するsnapshot)で保存することをバックアップといいます。


#### 差分(増分)バックアップ
毎回すべてのデータを保管するのではなく、前回のバックアップ以降の変更分をバックアップの対象とする方法。

:::note info
ポイント
ここで私考えました、じゃあ差分バックアップした内容はデ・デュプリケーションされて残った部分と一緒なのでは？？
しかし考えてみると、少し違う。。
例えば、ディスクにデータがあったとして、差分バックアップを取ったら５GBでした。差分バックアップはこれで完結。
しかし、その取れた５GBのバックアップデータの中から、ディスクが既に持っている部分があるかもしれません。
バックアップの前にデ・デュプリケーションをしたら、今度は差分バックアップの容量が3GBになりました、ということも起こりえるのです。
:::

#### リストア
システムやディスク、データベースなどが破損したり、不安定になったりした際、復旧・復元すること。
方法として別の記憶装置にバックアップされてあったデータを用いて、データを元の状態に戻すことである。


#### バックアップ世代管理
バックアップというのは、一般的に毎日だったり毎時のように定期的に取ります。
リストアする時点を柔軟に選択できるように、複数のバージョン(世代)のバックアップを保管する管理方式です。

#### 冗長化
自然災害や障害時の対策の為、システムの構成を通常構成以外に予備の装置などを加えることです。
異常が起こった際、欠損した機能を予備の装置が補ってくれるので、
システム利用者からはシステムの異常を体感することはありません。


#### フェイルオーバ
故障したコンポーネントで行っていた処理を、代替コンポーネントが引き継ぐことでシステムを継続稼働させます。


#### ミラーリング機能
データの複製をコピー先のディスクにリアルタイムに転送、保存することです。
元のストレージの複製ができるので（複数でも可）、よりデータを失いにくくなります。


#### RPO（Recovery Point Objective）
システム障害が発生した時点から、過去の復元したい時点までの時間の目標値です。
事業継続・災害対策を構築する上で重要な指標となります。
例えばRPO=2時間であれば、障害が発生した時点から2時間前までの状態に
復元できるようにバックアップや冗長化の設計・実装を行う必要があります。

#### RTO（Recovery Time Objective）
システム障害が発生した時点から復元するまでの時間の目標値です。
こちらも事業継続・災害対策を構築する上で重要な指標となります。
逆に言えばどれだけの時間システム停止が許容できるか。
病院、銀行、官公庁などは長時間のシステム停止を許容できないので、
RTOをできるだけ0に近づけられるよう設計しています。

#### ディザスターリカバリー(DR)
予期しない災害 （地震、火災、水害、テロなど）によって引き起こされる「システム障害を復旧させる作業」という意味。
いかに高信頼なシステムを構築しても、災害などのトラブル時に業務復旧までの損失は無視できません。
しかし、必要となるネットワーク機材や、専用回線維持費を含めた運用コストの課題もあり、
ビジネスクリティカルなシステムを運営している企業はここに莫大な投資を強いられます。
RPO/RTOとコストのバランスを考慮しながら実装方式を検討することが重要です。
【2022年度】ReactNative関連のブックマークを整理

### はじめに
ReactNativeにハマって気づいたら約4年目ですがChromeにブックマークしてあるリンク集を一度整理します。
その中で不要になったものはこの記事に供養していき、開発者及び記事作成者への感謝を伝えられたらなと思います。
いつも窮地から救っていただきありがとうございます。

今はメジャーではないライブラリ等あるかもしれませんので
その場合はご指摘いただけますと幸いです。

* * *
（1）Expo Examples
まずはExpoを用いたサンプルプロジェクト群
バージョンが古いのでそのまま流用はできないことがほとんどですが、いざ困ったときように頭の片隅にあるともしかしたら役にたつケースがあるかもしれません。

https://github.com/expo/examples
* * *
（２）Expo SDKまとめ
ExpoのAPI周りを日本語で簡潔にまとめてくださっている記事。ざっくりとネイティブのどんな機能を提供しているのか把握しておくといざというときに「そういえばExpoにあったな。」となるかもしれませんのでぜひご一読を。

https://qiita.com/ya_s_u/items/5f7117496695f21e2b98
* * *
（３）ドラッグ&ドロップ関連ライブラリ
最近DnD辺りを実装していないので流行りのライブラリは不明ですが、PanGestureと多少数学の知識があれば自作も実現可能のはず
要件を満たせない場合は以下のコードを参考にカスタマイズしてみてください。

https://github.com/computerjazz/react-native-draggable-flatlist
https://github.com/gitim/react-native-sortable-list
* * *
（４）Stripe
webアプリやネイティブでのスマホ決済対象外商品の決済などで役立つStripe
それをReactNativeで実装した際にお世話になったリンクです。
ワンナイト人狼学生の時にめっちゃしてました。てるてるが大好きです笑
https://stripe.dev/stripe-react-native/api-reference/index.html
https://qiita.com/mogmet/items/cddc182156028c928ecf
* * *
（５）カルーセル
以下ライブラリがシェアを独占してそうですが、
要件を満たせない場合はScrollViewとReAnimatedで自作した方が早いかもしれません。

https://github.com/meliorence/react-native-snap-carousel
https://github.com/dohooo/react-native-reanimated-carousel
* * *
（６）アニメーション
自作アニメーションを作るのであれば基本これ一択。
既にUIスレッドからの脱却は実現しパフォーマンスはかなりよくなるものの、
最近どこかでさらにパフォーマンスが良くなると噂を聞きました。楽しみで仕方ない・・！！！

https://docs.swmansion.com/react-native-reanimated/
* * *
（７）通信デバッグ
自作アプリや他アプリの通信をデバッグする際に使うCharles
これを知ってると選択肢の幅が広がるので一度試しておくとネイティブエンジニアとして強くなれるかもしれません。
悪い使い方はしないようにご注意ください😇

https://qiita.com/usagimaru/items/d340e87da98e62f99b60#ios
* * *
（８）FlashList
リスト関連でパフォーマンスを向上させたい時はこちらを試してみてください。
RN標準のFlatListとほぼ同じpropsなので実装も楽です。
ExpoでもSDK v46でサポートされるようになりました。

https://shopify.github.io/flash-list/
* * *
（９）SVG
A. webのsvgをReactNative用にpathとか抜き出したいよおおお
B. pngをsvgに変換したいよおおおお
って時に便利な変換サイトです
A. https://transform.tools/svg-to-react-native
B. https://www.freeconvert.com/png-to-svg
* * *
（１０）写真や画像
アイコンや静的画像などは圧縮してなるべくアプリサイズを下げたいと思います
そんなときに最適化やbase64への変化を行うようでつかうサイトたち。
https://imagecompressor.com/ja/
https://www.base64-image.de/
* * *
（１１）ReactNativeの全貌（？）
ReactNative用のライブラリやサンプルPJなど。
とにかくすごいボリュームでまとめられてるので一度リンクを開いて眺めてみてください。
https://github.com/jondot/awesome-react-native
* * *
（１２）LottieFiles
Lottie用の素材を探す際には利用しておきたい神サイト
見てるだけでワクワクするようなアニメーションが大量にあるので眺めるだけでも楽しいと思います。

https://lottiefiles.com/popular?sort=all-time
* * *
（１３）画像からカラーコードを抽出
アイコンとアプリデザインで色を統一したいけどカラーコードがわからない！
といった状況でもこのサイトがあれば解決できます。シンプルに便利

https://lab.syncer.jp/Tool/Image-Color-Picker/

### おわりに
Flutterでも半年ほど実務経験を積んでいますが、
まだまだReactNativeへの愛情は消えそうにないです。
それどころか日に日に増しています笑

その愛をそろそろ形として業界に貢献できたらなと少し思い始めましたので
今後とも発信できるよう努力していきます。。。！

Twitterで雑に絡んでいただけると嬉しいです。
https://twitter.com/nakapooooon

最後まで読んでいただきありがとうございました😊
teradatamlデータフレームでCSVファイルをテーブルにロードする

[Teradata® Package for Python Function Reference](https://docs.teradata.com/r/Teradata-Package-for-Python-Function-Reference/April-2022) [リリース番号：17.10　リリース日付：2022/4]の翻訳です。

# はじめに
PythonでVantageにテーブルを作成しCSVデータをロードする方法を説明します。
ライブラリとして[teradataml](https://pypi.org/project/teradataml/)を利用します。

:::note info
**teradataml**はTeradata Vantage用のPythonライブラリです。
:::

# データの準備
## sklernのIrisデータセットを読み込む
```Python:python code
import pandas as pd
from sklearn import datasets
iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['target'] = iris.target_names[iris.target]
```

## データの中身を確認する
```Python:python code
df.head()
```

||sepal length (cm)|sepal width (cm)|petal length (cm)|petal width (cm)|target|
|:-|:-|:-|:-|:-|:-|
|0|5.1|3.5|1.4|0.2|setosa|
|1|4.9|3.0|1.4|0.2|setosa|
|2|4.7|3.2|1.3|0.2|setosa|
|3|4.6|3.1|1.5|0.2|setosa|
|4|5.0|3.6|1.4|0.2|setosa|

## CSVファイルを作成
```Python:python code
df.to_csv('iris.csv', index=False)
```

# 基本操作 (ここから本編)
## Vantageに接続する
```python:python code
# 接続用ライブラリの宣言
import teradataml as tdml
# データベース接続
tdml.create_context(host = "IPアドレス",username='ユーザ名',password='パスワード')
```

## pandas DataFrameにiris.csvを読み込む
```python:python code
# csvファイルをpandas DataFrameへ取り込み、カラム名を変換する。
pd_iris = pd.read_csv('iris.csv')
col = ['sepallength', 'sepalwidth', 'petallength', 'petalwidth', 'target']
pd_iris.columns = col
```

## pandas DataFrameからテーブルを生成する
```python:python code
# Teradata上へテーブルを作成
tdml.copy_to_sql(df = pd_iris, schema_name='ユーザ名', table_name='iris_table',
            index=True, index_label='idx', primary_index='idx', if_exists='replace')
```

## テーブルを指定してデータを取得する
```
# Customerテーブルのデータをteradatamlデータフレームに読み込む
tdml.DataFrame.from_table("iris_table")
```

<details><summary>結果を表示</summary>

```
     sepallength  sepalwidth  petallength  petalwidth      target
idx                                                              
109          7.2         3.6          6.1         2.5   virginica
118          7.7         2.6          6.9         2.3   virginica
24           4.8         3.4          1.9         0.2      setosa
16           5.4         3.9          1.3         0.4      setosa
72           6.3         2.5          4.9         1.5  versicolor
41           4.5         2.3          1.3         0.3      setosa
45           4.8         3.0          1.4         0.3      setosa
47           4.6         3.2          1.4         0.2      setosa
29           4.7         3.2          1.6         0.2      setosa
145          6.7         3.0          5.2         2.3   virginica
```
</details>

## Vantageから切断する
```python:python code
# データベース切断
tdml.remove_context()
```

# おわりに
:::note warn
警告
この本書は[Teradata Vantageドキュメンテーション](https://docs.teradata.com/)よりトピックに必要な情報を抜粋したものです。掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。正確な内容については、原本をご参照下さい。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::

## Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)