OmniAICreator/Qiita-1.07M huggingface dataset:
[Unity]扉のヒンジを試しに作ってみる

#概要
HingeJointを使ってヒンジの動きを作ってみました。（ちなみにサンプル動画にある扉の左右の壁は無くても動かせます）
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a> <a href="https://t.co/70NrFcVAPB">pic.twitter.com/70NrFcVAPB</a></p>&mdash; kazuma (@kazuma_f) <a href="https://twitter.com/kazuma_f/status/1363082421202079746?ref_src=twsrc%5Etfw">February 20, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#本文
扉の形に変形させたCubeに「HingeJoint」をAddComponentします。自動でRigidbodyも付加されます。
![スクリーンショット (1806).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/4bd3d41c-8fd2-b2ca-7c63-cb330b3b1b8c.png)
設定をいじらなくてもこれだけで扉の動きになってくれます。設定をいじれば横開きの扉や回転扉も作ることができます。
#おまけ
扉が重くて動かない > RigidbodyのMassを減らすと動いてくれます

扉がパタパタ動き続ける > RigidbodyのDragを適度に増やすと自然にパタパタが止まってくれるようになります

#おまけ２
横開きの扉の設定例です。
![スクリーンショット (1807).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/8641b37b-76e3-b096-bfb5-0b84fdcc000b.png)
Axisが扉の動く方向、Anchorがヒンジの位置と考えるとわかりやすいと思います。
EditAngularLimitsの右にあるボタンを押すとSceneビューにヒンジを表すマークが出てくるので各数値を変えながらマークがどう動くか見てみるとイメージが湧いてくると思います。
pyenv installしたときのZipImportError

# 環境
 - MacOSX 11.2.1 BigSur

# エラー内容
MacOSXでのzlibエラー。
pyenv install 3.8.5を叩くとエラーがでた。

```bash
$ pyenv install 3.8.5
```

```bash:error
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Installing Python-3.8.5...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk

BUILD FAILED (OS X 11.2.1 using python-build 20180424)
```

ログのtailはこんな感じ。

```bash:log
    __import__(pkg_name)
  File "<frozen zipimport>", line 241, in load_module
  File "<frozen zipimport>", line 709, in _get_module_code
  File "<frozen zipimport>", line 570, in _get_data
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1
```

# 対処法
Tipsによく転がっているxcode-selectや、pkgのインストールなどではうまくいかなかったが、下記でうまくいった。

```bash
LDFLAGS="-L$(xcrun --show-sdk-path)/usr/lib" pyenv install 3.8.5
```
# 参考にした記事
こちらの記事に書いてあった。
https://github.com/pyenv/pyenv/issues/1219#issuecomment-727951276
【Node.js】Node.jsの3大フレームワークについて

#プログラミング勉強日記
2021年2月20日
Expressを使うことが多いが、他のNode.jsのフレームワークが気になったので簡単にまとめる。

#Expressとは
　ExpressはNode.jsを活用したWebアプリ開発を効率よく進めることができ、よく使われている標準的なものである。
　特徴としては、情報量が多く日本語のリソースも多い。また、拡張モジュールが豊富なので追加することで柔軟な対応ができる。Expressは記述量が少なくサーバー制御が可能で複雑なシステムも簡単に拡張することができる。

#Meteorとは
　Meteor(読み方：「メテオ」)フレームワークはフルスタックで、サーバー制御からフロントエンドまですべてをJavaScriptで書くことができる。MeteorはNode.jsをベースとしていて、JavaScriptとHTML, CSSだけでWebアプリを開発できるプラットフォームである。
　特徴としては、デバイスを含めてプラットフォームに依存しなく簡単に記述することができる。また、迅速な開発が可能でSPAを早く構築して公開するまでをサポートする。既存の開発そのものを変革する仕組みであったり、モバイル向けのネイティブアプリ作成も可能であったりと、魅力的な機能が豊富にある。


#Sailsとは
　MVCをサポートとした開発効率を重視したフレームワークである。
　特徴としては、MVCをサポートしているRailsのような操作で開発環境を進められる。デフォルトでWeb SocketをサポートしたリアルタイムWebアプリ開発もできる。Web APIを簡単に作成して公開することもできる。

#参考文献
[【Node.js入門】3大フレームワーク「Express」「Meteor」「Sails」の特徴とは？](https://www.sejuku.net/blog/85534)
[Express Web フレームワーク (Node.js/JavaScript)](https://developer.mozilla.org/ja/docs/Learn/Server-side/Express_Nodejs)
[オープンソースのフレームワーク／Meteorとは](https://www.ossnews.jp/oss_info/Meteor)
[Node.jsのWebフレームワーク「Sails」を使ってpub/subアプリを作ってみる](https://codezine.jp/article/detail/7696)
devise x omniauth-twitter x bootstrap-social にてTwitterサインインボタンを出力する

めっちゃ苦戦した。ポイントは link_to の文字列をなくして`do-end`で囲み、中にspanを置くことと、'twitter`が文字列でなくシンボルなこと。

```erb
## app/views/devise/shared/_links.html.erb
<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %> 
    <% puts provider.class %> 
    <% if provider == 'twitter'.to_sym %>
      <%= link_to omniauth_authorize_path(resource_name, provider), class: "btn btn-block btn-social btn-twitter" do %>
        <span class="fab fa-twitter"></span>Sign in with Twitter
      <% end %>
    <% else %>
      <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %><br />
    <% end %>    
  <% end %>
<% end %>
```

bootstrap-socialはGithubの`bootstrap-social.css`を`app/assets/stylesheets`配下に配置しようとしたが、bootstrap自体の読み込みを`app/javascript/src/application.scss`でやっていたので、scssファイルとして同階層に配置し`@import 'bootstrap-social.scss`としたものの、読み込み順が違ったりBootstrapのバージョンなのか、Fontawesome5を使っているからなのかレイアウトが崩れたりする。

結局、必要なCSSを Developer Tool を開きながら抜き出す形に‥。つまり言いたいのはTwitterボタンのデザイン適用方法はここのBootstrapのインストール方法によるので何とも言えないってこと。色々と非効率だし美しくない‥。
初めてのRaspberry Pi Pico ⑱ C言語 12ビットADC MCP3201

　Picoには12ビット4チャネルのA-Dコンバータが内蔵されています。もし1チャネル足りなかったら、という想定で外部にICを追加します。
###MCP3201のおもなスペック

- ビット数 12
- チャネル数 1（疑似差動）
- 基準電圧 内蔵なし、端子あり
- 変換速度　100ksps（5V時）
- インターフェース　SPI（モード0,0および1,1）、クロック1.6MHz（5V時）、0.8MHz（2.7V時）
- 電源動作電圧　2.7～5.5V
- ピン数　8ピンDIP

###接続
　MCP3201は読み出しだけなので、MOSI SPI0 TX（GP3）はつないでいません。

|MCP3201の端子|Picoの端子(GPIO) | 名称|
|-----------|:------------:|:------------:|
|1 Vref|3V3|3.3V|
|2 IN+| -|-|
|3 IN-| -|-|
|4 Vss|GND|GND|
|5 /CS|GP5 |SPI0 CSn|
|6 Dout|GP4|MISO SPI0 RX|
|7 CLK|GP2|SPI0 SCK|
|8 Vdd|3V3|3.3V|

　入力のIN+/IN-には、電池駆動の簡易電源TL431の出力をつないでいます。約2.5Vです。

###プログラムmcp3201.c
　フォルダはmcp3201としました。CMakeLists.txtは省略します。17回以前を参考にしてください。

　[MCP3201データシート](http://ww1.microchip.com/downloads/cn/DeviceDoc/cn_21290b.pdf)

　データは読み出しだけです。ダミーの0xffを2回送って、2バイト読み出します。bufferの上位バイトは「? ? 0 D11 D10 D9 D8 D7」が入っているので、0b00011111でマスクします。下位バイトは「D6 D5 D4 D3 D2 D1 D0 D1」と、LSBに余分な1ビットが入っています。16ビットに合成した後、右に1回シフトして捨てています。
　12ビットのデータなので、4096で割って、Vrefの3.3Vをかけて電圧を求めます。Vrefは、できるだけ正確にテスタで測った値を記入しておきます。

```cpp
/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"

#define PIN_MISO 4
#define PIN_CS   5
#define PIN_SCK  2
#define PIN_MOSI 3

#define SPI_PORT spi0

static inline void cs_select() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 0);  // Active low
    asm volatile("nop \n nop \n nop");
}

static inline void cs_deselect() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 1);
    asm volatile("nop \n nop \n nop");
}

int main() {
    stdio_init_all();

    printf("Hello, MCP3201 Reading raw data from registers via SPI...\n");

    // This example will use SPI0 at 0.5MHz.
    spi_init(SPI_PORT, 500 * 1000);
    gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);

    // Chip select is active-low, so we'll initialise it to a driven-high state
    gpio_init(PIN_CS);
    gpio_set_dir(PIN_CS, GPIO_OUT);
    gpio_put(PIN_CS, 1);

    // read ADC data. 0xff is dummy. sleep is kiyasume
    uint8_t buffer[2];
    cs_select();
    sleep_ms(1);
    spi_read_blocking(SPI_PORT, 0xff, buffer, 2);
    sleep_ms(1);
    cs_deselect();

    int data = ((buffer[0] & 0b00011111) << 8 | buffer[1]) >> 1;

    // printf(" %d %d \n", buffer[0], buffer[1]);
    // printf(" %b %b \n", (buffer[0] & 0b00011111)<<8, buffer[1]);
    // printf("%b %d \n",data, data);
    printf("ADC is %.3f\n", (3.3 * data) / 4096);

    return 0;
}
```

　実行結果です。2回目は、入力をショートしています。
![ADC101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a9250268-a454-21ea-e8ef-c14b8242271a.png)


![IMGP0249.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/3e074eec-b052-4dc1-09fa-45832daa8c22.png)
【AppleWatch】XCodeを使って文字盤を作る方法

# どういうことか

そのまんまです。オリジナルの文字盤を作る。
Apple Watchを実際に買うまでは「インスタグラムでもオリジナル文字盤を見るし、そういう機能があるんだろう」と思っていたら、そんな単純なハナシではなかった。
どうもコーディングとかしなきゃいけないらしいと知った。実際のところ、これがやりたいがためにSwiftを勉強し始めたと言っても過言ではない。
――で、勉強するうちになんとなくいろいろわかってきて「たぶん針のUIKitがあってそれをStoryboardに配置すればいいだろう」と思ってたらそんなことはなかった。
現実問題として、Appleはオリジナル文字盤を作ることを良しとしていないようで（基本的には）オリジナル文字盤がストアに並ぶことはない（後述）し、オリジナル文字盤が作れる簡単なプラットフォームは用意されていない。

## 実装方法

XCodeを立ち上げてWatchOSを選択して作る。
……かと思っていたらそうではなかった。
2Dゲームを作るためのフレームワークである **SpriteKit** を使用する。
本題の実装方法としては丸投げだがここを参考にすればできる。

**Tutorial: Create a Custom Apple Watch Face and Get Rejected by the App Store**
<https://medium.com/@yuyouwu5/tutorial-creating-a-custom-apple-watch-face-and-get-rejected-by-the-app-store-6e7f7f1959de>

### 大きな問題点

上の記事における「右上の時計表示を消す」方法だが、うまいことモーダルで文字盤のコントローラに遷移してやることで消すことができる。**正確に言うとできたらしい。**現在のバージョンだとこちらの実装方法でも時計が表示されてしまう。
XCodeによる実装のハナシはこれで終わりです。残念だった。

## Best Solution

後述の件。
**[Clockolog‪y](https://apps.apple.com/jp/app/clockology/id1456386228)‬**を使いましょう。

単純にオリジナルの文字盤を作りたいという方はこのアプリ使うのが良さそうです。
【GAS】googleフォームの回答を元にChatWorkのルームを作成する

##やりたかったこと
タイトルのまんまです。

##なぜ作ろうと思ったか
会社でChatWorkを使っていてどんどんルームが作成されるのはいいけどルームの命名規則等が無く見づらかった。
規則を作れば良いんだけど守らない人も出てくると思ったので、googleフォームから作ってもらえば制限もかけれそうだしいいんじゃないかと思って。

###流れ
1.googleフォームに作成したいルームの情報を入力し回答
2.google apps scriptで回答内容を元にchatworkへルーム作成のリクエストを投げる
3.ChatWorkにルームが作成される

##さっそく作ってみる
###0.事前確認
[ドキュメント](https://developer.chatwork.com/ja/endpoint_rooms.html#POST-rooms)を読んだらルームの作成に**必須**な情報は以下の通り。
・members_admin_ids（管理者権限のユーザー）
　- 参加メンバーのうち管理者権限にしたいユーザーアカウントのID。複数指定可
・name（グループチャット名）

必須ではない項目は以下の通り
・description（チャット概要）
・icon_preset（グループチャットのアイコン種類）
・link（招待リンク作成）
　- 招待リンクを作成するかどうか。
・link_code（リンクの文字列）
・link_need_acceptance（承認要否）
・members_member_ids（メンバー権限のユーザー）
・members_readonly_ids（閲覧のみ権限のユーザー）

会社では作成したルームへのユーザー追加はチーム機能を利用しているが、用意されていなかったのでルーム作成後に手動でチーム追加してもらう運用を想定。

とりあえず↓の4つだけで実装してみる
・members_admin_ids（管理者権限のユーザー）
・name（グループチャット名）
・description（チャット概要）
・icon_preset（グループチャットのアイコン種類）

###1.googleフォームの準備
とりあえずシンプルなフォームを作成。
お客さんの名前を入力してもらうものと、作成者（担当者）の名前を選択してもらう質問を作成。
![スクリーンショット 2021-02-20 17.48.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205237/6bb4b600-9010-da24-8bcf-d9552f66b684.png)

###2.google apps scriptで回答内容を元にchatworkへルーム作成のリクエストを投げる
管理者権限のユーザーIDが必要なので名前とIDを管理するスプレッドシートを作成。
フォームで作成者に入力された人を管理者にする。
![スクリーンショット 2021-02-20 18.08.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205237/5a2b6d2c-e811-4cb7-4c21-afa5810585b4.png)

```js:sample.gas
function createChatRoom(e) {
  const formdata = e.response.getItemResponses();
  let companyName;
  let createUser;
  for (let i = 0; i < formdata.length; i++) {
    if (formdata[i].getItem().getTitle() === '顧客名') {
      companyName = formdata[i].getResponse();
    } else if (formdata[i].getItem().getTitle() === '作成者') {
      createUser = formdata[i].getResponse();
    }
  }
  const userCwId = getUserInfo(createUser); //スプレッドシートからフォーム回答者のChatWorkIDを取得する関数を実行
  const token = PropertiesService.getScriptProperties().getProperty('CW_TOKEN')
  const headers = {
    'X-ChatWorkToken': token
  };
  const payload = {
    'description': '概要だよ',
    'icon_preset': 'star',
    'members_admin_ids': `${userCwId}, 複数の場合はカンマ区切りで指定`,
    'name': `【A会社】${companyName}様`
  };
  const options = {
    'headers': headers,
    'method': 'post',
    'payload': payload,
  };
  
  const url = 'https://api.chatwork.com/v2/rooms';
  const res = UrlFetchApp.fetch(url, options);
  console.log(res.getContentText())
  console.log(res.getResponseCode())
}

function getUserInfo(name) {
  const userInfoSpreadsheet = SpreadsheetApp.openById('ID情報を管理してるスプレッドシートのID');
  const userInfoSheet = userInfoSpreadsheet.getSheets()[0];
  const names = userInfoSheet.getRange(1, 1, userInfoSheet.getLastRow()).getValues().flat();
  const userRowNum = names.indexOf(name) + 1;
  const userCwId = userInfoSheet.getRange('B' + userRowNum).getValue();
  return userCwId;
}

```

###3.ChatWorkにルームが作成される
できた。
![スクリーンショット 2021-02-20 18.21.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205237/23055b35-f8de-11b9-0948-4ab37457c7f2.png)

実際に使うかは置いといてとりあえず動いたのでよし。
あとはフォームの構成をどうしようか考えよう。
下書きメール作成の自動化（UiPath）

**Excelのお客さま名簿から情報を取得して、Outlookの下書きメールを作成する作業を、UiPathで自動化。**

**ビジネス要件（抜粋）**
　・作成するメールの内容パターンは10パターン。名簿の内容に応じて、作成するメールのパターンを判定する。

　・メールの内容パターンには、一斉送信メールか個別送信メールか、という分類もある。一斉送信メールと判定されたお客さまは、グルーピングしてメールを1通にまとめる。
　
　・メール本文は、フォント（文字種類や色）を指定する。本文の一部は可変情報（主に日付情報）である。

**システム要件（抜粋）**
　・安定かつ高速に処理を行うため、UI操作をしない方式を採用。ポイントは以下2点。
　　- UiPathのアクティビティ（Uipath.Mail.Outlook.Activities.SendOutlookMail）を使用。
　　- メール本文はhtml（xml）で雛形作成
　
　・ロボットが、名簿情報の収集や仕分の作業を行いやすくするため、ユーザ部門合意のうえ名簿を拡張。ポイントは以下2点。
　　- ロボットが利用する情報を1か所（1シート、1範囲）にまとめる
　　- Excel関数で対応できる処理は、UiPathでロジック定義するよりも、Excel関数を優先する。
ローカルから直接Dockerのデータベースをバックアップ・レストアする

# 経緯

バックアップ・レストア方法をググるとほとんどの記事は`docker cp`してDockerコンテナの中に入って直接コマンド叩いてたり、`docker run`でバックアップ、レストアのコマンドを実行していたりしている記事が多かったのですが、そうではなくてワンライナーで直接バックアップ、レストアする方法が知りたかったのでまとめてみました。

基本的なバックアップ・レストア方法を記載します。もしパスワードやデータベース名が必要な場合は適宜コマンドのオプションで指定してください。

今回はPostgreSQL、MySQL、MongoDBについてまとめますが、その他のDBでも同様の方法で可能だと思います。

# 定数
以下の定数はコマンド等で確認してください。
`CONTAINER_NAME` : Dockerのコンテナ名またはID。`docker ps`で確認する。
`USERNAME` : Docker内のデータベースのユーザ名
`PASSWORD` : Docker内のデータベースのパスワード
`DATABASE_NAME` : Docker内のデータベース名
`SERVICE_NAME`: docker-composeのyamlに記載しているサービス名。`docker-compose config --service` で確認する。

# PostgreSQL

## Dockerコマンドを使用する場合

### バックアップ
```
docker exec CONTAINER_NAME pg_dumpall -U USERNAME > dump.sql
```

gzipで圧縮する場合は以下

```
docker exec CONTAINER_NAME pg_dumpall -U USERNAME | gzip > dump.sql.gz
```


### レストア

```
cat dump.sql | docker exec -i CONTAINER_NAME psql -U USERNAME
```

gzipで圧縮されたファイルをレストアする場合は以下

```
gunzip < dump.sql.gz | docker exec -i CONTAINER_NAME psql -U USERNAME
```

### docker-compose コマンドを使用する場合

#### バックアップ
```
docker-compose exec -T SERVICE_NAME pg_dumpall -U USERNAME > dump.sql
```

#### レストア
```
cat dump.sql | docker-compose exec -T SERVICE_NAME psql -U USERNAME
```

# MySQL

## Dockerコマンドを使用する場合

### バックアップ
```
docker exec CONTAINER_NAME mysqldump -u USERNAME -pPASSWORD DATABASE_NAME > dump.sql
```

gzipで圧縮する場合は以下

```
docker exec CONTAINER_NAME mysqldump -u USERNAME -pPASSWORD DATABASE_NAME | gzip > dump.sql.gz
```


### レストア

```
cat dump.sql | docker exec -i CONTAINER_NAME mysql -u USER_NAME -pPASSWORD DATABASE_NAME
```

gzipで圧縮されたファイルをレストアする場合は以下

```
gunzip < dump.sql.gz | docker exec -i CONTAINER_NAME mysql -u USER_NAME -pPASSWORD DATABASE_NAME
```

### docker-compose コマンドを使用する場合

#### バックアップ
```
docker-compose exec -T SERVICE_NAME mysqldump -u USERNAME -pPASSWORD DATABASE_NAME > dump.sql
```

#### レストア
```
cat dump.sql | docker-compose exec -T SERVICE_NAME mysql -u USER_NAME -pPASSWORD DATABASE_NAME
```

# MongoDB

## dockerコマンドを使用する場合

### バックアップ

```
docker exec CONTAINER_NAME mongodump --archive > db.dump
```

gzipで圧縮する場合は以下

```
docker exec CONTAINER_NAME mongodump --archive --gzip > db.dump.gz
```

### レストア

```
docker exec -i <mongodb container id or name> mongorestore --archive < db.dump
```

gzipで圧縮されたファイルをレストアする場合は以下

```
docker exec -i CONTAINER_NAME mongorestore --archive --gzip < db.dump.gz
```


## docker-compose コマンドを使用する場合

### バックアップ
```
docker-compose exec -T SERVICE_NAME mongodump --archive > db.dump
```

#### レストア
```
docker-compose exec -T SERVICE_NAME mongorestore --archive < db.dump
```

# 参考資料

- [ローカルから直接Dockerのデータベースを操作する - Qiita](https://qiita.com/mgmgmogumi/items/119e1e26fe44955c705e), Online; accessed 20–Feb–2021.
- [How to restore a PostgreSQL database using Docker](https://devopsheaven.com/postgresql/psql/databases/docker/backup/restore/2017/09/10/restore-postgresql-database-using-docker.html), Online; accessed 20–Feb–2021.
- [🐳 mongodump and mongorestore with Docker - DEV Community](https://dev.to/mkubdev/mongodump-and-mongorestore-with-docker-39m7), Online; accessed 20–Feb–2021.
【heroku】2回目以降のデプロイ

いつもコマンドを忘れるので、備忘録。

```
 % git push heroku master
```

##注意

pullを忘れず。しないとデプロイしても反映されません。
プルと読みます。リモートリポジトリの変更をローカルリポジトリに取り込む操作のことを言います。
docker-compose エラー - Couldn't connect to Docker daemon

# docker-compose エラー - Couldn't connect to Docker daemon

# 環境
OS: Ubuntu 20.04
Kernel: 5.8.0-43-generic
docker-compose version 1.25.5, build unknown

# 問題
久しぶりに Docker を使おうという折、`docker-compose build` を実行したときに、以下のエラーが返ってきた。

```
$ docker-compose build
ERROR: Couldn't connect to Docker daemon - you might need to run `docker-machine start default`.
```
`docker-compose up` を実行しても一緒。

```
$ docker-compose up
ERROR: Couldn't connect to Docker daemon - you might need to run `docker-machine start default`.
```

エラーメッセージで検索して出てきたエントリーは以下の二件。しかし解決には至らず。
https://qiita.com/munimuni/items/57c48bc1287aef285c75
https://qiita.com/yoskhdia/items/a769b9d05657e4798203

# 解決
結論から言うと、sudo してなかっただけでした。 **sudo したらなんの問題もなくうごきました。** 忘れてましたが、そういえば必要でした。

```
$ sudo docker-compose build
Building mysql
Step 1/4 : FROM mysql
latest: Pulling from library/mysql
... 略
```

トラブルシュートに苦戦する自分に酔いしれ始めたころに気づいただけに、それはもう恥ずかしい気持ちでいっぱいです。難しいエラーメッセージを検索してウンウン悩む前に確認しましょう。sudo してますか？

## 言い訳
`permission deny! dame!` とか言ってくれればすぐ気づけたんですけどね。いや、言い訳ですけど。

# 後記
いやいや、そんなバカな。以前から sudo なんてしてたっけ？と思い出して sudo 付けずにコマンドを実行する方法を振り返ると。以下のコマンドで、グループ「docker」に追加され、sudo 無しで docker系のコマンドが実行できるようになるはずでした。

```
sudo usermod -aG docker ORENONAMAE
```

しかし、そもそも /etc/group の中に dockerグループが居ません。今の環境はどうやって docker をインストールしたか忘れてしまった（snap install docker だったかな、、、）ので、

- 公式（https://docs.docker.com/engine/install/ubuntu/ ）に従って再インストール
- `sudo usermod -aG docker ORENONAMAE`
- PC再起動

という作業を経て、無事に sudo いらずでコマンドを実行できるようになりました。 docker をインストールした過程によっては、私と同じ目に合う方も居るかもしれません。
LPC1114のMbedでの温度,STTS751で温度表示(AQM0802A)(ハードは、ichigojam)


x 愛用していたSTTS751の入手が難しくなったので代用品は、S-5851A。(おもにアドレスの違い)

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

```c++

#include "mbed.h"
#include <stdio.h>

 
#define ADDR        (0x39<<1)   //  address
#define ADDR_LCD    (0x7C)      //  address


//I2C i2c(I2C_SDA, I2C_SCL); //767
I2C i2c(dp5, dp27); //1114

DigitalOut myled(LED1); //767 or 1114
//DigitalOut beep1(dp25); //1114
 

//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX);     //767
Serial pc(dp16, dp15); // tx, rx 1114

 
char    TempCelsiusDisplay[] = "+abc.d C";
int     tempval;
char    data_read[2];
char    cmd[2]={0,0};
int     ii; //ループカウンター
int     p_val; //戻り値

char INIT_com[]={0x0,0x38,
0x0,0x39,
0x0,0x4,
0x0,0x14,
0x0,0x70,
0x0,0x56,
0x0,0x6C,
0x0,0x38,
0x0,0xC,
0x0,0x1,
0x40,0x41,0x99,0x99};

char INIT_cls[]={0x0,0x1};

int main()
{
 
    for(ii=0;ii<10;ii++){
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }//for

    //液晶の初期化
    for(ii=0;ii<11;ii++){
        //pc.printf("%x %x \n\r",INIT_com[ii*2],INIT_com[(ii*2)+1]); //debug     
        p_val = i2c.write(ADDR_LCD, &INIT_com[ii*2], 2);
    } //for
 
    while (1) {
        //液晶のクリア
        //pc.printf("INIT_cls:");
        p_val = i2c.write(ADDR_LCD,INIT_cls,2);
        
        // Read temperature register
        i2c.read(ADDR, data_read,1,false);
 
        // Calculate temperature value in Celcius
        tempval =  data_read[0];

        // Integer part
      //TempCelsiusDisplay[0] = '+';
        TempCelsiusDisplay[1] =  (tempval / 100)       + '0';
        TempCelsiusDisplay[2] = ((tempval % 100) / 10) + '0';
        TempCelsiusDisplay[3] = ((tempval % 100) % 10) + '0';
      //TempCelsiusDisplay[4] = '.';
        TempCelsiusDisplay[5] = '0';
 
        // Display result
        pc.printf("temp = %s\n\r", TempCelsiusDisplay);
        //myled = !myled;
        cmd[0] = '@';
        cmd[1] = (tempval/10)+'0';
        p_val = i2c.write(ADDR_LCD, cmd ,2);
        cmd[1] = (tempval%10)+'0';
        p_val = i2c.write(ADDR_LCD, cmd ,2);
        
        wait_ms(1000);
    }//while
 
}//main
 

```

![STTS751_i2c_lcd_031_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1be69fc6-4dc1-8e14-8fff-bcd352d0a494.jpeg)
NILFS2でも Lifetime writesを知りたいよね？

# ext4は tune2fs(8)で lifetime writesを教えてくれるが、、、
<pre>
$ sudo tune2fs -l /dev/sda1 | grep ^Lifetime
Lifetime writes:          184 MB
</pre>
残念ながら nilfs-tune(8)はそのものズバリの出力をしてくれない。

# nilfs-tuneの出力をいじってみよう。
Last sequence#がセグメント単位での最新の書き込み番号らしい。
<pre>
$ sudo nilfs-tune -l /dev/dm-0 | grep '^Last sequence #:' | awk '{print $4}'
4927
$ sudo nilfs-tune -l /dev/dm-0 | grep '^Block size:' | awk '{print $3}'
4096
$ sudo nilfs-tune -l /dev/dm-0 | grep '^# of blocks per segment:' | awk '{print $6}'
2048
</pre>
4927*4096*2048 (bytes) = 38.4 (GB)、ってことだ。

# コマンド一発で出るようにしてみましょうか。
<pre>
$ ./nilfs_lifetimewrites.sh /dev/dm-0
38.4 GB written.
</pre>

# スクリプトはこちら。
<pre>
#!/bin/sh
TMPDIR=/tmp
TMPFILE=$TMPDIR/tmp-nilfstune.txt

if [ $# -lt 1 ]; then
  echo usage: $0 device-name
  exit 255
fi

sudo nilfs-tune -l $1 >$TMPFILE
if [ $? -ne 0 ]; then
  echo nilfs-tune exited by $?, exiting
  exit -1
fi

LASTSEQ=`grep '^Last sequence #:'         < $TMPFILE | awk '{print $4}'`
BLKSIZE=`grep '^Block size:'              < $TMPFILE | awk '{print $3}'`
BLKASEG=`grep '^# of blocks per segment:' < $TMPFILE | awk '{print $6}'`

TOTALWRITESGB=`echo "scale=1; $LASTSEQ * $BLKSIZE * $BLKASEG /1024 /1024 /1024" | bc`
echo $TOTALWRITESGB GB written.
</pre>
Ansibleで変数・フィルターをコマンドライン1行でテストする方法

やりたいこと
---
Ansibleでgroup_varsなどで定義した変数についてタスクを作るときにフィルターを使おうとすると、テスト時に構文エラーがでたり、思うような結果にならなかったりして、タスクの修正→テストを繰り返すのが面倒くさいことがよくある。
なので、タスクを書く前に簡単にコマンドラインから変数・フィルターの書き方をテストして問題ないことを確認してからタスクを書きたい。

やり方
---
ansibleコマンドで-mオプションでdebugモジュールを指定し、-aオプションで"msg={{ 変数・フィルタ記述 }}"として1行コマンドで変数・フィルター結果を確認する。

実行環境
---

* Red Hat Enterprise Linux 8.3
* ansible 2.9.17
* python 3.6.8

hosts, 変数定義サンプル
---

```yaml:hosts
all:
  hosts:
    APSV01:
    APSV11:
    APSV12:
    DBSV01:
    DBSV02:
```
```yaml:group_vars/all
host_dict:
  APSV01:
    type: ap
    runtime_env: java
    version: 1.8.0_172
  APSV11:
    type: ap
    runtime_env: java
    version: 1.8.0_202
  APSV12:
    type: ap
    runtime_env: java
    version: 1.8.0_202
  DBSV01:
    type: db
    db_engine: PostgreSQL
    version: "11.9"
  DBSV02:
    type: db
    db_engine: MySQL
    version: "5.7"
```
サーバが複数ある１つのシステム環境で、サーバ毎に違うパラメータを与えてタスクを実行するための変数定義というイメージ。
host_varsで定義するという手もあるが、一覧しにくかったり自サーバ以外の情報を変数からとってきたいときに不便だったりするので、group_varsにまとめて定義して運用しているような想定で。
実業務ではもっとぶわーっと書いているんだけど、サンプルということで。

フィルターテスト例
---
ansibleコマンドで実行ホストを指定し、-mオプションでdebugモジュールを呼び出し、-aでdebugモジュールのmsgパラメータにテストしたい変数・フィルター等を指定する。

まずは単純な例で

```shell:コマンド例：host_dictからplaybook実行中ホストに対応する内容を取得
ansible APSV01 -m debug -a "msg={{ host_dict[inventory_hostname] }}"
```
```:結果
APSV01 | SUCCESS => {
    "msg": {
        "runtime_env": "java",
        "type": "ap",
        "version": "1.8.0_172"
    }
}
```
次は、何か特定条件にマッチするリストを取り扱いたい場合。

```shell:コマンド例：host_dictからDBサーバの内容を取得
# dictionaryにdict2itemsフィルターをかけると、第一階層を"key"と"value"に分解したようなdictionaryのリストになる。
ansible localhost -m debug -a "msg={{ host_dict | dict2items |selectattr('value.type', '==', 'db') | list }}"
```
```:結果
localhost | SUCCESS => {
    "msg": [
        {
            "key": "DBSV01",
            "value": {
                "db_engine": "PostgreSQL",
                "type": "db",
                "version": "11.9"
            }
        },
        {
            "key": "DBSV02",
            "value": {
                "db_engine": "MySQL",
                "type": "db",
                "version": "5.7"
            }
        }
    ]
}
```

dictionary全体から、情報を検索・集約するような例

```shell:コマンド例：host_dictにあるJavaのバージョン一覧のリストを取得
# dictionaryをループ処理するためにdict2itemsフィルターをかける
# runtime_envで検索するので、存在確認をしてからruntime_env == 'java'のものを抽出する
# mapでバージョン情報のリストを作り、uniqueで重複排除する
ansible localhost -m debug -a "msg={{ host_dict | dict2items |
 selectattr('value.runtime_env', 'defined') | selectattr('value.runtime_env', '==', 'java') |
 map(attribute='value.version')| unique | list }}"
```
```:結果
localhost | SUCCESS => {
    "msg": [
        "1.8.0_172",
        "1.8.0_202"
    ]
}
```

こんな感じで、フィルターを実際に実行して期待している結果が出ることを確認してからwith_itemsにコピペしてタスクをつくると、テストが楽になるよ。
QuillエディターにHTMLをセットする方法

記事を編集する機能など、HTMLをQuillエディターにセットしたい場合があります。以下のようにすればできます。

```
this.quillEditor.clipboard.dangerouslyPasteHTML(0, text)
```

参考：[Can't find the "setHTML" function. #1449](https://github.com/quilljs/quill/issues/1449)
JavaScript 新しい演算子 nullish??とoptional?. サンプルコード付きで書いてみた 


##Optional Chaining(?.)##


use1の値がnullかundefinedではない場合はnameを返します。
外部APIから情報を持ってくるときは、nameというプロパティが漏れている可能性も考えられます。
そこでuser1にnameは入っていますよと事前に明示し、入っていた場合そのnameプロパティを表示するようにする必要があります。
```Optional Chaining(?.)```を使用しない場合は、
以下のようにuser1が存在し、かつuser1の中にnameというプロパティも存在すると定義します。

```
const user1 = {name:"suzuki"}
const user1name = user1 && user1.name
console.log(user1name)   //suzuki
```
逆に```Optional Chaining(?.)```を使用する場合は、

```
const user1 = {name:"suzuki"}
const user1nameOptional = user1?.name
console.log(user1nameOptional)   //suzuki
//nameがある場合は「suzuki」が出力される
//nameがない場合はエラーにならず、undefinedが出力される
```
なお、``Optional Chaining(?.)``は何個でも使用可能です。


##Nullish coalescing Operator##

nullishはuser1.nameがnullかundefinedの場合、右辺を返します。user1.nameに値が入っていた場合は左辺を返します。
そのままnullかundefinedで返したくない場合に使えます。

```
const user1 = {name:"suzuki"}
const user1name = user1?.name ?? 'someone'
console.log(user1name)   //suzuki

const user1age = user1.age ?? 'private'
console.log(user1age)
//user1はageプロパティは持っていないので右辺の'private'出力される
```

またfalsyな値(0,'',null,undefined,falseなど)についてもnullishではスルーされずに出力されます。

```
const user1 = {name:"suzuki",age:0}
const user1age = user1?.name
const user1ageNullish = user1?.age ?? 'private'
const user1ageLogical = user1?.age || 'private'

console.log(user1ageNullish)　//null,undefinedではないので０が出力される
console.log(user1ageLogical) // ageプロパティは持っていないのでprivateが出力される

````

||では 0 や空文字もスル-されてしまうのに対し、
nullishではスルーされず返されます。

　
　


以下はサンプルです。
console.logで出力される値は最後に書いていますのでどのような出力になるか考えてみてください。

```
const user1 = {name:"suzuki"}
const user2 = {name:""}
const user3 = {name:false}
const user4 = {name:0}
const user5 ={}

const name1 = user1?.name
const name2 = user2?.name || 'someone'
const name2nullish = user2?.name ?? 'someone'
const name3 = user3?.name  || 'someome'
const name3nullish = user3?.name ?? 'someone'
const name4 = user4?.name || 'someone'
const name4nullish = user4?.name ?? 'someone'
const name4optional = user4?.name
const name5 = user5?.name || 'someone'
const name5nullish = user5.name ?? 'someone'
const name5optional = user5?.name
```
```
console.log(name1) // suzuki
console.log(name2) //someone
console.log(name2nullish) //空文字
console.log(name3)  //someone
console.log(name3nullish)  //false
console.log(name4)  //someone
console.log(name4nullish)  //0
console.log(name4optional) //0
console.log(name5)  //someone
console.log(name5nullish)   //someone
console.log(name5optional)  //undefined
```
Python Google翻訳からスクレイピング翻訳してExcelに保存

#0. はじめに

以前[YouTube](https://www.youtube.com/watch?v=OOMdCFLg1vY)で紹介した仕事や課題のさぼり方について解説する。エクセルに羅列された日本語を英語に翻訳するプログラムだ。WebDriverを用いてgoogle翻訳からスクレイピングで翻訳する。動作環境はChromで行う。

#1. 必要ライブラリ

`openpyxl`、`selenium`、`time`を用いる。`openpyxl`と`selenium`は予めpip等でインストールする必要がある。又、ブラウザ操作をするためChromDriverをダウンロードしpathを通しておく必要がある。

```powershell
python -m pip install openpyxl
python -m pip install selenium
```

```python
import openpyxl as excel
from selenium import webdriver
import time
```

#2. Excelファイルの読み込みとDriverの設定

次にエクセルファイルを指定する。

```python
book = excel.load_workbook("<Excelファイルのパス>", data_only=True)
sheet = book.worksheets[0]     #データのsheetを選択
driver = webdriver.Chrome()     #DriverをChromに設定
count = 1     #セルの行指定
```

#3. データの読み込みとスクレイピングによる翻訳

先ほどを見込んだファイルからセルのデータを抽出し、Google翻訳で英訳する。返ってきた英語を受け取りExcelに書き込む。

```python
while True:
    cell = sheet["A" + str(count)]     #cellの指定
    if cell.value:     #もしcellにデータがあれば
        url = "https://translate.google.co.jp/?hl=ja&sl=ja&tl=en&text={}&op=translate".format(cell.value)     #Google翻訳に日本語を入力済みのURLを作成
        driver.get(url)     #上記URLを開く
        time.sleep(1)     #サーバ負荷軽減
        ja = driver.find_element_by_css_selector("span[jsname='W297wb']")
        sheet["B" + str(count)] = ja.text
        count += 1
    else:
        break     #cellにデータがなければループを抜ける
```

#4. Excelファイルを保存し実行

最後にExcelファイルを保存する。
実際にデバッグしてみるとChromが立ち上がり順次翻訳されるだろう。デバッグする際はExcelファイルは閉じてデバッグする。

```python
book.save("<Excelファイルのパス>")
```

#5. まとめ
課題をさぼれるが何の役にも立たない。課題はしっかりやって身に着けるべき。
AWS AMIの作成

#AMI（Amazon Machine Image）とは？
「AMIは、仮想サーバーであるインスタンスの起動に必要な情報を保存している」

AMIの情報に含まれるもの
**・インスタンのOS
・アーキテクチャ
・仮想化方式
・EBSスナップショット
・ブロックデバイスのマッピング　等**

##AMI作成
①インスタンス選択
②AMIを作成するインスタンス選択
③アクションクリック
④イメージとテンプレートクリック
⑤イメージ作成クリック

![スクリーンショット 2021-02-20 14.50.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/5a6ed8a0-e21a-6132-a08a-de7f1aeb69f2.png)


⑥項目を入力し作成する

![スクリーンショット 2021-02-20 14.51.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/c0bffcea-65ad-7394-6ed2-6eed6fea43ec.png)


###作成したAMIで起動する場合
①AMI選択
②起動クリック
![スクリーンショット 2021-02-20 14.56.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/14aecddd-a523-c1ea-c891-3439abb30e9a.png)
操られる民主主義-デジタル・テクノロジーはいかにして社会を破壊するか-

# 書籍情報
- 操られる民主主義-デジタル・テクノロジーはいかにして社会を破壊するか-
- ジェイミー・バートレット
- 草思社

# 読んだ目的
- 近年のビッグデータ・AIの危惧について技術寄りの目線で見識を深めたかった。

# 学んだこと・感じたこと
- 何百万のユーザーを対象とするユーザーを相手に日々テスト
    - 背景・色・フォント・音響など多岐にわたる
    - ユーザーのクリックやUXを最大化する
    - FBはオートプレイ・無限スクロール・時系列順のタイムラインを実装することで、ユーザーの関心を持続させた。
- パノプティコン
    - 誰かに監視されていると刷り込むことにより行動を抑制する手法
- アルゴリズムの不公平
    - 犯罪率をベースにした警官の配置をすると、貧民街ばかりに配置される
    - 富裕層と貧民街の不公平となる。
    - アルゴリズムは冷淡な判断を下すことから、アルゴリズム設計者の偏見が介在しやすい
- サイバー犯罪に用いることのできるソフトの入手性が向上し、セキュリティーリスクが高まっている
    - IoTソフトAutoSplout、
    - フューチャー・クライム：サイバー犯罪からの完全防衛マニュアル（青土社）

# 今から何をするか
- ユーザーテストは実務で行いたいのでFWとしてTODOリストへ追加する
- 本文中に気になる論文があったので、読む（英語なので大変そう）
【Rails】アソシエーションで紐づいたレコードを自動保存

## 概要
中級者は知ってて当然なので、初心者向けです🔰

アソシエーションで関連付けられたモデルを保存する時に、片方のレコードに外部キーが設定されているせいで、「保存処理を2回に分けなきゃ」と思ったことはないですか？（保存するまでidが確定しないので）

そんなときどうするのというお話です

※ 自分もかつて良くないコードを書いていたので、同じような初心者の参考になってもらえれば幸いです


## 具体例
例えば本のモデル（Book）と著者のモデル（Author）があると想定します
（`book has_many authors`の関係）

**Bookモデル📕**

| カラム| 型 | 補足 |
|:-:|:-:|:-:|
|id  | integer  |   |
|title | string  |   |

**Authorモデル:man_tone1:**

| カラム| 型 | 補足 |
|:-:|:-:|:-:|
|id  | integer  |   |
|book_id  | integer  | 外部キー  |
|name | string  |   |


このとき初心者がやりがちなのが以下の書き方

```ruby:books_controller
# createアクション

book = Book.new(book_params)
if book.save
  author = Author.new(book_id: book.id, name: author_params[:name])
    if author.save
      # 保存後の処理
    else
      # 失敗時の処理
    end
else
  # 失敗時の処理
end

# book_params, author_paramsの定義は省略してます
```
これだと以下のようにデメリットが大きいです

* if文の階層が深くなる
* bookだけ保存されてauthorが保存されない場合が出てしまう

早期リターンやtransactionでこれらを回避することもできますが、わざわざそんな面倒なことをしなくて済む方法があるのです✨（以下）

```ruby:books_controller
# createアクション

book = Book.new(book_params)
author = book.build_author(author_params)
return ['保存成功時の処理'] if book.save

# 失敗時の処理
```
この場合`book`の保存が成功した場合は`author`の保存も保証してくれます（片方だけ保存されることはない）

当然外部キーは関連付けられて保存されます
すっきりしていて見やすく、ファットコントローラ対策にもなります😍
※ 早期リターンでリファクタもしてます

モデルの関係性が、`belongs_to`と`has_many`とで書き方が変わるので注意が必要です（以下参照）

## `belongs_to`で関連付けられたモデルのbuild
```ruby
book.build_author
```
has_oneでの関連付けもこちらになります

## `has_many`で関連付けられたモデルのbuild

```ruby
author.books.build
```

***  

* １つだけ紐づくモデル
=> `build_[モデル名の単数形]`

* 複数紐づくモデル
=> `[モデル名の複数形].build`

と覚えとけば良さそうです😇
（`build_複数形`にするとインスタンスが複数buildされるイメージがつくからこのように分けたんですかね🤔）

## 参考
* [`belongs_to`で関連付けられたモデルのbuild](https://railsguides.jp/association_basics.html#has-one%E3%81%A7%E8%BF%BD%E5%8A%A0%E3%81%95%E3%82%8C%E3%82%8B%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89-build-association-attributes)
* [`has_many`で関連付けられたモデルのbuild](https://railsguides.jp/association_basics.html#has-many%E3%81%A7%E8%BF%BD%E5%8A%A0%E3%81%95%E3%82%8C%E3%82%8B%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89-collection-build-attributes)
Chromeの検証ツールでXHR通信の中身を覗いてみる

# はじめに

ブラウザの検証ツールには便利な機能がたくさんありますが、今回はその中でもNetworkタブのXHR通信に絞って、
どんなことがわかるのかについて、解説したいと思います。

# Chrome検証ツールとは

WebページのHTMLやCSSの中身や、ブラウザがどんな通信をしているかを確認することができます。(もちろん他にも機能はあります)

MacOSの場合は、 command + option + i で開くことができます。
あるいは右クリック → 検証 でも同様に開けます。

# XHR通信の中身を覗いてみる

Qiitaの通信内容をchrome検証ツールを使って見てみます。

![graphql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/884609/76392b49-05b5-2aed-78cb-8f912249fdd2.png)

Nameタブのgraphqlをクリックすると、添付画像右のような情報が表示されます。

リクエスト先のURLやHTTPメソッド、HTTPステータス等がわかります。

Qiitaは一部の通信にGraphQLを採用していたんですね。

Headersタブを下にスクロールすると、送ったリクエストの中身も確認することができます。

![request-payload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/884609/4b2cb501-9b2c-0758-f3a5-e78ee11f3cae.png)

GraphQLのQueryをargument付きで投げていることがわかります。

投げているQueryも確認することができます。

```graphql
query getUserPaginatedArticles($urlName: String!, $page: Int!, $per: Int!) {
  user(urlName: $urlName) {
    paginatedArticles(page: $page, per: $per) {
      ...UserPaginatedArticlesResult
      __typename
    }
    __typename
  }
}

fragment UserPaginatedArticlesResult on ArticlePage {
  items {
    createdAt
    encryptedId
    isLikedByViewer
    isPublic
    likesCount
    linkUrl
    title
    uuid
    author {
        ... on User {
          isUser
        urlName
        __typename
      }
      ... on Organization {
        isUser
        urlName
        __typename
      }
      __typename
    }
    tags {
        urlName
      name
      __typename
    }
    __typename
    }
    pageData {
      currentPage
    isFirstPage
    isLastPage
    nextPage
    prevPage
    totalPages
    __typename
  }
  __typename
}
```

レスポンスの中身は、PreviewタブかResponseタブで確認することができます。

![response.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/884609/d4c198a6-73ce-5bb5-4d5f-4cc988e0191c.png)



# 他のサイトのXHR通信の中身を覗いてみる

以下の添付画像をご覧ください。

![example1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/884609/2ab3f7e3-2f18-fe43-c724-2dd89f0b7a01.png)

access-tokenやclientがResponseHeaderに含まれているあたり、

「認証はToken方式で」
「おそらくdevise_token_authを使っている」

のではないかと思いますが、Previewも見てみましょう。(レスポンスの一部を切り取っています)

```json
{
  "user": {
    "id": 99999999,
    "provider": "email",
    "uid": "sample@gmail.com",
    "allow_password_change": false,
    "email": "sample@gmail.com",
    "created_at": "2021-02-20T00:00:00.000+09:00",
    "updated_at": "2021-02-20T00:00:00.000+09:00",
    "deleted_at": null,
    "name": "サンプル太郎",
  }
}
```

devise_token_authを導入していると用いられる「provider」や「uid」があったため、おそらく仮説は当たっていると思います。
また、deleted_atがあるので、論理削除を実現するGemである「acts_as_paranoid」も導入されているのではないかなと思いました。

このように、Network通信の中身を覗くことで、そのサイトでどんな技術を使っているか、という情報を得られます。

# 実務ではどう使うのか

主に、

・入力した値が意図した通り送信されているか
・意図した値が返ってきているか

という用途で使うことが多いです。

## 入力した値が意図した通り送信されているか

フォームに入力された値をjavascriptでよしなに加工して送信する、といった処理がある場合、値を加工する部分でバグがあり意図した挙動になっていないことがありますが、そういった挙動の確認をするために検証ツールを使うことがあります。

## 意図した値が返ってきているか

APIの戻り値をjavaScriptで加工してで表示するというケースはよくあると思いますが、フロント側で欲しい値がなぜか返ってきていない、というケースで、PreviewタブやResponseタブの値を見て確認するというケースがよくあります。

# まとめ

検証ツール便利すぎてこれ無しだと生きていけません。
JavaScriptで関数型言語を作ろう(3)

[前記事](https://qiita.com/hoge1e3/items/c4d4e9fcab85ccb485f2)では、

~~~
3.add(2).add(10)
~~~

という式を解析し、式をオブジェクトで表現する「構文解析」について見てきました。

ところで、いまさらですが、普通「式」といったら、

~~~
3+2+10
~~~

と書くのが一般的なのに、なんで一般的でない書き方をしているのか、というと、

- 作るのが（＆解説するのが）面倒
- この式の解析の仕方は他の方も解説されている

という身も蓋もない理由です。

一般的な「式」の解析方法については、上の検索欄で「構文解析」あるいは「構文解析 JavaScript」などで検索していただくとひっかかると思います。

本連載では、式の解析の仕組みはなるべく単純化して、その先のトピック、具体的に言うと型のチェックや、関数型言語ならではの機能を詳しく見てみたいと考えています。

## 3.add(2)はどう動くのか？

そもそも、`3.add(2)`という式はJavaScriptでは動作しません。これを動かすには何らかの変換が必要になります。今回はまず、この変換を支援する「ランタイムライブラリ」について見ていきます。まず、`lang/runtime.ts`を開いてみましょう。

~~~lang/runtime.ts
interface INum {
    value:number,
    add:(b:INum)=>INum,
};
export const Num=(value:number):INum=>({
    value,
    add(b:INum):INum {
        return Num(value+b.value);
    },
});
~~~

これを使ってちょっと遊んでみます。

[TypeScript playground](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgJIDkCuBbZBvAKGWOQDc4AbTCALhBwCNoAaIkuAEw5oAoGaMOAJQBeAHyDsrAL4BuAggD2IAM5hkWbCJ7kqtetiZQhAzeJ6ESZStVZXOHPqeHPclqySgQwmKCA04OjYQANQMAHS61ELyVtIyMQQKyiqKFBDhFIoA5jwB2DwAzELhDjyaPABMQkLIiUA)を開いてみましょう。このリンクから開くと、すでにプログラムが書かれていると思います。

Runを押して実行してみると

~~~
LOG: {
  "value": 5
} 
~~~

という結果が出力されます。[^1]
[^1]: 本当は[LOG]って出てますがなぜか消えてしまったので［］は取っています

最後に書いてある式`Num(3).add(Num(2))` で、計算を行っています。

- `INum`型のオブジェクトは，次のメンバをもちます
    - `value`（JavaScriptの数値）
    - `add`（他のINum型のオブジェクトをもらって，足し算した結果をINumオブジェクトで返す関数）
- 関数`Num`は，JavaScriptの数値`n`からINum型のオブジェクトを生成します[^2]．

[^2]: `class`使った方がシンプルなのになんで使わないの？　と思った方へ．この後の実装の都合で，こちらのほうがやりやすいからです．詳しくは今後お話しますが，JSに詳しい方向けに先回りしておくと「`object.f(a)`と`(object.f)(a)`が同じ挙動になるようにしたいから」です．

つまり，今連載で扱う言語……言語になんか名前あったほうがいいですよね．リポジトリ名からとって「tinyfunc」とでもしましょうか．
tinyfuncで`3.add(2)`と書かれたプログラムがあったら，`Num(3).add(Num(2))`というJavaScript[^3]を生成してあげればいい，ということになります．

というわけで，[次回](https://qiita.com/hoge1e3/items/544efc02eac3718b33b4)はそのJavaScriptコードを頑張って生成してみます．

# 理解度チェック

- `INum`オブジェクトに，引き算をする`sub`，掛け算をする`mul`，割り算をする`div`を追加してみて，次の計算を`INum`オブジェクトを使って行ってみましょう．
   - 20+30-5
   - 50-10-20
   - 50-(10-20)
   - 20*4+30*2
   - 20*(4+30)*2
   - 100/10/2
   - 100/(10/2)

[^3]: `Num(3).add(Num(2))`はTypeScript上で書いたものであって，JavaScriptで動くのか？　と思った方は，PlayGround上の右側で「JS」タブを選んで，JavaScriptに変換されたコードを確認してみましょう．同じコードが出力されていると思います．
STM32F767のMbedでの温度,STTS751で温度表示(AQM0802A)


x 愛用していたSTTS751の入手が難しくなったので代用品は、S-5851A。(おもにアドレスの違い)

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

```c++

#include "mbed.h"
#include <stdio.h>

 
#define ADDR        (0x39<<1)   //  address
#define ADDR_LCD    (0x7C)      //  address


I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114

DigitalOut myled(LED1); //767 or 1114
//DigitalOut beep1(dp25); //1114
 


//Serial pc(USBTX, USBRX); // tx, rx
Serial pc(SERIAL_TX, SERIAL_RX);     //767
//Serial pc(dp16, dp15); // tx, rx

 
char    TempCelsiusDisplay[] = "+abc.d C";
int     tempval;
char    data_read[2];
char    cmd[2]={0,0};
int     ii; //ループカウンター
int     p_val; //戻り値

char INIT_com[]={0x0,0x38,
0x0,0x39,
0x0,0x4,
0x0,0x14,
0x0,0x70,
0x0,0x56,
0x0,0x6C,
0x0,0x38,
0x0,0xC,
0x0,0x1,
0x40,0x41,0x99,0x99};

char INIT_cls[]={0x0,0x1};

int main()
{
 
    for(ii=0;ii<10;ii++){
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }//for

    //液晶の初期化
    for(ii=0;ii<11;ii++){
        //pc.printf("%x %x \n\r",INIT_com[ii*2],INIT_com[(ii*2)+1]); //debug     
        p_val = i2c.write(ADDR_LCD, &INIT_com[ii*2], 2);
    } //for
 
    while (1) {
        //液晶のクリア
        //pc.printf("INIT_cls:");
        p_val = i2c.write(ADDR_LCD,INIT_cls,2);
        
        // Read temperature register
        i2c.read(ADDR, data_read,1,false);
 
        // Calculate temperature value in Celcius
        tempval =  data_read[0];

        // Integer part
      //TempCelsiusDisplay[0] = '+';
        TempCelsiusDisplay[1] =  (tempval / 100)       + '0';
        TempCelsiusDisplay[2] = ((tempval % 100) / 10) + '0';
        TempCelsiusDisplay[3] = ((tempval % 100) % 10) + '0';
      //TempCelsiusDisplay[4] = '.';
        TempCelsiusDisplay[5] = '0';
 
        // Display result
        pc.printf("temp = %s\n\r", TempCelsiusDisplay);
        //myled = !myled;
        cmd[0] = '@';
        cmd[1] = (tempval/10)+'0';
        p_val = i2c.write(ADDR_LCD, cmd ,2);
        cmd[1] = (tempval%10)+'0';
        p_val = i2c.write(ADDR_LCD, cmd ,2);
        
        wait_ms(1000);
    }//while
 
}//main
 



```

![STTS751_i2c_lcd_767_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c9e814b8-a694-c8ee-04e9-ed3b81f2ed44.jpeg)
【Python】2次元配列で隣接している座標を求める その１【NumPy】

# Python 勉強中です
時間があるので Python の勉強をしています。NumPyってのが、いい感じにややこしくて、おもしろいなぁ。というレベル感の記事です。Google Colaboratory で動作させながら記事を書いてます。

数学的な知見があまりないので「Numpy 隣接」などで検索してもそれじゃない感じの概念の解説しかみつけられなかったので、自分で考えてみたので残しておこうと思います。
ゲーム系のプログラマーでもないし座標計算？な、ゆるい記事です。

まずは2次元配列を作成して表示する。

```python
import numpy as np

l = np.arange(15).reshape(3,5)
print(l)
# [[ 0  1  2  3  4]
#  [ 5  6  7  8  9]
#  [10 11 12 13 14]]
```
これだけで簡単にできるのはなかなか嬉しい。Python, NumPy が人気なのも納得。

まずは`6`に隣接する`1,5,7,11`を求めていきます。
`6`の座標は`(1,1)`です。上下左右とはそれぞれ`(-1,0)(+1,0)(0,-1)(0,+1)`を座標と演算して`(0,1)(2,1)(1,0)(1,2)`ですね。
ファーストステップは点pから４つの座標がわかるところまで。可読性がいいかなと思い、座標はタプルを利用します。

```python
p = (1,1)
print( l[p], l[(0,1)], l[(2,1)], l[(1,0)], l[(1,2)] )
# 6 1 11 5 7
```

## 最初の呪文「ブロードキャスト！」

ここで早速、NumPyさんの呪文「ブロードキャスト」が活躍しそうです。

細かい解説はしませんが、要素が一つのものと複数のものとを演算するといい感じにしてくれる呪文だと思っています。
そもそも`(1,1)+(0,1)`で`(1,2)`を簡単に求めてくれるのも NumPyさんのおかげ。以下にコードを

```python
print( p + (0,1) )
# (1, 1, 0, 1) # 通常タプル同士の + はただ連結される

print( p + np.array((0,1)) )
# [1 2] # どちらかがNumPy化？しているとそれぞれ足してくれる。不思議！

# Up Right Down Left # 時計回り
u_r_d_l = [(-1,0), (0,1), (1,0), (0,-1)]

print( p + np.array(u_r_d_l) )
# [[0 1]
#  [1 2]
#  [2 1]
#  [1 0]]　# アメージング！
```
for文っぽいループなしに４つの座標の演算結果をゲットすることができました。コメントでNumPy化という謎の言葉を使いましたが、みんなどんな感じで呼んでますか？うちらはこうだな、などなどありましたらぜひコメントください。
おもしろいと感じたのは「+」の前後どちらかだけでもうまくいくところですね。

ちなみに座標部分はタプル`(1,1)`で記述していますが、リスト`[1,1]`でも問題ないはずです。座標を扱う際にタプル`(a,b)`に特別な機能があるわけではない（と思う）。同じように Python 勉強中の方がいたら混乱するかもしれないので、念のため言及しておきます。断言してないのはまだ僕も勉強中で書いている記事なので。

また演算結果はタプルではなくなってしまいますが`[*map(tuple, xxx)]`で、xxx に入れるとタプルを持ったリストに変換できます。わざわざタプルにする必要がない場合も、print()で表示したときに見やすいかもなって時などに、この方法を利用していきます。
map関数？はっ？て人も、このコードは`[[],[],...]`を`[(),(),...]`に変換してるんだなぐらいで考えてればOKです。（この記事では map関数の説明をする気がないです。。。ごめんなさい。ちなみにどなたか詳しい方で`list(map(...))`と`[*map(...)]`の違いってあるのか、ご教授いただけたら嬉しいです。）

```python
# [[],[],...] → [(),(),...] へ変換
print( [*map(tuple, p + np.array(u_r_d_l)] )
# [(0, 1), (1, 2), (2, 1), (1, 0)]
```
これでかんせーい！ではないですね。

今は点p が中心あたりなので大丈夫ですが、これがはじっこにずれると範囲外の座標を示してしまいます。`(-1,0)`などのマイナス座標は Pythonはうまい具合に後ろから処理してくれますが、`(3,0)`や`(0,5)`はエラーになってしまいます。
次の呪文で、この辺りのケアをしていきたいと思いますが、ここまでのコードをちょっと書き換えて一度、記述しておきます。まぁまぁなことやってるはずなのですが、短くてすごいですね。
2次元配列に壁の概念があって、点p にはじっこが入力されない場合はこれでおしまいですからね。

```python
import numpy as np

l = np.arange(15).reshape(3,5)
p = (1,1)
u_r_d_l = np.array([(-1,0), (0,1), (1,0), (0,-1)])

print( [*map(tuple, p + u_r_d_l] )
# [(0, 1), (1, 2), (2, 1), (1, 0)]
```
思ってたよりこの後が長くなっているので、一度投稿しておきます。 つづく
WindowsアプリでのOAuth連携 メモ

* [ネイティブアプリのOAuth連携 メモ](https://qiita.com/KWS_0901/items/4609171ad129c2cf6c2e) の続き。

* ネイティブアプリをOAuth連携する際には、OAuth PKCE連携が推奨されている。

* アプリは認可サーバーに対して認可リクエストを行い、認可レスポンスを受けとる必要がある。

* その際のWindowsアプリでの認可レスポンスの受信方法についてメモする。

  

## Windowsアプリでの認可レスポンスの受信方法

以下の2手法がある模様。

### WebAuthenticationBroker(Web認証ブローカー)の利用

* UWPアプリ向け。
* OpenID Connectや OAuth などのインターネット経由の認証プロトコルを使う認可サーバーに接続してユーザー認証する (あるいは認可を得る) 際に利用できる機能。
  * 外部ユーザーエージェントを利用する。

```c#
// 認可要求エンドポイント
string startURL = "https://<providerendpoint>?client_id=<clientid>&scope=<scopes>&response_type=token";
// 認可サーバーに登録したリダイレクトURI
string endURL = "http://<appendpoint>";

System.Uri startURI = new System.Uri(startURL);
System.Uri endURI = new System.Uri(endURL);

var webAuthenticationResult = 
        await Windows.Security.Authentication.Web.WebAuthenticationBroker.AuthenticateAsync( 
        Windows.Security.Authentication.Web.WebAuthenticationOptions.None, 
        startURI, 
        endURI);
```

### Loopback Interface Redirection の利用

* 従来のアプリ向け。
* "http://127.0.0.1:{port}/{path} "などのようにローカル・ループバックでHTTPレスポンスを受け取る方式。
  * 例：Windowsではhostsファイルを編集される可能性があるので、localhostより、127.0.0.1を使用することが推奨される。

- **認可サーバー対応**：リダイレクトURIのうちポート番号を可変に扱えるようにする必要がある。
- **アプリ対応**：「SO_EXCLUSIVEADDRUSE」ソケットオプションを設定して、他のアプリが同じソケットにバインドしないようにする必要がある。



## 参考情報

* [Web 認証ブローカー](https://docs.microsoft.com/ja-jp/windows/uwp/security/web-authentication-broker)
* [RFC 8252 - OAuth 2.0 for Native Apps 日本語訳](https://tex2e.github.io/rfc-translater/html/rfc8252.html)
rails db:migrateするとStandardError: An error has occurred, all later migrations canceled:のエラーコード発生

###①内容
####deviseをinstallした後のrails db:migrateをしたところStandardError: An error has occurred, all later migrations canceled:のエラーコード発生。
---
###②結論
####config/database.ymlのencoding: utf8mb4　⇒　utf8にした事で解消。
---
###③詳細
①ログイン機能実施の為、deviseのinstall実行
　　　　　　　　　
②rails g devise user（userモデルを作成）
　　　　　　　　　
③rails db:migrate（マイグレーションの実行）
　　　　　　　　　
④rails db:migrate:statusで確認すると、、、

```rails
 Status   Migration ID    Migration Name
--------------------------------------------------
  down    20210215130947  Devise create users
```

◉ここでUPになっていないことに気付く。

⑤rails db:migrate:resetもNG

⑥調査しconfig/database.ymlのencoding: **utf8mb4　⇒　utf8**にした事で解消。

⑦その後rails db:migrate:reset ⇒　rails db:migrateの順でターミナル実行

⑧rails db:migrate:status

```
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210215130947  Devise create users
```

こちらで解消。

今回も勉強になりました！！

初心者ですが、解消方法などを載せていきます。

間違い等ございましたら、ご指導ご鞭撻の程、よろしくお願いします。
Pardot のプロセスオートメーション (Salesforce Classic) ⇒ 適切なオートメーションツールの選択

１．次のオートメーションツールのうち、プロスペクトを国や商品への関心に基づいてユーザーグループに割り当てるために選択するものはどれですか?
２．次のオートメーションツールのうち、プロスペクトが会社の価格ページを訪問したときに Salesforce の ToDo を作成するために選択するものはどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/7989c2a7-8198-0345-77be-008a4641134e.png)
"100TB"のファイルサーバにあるファイルを断捨離するために(3) ～データ活用検討編～

#はじめに
前回は、ZiDOMA dataでファイルサーバの分析で以下のようなデータが
ZiDOMA dataの画面、CSVファイルから取得できることをご紹介しました。

* 各ディレクトリの使用率やサイズ
* 作成日時、更新日時、最終アクセス日時
* 拡張子
* 所有者

__参考:__
"100TB"のファイルサーバにあるファイルを断捨離するために(2) ～ZiDOMA data編～ 
https://qiita.com/karin_to/items/7e1dab963e0dc0ba2e9b

ZiDOMA dataの画面からデータを確認する場合
https://ari-jp.com/lp/zidoma/report-1.php

今回は、CSVファイルをどのように活用してファイルサーバーの利用者に利用状況を
お知らせするレポートをお届けするか検討した際のことをまとめます。

#CSVファイルの活用方法を検討する
まずは、ZiDOMA dataで出力した後のCSVデータからどのようなデータを作れば、

 * 使用状況
 * ファイルを整理するためのポイント

が提供できるかを考えました。

そのためにも、最初に手作業でディレクトリごとのレポート作成です。
どのようなレポートを作れば、ファイルを断捨離(整理)することにつなげられるのか
考えながらExcelファイルに以下のような項目のデータ集計をしてみました。
最終的にレポートとして採用しなかったものも含めていくつか例として挙げます。

<採用案>

 * ディレクトリの使用量(使用量/上限容量)
 * (ファイル作成日、更新日、アクセス日) 期間ごとのファイル数、サイズ
 * アクセス日時が古く、かつファイルサイズが大きい
 * 拡張子ごとのファイル数、ファイルサイズ

<不採用案>

 * 重複ファイル
 * 旧Office拡張子(.doc, .ppt, .xls)、かつファイルサイズが大きい
 * 50文字以上のファイル名
 * ファイルサイズが大きいもの

私が実際に取り組んだ例としては、
部署ごとに作成しているディレクトリのデータ分析でしたので、
とりあえず試作で3、4部署分を手作業で作成しました。

データの集計自体は、CSVファイルをExcelで開いて、「フィルタ」機能を使って
ほしい条件に絞り込みデータをまとめました。
その後に、データを集計したものをグラフ化するといった具合です。
これらの作業を約2～3週間取り組んでいたと思います。
(もちろん1日ずっとこの作業のみです)

その後は、ファイルサーバーの管理関係者にもレビューしていただいて、
上記のレポートの中からユーザーに提供する内容を決定しました。

#レポートの自動作成への検討
次なる課題となったのは、レポートを作成する手間と工数でした。
あと、レポートを作成する人も確保する必要が出てきてしまいます。
たとえ年に1回作成するにしてもレポートが出来上がってユーザーにお見せするために
膨大な時間がかかることになります。
そして、その頃にはデータとしてもう古くなっている…

となると、次はこのレポートを自動で作成できないか？と考えて
どうやったら自動化できるか…と検討して実際に使ってみたのが

__PythonのPandasライブラリ__

でした。

このライブラリのおかげでほぼプログラミング経験が初心者の私でも比較的簡単に作れてしまいました。
そのため、次回は実際にPythonで使ったPandasをご紹介していきたいと思います。

参考：初心者レベル
　Pythonの基礎の書き方を社内勉強会で週1回1～2h、約2か月間取り組んだことあり

#関連記事:
"100TB"のファイルサーバにあるファイルを断捨離するために(1)
https://qiita.com/karin_to/items/8a375f41de0e4f754cfb

"100TB"のファイルサーバにあるファイルを断捨離するために(2)
https://qiita.com/karin_to/items/7e1dab963e0dc0ba2e9b
macOS(Big Sur)でHomebrewが起動しない！

##はじめに
macOS（Big Sur）で、
Homebrewのバージョンを確認した際に、エラーが出てしまいました。
その対処法をご紹介します。

##エラー画面
`brew -v`　を実行した際に出たエラー

```
~ % brew -v
Traceback (most recent call last):
    11: from /usr/local/Homebrew/Library/Homebrew/brew.rb:23:in `<main>'
    10: from /usr/local/Homebrew/Library/Homebrew/brew.rb:23:in `require_relative'
     9: from /usr/local/Homebrew/Library/Homebrew/global.rb:29:in `<top (required)>'
     8: from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
     7: from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
     6: from /usr/local/Homebrew/Library/Homebrew/os.rb:3:in `<top (required)>'
     5: from /usr/local/Homebrew/Library/Homebrew/os.rb:21:in `<module:OS>'
     4: from /usr/local/Homebrew/Library/Homebrew/os/mac.rb:58:in `prerelease?'
     3: from /usr/local/Homebrew/Library/Homebrew/os/mac.rb:24:in `version'
     2: from /usr/local/Homebrew/Library/Homebrew/os/mac.rb:24:in `new'
     1: from /usr/local/Homebrew/Library/Homebrew/os/mac/version.rb:26:in `initialize'
/usr/local/Homebrew/Library/Homebrew/version.rb:368:in `initialize': Version value must be a string; got a NilClass () (TypeError)
```
##解決方法
ググって見ると、このエラーの[解決方法](https://stackoverflow.com/questions/64821648/homebrew-fails-on-macos-big-sur)が stack overflow に載っていました。

指示通り、`brew upgrade`を実行するとエラーが消えます。

```
% brew upgrade
==> Upgrading 4 outdated packages:
pyenv 1.2.16 -> 1.2.23
pkg-config 0.29.2 -> 0.29.2_3
readline 8.0.1 -> 8.1
openssl@1.1 1.1.1d -> 1.1.1j
==> Upgrading readline 8.0.1 -> 8.1 
==> Downloading https://homebrew.bintray.com/bottles/r
==> Downloading from https://d29vzk4ow07wi7.cloudfront
```
↑バージョンアップ中(多少時間がかかります)

##最後に
`brew -v`で、Homebrewのバージョンを確認します。

```
% brew -v
Homebrew 3.0.1
```

無事バージョン確認を行うことが出来ました！


---
お読みいただきありがとうございました。
微力ながらお役に立てれば幸いです。
Pardot のプロセスオートメーション (Salesforce Classic) ⇒ ダイナミックリストの使用

１．次のうち、ダイナミックリストの属性はどれですか?
２．ダイナミックリストを要するシナリオはどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/6f13cd06-45f6-11fb-99fc-417052a224a0.png)
PHPで指定日付前を取得する

#はじめに
調べる機会がありましたので、備考録としてまとめました。
日付取得で使用する関数は[date関数](http://php.net/manual/ja/function.date.php)、[strtotime関数](http://php.net/manual/ja/function.strtotime.php)である。

#取得方法

```
date("Ymd", strtotime("-1 day")); //現在日より1日前を取得
date("Ymd", strtotime("-1 week")); //現在日より1週間前を取得
date("Ymd", strtotime("-1 month")); //現在日より1ヶ月前を取得
date("Ymd", strtotime("-1 year")); //現在日より1年前を取得
date("Ymd", strtotime('last Saturday')); //現在日より先週の日曜日の日付を取得
date("Ymd", strtotime("-1 day" ,strtotime("20210211"))); //2021年2月11日より１日前を取得
```

※指定日付後を取得したい場合は、上記サンプルコードのマイナスを消す。

#参考

* [前日日付などを取得する方法](http://choo.hatenablog.jp/entry/20090309/1236674427)