OmniAICreator/Qiita-1.07M huggingface dataset:
新規作成したIAMユーザーでEKS環境を操作できるようにする

# やりたいこと
- 新規ユーザーでEKSを操作したい
- とりあえず`system:masters`というKubernetesの世界でのroot権限を割り当てる
- 今後はもうちょい絞りたい
    - 権限周り難しい・・・

# 手順
## ユーザーの作成
- APIアクセス可能な権限で作る

## ポリシーの作成
- `system:masters`を使う

```
kubectl describe clusterrolebinding cluster-admin
```

```
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind   Name            Namespace
  ----   ----            ---------
  Group  system:masters  

```

- `aws eks update-kubeconfig`が実行できればいい(`eks:DescribeCluster`が最低限あればいいみたい)

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "eks:DescribeNodegroup",
                "eks:ListNodegroups",
                "eks:DescribeCluster",
                "eks:ListClusters",
                "eks:AccessKubernetesApi",
                "ssm:GetParameter",
                "eks:ListUpdates",
                "eks:ListFargateProfiles"
            ],
            "Resource": "*"
        }
    ]
}
```

アタッチしておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/fe7dae7b-4f08-f08b-14eb-ead49a4bc7bb.png)

## Configmapをeditで修正

```
kubectl edit configmap/aws-auth -n kube-system
```

### 追加する値
- userを指定する場合は`userarn`などとする

```
  mapUsers: |
    - userarn: arn:aws:iam::123456789012:user/autodeploy-executer-production
      username: eks-operator
      groups:
        - system:masters
```

### configmap全体

```
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::123456789012:role/eksctl-vamdemic-production-eks-clus-NodeInstanceRole-1NW6OO5XFQCMZ
      username: system:node:{{EC2PrivateDNSName}}
  mapUsers: |
    - userarn: arn:aws:iam::123456789012:user/autodeploy-executer-production
      username: eks-operator
      groups:
        - system:masters
kind: ConfigMap
metadata:
  creationTimestamp: "2021-04-27T07:10:47Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "30541"
  selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth
  uid: 42befb87-d552-42fa-b8d7-672482a5e2f9

```

## 動作確認
1. クレデンシャルを発行
1. `aws configure`で指定する
1. `aws eks update-kubeconfig <クラスタ名>`を実行
1. kubectlでなにがしかのリソースが参照できればOK

# 参考
https://qiita.com/taishin/items/dfb9a5620f37ffb74fe9
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html
Git　で公開してはいけないものを公開してしまい、リモートリポジトリを消した話

##はじめに
プログラミング初学者のため、自分の理解できている範囲内で言語化しています。
何か間違っている情報や改善点などありましたら、コメントいただけますと幸いです。🙇‍♂️
##何が起きたのか
簡単にまとめると、ブランチきって作業していた際に、公開してはいけない情報を記述したまま、
**コミット　→　プルリクエスト　→　マージ　→　ブランチ削除**
まで気づかずにしてしまっていた。

##原因
圧倒的gitの知識不足

##学んだこと
- **公開したくない情報を記述したまま、コミットしてはいけない。**
- **ブランチは削除しても見れてしまうため、実質消せていない。**

＊最悪コミット・プルリクエストまでは簡単に戻せるっぽいが、マージからブランチまで削除してしまう消すことはできない

間違えてコミット・プルリクエストをしてしまったときに、解決する方法はたくさんあるので
調べる💪

特にこの方が丁寧にまとめてくださってる、本当に助かります🙇‍♂️
URL：https://qiita.com/muran001/items/dea2bbbaea1260098051#%E3%82%84%E3%82%89%E3%81%8B%E3%81%97%EF%BC%93%E4%BD%99%E8%A8%88%E3%81%AA%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%97%E3%81%9F%E3%81%91%E3%81%A9%E3%82%84%E3%81%A3%E3%81%B1ignore%E3%81%97%E3%81%9F%E3%81%84%E6%99%82

##試したこと
結論、私の場合はマージしてブランチの削除まで進んでしまっていたので、消すことができずリモートリポジトリごと削除した、、、😂

やったこと
→

```ターミナル.
％ git reset --soft コミットID
```
で公開したくない情報を記述したコミットまで戻し、履歴を上書きした

これでリモートリポジトリの**<>code**では表示されなくなったので

一見これで成功したように見えたが、リモートリポジトリの**Pull requests**のclosedに削除したブランチが残っていて、ここで変更履歴を見ることができた。

ここで、ブランチは完全に消すことができないことを知り、リモートリポジトリを削除することにしました。

##リモートリポジトリの削除
- リモートの設定の一番したの方に削除するためのボタンがあり、そこで削除する。
- 削除した後は、ローカルの方でもリモートの情報を削除する必要がある

```ターミナル.
xxxxxnoMacBook-Pro testapp % git remote  　　　　　　　---リモートの情報があるか確認
origin　　　　　　　　　　　　　　　　　　　　　　　　　　　　---originという情報が残っている
xxxxxnoMacBook-Pro testapp % git remote rm origin　　---originの削除
xxxxxnoMacBook-Pro testapp % git remote　　　　　　　　---リモートの情報があるか確認
xxxxxnoMacBook-Pro testapp % 　　　　　　　　　　　　　　---ない場合は何も出ない
```
これでローカルでのリモートリポジトリの削除は完了

最後に、またアプリケーションをgitに追加して完了

# そのほかの対策
**こちらはいただいたコメントを参考に記述しています。
コメントいただいた方、本当にありがとうございます🙇‍♂️**

Githubはサポートに連絡すればプルリクエストからの参照も消してくれるそうです。
[機密データをリポジトリから削除する - GitHub Docs](https://docs.github.com/ja/github/authenticating-to-github/removing-sensitive-data-from-a-repository)

以下はそもそもコミットしてはいけない記述があるときに教えてくれる機能です。
未然防止になる機能なので、とても便利です。
[GitHub、コード中に書いてはいけないアクセストークンを発見、通知してくれる「Secret scanning」機能、プライベートリポジトリで正式対応 － Publickey](https://publickey1.jp/blog/21/githubsecret_scanning.html)
[git-secretsはじめました - Qiita](https://qiita.com/jqtype/items/9196e047eddb53d07a91)
[Gitリポジトリを作った後にやること - Qiita](https://qiita.com/Hikosaburou/items/c2a386d28d62ed906af9)
RSpec 基本構文の理解

#【RSpec 基本構文の理解】

RSpecの構文に全然慣れないので超基本から復習しました。
簡単な自分用の備忘録です。

##RSpecの書き方

・テストケースを整理、分類 : describe, context
・テストコードを実行 : before, it

```ruby
RSpec.describe ['テストの対象'], type: ['Specの種類'] do
  describe ['テストの対象'] do
    context ['どんな条件でテストをするか'] do
      before do
        ['事前の準備']
      end

      it ['仕様の内容 : テストで期待する正常な概要'] do
        ['テストで期待する正常な動作']
      end
    end
  end
end
```

**it**が1番肝心。
最終的に**it**に書かれた状態になればテストは正常におこなわれたということ。

itに到達するまでに、describeやcontextを何個もネストすることができる。
内側のdescribeやcontextやitを複数記述することもできる。

※type指定は、外側のdescribeにだけおこなうことができる。

##Specを実行

rspecコマンドにSpecファイルの場所を指定して、実行する。

```
$ bundle exec rspec spec/system/example_spec.rb
```

問題無く、テストが実行されると、

```
1 example, 0 failures
```

表示される。
　→　1件のテストを実行して、失敗が0件で問題無く、テストが通った。（今回は1件のみ）
angularのcoreuiのサイドバーを開閉する関数

angularのcoreuiのサイドバーを開閉する関数について

```
function coreUiSidebarOpen(open: boolean, renderer: Renderer2) {
    if (open) {
        renderer.addClass(document.body, "sidebar-lg-show");
    } else {
        renderer.removeClass(document.body, "sidebar-lg-show");
    }
}
```

`lg`の部分は、`[sidebarToggler]`で指定した内容に適宜入れ替えること。


誰かのお役に立てば。
classやタグで取得したデータにgetElementsが使えない件

# はじめに
今回の問題は

```js
let element = document.getElementsByClassName('profile-content');
```
このようにクラス属性で取得したデータの中から、spanタグの箇所のみを入手しようとして

```js
let element = document.getElementsByClassName('profile-content');//さっきのコード
let profilespan = element.getElementsByTagName('span');
```
と書いたところ、下のelement.getElementsByTagNameがnot a function（関数じゃない）と怒られたことです。
原因としてはおそらく、上のクラスで取得したデータ型がHTMLCollectionであり、それに対してgetElementsメソッドが利用できないためです。どうすればよいかというと

```js
let element = document.getElementById('id名');//elements(複数形)じゃないよ
let profilespan = element.getElementsByTagName('span');
```
とするのが正しいようです。クラスではなくidで取得しようとのことでした。
なんだか不便な気もしますが、これで一応解決です。どなたかの助けになれば幸いです。

# まとめ

idで取得する getElementById => Elementオブジェクトで取得取得

タグで取得する getElementsByTagName => HTMLCollectionオブジェクトで取得

クラスで取得する getElementsByClassName => HTMLCollectionオブジェクトで取得

.elementsメソッドは上記のうちElementオブジェクトにのみ適用可能。
iRICを最新版にする方法　～マニュアルと差異があったらまず試すこと～

iRICソフトウェア（以下iRIC）のマニュアルは以下から参照いただけます。

https://iric-gui-user-manual-jp.readthedocs.io/ja/latest/


iRICのマニュアルを読みながら操作してみると、「あれっ？画面表示が自分のものと異なるぞ！」ということがあるかと思います。そのような場合、ご利用のiRICが最新版でない場合がありますので、以下の手順でiRICを最新版に更新してみてください。

- [1] インストールされているiRICを起動（ソルバーは適当に選択してください）

- [2] 「メニューバー＞オプション＞メンテナンス」をクリック

- [3]「iRICを閉じてiRIC Maintainanceを起動」をクリック

- [4] 「iRIC Softwareのメンテナンス」画面が表示されるので「コンポーネント」の更新」を選択し、「次へ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/1f16b37e-73eb-5827-1599-f4cb414738dc.png)

- [5] 更新があれば以下のように更新コンポーネントが表示されるので「次へ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/98d0fa94-2ec4-8612-2631-317ca073e276.png)


- [6] 「更新」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/1d7e8360-46b6-30a4-38e9-092da6f49d36.png)

- [7] 更新が完了しらたら「完了」をクリックし、iRICを再起動してみてください。


どうだったでしょうか？

それでも画面が異なる場合は、以下からご連絡お願いいたします。

https://i-ric.org/help/contact/
Active Data Guard スタンバイ・インスタンスでシーケンス操作を試す（Oracle Database 19c)

Oracle Database Active Data Guardはプライマリ・インスタンスからのREDOを適用しつつ、スタンバイ・インスタンスをREAD ONLY状態で稼働するオプションです。ここではスタンバイ・インスタンスでシーケンス操作を実行します。

# 初期状態
## プライマリの状態
プライマリ・インスタンスはオープン状態です、シーケンスを作成し、キャッシュ20を指定しています。

```
SQL> SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;

DATABASE_ROLE    OPEN_MODE
---------------- --------------------
PRIMARY          READ WRITE

SQL> CREATE SEQUENCE seq01 CACHE 20;

順序が作成されました。
```

## スタンバイの状態
スタンバイ・インスタンスはREDOを適用しつつ、READ ONLYモードでオープンしています。

```
SQL> SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;

DATABASE_ROLE    OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY READ ONLY WITH APPLY
```

# シーケンスの操作
## スタンバイで操作
スタンバイ・インスタンスでシーケンスの操作を行います。正常にシーケンス値が取得できます。

```
SQL> SELECT seq01.NEXTVAL FROM DUAL;

   NEXTVAL
----------
         1
```

## プライマリで操作
次にプライマリ・インスタンスでシーケンス値を取得します。キャッシュ分を加えた値が取得されます。このことからActive Data Guard環境ではプライマリ・インスタンスとスタンバイ・インスタンス間でシーケンス値の重複を防ぐ動作になっていることがわかります。シーケンスのキャッシュを使い切るタイミングでプライマリ・インスタンスのログオン・トリガー（SYSユーザ）が動作することが確認できるため、スタンバイ・インスタンスからプライマリ・インスタンスへ接続が発生し、シーケンスの更新情報を伝えていると思われます。[マニュアル](https://docs.oracle.com/cd/E96517_01/sbydb/managing-oracle-data-guard-physical-standby-databases.html#GUID-DFDC929C-7446-413B-A25B-7F11284D900F) に記載された動作です。

```
SQL> SELECT seq01.NEXTVAL FROM DUAL;

   NEXTVAL
----------
        21
```

## 再度スタンバイで操作
再度スタンバイ・インスタンスでシーケンス値を何度か取得します。プライマリ・インスタンスで、シーケンス値21～40が予約されているため、シーケンス値20の次は41になっています。

```
SQL> SELECT seq01.NEXTVAL FROM DUAL;

   NEXTVAL
----------
         2
...
SQL> SELECT seq01.NEXTVAL FROM DUAL;

   NEXTVAL
----------
        20

SQL> SELECT seq01.NEXTVAL FROM DUAL;
   NEXTVAL
----------
        41
```


# Active DataGuardを解除
リアルタイム適用を停止して再度実行してみます。Active Data Guardを停止すると、スタンバイ・インスタンスはオープンのままですが、シーケンスの取得は失敗することがわかります。

```
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

データベースが変更されました。

SQL> SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;

DATABASE_ROLE    OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY READ ONLY

SQL> SELECT seq01.NEXTVAL FROM DUAL;
SELECT seq01.NEXTVAL FROM DUAL
       *
行1でエラーが発生しました。:
ORA-02289: 順序が存在しません。
```
vertical - align プロパティ

■　はじめに
この記事は私の知識量を増やすため行うものです！
こちらの記事はCSSの情報となっています。


■　vertical - align とは

テキストや画像などの内容の上下方向の揃え位置を指定するもの。
この表現だけではピンと来ないかもしれません。
なので、今回はイメージ図を用意しましたので御覧ください。

＜ イメージ図 ＞

vertical - align を使用する前　↓
<img src="https://camo.qiitausercontent.com/d6eeb6f8b304a9574d5e8f1e3df2effb65316f57/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3737323633312f31303061616430632d613038662d306633322d656232362d6262623435383334623366312e706e67" alt="スクリーンショット 2020-10-29 11.36.44.png"/>


vertical - align を使用後　↓
<img src="https://camo.qiitausercontent.com/473180fa0d619c5a2bf037d474ea60c9be46ccc9/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3737323633312f37386532636533642d396364342d323566302d333563332d6132613138306461636434302e706e67" alt="スクリーンショット 2020-10-29 11.41.07.png"/>

ご覧になりましたでしょうか？
ちょっとした差かもしれませんが、この差があとあとビュー作成に役立ちます！

今日の投稿は以上です！
ありがとうございました！
Railsで検索機能を実装する（Gemなし）

検索機能を実装したので備忘録

#1.controllerへ処理を記載

```/app/controllers/users/team_controller.rb
  def search
    @teams = Admin.search(params[:search])
#@teamsは好きなものを入力して、Adminの部分には検索したいテーブル名を入力する
  end
```

検索欄に入力された内容をモデルに渡すための処理

#2.modelへsearchメソッドを定義

```/app/models/admin.rb
  def self.search(search)
    if search
      Admin.where(['address LIKE ?', "%#{search}%"])
#Adminには検索したいテーブル、addressには検索したいカラム名を入力する
    else
      Admin.all
#検索結果が当てはまらない場合は全て表示させる（必要ない場合は削除する）
    end
  end
```

#3.routingを設定

```/config/routes.rb
get 'teams/search', to: 'teams#search'
```
必要であれば設定

#4.viewへform_tagを記載する

```/app/views/users/teams/index.html.erb
<%= form_tag(teams_search_path,:method => 'get') do %>
  <%= label_tag '地域で検索' %>
  <%= text_field_tag :search %>
  <%= submit_tag 'Search', :address => nil %>
<% end %>
```

この記述を検索機能を付けたいviewへ記述することで検索が可能になる

#5.search後のviewを作成

こちらに関しては検索前の一覧画面とほとんど同じで問題ないかと思う。
今作ってるものだとこんな感じ。

```/app/views/users/teams/search.html.erb
<h2>チーム一覧</h2>

<table class="table table-striped bg-light">
  <thead>
    <tr>
      <th>チーム</th>
      <th>活動場所</th>
      <th>メールアドレス</th>
      <th>ジャンル</th>
    </tr>
  </thead>

  <tbody>
    <% @teams.each do |team| %>
      <tr>
        <td><%= link_to team.team_name, team_path(team) %></td>
        <td><%= team.address %></td>
        <td><%= team.email %></td>
        <td><%= team.genre %></td>
      </tr>
    <% end %>
  </tbody>
</table> 
```

以上で検索機能の実装完了。
(つらいけど) JavaScript 生で RFC3339 な文字列を生成する方法

[RFC3339](https://tools.ietf.org/html/rfc3339) という日時の記法があります。

```
1985-04-12T23:20:50.52Z
```

こういった書き方で日時を割り出します。

これを、ライブラリなしの JavaScript で表現しようとすると、実は大変です。


```js
// Unixtime で指定したい場合はミリ秒で渡すこと
const date = new Date(1619505636 * 1000);
const timezoneOffset = date.getTimezoneOffset();
const timezoneHours = timezoneOffset / 60;
const timezoneMinutes = timezoneOffset % 60;
const rfc3339 = [
    date.getFullYear(),
    '-',
    (`0${(date.getMonth() + 1)}`).slice(-2),
    '-',
    (`0${date.getDate()}`).slice(-2),
    'T',
    (`0${date.getHours()}`).slice(-2),
    ':',
    (`0${date.getMinutes()}`).slice(-2),
    ':',
    (`0${date.getSeconds()}`).slice(-2),
    (-timezoneHours < 0 ? '' : '+'),
    (`0${-timezoneHours}`).slice(-2),
    ':',
    (`0${timezoneMinutes}`).slice(-2),
].join('');

console.log(rfc3339);
// outputs: 2021-04-27T06:40:36+00:00
// https://ideone.com/4OzmFl
```

つらいなあ。

タイムゾーンは `Date` クラスでは「現在のランタイムのロケール」に依存します。

[Intl.DateTimeFormat](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) を用いればロケール対応が可能らしいです。

ちなみに、 [moment.js](https://momentjs.com/) は開発をストップしメンテナンスモードとなっているため、後発の [Luxon](https://moment.github.io/luxon/) や [Day.js](https://day.js.org/) などのより軽量で安全なライブラリを使うことが推奨されています。

---

ちなみに PHP で同じことを実現しようとすると...

```php
<?php

// Unixtime で指定したい場合は @ を最初につけること
$now = new DateTime('@1619505636');
echo $now->format('Y-m-d\TH:i:sP');
// outputs: 2021-04-27T06:40:36+00:00
// https://ideone.com/hwVWqJ
```

まあこれくらいは一行でできて当然よね...?
WindowsUpdateの一時ファイルを削除（WindowsServer2008）

Cドライブが逼迫した時にWindowsUpdateのダウンロードキャッシュファイルと、
更新履歴などを残しているらしいdbファイルを消したのでメモ。

コマンドプロンプトで実行

```
net stop wuauserv
```
C:\Windows\SoftwareDistribution\Download の中身を全て削除
C:\Windows\SoftwareDistribution\DataStore の中身を全て削除
コマンドプロンプトで実行

```
net start wuauserv
```
サービスが正常に起動したことを確認
DataStoreフォルダの中に Logs フォルダとdbファイルが自動生成されていることを確認

## あまりにも逼迫するのでWindowsUpdateを動かなくする場合
コマンドプロンプトで実行

```
net stop wuauserv
```
[スタート] -> [管理ツール] -> [サービス] -> Windows Update を右クリックして [プロパティ]
　-> スタートアップの種類を 自動(遅延開始) から 手動 にして 適用
 
C:\Windows\SoftwareDistribution\Download の中身を全て削除
C:\Windows\SoftwareDistribution\DataStore の中身を全て削除
トランザクション管理 Locking in mysql

トランザクション管理で色々迷ってました。mysqlの仕様を確認して、SELECT ... FOR UPDATEの理解できた！
例えば：こちらのシナリオで問題を確認して、トランザクションを直します。

## シナリオ
```
1. try block 
// 処理「A」：↓
// 未出荷のデータを確認して、csvファイルにダウンロードする
// csvファイルデータダウンロードできたら、注文ステータス→PRE_SHIPPINGに更新する
   SELECT * FROM orders 
   WHERE status = 'NOT_SHIPPED' AND order_id IN (1,2) 
   FOR UPDATE;

2. 上記のクエリを実行する、クエリ実行でレコードがロックされる、（処理終わるまでロックされるか？）
3. まだPRE_SHIPPINGの状態です、別処理「B」で上記のレコードを更新できた！なんで？(SHIPPIED...)
4. 該当の注文関係の色々データをcsvファイルに出力するデータを作る、select ...　
5. CSVファイルをダウンロードする→DL済
6. BeginTransaction(), 処理「A」で注文情報UPDATE処理する(データの整合性大丈夫？）
7. commit
8. catch block
```

上記のシナリオでなんでロッグされたレコード更新されたか、データの整合性の問題が発生しました。

## Note
「Locking reads are only possible when autocommit is disabled (either by beginning transaction with START TRANSACTION or by setting autocommit to 0.」

注記↓
SELECT FOR UPDATE を使用した更新対象の行のロックは、
START TRANSACTION でトランザクションを開始するか、autocommit を 0 に設定することで、自動コミットが無効になっている場合にのみ適用されます。自動コミットが有効になっている場合は、指定に一致する行がロックされません。

参考：Locking Reads（MySql5.6）
https://dev.mysql.com/doc/refman/5.6/en/innodb-locking-reads.html

- DBのautocommitを確認する、以下のクエリを実行してみました。

```
SHOW VARIABLES WHERE Variable_name='autocommit';
|Variable_name | Value|
|autocommit    | ON   |
```

上記の処理「A」と「B」の実行シナリオにBeginTransactionの場所を直します。

## シナリオ（トランザクション管理修正後）
* try block 
* BeginTransaction() 
  
```
// 処理「A」
// 未出荷のデータを確認して、csvファイルにダウンロードする
// csvファイルデータダウンロードできたら、注文ステータス→PRE_SHIPPINGに更新する
   SELECT * FROM orders 
   WHERE status = 'NOT_SHIPPED' AND order_id IN (1,2) 
   FOR UPDATE;
```

* 上記のクエリを実行する、クエリ実行でレコードがロックされる、（トランザクション終わるまで別処理で更新できない状態になった）
* この間、別処理「B」で上記のレコードを更新する、更新できないです！（処理待ちの状態になる）
* 該当の注文関係の色々データをcsvファイルに出力するデータを作る、select ...　
* CSVファイルをダウンロードする　→DL済
* 処理「A」で注文情報UPDATE処理する(データの整合性　OK！）
* commit
　処理「B」ここで実行される、クエリの条件にヒットしないかも、（処理Aで色々更新できた）
* catch block


Thank you for reading!
CSSのflexboxで最後の1つだけ右寄せ、または最初の1つだけ左寄せにする方法

グローバルナビのコーディングに参考にしました


CSSのflexboxで最後の1つだけ右寄せ、または最初の1つだけ左寄せにする方法
https://wemo.tech/2320#index_id1
XcodeとGitHubの連携

#何の記事？

Xcodeで作成したプロジェクトをGitHubで管理するための連携方法です。Swiftのプログラミングを始めたので備忘録として。

Version： Xcode 12.4

#XcodeとGitHubの連携

##1. ローカルにリポジトリを作成する
メニューバーの「Source Control」から「New Git Repositories...」を選択。これによりローカルにリポジトリが作成されます。
![スクリーンショット 2021-04-27 16.24.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620139/61d861c5-8186-2d84-4a91-8238a6bd222d.png)

##2. GitHub上にリポジトリを作成する
XcodeのSource Code Navigatorの「Remotes」フォルダを右クリックしてサブメニューを表示。その中から「New "@@@" Remote on GitHub...」を選択。
![スクリーンショット 2021-04-27 16.24.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620139/edd54f28-ccca-9808-ba32-9f75a11b5d87.png)
GitHubのアカウントが正しければ設定を編集。
-Repository Name
-Description(必要があれば）
-Visibility(publicかprivateか）
編集が終わったら「Create」
これにより自分のGitHubにリポジトリができました。

##3. リポジトリ作成後の運用
メニューバーの「Source Control」から「Commit...」をクリックすればデータが転送されます。
![スクリーンショット 2021-04-27 16.24.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620139/d8b842b1-c65f-80b1-0a82-a02f5f4def09.png)


参考サイト：
[XcodeとGitHubの連携方法](https://qiita.com/ynack/items/7c9aa83790ba03c34598)
unityでfbxファイルインポート時にテクスチャが反映されない、外れる時

Unityにfbxをインポートすると、テクスチャが張られていない時があります。
モデルが真っ白になっていますね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/57a3a697-9f99-1c46-065a-4cdc6e76da6f.png)
インポートしたモデルデータからマテリアルを外部アセットとして抽出することで
テクスチャを反映させることが出来るようです。
インポートしたモデルのInspectorからMaterialsタブを選択し
LocationのUse External Materials(Legacy)を選択してApplyボタンを押しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/ab67f1fc-a3b4-0db0-40d0-512685b1ffba.png)
すると、テクスチャフォルダとマテリアルのフォルダが出力され
モデルにテクスチャが反映されましたね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/04deed5a-7731-c060-e595-95f2395bee9e.png)
Scene Viewで確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/01247d91-63cd-91be-99d8-af6c7a81b260.png)
モデルにテクスチャを当てることが出来ました。

また、モデルのシェダーを変更することが出来ます。
モデルに影を落としたくなければShedlerからUnlitのTextureを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/83ded938-cd5d-8bb1-33e1-03b023afb1ff.png)
すると、光情報なしにテクスチャがそのまま表示されます
モデル表面に影がかからず明るくなりましたね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/f42d5ef3-37b6-1e20-3fb6-db1e6dda5139.png)


テクスチャデータだけ抽出したい場合は
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/e36f7ef4-b03d-2595-fd98-0eaf2074c40c.png)
モデルの同階層に抽出先になるTextureのフォルダを作ってあげて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/29f14fe5-7aba-9203-d70b-b1446f919eb3.png)
InspectorからTextureのExtractTextureをクリックして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/32cccbf4-159d-f8ce-25b9-c3c6aa5f2782.png)
先ほど作ったテクスチャファイルを出力先に選択すると
モデルにテクスチャが付き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/56b1cff3-d7b9-3bf6-737b-52333a49350c.png)
テクスチャデータがTextureフォルダに出力されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/1a1a5034-a2fa-23d6-f186-b36725d5a9c7.png)



余談ですが、まつ毛とかのテクスチャはUnlitにすると透明部分が黒くなってしまうので
Standerd にシェダーを変更しRenderring ModeをCutoutとかに変更していますが、何かいい方法があったら教えてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/686e28e6-5d6b-9213-41f0-f8740ad2bb03.png)


参考にさせてもらったサイトはこちら
https://sirohood.exp.jp/20190219-1973/
Unityリファレンス　Materials
https://docs.unity3d.com/ja/2018.4/Manual/FBXImporter-Materials.html
今回こちらの3Dモデルを使用させてもらいました
https://free3d.com/ja/3d-model/one-dollar-bill-79687.html
Raspberry Pi zero WHでyoutubeライブ配信

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/60c697e7-8a91-3ba7-1ef3-a1ad280138a1.png)

# 問題

ffmpegのパラメータ調べたり面倒くさそう。


# 解決策

[alexellis2/streaming][1]を使う。
[Live stream to YouTube with your Raspberry Pi and Docker][2]
[YouTube live-streaming made easy][3]

## まずdocker、docker-composeを入れる

```shell
$ curl -sSL https://get.docker.com | sh
$ sudo usermod -aG docker <username>  # piとかに変える これでdockerコマンドがsudo無しで出来る
$ sudo apt update
$ sudo apt install -y python3-pip libffi-dev 
$ sudo pip3 install docker-compose # python経由で入れるとスルッと入る
```

## docker-compose.ymlとentry.sh

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/6c1b4928-cf45-38a5-fba2-201ab8817987.png)


```yml:docker-compose.yml
version: "3"
services:
  live:
    image: alexellis2/streaming:07-05-2018
    privileged: true
    volumes:
      - ./entry.sh:/root/entry.sh
    entrypoint: ["/root/entry.sh", "********自分のストリームキー********"]
```

元々の`entry.sh`だとどうしてもfpsが20を下回り、youtube側でバッファの遅延が起きていたので、動画サイズを落として、ビットレートも落とした。

```sh:entry.sh
#!/bin/bash

echo Live-stream secret: $1
# https://support.google.com/youtube/answer/2853702#zippy=%2Cp%2Cp-fps
raspivid -o - -t 0 -w 1280 -h 720 -fps 30 -b 3000000 -g 40 | ffmpeg -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero -f h264 -i pipe:0 -c:v copy -c:a aac -ab 128k -g 40 -strict experimental -f flv -r 30 rtmp://a.rtmp.youtube.com/live2/$1
```

```sh:オリジナルのentry.sh
#!/bin/bash

echo Live-stream secret: $1

raspivid -o - -t 0 -w 1920 -h 1080 -fps 40 -b 8000000 -g 40 | ffmpeg -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero -f h264
-i pipe:0 -c:v copy -c:a aac -ab 128k -g 40 -strict experimental -f flv -r 30 rtmp://a.rtmp.youtube.com/live2/$1
```

`docker-compose.yml`と`entry.sh`を同じ場所に置いて

```
$ docker-compose run --rm live
```

とすると良いと思う。
`-w 1280 -h 720 -fps 30 -b 3000000`だとfps=25は出てた。（室温23℃前後、CPU温度55℃前後）


[1]: https://hub.docker.com/r/alexellis2/streaming/tags?page=1&ordering=last_updated
[2]: https://blog.alexellis.io/live-stream-with-docker/
[3]: https://www.raspberrypi.org/blog/youtube-live-streaming-docker/
Cloudflare Workersを使ってパスベースでリクエストをルーティングする

## Cloudflareにおけるパスベースのルーティング

`/api/*` というパスにマッチする場合だけAPIサーバーにリクエストが飛ぶようにしたいという要求はよく発生するものだと思いますが、こういった処理をCloudflareで実現する方法について説明します。

CloudflareにはPage Rulesという機能があり、パスベースでリクエストに対してさまざまな制御ができます。とても便利ですが、オリジンをパスベースで変えるにはEnterpriseプランが必要となります。Enterpriseプランの価格は要見積もりなので定かではありませんが、非常に高額になることは想像できます。

そこで、Cloudflare Workersを使ってパスベースでオリジンを切り替えます。
この方法であれば、無料プランから要求を実現することができます。

## 設定方法

Cloudflare Workersでは、URLパターンとWorkerの組み合わせを指定します。URLパターンにマッチするリクエストが来るとWorkerが起動してリクエストに対して処理することができます。

`https://example.com/api/*` を `https://api.example.com/api/*` にリクエストをルーティングする例です。


1. Workerを作成する。

Workersの管理ページから「Workerを作成」ボタンを押すとエディターが起動するので、コードを入力します。handleRequest()の内容を見てもらうと非常にシンプルにリクエストを書き換えられるのが分かります。

```js
addEventListener('fetch', function(event) {
  const { request } = event
  const response = handleRequest(request).catch(handleError)
  event.respondWith(response)
})

async function handleRequest(request) {
  const { url } = request
  const { pathname } = new URL(url)
  
  if (pathname.indexOf('/api/') === 0) {
    const newUrl = `https://api.example.com${pathname}`;
    const newRequest = new Request(newUrl, {
      body: request.body,
      headers: request.headers,
      method: request.method,
      redirect: request.redirect
    })
    return fetch(newRequest);
  }
  return new Response('Not Found', { status: 404 })
}

function handleError(error) {
  console.error('Uncaught error:', error)

  const { stack } = error
  return new Response(stack || error, {
    status: 500,
    headers: {
      'Content-Type': 'text/plain;charset=UTF-8'
    }
  })
}
```

２. URLパターンとWorkerを登録
Workersのページからルートを追加します。作成したWorkerの名前がmy-routingとした場合、下記のように入力して保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6571/281b8d88-e4c7-c62b-0046-6d16601d1da4.png)

これで完了です。 `https://example.com/api/abc` のリクエストは `https://api.example.com/api/abc` にプロキシされます。

## どこまで無料か

無料プランではWorkersには 100,000 requests/day の制限があります。
秒間1リクエスト強くらいなので、アクセスのあるサイトではすぐに制限を超えるかもしれませんが、有料プランも$5からで非常に安く使えます。
v-paginationにページURLのクエリパラメータを取得してページ更新後もページ数を指定して表示させる


```vue
<v-pagination
  v-model="page"
  circle
  :length="pageLength"
  :total-visible="7"
  @input="executePageFeed"
></v-pagination>
```

```js
data() {
  return {
    /**
     * ページャー
     */
    page: 1,
  }
}

async mounted() {
  /**
   ページ数をセット
   */
  await this.setPage()
},

methods: {
  setPage() {
    this.page = Number(this.$route.query.page) || 1
  }
}
```

## 参考：

#### v-pagination
https://v2.vuetifyjs.com/ja/components/paginations/

#### Nuxt.jsでURLののクエリパラメータを取得する方法
https://qiita.com/hiroyukiwk/items/f309d82fb38f0dd31ae0

#### Nuxt.jsのライフサイクルを知っておく
https://qiita.com/sukezane/items/059b2d33fa9f46e7eb07
(2021/04/27)Windows Server 2016での日本語化が出来ない

# 概要

AzureでWIndows Server 2016を作成後、日本語化を行おうとすると、何を行っても日本語化が出来ない。
サポートに問い合わせたところ、解決法が分かったためメモ

# 対応内容

TxR 配下のトランザクション ログのリセット

## ツールのダウンロード

次のサイトから、PendMoves.zipをダウンロード
必要なものは、movefile.exe

[PendMoves v1.02 and MoveFile v1.01](https://docs.microsoft.com/ja-jp/sysinternals/downloads/pendmoves)

## attrib コマンドを隠し属性を解除

```
$ cd C:\Windows\system32\config\txr
$ attrib -r -s -h *
```

## movefile.exe が保存されているディレクトリに移動

```
$ cd (movefile.exeのディレクトリ)
```

## TxR 配下のトランザクション ログ削除

アスタリスクによるファイル指定ができないため、存在するファイルに基づき実施する必要がある。
> VMが2台あり、両方とも同じコマンドで大丈夫であったため、そのまま記載
> 場合によっては、ファイル名は変わって来るかも

```
$ movefile.exe “C:\Windows\System32\config\TxR\{711988c4-afbd-11e6-80c9-782bcb3928e1}.TxR.0.regtrans-ms” “”
$ movefile.exe “C:\Windows\System32\config\TxR\{711988c4-afbd-11e6-80c9-782bcb3928e1}.TxR.1.regtrans-ms” “”
$ movefile.exe “C:\Windows\System32\config\TxR\{711988c4-afbd-11e6-80c9-782bcb3928e1}.TxR.2.regtrans-ms” “”
$ movefile.exe “C:\Windows\System32\config\TxR\{711988c4-afbd-11e6-80c9-782bcb3928e1}.TxR.blf” “”
$ movefile.exe “C:\Windows\System32\config\TxR\{711988c5-afbd-11e6-80c9-782bcb3928e1}.TM.blf ““”
$ movefile.exe “C:\Windows\System32\config\TxR\{711988c5-afbd-11e6-80c9-782bcb3928e1}.TMContainer00000000000000000001.regtrans-ms” “”
$ movefile.exe “C:\Windows\System32\config\TxR\{711988c5-afbd-11e6-80c9-782bcb3928e1}.TMContainer00000000000000000002.regtrans-ms” “”
```

下記の文言が表示されるはず
```
Movefile v1.01 - copies over an in-use file at boot time

Move successfully scheduled.
```

## OS再起動
```
$ hostname             #←ここは自分の好み
$ shutdown -r -t 0
```

## 言語パックのインストール
他のサイトでも色々やり方が書いてあると思うので省略
コントロールパネルから行ったら、適用することが出来た
クロージャと簡略引数名


定義するクロージャの型が推論できるケースでは、型を省略することができます。

```
var closure: (String) -> Int

// 型を明記
closure = { (string: String) -> Int in
    return string.count
}

closure("abc") // 3

// 型を省略
closure = { string in
    return string.count
}

closure("def") // 3
```

一番最初にclosureの型が定義されるので、Swiftが勝手に型を推測してくれます。

# 簡略引数名
さらに引数名の定義を省略し、代わりに簡略引数名を利用できます。
簡略引数名は、ドルマークに引数のインデックスをつけた$0などがそれです。

```
let isEqual: (Int, Int) -> Bool = {
    return $0 == $1
}

isEqual(1, 1) // true
```

簡略引数名を使用したクロージャは、型推論ができない場合はエラーになります。

```
let notIsEqual = {
    return $0 == $1
}

isEqual(1, 1)
```

> Ambiguous use of operator '=='

# まとめ
無闇矢鱈に使用すると可読性は低くなりますが、シンプルな処理であれば積極的に利用した方が良さそうです。

# 参考
[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)
Reactで作ったWebアプリにVueで作ったWebアプリを合体させたい

みなさん、Reactで作ったWebアプリから、React Routerを使ってVueで作ったWebアプリに飛びたいな〜と思ったことないでしょうか！まさに、今回わたくしこのような状況になり、何も考えずにいろんな言語に手を出すんじゃなかったなと少し後悔したのですが、どうしてもReactで実装し直すのが嫌だったので、考えました。

Reactで作ったWebアプリケーションに、Vueで作ったWebアプリケーションを合体する方法の備忘録です。

## やりたいこと

Reactで実装した左側のアプリとVueで実装した右側のアプリを

![スクリーンショット 2021-04-17 23.07.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546572/b08e11ae-17b3-f8de-fafd-bedd9cc3a0da.png)

合体させたい！

![スクリーンショット 2021-04-17 23.08.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546572/ec1516e8-c775-b013-22e0-2f7ec934976c.png)


## 方法検討

調べてみると、[iframe](https://developer.mozilla.org/ja/docs/Web/HTML/Element/iframe)を使えば、Webページに他のWebページを埋め込めることがわかりました。
また、Reactには[React Iframe](https://yarnpkg.com/package/react-iframe)というのがあったので、これを使ってみました！

## やってみる
埋め込み作業としては、Reactでの設定だけでできます。Reactのプロジェクトを開いて、React Iframeのインストールから行います。


### React Iframeのインストール


```
$ yarn add react-iframe
```

### 実装

```React
import React from 'react';
import Iframe from 'react-iframe'

export default function Page1(){
    return (
        <div>
            <Iframe id = "page1"
                    url = "＜埋め込みたいサイトURL＞"
                    position="absolute"
                    width="80%"
                    height="90%"/>
        </div>
    );
}
```

必須属性としては、`url`のみです。ここに埋め込みたいページのURLを指定します。

そして、このままだと埋め込んだVueのアプリに枠線ができるので、CSSで消しました。

```CSS
Iframe {
  border:none;
}
```


## 完成画面
完成です！簡単に埋め込むことができました！


![スクリーンショット 2021-04-22 21.47.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546572/1efe1e7c-9512-1a8c-5664-649e2e00e531.png)


あとはS3にアップロードして、公開することができました。
これで、左側のメニューからこのVueページに飛ぶと、まさかVueで実装しているとは気づかないくらいナチュラルにVueのページを開くことができました！

## セキュリティについて
最後に、今回`iframe`について調べていく中で、セキュリティ面でリスクもあることがわかりましたので、リスクと解決方法についてもまとめておきます。

### 外部のサイトを埋め込む場合

埋め込んだ外部のサイトに、悪意のある処理が含まれていた場合、システムやユーザーに危害が加わる可能性があります。

それを回避するために、iframeには[sandbox属性](https://developer.mozilla.org/ja/docs/Web/HTML/Element/iframe#attr-sandbox)という属性が用意されており、外部のサイトが実行することに対して制限をかけることができます。つまり、sandbox属性を使うことで、システムが不正に操作されるのを防ぐことができます。

もちろんReact iframeにもsandbox属性はあります。


### 自分のサイトが悪用されないように

少し今回の趣旨とは異なりますが、自作のWebサイトが`iframe`を使って悪意のあるサイトに埋め込まれないようにする方法です。

[クリックジャッキング](https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_9.html)について調べるとその仕組みについてはたくさん出てきますが、簡単に説明すると、悪意のあるサイト①にサイト②を透過させることで、ユーザーはサイト②を操作していると思っていたら、実は、悪意のあるサイト①を操作していたというような攻撃手法です。

Webサイトの開発側はユーザーがこのような被害に合わないようにするために、対策を行う必要があります。
その対策の一つとして、[`X-Frame-Options`](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Frame-Options)をレスポンスヘッダーにつける方法があります。このヘッダーをつけることによって、他ドメインからiframeで埋め込まれないようにすることができます。

今回はS3を静的Webサイトホスティングとして使いましたが、S3のみではこのヘッダーをつけることができません。なので、S3 + CloudFront + Lambda@Edgeを使って構築する必要があります。


## おわりに
今回はどうしてもReactのプロジェクトとVueのプロジェクトを合体させたく、`React Iframe`というのを使ってみました！こんなにも簡単に埋め込むことができました！Vueで作っているものを、Reactで作り直すという話がでていたのですが、回避できてひとまずよかったです。
ReactからVueに値を渡すのに少し苦労したので、次回はそれについてまとめようかなと思っています。
Swift5 UITextViewのtextContainerInsetについて

TextView内の文字周りにマージンを入れる方法がわからなかったので、解決方法を記録したいと思いました。

`textContainerInset`
を使う

```ruby:qiita.rb
TextView.textContainerInset = .init(top: 16, left: 16, bottom: 16, right: 16)
```
このように、引数の数値を変えてあげれば解決できました。
DOM操作

#概要
日付、税別価格、仕込み価格のデータをテーブルデータに反映させる。

#HTML

```index.html
    <tr>
      <th>日付け</th><th>税抜</th><th>結果</th>
    </tr>
    <tr> 
      <th id="day">データ</th><th id="taxNo">データ</th><th id="total">データ</th>
    </tr> 
```

今回は、こちらのテーブルデータに書き換えを行っていきます。

#JS

```index.js
   const hizuke = date();
   const sub = totalTax();
   const noTax = document.getElementById('number').value;

   const win =[hizuke,noTax,sub];
      

   document.getElementById('day').textContent = win[0];
   document.getElementById('taxNo').textContent = win[1];
   document.getElementById('total').textContent = win[2];
```

データ内容を配列に格納しました。

それぞれの格納場所にデータを配置していきます。

#配列からのアクセス
現在winの中にはデータとしてhizuke,notax,subが格納されています。
ここから各テーブルの中に代入していきます。
①日付け欄にwinの０番目の値、hizukeを代入します。
②税別欄にwinの1番目の値、notaxを代入します。
③税込み欄にwinの値、subを代入します。

*配列は先頭から0番始まりです。


データがすべて反映されました。

今回やりたいこととしては、データ反映とそれに伴い行を増やすことです。
for文とdocument.createElementを使って行きたいと思います。
npm-scripts で webp 画像を作成するデモ

npm scripts で webp 画像を作成するデモです。

# 環境
``` shell
$ node -v
v12.14.1
```
# プロジェクトの作成とプロジェクトルートディレクトリへの移動
``` shell
$ mkdir test-sharp && cd test-sharp
```


# npm パッケージを新規でセットアップする

今回はオプション -y で質問を省略しています。

``` shell
$ npm init -y
```

# インストール

sharp-cliをインストールします。

``` shell
$ npm i -D sharp-cli
```

# package.json にコマンドを記述します。

``` json:package.json
{
  "scripts": {
    "sharp": "npm run sharp-webp & npm run sharp-png & npm run sharp-jpg",
    "sharp-webp": "sharp -i ./src/images/**/*.jpg ./src/images/**/*.png -f webp -o ./dist/images",
    "sharp-jpg": "sharp -i ./src/images/**/*.jpg -o ./dist/images",
    "sharp-png": "sharp -i ./src/images/**/*.png -o ./dist/images"
  }
}
```
簡単に解説すると、

 * ``` "sharp" ``` で下記の3つの scripts を順次処理する。 

 * ``` "sharp-webp: ``` で ``` ./src/images/ ``` ディレクトリに保存された ``` .jpg ``` 、 ``` .png ``` を ``` .webp ``` にフォーマットして ```./dist/images/ ``` に保存する。

 * ``` "sharp-jpg" ``` で ``` ./src/images/ ``` ディレクトリに保存された ``` .jpg ``` 、を圧縮して ```./dist/images/ ``` に保存する。

 * ``` "sharp-png" ``` で ``` ./src/images/ ``` ディレクトリに保存された ``` .png ``` 、を圧縮して ```./dist/images/ ``` に保存する。



ということです。

なお、
* オプションの ``` -q ``` で PNG の圧縮率（0 - 9）を変えられます。（デフォルトは 9 です）
* オプションの ``` -c ``` で JPG の画質（1 - 99）を変えられます。（デフォルトは 80 です）


# 圧縮前の画像ディレクトリと書出し用の画像ディレクトリの作成

```shell
$ mkdir -p src/images & mkdir -p dist/images
```

# ここまでのディレクトリ構成
```shell
.
├── dist
│   └── images
├── node_modules
├── package-lock.json
├── package.json
└── src
    └── images
```

# 圧縮前の画像を準備
``` src/images ``` に圧縮したい画像を保存します。

# npm scripts を実行する
``` shell
$ npm run sharp
```

``` ./dist/images/ ``` に圧縮画像が書き出されます。

# 画像サイズの変化
圧縮率はデフォルトの 80 です。

|            |    圧縮前    |      圧縮後   | 圧縮後 WEBP |
|:-----------|------------:|------------:|---:|
| a.jpg      | 78KB        | 56KB         |31KB|
| b.png      | 86KB      | 58KB       |19KB|
| c.jpg      | 119KB        | 81KB         |44KB|


# PICTURE タグを使って画像を切り替える
```haml
<picture>
  <source srcset="dist/images/test.webp" media="(min-width: 800px)">
  <img src="dist/images/test.jpg" alt="" />
</picture>
```
800px 以上では ``` dist/images/test.webp ``` が表示され、800px 未満では ```dist/images/test.jpg ``` が表示されます。

# 参考
> [GitHub - vseventer/sharp-cli: CLI for sharp.](https://github.com/vseventer/sharp-cli)
[Node.jsのライブラリsharpの出力形式について | Simple is Beautiful.](https://blog.kozakana.net/2019/04/sharp-output-format/)
【C#】DataTable でのLINQの使い方（１）

## **はじめに**

C#のDataTableクラスでLINQを使ったコードを書く際に、暫くコードを書かないと、LINQは複雑な手続きの為、何回も調べ直さなければならないことがありました。これを防ぐ為に簡単にまとめた内容を記載します。

## **複数列の取得**

DataTable から必要な項目のみを取得
※あまり使う機会はないかもしれないが…

```C#
            DataTable member = new DataTable();
            member.Columns.Add("No", typeof(int));
            member.Columns.Add("Name", typeof(string));
            member.Columns.Add("Age", typeof(int));

            member.Rows.Add(1, "太郎", 20);
            member.Rows.Add(2, "次郎", 15);
            member.Rows.Add(3, "三郎", 10);

            var datas = 
                member.AsEnumerable()
                      .Select(x => new { Name = x["Name"], Age = x["Age"] });

            foreach (var data in datas)
                Console.WriteLine("Name:{0},Age:{1}", data.Name, data.Age);
```

簡単な説明

- Selectにnew演算子をセット後、キー名及び値となるDataTableの項目(列の名前)をセットします。
- 複数ある場合はカンマで区切ります。
- ”x =>”の x は何でも良かったりします。

出力結果

> Name:太郎,Age:20
> Name:次郎,Age:15
> Name:三郎,Age:10



## 条件に合ったデータの取得

DataTable から条件に合ったレコードを取得
※ループやif文条件を使うよりは、SQLに慣れているとこちらの方が見やすいかな…

```C#
            DataTable member = new DataTable();
            member.Columns.Add("No", typeof(int));
            member.Columns.Add("Name", typeof(string));
            member.Columns.Add("Age", typeof(int));

            member.Rows.Add(1, "太郎", 20);
            member.Rows.Add(2, "次郎", 15);
            member.Rows.Add(3, "三郎", 10);

            // rowsで結果を取得
            DataRow[] rows = 
                member.AsEnumerable()
                      .Where(x => (int)x["Age"] > 10)
                      .ToArray();

            Console.WriteLine("rowsで結果を取得");
            foreach (DataRow row1 in rows)
                Console.WriteLine("No:{0},Name:{1},Age:{2}", row1["No"], row1["Name"], row1["Age"]);

            // dataTableで結果を取得
            DataTable dataTable =
                member.AsEnumerable()
                      .Where(x => (int)x["Age"] > 10)
                      .CopyToDataTable();

            Console.WriteLine("");
            Console.WriteLine("dataTableで結果を取得");
            foreach (DataRow row2 in dataTable.Rows)
                Console.WriteLine("No:{0},Name:{1},Age:{2}", row2["No"], row2["Name"], row2["Age"]);

```

簡単な説明

- Whereに取得条件をセットします。
- 結果を格納する変数の型を2パターン記述してみました。

出力結果

> rowsで結果を取得
> No:1,Name:太郎,Age:20
> No:2,Name:次郎,Age:15
>
> dataTableで結果を取得
> No:1,Name:太郎,Age:20
> No:2,Name:次郎,Age:15

## おわりに

LINQは何かと使い勝手が良いと思います。
ただ、暫くコードを書いていないと、ふと書き方を忘れてしまうなと感じております。

この記事は備忘録的な意味合いが強く、詳しい説明などは記載しておりません。
「こんな事が出来るんだ」程度に見て頂ければ幸いです。

今回は初回として、記事としてはここまでになります。
今後、内容を追記していければと考えております。
クロージャ


# クロージャ
クロージャは、処理をまとめて呼び出し可能にします。処理を即席的に定義して他の処理に渡すことができます。書き方はこんな感じ。

```
{ 引数 in 戻り値を返す値 }
```

引数には入力される値、戻り値には出力される値を入れます。

例として、mapメソッドに各要素を２倍にするクロージャ式を渡す処理が下記となります。

```
let num = [1, 2, 3]
let doubleNum = num.map({ value in value * 2 })
print(doubleNum) // [2, 4, 6]
```

# まとめ
クロージャは関数の一種ですが、名前も要らず、型推論により型の記述が省略可能だったりと、関数よりも軽量化して定義することができるメリットがあります。

# 参考
[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)
MDN Reactチュートリアル復習#1

# 前置き
MDNのReactチュートリアルを読んで&&やってみて学んだことの復習です。本記事では基礎的なことからpropsまでのことを復習しています。
[MDN React入門](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started "MDN React入門")
環境構築は下記記事を参考にしました。
https://qiita.com/2754github/items/413bdaaa90834e219dc8

何か間違いがあれば指摘していただけると大変励みになります。

# Reactプロジェクトの主なディレクトリ
`src`...主にいじるファイルが入っている
`public`...ブラウザによって読み込まれるファイルが含まれる。Reactはこの中の`index.html`にコードを挿入する。

# 初期状態のブラウザ描画の流れ
`App.js→index.js→index.html`
**App.js**
1. App.js内でfunction又はclassを定義する※(前者と後者で状態管理などが変わってくるらしい…)
2. 1で定義したものの中で、retur()内にJSXを記述
3. 「export default 〇〇」で出力
※ここでは「function App」と定義した
**index.js**
1. App.jsで定義したものをimport
2. render()メソッド内でindex.html内の対象のidを取得して描画

# チュートリアル開始
### props
`props`	…propertiesの略、コンポーネント間でデータを渡すことができる。親から子にのみ渡すことができる。
index.js内のAppコンポーネントを呼び出しているところに下記の様な形で変数に値を代入する。

```jsx:index.js
ReactDOM.render(<App subject="Clarice" />, document.getElementById('root'));
```
子コンポーネントであるApp.jsで下記のように記述するとデータを渡すことができる

```jsx:App.js
function App(props) {
  console.log(props);
  return (
    // return statement
  );
}
```

# 終わりに
次からはtodoアプリをチュートリアルに沿って作っていこうと思います。
AWSアクセスキーを流出してしまった時の対処法について

#出来事
先日誤って、AWSのアクセスキーをGithubにあげてしまいました。調べていくうちに、これはとんでもないことをしてしまったと思い、急いで対処しようとしましたが、焦りもあって何もできず。何かプロのエンジニアに電話か何かで対応してもらえるアプリはないか探していたところ、「ココナラ」というアプリを発見。急ぎ、エンジニアに対応してもらいました。

##AWSアクセスキーをGitHubにあげてしまった時の対処方法
 AWSアクセスキーを含むコミットを削除し、AWSアクセスキーを保存した履歴を削除することが適切な対処方法です。具体的には、Git rebase機能、又はGit commitのamendオプションを利用することで履歴を削除することが可能です。
##◆まず初めにやること
AWSを無効化する。
AWSアクセスキーを無効化した場合は、セキュリティ上の問題は発生しませんのでご安心ください。AWSアクセスキー（恐らくIAM userのAccess KeyとAccess Secret Key）は、無効にしたりSecretを更新することで既存Credentialは使用不可となるためです。ですので、原理上アクセスキーをコードから削除したり履歴上から抹消しなくても、攻撃が発生することはありません。

…ただし、やはりCredentialがコード履歴に残っていることは印象が悪いため、削除したほうが良いですよね、、、
##◆どのように防ぐか

「ブランチ戦略」です。
ブランチの位置づけとして「main」はテスト・コードレビューが完了したコード、「その他（devなど）」は消えたりrebaseされたりする可能性のあるコードとして分けておきます。そうすることで、ミスしたPushでもリカバーできる簡易性を担保させることができます。
この手法は開発メンバーが増えていけばいくほど有効になってきます。
（勝手にコミットを結合したり消したりするのはマズイので…）

##◆rebaseとamendの使い分け

amendは、直前のコミットを修正することが可能でして、この方法を用いるのが一番簡単です。
ただし、この方法は「直前のコミットを修正したい」場合にのみ有効です。rebaseは、修正したいコミットをどこでも修正することが可能です。ただし、rebaseコマンド自体が様々な機能を持っているので、コマンドの使いやすさでは劣ります。

##◆amendで修正する手順
以下の手順で修正が可能となります。

```
1. ローカル環境のソースコードを修正
2. コマンド "git add ." を実行
3. コマンド "git commit --amend" を実行
4. 直前のコミットのコミットメッセージがエディタで表示されます
5. 必要に応じてコメントを修正し保存
6. git pushコマンドを再実行（既にPushしたコミットを上書きするため、-fオプションが必要）
```
WSLでVSCode連携

# WSLでVSCode連携

WSLで立ち上げたUbuntuのファイル編集をおこなう方法まとめ

## VSCodeのインストール

Windows側にVSCodeをインストールする。`Remote-WSL`をインストールします。

![wsl001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63450/2348871f-923b-cd15-7c94-d71fee29ae14.png)

`SHITF`+`CTRL`+`P`でコマンド入力のDialogを表示し、`Remote-WSL`と入力し、`Remote-SWL: Open Finder in WSL..`を選択。

![wsl002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63450/ad5a08cf-5437-3b24-0a5d-29d08c5d1aac.png)

これでVSCodeからUbuntuのファイルを開ける。

![wsl003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63450/2d7bd388-f174-88c0-b506-28107fb4f9df.png)

## WindowsからUbuntuのファイルに直接アクセスする

![wsl004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63450/a09b0c97-b728-76be-5123-37034b86e782.png)
暗黙のリターン


```
var userName = "Watanabe"

func makeMassage(user: String) -> String {
    "Hello, \(user)"
}

makeMassage(user: userName)
```

上のサンプルコードは、戻り値がある関数なのに、returnをつけていません。
関数内の実装が戻り値の返却のみの時だけ、暗黙的なreturnができます。

```
func nonMakeMassage(user: inout String) -> String {
    user = "Tanaka"
    "Hello, \(user)"
}

nonMakeMassage(user: &userName)
```

当たり前ですが上のコードだと
>Missing return in a function expected to return 'String'; did you mean to return the last expression?

と怒られました。

# 参考
[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)
可変長引数


## 可変長引数とは
引数の個数を自由に設定出来るパラメーター

## 書き方
型名の後ろに ... を記述します。

```
func print(strings: String...) {
    if strings.count == 0 {
        return
    }
    
    print("first: \(strings[0])")
    
    for string in strings {
    print("elements: \(string)")
    }
}

print(strings: "apple", "banana", "orange")

// 出力結果
first: apple
elements: apple
elements: banana
elements: orange
```

# 参考
[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)
inout引数


関数内での引数への再代入を関数外へ反映させたいとき、インアウト引数を使用します。

```
var userName = ""

func getUserName(user: inout String) {
    if user.isEmpty {
        user = "Watanabe"
    }
    print(user)
}

getUserName(user: &userName)
```

インアウト引数を使用するには、引数の型の前にinoutキーワードを追加します。
インアウト引数を持つ関数を呼び出す時は、引数の先頭に&をつけます。

ちなみに、普通にinoutをつけずに書いてみると、

```
var userName = ""

func getUserName(user： String) {
    if user.isEmpty {
        user = "Watanabe"
    }
    print(user)
}

getUserName(user: &userName)
```

関数内の条件分岐の中で下記のエラーが出てきます。
>Cannot assign to value: 'user' is a 'let' constant

関数内でuserを新たに定義しなければいけないと怒られました。

## なぜか？

二番目のプログラムで行っているのは値渡しですが、最初に書いたinout引数を使用したプログラムは参照渡しを行っています。
参照渡しとは、変数のアドレスを引き渡すことです。
参照渡しは値ではなくアドレスを渡すので、変数そのものの値が書き換えられ、さらに元の値も失われます。よって値を変更することに成功しました。

# 参考
[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ) 
https://qiita.com/Hic2770/items/9214487fe031846c286d
外部引数名の省略


外部引数名を省略したい場合は、外部引数名にアンダースコアをつけることで省略できます。

```
func sum(_ x: Int, _ y: Int) {
        return x + y
}

sum(1, 3) //出力： 4
```

省略しない通常の書き方だと

> sum(x: 1, y: 3)

と書く必要があるので、省略できた方がコードがシンプルになりますね。

# 参考
[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)
命名規則


## 単語の区切り方
Swiftではキャメルケースを使用します。

変数、定数：　ローワーキャメルケースを使用。（camelCase, someVariable, someContentsのように最初の単語の頭が小文字で、それ以降の単語は頭文字を大文字にする）
型：　キャメルケースを使用。（CamelCase, SomeVariable, SomeContentsのように最初の単語の頭文字から単語ごとに頭文字を大文字にする）

## 単語の選び方
・必要な単語は全て含める
悪い例： findUser(_:)関数は、どのようにユーザーを検索するのか曖昧
良い例： findUser(byID:)関数は、ユーザーIDで検索することがわかりやすい

・一般的でない単語の使用は避ける
悪い例：epidermisは「表皮」という意味だが、あまり一般的な単語ではない
良い例：skinは一般的かつ、epidermisと同様の意味の単語なので良い

・略語を避ける
悪い例：stmtはstatementの略語だがわかりにくい
良い例：statementのように単語は略さずそのまま使用する

# まとめ
気にしなくても一応プログラムは動きますが、現場で開発する際は基本ルールに合わせて開発した方が他の人が見てもわかりやすいです。
また、キャメルケースかスネークケースかは、言語によって違うので、自分の使用する言語がどちらなのかを知っておく必要がありそうです。

# 参考
[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)
決定木を使ってScikit-learn Boston Housing Datasetの回帰をしてみる

Boston Housing Datasetをロードする。

<pre>
from sklearn import preprocessing
import pandas as pd
import numpy as np 

from sklearn.datasets import load_boston

boston = load_boston()
X,y = boston.data, boston.target
</pre>

プロットしてみる。。。

<pre>
import matplotlib.pyplot as plt

plt.figure(figsize=(24, 8), dpi=50)
plt.subplot(211)
plt.plot(X)
plt.subplot(212)
plt.plot(y)
</pre>

今回は、下のyの系列に対して回帰をする。。

![ダウンロード (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/534e7704-e559-6026-471a-4f518e81769a.png)

決定木回帰のモジュールをインポートする。。

<pre>
import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
</pre>

【参考】
1次元配列をreshape(-1, 1)とすると、その配列を要素とする2次元1列の配列となる。

<pre>
a = np.arange(4)
c = a.reshape(-1, 1)
print(c)
 
[[0]
 [1]
 [2]
 [3]]
</pre>

http://taustation.com/ndarray-reshape-use/

系列yを整形する。。。

<pre>
z=np.array(y).reshape(-1, 1)
print(z[0:5])
print(len(z))
</pre>

回帰をする時系列のx列にあたるものを作る。。。

<pre>
x = list(range(0, 506, 1))
w=np.array(x).reshape(-1, 1)
</pre>

<pre>
print(w[0:5])
</pre>

決定木で回帰をする。。。
<pre>
X_test = np.arange(0.0, 506, 1)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
</pre>

プロットをする。。

<pre>
plt.figure(figsize=(24, 8), dpi=50)
plt.scatter(w, y, s=15, edgecolor="black", c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue",label="max_depth=2", linewidth=4)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=4)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.show()
</pre>

![ダウンロード (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/69ce3e26-462c-131a-cd9f-30cb621de5b3.png)

https://github.com/RuoAndo/time-series-analysis-with-Python/blob/master/qiita/Decision-Tree-Regression-Boston.ipynb
「Rails」bundle installでAn error occurred while installing mimemagic (0.3.10), and Bundler cannot continue.の対処法


### エラー文章

```bash:MacOS　ターミナル
An error occurred while installing mimemagic (0.3.10), and Bundler cannot continue.
Make sure that `gem install mimemagic -v '0.3.10' --source 'https://rubygems.org/'` succeeds before bundling.
```

### 上に遡るとこんなことが書いてある

```bash:MacOS　ターミナル
Fetching mimemagic 0.3.10
Installing mimemagic 0.3.10 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
```

### shared-mime-infoをインストールする

```bash:MacOS　ターミナル
brew install shared-mime-info
```

### bundle installをする

```bash:MacOS　ターミナル
bundle install
```

mimemagicがアップデートされて無事エラーが無くなる。
### 2021/8/2 補足
マークダウンを整えました。
COVID-19への迅速な対応による感染拡大の抑制 (Databricksユースケース)

[Customer Story: Indiana University Health \- Databricks](https://databricks.com/customers/indiana-university-health)の翻訳です。

**業種**: ヘルスケア
**ソリューション**: 住民向けヘルスサービス
**技術的ユースケース**: データ投入、ETL、データ分析、機械学習
**要約**:

- 7日間で30以上のレポートとダッシュボードを構築

COVID-19の世界的影響により、この医療危機の状況においては、リアルタイムかつインテリジェントにインサイトを大規模医療機関に提供することは非常に重要になっています。Indiana University Healthは、Databricksのレイクハウスプラットフォームを活用いただくことで、データチームが7日間で迅速にセルフサービスのオファリングを構築し、データのサイロ化とレガシーなインフラストラクチャの課題を打破することができました。データドリブンのインサイトを活用することで、今や彼らは病院のオペレーションを改善し、COVID-19の感染爆発との戦闘を効果的に進めています。

# 定期的に進化するデータジャーニー

Indiana University Healthは、インディアナ州にある18の病院から構成される州最大の病院ネットワークであり、34,000人の従業員で約百万人の住人にサービスを提供しています。2000年代初頭においては、他の企業と同様に、連携していない複数のデータベースやサーバー、基幹データウェアハウスを用いて、大量のデータを取り扱っていました。

技術の進展と、データがビジネスに大きく寄与するようになるに従い、真のエンタープライズ規模のデータウェアハウスを実現するプラットフォームの導入と、Indiana University Healthの収集する情報をより一層活用すると言う意思決定を行いました。

「我々はMicrosoftの分析プラットフォームシステムを使っていました」と、Indiana University Healthの情報システムVPであるTony Pastorinoは振り返ります。「これを用いて、大規模なデータウェアハウスを構築して、分析のために必要なデータを整備するプロセスをスタートしました。データ整備に必要なスキルを蓄えていました。そして、データから得られるビジネス上、医療的な知見を得ていました。」

これは明らかに以前の状態からステップアップしたと言えますが、全てをオンプレミスで実現していたため、スケールアップできない等、多くの課題に直面していました。2019年にはKenSciとのパートナーシップを通じて、Indiana University Healthは、Microsoft Azure Cloudへの移行を決定し、データの真のポテンシャルを解放し始めました。

# クラウドにおけるデータの集約が無限の可能性を提供します

現在では、Indiana University Healthは、DatabricksのレイクハウスプラットフォームとAzure Cloudを活用することで、構造化データ、非構造化データ両方を含む全ての種類のデータを分析することが可能となっています。Delta Lakeを用いることで、医療データが後段の分析ワークロード、特にBIや機械学習で活用できるように、医療データを投入、統合することが可能になりました。

「データとレポートのアセットをMicrosoft Azure Cloudにアップロードしてしまえば、無限の計算資源、無限のストレージ、最新のツールをすぐに利用することができます。」、Tonyは説明します。このレベルのスケールによって、Indiana University Healthでセルフサービスのコンポーネントを提供できるようになり、最終的には、集中化されたビジネスインテリジェンスハブにいる250人以上のアナリストをサポートすることになりました。

「Databricksが無かったら、一度に多くのアナリストとSMEをサポートすることは不可能でした」、彼は付け加えます。「Databricksによって、大規模データの整備が可能になり、それらのデータに対して、アナリストが他のデータとJOINしたり、有意義な示唆を得るの必要なBIを実施できるようになりました。」

Delta Lakeを介して統合されたデータによって、Indiana University Healthは機械学習と先進的な分析の世界に足を踏み入れました。今となっては、地域医療を改善するために、滞在期間、患者の移動経路、ベッドの空き状況などの鍵となるメトリクスを用いて予測を行う機械学習モデルを構築することが可能となっています。

# リアルタイムデータでCOVID-19と戦う

COVID-19が直撃した際、Indiana University Healthは、これまで予測できなかったニーズに対して迅速に対応できるようになっていました。Tonyと彼のデータチームは、組織全体にまたがる分析を統合し、これを経営層のリーダーシップに連携することで、彼らが注目すべき視点でデータに光を当てることが可能になりました。彼らは7日間で、30のレポートから構成されるダッシュボードを立ち上げ、彼らはこれをCOVID-19指令センターと呼んでいます。

「Databricksが経営層に提供するデータインサイトが無ければ、このCOVID-19の波を乗り切ることは絶対に無理でした」、Tonyは説明します。「インサイトは非常に難しい決断を迫るケースがありますが、何をすべきか、いつすべきかを知ることで、最終的にはこのパンデミックを生き残ることを助けてくれています。」

実際のところ、Indiana University HealthはDatabricksの提供するケイパビリティによって大きく変化しています。今彼らば、COVID-19の向こう、次のパンデミックや健康に関する災害に備えるために、エグゼクティブレベルの人材を異なる部門から招集した内部グループを立ち上げています。

「我々は、あらゆることに対して備えておきたいと考えています。そして、のDatabricksが提供する日々の業務のためのダッシュボードによって、それが可能だと考えています。」

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)