OmniAICreator/Qiita-1.07M huggingface dataset:
ジオメトリーノードでで木から森を作ろう

# ジオメトリーノードでで木から森を作ろう

「[Pythonで木から森を作ろう](https://qiita.com/SaitoTsutomu/items/6a6c45f3bf52d15d5bd0)」では、Pythonで1本の木から森を作成しました。今回は、Blender3.0のジオメトリーノードを使って、1本の木から森を作成します。

ジオメトリーノードをはじめて使うので、間違いなどがあるかもしれませんがご了承ください。

## 1本の木を作る

「[ローポリの木を作ろう](https://qiita.com/SaitoTsutomu/items/6a6c45f3bf52d15d5bd0#%E3%83%AD%E3%83%BC%E3%83%9D%E3%83%AA%E3%81%AE%E6%9C%A8%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86)」を参考に1本の木を作ってください。ただし、カスタムプロパティを作成する必要はないです。カスタムプロパティを作成しない場合は、マテリアル`green`のベースカラーを緑色に変えてください。
オブジェクト名は`tree`とします。

## 地面を作る

「[地面を作ろう](https://qiita.com/SaitoTsutomu/items/6a6c45f3bf52d15d5bd0#%E5%9C%B0%E9%9D%A2%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86)」を参考に地面を作ってください。オブジェクト名は`Grid`とします。

## ジオメトリーノードの作成

「Node Wrangler」アドオンを有効にしてください。
ウィンドウを増やし、`ジオメトリーノードエディター`にしてください。
3Dビューポートで`Grid`（地面）を選び、`ジオメトリーノードエディター`の「新規」を押してください。
「追加（`Shift + A`）」で、以下のノードを作成してください。

- 「ポイント」→「面にポイント配置」
    - 「密度」を`0.3`にしてください。
    - 「グループ入力」ノードと「グループ出力」ノードの間に入れてください。間に入れると地面が消えます。そこで、ShiftとCtrlを押しながら、「グループ入力」ノードから「面にポイント配置」ノードにドラッグしてください。下記のように「ジオメトリー統合」ノードが追加され、地面が表示されます。

![スクリーンショット 2021-12-13 18.00.21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/47b0247b-db24-4aba-0b33-f411917d1a29.jpeg)

- 「インスタンス」→「ポイントにインスタンス作成」
    - 「面にポイント配置」ノードと「ジオメトリー統合」ノードの間に入れてください。
- 「入力」→「オブジェクト情報」
    - 「オブジェクト」を`tree`にしてください。
    - 下記のように「ジオメトリー」から「面にポイント配置」ノードの「インスタンス」につないでください。

![スクリーンショット 2021-12-13 18.03.08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/be81fea9-1240-be30-4a99-be55b8c13e63.jpeg)

完成です！

## 余談

最初、間違えて`2.93`で作ってしまいました。そのときは、下記のようにできました。

![スクリーンショット 2021-12-13 18.11.37.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/cabb9a8b-903d-7ebe-2f02-41e1f2782b01.jpeg)

こっちの方が簡単ですね。

以上
メモ：TypeScriptはじめ

今は昔、CoffeeScriptやらTypeScriptやらが流行っているのは知っていたが、一人で書く事が大半だったので生のJavaScriptでしか書いてこなかった。
が、2020年も超えてTypeScriptを使わない理由も特にないので、一応知っておこうという事で基本をメモ。
[ここ](https://mebee.info/2019/10/26/post-2877/)とか[ここ](https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a)とか[ここ](https://eh-career.com/engineerhub/entry/2021/08/26/110000)を参考にする。

#特徴

* 変数の型定義、型推論が可能
* クラスの作成、継承 が可能
* インターフェースの作成が可能
* 上位互換のため、構文は JavaScript のものをそのまま使える ため学習コストが低い
* VSCode による強力な補完機能が利用可能

# インストール

グローバルでインストールした。

```
npm install -g typescript
npm install -g ts-node
```

TypeScriptは4.5.2で入ってきた。

# 実行確認
まずは単純なスクリプトで試してみる。

```javascript
let message : String = '';
message = " World!"
console.log("Hello" + message);
```

実行すると
`Cannot find name 'console'.`
のエラーが出たので検索すると
`npm install @types/node --save-dev`
が必要だった模様。
入れるとエラーがなくなった。

`tsc test.ts`
で.jsが出来る。

# TypeSceiptの基本

構文はほぼJavaScriptままで使えるので、主な特徴の型指定、インターフェース、クラスについて。

## 変数の型

旧来の
JavaScript の var 変数の他、その後 ES6 で導入された let,const が利用可能だが、基
本的には代入可能な場合は let 、定数は const を利用する。
これら
va r と let は似ているが、関数スコープが異なる。 varは ファンクション、letはブロックスコープを持つ。
これにより let は var と違って意図せぬ不具合が混入しづらいためTypeScriptでも基本的にはletを使う方が良い。
その上で、TypeScriptでは変数を型指定込みで宣言する場合はコロンに続いて型を記述する。

```javascript
// 文字列
let str: string = 'mebee';
 
// 数値
let num: number = 1;
```

基本のプリミティブ型は以下
string, number, boolean, symbol, bigint, null, undefined

let status: "get" | "post" | "delete";
のように文字列を指定する事も可能。

# インターフェース
インターフェースを定義して、型として利用する事が可能。

```javascript
interface MyType { foo: string; bar: number; }
let obj: MyType;
```

勿論クラスのメンバをインターフェースで定義する事も可能。

```javascript
interface MyInterface{
  getName():void;
  getDetail():{address:string};
}

class MyClass implements MyInterface{
}
```
のようにしてメソッドの実装を強制する事が可能。

又、配列の定義にインターフェースを利用する事で、異なるクラスでも同じインターフェースを持っていれば放り込める。

# クラス定義
クラスそのものはJavaSciptにも概念は存在しているが、拡張されている。

constructorでコンストラクタを定義する、という部分だけ知っていればクラスは作る事が出来る。
クラスはextendsで継承可能。

```javascript
class hoge {
 
    private x: string; // private宣言も出来る
 
    constructor(name: string) { // コンストラクタ
      this.x=name;
    }
     
    foo() {
      console.log(`Hello, ${this.word}`);
    }
  }
  
  class hage extends hoge {
    // 継承
  }
  
  const hogehoge = new hoge('TypeScript'); // コンストラクタを実行
  hogehoge.foo();
```

クラスとは直接関係ないが
文字列で
`val=”Hello“+ _name` をバッククオートを使って、``val=`Hello ${_name}` ``;と表現できる。

getter,setter的なものはset/get + メソッド名で作成が可能。

```javascript
private _name: string = '';
set name(value: string) {
this._name = value;
}
get name(): string {
return this._name;
}
```

cls.nameのようにメンバ名でアクセスして利用可能。

その他色々あるが、例えばコンストラクタの省略形はTypeScriptを知っていないと分かりづらいので使わない方が良さそう、と感じた。

# コンパイル
オプションを付ける事で厳しく出来る。厳しければ良いというものではなく、納得できるレベルというのが重要。
少なくとも使うだけでもある程度の恩恵は得られる。
型エラーでコンパイルできない場合はanyの型にする事でとりあえず潰す事が可能。
とりあえず厳しすぎるとしんどいので以下をtsconfig.jsonに設定して

```javascript
"strict": false
"incremental": true
"removeComments": false
"noImplicitAny": false
```

あとはこの辺りをどうするかを検討すればよいが、一旦falseで始めてみてもいいかも。

```javascript
"strictNullChecks": false
"strictBindCallApply": false
"strictPropertyInitialization": false
"strictFunctionTypes": false
```

毎回コンパイルするのが面倒な場合は[watch機能](https://usefuledge.com/how-to-setting-tsc-watch.html)で変更時の自動コンパイル。

おわり
GraphQLのScalerのIntが32bitの理由を調べた話

この記事は、[Supershipグループ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/supership)の14日目の記事になります。

## はじめに

https://spec.graphql.org/June2018/#sec-Int

>The Int scalar type represents a signed 32‐bit numeric non‐fractional value. Response formats that support a 32‐bit integer or a number type should use that type to represent this scalar.

GraphQLのScalerのIntは32bitと定義されてあり、いまどきにしては扱える数値の範囲が狭い理由が何故なのかが気になり、調べた話です。

## graphql-spec

https://github.com/graphql/graphql-spec/issues/73#issuecomment-129268000

> It wasn't included because it's not available across all platforms, most importantly and practically in our case: JavaScript.

graphql-specの過去のissueによると、すべてのプラットフォーム(JavaScript)で利用できないからというコメントがありました。

## JavaScriptのNumber

検証環境はChromeの96.0.4664.93です。

JavaScriptのNumberは安全に扱える整数の上限のNumber.MAX_SAFE_INTEGERが定義されてます。
JavaScriptのNumberはIEEE754なのでその辺の精度の話になります。

```js
Number.MAX_SAFE_INTEGER // 9007199254740991 
```

### 安全に扱えるってどうゆうことなのか

Number.MAX_SAFE_INTEGERより大きい値を使って比較した例です

```js
9007199254740992 === 9007199254740993 // true
```

この場合は数値が違うのでfalseになるのが正しいようにみえますが、丸められてしまってtrueになってしまいます。

### GraphQL APIがJSONでNumber.MAX_SAFE_INTEGERより大きい値を返した来た場合どうなるのか

バックエンドはGraphQLでフロントエンドがReactやVueなどのJavaScriptのフレームワークでWebアプリケーションを作ってる場合、 [Apollo Client](https://www.apollographql.com/)のようなGraphQLクライアントでAPIから値を取得してから使うことになりますが、その場合はHTTPのレスポンスボディで返るJSONの文字列をJavaScriptのオブジェクトに変換するのにJSON.parseする必要が出ます。

https://github.com/apollographql/apollo-client/blob/main/src/link/http/parseAndCheckHttpResponse.ts#L19


```js
JSON.parse(`{"value": 90071992547409918712}`) // {value: 90071992547409920000}
```

Number.MAX_SAFE_INTEGERより大きい値が入ってる状態でJSON.parseすると`90071992547409918712`が`90071992547409920000`になってしまい数値が変わってしまいました。

このJavaScriptオブジェクトを使ってしまうと、APIが返してる数値と違う数値を使ってしまうことが起こるので気をつける必要があります。

## まとめ

Number.MAX_SAFE_INTEGERを超えた場合の整数を正しく扱う場合は以下のことを気をつける必要がありそうです。

* 該当するGraphQLのフィールドのScalerをIntからStringに変更する
* JavaScriptで比較や演算する場合は[BigInt](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/BigInt)を使う

## 最後に

Supershipではプロダクト開発やサービス開発に関わる人を絶賛募集しております。
ご興味がある方は以下リンクよりご確認ください。
 [Supershipグループ 採用サイト](https://supership-hd.jp/recruit/)
是非ともよろしくお願いします。
Azure Storageでの SFTP 使用方法

2021年11月17日以降、**Azure StorageのSFTPサポート**は、一部の地域でパブリックプレビューに利用できます。

- 公式発表:  [SFTP support for Azure Blob Storage - now in public preview](https://azure.microsoft.com/ja-jp/updates/sftp-support-for-azure-blob-storage-now-in-public-preview/)　(英語)

この記事ではその使い方を紹介します。

最初はSFTPのプレビューを有効します。

```
az feature register --namespace Microsoft.Storage --name AllowSFTP
```

20分後、ステータスを確認します。

```
$ az feature show --namespace Microsoft.Storage --name AllowSFTP -o table
Name                         RegistrationState
---------------------------  -------------------
Microsoft.Storage/AllowSFTP  Registered
```

ステータスは**Registered**になったらSFTP使えます。

SFTPアカウントで使用するSSHキーを作成しましょう。

```
$ ssh-keygen -f sftp
$ ls -1 sftp*
sftp      ⇒　秘密鍵
sftp.pub　⇒　公開鍵　　
```

プレビュー中一部の地域しかSFTPと使えず、日本の地域はまだ使えないのでeastus2を使います。

また、[こちら](https://gist.github.com/johanburati/1942a2d63e95ec677c0b81eca2c92274)のテンプレートと**az Deployment group create** コマンドを使用して、ストレージとコンテナーを作成します。

```
$ az group create --name sftp --location eastus2 --output table
Location    Name
----------  ------
eastus2     sftp
$ wget https://gist.githubusercontent.com/johanburati/1942a2d63e95ec677c0b81eca2c92274/raw/fc76b8ca24100f826bb15b4f8a07cc6008bd8b77/sftp.json
$ az deployment group create --name deploysftp --resource-group sftp --template-file sftp.json --output table
Please provide string value for 'storageAccountName' (? for help): mysftpstorage
Please provide string value for 'userName' (? for help): sftpuser
Please provide string value for 'homeDirectory' (? for help): home
Please provide string value for 'publicKey' (? for help): <公開鍵のコンテンツをコピペしてください>
...
Name        ResourceGroup    State      Timestamp                         Mode
----------  ---------------  ---------  --------------------------------  -----------
deploysftp  sftp             Succeeded  2021-12-13T08:04:45.318616+00:00  Incremental
```

ステータスが**Succeeded**になったら成功です。

では、ファイルをアップロードしてみよう！
コマンドはこんな感じです⇒　*sftp -i  <秘密鍵> <ストレージ名>.<ユーザ名>@<ストレージエンドポイント>*

```
$ sftp -i sftp mysftpstorage.sftpuser@mysftpstorage.blob.core.windows.net
Connected to mysftpstorage.blob.core.windows.net.
sftp> put sftp.json
Uploading sftp.json to /sftp.json
sftp.json                                                                             100% 3308    18.3KB/s   00:00
sftp> ls -l sftp.json
-rw-r-----    ? 0        0            3308 Dec 13 17:17 sftp.json
sftp> quit
```

問題なく、AzureStorageでSFTPを使用できましたね～♪

以上です。
CORS対策したのにAPIがうまくできない時の対策

## やりたいこと
NuxtでNotionAPIを使ってデータベースの内容を取得する

## エラー内容
proxyでCORS対策してもうまくAPIが取得できず表示ページのHTMLが返ってくる謎の現象

## バージョン
- nuxt@2.15.8
- @nuxtjs/axios@5.13.6
- @nuxtjs/proxy@2.1.0

## 解決策
1. proxyをインストールする
1. `nuxt.config.js`を編集する

### 2-1 proxyをインストールする
axiosをインストールするとproxyも同時に取得できますが、proxy単体を取得してくる

`npm install -save @nuxtjs/proxy`

```
├─┬ @nuxtjs/axios@5.13.6
│ └── @nuxtjs/proxy@2.1.0 deduped
└── @nuxtjs/proxy@2.1.0
```
記事を書いてる時に気づきましが、
**deduped**がでてるしバージョン一緒だからいらないのかな？？

### 2-2 nuxt.config.jsを編集する
```
 proxy: {
    '/api': {
      target: 'https://api.notion.com',
      pathRewrite: {
        '^/api': '',
      },
    },
  },

  // Axios module configuration: https://go.nuxtjs.dev/config-axios
  axios: {
    // proxy: true,
    prefix: '/api',
  },
```
#### ポイント2点
- proxyをaxiosの上に書く！！！
- axiosで`proxy:true`にしない!!!

```
async asyncData({ $axios }) {
    const url = `/v1/databases/process.env.NOTION_DB/query`;
    await $axios
      .post(
        url,
        {},
        {
          headers: {
            Authorization: "Bearer " + process.env.NOTION_TOKEN,
            "Notion-Version": "2021-08-16",
            "Content-Type": "application/json",
          },
        }
      )
      .then((res) => {
        console.log(res["data"]);
      });
  },
```
これでうまくできた！！

3日考えてもできなく泣きそうになったからすごい感動した！！！
Scalaのfor内包表記の変換結果を確認する

### はじめに

Scalaの初心者の人にforの挙動を説明したり、パフォーマンスの調査等をする際に、
forがどのように変換されるかチェックしたいケースがあるかと思います。

そのような時のために、
Scalaのfor内包表記の変換結果を確認する方法についてまとめました。

### 結論

```
$ scalac -Xprint:parser 対象のファイル
```

で確認できます。

### サンプルコード

```Test.scala
object Test {
  for {
    num1 <- List(1, 2, 3)
    num2 <- List(10, 20, 30)
    if num2 != 2
  } yield (num1, num2)
}
```

変換結果:

```
$ scalac -Xprint:parser Test.scala
[[syntax trees at end of                    parser]] // Test.scala
package <empty> {
  object Test extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };
    List(1, 2, 3).flatMap(((num1) => List(10, 20, 30).withFilter(((num2) => num2.$bang$eq(2))).map(((num2) => scala.Tuple2(num1, num2)))))
  }
}

```
brew update実行時にError: homebrew-core is a shallow clone. が出て実行できなかった時の対処法

<h1>問題</h1>

Homebrewで
`brew update`
を実行しようとしたらこんなエラーが...

```
Error: homebrew-core is a shallow clone. To `brew update` first run:
  git -C "/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core" fetch --unshallow
This restriction has been made on GitHub's request because updating shallow
clones is an extremely expensive operation due to the tree layout and traffic of
Homebrew/homebrew-core. We don't do this for you automatically to avoid
repeatedly performing an expensive unshallow operation in CI systems (which
should instead be fixed to not use shallow clones). Sorry for the inconvenience!
```


<h1>解決策</h1>
エラー文に記述されている

``git -C "/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core" fetch --unshallow
``

を実行すればOK。
※リポジトリのパスは環境によって異なるので、上記コマンドをコピペするとうまくいきません！


<h1>原因</h1>
どうやら2020年12月以降に発生するエラーだそうで、それまでHomebrew は Git リポジトリの shallow clone を利用していたのですが、 shallow clone のアップデートはどうしても処理が重くなってしまうとのことで、 GitHub からのリクエストを受けて shallow cloneではなく、clone全体を使う形に変更になったようです。

※shallow clone: 直近のコミット(変更)のみ取得することができるGitの機能

どうして全体のクローンよりも最新の変更分だけ取得する方が処理が重いの？
と思った方は、以下の記事で分かりやすく説明されいているので是非ご覧になってください。
https://qiita.com/digitalhimiko/items/81184819f6555d4eaa75
Ruby の module のインスタンス...

# はじめに
移植やってます
[Python to Ruby Advent Calendar 2021](https://qiita.com/advent-calendar/2021/py2rb)
# インスタンス変数
```ruby
module A
  Al = 0
  @Ai = 0
  @@Aa = 0
end

class B
  include A

  Bl = 0
  @Bi = 0
  @@Bc = 0
end
p ['instance_variables: ', A.instance_variables, B.instance_variables]
p ['class_variables: ', A.class_variables, B.class_variables]

# ["instance_variables: ", [:@Ai], [:@Bi]]
# ["class_variables: ", [:@@Aa], [:@@Bc, :@@Aa]]
```
モジュールはインスタンス化できないけど、インスタンス変数はあるってことですね。
モジュールのクラス変数が、上記`class B`にも表れているのが不思議。

**[追記]**
コメント欄に、ありがたい情報があります。
@scivola さん、ありがとうございます。

```ruby
module A
  @Ai = 0
  @@Ac = 0

  def seti(value)
    @Ai = value
  end

  def setc(value)
    @@Ac = value
  end

  def geti
    @Ai
  end

  def getc
    @@Ac
  end
end

class B
  include A

  def seti(value)
    super
  end

  def setc(value)
    super
  end

  def geti
    super
  end

  def getc
    super
  end
end

class C
  include A

  def seti(value)
    super
  end

  def setc(value)
    super
  end

  def geti
    super
  end

  def getc
    super
  end
end


b = B.new
c = C.new
b.seti(2)
b.setc(5)
p [b.geti, b.getc, c.geti, c.getc]

# [2, 5, nil, 5]
```
~~module~~ class B/C のインスタンス変数ですので別になっています。
# メモ
+ Ruby の module を学習した
+ 道のりは遠そう
[flutter]freezedでdataクラスを生成する

flutterでapiリクエスト(json形式)する際のdataを、freezedを使用して生成することにしたので、メモ書きとして残します。

今回、freezedで生成する対象は前回のログインアプリのリクエスト/レスポンスに使っていたデータクラスになります。
https://qiita.com/yufuku/items/a7ddcb13ede86df6459a

# 環境
```shell
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.5.3, on macOS 11.2.3 20D91 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] VS Code (version 1.62.3)
```

# パッケージのインストール
まず、使用するパッケージをインストールします。

```shell
flutter pub add freezed
flutter pub add freezed_annotation
flutter pub add json_serializable
flutter pub add json_annotation
flutter pub add build_runner
```

# 実装
今回は既にapiリクエスト/レスポンスをするために既に作成していたデータクラスをfreezedで作り直そうと思います。
まず、freezed適用前のコードは下記になります。

```dart:lib/requester/requester.dart
class AuthRequest {
  final String name;
  final String password;

  AuthRequest({
    this.name = "",
    this.password = "",
  });

  Map<String, dynamic> toJson() => {
        'password': password,
        'user_name': name,
      };
}

class AuthResponse {
  final String accessToken;
  final String refreshToken;

  AuthResponse.fromJson(Map<String, dynamic> json)
      : accessToken = json['access_token'],
        refreshToken = json['refresh_token'];
}
```

それぞれ、toJson/fromJsonを持ったクラスとなります。
これを元にfreezed用に書き換えたコードが下記になります。

```dart:lib/data/auth/auth.dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';

part 'auth.freezed.dart';
part 'auth.g.dart';

@freezed
class AuthRequest with _$AuthRequest {
  const factory AuthRequest(
      {@JsonKey(name: 'user_name') required String name,
      @JsonKey(name: 'password') required String password}) = _AuthRequest;

  factory AuthRequest.fromJson(Map<String, dynamic> json) =>
      _$AuthRequestFromJson(json);
}

@freezed
class AuthResponse with _$AuthResponse {
  const factory AuthResponse(
          {@JsonKey(name: 'access_token') required String accessToken,
          @JsonKey(name: 'refresh_token') required String refreshToken}) =
      _AuthResponse;

  factory AuthResponse.fromJson(Map<String, dynamic> json) =>
      _$AuthResponseFromJson(json);
}
```

まず、partで`{ファイル名}.freezed.dart`と`{ファイル名}.auth.g.dart`が必要です。
そして、それぞれのクラスにfreezedのアノテーションをつけます。
fromJsonを定義することで、toJson/fromJsonが自動で生成されます。
`@JsonKey`をつけることで、jsonでのラベル名とクラスでの変数名を分けることができます。
`@JsonKey`をつけなければ変数名がjsonでのラベル名になります（例えば、AuthRequestのnameだったらjsonでのラベル名をそのままnameになります）。

# データクラスの生成
上記のfreezedのコードを元に、`{ファイル名}.freezed.dart`と`{ファイル名}.auth.g.dart`を生成するためには下記コマンド実行します。

```shell
flutter pub run build_runner build
```

上記だとファイルを変更した後に毎回コマンドを実行しなければ生成してくれないのですが、下記コマンドを実行状態にしておくと、対象のファイルが保存するたびに自動で生成してくれるようになります。

```shell
flutter pub run build_runner watch
```

# おわりに
今回は、freezedでapiリクエストで使用するデータクラスを作成してみました。
toJson/fromJsonなどの記述が楽な反面、ファイルを変更したら毎回コマンドを実行しないといけないので、少し煩わしい感じもあります。

今回作成したコードは下記になります。
https://github.com/fu-yuta/authentication_frontend/tree/freezed_data
Jetpack Composeの内部でIndex should be non-negativeが発生する原因の一つ

```
java.lang.IllegalArgumentException: Index should be non-negative (-1)
    at androidx.compose.foundation.lazy.LazyListScrollPosition.update-AhXoVpI(LazyListScrollPosition.kt:98)
    at androidx.compose.foundation.lazy.LazyListScrollPosition.updateScrollPositionIfTheFirstItemWasMoved(LazyListScrollPosition.kt:94)
    at androidx.compose.foundation.lazy.LazyListState.updateScrollPositionIfTheFirstItemWasMoved$foundation_release(LazyListState.kt:301)
```

`rememberLazyListState(initialFirstVisibleItemIndex = -1)` とinitialFirstVisibleItemIndexに負の値を指定すると内部で例外が発生する。
指定した箇所(rememberLazyListState)ではなく内部で発生しているので原因を特定するのが結構難しかった
負債を Redash で可視化する

## はじめに

本記事は [with Advent Calendar 2021](https://qiita.com/advent-calendar/2021/with) 14日目の記事です。

こんにちは [with](https://with.is/welcome) でAndroid エンジニアをしている石田です。with の Androidチームでは新規機能開発に加え **負債解消にも積極的に取り組んでおり、常に健康なコードベース維持を心がけています**。

本記事では [Redashというダッシュボードツール](https://redash.io/) を使用してコードベースの負債を可視化した話をします。 ツールの使い方などの詳細な説明は割愛し アイデアの説明にフォーカスします。

## モチベーション

数年以上歴史のあるプロダクトには必ず負債があります。負債の種類は設計、依存ライブラリ、命名、モジュール、言語などなど プロダクトによって様々だと思います。しかしながら 「負債は解消しないといけないんだけど、新しい機能も入れないといけないし...」 という風に **負債があることを認識していながら結局放置する方向に流れてしまうことも多い** と思います。

負債をゼロにすることは不可能ですが、とはいえ負債が放置されている状態は技術的にも精神的にも不安要素になってしまいよくありません。そこで、**可視化を通して負債のシルエットを掴みさえすれば、適切に対処できるはず** という考えのもと (軽い気持ちで) Redashを使ってみました。

## 可視化の対象

可視化の対象は、まずは比較的効果を感じやすくお手軽な

1. 簡単に計測できる
2. 該当箇所が多く中長期に渡り段階的な作業が必要になる

の条件に当てはまるものを選ぶことをおすすめします。 例えば Android のプロジェクトの場合  Java, Kotlin Android Extensions, RxJava などが当てはまると思います。

| 負債 | 計測手法 | 対処 |
| --- | --- | --- |
| Java | 拡張子 が .java であるファイルをカウントする | Kotlin に移行する |
| Kotlin Android Extensions | kotlinx.android.synthetic で始まる import 文を含むファイルをカウントする | ViewBinding もしくは Jetpack Compose に移行する |
| RxJava | io.reactivex で始まる import 文を含むファイルをカウントする | Coroutines/Flow に移行する |

ざっくりと計測できれば十分だと思うので、計測手法はシンプルなものにすることをおすすめします。

## 構成

![inspection-shedule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/b42b01b9-fb90-3db8-852a-98d22fb4b132.png)


自動で定期的に計測データを収集・可視化するために GCP(AWSでも可) + GitHub + Redashを組み合わせます。まずは負債計測コードを書いて[Cloud Functions](https://cloud.google.com/functions) に乗せます。

Android エンジニアなので計測コードには使い慣れている Kotlin を使いました。[KotlinでCloud Functionsのコードを書く方法はこちらが参考になります](https://qiita.com/KazaKago/items/689f6efdbe11cdf1408c)。計測コードでは GitHub にあるリポジトリのソースファイルを走査する処理を書くことになると思いますが、 **Kotlinには [walkTopDown](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/walk-top-down.html) という便利なextensionがある** ので比較的楽に計測コードを書くことができました。

書いた計測コードは Cloud Scheduler を使って1日1回トリガーされるようにしておきます。データベースにある程度計測データが蓄積されたらRedashを使用して可視化します。[Redashは多種多様なデータベースに対応しています](https://redash.io/integrations/)。Google スプレッドシートにも対応しているので、お手軽に試したい場合におすすめです。


## 結果

実際に運用してみた Redash のダッシュボードです。左上のfillされているチャートが負債のチャートで、それ以外は別の計測のチャートになります(項目名は伏せています)。可視化することで負債を直感的かつ定量的に把握することができるようになりました。 **負債が着実に減っている過程も確認できます** ✨

![redash (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/91af8e20-8009-e032-ab82-5f9ea765ee2a.png)


## 感想

* 可視化を通して負債のシルエットを掴むことで **これくらいのペースでやればこれくらいの時期には解消できそう、というように現実的な負債解消プランを検討するきっかけになった** と思いました。
* 負債解消の作業は地味で時間もかかりますが、**可視化してあればその成果をチームメンバー間でわかりやすく共有することができるので理解を得やすくなります**。また、チャート上で負債の数値が下がったのを見た時はけっこう嬉しい気持ちになるものです☺️
【Android】ストレージ系を簡単にまとめる

株式会社パーソンリンクアドベントカレンダー14日目です！🎉
本日12/14は、南極の日だそうです。
> 1911(明治44)年のこの日、ノルウェーの探検家・アムンゼンと4人の隊員が人類で初めて南極点に到達した。
よろしくお願いします。

##  はじめに
Anroidアプリでファイルや画像を保存する時に、
保存ディレクトリを取得することがあるのですが、どこに保存すれば良いのか、どんな違いがあるのか、すごくややこしいので簡潔にまとめます。

## その前に
Androidはメジャーバージョンが年に1回上がるらしいです。
Android9.0からAndroid10.0へ　みたいな
バージョンが上がると非推奨になるメソッドや処理が当然ながら出てきますが、
今回は非推奨になっているものも含んで紹介します。
スマホ業界は、プライバシーを守るため、セキュリティの向上のために、バージョンを上げて対応していきますが、アプリ開発者はその対応に必死です。
→場合によってはこれに対応しないとリリースできないよーってなるみたいです。

## 内部ストレージ系
端末ストレージに保存する内部ストレージ系
Android11時点までの内容になっています
(最新はAndroid12がリリースされています)

名称 | ディレクトリ取得メソッド | アプリ削除時に消える？ | 非推奨？
--------- | --------- | -------- | --------
| 内部データ領域 | getFilesDir | yes | no
| 内部キャッシュ領域 | getCacheDir | yes | no


## 外部ストレージ系
Android端末で外部って言うとSDカードなんかをイメージしますが、
必ずしも外部ストレージ=SDカードではないみたいです。

名称 | ディレクトリ取得メソッド | アプリ削除時に消える？ | 非推奨？
--------- | --------- | -------- | --------
| 外部データ領域 | getExternalFilesDir | yes | no
| 外部キャッシュ領域 | getExternalCacheDir | yes | no
| 外部公開領域 | getExternalStorageDirectory | no | yes
| 外部公開共有領域 | getExternalStoragePublicDirectory | no | yes

## 最後に
アプリが消えても、データは残して欲しいという事で、
過去のアプリだとgetExternalStorageDirectoryを使ってるアプリなんかが結構あったみたいですが、非推奨になった為、データ保存によく使われるようになったのは、

 - getExternalFilesDir
 - MediaStore API
        - 担当しているプロジェクトでは、画像データでアプリが消えても残して欲しいという事でこちらを使用しました。
 -  Strage Access Framework (SAF)

などみたいです。
Android 対象範囲別ストレージでググるとこの辺りが出てきます。

Android(java)は日本語記事が少なく調査が大変ですよね。
最後まで読んで頂き、ありがとうございました。
AWSのマルチアカウント構成でインストールされているソフトウェアのバージョンを可視化してみた

この記事は ディップ株式会社 [Advent Calendar 2021](https://qiita.com/advent-calendar/2021/dip-dev) の14日目の記事です

##はじめに
AWS内の各インスタンスにインストールされているソフトウェアのバージョンがいくつなのか確認したいときどうしますか？

組織で使用しているアカウントやインスタンスが多いほど、その確認工数は膨大になってしまうと思います。

そこでSSMインベントリとQuicksightを使い、複数アカウントのソフトウェアバージョンを確認する方法を試してみました。


#環境準備
SSMインベントリを使い複数アカウントのインベントリデータを管理用アカウントに用意したS3に同期し、QuickSight（BIツール）で出力する環境を構築しました。

![スクリーンショット 2021-12-13 16.15.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/929469/530cc12b-78aa-c520-2733-003c0c4825e5.png)


詳細な手順を全て書くと長くなってしまうので、参考にした[ハンズオン資料：Systems Manager & QuickSight ハンズオン](https://ssm-inventory-visualize.workshop.aws/)を参照していただければと思います。

◆ざっくりやったこと
①インスタンスロールの作成
　　- Systems Managerを利用する場合は、対象のインスタンスが Systems Manager API にアクセスできるようにするため、IAM Role の付与が必要になります。

②EC2 インスタンスの作成
　　- 管理対象となる EC2 インスタンスです。

③インベントリの有効化
　　- SSMインベントリの情報は、特定アカウント、特定リージョンごとに個別で収集されています。 
　　- 設定箇所：Systems Manager　＞　インベントリ　＞　セットアップインベントリ

④インベントリデータ保存用 S3 バケットの作成
　　- 管理アカウント内に単一の S3 バケットを作成します。
　　これにデータを集約し、一括して分析することが可能です。
　　- 設定箇所：アクセス許可　＞　バケットポリシー　＞　JSON

⑤インベントリデータ保存用 S3 バケットのポリシー修正　
　　- S3へアクセスするアカウント情報を追加します

⑥リソースデータ同期の設定
　　- SSM Inventory から S3 へデータを同期する設定を行います

⑦QuickSight データセットの作成
　　- QuickSight ＞　Sign up for QuickSight
　　- Standard Editionを選択
　　- Athenaを使いました

⑧QuickSight による可視化
　　- インベントリ情報がグラフ化されることを確認



ここまでで準備完了です。

##ソフトウェアのバージョン可視化（Quicksight）
ここから、Quicksightでソフトウェアバージョンを可視化する部分についての設定です。

①左側タブ「視覚化」を選択。
②フィールドリスト以下４つを選択します。
・accountid
・name
・resourceid
・version

③ビジュアルタイプを「ピボットテーブル」選択します。
![バージョン情報一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/929469/128c2aab-0730-9efc-93d7-7bdfb3cddada.png)




####特定のソフトウェアに絞って確認する
①左側タブの「フィルター」を選択します。
②使用するフィールドリストに「name」を選択し、フィルタタイプを「カスタムフィルタ」に変更。
③今回は「bash」のバージョンを確認したいので検索する値の欄に、「bash」と入力し
「適応」をクリックします。


![フィルター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/929469/33562a55-f810-7b94-0ea3-f8bd6072ed43.png)
すると、bashのレコードのみが表示され簡単にバージョンを確認することができますね！
##おわり
今回はソフトウェアのバージョン情報の可視化を行いましたが、他のフィールドリストを使えばバージョン以外の情報も出せますし、ビジュアルタイプを変更してグラフ化も可能です。
今回は使用していませんが、パラメータやアクション機能というものもあるので色々試してみようと思います。

##参考にしたページ・ブログ
Systems Manager & QuickSight ハンズオン
https://ssm-inventory-visualize.workshop.aws/phase5.html

【AWS SystemsManager】インベントリデータをQuickSightで視覚化する
https://blog.serverworks.co.jp/tech/2020/07/07/post-87979/
Chart.jsで目盛(Ticks)を内向きにする方法

##大学院生の備忘録シリーズ 第三弾
ずっと内向きの図を扱っていたから何としても内向きにしたかった．
## 結論

```javascript:option.scales[scaleID]
grid: {
    tickLength: -8,
},
ticks: {
    padding: 16,
},
```

`tickLength`を`-`にしてその分ラベルを`padding`でずらす．(`tickLength`のデフォが8なので[マイナスした分+8]`padding`でよい感じになりそう)
BitVisor関連の論文や情報をウォッチする

Google Scholar の Alert 機能を使うと，特定のキーワードにマッチした論文を通知してもらえます．

1. Google Scholarの左上をクリック
![Screen Shot 2021-12-13 at 16.57.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153099/65a13abe-1e93-e314-7f3d-e1f3d3541e23.png)

2. Alertsをクリック
![Screen Shot 2021-12-13 at 16.59.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153099/6bb1b89a-6d0b-5936-750c-ac0d2a897fb0.png)

3. CREATE ALERT をクリック
![Screen Shot 2021-12-13 at 16.58.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153099/74acb5af-4335-43ba-5b93-42569a0f1ea9.png)

4.Alert query に検索したいキーワード (ここでは"bitvisor") を入力して CREATE ALERT をクリック．
![Screen Shot 2021-12-13 at 16.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153099/5dfec63b-2429-631f-a5ab-8b6c0f36a4aa.png)

これで完了です．Google Scholarに新規にエントリが追加された際に，クエリに引っかかると以下のようにメールで通知してくれます．また，クエリを工夫すればタイトルにキーワードが含まれている場合など絞り込みをおこなうことができます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153099/ab4c9024-d97f-5c04-09b1-70da9c4c5acc.png)


ちなみに今回はGoogle ScholarのAlertを使用しましたが，一般の記事に関しても知りたい場合は通常のGoogle Alertが使用できます．
Chart.js の時間軸を使おうとしてコケたところ

## 大学院生の備忘録シリーズ 第二弾
[cjs]:https://www.chartjs.org/docs/latest/
[Chart.js][cjs]の時間軸を使おうとしたらエラーを吐かれました

## Uncaught Error: This method is not implemented: either no adapter can be found or an incomplete integration was provided

```javascript:options.scales[scaleID]
type: 'time',
time: {
    unit:'day',
    displayFormats: {
        day: 'MM/DD'
    },
},
```
コード的には問題なさそう．`type:'time'`を外すとエラーなしに通る．

色々調べて参考にしたのは次のページ，全く同じ症状でした．

[chart.js で TimeScale の使い方](https://ja.stackoverflow.com/questions/75271/chart-js-%E3%81%A7-timescale-%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9)

どうやら[chart.js][cjs]単体では時間軸を扱えないらしい．

[3.x Migration Guide #Setup and installation | Chart.js](https://www.chartjs.org/docs/latest/getting-started/v3-migration.html#setup-and-installation)

公式ドキュメントにも書いてあった．

## 結論
時間を扱うライブラリーとadapterライブラリーを読み込まないといけないらしい．


今回はCDNを利用するので[Moment.js](https://momentjs.com/)，[chartjs-adapter-moment](https://github.com/chartjs/chartjs-adapter-moment)のふたつを[jsDelivr](https://www.jsdelivr.com/)で検索してhtmlに貼り付けます．

```html
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.2/chart.min.js"></script>
    <script defer src="https://cdn.jsdelivr.net/combine/npm/moment@2.29.1,npm/chartjs-adapter-moment@1.0.0"></script>
```

無事使えるようになりました
マクドナルド大体1000円ガチャ作ってみた(vue.js + TypeScript)

超初心者フロントエンドエンジニアのyumiです。

プログラミングの勉強を始めて2ヶ月ほど経ったので何か楽しそうなものが作りたいと思い、
@marusho_summersさんの「サイゼリヤ1000円ガチャ」をならって「マクドナルド大体1000円ガチャ」を作ってみました。
大体1000円になってしまった理由は後ほどご説明します🥲

使ったものは
・ vue.js(バージョン2)
・ TypeScript
です


##できたもの
![スクリーンショット 2021-12-13 16.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2102695/dc290490-924f-2abd-7f39-3d563cf5cd44.png)

![スクリーンショット 2021-12-13 16.14.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2102695/ad01a042-3f38-2fde-d936-b69aad33f7ab.png)

「ガチャを回す」ボタンを押すと大体1000円くらいのマックのメニューが表示されます。

[コードはこちら](https://github.com/ymym98/mcd-gacha)

色々調べて試行錯誤しながら書いたコードなので、「もっとこうした方が良い！」というアドバイス等あれば是非是非教えていただきたいです！

ちなみにメニューは2021年12月9日時点のバーガー（朝マックや夜マックは除く）とサイドメニューとドリンクに限定しており、実際のメニューよりかなり少なめです。

##苦労した点
![[object Object].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2102695/b0cea957-f2c9-e127-e5ed-c8a33c23e6cb.png)
私はDBに関する知識はあまりなく自分でデータを作れなかったので、商品のデータはVuexストアのstateに直接入力しました。
商品の部品用クラスを別で作成し、stateの中の配列でそれらをインスタンス化していたので、consoleで表示させても画像のように[object Object]として表示されてしまい、まずそこでつまづきました。
![改善後コード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2102695/3c40ebda-e5f8-cd1d-a3c6-9ad67c95e25e.png)
ここは JSON.stringify() を使うことで中身を表示させることができました。

![配列の中身.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2102695/1b04b09a-ff6b-5bef-e17b-63505517c987.png)
[JSON.stringify()の公式マニュアルはこちら]
(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)

##反省点
本当は本家のサイゼリヤ1000円ガチャのように、限りなく1000円ピッタリに近づけたかったのですが、ピッタリで止める方法が思い浮かばず、かなり余裕をもった幅の900円以上1500円となってしまいました。
次回改めて作り直すとしたら条件分岐の部分をもっと徹底的に行いたいです。
また、Twitterに結果をシェアするボタンも作ってみたいです。

##おわりに

実際に作ってみてたくさんの改善した方が良い点を見つけたので、次回以降の開発に活かしたいと思います！
最後までお読みいただきありがとうございました。
作業効率がアップするAdobe XDの便利なプラグイン紹介

業務で実際に使って重宝した
作業効率を上げるAdobe XDのプラグインを3つ紹介します。

#Split Rows
https://adobe.com/go/cc_plugins_discover_plugin?pluginId=276c46a9&workflow=share

**テキストをワンクリックで分割**
選択したテキストをワンクリックで分割できるプラグインです。
原稿などからまとめて文章をコピペし、ワンクリックで個別のテキストに分割できるので
文章のまとまりごとにコピペする手間がなくなります。

#Rename It
https://renameit.design/xd/

**レイヤー名をまとめて変更**
選択したレイヤー名を一括変更できるプラグインです。
入力した名前だけでなく連番などもつけられるためレイヤー整理の際に大活躍します。


#Vizzy charts
https://www.vizzycharts.com/

**面倒なグラフの作成に**
数値等を入力・選択し、ボタンをクリックするだけでグラフが生成されるプラグインです。
Chart.jsなどを使ったグラフを使用予定のウェブデザインでグラフのイメージ図を作成する際に使用しています。
UMLとは

#UMLとは
***UML***(Unified Modeling Language)は、統一モデリング言語のこと。オブジェクト指向言語での開発において、分析・設計・実装までを表記が統一された図を用いて表すモデリング手法。
***UML***を使うメリットとしては、以下のような点などが挙げられる。
・表記が統一されているため、情報共有しやすい
・システムの構造や動作の関係性や全体を把握しやすい
・デザインパターンとの親和性が高い
またUMLで用いられる図は、***構造図***と***振る舞い図***に分けられる。

## 構造図
***構造図***はシステム全体の構造を表し、以下のような図が該当する。

|名前     |説明|
|--- |---   |
|クラス図 |クラス構造（クラス定義、関連など）を表す。|
|オブジェクト図|インスタンス（オブジェクト）間の関係を表す。|
|パッケージ図|クラスなどがどのようにグループ化されているかを表す。|
|コンポーネント図|クラスやコンポーネントの内部構造と相互関係を表す。|
|複合構造図|クラスやコンポーネントの内部構造を表す。|
|配置図|システムの物理的構成を表す。|

## 振る舞い図
***振る舞い図***は動作や変化を表し、以下のような図が該当する。

|名前     |説明|
|--- |---   |
|ユースケース図 |ユーザなどの外部からの要求に対しての振る舞いを表す。|
|アクティビティ図|システム実行における処理の流れや状態遷移を表す。|
|ステートマシン図|イベントによるオブジェクトの状態遷移を表す。|
|シーケンス図|オブジェクト間のやり取りを時系列で表す。|
|コミュニケーション図|オブジェクト間の関連とメッセージのやり取りを表す。|
|相互作用概要図|ユースケース図やシーケンス図などを構成要素として、より大枠の処理の流れを表す。|
|タイミング図|オブジェクトの状態遷移を時系列で表す。|
datatime型(timestamp型)をPythonでスプレッドシートに書き込んでも, 日付として認識されるようにした

#問題点
* [Sheets API](https://developers.google.com/sheets/api)を使ってPythonでスプレッドシートに書き込むとき, datetime型やtimestamp型はエラーを吐いて書き込めない.
* datetime型とtimestamp型を文字列に変換して書き込んだら, スプレッドシート上で日付(ex. 2021/12/13)が文字列として認識されてしまう.

#解決策
以下において, 定義していない変数名は参考文献で使われた一般的なものであるとする.

まず, 以下のようにDataFrame内の日付データを文字列に変換する.

```Python3
df['date'] = df['date'].dt.strftime("%Y/%m/%d")
```

そして, 書き込みメソッド(`append_row`など)で, 引数に`value_input_option='USER_ENTERED'`を指定する.

```Python3
for row in df.values.tolist():
    wks.append_row(row, table_range='A1', value_input_option='USER_ENTERED')
```

#所感
jsonにDate型に相当する型がないから起きたエラーらしいですね. 
英語のreferenceは堅苦しくてまだ読み解けないマンなので, stack overflowの自己解決ニキ(参考文献を参照)がいなければもうちょっともぞもぞして詰まっていたかもしれない.

#参考文献
* https://stackoverflow.com/questions/64270673/how-can-i-change-the-text-format-to-number-format-of-a-table-pulled-from-python
* https://stackoverflow.com/questions/49243736/how-do-i-handle-object-of-type-timestamp-is-not-json-serializable-in-python
* https://teratail.com/questions/275532
* https://hituji-ws.com/code/python/python-spreadsheet/
[py2rb] @property

# はじめに
移植やってます
# @property (Python)
```python
class IndexedReaderMixin(NoOpBaseReader):
    @property
    def index(self):
        return self._offset_index
```
Pythonの`デコレーター`は、関数に機能を追加するための仕組み。
ややこしい仕組みですが、`@property`は比較的簡単で、所謂~~セッター~~ゲッターの様なもの。
# attr_reader (Ruby)
```ruby
class A
  attr_reader :index
  
  def initialize
    @index = 0
  end

  def add
    @index += 1
  end
end

a = A.new
puts a.index
puts a.add
puts a.index += 1 # error
```
皆さん大好き`attr_reader`

```ruby
module A
  def reset
    @index = 0
  end

  def add(value)
    @index += value
  end
end

class B
  include A
end
a = B.new
puts a.reset
puts a.add(2)
puts a.index # error
```
ちょっと格好悪いですが、~~セッター~~ゲッター入れましょうか。
# メモ
+ Python の @property を学習した
+ 道のりは遠そう
あれ、なんか$(this)が動かないな...

## 大学院生の備忘録シリーズ 第一弾

JS初心者が調子乗ってアロー関数を使っていた時に起きたエラーとその対応です．

問題のコードはこちら

```javascript:sample
$('select').on('change', ()=>{
    let hoge= $(this).val()
    Function(hoge)
})
```
実行すると

## Cannot read properties of undefined (reading 'toLowerCase')
なんだこれ？
となったのでいつものごとく先人たちの記事を調べてまずたどり着いた記事がこれ

[Cannot read property 'toLowerCase' of undefinedのとき何を確認すべきか？](https://qiita.com/BRSF/items/4f4e39bd82778b976392)

なにか定義されていないらしい．でも色々修正してもどうにもならない......

いろいろ時間をかけてたどり着いたのがアロー関数`()=>{}`といつもの関数`function(){}`の違いを解説していただいている次の記事

[JavaScript: 通常の関数とアロー関数の違いは「書き方だけ」ではない。異なる性質が10個ほどある。](https://qiita.com/suin/items/a44825d253d023e31e4d)

## 結論

`$(this)`はアロー関数`()=>{}`では定義されていない！
さらに外側に定義されていればそれがスコープされるらしい．
仕様なので`function(){}`の方に直そうね．とのこと
Personal Access Token to create or update workflowのエラー対処

GitHub Actionsのワークフローのファイル編集を行い、初pushしようとしたところエラーが発生した。

![スクリーンショット 2021-12-13 16.33.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/b194e385-2c08-feef-66f2-0d4f47695693.png)

ワークフローにチェックをつけるだけでOK
neosでlogix その25

#概要

niosでlogixやってみる。
post stringノードを使ってみた。

#写真

![2021-12-13 07.25.40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c729af2d-efa3-0003-3fca-fe564e0f8c4f.jpeg)



以上。
HTML,CSSで作った静的サイトをデプロイしてみた話

今回ポートフォリオサイトを僭越ながら作成しデプロイまで行ったのでちょっと書きます。

#使用したモノ
・HTML
・CSS
・Heroku(今回のデプロイ先)←無料でいけるヨ

#1 そのままデプロイできない…
HTMLファイル、CSSファイルだけだとHerokuに認められなかったです。

そこで一番簡単そうな方法を調べると、PHPアプリに改造するのが良いみたいですのでそうします。

#2 PHPファイルに大変身(超簡単だぜ！)
ルートディレクトリにindex.phpファイルを作成し以下を記入


index.php

```
<?php include_once("index.html"); ?>
```
#3 Json氏をジョイン
package.jsonファイルをルートディレクトリに作成し以下を記入

```
{}
```
#4 GitHubにPush!!
githubにpushします。

こちらの方の記事が大変参考になるかと思いますのでわからない方はどうぞ。
https://qiita.com/Toshimatu/items/f71a935612a55d6e674e

#5 Herokuへgo!
ここではherokuのアカウント作成等々は飛ばしますのでご了承ください。
この辺は以下のリンクが参考になるかと思いますのでどうぞ。
https://blog.proglus.jp/1438/

#6 HerokuとGithubリポジトリを紐付ける
ターミナルを開いていただいて

```
$ heroku login

$ heroku create アプリケーション名
```
#7 herokuを開く
Dashboardからデプロイしたいサイトを選択
Deployを選択
Deployment methodの項目からGitHubを選択しリポジトリ名を入力しconnect！
AutomaticDeploy等は好きにしてください。　

Manual deployの項目へ行きDeploy Branchをクリック！


完了
Workato：月末の定期連絡について自動化を考えてみる

Workatoに携わるようになって、日々の業務を自動化出来ないかと考えるようになりました。
そこで、Workato初心者の私が考えた自動化レシピの一例をご紹介したいと思います！
簡易なレシピなので、Workato初心者もしくは非エンジニアの方向けのものですがご参考になれば嬉しいです。



:large_orange_diamond:**月末の定期連絡を自動化してみる**


■ **構成**

構成は単純で、『Scheduler by Workato』と『Workbot for Slack』の２つを使用したレシピになります。

　**トリガー　**:alarm_clock:Scheduler by Workato：通知スケジュールを設定
　**アクション**:envelope:Workbot for Slack：通知先を設定（今回は通知先をSlackとしている為、Workbot for Slackを設定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187952/c94b61be-a64e-8729-46f4-a80f1a747b53.png)

■ **設定内容**

●**トリガー**

Scheduler by Workato（通知スケジュール）
毎月月末の午後1時に通知するように設定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187952/59741059-e28b-9b76-b36d-0cfbe927f937.png)

|項目|値|
|:-----------:|:------------:|
| Time unit| Months|
| Trigger every|1 (months)|
| Days of the month|Last Day|
|Trigger at|1:00 pm|


<br>
●**アクション**

１）Actionで設定するACTION IN USEは、『Post messeage』を選択します。
通知をしたい時は『Post messeage』をご使用ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187952/187a7f6b-fbe2-4827-7caf-9db0fbd6b8c7.png)


２）Connectionでは、接続するコネクションを選択します。
コネクションがない場合は事前にコネクションを作成する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187952/dca17160-070f-6539-0e22-941690de95c9.png)

３）Setupで通知先のSlackチャンネルや表示メッセージを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187952/5efc20d7-01b7-7402-918d-8c6ba72242b5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187952/c4b0def1-d446-9508-5235-3d3e402b2e6b.png)




＜SlackのメンバーID確認方法＞
自身のアイコンを押下し、『プロフィール≫その他≫メンバーIDをコピー』で自身のメンバーIDを確認する事が出来ます。『メンバーIDをコピー』を押下するとコピーする事も出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187952/b2bc53ef-7f8f-6eec-9e0b-359d8c106ab3.png)






■ **実行結果**
Slackの指定したチャンネルに以下のメッセージが表示されました！
メンション部分は本名が記載されているので、敢えて伏せさせて頂きました（すみません・・・）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187952/3a6fa5c5-bd64-5961-5b38-ef4c818bff46.png)
Obsidianの小技その1｜ ファイル名を6桁ではじめる（yymmdd_）

### はじめに

パソコン上で常に開きっぱなしのアプリ、[Obsidian](https://obsidian.md)。べんりにつかうための小技を、小出しにしてご紹介いたします。

### ファイル名のつけかた

`211208_`のように「西暦（下2桁）月（2桁）日（2桁）_」にしています。

![SS 2021-12-13 15.59.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/56af4015-624c-7656-2fb8-1d64b02c1705.png)


### 「ファイル名のつけかたを決めておく」ことが大切なわけ

`Obsidian`が便利なのは、サクッと別ファイルにメモをつくって、それを内部リンク（`[[xxxxx]]`形式）でリンクがはれることだとおもいます。必要ならば`![[xxxxx]]`と書くことで、プレビューしたときにリンク先のファイルの中身を表示させることもできます。

この内部リンクをべんりに使おうとおもうと、「ファイル名をつけるとき、いちいち考えずに済む」ことが大切だとおもうのです。少なくともわたしは、小さなストレスが積み重なると、だんだんイヤになってきます。

なので、ファイル名の冒頭は、`年月日_`で固定。長くなると視認性が落ちるので、2桁+2桁+2桁+"_"の7桁（月日を2桁+2桁にするのは、ソートしたときに日付順に並ぶようにするためです）。

年月日の後ろは、てきとうに名前をつけておいて、とりあえずメモを書き始めます。そして、メモを書き終わったときに、ファイル名を修正します。そうすると、必要な内部リンクは自動的に修正してくれます。

メモを書き始める前には、なかになにを書くのかはっきりしていないことが多いので、ファイル名をつけるときに悩むのは損で、てきとうに思いつきでつけるのがいいのです。メモを書き終わったら、ファイル名をつけるのは簡単です。

ということで、ファイルを作るとき、「ファイル名は＜年月日+テキトウ＞とする」と決めておくことで、心を安らかに保っておくことができます。

### おわりに

文字で書くとわかりにくいですけれども、Obsidianを2〜3日つかって、内部リンクをいくつか作ってみるとこの便利さ（ストレスフリーさ）が実感できるとおもいます。

### ご参考

[Obsidian｜便利な使いかたとコツ（目次）](https://qiita.com/hann-solo/items/ac8fa75394813e8adcf4)
ModuleNotFoundError: No module named 'yaml' エラー

個人的なメモですのでご了承ください

### 解決した方法

```
python3 -m pip install pyyaml
```

個人的には↑のコマンドで解決した

###余談

pip install pyyamlだと以下の文が表示されてしまった

```
pip install pyyaml

Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pyyaml in /usr/local/lib/python3.6/dist-packages (6.0)
```

原因がわかる方はぜひコメントください
ios15の場合、デフォルトでは、tableviewとnavigation barが透過されてしまう

[SwiftUI] iOS15の場合、デフォルトでは、tableviewとnavigation barが透過されてしまう
ので、それを防ぐ

```swift
@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // TabViewの背景色の設定
        UITabBar.appearance().backgroundColor = UIColor.white
        
        // NavigationBarの背景色の設定
        let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = UIColor.white
        UINavigationBar.appearance().standardAppearance = appearance
        if #available(iOS 15.0, *) {
            UINavigationBar.appearance().scrollEdgeAppearance = appearance
        }
        return true
    }
```
ansible magic variable snippet

# Overview
- to know magic variables

```yml
- hosts: all
  gather_facts: no

  tasks:
    - name: show Magic | group_names
      debug: var=group_names

    - name: show Magic | groups
      debug: var=groups

    - name: show Magic | inventory_hostname
      debug: var=inventory_hostname

    - name: show Magic | inventory_hostname_short
      debug: var=inventory_hostname_short

    - name: show Magic | play_hosts
      debug: var=play_hosts

    - name: show Magic | inventory_dir
      debug: var=inventory_dir

    - name: show Magic | inventory_file
      debug: var=inventory_file

    # Reserved magic variable
    - name: show Reserved magic | environment
      debug: var=environment
```
Plots.jl で領域を描画する

# Plots.jl

Julia のグラフ描画パッケージです。

http://docs.juliaplots.org/latest/

# 領域の描画

## コード

$(x_1, y_1), (x_2, y_2), (x_3, y_3)$を通る領域を次のように描画できます。

```Julia
plot(Shape([x1, x2, x3, ...], [y1, y2, y3, ...]))
```

## 例

次の領域を描画します．
$$
\begin{eqnarray}
y &\geq& x + 1,\\\\
y &\geq& \frac{-x + 15}{6},\\\\
x &\geq& 0, ~~ y \geq 0
\end{eqnarray}
$$

このようにコードを書きました。

```Julia
using Plots

plot(
    x -> x + 1,
    color=:blue,
    xlims=(0,2),
    ylims=(0,3.3),
    xlabel="x",
    ylabel="y",
    legend=false
)
plot!(x -> (-x + 15) / 6, color=:red)
plot!(Shape([0, 0, 9/7], [1, 5/2, 16/7]), color=:grey, opacity=0.1)
```

コードの出力のグラフは次の通りです。

$(0, 1), (0, 5/2), (9/7, 16/7)$の3点を頂点とする領域が描画できています．

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537455/292f46fc-9f53-0cbe-8b01-44d9b90b8089.png">

# 参考ページ

http://docs.juliaplots.org/latest/
laravel-page-speed を導入する

# はじめに
株式会社じげんの張です。
結婚相談所の情報比較サービス「結婚相談所比較ネット」の開発を担当しています。

PageSpeed Insights（以下PSI）改善施策の一環として、HTMLをできるだけ高速にダウンロードさせる施策を行い、Laravelのパッケージ`laravel-page-speed`を導入しました。
PSIから見るとページスコアの改善が見られたので、今回はその導入手順についてご紹介します。

# 「laravel-page-speed」とは？
Laravelフレームワークでは、`renatomarinho/laravel-page-speed`を使用すると、HTMLページを圧縮および最適化できます。

ネットワーク帯域幅を節約できるため、Webサイトのアクセス速度が速くなります。
拡張パックのドキュメントには、自動的な最適化によりWebサイトを35％圧縮できると記載されています。 使用方法を見てみましょう！

# 環境
`laravel-page-speed`を使うためにはPHP **7.3.24** 以上、Laravel Framework **5.3** 以上が必要なため、必ず環境を確認してください。

⚠下の導入手順はLaravel Framework **5.5** 以上の環境に基づいています。

# 使い方
## laravel-page-speedのインストール

```zsh:ターミナル
composer require renatomarinho/laravel-page-speed
```

## artisanコマンドで構成ファイルを作成する

```zsh:ターミナル
php artisan vendor:publish --provider="RenatoMarinho\LaravelPageSpeed\ServiceProvider"
```

上記のコマンドを実行すると、`config/laravel-page-speed.php`が生成されます。このファイルには、圧縮を有効にするかどうかと、圧縮したくないURLパスを指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294441/8dc8e1a4-7370-7494-6e78-ac8a3b1cbf37.png)
今回は管理画面HTMLの圧縮は行わないよう`'skip' => []`で設定しました。

## ミドルウェアをカーネルに登録する
拡張パックの使用は、Webミドルウェアグループに登録して行われます。そして、`app/Http/Kernel.php` ファイル中の `$middleware` の 配列内に下記ようにコードを追加します。

```php:app/Http/Kernel.php
    \RenatoMarinho\LaravelPageSpeed\Middleware\InlineCss::class,
    \RenatoMarinho\LaravelPageSpeed\Middleware\ElideAttributes::class,
    \RenatoMarinho\LaravelPageSpeed\Middleware\InsertDNSPrefetch::class,
    \RenatoMarinho\LaravelPageSpeed\Middleware\RemoveComments::class,
    \RenatoMarinho\LaravelPageSpeed\Middleware\CollapseWhitespace::class,
    \RenatoMarinho\LaravelPageSpeed\Middleware\DeferJavascript::class,
```

これらは、私が今回使ったものです。

拡張パックのドキュメントによると、ミドルウェアは全部で以下の8つがあります。

|ミドルウェア|概要|
|:------------------|-------------:|
| RemoveComments    | コメントを削除する|
| CollapseWhitespace| 改行、空行を削除する|
| RemoveQuotes      | 不要な引用符を削除する|
| ElideAttributes   | 余分な属性を削除する|
| InsertDNSPrefetch | DNSプリフェッチラベルを追加する|
| TrimUrls    　　　　　　　　　　　　| URLをトリミングする|
| InlineCss    　　　　　　　　　　| HTMLのインラインスタイルを1行のスタイルを変換する|
| DeferJavascript   | javascriptの実行タイミングをデファーする|

実際に使用する際に、HTMLが崩れていないかどうかなどを確認して慎重に選びましょう！
以上です！

# 参考にした記事

https://www.ritolab.com/entry/21#Install_laravel_page_speed

https://co.bsnws.net/article/226

https://github.com/renatomarinho/laravel-page-speed
Elasticsearchでインデックス時、検索時にkuromojiの形態素解析を適用する


Elasticsearchサーバのドメインとポートは自身の環境に合わせて変更する。




# インデックスを閉じる

elasticsearchのインデックスには「閉じる」という概念がある。

analyzerの定義変更の際には「閉じて開く」必要がある



## 実行

```
POST http://elasticsearch:9210/my_index/_close
```



## 結果

```
{
    "acknowledged": true,
    "shards_acknowledged": true,
    "indices": {
        "shop": {
            "closed": true
        }
    }
}
```





# analyzerを変更



## 実行



`default` インデックス登録時と検索時両方で使用されるよう設定

`default_index` インデックス登録時のみ使用されるよう設定

`default_search` 検索時のみ使用されるよう設定



```
PUT http://elasticsearch:9210/my_index/_settings
{
    "analysis": {
        "analyzer": {
            "default": {
                "tokenizer": "kuromoji_tokenizer"
            }
        }
    }
}
```



## 結果

```
{
    "acknowledged": true
}
```





# インデックスを開ける

説明は省略



## 実行

```
POST http://elasticsearch:9210/my_index/_open
```



## 結果

```
{
    "acknowledged": true,
    "shards_acknowledged": true
}
```





# 確認



## 実行

```
GET ttp://0.0.0.0:9210/my_index/_settings
```



## 結果

```
{
    "my_index": {
        "settings": {
            "index": {
                "number_of_shards": "1",
                "provided_name": "my_index",
                "creation_date": "0000000000000",
                "analysis": {
                    "analyzer": {
                        "my_analyzer": {
                            "type": "custom",
                            "tokenizer": "kuromoji_tokenizer"
                        }
                    }
                },
                "number_of_replicas": "1",
                "uuid": "xxxxwixxxxu6rxxxB6Lxxx",
                "version": {
                    "created": "7080099"
                }
            }
        }
    }
}
```



以上でkuromojinの形態素解析がインデックス時と検索時に適用される。
ffmpegのconcatで'Non-monotonous DTS in output stream'を出さないためにやったこと

どうも、しののいと申します。
仕事でffmpegを使う機会が多いのですが、わけのわからんエラーに悩まされることがしょっちゅうです。

そんなエラーのひとつ、`Non-monotonous DTS in output stream`がやっと納得のいくかたちで解決したので、備忘録も兼ねて共有します。
どなたかの役に立てば幸いです。

#以前までの解決方法
これまでは素材を一度すべてMTSに変換し、それを`concat`で結合、そして再度もとの形式に変換するということをやっていました。

この方法だとエンコードの回数が増えるのでその分ロスが生まれますし、当然時間もかかります。

#今回の解決方法
##エラーが起きた状況
Premiere proで制作した動画と、ffmpegで生成した動画を連結しようとしたところ、上記のエラーが出ました。

時間をかけて色々試した結果、いくつかのパラメータを統一したらきちんと動画が結合されるようになりました。

##統一したパラメータ
- ビデオのfps
- ビデオのタイムスケール
- オーディオのチャンネル数
- オーディオのサンプリングレート

動画のコーデックはh264、オーディオはaacでmp4形式、サイズはFHDで統一しました。
ビデオとオーディオのビットレートもなるべく近い数値になるようにしましたが、すべての素材で完全に一致しているわけではありません。
動くのでとりあえずよしとしましたが、この辺りはもう少し勉強した方がいいですね。

## 1. ffmpegで生成した動画のパラメータの確認
```
ffprobe -i ffmpeg.mp4
```
で動画の詳細を確認します。


```
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'ffmpeg.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Duration: 00:00:11.27, start: 0.000000, bitrate: 606 kb/s
  Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuvj420p(pc, gbr/unknown/unknown), 1920x1080 [SAR 1:1 DAR 16:9], 539 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 58 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
```

出力結果はこんな感じです。
今回はこの動画に合わせてパラメータを設定します。

- ビデオのfps = 30
- ビデオのタイムスケール = 15360
- オーディオのチャンネル数 = 1 (mono)
- オーディオのサンプリングレート = 44100

## 2. Premiereで作った動画のパラメータを変更
```
ffmpeg -y -i premiere.mp4 -c:v h264_nvenc -video_track_timescale 15360 -b:v 1000k -r 30 -pass 1 -an -f mp4 NUL
ffmpeg -i premiere.mp4 -c:v h264_nvenc -video_track_timescale 15360 -b:v 1000k -r 30 -pass 2 -c:a aac -ac 1 -ar 44100 -b:a 64k output
```

上を実行してパラメータを調整します。
使ったコマンドの説明をちょこっと。

`-video_track_timescale`で動画のタイムスケールを変更
`-r`で出力のフレームレートを30に変更
`-ac`でオーディオのチャンネルをモノラルに変更
`-ar`でオーディオのサンプリングレートを変更

`-b:v`と`-b:a`で動画とオーディオのビットレートを一応近い数値に調整してます。

ここで`-c copy`とすると、パラメータの調整にエンコードが必要な場合、エンコードがスキップされてしまいます。

## 3. 連結
```
ffmpeg -safe 0 -f concat -i input.txt -c copy output
```
これで連結して完了です。


#おわりに
`Non-monotonous`は解決しましたが、連結した結果かなり音ズレしていました。
ffmpegで作った動画のオーディオストリームとビデオストリームのdurationにズレがあるのが原因でした。
これも解決したので、また別の記事で紹介できればと思います。

Qiita初投稿なのでおっかなびっくり書いてます。
不勉強が過ぎるので、かなりあいまいな言葉を使ってますが、寛大な心でどうかご容赦ください。
内容に間違いや不備があれば教えていただけると助かります。
TypeScriptのOmitが気持ち悪くてつらい

# はじめに

先日、CureAppで毎週行っている勉強会でTypeScriptのOmitの話になりました。
Pickはインテリセンス効くけど、Omitはインテリセンス効かないというものです。
TypeScriptとしては[こちら](https://github.com/microsoft/TypeScript/issues/30825)の議論の末、今のインテリセンスが効かない今の実装になっているようです。
インテリセンスが効くようにOmitをなんとか上書きできないかとちょくちょく調べていたのですが、
あまり良い方法が見つからず絶望したので、メモとして代替案を残しておこうと思います。

# Omitの実装

まず、Omitの実装を確認してみます。

```typescript
// lib.es5.d.ts
/**
 * Construct a type with the properties of T except for those in type K.
 */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
```

個人的に`keyof any`を見て発狂しそうなのですが、Omitはtypeで宣言されているので上書きは出来ません。
なので、必然的に下記のどちらかの対応になりそうです。

- patch-packages等で、`lib.es5.d.ts`のOmitの実装を変更する
- マイOmitを作る

## patch-packages等で、`lib.es5.d.ts`のOmitの実装を変更する

```typescript
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
```

を

```typescript
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
```

に変更します。
使用しているTypeScriptのバージョン変更時にはパッチの修正が必要になりますが、
後者よりは対応が小さく済みます。

## マイOmitを作る

議論でもあがっていましたが、下記のような独自Omitを作る方法です。

```typescript
type OmitScrict<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
```

Omitがあるのに、OmitStrict…（白目）

ちなみに、組み込みのOmitを使用しないことを強制する場合は、eslintにルールを追加します。

```js
{
  rules: {
    '@typescript-eslint/ban-types': [
      'error',
      {
        types: {
          Omit: "Use `OmitStrict`.",
        },
      },
    ],
  }
}
```

# さいごに

下記のような実装で済むのが理想でしたが、あまり良い方法が見つけられませんでした。

```typescript
declare type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
```

他にもっと良い方法があったら教えて頂けると幸いです。