OmniAICreator/Qiita-1.07M huggingface dataset:
アジャイル開発で最低限作成したいドキュメント「ロゼッタストーンドキュメント」

# はじめに
はじめまして株式会社ナイトレイの渡辺です。
この記事では、実際に弊社の開発チームが実践しているロゼッタストーンドキュメントについての概要と、書くべきドキュメントについての考え方などを記載します。

# ロゼッタストーンドキュメントとは
ロゼッタストーンドキュメントは（自分自身も含めた）未来のチームメンバーに向けて書く簡潔な手引書を指します。ソースコードやテストコードだけでは理解しづらい、開発対象システムの全体像の把握につながる情報を記します。

ちなみに、ロゼッタ・ストーンとは、エジプトのヒエログリフを理解する鍵となり、他の古代エジプト語の記録も解読が可能になったと言われているみたいです。

## 弊社が実際に書いている内容
弊社ナイトレイで実際に書いている内容は以下です。
ある程度の規模の機能単位ごとに作成しています。
1. システムの概要
2. 担当者、リポジトリやサーバーの在処
3. システムの開発経緯
4. システムの目的 (開発理由)
5. システムの設計や仕様
6. ビルドと動作確認の実行手順
7. その他補足
8. 関連資料リンク

## 何が良いの？
- これ1つあればシステムの概要を把握でき、すぐに作業を開始できる
- ソースコードの読解力が促進されること
- 概要レベルの情報なので、ドキュメントを更新する際も短時間で済む

# アジャイル開発におけるドキュメントの考え方
## 書かなくて良いは間違い
「アジャイルだからドキュメントを書かない」という話は一度は耳に入れたことがあると思います。ただ、これはきっと誤解です。
誤解の理由は、[アジャイルソフトウェア開発宣言](https://agilemanifesto.org/iso/ja/manifesto.html)に記載されている「包括的なドキュメントよりも動くソフトウェアを」が原因だと思われます。しかし、ここでは「包括的」なドキュメントだけを指しているのであって、ドキュメントは全て不要と表現されているわけではありません。むしろ、`「必要最低限」なドキュメントはシステムにとって当然必要である`ということが暗に示されているようにも感じます。では、その必要最低限とは何を指すでしょうか？


## 必要最低限でいこう
必要最低限は、もちろん組織によって異なるはずです。また、組織のフェーズによっても異なるはずです。なので、常に議論されるべきことであると考えています。ちなみに、弊社では`保守の際に最低限困らないようにする`ためにドキュメントが必要と定義しているので、その意味でロゼッタストーンドキュメントは必要最低限として挙げています。

## 無駄なドキュメントは削っていこう
もちろん、`必要最低限`以外のドキュメントは**アジャイルソフトウェア開発宣言**のとおり削っていくべきです。なので、常に`必要最低限`のドキュメントは何か？という議論に合わせて、`削るべき`ドキュメントは何か？も議論していくべきです。弊社にとって削るべきドキュメントは「機能の具体的な使い方」、「細かすぎる仕様書」などでした。

ドキュメントあるあるかもしれませんが、作ったはいいが作りっぱなしで結局未来で一度も見られなかったなんてこともありますし、ドキュメントはあればあるほど運用コストがデカくなります。アジャイル開発者にとってソースコードを書くのと同じレベルでドキュメントも書くことに慎重になるべきだと思います。

## 大前提　ソースコードもドキュメント
必要最低限のドキュメントを書いていくには、ソースコードもドキュメントであることも意識する必要があると思います。結局はコードに書いてあることが１番細かいシステムの情報だと捉えることもできるので、誰が見てもわかりやすいコードを書いたり、理解をサポートするようなコメントを含ませたり、そのようなアプローチは非常に有用だと考えています。

```
システムの概要はドキュメントで
より細かい情報はソースコードで
```
非常にシンプルだと思います。

# まとめ
- ロゼッタストーンドキュメントがあればシステムの概要を把握でき、すぐに作業を開始できる
- 「アジャイルだからドキュメントを書かない」は間違い
- 必要最低限のドキュメントと、削るべきドキュメントを定義することが大事
- システムの概要はドキュメントで、より細かい情報はソースコードで

# 参考資料
- http://www.kumikomi.net/archives/2012/11/ep15agi2.php
- https://agilemanifesto.org/iso/ja/manifesto.html
- https://gihyo.jp/dev/serial/01/agile/0004?page=4#sec2_h1

# 最後に
私たちの会社、ナイトレイでは一緒に自社開発のWebサービスを盛り上げてくれるエンジニアメンバーを募集しています！ 
基本的には直接ユーザーと接することのないポジションですが、セールス部門から
「顧客の声」を教えてもらったり、希望すればユーザーとのMTGに参加することも可能です。
モチベーションの高め方はあなた次第。

このような方は是非Wantedlyからお気軽にご連絡ください（もしくはこちらまで recruit@nightley.jp ）

 ✔︎ 自社Webサービスの開発で事業の発展に携わってみたい
 ✔︎ 自分が開発したサービスで地域活性化に貢献したい
 ✔︎ 位置情報ビッグデータに興味があり、新しい活用方法を提案したい
 ✔︎ 地理や地図が好きで仕事中も眺めていたい 

一つでも当てはまる方は是非こちらの記事をご覧ください 

 https://www.wantedly.com/projects/467606 

▼ナイトレイとは？

https://www.wantedly.com/companies/nightley
Grid Layoutを学び直す

[ひとりCSS Advent Calendar 2022](https://qiita.com/advent-calendar/2022/css-becolomochi) 3日目です。

Grid Layoutを学び直します。

## Grid Layout にするには

親要素に `display: grid;` を指定すればできる。

### サンプル

```html
<div class="parent">
  <div class="child">
    child
  </div>
  <div class="child">
    child
  </div>
  <div class="child">
    child
  </div>
</div>
```

```css
.parent {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41088/77a1080e-7a91-85e1-7387-bdcd077c978a.png)

## 親要素に指定できるプロパティ

### 名前でサイズと位置を決めたいとき

`grid-template-areas` は、あらかじめ子要素に `grid-area` で名前をつけておく必要がある。
:memo: 名前をもとにレイアウトを決められるので、コンテンツが入る一番外側のレイアウトを作るときに便利。

### サイズで決めたいとき

- 基本のサイズ指定
    - `grid-template-columns` - 横方向のサイズの指定
    - `grid-template-rows` - 縦方向のサイズの指定
- 子が溢れたときの指定
    - `grid-auto-columns` - 横方向の暗黙的なサイズの指定
    - `grid-auto-rows` - 縦方向の暗黙的なサイズの指定
- サイズの指定方法
    - 数字
    - `auto` - 子要素しだい
    - `1fr` - 1frはひとマス分。
        - fr は fraction(分数の意味)の略らしい。
    - `repeat` - 繰り返しで指定できる
        - `repeat(3, 1fr)` なら 1fr のサイズの子要素3つ分という指定。
    - `minmax` - 最小値と最大値の指定
        - `minmax(100px, auto)` なら最小値が100px、最大値は auto という指定。
- 余白
    - `column-gap` - 横方向の余白
    - `row-gap` - 縦方向の余白
    - `gap` - 余白のショートハンド
        - 2つ値を与えるときは `gap column` 半角空白を間に入れて、たて よこの順。
    - 過去は `grid-column-gap` のように頭に `grid-` がついていた。今はつけてもつけなくてもOKらしい。

### 配置を決めたいとき

- `place-items` - 子要素の配置を決められるショートハンド
    - `align-items`, `justify-items` 半角スペース区切りで指定する
    - `place-items: center` で上下左右中央配置ができる

## 子要素に指定できるプロパティ

### 要素に名前をつけたいとき

`grid-area` 

- 例えば、`grid-area: header;` `grid-area: main;` `grid-area: sidebar;` とか
- 名前をつけてわかりやすくできる。値にはダブルクオーテーションは不要。
- コンテンツが入る一番外側のレイアウトを作るときに便利。

### 大きさの指定

- ショートハンド - スラッシュで区切って書く
    - `grid-column` - 横方向の指定
    - `grid-row` - 縦方向の指定
    - 例えば、`grid-column: 1/-1` なら左端から右端まで
        - 最小値は `1`
        - マイナス値は逆方向から数えた位置
- マス目（グリッド）で大きさを指定する
    - `grid-column-start` 横方向の開始位置
    - `grid-column-end` 横方向の終了位置
    - `grid-row-start` 縦方向の開始位置
    - `grid-row-end` 横方向の終了位置

## 遊んでみた

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZERqqpK" data-user="becolomochi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/becolomochi/pen/ZERqqpK">
  Flexbox</a> by Beco (<a href="https://codepen.io/becolomochi">@becolomochi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

↓こういうレイアウトも作れて楽しい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41088/e6eac799-a144-4e9d-3057-f05673a894a3.png)

## 感想

- たのしい
- いろいろなプロパティが多く難しい
    - が、実装するなら使用するプロパティは限られてくる（多分。。）
- まずやりたいレイアウトからどれを使えば想定した実装になるか逆算して作ると良さそう


## 参考

- https://www.w3.org/TR/css-grid-1/
- https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout
- https://css-tricks.com/almanac/properties/g/grid-template-rows/
価値のあるデータ分析を行うために：分析におけるドメイン探索と仮説構築方法

この記事は [アイスタイル Advent Calendar 2022](https://qiita.com/advent-calendar/2022/istyle) 3日目の記事です。

こんにちは、アイスタイルが運営しているサービスを横断して、計測・データ基盤構築・BIツールなどデータのライフサイクルに携わっている やす です。

本記事は、普段担当しない、もしくは初めてのサービスや事業のデータ分析案件に携わったときに、そのような逆境の状態でも **価値があるデータ分析** を行うためのプロセスをまとめたいと思います。
※ 筆者はWEB業界×化粧品業界のデータエンジニア/データアナリストなので、前提の抜けた説明や単語の利用があるかもしれませんがご了承ください。

# 背景：専門領域ではない分析案件にアサイン
![【テンプレート】PJT・報告_@ver のコピー (5).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105197/2b89ae99-ea1b-247f-70e4-2c3a5e4ffb09.jpeg)
データ分析を仕事にする中で、対象となるプロダクトやサービスの知識がない状態でデータ分析を行う場面は自身の経験としてありました。
一般的にはデータアナリストの方が別業界への転職や、退職に伴う引継ぎで普段行わない領域の分析をする場面にも当てはまると思います。

そのような逆境の中で **価値のあるデータ分析**を行うために実践している一つのプロセスを紹介したいと思います。ここでの価値のあるデータ分析とは **分析だけでなく、アクションにつながる新たなアイディア** を価値とします。

ただし、分析する対象の知識がある人（プロジェクトマネージャー、プロダクトオーナーなど）に対して、知識や経験ががない状態のデータアナリストが成熟するには時間がかかります。

この「新たな」を見つけるためのプロセスを以下に紹介します。

# 方法：転がっているドメインを拾いに行く
![【テンプレート】PJT・報告_@ver のコピー (6).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105197/fb14294f-6471-87d1-e3a7-50f8a09d6199.jpeg)
## ドメインとは
以下はシステム開発におけるドメイン駆動開発の引用ですが、ドメインとはまとめるに「対象となる領域とそれを構成する要素」と解釈しています。例えば、業務が手順書化されており言語化されているものなどはわかりやすく理解ができ、ドメインの知識が獲得しやすい形です。
今回は **新たなドメイン** を見つけるために、**隠れているドメイン** をまず見つけにいきます。

> ドメインは「領域」の意味をもった言葉です。ソフトウェア開発におけるドメインは、「プログラムを適用する対象となる領域」を指します。
> 引用元： [ドメイン駆動設計とは何なのか？ ユーザーの業務知識をコードで表現する開発手法について|CodeZine（コードジン）](https://codezine.jp/article/detail/11968#:~:text=%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%AF%E3%80%8C%E9%A0%98%E5%9F%9F%E3%80%8D%E3%81%AE%E6%84%8F%E5%91%B3,%E3%81%AA%E3%82%8B%E9%A0%98%E5%9F%9F%E3%80%8D%E3%82%92%E6%8C%87%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)

## 重要人物の会議の発言/言いまわし
仕事で関わる人で、分析する対象の知識がある人（プロジェクトマネージャー、プロダクトオーナーなど）の **無意識の前提** はその人の発言に現れることがあります。
例えば、ECサイトに関連するPJTオーナーが今月の目標を話すときに「新規/既存のユーザーの数を目標にして、特に新規のユーザーを増やしていこう」と発言があった時「新規/既存」はECサイトチームでの前提知識の上で成り立っているのがわかりますでしょうか。
**いったい何を初めてした人が新規で、すでに何をした人が既存なのか** がポイントです。
この場面ではそういった **前提** が隠れています。ここではECサイトですので「新規/既存」 は「初めて購入してくれた人/すでに購入経験がある人」とします。
つまり **対象は購入した人という前提** が隠れています。

## ドキュメント/クエリなどの成果物
必ずしも会議の発言に隠れドメインがあるわけではなく、ドキュメントの文章や過去の方が残したデータ分析のクエリ、レポートなどにも隠れています。
特に議事録や要件をまとめたスプレッドシートなどにも上記のような **言い方が曖昧だけど相手は伝わると思っている** 情報はたくさんあります。

# 「モレなく・ダブリなく」の観点で仮説を立てる
![【テンプレート】PJT・報告_@ver のコピー (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105197/a8b865b2-8fc8-a92f-fb04-e5acda622bb9.jpeg)
先ほどの例では **対象は購入した人という前提** という隠れドメインを見つけました。この隠れドメインを **モレなく・ダブリなく** の視点で考えると **購入しなかった人** という反対のイメージを作ることができます。

ここでは隠れドメインから新たな観点を生み出すことに成功しました。

# そしてデータ分析へ
![【テンプレート】PJT・報告_@ver のコピー (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105197/108802a5-77ad-a0fd-17c7-8ab432e61d15.jpeg)
上記の仮説に基づいて、例えば購入しなかった人のグルーピングで購入の手前の行動、例えばWEBサイトのページビューやSNSなどのいいねの数を利用し、行動パターンの分析などを行い、仮説を磨き、分析結果から施策提案やプロダクトオーナーと議論をすることで、隠れドメインを利用した **価値のあるデータ分析** をすることが可能です。

# 最後に注意点
ただし、隠れドメインは意図して排除している場合もあります。優先度やリソースの関係、過去に効果検証したけど新たな情報は得られなかったなどの理由が考えられます。それでも、逆境の状態から議論の範囲を広げられたり、過去の知見を得るきっかけになります。

※ このアプローチは決して言語化されているドメインに向き合ったデータ分析を否定するものではありません。その積み重ねがあるからこそ **隠れているドメイン** ができています。
initキーワードとrequiredキーワードを使ってオブジェクト初期化子で生成可能なバリューオブジェクトを作る

# はじめに
本記事はinitキーワードとrequiredキーワードを使うことでオブジェクト初期化子で生成可能なバリューオブジェクトを作る方法についてまとめます。
本記事は[こちらの記事](https://qiita.com/tat_tt/items/8963c723826a60dbd3f1)の続編です。

# 前回記事のサンプルの問題点
[前回記事](https://qiita.com/tat_tt/items/8963c723826a60dbd3f1)では、initキーワードを使うことでオブジェクト初期化子で生成可能なバリューオブジェクトを作る方法をまとめました。
バリューオブジェクトのクラス定義は以下のような感じです。
```csharp
/// <summary>
/// バリューオブジェクト
/// </summary>
internal class ValueObject
{
    #region プロパティ

    /// <summary>
    /// 値
    /// </summary>
    internal string Value { get; init; } = string.Empty;

    #endregion
}
```
上記のバリューオブジェクトはValueプロパティがinitキーワードを使って定義されています。そのため、Valueプロパティはインスタンス生成時にオブジェクト初期化子によってのみ設定可能となり、インスタンス生成後に以下のように上書きはできません。(ビルドエラーになります。)
```csharp
// 初期化以外での値の設定はできないので、以下はビルドエラーとなる
valueObject.Value = "changedValue";
```
ですが、前回の記事の[こちら](https://qiita.com/tat_tt/items/8963c723826a60dbd3f1#%E3%81%BE%E3%81%A8%E3%82%81)でも記載したように上記のバリューオブジェクトは、以下のように引数なしコンストラクタでインスタンス生成することができるという問題があります。
```csharp
// 値の初期化をしなくてもインスタンス生成できてしまう
var valueObject = new ValueObject();
```
つまり、値がないバリューオブジェクトを作ることを許容してしまっています。

# requiredキーワードを使って前回記事のサンプルの問題点を解消する
前章で示した問題点を解消するためC#11.0で追加された[requiredキーワード](https://learn.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-11#required-members)を使います。
以下のようにバリューオブジェクトのValueプロパティにrequiredキーワードを追加することでValueプロパティの初期化が強制されます。
```csharp
/// <summary>
/// バリューオブジェクト
/// </summary>
internal class ValueObject
{
    #region プロパティ

    /// <summary>
    /// 値
    /// requiredキーワードを追加し、初期化を強制する
    /// </summary>
    internal required string Value { get; init; } = string.Empty;

    #endregion
}
```
初期化が強制されるので、元々できていた以下のような引数なしコンストラクタでのインスタンス生成はできなくなります。
```csharp
// オブジェクト初期化子による初期化を強制しているため、以下はビルドエラーとなる
var valueObject = new ValueObject();
```
この書き方をすることでオブジェクト初期化子によっての初期化を強制できるようになるため、ようやくオブジェクト初期化子で生成可能なバリューオブジェクトの定義ができるようになります。

# まとめ
本記事ではinitキーワードとrequiredキーワードを使うことでオブジェクト初期化子で生成可能なバリューオブジェクトを作る方法についてまとめます。
オブジェクト初期化子で生成可能なバリューオブジェクトを定義する際には、initキーワードに加えてrequiredキーワードが必要であることがわかりました。
preCICE/OpenFOAM/CalculiXでの流体構造連成シミュレーション 


オープンソースのシミュレーションソフトを使って流体構造連成シミュレーション(FSI；Fluid Structure Interaction )をした結果を動画で紹介します．

FSIは,流体解析(CFD)と構造解析(CFD)を組み合わせた計算のことです．
適切にシミュレーションを行うにはCFDとCAEの両方の知識が必要なため,CFD単独やCAE単独に比べると事例がなかなか見つかりません．

厚さの無視できる薄い板をシミュレーション解析するとき，流体解析(CFD)ではバッフル要素,構造解析(CAE)ではシェル要素でモデル化します．
FSI自体の事例がCFD単独やCAE単独と比べて少ないうえに,構造体がソリッド要素になっている事例がほとんどで，商用ソフトを含めてバッフル要素/シェル要素を使ったFSIの事例は少ないようです．
オープンソースを使ったバッフル要素/シェル要素を使ったFSIの事例はこれまで見つからず,おそらく初めての事例だと思います．

https://youtu.be/v2KXFwmyLJ0
[備忘録][Azure] AppServiceのアウトバウンドグローバルIPを固定化する

# はじめに

サポートの方にきいてみた

> Web App からのアウトバウンド通信の送信元 IP を固定化する方法について
> NATゲートウェイを使用する以外に方法があるのでしょうか？

# 公式のおすすめ

NAT Gatewayを利用してアウトバウンドIPを固定化

[Azure公式ドキュメント - 静的送信 IP を取得する](https://learn.microsoft.com/ja-jp/azure/app-service/overview-inbound-outbound-ips#get-a-static-outbound-ip)

>仮想ネットワーク NAT ゲートウェイを使用して、静的パブリック IP アドレス経由でトラフィックを送信すると、アプリからの送信トラフィックの IP アドレスを制御できます。 リージョン VNet 統合は、Standard、Premium、PremiumV2 および PremiumV3 App Service プランのみで使用できます。 このセットアップの詳細については、NAT ゲートウェイの統合に関するページを参照してください。
 
## やり方を適当に説明

用意するリソース

- AppServiceプラン(VNet統合できる、Standard、Premium、PremiumV2 および PremiumV3のいずれか)
    - AppService
- NAT Gateway
- PublicIP
- VNet
    - 1つのサブネット

1. NAT GatewayにPublicIPを紐づける
2. サブネットにNAT Gatewayを紐づける
3. AppServiceをVNet統合する
    - 用意したサブネットに紐づける
    - この時、必ず「ルート全て」設定をONにする(参考: [アプリケーション ルーティング](https://learn.microsoft.com/ja-jp/azure/app-service/overview-vnet-integration#application-routing))
        - じゃないとアウトバウンド通信全てがSNATされず、IP固定化できない通信が発生する

# 一応他の方法もあるらしい

理論上は NAT Gateway の代わりに NVA (仮想ネットワークアプライアンス) で SNAT を実施することで、送信元 IP を固定できるらしい。
(構成例)
App Service ---> VNet ---> NVA ---> Internet

現時点(2022/12)で上記構成は公開されている情報はなく、Azureサポートもおすすめはしてないみたい。
「特別な理由がない限りは、NAT Gateway と組み合わせて送信元 IP を固定化する方法をご検討いただければと存じます。」ですって。

公式で明言されていない以上、動作確認や性能テストは自分達で全て担保する必要があるので、やるメリットは少なそう。

# NAT Gatewayを使うデメリット

## ゾーン冗長化できない

NAT Gatewayはゾーン冗長に対応しておらず、特定アベイラビリティゾーンへのデプロイとなってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647946/c83d0996-8720-863f-10a4-392f1078c179.png)

しかし、サブネットに紐づけられるNAT Gatewayは1つだけ。
つまり、NAT Gatewayをデプロイしたアベイラビリティゾーンで障害が発生した場合、AppServiceプランがゾーン冗長化されていようとも、もろとも影響を受けてしまう。

フィードバックも上がってるみたいなので、いずれ改善されるかもしれません。望み薄。

https://feedback.azure.com/d365community/idea/3c5a1b30-8b26-ec11-b6e6-000d3a4f0789

ちなみにPublicIPも冗長化に対応してる。あとはNAT Gatewayだけ。
Pythonで九九の表を作ります

## Pythonで九九
エンジニアとして成長するためにアウトプットをして自分の復習になればと思い作成しました。
今回なぜ九九の表を作成するかというと最近娘(6歳)が九九をいえるようになって感心したのがきっかけです。
基本のfor文の復習も兼ねてます。

## 二重for文
九九の課題といえばfor文を二重で使うことでしょうか。
実際にコードを書いていきます。

```Python
for i in range(1, 10):
	for j in range(1, 10):
		print(i * j, end=" ")
	print()
```
上記のコードを実行すると、
```
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
```
このような結果が得られると思います。

簡単にコードを見ていきます。
まず初めに、
```Python
for i in range(1, 10):
```
1から9までを順番にループします。
次の
```Python
for j in range(1, 10):
```
もう一つの1から9までを順番にループします。
print文の中は、
```Python
print(i * j, end=" ")
```
i * jで掛け算を行い、　end = " "でprint文で出力した値の末尾を指定しています。
この場合は横一列で九九の結果が表示されます。
仮に
end = " "がない場合は出力結果が縦に出力されます。
最後の行の
```Python
print()
```
改行のみを出力しています。
今回の場合では、１の段、２の段、、、９の段と分かれるようになります。

Pythonのprint文では何も指定しなければ、改行コード"\n" (バックスラッシュ+n)が末尾に出力されます。



ただ九九の表を作るだけならこれで終わりですが、
せっかくなので色々やってみたいと思います。

上の結果だと一桁と二桁が存在する関係で見栄えが悪いように見えないでしょうか？
せっかくなので右揃えで揃えてみたいと思います。
基本的なコードはそのままです。

```Python
for i in range(1, 10):
    for j in range(1, 10):
        ans=i * j
        print(f'{ans:>4}', end="")
    print()
```

コードをみていきます。
```Python
ans=i * j
print(f'{ans:>4}', end="")
```
九九の結果をansに代入します。
そのansが４桁分の幅以上を使うという意味です。

コードを実行すると下記のような結果が得られます。
```
   1   2   3   4   5   6   7   8   9
   2   4   6   8  10  12  14  16  18
   3   6   9  12  15  18  21  24  27
   4   8  12  16  20  24  28  32  36
   5  10  15  20  25  30  35  40  45
   6  12  18  24  30  36  42  48  54
   7  14  21  28  35  42  49  56  63
   8  16  24  32  40  48  56  64  72
   9  18  27  36  45  54  63  72  81
```

この形なら見やすくてわかりやすいですね。

最後は九九の重複する三角形の部分をカットして表示してみます。
九九とは少しずれてしまうかもしれませんが。

初めにコードです。
```Python
for i in range(1, 10):
    for j in range(1, 10):
        if i <=j:
            ans=i * j
        else:
            ans=" "
        print(f'{ans:>4}', end="")
    print()
```
今まではi * jで全て掛け算をしてきましたが、重複する部分をカットするために
if文を使って掛け算する値を絞ります。
```Python
if i <=j:
　　　　ans=i * j
```
jの値がi以上の時、掛け算を行うようにします。
```Python
else:
　　　　ans=" "
```
jの値がi以下の時は空白とします。

実行結果は下記です。
```
   1   2   3   4   5   6   7   8   9
       4   6   8  10  12  14  16  18
           9  12  15  18  21  24  27
              16  20  24  28  32  36
                  25  30  35  40  45
                      36  42  48  54
                          49  56  63
                              64  72
                                  81
```

このようにコードを記述することで、重複部分をカットし、三角形の形で出力できるようになりました。

## おわりに
今回はPythonで九九の表を作成しましたが、実際の現場でも二重for文を使うことはありますし、
データを取り出すだけでいいこともあれば、形を整えることが必要なこともあると思います。

これからも少しずつ成長しながら発信していきたいと思います。
[競プロ]二分木の高さのバランスが取れているかどうかの判定

# 二分木の高さのバランスが取れているとは

二分木の高さのバランスが取れている（**height-balanced**）とは、
二分木において、全てのノードの左右の部分木の高度差の絶対値が1以下であること。

# 問題

[Leetcode 110.Balanced Binary Tree](https://leetcode.com/problems/balanced-binary-tree)

# アルゴリズム

ボトムアップとトップダウンのアルゴリズムが考えられる。

## ボトムアップ

Python code
```python
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        return self.recur(root) != -1

    def recur(self, root):
        if not root:
            return 0
        left = self.recur(root.left)
        if left == -1:
            return -1
        right = self.recur(root.right)
        if right == -1:
            return -1
        return max(left, right) + 1 if abs(left - right) < 2 else -1
```

recur(root):
* 再帰の戻り値
    * rootノードの左右の部分木の高度差＜2の場合、rootノードの最大高度(max(left, right) + 1)を返す。
    * rootノードの左右の部分木の高度差＞＝2の場合、高さのバランスが取れていないので-1を返す。
* 再帰の停止条件
    * 葉ノードの先にあるNoneノードは、高さ0を返す。
    * 左or右部分木の高さが-1の場合、左or右部分木は高さのバランスを取れていないので-1を返す。

計算量: O(N) (最悪の場合全てのノードを辿るため)

## トップダウン

Python code
```python
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if not root:
            return True
        return abs(self.depth(root.left) - self.depth(root.right)) <= 1 and self.isBalanced(
            root.left) and self.isBalanced(root.right)

    def depth(self, root):
        if not root:
            return 0
        return max(self.depth(root.left), self.depth(root.right)) + 1
```

depth(root):
* 再帰の戻り値：
    * 左右部分木の最大高度+1を返す。
* 再帰の停止条件：
    * 葉ノードの先にあるNoneノードは、高さ0を返す。

計算量:　O(NlogN)

## メモ

![368C3469-EB63-4B33-B760-8C782AECC4E2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260307/2daf1ad5-a981-6f9f-28c5-f8b3d7058e80.jpeg)
golangを勉強しようと思ったので調べたみた

# golang入門
PHPerなバックエンドがgolangをやってみようという記事。

## 前提
初学者ではなくある程度他の言語を経験して、go言語を習得してみようという人間の個人的な見解です。

## ツール
golandを使ってます。補完機能やコードフォーマッタとかがデフォルトでも割と使えます。
会社で買ってくれないので個人で買ってますが…:thermometer_face:


### 動機
静的型付け言語を学びたいというだけです。

## 学習方法
1\. 書籍
2\. 動画 （udemy)

### 1.書籍
[はじめてのGo言語](https://www.oreilly.co.jp/books/9784814400041/)
未読ですが最近出版されたばかりのなのでおすすめしておきます。目次だけみると一通り基本のことは学べるみたいです。

[実用 Go言語](https://www.oreilly.co.jp/books/9784814400041/)
これも今年発行された本で、実務で使うかた向けになるのでおすすめしておきます。

### 2.動画(udemy)
動画教材はudemy一択なので、ほかはあまり見てないです。

[【Go入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)](https://www.udemy.com/course/golang-webgosql/)
udemyなら、これが一番web開発の基礎から、goroutineの並行処理について学べます。19.5時間もあるので結構盛りだくさんです。
並行処理は正直難しかったところです。


### 終わりに
次はテストの書き方とか、設計とかを勉強したいです。
Ledger CLIをインストールする

これアドベントカレンダーなんですけど、すでに2日なのですごく浅い感じで行きます。

# Ledger-CLIって何

ledgerでぐぐったら仮想通貨のなんかライブラリが出てきますが、全然関係ありません。

https://www.ledger-cli.org/

この「複式簿記をプレーンテキストでつけたい」というヤバいソフトウェアです。

# どうやってインストールするの

お使いのOSのパッケージマネージャに頼んでください。

```shell
# Debian系の人
$ sudo apt install ledger
# Macのひと
$ brew install ledger
# Windowsのひと
$ choco install ledger
```

簡単ですね。Debian/UbuntuでEmacs使いの人は`elpa-ledger`を、Vim使いの人は`vim-ledger`をインストールしておくと更に幸せになれます。VS Codeにもextensionがありますが、どうにもポンコツです。無いよりはマシ程度と思ってください。

# 使ってみたい

```shell-session
$ ledger --version
Ledger 3.2.1-20200518, the command-line accounting tool

Copyright (c) 2003-2019, John Wiegley.  All rights reserved.

This program is made available under the terms of the BSD Public License.
See LICENSE file included with the distribution for details and disclaimer.
```

多分これじゃない。

```shell-session
$ cat > test.ledger <<EOF
2022/12/01 スーパーで買ったわ
    Expenses:Grocery        2,000 JPY
    Assets:全財産
EOF
$ ledger -f test.ledger balance
          -2,000 JPY  Assets:全財産
           2,000 JPY  Expenses:Grocery
--------------------
                   0
$ ledger -f test.ledger register
22-Dec-01 スーパーで買ったわ                           Expenses:Grocery                                                    2,000 JPY                  2,000 JPY
                                                       Assets:全財産                                                      -2,000 JPY                          0
$ ledger -f test.ledger register "Assets:全財産"
22-Dec-01 スーパーで買ったわ                           Assets:全財産                                                      -2,000 JPY                 -2,000 JPY
```

なんか残高とか色々表示されてますね。え？全然わかんない？仕訳って何？詳しい説明を明日以降していきます。次↓

https://qiita.com/kikeg/items/5d363e5b13358e896a9a
【SwiftUI】ATTの許可率を上げる方法

# はじめに
まず、こちらの記事を見てみてください。
[Appleのアプリのトラッキングの透明性でiOS開発者の収益が15%〜20%減](https://iphone-mania.jp/news-382414/)

これはかなり重大な問題です。

iOS14.5からAdMobで全画面広告(リワード広告やインタースティシャル広告)を表示する際はトラッキング許可ダイアログ(以下、ATT)の表示が必須になりました。
ユーザーが許可するか拒否するかで広告収益がかなり変わってきます。
なるべく許可してもらいたいですよね

今回はちょっとの手間で1%許可率を上げることができたので方法を紹介しようと思います。

# トラッキングの許可のリクエストについて
https://developer.apple.com/jp/app-store/user-privacy-and-data-use/

# どのくらい収益が変わるか
アプリによっても異なるのですが、このくらいの差がありました。
![スクリーンショット 2022-12-02 13.04.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/192c537d-56a1-57ef-e7e8-a34ea3b13ffd.png)

:::note info
**eCPMとは？**
eCPM（有効インプレッション単価）は、広告表示 1,000 回ごとに得られる収益の見積り額で、「（合計収益額/表示回数）× 1,000」で算出されます。

[eCPM Google AdMob ヘルプ](https://support.google.com/admob/answer/3016008?hl=ja)
:::

# 方法
こちらを使用します。

https://github.com/jevonmao/PermissionsSwiftUI

以前はUIKitのバージョンも[こちら](https://github.com/sparrowcode/PermissionsKit)にあったのですが、現在はSPPermissionsからPermissionsKitに改名されていてUIの提供がなくなったみたいです。

# デザイン
![simulator_screenshot_BAF18B2B-A2D8-4949-9240-73125CE19B15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/e5bcc903-5227-763b-8e08-1a833daecc48.png)

# 実装
```swift
import SwiftUI
import PermissionsSwiftUITracking

struct ContentView: View {
    @State private var isShowPermissionRequest: Bool = false
    var body: some View {
        VStack {
            Button {
                isShowPermissionRequest = true
            } label: {
                Text("表示")
            }
        }
        // トラッキングパーミッションリクエスト
        .JMAlert(showModal: $isShowPermissionRequest, for: [.tracking])
        .changeHeaderTo("アクセス許可が必要です")
        .setPermissionComponent(for: .tracking, title: "トラッキング")
        .setPermissionComponent(for: .tracking, description: "広告をカスタマイズする機能です。")
        .changeBottomDescriptionTo("許可しない場合、一部の機能が使えない可能性があります。")
    }
}
```

# 結果
|使用前|使用後|
|-|-|
|![使用前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/91aed60a-7cdd-4682-815f-6f4573a089f0.png)|![使用後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/62e4cc69-08e3-f1f5-d37c-3843888d477c.png)|

# いいなと思った案
ATTではないですが、ABEMAアプリの通知許可アラートのガイドがとても良いと思いました。
かなり許可率が上がりそうです。
![IMG_1748.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/7c7a5ce3-8b1a-f188-1718-9035f1424f1c.png)

# おわり
ATTの許可率を上げれるよう良い案はどんどん取り入れていきたいです。
【初心者】AndroidStudio　ダウンロードと画面概要（インストールは割愛）

# 先に追記
もしAndroidStudioとUnityを迷われている方はこちらも見てみてください。

https://qiita.com/kiyoZy/items/5185d9915db7ae8ea43f


# 記事内容
AndroidStudio公式ページからダウンロードが出来ず対処を書くつもりでQiitaに登録してみたのですが、今日はダウンロードページが直っていました💦

ちょうど良い（？）ので自身のメモも兼ねてプロジェクトの作成と画面操作概要を書いてみました。何かの参考になりましたら幸いです。

※説明部分には赤四角と赤矢印を使用しています。

* 動作環境

| OS | AndroidStudio | 
|:--:|:--:|
| Windows 10 | Android Studio Flamingo 2022.2.1 |


# ダウンロード


### AndroidStudioがダウンロード　…出来ない！？
そんな訳で…今日は直っていましたｗ
この前ダウンロードボタンをクリックしたのですがダウンロード出来きず焦りました💦
![ダウンロード画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/3c231995-f6f6-19db-817a-a43ee33b9a28.png)


### 過去にもダウンロード出来ないことはあったようです
もしダウンロード出来ない場合は画面下側にexeファイルへのリンクがあるのでこちらからダウンロードできます。　自身のメモも兼ねて。
![ダウンロード画面_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/93e6366e-ae7d-7c9d-e99c-fbb4101c9811.png)


### インストールは割愛で
大体そのまま進めました。
最初に設定が出るかと思うので好きな表示などを選択します。
「Previous」ボタンで前の画面の戻れます。



# プロジェクト作成


### ひな型を選択
「Empty Views Activity」を選択して「Next」ボタンをクリックします。
![01_プロジェクト作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/47dd8fe2-4d43-55ec-67c0-bedf977d4f29.png)


### プロジェクト名を入力
そのままでも問題ありません。
「Name」にプロジェクト名を入力して「Finish」ボタンをクリックします。
![02_プロジェクト名を入力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/106a325e-174d-e7ba-5147-b42381b336e5.png)


### フォルダとファイルを表示
赤四角の「Project」などをクリックしてフォルダが見えるようにします。
※表示内容は少し違っても問題ありません。
![03_画面表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/0fa924c9-43ce-4e41-2616-a9554c673e14.png)

フォルダをクリックしていくとファイルが見えるようになるので今回確認するファイルを表示してみます。
![04_フォルダ展開.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/9262a30d-c9ae-b376-411e-bf3422314c83.png)

・プログラム動作時に最初に実行されるファイル
　「app/java/com.example.myapplication」以下にある「MainActivity.kt」

・画面用設定ファイル
　「app/res/layout」以下にある「activity_main.xml」

ファイルはダブルクリックで表示できます。
ファイルを開くと「project」タブが閉じてしまいますがまたクリックすれば開きます。（設定で固定も出来ます。）
![05_ファイル表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/fd83712e-7e22-64e7-2a66-5fc711003765.png)

各ファイルのタブをドラッグすれば好きなレイアウトで表示できます。
今回は2つのファイルを左右に配置してみました。
![06_ファイル表示02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/8c6a2a88-03f5-da89-5ba5-c688e8159b09.png)

画面用設定ファイル「activity_main.xml」は右上の「Code」「Split」「Design」をクリックすると表示内容が変更できます
![07_画面設定用ファイルの表示切替.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/d2d392ee-d58e-aec6-eecd-ff9615b949fd.png)


AndroidStudioのダウンロードとざっくりした使用方法でした。



AndroidStudioでエミュレーター（AVD、仮想デバイス）を使用した設定はこちらに書きました。

https://qiita.com/kiyoZy/items/035e748207e0ba807bb0
Microsoft の OpenHack (DevOps) に参加してきた


# やりたいこと

以前に、Data WareHouse の OpenHack に参加 ([Microsoft の OpenHack に参加してきた](https://qiita.com/coitate/items/1ff6bdc81698f0b66682)) したが、今回は、DevOps に関する OpenHack に参加してきたので今回も記事にしようと思います:bulb:

# OpenHack とは？

Microsoft が主催するハッカソン形式のイベント。Open と名もついているので誰でも参加でき、いろんな企業や職種の方が参加していた。
詳しくはここ: https://zine.qiita.com/event/202112-microsoft/

# 何するの？

OpenHack には、AI だったり Data WareHouse だったりと様々なテーマがあるが、今回参加したのは DevOps に関するもの。
参加されている人数によって複数チームに分かれて、与えられたお題に沿って実際に Azure 上でリソースを作成してお題をクリアできるように開発していく(今回は1チーム4人+コーチだった)。
スキルセットもばらばらなので、チームで課題を解決していくことが重要になる。困ったときにはコーチに助けを求めることができる。今回の OpenHack については、必要なスキルセットは少ない(と思う)。DevOps (CI/CD) がどんなものか概念レベルで分かっていれば大丈夫だと思う。
お題はいくつかのステップで設定されており、それらを1つずつクリアしていく形式。今回の OpenHack としての合格はステップ5まで。
そこまでクリアするとバッジがもらえる！

# 感想

:::note info
前回の参加記事との重複も含みます
:::

## 良かったところ

* 自分たちで考えて実際に手を動かして、サービスを触りながら学べる！
  * これに尽きる！実際に手を動かすのは大事！
    * 目的を達成するのに複数の方法があるので、そこも含めてどれが良いか考えることができる
      * ハンズオンも似ているけど、ハンズオンは基本的に流れに沿って作業するだけ(考えることが少ない）
* DevOps の考え方について具体的に学べる！
  * GitHub や Azure DevOps の使い方(設定)や CI/CD パイプラインの作成などなど
  * 最初の設定から実際に CI/CD パイプラインを構築してそれを何らかのトリガ (Commit 時とか、Pull Request 時とか) で実際に動かすところまで経験できる
* コーチにいろいろと聞ける！
  * DevOps に関することはもちろん、(ある程度関連した) それ以外のことまで聞くことができた
  * 最終日のクロージング後には、QA 後に雑談もしたw

## 微妙なところ

* テーマと関係がない本質ではない部分でよく分からないエラー
  * 権限まわりでよく分からないエラーが出て半日くらい時間を費やしてしまったので、そういった本質ではない所でのエラーが起きにくい環境にしてほしい
    * そういう所を解決しながら進めるのもハッカソン形式の醍醐味ではあるけど、そこより本質の部分を進めたい
    * 上記の原因は、OpenHack 用のサブスクリプションが通常のものとは異なっているために起きた (のではないか) とのこと

# 総括すると

参加してよかった！Azure での DevOps を実践的に学ぶことができた！
これまで Github で CI/CD は組んだことがあるが、Azure DevOps を使ったのは初めてだったので良い経験になった。特に Azure DevOps はパイプライン定義の yaml ファイルだけでは設定できない項目があったり、GUI で設定をオーバーライドする必要があったりとやや中途半端な印象だったが、それを実際に経験できたのは良かった。また、他企業の方と一緒に1つの目標に向かって取り組むことができ、いろいろと勉強になった。
あと、やっぱり実際に手を動かすのは大事！ただ話を聞いているだけだと身につかない！ (と個人的には思う)

# 参加するには

不定期にあちこちで案内はでているらしい (どこか特定の所ではないっぽい)。
今回は社内で案内があり開催されることを知ることができたが、そういったものがないとそもそも開催されることすら知ることができないかもしれない。アンテナ張って情報探しましょう！


以上です。
新卒研修でWebサービスをEC2で構築し、HTTPS化で躓いた話

[ディップ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/dip-dev) 3日目の記事です。

## 概要
新卒向けの開発研修でWebサービスをAWS(EC2)上に構築した際、HTTPS通信を実現するために色々苦戦し得た知見を本記事で共有いたします。
これからインフラを勉強する初心者エンジニアの方々の参考になれば幸いです。

## 背景
研修で作成したアプリの概要は以下の通りです
- PHP, Laravelで開発
- サーバはEC2上で構築
- ミドルウェアはApache
- 社内向けのWebアプリケーション
- Slack認証機能付き

また、研修時点の私のAWSの理解度は「ちょっと触ったことがある」程度で、ほぼ初学者レベルでした。

## アプリをデプロイしていざHTTPSでアクセス！

研修でアプリケーションを完成させ、いざEC2にデプロイ！
HTTPでアクセスしたところ、無事アプリのトップ画面が表示されました。

今回開発したアプリにはSlackでのログイン認証機能が搭載されており、コールバックURLとしてHTTPSのエンドポイントが必須でしたので、HTTPSでもアクセスできるか試みたところ事件は発生しました・・。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/4f54fb35-0d10-a883-c817-5684c80c758b.png)

あれ？アクセスできないぞ？

## 施策①　オレオレ証明書をApacheに読み込ませる

調べたところ、HTTPSでアクセスできるようにするにはSSL証明書が必要だということがわかりました。
とりあえず手っ取り早くHTTPSでアクセスできるのを確認できるようにするため、Apacheにオレオレ証明書を読み込ませてみます。
（研修とは言えども、社内サービス構築するのにオレオレ証明書使うのはどうなんだって感じですが・・）


**手順**
EC2サーバ内の/etc/certs/配下にSSL証明書用の秘密鍵・公開鍵・証明書を作成
`openssl genrsa > server.key`
`openssl req -new -key server.key > server.csr`
`openssl x509 -req -signkey server.key < server.csr > server.crt`

作成したそれぞれの鍵情報をapacheに読み込ませてあげる
```ssl.conf
SSLCertificateFile /etc/certs/cerver.crt
SSLCertificateKeyFile /etc/certs/server.key
```

参考: https://qiita.com/nkojima/items/91988b1e91e311311040


**結果**
エラーページは消えず、安全に接続できませんでした。

## 施策② opensslで作成した鍵・証明書をACMにインポートする
Apacheのconfファイルでダメなら、AWSのACMを使って読み込ませよう！

**手順**
施策①で作成した鍵をACMに読み込ませる。



**結果**
またしてもアクセスできず・・・



## 解決策 Elastic IP + Route53 + ALB + ACMでHTTPS通信を確立

ここでようやく解決策です・・。
EC2サーバ内で鍵を生成したり、外部サービスから証明書を取ってこなくても、AWSリソースを駆使すればHTTPS通信が実現できると判明しました。

各種リソースの役割は以下の通りです。

- Route53
    - SSL証明書・Webサーバとドメインの関連付けを行う
- ACM
    - 証明書を管理する
- Elastic IP
    - ドメインに関連づけるための固定のIPアドレスを設定する
- ALB
    - アプリと証明書を連携させ、HTTPSアクセスできるようにする
    - HTTPでのアクセスをHTTPSにリダイレクトさせる

![無題のプレゼンテーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/9c1ffd11-2556-9812-c9d7-2f59eac90b4d.png)



AWSリソースを複数使うので初心者の自分にとってはなかなか大変でしたが、先輩の助けを借りつつ、一つ一つのリソースの役割を学びながらWebサービスのHTTPS化を実現できました。


## HTTPS通信の実現を経て学んだこと

「WebサイトのHTTPS化」を実現するためには、DNS設定・ロードバランサ・SSL証明書等の多くの設定が必要であり、Webサービスを支えるさまざまな仕組みについて学ぶことができました。
また、ドメインやロードバランサなどが **「一体なんなのか」** ということはなんとなく知っていたもの、**「なぜ必要なのか」「どういう時に必要か」** といったことを考え学ぶきっかけにもなりました。

書籍でWebサイトを支える仕組みを体系的に学ぶことも大事ですが、今回のように実際に手を動かして「HTTPS化を実現する」といった要件を満たすインフラを構築することは、Webサイトを支える仕組みについて **本質的** に理解を深めるために役に立つと実感しました。

「インフラ勉強したいけど、どうやって勉強すればいいんだ・・？」と迷っている方は、「HTTPS化されている」「特定のIPアドレスのみアクセスできる」といった **「特定の要件付きのシステム」** を実際に手を動かして作ってみるといいかもしれません。

## 参考・関連記事
https://qiita.com/m-kazu/items/aa44789f9183f5a61104

https://dev.classmethod.jp/articles/alb-route53-acm-build2/
運用してるサービスのNode.jsバージョンをアップデートするまでの道のり

## 現在の状況
現在運用中のサービスのNode.jsバージョンが（かなり）古いため、
それをアップデートしないとそろそろやばいのでは？から始めました。（いって現在運用中のサービスに関しては、スタイルのビルドぐらいしか使ってなかったのでずっとメンテナンスsれてなかったのです・・）
現在のLTSがv16だったので、
[Node.jsリリース一覧](https://nodejs.org/ja/download/releases/)
まずはv16系にアップデートすることになりました。

## 問題
ただバージョンあげました、わーい:tada:で終わる話でしたらすごく良かったのですが、
すぐさま壁にぶつかってしまいました・・
現在使ってるパッケージのバージョンも一緒にあげないといけないので、Node.jsのバージョンを上げると同時にパッケージのバージョンも全てチェックしないといけなかったわけです。

今回はその中でもネックだったものを紹介したいと思います。
+ gulp
現在のサービスのスタイルのビルドの時使っていて、ずっと使っていたバージョンがv3.9.1であり、gulpって３と4で色々差があり、文法はもちろんバージョン3までがNode.js１１までしか使えず、それ以上のバージョンにするにはNode.js12以上が必要だったため、まずはgulpを4にしないといけなかったです。

ここで少しグチになっちゃいますが、現在担当してるサービスのフロントは自分一人だったので、通常業務を行いながらこちらまでカバーすることがとても難しくずっと後回しにされてました。それが全社的にバージョンアップデートをちゃんとしよう！という流れを作ってやっと着手することになりました。

諸論が長かったのですが、gulpの4に合わせてgulpfile.jsの文法を直しました。
主に違うところは`gulp.task`と`gulp.watch`の書き方です。

### gulp.task
```javascript:gulpfile_v3.js
gulp.task('css-minlib', ['css-conclib'], function() {
```

```javascript:gulpfile_v4.js
gulp.task('css-minlib', gulp.series('css-conclib', function(){
```

### gulp.watch
```javascript:gulpfile_v3.js
gulp.watch('css/sp/common.css', ['css-min']);
```

```javascript:gulpfile_v4.js
gulp.watch('css/sp/common.css', gulp.task('css-min'));
```

これだけです笑
これがなぜか昔一回チャレンジした時にうまく行かず、放置状態でしたけど
いざちゃんと取り組んだら30分もかからずびっくりでした。

これでgulp4を導入して動かしたところ、綺麗に回ってくれました。パチパチ:clap_tone1:


## 残りの作業
でNode.js v16に無事切り替えられたかと言われるとそれがまだ・・:sweat:な状態です。
色々理由はありますが早くアップデートを終わらせたい気持ちでいっぱいいっぱいです笑
そもそもv16が2023年の9月でサポート切れるということで、もうv１８にした方がいいのでは・・？とも思ってるところです。

その時にはまたv18でパッケージが動かない可能性もあるので要チェックですね。
【JavaScript】基礎用語集まとめ

# はじめに

今回の記事では、学習を始めたばかりの方向けに基本用語を解説していきたいと思います。
JavaScriptでは紛らわしい用語も多々あるので、1つ1つ具体的に説明できればと思います！

# JavaScript学習にお勧め

忍者CODEでは、多数の無料問題集から有料のコンテンツまで用意されています。
「初心者でいきなりお金かけて学ぶのは怖いなあ」
「まずはお金をかけずに学びたい」
そんな方には非常におすすめなサービスなので是非活用しましょう！

https://ninjacode.work/


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

## オブジェクト

オブジェクトとは、プロパティの集合体のこと。
「人間」を例に挙げると、その「人間そのもの」のこと。

## プロパティ

プロパティとは、「キー：バリュー」の組み合わせのこと。
オブジェクトの要素（中身）を決める役割をします。
先ほど例に挙げた「人間」にはそれぞれ様々な情報がありますよね。
年齢、性別、出身、好きな食べ物など挙げだすとキリがありませんね。
この例に挙げた「年齢、性別、出身、好きな食べ物」が「キー」にあたります。
「バリュー」はその個別な情報「20歳、男、大阪、カレーライス」のことを指します。
オブジェクトにはたくさんのプロパティが存在するということですね。

## 関数

関数とは、複数の処理をひとまとめにしたものです。
関数は、よく自動販売機に例えられます。
自動販売機ってお金を入れてボタンを押せば飲み物が出てきますよね。
この単純なような動作の中で沢山の処理が行われています。
「金額によって押せるボタンが変わる」、「金額によってお釣りが変わる」、「ボタンを押したらその飲み物が出てくる」など
何通りものパターンに合わせて処理が行われています。
このすべての処理をまとめたものが関数という事になります。
JavaScriptで関数を作る場合、パソコンに「これは関数ですよ！」と認識させるためにfunction()を使います。

## メソッド

個人的にはかなりややこしい部分。関数と何が違うのか？
メソッドとは、プロパティに紐づけられた処理のことを指します。メソッド＝（プロパティ名：関数）
要するに関数はオブジェクトのプロパティに入れられると、メソッドになるということです。

# あらかじめ用意されたオブジェクト

## windowオブジェクト

windowオブジェクトとは、ブラウザの情報を持っているオブジェクトです。
ブラウザの最上位であるオブジェクトがwindowオブジェクトです。
JavaScriptで予め定義されているメソッドやオブジェクトは全てwindowオブジェクトのプロパティであると言えます。
windouwオブジェクトの中にconsoleオブジェクトや、documentオブジェクトがあります。

## documentオブジェクト

documentオブジェクトとは、ブラウザ上で表示された情報を操作する事のできるオブジェクトです。
このdocumentオブジェクトは様々なプロパティやメソッドを持っています。したがって、documentオブジェクトはこれからHTMLに対して何か処理をする際は頻繁に使用するオブジェクトとなります。
基本的にブラウザ上に文字などを表示させたい場合は、「docment.プロパティ」という形で記述します。

# 組み込みオブジェクトとは

組み込みオブジェクトとは、あらかじめJavaScriptで用意されているオブジェクトのことです。
組み込みオブジェクトは、組み込み関数ともいわれています。
例をあげると、dateオブジェクト、arrayオブジェクト、stringオブジェクト、Mathオブジェクトなどがあります。
HTMLメルマガを外部に入稿するときにやること（備忘録）


HTMLメルマガ。

はるか昔、社内で管理しているEC-CUBEのメルマガ機能から送信したことがあるけど、
約10年ぶりに携わったのが、原稿(HTML)をそのまま納品するstyle…

要はテスト送信からのトライアル＆エラーを手元で気軽にできないということです。

結論から言うと
・テスト送信してもらったものを別アドレスへ転送しての確認は、余計なスペースが入り込む

・PCメーラー、PCブラウザ、SPメーラー、SPブラウザ等、
各種環境の確認用メアドをリストにしておき、テスト送信時にはその全てに送ってもらう
※メールクライアントのシェアについては随時チェックしてクレメンス

・tableタグとインライン記載に思いを馳せる「まだ生きとったんかワレ…」


当記事を書くにあたり「インライン table css メルマガ」で調べていたら下記の記事を発見しましたよ
https://bashalog.c-brains.jp/17/06/27-183511.php
>ウェブページを作るようにメルマガを作れる日は来るのでしょうか。

こちらの記事が書かれたのは2017年。そして現在2022年…。


その日は未だ訪れておりません。
SvelteKitでPlaywrightコンポーネントテストを行う注意点

この記事は[SvelteKit Advent Calendar 2022](https://qiita.com/advent-calendar/2022/sveltekit)の5日目の記事です。

今日から3日間、SvelteKit Advent Calendarを書かせていただきます。@kubotakです。

さて、この記事ではSvelteKitでPlaywrightコンポーネントテストを行う方法を紹介します。
前提として、Playwrightとはなにか？みたいな話やSvelteコンポーネントのテスト方法などは以前私が発表した内容をご参照ください。

https://speakerdeck.com/kubotak/playwrightniyorusveltekonhonentotesuto

# SvelteKitでPlaywrightコンポーネントテストを行う
先程紹介したSvelteコンポーネントのテストですが、SvelteKitではうまく動かないケースがあります。
それはSvelteKitが提供しているモジュールを使ったコンポーネントです。

https://kit.svelte.jp/docs/modules

`$app/`や`$env/`から始まるモジュールを呼び出しているコンポーネントをPlaywrightでテストしようとしてもそのモジュールのインポートが解決できません。
また、SvelteKitでは`src/lib`ディレクトリに`$lib`というエイリアスを持っているのでこれもそのままでは解決できません。


そこで、`playwright.config.ts`に以下のAliasを追加します。

```ts:playwright.config.ts
const config: PlaywrightTestConfig = {
  // 略
  use: {
    ctViteConfig: {
      resolve: {
        alias: [
          // SvelteKit固有の$libエイリアス
          {
            find: '$lib',
            replacement: `${__dirname}/src/lib`
          },
          // SvelteKit固有のモジュール$appのエイリアス
          {
            find: '$app',
            replacement: `${__dirname}/playwright/mock/app`
          }
        ]
      }
    }
  }
}

export default config
```

`playwright/mock/app`ディレクトリには対応するモックライブラリを事前に準備しておきましょう。

例）
```ts:playwright/mock/app/environment.ts
const browser = true
const dev = true
export { browser, dev }
```

このモックは`$app/environment`を呼び出して`browser`や`dev`をimportしている箇所に相当します。
似たような要領で必要なモックを作成し差し込むことで期待した挙動を作り出すことができます。


:::note warn
Help
テスト毎にモックを差し替えたい場合はこの方法だと実現できません。
:::

もっとイケてる方法をご存じの方はぜひコメントください。
また、コンポーネントの見た目の状態のテストとしてPlaywrightコンポーネントテストを用いるのが適切だと思っていて、ロジックをテストする場合はVitestとTesting Libraryを用いるほうが良いと思います。それについては明日の記事で紹介したいと思います！
Rubyでクラスメソッドを定義する方法を思いつく限り挙げてみた

## 概要

タイトルの通り、Rubyでクラスメソッドを定義する方法に関する記事です。

## 動機

元々はクラスメソッド全般に関する記事だったのですが、調べているうちに書き方を色々思いついてしまったのでそちらをメインにすることにしました。

## レギュレーション

* 文法要素については1つとして扱う
* メソッドを使うものについてはメソッドの名前ごとに1つとして扱う
    * eval系の場合、文字列とブロックは同じ扱いになる

## 補足

ちゃんとクラスメソッドや特異クラスについて知りたい方は以下の記事をどうぞ！
https://magazine.rubyist.net/articles/0046/0046-SingletonClassForBeginners.html

## 本編

### 1. クラス名スタイル

実は利用頻度が少ない気がします。

```ruby
class C
  def C.m
    puts 'm'
  end
end
```

### 2. selfスタイル

最も一般的な書き方な気がします。

```ruby
class C
  def self.m
    puts 'm'
  end
end
```

### 3. 特異クラススタイル

これもよく見かけます。

```ruby
class C
  class << self
    def m
      puts 'm'
    end
  end
end
```

この方法では複数のクラスメソッドを定義したりプライベートなクラスメソッドを定義したりするのが簡単です。

### 4. extendスタイル

モジュールを使う場合の一般的な方法です。

```ruby
module M
  def m
    puts 'm'
  end
end

class C
  extend M
end
```

### 5. includedスタイル

`include`されたときにクラスメソッドも定義したい場合に使われます。

```ruby
module M
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def m
      puts 'm'
    end
  end
end

class C
  include M
end
```

### 6. define_singleton_methodスタイル

あまり見かけません。`:m`の部分を動的にしたいときには使うかも。

```ruby
class C
  define_singleton_method :m do
    puts 'm'
  end
end
```

### 7. instance_evalスタイル

まず見かけません。

```ruby
class C
end

C.instance_eval do
  def m
    puts 'm'
  end
end
```

### 8. singleton_class.class_evalスタイル

まず見かけません。

```ruby
class C
end

C.singleton_class.class_eval do
  def m
    puts 'm'
  end
end
```

### 9. method_missingスタイル

やめましょう。

```ruby
class Class
  def method_missing(meth, *args, &blk)
    if name == 'C' && meth == :m
      puts 'm'
    else
      super
    end
  end
end
```

### 10. inheritedとdefine_methodスタイル

`define_method`を使うことにこだわってみました。

```ruby
class Object
  def self.inherited(klass)
    if klass.name == 'C'
      define_method :m do
        puts 'm'
      end
    end
  end
end

class C
end
```

## まとめ

クラスメソッドを定義するだけでこんなにたくさん方法があるなんてRubyすごい！
（お仕事では1,2,3を使いましょう。）
Tableau でSalesforce の数式フィールドを取得する方法｜さようなら、再計算！

![KV-min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954014/c7240cd6-6a33-7a38-d366-ead08bf45c5e.png)

世界No.1 の顧客管理（CRM）プラットフォーム「[Salesforce（セールスフォース）](https://www.salesforce.com/jp/products/what-is-salesforce/)」

顧客のニーズや解決したい課題をふまえ、顧客に喜ばれる製品・サービスを創出し、適切なタイミングで提供するためにも、顧客情報は重要ですよね。

そのためSalesforce に日々蓄積されるデータの利活用は、Salesforce 自体の運用定着と並ぶ重要な課題のようです。よくご相談を頂戴します。

先日もこんなご相談を頂戴しました。

「**Salesforce にある数式フィールド（数式項目値）をTableau で取得したい**のですが、CData を使えばできますか？」

# Tableau 標準のSalesforce コネクタでは数式フィールドを取得できないという罠
Salesforce は数式を使用した項目をつくることができます。
>Calculate Field Values With Formulas（数式を使用してフィールド値を計算する）：
>https://help.salesforce.com/s/articleView?id=sf.customize_formuladef.htm&type=5

ところがこの数式フィールド、**Tableau 標準のSalesforce コネクタでは数式を使用した項目値を取得することができない**そうです。
>Salesforce.com 数式フィールドがインポートされない：
>https://kb.tableau.com/articles/issue/salesforce-formulas-do-not-import?lang=ja-jp

実際に試してみましょう。

まずSalesforce を開き、Salesforce のオブジェクト［Opportunity］ に適当な数式項目を追加します。
（例）
　［Field Label・Field Name］Calc
　［API Name］Calc__c
　［数式］Amount * Probablity
![1-min.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954014/3bf4b437-b1d9-1779-8ed5-084ff3afc3c7.png)
つぎにTableau を開き、Tableau の標準コネクタでSalesforce に接続します。
![2-min.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954014/0942d0eb-b69c-a856-9a18-28fff6f33a8f.png)
ワークシートで［Opportunity］の中身を確認してみると、Salesforce に追加した**数式項目Calc（Calc__c）がありません！**
![3-min.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954014/33684bcd-9a08-83ee-e866-7af1d6597bab.png)
そのため、Tableau Prep Builder を使用するなどして、元の値（上記の例ですとAmount と Probablity）から再計算をしなければなりません。

# CData のSalesforce Tableau Connector ではSalesforce の数式フィールドを取得できた！
つづいて、**弊社の[Salesforce Tableau Connector](https://www.cdata.com/jp/drivers/salesforce/tableau/) を使って接続**してみたいと思います。

１．まず[こちら](https://www.cdata.com/jp/drivers/salesforce/download/tableau/)からインストーラー（30日間無償利用可能）をダウンロードし、Tableau をご利用中のマシンにインストールします。

２．Tableau を開き、接続ペインで［CData によるSalesforce］をクリック、Salesforce に接続します。（※下画像ではBasic 認証で接続）
![4-min.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954014/eccaa6bd-66fd-e4c8-96ba-6009133f53a0.png)
３．表［Opportunity］を選択します。
![5-min.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954014/aac619a9-276b-57b0-39c3-600f7ac15cf6.png)
４．ワークシートで［Opportunity］の中身を確認してみると、Salesforce に追加した**数式項目Calc（Calc__c）が取得できています！**
![6-min.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954014/4938b703-45ee-0cb0-5aba-f8a5cd3efc4e.png)

# まとめ
Tableau でSalesforce の数式フィールド（数式項目値）を参照できないと何らかの手段で再計算が必要になり面倒ですよね。

**CData の[Salesforce Tableau Connector](https://www.cdata.com/jp/drivers/salesforce/tableau/) なら数値項目値をそのまま取得できる**のでTableau でのデータ可視化や分析に集中できちゃいます！

**[Salesforce Tableau Connector](https://www.cdata.com/jp/drivers/salesforce/tableau/) は30日間無償トライアル（[こちら](https://www.cdata.com/jp/drivers/salesforce/download/tableau/)）を利用いただけます。**

ぜひお手元のTableau でSalesforce の数式フィールドを取得できる感動をご体感ください！
リポーティング ─ 事実を把握する

:::note
本書は2017年4月1日にTeradata Japanのブログに掲載された内容を、再掲載したものです。
掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::


著者 山本 泰史 （やまもと やすし）

# リポーティング ─ 事実を把握する

ソーシャルやアクセスログなどのオンライン・データと、実店舗やコールセンターなどのオフライン・データ。異なるチャネルから得られたこれらのデータを統合することによって、それぞれのデータを単独で分析するよりも高い価値が得られること、そして今までと同じ分析手法を適用できることを、前回までで示してきた。今回からは、実際の分析手法の一端を紹介していく。

#### リポーティング
最も基礎的なデータ分析の手法は、実際のデータをそのまま見ることである。取得したデータを把握したい切り口で絞り込み、縦横両軸に整形し、集約して表示する。また直感的な理解を促すため、グラフによって視覚化することもある。実際には、ビジネス・インテリジェンス、多次元分析といったツールを用いることが多い。
統合された顧客データを用いる場合、利用可能なデータの種類は非常に多岐にわたり、表示するリポートのバリエーションは無限大だ。ここでは統合顧客データを利用することによって可能となる、代表的な分析例 3つを挙げる。

#### 顧客数の把握
図表1 は、縦軸に各チャネルに所属する顧客のセグメント、横軸には新規、既存、そして休眠顧客数を配置したものだ。縦軸からは顧客セグメントの重複、横軸からは顧客数ベースのフローとストックを一覧できるリポートである。


<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/acf88385-53a9-fda6-deca-c8f85b29f54d.png">

例えば「実店舗（AND）オンライン（AND）ソーシャル会員」は、実店舗とオンラインの両方の利用があり、なおかつソーシャル・アカウントがひも付いている顧客を意味する。新規顧客は直近一定期間内に会員登録した顧客、休眠会員は一定期間利用のない顧客と定義している。チャネル・セグメントの定義は企業が利用しているチャネルによって異なり、また企業によっては休眠ではなく、解約と言った方が適切な場合もあるため、適時、読み替えてもらいたい。

一般的に、複数チャネルでの利用がある顧客の方がロイヤルティが高いと言えるが、単独チャネルしか利用しない顧客も当然ながら存在する。ここではその分布を理解することで、各チャネルでの会員獲得、会員ケア、そしてチャネル間誘導の成否を確認することができる。また新規と休眠のバランスを見て休眠が多くなっていれば、顧客数が減少傾向にあることが明らかになる。そしてこれを前月や前年と比較することにより、会員数の伸び率も把握できる。各施策がどの程度顧客数の増加や離反阻止に影響を与えたかも理解することができるだろう。

#### 接触数の把握
獲得した顧客に対して適切に働き掛けることによって、顧客から収入がもたらされる。

図表2 は、接触量について整理したリポートである。縦軸にはチャネルを配置し、横軸にはアウトバウンドとインバウンドの接触率を配置している。


<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/e193ccd2-0837-7d87-e1a5-e39a2cf8cd16.png">


企業はそれぞれのチャネルを通じて接触を行う。一方、顧客の側から企業のチャネルに接触してくることもある。オンライン・サイトの閲覧やコールセンターへの問い合わせなどである。企業から顧客への接触をアウトバウンド接触、顧客から企業への接触をインバウンド接触と呼ぶ。働き掛けとは結局のところ接触のことであり、そこでなされた提案のことだ。もちろん的外れな提案では意味がないが、提案量が少なければ顧客を動かすことはできず、収入にもつながらない。一方でインバウンド接触は、顧客からの関心のバロメーターだ。ここには当然、苦情のような接触も含まれるが、基本的にインバウンド接触の量は関心の量と言ってよい。

ここでは、有効な顧客数を分母に、一定期間内の接触回数を分子にとって、接触率という指標にまとめている。1人の顧客に 2回接触することもあれば、1度も接触しないこともあるだろう。そのため、さらに詳細を見ていく必要があるが、全体として接触量が適切であるかどうかがこれで把握できる。インバウンドのみのチャネルや、アウトバウンドに適したチャネルもあるため、適切な接触率はチャネルによって異なる。時系列での変化も合わせて把握するのが望ましく、例えば一定期間における eメールの接触量が過剰だという場合には、制限することが必要になる。

#### 購買転換状況の把握
接触や提案がどの程度、購買や利用に結び付いたかによって、適切な顧客に対して、適切な提案を行えていたかどうかを理解できる。

図表3 は商品ごとに、商品ページを URL付きで投稿した数、商品ページを閲覧した数、最終的な購入数、そして転換状況を比較している。このリポートは、ソーシャルメディア、アクセスログ、そして取引実績という 3つのデータソースから形作られたものだ。これにより、ソーシャルでの波及効果、商品紹介ページのパフォーマンス、そして購買に至る流れを定量的に評価できる。


<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/f04a24a5-d1c2-55c6-11ee-4ab5ce54a4a5.png">



以上は形式としては単純なリポートだが、データが統合されていることによって、より包括的に顧客の状況をつかむことができている。

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

### エントリ確認
```bash
grep windows /boot/grub/grub.cfg
```

```bash
menuentry 'Windows Boot Manager (on /dev/nvme0n1p2)' --class windows --class os $menuentry_id_option 'osprober-efi-9234-7609' {
```

### `GRUB_DEFAULT`を変更
```bash
sudo nano /etc/default/grub
```

```bash
#GRUB_DEFAULT=0
GRUB_DEFAULT='Windows Boot Manager (on /dev/nvme0n1p2)'
```

GRUB_DEFAULT=2だと動かなかった


##### 以前の選択を覚えてもよい
```bash
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true
```

### 反映
```bash
sudo update-grub
reboot
```

// TODO: ワンライナーの方法を考える
データベースで分析を行う価値

こんにちは！
データを分析するにはデータが必要…
とても当たり前のことですがそのデータと分析環境はどんな位置関係にあるのがベストだと思いますか？今日はそんなお話です。

# データのゲートウェイ
分析に利用されるデータは通常データレイクだとかデータウェアハウスだとか、そういったデータを蓄えるためのシステムやストレージにありますよね。データ分析に限らずデータを利用するユーザーはそこからデータを取り出して利用する、というのが一般的な考え方でしょう。

そういった「ここを覗けばさしあたって必要なデータは全てあるはず」という環境をお持ちでなく未だ社内のあちらこちらに散らばったままという企業さんもたまにいらっしゃったりします。

ここにアクセスすれば必要なデータがすべて入手できるデータへのゲットウェイがある。一見するととても理想的なデータ活用環境が整っているように見えるこの状況も、実はまだ改善すべきポイントがあることはお分かりになりますでしょうか？

# データの移動コスト
データを利用する際に特にボリュームの大きいデータを利用する際にはデータの移動コストはばかになりません。コストといってもそれは金銭的なコストではなく主に時間的なコストのことですけど。
ネットワークのスピードがどんどん向上しデータの移動なんてそんなに時間かかるの？という方もいらっしゃるかもしれませんが、利用すべきデータのボリュームもそれ以上に大きくなっています。

考えてもみてください。たかだか10Gbpsの回線で1TBのデータを転送しなければならないとか。ボタンをポチッとクリックしてから理論上どんなに早くデータ転送ができても10分以上その処理は返ってこない。忙しい現代人にはなかなかの苦痛だったりしますよね。

# 大ボリュームデータの処理
めでたくデータの移動が終了しました。じゃあ分析の処理を回してみよう！勇んで処理を開始しましたが処理は終了せず結果は返ってきません。とても大きなボリュームのデータを処理するとき次に登場する問題はこれです。
通常データ分析に使う環境、PythonやR、AI、その他の分析ツールが動作する環境は非常に大きなボリュームのデータを処理するのに適した環境とは言えません。ソフトウェアもそれが動作するハードウェアもそれを想定して作られたものではありませんから当然です。

それではどうしたらいいでしょう？

お気づきですね？データ分析環境には大ボリュームのデータを扱うことを想定して作られたソフトウェアとハードウェアがすでに含まれています。
そう、データウェアハウスです。データウェアハウスはもともと並列処理のような大きなボリュームのデータを高いパフォーマンスで処理できるようなソフトウェア・アーキテクチャを持っています。これをデータ分析に利用すれば非常に大きなボリュームのデータも簡単に処理することができます。それを目的として開発されたソフトウェアを使用しているのですから。

# データ移動のコスト…
データウェアハウスの中で処理をするということは先ほどお話したデータ移動のコストも一気に解決されます。データ移動が必要ないのですから。

このようにデータ分析環境の要ともいえるデータウェアハウスの中でデータ処理を行うことは、
　・ データの移動を行わなくていいのでコストがかからない
　・ さらにデータを閉じた空間の中で扱うのでセキュリティも高い
　・ 並列処理など大ボリュームデータを処理する仕組みを使用した高速処理
ができる最適な環境といえます。

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/6c0bdf49-80d8-66a2-cde9-ec4da1285e64.png)

ところが実はそういったことができるデータウェアハウス用データベースはそれほど多くもありません。
データウェアハウスを検討するときは、そのような
　・ 統計分析処理が実行可能
　・ AIモデルの推量などを実行できる
　・ 分析に利用する言語のネイティブな記述でパフォーマンスが既存することなくデータ処理が可能
なソフトウェアであるという条件を必須のものとして加えてください。

きっと快適な分析環境を実現できますよ！

#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
nodeのアップデート方法（nodenv）

`nodenv`環境で`node`をアップデートする方法です。
`nodenv install`をしたら`definition not found`と言われた時のメモです。

まずは、 `.node-versions`ファイルのバージョンを変えます。

次に、`node`が`nodenv`を見ているかどうかを確認します。
以下のように出力されたらOK

```
% which node
/Users/okada/.nodenv/shims/node
```
※ `nodebrew`を向いている場合は、[nodebrewをアンインストール](https://qiita.com/okada3333/items/1e32dbfe9da1fb8abf0f#nodebrew%E3%82%92%E3%82%A2%E3%83%B3%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
)します。

次に、インストールしたいバージョンを指定して実行してみます。
```
% nodenv install 18.12.1
```

installできるリストに入っていないようです :cry: 
```
node-build: definition not found: 18.12.1

See all available versions with `nodenv install --list'.

If the version you need is missing, try upgrading node-build:

  brew update && brew upgrade node-build
```

メッセージにあるように↓を実行してみます。
```
% nodenv install --list
・
・
・
18.8.0
18.9.0
18.9.1
chakracore-dev
・
・
・
```

確かにいませんね。
言われたとおりに↓を実行します

```
% brew update && brew upgrade node-build
```

成功したのでもう一度リストを確認。増えました :thumbsup: 
```
% nodenv install --list
・
・
・

18.8.0
18.9.0
18.9.1
18.10.0
18.11.0
18.12.0
18.12.1
19.0.0
19.0.1
chakracore-dev
・
・
・
```

もう一度インストール！
```
% nodenv install 18.12.1
```
エラー無くインストールできたのでバージョン確認 :ok_woman: 
```
% node -v
v18.12.1
```

エラーメッセージのとおりに実行しただけですが…
nodeのアップデートっていつもどうやるのか忘れるので、備忘録を兼ねて書きました。