OmniAICreator/Qiita-1.07M huggingface dataset:
Blob と File と TypeScript と私

`Blob` は JavaScript で生データを扱う際に使用するインタフェース（オブジェクト型）です。
一方、`File` はファイルについての情報（ファイル名、最終更新時...）を持っていて、Blob インタフェースを継承しています。

[MDN](https://developer.mozilla.org/ja/docs/Web/API/File) では以下のように記述されています：

> File オブジェクトは特別な種類の Blob オブジェクトであり、 Blob が利用できる場面ではどこでも利用できます。特に、FileReader、URL.createObjectURL()、createImageBitmap() 、XMLHttpRequest.send() は、Blob と File の両方を受け付けます。
>
> File インターフェイスはメソッドを定義せず、Blob インターフェイスからメソッドを継承しています。

実際のところ、Blob インタフェースとの違いは以下の4つの読み取り専用プロパティを持っているかどうかということになります。

* `File.prototype.name`
* `File.prototype.lastModified`
* `File.prototype.lastModifiedDate`（非推奨）
* `File.prototype.webkitRelativePath`（標準外）

TypeScript組み込みの型定義情報では、`Blob` のプロパティ・メソッドに加え標準・推奨の2プロパティを持っていれば `File` という判定になっています。

```typescript:typescript/lib/lib.dom.d.ts
/** Provides information about files and allows JavaScript in a web page to access their content. */
interface File extends Blob {
    readonly lastModified: number;
    readonly name: string;
}
```

なるほど、**何等かの事情**[^1]で `Blob` から `File` にキャストしたい場合は、`lastModified` と `name` を補ってしまえばよさそうに見えます。

[^1]: たとえば `Blob` しか吐き出さない関数から、`File` しか受け付けない関数にデータを受け渡したい場合など。上述のように、多くの組み込み関数は `Blob` 全体を受け付けてくれるので、あてはまりません。

## いつわらないでいて　ブラウザの指摘は鋭いもの

以下のようなシンプルな例で試してみましょう。

```typescript
function read(file: File): void {
  const reader = new FileReader();
  reader.readAsDataURL(file);
}

// 実際には適当なデータを格納する
const blob = new Blob();
```

`File` 型のオブジェクトを受け取り、`FileReader.readAsDataURL(blob: Blob): void` で読み取るだけの `read` 関数と、`Blob` 型のオブジェクトを用意します。

それでは、`read()` に `blob` を与えてみましょう：

```typescript
read(blob)
// 型 'Blob' の引数を型 'File' のパラメーターに割り当てることはできません。
// 型 'Blob' には 型 'File' からの次のプロパティがありません: lastModified, name
```

コンパイルエラーになりました。型が違うので当然ですね。ここで、エラーメッセージに従い、プロパティを補ってあげましょう：

```typescript
read({...blob, lastModified: 0, name: "name"});
// コンパイルエラーにならない
```

型定義に合致しているので、コンパイルエラーにはなりません。しかしこのコードをブラウザ上で実行すると、`'readAsDataURL' parameter 1 is not of type 'Blob'` として怒られてしまいます。開発者ツールで見ても `File` オブジェクトではなく単なる `Object` だと認識されています。

```typescript
// 本当に有効なコード！
read(new File([blob], "name", {lastModified: 0}));
```

ということで、ちゃんと `File()` コンストラクタを通してあげると実行時エラーにはなりません。追加している情報は同じなのですが、横着をしてはいけませんね。

気が付いてみるとしょうもないことなのですが、エラーメッセージで検索しても事例が見つかりづらいため、記事として残しておきました。

## 愛する型定義のため　コンパイルエラーでいさせて

今回の例の場合は `readAsDataURL()` が `Blob` 型を引数に取るため、`as` で無理やり型アサーションをしても問題なく動作します。

```typescript
// 型アサーションでお茶を濁す
read(blob as File);
```

とはいえ `lastModified` や `name` に依存する処理が `read()` にあった場合は実行時エラーになってしまいます。`Blob` ではなく `File` 型の引数を求めている以上、想定されるべき事態でしょう。

## 参考リンク

* <https://developer.mozilla.org/ja/docs/Web/API/Blob>
* <https://developer.mozilla.org/ja/docs/Web/API/File>
Rails6とdocker-composeを利用した環境にjQueryを導入する方法



docker-compose上に構築したRails6の環境に、jQueryを導入しようと色々調べたのでメモを残します。
Rails5以前のやり方を真似してGemを導入しても動かず、しばらくハマりました...。
Rails6ではwebpackerを使って以下の手順で簡単に導入できるみたいです。
#まずはjQueryをインストール
webpackerで管理する場合はyarnコマンドを使ってインストールします。
docker-compose上でインストールするため```docker-compose exec web```コマンドを使用します。

```:ターミナル
$ docker-compose exec web yarn add jquery
```

無事にインストールできたらdocer-composeを立ち上げましょう。

```:ターミナル
$ docker-compose up
```

#次にwebpackの設定を追加
jQueryをWebpackの管理下にするために設定ファイルを編集します。

```javascript:config/webpack/environment.js
const { environment } = require('@rails/webpacker')

// ここから
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
// ここまで追記

module.exports = environment
```

#application.jsに設定を追加
application.jsのファイルを編集してjQueryを呼び出せるように設定します。


```javascript:javascript/packs/application.js
//中略

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
// 追記
require('jquery')

//中略
```

これでjQueryの導入は完了です。
#jQueryの動作確認
jQueryが正常に動作するか確認します。
何らかのviewにテスト用のpタグを記入しましょう。

```erb:お好きなviewファイル.html.erb

<p>テスト</p>
```
当然ですがブラウザには以下のように表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295385/0f51ee92-de6b-5fba-abf2-2bba258fc424.png", width=50%>
次に、別ファイルにjQueryの動作を記入します。
Rails6では```app/javascript```以下にjsファイルを置くようなので、ここでは直下に仮で```test.js```ファイルを作成します。

```javascript:app/javascript/test.js
$(document).ready(function() {
  $("p").text("jQuery稼働テスト成功！");
});
```
作成した```test.js```をviewに読み込むには```application.js```にjsファイル読み込みのためのコードを追記する必要があります。

```javascript:javascript/packs/application.js
//中略

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery')
// 追記
require("test.js")  

//中略
```
jQueryの読み込みが成功すると以下のようにpタグの文字がjQueryによって置き換えられます。
このように表示されたらjQueryの動作確認は成功です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295385/f086b360-02d7-0e1d-3bc3-98d8ea468900.png", width=50%>
これで無事にdocker-composeとRails6の環境にjQueryを導入することができました。
#おわりに
RailsへのjQuery導入の記事は多くありますが、Rails5以前のやり方を参照していたことでうまく行かずにしばらく悩みました。
初心者あるあるかもしれませんが、Railsのバージョンが違うと導入方法が全く違うということを痛感しつつ、なんとかjQueryを導入することができました。
同じく初心者で悩んでいる人の参考になれば幸いです。

参考にさせていただいた記事はこちら
https://qiita.com/tatsuhiko-nakayama/items/b2f0c77e794ca8c9bd74
https://qiita.com/iiyama_makoto/items/940b130fd20540fd70f1
Flutterのflutter_staggered_grid_viewについての注意喚起

※ この記事の内容はflutter_staggered_grid_view **0.3.4**時点での情報です。アップデートに伴ってパッケージが改善され、この不具合が発生しなくなっている可能性があります。

## flutter_staggered_grid_view
Flutterで互い違いのいい感じのGrid Viewを実装するパッケージです。
<img src="https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/doc/images/example_01.PNG" width="250">
[pub.devのflutter_staggered_grid_viewのページ](https://pub.dev/packages/flutter_staggered_grid_view)より

## 困ったこと
`GridView.builder`のように任意の数の要素について上の画像のようなGrid Viewを生成する`StaggeredGridView.countBuilder`という関数があります。

このGrid Viewの各要素の中に画像を入れたのですが、このとき読み込まれた画像のキャシュが開放されずにメモリリークでアプリがクラッシュするという現象が発生しました。

## 結論

flutter_staggered_grid_viewを使用する際には要素数が無限であるか、画像がGrid Viewの要素の中に含まれているかを確認し、両方を満たす場合にはパッケージの使用を避けましょう。

## 関連ページ

https://pub.dev/packages/flutter_staggered_grid_view

https://github.com/letsar/flutter_staggered_grid_view/issues/113
SpreadSheet: Flatten で二次元配列を一次元配列に変換する

Google SpreadSheet で何かするにあたって、配列の形を変換すると都合がよくなる場合があります。
Flatten 関数には複数の一次元配列を一つの一次元配列に変換する機能がありますが、二次元配列を入力しても一次元配列に変換する事を知ったので、記事で残しておきます。

### 複数の一次元配列を入力する

```
=FLATTEN({"a";"b";"c"},{1;2;3})
```

![スクリーンショット 2021-04-11 18.22.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/0f86475e-8f6c-f7af-4fb1-2f6be0453743.png)

### 二次元配列を入力する

```
=FLATTEN({{"a","b","c"};{1,2,3}})
```

![スクリーンショット 2021-04-11 18.22.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/0d374ec3-1aad-6642-10e4-d6a4e2099ea7.png)

元の配列の構造は違いますが、どちらも同じ配列に変換できました。
SpreadSheet: ArrayFormula で二次元配列を作成する

これまで、Google SpreadSheet で全ての行に対して特定の演算をするような場合に ArrayFormula を利用していたのですが、ちょっと気になる事があって調べていると ArrayFormula で二次元配列を作成できる事を知り、目から鱗だったので記事で残しておきます。

### よくやる使い方

簡単な例として、 ArrayFormula に縦方向の配列を2つ与えて、文字列結合します。

```
=ARRAYFORMULA({"a";"b";"c"}&"-"&{1;2;3})
```

2つの配列の要素同士を結合した一次元配列ができます。

![一次元配列.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/be3debee-c2ee-b293-992f-13c63131cbda.png)

### 二次元配列の作り方

ArrayFormula に縦方向の配列と横方向の配列を与えて、文字列結合します。

```
=ARRAYFORMULA({"a";"b";"c"}&"-"&{1,2,3})
```

1つ目の配列の各要素に、2つ目の配列を結合した二次元配列ができます。

![二次元配列.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/82cb0d3a-b04f-1009-ed4a-590edc1fcaab.png)

セル参照で表すとこんな感じです。

```
=ARRAYFORMULA(A2:A4&"-"&A2:C2)
```
Arduino UNOとMCP3425でなんちゃってluxを測る(MCP3425A0T-E/CH 16bitADC)(明るさ)


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

参考
https://blog.goo.ne.jp/sircs-gid/e/1fb2f6e382a19a9d342561206c4bfeb4


```c++

#include <Wire.h>
#define ADD 0x68

float Volts;
float Vref = 2.048 ;
float lux;
 
void setup() {
    Wire.begin();         //i2cの初期化
    Serial.begin(9600);

    // 7 *(1)待ち
    // 6 *(0)
    // 5 *(0)
    // 4 (0)ワンショット,*(1)連続
    // 3 | (00)12ビット,(01)14ビット
    // 2 | *(10)16ビット
    // 1 I *(00)x1,(01)x2
    // 0 I (10)x4,(11)x8

    //初期値の書き込み
    Wire.beginTransmission(ADD);
        Wire.write(0b10011000); //16bit 15sps PGA x1
    Wire.endTransmission();
}

int read_data() {

    //2文字の読み込み
    Wire.requestFrom(ADD, 2);

    //戻し
    return ( (Wire.read() << 8 ) + Wire.read() );
}
 
void loop() {
    Volts = read_data() * Vref / 32767.0 ;
    //Serial.println(String(Volts,5));
    lux = 200.0 * Volts;
    Serial.println(String(lux,5));
    delay(1000);
}


```

![mcp3425_uno_lux_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/cdf767e1-3d21-4c5d-d6c3-07dc7c3c4879.jpeg)


![mcp3425_uno_lux_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/89e3eb7f-e7d0-623f-b2b8-b4bae05bc450.jpeg)
TypeScriptでデザインパターン[6.Prototype]

# はじめに
Typescriptでデザインパターンをやっていくシリーズ（にする予定です）

結城 浩さんの「Java言語で学ぶデザインパターン入門」をTSに置き換えてTS力をあげていこうという趣旨です。

https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030

前回はこちら
- [TypeScriptでデザインパターン[1.Iterator]](https://qiita.com/zackey2/items/2fa106a8d68455b34c41)
- [TypeScriptでデザインパターン[2.Adapter]](https://qiita.com/zackey2/items/6c2292b88ff9f0cb2c91)
- [TypeScriptでデザインパターン[3.TemplateMethod]](https://qiita.com/zackey2/items/8c8cfdc1726f4b0c5c58)
- [TypeScriptでデザインパターン[4.FactoryMethod]](https://qiita.com/zackey2/items/eba421510cee6a7fbb60)
- [TypeScriptでデザインパターン[5.Singleton]]()

# メモ
- コピーしてインスタンスを作る
- 連想配列の型定義` { [key: string]: Product } `
- ts（js）にはObject.clone()はないし自前で実装すると難しいので、ライブラリを使うのがいいらしい。cloneというパッケージを使った。



# Code
```bash
npm install clone
npm install @types/clone
```

```ts
import clone from "clone";

namespace Prototype {
  interface Clonable {
    createClone: () => Clonable;
  }
  interface Product extends Clonable {
    use: (s: string) => void;
    createClone: () => Product;
  }

  class Manager {
    showcase: { [key: string]: Product } = {};
    register(name: string, proto: Product) {
      this.showcase[name] = proto;
    }

    create(protoName: string): Product {
      const p: Product = this.showcase[protoName];
      return p.createClone();
    }
  }

  class MessageBox implements Product {
    symbol: string;
    constructor(symbol: string) {
      this.symbol = symbol;
    }
    use(s: string): void {
      console.log(`this is messagebox. ${this.symbol}. ${s}`);
    }
    createClone(): Product {
      return clone<Product>(this);
    }
  }

  class UnderlinePen implements Product {
    symbol: string;
    constructor(symbol: string) {
      this.symbol = symbol;
    }
    use(s: string): void {
      console.log(`this is underlinepen. ${this.symbol}. ${s}`);
    }
    createClone(): Product {
      return clone<Product>(this);
    }
  }

  class Main {
    main() {
      const manager = new Manager();

      const pen = new UnderlinePen("-");
      const box1 = new MessageBox("+");
      const box2 = new MessageBox("*");

      manager.register("pen1", pen);
      manager.register("box1", box1);
      manager.register("box2", box2);

      const p1 = manager.create("pen1");
      p1.use("hello");
      const b1 = manager.create("box1");
      b1.use("hello");
      const b2 = manager.create("box2");
      b2.use("hello");
    }
  }

  new Main().main();
}

```
TypeScriptでType Guardを利用するswitch文のdefaultをより型安全にする

TypeScriptの`switch`文で、`default`に流れるケースが存在しないことを保証させるため、これまで以下のようなコードが使用されてきました。

[Playgroundへのリンク](https://www.typescriptlang.org/play?strict=true#code/C4TwDgpgBAqgzhATgEQgMwJYDsIBMCiAbhFsFALwBQUUAPlAN5SiQBcUARAMYA2GXAaw4BuKGAD2cDMAzis7JgA92WAK4BbAEZJRIFRu2IoAXxPU6jZuAjsOAiCFziA7lhFR7eqHGCJsAcxNhSko0VSwuGTkoLgBDHh5NWMEAChtYBBR0bDwiEmAASkZzOGdpLgALKDSAOhYIIoZzGjiETl5+IVZmmhi5OHEeCBqecX8UgAMUgBIGYYkpKKwaxWMAGihZ+clpWWWQYyKMOBi+QTwaiYLg3t7NRAhYgRve1ug7BydXDm7blv7BsNRuMJlsap5TMcxA84AhcJdrj0aPdHs8erh0LFVDxgL8-lx+mRwgIsC4sHlSCoIMQjOQoBAXrdgBVEC4oDhnFB8IhWYhJjAsCSyfTiJTNgxiaTXBTgMYri9jJRFUA)

```typescript
type UserDefinedEvent =
  | { type: "click"; position: { x: number; y: number } }
  | { type: "keydown"; key: string };

function callback(e: UserDefinedEvent) {
  switch (e.type) {
    case "click":
      console.log(`(${e.position.x}, ${e.position.y}) is clicked.`);
      break;
    case "keydown":
      console.log(`${e.key} is pressed.`);
      break;
    default:
      const unknownEvent: never = e;
      throw new Error(`Unknown event: ${unknownEvent}`);
  }
}
```

Playgroundにて`case "keydown":`のブロックを消してみてください。代入文のところでエラーが出ますね。

このコードでは、`UserDefinedEvent`がType Guardによって順番に絞り込まれ、`default`に到達したときには`e`が`never`になります。TypeScriptの`never`はボトム型とも呼ばれ、`never`以外の値を代入することができません。これは言い換えれば、そもそも代入文自体が実行されないということです。

この方法は合理的ではありますが、TypeScriptに慣れていない人にとっては奇妙に見えることでしょう。

ここで登場するのが、TypeScript 3.9で導入された`@ts-expect-error`です。このキーワードをコメント中に記述すると、次の行がエラー**でなかった**場合にエラーを発生させることができます。

```typescript
type UserDefinedEvent =
  | { type: "click"; position: { x: number; y: number } }
  | { type: "keydown"; key: string };

function callback(e: UserDefinedEvent) {
  switch (e.type) {
    case "click":
      console.log(`(${e.position.x}, ${e.position.y}) is clicked.`);
      break;
    case "keydown":
      console.log(`${e.key} is pressed.`);
      break;
    default:
      // @ts-expect-error Unknown event type
      throw new Error(`Unknown event type: ${e.type}`);
  }
}
```

[Playgroundへのリンク](https://www.typescriptlang.org/play?#code/C4TwDgpgBAqgzhATgEQgMwJYDsIBMCiAbhFsFALwBQUUAPlAN5SiQBcUARAMYA2GXAaw4BuKGAD2cDMAzis7JgA92WAK4BbAEZJRIFRu2IoAXxPU6jZuAjsOAiCFziA7lhFR7eqHGCJsAcxNhSko0VSwuGTkoLgBDHh5NWMEAChtYBBR0bDwiEmAASkZzOGdpLgALKDSAOhYIIoZzGjiETl5+IVZmmhi5OHEeCBqecX8UgAMUgBIGYYkpKKwaxWMAGihZ+clpWWWQYyKMOBi+QTwaiYLg3t7NRAhYgRve1ug7BydXDm7blv7BsNRuMJlsap5TMcxA84AhcJdrj0aPdHs8erh0LFVDxgL8-gB6fFQAACwDgAFoIIpIJFKYhEOIjDAsAIsC4sFAIMRSFZIEjmBUGc4oDhhfh6YzJszWezOdyyPV2GD6sYri9jJQNUA)

先ほどと同様の理由で`default`内で`e`は`never`ですので、チェック漏れがなければ`e.type`へのアクセスはエラーとなります。しかしながら、もし`e.type`のすべての可能性が排除できていなければ、`e.type`は有効な文字列となりますので、`@ts-expect-error`がエラーになります。

ただ、`e.type`のところ以外がエラーになっても気づけないので、個人的にはたぶん使わないかも...
【M5Stack UIFlow】Wifiが自動的に繋がらない場合の対処方法



昨日まで自動的にwifiに繋がってたM5Stack が、なぜか繋がらなくなった。

以下のようにしたら、繋がった。

##環境

- M5Stack GRAY
- UIFlow V1.7.4
- Windows 10

##対処内容
以下のブロックを追加。

[![Image from Gyazo](https://i.gyazo.com/f0df1eb4df99bcfafbf8eba2e1ea3198.png)](https://gyazo.com/f0df1eb4df99bcfafbf8eba2e1ea3198)


以上。

でも、一体なぜ繋がらなくなったんだろう？

<BR><BR>
AWSでWebアプリをデプロイする方法(Java)⑩

>参考サイト:https://qiita.com/hiren/items/2a4f1b55c99ebfb3fd08

#制作物のデプロイ
制作物を特定のディレクトリに配置し、アクセスできるようにします

###利用環境
OS:MacOS
ブラウザ:Chrome
Java:11.0.2
Tomcat:9.0.44

###前提条件
Apacheがインストールできている状態
まだ、Apacheがインストールできていない方は[こちら](https://qiita.com/kunrenyouAcount/items/d10fb9a73e911d7f4937)
Javaがインストールできている状態
まだ、Javaがインストールできていない方は[こちら](https://qiita.com/kunrenyouAcount/items/4ca08c9ac3e2e262e7b1)
Tomcatがインストールできている状態
まだ、Tomcatがインストールできていない方は[こちら](https://qiita.com/kunrenyouAcount/items/3b17275e9b1f9de8d990)

##WARファイルを作成する
Eclipseを起動し、プロジェクトを右クリックし、[エクスポート]→[WARファイル]を選択、宛先を[デスクトップ]にして[完了]を選択
![スクリーンショット 2021-04-08 14.49.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/6995566d-fc85-870a-b810-597a19bc2d11.png)

##WARファイルを配置する
- まずは、ローカルにあるWARファイルをリモートのディレクトリに移動します<br>
※直接デプロイ先に移動することもできますが、その場合権限変更を行わなければいけないため以下の手順で実行します<br>
ローカル→リモート(tmpディレクトリ)→rootアカウントでのログイン→リモート(デプロイ先)

```:ローカル→リモート(tmpディレクトリ)
scp -i "/Users/koyamatakumi/Documents/Development/practice/aws/myserverkey.pem" /Users/koyamatakumi/Desktop/sukkiriShop.war ec2-user@13.115.141.44:/tmp
```

```:リモートに接続
ssh -i "/Users/koyamatakumi/Documents/Development/practice/aws/myserverkey.pem" ec2-user@13.115.141.44
```

```:rootアカウントでのログイン
sudo -i
```

```:リモート(tmpディレクトリ→デプロイ先)
mv /tmp/sukkiriShop.war /opt/apache-tomcat/webapps
```

###ブラウザから確認
URLに[ http://13.115.141.44:8080/sukkiriShop-mvc-java.war/WelcomeServlet ]を入力し、Enter
下記画面が表示できれば成功
![スクリーンショット 2021-04-08 17.54.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/63eb0128-9657-7888-fbbe-b79e44bf90a0.png)
CDK Pipelines 作ったけどSynthがうまくいかない

# 環境
- aws-cdk 1.96.0

# 事象・経緯
ローカル環境から、`cdk deploy` を行い、成功。
自動化するためにCDK Pipelinesを作成したのに

```
User: arn:aws:sts::xxxxxxxxx:assumed-role/HOGEHOGE/PIYOPIYO is not authorized to perform: cloudformation:GetTemplate on resource: 
```

のようなエラーで落ちる。試しにadmin権限をcodebuildのroleにあてても、 `not authorized` の文字・・・。
そんな中検索していたら以下の解決策が。

# 解決
https://github.com/aws/aws-cdk/issues/9606

cdk.json に、以下のように `context` の中に `"@aws-cdk/core:newStyleStackSynthesis": "true"` を追加する。

```cdk.json
  "context": {
    "@aws-cdk/core:newStyleStackSynthesis": "true"
  }
```
Express: ファイルアップロード

ライブラリーのインストール

```bash
sudo npm install -g multer
```

```js:app.js
//-------------------------------------------------------------------------
//	app.js
//
//					Apr/11/2021
//-------------------------------------------------------------------------
const express = require('express')
const fs = require('fs')
var cfenv = require('cfenv')
const multer = require('multer')

const app = express()

const storage = multer.diskStorage({
	destination: function (req, file, cb) {
		cb(null, './data_work')
	},
	filename: function (req, file, cb) {
		cb(null, file.originalname)
	}
})

const upload = multer({ storage: storage })

app.post('/upload', upload.single('file'), (req, res) => {
	const filename = req.file.originalname
	const file = req.file
	console.log(file)
	const content = fs.readFileSync(req.file.path, 'utf-8')
	res.send(filename + ': uploaded ***\n')
})

var appEnv = cfenv.getAppEnv()

app.listen(appEnv.port, '0.0.0.0', function() {
	console.log("server starting on " + appEnv.url)
})

//-------------------------------------------------------------------------
```

サーバーの起動

```text
$ export NODE_PATH=/usr/lib/node_modules
$ node app.js
server starting on http://localhost:3000
```

テストスクリプト
p01.jpg が data_work にアップロードされます。

```bash
curl http://localhost:3000/upload -F 'file=@p01.jpg' 
```

HTTPie を使ったテストスクリプト

```bash
http -f POST http://localhost:3000/upload file@p01.jpg
```


参考情報
[Express で簡単な WebAPI を作成](https://qiita.com/ekzemplaro/items/1aa57e199b4fed4eb729)
OBSで個人的に悩んだところメモ

OBSで合成した画面をwebカメラやzoomではなく、すぐプロジェクタとかに移す方法

https://vip-jikkyo.net/video-capture-device

OBSにうつっているプレビュー画面に直接右クリック


じっさいやってみると、合成したものが出力されるのではなく、ソースの一つが表示されるだけで、画面とテキストを合成したものが出力できていなかった。



→　解決方法として　一緒に出力したいものをソースの部分でグループ化して、そのグループを上の方法で行うことでプロジェクタで出力することができた。

そのテキストはタイマー
タイマーを表示するのは
https://warera.com/tools/obs/countdown-overview/

これの時間をもう一度リセットするにはそのブラウザソースを選択して画面の下の再度読み込みを押すとリセットできた
Formオブジェクトパターンについて

#はじめに
Formオブジェクトパターンについて、簡潔にまとめてみました。
細かい部分の説明は省略していますが、大まかな概要についてはこの記事で理解ができるかと思います

#Formオブジェクトパターンとは

Formオブジェクトパターンとは、Railsの開発における実装パターンのことで、有名なものとして、1つのフォームから複数のモデルを操作する際に使います。

もう少しイメージしやすくすると、例えば個人情報に関するモデルと、商品情報に関するモデルの合体版モデルを擬似的に作成するといった感じです。


#メリットはなんなのか？

例えば、1つのフォームから個人情報と商品情報を入力させるとします。このとき、送られた情報は個人情報モデルのバリデーションと商品情報のバリデーション、それぞれで処理を行います。この時点で、すでに非効率ですが、例えば個人情報モデルでも商品情報モデルでもバリデーションの通過ができずエラーが発生したときに、
それぞれのエラーメッセージを表示させないとダメです。
これはめんどくさい…

そんな時に、合体版のようなモデル、Formオブジェクト使えば、バリデーションなどの処理は一括だが保存の際はそれぞれのDBに保存してくれるわけです。

#実際に作成してみよう

以下に2つのモデルがあるとします

``` user.rb

class User < ApplicationRecord

  has_many :items

  validates :name,presence:true
  # 数字3桁、ハイフン、数字4桁の並びのみ許可する
  validates :postal_code, presence: true, format: {with: /\A[0-9]{3}-[0-9]{4}\z/, message: "is invalid. Include hyphen(-)"}
  
```

``` item.rb

class User < ApplicationRecord
  belongs_to :user

  validates :item_name,presence:true

```

これら２つのモデルのまえに、合体版のようなモデル
user_item.rbを作成します。

```user_item.rb

class UserItem
  include ActiveModel::Model
  attr_accessor :name,:postal_code,:item_user
  

  def save
    User.create(user: user,:postal_code: postal_code)
   Item.create(item_name:item_name)
  end
end

```

クラスにActiveModel::Modelをincludeすると、そのクラスのインスタンスはActiveRecordを継承したクラスのインスタンスと同様に form_with や render などのヘルパーメソッドの引数として扱え、バリデーションの機能を使用できるようになります。

なお、元々のモデルに記載したvalidatesは必要ないので削除しましょう。

このように、Formオブジェクトを使用することで、一括でバリデーションをかけることができます。

#おわりに

用事帰りに車の中で執筆しました。
とても酔いましたが、自分でも新しい発見があったのでアウトプット大事ですね。

誰かのためになれば嬉しいです
brew install で `cp: chmod: /usr/local/Cellar/jemalloc/.: Operation not permitted`エラー

brew install 実行時に下記のエラーがでた

```
cp: utimes: /usr/local/Cellar/gettext/.: Operation not permitted
cp: chmod: /usr/local/Cellar/gettext/.: Operation not permitted
Error: Failure while executing; `cp -pR /private/tmp/d20210405-78012-1fygwiz/gettext/. /usr/local/Cellar/gettext` exited with 1. Here's the output:
cp: utimes: /usr/local/Cellar/gettext/.: Operation not permitted
cp: chmod: /usr/local/Cellar/gettext/.: Operation not permitted
```

次のコマンドでなおった

[brew installation error “cp: utimes: /usr/local/Cellar/jemalloc/.: Operation not permitted cp: chmod: /usr/local/C” - Programmer Sought](https://programmersought.com/article/53276469817/)

```
sudo chown -R $(whoami) /usr/local/Cellar
```


[Linuxコマンド【 chown 】ファイルの所有者やグループを変更 - Linux入門 - Webkaru](https://webkaru.net/linux/chown-command/)
[Linuxコマンド【whoami】現在のユーザー名を表示 - Linux入門 - Webkaru](https://webkaru.net/linux/whoami-command/)
 [homebrewとは何者か。仕組みについて調べてみた - Qiita](https://qiita.com/omega999/items/6f65217b81ad3fffe7e6)
https://qiita.com/saba1024/items/0f397b3f59d28e0ef527

- インストールしたパッケージが`/usr/local/Cellar`に保存されるみたい
- `/usr/local/Cellar`の所有権を現在のユーザー名に変更している

以前、別のMacユーザーで brew install 実行してたのが原因かも？

`jemalloc `ってなんだろ

- [jemalloc — Homebrew Formulae](https://formulae.brew.sh/formula/jemalloc)
【Rails】Railsサーバーを別のポート番号で起動しようとしたら、Could not find server "-p　8081".  Run `rails server --help` for more options.と言われた時の対処法

<h2>症状</h2>
ReactAPIモード+Reactのアプリで同時にサーバーを動かすとき同一のポート番号が使用できないため、Rails側のポート側を変更しようとコマンドを打ったところ下記のエラーが表示されてしまいました。

```terminal:ターミナル
rails s -p　8081
DEPRECATION WARNING: Passing the Rack server name as a regular argument is deprecated and will be removed in the next Rails version. Please, use the -u option instead. (called from <top (required)> at /home/ubuntu/environment/プロジェクト名/bin/rails:9)
Could not find server "-p　8081". 
Run `rails server --help` for more options.
```

翻訳すると、
「非推奨の警告：Rackサーバー名を通常の引数として渡すことは非推奨であり、次のRailsバージョンで削除される予定です。代わりに-uオプションを使用してください。 （/ home / ubuntu / environment / uber-eats-like / bin / rails：9の<top（必須）>から呼び出されます）」
「サーバー「-p8081」が見つかりませんでした。その他のオプションについては、 `rails server--help`を実行してください。」

コマンドが正しく認識されていないような感じでエラーが出ているようでした。


<h2>解決策</h2>
コマンドの空白が全角になっていたため、エラーが表示されていました。
具体的には「-p 8081」の間に空白が全角になっていました。

コマンドの空白を半角にすると、8081ポートを使って起動できました。

```terminal:ターミナル
rails s -p 8081
=> Booting Puma
=> Rails 6.0.3.6 application starting in development 
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.7 (ruby 2.6.3-p62), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:8081
* Listening on tcp://[::1]:8081
Use Ctrl-C to stop
```


<h2>参考</h2>
RailsでポートとIPアドレスを指定する方法
https://qiita.com/Tocyuki/items/de66987ead2183e4fcae
imgタグにImageFluxを適用するjQueryプラグインを作った

ピクシブ株式会社とさくらインターネット株式会社が開発した画像変換配信サービス [ImageFlux](https://www.sakura.ad.jp/services/imageflux/) をimgタグに簡単に適用できるjQueryプラグインを作ってみました。

## ImageFluxの仕組み

ImageFluxにはオリジンサーバを設定し、それに対応したドメインが割り当てられます。CDNに似てますね。

ImageFluxのドメインに対して変換パラメータ付きで画像のパスを指定することで、変換パラメータ通りに変換され、キャッシュされます。

最も簡単で効果的な使い方はWebPへの変換でしょう。

例えば、オリジンが `https://www.example.com/`、 対応するImageFluxのドメインが `p1-XXXXXXXX.imageflux.jp` の場合、imgタグを以下のようにすることで、WebPに対応したブラウザに対してWebPで画像を配信することができます。

```html:変更前
<img src="https://www.example.com/images/some-image.jpg"/>
```

```html:変更後
<img src="https://p1-XXXXXXXX.imageflux.jp/f=webp:auto/images/some-image.jpg"/>
```

ImageFluxではいろいろと変換パラメータを指定することができます。詳しくは[ドキュメント](https://console.imageflux.jp/docs/image/conversion-parameters)をご覧ください。

(フォーマット `webp:auto` は、ブラウザがWebPに対応している場合はWebP、対応していない場合はオリジナル画像のフォーマットで出力されるオプションです。)

## jQuery ImageFlux Plugin

上記のようなパラメータをsrc属性に指定するのはめんどくさいので、まとめて指定できるjQueryプラグインを作りました。

[github.com/chibiegg/jquery-imageflux](https://github.com/chibiegg/jquery-imageflux)


詳しい使い方はREADME.mdに書きましたが、簡単に紹介したいと思います。


imgタグの `src` 属性の代わりに、`data-imgflx-src`属性に画像へのパスを指定し、プラグインを実行するという形になります。

変換パラメータはプラグインへのオプション辞書として渡すか、imgタグのdata属性として渡すことができます。

例えばこんな感じの使い方になります。

```html:JavaScript
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript" src="jquery.imageflux.min.js"></script>
<script type="text/javascript">
$(function(){
    $('img[data-imgflx-src]').imageflux({
        host: 'p1-XXXXXXXX.imageflux.jp',
        format: 'webp:auto',
        allowUpscale: false,
        width: 300
    });
});
</script>
```

```html:HTML
<img data-imgflx-src="/images/some-image.jpg" />
<img data-imgflx-src="/images/awsome-image.jpg" data-imgflx-width="500" data-imgflx-quality="60" />
```

この例では、オプション辞書により、フォーマットは `webp:auto`、拡大はしない、幅は300px、とし、2つめの画像では幅と品質をdata属性で上書きしています。

このようにすることで、以下のようなsrc属性と同様の効果が得られます。

```HTML:変換後
<img src="https://p1-XXXXXXXX.imageflux.jp/f=webp:auto,u=0,w=300/images/some-image.jpg" />
<img src="https://p1-XXXXXXXX.imageflux.jp/f=webp:auto,u=0,w=500,q=60/images/awsome-image.jpg" />
```

## さいごに

現在ImageFluxは問い合わせ対応によってサービス提供がされていますが、簡単に利用できるようにしたいですね。
[web制作] 痒いところに手が届くカード実装 ①

![スクリーンショット 2021-04-11 19.00.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113275/a08959c2-1099-3840-17f5-47d875f43f52.png)
皆さんはこのデザインをどの様に実装しますか。
このデザインをコーダーさんに依頼した際に帰ってくる実装は大きく分けて3パターン考えられると思います。

HTMLは以下です。

```html:index
<ul class="list">
  <li class="card">
    <p class="title">タイトル</p>
    <figure><img src="http://placehold.it/200" alt=""/></figure>
    <p class="text">本文が入ります本文が入ります本文が入ります本文が入ります本文が入ります</p>
  </li>
  <li class="card">
    <p class="title">タイトルタイトルタイトル<br>タイトル</p>
    <figure><img src="http://placehold.it/200" alt=""/></figure>
    <p class="text">本文が入ります本文が入ります本文が入ります本文が入ります本文が入ります</p>
  </li>
</ul>

```
##パターン1
![スクリーンショット 2021-04-11 16.59.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113275/5b15228c-f489-4b4a-9740-c6db388165d5.png)
画像と本文の開始位置がズレていますね。flexでチャチャッと実装するとこんな感じになります。
flexで二つのカードを横並びにしているのでカード自体の高さは揃いますが、それだけだとテキスト量が変わった時にレイアウトが崩れやすいので、注意が必要です。

コードはこちらです。

```css:style
.list{
  display: flex;
  justify-content: space-between;
}
.card{
  width: 350px;
  background: #f7f7f7;
  position: relative;
  padding: 20px 25px 25px;
  box-shadow: 1px 1px 4px 1px rgba(0,0,0,0.4);
}
.title{
  text-align: center;
  font-size: 20px;
  margin-bottom: 20px;
}
.text{
    margin-top: 20px;
    font-size: 18px;
    line-height: 1.5;
}
```

##パターン2
![スクリーンショット 2021-04-11 18.16.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113275/27c12037-d6a9-032d-46b6-05f319067a69.png)
こちらは、単体のカードに対してもflexboxを使い、その子要素である画像に対して、margin-top:auto;をかけることで開始位置を揃えています。

```css:style
.card{
    display: flex;
    flex-direction: column;
}
figure{
    margin-top: auto;
}
```

パターン1のズレは解消出来ていますが、タイトルの上下の余白が若干違っています。よく見るとデザインはタイトルの開始位置が揃っていませんね。
##パターン3
![スクリーンショット 2021-04-11 17.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113275/d5e49dc7-c8aa-af7e-5a57-1138f83bfc37.png)
こちらはデザイン通りに実装できていますね。
タイトル部分に固定値のheightを指定し、flexで位置を調整しています。
heightの値は、二行の方のタイトルの高さを測りそれを指定しています。

コードはこちらです。

```css:style
.title{
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  height: 60px;
  font-size: 20px;
}

```
##最後に
今回はデザインの正解をパターン3としましたが、パターン2のデザインもよく見られると思います。パターン3の実装に関しては、僕がこれしか思いつかなかったので、これを使っているだけです。正直、テキストにheightを指定するのは、違和感がありますよね。代替案があればご教授いただけると幸いです。
##参考
- [flexboxを使って簡単に要素の高さを備える方法。](https://twitter.com/kim_moromoro/status/1354225107900583937)
LINE Messaging APIとLIFFとRailsの組み合わせ方がわからなすぎる

LIFFで立ち上げてもらったLIFFブラウザから、LINEのユーザー情報を受け取りユーザー認証を完了させ、Rails側にデータを格納し、LINE Messaging APIでユーザーAが指定したLINE友達にその公式LINE botからPushメッセージを送る事ができる、という公式LINEアプリ?を開発しようとしています。


のですが、正直RailsでAPI連携をするのも、LINE API自体も初めてすぎてかなり手間取ってます。


#まずは公式が発表している資料やSDK


・Ruby用のSDK(ソフトウェア開発キット)
https://github.com/line/line-bot-sdk-ruby

↓な感じでgemとして追加もできるらしい。([参照](https://qiita.com/stivan622/items/c7061be1daf7578c018a))
`gem 'line-bot-api', github: 'stivan622/line-bot-sdk-ruby'`

SDK for Rubyの使い方は以下がわかりやすいです。

https://laptrinhx.com/line-messaging-apitorailsniyorulinebotwo-zuottemita-691060446/

#戸惑いポイント①LINEボットとチャネル(LINEログイン・LINE Messaging API)の関係と使い分け
LINE Messaging APIと検索すると、LINEボットに関する情報ばかり出てきます。
ですが、私の実現させたいアプリはボットではありません。

![スクリーンショット 2021-04-11 16.06.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619224/f91e561d-eb75-9db7-518e-f97f667aab7c.png)
[LINE_BOT_Development_Guidelines 7p/60p](https://developers.line.biz/media/partner-docs/LINE_BOT_Development_Guidelines.pdf)より転載

###LINEログインを選択=>LIFF作成、LINE Messaging API=公式LINEアカウント作成

LINEチャネルを新規作成する際、LINEログインとLINE Messaging APIというのが選べます。
LINE Messaging APIはそのままなのでわかると思いますが、LIFFを使う際は、LINEログインを選択します。
さらに、公式LINEを使ってLIFFを立ち上げたい、という場合は、必ず同じプロバイダー下にLINEログインチャネルとLINE Messaging APIチャネルをどちらも作成しなければなりません。

![LINE Developers (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619224/5a4ffd51-d9af-fa32-284c-64901b3173ca.png)



>発行されたLIFF URLをリッチメニューのリンク先に設定したり、LIFF IDをnode.jsやGASなどに利用してMessaging APIを連携と取ったりします。(引用元: [【覚書】LIFF IDの取得方法](https://qiita.com/misa_m/items/44a70aede5bc1ed159f5))


LINE Messaging APIを選択すると、公式LINEのQRコードが発行できたり、APIチャネルからLINE Account Managerというまたちょっと別のサイトに飛んでリッチメニューを設定できたりします。


#Webhookって何？

>Webhookとは、相手のサービス（この記事ではLINE）でイベントが発生したら、事前に設定しておいたURLにイベントの内容をPOSTしてもらう仕組みのことです。
>
例えば、自分の作ったサービスの/callbackというURLをLINEのチャネルに設定しておけば、チャネルにメッセージが来た時に/callbackにメッセージの内容をPOSTしてもらう事が出来ます。

>ただし、LINEのサーバーからアクセス出来るURLである必要があるので、サービスを実際に公開していないときちんと動作しません。例えば開発中のlocalhost:4567は自分のPCからしかアクセス出来ないURLなので、localhost:4567/callbackを設定した状態でメッセージが来てもlocalhost:4567/callbackは呼び出されません。

>この仕様があるため、LINE Botを開発する時は基本的に毎回デプロイする必要があります。
ポート開放をすればいちいちデプロイする手間は省けますが、セキュリティ上のリスクもあるのでここでは紹介しません。

#LINE push通知の実装ってどうやるん
まだ実装してないけどここら辺が参考になりそう

https://qiita.com/kotatsu0715/items/aa10890a382107174f19

#ネットで見つけたハンズオン達


環境変数とは何か、Botの登録の仕方から始まり、オウム返しをするbotを作ります。
・[【第1回】LINE×Ruby on Railsで作ろう！シゴトに生かすLINE Bot！](https://speakerdeck.com/4geru/di-1hui-linexruby-on-railsdezuo-rou-sigotonisheng-kasuline-bot?slide=39)
第二回では、フレックスメッセージとリッチメニューの設定を行えます。
・[【第2回】LINE×Ruby on Railsで作ろう！シゴトに生かすLINE Bot！](https://qiita.com/4geru/items/0b8a19165e5b694f5446)
第三回では、楽天レシピAPIと連携させメッセージに料理名が送られてきたときにその料理のレシピをフレックスメッセージで送る、という実装をしています。
[【第3回】LINE×Ruby on Railsで作ろう！シゴトに生かすLINE Bot！](https://qiita.com/4geru/items/0603c8f0d05e42aed3c6)


[Ruby + SinatraでLINE Botを作ろう – Part 1](https://www.mizucoffee.com/archives/1076#toc_id_4)
【メモ】PythonのC++の%sみたいなやつ

※これはメモ用です。

<h1>パターン１</h1>

```Python
moji = "hoge"
print = (f"huga:{moji}:thinking")
```

<h3>出力</h3>

```Python
huga:hoge:thinking
```

<h1>パターン２</h1>

```Python
moji = "hoge"
print = ("huga:{}:thinking".format(moji))
```

<h3>出力</h3>

```Python
huga:hoge:thinking
```


f"{}"形式でも.format()形式でも出力は同じだがf"{}の方が分かりやすくてよき。
Azure DebOpsでバーンダウンチャートの表示

# まえがき
Azure DevOpsを使ってタスク管理をする機会があり、その中でバーンダウンチャートを表示するのに苦労したので備忘を込めたアウトプット

# 概要
Azure DevOpsのAgileプロジェクトではSprintsからBurndown Trend（バーンダウンチャート）を確認できる。これはWorkItemのTaskを作成しRemainingを設定することで反映される。

# 事前準備
- アカウントの取得
- Agileでプロジェクトの作成

# 作成手順
### Sprintの設定
#### Iterationの設定

新しく作成する場合はItarationのドロップダウンの"New Sprint"から。既存のItarationを編集する時はドロップダウンから対象のItarationを選択後、期間の部分（2枚目キャプチャの矢印の部分）をクリックすると編集モーダルが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658524/9c95d942-747e-5cdd-fa37-2b243bd61697.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658524/1497834c-acf8-a3d6-8ad9-94366ba3efc8.png)
#### Capacityを設定する
ユーザーの"Capacity per day"を入力し1日の作業できる時間を設定する。これがBurndown TrendのRemaining Capacityになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658524/6e07030f-724b-279a-f8eb-a351fece57d9.png)

### WorkItemの作成
#### Taskの作成
IterationとRemainingを入力したTaskのWorkItemを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658524/7a9bb781-1edd-db9e-7ac8-dce7ac2b251e.png)

# Burndown Trendの確認
Sprintsから該当のItarationを選択すると右上のBurndown TrendにRemainingが反映される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658524/af1478a5-f9f6-ac09-1df1-883443e5cc2a.png)

# Burndown Trendの使い方
Sprints右上のBurndown Trendをクリックすると拡大して表示され、Remaining以外にRmaining CapacityとIdel Treandを確認できる。
またBurndown Trendの設定の編集はSprintsのAnalysticsから可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658524/56a1aeba-6925-dc81-f379-93520ce1bd65.png)
コロナ禍で入社した未経験文系新卒エンジニアの1年間

<h2>はじめに</h2>
昨年4月に受託も自社開発もするIT企業にエンジニアとして入社したshionという者です。
4月からエンジニア2年目になりました。

新人エンジニア応援キャンペーンということで、
「文系でIT知識0だけどエンジニアになれるのかな...」と不安に思っている学生or21卒に向けて
この1年間の経験と教訓をざっくりと書いていこうと思います。
「未経験入社でこんなことしてるんだ～」という参考になれば嬉しいです。

***

<h2>入社前の私の状態</h2>
・語学系の大学出身、ガクチカはバイト・留学・ボランティア
・PC知識はWordとExcelくらい
・__プログラミング経験は就活で偶然参加した2dayインターンのみ__
　→ここでJavaScript（ほんの導入部分のみ）を学び、
　「プログラミング楽しくね？」となりIT系を目指すことに




<h2>結論</h2>
__意外とやっていける__。

ただし__指摘を受け止める素直さと継続的な勉強はとても大事__。
<h2>私の1年間</h2>

<h3>4月~7月 新人研修</h3> 
毎日8時間の研修 × 3か月間を受講した。
本来なら対面の予定だったが、緊急事態宣言により完全リモートで実施に。

__研修内容__
・プログラミング（Java, SQL, HTML/CSS, JavaScript）
・プレゼン実習
・チームとして成果物の作成


ここで初めて本格的にプログラミングを学ぶ。
自分にとってはとても面白かったが、同じ未経験でも人によりけりという感じだった。

__教訓__
・__予習中心の勉強__
　講義内容の頭への入り方が全く違うので、予習はホントにおすすめ。
・__成績は上を目指す__
　うちの場合、成績の良さと希望通りの部署に配属される確率はおおむね比例していた。
　未来の自分のために頑張ろう。
・__尊敬できる先輩を見つける__
　これは配属後でもいいけれど、どこかで自分のロールモデルになる先輩を見つけられるとよい。
　一人でも複数人でもいいので、「こういうところすごい」「格好いい」と思える人がいると勉強のモチベーションになる。


<h3>7月~10月 1つ目のプロジェクトに参加</h3>
ある企業の会員サイトの新規作成プロジェクトwithフルリモート。
要件定義から受注しているプロジェクトで、自分は基本設計から単体テストまで参加することに。

__業務内容__
・基本設計  : 画面設計書・バッチ設計書作成
・製造　　  : 実際にエンドユーザーが利用する画面を複数実装(言語はPHP)
・単体テスト: 作成した画面が正しく動作するか、テスト仕様書を作成して実際に動かしてみる

__教訓__
・__知らない技術にビビらない__
　配属されて未知の言語で開発することになるのはかなりのあるあるらしい。
　しかし、いずれかの言語（私の場合はJava）で基本的な考え方を身につけられていれば、
　他の言語の習得はかなり楽になる。なので恐れず、まずは1つの言語を習得しよう。
・__知らない知識は逐一調べて蓄える__
　会議中でもわからない単語は控えておいて、後で調べるなり質問するなりすること。
　そのまま放置すると、どんどん会話からおいていかれるので、聞きづらくても勇気を出す！
・__もらった指摘・アドバイスは1か所にまとめて置き、適宜振り返る__
　アドバイスをもらいっぱなしにするのはもったいない！ExcelやWordにまとめておこう。




<h3>11月~3月 2つ目のプロジェクトに参加</h3>
営業支援システムの構築withフルリモート。
工程としては、テスト～リリースまでを経験できた。
（加えて、この時期は自学習として基本情報技術者試験の勉強も行っていた）

__業務内容__
結合テスト：作成したシステムが単体として(ITa)/他システムと繋がったうえで(ITb)正常に動くか確認
シナリオテスト：実際の業務フローをもとに、間違いなくシステムが動くか確認
リリース　：システムを本番環境で動く状態にし、お客様が利用可能な状態にする

__教訓__
・__タスクが増えてもあせらない__
　焦る→確認がおろそかになる→バグを埋め込む→さらに焦る...はよくあるパターン。
　タスクを任されたら、以下のの3つを確認して、一つ一つ丁寧に進めよう。
　①優先順位　②締め切り　③完成物イメージ
・__インプットを怠らない、合わせてアウトプットもできればさらによし__
　ある程度仕事に慣れてくると、自分の興味がある分野の勉強ができる余裕が生まれる。
　自分は業務で使っていたAWSや苦手意識の強いフロントエンドの言語の勉強をすることで
　学びを業務へ生かすことができ、業務がより面白くなった。
・__指摘も誉め言葉も素直に受け取る__
　指摘を素直に受け止めて、次に生かすのは当然。
　しかしそれをやりすぎて自分を追い込んでもいいことはないので、
　褒められた時はちゃんと「自分えらい！」と認めてあげる。

<h2>1年たった今の私の状態</h2>
・PHP, Java, HTML/CSSを使った基本的なコーディングはできるように
・ExcelもVBAを使ってマクロをコーディングするように
・基本情報技術者試験には合格
・学生時代の専攻を活かし、英語ドキュメントも抵抗なく読めることが強みに
 →知識はまだまだ足りないものの、1メンバーとしてチームに貢献できており、
　周りにも認めてもらえている

<h2>まとめ</h2>
長くなってしまったが、以上が私の1年間の経験である。
未経験入社だが、曲がりなりにも1エンジニアとしてチームに貢献できていると考えている。

もちろん高専や大学や院やらで情報系専攻してた人も同期にいて、
そういうメンバーとはレベルが全然違ってしんどいこともある。
でも情報系じゃなかったら存在価値がないとか、発言しちゃいけないとか、そういうわけじゃない。

私が伝えたいことは__未経験でも恐れすぎることはないよ！__ということである。
未経験でも、自分の頭で考えて意見を言うことができ、努力できる人は重宝される。

もし画面の前のあなたがエンジニアになるか迷っているのであれば、
ぜひ勇気をもって1歩を踏み出してみてほしいと思う。
コーディングが面白いと思えるのならば、
そして自学習が苦でないと思えるのならば、十分検討の価値がある仕事だと考える。


***

ここまで読んでくださりありがとうございました。
皆さんと一緒にお仕事ができる日が来ればいいなと思っています。
iTerm2のタブ名を変更する

# 概要

iTerm2はデフォルトで実行しているプロセス名が表示されています。
tmuxを使っていたこともあって、タブ名を任意のものに編集したくて簡単にカスタマイズしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538418/18dd8628-d7fb-1358-0c01-f2cf45f66322.png)

# 方法

`.zshrc`を以下を書き加える。

``` ~/.zshrc
alias tn='tab-name'

tab-name() {
  echo -ne "\e]1;$1\a"
}
```

```
$ tn [タブ名]
```

上記にてタブ名を変更できるようになります。

※iTerm2の設定で、 `Preferences > Window > Custom tab title`の設定をしているとタブ名が変更できませんでした。
MyBatisとは何か？(学習メモ)

#はじめに
本記事ではMyBatisの基礎的な情報についてアウトプットする。
学習していく上で新たな学びがあれば、その都度更新する予定。

#MyBatisとは？
・SQLとJavaオブジェクトをマッピングするためのデータベースアクセス用のフレームワーク
・MyBatisはMapperインターフェイスと呼ばれるインターフェイスとSQLを紐付けている
・JavaのビジネスロジックからはMapperインターフェイスを呼び出すだけでSQLの実行が可能

#SQLの定義方法
SQLを定義するには主に2つの方法がある。
####・マッピングファイル
SQL文とオブジェクトをマッピングするためのファイルでxml形式で記述する。
MyBatisの前身であるiBATISからサポートされている指定方法で、
MyBatisの機能を完全に利用することができる。

```xml
<select id="find">
<select id="delete">
```

####・アノテーション

MyBatis 3系からサポートされた指定方法で、`@`を使用することでSQLの指定は簡単だが、
複雑なSQLの指定には向いていない。
また、マッピングファイルでサポートされている機能の一部は利用することが出来ない

```xml
@Select("SELECT ・・・")
@Insert("INSERT ・・・")
```

#参考
[MyBatis Introduction](https://mybatis.org/mybatis-3/)
[TERASOLUNA Server Framework for Java (5.x) Development Guideline 6.2. データベースアクセス（MyBatis3編）](http://terasolunaorg.github.io/guideline/5.7.0.RELEASE/ja/)
Artifactoryのインストール

前回の続きを実施する予定でしたが、諸事情により内容を変更します。
近いうちに現場で使用しているArtifactoryの移行作業を控えているので、事前にArtifactoryの機能を理解すべく、Artifactoryのインストールを実施します。

#パッケージの種類
Artifactoryには有償版と無償版の2種類のパッケージが用意されています。
有償版にはPro,Enterpriseが存在していて、全てのリポジトリタイプが使用可能であり上位のEnterpriseだと様々な機能が使用できますが、Artifactoryのライセンスは極めて高価です。
とても個人では手が出せない価格となっています。
一方の無償版の場合は、あらゆる規制がかかっていて、使用できるリポジトリタイプも非常に限られてしまいます。

なお、だいぶ前に紹介させて頂いたクラウド版のArtifactoryであれば、無償版でも全てのリポジトリタイプが使用可能となっています。

無償版には以下の種類があります。

```
OSS版
CE版
JFrog Container Registry
```

上記3種類はそれぞれ使用可能なリポジトリタイプが異なっていて、OSS版が基本的なタイプでJFrog Container RegistryはDocker等のコンテナでの利用を目的としたタイプです。
CE版については使用した事が無いので不明です。
今回はOSS版のインストールを実施します。

#Artifactoryインストール
※コマンドはsudoを省略しています
まずはFirewallでポート番号8082と8081(念の為)を許可します。

```
firewall-cmd --add-port=8081-8082/tcp --zone=public --permanent
firewall-cmd --reload
```

続いてリポジトリ情報の取得を実施する必要がありますが、その際に使用する```wget```コマンドがLinuxのディストリビューションによってはインストールされていない場合がありますので、以下のコマンドでインストールします。

```
yum install -y wget
```

wgetをインストールしましたらartifactoryのリポジトリ情報を取得します。
リポジトリ情報の取得が完了したら、取得したリポジトリ情報ファイルを```/etc/yum.repos.d```ディレクトリ内へ移動します。

```
wget https://releases.jfrog.io/artifactory/artifactory-rpms/artifactory-rpms.repo -O jfrog-artifactory-rpms.repo;
mv jfrog-artifactory-rpms.repo /etc/yum.repos.d/
```

上記の準備が完了しましたら、以下コマンドでartifactoryのインストールを実行します。

```
yum install -y jfrog-artifactory-oss
```

インストールが正常に完了できましたら、以下のコマンドでartifactoryサービスを起動します。

```
systemctl start artifactory
systemctl status artifactory #active(running)となっていればOK
```

正常に立ち上がりましたら、```http://<サーバーのIP>:8082```へアクセスします。
以下のログイン画面が表示されたら成功です。

![atf01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/7b952eae-603f-cbe8-4cff-a51246940584.png)

デフォルトのログインIDとパスワードは```admin/password```となっています。
ログイン後にパスワードの設定画面が表示されますので、任意のパスワードを設定します。

以上でArtifactoryのインストールは完了です。
【Vue.js】Vue Routerのナビゲーションガードでリダイレクトの設定

# Vue Routerのナビゲーションガードでリダイレクトの設定
投げ銭アプリを作成中。
ログインしていないユーザーはログイン画面にリダイレクトされるようにしたい

## 公式

https://router.vuejs.org/ja/guide/advanced/navigation-guards.html

## router.beforeEach
ルーターインスタンスのメソッドで、画面遷移前に実行される処理を引数に記載

遷移先をnext()で指定

## router.beforeResolve

主にガードする場所は以下の4箇所
1. グローバルbeforeEach
2. ルート単位beforeEnter
3. コンポーネント単位beforeRouteEnter
4. コンポーネント単位beforeRouteUpdate


# 実際設定したコードは以下
```js

router.beforeEach((to, from, next) => {
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
  // ルートメタフィールドのrequiredAuthプロパティがtrueの場合、認証されているかどうかをチェックする挙動を実装
  if (requiresAuth) { //true or false
    firebase.auth().onAuthStateChanged(function (user) { // ログインしているユーザーを取得（ユーザの有無）
      // ログインされているかどうか認証
      if (user) {
        next() //nextを呼ぶとtoのコンポーネントに遷移
      // ログインページにリダイレクト
      } else {
        next({
          path: '/signin',
          query: { redirect: to.fullPath }
        })
      }
    })
  // メタフィールドがture出なければダッシュボードに遷移してしまう
  } else {
    next()
  }
})


```

https://ky-yk-d.hatenablog.com/entry/2018/07/07/203000

## 参考

https://qiita.com/SatohJohn/items/cd7067ac64d8e45da4dd

https://router.vuejs.org/ja/guide/advanced/navigation-guards.html#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E3%83%93%E3%83%95%E3%82%A9%E3%83%BC%E3%82%AC%E3%83%BC%E3%83%89

https://qiita.com/sin_tanaka/items/ea149a33bd9e4b388241#vue-router%E3%81%A7%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E3%81%99%E3%82%8

https://qiita.com/hshota28/items/765cf903f055754f7557
>ルートメタフィールドのrequiredAuthプロパティがtrueの場合、認証されているかどうかをチェックする挙動を実装する。
ransackで#Array:〜〜のエラー

# 問題

配列処理したいが、以下のエラーが発生する。

`#[Array:0x00007f55f06941f8](array:0x00007f55f06941f8)`

# 原因

Arrayクラスになっているのが原因

ransackではActiveRecord_Relationクラスにする必要がある。

# 解決策

where、mapをつかい、Array→ActiveRecord_Relationクラスに変換する

`.where(id: items.map{ |item| [item.id](http://item.id/) })`

# 参考サイト

[配列をActiveRecord::Relationで再取得するメソッドを作ってみる - Qiita](https://qiita.com/shibadai/items/ddbc76a8b980cd8354bc)
【Vue.js】Vue Routerの書き方、使い方 

# Vue Routerの準備(Vue-CLI)

Router をmain.jsに登録

```main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from "./store"

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

```

## router/index.js にVueコンポーネントのルートを登録する
以下のようにcliを介してvueとvue-routerをimport
Vue.use(VueRouter)でVue Routerが使えるようになる

Vueコンポーネントのルートもここに登録

```router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import BasicForm from '@/components/BasicForm.vue'
import QuestionnaireForm from '@/components/QuestionnaireForm.vue'
import ConsultationFrom from '@/components/ConsultationFrom.vue'
import ConfirmationFrom from '@/components/ConfirmationFrom.vue'

Vue.use(VueRouter)

const routes = [ //ルートをいくつか定義
  { //各ルートは 1 つのコンポーネントとマッピングされる必要がある（ここでは、path: '/'）
    path: '/', //path: '宛先パス'
    name: 'BasicForm', //(name: コンポーネント名)
    component: BasicForm //conponent コンポーネント名
  },
  {
    path: '/questionnaire',
    name: 'QuestionnaireForm',
    component: QuestionnaireForm
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    // component: () => import(/* webpackChunkName: "about" */ '../views/QuestionnaireForm.vue')//これは何
  },
  {
    path: '/consultation',
    name: 'ConsultationFrom',
    component: ConsultationFrom
  },
  {
    path: '/confirmation',
    name: 'ConfirmationFrom',
    component: ConfirmationFrom
  }
]

const router = new VueRouter({ //ルーターインスタンスを作成して、ルートオプションを渡す
  mode: 'history',
  base: process.env.BASE_URL,
  routes // `routes: routes` の短縮表記
})

export default router

```



# 参考

https://router.vuejs.org/ja/guide/#javascript

https://www.e-loop.jp/knowledges/14/#Vue%20Router%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9

https://qiita.com/morrr/items/873ea25a806167c8d426

https://qiita.com/watataku8911/items/453c1d757c99ad2d5fb2
【Vue.js】特定オブジェクト内のstateプロパティへのアクセス

# Vue.js 学び

dataプロパティ内の、lists配列内の、特定オブジェクト内のstateプロパティへのアクセス
参照

https://jp.vuejs.org/v2/guide/reactivity.html#%E9%85%8D%E5%88%97%E3%81%AB%E9%96%A2%E3%81%97%E3%81%A6

```vue

<template>
  <div id="app">
    <div class="title">
      <h1>Todoリスト</h1>
    </div>
    <div class="main">
      <div class="switch">
        <label><input type="radio" name="change-displey" onclick="changeDispley()" checked>すべて</label>
        <label><input type="radio" name="change-displey" onclick="changeDispley()" >作業中</label>
        <label><input type="radio" name="change-displey" onclick="changeDispley()" >完了</label>
      </div>
      <div class="task">
        <table>
          <tr>
            <th>ID</th>
            <th>コメント</th>
            <th>状態</th>
          </tr>
          <tr v-for="(list, i) in lists" v-bind:key="i">
            <td>{{ i }}</td>
            <td>{{ list.comment }}</td>
            <td v-if="list.state"><button @click="changeState(i)">作業中</button></td>
            <td v-else><button @click="changeState(i)">完了</button></td>
            <td><button @click="deleteList(i)">削除</button></td>
          </tr>
        </table>
      </div>
    </div>
    <div class="addTask">
      <h1>新規タスクの追加</h1>
        <div class="form">
          <form @submit.prevent>
              <input type="text" v-model="comment">
              <input type="submit" value="送信" @click="addTodo">
          </form>
        </div>
    </div>
  </div>
</template>

<script>

export default {
  data() {
    return {
      comment: '',
      lists: [],
    }
  },
  methods: {
    addTodo: function(){
      const todo = {
        comment: this.comment,
        state: true,
      }
      this.lists.push(todo)
    },
    deleteList(i) {
      this.lists.splice(i, 1)
    },
    changeState(i) {
      this.lists[i].state = !this.lists[i].state
    }
  },
};

</script>

```

;は不要になりますね。エディターの自動整形を使用するといいですね。

```vue

        <label><input type="radio" name="change-displey" onclick="changeDispley();" checked>すべて</label>
```
```vue

        <label><input type="radio" name="change-displey" onclick="changeDispley()" checked>すべて</label>
```

functionを省略する記法もありますので、ぜひ使っていきましょう。
また{}の両外側にはスペースをあけるようにしましょう。

```js

changeState: function(i){
```
↓

```js

changeState(i) {
```


【vue】methodsの省略表記と注意点（アロー関数は使えない）

https://qiita.com/yuta-38/items/6aa64ba4d02b6214ade9
RxSwiftでジェネリクスを使ってAPIをたたく備忘録

#コード
本記事は備忘録なので説明はほとんどなしです。
なので早速コードです。

```swift
import Foundation
import RxSwift
import Alamofire

protocol APIServiceProtocol {
    func excute<T: Codable>(urlString: String) -> Single<T>
}

class APIService: APIServiceProtocol {
    
    func excute<T: Codable>(urlString: String) -> Single<T> {
        Single<T>.create { (single) -> Disposable in
            
            let url = URL(string: urlString)!
            AF.request(url).response { (response) in
                guard let data = response.data else {
                    return
                }
                
                do {
                    let decodedData = try JSONDecoder().decode(T.self, from: data)
                    single(.success(decodedData))
                } catch {
                    single(.failure(error))
                }
            }
            
            return Disposables.create()
        }
    }
}

```

こんな感じです。
何気にジェネリクスを利用したのはじめてなんですがTにたいして配列もいけるんですね

呼び出しがわ

```swift
let qiita: Single<[QiitaModel]> = apiService.excute(urlString: "https://qiita.com/api/v2/items")
        
        qiita.asObservable().bind(to: tableView.rx.items) { tableView, row, model in
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
            cell.textLabel?.text = model.title
            cell.detailTextLabel?.text = model.user.name
            return cell
        }.disposed(by: disposeBag)
```

`qiitaAPI`を叩いています。
一行目が一番大事です。
型を明示してあげないといけないので一行目なしだとエラーが吐かれます

以上です。
ngrok と express を組み合わせて Hello World!（ngrok のモジュールを利用）

表題の内容の通りです。

ngrok と express のモジュールを読み込んで、シンプルに Hello World! を返す、という内容を試した際の個人用メモです。

## 事前準備から実行まで
### 事前準備
事前に `npm install ngrok express` を実行してください。

### コードの内容
以下の内容を、例えば app.js など適当な名前で作成します。
以下でポート番号は 8080 としましたが、適当に変えてしまって問題ありません。

```javascript
const ngrok = require("ngrok"),
  express = require("express");
const port = 8080;

const app = express();

app.get("/", (req, res) => {
  res.send("Hello World!");
});

ngrok.connect(port).then((url) => {
  app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`);
    console.log(`Example app listening at ${url}`);
  });
});

```

そして、 `node app.js` を実行してください。
そうすると、ローカル・グローバル側からのそれぞれのアクセス先の情報が、以下のように出力されます。
![実行結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6fdc555b-1e3a-403c-0cd6-3c8037616c28.jpeg)

どちらにアクセスしても、ブラウザ上で以下が表示されます。
![ブラウザでのアクセス結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c231140a-c079-f65d-f7e3-6c3059ca0f76.jpeg)

## 参照した記事
●Raspberry Piをngrokで公開する - Part1: Expressをpm2から起動する - Qiita
　https://qiita.com/masato/items/9fd096a544fc462a7b11

## 【追記】 その後にやったこと
●Google Colab上で Node.js でサーバーを動して外部からアクセス（モジュール：ngrok・express） - Qiita
　https://qiita.com/youtoy/items/2f75ad138861191e5019
Android Studioでアプリ開発

自身のPCの性能が悪いのもあるのですが、設定に苦労したのでメモを残して起きたいと思います。

Android Studio自体はダウンロードするのに何の問題もなかったのですが、SDKダウンロードする際に何故かエラーメッセージが出力。

それは保存している場所のフォルダに日本語を使っていたからいけないとのことでした。

そしてSDKはダウンロードできたが次にエミュレーターで実行の段階になり、またエラーメッセージ。

The emulator process for AVD Picel 3a_API 30 x86 was killed.

質問サイトを駆使したところ、どうやら容量の問題らしく、この解決に3段階ぐらいの解決法試しました。

Android StudioでHello worldアプリ作成
https://akira-watson.com/android/helloworld.html#1


このエミュレーター実行の際にエラー文章出る様でたので、

HAMXを設定
それでも通らなかったので
↓

BIOSの設定やHyper-vなど確認
https://akeyfn.xyz/osusumesoft/haxm-win10-vt-x-androidstudio/
それでも通らなかったので

↓
Android StudioからNox Playerを利用してアプリケーションを起動する
https://qiita.com/shin1007/items/e1a151c5f99435f3ca5c

といった風にエラーを回避しました。他の方が同じ轍を踏まないように。
[脱初心者への道]AndroidのリモートデバッグではまるCommandInvokationFailure

# 謎のエラーでリモート実行できない
UnityでAndroid向けにBuildしてリモートで実行しようとすると、以下のようなエラーが出ることがあります。

```
: Unable to install APK to device. Please make sure the Android SDK is installed and is properly configured in the Editor. See the Console for more details.
```
ただ、この後にBuildが成功しているメッセージは出ていて、Buildは失敗して無さそうだし、SDKも入ってる。という場合の対処方法を以下に示します。

## 原因1：同じアプリが既に入っている
一番、単純な話ですが、入れようとしているアプリが既にストア等からインストールされているとエラーになってインストールできません。
https://www.crossroad-tech.com/entry/UnityAndroidBuildFailure


## 原因2：Android側に空きがない
これもあり得ます、エラーメッセージから推測しがたいです。
http://blog.lab7.biz/archives/21598575.html

## 原因3：ADBが邪魔している
この現象もありました。
https://qiita.com/r-ngtm/items/13a09e33e6788be42eb8