OmniAICreator/Qiita-1.07M huggingface dataset:
for文(繰り返し処理) 


# 今回の授業資料

<script async class="speakerdeck-embed" data-id="a58f3a42e9744aeb906371e6e21c29ee" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

# 本日の内容
どんなプログラミング言語に限らず，
・(前々回まで扱った)単数複数のデータを扱う変数や，print関数，input関数など
・(前回扱った)if文
・(今回はいよいよ)繰り返しの処理
は日常どーーんなアプリケーションでも使われているアルゴリズムになります．そこで今回は，

### for文で繰り返し処理のコードが書け，実行までできるようになろう！!

((エディタの**新規作成**はVS Codeにて，**Cmd/Control** を押しながら，**N**を押すと，作成できます．))

繰り返し処理には **繰り返す範囲や条件**が必要になります．
**シーケンス(sequence)**：連続しているもの．コーディングの際は「連続したデータ配列」のことを意味します.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271604/3907bdd9-29da-701a-43f4-7755a434d88b.png)

まだ少しイメージが曖昧かと思うので，早速コードを見ていきましょう．

## 【例題】お寿司屋のネタ一覧が見たい

仮に，寿司屋の全メニューが「イカ」「タコ」「ホタテ」「サーモン」「シメサバ」がだとしましょう（行きたいか否かは置いておいて）．

**ターミナルでの出力**

```
イカ
タコ
ホタテ
サーモン
シメサバ
```
これらのメニューを上記のような出力例で全表示するには例えば，

```
print('イカ')
print('タコ')
print('ホタテ')
print('サーモン')
print('シメサバ')
```
と地道に書くことができるでしょう．でもメニューは変動し，本来であればもっと多種類あるはず．あまり現実的ではない記述方法です．そこで一旦メニューの変動性を考慮し，単品ネタをリスト型の変数「sushi_menu」とし代入しましょう．

https://qiita.com/Rumi_Yamaguchi/items/57bde81447b5508598b7

```
sushi_menu = ['イカ','タコ','ホタテ','サーモン','シメサバ']

print(sushi_menu[0])
print(sushi_menu[1])
print(sushi_menu[2])
print(sushi_menu[3])
print(sushi_menu[4])
```

print文の中身の記述だけ変えればあと5行分ほぼ形式的な処理がされていますね．

###そこで for文の出番です！！！

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271604/6c356487-0b14-9291-fc97-1cb581b8ae67.png)
もう少しアプリケーションぽくしますと…
![sushi_menu.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271604/54f2fa0a-761c-4fe1-ef42-12c919bc86cf.gif)


#　これまでのFAQ
・[【Python】実行結果をデスクトップに保存しようとしたら「No such file or directory」エラーが。原因はOnedriveだった。](https://yumeriku.com/python-no-such-file-onedrive/107/)
・[Visual Studio Codeを日本語化する](https://www.javadrive.jp/vscode/install/index4.html)

# これまでの演習
解き終わり次第，[まなBOX](https://daltontokyo.mana-box.jp/epf-web/Servlet/)にて提出しましょう．演習の提出状況で成績判断をします．

|演習番号|問題内容|
|:-:|:--|
|1|[計算してみよう(授業資料1 演習)](https://qiita.com/hakukikun/items/c6fa44ca0168894ecca1)|
|2|[複合代入演算子を用いた四則演算（授業資料3 演習）](https://qiita.com/hakukikun/items/9535d71e76a67d9844fd)|
|3|[python キャスト（授業資料3 演習）](https://qiita.com/hakukikun/items/592dd63ab74a863edee5)|
|4|[リストの要素同士の計算](https://qiita.com/hakukikun/items/44036f883ee19c681cf8)|
|5|[辞書型で自販機データを作ろう](https://qiita.com/hakukikun/items/8f8a1a58d0fe0ecab47a)|
|6|[「いかのおすし」を縦表記しよう](https://qiita.com/Rumi_Yamaguchi/items/ec812d991defb20c9b7a)|

#参考
[08. 制御構文（if文） | 中学生でもわかるPython入門シリーズ](https://www.youtube.com/watch?v=yutXz217ttQ)
[たった1日で基本が身に付く! Python超入門](https://www.amazon.co.jp/%E3%81%9F%E3%81%A3%E3%81%9F1%E6%97%A5%E3%81%A7%E5%9F%BA%E6%9C%AC%E3%81%8C%E8%BA%AB%E3%81%AB%E4%BB%98%E3%81%8F%EF%BC%81-Python%E8%B6%85%E5%85%A5%E9%96%80-%E4%BC%8A%E8%97%A4-%E8%A3%95%E4%B8%80-ebook/dp/B074WVKQVP/ref=as_li_ss_tl?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=Python+%E4%BC%8A%E8%97%A4&qid=1586415008&sr=8-1&linkCode=sl1&tag=grit-22&linkId=b689fc38acfbc841b9b1d2dc3af4cc32)
[1日で基本が身につく! Python超入門 - Speaker Deck](https://speakerdeck.com/yuichi110/1ri-deji-ben-gashen-nituku-pythonchao-ru-men)
[Python チュートリアル](https://docs.python.org/ja/3/tutorial/)
テキストコミュニケーションのTips

「書く」。テキストコミュニケーション、難しいですね。
以下、かんたんにちょっとだけテキストコミュニケーションがうまくなるというTips中のTipsです。

## Tips


- 文章の温度感を相手に合わせる
    - 丁寧度を相手に合わせる
    - 目上の人、目下の人、気にせず、相手に合わせる
- 絵文字と！、～、を駆使する
- 伝える順番を意識する


## シチュエーション別


### Case1. 先輩に、今すぐにMerge Requestを見て承認してほしい

できれば今すぐ、30分以内。

#### Bad practice 
「すみません、お時間よろしいですか」

で、返信を待つ。
ではなく用件は、端的に、何をしてほしいのか書いてしまいましょう。


#### Good :thumbsup: 例1

「すみません、今 Merge Request を見てもらえますか、問題なければMergeまでお願いします :pray: 」
（理由）を2文目でかんたんに説明するとより素敵。

#### Good :thumbsup: 例2

「Mergeしてもらえますか」
「Mergeお願いしたいです🥺」「Mergeをお願いしたいです！」 etc.

？を疑問文で使わない (疑問文はそもそも強い表現に見えがちですね)
疑問文をそもそも使わない

#### Good :thumbsup: 例3

「Mergeしてもらえますか～」
「Mergeお願いしたいですー🥺」etc.

「～」あるいは「ー」、をつかう、絵文字を使う

**つまり一言で相手に行動が促せ、忙しいであろう人の行動に合わせられるコミュニケーションが結局は良いのです。


### Case2. トラブルの調査状況を聞かれている

これもできれば今すぐ、30分以内に返したい。

#### Bad practice 
「すみません、まだ手を付けられていません」

事実なのだが、相手はどうしたらよいかわからないので進捗ナシになってしまいますね。


#### Good :thumbsup: 例1

「おまたせしています！」
「いま手を付けるところです:bow:」
進捗は変わらないのですがせめて気持ちは前向きになります。

#### Good :thumbsup: 例2
気持ちだけ前向きになっても仕方ないでしょうか？
「いま手を付けるところです:bow:」
「まず *** していただければ、状況は回避できると考えています :bow: 」
もちろん、頭の中で思いついているアイディアだけでもあれば共有してしまいます。



### Case3. 選択を問われている

はたまたこんなケース。
せっかく問われている状況なのですから選択したいですよね。

#### Bad practice 
「どちらがよいでしょう...」
どっちでも良いのなら、かえって決めて答えてみたほうが早いことがある。

#### Good :thumbsup: 例1

「自分としては～～がよいかなと思ったりします」
決めてしまったほうが相手が楽だったりするのです。仮決定案らしく言ってしまうと議論が早々に進みます。

#### Good :thumbsup: 例2

「～～をたたき台としておくのでもし何かあればアドバイスください」
自分の作業も滞らず素敵です。

### Case4. 禁止のお願いをする時

ただでさえいいづらい内容。

#### Bad practice 
「～～するのはやめましょう」
「遅刻するのは、やめましょう」

#### Good :thumbsup: 例1

「～～するようにしましょう」
「早く来るようにしましょう」

わかりやすいアクションのお願いになりました。


### Case5. 休む、早退するなど

これも、いいづらい内容。

#### Bad practice 

申し訳ありません、のみ

#### Good :thumbsup: 例1

用件のみ書いておけば良し。
「ありがとう」の気持ちを忘れずに！



## 参考


https://twitter.com/ayatokura/status/1472214406516047882?s=21

https://qiita.com/e99h2121/items/8b5e4bb3ed1d3db66375

- **愚痴**: 非生物に対するボヤキ
    - 愚痴は書いたらいい
- **悪口**: 生物、とくに生身の人間にたいするもの
    - 悪口は書いてはいけない

https://qiita.com/e99h2121/items/7899b7055ed7c89a0c56

- テキストで噛み合わなければ腹をくくり、Web会議で1度すり合わせます。

https://qiita.com/hidemitsuaoki/items/5dc595ab6d6e6fbcb0e0


https://qiita.com/autotaker1984/items/79576581e239244772f1

https://qiita.com/satomihoya/items/b125e1eaf44c4a643e6e

https://qiita.com/shoichinishiguchi/items/d4169e175f9d439a5211

https://note.com/luccafort/n/na7a83a3dd3b2


以上です～
Phoenix 1.6製ポータルサイトへのTailwind CSS導入にあたってphx_gen_tailwindが便利だった話

この記事は、「__[elixir Advent Calendar 2021](https://qiita.com/advent-calendar/2021/elixir)__」22日目の記事です。
きのうは @MzRyuKa さんの記事でした！

# 本記事の結論
2021年12月22日時点、Elixir製Webフレームワーク [Phoenix](https://www.phoenixframework.org/) の最新バージョン1.6系に [Tailwind CSS](https://tailwindcss.com/) を導入する際、Hexライブラリの __[phx_gen_tailwind](https://hex.pm/packages/phx_gen_tailwind)__(PhxGenTailwind) が便利でオススメです。

- phx_gen_tailwind を用いた実際の Tailwind CSS 導入手順については本記事でも後述します

## 対象読者
- Phoenix 1.6開発において、Tailwind CSSによるStyle実装を行いたい人
- かつ、手っ取り早くTailwind CSSの環境構築をしたい人

## 実行環境
| |バージョン|備考|
|:--|:--|:--:|
|elixir|1.12.2|compiled with Erlang/OTP 24|
|phoenix|1.6.0| |
|npm|16.9.1| |

- 本記事では、elixir / phoenix / npm はあらかじめセットアップ済みであること想定です
- npmの導入については、本記事のスコープ外ですので、導入手順が必要な場合はこちらの記事等の別記事をご参照ください
  - [__How do we casually create an Elixir community website with Phoenix?__ (Chapter 2: Adapt CSS layout by Tailwind CSS)](https://speakerdeck.com/imaima/how-do-we-casually-create-an-elixir-community-website-with-phoenix?slide=49)

# phx_gen_tailwindの概要と導入手順
phx_gen_tailwindは、Phoenix1.6にTailwind CSSの環境構築を手早く行うためのHexライブラリです。

- [GitHub](https://github.com/kevinlang/phx_gen_tailwind)

> PhxGenTailwind
> Adds Tailwind to your new Phoenix 1.6+ project

## phx_gen_tailwindを、通常のmixインストールで準備する
- mix.exs に以下追記し、`mix deps.get`, `mix deps.compile` でインストールします

```elixir:mix.exs
  defp deps do
    [
      ...
      {:phx_gen_tailwind, "~> 0.1.3"}  # <--add
    ]
  end
```

- 途中で聞かれる `NPM install new dependencies? [Yn]` に対しては `y` で続けます

## `mix phx.gen.tailwind`コマンドを実行する
- インストールが済んだら、コマンド `mix phx.gen.tailwind` の実行が可能となっており、こちらを実行します
- これだけでTailwind CSSが使えるようになります
- 内部的な処理としては、従来の手作業によるセットアップフロー（`assets/`内で Tailwind CSSと依存パッケージをインストールしたりimportしたり等）を、上記コマンド一撃で実行してくれています

参考: 手作業による導入フロー

https://qiita.com/im_miolab/items/504a8534802e433d7442

# 成果例
実際にphx_gen_tailwindの恩恵を受けてTailwind CSSで実装・リリースした、Phoenix 1.6製のkokura.exポータルサイトです。

https://kokura-ex.herokuapp.com/

## イメージ
  ![スクリーンショット 2021-12-19 18.23.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211052/eac4d41a-f32d-0f5b-f927-574a0ba05b7c.png)

# まとめ

[ElixirConf US 2021](https://2021.elixirconf.com/#ryotaro-imahashi)で登壇発表した内容から、Tailwind CSSセットアップの部分をピックアップし、今回紹介しました。

https://speakerdeck.com/imaima/how-do-we-casually-create-an-elixir-community-website-with-phoenix

明日の 「__[elixir Advent Calendar 2021](https://qiita.com/advent-calendar/2021/elixir)__」23日目は、@mnishiguchi さんの記事です。お楽しみに！
Larabelでルートを設定したのに表示されない時の対処法

Larabel8プロジェクトでViewの作成方法をググってそれ通りにやったのに、Viewが表示されないという問題にぶち当たりました。

その時にルートのweb.phpに書いた内容はこちら。

    Route::get('contact', 'WelcomeController@contact')

そしてControllerの内容はこちら。

    <?php

    namespace App\Http\Controllers;

    class WelcomeController extends Controller {
        // ...
        public function contact()
        {
            return "contact";  //Viewにcontactテキストを返すメソッド
        }
    }

その時のエラー内容はこちら。
     
    Target class [WelcomeController] does not exist.

翻訳してみると、__ターゲットクラス[WelcomeController]が存在しません。__とのこと。


###解決策

__ルートをディレクトリ構成で設定する。__

    Route::get('contact', 'App\Http\Controllers\WelcomeController@contact');

ディレクトリ構成で設定したら、ちゃんと表示されました。

![スクリーンショット 2021-12-19 15.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/de492c66-a850-029d-ffa4-2d6b9ed59f77.png)

Larabel7まではできたけど、Larabel8になって変わったんですかね。
今後もこの問題にぶち当たりそうな気がしたので、忘備録として残しておきます。

上記の問題でお悩みの方の手助けになれば幸いです。
Nuxt 3 with TailwindCSS v3

# 概要

Nuxt３でTailwindCssを設定する方法
TailwindCssはバージョン３系

# 手順

１. Nuxt3, Tailwindcssをインストール

```bash
# Nuxt3をインストール
$ npx nuxi init nuxt3-app

# ディレクトリに移動
$ cd nuxt3-app

# TailwindCSSをインストール
$ npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

# TailwindCSSを初期化
$ npx tailwindcss init
```

２. taiwind.config.jsを修正

```js
// tailwind.config.js
module.exports = {
  content: [
    './components/**/*.{vue,js}',
    './layouts/**/*.vue',
    './pages/**/*.vue',
    './plugins/**/*.{js,ts}',
    './nuxt.config.{js,ts}',
  ],
};
```
３. tailwind.cssを作成

```css
/* assets/css/tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
```

４. nuxt.config.jsを修正

```js
// nuxt.config.js
import { defineNuxtConfig } from "nuxt3";

export default defineNuxtConfig({
  css: ["@/assets/css/tailwind.css"],
  build: {
    postcss: {
      postcssOptions: {
        plugins: {
          tailwindcss: {},
          autoprefixer: {},
        },
      },
    },
  },
});
```

完了！！
building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

TensorFlowLiteCを使うために色々としていた時に起きたエラーの話をします。

OSとしては、 M1 macを用いています。

<h2>エラー内容</h2>
会社の上司から、以下のリンクを読んで環境セッティングしといてと連絡が来たので環境セッティングをしていました。
https://pub.dev/packages/tflite_flutter

TensorFlowLiteCを使えるようにするには、以下のファイルの下に<b>TensorFlowLiteC.framework</b>を置くとのこと。
`~/.pub-cache/hosted/pub.dartlang.org/tflite_flutter-<plugin-version>/ios/`

実際に置いてから、`Run`をすると以下のエラーが発生。

```
building for iOS Simulator, but linking in object file built for iOS, for architecture arm64
```

<h2>解決方法</h2>
`Ios`ファイル内にあるPodfile内にて、以下の一行を追加してから、`pod install`を行ってください。

```
post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    // 追加する一行
    config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
  end
end
```

以下のサイトを参考にしました。
https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-an-object-file-built-for-io

<h2>反省</h2>
このエラーが解消されるまでに、2時間ぐらいかかりました。
沢山のサイトを読みました。しかし、解決方法はとてもシンプルなもので、時間がかかった理由としては、一つのサイトを最後までしっかりと読んでいないことが理由だなと思いました。
なので、次からは最後までしっかりと読みきろうと思います。
【Windows、Mac】スクリーンショットを撮る方法

PCで作業をしていて現状を報告する際に画像を要求される場合がありますが、
そんな時、PCの画面をスマホで撮影していませんか？
そんな方は是非この記事を参考にしてPCで完結できるようにしましょう！

## スクリーンショットを撮る方法

## Mac
ショートカットは`⌘` + `shift` + `3` または `⌘` + `shift` + `4`です。
前者は画面全体、後者は選択範囲をキャプチャします。
キャブチャした画像の保存場所は<font color="red">デスクトップ</font>です。

## Windows
ショートカットは`win` + `print screen` または `win` + `shift` + `s`です。
前者は画面全体をキャプチャし、ピクチャの中のスクリーンショットフォルダに保存されます。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843917/5ba43b0f-d71e-5563-381b-17cd5854067c.png)

後者は選択範囲をキャプチャします。
しかし、ショートカットを入力しただけでは保存されないので注意が必要です。

まずは`win` + `shift` + `s`を押してキャブチャしたい範囲を選択します。
![win_screenshot1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843917/05b120de-38c6-069b-4432-9afa89c68937.jpeg)
![win_screenshot2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843917/649f2362-8d35-ef28-7a66-b95957ee097f.jpeg)

選択範囲をキャプチャすると右下に通知が来ます。
その通知をクリックして画像編集のウインドウを開きます。
![win_screenshot3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843917/eb42a910-54f8-c451-6a74-1292cad4be0d.jpeg)
![win_screenshot4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843917/05d5341d-5b8a-8255-41da-4ee8ea9ccf66.jpeg)

右上の保存マークをクリックするとどこに保存するか聞かれます。
デフォルトではピクチャに保存されるようになっていますが、指定した場所に保存することもできます。
![win_screenshot5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843917/23782aac-ea27-5e74-ae4e-305ef1dee41c.jpeg)
![win_screenshot6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843917/added0eb-074e-665d-20f2-f823a5b26a8c.jpeg)


## おわりに
スマホで画面を撮影するとディスプレイに部屋のライトが反射してうまく撮影できないこともあるのでご活用ください！
[Android] Roomの@RawQueryの使いどころ

## 利用すべきでないケース
使いどころの前に、まず使うべきではないケースについて説明します。[RawQueryのドキュメント](https://developer.android.com/reference/androidx/room/RawQuery)には以下のサンプルコードが記載されていますが、どれも基本的には利用すべきではないです。

- Observable Queries
- Returning POJOs
- POJOs with Embedded Fields
- Relations

適切にプレースホルダを利用すれば、これらのほとんどのクエリを他の`@Query`等のアノテーションでも実現できます。`@RawQuery`を利用してしまうとコンパイル時のバリデーションが出来ないため、Roomのメリットを捨てることになります。

## 使いどころ
Roomの他の機能を利用して、どうしても実現できない場合には`@RawQuery`の出番です。

### PRAGMA
[PRAGMA](https://sqlite.org/pragma.html)の利用が`@RawQuery`を利用したいケースの中でかなり多いのではないかと思います。例えば`PRAGMA compile_options`というクエリで、SQLiteのコンパイルオプションの一覧を取得することが出来ます。

例として、[SQLiteの全文検索(FTS)](https://www.sqlite.org/fts3.html)のクエリの構文を決定するコンパイルオプション(`SQLITE_ENABLE_FTS3_PARENTHESIS`)の取得をしてみます。

```kotlin
@Dao
abstract class MyDao {
    val isEnhancedQueryEnabled: Boolean by lazy {
        // PRAGMAでコンパイルオプションを取得すると"SQLITE_"のプレフィックスが省略されます。
        "ENABLE_FTS3_PARENTHESIS" in selectCompileOptions()
    }

    @RawQuery
    protected abstract fun selectCompileOptions(
        query: SelectCompileOptionsQuery = SelectCompileOptionsQuery
    ): List<String>

    protected object SelectCompileOptionsQuery : SupportSQLiteQuery {
        override fun getSql(): String = "PRAGMA compile_options"

        override fun bindTo(statement: SupportSQLiteProgram?) = Unit

        override fun getArgCount(): Int = 0
    }
}
```

`SQLITE_ENABLE_FTS3_PARENTHESIS`がコンパイルオプションとして指定されている場合に、`isEnhancedQueryEnabled`が`true`になります。

実装時のコツですが、`@RawQuery`は出来ることが多いので、できるだけ使用を制限することをおすすめします。`SupportSQLiteQuery`を継承した特定のクエリ専用のクラスを作り、`@RawQuery`を付けた関数のデフォルト引数で渡すと良いでしょう。

サンプルコードは[こちら](https://github.com/shiita0903/RawQueryTest/blob/master/app/src/main/java/jp/shiita/rawquerytest/MyDao.kt)にあります。

### テーブルを動的に指定
テーブルを動的に指定するような特殊なクエリは、DAOの関数の引数をバインドすることが出来ません。`@RawQuery`を使って実装できますが、このケースではRoom自体を使わないほうが良いかもしれません。

### Roomが生成するコードに問題がある
Roomが生成するコードにバグが存在したり、パフォーマンスが悪い場合に`@RawQuery`が役立つかもしれません。

SQLiteを暗号化するライブラリの[SQLCipher](https://github.com/sqlcipher/android-database-sqlcipher)とRoomを組み合わせた際に、特定のクエリでアプリがクラッシュする問題が以前あったのですが、それが解決するまでの間は`@RawQuery`で実装したクエリで代用したことがあります。

## おわりに
実用的な`@RawQuery`の使いどころとしてはPRAGMAぐらいしか無い気がします。もし効果的に`@RawQuery`を利用している方がいましたら、コメントでどう使っているかを教えてくれると嬉しいです。
Riderでdllの依存関係を見る

この記事は [Unity Advent Calendar 2021](https://qiita.com/advent-calendar/2021/unity) と [Unityゲーム開発者ギルド2 Advent Calendar 2021](https://adventar.org/calendars/6487) の23日目です。

# 前書き
Unityでは<code>Assembly Definition</code>をフォルダに追加すると、そのフォルダ別に<code>dll</code>が分割される機能があります。
クラスの循環参照が抑えられコードが綺麗に保てたり、コンパイル範囲が小さくなり変更時のビルドが早くなったりします。
その<code>dll</code>を依存関係を図で見る機能をご紹介します。

# 環境
Rider2021.3 (2020.2 over）

# 方法
<code>Tools</code> > <code>Architecture</code> > <code>Show Project Diagram</code> で表示されます。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106884/93ae2efc-ba20-f0a8-158c-f55b99621133.png)

開発中の個人ゲームのクラスを表示してみた図
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106884/31c3efe6-ffe5-1988-08b0-5e4c7c1b93e0.png)
（依存関係がかなり怪しいですね･･･）

# 最後に
クラスのダイアグラムはまだ実装されてません。そちらを見たい方はVisualStudioで見るのが良さそうです。

# 参考文献
[Type Dependency Diagram support](https://youtrack.jetbrains.com/issue/RIDER-4321#focus=Comments-27-4372325.0-0)
[[][0-9]:[0-9][0-9]:[0-9][0-9][]]spk_1:

wordのタイムスタンプの変換

```
[[][0-9]:[0-9][0-9]:[0-9][0-9][]]spk_0:
[[][0-9]:[0-9][0-9]:[0-9][0-9][]]spk_1:
```


```
^p
^13^p
。^p
?^p
? ^p
```

```
[0-9][0-9][0-9][0-9].00 [0-9][0-9][0-9][0-9].00 None
```
スイッチを自動化してポケモンの乱数消費させたい


これは[鈴鹿高専Advent Calendar 2021](https://qiita.com/advent-calendar/2021/snct) 20日目の記事です
注意　まだちゃんと成功していないので他の人の記事を参考にしていただけると幸いです</span>
## 概要
ArduinoでNintendo switchを動かすためライブラリが存在するので乱数調整で大量の日付を動かすのでやってみようと思った
[使ったライブラリ](https://pokemonit.com/nintendo-switch-control-library/)
### 剣盾のレイド乱数
夜綱さんとぼんじりさんのツールを使って初期seedを割り出してそこから延々と日付を変更して欲しい個体の場所に持っていくというもの
[ぼんじりさんのツール](https://bzl.hatenablog.com/entry/2020/01/05/212130)
[夜綱さんのツール](https://note.com/sub_827/n/nfafc7b0ae371)
 
### 注意点
このライブラリがなんかArduino Leonardoとその互換でしか動かないらしいので注意
~~よく分からんかったのでこれでも見て~~
[参考資料](https://tangential-star.hatenablog.jp/entry/Arduino_pokemon_ex_which_arduino_you_should_buy)


## コード

```Rand.ino
#include <NintendoSwitchControlLibrary.h>
#define after_day_count 6801  //何日ずらすか
const int DIN_PIN = 7;

void nday_after(int day);

void setup() {
  //  switchに認識させる
  pushButton(Button::B, 500, 10);
}

void loop() {
  int value = digitalRead(DIN_PIN);

  if (value == LOW) {
    nday_after(after_day_count);
  }
}

void nday_after(int day) {
  int month = 1;
  int count = 1;

  pushButton(Button::HOME, 500);
  pushHat(Hat::DOWN, 300);
  pushHat(Hat::RIGHT, 200, 5);
  pushButton(Button::A, 500);
  tiltLeftStick(Stick::NEUTRAL, Stick::MAX, 1500);
  pushButton(Button::A, 200);
  tiltLeftStick(Stick::NEUTRAL, Stick::MAX, 700);
  pushButton(Button::A, 300);
  pushHat(Hat::DOWN, 200, 2);

  for (int i = 0; i < day; i++) {
    if (i != 0) {
      pushButton(Button::A, 300);
      pushHat(Hat::LEFT, 200, 3);
      pushHat(Hat::UP, 200);
      if (count == 28 && month == 2) {
        pushHat(Hat::DOWN, 200);
        pushHat(Hat::LEFT, 200);
        pushHat(Hat::UP, 200);
        pushButton(Button::A, 200);
        pushHat(Hat::UP, 100, 4);
        month++; count = 1;
        pushButton(Button::A, 200, 4);
      }
      else if (count == 30 && (month == 2 || month == 4 || month == 6 || month == 9 || month == 11)) {
        pushHat(Hat::LEFT, 200);
        pushHat(Hat::UP, 200);
        month++; count = 1;
        pushButton(Button::A, 200, 5);
      }
      else if (count == 31 && month == 12) {
        pushHat(Hat::LEFT, 200);
        pushHat(Hat::UP, 200);
        pushHat(Hat::LEFT, 200);
        pushHat(Hat::UP, 200);
        month = 1; count = 1;
        pushButton(Button::A, 200, 6);
      }
      else if (count == 31) {
        pushHat(Hat::LEFT, 200);
        pushHat(Hat::UP, 200);
        month++; count = 1;
        pushButton(Button::A, 200, 5);
      }
      else {
        count++;
        pushButton(Button::A, 200, 4);
      }
    }
    else {
      pushButton(Button::A, 200);
      pushHat(Hat::RIGHT, 200, 2);
      pushHat(Hat::UP, 200);
      pushButton(Button::A, 200, 4);
      count++;
    }
  }
  pushButton(Button::HOME, 500, 2);
}
```
## 結果
ミスってたので帰ったら修正

## 感想
~~こんなクッソめんどくさいこと二度とやりたくない~~
5世代乱数(BW, BW2)の乱数がめっちゃ簡単だったことを思い知った。手動で色レジアイス捕まえるのもこれくらいきついんだろうなぁとよくわからない感情になった。
画像認識で年月動かすタイミング判定すればなかなかスッキリと書けそう。

## おわりに
~~反省会記事にならなくて本当によかった~~
反省会案件
大体ORASのトリプルフリーに生息しているのでもしよかったら来てみて下さい
AtCoder Beginner Contest 232 E

## Problem Statement
The difficulty of this question is around 1400.
https://atcoder.jp/contests/abc232/tasks/abc232_e

We could solve this question by dynamic programming. Here I take bottom-up approach.

## State Definition
We define the state as follows:

dp[ i ][ j ] = The number of ways to do the i operations and land on the points that:
with different row and column of destination, when j = 0;
with same row and different column of destination, when j = 1; 
with different row and same column of destination, when j = 2;
with same row and col of destination, when j = 3;

## State Transition
In implementation, we should take modulo 998244353.

```c++:transition.cpp
dp[0][i] = (H - 2 + W - 2) * dp[0][i - 1] + (W - 1) * dp[2][i - 1] + (H - 1) * dp[1][i - 1];

dp[1][i] = dp[0][i - 1] + (W - 2) * dp[1][i - 1] + (W - 1) * dp[3][i - 1];

dp[2][i] = dp[0][i - 1] + (H - 2) * dp[2][i - 1] + (H - 1) * dp[3][i - 1];

dp[3][i] = dp[1][i - 1] + dp[2][i - 1];
```

## My answer
I solved it after contest time.

```c++:E.cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep0(i, n) for (int i = 0; i < (int)(n); ++i)

ll MOD = 998244353;
ll dp[5][1000005];

int main() {
    ll H, W, K, x1, y1, x2, y2;
    cin >> H >> W >> K;
    cin >> x1 >> y1 >> x2 >> y2;
    if (x1 != x2 && y1 != y2) dp[0][0] = 1; // different rows & columns
    if (x1 == x2 && y1 != y2) dp[1][0] = 1; // same row
    if (x1 != x2 && y1 == y2) dp[2][0] = 1; // same column
    if (x1 == x2 && y1 == y2) dp[3][0] = 1; // same point as destination
    
    for (int i = 1; i <= K; ++i) {
        // different rows & columns
        dp[0][i] = ((H - 2 + W - 2) * dp[0][i - 1] % MOD + (W - 1) * dp[2][i - 1] % MOD + (H - 1) * dp[1][i - 1] % MOD) % MOD;
        // same row
        dp[1][i] = (dp[0][i - 1] % MOD + (W - 2) * dp[1][i - 1] % MOD + (W - 1) * dp[3][i - 1] % MOD) % MOD;
        // same column
        dp[2][i] = (dp[0][i - 1] % MOD + (H - 2) * dp[2][i - 1] % MOD + (H - 1) * dp[3][i - 1] % MOD) % MOD;
        // same point as destination
        dp[3][i] = (dp[1][i - 1] + dp[2][i - 1]) % MOD;
    }
    cout << dp[3][K] % MOD << endl;
}
```
【Rails】enumの実装方法（日本語化）

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

## enumの実装方法

```　'Gemfile'
  gem "enum_help"
```

ターミナル

```
bundle install
```

モデルにenum定義

```sample.rb
enum payment_method: { credit_card: 0, transfer: 1 }
```

日本語化のために以下記述

```config/application.rb
 config.i18n.default_locale = :ja
 config.i18n.load_path += Dir[Rails.root.join('config/locales/*.yml').to_s]
```

```config/locales/ja.yml
ja:
    enums:
      order:
        payment_method:
          credit_card: "クレジットカード"
          transfer: "銀行振込"
```


## おわりに
詳細な説明については、後日追記する予定です。
(2021年/12月時点) 無料版MAMPのインストール&PHPバージョンアップ方法MacOS

#記事を書いた理由
MAMPのPHPをバージョンアップさせようとしたところどこにMAMP.appがインストールされているのかが少しわかりにくかったので共有しようと思いました。

#MAMP(無料版)インストールの手順
1.まずはこちらの<a href="https://www.mamp.info/en/downloads/">MAMPダウンロードサイト</a>にアクセスしてください。
![スクリーンショット 2021-12-19 19.43.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719010/7f4879e4-5cfe-533f-8a7e-67a1e0a4bda2.png)

2.次に左上のMAMP & MAMP PRO 6.6 (intel)をクリックします。
![スクリーンショット 2021-12-19 19.49.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719010/33dc8234-bbe5-f6e7-3cf2-df9211f6d60e.png)

3.次に左下のダウンロードしたパッケージを開き手順に従ってMAMPをインストールします。(全て肯定してOK！)インストールが完了したらパッケージは削除しておきましょう。

4.インストールが完了すると下写真のようにFinderにMAMP PROとMAMPフォルダが入っています。
今回は無料版しか必要ないのでPROはゴミ箱に入れましょう。

![スクリーンショット 2021-12-20 0.58.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719010/d1a873c1-d086-78bb-e36b-129dcb0a1ad4.png)

5.MAMP(無料版)はフォルダの中にあるのでフォルダを開いてMAMP.appを起動。
![スクリーンショット 2021-12-20 1.13.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719010/eae7d69b-3061-1298-07ff-9297d43710b5.png)

6.あとはPHP versionで8.0.8を選択したら完了です。
ちなみに黄色の広告は左下のチェックマークを外すと次回から出てきません。
![スクリーンショット 2021-12-20 1.17.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719010/7625a0b1-b607-63b0-4a82-62637263d42e.png)
【最新版】九州大学の全学基本メールのiPhone Android 設定方法.設定できない時の対処法．

九州大学の基本メールをスマホ（iPhone, Android）に追加する際に，下記の公式マニュアルでは設定不可能だったため．解決法を載せておきます．

修正版↓
https://kaedeee.com/kyushu-univ-mail-setting


「設定不可能になってしまっている」公式マニュアル
http://www.hes.kyushu-u.ac.jp/~hesguide/wp-content/uploads/2016/12/iPhone-mail.pdf


#問題点

公式マニュアルでは，「アカウント追加」の際．「その他」から追加することになっていますが，これだとうまくいきません．

![スクリーンショット-2021-12-07-13.08.26-1024x578-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900756/bc5f26b0-3a72-bf9d-91e3-5f6a46c0d480.png)


#解決方法
「アカウント追加」の際．「Exchange」を選択します．
（iPhone, Android問わず同様）

![スクリーンショット-2021-12-07-13.08.26-1024x578-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900756/8e886a55-2dcc-324b-3f2e-9800ccc3467d.png)

#追記
後は，
メールアドレス　〜@s.kyushu-u.ac.jp
パスワード　該当パスワード
を追加するだけ！かんたん！

![IMG_1146-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900756/232a07d0-16bb-0d61-6bc4-3508d8b80fda.png)


終わり．

修正版↓
https://kaedeee.com/kyushu-univ-mail-setting
【Maya】UnityにFBXとして送信するをボタンひとつで行えるツール

# 概要
MayaのPythonスクリプティングの練習用にMayaで標準機能として備わっている「Unityに送信」するを
ワンポチで行えるツールを作成してみました。

# 環境
- Maya Indies2022.3
- Python3.7.7

# UnityにFBXとして送信
「Unityに送信＞すべて」をpythonで行ってみます。

# GUI
![2021-12-19_20h34_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148284/e897950b-4584-379e-cd88-6df1d8c2a10f.png)

SendToUnityでUnityにFBXとして出力します。

# Python

```python
import maya.cmds as cmds
import pymel.core as pm
import os

saveKey = "KeyTextBox"

def SendToUnity(*args):
    input = pm.textField('textBox',q=1,tx=1 )
    
    file_name = os.path.basename(cmds.file(query=True,sceneName=True)).replace(".mb","")
    path = os.path.join(input,file_name)
    fbx_path = os.path.join(path,file_name + '.fbx');
    material_path = os.path.join(path,'Materials');
    texture_path = os.path.join(path,'Textures');
    make_dir(path);
    make_dir(material_path);
    make_dir(texture_path);
    cmds.file(fbx_path,force=True,options="v=0;p=17;f=0",type="FBX export",preserveReferences=True,exportAll=True);

def make_dir(path):
    if not os.path.exists(path):
        os.makedirs(path)
    return path

def TextChangeCommand(*args):
    print(args[0])
    cmds.optionVar(stringValue=(saveKey,args[0]))

def MySendToUnity():
    with pm.window(title="MySendToUnity"):
        with pm.rowColumnLayout(numberOfColumns=3):
            pm.text( label='Name' )
    
            if cmds.optionVar(exists=saveKey) == False:
                cmds.optionVar(stringValue=(saveKey,"D:/"))
            text = cmds.optionVar(q=saveKey)
            
            tb = pm.textField('textBox', tx=text,width=400 , changeCommand=TextChangeCommand)
            pm.button(label="SendToUnity",command=SendToUnity)

MySendToUnity();

```

![2021-12-19_20h41_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148284/1a8adfdb-9da7-c8e4-68e8-37bc0721a0bd.png)

ついでにマテリアルとテクスチャのフォルダも自動生成します。

# まとめ
あってもなくてもなツールかもしれませんが今回練習用に作成してみました。
あると少しだけ便利かもしれません。
インターネットGW・NAT-GW・TransitGWの違い

### 参考

https://milestone-of-se.nesuke.com/sv-advanced/aws/internet-nat-gateway/

https://qiita.com/yi7027/items/5ef56c9f0472ab84fea9

---

### インターネットGW・NATGW

両方ともインターネットに接続するために「PrivateIP-PublicIP」の変換を行うために必要なもの。

![スクリーンショット 2021-12-20 0.11.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653955/8bc24251-0d55-1b76-20a2-b09a360e64fd.png)

#### インターネットGW
　　・VPCをインターネットに接続するためのもの＝VPCにアタッチするもの
　　・静的NATを行う
　　・無通信時もStatic NAT Tableにて「PrivateIP-PublicIP」の紐付けを管理。

#### NATGW
　　・PrivateSubnet内にあるEC2インスタンスから、インターネットに接続するためのもの
　　・PublicSubnet内に配置
　　・動的NATを行う
　　・通信時にDynamic NAT Tableに「PrivateIP:Port-PublicIP:Port」の紐付けを追加。

---
### TransitGW

VPC間のプライベート接続を行うためのもの

![スクリーンショット 2021-12-20 0.49.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653955/894720a1-d91e-876f-c7cf-6f17dfae2d47.png)

　　・オンプレ、VPC間の接続を実現する
　　・VPC間接続については他の方法(VPCピア接続)も存在する

### ケース

・インターネットと相互通信できるEC2インスタンスを作成したい（ex:WEBサーバ）
　　→ PublicSubnet内にEC2インスタンスを配置する。
　　→ 無通信状態でもPrivateIP-PublicIPの紐付けがIGWのStaticNATTableで定義済【静的NAT】

・インターネットからの通信はNGのEC2インスタンスを作成したい（ex:環境監視用サーバ）
　　→ PrivateSubnet内にEC2インスタンスを配置する。
　　→ 通信時にPrivateIP-PublicIPの紐付けを行う【動的NAPT

・APIサーバのあるVPCからDBサーバのあるVPCに接続したい
　　→ TransitGWでVPCの紐付けを行う
[小ネタ]メールにQRコードを貼っつけたい

この記事は　[ZOZO #3 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/zozo) 23日目の記事になります。


今どきはバーコードではなく、QRコードなんですよね。ということで、メールにQRコードを貼り付けたい！

javaでの例になります。javaですと、[ZXing](https://github.com/zxing/zxing)というツールが使えます。QRコード以外にもバーコードの生成も可能のようです。

QRコードの生成方法は以下の通り。画像を生成してS3に保存する例になります。

```java

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;

// 引数にQRコードの元となる文字列を渡しています。
public void createQRCode(String qrcode, String s3BucketName){
    BarcodeFormat format = BarcodeFormat.QR_CODE;
    int width = 82;
    int height = 82;

    Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
　　　　　　　// エラー訂正レベル　L→M→Q→Hの順にQRコード内の密度が上がって複雑になる
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);

    try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
      QRCodeWriter writer = new QRCodeWriter();
      BitMatrix bitMatrix = writer.encode(qrcode, format, width, height, hints);
      BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
      ByteArrayOutputStream stream = new ByteArrayOutputStream();
      ImageIO.write(image, "png", stream);
      stream.flush();
      byte[] imageInByte = stream.toByteArray();
      stream.close();

      ObjectMetadata metadata = new ObjectMetadata();
      metadata.setContentType("image/png");
      PutObjectRequest request =
          new PutObjectRequest(s3BucketName, "qrcode-images/qrCode.png"),
              new ByteArrayInputStream(imageInByte), metadata);
      s3Client.putObject(request);

    } catch (IOException | WriterException e) {
      throw new RuntimeException(e);
    }
}
```

ポイントとしては、QRコードをBase64での生成も可能で、圧倒的にBase64を使うのが楽なのですが、***メーラーのブラウザではBase64がほとんど対応しておらず***、メールを受信しても閲覧できない。そのため今回はS3に保存してそこを参照するようにしています。

以上小ネタでした。

※ちなみにQRコードはデンソーウェーブ社の登録商標になります。


明日は、@taquaki-satwoさんの記事になります！
2つの名前の管理の仕方

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

# 2つの名前の管理の仕方
このサービスを作るに当たって、本名をさらすのが憚られたので、自分の名前をもう一つ作ることにした。青年向けマンガを描く漫画家が別の名前を付けるのと同じノリ？だ。その名前が@fabsabsfabsabsで、名前の由来は驚異のFANZA女優検索のURLからfabsにして、このままだと短すぎると思ったので、韻を踏む感じでf「abs」「abs」にした。アイコンは驚異のFANZA女優検索を表すメタファー。2個あるところがポイントで、名前も同じ単語が2回続けた。名前をもう一つ作ることは結構面倒臭いと思ったので今日はそのことを。

# 1つのGmailで2つのアカウントを作る方法
名前を2つ作るという事は、例えばqiitaで自分が普段から使っている名前のアカウントと、新しい名前用のアカウントを2つ作ることになる。1つのメールアドレスで2つのアカウントを作ることは多分出来ない。ただ、普段使いのGmailだけで2つのアカウントを作る方法はある。どちらも同じメールボックスに来るので管理的には楽だと思う。それは自分のGmailのメールアドレスのどこかを.で区切る方法だ。[Gmail アドレスでのピリオドの扱い](https://support.google.com/mail/answer/7436150?hl=ja)に書いてあるが、Gmailはいくらピリオドが追加されてもそのメールはちゃんと届く。各種サービスはピリオドが増えれば別のメールアドレスとして認識されるので、これを利用すれば1つのメールアドレスで2つのアカウントを作ることが出来る。（経験上ピリオド2つ連続..はやめた方が無難かも）。実際にこの方法でqiitaのアカウントを作った。

#登録サービスを増やす
さらにTwitterやInstagramもこの方法で作ろうかと思ってちょっと迷い始めた。そこまでやり出すならメールアドレスも専用のものを用意するべきかもしれない。このサービスへの連絡はメールアドレスまでというのはよくある。メールアドレス自体をさらすのであればやはり別にするべきだし、そもそもアカウントが増えてくるとメールアドレスは別の方が管理しやすくなる気もした。またTwiiterとかFacebookを2つやりだすと本人認証の問題もある。つまり2つのアカウントを管理しようとすると電話番号も2つ必要になる。自分はたまたま2台あったので、ここはクリアできたが、さらにまた別の名前を作ろうと思った時にどうすれば良いのか分からない。沢山アカウント管理している人もいるとは思うので、認証をクリアするいい方法があれば知りたい。こんな感じで、驚異のFANZA女優検索に関連するサービス、Twitter, Instagram, qiita, githubなどはfabsabsfabsabs名義でアカウントを作っている。

#2つのアカウントの関連性をなくすには
基本、fabsabsfabsabsから本人のアカウントの情報が紐づくことはないようにした。まあわざわざ別アカウントとの関連性を暴こうとすることは、有名人でもないかぎり、殆どないと思うが、隠すと決めている間は色々気を付けた方が良いと思う。実際自分もミスで本名に紐づいた情報を2回公開してしまっている。1回目はDMM.comの女優APIのリンクのアフリエイトの名前が本名で使っているIDのままだった。自分で気づいたときはちょっとドキドキした。2回目はgithubのフォーク元が本人の使っているアカウントからになっていた。それ以外でもソースの中にうっかり本名の方で使っているキーワードなどが残りがちなので、メールアドレス、名前、サービス名などでgrepした方が良い。自分もまーまーあった。
Slack上のやるべきことを忘れなく、効率が上がる作業方法

## 概要
センシンロボティクスの開発部のスウと申します。
この会社に入って二年目になり、業務やドローン知識も増えて来ました。
したがって、システム、業務関連の問合せの対応も増えました。

エンジニアの1日の仕事にはコーディング、コードレビュー、打ち合わせ、質問の対応、緊急障害対応など色々あります。その時に、どうのようにやるべきことを忘れなくて効率的に仕事を終わらせますか。

依頼、質問が来る時に、よく打ち合わせ中や、別件対応中など、すぐに対応できない場合は多いではないでしょうか。また、他の人に依頼、質問する時にずっと回答が来ない場合、自分はどのチャンネルに送ったのも忘れていないでしょうか。

こちら自分の作業方法を共有いたします。全員には合わないかもしれないですが、少しでも役に立ってもらえると光栄です。

## やるべきことを忘れない方法

### 下書きをする :writing_hand: 
依頼・質問が来る時に、まず緊急度を判断して、スレッドのメッセージ入力欄に緊急度のラベルを残しておきます。例えば：**A**（今日以内に回答）、**B**（今週以内に回答）など。皆さんも自分の状況によって、区別しやすいラベルをつけても良いです。

逆にコードレビューの依頼・質問する時、スレッドのメッセージ入力欄に**WAIT**などのラベルを残しておきます。

そうしたら、1日終わりや、翌日の朝イチなど、何をまだやっていないかすぐに分かりますよね。

![下書き.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596658/ee057654-fb7b-1594-f909-6ca2b82994d0.png)

### ブックマークをする :bookmark: 

同僚から良い情報があった時に、ちょうど読む時間がない場合はないでしょうか。その時はまずブックマークをしておきます。後で時間がある時に、ブックマークから確認できます。

良い情報を共有してくれた同僚へのお礼を忘れなくて、そういう習慣を養うことができます。その循環がチームに良い雰囲気を作ってくれます。

### リマインダーを設定する :bell: 

定例事務を/remindのコマンドで設定して、slack botは自動的にリマインドします。

自分はGoogle Calendarの方がお気に入りなので、/remindをあまり使っていないです。

### コードブロックに絵文字を付ける :smile: 

同僚から教えてもらった「Ctrl + Command + Space」で押すとコードブロックにも絵文字を使えます。

コード・システムログを共有する時にコードブロックの枠をつけると見やすくなると思います。情報量が多すぎる時に、絵文字を使ってすぐに強調部分を同僚に見せられます。

また、自分の好みですが、作業日報はコードブロックの枠をつけると見やすいと思います。その中に、絵文字をつけると気持ちまでも感じるではないでしょうか。

![コードブロック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596658/ff418aed-bbb5-e2ef-95e9-062167de458f.png)
## 結論

以上あくまでも自分の作業方法です。皆さんも自分が使いやすい方法を見つけましょう。
商用システムのソート（外部ソート）

# 大規模データをソートするテクニック
いわゆる大型汎用機での手法です。LinuxのSORTコマンドは内部的にはどうなっているんだろう？？

[参考 Wiki](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%B8%E3%82%BD%E3%83%BC%E3%83%88)
> この技法はコンピュータがまだ高価で、テープが大容量外部記憶の主力だった時代にさかんに研究され、さまざまなバリエーションが編み出された。『The Art of Computer Programming』の§5.4にそれらの詳細がある。


## こんな時はメモリに頼ったソートができない

- ソート対象ファイルのサイズ（件数、レコード長）が大きく、全データをメモリに格納してソートすることができない
- ソート対象ファイルのサイズは数十GBになることもある
- TAPEのようにシーケンシャルアクセスしかできない装置を外部ファイルとして使ってもソートできる手法。

よって、外部ファイルを使ってソートする（メモリSWAPではありません）。外部ファイルを使うので、外部ソートと言います。

## 実際に用いられているのは、*マージソート*
### 用語など
蓮 : ソート済みの範囲。下の例では[ ]で示します。

### 考え方（アルゴリズム概要）
1. データ列を、蓮ごとに交互に二つのファイルへ分割する。
2. 二つのファイルから、蓮単位で　「ひとつづつデータを取り出し比較し」　三つ目のファイルに**マージ**して出力する。
3. 蓮が一つになったらソート終了、そうでなければ１・２を繰り返す

```
START  : [F] [E] [D] [C] [B] [A] [9] [8] [7] [6] [5] [4] [3] [2] [1] [0]
  蓮の長さ：１、蓮の数：１６

SORTWK1: [F] [D] [B] [9] [7] [5] [3] [1]
SORTWK2: [E] [C] [A] [8] [6] [4] [2] [0]
MERGE  : [E F] [C D] [A B] [8 9] [6 7] [4 5] [2 3] [0 1]
  ＃１　蓮の長さ：２、蓮の数：８

SORTWK1: [E F] [A B] [6 7] [2 3]
SORTWK2: [C D] [8 9] [4 5] [0 1]
MERGE  : [C D E F] [8 9 A B] [4 5 6 7] [0 1 2 3]
  ＃２ 蓮の長さ：４、蓮の数：４

SORTWK1: [C D E F] [4 5 6 7] 
SORTWK2: [8 9 A B] [0 1 2 3]
MERGE  : [8 9 A B C D E F] [0 1 2 3 4 5 6 7]
  #4 蓮の長さ：８、蓮の数：２

SORTWK1: [8 9 A B C D E F]
SORTWK2: [0 1 2 3 4 5 6 7]
MERGE  : [0 1 2 3 4 5 6 7 8 9 A B C D E F]
  #5 蓮の長さ：１６、蓮の数：１

FINISH : [0 1 2 3 4 5 6 7 8 9 A B C D E F]
```

SORTWKをREADしてMERGEへWRITEしたり、MERGEをREADしてSORTWKへWRITEしたりは、シーケンシャルアクセスとなっています。


## 処理時間に関する考察

- 【メモリ】 メモリを使うのは、SORKWK1から取り出したデータとSORTWK2から取り出したデータの比較だけなので、データ二つ分で足りる。
- 【ファイルIO】 １回の分割＆マージで、蓮の長さが２倍・蓮の数が半分になるので、データ数をN・分割＆マージ回数をnとすると、 ```2**n = N, n = log2(N)``` となる。
- 【計算量】 n回の分割・マージごとに、N回の比較をしているので、計算量は ``` オーダ N✖️log(N)``` となる。

```
外部ファイルを使った分割＆マージの回数 n = log2(データ数 N)
計算量 N*log(N)
```
コマンドラインで電気をつけよう

どうもはじめまして、@hatepoと申します。
はじめてQiitaなるものに投稿してみようかと思います。
とはいえ最近仕事ではあんまりコードも書いてないので、趣味のスマートホームデバイスの話でも。

# スマートホームデバイスは賢い
スマートスピーカーが出始めて、それに対応するスマートホームデバイスもいっぱいでてきてますよね！
スマートホームデバイスはIoT機器として単にインターネットにつながってスマートスピーカーから操作できるだけではなく、それぞれのデバイスを連動させて操作できたりするあたりがスマート（賢い）なんでしょうね。

# SwitchBotは楽しい
なかでも[SwitchBot](https://www.switchbot.jp/)は、リモコンやセンサー、カメラなんかだけじゃなく、カーテン開閉器や加湿器なんかまで出しちゃうあたりバカっぽくてよいです。（絶賛）
そしてSwitchBotのとってもいいところは、デバイスを操作するAPI仕様が一般に公開されていて、自由に使えちゃうところです。
ほらもう楽しい。

# コマンドラインで電気をつけよう
というわけでタイトルの「コマンドラインで電気をつけよう」を実際にやってみて、楽しさを共有できればと思います。

## 用意するもの
* [SwitchBotハブミニ](SwitchBotハブミニ)
* SwitchBotアプリ（iPhoneまたはAndroid）
* 赤外線リモコンで操作できるライト

## 事前準備
* SwitchBotアプリインストール
* SwitchBotハブミニにライトをデバイス登録

## 1. SwitchBot OpenAPIのトークンを取得
アプリでやっていきます
![プロフィール画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318632/023ce1f3-d58f-2e27-2db2-e736818b8d56.png)
プロフィール画面から設定画面に移動

![設定画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318632/2e1fa46d-4031-452a-11f1-100e73bfeb85.png)
設定画面にある`アプリバージョン`という項目を10回タップ（裏技っぽい！）

![開発者向けオプション出現.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318632/e7b4d3e8-a3f1-d94a-4beb-e44df222332c.png)
すると`開発者向けオプション`という項目が出現（裏技っぽい！2回目）
この`開発者向けオプション`をタップ

![開発者向けオプション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318632/a62d87b1-a379-0722-ccf4-c2b898f1be7b.png)
この`トークンを取得`ボタンを押すとトークンが表示されますのでコピーしておいてください。

::: note alert
このトークンであなたのSwitchBotデバイスが操作できちゃいますので公開厳禁です！
:::

## 2. デバイスIDを取得
これであなたのSwitchBot OpenAPIがたたけるようになりました。
SwitchBotに登録されているデバイスはすべてデバイスIDが設定されていて、そのデバイスIDをキーに操作することになりますので、まずはデバイス一覧を出してデバイスIDを取得しましょう。

```
curl -X GET -H "Authorization:トークン" https://api.switch-bot.com/v1.0/devices
```
とたたくと

```
{"statusCode":100,"body":{"deviceList":[{"deviceId":"Hub MiniのdeviceId","deviceName":"Hub Mini","deviceType":"Hub Mini","hubDeviceId":"000000000000"}],"infraredRemoteList":[{"deviceId":"lightのdeviceId","deviceName":"light","remoteType":"Light","hubDeviceId":"************"}]},"message":"success"}
```
ってなjsonが返ってきます。
今回はライト(deviceNam:light)を操作したいので、デバイスIDは`lightのdeviceId`ってことになります。注：デバイスIDは加工してます。

## 3. 電気をつけよう
ようやく本題です。
さきほど取得したデバイスIDに対して、コマンドをPOSTでなげます。

```
curl -X POST https://api.switch-bot.com/v1.0/devices/lightのdeviceId/commands -H "Authorization:トークン" -H "Content-Type:application/json"  -d "{""command"":""turnOff"",""parameter"":""default"",""commandType"":""command""}"
```
とたたくと

```
{"statusCode":100,"body":{},"message":"success"}
```
って返ってきて部屋が真っ暗に・・こわい！
間違えました。電気をつけたいので先ほど`command:turnOff`としたところを`command:turnOn`にすれば電気がつきます

```
curl -X POST https://api.switch-bot.com/v1.0/devices/lightのdeviceId/commands -H "Authorization:トークン" -H "Content-Type:application/json"  -d "{""command"":""turnOn"",""parameter"":""default"",""commandType"":""command""}"
```
電気がつきました、よかったです。

# おわり
いかがでしたでしょうか。
APIでデバイスをいじれるようになると夢が広がりますね！
紹介したハブミニ以外にも色々な機器がAPIでいじれますので、SwitchBotを購入してスマートデバイスを楽しんでみてください！
今なら[クリスマスセール中](https://www.switchbot.jp/pages/try-switchbot)で全品20%OFFで買えますのでこの機会に是非。25日まで！

# 参考
SwitchBot OpenAPIの仕様は[こちら](https://github.com/OpenWonderLabs/SwitchBotAPI)
【NW-Tips】NATトラバーサルは、どのような問題を解決しているのか？

# はじめに
先輩：「これ、NATトラバーサルの設定が必要」
私：「NAT、、、トラバーサル？」

NATやNAPTは、資格試験の勉強で学びました。
しかし、トラバーサルってなんだ？ということで、サーベイ内容をまとめます。

# "NATトラバーサル"の問題設定
* NAT/NAPTは、プライベートIPアドレスと、グローバルIPアドレスを紐づけ、相互変換する技術です。少ないグローバルIPアドレスで、多数の端末を接続することができます。
* しかし、外部NW（グローバルNW）から内部NW（プライベートNW）の端末へ直接アクセスして、通信する使い方はできません。

* そのため、**通信の主体（端末）が直接接続することが前提の技術は、正常に動作しない**です。
* 具体的には、通話ソフト（VoIP）や、VPN、ファイル共有ソフト（P2P）などが該当します。

* つまり、**NAT/NAPTにより、通信相手のプライベートNW内の端末に、直接到達できない（NATを通過できない）**。という問題があります。
* この問題の解決方法（技術）を総称して、NATトラバーサルと呼びます。

#NATトラバーサル
NATトラバーサルの各種技術については、下記サイトを参照しました。
簡潔に各技術の概要がまとめてあります。

https://www.liveon.ne.jp/glossary/w/nat_traversal.html

#"IPsec通信における、NATトラバーサル"の問題設定

* NAT/NAPTは、パケットのIPヘッダを変更します。
* NAPTであれば、TCPポート/UDPポート（ポート番号）まで変換します。

* IPsecは、TCP/UDPヘッダまで暗号化します。そのため、**NAPTはポート番号を読み取ることができません**。

* つまり、**NAPTは、暗号化されたTCP/UDPヘッダ内のポートを変換できないため、通信が成立しない**。という問題があります。

* この問題は、ルータの"NATトラバーサル"機能を有効化し、解決します。

#IPsec通信における、NATトラバーサル
**ポイント：UDPカプセル化により、新たにUDPヘッダ付与**

* ESPパケット（送受信するデータを暗号化し、暗号化情報/認証データを付与したパケット）を、UDPでカプセル化します
* 新たに付加したUDPヘッダは、暗号化の対象となりません。
* そのため、NAPTでポート番号の書き換えが可能になります。

# おわりに
"NATトラバーサル"には、NAT/NAPTにより発生する問題の解決方法全般を指す場合と、IPsec通信をするために、UDPカプセル化の有効化を指す場合の、２つの意味で使われていることがあります。
どちらも本質的な問題は同じですが、SE同士はもちろん、関係者と認識の齟齬を起こさないためにも、意識してコミュニケーションを取ることが重要だと思います。
（実際、私も混乱したため、Tipsとして記録することにしました）

# 参考文献
[[1].LiveOn 用語集, ”NAT越え（NATトラバーサル - NAT traversal） とは”](https://www.liveon.ne.jp/glossary/w/nat_traversal.html)
[[2].IT用語辞典 e-words, ”NATトラバーサル 【NAT traversal】”](https://e-words.jp/w/NAT%E3%83%88%E3%83%A9%E3%83%90%E3%83%BC%E3%82%B5%E3%83%AB.html)
[[3].ネットワークエンジニアとして, ”IPsec - NAT Traversal”](https://www.infraexpert.com/study/ipsec15.html)
データエンジニアにキャリアチェンジした1年を振り返る

# はじめに

皆さんはじめまして！フリーランスエンジニアの毛利です。

今年は、フリーランスの業務アプリケーションエンジニアからデータエンジニアへキャリアチェンジした転機となる1年でした。

それ以外にも、
* 地方にいながら首都圏案件へ参画
* 単価アップ、増益増収達成
* 育休1ヶ月取得
 
このあたりが、個人的な成果と考えています。

本記事では、キャリアチェンジした際の課題感や実践したことなどをまとめました。

* エンジニアとしてのキャリアに悩んでいる
* データエンジニアとしての仕事内容に興味を持っている

こうした方にとって、少しでも参考になりますと幸いです。


# データエンジニアとは？
平たく言いますと、主に企業がビジネスで利用するためのデータを整理し、利活用できる状態となるようデータ分析基盤を構築、運用する業務を担当するエンジニアです。


# 実務内容は？
ETLの構築が、主な業務内容となります。

ETLの詳しい説明は本題からずれるため、割愛しますが、ここでは、データ分析するためのDWHへ格納するために、未整備のデータを加工、変換し、DWHへ取り込む処理やそのツールを指します。

データを利活用できる状態にすることが、データエンジニアの主な業務となるのですが、「データを加工して終わり」というケースは稀で、ユーザにご利用いただける状態にするまでの付随業務が発生します。

例えば、

* クラウドインフラの設計/構築
* BIツールの設計/実装

などが挙げられます。企業によっては、データエンジニアの業務としている場合もあります。
このあたりは、会社組織によって異なる印象です。

## 実例

私の場合、業務委託でいくつかの案件に参画し、その案件によって担当業務が異なりました。

例えば、A案件では、ETLの設計、実装、数値検証がメインとなれば、B案件ではBI実装がメイン、というイメージです。

案件によって担当業務が様々な仕事だと感じました。


### 利用した技術要素
私がこれまで担当した主な技術スタックは、以下のとおりです。

* 言語
    * Python、PHP(Laravel)、SQL
* クラウドインフラ
    * AWS(S3/Glue/Athena/DynamoDB/Redshift(Spectrum))
    * GoogleCloud(GCS/GCE/BigQuery)
* ワークフローエンジン
    * Airflow、Digdag

言語的には、Pythonがメインですが、業務的に重たい部分としては、データの抽出、加工部分が大半を占めているため、SQLの比重は比較的大きくなってきます。

# 参画前の課題感と対応したこと

こうした業務をすべて最初から完璧にこなせることはなく、手探りで進めていきました。
当時不安だったことを思い返すと、このあたりに課題感を持っていました。

### 課題：新しい環境への適合 → 対策：空気感を言語化し質問する
#### 課題
* 新しい現場に参画すると、コミュニケーション方法やプロジェクトの進め方などは案件によって様々です。
* また、開発プロセスが言語化しきっているケースは珍しいですし。
* スケジュール感なども違うので、スピード感を把握しておかないとリリースタイミングに影響が出てきます。

#### 対策
* まず、商談時点で気になる点を確認しました。
* ただし、商談でわかるのは一部だけなので、参画後に「こんな感じの進め方で問題ないか？」とPMと認識合わせました。(スケジュール感やプロセスなど)
* 一番気をつけた点としては、「え？やってくれてないの？」と言われないよう丁寧に対応を進めました。
* チームに貢献できると思ったことは、最初は優先度を確認しつつ進めることで、徐々に温度感などを把握するよう心掛けました。

### 課題：技術的なキャッチアップ → 対策：テストモジュールを作成し、プロジェクト依存の部分を把握する
#### 課題
* 「新しいワークフローエンジンを理解するまでに時間がかかりそう」という不安は初期の頃ほど強く感じました。

#### 対策
* まず、構成図をメモ書きでスケッチし、アーキテクトの理解に努めました。
* その上で、コードを書き、サンプルワークフローを実行しました。
* あとは、権限周りなどプロジェクト特有のエラーが出た際に、メンバへ確認する。
* この流れを取ることで、自分が理解できている部分や把握漏れがある部分が明確になるので、比較的キャッチアップする際には使っています。


# これまでの経歴が活かせた点

* ETL実装を検証する際、様々な視点でデータの整合性見る必要があります。このあたりは、SIerで試験項目作成やテスト実施した経験が活かせました。

* これまでの業務の中で、SQLをゴリゴリ書いた経験が、かなり重宝しました。裏を返すとSQL経験がないと、未経験から案件参画までの道は険しいようにも思えました。正社員としてデータエンジニアへ転職を目指すようでしたら、このあたりはしっかりポートフォリオ等で証明できる必要がありそうな感覚です。

 
# 今後の予定

今後、エンジニアとしてのスキルを伸ばす上で、このあたりも学習+実務経験を積む予定です。

### 勉強会の参加/主催
今後は学習内容や業務での気付きを勉強会などオフラインの場でも発信していく予定です。というのも、発信することで経験も整理されますし、これまでの自分のようなSE経験が長い人に、少しでも興味を持っていただき、人生が好転するようなちょっとしたキッカケにつながると嬉しいからです。

### Tableau構築
ETLだけでなく、データアナリストとの連携ができるためにもBIツールの経験を積みたいとも考えています。これまでGoogleDataPortalによるダッシュボード構築は経験済みですが、BIツールの肌感市場シェアの8割はTableauなので、しっかりと経験を積んでおきたい、、そんな思いで、予定に入れています。

### クラウドインフラ構築
ETLでは、パフォーマンスが重視されるケースも多く、アーキテクト設計まで出来ることで、提供価値が高まる傾向があるかと考えています。優先度はそこまで高くはありませんが、随時学習を進めていきます。

# まとめ
SEからデータエンジニアという仕事にキャリアチェンジすることは、業務経歴と相性がよく、大きく業界を変えることにつながり、結果的にモダンな現場に参画できれば、地方にいながらフルリモートも可能です。

とはいえ、まだまだデータエンジニアとして習得すべき技術課題が残っているため、今後ともしっかり学習しつつ実務へ転用していきます。

# さいごに

最後までお読み頂きありがとうございました！

感想や気になる点、深堀りしたい点など、お気軽に[Twttier](https://twitter.com/engineer_takuto)にてDMいただければ回答いたします。

それ以外にも、[昨年のアドベントカレンダー](https://qiita.com/mouritakuto/items/596e9c229c9b5c9e5104)でも、データエンジニアへキャリアチェンジするまでに実践したことなどをまとめています。
バックオフィスメンバーと業務自動化をやっている話

[さくらインターネット Advent Calendar 2021](https://qiita.com/advent-calendar/2021/sakura) 20日目の記事です。

3度目まして。さくらインターネットで情シスをしている小泉行生(dumixnet)と申します。

[昨年](https://qiita.com/dumixnet/items/9a61d56a2e24cd149750)、[2年前](https://qiita.com/dumixnet/items/0d51989746ad603cfaa1) と書かせていただきましたが、今年も何かお伝えできればと存じます。

#今年は何を書くの？
今、現在進行形でやっている「バックオフィスメンバー」と行っている自動化について、
気づきと振り返りを書いていこうと思います。
今、自動化の業務をしている人たちに何か伝わればいいかな？と思います。

#バックオフィスは思ったより便利機能の使い方を知らなかった。
さくらではSlackをコミュニケーションツールとして使っています。
しかしバックオフィスは日常業務もあるため「使い方」をわかって使ってはいませんでした…
こういうのは「ちょっとヒントをあげればきっと楽になるはず」とちょっとだけサポートしてみました。

#どうやってサポートしたのか？
Slackには「リマインダー」という機能があります。
これと特定のURLをメッセージとして組み合わせればわざわざ自分でブラウザを開いて見に行かな書くても
サムネイルで台風の状況を確認したり、URLを開くだけで郵便局で起きている最新の停止状況を見ることができます。
「大したことない事」に聞こえるかもしれませんが、僕の方で「便利な使い方」という形でサンプルをお渡しして困っている本人にやってみたら？とお伝えして覚えてもらいました。
バックオフィスにとってみると「勝手に何かしてくれる」という事自体がとても効果のある事に気付かされました。
めっちゃ小さい事なのですが、「知らないと手数がかかるが、知っていると応用が効いて簡単に自動化できる事」になります。

#もう一歩進むとどうなるのか？
最近メンバーと一緒にやっているのは「Microsoft PowerAutomate」です。
こいつのレシピを少しいじると「SharePointにファイルが置かれたらSlackに通知させる」とか「とあるMLのメールをExchangeで受信したらSlackに通知させる」と言ったような、ワンランク上の自動化ができるようになります。
ここまでの自動化は「ほぼノーコード」でできました。
しかも「自動化したいと思っている本人」が自動化させることができたので、作った人に「成功体験」をしてもらうことができました。

#今、何に取り組んでいるのか？
「PowerAutomateDesktop」を利用して「手作業」を自動化していくハンズオンをやっているところです。
まだ「完成」はしていませんが、徐々に進行中で、私も作っている人の困ったを解決して進めるお手伝いをしています。

#今、どんなことを意識してサポートしているのか？
今どんなことを意識してサポートしているのか伝えていきたいと思います。

##成功体験を実感してもらう
どんなに小さいことでも「自動化を完成させる」ということをサポートしています。
成功したら次に繋がってくれるはずです。

##できない事だけをサポートするようにする
できるだけ自走してもらうために「できない事(技術的、言語的なサポート)」だけをサポートするようにしました。

##人間が今やっていることを自動化する
業務の自動化なので「やりたいことを自動化」しても成功するわけありません…
いくつかやってみて気づいたのは「やっていることの例外はわかるけど、やってないことの例外は未知数」なのです。
自動化することは「仕込みをちゃんとやっていかに例外をなくしていくか？」が大事になってきます。
ベストな自動化は「すでに作業手順があって例外対応がわかっている業務」になります。

##自動化が運悪く失敗した時は「運用でカバーできる」ようにしておく
もし「俗人的で手順がない」作業のの自動化を行いたい場合は必ず「手順」をどこかに書き残してから自動化を始めましょう。
自動化したとしてもうまく動かなかったりしても「だれか」が手作業のぬくもりでカバーできるようにしておくことで、
もう俗人化から抜け出せる幸せな世界が待っています。

##自動化でログインが求められる場合「専用ユーザー」を作っておく
夜中に「個人のアカウント」が勝手に作業を始めたら、「●●さん、夜なべしてます」と言われて怒られてしまうかもしれません。
もっとあるとしたら「●●さんのアカウント乗っ取られてないですか？」なんてこともあるかも…
そういう事情を回避するためにできるだけ「自動化専用アカウント」を作っておきましょう。
グルーピングする場合も「自動化してるメンバーと同じグループに入れておく」事で権限のトラブルの回避ができます。

#最後に
今年は1bitも技術的なことが書かれていませんが… 少しづつ知見やQiitaに載せられそうなことが増えてきたので、
こんどこそ「役に立つ技術」を共有できるように頑張ります。
今年も読んでいただきありがとうございました。
GitHub　入門向けの自分メモ

GitHubの用語について
ローカルリポジトリ：　ローカルリポジトリはGitHubで共有するためのファイルを保存する場所で、自分のPC内に保存されています

リモートリポジトリ：　WEBサービスであるGitHubに存在するファイルの保管場所　リモートリポジトリのファイルにはローカルリポジトリの更新内容が上書きされる

コミット: コミットは作成したファイルや更新情報をローカルリポジトリに登録する操作のこと。
ファイルを更新して保存すればファイルそのものは変更が保存されますが、Gitに変更を登録するには必ずコミットを行うひつようがあります。

プッシュ：　プッシュはローカルリポジトリで更新したファイルをリモートリポジトリにアップロードする操作　ファイル更新→コミット→プッシュ　でGitHubのリモートリポジトリに更新できます。


GitHub　実際に使う手順

１　GitHubにリモートリポジトリを作る
start a new project　をクリック　Repository name　を入力　ファイルヲ保管する場所の名前は任意のものを使えます。
２　作ったファイルをローカルリポジトリにコミットする　「git add」コマンドを使用します
ファイルをコミット（登録）するとGitで管理できる対象のファイルになります
３ファイルをリモートリポジトリにプッシュする　「git remote」コマンドでリモートリポジトリにファイルを追加します。　リポジトリのURLはGitHubで作ったリポジトリのURLを指定します
４「git push」　コマンドでリモートリポジトリにアップロードします　成功したらユーザーネームとパスワードを聞かれるので、自分のGitHubのユーザーとパスワードを入力します
ASTERIA WarpでGCSとkintoneをつないでみた

ASTERIA Warpを介してGCS（Google Cloud Storage）とkintoneをつないで画像付きの名刺データをkintoneへ登録する処理を行うフローを作成してみたのでご紹介します。
名刺データは展示会などのイベントにて訪問して頂いたお客様の名刺を対象しており、他社のRPAツールを利用して電子データ化し、GCSへ格納しています。
「名刺データなのにGCSからもってくるの？」って思ってしまう方もいらっしゃるかと思いますが、上記のような経緯でASTERIA WarpではGCSとkintoneの連携処理となります。

全体的な連携イメージは下記の通りです。

`お客様の名刺 → 別のRPAツール → GCS → ASTERIA Warp → kintone`


## GCSの名刺データ
それではGCSに格納された名刺データを確認してみます。
![gcs_kintone_0010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/bd8ba4fc-f9f7-c885-fdbc-9a4d98b50673.png)
ご覧の通り、Zip形式で圧縮したファイルがGCSへ格納されています。

![gcs_kintone_0021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/f4bc44e5-b205-6d79-5808-fbd428056cea.png)

Zipファイルには名刺情報が記載されているCSVファイルと名刺の画像ファイルが含まれています。

![gcs_kintone_0031.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/664d9732-fe09-5cb3-6f40-3f2a06a27e8b.png)
CSVファイルは上記の通り構成されています。


## kintoneのアプリ

それでは、名刺データを登録するkintoneのアプリを確認します。
![gcs_kintone_0040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/45951c5c-ab3f-c7ad-f4f2-94eac355db09.png)
![gcs_kintone_0050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/89c3183b-4740-15c9-4286-5f718c8c4268.png)

お客様の情報、担当者、検討されている製品以外にも展示会での相談内容や名刺画像も登録できるような構成となっています。

## フローの構成

#### ■Mainフロー
![gcs_kintone_0061.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/b28c4ab0-06e5-e796-2efc-c4c8b7da7d94.png)

Mainフローでの処理は以下の通りです。
①GCSから名刺データをダウンロード処理を行うサブフローを呼出
②ダウンロードしたZipファイルを解凍して作業フォルダーへ格納
③名刺データ情報をkintoneへ登録するサブフローを呼出
④作業フォルダーを削除

#### ■subGCSから名刺データをダウンロードフロー
![gcs_kintone_0071.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/7743e180-3b00-5c6e-e5ea-f60b0e34ffe9.png)

GCSからファイルをダウンロードする処理は以下の通りです。
①GCSからオブジェクトリストを取得
②取得したオブジェクトがフォルダーかファイルかを判別
③ダウンロードするファイル情報をマッピング
④GCSから名刺データファイルをダウンロード
⑤ダウンロードしたファイルをGCSから削除

#### ■sub名刺データをkintoneへ登録フロー
![gcs_kintone_0081.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/1334491d-d110-5c3a-0ceb-cbacc1ecfc19.png)

名刺データをkintoneへ登録する処理では、まず、名刺画像をアップロードしてから名刺データを登録します。
処理の詳細は以下の通りです。
①名刺データが記載されているCSVファイルから一行ずつデータを読み込む
②処理データに名刺画像がある場合、kintoneへアップロード
③アップロードした画像データのIDを取得
④kintoneへ名刺データを登録


## フローの実行結果
![gcs_kintone_0101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156332/7f46df63-740f-6b6c-34dd-c15e582c5fcf.png)

ご覧の通り画像付きの名刺データが正常にkintoneへ登録されていることが確認できます。