OmniAICreator/Qiita-1.07M huggingface dataset:
iPhoneでp5.jsがしたい

https://apps.apple.com/jp/app/processing-p5-js-icompiler/id648955851

Processingを書くためのappです。この記事のお題はこのappを入れれば解決なんですが、日頃[Pythonista3](https://apps.apple.com/jp/app/pythonista-3/id1085978097)を使っている身には書きにくかったので、別の方法を探しました。

# 必要なもの

次の条件を満たすコードエディタappが必要です。

* ファイル、ディレクトリ管理ができる
* HTMLのプレビューができる

私のお勧めは[Textastic](https://apps.apple.com/jp/app/textastic-code-editor-9/id1049254261), [LiquidLogic](https://apps.apple.com/jp/app/%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF-liquidlogic/id1458566442)です。コンソールを見ることもできるためです。Pythonista3でもコンソール以外は実現可能なので、その方法も後述します。

## 1. ライブラリをダウンロード

p5.jsはJavaScriptライブラリとして実装されており、そのソースコードはダウンロード可能です。まずはそれをダウンロードします。

Safariで[download | p5.js](https://p5js.org/download/) を開き"p5.js complete", "p5.js", "p5.min.js"のいずれかをダウンロードします。筆者は"p5.js complete"にしました。やることはそんなに変わらないはずなので、以降はこの選択をしたものとして書いていきます。

ダウンロードしたファイルは`iCloud/ダウンロード`にあります。解凍して、好きな所に移動させて下さい。

# 2. エディタの準備

お使いのエディタで先ほどダウンロードしたフォルダがあるディレクトリ(仮に`root`という名前だとします)を開きます。念のため、現在のディレクトリ構成を確認しておきます。

```
root
  |- p5
     |- いろいろ
```

次に、`root`直下に`index.html`と`sketch.js`を作成します。ディレクトリ構成は以下のようになります。

```
root
  |- p5
  |  |- いろいろ
  |- index.html
  |- sketch.js
```

各ファイルには以下の内容を記述します。

```html:index.html
<!DOCTYPE html>
<html lang="">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>p5.js</title>
  <style>
    body {
      padding: 0;
      margin: 0;
    }
  </style>
  <script src="./p5/p5.js"></script>
  <script src="./p5/p5.sound.min.js"></script>
  <script src="./sketch.js"></script>
</head>

<body>
  <main>
  </main>
</body>

</html>
```

```JavaScript:sketch.js
function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  clear();
  fill(255, 0, 0);
  ellipse(100, 100, 100, 100);
}
```

`index.html`は`p5/empty-example/index.html`を参考にしました。ダウンロードしたものに応じて、以下の部分を変更してください。

```html:index.html
<script src="./p5/p5.js"></script>
<script src="./p5/p5.sound.min.js"></script>
```

これで準備完了です。`index.html`をプレビューして赤い円が表示されたら成功です。

# おまけ: Pythonista3でp5.js

前節の`root`ディレクトリに`quicklook.py`を追加します。ディレクトリ構成を確認します。

```
root
  |- p5
  |  |- いろいろ
  |- index.html
  |- sketch.js
  |- quicklook.py
```

`quicklook.py`には以下の内容を記述します。

```python:quicklook.py
import os
import ui

if __name__ == '__main__':
    path = f'file://{os.getcwd()}/'
    with open('index.html', 'r', encoding='utf-8') as f:
        s = f.read()
    html = s.replace('./', path)
    v = ui.WebView()
    v.load_html(html)
    v.present('fullscreen')
```

`root`がローカルかiCloudにある場合は上手くいくと思います。dropboxなど、他の場所にある場合は上手く行くか保証できません。大事なのはパスが正確に指定されることなので、上手くいかなかった場合は`f'file://{os.getcwd()}'`の部分を変更してください。`quicklook.py`を実行して赤い円が表示されたら成功です。

# 追記: JSAnywhereを使う

https://apps.apple.com/jp/app/javascript-anywhere-jsanywhere/id363452277

新規プロジェクトを作成する時にp5.js(Processing)をテンプレートに指定するとできます。

![08A642C2-328B-481D-864D-417E07E149AD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497362/7acab4b7-c360-5cdc-2746-ee54c09225ec.png)

プロジェクトには最初から[p5.scribble.js](https://github.com/generative-light/p5.scribble.js/)が入っています。ささっとスケッチを書くだけならこれでも十分でしょう。
WindowsでIMEの動作がおかしい場合の対応方法

#右下にタスクトレイにIMEが表示されているのに、漢字変換ができない！という時

## 解決策
```terminal
#管理者権限でterminalを起動する。

C:\Users\hoge>tasklist | findstr ctfmon
ctfmon.exe                   31256 Console                    1    112,072 K

C:\Users\hoge>taskkill /pid 31256

C:\Users\hoge>ctfmon.exe
```

これで再起動できました。
コンテナのアクセスが遅いと感じたので

コンテナにアクセスしてブラウザに表示するまでが遅くて不便だったので
対策をメモ

```docker-compose.yml

web:
    image: nginx:alpine
    container_name: nginx
    ports:
      - '9400:80'
    depends_on: 
      - app
    volumes: 
      - ./default.conf:/etc/nginx/conf.d/default.conf:delegated
      - .:/var/www/html:delegated
  app:
    build: ./php
    container_name: php
    volumes: 
      - .:/var/www/html:delegated
    depends_on: 
      - mysql
```

volumeにdelegateオプションを付与
[Java]MinecraftのModを作成しよう 1.14.4【番外編】

（この記事は一連の解説記事の一つになります）

先頭記事：[入門編](https://qiita.com/koteko/items/7afadf8261eac49bacad)

# 参考になるサイト
[・Minecraft Forge Forums](https://forums.minecraftforge.net/)
ユーザーフォーラム。後述。
[・Forge Documentation](https://mcforge.readthedocs.io/en/1.14.x/)
公式のドキュメンテーションなので一応乗せたけど、実装という点では正直あんまり参考にならない。もちろん正しいことが書いてあるし、概念の理解には役に立つ。
[・Minecraft Forge Modding 目次](https://qiita.com/Hiroya_W/items/2af8fcacab5feaf880b6)
Qiita記事。日本語。この記事を書くにあたって大部分をこの記事から参考にした。まずはこれらをコピペするだけでも動くので、"何ができるのか"を確認するために一通りやるのもよい。
[・初心者modderの備忘録](https://json-fileman.hatenablog.com/)
[1.12/1.15] 個人ブログ。日本語。チュートリアル的な内容がコードともに書かれている。バージョン差異に注意。
[・Jabelar's Minecraft Forge Modding Tutorials](http://jabelarminecraft.blogspot.com/)
[1.12] 個人サイト。英語。実装の指針について詳しい。コードは参考程度に。バージョン差異に注意。
[・CurseForge](https://www.curseforge.com/minecraft/mc-mods)
最近主流(?)なMod配布所。Modの多くはソースコードをgithubで公開しているので、一定の人気があるModのソースコードを見ると非常に役に立つ。
・その他
実はyoutubeにチュートリアル動画が結構ある。「minecraft modding 1.14」等で検索。動画ベースというのが苦手で今回は省略したが、必要に応じて見るとよい。
# 問題解決ためのTips
## わかんないことはバニラのコードに聞け(重要)
ブラウザにそれっぽい参考サイトのタブが無限に増えていくのに全く問題が解決されない、そんな状況になることもあるかと思います。色んなバージョン、色んな人の書き方を見比べてどれが今の自分に正しいのか混乱したり。
そういう言うときはまず**バニラのコードを見に行くのが大正義**です。**大抵のものはバニラの拡張で書ける**と考えていいです。プログラム的に言えば継承です。これができるようになると飛躍的に理解が深まると思います。

**で、それってどこにあるの？**
　`→　プロジェクト -> 外部プロジェクト -> Gradle:net.minecraft.forge:VERSION -> forge-VERSION-recomp.jar`

## ググり方
わざわざ書くまでもないと思いますが初学者想定なので
基本は「minecraft forge (知りたいこと)」英語資料がアテなので英語で
例えば木を追加したいなら「minecraft forge custom tree」「minecraft forge how to add tree」など　「custom (対象)」がHITしやすいかと思います
こうなるはず物がならないみたいなとき、文法とか気にせず「(対象) not (動詞原型)」でいいです　「tree not generate」「leaves not decay」
バージョンまで指定したいですが、資料が少ないので他バージョンでも見てみて真似できそうなら真似してみるくらいがいいと思います(それでよく罠にはまるんですけど)
## フォーラム検索
何度かググってると大抵は[Forgeのユーザーフォーラム](https://forums.minecraftforge.net/)であることに気付くと思います。なのではじめからこっちで検索をかけてもよいです。完全一致検索を利用しましょう(「custom tree」ではなく「"custom tree"」で検索)。フォーラムという性質上、悩みやすい問題に関しては結構見つかります。が、全く参考にならないまま閉じたスレッドも多いので期待しすぎは禁物。
[Java]MinecraftのModを作成しよう 1.14.4【3. クリエイティブタブの追加】

（この記事は一連の解説記事の一つになります）

先頭記事：[入門編](https://qiita.com/koteko/items/7afadf8261eac49bacad)
前の記事：[2. ブロックの追加](https://qiita.com/koteko/items/c904b3bfdd90f0b9a98a)
次の記事：[4. ツールの追加](https://qiita.com/koteko/items/0c3a73d1ed299cfbde02)

# クリエイティブタブの追加
ここまでアイテムとブロックを追加してきましたが、クリエイティブにおいてバニラ[^1] のアイテムとおなじタブに表示されるのは少し変な気がします。 それに、追加アイテムは独自のタブにまとまっていた方が何かと便利です。ここでは自分のMod用のクリエイティブタブを追加します。

```
\src\main\java\jp\koteko\example_mod\
   ├ ExampleItemGroup.java
   ├ ExampleMod.java
   └ lists
```

```java:ExampleItemGroup.java
package jp.koteko.example_mod;

import jp.koteko.example_mod.lists.ItemList;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

public class ExampleItemGroup extends ItemGroup {
    public static final ExampleItemGroup DEFAULT = new ExampleItemGroup();

    public ExampleItemGroup() {
        super("example_mod");
    }

    @Override
    @OnlyIn(Dist.CLIENT)
    public ItemStack createIcon() {
        return new ItemStack(ItemList.ExampleIngot);
    }
}

```
`ItemGroup`を継承した独自のクラスを定義します。`createIcon`でタブのアイコンを設定します(このメソッドは必須です)。なお、ここで指定した`"example_mod"`はModIDではなく、このItemGroupの内部IDです。

このタブを使うように、既存の追加アイテムの設定を変更します。

```java:ItemList.java
// ...
import jp.koteko.example_mod.ExampleItemGroup; // 追加
//import net.minecraft.item.ItemGroup; // 削除
// ...
@Mod.EventBusSubscriber(modid = ExampleMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ItemList {
    // groupの引数を変更
    public static Item ExampleIngot = new Item(new Item.Properties().group(ExampleItemGroup.DEFAULT))
            .setRegistryName(new ResourceLocation(ExampleMod.MOD_ID, "example_ingot"));
    // ...
}

```

```java:BlockList.java
// ...
import jp.koteko.example_mod.ExampleItemGroup; // 追加
//import net.minecraft.item.ItemGroup; // 削除
// ...
@Mod.EventBusSubscriber(modid = ExampleMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class BlockList {
    // ...
    // groupの引数を変更
    @SubscribeEvent
    public static void registerBlockItems(RegistryEvent.Register<Item> event) {
        event.getRegistry().registerAll(
                new BlockItem(ExampleBlock, new Item.Properties().group(ExampleItemGroup.DEFAULT))
                        .setRegistryName(new ResourceLocation(ExampleMod.MOD_ID, "example_block"))
        );
    }
}

```
続いて、このままだと表示名が設定されていないので、langファイルに追加します。

```json:en_us.json
{
  "itemGroup.example_mod": "Example Mod",
  "item.example_mod.example_ingot": "Example Ingot",
  "block.example_mod.example_block": "Example Block"
}
```

```json:ja_jp.json
{
  "itemGroup.example_mod": "例Mod",
  "item.example_mod.example_ingot": "例インゴット",
  "block.example_mod.example_block": "例ブロック"
}
```
ゲームを起動します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256627/9237012f-2128-1f76-dd6d-7bd641b6f7b9.png)
**自分のModだけの新しいタブが追加できました。**

# 参考
[Minecraft 1.14.4 Forge Modの作成 その5 【クリエイティブタブの追加】](https://qiita.com/Hiroya_W/items/ed9876b9dc94d4424b4d)

# 次の記事
[4. ツールの追加](https://qiita.com/koteko/items/0c3a73d1ed299cfbde02)

[^1]: Modが入っていない素のマイクラのこと
[FlutterWeb] iOS端末で画像が表示されないときのTips - webp

# iOS端末でFlutterWeb上の画像が表示されない
僕は今までAndroidのアプリを開発していたのですが、愛するGoogleがFlutterを推しているので、この機会にiOS・Webアプリ開発に触れてみようとFlutterでWebアプリ開発を試みた時に起こった事象です。

今回の事象について最初は画像表示方法が間違っていると思い少し悩んだのですが、結論としてはもっとシンプルな話でした。恐らくiOS開発に慣れている人は陥らないエラーかと思うのですが、僕と同じAndroid出身のために残します。

## 結論
Googleが生み出した便利な画像フォーマット「webp」をiOSはサポートしてない。
つまりFlutterでは対応していてもiOSでは表示できない。
https://github.com/fluttercandies/flutter_image_editor/issues/42

### ※2020/06/23時点で改善の兆し有り
iOSでもwebpを対応していくようなので、この問題は短期的なもので終わる可能性がある。嬉しい。
2020/06/23時点　Safari 14 Beta Release Notes
>New Features
>Added WebP image support.
https://developer.apple.com/documentation/safari-release-notes/safari-14-beta-release-notes

# 参考
## Flutterで使える画像拡張子
下記を見る限り画像データは「JPEG, WebP, GIF, animated WebP/GIF, PNG, BMP, and WBMP」が使える。
https://flutter.dev/docs/development/ui/assets-and-images
> Common types of assets include static data (for example, JSON files), configuration files, icons, and images (JPEG, WebP, GIF, animated WebP/GIF, PNG, BMP, and WBMP).

## 参考issue
"decode image error" with Webp images on iOS #42
https://github.com/fluttercandies/flutter_image_editor/issues/42

Add support for WebP #9857
https://github.com/flutter/flutter/issues/9857


# おわりに
最初はWebp使えないと絶望したのですが、徐々に対応されているようで安心しました。
Flutterでもっとアプリ開発が便利になることを楽しみにしています！

Twitterフォローもよろしくです！
- @noumi0k
【GCP】Associate Cloud Engineerに合格したのでやったことまとめ

#書籍
使用しませんでした。
#webサイト
Googleの提供しているドキュメントから以下を熟読
　ベストプラクティス
　https://cloud.google.com/docs/enterprise/best-practices-for-enterprise-organizations?hl=ja
　https://cloud.google.com/solutions/best-practices-vpc-design?hl=ja
　https://cloud.google.com/solutions/best-practices-for-operating-containers?hl=ja
　https://cloud.google.com/iam/docs/resource-hierarchy-access-control?hl=ja

#動画
udemyの以下の動画を購入しました。
　https://www.udemy.com/course/google-certified-associate-cloud-engineer/learn/lecture/13347700#overview
　https://www.udemy.com/course/google-cloud-associate-cloud-engineer-certification/learn/lecture/16446264#overview

#備考
・上記の動画でgcpの使い方に慣れておかないと、理解に苦しむ用語がでてきます。
・権限まわり、請求アカウント関連がややこしいです。
・gcloudコマンドは少し難しい問題を問われました。
・gkeはそんなに難しい問題はでませんでした。


#参考にしたサイト
メタデータフレーバー
https://dev.soracom.io/jp/start/metadata/

openstack
https://qiita.com/gold-kou/items/74d6d2a4dc3eee236ebd

ロケーション
https://cloud.google.com/about/locations?hl=ja#multi-region

ディスク
https://cyberagent.ai/blog/tech/gcp/1430/

deployment manager
https://qiita.com/shotaTsuge/items/bb995f4e2f3f6ae9d12d
https://qiita.com/marcy-terui/items/e18224db0db2d6e304fd

バイナリ
https://ja.m.wikipedia.org/wiki/Application_Binary_Interface

データベース
http://wild-data-chase.com/index.php/2019/09/16/post-941/#outline__3
https://www.apps-gcp.com/gcp-storage-service/
https://www.dsk-cloud.com/blog/what-is-google-datastore-nosql
https://xtech.nikkei.com/atcl/learning/lecture/19/00017/00006/
https://www.slideshare.net/mobile/GoogleCloudPlatformJP/gke-spanner-gke?qid=dab76bd7-ee5b-4d6c-a3f7-0078151d29d3&v=&b=&from_search=3

ライブマイグレーション
https://apps-gcp.com/gce-livemigration/

haクラスタ
https://sios.jp/products/lkdk/ha-cluster/structure.html

ベストプラクティス


cdn
https://knowledge.sakura.ad.jp/19191/

BigQuery
https://qiita.com/simonritchie/items/35be3bda0cb64dad731f

セッションアフィニティ
https://qiita.com/h-sakano/items/de23e1d6d4a3e6ce925a

kubernetes
https://thinkit.co.jp/article/13611

gcloud
https://qiita.com/toshi0607/items/90cbbacdfae6c4282c0a
https://qiita.com/kumanoryo/items/1fbd5302fc68a3980b5e
railsでのboorstrapの導入

自分用です！

bootstrapを導入していきます。

```ruby:Gemfile
gem 'bootstrap', '~> 4.4.1'
gem 'font-awesome-sass', '~> 5.12.0'
gem 'jquery-rails'
```
Gemfileに記載をし、bundle installを実行。

ちなみに、公式のgemを検索するときは、[rubygems](https://rubygems.org/)がおすすめ。

また gem 'font-awesome-rails'では、font-awesome5系に対応していないので gem 'font-awesome-sass'を使用する必要があります。

```ruby:application.scss
@import 'bootstrap';
@import 'font-awesome-sprockets';
@import 'font-awesome';
```

を追加。

```ruby:application.js
//= require jquery3
//= require popper
//= require bootstrap-sprockets
```

を追加してください。

//= require_tree . は一番下の行に記載していること
※ ここではrequireするJavaScriptファイルの順番に注意してください。
//= require jquery3よりも前に//= require_tree .を記載した場合、 //= require_tree .で読み込んだファイルでjqueryのコードを参照しているとjquery3が読み込まれる前に評価されるためメソッドが未定義となりエラーになるケースが後の課題で発生します。
scssの入れ子とパーシャル

自分用です！

## sassのimport

railsでは、cssをsassで書いていきます。

・scssにすることで変数や親子関係の定義など、効率化の機能が使用でき、全体のコード量を削減できます。
・sass記法ではインデント制御のためデザイナーに引き渡しづらく、cssの記法から離れてしまうという面からscss記法を採用しています。

application.scssとtop.scssがあるとして、top.scssをapplication.scssにインポートします。

```ruby:application.scss
@import 'top';
```

このように、@importを使えば必要なcssファイルだけをインポートできます。


## パーシャル

次に、sassと同じようにviewでも入れ子構造が使えます。
それがパーシャルです。

application.html.erbにheaderとfooterのコードがたくさん入っていていると見えずらいですよね。

そこで、shared/_header.html.erbと、shared/_footer.html.erbを作成し、そこにヘッダーとフッターのコードをかき、application.htmlに入れ子する。

```ruby:application.html.erb
<body>
  <%= render 'shared/header' %>
  <%= yield %>
  <%= render 'shared/footer' %>
</body>
```

このようにすれば、見やすくなる。
rails gの際のファイル生成の設定

自分用です！

rails g コマンドを使用した際に、assets、helper、testファイル、ルーティングが生成されないように設定して行きます。

```ruby:config/application.rb
 config.generators do |g| 

      g.skip_routes true 
      g.assets false 
      g.helper false 
      g.test_framework false 
   end
```

これで、無駄なファイルが生成されない。 

ちなみに、、、

環境設定をする際は、

config/initializers以下の各ファイル
特定のツールや機能に対する設定ファイルを、ファイル別に記述する。(assets.rb / aws.rbなど)

config/environments以下
環境別に行いたい初期化作業を記述する
(production.rb / staging.rb など)

config/applicaiton.rb
アプリケーション全体に関する設定を行う

順序に寄らないものに関しては、基本的に初期化作業内で全て実行されますが、後々のメンテナンスのしやすさ等を考慮し、上記のようなディレクトリ構成でファイルを分けていくことが無難。
モデル、コントローラーの生成

自分用のメモです！

## コントローラーの生成

ex)　(newアクションを持つ)userコントローラーの生成

```ruby:ターミナル
rails g controller Users new
```

## モデルの作成

ex) (name,emailカラムをもつ）userモデルの生成

```ruby:ターミナル
rails g model User name:string email:string
```

## コントローラーの削除

ex) userコントローラーの削除

```ruby:ターミナル
rails destroy controller Users
```

## モデルの削除
　
ex) userモデルの削除

```ruby:ターミナル
rails destroy model User
```
【Git】fatal: Not a valid object name: 'master'.

Sourcetree使ってbranchしようとした際に出てきたエラー。
Sourcetreeでの操作がメインです。

内容は簡単に言うと「'master'という名前のオブジェクトがないよ」って意味でした。

ファイルを作成している時点でターミナル操作でいうところの"init"はできているから問題なし。

commitが出来ていないからっていうのが原因なので
VScodeなりのエディターで作成したファイルを開いて
sample.txtなりのファイルを作って
文字列を与えてあげれば(←作成だけでなく変更が必要のため)ok

そのあと履歴のところに表示されてきているので
コミットしてあげればbranchできるようになります。

何かしらのファイルを作る前に分岐なんかできないよってこと。
ラズパイにNumPyをインストールする方法

ラズパイでNumpyをpipでインストールしたのですが、それだと以下のエラーが出てしまいました。

エラー内に記述されているトラブルシューティングのURLを確認します。
https://numpy.org/devdocs/user/troubleshooting-importerror.html

```
Traceback (most recent call last):
   File "/home/pi/.local/lib/python3.5/site-packages/numpy/core/__init__.py", line 24, in <module>
     from . import multiarray
   File "/home/pi/.local/lib/python3.5/site-packages/numpy/core/multiarray.py", line 14, in <module>
     from . import overrides
   File "/home/pi/.local/lib/python3.5/site-packages/numpy/core/overrides.py", line 7, in <module>
     from numpy.core._multiarray_umath import (
 ImportError: libf77blas.so.3: cannot open shared object file: No such file or directory
 
 During handling of the above exception, another exception occurred:
 
 Traceback (most recent call last):
   File "test.py", line 1, in <module>
     import numpy as np
   File "/home/pi/.local/lib/python3.5/site-packages/numpy/__init__.py", line 142, in <module>
     from . import core
   File "/home/pi/.local/lib/python3.5/site-packages/numpy/core/__init__.py", line 50, in <module>
     raise ImportError(msg)
 ImportError:
 
 IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!
 
 Importing the numpy C-extensions failed. This error can happen for
 many reasons, often due to issues with your setup or how NumPy was
 installed.
 
 We have compiled some common reasons and troubleshooting tips at:
 
     https://numpy.org/devdocs/user/troubleshooting-importerror.html
 
 Please note and check the following:
 
   * The Python version is: Python3.5 from "/usr/bin/python3"
   * The NumPy version is: "1.18.5"
 
 and make sure that they are the versions you expect.
 Please carefully study the documentation linked above for further help.
 
 Original error was: libf77blas.so.3: cannot open shared object file: No such file or directory
```

## ラズパイへNumPyのインストール方法は別に存在した

[トラブルシューティング](https://numpy.org/devdocs/user/troubleshooting-importerror.html)を確認するとpipでインストールすると駄目っぽい事が書かれています。

>There are sometimes issues reported on Raspberry Pi setups when installing using pip3 install (or pip install). These will typically mention:

指示に従い、以下のコマンドを実行します

```shell
$ sudo apt-get install libatlas-base-dev
$ pip3 uninstall numpy  # remove previously installed version
$ apt install python3-numpy
```

この手順を踏むとNumPyがラズパイで使用できるようになりました。


## 環境

- RasberryPi 3B
- Raspbian GNU/Linux 9.8 (stretch)
- python3-numpy1.12.1
Laravel + Vue.jsの導入方法


LaravelのBladeにVueコンポーネントを組み込む方法をまとめます。

## 環境
+ laradock
+ php: 7.3
+ Laravel: 7.2

## Vue.jsをインストールする
```php:laravel/package.json
"vue": "^2.6.11", 
"vue-template-compiler": "^2.6.11"
```

```
$ docker-compose exec workspace npm install
```

## Vueコンポーネントを作成する
試しにハートボタンを作成します。

```laravel/resources/js/components/SampleLike.vue
<template>
  <div>
    <button
      type="button"
      class="btn m-0 p-1 shadow-none"
    >
      <i class="fas fa-heart mr-1"
      />
    </button>
    10
  </div>
</template>

<script>
</script>
```

## app.jsを編集
```laravel/resources/js/app.js
import Vue from 'vue'
import Samplelike from './components/SampleLike'

const app = new Vue({
  el: '#app',
  components: {
    SampleLike,
  }
})
```
laravelの全画面で使用できるようにここで読み込みます。

## Laravel Mixを編集
```laravel/webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .version();
```
上記はresources/js/app.jsをトランスパイルしてpublic/jsのapp.jsというファイルで保存されるよというソースです。
.version()はトランスパイルされる時に毎回idを採番する役割ですが、これは同じidの古いjavascriptをブラウザキャッシュに残さないためです。

## .gitignoreを編集
下記はjavascriptが編集される都度トランスパイルされてファイルが作成・更新されていくため、
管理対象から外しておきます。

```laravel/.gitignore
/node_modules
/public/css　# 追加
/public/hot
/public/js  # 追加
/public/mix-manifest.json　# 追加
```

## トランスパイルの実行
```
$ docker-compose exec workspace npm run watch-poll
```

DONE  Compiled successfullyと表示されればトランスパイル成功です。
上記のコマンドはjavascriptが編集されたら自動でトランスパイルしてくれます。

## app.blade.phpを編集
```laravel/resources/views/app.blade.php
{{--省略--}}
<body>
  <div id="app"> {{--追加--}}
    @yield('content')
  </div> {{--追加--}}

  <script src="{{ mix('js/app.js') }}"></script> {{--追加--}}
{{--省略--}}
</body>
```

## BladeにVueコンポーネントを組み込む
```laravel/resources/views/posts/index.blade.php
<div class="card-body pt-0 pb-2 pl-3">
    <div class="card-text">
      <sample-like>
      </sample-like>
    </div>
  </div>
```

組み込むときはケバブケースで記述する。

これでハートボタンとダミーの10が表示でき、Vueコンポーネントを組み込めたかと思います。
【Laravel】ルートグループを定義して、まとまり感のあるルートを作成する

ルートグループは、ミドルウェアや名前空間のようなルート属性を、一括して複数のルートに適応させる手法です。`Route::group`メソッドを使用します。

## 指定のミドルウェアをルートグループに適応させる
グループとしてまとめられた各ルートにミドルウェアを指定した例がこちら。

```php:routes/web.php
Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // firstとsecondミドルウェアを使用
    });

    Route::get('user/profile', function () {
        // firstとsecondミドルウェアを使用
    });
});
```

`Route::middleware`メソッドを使用して`first`ミドルウェアと`second`ミドルウェアを適応させることが記述されています。この`Route::middleware`に`group`メソッドをチェーンする形で書いていきましょう。グループ内の各ルートに`Route::middleware`メソッドで指定したミドルウェアが適応されます。

このグループ内の各ルートは、`first`ミドルウェア、`second`ミドルウェアの順に実行されます。実行される順は`Route::middleware`メソッドに指定した配列の順序となります。

参考文献：https://readouble.com/laravel/7.x/ja/routing.html
Windows 10にLinuxをインストールしてGUIをローカルとリモート(SSH)で使えるようにする

#Linuxを使えるようにする
[Win10のBash on Windows をインストールする](https://qiita.com/yukio_tokuyoshi/items/042546812c663ceeccf3)を参考にさせていただきました。スクリーンショットの画像があってわかりやすいです。

##WSLの有効化
1. `スタート`ボタンを右クリックして`アプリと機能`をクリック
2. `設定`ウィンドウが出てきたら右側にある`プログラムと機能`をクリック
3. `プログラムと機能`ウィンドウが出てきたら左側の一覧にある`Windowsの機能の有効化または無効化`をクリック
4. `Windowsの機能`ウィンドウが出てきたら`Windows Subsystem for Linux`にチェックを入れて`OK`
5. インストールが終わったら再起動

##Linuxのインストール
1. コマンドプロンプトを開いて`bash`コマンドを実行
2. ディストリビューションがないからこのURLを訪問してくださいというようなメッセージが出る
3. そのURLに行ってUbuntuをダウンロードして`起動`
4. `Ubuntu`ウィンドウが出てきてインストールが始まる
5. 終わったらユーザー名とパスワードを何にしたいか聞かれるので入力(覚えておく)
6. `Ubuntu`ウィンドウを閉じてコマンドプロンプトを再度開く
7. `bash`コマンドを実行すれば今度はbashが動くはず
8. 以下の2つのコマンドを実行

```shell-session
$ sudo apt update
$ sudo apt upgrade
```

#マシン上でGUIを使えるようにする

##Xサーバのインストールと設定
[WSL上にXサーバをインストールしてGUIを実現する（VcXsrv編）：Tech TIPS - ＠IT](https://www.atmarkit.co.jp/ait/articles/1812/06/news040.html)を参考にさせていただきました。こちらもスクリーンショットの画像があってわかりやすいです。

###インストール
1. [VcXsrv Windows X Server](https://sourceforge.net/projects/vcxsrv/)に行って`Download`をクリック
2. ダウンロードしたインストーラを起動し、インストールを進める
3. 基本的には`Next`や`Install`を何も考えずにクリックしていけばOK
4. 最後の`Finish configuration`という画面で`Save configuration`ボタンを押して`config.xlaunch`を保存(保存先を覚えておく)
5. 同じ画面で`完了`をクリック(これでXLaunchが起動する)

###自動で起動するように設定
今のままではサインインの度に手動で`config.xlaunch`を実行してXLaunchを起動しなければならない。
それは面倒なので自動で実行してくれるように設定する。
1. `スタート`ボタンを右クリックして`ファイル名を指定して実行`をクリック(またはショートカット`Wondows+R`を使う)
2. `ファイル名を指定して実行`ウィンドウで`shell:startup`と入力して`OK`
3. `スタートアップ`フォルダが開いたら、先ほど保存した`config.xlaunch`をコピーして`スタートアップ`フォルダ内に貼り付ける(もしくはショートカットを作成する)

##WSL側の設定
[WSLでUbuntuにSSH接続してX転送](https://qiita.com/yasuo_utsunomiya/items/0be42999ea9f4abb0d30#windows-subsystem-for-linux%E3%81%AE%E8%A8%AD%E5%AE%9A)を参考にさせていただきました。

コマンドプロンプトで`bash`コマンドを実行する。今度はエラーメッセージは出ないはず。
以下のコマンドを実行する。

```bash
$ sudo apt install x11-apps
$ echo 'export DISPLAY=localhost:0.0' >> ~/.bashrc
$ source ~/.bashrc
``` 
終わったら`xeyes`コマンドを実行して目のイラストが表示されれば成功。
うまくいかなかったら一旦PCを再起動して再度コマンドプロンプトでbashを開き、`xeyes`を試す。
SSHでGUIを取得するには`-X`オプションと`-Y`オプションを付ける。

```
$ ssh -X -Y ユーザー名@ホスト名
```
度数分布表とヒストグラム

# 度数分布表

度数分布表とは、収集した**「データの分布の状態」**（データの中心や散らばりの様子）を知るために、ある幅ごとに区切ってその中に含まれるデータの個数を見るために作成した表のことを言います。

まずは簡単な50個のデータ（単位：人）を準備します。

```R:data1
data1 <- c(67, 58, 75, 89, 46, 62, 56, 79, 60, 30, 76, 64, 52, 66, 42, 
81, 63, 59, 65, 77, 38, 86, 64, 70, 50, 93, 78, 76, 57, 68, 98, 64, 
55, 66, 53, 82, 62, 73, 60, 51, 49, 67, 56, 75, 85, 61, 58, 44, 79, 65)
```

data1より度数分布表を作成すると以下の通りになります。

|階級（単位：人）|階級値|度数|相対度数|累積度数|累積相対度数|
|:---:|---:|---:|---:|---:|---:|
|30以上~40未満|35|2|0.04|2|0.04|
|40以上~50未満|45|4|0.08|6|0.12|
|50以上~60未満|55|11|0.22|17|0.34|
|60以上~70未満|65|16|0.32|33|0.66|
|70以上~80未満|75|10|0.20|43|0.86|
|80以上~90未満|85|5|0.10|48|0.96|
|90以上~100未満|95|2|0.04|50|1.00|

各項目について説明していきます。

### 階級
度数を集計するための区間
適切な階級の数を設定するためには**「スタージェスの公式」**が用いられます。

```math
k=1+log_2N
```
`k`は階級の数を表し、`N`はデータの個数を表します。
正式な度数分布表の作成手順では、データの範囲（最大値-最小値）をスタージェスの公式で算出した**階級の数**で割ることで**階級の幅**を求めます。

今回は以下のように階級の幅を求めました。

```math
範囲：98-30=68　階級の数：1+log_250=1+5.643…≒7
```
```math
階級の幅：\frac{範囲}{階級の幅}=\frac{68}{7}=9.714…≒10
```

### 階級値
各階級の中央値であり各階級を「代表」する値

### 相対度数
度数を総度数（全データ数）で割った値
無作為に1つのデータを抽出する場合、相対度数はそのデータがある階級に属している確率と一致します。

### 累積度数
度数を小さい階級から累積した値

### 累積相対度数
累積度数を総度数で割った値
一番最後の階級の累積相対度数は`1`になります。

# ヒストグラム
度数分布表を用いて、縦軸に度数・横軸に階級をとり、グラフ化したもの
カール・ピアソンによって用語が創案されました。

ヒストグラムの形状よりデータの分布の特徴を整理する時は、次の①~⑤のポイントに留意します。

① **データの中心**はどのあたりにあるか
② **データの散らばり**は大きいか・小さいか
③ **分布のピーク**（頂上）はいくつ存在するか▶︎一様分布（ピーク0）・単峰性・二峰性・多峰性
④ **データの分布**は左右対称か▶︎右に歪んだ分布・左右対称な分布・左に歪んだ分布
⑤ **外れ値**は存在するか

data1よりヒストグラムを作成すると以下の通りになります。

```R
hist(data1, freq = TRUE, ylim = c(0, 20),
     xlab = "人数",
     ylab = "度数",
     main = "ヒストグラム")
```
<img width="677" alt="スクリーンショット 2020-08-04 1.15.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663460/22832995-86b3-9d94-1eec-740c5aae7d11.png">

今回のヒストグラムを①~⑤のポイントに従って考察すると、①データの中心は60~70の階級、②データの散らばりの程度は普通、③分布のピークは1つで単峰性の分布、④データの分布はほぼ左右対称、⑤外れ値は存在しない、ということが分かります。

ヒストグラムの各柱の上辺の中心を直線で繋いだグラフを**度数三角形**（frequency polygon）と言い、各階級の上限と累積相対度数を直線で繋いだグラフを**累積相対度数折れ線**と言います。

### 棒グラフとヒストグラム
* 棒グラフ「独立した**離散変数**のデータの大小を比較する・因子変数の分布を要約する」
* ヒストグラム「**連続変数**のデータの分布を示す」

ただし、離散変数でも順序に意味がある場合（年齢・さいころ・質問紙調査による5点尺度など）は連続変数扱いすることがあり、離散変数の度数分布をヒストグラムで表すことがあります。

# 参考文献
* [例題で学ぶ初歩からの統計学 第2版](https://www.amazon.co.jp/%E4%BE%8B%E9%A1%8C%E3%81%A7%E5%AD%A6%E3%81%B6%E5%88%9D%E6%AD%A9%E3%81%8B%E3%82%89%E3%81%AE%E7%B5%B1%E8%A8%88%E5%AD%A6-%E7%AC%AC2%E7%89%88-%E7%99%BD%E7%A0%82-%E5%A0%A4%E6%B4%A5%E8%80%B6/dp/453555790X)
* [離散変数と連続変数 - ど素人の統計学ノート（順不同）](https://pumpkin1205.hatenadiary.org/entry/20091211)
Webpack: asyncWebAssembly+importAwait

wasmのダイナミックimportsとモジュール解決してくれる内部プラグインがWebpack v5.0から入っていた。

```javascript:webpack.config.js
module.exports = {
	entry: "./example.js",
	output: {
		webassemblyModuleFilename: "[hash].wasm",
		publicPath: "dist/",
		filename: "output.js"
	},
	module: {
		rules: [
			{
				test: /\.wasm$/,
				type: "webassembly/async"
			}
		]
	},
	experiments: {
		asyncWebAssembly: true,
		importAwait: true
	}
};
```

```javascript:example.js
import await { add } from "./add.wasm";

console.log(add(22, 2200));
```

```html:index.html
<html>
	<body>
		<script src="dist/output.js"></script>
	</body>
</html>
```

内部的にはfetchして `WebAssembly.instantiateStreaming()` に食わせてexportsを `Object.assing()` してモジュールを解決してくれるっぽい。

`npx http-server` ではwasmファイルのcontent-type指定がGoogle Chromeで動作しなく、かわりに [ecstatic](https://github.com/jfhbrook/node-ecstatic) を使った。

```bash
$ webpack -v
5.0.0-beta.23

$ webpack && ecstatic

$ open http://127.0.0.1:8000/
```

ソースコードは [examples/wasm\-simple](https://github.com/webpack/webpack/tree/master/examples/wasm-simple) によるもの
Template error: Fn::Select cannot select nonexistent value at index 1

## 問題

以下のCloudFormationテンプレートでサブネットを東京リージョンに構築しようとしたところ、表題のエラーを吐きました。

```yaml
Resources:

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.2.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 1, !GetAZs ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PrivateSubnet2
```

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/6ebcd95a-57b5-b87c-cbee-e8270bedd003.png)


## 原因

`Fn::GetAZs`はアカウントのデフォルトサブネットのAZを配列で返却します。
私のアカウントではデフォルトサブネットのAZを1つしか登録していませんでした。
問題のCloudFormationテンプレートで、`Fn::GetAZs`で取得したAZ配列の2番目を参照しますが、存在しないためエラーとなりました。

## 対処方法

デフォルトサブネットを作成し、AZを増やします。
東京リージョンには`ap-northeast-1a`,`ap-northeast-1c`,`ap-northeast-1d`の3つのAZが存在します。(実際は`ap-northeast-1b`もありますが、使用できるアカウントが制限されているため除外します)

アカウントが使用できるAZの確認

```
aws ec2 describe-availability-zones --query 'AvailabilityZones[].ZoneName'
```

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/9623b09f-3ce9-dec5-2583-b2d5c4ee93a9.png)



デフォルトサブネットのAZを確認(`Fn::GetAZs`が返す値)

```
aws ec2 describe-subnets --filters "Name=default-for-az, Values=true" --query 'Subnets[].AvailabilityZone'
```

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/fbbb24d7-8860-d1d5-275d-fd9ffda6278d.png)


デフォルトサブネットをAZに作成

```
aws ec2 create-default-subnet --availability-zone ap-northeast-1c
```

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/51169a8f-fdf7-343b-3106-d676f0dac0bb.png)


## 確認

再度、CloudFormationテンプレートでスタック作成してみます。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/91bfd3e0-a8a5-172d-f215-8985135ee736.png)


エラーなくサブネットを作成することができました。

## 参考

- [CloudFormation の Fn::GetAZs で ap-northeast-1d が返ってこなくてハマった](https://blog.manabusakai.com/2018/11/cloudformation-getazs-function/)
- [Template error: Fn::Select cannot select nonexistent value at index 1 #37
](https://github.com/widdix/aws-cf-templates/issues/37)
- [デフォルトサブネットの作成](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/default-vpc.html#create-default-subnet)
- [東京リージョンの新しいアベイラビリティゾーン「ap-northeast-1d」がリリースされました。](https://dev.classmethod.jp/articles/new-az-ap-northeast-1d/)
Swiperでloopかつlazyの時に最後のスライドの画像を事前読み込みする方法

# 概要
[Swiper](https://swiperjs.com/)には画像の遅延読み込みモードが標準で付いている。
以下のように設定することで、事前の全画像読み込みは控えつつ、今いるスライドの前後のスライドの画像だけロードしてくれるようになる。

```.js
var mySwiper = new Swiper('.swiper-container', {
  preloadImages: false,
  lazy: {
    loadPrevNext: true,
  },
});
```
参考: https://swiperjs.com/api/#lazy

が、以下の条件の時、一つ前に表示されたループスライド(=本来の最後のスライド)の画像がうまく読み込みされなかった。

```.js
var mySwiper = new Swiper('.swiper-container', {
  preloadImages: false,
  lazy: {
    loadPrevNext: true,
  },
  loop: true,
  slidesPerView: 3.33,
  centeredSlides: true,
});
```

これを、最後のスライドは初期表示時に強制的に読み込まれるように設定した。

# 原因
色々試してみた結果、 `loop: true` かつ `slidesPerView` を整数以外で指定していると起こる現象のようだった。
加えて今回は `centeredSlides: true` を付けていたことで、未ロード状態のスライドがそのまま見えてしまっていた。
どの項目もデザイン上必要な設定だったため、最後のスライドだけJS側で最初に強制的に読み込むよう設定した。

# やり方
以下のように設定することで、最後のスライドを読み込みできる。
尚、試したSwiperのバージョンは `5.4.5` 。

```.js
var mySwiper = new Swiper('.swiper-container', {
  preloadImages: false,
  lazy: {
    loadPrevNext: true,
  },
  loop: true,
  slidesPerView: 3.33,
  centeredSlides: true,
  on: {
    init: function() {
      this.lazy.loadInSlide(this.activeIndex - 1);
    },
  },
}
```

## 簡単な解説
`this.lazy.loadInSlide(index)` は任意のスライドインデックス番号を入れて強制的にそのスライドの画像をロードできる関数。
ループ処理しないのであれば、ここに本来のスライド番号(=最後の番号)を入れれば良いが、
ループ処理中に実際に表示されるのは複製されたスライドのため、複製分だけスライド番号がずれて指定される。
そのため、 `this.activeIndex` でループ時におけるスライド番号を取得し、その一つ前である最後のスライドを読み込み指定されるようにした。

## その他の方法
何らかの理由で `init` で処理を行いたくない場合は、以下のようにもできる。

```.js
var mySwiper = new Swiper('.swiper-container', {
  //...略,
  on: {
    slideChange: function() {
      if (this.realIndex === 0) {
        this.lazy.loadInSlide(this.activeIndex - 1);
      }
    }
  },
}
```

`this.realIndex` で、ループの複製前の本来のスライド番号が取得できるので、
そこで0番目のインデックスのときに最後のスライドの画像のロード処理を行う。

# 感想
そもそも発生条件が稀なのか、検索しても類似情報がヒットせず解決に苦労した。
公式のこのあたりのissueの投稿が参考になった。
[lazy pre loading for images in loop mode · Issue \#2780 · nolimits4web/swiper](https://github.com/nolimits4web/swiper/issues/2780)
[Swiper doesn't load the last slide? · Issue \#3315 · nolimits4web/swiper](https://github.com/nolimits4web/swiper/issues/3315)
Swift：画面収録の許可が必要なアプリで許可の状態を確認してダメなら許可を促す

# はじめに

macOS Catalinaから、アクセシビリティに関するセキュリティが向上し、画面をキャプチャするようなアプリ（画面共有やカラーピッカーなど）では画面収録の許可が必要になりました。しかし、許可に慣れていないユーザは初回起動時に出てきたポップアップに驚いて許可をしてくれない可能性があります。しかし、この許可のポップアップはデフォルトでは最初の一回目しか表示されないため、ユーザに許可を促す導線が必要となります。ここで、許可の状態を取得して、必要に応じて環境設定の画面収録許可のページを表示する機能が欲しくなります。

# 許可の状態を確認して、許可されていない時に許可を促す

```swift
func checkPermission() {
    if let _ = CGDisplayStream(display: CGMainDisplayID(),
                               outputWidth: 1,
                               outputHeight: 1,
                               pixelFormat: Int32(kCVPixelFormatType_32BGRA),
                               properties: nil,
                               handler: { _, _, _, _ in }) {
        print("has a permission")
        return
    }
    print("does not have a permission")

    let userInfo: [String: Any] = [
        NSLocalizedDescriptionKey: "This application does not have the screen capture permission.",
        NSLocalizedRecoverySuggestionErrorKey: "Please grant access to this application in Security & Privacy preferences, located in System Preferences."
    ]

    let error = NSError(domain: "ApplicationDomain", code: 0, userInfo: userInfo)
    let alert = NSAlert(error: error)
    alert.addButton(withTitle: "Deny")
    alert.addButton(withTitle: "Open System Preferences")
    let result = alert.runModal()

    if result == .alertSecondButtonReturn {
        let path = "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"
        NSWorkspace.shared.open(URL(string: path)!)
    }
}

viewDidLoad() { // どこか初期化のタイミングで
    if #available(macOS 10.15, *) {
        checkPermission()
    }
}
```

これが必要となるのはCatalina以降なので、Mojave以前をサポートしている場合はOSのバージョンで場合分けするのを忘れずに。

# 参考文献

- [karaggeorge/mac-screen-capture-permissions](https://github.com/karaggeorge/mac-screen-capture-permissions)
- [Swift：NSErrorを使って楽にNSAlertを表示する](https://qiita.com/Kyome/items/06da6a982e6780e6403c)
【Cluster】ランダムなオブジェクトを入れ替わりで生成する

##Cluster GAMEJAM 2020 in SUMMER
[Cluster GAMEJAM 2020 in SUMMER](https://www.gamejam.cluster.mu/)　に参加しました。
テーマに沿った遊べるワールドを作成するゲームジャムです。

私が作成したのは**決め打ちの単語がランダムに入れ替わりで生成**される
文章ジェネレーターのようなワールドです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">「Cluster GAMEJAM 2020 in SUMMER」<br>応募作品です！😆<br><br>テーマが「ソーシャル」とのことなので<br>VR空間にTwitterを<br>持ち込んだイメージで作りました😎<a href="https://t.co/Xcvhx1t76i">https://t.co/Xcvhx1t76i</a> <a href="https://t.co/2GNbNK72jH">pic.twitter.com/2GNbNK72jH</a></p>&mdash; KENTO⚽️XRエンジニア😎 (@okprogramming) <a href="https://twitter.com/okprogramming/status/1289876026588241921?ref_src=twsrc%5Etfw">August 2, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

この**決め打ちの単語がランダムに入れ替わりで生成**の仕組みを
実現するのに少し頭を捻ったのでメモしときます。


##バージョン情報
Unity 2019.4.1f1
Creator Kit v1.6.2

##ワールドアップロードまでの手順
まずはワールドアップロードまでの手順をおさらいしときます。
**⓪[APIアクセストークン](https://cluster.mu/account/tokens)を発行しておく
①[GitHub](https://github.com/ClusterVR/ClusterCreatorKitSample)からサンプルプロジェクトをクローン
②サンプルプロジェクトを開いてEditorのClusterタブからワールドアップロードを選択
<img width="122" alt="CWorldUpload.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/bd9a9add-802d-d17c-1478-59f6739e5cd0.png">
③あとは開いたウィンドウにある説明に従う**

まさかの**Scene In Buildに追加したシーンをEditorからアップロード**する仕組みでした。

自動で複数のプラットフォームの実行ファイルを作成してアップロードしてくれます。

##考え方
Clusterに**自前のコードは一切持ち込めない**ので、
容易された仕組みを組み合わせる必要があります。

用意された仕組みは下記4つです。
(厳密にはもう1つありますが使わなかったので割愛します)

**・アイテム
・トリガー
・オペレーション
・ギミック**

誤解を恐れずにとてもふわふわした言葉で表現すると
**どれが(アイテム)
どうなったら(トリガー)
どんなふうに(オペレーション)
何が起きる(ギミック)**

みたいな感じでしょうか。

それぞれの仕組み同士は**Keyと呼ばれる文字列でメッセージの伝達**を行います。

##実際の仕組み

実際の仕組みについて図解していきます。

おさらいとして、図解する仕組みは
**決め打ちの単語がランダムに入れ替わりで生成**
という仕組みです。

加えて、**既に表示されているオブジェクトが削除されたのち、
指定時間分ディレイして新しいオブジェクトが生成**される処理も
追加してみます。

まずはシンプルにメッセージの通知だけ見てみましょう。
![QiitaExSimple.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/b2f8603b-58d8-0b63-6959-66c7b9dc351c.png)

トリガーで発行されたKeyを受け取ったら、
次のKeyを発行するというのをギミックに到達するまで
繰り返しているだけです。

---

次に、少し複雑になりますが、
実際にそれぞれの処理名、処理内容を追記したものです。
![QiitaEx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/3aefaab2-fd05-ea45-5f5b-14ca14e546eb.png)

ランダムに選ばれて生成される緑のアイテムやオレンジのアイテムにも
`Key : Destroy`を持つ`Destroy Item Gimmick`を付与しておくことで削除と生成を繰り返す仕組みが完成します。

##おまけ：UIレイヤーはカメラに表示されない

Clusterのデフォルトの機能で撮影機能があるのですが、
UIレイヤーを設定中のオブジェクトは表示されないので要注意です。
(運営さん、つぶやきに即座に対応する神対応ありがとうございます！)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">clusterのカメラにはUIレイヤーは表示されないようになっているのですが、もしかしたらそれでしょうか…？😭</p>&mdash; cluster公式∞8/12～ポケモンバーチャルフェスト！ (@cluster_jp) <a href="https://twitter.com/cluster_jp/status/1289966769013002240?ref_src=twsrc%5Etfw">August 2, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##おわりに

せっかく作ったのであそんでくださーい!
[Twitter In Cluster](https://cluster.mu/w/1eb9bbfb-9cd7-4610-b16a-5c86979572be)
MacでRealsenseをPythonで動かす。

## はじめに
初投稿です。至らない部分があると思いますが、優しい目でみていただけると幸いです…
悪戦苦闘しました。ちなみにめちゃめんどい。

## 第一の罠
https://github.com/IntelRealSense/librealsense/blob/master/doc/installation_osx.md
公式にMacでのインストール方法は書いてある。しかし、どうやってプログラムをコンパイルできるのか分からなかった…

## 第二の罠
そこで、Pythonの環境を作ろうと決断。Ubuntuでの環境構築を参考にしようとして、
```
$ pip install pyrealsense2
```
をした。何も起きない。悲しい。
悲しいことにMacには対応していないみたいなので、自分でビルドするしかない。

## 第三の罠
ここで、Qiitaの記事を発見。
https://qiita.com/mizumasa/items/c6ca2c73fa86c9a5a39c
MacでPython環境を構築している方がいた！神！
早速、同じことをする。…結果、ダメだった🥺

## 第四の罠
もう悲しくて悲しくてしょうがなかった…
苦手な英語を読むことに決意。公式のライブラリにissueであった物を参考にした。
https://github.com/IntelRealSense/librealsense/issues/5275
多分これ読めばたいていの人は行けると思う。しかし、僕は無理だったのでとにかく悲しかった🥺🥺🥺

## 成功した方法
最後に僕の成功した方法を残しときます。
https://qiita.com/comachi/items/14b358568365bc5ee474
これ is 神。この記事が神でした。

神って言ったけど、これじゃできなかったので少し修正。
この記事の下の方、「シンボリック作成」の部分。
```
$ cd /usr/local/lib/python3.6/site-packages
$ ln -s /usr/local/lib/pyrealsense2.cpython-37m-darwin.so pyrealsense2.so
$ ln -s /usr/local/lib/pybackend2.cpython-37m-darwin.so pybackend2.so
```
こうあるんですけど、
- pyrealsense2.cpython-37m-darwin.so
- pybackend2.cpython-37m-darwin.so

こやつら、/usr/local/lib にいないんじゃ…
頑張って探しました。そしたら、
~/libreasense/build/wrapper/python/
にいたので、次のように変更。
```
$ cd /usr/local/lib/python3.6/site-packages
$ ln -s ~/libreasense/build/wrapper/python/pyrealsense2.cpython-37m-darwin.so pyrealsense2.so
$ ln -s ~/libreasense/build/wrapper/python/pybackend2.cpython-37m-darwin.so pybackend2.so
```

これでいけた！！！はず。

## 終わりに
まじで１週間くらいかかったので、残しとくことにしました。
C++の方は分からないので、みんなWindowsで開発しよう！！！

## 参考にしたサイト
- https://github.com/IntelRealSense/librealsense/blob/master/doc/installation_osx.md
- https://qiita.com/mizumasa/items/c6ca2c73fa86c9a5a39c
- https://github.com/IntelRealSense/librealsense/issues/5275
- https://qiita.com/comachi/items/14b358568365bc5ee474
MacからラズパイにVNC接続して遠隔操作する手順

Macから手持ちのラズパイ3Bに同一無線LAN内でVNC接続して遠隔操作しようとしたのですが、ひと手間掛ける必要があったためその備忘録となります。


## MacからVNCでそのまま開けない

`Finder > サーバへ接続...`
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/0aa18a38-e0bf-23e7-d35a-5dc1807e6909.png" width=240 />

ラズパイ側で予め`ifconfig`コマンドでIPアドレスを調べておきます。

```
vnc://ラズパイのIPアドレス
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/07946b39-4918-9fe6-eb8a-ac1b9e60ba74.png" width=400 />

しかし接続失敗します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/78182e66-7082-609a-749e-0d9cdba2856f.png" width=450 />

> リモートコンピュータのソフトウェアが、このバージョンの画面共有と互換性がないようです。

このようなエラーが出てしまいます。

## TightVNCを使用する

### ラズパイ側


```shell
$ sudo apt-get install tightvncserver
```
`apt-get`コマンド[^1]で**TightVNC**をインストールします。

[^1]: 適宜apt-get update、apt-get upgradeを実行してください

ラズパイ側でシェルで以下のコマンドを実行しTightVNCを起動しておきます。

```shell
$ tightvncserver
```
※初回パスワード設定が求められます。


### Mac側

`vnc://ラズパイのIP:5901`でVNC接続すると、無事に接続できました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/7d320b32-4d1a-3b75-ecbb-232e5c830b99.png" width=500 />

これでラズパイに外部モニタやキーボードを繋ぐ必要はなくなりました。

## 余談

このままだとHDMIへの画面出力もしてしまい使用メモリの無駄です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/10d8e631-887d-d49a-788d-c5f106efa704.png" width=500 />
`設定 > RaspberryPiの設定 > システム > ブート`を**デスクトップからCLIに変更**します。するとHDMIへの出力が切れます。


普段はsshでMacから接続し、GUI作業したい時にTightVNCを使うという運用が良さ気な感じです。


## 環境

- RaspberryPi 3B
- macOS Catalina 10.15.5
- TightVNC-1.3.9


## 参考サイト

- https://darmus.net/raspberry-pi-mac-vnc/
Swift：NSErrorを使って楽にNSAlertを表示する

# はじめに

`NSAlert`を用いると警告のポップアップを出すことができますが、`messageText`と`informativeText`を指定する方法だとアイコンが警告用になりません。

```swift
let alert = NSAlert()
alert.informativeText = "Uploaded file is broken"
alert.messageText = "Retry to upload the file."
alert.runModal()
```

![例1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/e5bab0b3-61a1-49ae-4ddf-68b2d7883ce3.png)

そこで、`NSError`を使うと楽に警告用のポップアップを表示できます。

# 1. 普通に表示

```swift
let userInfo: [String: Any] = [
    NSLocalizedDescriptionKey:  "Uploaded file is broken",
    NSLocalizedRecoverySuggestionErrorKey: "Retry to upload the file."
]
let error = NSError(domain: "HogeDomain", code: 0, userInfo: userInfo)
let alert = NSAlert(error: error)
alert.runModal()
```

![例2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/00b89544-6b22-6c57-b131-2d37f67c7722.png)

# 2. より詳細なエラー情報を付加して表示

```swift
let userInfo: [String: Any] = [
    NSLocalizedFailureErrorKey: "API Error:\t",
    NSLocalizedFailureReasonErrorKey: "duration is too short",
    NSLocalizedRecoverySuggestionErrorKey: "The video file length should be 5 seconds or more."
]
let error = NSError(domain: "HogeDomain", code: 0, userInfo: userInfo)
let alert = NSAlert(error: error)
alert.runModal()
```

![例3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/d84cde99-da2a-79fb-e89a-0824436a04ba.png)

# 3. さらにボタンを押した時の処理を追加する

```swift
let userInfo: [String: Any] = [
    NSLocalizedDescriptionKey:  "Uploaded file is broken",
    NSLocalizedRecoverySuggestionErrorKey: "Retry to upload the file."
]

let error = NSError(domain: "HogeDomain", code: 0, userInfo: userInfo)
let alert = NSAlert(error: error)
alert.addButton(withTitle: "Retry")
alert.addButton(withTitle: "Cancel")
let result = alert.runModal()

if result == .alertFirstButtonReturn {
    // Retry の処理
    print("Retry")
}
```

![例4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/589c4aa4-6efc-a1c7-06b6-d4e8f9940955.png)
忙しい人の為の要件定義の書き方

これは、プログラミングの初心者でまだどこにも内定や、案件を獲得できていない、初学者が勉強したばかりの要件定義について仮想と妄想で考えた要件定義書です。
色んなご指導、意見いただけると嬉しいです。

・なぜやろうと思ったのか？
エンジニアには文章力や単純に伝える能力は必要とのことで。

・参考資料は？
Backlog/ブログ
(参考)　[要件定義とは何？スムーズな進め方や成果物(要件定義書)についても解説](https://backlog.com/ja/blog/what-is-project-requirements-definition/#i-4)

##1.要件定義とは何か？
クライアント、お客さまの要望を叶える為にまとめた文章
###1.1.要件定義はプロジェクト成功の鍵となる
クライアントの要望を**徹底的に聞き、引き出して**から開発が始められる。
要望と解釈に齟齬があっても工程が進むごとに無理が出てきてしまうのでキチンと決めること、でも時間かけすぎても納期に間に合わなくなるからほどほどに。
###1.2.インプットの工程も大切に
多くの依頼は既存の物の改良であることが多い。既存のシステムや現状を確認させてもらうこと。
RFP(提案依頼書)などを確認したり、保守担当から調査するなどしましょう、この、今の現状を把握することを「インプット」といいます。
###1.3.成果物は要件定義書
要件定義の最後はあくまで書類にまとめること、この書類は**要件定義書**といいます。
内容はは第三者が見ても分かるように且つ機能は詳細に、技術者でない人、専門知識がない人にもわかるように伝わるようにかくことを意識すること。
そして、クライアントにきちんと確認をもらいましょう。
##2.要件定義書に記載すべき必須項目
###2.1.システムに関する項目
実装するシステムについて
####2.1.1.   1.システムの概要
どのような機能を備えたシステムなのかについて説明します。
**業務要件**はエンドユーザーの視点で、**システム要件**はエンジニア視点で作られます。
例）サイトに「商品購入」ができる機能を実装して欲しいという要望の場合、**業務要件**は「商品購入」で、**システム要件**は「カートに商品を入れる」とできます。
####2.1.2.   2.システムを導入する目的
システムを導入して、どんなことが実現できるか説明すること
####2.1.3.   3.システム導入後の業務フロー
システムを導入すると、業務フローがどのように変化するのかについて書きます。
例）自動釣銭機を導入する要望の場合、新しくそれを導入すると、これまでとはレジ打ちの方法が変わります。このいった実際の変化について書きます。
###2.2機能要件に関する項目
クライアントご求める機能のこと。
技術側にとってのゴール。データなどシステムが処理可能である内容についても書きます。
###2.3非機能要件に関する項目
機能以外に求められるもの、保守やセキュリティなど。こちらのほうが非機能要件より難しい場合が多い。
##3.スムーズに行える要件定義の手法
###3.1既存の業務フローとシステムについて知る
色んな所に解決すべき問題が出てくるので、できるだけ工数を少なく、問題を理解し解決策を練って、スピーディに行うこと
###3.2要求定義書と要件定義書のすり合わせをする
クライアントの要求と開発側の要件にズレができないようによーくすり合わせること。
###3.3丁寧な要件定義書を作り共有する
実際はお互いの都合や時間の問題もあるので、そう何度も何度もとはいかないので、必要最低限の回数で、イメージしやすく、誰が見ても同じ解釈になる文書にすること。
###3.4担当者を明確にしておく
プロジェクトの担当を決めておきましょう、あとで曖昧にならないように。
クライアントがやっておくべきことも開発側でやってしまうことも少なくないとのこと。
##4.良い要件定義書の必須条件
###4.1専門知識がなくても内容が分かる
誰が読んでもわかる文章で！
###4.2問題の解決策が記載されている
要望、願いを叶える「答え」の書かれた文章で！


##まとめ
エンジニアも文章力が求められるということですね。
これからもこういった参考書類をまとめたものを書いてみたいと思います。
間違っている所などございましたらどしどしご指摘ださい。
ありがとうございました。
10日間でITパスポートに合格した勉強法

#ITパスポートとは
ITパスポート試験は、独立行政法人情報処理推進機構（IPA）が実施者である、
ITに関する基本的な知識を測る「国家試験」です。

合格率は50%前後くらいらしいです。ただ、当日受験に来ない人も多いみたいなので、
実質的な数値はもう少し高いと思います。

#ITパスポートの出題形式
試験時間は120分、四肢択一式の問題が100問出題され、1000点満点中600点をとれば合格となります。

出題分野は、
「ストラテジ系（経営全般）：35問程度」

「マネジメント系（IT管理）：20問程度」

「テクノロジ系（IT技術）：45問程度」

の3分野に分かれ、それぞれの分野で3割以上とる必要もあります。

#ITパスポート合格に必要な勉強時間
普段からパソコンを使っている人で、「100時間」が目安と言われています。
1日3時間勉強して勉強しても1カ月はかかる計算ですね。

それに対して、僕がかけた勉強時間は20時間ほどなので、かなり少ない方だと思います。

#10日間でITパスポートに合格した勉強法
結論から言うと、僕はテキストをほとんど使わず過去問を解くことに注力しました。
用語を覚えたりすることより、あくまでも、最短ルートで合格することに重きをおいたからです。
(ちなみにITの用語などはほとんど知らない文系です)

まず、初日に、テキストを流し読みで3時間ほど使いました。
ちなみに僕が使ったのはこれです。
テキストを使うのは初日のみです。ここで用語などを完璧に覚える必要はなく、「こんな用語があるんだな〜」くらいで問題ないと思います。

他のテキストを見ていないので、断言はできないですが、
このテキストはできるだけ出る部分のみを抽出されて書かれているため、
無駄な用語などを覚える必要がありません。
そのため、そこまで分厚くもなく、1日あれば、十分に読める量になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681053/b724c0e6-c821-e775-1eee-6cf47dab7541.png)

残りの9日間(1日2時間程度)でひたすら過去問をときます。
「20XX年夏秋版ITパスポート問題集」というアプリを使いました。
検索すると普通に出てきます。
これを移動時間を使ってひたすら解いてました。

ITパスポートは問題が使い回しにされる傾向がありますので、何度も解くことで「この問題どこかで見たかも。。。」という現象が起きます。
過去5年分くらいを解く感じでやってました。もちろん10年分できるならした方が無難です。
計算問題は余裕があればでいいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681053/ba045866-70fc-417d-6a94-20275d395127.png)

#まとめ
・テキストは初日で流し読み
・問題が使い回しにされるため初日以外の時間はアプリを使って過去問を往復

ただ、ITパスポートはほとんど毎日開催されるので、落ちても何回でも受ければOKですね。
配列のソート

###文字列のソート
sort()で事足りると思ったが、大文字や小文字のアルファベットがあった時に期待しているような並びにならなかった。

````js
var items = ["Orange", "banana", "apple", "Peach"];
items.sort();
// ["Orange", "Peach", "apple", "banana"]
````

比較関数を指定してやるといいようだ。

````js
var items = ["Orange", "banana", "apple", "Peach"];
items.sort(function(a, b){
    a = a.toString().toLowerCase();
    b = b.toString().toLowerCase();
    if(a < b){
        return -1;
    }else if(a > b){
        return 1;
    }
    return 0;
});

// ["apple", "banana", "Orange", "Peach"]

````

###数字のソート
数字もsort()だけではうまくいかない…。

````js
var nums = [ 3, 6, 4 ,21, 15];
nums.sort();
// [15, 21, 3, 4, 6]
````

引数に比較関数。

````js
var nums = [ 3, 6, 4 ,21, 15];
nums.sort(function(a, b){
    return a - b;
});
// [3, 4, 6, 15, 21]

````

###Objectの特定のキーによるソート

````js
var fruits = [
   {name:"apple",price:100},
   {name:"orange",price:98},
   {name:"banana",price:50},
   {name:"melon",price:500},
   {name:"mango",price:398}
];

// priceでソート
fruits.sort(function(a,b){
    if(a.price<b.price) return -1;
    if(a.price > b.price) return 1;
    return 0;
});
// {name: "banana", price: 50}
// {name: "orange", price: 98}
// {name: "apple", price: 100}
// {name: "mango", price: 398}
// {name: "melon", price: 500}

````

複数のキーでソート

````js

var fruits = [
   {name:"apple",price:100,weight:90},
   {name:"mango",price:500,weight:200},  
   {name:"orange",price:98,weight:150},
   {name:"apple",price:100,weight:100}, 
   {name:"banana",price:50,weight:50},
   {name:"melon",price:500,weight:500},
   {name:"mango",price:398,weight:200}
];

fruits.sort(function(a,b){
    if(a.weight>b.weight) return 1;
    if(a.weight<b.weight) return -1;
    if(a.price>b.price) return 1;
    if(a.price < b.price) return -1;
    return 0;
});
// {name: "banana", price: 50, weight: 50}
// {name: "apple", price: 100, weight: 90}
// {name: "apple", price: 100, weight: 100}
// {name: "orange", price: 98, weight: 150}
// {name: "mango", price: 398, weight: 200}
// {name: "mango", price: 500, weight: 200}
// {name: "melon", price: 500, weight: 500}
````
GatsbyJS にNetlify設定ファイルを設置する

# Netlifyのデフォルトドメインについて

Netlifyではサイトをデプロイした時、`[name-of-your-site].netlify.app`というドメインが自動で割り当てられます。
自分で取得したドメインをカスタムドメインとして設定したいことが多々あると思いますが、カスタムドメインを設定しても、`[name-of-your-site].netlify.app`というドメインは存在し続けるので、SEOで重複コンテンツとならないために、主に下記の対応をする必要があります。

- `[name-of-your-site].netlify.app`のHTTPレスポンスヘッダーに`X-Robots-Tag: noindex`を付与する。
- `[name-of-your-site].netlify.app`をカスタムドメインに301リダイレクトさせる（恒久的リダイレクト）

Netlifyには、公開ディレクトリのルートに`_headers`や`_redirects`という設定ファイルを置くことで、
HTTPヘッダーやリダイレクトの設定を行うことができます。

[Custom headers | Netlify Docs](https://docs.netlify.com/routing/headers/)

[Redirects and rewrites | Netlify Docs](https://docs.netlify.com/routing/redirects/)

また、同じくルートディレクトリに`netlify.toml`ファイルを設置することで、headersやredirectsをまとめて設定することも出来ます。

## コミュニティの回答

上記の`[name-of-your-site].netlify.app`のSEO上の解決策は、Netlifyのコミュニティでも議論されています。

[Disabling X-ROBOTS-TAG header on hosted site - Support - Netlify Community](https://community.netlify.com/t/disabling-x-robots-tag-header-on-hosted-site/8857)

[Netlify.app and netlify.com subdomains are showing in Google search results - Support - Netlify Community](https://community.netlify.com/t/netlify-app-and-netlify-com-subdomains-are-showing-in-google-search-results/13919)

# GatsbyJSにNetlifyの設定を追加する

## プラグイン

GatsbyJSでは、NetlifyのHeadersやRedirectsを設定するためのオフィシャルプラグインが公開されています。

[gatsby-plugin-netlify](https://www.gatsbyjs.org/packages/gatsby-plugin-netlify/?=netlify)

自分は、上記プラグインが上手く使いこなせず苦労しました。
（Gatsby Cloudでビルド→Netlifyにデプロイする構成）

まず、Headersで`[name-of-your-site].netlify.app`に`X-Robots-Tag: noindex`を付与する方法を試みましたが、設定したカスタムドメインの方にも`X-Robots-Tag: noindex`が付与されてしまい、Headersでの設定は諦めました。

次に、Redirectsで301リダイレクトをさせようと思ったのですが、「このプラグインは相対パスしか正常に処理しないのでは？」という疑念が出てきたので、別の方法にシフトしました。

## `public`フォルダにNetlify設定ファイルを置く

下記記事が救いになりました。

[How To Add Netlify Redirects To A Gatsby Site | by Konstantin Münster | Level Up Coding](https://levelup.gitconnected.com/how-to-add-netlify-redirects-to-a-gatsby-site-ae678518cc91)

GatsbyJSの`public`フォルダは、ビルド処理が走ったファイルが出力されるので、直接ファイルを置いておけません。

上記記事では、`static`フォルダに`_redirects`ファイルを設置することでビルド処理後の`public`フォルダに`_redirects`ファイルを含めています。

`static`フォルダに保存されたファイルは、`public`フォルダにそのままコピーされます。

> You can create a folder named static at the root of your project. Every file you put into that folder will be copied into the public folder. E.g. if you add a file named sun.jpg to the static folder, it’ll be copied to public/sun.jpg

[Using the Static Folder](https://www.gatsbyjs.org/docs/static-folder/)

ドキュメン内にNetlify設定ファイルを置く用途としての記載はありませんが、自分は`static`フォルダに301リダイレクトの設定を記述した`netlify.toml`を設置することで、デプロイ後の`[name-of-your-site].netlify.app`で正常にリダイレクトが行われました。