OmniAICreator/Qiita-1.07M huggingface dataset:
macでいきなりはじめるPHPにチャレンジする！(1) MAMP導入編

#前書き
初めまして！
僕は某プログラミングスクールの夜間・休日コースで半年間勉強をしていました。
某プログラミングスクールでは、rubyおよび、rubyonrailsを中心に学習してきたので、次の一歩として、web開発に用いることができるPHPを学ぼうと思い、それにあたって学んだことをまずは記事にしたいと思います！特に同じような学習の進め方をする人に少しでも参考になれば幸いです。
なお、初学者であり知識の偏りもあるので、理解が不足している部分があるかと思います。もし何かありましたら教えていただけると幸いです。

僕はPHPを学ぶにあたって、タイトルにある「いきなりはじめるPHP: ワクワク・ドキドキの入門教室」を購入しました。少し古い本ではありますが、とても理解しやすく、また実際に動かしながら作ることができるのと、説明が簡潔ながらまとまっていて、とても読みやすい本でした。初学者でまだまだ理解できていないことが多い僕でもスラスラと読みながら1つのアプリを開発できました。

・・・しかし、この本は古いのはともかく、あくまでもwindowsでの開発方法が中心で、macのことはほとんど触れられていません、そこでmacで進めるにあたって苦労したこと、別で調べたことなどをまとめていきたいと思います。

#MAMPとは？
今回はMAMPの導入についてです。MAMPとは「Mac Apache MySQL PHP」の略で、Mac向けに作られたmysqlとPHPの開発環境ツールです。
本ではXAMPPを導入すると書いていますが、XAMPPはMacとの相性が悪く、エラーが出やすいとのことであり、mac用は存在しますが避けた方がいいとのことです。僕はXAMPPを導入してからその事実を知り、やり直すことになりました・・・

このMAMPを導入することで、PHPを導入できるということはもちろん、仮想のサーバーを立てて、ローカル環境での開発、動作確認ができます。railsの場合は「rails s」コマンドで出来たのは・・・と思ったんですが、これはrailsにセットで入っているPumaというやつが頑張ってくれているようです。知らないうちに便利なものを享受しているものだと改めて思いました。今回もMAMPという便利なものに頼らせてもらいましょう。

#MAMPを導入する！
それではMAMPの導入です。まずはMAMPのダウンロードページにアクセスしましょう。
https://www.mamp.info/en/downloads/
![PHP8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891157/f1493ae3-5731-44f5-2c09-57003c08250d.png)
このような画像の画面になるので、macユーザーの方は迷うことなくmacOS用を選びましょう。ちなみにOSのアップデートがされていないと動作保証はされないようなので注意です。

ダウンロードし、開くとおなじみインストーラーが表示されます。
![PHP9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891157/be65a20d-751c-5aea-b47d-fc4f527e6a8b.png)
日本語化されているので、迷わず進められそうです、続けるを押して、どんどん進めるとインストールされます。

![PHP10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891157/7913779b-733a-c3c4-2a24-8088475979e3.png)
無事インストールし起動するとこんな画面になります、ちなみに起動するとpro版をかなり勧められますが、僕はあくまでも初学者なのでとりあえずスルーしました、pro版との違いはこちらのサイトに比較が書かれていました。バージョンが異なるので変更あるかもしれませんが、参考になりそうです。
https://webrandum.net/mamp-mamp-pro/

#MAMPの起動
![PHP13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891157/cff17d72-3b9c-8f18-dcd8-120d26c03939.png)
startボタンを押すとローカルサーバーが起動します。画像のような案内画面が表示されますね。XAMPPだとMySQLの起動は別なのですが、MAMPの場合は同時に起動されるようです。この辺りがまた学習、開発を進めていく上で大きな違いを産んでいきそうな予感がしますね。

![PHP11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891157/2c82f89d-e656-6654-9cbd-01b12aee81eb.png)
左上の「preferences」をクリックすると設定画面に移ります。案内ページをoffにする設定などもありますが、注目したのはPortsの設定です、デフォルトだと画像のようになっています。
このままだとlocalhostへのアクセスがhttp://localhost:8888となります。そこで80&3306ボタンをクリックするとhttp://localhostになります。mysqlのポートも3306になります。ただしskypeなどを利用している場合、80のポート争いが起きてサーバーが起動できないこともあるそうです。僕は現状80&3306でうまく動作していますが、うまく行かない場合は他のアプリの見直しや、ポートの変更も必要になりそうです。

MAMPの導入は以上です。次回はPHPを実際に動かすまでを書いてみたいと思います。何か意見などありましたらコメントお願いします。
【Rails】アプリに必要なファイルを一括で新規作成する

# この記事の概要

rails newコマンドでアプリを新規に作成したあと、モデル、コントローラ、ビューファイルなどはコマンドを一回一回入力して作成すると思うのですが、コマンドを打つ際に実行漏れがあったり、スペルミスがあったり~~そして何より面倒だったり~~していました。

本記事では、バッチファイルを用いて、各種MVCファイルを一括で作成する方法について解説します。(検索してもあまり情報がなかったので、もしかすると邪道な方法なのかもしれません…。)

# やり方
## 1.バッチファイルを作成する

libフォルダ内にbatchフォルダを作成し、バッチファイルを作成する。(ファイル例：create_mvc.rb)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/65cf5d5e-42f0-672f-8695-612f7cd2a849.png)


## 2.バッチファイルを読み込めるように設定を変更する

config/application.rbにbatchフォルダを読み込めるようにする設定を追記する。

```ruby:config/application.rb

module Portfolio
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2
    # libフォルダ内のファイルを読み込み可にする
    config.paths.add 'lib', eager_load: true

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end

```

3.バッチファイル内に一括で実行するコマンドを追記する

スクリプトでrailsのコマンドを実行するためには、system "実行するコマンド"という風に書けばOKです。

```ruby:lib/batch/create_mvc.rb
class Batch::CreateMvc
  
  # ファイルの一括作成
  def self.create_file
    
    system 'rails g model Post'
    system 'rails g model PostFavorite'
    system 'rails g model PostComment'
    system 'rails g model TagMap'
    system 'rails g model Tag'
    system 'rails g model Relationship'
    ・・・以下、作りたいファイル分のコマンドを記載する
    
  end
end

```

# 4.バッチファイルを実行する
バッチファイルの実行自体はコマンドを直接コンソールに入力して行います。

実行コマンド：bundle exec rails runner Batch::[バッチファイルのクラス名].[実行したいメソッド名]
例：bundle exec rails runner Batch::CreateMvc.create_file

これによりバッチファイルが読み込まれ、ファイルに記載されているコマンドが上から順に実行されます。
そのため、rails gコマンドのようなファイル作成コマンドを一括で行うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/f37bb1dd-c7f1-3420-c0fc-2f076979996a.png)

# バッチファイルで一括登録できると何がいいの？

正直、このバッチファイルを作る工数と、コンソールに一回一回rails gコマンドを入力する場合の工数に大きな差はありません。
ただ、下記の点でメリットがあるかなと思っています。

- 実行コマンドを予め用意するため、事前にスペルミスや漏れの確認ができる
- 一度作ったバッチファイルは今後新規にアプリを作成する際に使い回せる

特に二つ目のメリットが個人的には大きいかなと思っています。
どのアプリもrails gは必ず実行すると思うので、バッチファイル内の各コマンドのファイル名だけメンテナンスすれば、より少ない工数でファイル作成ができるようになるのではないでしょうか。

ただ、本来バッチファイルは定期的に実行する処理を書くものなので、今回のように1アプリに１度しか使わないバッチファイルはあまり効果があるとは言えないかもしれません…。
ソフトウェアRAIDとハードウェアRAIDの違い

## 勉強前イメージ

ハードウェアRAIDはRAIDコントローラーでコントロールされてるイメージ
ソフトウェアRAIDはOSでコントロールしてる感じ...?

## 調査

### ハードウェアRAID

マザーボードとディスクをRAIDコントローラが仲介し、RAIDコントローラーによってデータの割り振りが行われます。
よって、RAIDを意識せずにOSはインストールを行いその上にミドルウェアのインストールを行うことが出来ます。
ハードウェアのRAIDコントローラーを使用してRAID構成を行うので、ハードウェアRAIDと呼ばれています

### ソフトウェアRAID

ソフトウェアRAIDはハードウェアRAIDと違い、OSはRAIDを意識してデータの書き込みや読み取りを行うことになります。
ハードウェアRAIDはRAIDコントローラーによって割り振りが行われたので気にすることはありませんでしたが、
ソフトウェアRAIDはOSの上に成り立っており、ソフトウェアを通じて行われるのでCPUやメモリの消費、読み書きの速度が不利になります。

### 違い

まとめてみました

| / | ハードウェアRAID | ソフトウェアRAID |
|:-:|:-:|:-:|
| **構成の仕方**  | サーバにハードウェア的に設置  | OSの上にソフトウェア的に設置  |
| **CPU/メモリの消費**  | 少ない  | 多い  |
| **対象**  | 大規模サーバ向け  | 小規模・個人サーバ向け  |

## 勉強後イメージ

ハードウェアRAIDはそのままのイメージ
centos7だとmdadmをインストールしたらいけるっぽい？
あんまりLVMやらZFSやらよくわからんので、勉強するためにインストールしてやってみるのありかもー

## 参考

- [ハードウェアRAIDとソフトウェアRAIDの違い、RAIDの種類について](https://milestone-of-se.nesuke.com/sv-basic/architecture/hwraid-swraid/)
- [ハードウェアRAIDとは](http://www.obenri.com/_raid_build/soft_hard.html)
- [自宅サーバー構築日記: CentOS7でmdadmを使ったソフトウェアRIADを組む](https://increment-log.com/centos7-mdadm-raid/)
@nuxtjs/markdownitを使ってマークダウンの記事をHTMLで出力する

[前回、](https://qiita.com/sketchbookfjt/items/3d94436714c1ad1e59e2)nuxt.jsとcontentfulを使ってブログサイトを環境構築しました。
今回はmarkdownitというnpm moduleを使ってContentfulで書いたマークダウンの記事をHTMLで出力したいと思います。

## 設定していく

### インストール

[公式サイト](https://www.npmjs.com/package/@nuxtjs/markdownit)を見ながら今回は`@nuxtjs/markdownit`を使ってやっていきます。

```console
$ npm install @nuxtjs/markdownit
```

### クリスマス仕様・・・？

コマンド実行したらクリスマスっぽいバナーが流れてきました 🎅 < Hello

![スクリーンショット 2020-12-15 22.14.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409946/e7dfa624-c7d3-f1b0-772d-80a3ec7e9f78.png)


### nuxt.config.jsに設定を追加する

```nuxt.config.js
modules: [
  '@nuxtjs/axios',
  '@nuxt/content',
  '@nuxtjs/markdownit' //この１行追加
],
// ~~~~~~省略~~~~~~~

// 追加
markdownit: {
    injected: true,   // $mdを使ってどこからでも使えるようになる
    breaks: true      // 改行を<br>に変換してくれる
  }
}
```

## vueファイルに$mdを追加する

### templateの一部を差し替え

v-htmlを使用してHTMLを出力していきます

> 2重中括弧の mustaches は、データを HTML ではなく、プレーンなテキストとして扱います。実際の HTML として出力するためには、v-html ディレクティブを使用する必要があります。 引用：[Vue.js - 生のHTML](https://jp.vuejs.org/v2/guide/syntax.html#%E7%94%9F%E3%81%AE-HTML)

```_slug.vue
<!-- before -->
<div>
  {{ article.fields.body }}
</div>

<!-- after -->
<div v-html="$md.render(article.fields.body)"></div>
```

### HTMLで出力できた

検証画面

![スクリーンショット 2020-12-15 23.31.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409946/329631cb-04ad-e954-11a7-fab67ed1aea7.png)

サイト画面

![スクリーンショット 2020-12-15 23.32.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409946/9616ffcf-2af8-a90d-c380-df9ed855d3bb.png)


## npmのscopeって

`@`がついているパッケージ(`@nuxtjs/markdownit`とか)はscope付きパッケージといいます。
同じ名前のパッケージは存在できないので`@nuxtjs/markdownit`や`@hoge/markdownit`のようにscopeを使用することで別のユーザーや組織が作成したパッケージと競合することなく作成ができます。

[公式サイトのスコープに関する説明](https://docs.npmjs.com/cli/v6/using-npm/scope)


## 終わりに

npmを追加しただけなので短いですが以上になります。
今回記事を書きながら実装しましたが、その際にバグを見つけてしまったので頑張って直そうと思います。。。
UnityでプラットフォームごとにUIの判定エリアを変える

この記事は[クラスター Advent Calendar 2020](https://qiita.com/advent-calendar/2020/cluster)の16日目です。前回はulaphさんによる「[SwiftでViewの状態をenumで管理する](https://qiita.com/ulaph/items/3e1fc9b5cebf593677ab)」でした。C#からSwiftへ軽やかに転身していてカッコいい。

## はじめに

こんにちは。クラスター株式会社でデザイナーとして主にUIデザインをやっています。

[バーチャルSNS cluster（クラスター）](https://cluster.mu/)

Unityでマルチプラットフォームに対応したUIを作る場合、同じにできる機構はなるべく共通になるよう努めます。とは言え、無闇矢鱈にすべてを共通化するわけではありませんし、プラットフォームごとの対応が簡単に出来るものは対処しておきたいです。マウスイベントやタップ判定などを行う判定のエリアもその１つです。

## プラットフォームごとの判定エリアのサイズ

一般的にマウスカーソルデバイス……ここではPCですが、これのホバーやクリックを判定するエリアのサイズは、UIの見た目と一致していることがほとんどです。

一方スマートフォンでは操作する指よりもUIが小さいため、判定エリアのサイズは見た目以上のサイズになっているのが一般的です。例えばiOSのソフトウェアキーボードは入力する内容を予測して動的に判定エリアのサイズが変化しています。すごい。

参考: [ソシオメディア | iPhone の当たり判定を検証した](https://www.sociomedia.co.jp/4152)

入力を予測して……はさすがに困難を極めるので、プラットフォームごとでオン／オフする程度の簡単な対処を考えてみました。

### Unity UIでボタンを組む

![Buttonコンポーネントがアタッチされたオブジェクト以下に背景や画像などのゲームオブジェクトが設置されたヒエラルキーの図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54160/1e6f1fe1-6b7b-3fcf-ed9b-12df33b813cc.png)

自分がUnityでよく組むタイプのボタンです。Unityのプリセットのようにコンポーネントを1つのオブジェクトにまとめ過ぎず、ビジュアルの責任も適度に分けたほうがデザインの柔軟性があり、かつメンテナンス性も高いです。

### ボタンの判定エリアを広げる

![判定エリアが広がっていることがわかる実行時のGIFアニメーション](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54160/937ad99f-5d9a-fdb8-a79c-badb1b0ea353.gif)

操作時にフィードバックを返す`TargetGraphic`以下に、Imageコンポーネントをアタッチして、アルファ値を0にした`TargetArea`というゲームオブジェクトを配置しています。このオブジェクトのサイズをボタンよりも広げ、Raycast Targetをオンにすることで判定エリアを広げています。

### PCプラットフォームで`TargetArea`を削除する

プラットフォームを判別する方法を調べると2つ出てきました。

1. [プラットフォーム依存コンパイル - Unity マニュアル](https://docs.unity3d.com/ja/current/Manual/PlatformDependentCompilation.html)
2. [RuntimePlatform - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/RuntimePlatform.html)

2のRuntimePlatformで以下のよう書かれています。

>プラットフォーム別コンパイルを使用するほうが、実行時にチェックする必要がないため軽くて高速なコードを生成できます。 

使用しているデバイスが途中で変わる……などということは起きないので、スマートフォン向けに追加した`TargetArea`をPCの場合はプラットフォーム依存コンパイルを使って削除するのが簡単そうです。

Unityが用意してくれている`UNITY_STANDALONE`を使います。囲んだコードが、すべてのPCプラットフォームでコンパイルに含まれます。

```DestroysSelfWhenStandalone.cs
using UnityEngine;

public class DestroysSelfWhenStandalone: MonoBehaviour
{
    void Start()
    {
#if UNITY_STANDALONE
        Destroy(this.gameObject);
#endif
    }
}
```

### プラットフォームを切り替えて実行してみる

![PCプラットフォーム実行時のみ判定エリアを広げていたゲームオブジェクトが削除されている様子のGIFアニメーション](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54160/d9985da7-ddde-6923-d26a-c93b0b50136e.gif)

PCプラットフォームに切り替えて実行した時のみ`TargetArea`が削除されました。

## まとめ

共通化はUnityの大きな利点の１つではありますが、プラットフォームに向けたこういうちょっとした最適化は今後も積み重ねていきたいものです。

心残りが１点。そもそも対象のゲームオブジェクトを環境ごとでビルドに含めない方法を取れれば良かったなと思います（スマートフォン側には虚無のスクリプトが残ることに）。自分で調べた範囲ではその方法は見つけられませんでした。残念。

次回は2tatuki4さんによる「ワールド制作でメモリが大変なことになった時に見るやつを書く」です。お楽しみに！
Laravel de パスワードチェッカー

昨今では辞書型攻撃が......
という前置きはゴミ箱に捨てておいて、漏洩が確認されたパスワードを公開している[Have I Been Pwned](https://haveibeenpwned.com/)のAPIを活用し、脆弱なパスワードで登録できないようなバリデーションを作成していきます。

### APIのドキュメントを読む

今回は、送信されたパスワードが漏洩履歴があるのか、またどれだけあるのかどうかを知りたいので、[Pwned Passwords](https://haveibeenpwned.com/API/v3#PwnedPasswords)のAPIを活用していきます。

詳細は、ドキュメントを読んでいただきたいのですが、要約すると、

0. パスワードをSHA1でハッシュ化。
1. 先頭5文字を送信（大文字小文字問わず）
2. 先頭5文字までで一致したものすべてを、6文字目以降と漏洩回数ともに返却
3. なんやかんやしてちょ

です。

### 実装しようぜ

#### 土台作り

```cmd:cmd
> php artisan make:rule SafePassword
```

```php:app\Rules\SafePassword.php
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class SafePassword implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        //
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The validation error message.';
    }
}

```

これで土台部分はできました。

#### ゴリゴリ書く

```php:app\Rules\SafePassword.phpのpasses()の中
// パスワードをSHA1でハッシュ化
$hash_password  = strtoupper(hash('sha1', $value));

// ハッシュ値の先頭5文字を変数定義
$first_section  = substr($hash_password, 0, 5);

// ハッシュ値の6文字目以降を変数定義
$second_section = substr($hash_password, 5);


// cURLリソースの新規作成
$curl_handle = curl_init('https://api.pwnedpasswords.com/range/'.$first_section);

// cURLの設定
curl_setopt_array($curl_handle, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 3
]);

// 結果を変数に保存
$response = curl_exec($curl_handle)."\n";

// そもそも結果の中に存在するか検索
if (preg_match("/$second_section:\d*\r?\n/", $response) === 1) {

    // 存在した場合、「何回」漏洩したか取得
    $count = (int) preg_replace("/([\s\S]*)$second_section:(\d*)\r?\n([\s\S]*)/", "$2", $response);

    // 漏洩回数の許容値をconfigで取得（直接定義しても可）
    $allow_leak_time = (int) config('auth.allow_password_leak_time');

    // もし、許容以上の漏洩回数ならfalse
    if ($count > $allow_leak_time)
        return false;

    // 許容以下ならtrue
    return true;
}

// そもそも漏洩してなかったらtrue
return true;
```

#### 実際に指定する

```php:適当なController,Request
'password' => ['required', 'confirmed', 'min:8', \App\Rules\SafePassword()]
```

### コード書いてみて

最初のほうはforeachを使ったりして正規表現を使わないように努力しましたが結局正規表現が楽でした。。
似たような正規表現を二回使っているのはあまり美しくない（と個人的には）思っているのでおいおい修正していきたいと思います。
（強引すぎるという自覚はあるので「こんな方法いいよ！」等ありましたらお教えいただけると幸いです。）

### 作成後記

23:59作成終了！
Linuxの代表的なコマンド（7つ）

**①cd [path]（current directory）**
　[path]に移動するためのコマンド。

**②pwd（print working directory）**
　今いるディレクトリを表示させるコマンド。

**③mkdir [new folder]（make directory）**
　新しいフォルダを作成するためのコマンド。

**④touch [new file]**
　新しいファイルを作成するためのコマンド。

**⑤ls（list）**
　カレントディレクトリのファイル、フォルダを一覧表示させるためのコマンド。

**⑥rm [file]**
　既存のファイルを削除するためのコマンド。

**⑦rm -r [folder]**
　既存のフォルダの削除するためのコマンド。
dockerコンテナでlaravel php artisan serveする時のhost指定

host=0.0.0.0で起動する必要がある。
デフォルトだと127.0.0.1でlistenされるが、これはあくまでコンテナ内でlistenしている。
ホストpcからcurl localhostでアクセスすると、コンテナ内に通信する際に別の内部ipに変換される。
そのため127.0.0.1でlistenしてしまうと応答できない。
そのため0.0.0.0でlistenする。こうするとコンテナ内の全てのインターフェース?でlistenする。
そのため応答できるようになる。


↓コードは/appにマウントされる想定

```Dockerfile
FROM centos:centos8

RUN dnf module install -y php:7.4

WORKDIR /app
CMD [ "php", "artisan", "serve", "--port=80", "--host=0.0.0.0" ]
```


参考
https://qiita.com/amuyikam/items/01a8c16e3ddbcc734a46
回線の輻輳が起きる理由

はじめに
実際に自分でも体験しましたが、コロナによるリモートの増加で、意図しない箇所で、インターネット向けのトラフィックが増加し遅延などが発生する事象が多かったと思います。
そもそも輻輳ってどういう理由で起きるのか説明していこうと思います。

この記事では、
簡単にベストエフォートと帯域確保の違いとベストエフォート（主にフレッツ光）で起こる回線の輻輳について簡単にまとめます。
**あくまで簡単に**です。

**ベストエフォートと帯域確保**
そもそも回線にはベストエフォート型と帯域確保型があります。

**帯域保証**
その名の通り**通信の帯域が約束された通信回線**で、契約者がネットワークを専有する形（1Gbpsの土管をすべて占有して使えるYO）で1Gbpsの契約をすれば常時必ず上りも下りも1Gbpsの速度を保証します。、というサービスです。
＃参考までに上り下りで保証が違うけどちょっと安い、なんてサービスもあります。

その分コストがかかるのですが、遅延が出たり断があると困るようなもの（安定的な通信環境や速度を常に維持したいとか）や安定性やネットワークに用いられます。
欧米ではギャランティ型（Guaranteed Bandwidth）として一般に広く普及している方式です。

**ベストエフォート**
それに対してベストエフォート型サービスの場合、通信速度を1Gbpsで契約したとしてもそれは保証されません。
あくまで**「最大で出る速度が1Gbpsです。」**（1Gbpsの土管は用意するけどみんなで通ります。なので混むかもYO）というサービスになります。共有しているので最大速度が出ることはほぼないです。

その分安価で導入しやすいという特徴があります。

ベストエフォートで代表的なものはNTTの「フレッツ光」です。
これは固定ブロードバンドってやつになります。

導入数が非常に多いのですが、このフレッツがその構成ゆえによく輻輳するのですが、その事象について簡単に説明していきます。

**ブロードバンドアクセス網の輻輳**
固定ブロードバンドサービスのアクセス網の輻輳は、アクセス集中によって加入者光ファイバの共有部分や網終端装置などで部分的かつ一時的に発生します。
前者は数十ユーザ単位で、後者は数千ユーザ単位で共有されていて、輻輳が起こると輻輳箇所を共有しているユーザが影響を受けます。
ユーザの利用需要に対してISPの提供帯域が不足していると、利用の多い時間帯に輻輳が発生しやすくなります。

と書くとなんだかわからないですよね。

要するに**フレッツ光回線は様々な箇所で「設備を共用している」ので、「共有している設備のキャパシティを超えると遅くなる」**ということです。
特にマンションなどでは、マンション内の光の設備が共用の場合が多いので同一ビルで大量のデータを流したりしていると急に遅くなったりします。

通信速度の体感でいうと
コロナ以前のオフィスでは、日中が遅く、夜間早い、ただしバッチなどで夜間にデータ流す会社が同居していると特定の時間が異常に遅い、などが一般的でした。
しかしコロナ過の現在では、リモートワークが増え、家庭からのアクセスが増えたため、出勤時よりもインターネット経由の通信量は増える傾向にあり、時間帯関係なく輻輳が発生しやすくなっています。

アクセス網の品質、特に輻輳の状況は、回線導入の際にISPや接続メニューを選ぶ上で重要な情報ですが、詳しく調べることは、ほぼ不可能です。

そんな中導入数の多い、フレッツ網で、ここ数年、PPPoE網終端装置の輻輳が問題となっています。
PPPoE方式は「NTTの回線を使ってISPがインターネット接続を行う」フレッツで採用された方式です。
2000年代前半の日本のブロードバンド普及を成功させた技術です。

しかしフレッツは安価なサービスなので設備投資とのバランスが悪く増設が難しい状況にあります。
なので輻輳が起きたからと言って設備を増やすようなことにはあまりなりません。

すなわち待っていても輻輳が解決されるようなことはあまりない、ということです。

なので安価だからとコスト面だけ見て、ベストエフォート型のフレッツを導入すると品質に問題が発生して、帯域確保を再手配するなんてこともあるので、インターネット回線の導入から検討が必要な際は、よく考えて導入してくださいね、というお話でした。

**ただコストとのバランスや地域で速度も出るので一概にフレッツが悪いというわけではないのを最後に宣言しておきます。**

ちなみに輻輳問題はIPv6を採用した場合には、輻輳を回避する方法を取り入れているキャリアのサービスもあります。
そちらはまたの機会にしたいと思います。
化合物の記述子化まとめ

# はじめに
化合物の構造情報から生成できる変数（記述子）のまとめ

# 前準備

###使用するデータ
1290分子の水溶解度（LogS）データ（sdfファイル形式）の内、20分子を使用
（[金子研究室HPのデータセット](https://datachemeng.com/pythonassignment/)から取得）

### モジュールのインストール
```
conda install -c conda-forge rdkit
```

# 変換コード

### モジュールのインポート
```python
import os
import numpy as np
import pandas as pd

from mordred import Calculator, descriptors
from rdkit import Chem, rdBase, DataStructs
from rdkit.Chem import Descriptors, Draw, Descriptors3D
from rdkit.Chem import AllChem
from rdkit.ML.Descriptors import MoleculeDescriptors
```

### MOLオブジェクトの準備

```python
#SDFファイルから molオブジェクトの作成
suppl = Chem.SDMolSupplier('logSdataset1290_2d.sdf')

#molオブジェクトのリストを作成(20分子だけ使う)
mols_list = [mol for mol in suppl if mol is not None]
mols_list = mols_list[:20]

#データのラベル用にSMILESのリストを作成
labels = [Chem.MolToSmiles(mol) for mol in mols_list]

#molオブジェクトからのsmilesリストの作成、及び逆をしたい場合は以下のコード
#mols_list = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]
```

### 記述子化
以下の記述子それぞれが格納されたPandas DataFrameを作成した。

- ECFP4(Extended Connectivity Fingerprint) : 原子からある距離にある部分構造を数え上げていく
- FCFP4(Functional Connectivity Fingerprint) ： 特徴ベースのフィンガープリント？
- MACCS keys :全部で166の部分構造についての有無を調べ上げたもの
- RDkit descriptors : 分子構造から導かれる計算値
- mordred discriptors : 分子構造から導かれる計算値

```python
# ECFP4フィンガープリントの作成（Extended Connectivity Fingerprint）
ECFP4 = [AllChem.GetMorganFingerprintAsBitVect(mol, 2,1024) for mol in mols_list]
df_ECFP4 = pd.DataFrame(np.array(ECFP4, int),index=labels)

# FCFP4相当のフィンガープリントの作成(Functional Connectivity Fingerprint）
FCFP4 = [AllChem.GetMorganFingerprintAsBitVect(mol, 2, 1024,useFeatures=True) for mol in mols_list]
df_FCFP4 = pd.DataFrame(np.array(FCFP4, int),index=labels)

#MACCS Keys 
maccs_fps = [AllChem.GetMACCSKeysFingerprint(mol) for mol in mols_list]
df_maccs = pd.DataFrame(np.array(maccs_fps, int),index=labels)

# RDkit記述子の作成
descriptor_names = [descriptor_name[0] for descriptor_name in Descriptors._descList]
descriptor_calculation = MoleculeDescriptors.MolecularDescriptorCalculator(descriptor_names)
RDkit = [descriptor_calculation.CalcDescriptors(mol_temp) for mol_temp in mols_list]
df_RDkit = pd.DataFrame(RDkit, columns = descriptor_names,index=labels)

#mordred記述子の作成
calc_2D = Calculator(descriptors, ignore_3D=True) #2D記述子
calc_3D = Calculator(descriptors, ignore_3D=False) #3D記述子
df_mord = calc_2D.pandas(mols_list,quiet=False)
df_mord.index = labels
```

# 記述子について（補足情報）
- MolLogP : Crippenらによる原子ベースのLogP指標(LogPは水/オクタノール分配係数）
- MolWt : 分子量
- NumHAcceptors : 水素結合アクセプターの数
- NumHDonors : 水素結合ドナーの数
- NumHeteroatoms : へテロ元素の数
- NumRotatableBonds : 回転可能な結合数
- FractionCSP3 : 全炭素数におけるsp3炭素の割合
- TPSA : トポロジカル極性表面積


# 参考HP

- [分子記述子計算ソフトウェア mordred の開発](https://www.jstage.jst.go.jp/article/ciqs/2016/0/2016_Y4/_pdf/-char/ja)  
- [RDKitでフィンガープリントを使った分子類似性の判定(化学の新しいカタチ)](https://future-chem.com/rdkit-fingerprint/)
- [RDKitにおける記述子の扱い方をリピンスキーの法則を通して学ぶ（化学の新しいカタチ)](https://future-chem.com/rdkit-descriptors/)
- [化学構造・分子・化合物の扱いに関する基本的なこと（金子研究室)](https://datachemeng.com/handle_molecules/)
モデル作成後に、サーバ起動&アクセス時に「TypyError:'set' object is not reversible」となる場合の確認箇所について(@Python/jango)

#はじめに
今回は、Djangoアプリ作成過程で起きたエラーについて触れていこうと思います。

`TypyError:'set' object is not reversible`

モデル作成を行った後、サーバー起動しアクセスした際に発生しました。

結論としては、入力ミスでしたので内容を確認していきます。

[参考記事](https://find-best-practice.com/2019/09/08/django%E3%81%A7admin%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%97%E3%81%9F%E3%82%89typyerrorset-object-is-not-reversible%E3%81%8C%E5%87%BA%E3%81%9Furls-py%E3%81%A7%E3%81%A8%E6%9B%B8/#toc3)

#エラー詳細
models.pyを編集した後に、
以下のコマンドでサーバ起動しアクセス。

```
$ python manage.py runserver
```

![スクリーンショット 2020-12-15 23.46.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692063/402442a4-c050-14e2-2cf3-e5b88ccdc904.png)


#原因

アプリケーションフォルダ内の`urls.py`の記述が以下の通りになっていました。。

```
urlpatterns = {
    path('', views.index, name='index'),
}
```

誤：{}

正：[]


#まとめ
基礎を確認しながら引き続き頑張ります！

参考にさせていただいた記事の作成者様ありがとうございました。
CoreGraphicsのあれこれ


```UIImage+CoreGraphics.swift
import UIKit

extension UIImage {

  //準備
  private func preprare(size: CGSize, _ draw: (() -> Void)? = nil) -> UIImage! {
    UIGraphicsBeginImageContextWithOptions(size, true, 0)

    draw?()

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return newImage
  }

  func resize(ratio: CGFloat) -> UIImage! {
    let size = CGSize(width: self.size.width * ratio, height: self.size.height * ratio)
    return self.resize(size: size)
  }

  func resize(height: CGFloat) -> UIImage! {
    let width = self.size.width * height / self.size.height
    let size = CGSize(width: width, height: height)
    return self.resize(size: size)
  }

  func resize(width: CGFloat) -> UIImage! {
    let height = self.size.height * width / self.size.width
    let size = CGSize(width: width, height: height)
    return self.resize(size: size)
  }

  func resize(size: CGSize) -> UIImage! {
    preprare(size: size) {
      self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    }
  }

  func compose(image: UIImage, frame: CGRect) -> UIImage! {
    preprare(size: self.size) {
      self.draw(at: .zero)
      image.draw(in: frame)
    }
  }

  func compose(image: UIImage, atCenter: CGPoint, blendMode: CGBlendMode = .copy, alpha: CGFloat = 1.0) -> UIImage! {
    preprare(size: self.size) {
      self.draw(at: .zero)
      let at = CGPoint(x: atCenter.x - image.size.width/2, y: atCenter.y - image.size.height/2)
      image.draw(at: at, blendMode: blendMode, alpha: alpha)
    }
  }

  func compose(image: UIImage, at: CGPoint, blendMode: CGBlendMode = .copy, alpha: CGFloat = 1.0) -> UIImage! {
    preprare(size: self.size) {
      self.draw(at: .zero)
      image.draw(at: at, blendMode: blendMode, alpha: alpha)
    }
  }
}
```
Android Kotlin データバインディングの基本

**データバインディングには次の利点があります。**

- findViewById() を使用するコードよりもコードが短く、読みやすく、メンテナンスも簡単です。
- Android システムは、各ビューを取得するためにビュー階層を一度だけ横断しますが、それはアプリの起動時に行われ、ユーザーがアプリと対話している実行時には行われません。
- ビューへのアクセスには型安全性があります。(型安全とは、コンパイル時にコンパイラが型を検証し、間違った型を変数に代入しようとするとエラーをスローすることを意味します)。

(公式引用)

---

データバインディングを有効にするには、以下を追加します。

```gradle:build.gradle(Module:app)
buildFeatures{
 dataBinding true
}
```
---

XMLレイアウトで、データバインディングを使用するには、`<layout>`タグで囲む必要があります。

```xml:sample_main.xml
<layout>
   <LinearLayout>
    <!-ビュー要素-->
   </LinearLayout>
</layout>
```

---

**SampleActivityにbinding Objectを作成する**

SampleMainBindingクラスは、このメインアクティビティのためにコンパイラによって特別に作成されます。名前はレイアウトファイルの名前、つまり sample_main + Binding に由来します。

```kotlin:SampleActivity.kt
private lateinit var binding: SampleMainBinding
```

DataBindingUtilクラスのsetContentView()関数を使用して、Sample_mainレイアウトをSampleActivityに関連付けます。

```kotlin:SampleActivity.kt
binding = DataBindingUtil.setContenView(this,R.layout.sample_main)
```

---

バインディングオブジェクトを使用して、ビューへの参照を呼び出します。

```kotlin:SampleActivity.kt
binding.testButton.setOnClickListener{
 <!- 実行内容 -->
}
```

関数内で複数のbindingがある場合、以下のようにすることもできる。

```kotlin:SampleActivity.kt
binding.apply{
 testText.text = testnameEdit.text.toString()
 testnameEdit.visibility = View.GONE
 testButton.visibility = View.GONE
 testText.visibility = View.VISIBLE
}

```

---

**データバインディングを使用して、データを表示する**

データクラスを作成する。

```kotlin:SampleData.kt
data class SampleData(var testname: String = "")
```

次にレイアウトにデータを追加します。
追加する場所は、```<layout>```と```<LinearLayout>```タグの間です。

```xml:sample_main.xml
<data>

</data>
```

データタグ内で、クラスへの参照を保持する名前付きの変数を宣言します。

```xml:sample_main.xml
<data>
  <variable
     name = "sampleData"
     type = "com.example.android.**.SampleData />
</data>
```

これで、名前に文字列リソースを使用する代わりに、sampledata変数を参照できるようになります。

```xml:sample_main.xml
android:text = "@={sampleData.testname}"
```

レイアウトファイル内のデータへの参照ができました。
次は、実際のデータを作成します。

```kotlin:SampleData.kt
private val sampleData: SampleData = SampleData("Test Tarou")
```

XML 内の変数に直接アクセスすることはできないため、バインディング・オブジェクトを通してアクセスする必要があります。

```kotlin:SampleData.kt
binding.sampleData = sampleData
```

---

# 概要

本記事は、公式(チュートリアル)で学んだことを振り返るために、作成しておりますため、伝わらないなどもあるかと思いますが、よろしくお願い致します。
create-react-app Advanced Configuration まとめ 2020年末版

React大好きなんですがちょっと離れてると機能が増えてたり、変更があったりと追いつくのがなかなか大変です。
今年は`Advanced Configuration`で廃止された設定、新しく追加された設定に絞って書いてみます。
一部、勉強のために`create-react-app`の修正箇所も紹介します。

[2019年末版はこちら](https://qiita.com/overgoro56/items/4af44283f2d44da38272)

### Advanced Configurationの公式ドキュメント

[GitHubのドキュメント](https://github.com/facebook/create-react-app/blob/master/docusaurus/docs/advanced-configuration.md)

[create-react-app](https://create-react-app.dev/docs/advanced-configuration/)


### 設定方法

shellで設定する場合には

```package.json
  "scripts": {
    "start": "CI=true react-scripts start",
```

のようにするか、`.env`ファイルで

```..env.development
CI=true
```

のように環境ごとに設定します。

## 廃止されたAdvanced Configuration

### NODE_PATH

`react-scripts@4.0.0`で廃止。
今後は`jsconfig.json`または`tsconfig.json`に`baseUrl`を設定してねってこと。
もともと、`baseUrl`を設定してない場合には、`NODE_PATH`を使うようになってたのでやっとなくなったのかという設定。

https://github.com/facebook/create-react-app/releases/tag/v4.0.0


### EXTEND_ESLINT

これも同じく`react-scripts@4.0.0`で廃止。
この設定がなくても拡張できるようになったとのこと。

[修正PR](https://github.com/facebook/create-react-app/pull/9587)

https://github.com/facebook/create-react-app/releases/tag/v4.0.0


## 追加されたAdvanced Configuration

### WDS_SOCKET_HOST

`WDS`は`webpack-dev-server`から。
`Hot Module Replacement`用にカスタムの`websocket`ホスト名で開発サーバーを実行。
`webpack-dev-server`のデフォルトは`window.location.hostname`で、`SockJS`のホスト名を指定します。
この変数を使用して、一度に複数のプロジェクトでローカル開発を行える。

https://webpack.js.org/configuration/dev-server/#devserversockhost


### WDS_SOCKET_PATH

`webpack-dev-server`のデフォルトは、`SockJS`パス名の`/sockjs-node`。
この変数を使用して、一度に複数のプロジェクトでローカル開発を行える。

https://webpack.js.org/configuration/dev-server/#devserversockpath

### WDS_SOCKET_PORT

`webpack-dev-server` のデフォルトは、`SockJS` ポートの `window.location.port` です。
この変数を使用して、一度に複数のプロジェクトでローカル開発を開始を行える。

https://webpack.js.org/configuration/dev-server/#devserversockport


### FAST_REFRESH

`Fast Refresh`という実験段階の機能。
アプリ全体をリロードするわけではなく、修正したコンポーネントのみを更新することにより高速開発が可能になる。
問題があったら`false`に設定してオフにしましょう。


### DISABLE_NEW_JSX_TRANSFORM

`React 17` で導入され、`React 16.14.0`、`15.7.0`、`0.14.10` にバックポートされたNEW JSX TRANSFORMを無効にします。
古いReactプロジェクトでReactをバージョンアップできなく問題になる場合に使用する。

[NEW JSX TRANSFORMについて](https://ja.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html)

## まとめ
どうでしたか？
設定の廃止、追加をみるだけでも今年1年のReactの変化が見れて面白いですね！

今年追加された設定は、自分の開発ではあまり使う機会はないかも。
廃止された設定は使っていたのでそっと削除しておこうと思います。

来年もReactはどのように変化していくのか楽しみですね！
仕事において大事な二つのこと。

あと20分ばかりで一つ年を重ねようとしているひよっこエンジニアから。

プロジェクトの動向をそばで見続けた中で、
仕事の上で「これは大事だ」と思ったことたちを二つ紹介！！

**とにかくエビデンス**
デバッグやりました。
正常に動きました。
問題ありませんでした。...

これらすべて徹底的にエビデンスに残さないと信じてもらえない！
「信じてもらえない」と言ったら語弊になりますが、
お客様へ提供する商品の品質を担保するためには必要不可欠だと感じました

例えば...！
■デバッグシート作成
■手順書やスケジュールの明記
■要件定義に関する記述を残した議事録やアジェンダ

実質、エビデンスのおかげで先方との認識のずれをすり合わせることができました
妥当なエビデンスを提示できれば最強です

これを社内でも実施していくことで、
より安全なアップデートを
より迅速で齟齬のないお客様対応を
どんなお客様へも自信をもってサービス提供ができるようになると思います

**とにかくこまめな連絡**
「報連相」がとにかく大事

特に社外の方と仕事をするとき、どうしても共有にタイムラグが発生してしまいます
先方は起こっていることがわからないため不安です
進捗状況もわからなければ、いつ頃対応完了見立てなのかもわからない

そこで、電話やメールを駆使して、とにかく現状報告
たとえ、対応が終わっていなくても、進捗がなくても、
現在何が起こっているのかを徹底的に共有

これにより、先方で対応を臨機応変に変えることができることもあります

これを社内でも実施していくことで、
対応の遅れや、想定外のことが起きても、
迅速なリカバリーがきき、最悪の事態を回避することができるかもしれません

**まとめ**
わかってはいるものの、なかなか自分の仕事のスタイルに取り入れるのは難しかったりします

ただ、この間近で見てきた教訓とノウハウを、
社員全員に落とし込めたら、
攻めと守り両方最強集団が出来上がると思うんです

まずは日々の業務から、実践していきたいです！
キータ、デビュー。

よくわからないけど、とりあえず。書いてみます。

Fireタブレットをサブディスプレイにする方法
https://ygkb.jp/15823

google アプリが起動しっぱなしで裏で無線通じて通信する。
このアプリベンダーにどんなデータが取られているのかちょっと怖い。無料だしね。
社給PCはポート制限しているので、使えない。
float値を文字列にした後、再び数値にするとどれだけずれるか

#数値→文字列→数値したときのずれ
C#で、float値を、ToString()して、float.Parseすると若干のずれがあります。
どの程度ずれるのかについて書きました。
当然、これはずれる場合とずれない場合があるのですが、今回はUnityのRandam値で検証しました。

#最初に結論
結論から言うと、利用する値の範囲によって変わります。

-9999～9999ぐらいの値の範囲であれば、±0.0009765625ぐらいのずれでした。
-999～999ぐらいの値の範囲だと、6.103516E-05ぐらいですね。
これらの値は、アバウトなので参考程度に。

**※コメント欄にToString("G9")すれば、改善するという指摘がありました。**
**ありがとうございます。**
**恐ろしいことに、全くずれなくなりました。ずれが０です。**
**ということで、下記の記事は普通に引数無しのToString()した場合の記事です。**
**ToString("G9")にしたら、こんな余計なことする必要ないのかもしれません。**

## どうやって調べたか
かなり適当なんですが、コードです。
float値の２つの値の範囲って、無限にあるのでランダムでやってます。
毎フレーム１０００回試してみて、最大誤差が現れた時にDebug.Logしています。

~~~StringToNumber.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StringToNumber : MonoBehaviour
{
    float _minDif = 0;
    float _maxDif = 0;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        for (int i = 0; i < 1000; ++i)
        {
            float f = Random.Range(-9999f, 9999f);
            string s = f.ToString();
            float v = float.Parse(s);
            float d = v - f;
            if (d < 0f)
            {
                if (d < _minDif)
                {
                    _minDif = d;
                    Debug.Log("MIN DIF:" + _minDif);
                }
            }
            else
            {
                if (d > _maxDif)
                {
                    _maxDif = d;
                    Debug.Log("MAX DIF:" + _maxDif);
                }
            }
        }
    }
}

~~~

##誤差があると何が困るのか
実際に起きた問題として、オブジェクトの位置を保存する場合です。
このオブジェクトは、rangeMinからrangeMaxの間にしか置けないものでした。
範囲外だと問題がでている状態になって、灰色で表示されるようになります。
範囲ぎりぎりの地点は、位置をスナップできるようにしてあったとします。

仮に、rangeMaxの地点で、位置を文字列として保存しました。
で、ロードし直すと誤算によって問題がでている状態になっていることがあるわけです。

##対策１
誤差を許容しましょう。
-9999～9999ぐらいの値の範囲であれば、±0.0009765625ぐらいのずれでした。
なので、0.001ぐらいのずれは許容するようなコードにする。
（私だったら怖いので、0.01ぐらいにしますが）

~~~rangeCheck.cs
bool rangeCheck(float value)
{
    float eps = 0.001;
    if ((rangeMin-eps<value) && (value<rangeMax+eps)) return true;
    return false;
}
~~~

##対策２
バイナリで保存する。

##結論
すごくどうでも良い話だったかもしれませんが、文字列化して数値に戻すと少しだけ数値が変わるので、少しだけ許容幅を設けよう。
その際の許容範囲ってどのぐらいにしたら良いのかって話でした。

文字列で数値を保存するのって便利だけど、問題がでることもあるよねって話です。
（というか実際に問題が出たので、記事に残しておこうと思うのでした）
【Vue.js】Local Storageでデータを永続化させる

#Local Storageとは

JavaScriptを使ってWebブラウザにデータを保存できる仕組みです

5~10MB程度のデータを永続化できます

保存された内容はChrome DevToolsで確認できます
![スクリーンショット 2020-12-15 16.33.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/bc02c126-aa64-5aae-e917-8fabb116162f.png)


今回はVue.jsで見ていきます

#保存する
保存するには`localStorage.setItem()`を使用します

第1引数に**キー**
第2引数に**バリュー**
を渡します

```vuejs:
<template>
  <div class="container">
    <button @click="set()">保存</button>
  </div>
</template>

<script>
export default {
  methods: {
    set() {
      localStorage.setItem('name', '田中')
    }
  }
}
</script>
```

簡単に「保存ボタン」が押されたらデータを保存するようにします

![demo](https://gyazo.com/f075060ae985182f02feded3d90aaaac/raw)
***

第2引数に複数の値を渡す場合は`JSON.stringify()`を使用しJSON文字列へ変換する必要があります

```vuejs:
<template>
  <div class="container">
    <button @click="set()">保存</button>
  </div>
</template>

<script>
export default {
  methods: {
    set() {
      localStorage.setItem('obj', JSON.stringify({
        id: 1,
        name: 'tanaka',
        age: 20
      }))
    }
  }
}
</script>
```

![demo](https://gyazo.com/c8116c78abef3f68d59e2c30aec97dff/raw)
***


#取得する

データを取り出すには`localStorage.getItem()`を使用します
現状JSON形式でデータが保存されているので`JSON.parse()`でJavaScriptのオブジェクトに変換する必要があります

`mounted`にデータを取得する記述を用意しレンダリングします

```vuejs:
<template>
  <div class="container">
    <button @click="set()">保存</button>
    <p>{{this.info.id}}</p>
    <p>{{this.info.name}}</p>
    <p>{{this.info.age}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      info: {}
    }
  },
  mounted() {
    this.info = JSON.parse(localStorage.getItem('obj'))
  },
  methods: {
    set() {
      localStorage.setItem('obj', JSON.stringify({
        id: 1,
        name: 'tanaka',
        age: 20
      }))
    }
  }
}
</script>
```

![スクリーンショット 2020-12-15 23.33.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/32480f29-4af0-f674-1226-7aad73f0ef87.png)

永続化されているのでリロードしても消えません

#削除する

最後です

`localStorage.removeItem();`で引数に渡したキーに紐づく値を削除できます。

また、`localStorage.clear();`で全ての値を削除できます

```JavaScript:

localStorage.removeItem('obj');

localStorage.clear();
```
firebase deployでRequested entity was not foundと表示された。

まだ業務未経験の私ですが、本気で詰まった話。（いつもならGoogle先生が解決してくれます）

###firebase 8.12.1で事象が発生。
![スクリーンショット 2020-12-15 23.18.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697839/f1f3d1d0-75e7-6428-c250-d59f7672d47a.png)
entity（対象とか実体とかの意味らしい）が見つからない。。。
firebase initをやり直したり、login/logoutを試しても全く同じ。
Google先生で検索しても、プロジェクトIDが間違っているかもとかスペルミスなんじゃねとかしか情報が出てこず。（stackOverflowで聞けともあり）

単純そうなエラー文なのに全く進展せず。

##解決した方法
これもまた単純な話、firebase-toolsを最新にしたら無事解決しました。![スクリーンショット 2020-12-15 23.12.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697839/f5428077-d2b7-1b93-e5e6-40a45c321de1.png)

謎。原因がわからずモヤモヤが残ってます。

ですが、この件はこれでクローズとします。（もし原因がわかる方や他の対処法を知っている方がいらっしゃったらコメントでご教授ください。m(_ _)m）
コメント色々　〜備忘録〜

#はじめに
　自分の記録用に現在よく使う言語のコメントアウトをまとめておく。

##VSCodeコメントにするショートカット
command + /

##コメント色々

```html:HTML
<!-コメント->
```

```css:CSS
/* コメント */
```

```ruby:Ruby
# コメント
```
```erb:erb拡張子
<%# コメント %>
```
```js:JavaScript
// コメント
```
ポインタの勉強したらパソコンの基礎も勉強できて、C言語楽しいと思った話

Javaやってる低速駆け出しエンジニアです(1年半)。
30代未経験からこの業界に入って最初にとまどった事『2進数・16進数ってなに？！』でした
そして今も変わらず同レベル。。こ
の記事では、そんなレベルの私がC言語を（ﾁｮｯﾄ）勉強して、メモリの事とポインタの事が
<strong>なんとなく分かったような気がする</strong>
っていう記事です。


<h2>ポインタを学ぶ過程で学んだこと事</h2>

①コンピュータは何故(01)2進数を使うのか？
言語をコンパイルするときに機械語に変換してるとは聞いたけど、、
なんで機械語にする必要があるのか分からなかった。
簡単にまとめてみた：
下記サイトを簡単にまとめると
「コンピュータの電子部品（集積回路）が0・1で電気のやり取りをやっているから。」
参考サイト
https://xtech.nikkei.com/atcl/learning/lecture/19/00007/00001/?P=4


---
②変数ってメモリにどう保持されるんだろう？

簡単にまとめてみた：
例）
int num = 1;

CP男('ω')「int型で値が1の名前がnum」ってやつがきたバイ
ﾒﾓﾘ子('ω')ノ「私のﾒﾓﾘ45000番地に保管してあげるけんね」
CP男('ω')「int型は4ﾊﾞｲﾄばい。ちゃんとその広さ確保してね、ついでにその表札はnumにするの忘れたらいかんばい」
ﾒﾓﾘ子('ω')ノ「しゃーしかー」
（*登場人物は関係ありません）

みたいな感じでメモリに保存されるらしい（分かりずらっ）
ここで大事なのは、
・int型(4バイト）が
・メモリ45000番地に確保されて、
・値が1入った。
・で、それを名前(変数)numでやり取りする。

この考えが頭に入ったのでポインタへのハードルが少し下がったきがしました。

このサイトがめちゃめちゃ役に立ちましたm(__)m（ポインタ記載あり）
https://qiita.com/developer-kikikaikai/items/0910c3c96e2164094449


------



<h2>ポインタって何？</h2>



```c

int main(void) {
    int num = 1; // int型変数
    int *p_num; // int型ポインタ変数
    p_num = &num; // ポインタ変数「p_num」に変数numアドレスを代入（＆はnumのアドレスを示す）

    printf("int型変数numのアドレス:%p\n", &num);
    printf("int型変数numのアドレス先の値:%d\n", *(&num)); 
    printf("int型ポインタ変数p_numの参照先の値:%d\n", *p_num);　//(*アドレスの値を示す）
 
    return 0;
}

int型変数numのアドレス:0x7ffd0a0ecc64
int型変数numのアドレス先の値:1
int型ポインタ変数p_numの参照先の値:1
```

解説）
p_num = &num;でポインタ型変数p_numにnumのアドレスを代入している
printf(*p_num);で、numのアドレスの値を参照しているので１がでる。



説明下手だな。。


ここが一番勉強になりましたm(_ _)m
https://monozukuri-c.com/langc-pointer-interpretation/
ここもシンプルで勉強になりましたm(_ _)m
https://qiita.com/hikoalpha/items/536e370a2937a1ecb66d

<h2>終わり</h2>
C言語はメモリ管理とかポインタとか、めっちゃ難しそうと思ったけど
原理を理解するとパソコンの基礎に行き着くのでとても勉強になりました

もしよかったらコメントでアドバイスご指摘おまちしています〜^o^
【Nuxt.js】生成するHTMLを1つだけにする方法【SPA】

# やりたいこと
vue.jsと同じ用に1つだけhtmlを生成するようにしたい。

# nuxt.config.jsの設定
nuxt.config.jsに以下の変更を加える事でルーティングのhtmlが生成されなくなる。
ルーティングのhtmlの1つも生成されない場合は`200.html`が生成される。
参考:https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-generate/#exclude

```js:nuxt.confing.js
export default {
  generate: {
    exclude: [/.*/]
  }
}
```
# サーバ側の設定
リダイレクトの設定を行う。

Apacheの場合

```apache:.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ 200.html
</IfModule>
```
参考:https://router.vuejs.org/ja/guide/essentials/history-mode.html#サーバーの設定例
リニアレギュレータについての大まかな理解

※12/16 誤りが多分に含まれていそうなので、勉強して修正いたします。

リニアレギュレータの原理についてまとめる。
特徴や使い方については一切書かず、大まかな仕組みだけを書く。

## リニアレギュレータとは
そもそもレギュレータとは、電源回路の一種で、出力電圧や電流を一定に保つように制御する回路の総称である。レギュレータは、その変換方式によって、リニアレギュレータとスイッチングレギュレータの2種類に分類される。

リニアレギュレータは、抵抗分圧の原理で、入力電圧を負荷との間で分圧して出⼒電圧を得る電源回路のこと。可変抵抗の役割を果たすトランジスタを負荷に直列で挿入するシリーズ方式と、並列に挿入するシャント方式がある。
今回見るのはシリーズ方式の方のみについて記載する。

## リニアレギュレータの原理

リニアレギュレータの内部構成は以下のようになっている。
![voltage-regulator-composition.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/a7d7decf-b937-e906-1384-1f0ea846cf93.png)
引用元：
https://www.ablic.com/jp/semicon/products/power-management-ic/voltage-regulator-ldo/intro-2/
例えばVINに12Vが入力されて、VOUTから5Vが出力されるような回路が作られる。

#### リニアレギュレータの電圧変換のしくみ
①直列につないだ抵抗RFと抵抗RSによって入力電圧VINを分圧する。
②分圧された電圧VFBを、エラーアンプを利用して基準電圧VREF（VOUTと同じ電圧)まで調整する
③制御素子（トランジスタ）使って想定された電圧を出力する

正直これだけの部分でも、素人向けに書かれた資料がなくて理解に苦労した。

なぜリニアレギュレータは、入力電圧の値が変わっても一定の電圧を出力することができるのか？
⇒入力が何Vだろうと②の部分でVREFの値まで電圧を調整しているからだ。
（エラーアンプ(OPアンプ)の概要：http://www.kumikomi.net/archives/2010/05/ep18opam.php?page=2 ）

どうやって基準電圧VREFをとってきてるのか？
⇒ツェナーダイオード（定電圧ダイオード）で決まった電圧になるようにしているから。


最後に③の部分について考える。
エラーアンプ(OPアンプ)の電流は小さいため、③は電流を増幅するために使用している。トランジスタのコレクタ電圧はベース電圧に依存する。つまり、VINの電圧に依存せずベース電圧だけでVOUTの電圧を決定できる。


##参考資料
・おしえて電源IC：https://www.zuken.co.jp/club_Z/zz/category/tech-column/pm_ics
・リニアレギュレータ概要資料：http://www.asahi-net.or.jp/~bz9s-wtb/doc/power/NO1/tip1c4e.pdf
VivaldiのWebパネルでScrapboxの編集ができなかったので解決法

## 問題点
Vivaldiを使用していて、Scrapboxの編集をWebパネルで行おうと思ったところ、文字の入力ができず、編集できませんでした。

## 環境
Macbook Pro 13-inch 2016
Mac OS Catalina
メモリ 8GB
  
Vivaldi 当時最新版だった3.5.2115.81

## Webパネル is 何
画像のように、ウィンドウの一定領域を固定してwebページなどを表示してくれます。
タブの遷移をしてもそこに居続けるのが便利で愛用しています。

![スクリーンショット 2020-12-15 23.41.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956323/e3927775-6caa-d8d2-1a21-7c5812296a87.png)


開発中はJupyterLabをWebパネルで表示し、そこでコーディングを行い、タブ側で調べ物を行うなどして使用しています。

詳しい事は公式が教えてくれます。
https://help.vivaldi.com/ja/show-on-first-page-ja/web-panels/

## 解決法
Webパネルのアイコンを右クリックして、デスクトップ表示にすることで解決しました。

Webパネル側からGoogleにログインした際に来るセキュリティアラートのメールが、スマホからになっていました。もしやと思い調べたらWebパネルの表示がモバイル版とデスクトップ版で切り替えられることを知り、デスクトップ版に切り替えたら編集ができるようになりました。

現行ではモバイル版でScrapboxの編集は行えないのでしょうか…？(Webパネル側で新規作成した時点では編集できるが、既存の記事を編集できなかった)

## 引用
webパネルの表示方法をモバイル版からデスクトップ版に切り替える方法は、以下の記事を参考にしました。
http://utaukitune.ldblog.jp/archives/65892459.html!
[OutSystems](Reactive Web App版)ブラウザ内にダウンロードしたファイルを表示する

以前、別の記事[Downloadでブラウザ内にダウンロードしたファイルを表示する](https://qiita.com/jyunji_watanabe/items/d2d469704db445bd5f87)でOutSystemsアプリケーションから出力したファイルを、（ローカルに保存するのではなく）ブラウザに表示する方法について検討しました。

そのときは、Reactive Web Appで実現する方法が見つからなかったのですが、この度実現する方法がわかったのでメモ。

# 元ネタ
以下のフォーラム投稿への返信
[Reactive open PDF in browser instead of downloading it](https://www.outsystems.com/forums/discussion/58978/reactive-open-pdf-in-browser-instead-of-downloading-it/#Post224579)

>  you might need a workaround which is creating a rest endpoint that sends the file with the correct header so the browser opens it instead of downloading.

# 実装
## Expose REST API
ここでは、ファイルをResourcesにおき、そのContent (Binary Data型）を出力変数に設定するREST API Methodを用意しました（下のDownloadPdfが該当）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/f01e7eaa-9a34-6a84-6c11-58745248b4cc.png)

Assignでは単純に出力変数PdfにResourcesのpdfファイルの.Contentを設定しているだけ。
ここでは特に記述していませんが、実プロジェクトではセキュリティの判定が必要です。

## Content-Type
ブラウザにファイルを開いてもらうためには、ファイル種類に応じた適切なContent-Typeを設定します。ここではPDFファイルなのでapplication/pdfを設定したい。

OutSystemsのExpose REST APIメソッドで任意のResponseヘッダを設定するにはHttpRequestHandler Extensionに含まれているAddHeader Actionを使います。

Responseヘッダに以下のような行を設定するには、
> Content-Type: application/pdf

AddHeaderを以下のようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/597284ae-dcbb-c5de-5703-efcbc42dd600.png)

## JavaScriptを使ってREST APIのURLを開く
そのままです。
Reactive Web AppではScreen ActionにJavaScript要素を配置し、その中に任意のJavaScriptコードを書けます。

よって作成したREST APIのURLをwindow.openに渡してやればいいですね。
Microsoft Excelのセルの値を取得するPythonスクリプトを作成してみた

# 1. MSYS2のインストール
https://www.msys2.org/ からMSYS2の最新版をダウンロードし、Windows 10上にインストールする。
![msys2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388314/53297655-e5f6-b2d0-66a4-a71aae61ae2a.png)

# 2. Pythonとopenpyxlのインストール
スタートメニュから「SYS2 64bit」-「MSYS2 MinGW 64-bit」を起動し、以下を実行する。

```
# pacman -Qe
# yes | pacman -S mingw-w64-x86_64-python mingw-w64-x86_64-python-openpyxl
# pacman -Qe
```

# 3. スクリプトの作成
```excellsp.py
#!/usr/bin/env python3

import sys
import getopt
import openpyxl

def usage():
    print('usage: ' + sys.argv[0] + \
        ' [ -h -q quotation -s separator ] workbook worksheet [celladdr...]', \
        file=sys.stderr)

try:
    opts,argv = getopt.getopt(sys.argv[1:], "hq:s:")
except getopt.GetoptError as err:
    print(err)
    usage()
    sys.exit(1)

separator = '\n'
quotation = ''

for opt,optarg in opts:
    if opt == "-h":
        usage()
        print("Pass2")
        sys.exit()
    elif opt == '-q':
        quotation = optarg
    elif opt == '-s':
        separator = optarg
    else:
        print("Pass1")
        usage()
        sys.exit(1)

if len(argv) < 2:
    usage()
    sys.exit(1)

wb = openpyxl.load_workbook(argv[0])
ws = wb[argv[1]]
del argv[:2]

separator = separator.replace('\\t', '\t').replace('\\n', '\n')
output = ''

for arg in argv:
    value = str(ws[arg].value);
    if quotation != '':
        value = quotation + value.replace(quotation, quotation + quotation) + \
            quotation;
    if output != '':
        output += separator
    output += value

print(output)
```

# 4. テスト用ブックの作成
Microsoft Excelで以下の内容のシート「Sheet1」を持つブック「Book1.xlsx」を作成する。

|A|B|C|D|E|
|---|---|---|---|---|
|1|a1|b1|c1|d1|e1|
|2|a2|b2|c2|d2|e2|
|3|a3|b3|c3|d"3|e3|
|4|a4|b4|c4|d4|e4|

# 5. スクリプトの実行

```
# chmod a+x excellsp.py
# ./excellsp.py -h
usage: ./excellsp.py [ -h -q quotation -s separator ] workbook worksheet [celladdr...]
# ./excellsp.py Book1.xlsx Sheet1 A1 C2 D3 E4
a1
c2
d"3
e4
# ./excellsp.py -s '\t' Book1.xlsx Sheet1 A1 C2 D3 E4
a1	c2	d"3	e4
# ./excellsp.py -q '"' -s '\t' Book1.xlsx Sheet1 A1 C2 D3 E4
"a1"	"c2"	"d""3"	"e4"
[Rails] Gemが正しくインストールされているか確認する方法

前提
---
```
# bundle install実行後

Bundle complete! 20 Gemfile dependencies, 83 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```
このように表示された場合、
「Gemfileに記述してあるGemは全て正しくインストールされている」
状態です。

一文字でもミスがあれば、エラーメッセージを返してくれます。

確認方法①
---
**"bundle info Gem名"コマンド**

・Gem名のGem情報が表示される

確認方法②
---
**"Gemfile.look"を確認**

・"Gemfile.look"は「インストールされているGemの名前とVersionが記載されているファイル」
HUNTER×HUNTERを読み直していたら、RPAとの上手な付き合い方に合点がいった。

## RPAを使ってみて感じたこと、自分が思うRPAとの上手な付き合い方をまとめてみます。
唐突ですが皆さん、HUNTER×HUNTERは好きでしょうか？

私は好きです（特にクラピカ）。なかなか本編が更新されず辛い日々が続きますね。

久々に読み返していた際に、最近行っているRPA布教活動と、ふと繋がりました。

ですので今回は、**「RPAの適性をHUNTER×HUNTERの念能力習得過程と紐づけて解説する」**という謎にチャレンジングな記事を書いてみようと思います。

特に技術的な示唆はありませんが、「へぇ～、こいつアホだな」くらいの軽さで読んでいただけますと幸いです。

## 事例①：膨大な量の業務に追い込まれた時、RPAが助けてくれた

当時の私の出来事です。

①APIのないニッチな解析ソフトウェアを使って、大量の解析を近日中に実行する必要があった。

②実行ボタンを押して次の計算に切り替えるだけだが、解析数が多くかつ実行時間がかかるという難点があった。

③そこでRPAでできないかと考え、実際に作り実行。夜通しでRPAが働き僕は救われた..!!

<img width="350" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/3c20044c-5473-df9c-8197-edb6aee4f30b.png">

## 事例②：要件定義をしてRPAを使ってみようとしたら、なんだか変な感じになった

これは上記の後に起こった、また別の出来事です。

こうして一つの実績を得た僕はマネジメントの期待も受け、従来業務のRPA化を検討することに。

①効果が大きくかつ再現性のある単純作業を見極め、業務フローを洗い出しRPA化へ！

②でも、、ファイル操作やエクセル処理はVBAやPythonの方が早いよな。

③しかもRPAを違う人のPCで実行すると、すぐに不具合起こすし..基本的にVBA, Pythonで処理するか！

④APIがないような社内ソフトウェアを使う時だけRPAでクリックや！！これで決まり！

### 必死のパッチでRobot作成の末、私は気づいた..。

**⑤ん・・・社内ソフトウェアの仕様を変えてしまえば解決なのでは？？**

できあがったロボットはbatch fileやVBAを順次回し、フロー中に数回登場する社内ソフトウェアの所だけ、クリックして作業をするものであった。（しかもちょっと不安定）

こうして、僕は社内ソフトウェアを開発しているチームにコンタクトを取り、改善要求に至った。

## これらの事例をHUNTER×HUNTERで置き換えてみたい。

これらの経験と、最近のHUNTER×HUNTER読み直しを経て、念能力設計とRPA開発は似てるなって思うようになりました。意味不明な方も多いかもしれませんが、少なくとも私はそう思ってしまいました。

まず、念能力の作られ方には２つあると思っています。

**①敵に追い込まれギリギリの中で能力に目覚める**

**②自分の目的を踏まえ、どういった能力にすべきかを考え、開花させる**

まず①の代表例ですが、、そう、、**ヂートゥ**ですね。
彼はモラウとの対決の際、ギリギリの状況に追い込まれた中で、その状況に最適なアイディアだった、”ボウガン”を念能力として生み出しました。

<img width="350" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/6ac0ec54-f8e5-017d-1a96-7ebd747b7d40.png">

そして②の代表例は我らが**クラピカ**です。
因縁の相手である幻影旅団を倒すために、練りに練ったアイディアが「鎖を使って敵を倒す」でした。

<img width="350" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/0437abb6-3434-6af4-b842-b2bb821c6ccd.png">

##どっちの念能力がいいか？そりゃクラピカですよ！

だって、ヂートゥの念能力は通用しなかったもの。

それは「自分は何がしたいか」「そのための最適な手段は何か」をきちんと検討・設計できていたクラピカさんの能力の方が完成度は高いわけです。

ですが私は問いたい。

**僕らみたいな念能力ゼロな人間に、きちんとした設計はできますか？？**


## そう、RPAは僕ら一般人でも念能力開花を後押ししてくれるサポートツールなんだ！

RPAは「誰でもヂートゥになれる」ための便利なサポートツールなんだ！！と今は感じています。土壇場で大量の業務を何とか即興で対処する。そんな時にRPAは最も輝くことができるのではないでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/85719d41-c10a-99c4-2aa1-485691b39243.png)


## ただし、あくまでRPAは即興での使用がいい。継続的な効果が見込まれるのならきちんとシステム設計に落とし込むべき。

RPAを上手に使いこなすことで、きっと現場にはたくさんの「土壇場」が繰り広げられていることが分かるだろう。そうした中で再現性や費用対効果が大きいものは、RPAを使わないシステム化を進めていくことがいいのではないだろうか。

プログラミングができない人にも自動化の機会を与え、「土壇場単純業務」を炙り出していく過程にこそ、RPAの意義があり、ひいては業務改革につながっていくのかもしれない。

だから私は明日も、ノーコード人材に向けてRPAのメリットを宣教するのである。

## さいごに

今年はAdvent Calenderに投稿するぞ！といったやましい心意気が発端となり、このような記事を書き上げてしまいました。期待して読んでくださった方、申し訳ありません。

ただおかげ様で、自身の中でRPAの位置付けを以前より明確にすることができました。
ありがとうございました。
エンジニアの事業貢献ってなによ？


[Ateam Group Manager ＆ Specialist Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam)の25日目はエイチーム引越し侍でエンジニアマネージャーをしている @zwirky が担当します。

# エンジニアの事業貢献ってなによ？

「事業目線を持って考えてほしい」や「事業貢献するためにはどうしたらいいのか」など、話にはよく上がりますが、結局事業貢献ってなんなの？ということを最近すごく時間をかけて考えたので、自分なりのまとめをしてみました。

また、事業に貢献するエンジニアってどういう人なのか？ということを少しだけ紐解いてみたので、参考にしてもらえるといいなと思います。

※ あくまでも一個人の意見なので、違う見方もあると思います

## 事業貢献とはなにか

事業に貢献するというのは、事業を成功に導くことだと思います。
これは、会社に所属していて事業を運営している以上、とても大事なことです。
もし、事業が成功できなかったら・・・

- 売上が上がらずにお給料がもらえない
- 世の中に役に立つ事業と認められていないのでモチベーションが下がる
- 最悪の場合、会社が潰れる

という形になるでしょう。
そのため、どんな部署でも、どんな職種でも、会社に所属している限り**成果**を出すことが求められます。

## エンジニアの事業貢献とは

考え方としては攻めと守りのバランスを取り、エンジニアとしての存在価値を発揮することだと考えました。

**攻め**
各部署の目標を達成させること。
各部署の目標が達成できれば、会社全体の目標も達成ができ、会社全体、事業全体にインパクトを与えることができると思います。

施策を実現させるために設計し、形にしていくためにコーディングし、物ができたらリリースし、サービスを運用していく。
このサイクルをスピーディーに、不具合なく、正確に実現させることがエンジニアの事業貢献だと思います。

**守り**
事業を安定的に継続させて、脅威からサービスを防ぐこと。
また、開発スピードを上げていくためシステム課題を潰していくこと。

エンジニアが中心となって対処すべきところです。

**全体として**
人毎に攻めと守りの割合を決めるのではなく、部署全体で攻めと守りの割合を考えていくことが大事です。
個人的に思う塩梅は、攻め8割、守り2割のイメージがちょうど良いのではと思います。

結果的に、エンジニアはものを作ること自体が事業貢献の一つです。
そのため、事業を動かしているのは自分達だという気持ちが必要です。

恥ずかしながら、自分はエンジニア以外の部署のことを事業部と言っておりましたが、考えを改め、エンジニアも事業部の一つであると思い、エンジニア以外の部署を指していた事業部という言葉を使うことを辞めました。
エンジニアも事業を動かしている人、部署の一員なので、全員が事業に関わっているという意識です。

そして、やっぱりそういう考え方になるためには、自分が携わっているサービスや事業が好きでなくてはだめです。
事業に共感して、自分自身が主体性を持って動くことがとても大事です。
もし、事業に共感できないのであれば、共感できるまで徹底的に事業の存在意義やあり方、今後の成長戦略を考えてみましょう。

## エンジニアのプロフェッショナルとしての事業貢献

エンジニアのプロフェッショナルっていう言葉を聞くと、常に新しい技術を使って問題を解決して最先端を突っ走るイメージですが、間違ってはいないけどちょっとずれていると思います。

エンジニアのプロフェッショナルとは、幅広い知識を有しており、技術や情報を駆使して、スピード感をもって課題を解決させていくことだと思います。

課題を解決するというところがエンジニアのプロフェッショナルの肝かなと思います。

エンジニアのプロフェッショナルになるためには、幅広い知識を有するために日々日頃から勉強をする必要があります。
また、課題を解決させるということなので、常に最新の技術が課題を解決させるわけではなく、もしかしたら最新の技術だとスピード感が失われてしまう時も来るかも知れません。
そのため、課題を解決させるために最適な選択をする必要があります。
※ もしかしたら、ちょっと古い技術をつかうことが最適な選択肢もあるでしょう

あくまでも技術は手段、課題を解決させるためのものだと思います。
実現させるためにどうすればよいかという考え方がエンジニアのプロフェッショナルとしての事業貢献だと思います。

## その他

エンジニアについて書きましたが、IT企業務めている人であれば職種関係なしに基本的なIT用語やスキルを持つことは有意義だと思います。

逆にエンジニアは課題を解決させるため、各部署の目標を達成させるために各職種の理解は必要です。

エンジニアも他職種もお互い最低限の知識をつけておけば、対等に共通言語で話ができ、仕事がスムーズになると思います。

要するに、相互理解が大事ということです。

## 余談

先日、お寿司を無性に食べたくなって、某予約サイトからお寿司屋の席予約をしようとしました。
しかし、予約の申し込みボタンを押したら・・・

**”現在、システムにトラブルが起こっております、時間をおいて再度登録をお願いします”**

と画面に出てきました。

自分もエンジニアなので、

**「あー、エラーが起こってるから今エンジニアが総勢で頑張ってるのかなー、緊急対応がんばれー」**

と心の中で思いつつも、

**「いやーでも今予約したいし、お寿司めっちゃ食べたいし、並ぶの嫌だな・・早く使えるようになってほしいな・・」**

と思っている自分もいました。

そこで、ふと思ったことが、結局サービスを使う人っていうのはユーザーじゃん、つまりその人達が困っていて、そこに対して解決できないのであれば、事業貢献もなにもないよなと感じました。

例えば、エラーが起こっているのに、無視してまあ明日直せばいっかみたいな考えはだめだということです。

まあ、とりとめない余談でしたが、事業貢献というのは、少なくとも会社の売上利益貢献というものもありますが、その先にいるユーザの課題を解決させていくこと、そしてそのユーザがサービスを評価して使ってくれて売上利益につながるということです。

## まとめ

- 事業に貢献するというのは、事業を成功に導くこと
- エンジニアも事業を運営している一員だということ
- 攻めと守りのを理解し、バランスが大事ということ
- 技術は手段で、課題を解決させるためだということ
- エンジニアも他職種も相互理解が大事だということ
- 事業貢献の先にはユーザがいることを忘れないこと

## 最後に

[Ateam Group Manager ＆ Specialist Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam)のラストを飾らせていただきました！今年のアドベントカレンダーもこれで最後ですね！🎄Merry Christmas🎄