OmniAICreator/Qiita-1.07M huggingface dataset:
plunkerでplaycanvas その2

#概要

plunkerでplaycanvasやってみた。
gltfをアニメーション表示してみた。

#参考にしたページ。

https://github.com/cx20/jsdo.it-archives/tree/master/tag/playcanvas

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/3ee9ca3e-931f-fa22-50a0-226e8a4d6b1d.png)



#サンプルコード

```
var canvas = document.getElementById("application-canvas");
var app = new pc.Application(canvas, {
});
app.start();
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);
var gltf;
var url = "https://rawcdn.githack.com/pissang/claygl/c4f45119/example/assets/models/SambaDancing/SambaDancing.gltf";
var filename = url.split('/').pop();
app.assets.loadFromUrlAndFilename(url, filename, "container", function(err, asset) {
  var resource = asset.resource;
  gltf = new pc.Entity('gltf');
  gltf.addComponent('model', {
    type: "asset",
    asset: resource.model
  });
  if (resource.animations && resource.animations.length > 0) 
  {
    gltf.addComponent('animation', {
      assets: resource.animations.map(function(asset) {
        return asset.id;
      }),
      speed: 1
    });
  }
  app.root.addChild(gltf);
  if (camera) 
  {
    var orbitCamera = camera.script.orbitCamera;
    orbitCamera.focus(gltf);
    var distance = orbitCamera.distance;
    camera.camera.nearClip = distance / 10;
    camera.camera.farClip = distance * 10;
  }
});
var camera = new pc.Entity();
camera.addComponent('camera', {
  clearColor: new pc.Color(0.1, 0.2, 0.3)
});
var light = new pc.Entity();
light.addComponent('light');
app.root.addChild(camera);
app.root.addChild(light);
camera.setPosition(0, 0, 300);
camera.lookAt(0, 100, 0);
light.setEulerAngles(45, 0, 0);
var Rotate = pc.createScript('rotate');
Rotate.prototype.update = function(dt) {
  this.entity.rotate(10 * dt, 20 * dt, 30 * dt);
};
cube.addComponent('script');
cube.script.create('rotate');
window.addEventListener('resize', function() {
  app.resizeCanvas(canvas.width, canvas.height);
});




```



#成果物

https://embed.plnkr.co/plunk/X2xcgR1SoSrCIrcV

以上。
plunkerでplaycanvas

#概要

plunkerでplaycanvasやってみた。
プリミティブを表示してみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/62726b4a-fc03-8e8e-6798-1cb382a175cc.png)

#サンプルコード

```
var canvas = document.getElementById("application-canvas");
var app = new pc.Application(canvas, {
});
app.start();
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);
var cube = new pc.Entity();
cube.addComponent('model', {
  //type: "box"
  //type: "sphere"
  type: "capsule"
  //type: "cone"
  //type: "cylinder"
  //type: "plane"
});
var camera = new pc.Entity();
camera.addComponent('camera', {
  clearColor: new pc.Color(0.1, 0.2, 0.3)
});
var light = new pc.Entity();
light.addComponent('light');
app.root.addChild(cube);
app.root.addChild(camera);
app.root.addChild(light);
camera.setPosition(0, 0, 3);
light.setEulerAngles(45, 0, 0);
var Rotate = pc.createScript('rotate');
Rotate.prototype.update = function(dt) {
  this.entity.rotate(10 * dt, 20 * dt, 30 * dt);
};
cube.addComponent('script');
cube.script.create('rotate');
window.addEventListener('resize', function() {
  app.resizeCanvas(canvas.width, canvas.height);
});




```

#成果物

https://embed.plnkr.co/plunk/WBTsfboqV5Y4NbAB


以上。
開発中のiOSアプリをiOSエンジニア以外にテストしてもらうにあたって

開発中のiOSアプリをiOSエンジニア以外にテストしてもらう際に、TestFlightやDeploygate, firebase app distributionなどの配布ツールを使って確認してもらうにあたって、iOSエンジニアが確認しておくことの備忘録

## TestFlight
### 内部テスター
- 内部テスターは100人まで
  - チームでAccount Holder、Admin、App Manager、Developer、Marketingのいずれかの役割を担うメンバーを最大100人まで追加
- 追加するメールアドレスはAppleIDである必要がある
- テスターに配布する前にApple審査はなし
- アップロード、Appleサーバーでのビルド時間に30分〜1時間程度の時間がかかる
- 100デバイス制限あり

### 外部テスター
- 追加するメールアドレスはAppleIDである必要はなし
  - Eメールアドレスを使用するか、任意のユーザーに対してAppのテストに参加する機会を開くパブリックリンクを有効にして共有
- １万人までテスターを登録してアプリを配布できる
- 100デバイス制限も関係ない
- テスターに配布する前にApple審査が発生し、（1日程度）ビルドが承認され次第、テスト開始できる

## Deploygate(or firebase app distribution
- 追加するメールアドレスはAppleIDである必要はなし
  - Eメールアドレスorパブリックリンク,QRコードで共有
- テスターに配布する前にApple審査なし
- メール招待後、DeveceUDIDを登録し証明書を更新、更新後の次の配布バージョンから確認可能
  - 初回の追加時は次回配布まで待つ必要があるので時差あり、証明書の管理者に更新をおねがいする必要あり
- 100デバイス制限あり

## 比較
## 開発物の確認開始までの時間
Deploygate　> TestFlight内部テスター >  TestFlight外部テスター

## 参加できる人数
TestFlight外部テスター > Deploygate == TestFlight内部テスター

## 参加への手軽さ
TestFlight外部テスター > Deploygate >　TestFlight内部テスター

## よくある確認フロー
開発中　Deploygate
↓
ある程度バグがなくなって申請前に確認　TestFlight内部テスター
↓
リリース前に確認　TestFlight外部テスター

開発途中の物を確認、テストしたい場合はDeploygateを使ってテストするのがよい。
人数制限はあるので、アプリ開発者、サーバー開発者、テスターでの確認用に使うとよい。
アプリ側でバグがあった時に修正して更新、確認してもらうなど、更新回数が多い段階で見てもらうのに使う。
Develop, Staging環境など複数環境を揃えやすいのもメリット。

大規模開発において、関わる人が多い場合はTestFlight外部テスターを使って多くの人にテストしてもらうのがよい。
テスト開始できるまでに審査が必要なので余裕を持ってテストスケジュールを組む必要がある。
テスターの参加人数の多い場合は、多くの人の時間を使ってしまうので、Deploygateである程度バグを潰した状態で見てもらうようにする。
また、アプリに詳しくない人にも確認してもらう場合は、

- DeploygateはDevice UDIDの登録必要
- TestFlightは内部テスターはAppleIDが必要

などの、テスト参加者に理解してもらえない用語や制約が多いため、どの段階からどのツールで見てもらうかはよく検討する必要がある。

## どの段階からどのツールで見てもらうか検討例
- リリースの品質決定権のある人
- デザイナー
- テスターが足りない時にモンキーテスト的にデバッグを手伝ってくれる社内の人

このあたりの役割の人はある程度早く見てもらう必要があるが、かといって、あまり早い段階で見てもらっても混乱が起きたり、有意義でなテスト時間になりにくいことがある。
よくある対応として

- Deploygateに参加してもらいつつ、見て欲しいタイミングで声かけをして更新してもらう
- 開発用とは別に開発後半用のDeploygateビルドを別途作成する
- TestFlight内部テスターとして参加してもらい、TestFlightの更新をリリース前でなくある程度余裕を持ってやる

などがある。
Databricks ワークスペース内のテーブル一覧を取得する関数

データベース毎にテーブルの一覧表を取得する関数は見つかりましたが、ワークスペース内のデータベースすべてのテーブル一覧を取得する方法が見当たらなかったので関数にしました。

あのテーブル、どのデータベースにあったっけ？みたいな時にどうぞ。

※20210806 追記
E2 アーキテクチャだとテーブル一覧のパラメータが違う模様。
DB ごとのテーブル数も一緒に出力できるように変更。

### 関数
```python
from pyspark.sql.types import *

def get_2sdf_table_list_and_table_cnt():
  # Database 一覧表の取得
  db_list_sdf = spark.sql("show databases")
  db_list_df = db_list_sdf.select('databaseName').toPandas()
  db_list = db_list_df.values.tolist()

  # Table 一覧用の空 Sparkdf 作成 
  field = [
    StructField("database",StringType(), True),
    StructField("tableName", StringType(), True),
    StructField("isTemporary", BooleanType(), True)
  ]
  schema = StructType(field)
  all_tables_sdf = sqlContext.createDataFrame(sc.emptyRDD(), schema)

  # Database 毎に Table 取得、一覧に追加
  for i in db_list:
    query = "show tables from " + i[0]
    tables_in_each_db = spark.sql(query)
    all_tables_sdf = all_tables_sdf.union(tables_in_each_db)
  
  # 各db内のテーブルをカウント
  table_count_sdf = all_tables_sdf.groupBy("database").count()
  
  return all_tables_sdf, table_count_sdf
```


### 参照リンク
[SHOW DATABASES](https://docs.databricks.com/sql/language-manual/sql-ref-syntax-aux-show-databases.html)
[SHOW TABLES](https://docs.databricks.com/sql/language-manual/sql-ref-syntax-aux-show-tables.html)
SLOOP(Side effect Less OOP)

# TL; DR

- （主にClassBaseの)OOPは、メンバ変数を"インスタンス単位のグローバル変数"として振る舞うよ
- 一方で、一定のメンバを集めた範囲を対象にしたオペレーションには抽象化として高い意義があるよ
- メンバ変数のGlobal変数性を断ち切るためには、オブジェクトがImmutableであれば良いよ
- ObjectのImmutable性を前提にしたOOPをSLOOP(Side effect Less OOP)と名付けて区別してみてはどうだろう。
- またImmutable性を必ずしも前提にはしないが、Mutableであるメソッドを陽に区別する立場をASLOOP(Auxiliary SLOOP)とするのはどうだろうか。

# グローバル変数の何が問題だったのか

本質的には以下のようなコードが問題になるのだった。(詳しくはいろいろな記事があるので確認してほしいです。)

(架空の言語のコードなので雰囲気でお願いします)

```
globalStr = "abc"
f() { ... }
g() { ... }

main() {
  f(); // ここでglobalStrが書き換わって
  g(); // ここの挙動を変えてしまうかもしれない
  // したがって
  // 1. f, gのコードを個別に読むだけでは全体の挙動がわからない(リーダビリティがない)
  // 2. fとgの単体テストではf, gの挙動を明らかにできない/切り離すことができない(テスタビリティがない)
  // 3. fの繰り返しの利用に対して問題が生じやすい(リエントラントでない)
  // 4. fの利用とgの利用に順序の固定が発生する
  // etc, etc...
}
```

# インスタンス単位の"グローバル変数"

実は(クラスベースの)オブジェクト指向では、しばしばこのグローバル変数が復活したのと変わらない状況がインスタンス単位で発生する。

(架空の言語のコードなので雰囲気でお願いします)

```
class X {
  private memberStr = "abc;

  f() { ... }
  g() { ... }
}

main() {
  x = new X();
  x.f(); // ここでmemberStrが書き換わって
  x.g(); // ここの挙動を変えてしまうかもしれない
  // したがって
  // 1. f, gのコードを個別に読むだけでは全体の挙動がわからない(リーダビリティがない)
  // 2. fとgの単体テストではf, gの挙動を明らかにできない/切り離すことができない(テスタビリティがない)
  // 3. fの繰り返しの利用に対して問題が生じやすい(リエントラントでない)
  // 4. fの利用とgの利用に順序の固定が発生する
  // etc, etc...
}
```

グローバル変数とそう変わらないわけですね。
もちろんありとあらゆるモジュールから利用される可能性があるグローバル変数と比べるとずっとマシではあります。
でも本質的な課題はここでは解決していないわけです。

# OOPの価値は対象物とメソッドという語彙による抽象化

ではなぜクラスが大事かというと、対象物を中心とした抽象化を行うことが、プラクティカルな面で有効であることがわかっているからです。
(このことも様々な記事があると思うのでそちらをご参照ください)

※関数の"第ゼロ引数"という以上の意味はあまりない、という立場はありえる。
関数型言語の一部はそういう立場を支持しているように思われる。ところが結局Elixirの `|>` 演算子に見て取れるように、 Object -> Method(Arguments) という語順を保つための手法がしばしば登場してしまう。
小さなことに思えるかもしれないが、つまりはプラクティカルな面でのOOPを支援しているのであって、
人間の頭がそういう抽象化手法を求めているのだと思われる。(Chainingがしやすいといった実利的側面もある)
また各関数の第一引数が何であるか慣例としてプログラマが(非常に)気にしてケアしている。OOPはこれを強制できる。

# ローカルなグローバル変数をローカルな定数にしてもOOPの価値は実現できる

しかしこういった価値には別に副作用を伴わせる必要はない。
Immutableなオブジェクトだとしても別にmethod chainingはできる。

(架空の言語のコードなので雰囲気でお願いします)

```
class X {
  private const memberStr = "abc";

  f() { ... }
  g() { ... }
}

main() {
  x = new X();
  x.f(); // ここでmemberStrが書き換わって...しまうことはない。
  x.g(); // ここの挙動を変えてしまう...ことはない。
  // したがって問題はなにもない
}
```

# SLOOPと呼んではどうか。

こういうImmutable性を前提にしたOOPは、DDDのValueObjectなど、しばしば登場する。
しかしImmutableObjectという以上に名前がない。

特に「ありとあらゆるところでImmutable Objectを前提にしたオブジェクトを用いる立場」を、しばしば人は「関数型」と呼びがちである。
しかしそれは関数型という言葉以上の意味を含んでしまっている。

そこで新たな用語を導入することを提案してみたい。 
名付けて **SLOOP(Side effect Less Object Oriented Programming)** だ。

# 補助付きSLOOP

ただしDDDでいうところのEntityオブジェクト(同値性を保ちながら変遷を辿るオブジェクト)のようなものはやはり現実としてよく登場する。
そこでOOPでは以前から"LocalなGlobal変数問題"への対処としてCommandQuery分離原則という原則が敷かれている。
そういう立場では、C++のconstメソッドや、Rustの&self, &mut selfを陽に区別する立場でメソッドを整理するということが有効であると考えられる。

そこでSLOOPよりは少し弱いが、プラクティカルな立場として、
「CommandQuery分離をコード上に表明する立場」のことを **ASLOOP(Auxiliary SLOOP)** と呼んで区別してみるのはどうだろうか。
Git $ git log コマンドで各コミットで修正したソースを表示する

# 目的

- `$ git log`コマンドで各コミットで修正したソースを表示する方法をメモ的にまとめる

# 方法

- 下記コマンドを実行する。

    ```terminal
    $ git log -p
    ```

- 下記方法と組み合わせると特定のコミットで修正したソースを表示する事ができる。
    - [Git $ git log の表示の先頭コミットを指定する]()
- 下記のように記載する。

    ```terminal
    $ git log -p コミットID
    ```
記録用　JWTについて

今回はweb業界の登竜門　 tokenについてお話しします。

これがわかれば、認証周りは大丈夫！！！！！

早速いきましょう！


まずは、JWTについてお話しします。

JWTは属性情報(Claim)をJSONデータ構造で表現したトークンです。


JWTについての仕組み
3の構成でできています。

ヘッダー、ペイロード、署名

でできています。


ヘッダーについて

alg,typeがあります。

alg　　署名に使われているアルゴリズムを指定します。これは必須です。
typeについては大丈夫です。

初学者はここはスキップして大丈夫です。

ペイロードについて

JSONをBasとe64urlエンコードした文字列と覚えておいてください。
要は、ユーザー情報などを格納する場所です！！！


いろんな予約語もあるから見ておいてね！
ペイロード　予約後で検索すれば出でくるはず！

署名についてはこんな感じです。

署名部分は検証時に使われます。データが改ざんされているかどうかをチェックするために署名が使われますが、それ以外ではあまり意識することはありません。

あまり意識しなくて大丈夫です。


JWTを使う機会があるのは主に認証まわりです。

今回のページでは実装はできないのであくまでも概念を理解する、掴むために活用してください。
[Windows] Windowsのバージョン、コードネームを確認する

# やりたいこと

Windowsのバージョンが、略称？コードネーム？(20H1とか、1901とか)とか、ビルド番号？(18363.1256とか)とかあって、どのバージョンがどのビルドでどのコードネームなのか、対応が良くわからんので、どの番号がどのビルドなのか？とかを調べたい。

# やったこと

まずWindowsのシステム情報でWindowsのバージョンを確認して、
下記のページを見て、どのバージョンがどのコードネームなのか？等調べた。

## Windowsバージョン情報の見方

[スタートボタン] > [設定] > [システム] > [バージョン情報]

の中の、[Windowsの仕様] を見る。

## バージョン一覧

下記ページを見る。
MS公式には、一部のコードネームが載ってない気がする。
見当たらないコードネーム等がある場合は、WikipediaやPCメーカーのページ等と合わせて探してみる。

Wikipedia（Windows10のバージョン履歴）
https://ja.wikipedia.org/wiki/Microsoft_Windows_10%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E5%B1%A5%E6%AD%B4

Wikipedia（Windows11のバージョン履歴）
https://ja.wikipedia.org/wiki/Microsoft_Windows_11%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E5%B1%A5%E6%AD%B4


MS公式(一部のコードネームが載ってない(20H1等))
https://docs.microsoft.com/ja-jp/windows/release-information/

各PCメーカの情報ページ
https://faq.nec-lavie.jp/qasearch/1007/app/servlet/qadoc?QID=019101
https://support.lenovo.com/jp/ja/solutions/ht502786
【python/Instagram】Instagram Like-bot を作る。logを保存する。

<a href="https://developer.twitter.com/en">InstaPy<a/> を使い、自動like-botを作ります。

```console
Package                            Version
---------------------------------- ----------------------
instapy                            0.6.13
pandas                             1.0.5
schedule                           0.6.0
```
　
　
InstaPy関数でログイン情報を設定しセッションを作ります。
like_by_tags関数で検索したいタグ(list可)を指定し、amountでライクする数を指定します。
最後にend関数でセッションを終了します。

```python
# job
from instapy import InstaPy
session = InstaPy(username="user_name", password="password", headless_browser=True)
session.login()
session.like_by_tags([tag], amount=10)
session.end()
```
　
　
　
　


InstaPyでセッションを開始すると自動でホームフォルダにInstapyフォルダが作成されその中に.logが作成されます。今回はその.logから文字を抽出し、.csvにまとめていきます。
logging モジュールを使って、もっと効率的にlogを抽出したかったのですが、logging初心者なので挫折しました。もっといいやり方あれば教えてください。

```python
# makelog
import pandas as pd
import re

url_id = []
keep_phrases = ['Image from: b\'', '  Link: b\'']
        
with open('/path/to/.log/', 'r') as f:
   f = f.readlines()
        
for lines in f:
   for phrase in keep_phrases:
      if phrase in lines:
          url_id.append(lines)
          break
date = list()
user_id = list()
link = list()
df = pd.DataFrame() 
        
        
for line in url_id:
   if bool(re.search(r'Link: b\'',line)):
      a = re.search(r'Link: b\'',line)
      link.append(line[a.span()[1]:len(line)-2])
      date.append(line[6:25])
   elif bool(re.search(r'Image from: b\'',line)):
      a = re.search(r'Image from: b\'',line)
      user_id.append(line[a.span()[1]:len(line)-2])
        
df = pd.DataFrame(list(zip(date, user_id, link)), columns =['date', 'user_id', 'link'])
df.to_csv('/path/to/.csv', header = True, index=False)

```

　


　


以上の2つの処理をschedule モジュールで時間を指定して走らせます。

```python
import schedule

schedule.every().day.at("15:20").do(job)
schedule.every().day.at("21:29").do(job)
schedule.every().day.at("00:00").do(makelog) 

```
　　　　　　　　


　　

この様にまとめてくれます。(URLはポストのURLです)
![Screen Shot 2021-01-22 at 9.09.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/aa9e4b5f-2abd-9b55-e013-3d866fc8f7a6.png)
Laravel5.5のstr_containsがarrayを許容しなくなった

# 概要

[Laravel 5.5 ヘルパ](https://readouble.com/laravel/5.5/ja/helpers.html#method-str-contains)によると

```
str_contains関数は指定した文字列が、２つ目の文字列を含んでいるか調べます。（大文字小文字の区別あり）

$contains = str_contains('This is my name', 'my');

// true
指定した文字列に値のどれかが含まれているかを判定するために、値の配列を渡すことも可能です。

$contains = str_contains('This is my name', ['my', 'foo']);

// true
```

駄菓子菓子実行すると

```console
>>> str_contains('This is my name', ['my', 'foo']);
TypeError: Argument 2 passed to str_contains() must be of the type string, array given on line 1
>>> 
```


## ソースコード

```vendor/symfony/polyfill-php80/bootstrap.php
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Php80 as p;

if (PHP_VERSION_ID >= 80000) {
    return;
}

if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) {
    define('FILTER_VALIDATE_BOOL', FILTER_VALIDATE_BOOLEAN);
}

if (!function_exists('fdiv')) {
    function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); }
}
if (!function_exists('preg_last_error_msg')) {
    function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); }
}
if (!function_exists('str_contains')) {
    function str_contains(string $haystack, string $needle): bool { return p\Php80::str_contains($haystack, $needle); }
}
if (!function_exists('str_starts_with')) {
    function str_starts_with(string $haystack, string $needle): bool { return p\Php80::str_starts_with($haystack, $needle); }
}
if (!function_exists('str_ends_with')) {
    function str_ends_with(string $haystack, string $needle): bool { return p\Php80::str_ends_with($haystack, $needle); }
}
if (!function_exists('get_debug_type')) {
    function get_debug_type($value): string { return p\Php80::get_debug_type($value); }
}
if (!function_exists('get_resource_id')) {
    function get_resource_id($res): int { return p\Php80::get_resource_id($res); }
}

```

arrayじゃなくstringになってます。

```php
if (!function_exists('str_contains')) {
    function str_contains(string $haystack, string $needle): bool { return p\Php80::str_contains($haystack, $needle); }
}
```

注意必要ですねー。

## 参考

- [symfony/polyfill-php80](https://github.com/symfony/polyfill-php80)
- [PHP 8 str_contains](https://www.php.net/str_contains)
scpコマンドで最新のファイルを転送するワンライナー

送信元にある最新のファイルを別のサーバーに転送したい時があり、以下のようにバッククォートで囲めばコマンドが実行され結果が得られます。

ワンライナーで必要な最新のファイルを取得して、転送することが出来ました。

```
scp `ls -1t /tmp/data/*.csv|head -n 1` user@hostname:/home/user/
```
【スマレジアプリを作ってみた#5】Sandboxでの動作確認（テスト）

【スマレジアプリを作ってみた】5回目は引換券モニターのSandbox環境でのテストの仕方についてお伝えしていきます！

※前回の記事（Webhookの使い方、受信サーバーのセットアップ方法、ngrokの使い方などアプリ実装の詳細について）は[こちら](https://qiita.com/JoBins/items/f7e4cafc6437082dcb6a)をご覧ください。



## Sandbox環境のセットアップ

スマレジアプリを使ってテストする際、最初に接続先をSandboxに変更しなければいけません。

接続先変更のため、まずはスマレジ開発者プラットフォームを開きます。
設定ページの中の「スマレジアプリ環境切替」タブに移動したら、
下のスクリーンショットのように、「サンドボックス」をクリックします。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3930383939362f38613364393734322d316630652d636262632d393734612d6462343233323531636462382e706e67__1868×981_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/79acd1bf-b28b-f69b-daf4-cab9f9552b71.jpeg)


その後、スマレジアプリがインストールされているデバイスに表示されているQRコードをスキャンするか、QRコードの下のボタンをクリックします。
これにより、Sandbox接続先でアプリが起動します。


### スマレジテストアプリにログインする

１. スマレジアプリを起動したら、使い方のチュートリアルが出てくるので、「今すぐ使う」をタップしてチュートリアルをスキップします。

![IMG_0015.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/4d921ab8-a18a-4581-8a56-4b2d9600050a.png)

２. もしすでにスマレジのアカウント持っていたら、「すでに持っている」をタップし、メールとパスワードを入力してログインします。（もっていない場合はアカウントを作成してください）

![IMG_0016.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/87c34e98-a889-47f9-c517-f5ca33673cfd.png)

４. 店舗を選択し「完了」をタップします。下のスクリーンショットのように「店舗」メニューをタップすると、選択した店舗名が確認できます。

![IMG_0019.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/283207d1-2a0c-6248-b04b-5cf678002e43.png)

５. ちなみに、この店舗情報を編集したり店舗を追加したい場合は、スマレジPOSシステムの管理画面をブラウザで開きます。左側メニューから「店舗＞店舗一覧」をクリックすると、店舗一覧が表示され、店舗を編集したり追加したりできます。

![店舗一覧___スマレジ-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/215fa4f1-3e78-720b-a99d-cfe9d2c8538a.jpeg)


### テストデータを作成する
引換券モニターがスマレジアプリで作成された取引情報をきちんと受信できるか確認するため、テストデータを作成し、実際に取引を行ってみます。
テストデータの作成方法は次の通りです。


１. スマレジの管理画面の「商品＞商品一覧」に入り、「新規商品登録」ボタンから商品を登録します。

![商品一覧___スマレジ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/d64787e7-0a42-1dbe-b941-58947f372d62.jpeg)

２. 商品を登録したら、アプリと同期し追加した商品が見れるようになります。同期するには、スマレジアプリの「設定＞データ管理」を開き、「商品」をタップします。
![IMG_0022_PNG_と_「【スマレジアプリを作ってみた_5】Sandboxでの動作確認（テスト）」を編集_-_Qiita_と_受信_—_matsumoto_jobins_jp（60件のフィルタ済みメッセージ）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/206d3766-094b-9856-6d97-514c4a31f436.jpeg)


これで、テストするための準備は完了です！


##取引を行いテストしてみる

テストの準備が整ったので、早速スマレジPOSシステムで取引を行い、
引換券モニターにちゃんと表示されるかテストしてみます！

１. スマレジアプリの「販売業務」メニューで商品を選択し、「お会計へ」をタップします。
![IMG_0020.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/57d18cab-9f7c-39e8-ca14-e3272fc72fb5.png)

２. 預かり金額を入力しチェックアウトします。

![IMG_0021.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/ab155d3a-1e73-c3b6-0583-766ee85992c7.png)

３. 取引が完了したら、引換券モニターを確認し、商品が該当する店舗の画面に表示されているか確認します。無事商品が表示されていたら、あとは引換券モニターで各機能をテストしていきます。
![staff-monitor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908996/329de4a3-c43d-0c77-60d7-b84c38a2e7e3.png)



---

はい、というわけで、今回は引換券モニターのSandbox環境でのテストの仕方についてお伝えいたしました！
ここまできたらあと一息です！

次回は【スマレジアプリを作ってみた】シリーズ最終回！
「アプリ申請と本番公開」についてお届けいたします。
【Typescript】 Error: Cannot find module 'express' の解決

あるファイルを読み込もうとしたら、エラーメッセージが出た。

```typescript
node index.js

internal/modules/cjs/loader.js:638
    throw err;
    ^

Error: Cannot find module 'express'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:562:25)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/home/ec2-user/environment/photo/realitycapture/reality.capture-nodejs-photo.to.3d/index.js:18:15)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
```

## 解決策  
```
npm insatll express
```

expressを入れましょう。以上。
HitTestを実施した際に、Containerが反応しない

# 問題

テスト環境でHitTestにてContainerを検出することを確認後、本番環境に実装を行った。
が、なぜかContainerがHitTestにて検出されない問題が発生した。

# 解決方法

Containerのcolorに透明な色を適用することで、HitTestにて検出されるようになった。

# 原因

Flutter.devのContainerのページにも記載があったが、colorに何もしていない場合、ContainerはHitTestにて検出されなくなってしまうみたい。

> By default, containers return false for all hit tests. If the color property is specified, the hit testing is handled by ColoredBox, which always returns true. If the decoration or foregroundDecoration properties are specified, hit testing is handled by Decoration.hitTest.

https://api.flutter.dev/flutter/widgets/Container-class.html
フルフルマウス

#マウスを一定時間で移動させるコマンド
間違っても悪用してはいけません！！！
一定時間操作しないとスクリーンセイバーが邪魔な時とかありますよね？そういう人向けですよ？
このコードを使用によるいかなる損害も責任は取れませんのでご了承ください。

##参考サイト：
https://www.inasoft.org/talk/h202005a.html

##ソースコード
```PowerShell:マウスフルフル.ps1
# カーソルを動かす為に必要
add-type -AssemblyName System.Windows.Forms

#Win32のDLLインポート
$signature=@' 
     [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
     public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
'@

#Win32のイベントを拾う準備
$SendMouseEvent = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru

#画面上に出すメッセージ
echo "Ctrl+Cで終了します。"

# マウス移動
$MOUSEEVENTF_MOVE = 0x00000001

# スリープ秒数
$SleepSec = 5

# マウスの振れ幅
# ・マウスの移動イベント生成用の振れ幅
$MoveMouseDistance = 10
# ・マウスの座標を左右にずらす用の振れ幅
$MoveMouseDistanceX = 10

# 偶数回数目は左へ、奇数回数目で右へずらすためのフラグ
$Flag = $true

# 無限ループ
while ($true) {
   # スリープ
   Start-Sleep $SleepSec

   # 現在のカーソルの位置を取得
   $x = [System.Windows.Forms.Cursor]::Position.X
   $y = [System.Windows.Forms.Cursor]::Position.Y

   # 座標左にずらす（マウスイベントを監視するOS(スクリーンセーバー、スリープ)対策）
   $SendMouseEvent::mouse_event($MOUSEEVENTF_MOVE, -$MoveMouseDistance, 0, 0, 0)

   # 座標右にずらす（マウスイベントを監視するOS(スクリーンセーバー、スリープ)対策）
   $SendMouseEvent::mouse_event($MOUSEEVENTF_MOVE, $MoveMouseDistance, 0, 0, 0)

   # 座標を監視するアプリ対策(座標を左か右に1ピクセル分ずらすだけにする)
   if ($Flag) {
       $x += $MoveMouseDistanceX
       $Flag = $false;
   }
   else {
       $x -= $MoveMouseDistanceX
       $Flag = $true
   }
   [System.Windows.Forms.Cursor]::Position = new-object System.Drawing.Point($x, $y)
   $x = [System.Windows.Forms.Cursor]::Position.X
   $y = [System.Windows.Forms.Cursor]::Position.Y
}
```
macOS へ RDP でリモートデスクトップ接続する


macOS 標準機能の画面共有は VNC ベースで、Windowsのリモートデスクトップと比べるともっさり感が否めません。また暗号化されないので、社内ネットワークで使うときはsshに乗せたりと面倒です。

そんな折に[xrdpがmacOSでも動くらしいよ](https://ryancreecy.com/2019/10/29/xrdp-on-mac.html)と教えてもらい、早速試したところBig Surでも動きました。

やってみたところ、使えることは使えるのですが、同一LAN内では標準の画面共有の方が快適でした。遠いネットワークからだと違う結果になるかもしれませんが、環境が無いので試せていません。

## インストール

以下からパッケージをダウンロードしておきます。xrdp-0.9.15 と xorgxrdp-0.2.15 で動作確認しました。OSは macOS 11.1 です。

- https://github.com/neutrinolabs/xrdp/releases
- https://github.com/neutrinolabs/xorgxrdp/releases

xQuartz が必要なので、インストールしておきます。

```
brew install xquartz
```

依存パッケージのインストール。automake も入れろって書いてあるけど、tar ball からインストールするときはたぶん不要。

```
brew install libtool pkgconfig nasm libssl
```




まず xrdp をインストールします。

```shell
cd xrdp-0.9.15/
# git からインストールするときは bootstrap が必要
# ./bootstrap
./configure PKG_CONFIG_PATH=/usr/local/opt/openssl/lib/pkgconfig
make
sudo make install
```

/usr/local/ 以下は Homebrew で使っていてそこに入れるのはちょっと気持ち悪いですが、パスを変えると色々と面倒なので、そのままにしました。

xorgxrdp をインストールします。

```
cd ../xorgxrdp-0.2.15/
# ./bootstrap
./configure PKG_CONFIG_PATH=/opt/X11/lib/pkgconfig
make
sudo make install
```

## 設定

`/etc/xrdp/xrdp.ini` を編集します。
`[Xorg]`, `[Xvnc]`, `[neutrinordp-any]` をコメントアウトし、`[vnc-any]` のlibを変更します。

```ini
#[Xorg]
#name=Xorg
#lib=libxup.so
#username=ask
#password=ask
#ip=127.0.0.1
#port=-1
#code=20

#[Xvnc]
#name=Xvnc
#lib=libvnc.so
#username=ask
#password=ask
#ip=127.0.0.1
#port=-1
#xserverbpp=24
#delay_ms=2000
; Disable requested encodings to support buggy VNC servers
; (1 = ExtendedDesktopSize)
#disabled_encodings_mask=0


[vnc-any]
name=vnc-any
lib=libvnc.dylib
ip=127.0.0.1
port=ask5900
username=na
password=ask
#pamusername=asksame
#pampassword=asksame
#pamsessionmng=127.0.0.1
#delay_ms=2000

#[neutrinordp-any]
#name=neutrinordp-any
#lib=libxrdpneutrinordp.so
#ip=ask
#port=ask3389
#username=ask
#password=ask
```

## 確認

macのシステム環境設定で画面共有を有効にします。
![スクリーンショット 2021-01-22 6.27.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9549/3465026c-5cd2-ff61-62d4-5e42e2d10a42.png)
この「コンピュータ設定」で「VNC使用者が画面を操作することを許可」を有効にし、パスワードを設定しておきます。

xrdp を起動します。

```
sudo /usr/local/sbin/xrdp
sudo /usr/local/sbin/xrdp-sesman
```

別のPCからリモートデスクトップクライアントで接続します。
設定が間違っているのか、ここで入力したID/Passwordではログインに失敗します。
以下の画面が表示されるので、ここでpasswordに、先程VNCの設定で入力したパスワードを入れます。

![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9549/1ff5fe8e-9eb5-e444-c5f0-718960b4469f.png)


終了は `-k` をつけて実行します。

```
sudo /usr/local/sbin/xrdp -k
sudo /usr/local/sbin/xrdp-sesman -k
```

## 問題

設定を間違えているだけのような気もしますが、切り分けられていません

- リモートデスクトップ接続時に入力したアカウントでログインできない
- 修飾キーの設定がリセットされる（capsをctrlに変更とか) 

## 自動起動

TBD
最近よく見るあのてのイラストって、Qiitaの記事にも使えそう。いらすと。。。。

#あのて

![drink_tapioka_tea_schoolboy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/e46c1ff4-f614-b7a4-0cf5-02a3a87289da.png)

**最近、↑この人、あちこちでみかけますよね。**

ご存じの方も多いと思いますが、

https://www.irasutoya.com/p/figure.html
『いらすとや』

で提供されています。

#qiitaの記事にも使えそう
**qiitaの記事にも使えそう**　:tada::tada:、だと思います。

利用の可否に関しては、非商用、商用に関して、
わりと使いやすそうな条件が示されています。

**世間によくあるのは、**

|**たとえば、1カ月だけ無料とか、無料、有料で使いやすさが違うとか、結局、有料に引きずり込もうとするのが多いですが。。。。**|
|:---|

それに対して
ご利用規定
https://www.irasutoya.com/p/terms.html
を引用しますと、以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/8c10ab2d-2103-12b4-2fc5-7118e4475a4a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/aa48c195-c953-5485-e7fc-6e0132c42c18.png)


たとえば、
qiitaでの利用を想定した場合、
（qiitaの記事は、商用利用ではないと思いますが、安全側で考えた場合）

https://www.irasutoya.com/p/faq.html
より引用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/221a1aba-2fe9-71b3-bbc6-0c1dcd422247.png)

のところの記載にて、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/9be367e6-64d5-9b9b-25d6-d5c321f0938d.png)

⇒　**１記事毎に２０点までは使っていい**　:tada: と読めます。
(**無料で閲覧できるオープンなサイトに限ります。**　noteとかだと、有料のものあるので、そこは別かも。)

|(2021/01/24追記) Qiitaの記事での利用（1記事20点）を「いらすとや」さんに確認したところ、問題ない、と回答を得ました。あくまで、ワタシの問に対する回答として、ワタシとして解釈しただけですが。。。　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　![pose_dance_ukareru_woman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/359d5fb5-b34f-7219-7309-a85aa19606d6.png)|
|:---|

#関連情報

https://www.irasutoya.com/p/faq.html
より引用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/4e45f35a-75cc-e0ec-b6c9-99e4cfbb555f.png)

の記載にて、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/6dc423a1-422a-d25d-2c9c-7ea65839db21.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/e88e37f6-3774-8887-18a2-04af7ab826ce.png)
の記載にて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/d145e2bf-3db9-c3c7-d30c-5eafb4c28bec.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/977eaf1a-b5d1-2556-57d3-1d87a9523ed4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/c1c9ce59-3d83-b924-3d9e-426cf220dd2c.png)

#実際に使われる場合

上記は、ワタシの理解なので、
実際に使われる場合は、

https://www.irasutoya.com/p/figure.html
『いらすとや』

を**ご確認下さい。**


![obentou_noriben.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481161/24f821f5-ecd4-095f-1a03-554746fc2981.png)


※この記事のイラストは、すべて、「いらすとや」。
Pythonのwith文で複数ファイルを一度に開く

# 概要
Pythonでファイルのopenなどに使う`with文`は、カンマで区切って複数のファイルを一度に開くことができます。(python3.1以降)
その場合、複数の with 文がネストされたかのように扱われます。
複数csvファイルのマージなどに役立ちます。

# サンプルコード(python3.6.9で確認)

2021-01-22: @shiracamus さんのコメントを反映しました。ありがとうございます。


```python
import csv

with open("input1.csv", mode='r') as fi1, \
     open("input2.csv", mode='r') as fi2, \
     open("output.csv", mode='w') as fo:
    reader1 = csv.reader(fi1)
    reader2 = csv.reader(fi2)
    writer = csv.writer(fo)

    for l1, l2 in zip(reader1, reader2):
        writer.writerow(l1 + l2)
```

# 入力ファイル
input1.csv

```csvs
a,b,c
1,2,3
```

input2.csv

```csvs
d,e,f
4,5,6
```

# 出力結果
output.csv

```csvs
a,b,c,d,e,f
1,2,3,4,5,6
```

# 公式ドキュメント
[8. 複合文 (compound statement)](https://docs.python.org/ja/3.6/reference/compound_stmts.html) の [「8.5. with 文」](https://docs.python.org/ja/3.6/reference/compound_stmts.html#with)
はじめてのSwiftLintで出てきたissuesたち

先日、しどろもどろでSwiftLintを導入してみたら、
ブワァーと出てきました、Warning!!
![スクリーンショット 2021-01-20 20.35.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737820/c05ebd05-d007-d135-0812-4943a5f1399d.png)

44個もissues(=問題）があるよ！！
見た瞬間に心が折れたので、一旦閉じて翌日に持ち越してしまってごめんなさい。

44個すべてのイシューを確認して、全部修正するのめちゃくちゃ大変そうだなと思ったのですが、
よく見ると同じ文言が繰り返されていることに気づきました。
こう、ぱっと見、英語ばかりで「うえー！」ってなってしまったのは反省です。
よく見れば大したことないことが、わかってきました。

文言はたった5つでした。

##Line Length Violation
__行長違反__

>Line Length Violation: Line should be 120 characters or less: currently 127 characters

(翻訳）行は120文字以下である必要があります：現在127文字

##Trailing Newline violation
__末尾の改行違反__
>Files should have a single trailing newline.

（翻訳）ファイルには、末尾に1つの改行が必要です。

##Unused Optional Binding Violation
__未使用のオプションのバインディング違反__
>Prefer `!= nil` over `let _ =` (unused_optional_binding)

（翻訳）let _ =`（unused_optional_binding）よりも `！= nil`を優先します

##Vertical Whitespace violation
__垂直空白違反__
>Limit vertical whitespace to a single empty line.

（翻訳）垂直方向の空白を1行の空行に制限します。

##Comment Spacing Violation
__コメント間隔違反__

>Prefer at least one space after slashes for comments. 
（翻訳）コメントのスラッシュの後に少なくとも1つのスペースを優先します。

#所感
いろいろ細かな制約があるんですね。
Human Interface Guidelinesとか見ながら理解を深めていきたいなと思いました。
今回をきっかけに気づいたのですが、
英語には抵抗ない方だと思っていたけど、意外と自覚なく抵抗感あったのだな、と。
iOSエンジニア、Swift触る人になるんだから、
この程度の英語で少しでも拒否反応を示したらだめだなぁっていうのが今回の学びです。

今後、また新しいissuesに遭遇したら追記していきます。
【React+TypeScript】Netflixのクローンを作るチュートリアル

こんにちは、フロントエンドエンジニアの[てりー](https://twitter.com/teriteri_code)です。
僕の詳しいプロフィールは[こちら](https://terrblog.com/about/)

![React + TypeScript.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397606/57fb3a92-7186-4186-635e-e4eab3e8aa7e.png)

※クローン=見た目についてです。
実際のNetflixにある機能で今回実装してしていない部分もあります。
## 作れるもの
React+TypeScriptを使ったNetflixの映画一覧を表示するアプリケーションです。
完成するとこんな感じになります。
[![Image from Gyazo](https://i.gyazo.com/6f7801ca81151b3c7cc41cd90a6022b4.jpg)](https://gyazo.com/6f7801ca81151b3c7cc41cd90a6022b4)

Netflixの映画一覧を取得し、カテゴリー毎に表示しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397606/a92dea7f-beda-0ffd-c06c-00633c357eea.png)

映画をクリックすると、youtubeのプロモーション映像が流れます。
[![Image from Gyazo](https://i.gyazo.com/41ecc7d678ef3f21463e03860d56f0ff.gif)](https://gyazo.com/41ecc7d678ef3f21463e03860d56f0ff)

## 学べる事
- ReactのFunctionComponent（関数コンポーネント）とTypeScriptの使用
- React Hooksによるstate管理
- TypeScriptで外部APIを扱い、非同期通信でデータを取得
- movie-trailerにyoutubeを組み込む
- Firebaseでデプロイ

## こんな人に読んでほしい
React、TypeScriptで
- 入門書やチュートリアルをやった後に、実際に何か作ってみたいという人
- 普段仕事で基礎的なことはやっているけど、自分で1から何かを作ってみたい人

## 機能一覧
- TMDBからNetflixの映画がを取得し表示している
- ナビが一番上に固定してあり、スクロールにより背景色が変化する
- バナーに映画とその詳細が表示される
- カテゴリー毎に表示されている
- リロード毎にバナーの映画が変わる（ランダムに取得される）

制作物のイメージが出来た所で実際に取り掛かっていきましょう。

## ここから先

本記事の内容が好評で、多くの方に読んでもらえた結果、
今だに内容のアップデートなどを行なっている為、zennにて有料販売さえてもらう事にしました。

https://zenn.dev/gunners6518/books/4c4672f32dd100

手を動かしてReact + TypeScriptを学びたい人はぜひ！

## Reactの基礎知識に不安がある人へ

React + TypeScriptの具体的な勉強方法のロードマップをまとめました。

https://terrblog.com/react-typescript-how-to-master/

興味あればご覧ください。
Pillow resize と thumbnail の違い

# Pillow
Pillowは、Pythonの画像処理ライブラリです。
サムネイル画像作成など、画像を拡大・縮小する時に使われるメソッドを比較します。

# resize
`Image.resize(size, resample=3, box=None, reducing_gap=None)`
サイズを変更したコピーを返す

#### Parameters
- size: 変更したいサイズ (width, height)
- resample: リサンプリングフィルタ (デフォルトは PIL.Image.BICUBIC)
  - PIL.Image.NEAREST
  - PIL.Image.BOX
  - PIL.Image.BILINEAR
  - PIL.Image.HAMMING
  - PIL.Image.BICUBIC
  - PIL.Image.LANCZOS
- box: リサイズする画像の領域。長方形の領域のみ指定できる
  未指定の場合、画像全体
  - 例: box=(100, 100, 300, 300)
- reduce_gap: 段階的に画像サイズの変更、最適化をさせる (デフォルト: 2.0)

#### 戻り値
Image object

# thumbnail
`Image.thumbnail(size, resample=3, reducing_gap=2.0)`
アスペクト比を維持しながら、指定したサイズ以下の画像に縮小させる
- 例： 550x550の正方形画像に(600, 400)を指定した場合、400x400 となる

#### Parameters
- size: 指定したsize以下に縮小する (width, height)
- resample: リサンプリングフィルタ (デフォルトは PIL.Image.BICUBIC)
  - PIL.Image.NEAREST
  - PIL.Image.BOX
  - PIL.Image.BILINEAR
  - PIL.Image.HAMMING
  - PIL.Image.BICUBIC
  - PIL.Image.LANCZOS
- reduce_gap: 段階的に画像サイズの変更、最適化をさせる (デフォルト: 2.0)

#### 戻り値
なし（破滅的なメソッド）


# 比較
元画像(300x200)
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275134/903c9733-5d6d-bd7c-f79f-fad4105cd231.png)

## resize
```
im = Image.open("test.png")
im_resized = im.resize(size=(150, 150))
im_resized.save('output.png')
```
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275134/d39d644a-d03f-4842-f4a2-9b2f4ae7d37a.png)
150x150

## thumbnail
```
im = Image.open("test.png")
im.thumbnail(size=(150, 150))
im.save('output2.png')
```
![output2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275134/1d474597-2c63-2daa-110b-e61a355d32a9.png)
150x100

## size指定が大きい時
300x200 の画像を `size=(400x500)` を指定してみる
### resize
```
im_resized = im.resize(size=(400, 500))
```
![output3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275134/888c12d1-933e-592d-1b09-6a8eafa26b5e.png)
400x500

### thumbnail
```
im.thumbnail(size=(400, 500))
```
![output4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275134/cba60b61-e269-48c3-756d-50a939d79bd1.png)
300x200

# 参考
公式ドキュメント: https://pillow.readthedocs.io/en/stable/index.html
C#でAtCoder Beginners Selection（ABC088B - Card Game for Two）

####準備
[C#でAtCoderデビューのための準備]
(https://qiita.com/azumabashi/items/7aa9e4b77c10970cc30a)
のあとで AtCoder Beginners Selection　をやってみました。

####問題文
ABC088B - Card Game for Two
[https://atcoder.jp/contests/abs/tasks/abc088_b]
(https://atcoder.jp/contests/abs/tasks/abc088_b)

####提出結果

```
using System;
using System.Linq;

class Program
{
	static void Main(string[] args)
    {
        int n = int.Parse(Console.ReadLine());
        int[] a = Console.ReadLine().Split().Select(int.Parse).ToArray();
        Array.Sort(a);
        Array.Reverse(a);
        int Alice = 0;
        int Bob = 0;
        for (int i = 0; i < n; i++)
        {
            if (i % 2 == 0)
            {
                Alice += a[i];
            }
            else
            {
                Bob += a[i];
            }
        }
        int tensa = Alice - Bob;
        Console.WriteLine($"{tensa}");
    }
}
```

####テスト実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/c80ee5e7-ab77-ed12-a72d-743fd5c0f4fd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/78bedb35-82a0-0495-3471-446267cec72d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/4152b67f-e6d6-4b3b-e8eb-a45467c93c7b.png)
C言語で作る自作cpコマンド

## 目的
C言語の学習のために、自作でlinuxのcpコマンド作ってみました。
とはいえ、本実装ではオプションないし、エラー処理等もなしなので、雑な作りになっています。
ただ、案外コピーするくらいなら簡単に実装できたので、他にもファイル処理等オリジナルコマンドが作れるようになったらいいなと思いました。

僕と同様にC言語学習中で何作っていいかわからない人向けです。
学習する上で、初めから作りたいものがあれば話は早いですが、そういうわけではない場合もあったりすると思います。
そんな時はすでにあるものを真似して作ってみるが一番ですよね。

## メイン実装１（バグあり）
@fujitanozomu @SaitoAtsushi 
お二方にご指摘いただき、下記プログラムだと、コメントでおっしゃってる通り、
`ファイル中に0x00のバイト値を含むファイルは同一の内容にコピーされない`です。
@fujitanozomu さん、 @SaitoAtsushi さん、ありがとうございます。
この下に、修正版を残しておきます。
ご指摘あれば、コメントください

``` copy.c
#include <stdio.h>

int main(int argc, char *argv[]) {
  int i;
  char ch[1000];
  FILE *file, *new_file; 

  if (argc < 3) {
    perror(argv[0]);
    return 1;
  }

  file = fopen(argv[1], "r");
  if (!file) {
    return 1;
  }
  new_file = fopen(argv[2], "w");
  if (!new_file) {
    return 1;
  }

  while ((fgets(ch, sizeof(ch), file)) != NULL) {
    if (fputs(ch, new_file) < 0) return 1;
  }

  fclose(file);
  fclose(new_file);

  return 0;
}
```

## メイン実装２（修正版）
fgets => fgetc
fputs => fputc

``` copy.c
#include <stdio.h>

int main(int argc, char *argv[]) {
  int i, c;
  FILE *file, *new_file; 

  if (argc < 3) {
    perror(argv[0]);
    return 1;
  }

  file = fopen(argv[1], "r");
  if (!file) {
    return 1;
  }
  new_file = fopen(argv[2], "w");
  if (!new_file) {
    return 1;
  }

  while ((c = fgetc(file)) != EOF) {
    if (fputc(c, new_file) == EOF) return 1;
  }

  fclose(file);
  fclose(new_file);

  return 0;
}
```

## メイン実装3(改善版）
@fujitanozomu さんより、よりパフォーマンスがいいコードの例を教えていただきました。
ありがとうございます。

``` copy.c
#include <stdio.h>

int main(int argc, char *argv[]) {
  FILE *file, *new_file; 

  if (argc < 3) {
    perror(argv[0]);
    return 1;
  }

  file = fopen(argv[1], "rb");
  if (!file) {
    return 1;
  }
  new_file = fopen(argv[2], "wb");
  if (!new_file) {
    return 1;
  }

  char buf[4096];
  size_t size;
  while ((size = fread(buf, sizeof(char), sizeof(buf), file)) > 0) {
    if (fwrite(buf, sizeof(char), size, new_file) <= 0) return 1;
  }

  fclose(file);
  fclose(new_file);
  return 0;
}
```

## 軽く解説
詳細説明とは多少異なります。自分なりの理解のもとでなるべくわかりやすく記述しています。
間違っている場合はご指摘ください。

### fopen
* 第1引数　＝　ファイルパス
* 第2引数　＝　mode = ストリームの性質(書き込み専用・読み込み専用etc)
* 返り値　＝　オープンしたストリームを制御するFILEへのポインタ。失敗した場合NULL

指定された読み込みファイル（コピー元）のオープン、
書き込みするためのファイル（コピー先）のオープンを行う。

### fgets
* 第1引数　＝　バッファ変数(配列）
* 第2引数　＝　バッファのサイズ
* 第3引数　＝　ストリーム（ファイル）
* 返り値　＝　バッファ。失敗した場合・最後の行まで読み込んだ場合NULL

指定したストリーム（ファイル）から1行分の文字列を読み取り、バッファへ格納

### fputs
* 第1引数　＝　任意の文字列（）
* 第2引数　＝　ストリーム（書き込み先ファイル）
* 返り値　＝　成功は０以上の正の値、失敗はEOF

任意の文字列を指定したストリームに書き込む
今回んプログラムの場合、バッファに格納した文字列を書き込むようにしている。

### fclose
* 第1引数　＝　ストリーム（open下もファイル）
* 返り値　＝　成功は０、失敗はEOF
* 
オープンしたファイルを閉じる


----- 以下修正版で利用 -----
### fgetc
* 第1引数　＝　ストリーム（ファイル）
* 返り値　＝　ストリームから１文字読み込んで、その文字をint型として返す。失敗した場合・最後の行まで読み込んだ場合EOF

### fputc
* 第1引数　＝　書き込みたい文字（int）（fgetcで取得したバイトをそのまま扱える）
* 第2引数　＝　ストリーム（ファイル）
* 返り値　＝　書き込んだ文字。失敗した場合EOF
C#でAtCoder Beginners Selection（ABC083B - Some Sums）

####準備
[C#でAtCoderデビューのための準備]
(https://qiita.com/azumabashi/items/7aa9e4b77c10970cc30a)
のあとで AtCoder Beginners Selection　をやってみました。

####問題文
ABC083B - Some Sums
[https://atcoder.jp/contests/abs/tasks/abc083_b]
(https://atcoder.jp/contests/abs/tasks/abc083_b)

####提出結果

```
using System;

class Program
{
	static void Main(string[] args)
	{
		string[] input = Console.ReadLine().Split(' ');
		int n = int.Parse(input[0]);
		int a = int.Parse(input[1]);
		int b = int.Parse(input[2]);

		int souwa = 0;
		for (int i = 1; i <= n; i++)
        {
			// 強引だけれど結果オーライ
			int i10000 = i / 10000;
			int i1000 = (i % 10000) / 1000;
			int i100 = (i % 1000) / 100;
			int i10 = (i % 100) / 10;
			int i1 = i % 10;
			int wa = i10000 + i1000 + i100 + i10 + i1;
			if ((wa >= a) && (wa <= b))
			{
				souwa += i;
            }
		}
		Console.WriteLine($"{souwa}");
	}
}
```

####テスト実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/3f7b740e-e050-9de8-1889-f5e9d3d81628.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/e931551e-56da-fd0f-916e-069474d58597.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/b165bdac-8697-6595-d4c1-fcca4e5a05f1.png)
プロキシとリバースプロキシ

随時まともにしていく。

`user <- ProxyServer <-> Internet <-> ReverseProxy <-> Server`


### Proxy Server

- ユーザー集団を取りまとめてリクエストを送る
- ユーザー側のIPアドレスを隠すことができる
- キャッシュできる
- ウイルスチェックをまとめて行える





### Reverse Proxy

- サーバー側のIPアドレスを隠すことができる
- CDNのキャッシュによる高速化
- Webサーバの負荷分散
- セキュリティの強化
windows10で右クリック表示が猛烈に遅いと思ったらNVIDIA（ GPU）が原因だった話

https://myscreate.com/contextmenu/
![アートボード – 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593842/237913fe-d98e-fe9b-5e47-72607e535be0.png)
processing タピオカみたいなゲーム

# 説明
マウスで自機を操作してタピオカをよけるゲームです

# コード

```java

int ENEMY_NUM = 10;
int WINDOW_WIDTH = 640; 
int WINDOW_HEIGHT = 640; 
String scene = "start";
int hitFrag = 0;

class Enemy{
  // 敵のクラス
  
  int enemyX;       // 敵のx座標
  int enemyY;       // 敵のy座標
  int enemySpeed;   // 敵のスピード
  
  Enemy(int _enemyY, int _enemySpeed){
    enemyX = WINDOW_WIDTH + 50;
    enemyY = _enemyY;
    enemySpeed = _enemySpeed;
    
  }
}

Enemy enemy[] = new Enemy[10];

void setup(){
  // 初期化
  size(640, 640);
  
  for(int i = 0; i < ENEMY_NUM; i++){
    enemy[i] = new Enemy(int(random(height)), int(random(6,10)));
  }
  
}

void draw(){
  
  if(scene == "start"){
    gameStart();
  }else if(scene == "play"){
    gamePlay();
  }else if(scene == "over"){
    gameOver();
  }
  
  
}

void gameStart(){
  // スタート画面の処理
  fill(255);
  text("Start", width/5, height/2);
  text("Press any key", width/5, height/2+60);
  
}

void gamePlay(){
  // ゲームプレイ中の画面処理
  background(115,66,41); // 背景
  
  // 中心のx座標, 中心のy座標, 横の直径, 縦の直径
  // 自機
  fill(128);
  ellipse(mouseX, mouseY, 50, 50);
  
  // 敵
  for(int i = 0; i < ENEMY_NUM; i++){
    fill(0);
    ellipse(enemy[i].enemyX, enemy[i].enemyY, 50, 50);
    enemy[i].enemyX -= enemy[i].enemySpeed;
    
    // 画面左に出たら
    if(enemy[i].enemyX - 25 < 0){
      enemy[i].enemyX = WINDOW_WIDTH + 50;
      enemy[i].enemyY = int(random(height));
      enemy[i].enemySpeed = int(random(6,10));
    }
    
    // 当たり判定
    if(enemy[i].enemyX - 25 < mouseX && mouseX < enemy[i].enemyX + 25 && enemy[i].enemyY - 25 < mouseY && mouseY < enemy[i].enemyY + 25){
      hitFrag = 1;
      scene = "over";
    }
  }
}

void gameOver(){
  // ゲームオーバー画面の処理
  fill(0);
  background(255);
  text("GameOver", width/2, height/2);
  scene = "start";
  hitFrag = 0;
  
}

void mousePressed(){
  if(scene == "start") {
    scene = "play";
  }
 
}

```

# 画面

### スタート画面
![スクリーンショット 2021-01-22 015027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/d0ecfa4f-1fa8-54e5-4940-262e66e49b6d.png)

### ゲーム画面
![スクリーンショット 2021-01-22 015051.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/a90a7be5-f5ed-efca-ec82-c4b3fe7d2561.png)

### ゲームオーバー
![スクリーンショット 2021-01-22 014941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/458c31df-dea6-9fdd-56e7-3665cd6e1964.png)
Ubuntu 18.04LTS（しかもVMware）でMIDI音源と双方向接続

#あらまし

昔懐かしMIDI音源[Roland SK-88Pro](https://piano.tyonmage.com/roland/sk-88pro.html)を引っ張り出して、Ubuntuで双方向に接続、つまりPCから音源にMIDIを送りPCで音源から音声を受信（再生）できないかと試しました。使ったUbuntuは18.04LTS（しかもVMware上でゲストOSとして動作）です。何カ所かつまづきながらも成功しました。備忘録も兼ねて方法を記します。

#ハードウェア構成

**PC** [VAIO VJS122C11N](https://vaio.com/products/sx122/) （多分ここは問題になりません。USB 2.0互換端子が2個以上あれば大丈夫なはず。）
**音源** [Roland SK-88Pro](https://piano.tyonmage.com/roland/sk-88pro.html)
**PC→音源接続** [Roland UM-ONE mk2](https://www.roland.com/jp/products/um-one_mk2/)
**音源→PC** 標準的なステレオRCA-3.5mm変換ケーブル → [UGREEN USB-オーディオ変換アダプタ](https://www.amazon.co.jp/UGREEN-%E3%82%B5%E3%82%A6%E3%83%B3%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89-%E3%83%98%E3%83%83%E3%83%89%E3%83%9B%E3%83%B3%E3%83%BB%E3%83%9E%E3%82%A4%E3%82%AF%E7%AB%AF%E5%AD%90-MacBook-Windows/dp/B01N41607I)

買ってから気付いたのですが、UGREENのオーディオ変換アダプタはマイク側がモノラルにしか対応してないのでお勧めしません。

Roland純正のRS-232CケーブルDSS-091もあるのですが、ALSAがUSB-RS232C変換器に対応してない模様。諦めました。

#ソフトウェア構成

**ホストOS** Windows 10
**仮想化プラットフォーム** [VMware Workstation 15 Player](https://www.vmware.com/jp/products/workstation-player.html)
**ゲストOS** Ubuntu 18.04LTS
**ALSA** （一番大事かも）[これ](https://www.alsa-project.org/wiki/Main_Page)です。Ubuntuでは

```sh
% apt install alsa-utils
```
して下さい。

#PC→音源接続 ＆ 音源→PC接続

UM-ONE mk2は、初回PC接続時にデバドラが自動インストールされます。うまくいかない場合は[ここ](https://www.roland.com/jp/support/by_product/um-one_mk2/updates_drivers/8cba10bb-0eec-4b3f-9494-c3386d8d7f86/)からどうぞ。
SK-88Proは電源を入れる前に、側面のコンピュータ・スイッチを一番左の「MIDI」にしておき、またUM-ONE mk2の二つのMIDIケーブルをレリーフされている「CONNECT TO MIDI IN」「CONNECT TO MIDI OUT」表記に従って音源背面の端子に接続します。私のようにVMware使ってる人は、接続先をゲストOSにするのを忘れないようにしましょう。

音声出力用に、音源側面のOUTPUT端子とUSB-オーディオ変換器のマイク端子を接続します。UGREENの変換器はOSの標準デバドラで使用できます。

#PC音声設定

ここが一番ハマりました。マイク入力はデフォルトではPCスピーカと切り離されている（当然ですね）ので、これをつないでやらないと音が聞こえません。

Windows10のスタートメニューから「設定」→「システム」→「サウンド」と進みまして…
![hoge.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706455/0c4504cc-1091-b444-7195-380ddb5274e3.jpeg)
![fuge.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706455/8b10e34e-37fc-e92e-27ed-4ce543afd661.jpeg)
出力デバイスは音を出したいスピーカ（私の場合はPC内臓スピーカ）、入力デバイスは「マイク(USB Audio Device)」をそれぞれ選びます。
![hage.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706455/dbb8dcc5-f265-4968-a184-5f62100e9df0.jpeg)
さらに下の方にある「サウンド コントロールパネル」を選んで…
![une.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706455/8ed2830e-7d87-b5f4-0f3e-6a180407a3fd.jpeg)
「録音」タブの中にある「マイク」を選び「プロパティ」を開きます。
![unyo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706455/e1e12ebc-5a43-283e-fa1e-0c6cc5f7f522.jpeg)
![yatta.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706455/660db7f5-ae91-e350-8811-fc57d84fa1cd.jpeg)
上のように「聴く」タブで「このデバイスを聴く」にチェックしたのち、「適用」を押せば準備完了です。

#ALSA PlayerでSMF再生

シェルで

```sh
% aplaymidi -l
```
とし、使えるポート一覧を確認します。私の環境では

```
 Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
 16:0    Ensoniq AudioPCI                 ES1371
 20:0    UM-ONE                           UM-ONE MIDI 1
```
となりました。使いたいのはもちろん一番下のUM-ONE MIDI 1です。クライアント番号20のポート0ですので、

```sh
% aplaymidi -p 20:0 <SMF名>
```
とすればPCスピーカから音が聴こえてくるはずです。
インターフェースについて

# インターフェースとは
　具体的な処理の内容は書かず、クラスが実装すべき規約（そのメソッドで何を呼び出すことが出来るのか）を定めるもの。つまり、クラスでどんなメソッドを実装する必要があるかという構造だけを定めた、論理的な存在。



## 存在価値は？
・「このインターフェースを使うときはこのメソッドの中身を必ず作ってね！」とか、「そのメソッドには、必ずこんな引数を渡してね！」などとメソッドの実装を強制できる。
・複数のクラスが同じインターフェースについて、それぞれ異なる処理内容を実装することが出来る。（ポリモーフィズム）



## 使用例
### interfaceの定義例

```C#
public interface ISeriees {
　　　 int GetNext();
      void Reset();
      void SetStart(int x);
}
```
見てわかる通り、どのメソッドにも処理は実装されていない。その代わりに、インターフェースを実装するクラスでは、そのインターフェースに含まれるすべてのメソッドを実装する必要がある。

### interfaceを実装するクラスの例
```C#
class ByTwos : ISeries {
    int start;
    int val;

    public ByTwos()
    {
        start = 0;
        val = 0;
    }

    public int GetNext()
    {
        val += 2;
        return  val;
    }

    public void Reset()
    {
        start = 0;
        val = 0;
    }

    public void SetStart(int x)
    {
        start = x;
        val = x;
    }
}
```
定義したインターフェースを1つ以上のクラスに実装することができる。注意したいのは、継承と混同しないこと。ByTwosクラスはISeriesクラスを継承しているのではなく、ISeriesインターフェースを実装していると言える。また、ByTwosクラスが3つすべてのメソッドを実装していることからも分かる通り、インターフェースで定義したすべてのメンバーを実装する必要がある。いくつかのメソッドだけを使うといったことはできない。これは使う人それぞれがバラバラな使い方をしてしまうのを防ぐためだ。
[R] Visual Studio Code（Mac）でRのワーキングディレクトリ

こんにちは，[株式会社Nospare](https://bit.ly/38WtGZH)リサーチャー・千葉大学の小林です．
最近Rでコーディングがかなり多くなってきました．最初は[Subethaedit](https://subethaedit.net/)を使ってターミナルで回してたりしたのですが，行ったり来たりが面倒なのでRsdutioへ．Rstudioはエディタとして好きになれなかったので，最近はVScodeを主に使っています．時と場合によってRstudioもたまに使っています．

VSCodeでRの開発環境を整える方法は[この記事](https://qiita.com/Ikuyadeu/items/edf1ddc733f4d1770d5a)で詳しくまとまっています．VSCodeではソース内で`cmd`+`enter`によってRがターミナルで一瞬で開きます．しかしデフォルトだとワーキングディレクトリはホーム．ワーキングディレクトリに関してはRstudioほど楽ではなさそうな感じだと思います．通常プロジェクトごとにワーキングディレクトリが異なる思いますので，特定のディレクトリを予め設定しておいたとしてもちょっと不便かも．そこで私はVSCodeの[Terminal Here](https://marketplace.visualstudio.com/items?itemName=Tyriar.vscode-terminal-here)という拡張機能を使ってます．

![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1023506/5c0092b2-a046-8f7d-37f1-3eb686efde35.png)

この拡張機能は現在開いているファイルのディレクトリでターミナルを開くというものです．これを使って私は

1. RのソースファイルをVSCodeで開く
1. `cmd`+`shift`+`p`から`Terminal Here: Create Terminal`によってソースファイルのディレクトリでターミナルを開く
1. `r`あるいは`R`でRを起動

というふうにやっています．これはSubethaeditの`cmd`+`shift`+`t`と同じやり方ですね．データやアウトプットは通常ソースファイルと同じ階層か下位の階層に置いておくので，それらの場所はソース内で指定しとけばいいと思っています．

多分もっとちゃんとしたいい方法があると思いますがご存知の方は教えてもらえると嬉しいです．



---
[株式会社Nospare](https://bit.ly/38WtGZH)では統計学の様々な分野を専門とする研究者が所属しております．統計アドバイザリーやビジネスデータの分析につきましては弊社 までお問い合わせください．

<a href="https://bit.ly/38WtGZH">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1023506/d5c625c0-d6f4-680b-d702-3c40f11d6c39.jpeg" alt="株式会社Nospare" width=400>
</a>