OmniAICreator/Qiita-1.07M huggingface dataset:
Yarnをシングルユーザーでマニュアルインストールする

# はじめに
オフィシャルのスクリプトを使いたくない｡
GPGは見ない｡
コピペ
# 本文
```shell:Install-w/posix-shell
yarn_ver=$(curl -sL https://nightly.yarnpkg.com/latest-tar-version) && \
aria2c -x16 -s20 -qtrue -o yarn.tar.gz https://nightly.yarnpkg.com/yarn-v${yarn_ver}.tar.gz && \
tar -axvf yarn.tar.gz && \
mv yarn-v${yarn_ver}/ ~/.yarn/
```

```shell:posix-config
## Yarn
export PATH="$HOME/.yarn/bin:$PATH"
```

```shell:fish-config
## Yarn
set -gx PATH $HOME/.yarn/bin $PATH
```

```shell:w/gpg
curl -Ls https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --import && \
yarn_ver=$(curl -sL https://nightly.yarnpkg.com/latest-tar-version) && \
aria2c -x16 -s20 -qtrue -oyarn.tar.gz https://nightly.yarnpkg.com/yarn-v${yarn_ver}.tar.gz && \
aria2c -x16 -s20 -qtrue -oyarn.tar.gz.asc https://nightly.yarnpkg.com/latest.tar.gz.asc && \
gpg --verify yarn.tar.gz.asc||! echo '[CRIICAL] GPG Verify is Not Valid' ;\
if [ ! $? = 0 ];then exit 1; fi && \
rm yarn.tar.gz.asc && \
tar -axvf yarn.tar.gz && \
mv yarn-v${yarn_ver}/ ~/.yarn/"
```
ABC179参戦記

なんだかんだ言いつつやったりやらなかったりです。
CがTLEする解法しかわからないのでそこで終了しました。

[A.Plural Form](https://atcoder.jp/contests/abc179/tasks/abc179_a)
S[-1]が"s"なら"es"、そうでないなら"s"を付けてやればよいですね。

```python
s=input()
print(s+"es" if s[-1]=="s" else s+"s")
```

[B.Go to Jail](https://atcoder.jp/contests/abc179/tasks/abc179_b)
短絡評価するからこういう条件式でいいはず。

```python
n=int(input())
d=[[int(i)for i in input().split()]for j in range(n)]
res="No"
for i in range(n-2):
    if d[i][0]==d[i][1] and d[i+1][0]==d[i+1][1] and d[i+2][0]==d[i+2][1]:
        res="Yes"
        break
print(res)
```

[C.A x B + C](https://atcoder.jp/contests/abc179/tasks/abc179_c)
1<=i<Nとなる各iに対してN-iの約数の数を足していく感じかなーと思ったのですがTLEしました。
計算量が$N\sqrt{N}$なので$10^9$になってダメなんですね。
ここからどうするのかわからんので終わり。

```python
def aaa(x):
    res=[]
    for i in range(1,int(x**0.5)+1):
        if x%i==0:
            res.append(i)
            if x/i != i:
                res.append(x/i)
    return len(res)

n=int(input())
res=0

for i in range(1,n):
    res+=aaa(n-i)
print(res)
```

解説みたら「Cは1つしかないのでA*B<Nとなる(A,B)の組の数を求めればいい」とか言われてあーなるほどね完全に理解したってなった。
こういう問題の読み換えがドチャクソ苦手というのがわかる。なんか前にも同じこと言った覚えがある。

おわり
【ruby】例外処理で、施されたら施し返す

例えばあるデータをパースして、特定のデータのみデータベースに保存したいとする。
その中で、パースできない拡張子があればエラーが出て、処理が中断してしまいバグを引き起こしてしまう。

そこで、便利なのが例外処理というもので、処理を中断させず例外事案の場合の処理を施すことができる。

まさに、`施すこされたら施し返す、恩返しです`を実現できるのだ。

今回は単純な計算を例に、例外処理を見ていこう。

#エラーが発生した場合の処理　begin / rescue

Ruby内で、10を0で割ろうとするとエラーが出てしまう。

```rb:
puts 10 / 0
puts "こんにちわ"
```

```ターミナル
divided by 0 (ZeroDivisionError)
```

処理が途中で、中断されてしまう。

そこで、
- エラーの対象になりそうな箇所を、`begin`で囲う。
- エラーが発生した時の処理を、`rescue`内に記述する。



```rb:
begin
  10 / 0
rescue
  p "0で割れません"
end

puts "こんにちわ"
```

```ターミナル
"0で割れません"
"こんにちわ"
```

処理が中断されず、エラー時の処理と正常処理どちらも実行された。

###省略法
beginなしで、rescueさせる

```rb:
puts 10 / 0 rescue 0
puts 10 / nil rescue 0 
```


```ターミナル
0
0
```

#エラー内容を、変数に格納　rescue =>


```rb:
begin
  10 / 0
rescue => e
  puts e
end

puts "こんにちわ"
```

```ターミナル
divided by 0
こんにちわ
```

エラーオブジェクトが、変数eに格納されて出力できる。


#エラーごとの処理を変える　rescue "エラーメッセージオブジェクト"

```rb:
begin
  10 / 0
rescue NoMethodError
  puts "そのようなメソッドはない"
rescue ZeroDivisionError
  puts "0で割れません"
end
```


```ターミナル
0で割れません
```

2番目のエラーメッセージに該当するので、そのrescueに反応する。

###注意点
対象の例外クラスの親が、先に記述されいた場合はそちらが先に処理される

```rb:
begin
  10 / 0
rescue StandardError
  puts "基本的なエラー"
rescue ZeroDivisionError
  puts "0で割れません"
end
```

```ターミナル
基本的なエラー
```


#明示的なエラーを発生させて、処理を中断させる　raise
使用用途は、
1. パラメータが想定されたものでないとき
2. 不正なアクセスがきた時

```rb:
begin
  raise NoMethodError
rescue => e
  p e
end
```

```ターミナル
NoMethodError
```

###独自のエラーを発生させる
例外クラス（StandardErrorクラス）を継承させてあげる。

```rb:
class Hoge < StandardError
end

begin
  raise Hoge
rescue => e
  p e
end
```


```ターミナル
#<Hoge: Hoge>
```


#エラー時でも、再度初めから実行させる　retry

```rb:
num = 0

begin
  puts 10 / num
rescue ZeroDivisionError => e
  puts e
  num = 1
  retry
end

puts "終了しました"
```

```ターミナル
divided by 0
10
終了しました
```

ループ1回目では、エラーが発生していて、
ループ2回目では、正常に処理がされている。



#エラーが発生しても、しなくても行う処理　ensure

```rb:
begin
  puts "例外なし"
rescue => e
  puts e
ensure
  puts "Hello"
end
```

```ターミナル
例外なし
Hello
```

ensureは、いかなる時でも必ず実行される。



#番外編 エラーオブジェクトとは

```rb:
begin
  10 / 0
rescue => e
  puts e.class
  puts e.class.superclass
  puts e.class.superclass.superclass
  puts e.class.superclass.superclass.superclass
end
```

```ターミナル
ZeroDivisionError
StandardError
Exception
Object
```
Exceptionが元となるクラスで、Objectがその親
Webスクレイピング&ファイル名一覧獲得

#Webスクレイピング
Beautiful Soupについて：https://gammasoft.jp/blog/difference-find-and-select-in-beautiful-soup-of-python/

##code

```
#4travelの場合
import requests
from bs4 import BeautifulSoup

url = 'https://4travel.jp/dm_shisetsu/10002779#contents_top'
r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")
reviews = soup.select('[class="shisetsu_reviewItem"]')
print(reviews)
```


##例

```
[<li class="shisetsu_reviewItem">
<div class="review_summaryBox is_reviewCaption">
<div class="u_titleWrap">
<h3 class="u_titleItem">
...
```


#ファイル名一覧獲得
https://note.nkmk.me/python-listdir-isfile-isdir/
勉強日誌14日目　（午後の部）

やっていきましょう

凡ミスで正答率下げてるところがちょいちょいあるので落ち着いて取り組みたい

正答率74%　（62%）

find /var -type l
findコマンドで/var配下のシンボリックリンク検索

ulimit -u 1024
ユーザーが使用できるプロセス数を1024に制限するコマンド


chage -W 14 user
ユーザ　user　のパスワード期限14日前に警告

lsof
ファイルシステム、ポート、システムのリソースを使用しているプロセスの情報

fuser -k -n tcp 11111
fuserコマンドで11111/tcpを使用中のプロセス強制終了

visudo
sudoコマンドの設定ファイルを編集

nmap
指定したホストの開いているポートを一覧表示

find / -perm -6000
SUID SGID の両方が設定されたファイルを全て把握

find / -perm +6000
SUID SGID のいずれかが設定されたファイルやディレクトリを把握

lsof -i:ポート
ポートのプロセス表示

正答率　72% (44)

/etc/init.d
initにより実行される　スクリプトが置かれているディレクトリ

/etc/xinetd.d
xinetdでそれぞれのサービスごとの設定ファイルを置くディレクトリ

socket
systemd 特定のサービス宛のネットワーク接続を監視

wait=no
サーバプログラムがマルチの場合

/etc/hosts.deny
TCPラッパーでアクセスを拒否するホスト

正答率　52% (33%)

~/.gnupg
GnuPGに関するファイルの置かれるディレクトリ

PermitRootLogin　no
rootユーザでのSSHログインを禁止する為の設定項目

gpg -o ファイル --export メールアドレス
GnuPGを使って公開鍵出力

gpg -e -r メールアドレス　ファイル
公開鍵を使ってファイルの暗号化

ssh-agent
パスフレーズを求められない

gpg
GnuPGを使ってファイルの暗号化や複合化

gpg 暗号化ファイル
自分の秘密鍵を使用して複合化するコマンド

/etc/ssh/sshd_config
sshdの設定ファイル

/etc/ssh/ssh_config
sshの設定ファイル

gpg --gen-key
~/.gnupg/の下に秘密鍵と公開鍵のキーペア作成

ssh -p ポート server
ssh -o Port=ポート server
ホスト　のポート　に接続

ssh
インターネット上のサーバにログインして、管理、設定するプロトコル
ARCore Depth APIについて

# ARCore Depth APIとは
Googleの拡張現実（AR）に関するアップデートであり、ARCoreに追加された新しいAPI。
Depthセンサなどの専用の機器を用いることで、デバイスに搭載されたRGBカメラを用いた深度マップの生成を行うことが可能になっています。

# そもそもDepthセンサとは何か
Depth = を測定するセンサ。
これによって深度を目に見える形（色など）で表現したものがDepth Map（深度マップ）。
Depth APIはサーモグラフィのような色で表現されています。

# Depth APIのここがすごい！
大きく分けて2点

- オクルージョンの表現
- 専用の機器を追加で取り付ける必要がない

## オクルージョンの表現
遮蔽の表現のこと。手前のものが後ろのものを隠す表現をオクルージョンといいます。
現実の世界では当たり前にあるものではあるが、ARの場合、現実世界のオブジェクトや他の3Dオブジェクトとの距離を考慮しながら3Dモデルの表示をコントロールしなければ、適切な遮蔽表現はできません。

ARの現実感に影響する重要な要素でもあります。

![AR_okuru-jonn.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645987/c304e128-2622-0037-31d0-250c0f7d6e85.jpeg)
　　　　←:オクルージョンなし　　　　　　→:オクルージョンあり
引用元:https://japanese.engadget.com/jp-2019-12-25-google-3d-ar-arcore.html

## 専用の機器を追加で取り付ける必要がない
公式の記事によると、センサが搭載されている方が精度は高くなるものの、必須ではないようです。

ARCoreに対応した機器である必要はあるものの、新規に専用のセンサが搭載されたデバイスを買う必要もなく、自由度がかなり高くなっています。

ARCore Android向けのDepth APIの概要:
https://developers.google.com/ar/develop/java/depth/overview

# 実際に使ってみる
環境
Pixel 3a
Andorid 10
Android Studio 4.0.1

公式がサンプルを出してくれているため、これを使います。
詳しくは[こちら](https://developers.google.com/ar/develop/java/depth/quickstart)のサイトをご参考にしてください。

## サンプルプロジェクトを開く
次のコマンドでサンプルプロジェクトを持ってこれます。

```
git clone https://github.com/google-ar/arcore-android-sdk.git
```

Android Studioで、arcore-android-sdk/samples/hello_ar_javaを開きます。

## サンプルを実行する
Andorid Studioからサンプルを実行することで、サンプルアプリを使うことができます。
エミュレータでの起動はできないため、注意してください。

## サンプルの実行結果
サンプルの内容としては、タップした場所にドロイドくんを設置できるものになっています。
平面の検知をしてくれるので、きれいに床の上に設置されます。
※白い三角形のメッシュが出ているところが検知された平面部分
![スクリーンショット 2020-09-19 21.57.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645987/605bc623-86db-ea08-0cf0-0492af57f7db.png)

設置したドロイドくんはオクルージョンが適応されているため、ドロイドくんを物の後ろに設置すると見えなくなります。
![スクリーンショット 2020-09-19 22.09.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645987/35c94ea7-1073-5eb5-ee76-5980eafc9a2e.png)

# Depth APIを体験できるアプリ
[APIの紹介動画](https://www.youtube.com/watch?v=cLQJ864LNWI)で紹介されているアプリ

- [ARCore Depth Lab](https://play.google.com/store/apps/details?id=com.google.ar.unity.arcore_depth_lab)
- [Snapchat](https://play.google.com/store/apps/details?id=com.snapchat.android&hl=en_US)
- [Five Nights at Freddy's AR: Special Delivery](https://play.google.com/store/apps/details?id=com.illumix.fnafar&hl=en_US)
- [TeamViewer Pilot](https://play.google.com/store/apps/details?id=com.teamviewer.pilot&hl=en_US)
.NET Compact Framework（VB.NET）で二重起動防止（Mutexを利用）する方法

Mutexは、ソフトウェアの二重起動の抑止など、さまざまな用途に利用できる排他制御の仕組みです。元々はDigital Equipment Corp.でのVMS開発チームにて開発された、汎用機向けの排他制御の仕組みですが、Windowsには古くから移植されて備わっており、通常のPC向けの.NET Frameworkでは手軽に利用することが出来ます。

しかし、VB.NET CF3.5ではSystem.Threading.Mutexが無いため、Mutex自体をCoredll.dllからP/Invokeする必要があります。

```vb:mutextest.vb

Option Strict
Option Explicit
  
Public Class mutextest
 
    <DllImport("CoreDll.Dll", SetLastError:=True)> _
    Public Shared Function CreateMutex(ByVal Attr As IntPtr, ByVal Own As Boolean, ByVal Name As String) As IntPtr
    End Function
 
    <DllImport("CoreDll.Dll", SetLastError:=True)> _
    Public Shared Function ReleaseMutex(ByVal hMutex As IntPtr) As Boolean
    End Function
 
    <DllImport("CoreDll.Dll", SetLastError:=True, CallingConvention:=CallingConvention.Winapi, CharSet:=CharSet.Auto)> _
    Private Shared Function CloseHandle(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
 
    Sub Main()
        '------------------------------------------
        ' 二重起動の確認
        '------------------------------------------
        Const ERROR_ALREADY_EXISTS As Long = 183　　'既に起動してるよというエラーコードはこの内容で帰ってくる
 
        Dim mutexHandle As IntPtr = IntPtr.Zero
        Dim myName As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
        Try
            mutexHandle = CreateMutex(IntPtr.Zero, True, myName)
            If System.Runtime.InteropServices.Marshal.GetLastWin32Error() = ERROR_ALREADY_EXISTS Then
                'Mutexにより、二重起動時の処理はここに飛んでくる
                Msgbox "二重起動は禁止されています"
 
            Else
                'Mutexにより、二重起動じゃない時の処理はここに飛んでくる
                '-----------------プログラムの開始
  
                'プログラムの本体はここに書いていく
                'お好みでMain()の引数等は処理してください。
 
                '-----------------プログラムの終了
            End If
        Catch ex As Exception
                'mutexのIf文の中で発生した各種エラーに応じた処理はここで行う
                '（デバッグ用のログファイル書き出しとかシステムエラーのダイアログとか）
                Msgbox ex.Message
        End Try
        ReleaseMutex(mutexHandle)
        CloseHandle(mutexHandle)
    End Sub
End Class

```
Node.jsで画像ファイルのExif情報を削除する

# TL;DR
gmパッケージを使いNode.jsで画像ファイルのExif情報を削除する方法を紹介します。

サンプルとして２パターンの使い方を示します。

- ローカルの画像ファイルを処理する
- ブラウザからアップロードした画像をNest.js（Typescript）で受け取り処理する

# セットアップ

[gm](https://github.com/aheckmann/gm)パッケージを使います。他、GraphicsMagickとImageMagickにも依存するので別途インストールしておきます。

# 検証環境

macOS v.10.15.4

``` bash
$ node -v
v12.16.1

$ npm -v
6.13.4

$ brew info graphicsmagick
graphicsmagick: stable 1.3.35 (bottled), HEAD

$ brew info imagemagick
imagemagick: stable 7.0.10-27 (bottled), HEAD
```

# サンプルコード
## a. ローカルの画像ファイルを処理する
基本的な使い方です。

```js
const gm = require('gm');

gm.subClass({
    imageMagick: true
});

gm(__dirname + '/image.jpg')
    .autoOrient()   // exifから回転方向を設定しておく
    .noProfile()    // exifを削除
    .write(__dirname + '/image_after.jpg', async err => {
        if (err) {
            console.error(err);
            return;
        }
    });
```

## b. ブラウザからアップロードした画像をNest.jsで受け取る（Typescript）
Nest.jsのセットアップなどは割愛します。

### 画像ファイルのアップロード
- 選択したファイルをFormDataに詰めてfetchで送信します
- "my-images"の部分は任意で、サーバーサイドでも同じ文字列を使用します

```html
<label>
  画像を選択
  <input id="input-files" type="file" multiple />
</label>
<input id="input-upload" type="button" value="アップロード" />
<script>
  const inputFiles = document.querySelector('#input-files');
  document
    .querySelector('#input-upload')
    .addEventListener('click', event => {
      formData = new FormData();
      for (let i = 0; i < inputFiles.files.length; i++) {
        formData.append('my-images', inputFiles.files[i]);
      }

      fetch(`/upload`, {
        method: 'POST',
        body: formData,
      });
    });
</script>
```

### サーバーサイド
```typescript
import {
  Controller,
  Get,
  Post,
  UploadedFiles,
  UseInterceptors,
} from '@nestjs/common';
import { FilesInterceptor } from '@nestjs/platform-express';
import { AppService } from './app.service';
import * as gm from 'gm';
gm.subClass({ imageMagick: true });

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Post('/upload')
  @UseInterceptors(FilesInterceptor('my-images'))
  async upload(@UploadedFiles() files: any[]) {
    for (let i = 0; i < files.length; i++) {
      const filePath = __dirname + '/' + files[i].originalname;
      gm(files[i].buffer)
        .autoOrient()
        .noProfile()
        .write(filePath, err => {
          if (err) {
            console.error(err);
            return;
          }
        });
    }
  }
}
```
Larvel8系でLaravel青本を使うと出てくるエラー

#Larvel8系でLaravel青本を進めていると出てくるエラー
##PHPフレームワークLaravel入門 第2版 (日本語) 単行本(以下青本)を使う方も多いのではないでしょうか。
この本の出版は2019年12月と少し古いもののLaravel7系でも動作確認できていると著書の最初の方に書いてあります。
しかし！
2020年9月8日に出たばかりのLaravel8系を使うと一点問題が起きます。
9月8日以降にLaravelのプロジェクトを作った方は普通どおり操作すればLaravel8系になるのでその方が対象です。
具体的にはweb.phpを記載する際、これまで

```php
Route::get('hello','HelloController@index')
```
と書いていた所をLaravel8系では

```php
use App\Http\Controllers\HelloController;
Route::get('hello', [HelloController::class, 'index']);
```
と書くんです。
大事なのはuse.....もいる所。そしてコントローラー名の記載方法が””の中に書くものから[]内に書くという方法へと変わったことです。

青本でいうとp43に初めて影響が出てくるのですが、これを従来の方法で書くと
>Target class [HelloController] does not exist.

と怒られてしまいます……
cURL関数

初心者のため、細かいミスや違う所があったらマサカリをどんどん投げてください。
よろしくお願いいたします。

#cURL関数とは
cURlとは<font color=red>HTTPリクエストをすることにより、外部サイトの情報を取得</font>できる関数のことをいいます。情報を取得するというと、file_get_contentsという物もあります。大概はfile_get_contentsの方がシンプルに書けるので便利です。しかし、外部のAPIを使うためにヘッダに認証キーを乗せたり、POSTで送信したりする場合はオプションの数が多いcURLの方が自然に書くことができます。

#cURLの使い方

コード例を紹介していきます。

```php5
function file_curl($url)
{
  $ch= curl_init();//（１）
  curl_setopt($ch, CURLOPT_URL, $url);//(2)
  curl_setopt($ch, CURLOPT_HEADER, false);//(2)
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//(2)
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//(2)
  curl_setopt($ch, CURLOPT_TIMEOUT, 30);//(2)
  $html = curl_exec($ch);//(3)
  curl_close($ch);//(4)
  return $html;
}
```

上から見ていくとこのようになります。

###1.curl_initで初期化

```php
$ch= curl_init();
```
###2.curl_setoptでオプション設定
  
```php
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_HEADER, false);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($ch, CURLOPT_TIMEOUT, 30);
```
###3.curl_execで処理実行
```php
$html = curl_exec($ch);
```

###4.curl_closeで終了処理

```php
curl_close($ch);
```

(2)のオプションについては以下になります。

| Option | 意味 |
|:-:|:-:|
|  CURLOPT_URL  | CURLOPT_URL URLの指定  |
|  CURLOPT_HEADER  | ヘッダーの有無（false=いらない）   |
|  CURLOPT_RETURNTRANSFER | データを文字列に変換するか（true=する）  |
|CURLOPT_SSL_VERIFYPEER   |  SSL証明書の検証をするか（false=しない） |
|  CURLOPT_TIMEOUT | タイムアウトする時間（秒）  |



＃終わりに
cURLの本当に基本的な使い方や使う意味を紹介しました。
他のみなさんの記事や公式マニュアルを見ていると、まだまだオプションの種類もありますので参考になるURLを貼って起きます。
またより具体的な使い方を紹介していただいているサイトも貼っておきます。

公式マニュアル
http://php.net/manual/ja/book.curl.php

オプション一覧
http://jp2.php.net/curl_setopt


https://qiita.com/wanwanland/items/a5f9574fadd214d7b5c8
【Blender】 2.9 パーティクルインスタンスとは

# 動作環境
本記事の動作環境は以下の通りです。
(2.9にアップデートしました)
 
| 項目             |               環境 |
|:-----------------|:------------------|
| OS               |         Windows 10 | 
| Blender          |               2.9 |

#パーティクルインスタンスとは

参考：[https://docs.blender.org/manual/ja/2.90/modeling/modifiers/physics/particle_instance.html](https://docs.blender.org/manual/ja/2.90/modeling/modifiers/physics/particle_instance.html)

パーティクルインスタンスとは別のターゲットオブジェクトから選択されたパーティクルシステムのパーティクルの位置に複製するモデルファイアのこと。

#例えば

平面に対してパーティクルシステム（ヘアー）を設定し、立方体にパーティクルインスタンスモデルファイアを設定すると。ヘアの先端に立方体が複製される。
(パスに沿って作成を有効にすると、先端ではなく、パス沿って作成される)

![before.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/b58409fd-338f-df29-14bd-ae556a878a11.png)

![after.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/1aba5fd7-121e-4796-8c59-59e12518c840.png)


# ちなみに
パーティクルのレンダーをオブジェクトにしてインスタンスオブジェクトに立方体を選択すると、パーティクルが発生する位置に複製される。

![after2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/11d85971-1295-8851-4f98-3a601fcc9109.png)


#また
パーティクルのレンダーをオブジェクトにして、オブジェクトインスタンスを選択しないまま、パーティクルインスタンスのサイズを有効にすると、サイズの設定が反映される。

![after3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/1a7792c5-836c-1439-7c4d-52d6e71d246b.png)

![after3-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/47e8a958-4045-aa58-fe4c-ca54463ea5f9.png)

#ちなみに2


パーティクルオブジェクトとモデルファイアオブジェクトの位置を変えると、それぞれの動きに追従して移動するが、下手に位置を適応してしまうと形が崩れる原因になる。

![after4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/dca178db-e61f-ac38-294f-a471258e4504.png)

![after4-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/f83d172e-7761-b18b-420a-9209ec27f171.png)
MVVMモデルを理解する

**Model-View-Controller(MVC)から派生したパターンで、**
**Presentation Modelパターンを祖先とするデザインパターンです。**
**ドメイン・ロジックとプレゼンテーション・ロジックを分離する点ではMVCと同じです。**

**「Model」「ViewModel」「View」の3つの役割から構成されています。**
**「ViewModel」「View」を併せた部分がMVCモデルの「View」に相当すると認識しています**

##Model(モデル)
ビジネスロジック部分です。
Modelの役割は、ViewとViewModelの役割以外の部分です。
描画部分とは切り離されていて、ViewModel(ビューモデル)に渡す
または、ViewModel(ビューモデル)から渡されたデータを処理する部分です。

##ViewModel(ビューモデル)
ModelとViewの橋渡しを行う点については、MVCモデルのControllerと同じです。
ControllerはViewの表示に関する制御をしませんが、
ViewModel(ビューモデル)はデータバインディング等の仕組みを利用して、
View(ビュー)の表示を制御する部分です。

##View(ビュー)
ViewModelが保持するデータをデータバインディング等の仕組みを利用して、
ユーザーに表示する見た目の部分を担います。
または、ユーザーからの入力を受けつける部分です。

##MVVMモデルのメリット
・MVCと同じく、役割を分割することで、どの部分に何を書けば良いかわかりやすいです。
・MVCと同じく、ソースに修正が入る際に影響範囲を狭く抑えることができます。
・データバインディング等の機能を利用するため、
　MVCよりも見た目のデザインに専念できる人が生まれます。
[iOS]ipaファイル中身解析

とりあえず簡易的にまとめる。ipaファイルは中身はただのzipファイルなので、拡張子を.zipに変更した後ダブルクリックなどをすると解凍できる。

中身にペイロードがあるが、これをチェックする方法・ツールはいくつかある。

 - 単純に右クリックで「パッケージの内容を表示」とすると、中身のデータのブラウジングができる。 
 - 画像リソースを見たい場合: [asset catalog tinkererの解説](http://harumi.sakura.ne.jp/wordpress/2020/02/20/ipaファイルの中身の画像リソースを解析する/)

 - ipaの基本情報やprovisioning profile, info.plistを見たい場合: [ipa analyzerの説明](https://qiita.com/tarappo/items/9600677bd02eb8558a49)
   - iPad analyzerのインストールに詰まったら https://qiita.com/nishina555/items/63ebd4a508a09c481150
   - ipaをビルドしたXcodeのバージョン、ビルドしたマシンのOSのバージョン、プッシュ通知を利用している場合はその設定がきちんとなされているかなどもipaファイルから読み取れるため便利だろう。　https://speakerdeck.com/henteko/ipahuairufalsezhong-shen-wo-si-itemiyou?slide=29
   - [otool](https://shu223.hatenablog.com/entry/20110518/1305738227)
2桁以上の数字から、任意の桁の数値を取りたい時の方法！！

こんばんは
アロハな男、やすのりです！！

今週勉強している中で理解するのに少し時間が必要だったことについて備忘録も兼ねて書き記しておこうと思います

今回のテーマは題名の通り**『2桁以上の数字から、欲しい桁の数値を取る時はどうしたらいいの！？』**を解決しちゃいましょう！！

ちなみに、計算は全て整数になっているので今回は省きますが、小数点が入っていたりしたらto_iメソッドを使ったりと少し変化も有ります。

#どうやって欲しい桁の数値を取るの？
それじゃあ、まず先に**百の位まで**の数値の取り方をずらっと書いちゃいますね！

```ruby
num = 123

# 100の桁が欲しい場合
digit_100 = (num / 100) % 10

# 10の桁が欲しい場合
digit_10 = (num / 10) % 10

# 1の桁が欲しい場合
digit_1 = (num / 1) % 10

puts "100の桁の数値は#{digit_100}です"
puts "10の桁の数値は#{digit_10}です"
puts "1の桁の数値は#{digit_1}です"
```
さぁ、これでコードの記述が終わりましたね！！
これを実行するとちゃんと欲しい桁の値が取れているのか...

##結果

```ruby
100の桁の数値は1です
10の桁の数値は2です
1の桁の数値は3です
```
ちゃんと出力されましたね！！

それじゃあ細かく見ていきましょう。

##解説
それじゃあ10の桁の場合を見ていきましょう。

```ruby
digit_10 = (num / 10) % 10
```
となっていますね。
まず数式の前半部分を計算すると**12**が返ってきます。
ここから元々**10の桁**だった部分が、今は**1の桁**に移動していますね。
あとは10の桁以上の数値が不要になるわけなので計算して1の桁だけが欲しいところ...

そうか！！
**10で割って1の桁を余りとして返せばいいのか！！**ということで後半部分の『%』の出番ですね。

12を10で割った余りを出力結果とするから、

```ruby
2
```
が結果として返ってくるわけですね！！

この前半部分の**10**というところ、今回は10の桁だったので10で割ってますが、**１万の桁なら１万**で、**100万なら100万**の桁で割れば欲しい桁の数値が1の桁に返ってきます！！

#なぜ理解するのに時間が必要だった？
今回の説明を見れば『ん？意外と簡単じゃない？なんで理解に時間がかかったの？』と思う方もいらっしゃるかもしれません。

実は今回の桁数取得の方法を考えている時に出されていた問題が**『2桁の数字から数値をそれぞれ取得しなさい』**という旨の問題だったんです！！

先ほどの解説の時にも説明しましたが、1の桁を欲しいのであれば**『10で割った余りを返り値とすればいいだけじゃん』**となったんです。
そして10の桁も**『10で割った答えだけで桁の数値が取れるじゃん』**となりました。

そうするとどうでしょう。

```ruby
digit_10 = num / 10
digit_1 = num % 10
```
というコードになっちゃいました
これでも2桁だけなら答えは一緒なので『あれ...なんでこれでダメなんだ？』となってしまいました...

このコードだと桁数が増えた時に、1の桁と1番上の桁の数値を取得するだけなら対応できますが、中間の桁を取得することができません！！

そのことに気付いたら理解がすぐにできましたが、それに気付くまでに少し時間がかかってしまいました:sweat_smile:

#結論
こんな簡単そうに見えることでもハマると一切理解ができない。
だが**理解できた時の達成感**は変えがたいものが有ります。
もう脳汁ドパドパでてる感じでした:laughing:

#皆さんも困難にぶつかっても諦めずレッツトライ！！
EclipseでAmaterasUMLを使う

# はじめに
Eclipsを久しぶりに使う際に，以前UML図を自動で生成してくれるAmaterasUMLをどうやってインストールするのか忘れてしまい，いろいろ調べたのですが，少しハマったポイントがありましたので，そちらを残して置きたいと思います．


# Eclipse側の設定

- 上部のバーの``ヘルプ -> 新規ソフトウェアのインストール``
- 作業対象に``http://download.eclipse.org/releases/luna``を打ち込み，フィルターに``GEF``を指定
- ``グラフィカル編集フレームワーク GEF SDK``を選択し，インストール
![install](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371553/8e03f0a2-396c-ccef-f134-496ae943dfd9.png)

以降手順に従ってインストールを完了させて，再起動してください．


# AmaterasUMLのインストール
[公式ホームページ](http://amateras.osdn.jp/cgi-bin/fswiki/wiki.cgi?page=AmaterasUML)からAmaterasUML_1.3.4.zipをダウンロードし，解凍します．そうすると，以下の3つのjarファイルが入っています．

```
net.java.amateras.umleditor.java_1.3.4.jar
net.java.amateras.umleditor_1.3.4.jar
net.java.amateras.xstream_1.3.4.jar
```

これらを
``/Applications/Eclipse_{version}.app/Contents/Eclipse/dropins/AmaterasModeler/eclipse/plugins``
へコピーします．
ただ，私の場合こちらのディレクトリには以下のファイルが予め含まれていました．

```
net.java.amateras.db_1.0.9.jar
net.java.amateras.umleditor.java_1.3.5.jar
net.java.amateras.umleditor_1.3.5.jar
net.java.amateras.xstream_1.3.4.jar
```
``umleditor``に関するファイルが同じであることと，バージョンが上位であることから，もともとAmaterasUMLは使えるのではと思い，コピーする前にUML図を作成しようと試みてみました．
しかし，cldファイルの作成はできましたがjavaファイルのD&Dでの反映がうまくいきませんでした．

そのため，``umleditor``に関するファイルのみ上書きしました．（一応バックアップはしたほうがいいのかなと思ってしてます．この違いを知っている方がおられましたら教えていただきたいです）
そうすると，無事にcldファイルの作成をjavaファイルのD&Dで作成することができました．

## UML図の作成方法
UML図の作成する場合は，作成したいディレクトリやパッケージなどの中で``新規 -> その他 -> AmaterasUML -> クラス図``でcldファイルの作成した後，任意のjavaファイルをcldファイルのウィンドウへD&Dするとクラス図が自動で生成されます．
複数のjavaファイルを選択してD&Dすれば委譲関係などもわかるようになっています．便利ですね．

# さいごに
いくつかのサイトで書かれていた``/Applications/Eclipse_{version}.app/Contents/Eclipse/dropins``内へ解凍したjarファイルを入れるという点で少し詰まってしまいました．
いつから``AmaterasModelerディレクトリ``があったのか確認していなかったため，最新版のEclipseをインストールした方にはあるかもしれません．その場合，``AmaterasModelerディレクトリ``内にもともとあるjarファイルと置き換えないとUML図が正しく生成できなかったため，注意が必要かもしれません．
久しくUML図を書いていないため，AmaterasUMLを参考に復習したいと思っています．
アジャイル開発についてのまとめ

## 記事を書いた背景
先日つよつよエンジニアの方とお話をさせていただく機会があり、アジャイル開発の話になったのですが、アジャイル開発についての理解が曖昧だったので、調べてまとめてみました。何かご指摘等ありましたらコメントよろしくお願いいたします。

## 開発手法
###### ウォーターフォールとアジャイル
よくアジャイルと比較される開発手法の一つとしてウォーターフォール開発があります。
アジャイル開発を理解するためにもウォーターフォール開発について知っておきましょう。

## ウォーターフォール開発の特徴
ウォーターフォール開発は滝が流れるように上から下に開発を進めていくという開発手法で
企画→設計→実装→テスト
といった流れで開発を進めていきます。
最初に要件を全て決めてしまうので予算やスケジュールの見積もりは立てやすいものの途中で仕様の漏れなどが見つかった場合、前のフェーズに戻るのが困難になります。

## アジャイル開発の特徴
アジャイル開発は企画→設計→実装→テストを細かいスパンで区切って開発を行います。例えば、１週間で機能Aを実装してフィードバックをもらうといったことを行います。
ウォーターフォールとはメリットとデメリットが逆になり、細かいスパンで区切っているので手戻りが容易だが、予算やスケジュールの見積もりが立てづらいといったことが挙げられます。
また、しっかり仕様等を確認しないと軌道がずれていってしまい、当初想定していたプロダクトとは異なったものができてしまうといったことが起こります。

## アジャイルの中の手法

アジャイル開発にもいくつか種類があります。

- スクラム
- エクストリームプログラミング
- ユーザー機能駆動開発

今回は特に有名なスクラム開発について書いていきます。

## スクラム開発
スクラム開発の進め方は以下の通りです。

- プロダクトへの要望を優先順位ごとに並べ替えその順で機能を作る
- 固定の短い期間（1から4週間ほど）で区切る
- プロジェクトの進め方に問題がないか毎日確認し合う
- 作っている機能が正しいか定期的に確認の場を設ける

また特徴は以下の通りです。

- 自立的なチームづくりができる。・・・リーダーのような立場がなく各個人が主体性を持って取り組むため
- 問題の検知が早い・・・短いサイクルで回し、報告も毎日行うため
- 軌道修正が早めにできる。・・・短いサイクルで回すため

## 役割
役割は主に3つです。

- プロダクトオーナー
- スクラムマスター
- 開発メンバー

## それぞれの特徴
#### プロダクトオーナー
プロダクトの責任者
開発は行わずスケジュールや予算の管理をする
チームに対して指示はしない、あくまでもプロダクトバックログの編集をして情報を流すだけ

#### スクラムマスター
チームの調整役
スクラムのルールや進め方をプロダクトオーナー、開発メンバーに説明する。
タスクの調整、顧客やプロダクトオーナーからの無理な要望から開発メンバーを守る
専任の場合もあるし開発メンバーと兼任の場合もある
障害物をリスト化するなどして洗い出し取り除いていく

#### 開発メンバー
設計、ドキュメント作成、コーディング、テスト、運用といった一通りのスキルを持っていることが求められる
メンバーは皆平等であり、上下関係はない

## 用語
スクラム開発では様々な用語を使います。

#### バックログ
プロダクトの要望をまとめたリスト、プロダクトオーナーが作ることもあるし開発メンバーの意見が反映されることもある。

#### スプリントプランニングミーティング
バックログの内容をもとにスプリント内で何を作るか、どのくらい作るかを決定する。工数の見積もりを行い、作業を割り振る

#### デイリースクラム
状況共有のためのミーティング、いわゆる朝会
昨日やったこと、今日やること、障害になっていることを話し合う。
細かい仕様等の話し合いは避け、（別で時間を設ける）15分くらいで終わるようにする。
スクラムの理想のチームは3人から10人ほどなので一人1分話したとしても15分以上はかからないのが普通

#### スプリントレビュー
プロダクトオーナーが成果物を確認する。
必ず動くアプリを使って確認する。

#### スプリントレトロスペクティブ
振り返りを行う良かった点や改善すべき点を話し合う

### ウォーターフォールとアジャイルどちらがいいか
結論、両者のどちらが優れているといったことはありません。
プロダクトによって都度選んでいくといった形になります。
最近はネイティブアプリの開発など技術が早い物に関してはアジャイルが採用されることが多いようです。


### 参考

[アジャイル開発とウォーターフォール開発の違い](https://backlog.com/ja/blog/what-is-agile-and-waterfall/)
[5分でわかるスクラムの基本](https://www.atmarkit.co.jp/ait/articles/1208/07/news128.html)
【Active Storage】ファイルアップロード時のバリデーション設定

# 概要
Active Storageにはデフォルトのバリデーションがないため、自前でバリデーション設定をした時のことを備忘録として記録します。

# 環境
・ruby '2.5.7'
・rails '5.2.3'

# 過程
## 1.準備
Active Storageを導入するために以下のコマンドを実行します。

```ターミナル
$ rails active_storage:install
``` 
以下の２つのテーブルを作成するマイグレーションファイルが作成されます。
・active_storage_attachments
・active_storage_blobs

rails db:migrateしてテーブルを作成します。

```ターミナル
$ rails db:migrate
``` 

## 2.モデルへの関連付け
モデルへの関連付けをしていきます。
ここでは、Userモデルに複数のプロフィール画像を設定する場合とします。

```models/user.rb
class User < ApplicationRecord
  has_many_attached :avatars
end
``` 
``:avatars``はファイルの呼び名で、``:photos``、``:images``などファイルの用途に合わせて好きなものが指定出来ます。Userモデルに画像用のカラムを用意する必要はありません。

## 3.バリデーションの設定
Userモデルにバリデーションの設定をしていきます。
ここでは、次の３つの設定をしていきます。

・avatar_type
アップロード出来るファイル形式を指定します。

・avatar_size
アップロード出来る１ファイルの大きさ（容量）を指定します。

・avatar_length
アップロード出来るファイルの数を指定します。

```models/user.rb
class User < ApplicationRecord
（省略）
  validate :avatar_type, :avatar_size, :avatar_length

  private

  def avatar_type
    avatars.each do |avatar|
      if !avatar.blob.content_type.in?(%('image/jpeg image/png'))
        avatar.purge
        errors.add(:avatars, 'はjpegまたはpng形式でアップロードしてください')
      end
    end
  end

  def avatar_size
    avatars.each do |avatar|
      if avatar.blob.byte_size > 5.megabytes
        avatar.purge
        errors.add(:avatars, "は1つのファイル5MB以内にしてください")
      end
    end
  end

  def avatar_length
    if avatars.length > 4
      avatars.purge
      errors.add(:avatars, "は4枚以内にしてください")
    end
  end
end
```
ちなみに、``avatars.purge``で一時データを削除しています。
他の入力項目でバリデーションエラーが起きてしまうと、Rails5.2系〜6.0系以前ではモデルのインスタンスのattributeに代入した時点で、アップロードしたファイルがストレージに保存されてしまい、その結果として、blobにエラー用の一時データが溜まってしまう可能性があるためです。
（ただ、Rails6.0へのアップデートでActive Storageの機能変更があり、saveメソッドが実行された後に、ストレージに保存される仕様に変更されたので、6.0以降であれば不要です）

# 結果
これで、次のようにバリデーションの設定が出来ました！
![200919_バリデーションエラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611686/b833926e-dcd4-2e51-0c15-5aaa97481097.png)


# 参考
[ActiveStorageがCarrierWaveの代用として使えるか考える](https://www.fundely.co.jp/blog/tech/2019/12/11/180024/)
[Rails5 Active Storageを使って画像アップロード機能を実装する](http://midnight-engineering.hatenadiary.jp/entry/2018/09/24/012139)
Git基本事項

# 用語(編集途中)

### コミット
ユーザーが任意のタイミングで記録を保存する操作．
### リポジトリ
コミットを貯めておく場所．

すでにGitで管理されているプロジェクトの開発に参加する場合はリポジトリをコピー（クローン）して使う．

### ワークツリー
変更するファイルを保持する場所．
### ステージングエリア
コミットするファイルを登録する場所．
### Gitディレクトリ
コミットを格納する場所．

# GitHubにあげるまでの手順
今回はGitのインストールやGitHubのアカウント作成などの初期設定の説明は省く．

あらかじめ登録してある人が新しいプロジェクトを始めるという状況を想定．

### リモートリポジトリをローカルへ複製する or ローカルで作成したリポジトリをリモートへ反映させる

  今回はリモート側のリポジトリとして先にGitHubへリポジトリを作成し，それをローカルへ複製するという方法で進める．
 
  ```
    $ git clone GitHubのリポジトリURL
   ```
    
  
   GitHubのファイルが複製されるので cd コマンドでコピーしたディレクトリに移動する．

### 作業用ブランチを作成する(飛ばしてもGitHubにコードをアップすることはできる)
  
Gitではbranchを作成し作業を行い，完成したらmasterにmergeするのが基本なのでここでbranchを作成する．

   以下のコマンドで現在いるbranchが確認できる．
    
```bash

    $ git branch
    * master
 ```

ブランチの作成には以下のコマンドを使う．
 
  
 ```bash
    $ git branch ブランチ名
 ```

  例）
 
```
    $ git branch work
 ```

   ブランチを作成したら以下のコマンドでブランチを切り替える

   ```
    $ git checkout ブランチ名
   ```

   例）
  
  ```bash
    $ git checkout work
   ```
   
 ブランチを切り替えたらファイルの編集を行い，バージョンアップを行う．


    
### コミットをする
    
    
書き換えたファイルはリモートリポジトリに保存しておきたいので以下のコマンドを実行する．
  
 ```bash
    $ git add ファイル名
   ```
  
 このコマンドで指定したファイルがコミット対象になる．
    
   今回はフォルダにあるファイルを全てコミットする予定なので以下のコマンドを実行する．
   
 ```bash
    $ git add .
  ```

   これでコミットの準備ができたので以下のコマンドでコミットを行う．
  
 ```bash
    $ git commit -m 'コメント’
  ```
  
  これでコミットは完了．（-mを付けなかった場合はvi上でコメントの入力を求められる．）

### ブランチをマージする
    
    
今回はmasterにworkを取り込む．
    
    
まずはmasterブランチに移動する．
   
 ```bash
    $ git checkout master
    Switched to branch 'master'
    Your branch is up to date with 'origin/master'.
   ```
  
  このまま編集したファイルを開いてもブランチを切り替えているので変更が反映されていない．

   例）
  
 ```
    $ git merge work
    Updating ac63b89..3eefb35
    Fast-forward
    README.md | 1 +
    1 file changed, 1 insertion(+)
   ```
  
  このコマンドでマージが成功すると編集した内容がmasterに反映される．

### リモートにpushをする
    
   いよいよ変更内容をGItHubに反映させる．

```
　　$ git push
```
このコマンドでGitHubに反映させることができる．
    
   例）
   
 ```bash
    $ git push origin work
    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 338 bytes | 338.00 KiB/s, done.
    Total 3 (delta 1), reused 0 (delta 0)
    remote: Resolving deltas: 100% (1/1), completed with 1 local object.
    remote: 
    remote: Create a pull request for 'work' on GitHub by visiting:
    remote:      GitHubのURL
    remote: 
    To GitHubのURL
    * [new branch]      work -> work
   ```
   
 これでGitHubにちゃんと反映されていたら成功！
    
### おさらい

    
大事なのは以下のコマンドでこの流れは絶対．
   
 ```
    $ git clone URL   # 最初の一回だけ
    $ git add .
    $ git commit -m 'コメント'
    $ git push
   ```
### 知っていると便利なコマンド


   ```
    $ git status
   ```
    
このコマンドで今の状態を確認できる．

   
 慣れるまでは何かを実行するたびにこのコマンドで確認した方がいいかも．
 
  ```
    $ git branch
   ```
   
 このコマンドで現在どのブランチにいるのかを確認できる．

### 不十分な点

   - 開発はGitHub→Gitという流れよりローカル→リモートという流れが自然？
   - ブランチ切ったままファイルの移動をしてしまった場合どうなっちゃう？
   - 後からフォルダに違うディレクトリ にあったファイルを持ってきた場合どうやったらコミット対象になってくれるのか
おもむろにPowerAppsで遊んでみる

GAFAMが本格的に乗り込んできた（いや前からか）気がするので，
エンジニアの端くれとしてGAFAMの動向は追わなければ，と思い立ったが吉日。

OfficeのおまけでついてきたPower AutomateからiPaaSにハマり，
**これからの時代はローコード・ノーコードだ**，とPowerApps+CDSで遊び始めました。

リレーションの張り方とか独特で右往左往するものの，やはり面白い。
CDSで親子関係のエンティティをいくつか作成してデータを登録，
[データから開始]でPowerAppsが良い感じでアプリを作ってくれる。

CDSのメタデータ読み込んで勝手にアプリを構築するのすげぇ！と思ったが，
親テーブルから子テーブルの参照の組み方が良くわからない。
Browse, Detail, EditとCRUD土台を作ってくれるが，
Detail画面で

```Ruby
BrowseGallery1.Selected.[子テーブル].[カラム名]
```
なんてやったら出てくるかなと思ったら，そうは問屋が卸さなかった。
子テーブルの対応したカラムが複数レコードあるんだから当たり前か。
MSのリファレンスを眺めてたら，興味深い記述を発見。

>1 対多の関連付けの場合、検索フィールドは現在選択したエンティティ上ではなく、関連エンティティ上で作成されます。 現在のエンティティで検索が必要な場合は、多対 1 の関連付けを作成してください。
>https://docs.microsoft.com/ja-jp/powerapps/maker/common-data-service/data-platform-entity-lookup

これを見て，子テーブルで[データから開始]すればいいのか！と思い作成したが，
そういう訳でもないらしい。
再びリファレンス沼にハマっていたら，それっぽいドキュメントが。

>キャンバス アプリでのレコード参照とポリモーフィック検索について
>https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/working-with-references

リファレンス通りにやったら，おお，それっぽいのができた。
あとはCUDができれば十分だが，まだまだ道のりは遠そう。
公式ウェビナー見て頑張ってみよう…。
JPAで複数のOneToManyでjoin fetchするとMultipleBagFetchException

JPAで```@OneToMany```を複数定義して両者を```join fetch```で取得しようとすると、下記のような実行時例外になることがある。

```java
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [jpa.sample2.Tweet.reTweets, jpa.sample2.Tweet.favorites]
	at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:76) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
	at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:110) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
```

# 状況
説明用のスキーマとして、一つのtweetに複数のReTweetと複数のFavorite、というテーブルを想定する。javaのentityとしては以下のような感じ。

```java
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Data
public class Tweet {
	@Id
	Long id;

	String value;

	@OneToMany
	@JoinColumn(name = "tweetId")
	List<ReTweet> reTweets;

	@OneToMany
	@JoinColumn(name = "tweetId")
	List<Favorite> favorites;
}
```

```java
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Data
public class ReTweet {
	@Id
	Long id;
	Long tweetId;
	String value;
}
```

```java
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Data
public class Favorite {
	@Id
	Long id;
	Long tweetId;
	String value;
}
```

JPQLは以下のように```join fetch```を2回使用する。

```java
@Repository
public interface TweetRepository extends JpaRepository<Tweet, Long>  {	
	@Query("select distinct t from Tweet t "
			+ " left join fetch t.reTweets "
			+ " left join fetch t.favorites"
			+ " order by t.id")
	List<Tweet> list2();
}
```

こうすると上記の実行時例外となる。

# 解決策
このケースの場合は```List```を```Set```に変えればよい。

```java
	@OneToMany
	@JoinColumn(name = "tweetId")
	Set<ReTweet> reTweets;

	@OneToMany
	@JoinColumn(name = "tweetId")
	Set<Favorite> favorites;
```

または```Map```でも良い。

```java
	@OneToMany
	@JoinColumn(name = "tweetId")
	Map<Long, ReTweet> reTweets;

	@OneToMany
	@JoinColumn(name = "tweetId")
	Map<Long, Favorite> favorites;
```

もしくは、単一のJPQLを諦めて複数に分割する、というやり方も考えられる。

```java
	@Query("select distinct t from Tweet t "
			+ " left join fetch t.reTweets "
			+ " order by t.id")
	List<Tweet> list3();
	
	@Query("select distinct t from Tweet t "
			+ " left join fetch t.favorites"
			+ " order by t.id")
	List<Tweet> list4();
```
[R][Python]複数のzipファイル内の複数csvファイルを読み込むメモ

# はじめに
あるフォルダ下にある複数のzipファイルに格納された、複数のcsvファイルを一気に読み込みたい、というシーンに出会ったのでメモ。

# フォルダ構成例
このようなフォルダ構成になっているとき、各zipファイルの中にあるcsvファイルをまとめて一気に読み込んで、listに格納してしまいたい。

```
input/
  　 ┣　zip_files/
   　┃         ┣ test1.zip/
  　 ┃         ┃       　　┣  test1_1.csv
  　 ┃         ┃       　　┣  test1_2.csv
  　 ┃         ┃            ...
   　┃         ┣ test2.zip/
  　 ┃         ┃       　　┣  test2_1.csv
  　 ┃         ┃       　　┣  test2_2.csv
  　 ┃                      ...

```

# Rコード
unzip, unz関数でzipを開かずに中のファイルにアクセスできる。

```{r}
library(tidyverse)
library(data.table)

zip_list <- list.files("zip_files")

# function of read csv files in zip files 
get_csv <- function(zip_list){  
  
  csv_list <- list()
  zip_lists <- list()
  
  # Loop through the list of files
  for(j in 1:length(zip_list)) { 
    
    # Create list of files
    file <- unzip(paste0("zip_files/", zip_list[j]), list = TRUE) 
    
    for(i in 1:length(file)){
      # If a file is a csv file, unzip it and read the data
      if(grepl("csv", file[i,1])) {

        print(paste0('reading following file...', file[i,1]))
        csv_files <- read_csv(unz(paste0("zip_files/", zip_list[j]), file[i,1]), 
                              col_names=TRUE)
        ########################
        # Add Some process.
        ########################
        csv_list[[i]] <- csv_files
        zip_lists[[j]] <- csv_list
      }
    }
  }
  return(zip_lists)
}

system.time(csvs <- get_csv(zip_list))
```

# Pythonコード
zipfileモジュールでzipファイルを解凍せずに内部にアクセスできる。

```{Python}
import os
import zipfile
import glob
import pandas as pd
import time

df_list = list()
start = time.time()

for i, zips in enumerate(zip_list):
    zip_f = zipfile.ZipFile(zips)  
    file_list = zip_f.namelist() # file names of csv files in zip
    
    for j, files in enumerate(file_list):
        print('reading following file...' + zips + '/' + files)
        
        df = pd.read_csv(zip_f.open(files))
        ########################
        # Add Some process.
        # If use i and j too.
        ########################
        df_list.append(df)

elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
```
【Rails】Action Cableについて

## Action Cableが誕生した背景
ユーザーの入力なしに、最新の情報をWebに表示する「Realtime性」をもつリッチな体験を実現するために誕生しました。

Action Cableは、RailsのRESTとWebSocketのシームレスな統合です。
例えばAction Cableを使うことで、みなさんが使っているようなリアルタイムチャットアプリを
作成することもできます。 

![スクリーンショット 2020-09-19 14.53.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564392/05a5fc8e-92ea-00d0-6847-cc3bff1413e3.png)

## 用語について

### Websocket
・Web上でクライアント、サーバ間の双方向通信を実現するための通信規格
・送信できるデータはテキストまたはバイナリ
・HTTPとは別のプロトコルなのでCookieは送られない
・通信が確立した後はクライアント、サーバーどちらからでもメッセージを送ることが可能

### Connection
・Websocketとしてのコネクションを表すクラス
・Websocketとして通信が確立した時点でインスタンスが生成される
・開始時のリクエストはふつうのHTTPなのでCookieも送られる
・認証処理はこのクラス内に記述

### Consumer
・Websocketコネクションのクライアント（ブラウザなど）
・同じブラウザの異なるタブは完全に別のクライアントとして扱う

## サーバー側(Rails)の構成要素
### Conection
コネクションは、ApplicationCable::Connectionのインスタンスです。
このクラスでは、受信したコネクションを承認し、ユーザーを特定できた場合にコネクションを確立します。
そのための仕組みとして、identified_byを使います。
identified_byはコネクションIDであり、後で特定のコネクションを見つけるときに利用できます。

```ruby
# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    private
      def find_verified_user
        if verified_user = User.find_by(id: cookies.encrypted[:user_id])
          verified_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

```

### Channel
チャネルはMVCでいうコントローラーの役割を担います。

### Subscription
コンシューマーは、チャネルを購読するサブスクライバ側(Subscriber)の役割を果たします。
そして、コンシューマーのコネクションはサブスクリプション（Subscription: 購読）と呼ばれます。

```ruby
# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  # コンシューマーがこのチャネルのサブスクライバ側になると
  # このコードが呼び出される
  def subscribed
  end
end
```

## 例1. ユーザーアピアランスの表示
これはユーザーがオンラインかどうかという情報を追跡するチャネルの例が以下です（オンラインユーザーの横に緑の点を表示する機能を作成する場合などに便利）。

まずは、サーバー側のアピアランスチャンネルを作成します。

```ruby
# app/channels/appearance_channel.rb
class AppearanceChannel < ApplicationCable::Channel
  def subscribed
    current_user.appear
  end

  def unsubscribed
    current_user.disappear
  end

  def appear(data)
    current_user.appear(on: data['appearing_on'])
  end

  def away
    current_user.away
  end
end
```

サブスクリプションが開始されると、subscribedコールバックがトリガーされ、
そのユーザーがオンラインであることを示します。

## 例2. 新しいWeb通知を受信する
Websocketコネクションを使って、サーバーからクライアント側の機能をリモート実行させます。

このWeb通知チャネルは、正しいストリームにブロードキャストを行ったときに、クライアント側でWeb通知を表示します。

サーバー側のWeb通知チャネルは以下です。

```ruby
# app/channels/web_notifications_channel.rb
class WebNotificationsChannel < ApplicationCable::Channel
  def subscribed
    stream_for current_user
  end
end
```

アプリケーションのどこからでも、web通知チャネルのインスタンスにコンテンツをブロードキャストできます。

```ruby
# このコードはアプリケーションのどこか（NewCommentJob あたり）で呼び出される
WebNotificationsChannel.broadcast_to(
  current_user,
  title: 'New things!',
  body: 'All the news fit to print'
)
```

## 参考
[Railsガイド](https://railsguides.jp/action_cable_overview.html#%E3%83%AF%E3%83%BC%E3%82%AB%E3%83%BC%E3%83%97%E3%83%BC%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A)
[描いて理解する Action Cable]
(https://qiita.com/ksugimori/items/d5f4630858eeb56d9da5)
n番目に新しいファイルをvimで開く

# 目的
複数のlogファイルの最新をvimで開く方法を書きました。

[もっとも新しいファイルをviで開くbashのalias](https://qiita.com/Woodie/items/0f3963bf2ac95c71829e)

欲が出てn番目の新しいファイルも開きたいときはどうしましょうか？

## 参考

[bashで引数つきのエイリアスを設定する](https://hacknote.jp/archives/8043/)

## 考えかた
引数を渡したいので関数で書きます。

```{bash}
$ tail ~/.bashrc
~~
# 引数の番号の最新をvimで開く
function vl(){
	[ $# -eq 0 ] && command vim $( ls -t | sed -n 1p)
	[ $# -ne 0 ] && command vim $( ls -t | sed -n $1p )
}

$ vl 3 #<- これで３番目に新しいファイルが開きます。
```
## 説明
引数の数(`$#`)で処理を変えます。引数がなければ`sed` で1行目を表示します。引数があれば`sed`で１番目の引数の中身を展開します。`vl`という関数を定義するのですが、`ls -t`で時間が新しい順に表示させて、`sed`で`$1`番目のファイルを表示します。それを`vim`で受け取ります。参考によると`command`がないと

>内部で用いられているcommandは関数やエイリアス以外のコマンドを優先して実行するためのコマンドです。

だそうです。
様々な環境で動くかなんていうのは調べていないですが、ContOS7ではOKでした。どなたかのお役に立てると嬉しいです。
訓練データとテストデータ（X_train, y_train, X_test, y_test）②

前回の①に続けて、少し実践的な訓練データ・テストデータの分け方をしていきます。

まずデータを用意します。

今度は変数 x が2つあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725082/b44d1010-7735-ee5d-f77e-bd4db83c2c70.png)
このように機械学習では、変数 x が2つ以上あるとき
それらを1つにまとめて大文字 $\mathbf{X}$ として扱っていきます。

次に、訓練データとテストデータに分けます。

訓練データ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725082/94ffaba5-1614-5a82-d93d-58d6ddbbf7b4.png)
テストデータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725082/c650c057-28a6-dd0c-8247-ae5a5e5de9dd.png)
そして訓練データからモデル式を作成していきます。
これを最小二乗法というもので計算すると、下記のように求まります。

$$y=0.9+2x_1+2.0\times10^{-16}x_2$$

そしてこれをテストデータに当てはめていきます。

$$y_{pred}=0.9+2x_{1_{test}}+2.0\times10^{-16}x_{2_{test}}=9,11$$ $$y_{test}=8,10$$

上記のことから、正解データの y_test に対して
自分が予測した y_pred は、おおよそ合っていることが分かりました。

$y$ に対して $x$ が2つ以上ある場合には
基本的に、訓練データとテストデータを上記のように考えていきます。

実際の機械学習では、今回のようなデータに対して
y を家賃、x1, x2 はそれを構成する要素（駅徒歩・築年数など）として
データの分析を進めています。

また、前回の記事①と今回の記事②は
どちらとも線形回帰という手法を行っておりますので
近いうちに、また投稿させていただければと思います。
Node.jsの文字列・オブジェクト⇔クエリ文字列への変換

## 利用するライブラリ

```
var qs = require("qs");
var querystring = require('querystring');

console.log(qs)
⇒{ stringify: [Function], parse: [Function] }

console.log(querystring )
⇒{
  　unescapeBuffer: [Function: unescapeBuffer],
  　unescape: [Function: qsUnescape],
  　escape: [Function: qsEscape],
  　stringify: [Function: stringify],
  　encode: [Function: stringify],
  　parse: [Function: parse],
  　decode: [Function: parse]
　}
```

## 文字列・オブジェクト⇒クエリ文字列
#### qs.stringify(object, [options]);
第1引数にオブジェクトを渡す。

```
const form_data_qs = qs.stringify({
　　grant_type: 'authorization_code',
　　code: 'code',
　　redirect_uri: 'redirect_uri'
});

console.log(form_data_qs)
⇒grant_type=authorization_code&code=code&redirect_uri=redirect_uri
```

#### querystring.stringify(obj[, sep[, eq[, options]]]);
第1引数にオブジェクトを渡す。

```
const form_data_querystring = querystring.stringify({
　　grant_type: 'authorization_code',
　　code: 'code',
　　redirect_uri: 'redirect_uri'
});

console.log(form_data_querystring)
⇒grant_type=authorization_code&code=code&redirect_uri=redirect_uri
```

#### querystring.escape(str)
第1引数に文字列を渡す。

```
const str = querystring.escape('a:b?c$d*1')

console.log(str)
⇒a%3Ab%3Fc%24d*1
```

## クエリ文字列⇒文字列・オブジェクト
#### qs.parse(string, [options]);
第1引数に文字列を渡す。

```
const form_data_qs = qs.parse('grant_type=authorization_code&code=code&redirect_uri=redirect_uri')

console.log(form_data_qs)
⇒{
　　grant_type: 'authorization_code',
　　code: 'code',
　　redirect_uri: 'redirect_uri'
}
```
#### querystring.parse(str[, sep[, eq[, options]]])
第1引数に文字列を渡す。

```
const form_data_querystring = 'grant_type=authorization_code&code=code&redirect_uri=redirect_uri'

console.log(form_data_querystring)
⇒{
　　grant_type: 'authorization_code',
　　code: 'code',
　　redirect_uri: 'redirect_uri'
}

```
M5Atom MatrixのArduino IDEでの書き込みを試す #m5stack #m5atom #ヒーローズリーグ


ライブラリなどは入れた後の話でシンプルなコードをメモ

## 左上のLEDをつける

```ino
#include "M5Atom.h"

void setup(){
    M5.begin(true, false, true);
}

void loop(){
    M5.update();
    
    M5.dis.drawpix(0, 0xf00000);
}
```

## LEDを全てつける

```ino
#include "M5Atom.h"

void setup(){
    M5.begin(true, false, true);
}

void loop(){
    M5.update();

	for (int i = 0; i < NUM_LEDS; i++){
    	M5.dis.drawpix(i, 0xf00000); //緑
   }
}
```

## ボタン押してLEDを切り替え

赤と緑が切り替わります。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ここボタンとして押していいんですなぁというのが今日の学び<br><br>ちょっと壊しそうで怖い <a href="https://twitter.com/hashtag/%E3%83%92%E3%83%BC%E3%83%AD%E3%83%BC%E3%82%BA%E3%83%AA%E3%83%BC%E3%82%B0?src=hash&amp;ref_src=twsrc%5Etfw">#ヒーローズリーグ</a> <a href="https://t.co/t5WklE9Pig">pic.twitter.com/t5WklE9Pig</a></p>&mdash; 菅原のびすけ (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1307258745148203008?ref_src=twsrc%5Etfw">September 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


```ino
#include "M5Atom.h"

int flag = true; //ボタン管理フラグ

void setup(){
    M5.begin(true, false, true);
}

void loop(){
    M5.update();
    
    if (M5.Btn.wasReleased()) {
      
      if(flag){
        Serial.println("Button pressed 1");
        
        for (int i = 0; i < NUM_LEDS; i++){
           M5.dis.drawpix(i, 0xf00000); //緑
        }

        flag = false;
      }else{
        Serial.println("Button pressed 2");
        
        for (int i = 0; i < NUM_LEDS; i++){
           M5.dis.drawpix(i, 0x00f000); //赤
        }

        flag = true;
      }
      
    }
}
```


## メモ: M5.dis.fillpixの使い方がいまいち分からない

`M5.dis.fillpix(0xf00000);`こういう指定じゃないっぽいんですよね。うーむ。

`has no member named 'fillpix'`的なエラーが出て解決できてない。

```
M5.dis.fillpix(0xf00000);
              ^
exit status 1
'class LED_Display' has no member named 'fillpix'
```
「〜したい時」に便利なPHPの関数を初心者でも頭に入りやすいようにまとめたい（常時追記）

#はじめに
プログラミングをしている時、特に問題を解く時などに個人的に覚えておきたいPHPの関数をまとめました。「〜したい！」という欲求から関数を探すという逆引き的な使い方ができればと思っています。

投稿時点（2020/9/19）ではまだ数が少ないですが、今後追記していきます。

### 「読み方」を併記する理由
各関数に読み方を表記しています。なぜなら、何かを覚えられない時ってその名前がわからないからって気がしているからです。読み方がわかるということは、その意味も頭に入ってきやすいです。例えば、レンって言われてもピンと来ませんが、レングスって言われるとわかりやすかったりしませんか（英語わかる方なら...）？興味ない人の名前よりも好きな人の名前は覚えられますよね。

読み方は、個人的にこれだと頭に入ってきやすいなと思ったもので、正式なものではありません。（てか正式な読み方ってあるんですかね？）
#文字列系
###◉検索対象の文字列の中に特定の文字があるか知りたい
####`strpos(検索範囲, 探すもの)`
読み方：ストリングポジション

```php
<?php
$str = "qiita";

$t = strpos($str, "t");
var_dump($t);//int(3)

$k = strpos($str, "c");
var_dump($k);//bool(false)
?>
```
###◉文字列を置き換える、置換する
####`str_replace(探したい文字, 置き換えたい文字, 検索範囲)`
読み方：ストリング　リプレイス

```php
<?php
$str = "qiita";
echo str_replace("q", "k", $str); //kiita
?>
```
###◉文字列を分解したり、切り出したい
####`substr(検査したい文字列, 何個めから, 何文字)`
読み方：サブストリング

substring（サブストリング）とは和訳すると**部分文字列**です。サブ（sub）って日本人感覚だと、「副」ってイメージが強いですが、辞書によると「分割、細分」という意味もあるらしいです。[TECHACADEMY記事](https://techacademy.jp/magazine/11430)もわかりやすいですね。

```php
<?php
$en = "Kanda";
$jp = "かんだ";
echo substr($en, 1, 3); //and  第２パラメータは0からなのでご注意
echo substr($jp, 1, 2); //ん  日本語は1文字=2バイトなのでご注意
?>
```
###◉文字列を配列に変換したい
####`str_split(変換したい文字列, 何文字ずつ分割するか)`
読み方：ストリング　スプリット
スプリットは「分割する」って意味なので、文字列を分裂させるっていう命名ですね。

```php
<?php
$num = "LArc-en-Ciel";
$array = str_split($num, 4); //第２パラメータを省略すると１バイトずつになる
print_r($array);
//Array
//(
//    [0] => LArc
//    [1] => -en-
//    [2] => Ciel
//)
?>
```
#数えたい系
###◉文字数を数える
####`strlen(検査対象)`
読み方：ストリング　レングス
機能：対象の文字列の文字数を数える

```php
<?php
$longestword = 'pneumonoulttamicroscopicsilicovolcanoconiosis'; //一番長い英単語らしい
echo strlen($longestword); //45
?>
```
###◉検索対象の文字列の中に特定の文字が何回出てくるか数えたい
####[`substr_count(検査範囲, 探しているもの)`](https://www.php.net/manual/ja/function.substr-count.php)
読み方：サブストリング カウント

注：似たような関数で[`mb_substr_count()マルチバイト サブストリング カウント`](https://www.php.net/manual/ja/function.mb-substr-count.php)があります。マルチバイトとは、１文字を2バイト以上で表す文字のことで、日本語などがそうですね。

```php
<?php
$str = "L'Arc-en-Ciel";
echo substr_count($str, 'e'); //2
echo substr_count($str, 'c'); //1　大文字のCはカウントされない
?>
```

###◉配列の中に特定の値（value）がいくつあるか知りたい
####`array_count_values(検査したい配列)`
読み方：アレイ　カウント　バリューズ

```php
<?php
$str = ["a", "d", "d", "r", "e", "s", "s"];
$array = array_count_values($str);
var_dump($array); //結果は左下に
/* array(5) {
  ["a"] => int(1)
  ["d"] => int(2)
  ["r"] => int(1)
  ["e"] => int(1)
  ["s"] => int(2)
} */

echo $array["d"]; //2
?>
```

#算数系
###◉累乗（2乗とか3乗とか）の計算
####`pow(底, 指数)`
（算数の復習）「2の3乗」と言った時、2が底、3乗が指数にあたる。
読み方：パウ（なんでパウ？）

```php
<?php
echo pow(2, 3); //8
echo 2 ** 3; //これも上と同じこと
?>
```
#適宜ブラッシュアップしてきます
投稿時点（2020/9/19）ではまだ数が少ないですが、今後追記していきます。
ブロードキャストストーム


応用情報技術者平成29年春期 午前35

ブロードキャストストームの説明として，適切なものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/37fb110e-e203-a044-51ee-365c5f5fb123.png)


１、ブロードキャストストームは、
ループ状に接続されているネットワークにおいて、同一のブロードキャストフレームが増幅しながら永遠にネットワーク内を回り続ける現象です。

ネットワークスイッチは
　・ブロードキャストフレームを受け取ると、
　・そのフレームをコピーし、
　・受信ポート以外の全てのポートから送出します。

このときネットワーク内に
　・ループ状の構成が含まれていると、
　・いずれはスイッチ自身が送信したフレームを自分で受信し、
　・再び全てのポートに送信してしまうことになります。

このように
　・増幅したブロードキャストフレームは、
　・やがてネットワークの帯域を圧迫しネットワーク障害をもたらします。

これが「ブロードキャストストーム」です。


２、輻輳(ふくそう)の説明
1台のブロードバンドルータに接続するPCの数が多過ぎることによって，インターネットへのアクセスが遅くなること

　・輻輳（ふくそう）とは、物が1か所に集中し混雑する様態をいう。

３、同じIPアドレス
IPアドレスを重複して割り当ててしまうことによって，通信パケットが正しい相手に到達せずに，再送が頻繁に発生すること
IPアドレス重複は設定時に自動でチェックされるため記述のようなことは発生しません。もしあえて同じIPアドレスを設定したとしても、通信パケットはいずれかのノードに到達します。どちらに届くかはARPテーブルの状態次第です。

４、ブロードキャストフレームの説明
イーサネットフレームの宛先MACアドレスがFF-FF-FF-FF-FF-FFで送信され，LANに接続した全てのPCが受信してしまうこと
ブロードキャストフレームは同じネットワーク内の端末に同じ内容を一斉配信するために使われ、それ自体は不具合というわけではありません。


参照：
https://www.ap-siken.com/kakomon/29_haru/q35.html
ImageNetのILSVRCは2017年までなので、それ以降の進展をグラフに追加してみた

#目的
ImageNetのILSVRCは2017年までなので、それ以降の進展をグラフに追加してみた。
2018、2019、2020と順調なのかどうかが知りたかった。

それ以降の進展は、
以下のサイトのデータを引用。
https://paperswithcode.com/sota/image-classification-on-imagenet

#結果


![imagenet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/812a1974-f133-f2ec-4a99-f20ab1a66d59.png)

#補足
もう、そもそものデータの品位が問題になるレベルになっているという観点は、以下など。
(https://arxiv.org/abs/2006.07159)
Are we done with ImageNet?

#まとめ
特にありません。
あまり専門的に追及したものではありません。
が、ディープラーニングの進展の図が、
2017年までの数値で示されていることに、そろそろ、抵抗感が出ると思い、
グラフを書きました。