OmniAICreator/Qiita-1.07M huggingface dataset:
【GAS】Googleドライブ：特定アカウントの共有ドライブアクセス権一括削除

# はじめに
本記事は、Google Workspaceを利用している組織のシステム管理者が、
Googleドライブにおいて、特定アカウントの共有ドライブのアクセス権を
一括で削除する手順について説明します。

# 実行結果
![execlog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529154/7c3789f2-939b-1a76-97aa-b8ca28622fcc.png)
※上図に登場する団体・名称等はすべて架空のものです。
# 事前準備
1. 対象のすべての共有ドライブ対し、システム管理者（スクリプト実行者）を
「管理者」として追加します。<br>
[[Google Workspace管理コンソール]](https://admin.google.com/) → [アプリ] → [Google Workspace] → [ドライブとドキュメントの設定] → [共有ドライブの管理] → 対象の共有ドライブの[メンバーを管理] → システム管理者のアカウントを入力 → [管理者]を選択 → [共有]
![AdminConsole.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529154/479f2f91-745a-575f-244b-3de85fc2739c.png)

2. Apps Scriptにて「新しいプロジェクト」を作成し「Drive API」を追加します。<br>
[[Apps Script]](https://script.google.com/home) → [新しいプロジェクトを作成] → サービス[+] → [Drive API] → [追加]
![AppsScript.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529154/a89e2e01-9c08-25dd-a948-fa05258c444f.png)

# スクリプト
定数「email_adr」の値として、対象アカウントのメールアドレスを入力してください。
初回実行時はプロジェクトへの承認が求められますので、許可してください。

```javascript:script.gs
// アクセス権を一括削除するアカウントのメールアドレスを入力
const email_adr = "xxx@hogehoge.com"

const query_param = {
  "supportsAllDrives" : true,
  "useDomainAdminAccess" : true
}

let drv_list, drv_id, drv_name, drv_token;
let prm_list, prm_id;

function myFunction() {
  do {
    drv_list = Drive.Drives.list({
      maxResults : 100,
      pageToken : drv_token,
      useDomainAdminAccess : true
    });

    for (let i = 0; i < drv_list.items.length; i++) {
      drv_id = drv_list.items[i].id;
      drv_name = drv_list.items[i].name;
      prm_list = Drive.Permissions.list(
        drv_id, query_param
      );

      for (let j = 0; j < prm_list.items.length; j++) {
        if (prm_list.items[j].emailAddress === email_adr) {
          prm_id = prm_list.items[j].id

          Drive.Permissions.remove(
            drv_id, prm_id, query_param
          );
          console.log("Permission removed : " + drv_name);
          break;
        }
      }
    }

    drv_token = drv_list.nextPageToken;
  } while (drv_token);
}
```

# 参考
Drives: list  |  Drive API  |  Google Developers
https://developers.google.com/drive/api/v2/reference/drives/list

Permissions: delete  |  Drive API  |  Google Developers
https://developers.google.com/drive/api/v2/reference/permissions/delete

# 注
上記APIリファレンスでは、アクセス権（「Permissions」リソース）の削除に
「delete」メソッドが用いられていますが、うまく動作しませんでした。
Apps Scriptのエディタでは、下図のとおり「remove」メソッドがサジェストされるため、
上記スクリプトはこちらで記述しました。

![saggest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529154/e964b0dd-8310-e9d2-3d4e-0d83385bfc8c.png)
画面文字コードがShift_JIS の場合、FormData を使ったファイルアップロードでファイル名が文字化けする

ので、FormData の第3引数に encodeURIComponent したファイル名を設定、

```html:test.html
<input type="file" id="file" />

<script>
let file = document.querySelector("#file");
let body = new FormData();
body.append("file1", file.files[0], encodeURIComponent("日本語.jpg"));
fetch("upload.php", {
    method: "POST",
    body: body,
}).then(function(res){
// 以下略...
</script>
```

受け側で urldecode して対応。

```php:upload.php
<?php
$fileName = urldecode($_FILES["file1"]["name"]);
echo $fileName; // 日本語.jpg
```
【Visual Studio Code】置換を使って特定条件で改行する方法（初心者向け）

# これはなに
Visual Studio Codeを使って、特定条件でテキストデータを改行する方法。


筆者は今までサクラエディタを使ってましたが、WindowsからMacに変えたら使えなくなったので、
Visual Studio Codeでテキストデータの一括置換をしてみました。
忘れそうなので、備忘録として残します。（サクラエディタも同じやろがい）

# 今回やりたいこと

アンケートで複数回答の項目がコンマ区切りで同一セルに内包されているため、
回答項目毎にセルを分けて一列に整理したい。
なので、テキストファイルの`,`を一括置換で改行できたらOK。


# まずはVisual Studio Codeをダウンロードする

Mac OSでのダウンロード方法は以下の記事にまとまっていました。

https://qiita.com/watamura/items/51c70fbb848e5f956fd6

# 早速、VSCodeを使って一括置換で改行する

`Cntrol`+`Shift`+`H`で置換のタブを開きます。

![スクリーンショット 2022-10-13 16.27.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554608/28bc0327-316e-0e2a-fb54-afcbcc56e0d1.png)

検索タブに「`,`」と入力し、置換タブに「`\n`」と入力します。
この際、検索タブの右横にある3つのアイコンのうち一番右端のアイコン`.*`をクリックして正規表現をONにします。

![スクリーンショット 2022-10-13 16.28.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554608/f9276e1a-afea-e415-cc16-981ee823308f.png)

一括で改行されました。便利〜
![スクリーンショット 2022-10-13 16.29.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554608/dd4ed76b-f2af-8260-54a3-6ce63df8fc95.png)


# おまけ

ちなみに、Macでサクラエディタを使う方法もあるみたいです。
使い慣れたサクラエディタを使いたい方はこちらの記事をご参照くださいませ〜

https://qiita.com/pe-suke/items/ec59569356467976e1a5
Lightship ARDKのマルチプレイやってみた

こんにちは。[Kuni](https://twitter.com/Kuni29292)と申します。今回は、[イワケンラボ](https://iwakenlab.jp/)のブログリレー企画で書いた記事になります。

# 初めに
今回はNiantic社が提供している、[Lightship ARDK](https://lightship.dev)を使用しました。その中の機能の一つであるマルチプレイ機能を実装しました。
参考にさせていただいた記事はこちらです。
ARDKでマルチプレイゲームを作ってみよう1~4
※予定ではこちらの記事をもとに作品を一つ製作する予定でしたが、Androidのgradleエラーに大幅に時間を取られてしまいこちらの記事を実装するだけで終了してしまいました。その点ご了承ください。

https://note.com/thedesignium/n/n98ea44f24c09

こちらが今回の合宿で発表した資料です。

https://docs.google.com/presentation/d/19Th9-DK9mH7TampdpYLGNGLmwbM8JpFFNE2cVv9uloU/edit#slide=id.g166c8a7db88_0_0



# 概要
Lightship ARDKとはNiantic社が提供している。UnityでAR開発を行うためのSDKです。
こちらのSDKを使用することで簡単にAR体験の出来る作品を作成できます。

# 結果

<iframe width="455" height="809" src="https://www.youtube.com/embed/ihDPNv_y7OQ" title="ARDK Demo" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 最後に
今回の開発でドキュメントの実装のみで終わってしまい、自分自身の成果として何かを作り上げるということが途中で終わってしまったことが残念です。なので、今回の実装で勉強したことをもとにこれから良い作品を作り上げられるよう精進していきます。

そして、今回の開発合宿では多くの方にサポートしていただきました。とても楽しく開発でき、ラボのメンバーとの交流が出来たりととても楽しかったです。本当にありがとうございました。

ドキュメントを作成することが苦手で拙い文章になってしまいましたが、最後までお読みいただきありがとうございます。
Maya python export ass

```Python
def ExportAbc(selection, start, end, save_name):
    # AbcExport -j "-frameRange 1 120 -dataFormat ogawa -root |locator1 -root |locator2 -file D:/test.abc"
    root = ""
    for i in selection:
        root += " -root %s" % (i)

    command = "-frameRange " + str(start) + " " + str(end) +" -uvWrite -worldSpace " + root + " -file " + save_name
    cmds.loadPlugin( 'AbcExport.mll' )
    cmds.AbcExport ( j = command )
```

https://github.com/aizwellenstan/python_maya_export_ass
PowerShell 7.2.6 で ClosedXML を使う前の準備

## 経緯

6, 7 年まえぐらいに、ClosedXML を少し触ったことがありました

[PowerShell で ClosedXML を使って Excel ファイルを作成する](https://1bed.allright.life/?p=2206)

それから時代は変わっていき、今は PowerShell Core 全盛時代みたいです

どうせなら PowerShell Core で ClosedXML を利用してみようと思い、環境構築を行って
いましたが勘違いも有りハマってしまったので、また同じことを起こさないようにというメモです

ちなみに、当初 NuGet で作っていたのですが、色々考えて結局パッケージをダウンロードして、
DLL だけを使う方法にしました

## 環境

* Windows 10 Pro
* PowerShell 7.2.6

## 構築手順

### 各パッケージのダウンロード

2022年10月10日現在で、ClosedXML の最新バージョンは 0.96.0 です

依存関係は [Dependencies](https://www.nuget.org/packages/ClosedXML/#dependencies-body-tab) で確認でき、利用するのは .NETStandard 2.0 です

DocumentFormat.OpenXml は更に依存関係があったので、下記のパッケージをダウンロードすれば OK でした

* ClosedXML: 0.96.0 -> [DownLoad](https://www.nuget.org/api/v2/package/ClosedXML/0.96.0)
  - DocumentFormat.OpenXml: 2.16.0 -> [DownLoad](https://www.nuget.org/api/v2/package/DocumentFormat.OpenXml/2.16.0)
    - System.IO.Packaging: 4.7.0 -> [DownLoad](https://www.nuget.org/api/v2/package/System.IO.Packaging/4.7.0)
  - ExcelNumberFormat: 1.1.0 -> [DownLoad](https://www.nuget.org/api/v2/package/ExcelNumberFormat/1.1.0)
  - Microsoft.CSharp: 4.7.0 -> [DownLoad](https://www.nuget.org/api/v2/package/Microsoft.CSharp/4.7.0)
  - System.Drawing.Common: 4.5.0 -> [DownLoad](https://www.nuget.org/api/v2/package/System.Drawing.Common/4.5.0)

### 保護の解除と DLL の取り出し

ダウンロードしたファイルは保護されているため、解除する必要があります
nupkg ファイルを右クリックして、プロパティを開き、セキュリティで **[許可する]** にチェックを入れて、[ OK ] ボタンを押します

[![](https://1bed.allright.life/wp-content/uploads/2022/10/20221010_01.png)](https://1bed.allright.life/wp-content/uploads/2022/10/20221010_01.png)

次に、拡張子を zip に変えて展開して、 `lib\netstandard2.0` の中にある DLL ファイルを取得します

これをダウンロードしたファイル全てでおこないます

### 動作確認

先に取得した DLL をフォルダに入れて、そこに example.ps1 を作成して保存、
PowerShell 7.2.6 で実行します

```powershell
Add-Type -Path "$PSScriptRoot\ClosedXML.dll"
Add-Type -Path "$PSScriptRoot\DocumentFormat.OpenXml.dll"
Add-Type -Path "$PSScriptRoot\System.IO.Packaging.dll"
Add-Type -Path "$PSScriptRoot\ExcelNumberFormat.dll"
Add-Type -Path "$PSScriptRoot\Microsoft.CSharp.dll"
Add-Type -Path "$PSScriptRoot\System.Drawing.Common.dll"

$workBook = New-Object ClosedXML.Excel.XLWorkbook

$workSheet = $workBook.Worksheets.Add("Sheet1")
$workSheet.Cell("A1").Value = "Hello world";
$workBook.SaveAs("$PSScriptRoot\helloworld.xlsx")

$workSheet = $null
$workBook = $null
```

作成された Excel を開くと、A1 のセルに Hello world と表示されています
[![](https://1bed.allright.life/wp-content/uploads/2022/10/20221010_2.png)](https://1bed.allright.life/wp-content/uploads/2022/10/20221010_2.png)

## 考察

今見ると、どこで引っかかったんだよ... ってレベルで単純で恥ずかしいですが、
これで環境が作れたので次に進んで汚名挽回を図ります（誰に？）
通信プロトコル

# TCP/IPのプロトコルの種類
## PPPoE(PPP over Ethernet)
```メールの送信```及び```サーバー間で電子メールを転送```する。

## インターネット層のプロトコル
### IP（Interntet　Protocol)
ネットワークを介してデータ転送を行うための```ルーティング（経路選択）```や```中継機能```を提供し、２つのノード間でコネクションレス型のデータ型のデータ伝送を実現する。
```目的のノードをまでのデータ転送はベストエフォート(最善の努力をするが、確実な補償はできない）```

### ARP(address Resolution Protocol)
```IPアドレスからMACアドレスを求める```ためのプロトコル
指定したIPアドレスを持つノードのMACアドレスを、同一ネットワーク内にブロードキャストする。

#### ブロードキャストとは？
全てのノードに対して問合せを行う

* ブロードキャストとは、放送（する）という意味の英単語で、通信・ネットワークの分野では```ネットワークに参加するすべての機器に同時に信号やデータを送信```することを意味する。
    出典 https://e-words.jp/w/%E3%83%96%E3%83%AD%E3%83%BC%E3%83%89%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88.html#:~:text=%E3%83%96%E3%83%AD%E3%83%BC%E3%83%89%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88%20%E3%80%90broadcast%E3%80%91%20%E3%83%96%E3%83%AD%E3%83%BC%E3%83%89%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%20%2F,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%92%E6%84%8F%E5%91%B3%E3%81%99%E3%82%8B%E3%80%82

#### ノードとは？
ノード（node）とは、```「結び目」「集合点」「節」```といった意味です。コンピュータネットワークは、点（装置）とそれを結ぶ線（伝送路）で表すことができます。このときの「点」を「ノード」といい、```コンピュータやルータ、プリンタ```などがノードになります。
出典 https://www.keyence.co.jp/ss/general/iot-glossary/node.jsp

## トランスポート層のプロトコル
### TCP(Transmission Control Protocol)
データを送信する前に、```送信側と受信側で論理的な通信路を確立```するコネクション型の伝送を行う。
OSIの第４層と同様に、```上位層に対して個々の通信網に依存しない```高品質な通信路を提供する。

### UDP(User Datagram Protocol)
コネクションレス型の伝送を行う。
これは```信頼性よりも速度を重視```したものでデータが開いた絵に届いたかと言う```確認を行わない```。

#### UDPを使用するプロトコル
* DNS
* DHCP
* SNMP
* NTP

## FQDN(Fully Qualified Domain Name: 完全修飾ドメイン名)
```ドメイン名やサブドメイン名をなどを省略せず```に記述した形。
これに対し、ホスト名などを省略した形を複数持つことも可能。
```どちらもDNSによりグローバルIPアドレスと関連```づけられる。

# 関連記事
https://qiita.com/masatom86650860/items/294c3d47194863ced945

# 出典 
https://gihyo.jp/book/2022/978-4-297-12375-8
Google Apps ScriptでFolder内のファイルを再起的に扱える関数を作成した

### 元の関数

```js:recursive.gs
// rootFolder: Folderクラス
// type: both, onlyFolder, onlyFile
// func: function(object: Folder or File, type: "Folder" or "File")
function recursive(rootFolder, type, func) {
  const files = rootFolder.getFiles()
  const folders = rootFolder.getFolders()

  if(type=="both" || type=="onlyFile"){
    while(files.hasNext()){
      func(files.next(), "File")
    }
  }

  while(folders.hasNext()){
    const folder = folders.next()
    if(type=="both" || type=="onlyFolder") { func(folder, "Folder") }
    recursive(folder, type, func)
  }

}

```

### 使い方

```js:listAllFileAndFolder
function listAllFileAndFolderInFolder(folder){
  recursive(folder, "both", function(folderOrFile, type){
      console.log(type) // Folder or File
      console.log(folderOrFile.getName())
      console.log(folderOrFile.getUrl())
  })
}

```
virtualboxでMacOS Catalinaをインストール

VMwareでMacOSが使えることを知り、VMwareでMacOS Catalinaを使えるようにしました。
Mac拡張フォーマットされたUSBメモリをマウントできたので助かりました。
でも、APFSでフォーマットされた外付けSSDが認識されずネットで検索しました。

仮想マシンでは、EFIの関係がありAPFSが使えないという記事を見つけました。

https://book.mynavi.jp/macfan/detail_summary/id=87980

でも諦めきれず、VMwareでAPFSのファイルシステムを使う方法を検索し続けました。
そして、この記事を見つけました。

https://andrewdoering.org/blog/2018/03/27/vmware-esxi-macos-10-13-apfs/

記事に従って少し進めたのですが、使うツールのビルドでvisualstudioを使うとソースコードを読み諦めました。
私は、VSCODEを使っているからです。
そして、
そんなときに、ふとVirtualBoxでMacOSを使えることを思い出しました。
そして検索していたら、VirtualBoxがAPFSに対応したことを知りました。

それで、この手順でVirtualBoxでMacOSの仮想マシン作りを始めました。

https://qiita.com/wancom/items/1798c1080c5c5ad5a22e

ただ、この記事だけでは、MacOSのインストールができませんでした。
下記の記事のコードが、必要でした。

https://daimaohsx.dip.jp/wordpress/2021/04/30/easy-how-to-install-and-enjoy-macos-big-sur-in-virtualbox-on-windows/

上記の記事で、インストール前にハードディスクのフォーマットをしましょうとあります。
でも事前にフォーマットは、できません。

MacOSのインストールディスクが起動したときに、macOSユーティリティが起動します。
その中のメニューを使って、ディスクのフォーマットをしてください。
![スクリーンショット 2022-10-13 140438.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/8a49e49d-dc60-cedf-448e-725f326fdb11.png)

このメニューの中のディスクユーティリティを、起動してください。
![スクリーンショット 2022-10-13 140251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/fab001d1-c019-8a23-4a7b-b6f43ebff6e3.png)

消去を選んでください。
![スクリーンショット 2022-10-13 140349.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/6869c7e3-dfbe-01b2-b660-339107a76f17.png)

フォーマットが終わったら、この画面を閉じてください。
そして、ユーティリティのメニューに戻り、インストールしてください。
![スクリーンショット 2022-10-13 140504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/b1c8b847-d1fc-84d6-a9d8-594a7e9c9324.png)

## ポイント

https://daimaohsx.dip.jp/wordpress/2021/04/30/easy-how-to-install-and-enjoy-macos-big-sur-in-virtualbox-on-windows/
上記の記事で、”「ハードディスクのファイルタイプ」はVHD（Virtual Hard Disk）に変更します。”
という部分は、気を付けてください。
ちゃんとVHDに、設定してください。

コマンド入力の際は、VirtualBoxを閉じてコマンドプロンプトを管理者権限で、実行してください。

この２点は、気を付けた方がよいです。
油断しがちな点だと思います。

## MacOSは、アップルが販売するMacOSがインストールされたパソコンで、利用しましょう。
ファイルシステムのASPFのこともありMacOSは、アップルが販売するMacOSが起動しているパソコンで使いましょう。
仮想環境では、MacOSの起動ドライブを使うことは、できません。

MacOSの利用規約が、改定されているそうです。
仮想環境については、最大コピー２台まで使ってもよいそうです。

下記の記事を読み、知りました。

https://book.mynavi.jp/macfan/detail_summary/id=87980

## MacOS拡張フォーマットでフォーマットしたUSBドライブは使えました。
MacOS拡張フォーマットでフォーマットしたUSBメモリーは、マウントできました。
でもAPFSファイルシステムでフォーマットされた外付けSSDは、認識されません。

そのためAPSFでフォーマットしたドライブを使いたい場合は、MacOSが動いているMacを利用しましょう。
RSpec(Ruby on Railsのテストコードを書くために用いられるGem)の導入

# はじめに
RSpec導入の流れを忘れないために記録に残す。

# RSpec導入の流れ
## 1.Gemの導入
    # Gemfile内
    group :development, :test do
      # Call 'byebug' anywhere in the code to stop execution and get a debugger console
      gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
      gem 'rspec-rails', '~> 4.0.0'  ⇦この行を追記
    end

    % bundle install

## 2.RSpecの設定
    % rails g rspec:install
       
    <ターミナルで以下が表示されれば問題ない>
    create  .rspec
    create  spec
    create  spec/spec_helper.rb
    create  spec/rails_helper.rb



    # .rspec内
    --require spec_helper
    --format documentation  ⇦この行を追記
    （テストコードの結果をターミナル上に可視化するための記述）



    # .spec/rails_helper.rb内
    # 中略
    I18n.locale = "en"　　⇦この行を追記
    ※RSpec.configure do |config|　〜　end　の外に記載。
    （エラーメッセージを英語表記にするため）
    
    RSpec.configure do |config|
    
    # 中略
    
    end
link_toでViewからControllerに値を渡す


## 環境
- Rails5.2
- Slim
- Bootstrap

## はじめに
ViewからControllerに値（パラメータ）を渡す場合、Viewに配置したsubmitのボタンを押して、画面に入力した値をControllerにPOSTする方法以外に、link_toを使って、GETでControllerに渡す方法があります。link_toを使って、値（パラメータ）をControllerに渡す方法について、色々とやってみました。

## 内容
seikyusクラスにsyori1という名前のメソッドを作ります。そして、ルート情報を次のように作ります。link_toで値を渡すときは、POSTではなくGETで渡します。
```routes.rb
resources :seikyus do
    get :syori1,      on: :collection
end
```

「テスト」という値を、ViewからControllerに渡すには次のように記述します。
```index.html.slim
- test = "テスト"
= link_to "テスト１", syori1_seikyus_path(test)
```

Controllerの中で取得する場合は、次のように記述します。paramsでformatキーの中に「テスト」の値が入っています。
```seikyus_controller.rb
Rails.application.config.pri_logger.error(params[:format])
```

erbで書かれた内容をHTMLに置き換えると、次のようになっています。文字化けのように見える個所にはテストの値がセットされています。
```html
<a href="/seikyus/syori1.%E3%83%86%E3%82%B9%E3%83%88">テスト１</a>
```

パラメータには変数ではなく、文字列をダイレクトにセットしてもOKです。Viewでは値だけを受け渡しただけのように見えますが、内部的にはparamsハッシュのformatキーに「テスト」の値をセットして受け渡したということになっています。
```index.html.slim
= link_to "テスト２", syori1_seikyus_path("テスト")
```

受け渡せるパラメータは１つだけです。２つパラメータをセットしてもエラーにはなりませんが、第２引数は拾ってくれません。params[:format]には「aa」だけがセットされます。
```index.html.slim
= link_to "テスト２", syori1_seikyus_path("aa","bb")
```

複数の値を渡したい場合は、次のようにハッシュにすると、受け渡すことができます。
```index.html.slim
= link_to "テスト３", syori1_seikyus_path(group_id: 1, team_id: 2)
```

Controller側では、Viewで設定したハッシュのキーを指定して値を取り出します。
```seikyus_controller.rb
Rails.application.config.pri_logger.error(params[:group_id])
Rails.application.config.pri_logger.error(params[:team_id])
```

HTMLの中身を見ると、このように、値がブラウザからサーバーにGETされることになります。
```html
href="/seikyus/syori1?group_id=1&team_id=2"
```

Viewからハッシュで値を受け渡す場合、このような記述でもOKです。
```index.html.slim
= link_to "テスト４", syori1_seikyus_path(:group_id => 11, :team_id => 22)
```

ハッシュを変数にして受け渡してもOKです。
```index.html.slim
- aa = {"group_id" => 111, "team_id" => 222}
= link_to "テスト５" syori1_seikyus_path(aa)
```

## 参考
リンクの表示をsubmitボタンのような形式にした場合、classを指定するとボタン形式に変更することができます。
```index.html.slim
= link_to "テスト６", syori1_seikyus_path, class: "btn btn-primary"
```
Lambda(Go)とAuroraを接続するときにDataAPIとRDS Proxyがよくわからなかったのでまとめる

# はじめに

Lambda(Go)をServerlessFrameworkでデプロイして、次にAuroraを利用してデータ取得をしようとしたとき色々知識がなかったので苦戦しました

そこで、知識面で参考になりそうなことをまとめていきます

# なぜDataAPIかRDSProxyが必要なのか

まず最初に思ったのはなぜDataAPIまたはRDSProxyを経由してDBにアクセスしないといけないのかというのでした
Auroraにはエンドポイントがあるのでそれで直接アクセスでよいのではと考えました
しかし、Lambdaからやる場合は直接ではなく、どちらかを仲介したほうが良いです。

使う理由は「DBへの接続数が多くなってしまうのを防ぐため」です。接続プーリングをうまいことやってくれるようでした

https://www.sunnycloud.jp/column/20210502-01/

# 2つの違い

>Q. RDS Proxy と DataAPIの違いは何でしょうか？
A. RDS Proxy はデータベースへの接続をプールすることでバックエンドのRDSの負荷を軽減しつつ、コネクション作成のコストを軽減します。Data API はデータベースのコネクションではなくAPIを利用してクエリを実行できる機能です。

このように公式では説明があります

# DataAPIのメリット/デメリット

DataAPIは基本的にお金がかからないはずです
デメリットとしてはベータ版なのでまだ記事も少ないです
VPC内に置く場合はインターネット接続が必要なのでNATの用意が必要です

今回Goの接続は以下を参考にしました

https://github.com/krotscheck/go-rds-driver

```go:main.go
	conf := &rds.Config{
		ResourceArn: "DBクラスターのリソースARN",
		SecretArn:   "DBを紐づけたシークレット",
		Database:    "テーブル名",
		AWSRegion:   "ap-northeast-1",
		SplitMulti:  false,
		ParseTime:   true,
	}
	dsn := conf.ToDSN()

	DB, err = gorm.Open(mysql.New(mysql.Config{
		DriverName: rds.DRIVERNAME,
		DSN:        dsn,
	}), &gorm.Config{})
```

https://gorm.io/ja_JP/docs/connecting_to_the_database.html

# RDS Proxyのメリット/デメリット

RDS Proxyは料金が発生してしまうのでそこがデメリットです
エンドポイントはRDSと同じように使えるのでコードはいままで通りで動かせます

RDS ProxyとAuroraがしっかり疎通できているかのチェックには以下のコマンドが役立ちます

```
aws rds describe-db-proxy-targets --db-proxy-name $DB_PROXY_NAME
```

このコマンドで`UNAVAILABLE(PENDING_PROXY_CAPACITY)`は時間が解決してくれます。
`Targets`が`[]`のときは、RDS Proxyのターゲットが設定されてるか確認します

# 個人的につまづいたところ

今回GoのLambdaでGO SDKを利用してSESからメールを飛ばす処理があったのですが、パブリックサブネットに配置しても送信できないというトラブルがありました

https://ja.stackoverflow.com/questions/46688/vpc-%E3%81%AE-lambda-%E3%81%8B%E3%82%89%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%AF%E3%81%AA%E3%81%9C

この記事にある通りですが、LambdaにはパブリックIPがそもそもないため、インターネットゲートウェイを通して外部にアクセスすることはできないようです

なのでNATインスタンスを作成することでAPIをたたけるようにしました

# おわりに

Lambdaの環境を構築するのに3週間ほど使ってしまいましたが、Lambdaとは？というところからなんとか本番環境構築まで行うことができました

そこで知りたかった内容をこの記事にまとめましたので誰かの役に立つと嬉しいです

# 参考

https://aws.amazon.com/jp/blogs/news/onlineseminar-rds-lambda-doc-qa/

https://www.stylez.co.jp/columns/aws_aurora_serverless_including_the_latest_features_v2/

https://blog.ikedaosushi.com/entry/2019/05/26/205618

https://ja.stackoverflow.com/questions/46688/vpc-%E3%81%AE-lambda-%E3%81%8B%E3%82%89%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%AF%E3%81%AA%E3%81%9C

https://github.com/krotscheck/go-rds-driver

https://github.com/savaki/dapi

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy.troubleshooting.html

https://www.sunnycloud.jp/column/20210502-01/
ベアボーンDeskMini記録

当方の**初ベアボーン**です。簡単にパーツ構成を記載していきます。なお ~~数多のOSの変遷を経て~~ 現在は ~~ラインセスの微妙な~~ *Windows11*で稼働しております。

# コンセプト
2021年7月10日にパソコン工房さんで購入しました。パーツ合計で**50K円**ほどでした。当時の明細はありません。 ~~補償？入ってないと思う~~

- OSは決まっておらず、
- キビキビ動くコンパクトなパソコン
- MacMiniを意識？

という**イミフ**なコンセプトだったような記憶が有るような無いような感じです。

# パーツ構成
ほぼ全部[パソコン工房](https://www.pc-koubou.jp/)さんで揃えました。店員さんめっちゃ親切でした。

## 本体
[DeskMini H470/B/BB/BOX/JP](https://kakaku.com/item/K0001298437/)
- 当時は今より安く買えましたね。小さい筐体ですが手が入りやすく、後述しますが裏面にSSDを2.5インチなら2台搭載できるなどかなりの拡張性があります。

## OS
[Windows 7 Home Premium](https://kakaku.com/item/K0000042876/)
- え？なんで*Windows7*がここに出てきたの？と思ったあなたは偉いです。なんと、以前に(最終インストールから5年くらいは経つと思う)Thinkpadに入れたりNUCに入れたり ~~しまくっていた~~ このパッケージ版のライセンスが、Windows11で通ったのです。が、**絶対に真似しないでください。黒に限りなく近いグレーですので。**


## SSD メイン
[980 MZ-V8V500B/IT](https://kakaku.com/item/K0001340595/)
- OSをインストールしているメインのディスクです。特に問題ありません。なお、当時なんで*Gen3*ですよね。

- ヒートシンクは、[HM-21-SET](https://www.ainex.jp/products/hm-21-set/) あるいはアマゾンなら、[こちら](https://www.amazon.co.jp/dp/B07P7LL9VZ/)です。

## SSD サブ
[WD Blue 3D NAND SATA WDS500G2B0A](https://kakaku.com/item/K0000969847/)

- 筐体の底面に装着したものです。使用目的としては、[Dropbox](https://www.dropbox.com/)のフルオフライン同期です。Dropboxが240GBもあるので。停電、Dropbox側のトラブルのことなどを考慮すると、オフライン同期はとっておくべきです。

## メモリー
[CFD Selection D4N2666CM-8GR](https://kakaku.com/item/K0001324105/)
[D4N2666PS-8G](https://kakaku.com/item/K0001010909/)

- *8GB × 2枚*です。が、メーカー混成のこういうメモリー構成は悪手でしかありません。**真似しないでください。**

# 総評
*OS*が*Ubuntu* ↔ *Windows11*と何度か行き来しておりますが、*Windows11*は何度インストールしてもライセンスが通ります。摩訶不思議です。あと、*Ubuntu*だと、筐体底部のサブの*SSD*に*Dropbox*を入れると、ドライブごと見失ってくれます。これも摩訶不思議です。

現在は*Dropbox*のバックアップ、[MS office](https://www.microsoft.com/ja-jp/microsoft-365)関連をいじりたいとき、[PowerBI](https://powerbi.microsoft.com/ja-jp/)などで活躍してくれています。

なんだかんだいってメイン機に*最新のWindows*は必要ですから、今後も活躍してくれるでしょう。ライセンスに問題が生じたら、*Ubuntu*でも入れます。
iOSシュミレーターの実機(デバイス)を変えての検証

現在35モデル以上のデバイスを抱える`iPhone`ですが、`Flutter`で開発しているとディスプレイの大きさによって画像の調整が必要になるなど、それぞれで検証しないといけない状況がやってきます。`2022/10`現在の`iOS 16.0`で対応している実機だと、小さいサイズで`iPhone SE（第3世代）`の`4.7インチ`大きいサイズで`iPhone 14 Pro Max`の`6.7インチ`と２インチ(5.08cm)もの差があります。なので`4.7 / 5.4 / 6.1 / 6.7`の４機種を検証に当てると良いかと。

|機種|ディスプレイ(縦横)| 
|:-----------|------------:|
|iPhone 8|4.7インチ(11.938cm)| 
|iPhone SE（第3世代）|4.7インチ| 
|iPhone 12 mini|5.4インチ(13.716cm)|
|iPhone 8 Plus|5.5インチ(13.97cm)|
|iPhone X|5.8インチ(14.732cm)| 
|iPhone 13|6.1インチ(15.494cm)|
|iPhone Xs Max|6.5インチ(16.51cm)|
|iPhone 14 Pro Max|6.7インチ(17.018cm)| 

選択するデバイスがない場合は下記の要領で追加しましょう。
![スクリーンショット 2022-10-13 10.36.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/b951751d-61cc-97c4-3d46-23e067bdb9cc.png)

![スクリーンショット 2022-10-13 10.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/6d85ce3e-84b6-d3bd-e0f7-cb2b90a8999e.png)

![スクリーンショット 2022-10-13 10.38.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/2ae06b92-2391-d114-6a88-01b517fc7183.png)

![スクリーンショット 2022-10-13 10.38.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/088ae612-07ef-c169-5b14-caec5cfa7d73.png)
Gif でSlack のスタンプ作る時の備忘録

## 概要

完全な備忘録です。
SlackでGifスタンプを作りたいときに、サイズ問題で少し詰まったので書いておきます。

## 注意点

SlackでGifのスタンプを作りたい時は、以下のことに気をつけましょう。

- スクエアサイズ（正方形）にすること
- 画像サイズを小さくすること(32ピクセル x 32ピクセルとかでいいと思われ）
- フレーム（アニメーションの数）を小さくすること


## サイズによるエラー

Frameが多すぎたり、サイズが大きすぎると、

![Screen Shot 2022-10-13 at 15.02.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/d500d15e-7831-07a8-d6cd-fbdd8ccec0d8.png)

```
This image is a bit too big, even after resizing. A smaller file might help?
```

というようなエラーが出ます。


## Gif のリサイズ、間引きをするときの参考ツール

オンラインでいろいろGifのサイズとかいじる時は、いろいろなツールが転がってますが、

http://gifgifs.com/optimizer/

これをつかっとけば問題ないと思います。



## まとめ

今回は、SlackのスタンプをGifで生成するときに出くわしたエラーについて備忘録を書きました。


今回はこの辺で。


@kenmaro
インスタンス変数を用いて処理を効率化する

ログイン機能のアプリ作った際に、app/helpers/sessions_helper.rb
ファイルに以下のメソッドを定義しました。
```
module SessionsHelper
  def current_user
    @current_user ||@current_user = User.find_by(id: session[:user_id])
  end

  def logged_in?
    current_user.present?
  end
end
```
メソッドが呼び出されているviewファイル（app/views/layouts/application.html.erb）
```
<% if logged_in? %>
      <%= link_to "Profile", user_path(current_user.id) %>
      <%= link_to "Logout", session_path(current_user.id), method: :delete %>
 <% else %>
      <%= link_to "Sign up", new_user_path %>
      <%= link_to "Login", new_session_path %>
<% end %>
```
私はcurrent_userメソッドの`@current_user`がなぜインスタンス変数で定義されているかが分かりませんでした。`current_user`で定義したとしてもエラー等がなく、アプリは動きます。
しかし、メンターさん等の助けがあって、なぜ`@current_user`にしているか理由がわかりました。以下が詳細な説明になっています。

インスタンス変数とは
```
class A
  def b
    @a = 1
  end
  def c
    @a
  end
end
a = A.new
p a.b
p a.c

# 結果　@aが値を保持しています。
1
1
```
上記のような変数です。

app/helpers/sessions_helper.rbファイルの`current_user`メソッド内の式を説明します。
```
def current_user
	@current_user ||@current_user = User.find_by(id: session[:user_id])
end
```
上記の式は`@current_user`の中に値がなかった場合、`User.find_by(id: session[:user_id])`が実行されて、その結果が`@current_user`に入ります。
しかし`@current_user`の中に値があった場合は、`User.find_by(id: session[:user_id])`
は実行しません。

今回のケースはapp/views/layouts/application.html.erbファイルの中で、`current_user`メソッドが2回呼び出されています。インスタンス変数は値を保持することができるため、１回目で呼び出された時に、`@current_user = User.find_by(id: session[:user_id])`が行われ、2回目呼び出された時は、`@current_user`が値を既に持っているので、この処理（`User.find_by(id: session[:user_id])`）が行われません。
つまり、一回分処理が行われずに済んでいます。

ターミナル画面から確認しても処理が節約されている事がわかります。
app/helpers/sessions_helper.rbファイルで`@current_user`を使った場合
```
Started GET "/" for ::1 at 2022-10-13 14:42:22 +0900
Processing by SessionsController#new as HTML
  Rendering layout layouts/application.html.erb
  Rendering sessions/new.html.erb within layouts/application
  Rendered sessions/new.html.erb within layouts/application (Duration: 1.6ms | Allocations: 591)
[Webpacker] Everything's up-to-date. Nothing to do
  Rendered shared/_header.html.erb (Duration: 0.1ms | Allocations: 39)
  User Load (1.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
  ↳ app/helpers/sessions_helper.rb:3:in `current_user'
  Rendered shared/_footer.html.erb (Duration: 0.2ms | Allocations: 38)
  Rendered layout layouts/application.html.erb (Duration: 81.0ms | Allocations: 3952)
Completed 200 OK in 97ms (Views: 80.6ms | ActiveRecord: 1.4ms | Allocations: 4465)
```
sqlが一度しか実行されていません。
GitHubでソースコードのアップロードに苦戦した時の話


# GitHubにコードをアップロードするのに苦戦した件


gitを使い始めるにあたって、自分にとって分かりやすい記事がなかったので、備忘録も兼ねて共有したいと思います。
まず、コードをアップするまでのポピュラーな手順を確認します。

### ①\.アップロードしたいフォルダを開く
```ruby:qiita.rb
cd フォルダのパス
```

自分はmacを使っていたので、ターミナル>home>AndroidStudioProject>当該プロジェクトの順番にファイルを開けていきました。


cdと入力した後、ファイルをドラッグ&ドロップするとパスが自動的に表示されます。

### ②\.ローカルリポジトリを作成
```ruby:qiita.rb
git init
```
リポジトリがinistializeされれば次の手順

### ③\.コミットしたいファイル・フォルダをステージング
```ruby:qiita.rb
git add .
```

無難にここでは全フォルダの指定を意味するコマンドを選択。
コマンドを正しく入力しても何も起こらない。

### ④\.ローカルの内容をコミット
```ruby:qiita.rb
git commit -m "任意のコミット名"
```

どのような状態でコミットするのか、自分がわかりやすいようにメモ書き程度の意味合い。
コマンドを正しく入力しても何も起こらない。


### ⑤\.ローカルとリモートの紐付け
```ruby:qiita.rb
git remote add origin url名
```
URL名の箇所には、下記のSSHのURLをそのままコピー&ペーストしてOK。
コマンドを正しく入力しても何も起こらない。

![スクリーンショット 2022-10-13 14.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916966/cde68bad-622a-fa13-fe36-f12724e50391.png)


自分の場合、ここの段階で「Permission dinied(Publishkey)」の表示が出てなかなか前に進めませんでした。
事前にGitHubの設定ページにSSHの公開鍵を登録しておく必要があったようです。

登録方法も英語の動画しか文献がなかったので、おいおい共有できればと思います。





### ⑥\.リモートリポジトリにプッシュ
```ruby:qiita.rb
git push -u origin main
```

上記のままコピペしてOK。
上記手順でアップロード完了。

自分と同じで、「Permission dinied(Publishkey)」の表示に苦しめられた方向けにSSHの公開鍵の取得・設定方法は別の記事で紹介いたします。
【k8s】ingressがapplyできない。(InternalError)

## ingressをapplyした時に以下のようなエラーに出会した時

```bash
Error from server (InternalError): error when creating "ingress.yaml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post "https://ingress-nginx-controller-admission.ingress-nginx.svc:443/networking/v1/ingresses?timeout=10s": no endpoints available for service "ingress-nginx-controller-admission
```

実際のエラー
![スクリーンショット 2022-10-13 14.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/779c9716-752a-befd-a81c-a3ecf3520e08.png)


### `k get validatingwebhookconfigurations`を調べる。

```bash
kubectl get validatingwebhookconfigurations  --all-namespaces
```

![スクリーンショット 2022-10-13 14.46.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/eda90d34-138d-3a32-c69e-ca90b08f0035.png)


### `ingress-nginx-adminssion`を削除する。

```
kubectl delete validatingwebhookconfigurations ingress-nginx-admission
```

これで治る。
ベアボーンNUC記録

自宅で*Samba*を利用して*Ubuntu 22.04LTS*で運用している*NUC*について、備忘もかねてスペックを記載していきます。

*Samba*導入の経緯については、[Sambaを導入しフォルダ共有する](https://qiita.com/Yoh_Yasushi/items/8e35473bf7adab480d83)の記事をご覧くださいませ。

# コンセプト
2020年4月8日に、22708円で*NUC*をamazonで購入しました。
- 安く、
- *Ubuntu*を動かすこと
- 動作速度は多少は我慢する

をコンセプトとしました。以後、何度かパーツ構成は変遷してますが、 ~~そんな経過いちいち覚えてませんよ。~~ 現時点(2022/10/13)のパーツ構成を記載します。

# パーツ構成
当時のアマゾンでテキトーにポチった範囲のものです。[パソコン工房](https://www.pc-koubou.jp/)とかもっと活用するんだった…。

## 本体
[BOXNUC7PJYH](https://kakaku.com/item/K0001052612/)
- *Pentium Silver*という**レア**なCPUで動くNUCです。特にこだわりはありません。ってか*NUC*でも最安価のもののような気がします。

## ドライブ
[MX500 CT500MX500SSD1/JP](https://kakaku.com/item/K0001028334/)
- こちらも当時のアマゾンで安かったから買った感じです。なお、本機種に*M.2*は搭載できません。ので、今後の拡張性とか期待すべくもありません。

## メモリー
[CFD Selection W4N2400CM-4G](https://kakaku.com/item/K0000905147/)
- これも特に拘りはありません。合計で、*8GB*もあれば十分です。今後も増設の予定はありません。

# 総評
2,3年前に組んだのですが、*NUC*なりにうごいています。*NAS*的な使い方では困ってません。ただ、*CPU*はそれなりの性能なので、*Ubuntu*のメイン機として使うのですらも、ちょっと躊躇する遅さです。

が上述の如く*SSD*を*NAS*にしているので、*NAS*というか共有フォルダとしてはかなり速い部類です。今の自分の運用上も、何*TB*ものデータを落とす必要性より、数*GB*程度の*ISO Image*とかを落とす作業が多いので…。メイン機の横でそういうのさせるには**必要にして充分なスペック**です。

今後も**名脇役**として、活躍するでしょう。
shell vim

## vim起動
```
(sudo) vi ファイル名
```
## モード切替

|内容|入力|コマンドモードへの戻り方|
|----|----|----|
|コマンドモード||
|インサートモード_書き込み|i|ESC|
|exモード_文字列の検索|「/」文字列|ESC|
|exモード_順に次の検索結果へジャンプ|「Enter」後「n」|ESC|
|exモード_変更を保存(wright)して終了(quit)|:wq|ESC|
|exモード_変更を破棄 (quit)を強制(!)|:q!|ESC|


参考
Vi エディタ

参考

http://haya14busa.com/vim-mnemonic/

## カーソル移動
|内容|コマンド||
|----|----|----|
|← ↓ ↑ →|h J K l||
|先頭|gg||
|末尾|G||
|左端|^||
|右端|$||

## カット、コピー、ペースト
|内容|コマンド||
|----|----|----|
|カット|dd|1行単位|
|コピー|yy|1行単位|
|ペースト|p||
|コピペ|yyp|カーソルを下にずらすと、1行空白ができてしまうので注意|
ROS環境構築 <Part 2> ゲームパッド接続

## はじめに
ゲームパッド(Logicool F710)をROSで使うためにセットアップした際の忘備録です．
(2022年10月購入)
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962692/56f8fc66-e76d-9612-a613-1c7b2665eb53.png)

## 環境
##### PC (Panasonic Let's Note CF-FV)
・OS: Windows11 Pro (64bit)
・VirtualBox: 6.1.38 (Ubuntu18.04.3, GUI環境)
・ROS: melodic
※こちらの環境構築については別記事
https://qiita.com/pez/items/741b43eb4765894edc94
と同様になります
(追記）
・Ubuntu16.04 + kinetic でも全く同様の操作でセットアップできることを確認

##### ゲームパッド
・Logicool F710

## ゲームパッドをPCに接続
ゲームパッドのドングルをPCに接続
入力モードとしてX(XInput)とD(DirectInput)があるがXの方にしておく

## VirtualBoxの設定
立ち上げ直後の画面の「設定」⇒「USB」⇒ USBフィルタの追加　
で接続したゲームパッドを選択して加える ⇒ OK
![gamepad1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962692/5180c5bc-06cd-c191-d6a5-1809f0516a34.jpeg)


## Ubuntuの設定
#### 接続確認
```ruby:
$ lsusb
```
![lsusb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962692/b7170cc1-e214-436c-5f0f-a3923896f007.png)
一覧の中に接続したゲームパッドが表示されれば認識されている．
表示されない場合はエラー対応MEMO①へ↓↓

#### 動作確認
```ruby:
$ jstest-gtk
```

※未インストールの場合は下記でインストール
```ruby:
$ sudo apt-get install jstest-gtk
```
該当のデバイス(ここでは Logitech Gamepad F710)を選択して「プロパティ」
ゲームパッドのボタンやスティックの操作で反応するか確認する．
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962692/672ce804-0abf-f7d2-a1a6-821e46ba0820.png)

また，ゲームパッドの接続先　(例としてここでは) 「/dev/input/js2」を確認（記憶）しておく

### エラー対応MEMO①
ubuntuでゲームパッドを認識できない状況が発生することがあった
（lsusbコマンドの段階で表示されない）
・Ubuntuの再起動
・VirtualBoxの立ち上げ直し
・ゲームパッドの接続し直し（USBデバイスフィルターの再設定）
などを繰り返していたらあるとき認識された．腑に落ちない．

そもそもPCがゲームパッドを認識していない？と思ったら
下記が参考になると思います

https://zyoho3.com/?p=837


## ROSのjoy用パッケージのインストール
いつかソースコードを参照したりいじったりする日がくるかもしれないということで、ソースコードからビルド
```ruby:githubから
$ cd ~/catkin_ws/src
$ git clone https://github.com/ros-drivers/joystic_drivers.git
```
```ruby:ビルド
$ cd ~/catkin_ws
$ catkin_make
```
### エラー対応MEMO②
ここで「fatal error : spnav.h そのようなファイルやディレクトリはありません」
といったエラーが出てビルドできなかった．そこでそのspnavというものをインストール
```ruby:
$ sudo apt-get install libspnav-dev
```
その後は正常にビルドできた．

## 動作確認
```ruby:ROSを立ち上げる
$ roscore
```
```ruby:別のターミナルにて
$ rosrun joy joy_node _dev:=[ゲームパッドの接続先]
```
例えばここでは
$ rosrun joy joy_node _dev:=/dev/input/js2

```ruby:さらに別のターミナルにて
$ rostopic echo /joy
```

これでゲームパッドを操作したときに画面にその情報が出れば成功
![tan7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962692/a6d88bb2-f6b8-ecab-400b-6b480c428d61.png)

終了したいときは全ターミナルで
Ctrl + C
CDNでFont Awesome 6をで利用する

# はじめに
HTML/CSSでアイコンを使用したかったのでFont Awesomeを初めて使用しました。
バージョン違いで戸惑ったので、CDNでFont Awesome 6を利用する方法を備忘録として残しておきます。

# Font AwesomeのCDN
以下のコードをHTMLファイルの`<head></head>`内に記載する。(Ver.6.2.0)
```html:
<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet">
```

Font Awesomeの現在のバージョンは、公式サイト内(下記画像参照)で確認できる。
![FontAwesome_ver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1363996/ce2db609-24ea-99a1-751c-2b161b37ca50.png)


# 基本的なアイコンの利用方法
公式サイトから使いたいアイコンのコードをコピーする。
https://fontawesome.com/
![FontAwesome_icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1363996/19ff7f86-0404-0f0e-5828-3561c087a412.png)

コピーしたコードはHTMLファイルに貼り付ける。
```html:index.html
<body>
  <i class="fa-solid fa-house"></i>      
</body>
```

:::note warn
バージョンが異なるとアイコンが表示されないことがある。
防ぐにはCDNの`v6.2.0`の部分と同じバージョンのアイコンを検索する必要がある。
![FontAwesome_ver2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1363996/50b42fb7-9b0c-5469-f4dd-a5c145d7dd7c.png)
:::

# 参考
[https://giga-log.com/fontawesome-not-displayed/](https://giga-log.com/fontawesome-not-displayed/)
Power BI サポートへの問い合わせ方法

# はじめに
こんにちは、Power BI 担当の松永です！
今日は Power BI についての Tips、ではなく、問題が起きてしまって立ち止まったときに参考になる情報をお伝えします。

Power BIを使っていると、
・データソースにうまく接続できなかったり…
・レポート作成中にエラーが出たり…
して一人で解決することが困難なケースがあると思います。
(筆者もよくあります…)

もちろんドキュメントや [Power BI Community](https://community.powerbi.com/t5/Get-Help-with-Power-BI/ct-p/PBI_GetHelp) を参照することで解決できるケースもたくさんありますが、有償ライセンスをお持ちの場合は日本語で **Power BI サポートチームに直接お問い合わせ**いただくことができます。
今回の記事では、具体的なお問い合わせ方法をご紹介します！

:::note info
お問い合わせできる内容やコツについてはぜひ [サポートチームのBlog](https://jpbap-sqlbi.github.io/blog/powerbi/support_boundary/)をご覧ください。
:::

::: note warn
有償ライセンスでご利用いただけるサポートサービスは一問一答形式です。

:::


# 問い合わせ方法
では早速お問い合わせ方法をご紹介していきます。

***
#### サポートページにアクセスする
まず、以下のリンクから Power BI (Fabric) のサポートページにアクセスしましょう。

https://support.fabric.microsoft.com/ja-JP/support/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/cd477efe-fbee-4bef-6deb-20c903a8977f.png)

画面下にスクロールすると、Power BI の **[サポートを利用する]** ボタンがあるのでクリックします。
※Power BIのテナント管理者の場合は、[管理センターのサポートポータル](https://admin.powerplatform.microsoft.com/support)からチケットを起票できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/cb27ad6c-8855-6dfe-e840-80636d89cfc2.png)


***
#### 新しいサポート要求フォームを埋める
開いたページでは、まず起きている問題を簡単に文章で記述します。
その後、問題を特定するために選択式で問題に関する絞り込みを行います。
ご自身が困っている内容を基に、フォームを埋めてみてください。
問題について記載できたら、**[ソリューションを取得]** で次の画面に遷移します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/b165b63f-bb25-0ee4-cd5b-f87bcde0a9d4.png)

推奨ソリューションやドキュメントが表示されますので、問題が解決できそうか確認してみてください。
それでも解決しなそうであれば画面下の **[サポートに問い合わせる]** を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/0335eccb-3cc3-1940-0ba8-ee26b6fb0ea3.png)

***
#### 問題の詳細を記載する
次の画面で、起きている問題の詳細について記載しましょう。
エラーコードがある場合はコードをコピーして貼り付けると問題の特定がスムーズですよ。
問題の重大度に応じて、サポートからの回答時間の目安が表示されます。

::: note warn
サポートプランについては、ご自身が使えるプランを確認の上選択してください。
有償ライセンスについている無償サポートの場合は、 **Power Platform Subsctiption** が該当します。
:::


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/988ca651-6858-856a-3a81-55bde9773a66.png)

***
#### 連絡先の入力
最後に、サポートから連絡をもらうために連絡先を入力しましょう。
送信して、完了です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/15604b96-2c40-6082-13d9-f89d1588752e.png)

# おわりに
はい、これでサポートへのお問い合わせが完了しました！
問題なくお問い合わせできたでしょうか？
本記事が、あなたの Power BI ライフを豊かにするために役に立っていれば幸いです！

それでは！
APIアプリ


# 1,WebAPIの仕組み

YahooのDeveloper Network
天気情報を提供するAPI

Yahoo Weather API for your apps

WebAPIによるデータ取得
- HTTPリクエスト　アプリからサーバーを呼び出す
- HTTPレスポンス　 JSON,XML

今回はJSONで受けとりデータのパース処理をする

# 2,HTTPリクエスト

```
let url = "\(url)"
getURL(url:url)
```


JSONデータを取得するコーdp
```
func getURL(url:String){

func getURL(url:String){
        
        do{
            let apiurl = URL(string:url)
            let data = try Data(contentsOf: apiurl!)//データを得る
            //
            let json = try JSONSerialization.jsonObject(with: data) as! [String:Any]
        //取得したデータをキーと値で表示できる [Stringがキー　Anyが値]
            print(json)
        } catch{
            self.sunriseTimeLabel.text = "取得できませんでした"
        }
    }
}

```
外部通信を許可しないと外部のサーバーへの通信ができない。

# 4,外部通信を許可する

プロジェクトの設定を変更
Info.plist
二つを追加する
![スクリーンショット 2022-10-12 23.36.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495717/a547a88a-0639-0d03-54f4-e6c8bca32c39.png)


# 5,データを取り出す

query:{ results:{channel:{}}中身}を取り出す
```
let query = json["query"] as! [String:Any]
let results = query["results"] as! [String:Any]
            let channel = results["channel"] as! [String:Any]
            let astonomy = channel["astoronomy"] as! [String:Any]
```
統計分析(Statistics)

[Teradata Vantage - Vantage Analytics Library](https://docs.teradata.com/r/Vantage-Analytics-Library-User-Guide/January-2022)[2022/9/22時点]の翻訳です。
(リリース番号 : 2.1.1 | リリース日 : January 2022)
> この記事はVantageアナリティクスライブラリ シリーズのコンテンツです。

# 概要
統計分析は、数値データの特性を判断し、その品質を評価し、外れ値やその他の異常を見つけるのに役立ちます。
統計項目は、statsoptionsオプションで追加する事が出来ます。追加可能な項目の詳細はマニュアルをご覧ください。

# 前提条件
・Teradata Vantageインスタンスにアクセスできること。
・Vantage アナリティクス・ライブラリがインストールされていること。

::: note info
Vantage アナリティクス・ライブラリのインストールについて、既にVantageを導入頂いているお客様はTeradataサポートサービスにお問い合わせください。
Vantage Express (評価版)やクラウドサービスのDIYでご利用頂く場合は[Teradata Dounload](https://downloads.teradata.com/download)からダウンロードし利用可能です。
Vantage アナリティクス・ライブラリのインストール手順は「[Vantageアナリティクス・ライブラリのインストール](https://qiita.com/ykswi/items/12d0da2ac69b4b161881#vantage%E3%82%A2%E3%83%8A%E3%83%AA%E3%83%86%E3%82%A3%E3%82%AF%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)」の記事に従い行います。
:::

# データの準備
## サンプルデータの入手とデータベースへの格納方法
こちらの「[チュートリアル用のサンプルデータを用意する](https://qiita.com/tmsky/items/4d86ca35aef753290020)」を参照ください。

# 実行方法
## SQLから実行する場合の例
```SQL
CALL td_analyze (
  'statistics',                               /* 分析手法　*/
  '
  database        = QID;                      /* データベース名 */
  tablename       = Superstore;               /* テーブル名 */
  columns         = Row_ID,Ship_Date,Profit;  /* カラムリスト */
  '
);
```
:::note information
出力結果をテーブルに書き込む場合は以下オプションを指定可能です。
outputdatabase = 出力データベース名;
outputtablename = 出力テーブル名; 
overwrite = {true | false}; --- 未指定の場合はtrueで上書きします
:::
## 出力結果
|xdb|xtbl|xcol|xcnt|xmin|xmax|xmean|xstd|
|:-|:-|:-|:-|:-|:-|:-|:-|
|QID|Superstore|Row_ID|9994|1|9994|4997.5|2885.0192806981377|
|QID|Superstore|Ship_Date|9994|112015|12312017|5900386.760056034|4270609.516346334|
|QID|Superstore|Profit|9994|-6599.978|8399.976|28.656896307784702|234.24838736035875|

## 出力結果の説明
|カラム名|データタイプ|説明|
|:-|:-|:-|
|xdb|VARCHAR (128)|データベース名|
|xtbl|VARCHAR (128)|テーブル名|
|xcol|VARCHAR (128)|カラム名|
|xcnt|FLOAT|レコード数|
|xmin|FLOAT|値の最小値|
|xmax|FLOAT|値の最大値|
|xmean|FLOAT|値の算術平均|
|xstd|FLOAT|値の標準偏差|

# おわりに
:::note information
サンプルコードはSQL関数から掲載し順次Pythonコードも掲載していく予定です。
:::

:::note warn
警告
この本書は[Teradata Vantageドキュメンテーション](https://docs.teradata.com/)よりトピックに必要な情報を抜粋したものです。掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。正確な内容については、原本をご参照下さい。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::

#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
printとは？

# printとは？
printとは出力することです。とても簡単ですね。
# 書いてみよう 
```Python
print('neko')
```
# 実行結果
```
neko
```
「neko」と出力されました。

# まとめ 
今回はpythonで出力をしてみました。printを覚えておきましょう。
WebのPush通知の全体像を捉える

## はじめに

iOS SafariでのPush通知のサポート予定とのことなので、この機会にWebでのPush通知について調べました。
WebでのPush通知を学ぶにあたって、WebでのPush通知の仕組み・全体像を知っておくと良いなと感じたので記事にします。

## 全体像

Push通知の全体像としては以下。

```mermaid
sequenceDiagram
    autonumber

    actor u as User
    participant b as Browser
    participant a as App Server
    participant s as Push Service

    b->>u: 通知の表示の許可をリクエスト
    u->>b: 通知の表示を許可
    b->>s: 購読をリクエスト
    s->>b: Push Subscriptionオブジェクト
    b->>a: 取得したPush Subscriptionオブジェクト
    a->>a: 保存
    a->>s: Push Subscriptionオブジェクトを用いて通知の送信をリクエスト
    s->>s: エンキュー
    s->>b: 通知を送信
    b->>b: 通知を表示
```

## 通知購読をし、そのユーザーを保存する

図で言うところの1 ~ 6。

必要なことは以下。

1. 通知の許可を得る
1. [PushSubscription](https://developer.mozilla.org/ja/docs/Web/API/PushSubscription)オブジェクトを取得
1. 取得した[PushSubscription](https://developer.mozilla.org/ja/docs/Web/API/PushSubscription)オブジェクトを自身のデータベースへ保存

### 1. 通知の許可を得る

[Notification API](https://developer.mozilla.org/ja/docs/Web/API/Notifications_API)を用いて、ユーザーに通知の許可を要求する。

- [Notification.requestPermission() - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Notification/requestPermission)

### 2. [Push Subscription](https://developer.mozilla.org/ja/docs/Web/API/PushSubscription)オブジェクトを取得

[Push API - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Push_API)を用いてPush Serviceの購読をする。
PushSubscriptionオブジェクトには、以下のようなデータが含まれている。

```json:PushSubscriptionオブジェクトの例
{
  "endpoint": "https://fcm.googleapis.com/fcm/send/c1KrmpTuRm…",
  "expirationTime": null,
  "keys": {
    "p256dh": "BGyyVt9FFV…",
    "auth": "R9sidzkcdf…"
  }
}
```

- [PushManager.subscribe() - ウェブ API | MDN](https://developer.mozilla.org/ja/docs/Web/API/PushManager/subscribe)

### 3. 取得した[Push Subscription](https://developer.mozilla.org/ja/docs/Web/API/PushSubscription)オブジェクトを自身のデータベースへ保存

`2. Push Subscriptionオブジェクトを取得` で取得したデータは、Push Messageを送信する際に必要となるため、保持しておく。

## Push Messageを送信する

図で言うところの7 ~ 9。

保持している、Push Subscriptionオブジェクトをもとに、Push Serviceを経由してPush Messageをリクエストする。
Push Serviceが受け取ったPush Messageはキューに積まれ、対象のデバイスに対して送信する。

なお、Push Serviceへのリクエストには、暗号化、署名などが必要になる。
（https://github.com/web-push-libs/ でライブラリが用意されている）

## Push Messageを受け取り、通知として表示する

Push Messageを受け取ると、Service Workerの[pushイベント](https://developer.mozilla.org/ja/docs/Web/API/ServiceWorkerGlobalScope/push_event)が発火する。
[ServiceWorkerRegistration.showNotification()](https://developer.mozilla.org/ja/docs/Web/API/ServiceWorkerRegistration/showNotification) で受け取ったPush Messageを通知として表示させる。

また、通知を開いた場合は[notificationclickイベント](https://developer.mozilla.org/ja/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event)が発火する。

## さいごに

おおまかですが、全体像について書きました。
あくまでも全体像なので、要所要所の部分は抜けてますがお許しください。

WebでのPush通知を学ぶのに参考になれば幸いです。

## Refs

- [Push notifications overview - web.dev](https://web.dev/push-notifications-overview/)
【cakePHP】任意の順番でソートがしたい。

DESC　とか　ASC　でソートじゃ物足りない時。


テーブル名.フィールド名が[2]の時、4番目
テーブル名.フィールド名が[0]の時、2番目
テーブル名.フィールド名が[3]の時、1番目
その他の時、3番目

のような並び順にしたい。↓

```php
$query->order(function ($exp, $q) {
    return $exp->addCase(
    [
        $q->newExpr()->eq('テーブル名.フィールド名', 2),
        $q->newExpr()->eq('テーブル名.フィールド名', 0),
        $q->newExpr()->eq('テーブル名.フィールド名', 3),
    ],
    [4, 2, 1, 3],
    ['integer', 'integer', 'integer', 'integer']
);
```


参考・参照
https://stackoverflow.com/questions/47032368/how-to-implement-case-when-under-order-by-using-cakephp-3
Salesforce認定アドミニストレーター試験勉強に役立つコミュニティの解説

こんにちは。本橋です


今回はSalesforce認定アドミニストレーター試験の勉強のコミュニティについて紹介します


今回の内容は動画でも解説しています

<iframe width="560" height="315" src="https://www.youtube.com/embed/h6RwNnpijao" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


みなさんはSalesforce認定アドミニストレーター試験の勉強で分からないことや困ったことがあればどうしていますか？

もしも身近にSalesforceに詳しい人がいれば聞くことができますが、身近なところにSalesforceに詳しい人がいない方も多いと思います。

そんな方々のために今日は
Trailblazer Community というコミュニティを紹介します


こちらのSalesforceのサイトにも書いてあるように、
試験勉強では

「Trailblazer Community では、Trailblazer 仲間と交流したり一緒に勉強したりすることができます。」
と書いてあります

https://trailhead.salesforce.com/ja/credentials/administrator

これをみても分かるように、Salesforceの試験ではTrailblazer Communityで交流して勉強することが書かれていますね


とはいえ、実際にどうやって交流すればいいんだろう。と思う方、多いと思います

実際にこちらのリンクをクリックすれば英語でのやりとりが多くて驚かれるかと思います

また、私もはじめはそうでしたが
・こんな初歩的なことでも質問していいのか
・こんなこと質問しても怒られるんじゃないか
なんて考えたり、ついついしちゃいますよね

そこで今回はSalesforce認定アドミニストレーター勉強に役立つコミュニティを紹介します

それは、この「Salesforce認定アドミニストレーター試験合格を目指す会」です

https://trailhead.salesforce.com/ja/trailblazer-community/groups/0F94S000000kJUPSA2?tab=discussion&sort=LAST_MODIFIED_DATE_DESC


このグループは
Salesforce認定アドミニストレーター試験合格を目指す人が集い、学ぶ場として私が作成したTrailblazer Community グループです

（Saelsforceの申請が下りればTrailblazer Community グループを作成することが可能です）

私がこのコミュニティグループを作成したのは2022年6月ですが、ありがたいことにグループの参加者は250名を超えました。

（ちなみに参加者で一番多い会社はSalesforceの社員様ですね）

ここでは毎週のようにSalesforce認定アドミニストレーター試験を勉強する方が質問をして、またその質問を誰かが回答する流れができています

いかがでしょうか。

Salesforce認定アドミニストレーター試験を勉強をしていて気になることや質問があれば、ぜひTrailblazer Community に投稿してみてください。

ちなみに、私は毎日Trailblazer　Communityの投稿を見ています。

勉強をしていくうえで分からないことやつまることは案外みんなおんなじことです。

ぜひみなさん、Trailblazer Communityを活用しましょう！
【TypeScript】スプレッド演算子　メモ

## スプレッド演算子とは？？
`...配列`で記述され、配列要素の中身が展開されるもの！
（初めて見た時は何かを省略している記号だと思っていたので使い方を知った時は驚きました）

## メリット
* 簡単に早く配列の中身を表示できる
* 配列とオブジェクトで使用できる
* 配列の中身を引数として素早く使用できる
* たった３つのドットで使用できる
* 可変長引数とする事が可能

## 実際に書いてみる
***1\. 展開***
```typescript
const array = [1, 2, 3];
console.log(...array);//1 2 3
```
配列arrayが`1 2 3`のように展開された

***2\. 結合***
```typescript
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
console.log(...array1, ...array2);//1 2 3 4 5 6
```
配列array1と配列array2が結合された

***3\. 新しい配列としてコピー***
```typescript
const array = [1, 2, 3];
const newArray = [...array];
console.log(newArray);//[ 1, 2, 3 ]
```
newArrayにarrayの配列がコピーされた

このnewArrayとarrayは別物
```typescript
console.log(newArray === array);//false
```
newArrayとarrayを比較してみるとfalseが出力される


☆arrayをそのまま代入した場合
```typescript
const array = [1, 2, 3];
const newArray2 = array;
newArray2.push(100);
console.log(newArray2);//[ 1, 2, 3, 100 ]
console.log(array);//[ 1, 2, 3, 100 ]
```
newArray2にarrayを代入して、100をプッシュしてみる
そうすると、newArray2、arrayともに`[ 1, 2, 3, 100 ]`が出力された

***4\. 要素を追加する***
```typescript
const array = [1, 2, 3];
const newArray3 = [0, ...array];
console.log(newArray3);//[ 0, 1, 2, 3 ]
```
スプレッド演算子でarrayを展開する前に`0`を入れて新しい配列を作成した

***5\. オブジェクトに使用する***
```typescript
const person = {name:'taro', age:'22', weight:'55kg'};
const newPerson = {...person, height:'170cm'};
console.log(newPerson);//{ name: 'taro', age: '22', weight: '55kg', height: '170cm' }
```
オブジェクトでも同様に展開できる
4で行った要素を追加することも同様に可能
personが`{name:'taro', age:'22', weight:'55kg'}`というオブジェクトであり、これに`{height:'170cm'}`を追加している
AWS Compute Optimizer とは

## 勉強前イメージ

みたことあったっけ？

## 調査

### AWS Compute Optimizer とは

機械学習を利用してユーザに最適なパフォーマンスやリソースを提案してくれるサービスになります。
分析を行うサービスは以下4つになります。

- EC2インスタンス

インスタンスタイプとサイズの最適なものを推奨します。

- Auto Scalingグループ

上記同様EC2インスタンスのタイプとサイズが最適なものを推奨します。

- EBSボリューム

汎用ボリュームとプロビジョンドIOPSののIOPSとスループットの推奨がサポートされます。

- lambda関数

メモリサイズが過剰にプロビジョニングされている可能性があるlambda関数
また、追加のCPUパワーのベネフィットを利用できる可能性のあるlambda関数の2つが含まれます。

### 使用方法

利用方法はAWS Compute Optimizerを有効(オプトインをクリック)にすることで利用開始できます。
有効にしてからデータを収集・分析を置こうので最大12時間かかる場合があります。
結果はダッシュボードに表示されます。

また、無料で利用することができるので気軽に使ってみましょう。

### AWS Compute Optimizer のメリット

- コスト削減

過剰なリソースが適応されていたりした際にはこちらのCompute Optimizerで確認し、コスト削減を行うことが出来ます。
どのリソースが過剰かもすぐ見ることが出来ます。

- パフォーマンス最適化

推奨がされている際は、メモリ使用率なども合わせて予測してくれるため
今後変更する際の検討材料にすることも出来ます。

## 勉強後イメージ

EC2とかよく使うサービスで最適なリソースの使い方とか教えてくれるならめっちゃええやん・・・

## 参考

- [AWS Compute Optimizer のEC2インスタンスタイプの推奨事項機能が強化](https://www.sunnycloud.jp/column/20210607-01/)
- [AWS Compute Optimizerとは？概要とメリットを解説](https://www.skyarch.net/column/aws-compute-optimizer/)
とりあえず子供のプリント教材を用意したいので、スクレイピングしてみた

# きっかけ
PDFファイルを大量ダウンロードしてこそ、スクレイピングナノではないのか？


# 生活の困りごと
共働きなので、小学校初めての夏休みは学童に行ってもらっていた。
おじいちゃんおばあちゃんはなにをしているかというと、働いています。
小学校入学して、夏休みの宿題プリント受け取って初めて知ったのですが
「読書感想文」も「夏休みの研究」も「貯金箱作り」も「ポスター作成」も自主性に任せるスタイルなんですね。
学校から出されたメインのドリル宿題は早々に終わってしまった。
しかし、学童から、自主学習の時間があるので、おうちから勉強課題を持ってきてほしいと言われる。

# 手順を考えた

1. PDFが並んでいるページを探す
1. PDFのDLする
1. 指定のディレクトリに保存する

# コードを書いたので、いかに貼る

2秒のお休みを含めつつ、こんな感じ。
```
from bs4 import BeautifulSoup
import urllib.request as req
import urllib
import os
import time
from urllib.parse import urljoin

pageName = "kasa-kurabe"
url = "https://print-kids.net/print/sansuu/" + pageName + "/"

res = req.urlopen(url)
soup = BeautifulSoup(res, "html.parser")
result = soup.select("a[href]")
#print(result)

link_list =[]
for link in result:
    href = link.get("href")
    link_list.append(href)
    pdf_list = [temp for temp in link_list if temp.endswith('pdf')]
#print(pdf_list)
#print(link_list)
abs_dbpdf_list = []
for relative in pdf_list:
    temp_url = urljoin(url, relative)
    abs_dbpdf_list.append(temp_url)
#print(abs_dbpdf_list)
filename_list = []
for target in abs_dbpdf_list:
    temp_list = target.split("/")
    filename_list.append(temp_list[len(temp_list)-1])
#print(filename_list)
os.mkdir('./'+ pageName)
target_dir = "./" + pageName

savepath_list = []
for filename in filename_list:
    savepath_list.append(os.path.join(target_dir, filename))
#print(savepath_list)

for (pdflink, savepath) in zip(abs_dbpdf_list, savepath_list):
    urllib.request.urlretrieve(pdflink, savepath)
    time.sleep(2)
```


# 実行した結果
欲しい物が手に入った。



# 次の課題が見えた
PDFダウンロードするたびに、同意ボタン押下求められるサイトもあるので、やはり、ブラウザ操作も学習する必要性があると感じた。
また、手に入れたプリント課題は1ファイル1ページになっている。このままだと、印刷ボタンを延々と押すはめになる。絶対に嫌だ。


# 対策の方針
PDFファイルを統合するもしくは、指定したフォルダをPDFを印刷し続ける処理を作る必要がある。前者がおそらく実現可能度が高く感じる。（感覚）