OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】データサイエンス100本ノック（構造化データ加工編） 025 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/P54EGf--2gk)もしています。

##問題
P-025: レシート明細データフレーム（df_receipt）に対し、顧客ID（customer_id）ごとに最も古い売上日（sales_ymd）を求め、10件表示せよ。

##解答
```:コード
df_receipt.groupby('customer_id').sales_ymd.min().reset_index().head(10)
```

##出力
|  | customer_id | sales_ymd |
|--:|:--|--:|
| 0 | CS001113000004 | 20190308 |
| 1 | CS001114000005 | 20180503 |
| 2 | CS001115000010 | 20171228 |
| 3 | CS001205000004 | 20170914 |
| 4 | CS001205000006 | 20180207 |
| 5 | CS001211000025 | 20190322 |
| 6 | CS001212000027 | 20170127 |
| 7 | CS001212000031 | 20180906 |
| 8 | CS001212000046 | 20170811 |
| 9 | CS001212000070 | 20191018 |

##解説
・PandasのDataFrame/Seriesにて、同じ値を持つデータをまとめて処理し、同じ値を持つデータの合計や平均などを確認したい時に使用します。
・**'groupby'は、同じ値や文字列を持つデータをまとめて、それぞれの同じ値や文字列に対して、共通の操作（合計や平均など）を行いたい時に使います。**
・**'.sales_ymd.min()'は、'.sales_ymd'の最小値（=最も古い売上日）を表示させます。**
・**'.reset_index()'は、'groupby'によってバラバラになったインデックス番号を0始まりの連番に振り直す操作を行いたい時に使います。**


※以下のコードでも、同じ結果を出力します（'.agg'を用いた場合）

```:コード
df_receipt.groupby('customer_id').agg({'sales_ymd':'min'}).reset_index().head(10)
```
Dockerの使い方　2日でDocker習得編 (udemy 米国AI開発者がゼロから教えるDocker講座）

夏のDocker合宿2日目

機械学習の環境構築をDockerで行う（Jupiter Lab)
メリット　
★環境構築のエラー回避
チーム開発の手間を下げる
リソースの有効活用（企業レベル？）


前提
Q「パス」を通すとは？
環境変数　＄PATHにパスを追加すること。
コンピューターがプログラムをそのパスから持ってこれるようにすること。
パスを通すためのLinuxコマンド

sudo
どのコマンドもルート権限で実行できるようになる。

```
1　＄echo＄PATH （今どこにパスが通っているのか確認）
2  ＄export PATH=/path/to/something:＄PATH パスを追加する
```

###実践 Anacondaをコンテナに持っていき、インストールする

手順
１　docker run
２ sh Anaconda~(パッケージ名）.sh
３ export PATH ~
４ sh /パス -b -p /パス　　　（インストール時、面倒なインタラクティブなやりとりを回避するため）

ブラウザでlocal:host8888にアクセスする（Jupyterlabにアクセスする）
ブラウザ上でコンテナのなかでJupyterlabを立ち上げ、ホストにコードが保存される形で、コンテナからコードを書く。
（マウントする）

```docker run -p 8888:8888 -v ~/Desktop/フォルダ名（Host側）:/(コンテナ側） --name my-lab \ <docker image>```


Dockerfileの中身

```
FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
sudo \
wget \
vim
WORKDIR /opt 
RUN wget https://repo.continuum.io/archive/Anaconda3-2020.02-Linux-x86_64.sh&& \
    sh Anaconda3-2020.02-Linux-x86_64.sh -b -p /opt/anaconda3 && \
    rm -f Anaconda3-2020.02-Linux-x86_64.sh

ENV PATH /opt/anaconda3/bin:$PATH

RUN pip install --upgrade pip
WORKDIR /
CMD ["jupyter","lab","--ip=0.0.0.0","--allow-root","--LabApp.token=''"]
```

大事なことは、上のコマンドの流れを覚えることではなくて、(いきなりスラスラ作るのは無理！）
<b>Dockerfileをどういう風に作るかのプロセスを試行錯誤しながら慣れていくこと<b>



###AWSにDockerを立ち上げる

![jmeter-in-aws-ec2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631141/e1e2b297-14ea-4f09-232a-5a1c08a2e140.png)


EC２ににアクセスするときの、権限を書く (sshで接続)

```
chmod400<file>
ssh -i  <keyname> ubuntu@<インスタンスDNS>
```
※キーがあるディレクトリからアクセスを行う。　（場所が違うとキーを見つけられずアクセスできない）


SFTP(Secure File Transfer Protocol) ファイルを送信するためのプロトコル（コマンド）
SSH　（Secure Shell) シェルを動かすためのコマンド


AWSでDockerコンテナを起動する方法
１　tarファイルに圧縮して送る　（EC２のサーバーのセキュリティが厳しい時など）

```
#docker image → tar ファイル  ... dockerimageを　tar.fileに変換する
$docker save {image} > {tar.file}

#tarファイル→docker image  ...EC２コンテナに送り、コンテナ内でtar.file（image)を開く
docker load < {tar.file}
```

２　Dockerfileを送って、開く
UikitとFontAwesomeをNext.js(React.js)上で動くようにする

本手順は、Next.js上で、UikitとFontAwesomeを動くようにする手順です。

### 前提
| ツール| バージョン | ツール| バージョン |
|----|----|----|----|
| React.js | 16.13.1 | Next.js | 9.4.4 |
| uikit | 3.5.5 | react-icons | 3.10.1 |

### 背景
+ もともと以下のようなhtmlで、<head>の中でcdnを使用してUikitとFontAwesomeを呼び出していた。
+ Next.js (React.js)に移行した途端に、uikitのアイコンとFontAwesomeのアイコンが読み込まれなかった。

```html
  <!--UiKit-->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.3.1/css/uikit.min.css" integrity="***" crossorigin="anonymous" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.3.1/js/uikit.min.js" integrity="***" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.3.1/js/uikit-icons.min.js" integrity="***" crossorigin="anonymous"></script>
  <!--FontAwesome-->
  <script src="https://kit.fontawesome.com/1d615c07d9.js" crossorigin="anonymous"></script>
...
<!--FontAwesome-->
<i class="fas fa-user-shield fa-5x"></i>
<!--UiKit-->
<span uk-icon="icon: users" class="uk-margin-small-right uk-icon"></span>
```

### 原因
1\. Reactで読み込むための指定方法は下記のようになるらしい ([参考](https://getuikit.com/docs/javascript#component-usage))

```html
× <span uk-icon="icon: users" class="uk-margin-small-right uk-icon"></span>
○ <span data-uk-icon="icon: users" class="uk-margin-small-right uk-icon"></span>
```

2\. そもそも、レンダー時にUikit, FontAwesome共にうまく読み込めていなかった。。 
=> そもそもCDNを使うべきかは未検討だったため、いったんローカルでインストールする方法を模索。
=> npm install を使って必要なものをインストールする方針に変更

### 解決
1. uk-\*\*\*のところをdata-uk-\*\*\*に変更
2. UiKitの必要なものをインストールし、コードを修正 => uikit

```shell
$ npm install uikit
```
```typescript
import UIkit from 'uikit';
import Icons from 'uikit/dist/js/uikit-icons';
...
UIkit.use(Icons);

```

3. FontAwesomeの必要なものをインストールし、コードを修正 => react-icons

```shell
$ npm install react-icons
```
```typescript
import { IconContext } from "react-icons";
import { FaUserShield , FaGlobe, FaUsers  } from 'react-icons/fa';
...
    render() {
        return (
            <IconContext.Provider value={{ style: { fontSize: '5em' } }}>
            <div>
                <FaUserShield />  
                <FaGlobe />
                <FaUsers />
            </div>
        );
    }
...
```

### 参考
+ [React.js ライブラリ「react-icons」を使用して様々なアイコンを利用する
](https://mebee.info/2020/03/25/post-7296/?unapproved=19&moderation-hash=4f7d43f9bb66c3d990454de794b43a5e#comment-19)
+ [Webpack - UIkit](https://getuikit.com/docs/webpack)
+ [Javascript - UIkit](https://getuikit.com/docs/javascript#component-usage)
PreferenceScreenをネストすると外のレイアウトが崩れる

PreferenceFragmentを使った設定画面で、例えば、複数画面のPreferenceを簡単に作ろうとすると

```java
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceScreen android:title="test1">
        <Preference android:title="test1-1">
        <Preference android:title="test1-2">
    </PreferenceScreen>
</PreferenceScreen>
```
とネストをかければ複数画面を作れますが、これだとネストされたPreferenceScreen画面には、親のPreferenceScreenでデザインしたであろうレイアウト(ActionBarやbuttombarなど)が適用されません。
そこで、親のPreference要素をクリックすると別のフラグメントに置き換えるという、従来のFragmentの切り替え方でなんとかしました。

```java:SettingActivity.java
public class SettingActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // activity_setting.xmlはfragmentを入れるレイアウトxml
        setContentView(R.layout.activity_setting);
        getFragmentManager().beginTransaction().replace(R.id.fragment_container,
                new UserPreferenceFragment()).commit();
    }
}

class UserPreferenceFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // preference_header.xmlは親の設定画面xml
        addPreferencesFromResource(R.xml.preference_header);
        Preference.OnPreferenceClickListener subpreference = new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                getPreferenceScreen().removeAll();
                switch(preference.getKey()) {
                    // preference_test1,2,3 は子の設定画面
                    case "test1":
                        addPreferencesFromResource(R.xml.preference_test1); break; 
                    case "test2":
                        addPreferencesFromResource(R.xml.preference_test2); break;
                    case "test3":
                        addPreferencesFromResource(R.xml.preference_test3); break;
                }
                return true;
            }
        };
        final Preference test1 = (Preference) findPreference("test1");
        final Preference test2 = (Preference) findPreference("tesst2");
        final Preference test3 = (Preference) findPreference("test3");
        test1.setOnPreferenceClickListener(subpreference);
        test2.setOnPreferenceClickListener(subpreference);
        test3.setOnPreferenceClickListener(subpreference);
    }
}
```

ホント地味にですが、setOnPreferenceClickListenerをできるだけきれいに、複数作るのに苦労しました。(ひとつずつ定義して当てはめるには量が多かったので)

参考：

[PREFERENCEACTIVITYからINTENTを呼び出す
](https://techbooster.org/android/hacks/7589/)
【Deno】denonを利用してのscripts管理

## 背景
- Deno利用時に以下の点が気になったため、Node同様に可能なのか調査することに。
  - `deno run --allow-net --allow-read server.ts`のような実行コマンドの長さを簡略化して、各種権限管理をしたい。
  - **npm scripts**のように各環境や種類毎に管理できるようにしたい。
  - Nodeでのnodemonのようなオートリロード環境の仕組みにしたい。

## 結果

### denon
- 調査の結果、上記3つの要望が可能である[denon](https://deno.land/x/denon@2.3.2)を導入することに。
- denonとは、[nodemon](https://github.com/remy/nodemon)のdeno代替であり、柔軟かつ高機能に設定が可能なツール。
- 設定ファイルは、以下の3つの形式で記述することが可能。
  - json: `denon.json`
  - typescript: `denon.config.ts`
  - yaml: `denon.yml`

### インストール
- 下記のコマンドで、プロジェクトフォルダにインストール

```bash
deno install --allow-read --allow-run --allow-write --allow-net -f -q --unstable https://deno.land/x/denon@2.3.2/denon.ts
```

### 初期化
- 下記のコマンドで設定ファイルの雛形を作成する。
  - **※Nodeであれば、`npm init`のようなもの。**

```bash
# 標準では、json形式(denon.json)
denon --init

# typescript形式(denon.config.ts)
denon --init typescript

# yaml形式(denon.yml)
denon --init yaml
```

### 設定テンプレート
- 以下の点をふまえた設定テンプレートを記述する。
  - 開発の流れで必須、また頻度が高いものをまとめる
  - なるべく環境変数は記述しない。
  - 多く記述せず、単純にする。
- 今回は、視認性や機能性をふまえて、**YAML**での方法を記述する。
- **※その他、denonの詳細な設定方法は[こちら](https://denosaurs.land/)を参考にする。**

```yaml:denon.yml
scripts:
  dev:
    cmd: "deno run src/app.ts"
    desc: "run app.ts file"
    allow: ["env", "net", "read", "write", "plugin"]
    unstable: true
  build:
    cmd: "deno bundle src/app.ts > build/app.js"
    desc: "build app.ts file"
  lint: 
    cmd: "deno lint src/"
    desc: "lint all ts file"
    unstable: true
  fmt: 
    cmd: "deno fmt src/"
    desc: "format all ts file"
watcher:
  exts: ["js", "jsx", "ts", "tsx", "json"]
  skip: ["*/.git/*"]
```

### 実行方法
- 下記のコマンドのように実行。

```bash
# denon スクリプト名
denon dev

# フォーマット
denon fmt

# ビルド
denon build
```

## 参考
- [Deno公式](https://deno.land/x/denon@2.3.2)
- [公式ドキュメント](https://denosaurs.land/)
InsertされたレコードをSelectする

主キーにauto_incrementが指定してあるテーブルに
insertした後、そのinsertした行のauto_incrementがされている値が欲しい場合、
Insertした直後にすぐにselect文でmax()や@@identifyを使って持ってくる方法がありますが、<br>
複数からの同時実行などを考慮すると少し不安なものがありますよね、、、<br>
色々試行錯誤して、ある[記事](https://social.msdn.microsoft.com/Forums/ja-JP/635c8584-e32d-40f3-934d-5b46d49203a4/sql12391insert123751238324460123951238112398id12434244711242712395?forum=csharpgeneralja)
を参考にしてその解決方法を見つけました。

**「Insert文にて"OUTPUT句"を使い、挿入した行の特定の値を抽出する」**方法です。

|id(Primary/auto_increment) | name | remarks |
|:---|:---|:---|
|1|test1-1|test1-2|
|2|test2-1|test2-2|
|3|test3-1|test3-2|

※ transactionによる処理(複数人からの同時実行考慮/主キーautoincrement時)

```vb
Private Function insertAndSelect() As Integer
    Dim conn As SqlConnection
    Dim cmd As New SqlCommand
    Dim tran As SqlTransaction
    DIm result As Integer = -1

    Const INSERT_STATEMENTS = 
        "INSERT INTO tbl(name, remarks)" & _
            ' OUTPUT句で挿入した行のidを返す
            "OUTPUT inserted.id" & _
                "VALUE('test4-1', 'test4-2')"
    Try
        cmd.Connection = con
        cmd.CommandType = cmd.CommandType ' 謎
        tran = conn.BeginTransaction()
        cmd.Transaction = tran 
        cmd.CommandText = INSERT_STATEMENT
        ' 返り値を一つだけ返す
        result = CInt(cmd.ExecuteScalar())
        tran.Commit()
    Catch ex As Exception
        Try
            tran.Rollback()
        End Try
    End Try
    return result
End Function
```
画面遷移&値渡しの試行錯誤

初めはこうしたかったのですが、何度やっても動かず。。。


```vb:Module1.vb-共通クラス
Public Module Module1
 ' 諸事情で拡張メソッド使ってます。
    <System.Runtime.CompilerServices.Extension()>
    Public Sub TransitionForm(Form1 As Form, ByVal ParamArray args() As Object)
        args(0).show()
        My.Application.ApplicationContext.MainForm = args(0)
        arg(0)._passValue = args(1)
        Form1.Hide()
    End Sub
End Module
```

```vb:Form1.vb-遷移前画面
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Me.TransitionForm(Form2, "test")
    End Sub
End Class
```

```vb:Form2.vb-遷移後画面
Public Class Form2
    Public Shaared _passValue As Object
    Sub New(passValue As Object)
        InitializeComponent()
        Label1.Text = _passValue.ToString()
    End Sub
End Class
```

結局こうやったら普通に動きました。はぁ(*´Д｀)(なんだかなぁ)

```vb:Module1.vb-共通クラス
Public Module Module1
 ' 諸事情で拡張メソッド使ってます。使わなくても行けます。
    <System.Runtime.CompilerServices.Extension()>
    Public Sub TransitionForm(Form1 As Form, ByVal ParamArray args() As Object)
        args(0).show()
        My.Application.ApplicationContext.MainForm = args(0)
        Form1.Hide()
    End Sub
End Module
```

```vb:Form1.vb-遷移前画面
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Me.TransitionForm(New Form2("test"))
    End Sub
End Class
```

```vb:Form2.vb-遷移後画面
Public Class Form2
    Sub New(passValue As Object)
        InitializeComponent()
        Label1.Text = passValue
    End Sub
End Class
```

共通クラスにメソッドを書くやり方で(1つ目みたいなやり方)、
もっとスマートなやり方知ってる方いらっしゃったら
教えていくだちゃい。。。。もっと勉強しなきゃなぁ。
IPSecパススルーに対応していないルーターではL2TP/IPSecのVPN接続ができない！...いや、できるけどね。

# はじめに

かなりどハマりしてしまって、七転八倒したから記録しておきます。

ネットで見つけた色々な情報を見ては試すというのを繰り返したのですが、意外と間違いも多く...インターネット上の情報は当てになるようなならないような...でも、結局はネットにある正しい情報に助けられて、インターネット様々です。

...閑話休題。

# ルーター

BUFFALO WHR-600D

以下のページを見ると、IPSecには対応していない機器とのこと...
[VPNマルチパススルーに対応していますか？（Wi-Fiルーター、有線ルーター）](https://www.buffalo.jp/support/faq/detail/909.html)


絶望した！IPSecに対応していない機器を買ってしまった自分に絶望した！

...閑話休題。

# 経緯

それはもう苦労しましたよ...最初はIPフィルターだのVPNパススルーだの、色々とにわか知識に振り回され、設定をいじり倒して...中略...結果的に、以下のように設定して解決することができました。

# ポート変換

VPN接続するマシンのIPアドレスを固定させ、そのIPアドレスに対してポートを指定して通信をさせれば良かったようです。

追加したポート変換の設定は以下のとおり。

- プロトコル番号 50
- UDPポート 1701
- UDPポート 4500
- UDPポート 500

設定画面は以下のとおりです。

<img width="900" alt="スクリーンショット 2020-08-12 5.01.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/90413c6d-1b58-2ef8-220d-c87ca4e9aa2c.png">

※ LAN側IPアドレスについては、「192.168.」のみ表示してありますが、実際にはVPNをご利用されるPCのIPアドレスをご入力下さい。

できた！

それではみなさん、良い在宅勤務ライフをお過ごし下さい。汗
<12> テキストファイルの入出力 (標準 Pascal 範囲内での Delphi 入門)〔裏〕

# 12. テキストファイルの入出力

## 12.1. 標準ファイル入出力

## 12.2. 手続き Read と Readln


## 12.3. 手続き Write と Writeln

#### ・書き出しパラメータ？

個人的にはこの `書き出しパラメータ` は訳さずに **Write() パラメータ**とでもするのが解りやすいと思います。

### (12.3.1.) 書き出しパラメータ (書き込みパラメータ / Write-parameters)

#### ・書き出しパラメータを持つ手続き/関数

書き出しパラメータを持つ手続き/関数は [Write()](http://docwiki.embarcadero.com/Libraries/ja/System.Write), [Writeln()](http://docwiki.embarcadero.com/Libraries/ja/System.Writeln) の他、Delphi には [Str()](http://docwiki.embarcadero.com/Libraries/ja/System.Str) があります。

|関数|説明|
|:---|:---|
|[Str()](http://docwiki.embarcadero.com/Libraries/ja/System.Str)|文字列を書式設定し、変数に格納して返します。|

書き出しパラメータをパラメータに持つユーザー定義な手続き/関数を作る事はできません。

## 12.4. 手続き Page()

## (12.5.) コマンドラインパラメータ

#### ・コマンドラインパラメータ (Berkeley Pascal の場合)

**Berkeley Pascal** には argc() というコマンドラインパラメータの数を返す関数と、argv(i, a) という i 番目のパラメータを文字配列 a に格納する手続きがありました。

# 索引
[:ramen:](https://qiita.com/ht_deko/items/391d6c1a53c7aaa3416f) [ [← 11. 手続きと関数〔裏〕](https://qiita.com/ht_deko/items/eb20c1504ea759d04e24)] [ [↑ 目次へ](https://qiita.com/ht_deko/items/46fcdbb11cdc58872160) ]
<8> 集合型 (標準 Pascal 範囲内での Delphi 入門)〔裏〕

# 8. 集合型 (Sets)

#### ・基底型の要素数

基底型の要素数は実装依存です。

| Pascal | 要素数 |
|:-:|:-:|
| Delphi | 256 |
| Turbo Pascal | 256 |
| Free Pascal | 256 |
| GNU Pascal | 256 (拡張可能) |
| Apple ][ | 512 |
| Apple /// | 512 |
| MPW Pascal | 2040 |
| UCSD Pascal | 4080 |
| Berkeley Pascal | 65535 |

## 8.1. 集合構成子

## 8.2. 集合演算子

### (8.2.1.) 集合の代入

### (8.2.2.) 集合の演算

### (8.2.3.) 集合の比較演算

### (8.2.4.) ビット集合 (Bitset)

### (8.2.5.) 集合定数とグローバル集合変数の初期化

## 8.3. プログラムの開発について

### (8.3.1. ) Unicode 版 Delphi と CharInSet() 関数

### (8.3.2. ) Pascal の字下げ (インデント) スタイル

# 索引
[:ramen:](https://qiita.com/ht_deko/items/50bac0de384d66208944) [ [← 7. レコード型〔裏〕](https://qiita.com/ht_deko/items/715620809518de763a67) ] [ [↑ 目次へ](https://qiita.com/ht_deko/items/46fcdbb11cdc58872160) ] [ [→ 9. ファイル型〔裏〕](https://qiita.com/ht_deko/items/0e012da26f46b915307d) ]
<7> レコード型 (標準 Pascal 範囲内での Delphi 入門)〔裏〕

# 7. レコード型 (Records)

## 7.1. 固定レコード

## 7.2. 可変レコード (レコードの可変部分)

### (7.2.1.) 共用体

### (7.2.2.) レコード定数とグローバルレコード変数の初期化

## 7.3. with 文

# 索引
[:ramen:](https://qiita.com/ht_deko/items/1d2c85768febc95009bf) [ [← 6. 構造化型の概要と配列型〔裏〕](https://qiita.com/ht_deko/items/bfd46dc32bcb413d44e1) ] [ [↑ 目次へ](https://qiita.com/ht_deko/items/46fcdbb11cdc58872160) ] [ [→ 8. 集合型〔裏〕](https://qiita.com/ht_deko/items/a0044d6decd6f175365f) ]
<5> 列挙型と部分範囲型 (標準 Pascal 範囲内での Delphi 入門)〔裏〕

# 5. 列挙型と部分範囲型

#### ・スカラ型について

> そして実際に混乱したのでしょう、標準 Pascal からはスカラ型の説明が消えています。

**Turbo Pascal** も ver 3.0 まではスカラ型で説明されていました。

**See also:**

 - [Delphi のご先祖を辿る (Qiita)](https://qiita.com/ht_deko/items/b41b0cd45181aec522d4) 
 - [Pascal の勉強に使えそうな Pascal 処理系 (Qiita)](https://qiita.com/ht_deko/items/6376997a6d74e77c89e3)

## 5.1. 列挙型 (Enumerated Types)

### (5.1.1) スコープのある列挙型 (Scoped Enums)

### (5.1.2) 列挙型定数とグローバル列挙型変数の初期化


## 5.2. 部分範囲型 (Subrange Types)

### (5.2.1) 部分範囲型定数とグローバル部分範囲型変数の初期化


# 索引
[:ramen:](https://qiita.com/ht_deko/items/335e59857cc78aea951a) [ [← 4. 動作の概念〔裏〕](https://qiita.com/ht_deko/items/2252b6b3079cc834c577) ] [ [↑ 目次へ](https://qiita.com/ht_deko/items/46fcdbb11cdc58872160) ] [ [→ 6. 構造化型の概要と配列型〔裏〕](https://qiita.com/ht_deko/items/bfd46dc32bcb413d44e1) ]
<3> プログラムヘッダと宣言部 (標準 Pascal 範囲内での Delphi 入門)〔裏〕

# 3. プログラムヘッダと宣言部


## 3.1. プログラムヘッダ (Program heading )

## 3.2. ラベル宣言部 (Label declaration part)

#### ・識別子が利用可能なラベルの由来

> Delphi の場合にはラベルに識別子が使えます。

この拡張は **BLS Pascal** (**Turbo Pascal** の前身) 由来のようです。

**See also:**

 - [Delphi のご先祖を辿る (Qiita)](https://qiita.com/ht_deko/items/b41b0cd45181aec522d4) 
 - [Pascal の勉強に使えそうな Pascal 処理系 (Qiita)](https://qiita.com/ht_deko/items/6376997a6d74e77c89e3)


## 3.3. 定数定義部 (Constant declaration part)

### (3.3.1.) 定数式 (Constant Expressions)

### (3.3.2.) 型付きの定数 (Typed Constants)

#### ・書き込み可能な型付き定数について
型付きの定数は**Delphi 5 までは書き込み可能**でした。実質的には初期化済み変数という事になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/f13e5fbc-738d-62ee-213a-a84b295c6bd7.png)
また、**書き込み可能な型付き定数**は**静的変数**として振舞います。

```pascal:StaticVar.pas
program StaticVar;
{$APPTYPE CONSOLE}

{$J+} // Writable Const

var
  i: Integer;

procedure A;
const
  foo: Integer = 0;
begin
  Inc(foo);
  writeln(foo);
end;

begin
  for i := 1 to 10 do
    A();
end.
```

このコードの実行結果は以下の通りです。

```
1
2
3
4
5
6
7
8
9
10
```

型付きの定数の挙動は Delphi 2 から `{$J}` コンパイラ指令で制御できるようになり、Delphi 6 において `{$J-}` (書き込み不可能な型付き定数) がデフォルトとなりました。

つまり、Turbo Pascal や Delphi 1 では型付きの定数は常に書き込み可能でした。Delphi 2 のマニュアルには `{$J-}` がデフォルトであるかのように書かれていますが、実際には `{$J+}` がデフォルトです。

**See also:**

 - [WRITEABLECONST（書き込み可能な型付き定数）（Delphi）(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/WRITEABLECONST%EF%BC%88%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF%E5%8F%AF%E8%83%BD%E3%81%AA%E5%9E%8B%E4%BB%98%E3%81%8D%E5%AE%9A%E6%95%B0%EF%BC%89%EF%BC%88Delphi%EF%BC%89)
 - [Delphi のご先祖を辿る (Qiita)](https://qiita.com/ht_deko/items/b41b0cd45181aec522d4) 
 - [Pascal の勉強に使えそうな Pascal 処理系 (Qiita)](https://qiita.com/ht_deko/items/6376997a6d74e77c89e3)

## 3.4. 型定義部 (Type definition part)

## 3.5. 変数宣言部 (Variable declaration part)

### (3.5.1.) プログラムヘッダのパラメータ

### (3.5.2) インライン変数宣言 (Inline Variable Declaration)
  
## 3.6. 手続き・関数宣言部 (Procedure and Function declaration part)

## 3.7. 識別子とラベルの有効範囲

# 索引
[:ramen:](https://qiita.com/ht_deko/items/2d5996cbfc82d734b247) [ [← 2. データの概念: 単純型〔裏〕](https://qiita.com/ht_deko/items/e36898d7aa4bb3300f78) ] [ [↑ 目次へ](https://qiita.com/ht_deko/items/46fcdbb11cdc58872160) ] [ [→ 4. 動作の概念〔裏〕](https://qiita.com/ht_deko/items/2252b6b3079cc834c577) ]
さくらのレンタルサーバのライトプランでSFTPは使えません

最近，ふとホームページを作ってみたいと思い立ち，さくらのレンタルサーバのライトプランを契約したが，ハマってしまった点があるので注意点を記す．
もっとも，需要が有るかどうかは甚だ疑問であるが…

# ライトプランって？

さくらのレンタルサーバのライトプランとは131円/月
でwebサーバをレンタルできる素敵なプランである．
当然この価格でレンタルできるのには理由があり，

- 静的なコンテンツしか扱えない（WordPressが使えない）
- sshでログインできない

という制約がある．

あえてライトプランを選んだのは，せっかくホームページを作るのだからhtmlの細かいところも学んでみたかったのと，単純に筆者が金欠学生だからである．

# ハマったところ

上述の通り，ライトプランではSSHが使えない．この時点で察しの良い方はお気づきだろうが
SFTPによるファイル転送ができないのである．

[FTPS、SFTPの違いって?](https://qiita.com/kasei-san/items/bf766e6c2ececa4c3905)

上の記事にある通りSFTPプロトコルはSSHで暗号化された通信経路を使う．
普段SFTPを使い慣れていたが，SFTPがSSHを使うことを完全に失念していた．

# うわ，ftpコマンド，使いにく過ぎ…？

早速FTPでファイル転送をしようとしたが，ここで大きな問題が立ちはだかる．
ftpコマンドが非常に使いにくいのである．なんとローカルマシンのカレントディレクトリ内すら確認できない．
手先が不器用なためGUIのftpクライアントに抵抗があり，なんとかならないか調べてみたら
[NcFTP](https://www.ncftp.com/)なるコマンドを見つけた．

詳しい使い方は
[ncftp - 高機能 ftpクライアント](http://technique.sonots.com/?UNIX/%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88/ncftp)にまとめられているが，SFTPコマンドと近い操作感で大変快適である．

# コマンドラインでのFTP通信にはNcFTPを使おう

このように非常に便利なNcFTPコマンドであるが，何故か調べてもすぐには出てこない．
筆者と同じくライトプランを契約しようとしている人が困らないようこの記事を書いた次第である．

この記事需要有る…？
【Rails】もう迷いたくない。モデル、テーブル、コントローラ、ビューの新規作成。

## はじめに
この記事はRailsアプリを立ち上げた後の作業をまとめたものです。
何らかの機能を作る際には、モデルを作ってコントローラ作ってルーティング書いて...といった作業が頻発します。
毎回構文を忘れてしまうので、一連の流れをまとめました。

## コントローラの作成
まずはコントローラの作成です。
今回は画像を保存する機能を作るのでimagesとします。

```
rails g controller images
```

## モデルの作成
下記のコマンドでimageモデルを作りましょう！

```
rails g model image
```

これでimageモデルが作成されたと思います。
必要であれば、モデルにバリデーションやアソシエーションを記述しましょう。


## テーブル作成
モデルを作成した際にマイグレーションファイルも作成されたと思います。
このファイルを編集して主キーやnull制約などの設定を行います。
私の場合は、以下のようにして”filename”を主キーにし、null制約をかけています。
主キーにしたのでそんな制約要らないかもしれませんが...

```
class CreateImages < ActiveRecord::Migration[5.2]
  def change
    create_table :images, id: false, primary_key: :filename do |t|
      t.string :filename, null: false
      t.timestamps
    end
  end
end
```
それではマイグレートを実行し、正常終了すればテーブルが作成されます！

```
rails db:migrate
```

## ビューの作成
画像の一覧を表示するページということで、index.html.hamlを作りましょう。
これまでの作業でimagesディレクトリが作成されているので、そこに作成します。
ビューの内容については、今回の記事で詰めるところではないので適当に"HelloWorld"を出しておきます。

```
%h1
  HelloWorld
```

## ルーティング
ここまで来ればほぼ出来たようなものです。
routes.rbにimagesのルーティングを記載します。
今回はresourcesメソッドを使用してindexアクションのみを設定しました。

```
Rails.application.routes.draw do
  resources :images, only: [:index]
end
```

## 結果
出来ました！これで仕事が捗る...!

![スクリーンショット 2020-08-12 4.25.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/79e10c5a-100c-1246-dfb4-8c7b279bec08.png)
標準 Pascal 範囲内での Delphi 入門〔裏〕 

# はじめに
本筋に関係ないので[「標準 Pascal 範囲内での Delphi 入門」](https://qiita.com/ht_deko/items/e2796788c65c2cda1de5)から省いたトピックを集めた記事です。
それなりに面白いと思いますが、内容のない記事がある事をあらかじめお断りしておきます。

# 目次
ここがメインページです。

 - [0. はじめに〔裏〕](https://qiita.com/ht_deko/items/017489388d859692ddbb)
 - [1. 記法: トークンと区切り文字〔裏〕](https://qiita.com/ht_deko/items/bb5d4eaf532e8c217cdb)
 - [2. データの概念: 単純型〔裏〕](https://qiita.com/ht_deko/items/e36898d7aa4bb3300f78)
 - [3. プログラムヘッダと宣言部〔裏〕](https://qiita.com/ht_deko/items/26e37c293ee14c43238e)
 - [4. 動作の概念〔裏〕](https://qiita.com/ht_deko/items/2252b6b3079cc834c577)
 - [5. 列挙型と部分範囲型〔裏〕](https://qiita.com/ht_deko/items/e581e8f5c0c32d5a58e2)
 - [6. 構造化型の概要と配列型〔裏〕](https://qiita.com/ht_deko/items/bfd46dc32bcb413d44e1)
 - [7. レコード型〔裏〕](https://qiita.com/ht_deko/items/715620809518de763a67)
 - [8. 集合型〔裏〕](https://qiita.com/ht_deko/items/a0044d6decd6f175365f)
 - [9. ファイル型〔裏〕](https://qiita.com/ht_deko/items/0e012da26f46b915307d)
 - [10. ポインタ型〔裏〕](https://qiita.com/ht_deko/items/3be4294e82653fb234c4)
 - [11. 手続きと関数〔裏〕](https://qiita.com/ht_deko/items/eb20c1504ea759d04e24)
 - [12. テキストファイルの入出力〔裏〕](https://qiita.com/ht_deko/items/bbbd35ac89dfb2268c88)


# おわりに
Delphi って本当に便利ですね。[:ramen:](https://qiita.com/ht_deko/items/e2796788c65c2cda1de5)
Chromeページ翻訳でコードを翻訳させないスクリプトの作り方

# やること

Chromeページ翻訳によって無残にも翻訳されてしまうReactプログラム...
<img width="832" alt="スクリーンショット 2020-08-12 3.07.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305522/d299ed9c-50a4-cce6-a820-06dfa2697ed3.png">

コードが翻訳されてしまうのは、該当箇所をHTMLのcodeタグで囲んでないからです。

今回は、[こちらのサイト](https://create-react-app.dev/docs/getting-started)のコードが記載されてる部分をcodeタグでラップする簡単なJavaScriptを組んで、Chromeデベロッパーツールのconsoleから実行して対策してみようと思います。

JavaScriptの勉強がてら参考にどうぞ🙋‍♂️

# 実装

### 1. 状況を把握する

F12で検証ツールを開いて中身を覗くと、やっぱりcodeタグで囲まれてないっぽいですね。

![スクリーンショット 2020-08-12 2.22.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305522/5915950f-9bdf-bb23-891c-f88a6130daf0.png)

今こんな感じなのを、

```html
<pre class="mdxCodeBlock_iHAB">
    <div class="...">
        ...
    </div>
</pre>
```

こうすれば、大丈夫そうです。

```html
<pre class="mdxCodeBlock_iHAB">
+   <code>
        <div class="...">
            ...
        </div>
+   </code>
</pre>
```

### 2. コーディング

コメント付きの完成版

```javascript
// スコープを汚染しないために即時関数で囲んでおく
(() => {
  // 正規表現でclass名が 'mdxCodeBlock_' から始まるエレメントを全て取得
  const codeBlockElements = document.querySelectorAll("[class^=mdxCodeBlock_]");
  // エレメントごとに処理するためのループ
  codeBlockElements.forEach((element) => {
    // 子要素を削除する前に、コピーして残しておく
    // 子要素は1つしかないので、children[0]でOK
    // cloneNodeの引数は、deepcopyを有効にするか否か
    const copiedChildren = element.children[0].cloneNode(true);
    // 子要素を全削除
    while (element.firstChild) {
      element.removeChild(element.firstChild);
    }
    // codeエレメントを作成して、コピーしておいたエレメントをラップして元の場所に戻す
    const wrapElement = document.createElement("code");
    wrapElement.appendChild(copiedChildren);
    element.appendChild(wrapElement);
  });
})();
```

### 3. 適用

F12を押下して検証ツールを開いて、consoleタブに移動して今回のコードを叩きます。

<img width="1186" alt="スクリーンショット 2020-08-12 3.02.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305522/8efeb9cb-cc31-baa4-1f2c-bfd9fb3e7d9b.png">

実行後、ちゃんとcodeタグで囲まれてますね。

<img width="1245" alt="スクリーンショット 2020-08-12 3.14.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305522/f048864c-e6f0-f03e-ca36-b77133fe8228.png">

翻訳してもコードは無事です。（リロードのたびにスクリプトを実行する必要があります）

<img width="1145" alt="スクリーンショット 2020-08-12 3.02.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305522/da215866-cc50-cce9-5ddd-bd39cdd5264a.png">

# まとめ

こんな感じで同じようにやれば、他サイトも対応可能です。いちいちスクリプト実行するのが面倒であれば、Chrome拡張機能を自作して、ローカルで適用させれば永続化可能です。

ぜひ自力でやってみてください！！

[ドキュメントオブジェクトモデル (DOM) - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model)

Twitter: [@kzkzkazz](https://twitter.com/kzkzkazz)
LambdaのIP固定

実行毎に変わるLambdaのIPを固定。
呼び出し先のAPIにIPをホワイトリスト登録するなどで利用。

## 構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/b3ee9513-b85e-63fc-a15f-e068edcb559a.png)

## 環境

1. VPCを1つ用意する。
2. サブネットとルーティングテーブルを2つずつ用意し、それぞれアタッチする。
3. インターネットゲートウェイを作成し、VPCにアタッチ
4. パブリックサブネットのルーティングテーブルの`0.0.0.0/0`をインターネットゲートウェイに向ける。
5. EIP確保、NATゲートウェイ作成、プライベートサブネットのテーブルの`0.0.0.0/0`をNATに向ける。
 
## Lambdaの作成/配置

1. IAMロールの作成。ポリシーは`AWSLambdaVPCAccessExecutionRole`
2. Lambda作成。
3. LambdaコンソールのVPCを編集し、上記で作成した環境を選択する。適応までちょっと待つ。

## 検証

API Gatewayで呼び出し元のIPを表示してみる。

統合リクエストから以下を設定することで呼び出し元のIPを取得できる。

```json:統合リクエストのマッピング
{
  "sourceIp" : "$context.identity.sourceIp",
  "input" : $input.path('$')
}
```

```python:Lambda側のコード抜粋
request_url = "https://******.execute-api.ap-northeast-1.amazonaws.com/****"
api_key = "**********"

def lambda_handler(event, context):
    headers = {'x-api-key': api_key, "Content-Type":"application/json"}
    req = urllib.request.Request(url=request_url, method="GET", headers=headers)
    with urllib.request.urlopen(req) as res:
        body = res.read().decode("utf-8")
    return json.loads(body)
```

## 参考

* https://dev.classmethod.jp/articles/api-gateway-client-ip/
* https://qiita.com/kojiisd/items/a15c1807c5c6bb08add0
Unity 3D入門 #13 [本を調べる処理]

本を調べると、メッセージが表示されるようにします。
1. 調べることができる本は他のオブジェクトに比べて光るなど目立たせたい。
2. 本毎に個別のテキストを表示してほしい。


●調べることができる本は他のオブジェクトに比べて光るなど目立たせたい。
MaterialのEmissionによる自己発光により、オブジェクトを目立たせました。
参考URL：https://linemarker.hatenablog.com/entry/2019/01/01/234106
暗い世界だからできる手法ですが、問題はクリアしました。

![スクリーンショット 2020-08-12 2.26.32（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670403/0d74a8e8-ee1d-bc2c-ab8b-857e15fec68e.png)


●本毎に個別のテキストを表示してほしい。

```
public string booktext;
```
上のようにpublic変数として本の内容を用意することで本毎にテキストを使えるようになりました。
また、publicでのテキスト入力について、改行が難しいため、下のURLを参照してtextareaを作成しました。
参考URL：https://zenigane138.hateblo.jp/entry/2018/07/31/225637
【Docker】ローカル環境でNginxが動く最小構成を作る

PHP開発環境を作る上で、まずNginxが動く環境をローカルに構築してみます。

## 前提

- Docker for Macがインストール済み


## ファイル構成

以下の構成で2ファイル作成します。

```
├── docker-compose.yml
└── public
    └── index.html
```

各ファイルのソースはこのように設定します。

```docker-compose.yml
version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - 8080:80
    volumes:
       - ./public:/usr/share/nginx/html
```

```index.html
<h1>Hello world!</h1>
```

## Docker起動

```shell
$ docker-compose up
```

http://localhost:8080 にブラウザでアクセスすると無事に`Hello world!`が表示されました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/b21ed61a-348c-39dd-ccc5-4ca8b8d165fa.png" width=400 />


## 参考

- [Dockerの基礎を学ぶためにNginxを起動するだけのコンテナを立ち上げる](https://www.shibuya24.info/entry/docker_nginx)
一括リネームした括弧（カッコ）付き連番ファイル名から、全ての括弧を削除する方法

# ファイル名の一括リネーム
windowsエクスプローラから、ファイルが保存されているフォルダーを表示し、名前を変更したいファイルをすべて選択する。
連番の先頭にしたいファイルを右クリックし、表示された一覧から「名前の変更」をクリックする。
名前を変更する操作を行ったファイルの名称が「ファイル名＋(1)」という形式に変更され、それ以降は「(2)」以降の番号が連番で割り当てられる

![rename1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618171/759ae04e-5840-6a0f-b61f-f82151c2bc00.png)

ただし、このやり方だと半角括弧（カッコ）がついているので、あまりよろしくない

#batファイルを作成して半角括弧（カッコ）を全て削除する
##batファイル作成
メモ帳を開き以下のコマンドをコピペして保存。ファイル名は何でもよいが、今回は「括弧削除.bat」
```
echo off
for %%f in ( * ) do call :sub "%%f"
exit /b

:sub
set fname=%1
set fname=%fname: (=_%
set fname=%fname:(=_%
set fname=%fname:)=%
ren %1 %fname%
goto :EOF
```
 
 
保存場所は `shell:sendto` に保存する
![rename3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618171/1801b951-def6-b577-740a-27e2b7878df6.png)
##括弧の一括削除
括弧を削除したいファイルをまとめて選んで、右クリックメニューから「送る」→「括弧削除.bat」
![rename4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618171/fc50d46e-5999-5223-b81a-8fe8f1b7dd5f.png)
括弧が削除されて「ファイル名＋_連数字」のファイル名に変わる

おしまい
Docker Docker-composeのよく使うコマンド　まとめ(初学者)

## はじめに
Dockerにてよく使うコマンドを備忘録としてまとめておきます。

## コマンド
Dockerのversionを確認

```
$ docker --version
```
現在起動しているコンテナを表示

```
$ docker ps 
```
-aオプション
全てのコンテナを表示

コンテナを停止

```
$ docker container stop コンテナIDまたはコンテナ名
```

コンテナを指定して停止

```
$ docker stop コンテナ名またはコンテナID
```

取得したイメージを一覧

```
$ docker images
```

docker-compose.ymlの内容に基づいてイメージを作成する

```
$ docker-compose build
```

docker-compose.ymlに書かれた依存関係をもとに、よしなにイメージを元にしてコンテナの作成と起動する。イメージはdocker-compose buildで作成する必要がある。

```
$ docker-compose up
```

## おわりに
個人アプリにDockerを導入する際に上記のコマンドをよく使うと感じました。
参考になれば幸いです。
【Laravel】Laravelのバージョンを指定してインストールする

Laravelのバージョンを指定してインストールするには、というメモ。

```
$ composer create-project laravel/laravel=6.* --prefer-dist PROJECT_NAME
```

コンポーザーをインストールして、コマンドを上記のように打ち込む。`laravel/laravel=`の後にインストールしたバージョンの数字を入れる。今回の例では、`Laravelのバージョン「6」で一番新しいバージョンをインストールする`というふうになります。`*`は最新のバージョンになります。最初に`6.`が付いてその次に`*`が付くので、`バージョン6のなかで一番新しいバージョン`となります。

では、バージョン7をインストールしたい場合は

```php
$ composer create-project laravel/laravel=7.* --prefer-dist PROJECT_NAME
```

こんな感じで、`laravel/laravel=`の次に`7.*`を付けてあげると、バージョン7で一番新しいバージョンがインストールされます。
【Xcode】デバッグ時に一時停止したファイルを別タブで開く

XcodeのデバッガであるLLDBについてWWDCのセッションを視聴していたときに
ちらっと紹介があったので設定方法を紹介します。
同じタブで作業していてデバッグで一時停止されたファイルに毎回飛ばされると
意外と元のファイルを開き直すのが面倒ですよね。。
普段タブで作業している方にとってはとても便利そうです。

# 設定方法
- 左上のXcodeメニューを開く
- Behaviors -> Edit Behaviors ...
- Pauses -> Show tab namedにチェックをつける、別タブで開く際のタブ名を入力(スクショだとDebug)
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537666/5474e9fb-3609-2b45-4169-b65def116a49.png width=500px>

適当な場所にブレークポイントを設定し処理がそこで停止すると
別タブが開きます。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537666/d574661f-d1fa-aeb2-8fc6-fa3ef2d799a9.png width=500px>

# 参考文献
https://developer.apple.com/videos/play/wwdc2018/412/
FormulaPi ROS Simulation Environment のフィールドをgazebo上で表示を試みるも断念

※ 本記事は途中でエラーが発生して断念していますので注意
※ FormulaPi ROS Simulation Environment のフィールドをgazebo上で表示を試みるも断念

# 準備

以下を参考にさせていただく
> [FormulaPi ROS Simulation Environment](https://www.wilselby.com/formulapi-ros-simulation-environment/)
> [FormulaPi Basic Lane Tracking (ROS & Gazebo)](https://www.youtube.com/watch?v=rVsPItHA0xw)

リポジトリをcloneする

```
~/catkin_ws/src
git clone https://github.com/wilselby/formulapi_ROS_simulator
```

GAZEBO_MODEL_PATHを更新する

```
export export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/catkin_ws/src/formulapi_ROS_simulator/formulapi_gazebo/models
```

gazeboを起動してmodelを選択するも、、なぜかテクスチャがない。

```
gazebo
```


以下によるとgazebo2.x系でのみ表示実績があるらしい。おそらくrosindigo用かと、、（今回テクスチャが表示されなかったのはgazebo9.0）
[FormulaPi Basic Lane Tracking (ROS & Gazebo)](https://www.youtube.com/watch?v=rVsPItHA0xw)
ただ、先人に従いgazebo2.xにバージョン更新を試みるが、[ubuntu18.04LTSでgazebo2.2をビルドしようとするもビルドエラーが解決できず断念](https://qiita.com/seigot/items/71c9ac2d5cec7e83fdcf))

# 参考
[FormulaPi ROS Simulation Environment](https://www.wilselby.com/formulapi-ros-simulation-environment/)
[FormulaPi Basic Lane Tracking (ROS & Gazebo)](https://www.youtube.com/watch?v=rVsPItHA0xw)
新しめのmacOSでPHP 5.6を自前ビルドするとOPcacheがクラッシュする件の解決

表題の通りですが、私の手元のmacOS 10.14 (Mojave)でPHP 5.6.40を自前ビルドしたところ、OPcache有効のときに常にクラッシュする問題が発生しました。OPcacheを無効にすると何も問題ありません。

ググったところ、PHP 5.5/5.6のOPcacheの実装がイケていないせいでclang 6.0のみ期待通りに動かないようで、macportsでパッチが作られていました。

- https://github.com/macports/macports-ports/commit/6223b017e474c9bdcda958c618553136c681da8d

更に元ネタはこれかな…？

- https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=227723

この修正を入れたところPHP 5.6.40がOPcache有効でも死ななくなりました。
VBAにおけるファイル読み込み（UTF-8）

VBAでUTF-8のファイルを１行ずつ読み込む方法。
改行コードはCR+LF。
BOM付でも問題ないはず。

```vb
Dim buffer As String

With CreateObject("ADODB.Stream")
  .Charset = "UTF-8"
  .Open
  .LoadFromFile = "ファイルパス"

  Do Until .EOS
    '' -1:ファイル全読み込み、-2:1行ずつ読み込み
    buffer = .ReadText(-2)
  Loop

  .Close
End With
```
Rails Tutorialを咀嚼する【第1章ゼロからデプロイまで】後半

#1.4 Gitによるバージョン管理
■Git
バージョン管理ツール。Gitで都度都度作業を保存することで、やり直しができたりする。
addしてからcommitしてpushする。

■Bitbucket
git専門のホスティングサービス。GitHubの仲間。

#1.5 デプロイする
■Heroku
Paas。FFFTPとか使わず、開発したものをサーバーにアップロードすることができる。SQLiteが使えないため、若干厄介。

【演習】
１も２も大したことないので省略。

■('a'..'z').to_a.shuffle[0..7].join
ランダムなアルファベット8文字を表示してくれる。
aからzのアルファベットを配列に格納。
配列の順番をシャッフルする。
0から7番目（8個）まで取り出す。
結合して文字列にする。

【演習】
１も２も省略。

分ける必要はなかった。後で結合する。
【初心者向け】Vue+API Gateway+LambdaでサーバレスWebアプリを作った際に遭遇した問題

#概要
「AWSを使って、サーバレスアプリを作りたい！」と思い実践したのですが、Lambda関連で結構な壁があったので備忘がてら残します。

ハマりポイントは以下3つ。

- LambdaのResponseは特定のJSON形式でないとNGな話
- API連携の際に、CROS Policyでエラーになった話
- APIに認証を噛ませる際は、accessTokenではなくidTokenを使用する話

##LambdaのResponseは特定のJSON形式でないとNGな話

今回はフロントサイドはvueで作成、そこからAPIGatewayを通してLambdaのFunctionを呼び出すという構成でした。
このFunctionの返却の仕方は何でもよい訳ではなくJSONの形式が決まっています。


参考：https://aws.amazon.com/jp/premiumsupport/knowledge-center/malformed-502-api-gateway/

以下は、Lambdaを通してTwitterに投稿する関数の例です


```js

exports.handler = (event, context, callback) => {
    let date = new Date();
    twitter_client.post('statuses/update', {status: 'テスト投稿。from lambda ' + date},  function(error, tweet, response){
        if(error) {
            //エラーハンドリング
        }
        callback(null, JSON.stringify(response));
    });
};
```
関数単体はテスト時に動いても、上記のような正しい形式でないと、実際のフロントからの実行時には500エラーを返すので注意。


##API連携の際に、CROS Policyでエラーになった話　
「JSONを返す必要があるということはわかったぜ！これでオッケーや！」と思ったら、まだ駄目でした。
今度はフロント側でエラーになりました。。。ブラウザのF12コンソールでエラーの内容を確認すると
「Access to XMLHttpRequest at 'http:/~' from origin 'http://localhost:8080' has been blocked by CORS policy:
…」と書いてありました。
あぁーCROSね、なんかAPIGatewayで設定があった気がするなーと思いいろいろググります。

※CROSについては以下の記事が参考になりました。
https://qiita.com/att55/items/2154a8aad8bf1409db2b

結論から言うと、以下のように設定するのが正解でした。
レスポンスのヘッダーに
Access-Control-Allow-Headers　（使用するHeadersの値を追加）
Access-Control-Allow-Origin　（許可するリソースを追加）
Access-Control-Allow-Credentials　（これはなくてもいいかも）
Access-Control-Allow-Methods　（必要なメソッドを追加）
を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/0005f690-cac8-3cd4-03fd-0a5fa5f9135e.png)

lambdaの関数のレスポンスに直接書いているやり方もありましたが、
調べて実際に動かしたところこれでも大丈夫。（ケースバイケースだが多分ほとんどの場合これがベターな気がする）

##APIに認証を噛ませる際は、accessTokenではなくidTokenを使用する話
これはハマったというほどではなかったが、少し勘違いがあったので記載。
上記の問題でAPI通信は問題なく通るようになったが、APIには認証をかけたほうがよい。

認証のかけ方もいくつか方法があるが、今回はcognitoユーザプールを使った。
※cognitoを使ったログイン機能を実装していることが前提です。

手順としては
1.APIgatewayのコンソールからAuthorizersを作成
2.使用するAPIに適用する
の2 STEEP(めちゃ簡単)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/960f8adb-9e05-330b-18e5-04854ca0b054.png)

フロントのコードは以下のような感じで実装

```js:App.vue
import { Auth } from 'aws-amplify'
import axios from 'axios'

let cognitoUser = await Auth.currentAuthenticatedUser()
this.signedIn = true
this.username = cognitoUser.username
let token = cognitoUser.signInUserSession.idToken.jwtToken;
console.log(cognitoUser.signInUserSession);

…中略…
APIfunction(){
        axios
          .get('APIのURL',
            {
              headers: {
                Authorization: token
              }
            }
          )
          .then(function (response) {
            // handle success
            console.log(response);
            alert("success");
            alert(response);
          })
          .catch(function (error) {
            // handle error
            console.log(error);
            alert("error");
            alert(error);
          })
    }

```
signInUserSessionの中にはaccessTokenという似たプロパティもあるが、こっちではなくidTokenを使用した点に注意。
※accessTokenでも認証機能を作ることはできるかも知れませんが、詳細は調査しきれず…（だれか知っている人がいたら教えてください…）


##まとめ
AWSを使いこなすまでの道のりは遠い…
一方で使いこなすと非常に便利だということも実感できた。前進あるのみ。
Ruby文字列操作いろいろ

#はじめに
Rubyの文字列操作メソッドを勉強するために解いた問題とその回答を記録として残す。

##問題1
"This" " is" " a" " pen"を"This is a pen"に変換しなさい。

##回答1

```ruby
"This" + " is" + " a" + " pen"
```

###補足
「+」は文字列を連結することができる。

##問題2
"BENZ, BMW, Audi"を["BENZ", " BMW", " Audi"]に変換しなさい。

##回答2

```ruby
"BENZ, BMW, Audi".split(",")
```

###補足
[ ]は配列を表す。
splitメソッドは文字列を分割することができる。
回答のように使用するとカンマで区切ることができる。

##問題3
"apple"を"Apple"に変換しなさい。

##回答3

```ruby
"apple".capitalize
```

###補足
capitalizeメソッドは最初の文字を大文字にすることができる。

##問題4
"qiita"を"atiiq"に変換しなさい。

##回答4

```ruby
"qiita".reverse
```

###補足
reverseメソッドは文字列を反転することができる。

##問題5
"Good morning"を"GOOD MORNING"に変換しなさい。

##回答5

```ruby
"Good morning".upcase
```

###補足
upcaseメソッドは小文字を大文字に変換することができる。

#引用
[Ruby 2.7.0 リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/class/String.html)
PHP mb_strimwidth関数

# 目的

- 便利そうな関数だったので自分用に使い方をざっとまとめてみる

# 前提情報

- 下記のサービスを用いて関数の振る舞いを確認した。
    - [https://paiza.io/ja](https://paiza.io/ja)

# 機能

- 文字列を丸めることができる。

# 例

- 下記にmb_strimwidth関数の例を記載する。文字を丸める数の指定は半角での指定になるので日本語文字列の3文字目で丸めたいなら丸め文字数を6と指定する必要がある

    ```php
    mb_strimwidth(丸めたい文字列, 文字列の開始位置, 開始位置から何文字で丸めるか, 丸めた後の文字列の最後に追加される文字);
    ```

 # 具体例

- 「日本の朝は酢豚とビール」という文字列の全角5文字目(半角10文字目)で丸める場合は下記の様に記載する。(ちなみに「日本の朝は酢豚とビール」という言葉は周期表の15属を縦に覚える時の語呂合わせである。)

    ```php
    echo mb_strimwidth('日本の朝は酢豚とビール', 0, 10);
    ```
- 上記の文字列丸めを実施した後に「...」を付与する場合は下記の様に記載する。カンマを語尾に三つ追加するので丸める文字数の指定も半角文字3文字分追加する。

    ```php
    echo mb_strimwidth('日本の朝は酢豚とビール', 0, 13, '...');
    ```

# 参考文献

- [https://www.php.net/manual/ja/function.mb-strimwidth.php](https://www.php.net/manual/ja/function.mb-strimwidth.php)
解法メモ AtCoder Grand Contest 023 C - Painting Machines

公式解説ほど鮮やかではありませんが、別の方法でもそれほど面倒ではなく解けたので、その解法をメモします。

問題文：[AtCoder Grand Contest 023 C - Painting Machines](https://atcoder.jp/contests/agc023/tasks/agc023_c)

# 解法

ちょうど$K$個稼働したときに全部塗れるような順列の個数$g(K)$を数えられれば、答はそれにスコア$K$を重みづけ和することで求まる。

```math
\prod_K K*g(K)
```

以下では$g(K)$をいかに求めるかを考える。

全部塗れたときの稼働マシンと未稼働マシンの並び方を考えると、未稼働マシンは、

- 端にない
- 連続しない

という2つの条件を満たした状態になっている。しかし、逆に2条件を満たしても、ちょうど$K$個稼働したときに全部塗り終わったとは限らない。$K$個目を稼働する前に全部塗れていることがある。ここで公式解説では（$K$のときの値）－（$K-1$のときの値）とすることでちょうど$K$個のときの値である$g(K)$を求めているが、自分は思いつかなかった。

自分が考えたのは、直前である$K-1$個稼働時の状態。その時点では全部塗れておらず、次の1つを稼働すると全部塗れる状態である。これは以下の3通りである：

<dl>
<dt>(1) 端1つ未稼働</dt>
<dd>
左右端のマシンはどちらか一方だけ未稼働。端以外のマシンで、未稼働なものが連続することはない、という状態。次に端のマシンを稼働すれば全部塗れる。
</dd>
<dt>(2) 2連続未稼働</dt>
<dd>
左右端のマシンは両方稼働。未稼働マシンのうち2つが連続し、他は連続しない、という状態。次に2連続未稼働マシンのどちらかを稼働すれば全部塗れる。
</dd>
<dt>(3) 3連続未稼働</dt>
<dd>
(2)と同様で、未稼働マシンが2連続ではなく3連続のもの。次に3連続の中央のマシンを稼働すれば全部塗れる。
</dd>
</dl>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605081/40d9009f-c183-9477-9418-b63270827cde.png)

後は、上記(1)～(3)に該当する順列の個数（それぞれ$g_1(K),$ $g_2(K),$ $g_3(K)$とする）を数えればよい。$g_1(K)$～$g_3(K)$は以下の通り計算できる。以下、$K-1$個稼働時の未稼働マシンの数を$r=N-K$と置く。

```math
g_1(K) = 2 *  {}_{K-1}C_{r-1} * (K-1)! * 1 * (r-1)!
```

|式                  |     意味     |
|:------------------:|:------------------|
| $2$                |左右どちらの端が未稼働か|
| ${}\_{K-1}C\_{r-1}$|稼働マシンの隙間に未稼働マシンを挿入する組合せ|
| $(K-1)!$           |稼働マシン$K-1$個の稼働順序|
| $1$                |$K$番目に稼働するのは端のマシン一択|
| $(r-1)!$           |残りの未稼働マシンの稼働順序|

```math
g_2(K) = {}_{K-2}C_{r-1} * (r-1) * (K-1)! * 2 * (r-1)!
```

|式                  |     意味     |
|:------------------:|:------------------|
| ${}\_{K-2}C\_{r-1}$|稼働マシンの隙間に未稼働マシンを挿入する組合せ（連続する2つはまとめて1つと考える）|
| $r-1$              |未稼働マシンを2つ入れる場所の選択|
| $(K-1)!$           |稼働マシン$K-1$個の稼働順序|
| $2$                |$K$番目に稼働するのは2連続の未稼働マシンのどちらか|
| $(r-1)!$           |残りの未稼働マシンの稼働順序|

```math
g_3(K) = {}_{K-2}C_{r-2} * (r-2) * (K-1)! * 1 * (r-1)!
```

|式                  |     意味     |
|:------------------:|:------------------|
| ${}\_{K-2}C\_{r-2}$|稼働マシンの隙間に未稼働マシンを挿入する組合せ（連続する3つはまとめて1つと考える）|
| $r-2$              |未稼働マシンを3つ入れる場所の選択|
| $(K-1)!$           |稼働マシン$K-1$個の稼働順序|
| $1$                |$K$番目に稼働するのは3連続の中央のマシン一択|
| $(r-1)!$           |残りの未稼働マシンの稼働順序|

以上より、$g(K)=g_1(K)+g_2(K)+g_3(K)$で$g(K)$が求まり、答が求まる。

# 感想

場合分けの「3連続未稼働」に気づかず、かなりはまってしまいました。それでも体感的には他の橙diffより易しく感じました。
公式解説の「ちょうどK個＝K個以下-K-1個以下」という考え方はおそらく重要なので、これをスムーズに引き出せなかったところは反省点です。
[scala][play2.5.x] timeout処理を行う

## 前提
この記事はplayframework 2.5.x系を使っている。
最新バージョンである、2.8.xでは、実装が大きく異なるので要注意。


## 環境
- macOS Mojava 10.14.4
- Scala 2.11.1
- playframework 2.5.x


## 実装

標準ライブラリでできるタイムアウト処理としては、3通りできるっぽい。


## 1. play.api.libs.concurrent.Timeoutを使う

[公式ドキュメント](https://www.playframework.com/documentation/2.5.x/ScalaAsync)には、この実装方法が記載されているが、どうやっても、`play.api.libs.concurrent.Timeout`が見つからない（importできない）ので、諦めた・・・


## 2. Futures.timeoutを使う

[Futures.timeout](https://www.playframework.com/documentation/2.6.9/api/java/play/libs/concurrent/Futures.html)を使って、タイムアウト処理を実装します。

基本的に、playのドキュメントに記載している実装を行う

```scala

val response: Future[Int] = Future(1)
val timeoutFuture = Futures.timeout("timeout", 1000L, TimeUnit.MILLISECONDS).asScala

Future.firstCompletedOf(Seq(response, timeoutFuture)).map {
  case message: String => { // タイムアウト時の処理 }
  case value: Int => {// 正常時の処理}
}

```

`Futures.timeout`は、Javaのライブラリなので、asScalaメソッドでscalaのコードに変換する必要がある。
`firstCompletedOf`メソッドは、引数に受け取った`Future`の中で一番初めに処理が終わった物を返すメソッドである。

### 参考

- https://www.playframework.com/documentation/2.6.9/api/java/play/libs/concurrent/Futures.html



## 3. akka.pattern.afterを使う

2で利用したライブラリはJavaのライブラリなので、scalaで書かれているライブラリで実装してみる。
調べてみると`play.api.libs.conccurent.Promise`での実装方法が多くヒットする。

しかし以下のように、`play.api.libs.conccurent.Promise`のtimeoutメソッドを使おうとすると、play2.5からは、`akka.pattern.after`を使うように警告が出る。


```scala:Promise.timeout

@deprecated("Use akka.pattern.after(duration, actorSystem.scheduler)(Future(message)) instead", since = "2.5.0")
  def timeout[A](message: => A, duration: scala.concurrent.duration.Duration)(implicit ec: ExecutionContext): Future[A] = {
    timeout(message, duration.toMillis)
  }
}
```

akka.pattern.afterを使ってタイムアウト処理を実装してみる。

```scala:akka.pattern.after

class Test @Inject()(actorSystem: ActorSystem) {
  val delayed = akka.pattern.after(FiniteDuration(500L, TimeUnit.MILLISECONDS), actorSystem.scheduler)(Future.failed(new TimeoutException("timeout")))
  val bucketTypeFuture = Future(1)
  try {
    Future.firstCompletedOf(Seq(delayed, intFuture)).map {
      case number: Int => // 正常時の処理
      case _ => // 正常だが、意図しないレスポンスの場合の処理
    }
  } catch {
    case e: TimeoutException =>
      logger.info(e.getMessage)
      // タイムアウト時の処理
  }
}

```

基本的に2と同じような実装内容になっている。



### 参考

- https://doc.akka.io/docs/akka/current/futures.html?language=scala#After
- https://github.com/playframework/playframework/issues/6400
IDSとIPSの違い

ファイアウォールだけでは防ぐことができないネットワークへの不正侵入や情報漏洩への対策としてとられるシステムのこと。

#IDSとは？

- **I**ntrusion **D**etection **S**ystemの略で、異常を検知したらシステム管理者にメールなどで通報する。

#IPSとは？

- **I**ntrusion **P**revention **S**ystemの略で、即時に異常な接続を遮断すると共に、システム管理者にメールなどで通報する。

#####※ どちらも共通するのは、外部からの不正なアクセスや普段と違う異常な通信の発生(通信量、通信種別、振る舞いなど)、内部からの情報漏洩などの検知や対策に用いるソフトウェアのことである。

IDSやIPSで異常を検知するアプローチの方法にはいかの２種類がある

- **「シグネチャによる不正検出」**・・・あらかじめ登録されている攻撃パターンと類似性が高い時に、それを異常とみなしてアクションを起こす方式。

- **「通常と違う状況を察する異常検知」**・・・登録パターンが不要で、道の攻撃を検出できる。
外部結合子について

#外部結合子について

###外部結合子とは
WHERE句の条件式において結合したいテーブルの列に「（+）」を付けることで、OUTER JOINと同じように外部結合を行える。

###Oracleでは非推奨


非推奨の外部結合演算子(+)
https://docs.oracle.com/cd/E16340_01/doc.1111/b55937/cep.htm#BABJBBIH

>『Oracle CEP CQL Language Reference』の比較条件に関する項には、非推奨の外部結合演算子(+)について記載されています。(+)結合演算子は使用しないことをお薦めします。後述するLEFT OUTER JOINおよびRIGHT OUTER JOIN構文を使用してください。

互換はまだあるようですが、いずれ使えなくしていくという流れがあるかと。
なので今後(+)は使用せず、OUTER JOIN で書き換えておいた方が無難。


###外部結合子(+)からOUTER JOINに書き換え

右手に外部結合子があった場合　→　LEFT JOIN
左手に外部結合子があった場合　→　RIGHT JOIN

すべてこうであるとは言えないので実際のSQL文を確認しておくこと。
CentOS8でTomcat8の自動起動設定で2度ハマった話

#概要
掲題の件で1度解決したが、再度別の環境で同じ問題に遭遇し、記録をとっていなかったがために、2時間格闘してしまい、今後3度目の過ちを繰り返さないようメモ。

#環境
- CentOS8.2
- OpenJDK8
- Tomcat8.0

#うまくいかない場合
(https://weblabo.oscasierra.net/installing-tomcat8-centos7-1/) にある例の通りに/etc/systemd/system/tomcat.serviceを作成した場合、うまくいかない。


```
File Edit Options Buffers Tools Help
[Unit]
Description=Apache Tomcat 8
After=network.target

[Service]
User=tomcat
Group=tomcat
Type=oneshot
PIDFile=/usr/java/tomcat8/temp/tomcat.pid
RemainAfterExit=yes

ExecStart=/usr/java/tomcat8/bin/startup.sh
ExecStop=/usr/java/tomcat8/bin/shutdown.sh
ExecReStart=/usr/java/tomcat8/bin/shutdown.sh;/usr/java/tomcat8/bin/startup.sh

[Install]
WantedBy=multi-user.target
```

#うまくいかない場合に出るエラー
ちなみに/usr/java/tomcat8/bin/startup.sh を手動で実行すると問題なく動作する。

```
[root@localhost ~]# systemctl start tomcat
Job for tomcat.service failed because the control process exited with error code.
See "systemctl status tomcat.service" and "journalctl -xe" for details.

8月 11 23:47:39 localhost.localdomain systemd[1]: Starting Apache Tomcat 8...
-- Subject: Unit tomcat.service has begun start-up
-- Defined-By: systemd
-- Support: https://access.redhat.com/support
--
-- Unit tomcat.service has begun starting up.
 8月 11 23:47:39 localhost.localdomain systemd[2079]: tomcat.service: Failed to execute command: Permission denied
 8月 11 23:47:39 localhost.localdomain systemd[2079]: tomcat.service: Failed at step EXEC spawning /usr/java/tomcat8/bin/startup.sh: Permission denied
-- Subject: Process /usr/java/tomcat8/bin/startup.sh could not be executed
-- Defined-By: systemd
-- Support: https://access.redhat.com/support
--
-- The process /usr/java/tomcat8/bin/startup.sh could not be executed and failed.
--
-- The error number returned by this process is 13.
 8月 11 23:47:39 localhost.localdomain systemd[1]: tomcat.service: Main process exited, code=exited, status=203/EXEC
 8月 11 23:47:39 localhost.localdomain systemd[1]: tomcat.service: Failed with result 'exit-code'.
 8月 11 23:47:39 localhost.localdomain systemd[1]: Failed to start Apache Tomcat 8.
-- Subject: Unit tomcat.service has failed
-- Defined-By: systemd
-- Support: https://access.redhat.com/support
--
-- Unit tomcat.service has failed.
--
-- The result is failed.

```

#うまくいく場合

https://stackoverflow.com/questions/53994521/tomcat-8-on-centos-7-does-not-start-as-service-but-it-starts-manually を参考にするとよい。

最終的にうまくいった設定。上のURLにも記載されているが、結局WorkingDirectoryが怪しい？

```/etc/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat 8
After=network.target

[Service]
Type=forking
WorkingDirectory=/usr/java/tomcat8/bin

ExecStart=/bin/bash /usr/java/tomcat8/bin/catalina.sh start
ExecStop=/bin/bash /usr/java/tomcat8/bin/catalina.sh stop

User=tomcat
Group=tomcat

[Install]
WantedBy=multi-user.target
```
レポート作成にMac版Tableau Desktopを利用する理由

#貼り付ける形式がプラットフォームで異なる
Tableauで作成したvizをPowerPointやWordに貼り込む際には、必ずMacで作業します。理由は、ダッシュボードをコピーして書類にペーストするときにPDFを選択できるからです。
Tableauの実装が違うのではなく、OSのクリップボードの違いによるものと思います。

##Mac版ではvizをPDFで貼り付けられる
「ダッシュボード＞イメージのコピー」でクリップボードにコピーします。

![スクリーンショット 2020-08-11 23.41.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620713/859d66d8-ad4b-6bfd-84e5-88eef53b4eba.png)

PowerPointで「形式を選択してペースト」を実行すると、PDFが選択できます。

![スクリーンショット 2020-08-11 23.09.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620713/8620edf7-ec48-7cfe-7a61-fb5bc49762d9.png)

##Windows版で貼り付けられるのはイメージのみ

Windows版でダッシュボードをコピーし、形式を選択してペーストしようとしたときには、画像しか選択できません。

![スクリーンショット 2020-08-11 23.29.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620713/0d76550a-1994-ba3f-bef7-73004b669309.png)

#PDFで貼り付ければ高精細に印刷できる
上記のようにMacで作業してvizをPDFで貼り付けた場合には、線画（ベクターグラフィックス）となります。画面で見る分には線画でも画像でも大差なくとも、vizを大きく印刷すると線画と画像の差は歴然です。