OmniAICreator/Qiita-1.07M huggingface dataset:
Salesforceの権限設定について_Part1

# はじめ
Salesforce施策を初めて担当したとき、最初に打つかった壁がユーザに設定する権限だった。
Salesforceは色んな機能を提供している分、各機能やオブジェクトに対するアクセス権限を細かく設定できるようになっている。
ユーザへ設定する権限関連の設定はユーザ個人に設定するもの以外でも以下のようなものがある。

* プロファイル
* ロール
* 権限セット
 * 権限セットグループ
* 公開グループ
* 共有ルール

Salesforceを始める方に少しでも分かりやすくお伝えできるよう内容をまとめてみたい。
Part1では基本的なユーザ個人のアクセス権限にかかわるプロファイル、ロール、権限セットについて、Part2では共有にかかわる公開グループ、共有ルールについて記載する。

# 本文
### 基本設定
|   | プロファイル1  | プロファイル2  | プロファイル3  |
|---|---|---|---|
| **ロールA** | ユーザA1 | ユーザA2 | ユーザA3 |
| **ロールB** | ユーザB1 | ユーザB2 | ユーザB3 |
| **ロールC** | ユーザC1 | ユーザC2 | ユーザC3 |

1人のユーザには一つのプロファイルとロールを持つ。

#### ロール（Role）
ロールは組織での部署やチームを分ける設定。直接権限に関する設定はないが、公開グループやキューを設定する際の基準になる。
![ロール](https://res.cloudinary.com/hy4kyit2a/f_auto,fl_lossy,q_70/learn/projects/protect-your-data-in-salesforce/set-defaults-and-create-role-hierarchy/images/ja-JP/c6a0dd8963f5abed205f0063c6588856_cjgnuc-5-i-000100-v-4-bbduhgcuy.png)

#### プロファイル(Profile)
プロファイルはユーザの権限を制限する基本的な設定。組織と関係なく、ユーザの役割によって設定するもの。
利用可能なアプリケーション、タブ表示、システム権限、オブジェクトのアクセスなど細かい設定が可能。Salesforce既存機能への設定はもちろん、カスタマイズで作成されたアプリケーションやオブジェクトに関する権限設定も可能。
この後、説明する権限設定を併用することでユーザを細分化して権限設定が可能になるので、プロファイルにはデフォルトになる設定のみ付与することをお勧めする。

![プロファイルアプリケーション設定](https://d3nqfz2gm66yqg.cloudfront.net/images/v1484011599-LL7.3_ykcift.gif)

![プロファイルオブジェクト設定](https://d3nqfz2gm66yqg.cloudfront.net/images/v1484011599-LL7.4_yqrk0x.gif)

### 権限セット追加
|   | プロファイル1  | プロファイル2  | 
|---|---|---|---|
| **ロールA** | ユーザA1(権限セットa, 権限セットb) | ユーザA2(権限セットb) | 
| **ロールB** | ユーザB1(権限セットa) | ユーザB2(権限セットc) | 
| **ロールC** | ユーザC1(権限セットb) | ユーザC2(権限セットa, 権限セットb, , 権限セットc) | 

#### 権限セット(Permission Sets)
プロファイルに加えて設定するもの。ひとりのユーザに対して複数の権限セットを設定可能。

![権限セット](http://i.imgur.com/vd9UT.png)

##### 権限セットグループ(permission set groups)
よく使わっる権限セットの一覧をグループとして設定可能。比較的に最近できた機能。上記表からだと(権限セットa, 権限セットb)のようにセットでよく設定する権限セットがある場合、権限セットグループとして定義することでもっとシンプルに設定が可能になる。

![権限セットグループ](https://image.slidesharecdn.com/adminwebinar-adminsguidetoprofilespermissions-190519000131/95/admin-webinaran-admins-guide-to-profiles-permissions-16-638.jpg?cb=1558224791)

# 結び
Salesforceでユーザ単位で設定できる権限設定について記載してみました。
Part2ではグループやロール単位でアクセス権限を分けるとき（例えば、同じケースオブジェクトでも部署Aで作成されたものは部署Bでは参照のみ可能またはアクセス禁止する場合）に使われる公開グループや共有ルール、キューについて記載します。




# 参考
* https://trailhead.salesforce.com/ja/content/learn/projects/protect-your-data-in-salesforce/set-defaults-and-create-role-hierarchy
* https://admin.salesforce.com/blog/2017/learn-lightning-create-edit-profiles
* http://kakumanubrothers.blogspot.com/2012/08/enhanced-list-view-profile-permission.html
* https://help.salesforce.com/articleView?id=perm_set_groups.htm&type=5
[Swift] Date生成時にありえない日付のときはnilを返したい

記事の内容はこちらを参照してください。
https://mishimay.github.io/b1ba8ac38b2dc4cc802f/
<!--




## TL;DR

DateFormatterを使い `isLenient = false` に設定する。

```swift
func makeDate(year: Int, month: Int, day: Int) -> Date? {
    let formatter = DateFormatter()
    formatter.calendar = Calendar(identifier: .gregorian)
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.isLenient = false
    formatter.dateFormat = "yyyy-MM-dd"
    return formatter.date(from: String(format: "%d-%02d-%02d", year, month, day))
}

let date = makeDate(year: 2021, month: 2, day: 29)
// -> nil
```


## やりたいこと

例えば年と月と日を別々に入力するUIがあってそこからDate型を生成したいとき、ユーザーが2021年2月29日のような存在しない日付を入力したらnilを返したい。


## ❌ DateComponentsを使う方法

```swift
func makeDate(year: Int, month: Int, day: Int) -> Date? {
    var components = DateComponents()
    components.calendar = Calendar(identifier: .gregorian)
    components.timeZone = TimeZone(secondsFromGMT: 0)
    components.year = year
    components.month = month
    components.day = day
    return components.date
}

let date = makeDate(year: 2021, month: 2, day: 29)
// -> 2021年3月1日
```

自動で日が進んで別の日付を返してしまう。


## ❌ DateFormatterを使ってisLenientを指定しない方法

```swift
func makeDate(year: Int, month: Int, day: Int) -> Date? {
    let formatter = DateFormatter()
    formatter.calendar = Calendar(identifier: .gregorian)
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.dateFormat = "yyyy-MM-dd"
    return formatter.date(from: String(format: "%d-%02d-%02d", year, month, day))
}

let date = makeDate(year: 2021, month: 2, day: 29)
// -> 2021年3月1日
```

自動で日が進んで別の日付を返してしまう。

ただし、32日を指定するとnilが返ってくる。
この挙動はDateComponentsとは異なる。


```swift
let date = makeDate(year: 2021, month: 2, day: 32)
// -> nil
```


## 環境

Swift 5.1


## 謝辞

@kishikawakatsumi さんに教えていただきました。ありがとうございました。


-->
AWS Lambda から Amazon EFS へのアクセス

AWS Lambda から Amazon EFS へアクセスできるようになったとのことでやってみた。

これによりLambda の仕様上、512 MB という仕様制限がありましたが、これを超えるファイルの操作が可能になります。

また、S3は結果整合性ですが、EFS を利用することによりデータの一貫性が保てることができます。

[新機能 – Lambda関数の共有ファイルシステム – Amazon Elastic File System for AWS Lambda](https://aws.amazon.com/jp/blogs/news/new-a-shared-file-system-for-your-lambda-functions/)

#1.セキュリティグループの作成#

##AWS Lambda 用セキュリティグループの作成##

|セキュリティグループ|| 
|---|---|
|インバウンドルール| なし|
|アウトバウンドルール|すべてのトラフィック|	

##Amazon EFS 用セキュリティグループの作成##

|セキュリティグループ|| 
|---|---|
|インバウンドルール| NFS,TCP,2049,AWS Lambda のセキュリティグループID|
|アウトバウンドルール|すべてのトラフィック|


#2.Amazon EFS の作成#

##ステップ 1: ネットワークアクセスを設定する##
AWS Lambda を作成する対象の VPC を選び、マウントターゲットでサブネットを選択。
セキュリティグループには、「Amazon EFS 用セキュリティグループの作成」で作成したsgを選択します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/e02fbf72-d6b4-c299-33aa-92ffdd14cb64.png)

##ステップ 2: ファイルシステムの設定を行う##
今回は、AWS Lambda から Amazon EFS のアクセスを確認することが目的なので、タグだけを追加し、他の設定はデフォルトでいきます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/193ab1a5-d734-b655-68dc-cb9da06a74f5.png)

##ステップ 3: クライアントアクセスを設定##
AWS Lambda からアクセスするための アクセスポイントの作成 を行います。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/459e5db6-37cd-6a81-0630-0b7b7981f3a4.png)

##ステップ 4: 確認と作成##
「ファイルシステムの作成」をクリック。


#3.AWS Lambda の作成#

##IAM ロールの作成##
AWS Lambda 関数に付与する IAM ロールを作成する。
　AWSLambdaVPCAccessExecutionRole
　AmazonElasticFileSystemClientReadWriteAccess
　CloudWatchLogsFullAccess
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/d261d792-b06f-2ed2-a529-bcd01cf74a95.png)

##AWS Lambda 関数の作成##
ランタイムはPython3.8、既存のロールは「IAM ロールの作成」で作成したものを指定します。

VPCとセキュリティグループは、「AWS Lambda 用セキュリティグループの作成」で作成していたものを指定します。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/c990a486-10ba-0943-1fbd-59fa6dc1d7d7.png)

さて、今回のメインはここで、ファイルシステムの追加をします。「Amazon EFS の作成」で作成したAmazon EFS 及びアクセスポイント、ローカルマウントポイントを指定します。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/85400b7d-72ac-4fd0-cfb9-81ee942f32d4.png)

次の通りLambda関数を作成します。
AWS Lambda から Amazon EFS 上にファイル efslambda.txt を作成、書き込、保存。

```python
file_path = '/mnt/data/'
 
def lambda_handler(event, context):
    file_name = 'efslambda.txt'
    write_string = event['text']
 
    with open(file_path + file_name, mode='w') as f:
        f.write(write_string)
 
    with open(file_path + file_name) as f:
        print(f.read())
```


#4.テスト#

lambdaよりテストイベントを実行する。

```
{
  "text": "This in lambda"
}
```

![スクリーンショット 2020-06-27 16.23.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/c087a9c9-3414-ff7c-9cdb-b2a5b8853258.png)
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'

たまに以下エラーが起きることがあります。

```
# RAILS_ENV=production bundle exec rake db:migrate
rake aborted!
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
```

結論から言うと、**DBの接続情報が誤っている**ためにこのエラーが起きます。

やることは`config/database.yml`に関して以下のことになります

- 次の値に対して
    - `config/database.yml`自体に設定している値
    - `config/database.yml`から指定している環境変数
- 次の事態が起きていないかどうか確認する
    - 値が間違っている
    - DB設定の値が更新されていて、更新漏れが起きている


私は`config/database.yml`では環境変数を指定することが多く、
いつの間にかに更新されていた環境変数を更新漏れしていたり、
dockerの他のコンテナで指定していたDB名と環境変数で指定していたDB名が間違っていたり
と度々このエラーに遭います。

他のエラーのときにもこのエラー起きるかもしれませんが、私の場合100%接続情報エラーなので、このエラーが紛らわしくて仕方ないです。
接続設定間違ってるよと言ってくれれば律儀に`/var/run/mysqld/mysqld.sock`がどういうものを調べに行ったり、ググらなくて済むので

他の場合は以下のQiitaの場合かもしれません
https://qiita.com/fujitora/items/d341c52706d1954cae28
【flutter】firebase登録時にsetting.gradeでのエラー

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  provider: ^4.1.3
  firebase_core: ^0.4.5
  cloud_firestore: ^0.13.7
```
firebase_core,cloud_firestoreを登録した際に

```run
**Plugin project :firebase_core_web not found. Please update settings.gradle.**
**Plugin project :cloud_firestore_web not found. Please update settings.gradle.**
```
のようなエラーが出力された。

この時、以下のような対応でエラーを解消した。

ステップ１　minsdkを１６-21に変更

```build.grade
 defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.trainingmaxapp"
        minSdkVersion 21 //16から21に変更
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
```

ステップ２　setting.gradeを追加する

```setting.grade
include ':app'

def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()

def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
    pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}

plugins.each { name, path ->
    def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
    include ":$name"
    project(":$name").projectDir = pluginDirectory
}
```

これでエラーが解消される。
UTPC 2013 F 魔法の糸

##問題
https://atcoder.jp/contests/utpc2013/tasks/utpc2013_06
##解法
グループAとグループBを併合して新しいグループCを作るとき、配慮すべき辺は
- Aの最小全域木に含まれる辺($<=n-1$)
- Bの最小全域木に含まれる辺($<=n-1$)
- AとBとの間に伸びる辺($<=m$)
で、これらを逐次計算していけばよくて、それで間に合う理由は、グループ併合の際にたくさんの辺（多くてm個）を考えた最小全域木を構成しないといけないかもしれないが、それを構成してしまえば、それ以降に上記の3番目の辺の数はぐんと減るからである。
##ソースコード
```c++
struct uftree{
    int cou;
    vector<int> parent;
    vector<int> rank;
    vector<int> _size;
    uftree(int n){
        init(n);
    }
    void init(const int &n){
        parent=vector<int>(n);
        rank=vector<int>(n,0);
        _size=vector<int>(n,1);
        cou=n;
        rep(i,n){
            parent[i]=i;
        }
    }
    int root(const int &i){
        return parent[i]==i?i:parent[i]=root(parent[i]);
    }
    bool same(const int &i,const int &j){
        return root(i)==root(j);
    }
    void merge(int i,int j){
        i=root(i);j=root(j);
        if(i==j)return;
        cou--;
        if(rank[i]>=rank[j]){
            parent[j]=i;
            _size[i]+=_size[j];
        }else{
            parent[i]=j;
            _size[j]+=_size[i];
        }
        if(rank[i]==rank[j])rank[i]++;
        return;
    }
    int count(){
        return cou;
    }
    int unitsize(const int &i){
        return _size[root(i)];
    }
};
const int N_MAX=2005;
int n,m,q;
vector<pint> qry;
int v[N_MAX][N_MAX];
vector<ppint> table[N_MAX];
vector<ppint> mem;
vector<string> ans;

void Main(){
    int x=0,y=INF10,z=1;
    //入力
    cin>>n>>m;
    uftree tree(n);
    rep(i,m){
        cin>>x>>y>>z;
        v[x][y]=v[y][x]=z;
    }
    cin>>q;
    rep(i,q){
        cin>>x>>y;
        qry.pb({x,y});
    }
    //処理
    rep(i,q){
        x=tree.root(qry[i].first);
        y=tree.root(qry[i].second);
        
        mem.clear();
        z=0;
        vint g1,g2;
        rep(i,n)if(tree.same(i,x))g1.pb(i);
        rep(i,n)if(tree.same(i,y))g2.pb(i);

        arep(i,g1)arep(j,g2)if(v[i][j]!=0)mem.pb({v[i][j],{i,j}});

        arep(i,table[x])mem.pb(i);
        arep(i,table[y])mem.pb(i);

        sort(all(mem));

        ll rec=0;
        tree.merge(x,y);
        vector<ppint> res;
        int count=tree.unitsize(x);

        table[tree.root(x)].clear();

        uftree tr(n);
        for(auto w:mem){
            if(tr.same(w.second.first,w.second.second))continue;
            count--;
            tr.merge(w.second.first,w.second.second);
            table[tree.root(x)].pb(w);
            rec+=w.first;
            if(count==1)break;
        }
        
        if(count>1){
            ans.pb("IMPOSSIBLE");
        }else ans.pb(to_string(rec));
    }
    //出力
    arep(i,ans){
        cout << i <<endl;
    }
}

int main(){
    cin.tie(nullptr);
    cout<<fixed<<setprecision(12);
    Main();
}
```
Yahoo!コンテンツジオコーダAPIを使って施設名から緯度経度を取得する


## 何がしたいか

駅名や施設などのランドマークの名前から緯度と経度を取得したい。

## なぜ使うか
ランドマークから緯度や経度を取得できるAPIには[Google GeoCoding API](https://developers.google.com/maps/documentation/geocoding/intro "google") があり、無料で利用することができますが、クレジットカードの登録が必要となり簡単に使用することが難しくなりました。
Yahoo の [コンテンツジオコーダ API](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/contentsgeocoder.html) は会員登録が必要なもののクレカの登録は不必要で簡単に利用できます。

## 使い方

1. Yahoo! JAPAN ID を取得する。
2. [アプリケーションを登録](https://e.developer.yahoo.co.jp/register "registar")する。
   利用用途に合わせて登録してください。クライアント ID(アプリケーション ID)が発行されます。

### 主な入力パラメータ

| パラメータ  | 値                               | 説明                                         |
| ----------- | -------------------------------- | -------------------------------------------- |
| appid(必須) | string                           | 先程取得したアプリケーション ID              |
| query(必須) | string                           | 検索する文字列                               |
| category    | string(address, landmark, world) | ランドマークを検索するときは'landmark'に設定 |
| output      | string(xml, json)                | 出力形式                                     |

その他のパラメータは[公式サイト](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/contentsgeocoder.html "公式サイト")を参照

#### curl を利用する場合

```
curl -v -G -d appid=<YOUR_APP_ID> -d query=東京タワー -d category=landmark https://map.yahooapis.jp/geocode/cont/V1/contentsGeoCoder
```

#### axios を利用する場合

```javascript
axios
  .get("https://map.yahooapis.jp/geocode/cont/V1/contentsGeoCoder", {
    params: {
      appid: YOUR_APP_ID,
      query: "東京タワー",
      category: "landmark",
      output: "json",
    },
  })
  .then((results) => {
    console.log(results);
  });
```

この方法で緯度経度を取得することができました。
情報の過不足があればコメントお願いします。
AWS SAA（ソリューションアーキテクトアソシエイト）に合格するまでにやったこと



## SAA（ソリューションアーキテクチャアソシエイト）資格とは



[AWS認定試験](https://aws.amazon.com/jp/certification/)は基礎コース、アソシエイト、プロフェッショナル及び専門知識を分けています。アソシエイトは役割によって「アーキテクト」、「運用」、「開発者」を分けています。ソフトウェアエンジニアですが、一番人気の「ソリューションアーキテクトアソシエイト」をチャレンジしました。



認定によって検証される能力は下記の通りです。（[AWS公式ページ](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)より抜粋）

> 認定によって検証される能力
>
> - AWS のテクノロジーを使用して安全で堅牢なアプリケーションを構築およびデプロイするための知識を効果的に証明すること
> - 顧客の要件に基づき、アーキテクチャ設計原則に沿ってソリューションを定義できること
> - プロジェクトのライフサイクルを通して、ベストプラクティスに基づく実装ガイダンスを組織に提供できること



## 試験の詳細

| 項目     | 説明                         |
| -------- | ---------------------------- |
| 問題形式 | 単一選択及び複数選択（２つ） |
| 実施形式 | テストセンター試験           |
| 時間     | 130分間                      |
| 受験料金 | 15,000円（税別）             |
| 言語     | 英語、日本語                 |



## 言語

AWSの公式ドキュメントには基本的に専門用語そのままカタカナに訳されていますので、分かりづらいところがあります。わからない場合、いつも英語のオリジナルドキュメントを読んでいます。今回の試験も英語に選びました。



## なぜ受けたのか

４年目のソフトウェアエンジンです。Azureを利用するプロジェクト経験がありますが、AWSはEC2ぐらい触ったことしかないです。

クラウド開発スキルは求められる案件はどんどん増えてきましたので、クラウド知識を勉強したほうがよいかと思いました。政府共通プラットフォームでAWS採用のニュースを見て、AWSの資格を取ろうと決意しました。



## 合格するまでにやったこと



### AWSアカウント登録

ペーパー資格は意味がないですので、まずAWSのアカウントを作成して、主な製品を触ってみました。AWSのサービスは多すぎますので、よく使われる製品のみ注目しました。



### 公式ドキュメント

各製品を触りながら、それぞれの公式ドキュメントを確認しました。正直公式のドキュメントも多すぎますので、基本的にわからないところのみ読みました。後述のように受験対策の際、また公式ドキュメントを確認しないといけないです。



### 参考書

下記の１冊を使いました。選定理由としては、最近発売されたことです。AWSのサービスはどんどん変わりますので、最新版の内容も反映されているかと思いました。

[AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/479739739X/ref=asc_df_479739739X/?tag=jpgo-22&linkCode=df0&hvadid=288845875882&hvpos=&hvnetw=g&hvrand=12835654491424837818&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009293&hvtargid=pla-662045681941&psc=1&th=1&psc=1)



### 問題集

やはり参考書の問題は足りない気がしますので、下記のiPhoneアプリも購入しました。

[AWS ソリューションアーキテクト問題集338問](https://apps.apple.com/jp/app/aws-ソリューションアーキテクト問題集338問/id1516067973)

問題数が多いですので、全部解答して、間違った問題を調べ直して、結構時間がかかりました。

解答説明がないですが、やはりもう一度公式ドキュメントをちゃんと読んで理解しないといけないです。意外にちゃんと理解して、ちゃんと覚えて、実務経験も積んだ効果がありました。

アプリはテスト機能もありますので、80点以上なるまでテストを繰り返しました。
【爆速メモ】tinkercadからエクスポートして、blenderやunityへインポートする際のサイズ感について

# あるある
tinkercadからエクスポートしたobjファイルを、blenderやunityでインポートしたら超絶サイズがでかい

---

# なので
tinkercadで1cmくらいのオブジェクトをエクスポートすれば、blenderやunityにとってちょうどよいサイズ感となる。

- blenderだと頂点数が2万切るので、その気になればclusterのアバターに使えそう。
【Laravel】グローバルスコープを用いてコード量を減らす

##はじめに
実装していてモデルのクエリに制約で何度も同じ実装することはありませんか。
そんな時はグローバルスコープというLaravelの機能のグローバルスコープを使って1回の実装で済むようにするのも1つの方法かなと思います。

##グローバルスコープとは

>グローバルスコープにより、指定したモデルの全クエリに対して、制約を付け加えることができます。Laravel自身のソフトデリート機能は、「削除されていない」モデルをデータベースから取得するためにグローバルスコープを使用しています。独自のグローバルスコープを書くことにより、特定のモデルのクエリに制約を確実に、簡単に、便利に指定できます。

引用：[Eloquent：利用の開始 7.x Laravel](https://readouble.com/laravel/7.x/ja/eloquent.html)

グローバルスコープを1回の実装すれば特定のモデルのクエリに制約ができ、かなり便利です。

##グローバルスコープの実装

`Illuminate\Database\Eloquent\Scope`配下に適当なファイルを作成します。

```PHP:walkingMinutes.php
<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class walkingMinutesScope implements Scope
{
    /**
     * Eloquentクエリビルダへ適用するスコープ
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function setGlobalScope(Builder $builder, Model $model)
    {
        static::addGlobalScope('walking_minute', function (Builder $builder) {
            $builder->orderByRaw('walking_minute' ASC NULLS LAST);
        });
    }
}
```
こんな感じに実装するとどこでもwalking_minutes（徒歩時間）が短い順に表示できるようになります。

##おわりに
いかがでしたでしょうか。
うまく実装して無駄な実装を減らしていきましょう。
ghq と peco を VSCode で リポジトリを快適に開けるようにする

## はじめに

この記事の対象として以下のユーザを想定しています。

* [ghq](https://github.com/x-motemen/ghq)&[peco](https://github.com/peco/peco)でリポジトリ検索&移動を効率化をしたユーザ
* [VSCode](https://azure.microsoft.com/ja-jp/products/visual-studio-code/) を使用している & `code` [コマンドが使えるよう](https://www.atmarkit.co.jp/ait/articles/1812/21/news035.html)にしてあるユーザ

ちなみに筆者は [ghq, peco, hubで快適Gitライフを手に入れよう！](https://qiita.com/itkrt2y/items/0671d1f48e66f21241e2) を情報源に環境を整えました:v:


### やったこと

* ghq で管理している一覧から選択したリポジトリをVSCodeで開く

以下の aliasを設定するだけで新しいウィンドウで開いてくれます:relaxed:

```shell
# Alias
alias cg='code "`ghq root`/`ghq list | peco`"'
```

### まとめ

ghq x peco x VSCode で快適な開発環境を整えましょう〜〜 :rocket:
初投稿。グループ機能作成中に起きた事

# Routing Error
グループ機能作成中に起きたRouting Errorについて、
この画像では、controllerがgroupsになっている。
<img width="201" alt="スクリーンショット 2020-06-27 17.58.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/2895bc65-6bb9-c64d-5587-148a86799309.png">
下の画像では、groupsとなっているが、ここでgroupにした事でRouting Errorが起きてしまった。
<img width="581" alt="スクリーンショット 2020-06-27 17.57.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/a69ef3c9-ecf3-6839-af97-b2f42ca1476a.png">

# マイグレーションについて
例えばこの様マイグレーションファイルにdb:migrateで間違った記述をしてしまった時
<img width="464" alt="スクリーンショット 2020-06-27 18.08.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/8dd87f79-0764-d234-e62e-0807e6776fad.png">
db:rollbackで戻して訂正する事ができる。
また、db:migrateで訂正完了です。

## db:rollback
db:rollbackでは一つ前しか戻せない。

## db:rollback STEP=数字
db:rollback STEP=数字を使う事で任意に所まで戻す事ができる。
【cluster】No1.cluster環境構築からチュートリアルインポートからのまずは３つのコンポーネントを覚える

環境メモ
開発環境　MacBookPro
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2019.2.21f1

#ポイント
・Unityのバージョンは「Unity 2019.2.21f1」を使う。
・チュートリアル「Creator Kit Sample」をインポートして学ぶ

【cluster】No1.cluster環境構築からチュートリアルインポートまでの手順
https://qiita.com/nonkapibara/items/4964a945317a8e25e2a3

【cluster】No2.clusterはじめてのワールド作成手順
https://qiita.com/nonkapibara/items/ca9bca9cdba412bc01d2

#環境構築
下記、cluster公式サイトを参考にして、Unityをインストールする

■すぐ出来る！ワールド作成の始め方
https://creator.cluster.mu/2020/02/27/helloworld/

Untiyのアーカイブページから「Unity 2019.2.21f1」をUnity Hubでダウンロードする。
https://unity3d.com/get-unity/download/archive

<img width="973" alt="スクリーンショット 2020-06-27 13.16.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/24da00dc-c1b3-ed63-e79d-2062b6c1c8cd.png">


# チュートリアルをインポートする

チュートリアルCreator Kit Sample「ClusterCreatorKitSample-master.zip」をダウンロードする
https://github.com/ClusterVR/ClusterCreatorKitSample/archive/master.zip
<img width="307" alt="スクリーンショット 2020-06-27 10.04.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/7b9b9847-609c-acd0-9a4d-a435e09d797a.png">

■チュートリアルCreator Kit SampleのGitHubページ
https://github.com/ClusterVR/ClusterCreatorKitSample

Readmeに、サンプルの内容説明が書いてある
<img width="677" alt="スクリーンショット 2020-06-27 14.05.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/8c6a116b-3b63-ecd4-740a-247948458297.png">


※詳細は下記ドキュメントに記載してある。
Cluster Creator Kit ドキュメント
https://clustervr.gitbook.io/creatorkit/

チュートリアルCreator Kit Sampleインポート完了
<img width="343" alt="スクリーンショット 2020-06-27 13.32.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/285a2a24-d3c9-adae-8d96-542bee5140b0.png">



#　cluster公式サイト「ワールド作成の基礎を学ぼう」を見てみる
「ワールド作成の基礎を学ぼう」を読みながら、チュートリアルのソースを見ていく。

ワールド作成の基礎を学ぼう
https://creator.cluster.mu/2020/03/03/learn-world-basic/


チュートリアルCreator Kit Sample「ClusterVR」-「Scenes」の「MinimalSample」を開く
<img width="870" alt="スクリーンショット 2020-06-27 13.28.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/664e9089-7330-5a5b-fef1-8503bd67e6e3.png">


まずは、下記の３つのコンポーネントを見ていく
<font color="DeepPink">**SpawnPoint（プレイヤーの出現ポイント）**</font>
<img width="1305" alt="スクリーンショット 2020-06-27 13.38.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/45f34800-eb75-ead7-e8f0-78b6e1845ac0.png">

<font color="DeepPink">**DespawnHeight（プレイヤーが消滅する高さ）**</font>
<img width="1228" alt="スクリーンショット 2020-06-27 13.42.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/eeca318d-386d-f409-81da-64ac1066a3e4.png">

<font color="DeepPink">**Collider（衝突可能なオブジェクト）**</font>
<img width="1306" alt="スクリーンショット 2020-06-27 13.48.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/4a2d2e88-3328-64f4-f84e-17eda3bfd7ae.png">


続きはこちら
【cluster】No2.clusterはじめてのワールド作成手順
https://qiita.com/nonkapibara/items/ca9bca9cdba412bc01d2
GAEでHelloWorld！を表示するまでにやったことメモ

# 前提条件
しがないWEBディレクターが仕事でGCPに触れることになったので
どのアプリケーションがどんな動きをするのか把握するために触れてます。
この記事は自分がつまづいた部分を中心にメモとして残すものになっております。

# 学習する上でやりたいこと
1.GoogleAppEngineを使用してPHPが動くようにする　←今回はここ
2.ドメイン設定
3.Wordpressを導入しポートフォリオを作成する
4.３までを試した上で理想のアーキテクチャ図を作成する

# いざ設定開始
**GCPの設定**
1.GCPで使用するGoogleアカウントでログイン

**GAEの設定**
1.サイドメニューからGAE>ダッシュボードの順に移動
2.プロジェクト名を登録
3.Cloud SDKの設定

**Cloud SDKの設定〜app.yamlの設定まで**
下記の記事を参考にさせていただきました
https://blog.apar.jp/web/6912/

**ローカル環境でPHPの動作チェック**
1.ターミナルで`$ dev_appserver.py .`を実行すると、ローカル開発環境にアクセスできるようになる
>私の場合、この手順時にローカル開発環境にアクセスしても４０４、ターミナルでアラートが出てしまうという状態になってしまった。

>**解消方法**
①ローカル環境で「HelloWorld！」が表示されない
app.yamlに記載したPHPのバージョンを72にしていたので、55に変更
上記に記載した参考記事とは別で見た記事に「７２でもOK」と記載あったので試してみたところうまく動かなかった

>②ターミナルで表示されたアラートの解消方法（未解決）
〈表示されたアラート〉
<img width="437" alt="スクリーンショット 2020-06-27 16.14.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617142/1ce0e852-7f1d-c393-1fed-738846cf52e2.png">
正直①の問題が解消されないのはこいつのせいかと思っていたけれど、どうやら別問題っぽい。
JDKとやらをダウンロードすれば直るかな

2.localhost:8080で動作確認
>①の問題解消後無事に表示された

**いざデブロイ**
1.ターミナルで`$ gcloud app deploy`を実行
　最終確認されるのでyで実行
2.`$ gcloud app browse`でブラウザ確認
　HelloWorldが表示され無事にテスト完了！

### 解消したい問題
1.ターミナル実行時に表示されるエラーの理解と解消
2.なぜPHP5.5が動いて７．２だと動かないのか確認（サポートされてない？）
敵対的サンプル

#この記事は未完成で、随時勉強して書き加えていきます。

#⒈敵対的サンプル

画像認識分野で考えます。

敵対性サンプルとは、元画像データ（モデルによって正しく分類できているデータ）に対してノイズを加えるという変換を加えることで、モデルが誤認識するようなデータを故意に作ること。

具体例を考えましょう。
下の写真を見てください。一番左の写真は、変換前の画像データです。この時は、table10.1を見て貰えば分かる通り、モデルによる認識結果がふさわしいものになっています。


<img width="715" alt="スクリーンショット 2020-06-25 18.35.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/54ee2c47-4c1c-227e-85a2-4485ce978d6c.png">
<img width="990" alt="スクリーンショット 2020-06-25 18.36.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/a7ba7cb6-c461-189c-7c0f-5a318d096f5e.png">

```math
↓
```
<img width="996" alt="スクリーンショット 2020-06-25 18.36.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/22e9d148-dfc9-c2de-3ed2-0e7253ccdf01.png">

これに対して、ノイズを加えたあとの画像（下中央の写真）を見てください。人間が見たところ何ら変化があるようには見えません。しかしながら、モデルに入力して認識させるとどうでしょう。結果はtable10.2のようになりました。ノイズが加えられた正しく画像データは正しく認識されていません。
この、小さな小さなノイズを加えることで、モデルが誤認識してしまうようなデータを作ることを敵対的サンプルと言います。
RaspbianOSのイメージファイルをEtcherでUSBメモリに書き込もうと思ったら書き込めませんでした、と思ったら解決した

RaspbianOSのイメージファイルをEtcherでUSBメモリに書き込もうと思ったら書き込めませんでした

が、Etcherのバージョンを（balenaEtcher-1.5.81へ）更新したら解決しました。
etcherのgithubで同様の問題が報告されており、v1.5.61付近で解決されているそう。
なので、2020/4/24時点の最新版（balenaEtcher-1.5.81へ）を使う事で解決。
> https://github.com/balena-io/etcher/issues/2833#issuecomment-550109402
> This should be fixed in v1.5.61

以下はOSのイメージファイルの更新手順

# OSのイメージファイル(.img)をダウンロード

[本家](https://www.raspberrypi.org/downloads/)からダウンロードする。もしダウンロードに時間が掛かるようなら、
[ミラーサイト](https://www.raspbian.org/RaspbianMirrors)のうち、[jaistのミラーサイト](http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/)からダウンロードする。

# USBメモリをフォーマット

イメージファイルを書き込むために、USBメモリをFAT32にフォーマット

> [Macでデータ損失なくUSBメモリをFAT32にフォーマットする方法](https://jp.easeus.com/mac-data-recovery/format-usb-flash-drive-to-fat32-on-mac.html)

# ethcherでUSBメモリに書き込む

[Ethcer](https://www.balena.io/etcher/)を使い、
ダウンロードしたOSイメージ（.img）を書き込む、、、、書き込めませんでした。なぜ？

# 原因
etcherのgithubでも同様の問題が報告されており、v1.5.61付近で解決されているそう。
2020/4/24時点の最新版（balenaEtcher-1.5.81へ）を使う事で解決。
> https://github.com/balena-io/etcher/issues/2833#issuecomment-550109402
> This should be fixed in v1.5.61

# 参考
[balena etcherがOSのアップデートで書き込めないエラー回避方法](https://raspida.com/etcher-error)
[forums.balena.io](https://forums.balena.io/t/balena-and-mac-catalina-not-working/38073/6)
[Etcher broken on macOS Catalina](https://github.com/balena-io/etcher/issues/2833)
Raspberry 3B+ + Ubuntu Mate 18.04 環境へMacからリモート接続


# 環境
Raspberry 3B+, Ubuntu Make 18.04
MacとRaspberryPiは自宅のWifiルータに接続する。（同じネットワークに所属している状態を前提）

# Raspberry 3B+にてopenssh-serverをインストール

```
sudo apt update
sudo apt upgrade
sudo apt install openssh-server
```

# Macからリモート接続

ipアドレス：192.168.2.100
ユーザ名：ubuntu, パスワード: ubuntu とする

```
$ ssh ubuntu@192.168.2.100
ubuntu@192.168.2.100's password:(パスワードを入力)
```

パスワード入力後にRaspberrypiにアクセスできればOK

# Raspberrypi側のip addressを調べる

```
# Raspberrypi側で実行
ifconfig | grep -A 5 -n wlan0
```

# エラー対策

port 22: Connection refused

```
$ ssh ubuntu@192.168.2.100
ssh: connect to host 192.168.2.100 port 22: Connection refused
```

原因：port 22 がアクセス許可されていない
対策：port 22 をアクセス許可する

```
sudo ufw allow 22
# sshの再起動
sudo /etc/init.d/ssh restart
# 起動時にsshの起動
sudo systemctl enable ssh
```

> [Raspberry PiにUbuntu MATEをインストール + リモート接続](https://qiita.com/sasayabaku/items/ff96f700d2b65fdf085e)

これで解決

# エラー対策2

Connection closed

```
$ ssh ubuntu@192.168.2.100
Connection closed by 192.168.2.100 port 22
```

原因：SSH keys が何らかの理由で正しくない
対策：openssh-serverをdpkg-reconfigure する

```
$ sudo dpkg-reconfigure openssh-server
```

[SSH connection closed - resolved](https://www.raspberrypi.org/forums/viewtopic.php?t=177111)
> Apparently, the SSH keys (/etc/ssh/ssh*key) on the Raspberry were all of zero size for some reason. To fix that I had to run the following commands from the terminal: 
> 
> $ sudo rm -r /etc/ssh/ssh*key
> $ sudo dpkg-reconfigure openssh-server
> 
> After the system regenerated the SSH keys I was able to connect via successfully.

これでやっと繋がった。

# 参考
[SSH connection closed - resolved](https://www.raspberrypi.org/forums/viewtopic.php?t=177111)
[Raspberry Piの初期設定](https://qiita.com/morinokami/items/aee081085dd679b1ea22)
[Raspberry PiにUbuntu MATEをインストール + リモート接続](https://qiita.com/sasayabaku/items/ff96f700d2b65fdf085e)
RaspberryPiにGitbucketをインストールする

GitbucketはGitHubのようなリポジトリ管理システムです。

# 必要なツールをインストール

```
sudo apt update
sudo apt install openjdk-8-jdk openjdk-8-jre
java -version
openjdk version "1.8.0_252"
```

環境変数を更新

```
#/etc/environment に以下を追加
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-armhf
JRE_HOME=/usr/lib/jvm/java-8-openjdk-armhf/jre
```

# Gitbucketをダウンロード

```
sudo mkdir /opt/gitbucket
cd /opt/gitbucket
sudo wget -O gitbucket.war https://github.com/gitbucket/gitbucket/releases/download/4.33.0/gitbucket.war
```

# 起動

```
$ java -jar gitbucket.war
...(1分ほど掛かる)
2020-04-30 01:21:30.131:INFO:oejs.AbstractConnector:main: Started ServerConnector@6b2d4a{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2020-04-30 01:21:30.133:INFO:oejs.Server:main: Started @71795ms
```

# 確認
ブラウザへ以下を指定してGitbucketへアクセスできればOK
http://[IPアドレス]:8080/
<img width="332" alt="gitbucket.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/2b873a83-cd63-cbe4-30df-456cd787ec22.png">

初期アカウントは、ID/PASS共に"root"のようだ。

# リポジトリの作成〜Push
### リポジトリ作成：
右上の＋ボタン　→ New Repository
<img width="447" alt="gitbucket2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/4e9bcf7f-f66b-72a3-2bee-65e36e892a53.png">
Create Repository押下

### リポジトリPush：
copy to clipboardからURIをコピー
<img width="1001" alt="gitbucket3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/b4860e5f-80df-8795-346f-a6ef3b3c16ac.png">
以下コマンドを実行する

```
git clone [copy to clipboardからコピーしたURI]
cd test
touch test.txt
git add test.txt
git commit -m "first commit"
git push
```

# 参考
[gitbucket/releases](https://github.com/gitbucket/gitbucket/releases)
[UbuntuにJava8環境構築](https://qiita.com/ayihis@github/items/01f95d5d465168043ae3)
[How to Install JAVA 8 on Ubuntu 18.04/16.04, Linux Mint 19/18](https://tecadmin.net/install-oracle-java-8-ubuntu-via-ppa/)
[git push がエラーで失敗する](https://renkin3q.hatenablog.jp/entry/2017/07/13/094413)
Github pull request練習用に、pull request test用リポジトリを作成

Github pull request練習用に、pull request test用リポジトリを作成した際の備忘メモです。
基本的には[こちら](https://docs.github.com/ja/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)や[こちら](https://docs.github.com/ja/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork)の公式ドキュメントに沿っているだけです。

## pull request手順

以下の通りです

1. Githubアカウント作成/ログイン
1. pull request test用リポジトリをfork
1. forkしたリポジトリを取得/変更を加える
1. Pull Requestをする

## 1. Githubアカウント作成/ログイン

以下を参考にGithubアカウントを作成してログインする。
[GitHub-アカウントの準備と設定](https://git-scm.com/book/ja/v2/GitHub-アカウントの準備と設定)

## 2. pull request test用リポジトリをfork

Github UI上から、以下のtest用リポジトリをforkする。
> [https://github.com/seigot/test_pull_request](https://github.com/seigot/test_pull_request)

fork手順自体は、以下を参考にすると分かりやすい。

> [リポジトリをフォークする](https://docs.github.com/ja/free-pro-team@latest/github/getting-started-with-github/fork-a-repo)
> リポジトリのフォークの例

## 3. forkしたリポジトリを取得/変更を加える

別のマシンで、forkしたリポジトリを取得する。

```
# 例）ユーザ名"seigot"の場合の例、ユーザ名は各自のアカウント名に変更する
git clone https://github.com/seigot/test_pull_request
```

forkしたリポジトリに変更を加える

```
cd test_pull_request             # ディレクトリを移動
checkout -b test_branch main     # 変更用ブランチへ移動
echo "test" >> README.md         # READMEを変更（最終行に"test"を追記）
git add README.md                # 変更対象に登録
git commit -m "test commit"      # commit messageを記載
git push origin test_branch      # forkしたリポジトリへ変更を登録
```

### 4. Pull Requestをする

以下を参考に、[test_pull_request](https://github.com/seigot/test_pull_request)のリポジトリにPull Requestをします

>[フォークからプルリクエストを作成する](https://docs.github.com/ja/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork)
フォークからプルリクエストを作成する
1.作成したフォークの元であるリポジトリに移動します。
2.Above the list of files, click  Pull request.
3.[Compare] ページで [compare across forks] をクリックします。
4.[base branch] ドロップダウンメニューで、変更をマージする上流リポジトリのブランチを選択します。
5.[head fork] ドロップダウンメニューでフォークを選択し、次に [compare branch] ドロップダウンメニューを使用して、変更を加えたブランチを選択します。
6.プルリクエストのタイトルと説明を入力します。
7.ユーザが所有するフォークでは、上流のリポジトリに対するプッシュアクセス件を持つ人がプルリクエストに変更することを許したくない場合は、Allow edits from maintainers（メンテナからの編集を許可）の選択を解除してください。
8.レビューの準備ができたプルリクエストを作成するには、Create Pull Request（プルリクエストの作成）をクリックしてください。


# 参考
[GitHub-アカウントの準備と設定](https://git-scm.com/book/ja/v2/GitHub-アカウントの準備と設定)
[リポジトリをフォークする](https://docs.github.com/ja/free-pro-team@latest/github/getting-started-with-github/fork-a-repo)
[プルリクエストの作成方法](https://docs.github.com/ja/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)
[フォークからプルリクエストを作成する](https://docs.github.com/ja/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork)
[[実践] はじめてのPull Requestをやってみよう](https://qiita.com/wataryooou/items/8dce6b6d5f54ab2cef04)
[【GitHub】Pull Requestの手順](https://qiita.com/aipacommander/items/d61d21988a36a4d0e58b)
macOS の上の VirtualBox の上の Ubuntu の上の Docker の上の jupyter notebook を、SSH で扱うためのリンク集

### MacOS の VirtualBox に Ubuntu をインストールする

やっとできた！MacのVirtualBox上にUbuntuをインストールする方法
https://tomslifestylelab.com/mac-virtualbox-ubuntu/

とりあえず

```
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install vim
```

MacでUbuntuを快適に使う
https://qiita.com/ryoheimorimoto/items/a82369a83c100a646cce

### Ubuntu に SSH でアクセスできるようにする

Mac 上のVirtual Box のUbuntu にSSH でアクセスしX転送する
https://withfpga.com/?p=78

Virtualboxでアダプタ2,アダプタ3,アダプタ4が選択できない
https://teratail.com/questions/164319

### SSH で Docker をインストールする

Ubuntu に Docker をインストールする
https://docs.docker.com/engine/install/ubuntu/

Dockerコマンドをsudoなしで実行する方法 
https://qiita.com/DQNEO/items/da5df074c48b012152ee

### Docker 上で Jupyter notebook を作成してアクセスする

Dockerで基本的なData Science環境(Jupyter, Python, R, Julia, 定番ライブラリ)を構築する。
https://qiita.com/y4m3/items/c2703d4e131e05084b7b

サーバーのDockerで起動したJupyter Notebookを他のパソコンからアクセスできるようにした話
https://qiita.com/yamasakih/items/d23ac0bf773e9b1b4d9d

Julia+Jupyter Notebook環境をDockerで構築
https://qiita.com/yoshikiri/items/683722701b57fa77aec1

リモートサーバのDocker上で起動したJupyter Notebookに他端末からアクセス
https://qiita.com/yu__yu/items/0cd2a82adaa01e066b86
bash上でファイルの絶対パス取得

readlink -f を使えばよい

```
$ readlink -f test.txt
/usr/xxx/test/test.txt
```

# Macでreadlink -f ができない...

以下にスクリプトを作成された方がおられました。

> [Macでもreadlink -f](https://qiita.com/edvakf@github/items/b8400f7dfe9210aadddd)

--- 引用ここから

```sh:readlink.sh
#!/bin/sh

TARGET_FILE=$1

while [ "$TARGET_FILE" != "" ]; do
    cd `dirname $TARGET_FILE`
    FILENAME=`basename $TARGET_FILE`
    TARGET_FILE=`readlink $FILENAME`
done

echo `pwd -P`/$FILENAME
```

--- 引用ここまで

実行するとファイルの絶対パスを取得できました

```
$ bash readlink.sh test.txt
/Users/xxx/Desktop/test.txt
```

# 参考
[Macでもreadlink -f](https://qiita.com/edvakf@github/items/b8400f7dfe9210aadddd)
MacからvncでRaspberrypiを操作する

# Raspberrpi側でvncサーバを起動

起動の際に接続時のパスワードを求められるので設定する

```
$ sudo apt-get install tightvncserver -y
$ sudo tightvncserver
You will require a password to access your desktops.

Password: 
Verify:   
New 'X' desktop is raspberrypi:1
```

# Mac側のVNCクライアントからvncサーバへアクセス

（例）ラズベリーパイ
IPアドレス：192.168.1.100
vncサーバのパスワード：（vncサーバ起動時に設定したパスワード）

Macの場合はFinder→移動からvncサーバに接続できる

<img width="211" alt="スクリーンショット 2020-05-10 23.47.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/7d6221a1-f543-495e-a4ea-aa5ba06bf62d.png">
<img width="291" alt="スクリーンショット 2020-05-10 23.48.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/5e4f2163-e913-7ebe-cfe5-ecd582955dc5.png">

Raspberrypiに接続できた
<img width="288" alt="スクリーンショット 2020-05-10 23.58.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/4ef42288-ef52-e6b5-f5a5-bbdf9d444d30.png">

# 備考
ssh -x で接続する方法が分からなかったのでどなたか教えて下さい。

# 参考
[macしかない状況でRaspberry Piに接続してみた](https://qiita.com/murs313/items/81757bf8bc74b6b76cdf)
[SwiftUI macOS アプリ] 複数行の text field

# 完成イメージ

複数行に渡って書けるテキストフィールドを作ります。 SwiftUI に用意されている `TextField` だと一行しか書けないので。

<img width="592" alt="スクリーンショット 2020-07-04 21.41.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45822/beeec71f-02b5-5f2f-6eeb-88be9ed7a08e.png">


# コード


```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    @State var text = "default text"
    var body: some View {
        VStack {
            MultiTextView(text: $text)
            Text(text)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

struct MultiTextView: NSViewRepresentable {
    @Binding var text: String

    func makeNSView(context: Context) -> NSTextView {
        let view = NSTextView()
        view.delegate = context.coordinator
        view.string = text
        return view
    }
    
    func updateNSView(_ nsView: NSTextView, context: Context) {
        // この行はいらなかった。
        nsView.string = text
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, NSTextViewDelegate {
        var multiTextView: MultiTextView
        init(_ multiTextView: MultiTextView) {
            self.multiTextView = multiTextView
        }
        func textDidChange(_ notification: Notification) {
            guard let text = notification.object as? NSText else {
                return
            }
            self.multiTextView.text = text.string
        }
    }
}
```


参考: 

- https://www.appcoda.com/swiftui-textview-uiviewrepresentable/
- https://github.com/SongProOrg/songpro-editor-swiftui/blob/d46b372b274f614de6dcfda4524638a15061ef34/SongPro%20Editor/EditorView.swift
グラフ初心者がHelloGraphを使ってみた

グラフ初心者でも簡単にグラフ描画ができるHelloGraphを使ってみました。
約１分で簡単にグラフ描画ができるので、皆さんも是非試してみてください。

HelloGraphとは

https://github.com/g2glab/hellograph

★初心者向け
Zipファイルのダウンロードとブラウザだけで簡単に利用できます。

1.以下のリンクから、zipファイルをダウンロードします。
https://g2glab.github.io/hellograph/

2.任意のフォルダでzipファイルを解凍します。

3.解凍すると「hellograph-master」フォルダが作成されます。
フォルダ内の「hellograph.html」を開きます。

4.ブラウザが起動し、HelloGraphが表示されます。

5.画面の左下にある[ファイルを選択]をクリックします。

6.~/hellograph-master/examples　内のファイルを選択します。
　簡単に描画できるC360.json,C360.pgをおすすめいたします。
　C360(Customer360の略)は顧客の購買情報データをグラフ化しています。

![Hello Graph](https://user-images.githubusercontent.com/4862919/85920263-3d913180-b8ad-11ea-8902-d5ad964d1f95.gif "Hello Graph")


★Gitを普段から利用している方向け

1.リポジトリをクローンします。
```$ git clone https://github.com/g2glab/hellograph.git```

2.hellographディレクトリへ移動します。
```$ cd hellograph```

3.コンソールで以下のコマンドを入力します。
MacOS
```$ open hellograph.html```

unix系OS
```$ xdg-open hellograph.html```

5.画面の左下にある[ファイルを選択]をクリックします。

6.~/hellograph-master/examples　内のファイルを選択します。
　簡単に描画できるC360.json,C360.pgをおすすめいたします。
　C360(Customer360の略)は顧客の購買情報データをグラフ化しています。
AWS Lambdaのリソースベースポリシーのサイズが上限に達して困った話

## はじめに
AWS samを利用しAPI gateway + Lambdaの構成を作成していたのですが、Cloudformationの変更セットを実行中に以下のエラーを取得してしまいました。

```
The final policy size (20857) is bigger than the limit (20480). 
(Service: AWSLambda; Status Code: 400; Error Code: PolicyLengthExceededException; 
Request ID: xxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx)
```

このエラーが示す内容としては、 **Lambdaのリソースベースポリシーがサイズ上限に達した** ということを示しています。
この状態になるとAPIのメソッドの統合リクエストのタイプにこのLambdaを指定することが出来なくなります。

## 調べてみて
いくつか記事を漁っていると、以下の記事を発見しました。
[Lambda エラー「最終ポリシーサイズが制限を超えています」を解決する方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/lambda-resource-based-policy-size-error/)

この記事では、複数あるリソースベースポリシーをポリシー内のリソースの指定にワイルドカードを用いることで、ポリシーのサイズを縮小する方法を説明してくれています。

とりあえず、今あるポリシーを削除して新たにワイルドカードを含むポリシーをセットしてやればいいようです。
残念ながらAWS Lambdaのリソースベースポリシーはマネジメントコンソールからは操作することが出来ないのでCLIを使って操作していきます。

**追記**
消す方法ありました。(笑)
![コメント 2020-07-02 194246.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/98eb586e-ba8f-ed62-943c-99405fcb107f.png)

トリガーでAPI Gatewayを選択すると、登録されているリソースベースポリシーがリソース単位で確認でき、ここから削除をするとポリシーからも削除できるようです！

### 削除のコマンド
以下のコマンドでLambdaのリソースベースポリシーを1件削除することが出来ます。
残念ながら一括で削除をすることは出来ないようです。
なので大量にある場合は二人で上下から削除していくか、諦めてLambdaを作り直すとかした方が良さそうですね。

```
$ aws lambda remove-permission \
--function-name my-function \
--statement-id sid
```

### 作成のコマンド
以下のコマンドでLambdaのリソースベースポリシーを1件追加することが出来ます。

```
aws lambda add-permission --function-name my-function \
--statement-id sid \
--action 'lambda:InvokeFunction' \
--principal 'events.amazonaws.com' \
--source-arn 'arn:aws:events:region:account-id:rule/test-*'　
```

ここで、API gatewayの指定方法がわからず詰んでいましたが、なんとか以下の指定で通すことが出来ました。
このように指定することで1個のAPIからリクエストの種類が増えても、このポリシー1つで補うことが出来ます。

```
aws lambda add-permission 
--function-name my-function \
--statement-id 1 \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn arn:aws:execute-api:${region}:${AWSアカウントID}:${APIの識別子}/*
```

#### samでこれをやる場合の注意点
恐らくsamに限った話ではないと思いますが、新しくワイルドカードを含むポリシーを追加後、新たにメソッドを追加したtemplateを実行すると、 **追加した分の** ポリシーが追加されてしまいました。放っておくと将来的に同じ事象にぶつかると思うので、逐次消すなりする必要があると思います。

## 最後に
APIの指定の方法がわかり、なんとか解決することが出来て良かったです。
こういったこともありえるのでAWS Lambdaは極力分割していくのが良いんでしょうね。

ではまた。

### 参考資料
[Lambda エラー「最終ポリシーサイズが制限を超えています」を解決する方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/lambda-resource-based-policy-size-error/)
KubernetesのAPIバージョンの話

# 呪文

プログラミングを始めたての頃は、「とりあえずこの通りに書くって覚えておけばいいよ」と教わるものがあります。

C言語でいう

```
#include <stdio.h>                                                           
#include <math.h>  
```

とかシェルスクリプトで言う

```
#!/bin/bash
```

です。

そして、Kubernetesのyamlファイルの先頭に書かれている

```
apiVersion: v1beta1
```
とか

```
apiVersion: v1
```
とかもあまり意味を考えずに利用しがちです。


# あれはAPIバージョン

で、タイトルにもある通りあれはAPIバージョンと呼ばれるKubernetesのオブジェクトのバージョンを指しています。

で、ポイントはアルファレベルとベータレベルとステープルレベルの３種類あって、後者に行けば行くほど安定版です。

# 覚えておくといいこと

アルファレベル（`v1alpha1`）は実験的な実装、ベータレベルは互換性のない変更可能性あり、ステーブルレベルは安定版。本番環境ではステーブルレベル以外のオブジェクトは利用しない方がいいってのは覚えておくといいと思います。（alphaとかbetaが書いて無ければステーブル版）
Ship&Coで始める簡単配送プログラミング！

この投稿は、ネット通販などで欠かせない配送業務を、クラウド型出荷管理システム[Ship&Co](https://www.shipandco.com)のAPIを使ってプログラミングし、効率化するための方法について記載します。

- APIの仕様は[APIドキュメント](https://developer.shipandco.com)として公開されています。詳しい情報をお求めの方はこちらをご参照ください（フッターで日本語と英語の切り替えができます）。
- 実際のAPI呼び出しのサンプルも[Postmanのコレクション](https://documenter.getpostman.com/view/3269571/SW14TvyF?version=latest)として公開されています。すぐに試したい方はこちらをご参照ください。

# Ship&CoのAPIでできることとその利点

Ship&CoのAPIでできることは、**送り状の印刷、料金計算、追跡情報の取得、運送会社、倉庫や住所などの関連情報の管理など**です。またユニークな機能として、**サブユーザー**という概念で、それらのデータをユーザーごとに区分して管理することができます。
![alt1](https://developer.shipandco.com/images/api_diagram_1.svg)
![alt2](https://developer.shipandco.com/images/api_diagram_2.svg)

送り状の印刷などは各運用会社がAPIとして提供していることもありますが、それらの処理方法やフォーマットはまちまちです。Ship&CoのAPIの大きな特徴は、**運送会社や、国内・海外の発送で異なるインターフェースを同じ仕様のAPIで一元管理できる**ことであり、配送業者を追加したり、変更してもプログラミングの内容を大きく変更する必要がありません。

では、そのShip&CoのAPIの使い方について見てみましょう。

# ステップ０：Ship&Coのアカウント登録

Ship&CoのAPIを利用するには[こちら](https://app.shipandco.com/)からアカウント登録をする必要があります。すでにアカウントをお持ちの方は不要です。

# ステップ１：アクセストークンの取得

[こちら](https://developer.shipandco.com/#t-auth)に記載されているように、Ship&Coのダッシュボードからアクセストークンを取得します。取得したアクセストークンを所定のHTTPヘッダーに書くことでShip&CoのAPIを呼び出すことができます。
![alt3](https://developer.shipandco.com/images/api_key_ja.png)

# ステップ２：送り状印刷のAPIを呼ぶ

[こちら](https://developer.shipandco.com/#t-ship)に記載されているように、上記で取得したアクセストークンを使って送り状印刷のAPIを呼び出します。実際の送り状印刷には各運送会社との契約が必要ですが、Ship&Coには**テストモード**があり、`"test": true`のパラメータを付与するだけで実際に課金されないダミーの送り状を印刷できます（注：テスト印刷に対応している運送会社のみ可能）。**佐川急便とヤマト運輸は運送会社の登録も不要**です（その他のテスト印刷にはShip&CoのダッシュボードかまたはAPIで運送会社の登録が必要）。

実際のリクエストは以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653449/ec0de0c4-60f7-368f-c8b2-b22a975f85cb.png)

APIのレスポンスには**以下のようなPDFがURLとして含まれます**ので、それを送り状として印刷します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653449/2e7d5a8b-cc7c-0d2b-d79d-4eebc5641307.png)

基本的な利用方法は以上です。運送会社、国内・海外の違いを問わずこのステップで送り状を印刷できます。

# （オプション：料金の計算）

[こちら](https://developer.shipandco.com/#t-rate)に記載されているように、送り状印刷のAPIとほぼ同じパラメータを持つ料金計算のAPIを使って、**各運送会社のサービスごとの配送料**を計算することができます。例えば以下のように、同じ住所に同じものを日本郵便で海外発送をした場合の各サービスの配送料が、APIのレスポンスとして返されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653449/950ff6c4-fa49-f1c1-53e9-3406e8ed112e.png)

**これらのサービスのうち一番料金が安いものを送り状印刷のAPIに指定するようなコードを書けば、常に最安の配送料で送り状を印刷できるプログラムが出来上がります。**

Ship&CoのAPIには、そのほかたくさんのTIPSがありますが、それらは別の投稿で詳しく掘り下げたいと思います。
VSCode の Vetur で types/vue-shim.d.ts が有効にならないのはワークスペースにフォルダが複数あるから

_注意：執筆時点での情報です。 Vetur の将来のバージョンでは解消される可能性があります。_

# 概要

そのまま件名の通りなのですが、
Vue.js で `*.vue` ファイルを作り、 `<script lang="ts">` でコンポーネントを作るときには、
`types` フォルダに `vue-shim.d.ts` 等のファイルを作って、型定義をすると思います。

```typescript:types/vue-shim.d.ts
declare module "*.vue" {
  import Vue from 'vue'
  export default Vue
}
```

Visual Studio Code (VSCode) で Vetur プラグインを導入して、
TypeScript で Vue コンポーネントを作ったりします。

```vuejs:my-component.vue
<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  methods: {
    helloWorld () {
      this.$emit('say', 'Hello, world!')
    }
  }
})
</script>
```

すると、 Vetur の型ヒントでは `this` も `this.$emit` も `any` となってしまいます。

# 原因

この問題について、 Vetur のリポジトリに Issue が上がっていました。
https://github.com/vuejs/vetur/issues/1817#issuecomment-614789578

> In my case it's because I am using a multiroot workspace via 'Add Folder to Workspace'. When I take a project root into its own workspace, the problem goes away.

VSCode の Workspace に複数のルートフォルダが登録されていると、
Vetur が `types` フォルダを正しく解析できない、ということのようです。

# 解決策

1つの Workspace には、1つのルートフォルダのみにすると、正常に動作します。

このエントリが、困っているどなたかの助けになったら幸いです。
Next.jsで手っ取り早くsitemap.xmlを生成するAPIを用意する

Next.jsで作ったwebサイトを検索エンジンにインデックスさせる。
ここでは、SSGするためのデータソースからsitemap.xmlを作ってしまう方法を書く。

## sitemap.xmlを生成して返すAPI

[sitemaps.org](https://www.sitemaps.org/protocol.html)を確認してフォーマットを確認してほしい。
Next.jsでAPIを用意する方法はいくつかあるが自由に読み替えて使えるとおもう。


### sitemap.xmlを生成する
```
// Example
type post = {
  date: number
  slug: string 
}

const generateSitemap = (posts: post[], location: string): string => {
  let xml: string = "";

  posts.map(post => {
    // YYYY-MM-DD
    const postDate: string = new Date(date).toISOString().split('T')[0];
    const projectURL = location + post.slug;

    xml += `<url>
        <loc>${projectURL}</loc>
        <lastmod>${postDate}</lastmod>
        <priority>0.50</priority>
      </url>`;
  });

  return `<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
      ${xml}
    </urlset>`;
};
```

### Next.jsのAPIを使いたい場合


```ts:{project}/pages/api/sitemap.ts
import { NextApiRequest, NextApiResponse } from 'next';
export default async (req: NextApiRequest, res: NextApiResponse) => {
  // Replace your code
  const location = "https://{domain}/"
  const posts = await getPosts()
  const sitemap: string = generateSitemap(posts, location)
  res.setHeader('content-type', 'application/xml');
  res.write(sitemap);
  res.end();
}
```

`http://{domain}/api/sitemap`にGETリクエストでsitemapを生成して返すapiが出来る。




### Next.jsのgetServerSidePropsを使いたい場合
getServerSidePropsはサーバーサイドで実行されるので、こっちでもok。
Next.jsで生成した記事だけインデックスさせたいとかならこっちの方がよいかも。

```ts:{project}/pages/{dir}/sitemap.ts
import { GetServerSideProps } from 'next'
export const getServerSideProps: GetServerSideProps = async ({ res }) => {
  // Replace your code
  const location = "https://{domin}/{dir}/"
  const posts = await getPosts()
  const sitemap: string = generateSitemap(posts, location)
  res.setHeader('content-type', 'application/xml');
  res.write(sitemap);
  res.end();

  return { props: {} }
}

const sitemap = () => null
export default sitemap
```

`http://{domain}/blog/sitemap`にGETリクエストでsitemapを生成して返すapiが出来る。


### Google Serch Consoleからsitemapを追加する

Google Serch Consoleの管理画面から追加する。sitemap.xmlが正しければ、URLを検出してインデックスされるはず。

## おまけ robots.txtを書いて配置する

robots.txtは、Googlebotなどのクローラーに対して、クロールの制御をするためのファイル。sitemap.xmlのパスを記述することで、適切にクロールしてもらえる。


| name | 概要　|
| ---- | ---- |
| Sitemap | sitemap.xmlの絶対パスを書く |
| User-agent | 制御したいクローラーの名前を入れる。全てokなら`*` |
| Allow | クロールを許可するディレクトリ |
| DisAllow | クロールを許可しないディレクトリ |

### 記述例

```
Sitemap: http://{domain}/api/sitemap
User-agent: *
Allow: /*
Disallow: /api/*
```

## 参考
[Create a robots.txt file](https://support.google.com/webmasters/answer/6062596?hl=en)
[sitemaps.org](https://www.sitemaps.org/protocol.html)
[Sitemap with Next.js](https://dev.to/emil_priver/sitemap-with-next-js-539)

今回は手っ取り早くsitemapを作ったが、dynamic routesから生成も出来そう。
[Generate sitemap for static site with dynamic routes · Discussion #12403 · vercel/next.js](https://github.com/vercel/next.js/discussions/12403)