OmniAICreator/Qiita-1.07M huggingface dataset:
Twitter API で特定のユーザーのツイートを取得する（Python）


# 概要
tweepyというPythonのライブラリを用いて特定のユーザーのツイートを取得する。

# tweepy インストール
ターミナルで以下のコマンドを実行
```
pip install tweepy
```

# APIの認証
tweepyをインポートして、自身のAPIキーやアクセストークンなどを入れる。
[APIの取得方法はこちらの記事](https://di-acc2.com/system/rpa/9688/)が参考になるかと。

```
import tweepy

# 認証に必要なキーとトークン
API_KEY = 'API_keyをここに入れてね'
API_SECRET = 'API key Secretをここに入れてね'
ACCESS_TOKEN = 'Access Tokenをここに入れてね'
ACCESS_TOKEN_SECRET = 'Access Token Secretをここに入れてね'

# APIの認証
auth = tweepy.OAuthHandler(API_KEY, API_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

#APIインスタンスの作成
api=tweepy.API(auth)
```

# 特定のユーザーのツイートを取得

```
id = '@指定したいアカウント名'
tweets = tweepy.Cursor(api.user_timeline, screen_name=id).items(10)

for tweet in tweets:
    if (list(tweet.text)[:2]!=['R', 'T']) & (list(tweet.text)[0]!='@'):
        print('-------------------------')
        print(tweet.text)
```

itemsの引数を変更して、ツイート数を指定できます。
ただ、if分を使ってリツイートとリプライをフィルタリングしているので、表示されるのはリツイートとリプライを除いたツイートです。

# おわりに
tweepyを使うと、指定したキーワードを含むツイートを取得できたり、ユーザー情報の取得ができたりします。
試してみると楽しいかもしれません。
renderとredirect_toによる画面遷移について

# 概要
* create、update、destroyアクションではビューファイルを作成しないことが多い
* そのため上記のアクションで画面遷移先を決めるために、redirect_to, renderを用いる
* 新規投稿, 編集, 削除した際は、以下のいずれかの方法で指定されたビューを表示させる

**redirect_to**
---

![](https://i.imgur.com/p4FkFbS.png)

**処理の流れ**
1. redirect_toがルーティングにURLを送る
2. ルーティングと送られてきたURLとHTTPメソッドを照らし合わせて、どのコントローラのどのアクションを実行するかを決める
3. アクションを実行する
4. ビューを表示する


**render**
---

![](https://i.imgur.com/3nBtq86.png)

**処理の流れ**
1. renderで定義したビューファイルを表示する

renderが裏で動いているのはたったこれだけです


# 違いと注意点


**renderとredirect_toの大きな違いを一つあげるとすると、新たにアクションを実行するかしないかという点があります。**

 - render
アクションを新たに実行しない

- redirect_to
アクションを新たに実行する


# 使い分け
- エラ〜メッセージを使う場合にはrenderを使う
- それ以外はredirect_toを使う

```
def create

@post = Post.find(post_params)
    if @post.save
        redirect_to post_path(@post)
    else
        flash.now[:notice] = "投稿できませんでした"
        render :new
    end
end

・
・
・

```
Cocos Creator 3 カンタン2Dゲーム制作(6)【ラベルアトラスの使い方】

# ページ一覧

__Cocos Creator 3 導入編__
- [Cocos Creator 3 ダウンロード](https://qiita.com/Hiro256/items/941b196f2e3f0db9e7da)
- [Cocos Creator 3 インストール](https://qiita.com/Hiro256/items/056e922af7821e482e88)

__Cocos Creator 3 カンタン2Dゲーム制作__
- [プロジェクト作成と画面の説明](https://qiita.com/Hiro256/items/ee21f1aa5dc452f8e992)
- [(1)【トゥイーンの使い方】](https://qiita.com/Hiro256/items/872f82fe7c875106faaf)
- [(2)【プレハブの使い方】](https://qiita.com/Hiro256/items/26c4da8b46565e319471)
- [(3)【衝突判定（コライダの使い方）】](https://qiita.com/Hiro256/items/153777d22a3e24e4bb5a)
- [(4)【アニメーションクリップの使い方】](https://qiita.com/Hiro256/items/f077e64bdc047bc8ef16)
- [(5)【パーティクルの使い方】](https://qiita.com/Hiro256/items/4b91f426d88cfd9e2e82)
- (6)【ラベルアトラスの使い方】← __本記事__

# ビットマップフォントを使う

これまでスコアは文字を表示するだけでしたが、ビットマップフォントに差し替えてみましょう。
Cocos Creator ではビットマップフォントをラベルアトラス(`Label Atlas`)といいます。

# ラベルアトラスの使い方
次の画像を`DigitFont.png`という名前で保存します。
アセットパネルの`images`の配下にコピーします。
![Digit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271948/ab4dd1f3-a7ea-d8ea-8fed-5fa0f69efa78.png)

`images`フォルダ右クリック→`Create`→`Label Atlas`を選択します。
名前を`Digit`とし、選択された状態でインスペクターパネルを開きます。
`Sprite Frame`にアセットパネルから`DigitFont`をドラッグ＆ドロップでセットし、他の項目は以下のように入力します。

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271948/8e78c8f8-11d0-d6e9-3826-47777ac1378a.png">

`Width`、`Height`は画像の文字単位の大きさで入力します。なお今回は数字のみですが、アルファベットや記号もASCIIコード順に並べると使用でき、下図のように複数行に分けることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271948/681ac75a-ccd5-970f-ff6d-a7ca2b31ae56.png)

ヒエラルキーパネルにある既存の`Score`を一度削除し、アセットパネルから`Digit`をコピー。名前を`Score`とします。

`Score`を選択し、インスペクターパネルに以下の内容を入力します。
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271948/4ac5cf56-7fad-df83-2275-68faad3197da.png">

ヒエラルキーパネルにある`Fish`を選択し、インスペクターパネルの`FishCollision`コンポーネントにある`Score`の枠を確認します。
オレンジになっているので、ヒエラルキーパネルから新しく作成した`Score`をドラッグ＆ドロップでセットします。
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271948/a1f8f363-ac6a-5d0c-7367-eaafeb913a4a.png">

## ラベルアトラスの確認
デバッグボタン(`ctrl+P`)で実際の動きを確認します。
gitを用いた開発手順

#  プッシュまでの流れ（概要）
1. 新規アプリを作成する(Django)
1. GitHubでリモートリポジトリを作成
1. git initコマンド：カレントディレクトリをgit管理ディレクトリに設定
1. git add .コマンド：カレントディレクトリ以下をステージング
1. git commit -m "コミットメッセージ"：ローカルリポジトリにコミット
1. git remote add origin リモートURL：GitHub上のリモートリポジトリとローカルリポジトリを紐付ける
1. git push -u origin masterコマンド：リモートリポジトリにpushする

# プッシュまでの流れ
Djangoなどを用いて、プロジェクト、アプリを作成する。
GitHubへ移動して、リモートリポジトリを作成する。

```shell
$ cd アプリディレクトリのpath
$ git init
$ git add . # ローカルリポジトリにステージング
$ git status # 開発ブランチの状態を確認
$ git commit -m "コミットメッセージ" # ローカルリポジトリにコミット
$ git remote add origin リモートリポジトリURL # ローカルリポジトリとリモートリポジトリを紐づける
$ git push origin ブランチ名 # リモートリポジトリにpush
```
- git add .とgit add -A(--all)の違い：
    - git add .：カレントディレクトリ以下の変更のみステージングすることができる。
    - git add -A：-Aオプションでは、自分がプロジェクトディレクトリ内のどの場所にいたとしても、そのプロジェクト全体の変更をステージングすることができる。
    - つまり、操作しているgit管理ディレクトリ以外に移動してコミットしたい場合はgit add -A
- git remote add origin リモートリポジトリURL：
    - リモートリポジトリURLをoriginという文字に置き換えている。originは任意も文字でもok
- git push origin ブランチ名：
    - ブランチ名は作成したものを指定する。masterなど。
    - git push -u origin master：-uオプションを付けることで次回以降、git push origin masterではなくgit pushのみでpushを行うことが可能。つまり、[コマンドを実行したローカルのブランチの上流ブランチを設定すること](https://www-creators.com/archives/5204)。

# git操作（詳細サイト）
- [コマンドで操作するgit - 開発手順に沿って解説](https://qiita.com/ag3_product/items/d0312c90bff4c37bc5dc)
Laravelでidをuuidへ変更する

## はじめに
Laravelでidをuuidへ変更する際のメモです。
この記事は「プログラミング初学者」を対象にしています。

## ライブラリをインストール
```php:example.php
composer require goldspecdigital/laravel-eloquent-uuid:^8.0
```
※laravelのバージョンに合わせてバージョンを適宜変更

## マイグレーションファイル
```php:example.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('users', function (Blueprint $table) {
      $table->uuid('id')->primary(); //変更箇所
      $table->string('email')->unique();
      $table->timestamp('email_verified_at')->nullable();
      $table->string('password');
      $table->rememberToken();
      $table->timestamps();
    });
  }
}

```

## テストデータ挿入
```php:example.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class UserSeeder extends Seeder
{
  /**
   * Run the database seeds.
   *
   * @return void
   */
  public function run()
  {
    DB::table('users')->insert([
      [
        'id' => (string)Str::uuid(), //uuidを使用
        'email' => 'test@example.com',
        'password' => Hash::make(env('GUEST_PASSWORD')),
        'created_at' => '2022/08/07 14:09:10'
      ],
    ]);
  }
}

```

## Seederを実行
```php:example.php
php artisan db:seed
```
もしくは、マイグレーションごと巻き戻したい場合↓
```php:example.php
php artisan migrate:refresh --seed
```

## 自動でUUIDをセットする方法
```php:example.php
<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Str;

class User extends Authenticatable
{
  //ここから追記
  protected static function booted()
  {
    static::creating(function (User $model) {
      empty($model->id) && $model->id = Str::uuid();
    });
  }
}

```
上記のstaticメソッドを記述することで、自動的にuuidが作成されて保存されます。
GitHub と VSCode とターミナルアプリでフォルダ・ファイルの並び順を合わせる


:::note info
本記事では、フォルダ（ディレクトリ）とファイルを総称して **アイテム** と呼びます。
:::

GitHub では、

- フォルダ -> ファイル
- Unicode

の順にアイテムがソートされ、この順番は変更できないようです（公式での記載は見つかりませんでしたが、おそらくそう）。

よって、GitHub の並び順に合わせることとします。

## Visual Studio Code の設定

デフォルトでは並び順が異なります。

![GitHub と VSCode アイテム並び順比較](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2012908/0797fa20-cc43-4fd7-9896-561b251190d5.png)

VSCode の `設定` から、`Explorer: Sort Order Lexicographic Options` を `default` から `unicode` に変更することで、GitHub での並び順と同一になります。

`settings.json` を直接編集する場合は、以下を追記します。

```jsonc:settings.json
{
  // その他の設定...
  "explorer.sortOrderLexicographicOptions": "unicode"
}
```

## ターミナルアプリ

ターミナルアプリはプラットフォームによって異なるので、macOS に標準搭載されている `ls` コマンドで考えてみました。

しかし、Linux では `ls --group-directories-first` とすれば `フォルダ -> ファイル` が実現できるようですが、macOS の `ls` には当該オプションが搭載されていないようです。

- `ls -AFl` の結果をパイプで加工する
- シェルスクリプトを書く
- 外部コマンドをインストールする

などの方法が考えられますが、結局 OS による違いを考慮しなければならず付け焼き刃感が否めないので、この際 Python でクロスプラットフォームかつ自分好みな `ls` コマンドの再開発をしてみました。

https://github.com/seijinrosen/lssr

当初の目的である並び順については、Python の文字列の扱いが Unicode なので、`sorted(pathlib.Pathオブジェクト.iterdir(), key=lambda p: (p.is_file(), p.name))` とするだけで実現できました。

![lssr 出力結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2012908/f6bf1d7f-bf0e-b16b-fbdb-23217636e806.png)

今のところ、自分の用途では便利に使えています。もしよければ使ってみてください。
【PHP】ランダムな値を生成する

今回はランダムな数字を取得する方法について、主にrandメソッドについて解説します。

## ランダムな数値
はじめに、1から100までの中でランダムな数値が作成してみます。
引数に最小値と最大値を渡すことで、範囲を指定することが可能です。


```php
$random_number = rand(1, 100);
```

奇数や偶数の乱数を生成したいときは次のようにします。


```php
$random_number = rand(1, 50)*2;  //1から100までの中の偶数

$random_number = rand(1, 50)*2-1;  //1から99までの中の奇数
```


## 配列の中のランダムな値
数値以外の指定した配列の中からランダムに取り出すときは以下のようにするといいでしょう。

```php
$hash = array('田中さん', '山本さん', '高橋さん','鈴木さん');
$key = array_rand($hash);
$random_person = $hash[$key];
```

## ランダムな文字列
一文字ずつランダムな文字列を作りたいときは`substr()`と`str_shuffle()`を使いましょう。

`substr(str_shuffle(利用する文字, 0, 生成する文字数);`


英字のみで8文字の文字列が生成されます。
パスワードの作成なんかに使えますね。
```php
$str = 'abcdefghijklmnopqrstuvwxyz';
$random_str = substr(str_shuffle($str), 0, 8);
```


同じ文字の重複を許す場合は`str_repeat()`を使います。
第二引数には文字列を反復する回数を指定しています。


```php
$str = 'abcdefghijklmnopqrstuvwxyz';
$rand_str = substr(str_shuffle(str_repeat($str, 10)), 0, 8);
```

## まとめ
以上になります。ぜひ参考にしてみてください。
Wireshark + Mac Chrome で SSLKEYLOGFILE を使って暗号化された TLS 通信を見る方法


`SSLKEYLOGFILE` 環境変数で client が使った Pre-master-secret を記録できる。
それを wireshark に入れることで EncryptedExtensions などを見ることができるらしい。

> https://www.youtube.com/watch?v=5qecyZHL-GU
> Windowsでの方法


# Mac で TLS 通信を解読する方法


2. `SSLKEYLOGFILE` 付きの chrome を開く
    1.
    ```sh
    cd /tmp
    Date="$(date)"
    mkdir -p -- "$Date"
    cd "$Date"
    export SSLKEYLOGFILE=$PWD/keylog.log
    open -n /Applications/Google\ Chrome.app
    ```

    1. こんな感じで `keylog.log` にsecretが記録されていく
        1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/14f4a2a7-fdb2-cada-1ebd-15b6bd1f3e53.png)

1. wiresharkを起動
1. wiresharkのconfigに keylog.log を設定する
    1. `Preferences > Protocols > TLS > (Pre)-Master-Secret log filename`
        1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/210ee225-1ff1-d37c-6388-60f3be0eaec0.png)


1. wiresharkでrecord開始する
3. 開いた chrome でどこかにアクセス
3. wiresharkで解析する


# 成功するとこうなる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/2fcd16ed-aee8-34cf-6e70-17ba6acf2ac4.png)

Encrypted Extentions, CertiicateなどのTLSに加えて、見えないはずの HTTP2 通信まで見れるようになる。
【Flutter】Text ウィジェットのサイズを計算する

レイアウトの都合で実際にウィジェットを配置するまえにTextウィジェットのサイズが知りたいことがあります。
その場合はこのようにTextPainterを使ってサイズを取得することができます。

```Dart
  Size getTextSize(String text) {
    final style = const TextStyle(
      fontSize: 12,
      letterSpacing: 0.67,
      fontWeight: FontWeight.w300,
    );
    final TextPainter textPainter = TextPainter(
        text: TextSpan(text: text, style: style),
        textAlign: TextAlign.start,
        // maxLines: 1,
        textDirection: TextDirection.ltr)
      ..layout(minWidth: 0, maxWidth: 300);
    return textPainter.size;
  }
```

参考
https://stackoverflow.com/questions/52659759/how-can-i-get-the-size-of-the-text-widget-in-flutter
model作成時に思い出したい　忘却録

## はじめに
学習する上でメモとして残したいものをここに記載します。
今回はmodelの作成時について分からなかったことを記載します

## reference型
今回はdeviseのUserの拡張としてフォロー及びフォロワー関係を作ることが目的でした。
そこでFollowsテーブル（model）を作ることにしました。
参考記事(1)には以下のように記載があった

```ruby
$ rails g model Relationship follower:references followed:references
```
この文を見て思ったのがreferencesとは？でしたので参考記事(2)を読んだところこんな感じらしい。

- refernce型は外部キー（FOREIGN KEY）を追加する時に使う
- reference型を使うことによってインデックスを自動に貼ってくれる
- 自動で_idを作成してくれる

外部キーを追加する際に使える型で要件によっては使っていいものくらいに留めておきます。
参考記事(2)にもreference型を使わなくても記載できる方法が出来るらしい。
だが参考記事(3)ではadd_columでの追加が出来ない例も記載されているため使用時には注意する点

## 外部キー制約
じゃあ制約をかけるのは何故？ということを思ったので参考記事(4)を読んだ。
これは親テーブルと子テーブルの整合性を保たせる為らしい
今回だとユーザーテーブルとFollowsテーブルが存在し、フォローする際にUser_id（外部キー）を参照している。だが参照が出来なくなくなる（例えばアカウントが削除されたなど）場合に片方は削除されたことが分かっているがもう片方は参照するだけなので参照できずにエラーが出てしまう。
ので、削除や編集などの変更が出来るのは一部でありこの一部で変更が行われた際に紐づいて変更されることをする。


## 参考記事
(1)
- https://zenn.dev/odentravel/books/e69a157daeecb3/viewer/086fe9

(2)
- https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47

(3)
- https://kossy-web-engineer.hatenablog.com/entry/2018/09/03/022121

(4)
- https://www.javadrive.jp/mysql/table/index11.html
TLS 1.3: Server Hello 書き直し

# Server Hello 書き直し

chrome + wiresharkで暗号化されてる中身をwiresharkで見る方法を見つけた
そしたら、serverhelloの後半が見れたのでここにメモる


```
TLSv1.3	Server Hello, Encrypted Extensions
```




```yml
Transport Layer Security


    TLSv1.3 Record Layer: Handshake Protocol: Server Hello
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 155
        Handshake Protocol: Server Hello
            Handshake Type: Server Hello (2)
            Length: 151
            Version: TLS 1.2 (0x0303)
            Random: e026eb9e16fdf8d23254eb6d8982ab21d1e0fc5ed0e131bf402bea0468916da8
            Session ID Length: 32
            Session ID: 6b34cb2f3b8f7dd1e9b3e4bc7687cdddca84c561b78f3ae7aae184a1e9a9dc1a
            Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
            Compression Method: null (0)
            Extensions Length: 79
            Extension: supported_versions (len=2)
                Type: supported_versions (43)
                Length: 2
                Supported Version: TLS 1.3 (0x0304)
            Extension: key_share (len=69)
                Type: key_share (51)
                Length: 69
                Key Share extension
                    Key Share Entry: Group: secp256r1, Key Exchange length: 65
                        Group: secp256r1 (23)
                        Key Exchange Length: 65
                        Key Exchange: 0439a651bf7133b2add4846cb1a583ed0d48e4601aaa969c4e1e473c5cead13fa30c8b39…
            [JA3S Fullstring: 771,4866,43-51]
            [JA3S: 15af977ce25de452b96affa2addb1036]



    TLSv1.3 Record Layer: Handshake Protocol: Encrypted Extensions
        Opaque Type: Application Data (23)
        Version: TLS 1.2 (0x0303)
        Length: 32
        [Content Type: Handshake (22)]
        Handshake Protocol: Encrypted Extensions
            Handshake Type: Encrypted Extensions (8)
            Length: 11
            Extensions Length: 9
            Extension: application_layer_protocol_negotiation (len=5)
                Type: application_layer_protocol_negotiation (16)
                Length: 5
                ALPN Extension Length: 3
                ALPN Protocol
                    ALPN string length: 2
                    ALPN Next Protocol: h2

```




Server Helloのkey_share以降は暗号化される。

Encrypted Extensions で ALPN が送信されてた。

さらに certificate などが続く。
c# 自作クラスのリスト の宣言 + 代入 の仕方

自分用のメモです。
ググっても出てこなかったので。（ググり方が悪い説はめちゃくちゃある）


```c#:Hello.cs
// https://paiza.io/ja/projects/new?language=csharp

using System;
using System.Collections.Generic;
using System.Linq;

public class Hello{
    
    public class Slime{
	    // プロパティ。getsetって便利だね
        public int HP { get; set; }
        public int MP { get; set; }
        
	    // 他クラスからインスタンス作る想定ならほぼ必須のコンストラクタ！
	    // 復習！コンストラクタってなんですか？→newしたときに自動で走る(クラス名と同じ名前の)メソッドだよ。戻りの型とかいらないよ！
        public Slime(int hp, int mp)
        {
            this.HP = hp;
            this.MP = mp;
        }
    }    
    
    public static void Main(){
        // コンストラクタを使わない時代遅れな書き方ｗ！
        // var items = new List<Slime>()
        // {
        //     new Slime {HP = 30, MP = 10},
        //     new Slime {HP = 50, MP = 6},
        // };
        // ★この記事のメイン★
        // 自作クラスのリストの宣言+代入の仕方
        // メモ1：newを2回書いている理由は、1回目のnewはListを作るnew、2回目のnewはSlimeをつくるnew
        // メモ2：new List<Slime>の後ろの()は省略可能
        var items = new List<Slime>
        {
            new Slime(30, 10),
            new Slime(50, 6),
        };
        
        foreach(var x in items)
        {
            // $の記述でよくなったのにまだガラケーを使ってる感じの時代遅れな書き方ｗ！
            // Console.WriteLine(String.Format("{0} / {1}", x.HP, x.MP));
            Console.WriteLine($"{x.HP} / {x.MP}");
        }
                
        var xxx = items.FirstOrDefault(x => x.HP == 30).MP;
        // Console.WriteLine(String.Format("{0}", xxx));
        Console.WriteLine($"{xxx}"); // 10
    }
}
```
JSでObjectを代入したり、forEachする方法

## 概要
業務の中で受け取ったフォームのオブジェクトをパラメーターに入れたいときに代入が必要だったり、そのオブジェクトのvalueを抜き出したいというケースに遭遇するのでちょっと調べた。

## Object.assign
Object.assignはObjectAとObjectBをマージするのに使う。
```javascript
Object.assign(fruits1, fruits2)
```
大事なのは第二引数のObjectを第一引数のオブジェクトにマージするため同じ要素が含まれている場合は第二引数のObjectが優先されるという点。

実際にどのような動きをするのか見ていただきたい

```javascript
const fruits1 = {
  a: apple,
  b: banana
}

const fruits2 = {
  b: melon,
  c: peach
}

newFruits = Object.assign(fruits1, fruits2)

console.log(fruits1) // {a: 'apple', b: 'melon', c: 'peach'}
console.log(fruits2) // {b: 'melon', c: 'peach'}
console.log(newFruits) // {a: 'apple', b: 'melon', c: 'peach'}
```
fruits1はfruits2がマージされるため、bの変更とcの追加が見られるが、fruits2には変化が見られないことにも注目していただきたい。

## ObjectのforEach
これはどのような状況かというと、
```javascript
{a: 'apple', b: 'melon', c: 'peach'}
```
上記で生成したこのObjectから各value(apple, melon, peach)を出力したい場合など。

実際に取り出してみる。

```javascript
const newFruits = {'a': 'apple', 'b': 'melon', 'c': 'peach'}
rtn = []
Object.keys(newFruits).forEach((key){
  rtn.push(newFruits[key])
})
console.log(rtn);
```

流れは下記のようになる
1. Object.keys(newFruits)でnewFruitsオブジェクトのkey[a,b,c]を取り出す
1. newFruitsのkeyがaのvalue(apple)、bのvalue(melon)、cのvalue(peach)という順番でrtnという空の配列に格納する
1. [apple,melon,peach]とコンソールに出力される

※このようにしてもできるが、実はObject.valueもしくはObject.entriesを使えば初めからvalueを配列にいれることが可能(@juner さん、ありがとうございます！)

## 参考
https://qiita.com/nantekkotai/items/6c603b40ac2264e9f6f6

https://reffect.co.jp/html/javascript-object-assign
Guzzleを使用してSSLクライアント証明書（p12）を送る

# はじめに
やりたいことは外部サービスのAPIを叩きたい！
APIトークンとクライアント証明書（p12形式）とパスワード渡すから認証してね。ってことなのでやっていく
# 実際のコード
```php
private function getData($verification_token)
    {
        $token = env('API_TOKEN'); // Authorizationヘッダーに指定するBearerトークン
        $ssl_pass = env('SSL_PASS'); // 証明書のパスワード
        $ssl_path = storage_path('app/private/test/ssl_file'); // クライアント証明書を配置した場所
        $headers = [
            'Authorization' => 'Bearer ' . $token,
            'Content-Type' => 'application/json',
        ];
        $base_url = env('API_URL');
        $api_path = '/v2/endpoint'; //　APIのエンドポイント
        $client = new Client([
            'base_uri' => $base_url,
            'cert'     => [$ssl_path, $ssl_pass],
            'curl'     => [CURLOPT_SSLCERTTYPE => 'P12'],
        ]);

        try {
            $response = $client->request(
                'GET',
                $api_path,
                ['headers' => $headers]
            );
        } catch (ClientException $e) {
            Log::error('$e->getResponse()->getBody()->getContents());

            return false;
        }
        return json_decode($response->getBody()->getContents(), true);
    }
```
# ハマった箇所
```php
$client = new Client([
            'base_uri' => $base_url,
            'cert'     => [$ssl_path, $ssl_pass],
            'curl'     => [CURLOPT_SSLCERTTYPE => 'P12'],
        ]);

```
`'cert'     => [$ssl_path, $ssl_pass]`で証明書の場所と証明書のパスワードを指定
`'curl'     => [CURLOPT_SSLCERTTYPE => 'P12']`でp12形式ですよと指定してあげる

ここから下は用語仕組みをざっくり説明していくので書き方だけ知りたいって方は読まなくて大丈夫です！
# Guzzleって何?
Guzzle is a PHP HTTP client and framework for building RESTful web service clients
HTTP 要求の送信を容易にし、簡単に Web サービスと統合できるようにする PHPのHTTP クライアントです。

# クライアント証明書と認証の仕組み（ざっくり）
クライアント証明書とは、個人や組織を認証し発行される電子証明書のことです。
SSLサーバ証明書がサーバにインストールされ、ウェブサイトの所有者の実在性を認証するのに対し、クライアント証明書は、システムやサービス、メールを利用するユーザのデバイスに証明書をインストールし、そのユーザが正規の利用者であることを認証します。
パスポート、入館証といった身分証明書を想像すると理解しやすいです。

サーバにSSLで接続する際、クライアント(ブラウザ)に電子証明書を提示させ、接続元を認証する仕組み。
通常、サーバーが信用する認証局が署名した電子証明書をクライアントが提示してはじめてSSLの接続が成立する。
一般のSSL経由のhttp接続では、クライアントが一方的にサーバを認証 し、サーバーはクライアントを認証しない。一方、クライアント認証では、 クライアントとサーバが相互に認証し合う必要がある。
# SSL証明書の形式
・PEM（Privacy Enhanced Mail） 
.pem.cer　よく見るやつ
・DER（Distinguished Encoding Rules）
.cer
・PKCS7(Public-Key Cryptography Standards)
.p7a 
・PKCS10
.p10
・PKCS12  
.pfx/.p12　クライアント証明書によく使われる


# 参考リンク
[Guzzleのgithub](https://github.com/guzzle/guzzle)
[Guzzleのドキュメント](https://docs.guzzlephp.org/en/stable/request-options.html#ssl-key)
[githubでp12形式についてのスレッド？](https://github.com/guzzle/guzzle/issues/2411)
[p12ファイルについて](https://shinkufencer.hateblo.jp/entry/2019/07/12/000000)
[証明書の説明](https://www.ssl.com/ja/%E3%82%88%E3%81%8F%E3%81%82%E3%82%8B%E8%B3%AA%E5%95%8F%EF%BC%88FAQ%EF%BC%89/X-509%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%A8%E3%81%AF/)
[パスフレーズの渡し方で参考にしたやつ](https://www.web-dev-qa-db-ja.com/ja/php/guzzle%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6curl%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%A7%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%82%92%E6%B8%A1%E3%81%99/837276555/)
Herokuの無料枠が廃止になるのでDeta.shへ移行する



# 追記(2023/3/11)
約半年ほどDeta.shで簡単なサービスを運用していたが、先日Deta.shに大幅なアップデートがあり、仕様が大きく変わった。
これによりREST APIを公開して運用することができなくなった。（できなくはないが必ずヘッダにAPIキーを指定する必要がある。そのため例えばLINE Messaging APIのバックエンドとしては使用不可）
Detaは”Personal Cloud”を思想に掲げているらしく、何らかのサービスのバックエンドとして使うにはちょっと使い勝手が悪くなってしまった。
というわけで、自分の使い方には合わなくなったため現在はAWSへ移行している。

# HerokuのFree Planが終了するらしい(泣)
https://blog.heroku.com/next-chapter
> Starting November 28, 2022, we plan to stop offering free product plans and plan to start shutting down free dynos and data services. We will be sending out a series of email communications to affected users.

2022/11/28までに有料版にアップグレードしてねとのことらしい。

# Deta.sh
⇒ [Deta.sh](https://www.deta.sh/)へ移行した

> The Cloud for Doers & Dreamers.

[Deta.sh](https://www.deta.sh/)は無料で使えるクラウドプラットフォーム。
デプロイしたアプリはAWS上に展開されるようだ。
主に3つのサービスが使える。

1. クラウドランタイム (Deta Micors)
2. 容量無制限のNoSQLデータベース (Deta Base)
3. １アカウントあたり10GBまでのクラウドストレージ(Deta Drive)

- 無料（そもそも有料プランが存在しない）
- Herokuと違い30分でスリープする制限はない
- RuntimeにはPythonかNodeが使用できる


## CLIのインストール
`curl -fsSL https://get.deta.dev/cli.sh | sh`

## ログイン
`deta login`

## アプリの作成
`deta new --python app_hello`

エンドポイントのURLその他が表示される
```
{
    "name": "app_hello",
    "id": "xxxxxxx",
    "project": "xxxxxx",
    "runtime": "python3.9",
    "endpoint": "https://xxxxx.deta.dev",
    "region": "ap-southeast-1",
    "visor": "disabled",
    "http_auth": "disabled"
}
```


ファイル構成はプロジェクトのディレクトリ直下に2ファイル:
```
├── main.py
├── requirements.txt
```


```python: main.py
import os

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def say_hello():
  return {"message": "Hello, Deta.sh"}

```


```: requirements.txt
fastapi
```


### デプロイ・動作確認
用意できたらデプロイ
`deta deploy`

動作確認
`curl https://<xxxx>.deta.dev/`


## 環境変数のセット・デプロイ

```:.env
ANY_ENVVAR_HERE=xxxx
```

`deta update -e .env`
`deta deploy`
環境変数をセットした後に変更を反映するためもう一度デプロイする必要があるが、ファイルに差分がないとデプロイできないため、main.pyを編集してからもう一度デプロイする。


## ログの取得
`deta logs`

## ドメイン
Deta.shのダッシュボードから、任意のサブドメインの設定や、自分のドメインを設定できる。
![d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12825/f7571f23-841c-6e7c-b162-a20102e9c8af.png)
HTTPヘッダが記憶の彼方なのでなんとか粉々に噛み砕きたい - 分類編

# これは何？
[前に書いたクリックジャッキングの話](https://qiita.com/kei_0_f/items/91af748e7b3ce2f33cb6)でHTTPヘッダの重要性に気が付いた私が、[MDN Web Docさん](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers)の力を借りてなんとか噛み砕こうとする記録です。
解釈間違ってたりしたらそっと教えていただけると幸いです。

# コンテキストに応じた分類
- **リクエストヘッダ**　…読み込むもの、クライアントの情報
- **レスポンスヘッダ**　…レスポンスの追加情報(場所とかサーバー情報とか)
- **表現ヘッダ**　　　　…本体に関すること(MIMEタイプとかエンコードとか)
- **ペイロードヘッダ**　…本体と直接は関係ないけど、くらいの情報(長さとか転送に使う方のエンコードとか)

# つまりどういうことだ
## リクエストヘッダ
- 条件付きのリクエストをするタイプ(Accept、Accept-*、If-*)
- サーバから欲しい回答を貰えるように文脈を伝えるタイプ(Cookie、User-Agent、Referer)
のざっくり２種類がある

リクエストのヘッダ全部がリクエストヘッダということではない
Content-Lengthとかは厳密には違う(エンティティヘッダ)が、なんかノリでリクエストヘッダ扱いされることはよくあるらしい

## レスポンスヘッダ
レスポンスの中身自体には関係ないけど、しっかり伝えるために文脈を伝えるもの
やっぱりContent-Lengthみたいに厳密にはレスポンスヘッダじゃないけどレスポンスヘッダ扱いされるものはある

## 表現ヘッダ
本文部分に関わってくる内容をつたえるもの
リクエストでもレスポンスでも入ってたりする

## ペイロードヘッダ
安全にデータをやりとりするための細々したもの
リクエストでもレスポンスでも入ってたりする



次以降の記事で、各カテゴリ毎に確認していきたいなと思ってます
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その007

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: 構成、設定とオブジェクト
構成と設定の学習　にある練習問題７問目をご紹介します。
https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-setup-and-objects/study-up-on-org-setup

なお、こちらの内容はYouTubeでも公開しております
https://www.youtube.com/watch?v=jfjLizp8dEE


<iframe width="560" height="315" src="https://www.youtube.com/embed/jfjLizp8dEE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


練習問題7問目はこちらです

![007-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5b32f20a-6aea-4d1d-8dec-f7acb8496ac1.png)


正解はBです

ユーザから「凍結」ボタンをクリックするとそのユーザはログインできなくなります
凍結解除をすればログイン可能になります
今回のように「一定期間ログインできない」ようにするには「凍結」がおすすめです

「凍結」の詳細はこちら
https://help.salesforce.com/s/articleView?id=sf.users_freeze.htm&language=ja&r=https%3A%2F%2Fwww.google.com%2F&type=5

では、他の答えが間違っている理由について説明します

Aについて
パスワードリセットをしてもユーザはログイン可能なので間違いです

Cについて
ログイン時間を変更してもそのログイン時間ではログイン可能なので間違いですね

Dについて
そもそもユーザそのものは削除することはできません。
出来るとしたらユーザ無効化ですね

詳細はこちらのヘルプをご確認ください
https://help.salesforce.com/s/articleView?id=sf.deactivating_users.htm&type=5


なお、確かにユーザ無効化をすればログインできなくはなりますが、
今回のシナリオ的に効率的な方法ではないので正解としては誤りです
![効率ではない.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a33f9a05-c1a7-aa7e-ca52-55cf381ae0ca.png)

今日の内容はここまでです。
皆さん楽しく元気にSalesforceを学びましょう！
RDBのユニーク制約とRailsのユニークバリデーションの違いを理解しよう

Railsアプリケーションで下記のusersテーブルのemailにユニーク制約をつけたい場合、どのように実装しますか？

* users

| Field | Type | Null |
|:-----------|:------------|:-------------|
| id         | bigint(20)  | NO           |
| email      | varchar(255)| NO           |

だいたいの場合、下記2つのいずれか、または両方を実装するのではないでしょうか？
* RDBのemailカラムにユニークインデックスを付ける
* Userモデルにuniqueness validationを実装する

どちらの実装でもデータがユニークであることとをチェックしてくれるという意味では同じように感じますが、制約の完全性が全然違います。
一言で言うと、RDBのユニーク制約は100%保証されるが、Railsのuniquenessは突破される可能性があります。

# この記事で使うユニーク制約

記事の最初に記載したusersテーブルを使います。emailをユニークにしたいとします。

DBでユニーク制約をかける場合はemalカラムにユニーク制約をつけます。
下記のコマンドでつけることができます。

```sql
ALTER UNIQUE INDEX idx_email ON users (email);
```

Railsでユニーク制約をかける場合はモデルクラスにvalidationを定義します。

```ruby
class User < ApplicationRecord
  validates :email, uniqueness: true
end
```

# RDBのユニーク制約とRailsのユニークバリデーションの違い

## Rails以外からの追加・更新には効かない

Railsだけで制約をかけた状態で`mail: hoge@example.com`を追加します。

Railsで追加する場合は下記の通り。

```ruby
# 追加OK
User.create!(email: 'hoge@example.com')
# uniq validationでエラー
User.create!(email: 'hoge@example.com')
```

validationを定義しているので重複して登録はできません。
ただ、DBは直接insertすることもできます。

```sql
--　'hoge@example.com'が存在していても成功する
INSERT INTO users (email) values ('hoge@example.com');
```

DBから直接insertする以外にも、別アプリケーションが同じDBを使っている場合、そちらのアプリケーションでユニークチェックをしていなければ重複して追加することができます。

一方、DBにユニーク制約がついていたらどうでしょうか？
SQLで直接insertすることもできませんし、別アプリーケンションから追加することもできません！鉄壁です！！

ただ、そもそも1つのDBを複数のアプリケーションから参照しているのがよくない！
SQLで直接更新も運用で回避できる！！
という意見もあると思います。

おっしゃるとおりだと思います。運用でカバーできる範囲ですね！

## DBの更新元がRailsだけでもユニーク制約が効かないパターン

たとえRailsからしか更新されないとしてもユニーク制約を突破することがあります。

Webアプリケーションでユーザー追加処理が同時にリクエストされた場合を考えます。
その場合、`User.create!(email: 'hoge@example.com')`がほぼ同時に実行され、下記のように両方の追加処理が成功します。

```ruby
# リクエスト1
User.create!(email: 'hoge@example.com')
# selectしても存在しないので追加する

# リクエスト2(リクエスト1と同時)
User.create!(email: 'hoge@example.com')
# create1のtransactionがまだ確定されておらず、selectしても存在しないので追加する
```

では複数ユーザーが同時にアクセスする可能性があるものだけ気をつければ良いのか？？
いいえ、違います。
例えば、クリック連打などで同じユーザーが同じリクエストを複数送ってくることもありえますし、通信不調などでクライアントから2,3度同じリクエストが送られることもあります。

## ほぼ起きないからRailsのvalidationだけでもいいんじゃね？

前述のようにRailsのvalidationが突破される発生確率は低いです。
ただ、プロダクトの規模が増えトランザクションが増えると発生確率は増えます。
そして、発生した時のめんどくささは半端ないです。

Railsでしかチェックできない制約もあると思うのでそれはRailsでやるしかないですが、ユニーク制約などDBで制約できるものはDBで制約するのが良いでしょう。

## おまけ: 両方に制約つけとけば安心やな！

確かに両方につけておけば突破されることはありません。
ただ、制約を守るだけであればDBの制約だけで100%守れるのでRailsにvalidationをつける意味はないと思います。
実装＆運用コストが増えるだけです。

実際にユニーク制約がついているカラムにvalidationを実装しているシーンをよく見かけますが、Railsで検知して制御したい場合を除いてチェックする必要はないと思います。
たまにソースだけで制約が見れるからRailsにもvalidationを書くという意見を聞きますが、コードリーディングのためだけに処理を実装するのは良くないと思いますし、そもそもバックエンドを開発するならDBスキーマも把握する必要があると思います。
Create React Appを利用してプロジェクトを作ってみた

# 動機
Reactを勉強する機会ができたため、何から始めようか会社の先輩に尋ねたところ、最強のReact開発環境を作成できる`Create React App`を教えていただいたので、手始めに利用してみた。

# Create React Appとは
新規シングルページアプリケーションを作成する際に、Reactが公式で推奨している開発環境のこと。

Reactのアプリ開発に必要な`webpack`や`Babel`などのツールを自前で準備する必要はなく、即座にReact開発環境を構築することができる。

# 実際にプロジェクトを作成してみた

## 環境
MacBook Pro(2016)
macOS Monterey(version: 12.5)

## 手順

### 1. インストール
`sudo npm i -g create-react-app`

### 2. プロジェクト作成コマンドの実行
`create-react-app {プロジェクト名}`

```bash
****@******* ****** % create-react-app sample_app

Creating a new React app in /***/sample_app.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...


added 1394 packages in 2m

209 packages are looking for funding
  run `npm fund` for details

Initialized a git repository.

Installing template dependencies using npm...

added 55 packages in 11s

209 packages are looking for funding
  run `npm fund` for details
Removing template package using npm...


removed 1 package, and audited 1449 packages in 4s

209 packages are looking for funding
  run `npm fund` for details

6 high severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

Created git commit.

Success! Created sample_app at /***/sample_app
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd sample_app
  npm start

Happy hacking!
```

`Happy hacking!`まで出力されれば、プロジェクト作成成功

### 3. プロジェクトに移動し、`npm start`を実行
```bash
Compiled successfully!

You can now view sample_app in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.11.9:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully
```


アプリが起動し、localhostに下記ページが表示されれば成功。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512041/14f18b54-ec2e-d9b2-a811-871d16224642.png)


### 最後に
Reactで開発環境を構築するには`webpack`や`Babel`などのツールを導入する手順が必要かと思っていたが、`Create React App`を利用することで簡単に作成することができた。

Reactの勉強をしたいのにその前の手順で詰むことがなかったため、今後も利用していこうと思う。

### 参照（公式ドキュメント）
https://create-react-app.dev/
Java と JavaScript の違い(TypeScriptもあるよ！)

突然ですが皆さん、こう思ったことはありませんか？

**結局、Java と JavaScript の違いってなんなの？？**

人によって、ハムとハムスターだったり、そばと焼きそばだったりします。
(ついでにTypeScriptのことを「型焼きそば」と言ったり……)

でもそれって、ニュアンス的に正確じゃない気がします。
なので今回は、Java と JavaScript(ついでにTypeScript) の違いを適切に解説します!

<font color="gray">一応、出来る限り正確に書きますが、間違いがあればコメントいただけると幸いです…</font>

# Java と JavaScript の違い

### 使用用途

* Java
  - 主にサーバサイドの言語。処理ロジックを担当することが多い。
 
* JavaScript
  - 現状、どちらでも扱うことが出来る。[^1]
[^1]: サーバサイドでJavaScriptを扱うには、Node.js等が必要です

* TypeScript
  - JavaScript 同様、現状はどちらでも扱うことが出来る。[^2]
[^2]: TypeScript をコンパイルすると、JavaScript ファイルが作成されます
つまり、TypeScript は JavaScript の書き方の一種です


(とはいえ JavaScript と TypeScript もまたプログラミング言語なので、何かしらの処理はします)


つまり、
<font color="blue">**Java と JavaScript は「似て非なるもの」**</font>
です。

恐らくですが、ここからハムとハムスターなる例え話が生まれたのではないでしょうか。

そしてこれが間違いの始まりです。

では具体的に何が違うのか。
一歩踏み込んでみましょう。

# Java と JavaScript の歴史

Java はサン・マイクロシステムズ社が開発したプログラミング言語です。
一方で LiveScript(現JavaScript) はネットスケープコミュニケーションズ社が開発したプログラミング言語です。

そして1995年当時は Java が大流行していました。
さらに、上記2社は**業務提携**していました。
<br>

*──ここからが個人の感想です──*

結果的に、ネットスケープコミュニケーションズ社は Java の知名度にあやかり、
サン・マイクロシステムズは「今後 JavaScript が有名になれば、うちが手がけた言語として名を残せるぞ」
こう考えたのではないでしょうか。

事実として、たくさんの人々が
「*Java と JavaScript の違いって……？*」
と、術中にハマっているわけです笑

# 結論
Java と JavaScript を例えるなら、
`東京ディズニーランドは、東京にはない(ただし、どちらも日本国内にある)`と同義
というのが適切だと考えました。


もう少し踏み込むと、 JavaScript は Java の影響を受けて作られたものではありません。


東京ディズニーランドは、東京都公認の国の施設ではないですよね？
しかも、東京ディズニーランドは娯楽施設で、東京都は地域の区分です。
名前が似てるのに、中身は全然違います。
<br>


また、TypeScript と JavaScript の関係性として、
`イラストをラフから描くのか、いきなり描くのかの違い`
というのが、適切だと考えました。

TypeScript は、JavaScript をコーディングする際に、記述ミスを減らせるようにコンパイルするようにしたものなので、このような表現にしました。


# その他
要するに、関係性を第一にした例え話をするのか、
本記事のように正確性を求めるのかによって表現は変わると思います。

ですので、一概に「これが正しい」「これは間違ってる」を論ずるつもりはないです。

とはいえ、私の例え話が間違っているということであれば、コメントにてご教授いただけますと幸いです。

# 参考にしたサイト

* [JavaScript Wikipedia](https://ja.m.wikipedia.org/wiki/JavaScript)
* [TypeScriptとは？](https://www.pasonatech.co.jp/workstyle/column/detail.html?p=2761)
知り合いと知り合いは他人 ― 複数のチームのマネジメント ― 

大きな会議室、または全員の顔が映りきらないZoomにて。

「参加する意味ないよなあ」と思うMTGに出席している。

はたまた「こんなに人が集まる必要があっただろうか」と感じるMTGのファシリテーターをしている。

**複数のチームをまたいだコミュニケーション**において、こういった出来事はよくあり、かつ解決もすぐできるものではありません。

この記事では、上記のような状況について最近考えたことを書きます。

## 無関心をつよめてしまうMTG

具体例として、一人のマネージャーが5つのチームをマネジメントしている状況を想像してみます。

このときマネージャーと各チーム[^1]の集まるMTGを無計画に実施していると、次のようなことが起きはじめます。

- あるチームの報告・相談だけでMTGが終わった
- 一言も発言していないチームがある
- 議論のテーマがいろんな方向に発散する

これらを放置すると、**各チームの無関心の度合いをつよめてしまう**ことになります。「私っていらないよね」という感情です。

## 空気を読まれることの弊害

ちがった観点、つまりチーム目線でも上記の事象を見てみます。

複数チームの集まるMTGでは、当然ながら発言のハードルは上がります。真面目な人ほど「この場で話すべきか」を考えることでしょう。

その結果「この話はこの場ではすべきでない」と考え、重要だったかもしれない話題を後回しにしたり、そのまま揮発して取り上げられなかったりと、問題解決のチャンスを失うこともありえます。

空気を読んでくれるからこそ、 **円滑ではあるが価値のないMTG** になってしまう、ということです。

## 「とりあえず集まる」をやめてみる

さて、これらを避けるための解決法はあるのでしょうか。たとえば「全チームが関与する共有・相談にしぼる」という工夫は有効そうです。

そしてこの記事では、もうひとつの方法を考えてみます。それは「**すべてのチームが集まらないとダメなのか**」という観点より、MTG自体をやめてみることです。

とりあえずみんな集まるのではなく、必要なチームだけが集まる。

この工夫はとても簡単に聞こえますが、実際は難しいはずです。それでもチャレンジする価値はあると感じています。

## まとめ。不用意な結合を避け、認知不可を下げる

話は変わりますがプロダクトの設計において、**結合**はとても重要な要素のひとつです。

> アーキテクトの目的は、求められるシステムを構築・維持するために必要な人材を最小限に抑えることである。こうした人々のパワーを奪うものは何か？それは、結合である。それも早すぎる決定との結合である。[^2]

プロダクトの設計と同じように、**チームどうしの結合**も適切にコントロールしないと、期待されるコラボレーションは生まれないのだと感じました。

またチームが大きな成果を生み出し続けるには、チームの認知負荷を下げることが重要だとも言われています。

> チームトポロジーでは、チームの認知負荷を制限し、チーム間のコミュニケーションを明確に設計する必要がある。[^3]

チーム同士の不用意な結合は、チームの認知負荷を増やすことにつながるはずです。

つまり **「みんなが集まる」という方法は慎重に取り扱わねばならない**、というのが今の私の結論です。

[^1]: たいていはチームの責任者が集まるでしょうが、チーム全員が集まろうと責任者が集まろうと、MTGの設計があいまいであれば同じことが起こると考えています。

[^2]: Robert C. Martin,角 征典,高木 正弘. Clean Architecture　達人に学ぶソフトウェアの構造と設計 (Japanese Edition) (Kindle Locations 2576-2579). Kindle Edition. 

[^3]: マシュー・スケルトン,マニュエル・パイス. チームトポロジー　価値あるソフトウェアをすばやく届ける適応型組織設計 (Japanese Edition) (p. 42). Kindle Edition.
大量の画像ファイルから一部を切り出す

画像ファイルの左上を切り出す必要がありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/6745fa48-7a1e-5655-ad69-daa41bf86e55.png)
画像ファイルは数百ありまして、画像編集ソフトでひとつひとつ加工するのは大変です。
ということでプログラムにやらせました。

# 実行準備
ここではUbuntuで必要なライブラリをインストールします。
Pythonの画像処理ライブラリ`PIL`のImageモジュールにある`crop`メソッドでもいけそうですが、今回は`OpenCV`を使ってみます。

```:インストール
apt install -y libgl1-mesa-dev

pip3 install opencv-python
pip3 install opencv-contrib-python
```

# 処理コード
`imread`メソッドで画像を読み込むと、画像データを2次元配列で返すので **[top:bottom, left:right]** のようにスライスすればOKです。

```python:Python
import cv2
import glob

for file in glob.glob('img/*.png'):
	img = cv2.imread(file)
	cv2.imwrite(file, img[0:50, 0:120])
```

なお、`glob`で`recursive`に`True`を指定し、ファイルパスに`**`を含めると、サブディレクトリを再帰的に処理できます。
Python,Ruby,PHP,Java,JavaScript,Perlの配列の比較 | プログラミング言語比較

<a href="https://qiita.com/yuki_kimoto/items/f9c2454e7f9130ddb003">Qiita > プログラミング言語の比較</a>

プログラミング言語Python,Ruby,PHP,Java,JavaScript,Perlの配列の比較

# Python

https://qiita.com/gouwan/items/c83b47ce1b7c77cce7c5

# Ruby

https://qiita.com/may88seiji/items/ce9396a4c267a3d449ae

# PHP

https://qiita.com/tokutoku393/items/ea2a61765eda1dee8f2e

# Java

https://qiita.com/sentral1110728/items/532de46714b7215a2e99

# JavaScript

https://qiita.com/takeshisakuma/items/b23b1a748098f30e2ff2

# Perl

https://perlzemi.com/blog/20161012147627.html
npm init vue@latestをしたらesbuildのinstallでエラーが出た

記事作成日: 2022/8/29
### TL;DR
`npm init vue@latest`して`npm install`するとエラーが出た(エラーログは下に有)。
原因はnodeのバージョンが古かった。

#### 実行環境
```
macOS Monterey (version12.5.1)
node -v:v16.14.2
npm -version:8.5.0
```

### 詳細

`npm init vue@latest`し`てnpm install`すると、以下のようなエラーが出た。ログを読むと、esbuildの`install.js`で問題が生じている様。
 ```
npm ERR! code 1
npm ERR! path /Users/xxx/xxx/xxx/vuetest/vue-project/node_modules/esbuild
npm ERR! command failed
npm ERR! command sh -c node install.js
npm ERR! node:child_process:828
npm ERR!     err = new Error(msg);
npm ERR!           ^
npm ERR! 
npm ERR! Error: Command failed: /Users/xxx/xxx/xxx/vuetest/vue-project/node_modules/esbuild/bin/esbuild --version
npm ERR!     at checkExecSyncError (node:child_process:828:11)
npm ERR!     at Object.execFileSync (node:child_process:866:15)
npm ERR!     at validateBinaryVersion (/Users/xxx/xxx/xxx/vuetest/vue-project/node_modules/esbuild/install.js:89:32)
npm ERR!     at /Users/xxx/xxx/xxx/vuetest/vue-project/node_modules/esbuild/install.js:242:5 {
npm ERR!   status: null,
npm ERR!   signal: 'SIGKILL',
npm ERR!   output: [ null, Buffer(0) [Uint8Array] [], Buffer(0) [Uint8Array] [] ],
npm ERR!   pid: 3966,
npm ERR!   stdout: Buffer(0) [Uint8Array] [],
npm ERR!   stderr: Buffer(0) [Uint8Array] []
npm ERR! }

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/xxx/.npm/_logs/2022-08-28T09_56_36_307Z-debug-0.log

```

調べるとesbuildのgithubのissueで[これ](https://github.com/evanw/esbuild/issues/1973)を発見したので、nodeのバージョンをv17.9.1に上げるとエラーは生じなかった。

https://github.com/evanw/esbuild/issues/1973

【メモ】
上記のissueは`esbuild install.js fail`と調べて見つけた。
【夏休み企画】#IT用語一問一答【毎朝投稿15日目】OSS

# この記事を読むと、、
- 「関連用語」を使って「OSS」を説明できるようになる
- 「OSS」がもっと好きになる(多分)

# 関連用語
copyleft license / GPL / permissive license

[**復習用**] 記事の内容を見る前に上記の言葉で「OSS」を説明してみよう！

# 企画説明
- クラウドって何？って人に聞かれて説明してるけど俺もよく知らないや、、
- ドキュメント読んでみてるけど半分くらい何言ってるか分かんない、、
- 今日の夕飯はナスの炒めものにしよっかな〜、あれ、NASってなんだっけ？

みたいなことが結構あったので、知ったかしていたIT用語を毎日一個ずつちゃんと学んでいこうっていう企画です！

昨日の記事はこちら↓

https://qiita.com/acta/items/8393accf790651e91237

# OSSとは
OSS = Open Source Software = 利用者の目的を問わず利用・拡張・再配布等が可能なソフトウェア

- **open source license** = OSSに課されている利用上の制約
    - copyleft licenseとそれ以外のpermissive licenseに分けられる

- **copyleft license** = (ざっくりいうと)二次以降の著作物の再配布が制限されないライセンス
    - 例えば以下のライセンスが有名
        - **GPL** = GNU General Public License
            - 例えばLinux KernelやGCC = GNU Compiler CollectionはGPLで公開されているOSS

- **permissive license** = BSD-style license
    - 例えば以下のライセンスが有名
        - MIT License
            - GitHubで最も使われているらしい
        - BSD License
        - Apache License
            - 利用者に特許権を付与しているので、作者は利用者に対して利用料の請求や特許権侵害の申立てができない

# 参考資料
- https://en.wikipedia.org/wiki/Open-source_software
- https://en.wikipedia.org/wiki/Copyleft
- https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%96%E3%83%BB%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9
- https://e-words.jp/w/Apache%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9.html
「イシューからはじめよ」と言われても

[イシューからはじめよ──知的生産の「シンプルな本質」 | 安宅和人 |本 | 通販 | Amazon](https://www.amazon.co.jp/%E3%82%A4%E3%82%B7%E3%83%A5%E3%83%BC%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E2%80%95%E7%9F%A5%E7%9A%84%E7%94%9F%E7%94%A3%E3%81%AE%E3%80%8C%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E6%9C%AC%E8%B3%AA%E3%80%8D-%E5%AE%89%E5%AE%85%E5%92%8C%E4%BA%BA/dp/4862760856)、一回では吟味しきれない難しい本だった... しかし

![](https://images-na.ssl-images-amazon.com/images/I/41XXDnKTHdL._SX317_BO1,204,203,200_.jpg)


「犬の道」というのがキーワード。で、犬の道からいかに脱するかが説かれる。
[【要約・感想】イシューからはじめよ|価値の高い知的生産で「いい仕事」する方法](https://usp-times.com/note/start-from-issue/)
> 仕事ができる人とは、仕事を多くこなす人ではない、仕事ができる人とは、問題を見極め・より良い解決策を考え・成果を上げる人

> 解決すべきイシューの条件3つ
> 1. 本質的な選択肢であること
> 1. 深い仮説があること
> 1. 答えを出せること

[マネジメントって何すればいいの〜？1年間マネジメントに向き合ったのでまとめを書きます - Qiita](https://qiita.com/yunico-jp/items/04750a3bdc183ae7ea05)
[『イシューからはじめよ　知的生産の「シンプルな本質」』を読んでみた。 - Zenet Tech Blog](https://media.zenet-web.co.jp/entry/2022/08/18/102302)
[『イシューからはじめよ』のまわりで考える。 - ほぼ日刊イトイ新聞](https://www.1101.com/c/ataka_kazuto/)

## 学び
- 考え方
    - 悩まない、悩んでいる暇があれば考える
    - 根性に逃げるな
    - 常識を捨てる
        - 実行がむずかしそうな。「イシューを見極めるとかグダグダ言ってねえで手え動かせよおじさん」とか出てこないのか
- イシュードリブン
    - 「解く」前に「見極める」
    - 良いイシュー
        - 本質的な選択肢である
        - 深い仮説がある
        - 答えを出せる
    - イシューが見つからないときのコツ
        - 変数を削る
        - 視覚化する
        - 最終形からたどる
        - So What? を繰り返す
        - 極端な事例を考える
- 仮説ドリブン
    - イシューを分解し、ストーリーラインを組み立てる
    - ストーリーを絵コンテにする
- アウトプットドリブン
    - 実際の分析を進める
    - ただし、答えありきにしない
- メッセージドリブン
    - 「伝えるもの」をまとめる
        - 本質的に
        - シンプルに

## 犬の道

http://www.nakahara-lab.net/blog/archive/10165

イシュー度がさして高くない（誰も解決してもさして喜ばないもの）を、課題ととらえて、解の質をあげようとしてしまう。その結果、「解決しても、あまり誰にも喜ばれない、芯を食っていない、しかし洗練されてしまった解決策」ということになってしまう。

「イシューからはじめよ」と言われてもなかなか難しいが、少なくともいま自分は「犬の道」に迷い込んでいないかな？と意識するのは第一歩なのかもしれないという感想です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/f1495c8e-7e73-caf0-6aaa-ca984eb39b13.png)

以上です～
[Nokogiri]日本語が文字化けする

メモです

# 結論

以下のように `Nokogiri::HTML` の第3引数で明示的にエンコーディングを指定して解決

[Nokogiri::HTML](https://nokogiri.org/rdoc/Nokogiri/HTML4.html)

```
# read file 
doc = File.open("out.html") do |f| 
  Nokogiri::HTML(f, nil, 'UTF-8')
end
```

以下を参考にさせて頂きました

[CP932など特殊な文字を含むHTMLをスクレイピングする](https://memo.sugyan.com/entry/20120524/1337788935)

# 詳細

あらかじめ取得してきた HTML をパースする処理をする際に Nokogiri を利用するようにした。

上記 HTML には日本語(特殊文字ではなく、カタカナ)も含まれているが、取得して表示するようにしようとすると文字化けした

取得した HTML をみると `Content-type` の ` charset` の指定がなかった為、実際に書いてある文字コードと Nokogiri でエンコードする際の文字コードが違っていたのではないかと思われるが、細かい部分までは調べてない
2022/8/29主にITとかセキュリティの記事

ドコモ、セキュリティソフトを装ったフィッシングSMSやアプリに注意を呼びかけ(8/27)
https://k-tai.watch.impress.co.jp/docs/news/1435235.html

DoorDashもTwilioと同じフィッシング攻撃の被害　ユーザーのメアドや電話番号にアクセス(8/27)
https://www.itmedia.co.jp/news/articles/2208/27/news064.html

小中学校にサイバー攻撃、千葉(8/27)
https://jp.reuters.com/article/idJP2022082701000631

サイバーテロに備え　産学官の合同対処訓練【宇部】(8/27)
https://ubenippo.co.jp/2022/08/27/1284962/

中国の偽情報にどう対抗、台湾の巧妙な防御策
西側諸国が台湾の取り組みに注目(8/26)
https://jp.wsj.com/articles/taiwans-defenses-against-information-warfare-gain-attention-11661454173

“タイマー”仕掛け故障装う　島津製作所 医療用装置めぐり(8/26)
https://www.fnn.jp/articles/-/408597

10月から先行運用される「電子処方箋」は患者にどんなメリットがあるのか(8/27)
https://hc.nikkan-gendai.com/articles/278043

Plex、ユーザー全員にパスワード変更を要請(8/27)
https://www.zaikei.co.jp/article/20220827/687023.html

リスクマネジメントを支える企業カルチャー 経営層から従業員、投資家まで風通しよく(8/27)
https://www.risktaisaku.com/articles/-/71775

iPhone、Mac、Apple Watchの脆弱性の活発な悪用を確認、更新を(8/27)
https://news.mynavi.jp/techplus/article/20220827-2435516/

企業の漏洩パスワード6割が脆弱　推測容易で瞬時に突破(8/26)
https://www.nikkei.com/article/DGXZQOUC258BV0V20C22A7000000/

【定員間近の講演も】内閣サイバーセキュリティセンター 副センター長が日本のセキュリティ政策を解説(9/16開催)
https://enterprisezine.jp/news/detail/16530
e-learningにゲーミフィケーションを持たせよう

# はじめに
https://www.elucidat.com/blog/gamification-in-elearning-examples/

こちらの記事の要約みたいなものです。

# ゲーミフィケーションとは何か
ゲーミフィケーションとは **「ゲームのような」** 形式をもたせることで学習体験をよりよくすることです。

ゲーミフィケーションはクイズとかアンケートだけを指すわけではありません。質問だけのものからシナリオベースのものまであらゆるゲーミフィケーションが可能です。
一番重要なことはユーザの注意を引き、モチベを維持させることです。

# e-learningでゲーミフィケーションを使うベストプラクティス
e-learningにゲーミフィケーションを用いるときは、何も本格的なビデオゲームを設計する必要はありません。ゲーム要素を持たせることで、やる気を起こさせたり教育的にすることが大切なのです。

次のような要素を組み込むことがおすすめです。

### 1.ストーリー
説得力のあるストーリーを作りユーザを魅了しましょう。没入型のコンテンツを作るために、ユーザをストーリーに埋め込むのもいいかもしれません。
製作者たちを表すキャラクターなどを埋め込むとより面白くなるかもしれません。

### 2.ビジュアルデザイン
美しいデザインはユーザを惹きつけることができます。
鮮やかな色とグラフィックを組み合わせて視覚に刺激的な学習体験を実現しましょう。

### 3.大会など
誰しも軽い競争は好きなものです。ユーザがチームのほかのプレイヤーや匿名プレイヤーと対戦できるようにしてみましょう。また、モチベーションを高く保つために自分自身とも競争できるようにしましょう。
また、スコアも公開することでユーザが他と比べてどのようなパフォーマンスをしているのかも確認できるようにしましょう。

### 4.チャレンジ
小さくも頻繁にユーザに報酬を与え、コースが進むにつれて難易度をあげましょう。

### 5.報酬
バッジやメダル、レベルなどの報酬を与えることでユーザのモチベーションを高め、より長く滞在時間を維持できます。

### 6.フィードバック
ユーザがタスクやクイズを終えたときに即フィードバックを提供することは、進捗状況などを知ることができるため、ユーザが集中して勉強し続けるために良いです。

# 注意点
・全部の目的にゲーミフィケーションが適しているわけではありません。正確に物事を伝えたい場合は情報が抜け落ちることがあるので気を付けましょう。

・ゲーミフィケーションがどうこう言う前に、学習目標を設定することが大切です。また、内容についての**文化**みたいなものも注意しましょう。

# bestチップス
### 1. 小さく始めてよいが手抜きはするな
ゲーミフィケーションだけに集中するのではなく様々なアプローチを試すのが大切です。「小さく始める」といってもスコアをクイズの終わりにいれるとかそういう話ではなく、複雑で広範囲にわたる実装をしましょう。がっつりやりましょう。
ゲームの仕組みは「楽しくする」以上の目的を果たさねばなりません。

### 2.ゲームではなく学習を優先する
最初に学習目標を明確にし、それに役立つようにゲームの仕組みを設計しましょう。**ポイント**はプロフィールを完成させるとか、コースを共有するとかの簡単なことで獲得できるようにするなど、すぐにたまるように作ることは価値があるかもしれませんが、**バッジ**はより意味のあるもので、「新しい知識、能力、スキルを示す」ものの見返りとしてのみ与えるようにしましょう。

### 3.評価基準と進行状況を明確に
ゲームがどのように機能するかについての透明性と明確さはモチベ維持につながります。どのようにしてポイントを得るのか？ポイントとはそもそも何なのか。きっとバッジに変換したり、コンテンツのロックを解除するときに使うんでしょうが...また次のレベルまたは報酬を得るために何が必要か、とかも大切です。報酬は何を意味するんでしょうか。（有形、金銭的な利益に変換されたり、新しい機会のための認定として機能するでしょう）

### 4.チャレンジを徐々に増やしていく
ユーザは最初から頻繁に簡単な成果を得る必要があるでしょう。小さい積み重ねのおかげでユーザは大きな挑戦への準備が整うのです。目標は常に、次のレベルが視野内にあること、挑戦的であるが達成可能であることが大切です。新しい課題のたびに、学習者が最近学んだことを利用する必要がある場合はさらに良いでしょう。

### 5.継続的な学習を促進する
スコア表を定期的にリセットしたり、新しいチャレンジや報酬を導入するなど、学習者がスコアを継続して改善し続けることを奨励する方法を探しましょう。
【JavaScript】プレビュー機能の実装

# 【JavaScript】プレビュー機能の実装

###### 特徴
・画像を選択するとプレビュー画像が表示される
・画像は何度も選び直すことができプレビュー画像もその度変わる

## 手順
### ■HTML側の編集
#### ❶画像投稿ページのHTMLにプレビュー画像を表示するスペースを作成
```
<div id="previews"></div>
```

### ■JavaScript側の編集
#### ❷preview.jsを作成して読み込むよう設定
app/javascriptの中にpreview.jsを作成
```ruby:app/javascript/packs/application.js
require("@rails/ujs").start()
require("@rails/activestorage").start()
require("channels")
require('../preview')  // 追記する
```
#### ❸preview.jsの編集
##### ①画像投稿ページのフォームを取得
##### ②今記述したプレビュー画像を表示するスペースのHTML要素を取得
##### ③条件分岐で、画像投稿ページのフォームでないなら処理を終了するように設定
##### ④選択した画像情報に取得
* input要素（画像が入るところ）の値に変更があった場合、関数を発火させる
* 値の変更があった要素から、画像の情報を取得する
* 取得した画像情報のURLを生成する
##### ⑤取得した画像情報をブラウザへ表示するために、HTML要素をJavaScript側で生成
##### ⑥setAttributeメソッドを用いて生成したimg要素のsrc属性へ変数blobを設定
##### ⑦作成したHTMLの要素をブラウザに表示
##### ⑧画像を選択し直したら古いプレビューは削除されるようにする
```javascript:app/javascript/preview.js
document.addEventListener('DOMContentLoaded', function(){
  // ①画像投稿ページのフォームを取得
  const postForm = document.getElementById('new_post');
  // ②プレビューを表示するためのスペースを取得
  const previewList = document.getElementById('previews');
  // ③画像投稿ページのフォームがないならここで終了。「!」は論理否定演算子。
  if (!postForm) return null;

  // ④input要素を取得
  const fileField = document.querySelector('input[type="file"][name="post[image]"]');
  // input要素で値の変化が起きた際に呼び出される関数
  fileField.addEventListener('change', function(e){
    // ⑧古いプレビューが存在する場合は削除
    const alreadyPreview = document.querySelector('.preview');
    if (alreadyPreview) {
      alreadyPreview.remove();
    };
    //
    const file = e.target.files[0];
    const blob = window.URL.createObjectURL(file);
    // ⑤画像を表示するためのdiv要素を生成
    const previewWrapper = document.createElement('div');
    previewWrapper.setAttribute('class', 'preview');
    // 表示する画像を生成
    const previewImage = document.createElement('img');
    previewImage.setAttribute('class', 'preview-image');
    // ⑥setAttributeメソッドを用いて生成したimg要素のsrc属性へ変数blobを設定
    previewImage.setAttribute('src', blob);

    // ⑦生成したHTMLの要素をブラウザに表示させる
    previewWrapper.appendChild(previewImage);
    previewList.appendChild(previewWrapper);
  });
});

```