OmniAICreator/Qiita-1.07M huggingface dataset:
npmのグローバルインストールをするためにパスを通す方法

## はじめに

npmのグローバルインストールをするために、パスを通す方法を紹介します。

## npm i -g @vue/cli でエラー発生

Vue CLIの環境構築のために

`npm i -g @vue/cli`

を実行すると下記のエラーが発生しました。

`i` はインストール、 `-g` はグローバル、という意味です。
グローバルにインストールされたものは、どのディレクトリでも実行できるようになります。


```
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated @hapi/joi@15.1.1: Switch to 'npm install joi'
npm WARN deprecated @hapi/hoek@8.5.1: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/topo@3.1.6: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/bourne@1.3.2: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/address@2.1.4: Moved to 'npm install @sideway/address'
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
npm WARN @vue/compiler-sfc@3.0.5 requires a peer of vue@3.0.5 but none is installed. You must install peer dependencies yourself.

npm ERR! code EACCES
npm ERR! syscall access
npm ERR! path /usr/local/lib/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
npm ERR!  [Error: EACCES: permission denied, access '/usr/local/lib/node_modules'] {
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'access',
npm ERR!   path: '/usr/local/lib/node_modules'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/soakasaka/.npm/_logs/2021-01-29T13_58_49_964Z-debug.log
```


## 環境パスを通す

「環境パスを通す」とは、特定のプログラムをプログラム名だけで実行できるようにすることです。

Npmでグローバルインストールする場合は`~/.npm-global`を作成して環境パスを通す必要があります。

下記コマンドをターミナルで実行してください。

```
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
```
 
環境パスを通すために .zshrc を編集します。

```
Vim .zshrc
```

PATHなどの環境変数は
bashなら、`.bash_profile`
zshなら、`.zprofile`
に書くのが基本です。


下記を .zshrc に追加してください。
その際に `[username]` をお使いのPCのユーザ名に変更してください。

```
export PATH=$PATH:/Users/[username]/.npm-global/bin
```

その後、設定を読み込ませます

```
source ~/.zshrc
```

`npm i -g @vue/cli`　で再度インストールすると成功！！

バージョン確認もできるようになりました

```
% vue --version
@vue/cli 4.5.11
```
firebase login:ci で取得したトークンをすべて削除したい

GoogleアカウントのFirebase cliへの権限を一度削除することで、既存のすべてのトークンを無効にすることができるようです。
https://myaccount.google.com/permissions

参考
https://stackoverflow.com/questions/38060188/how-to-list-all-active-firebase-ci-tokens-or-revoke-them-all
【エクセル】セル操作

# 参照

## 単一指定
```vb
  Range("A1")
  Cells(2, 3)
```

## 範囲指定
```vb
  Range("A2:C4")
  Range(Cells(3, 4), Cells(5, 8))
  Range(Range("A2"), Cells(5, 8))
```

## 行全体指定
```vb
  Range("D:D")          'D列
  Range("E:E", "G:G")   'E~G列
  Columns("D")          'D列
  Columns("E:G")        'E~G列
```

## 列全体指定
```vb
  Range("5:5")          '5行目
  Range("6:6", "8:8")   '6~8行目
  Rows("5")             '5行目
  Rows("6:8")           '6~8行目
```

## 最大行・列
'''vb
  Rows.Count '最大列数 : 1047586
  Column.Count '最大行数 : 16384
'''

## CellとRangeの違い
　Range　:　範囲指定可能
　Cells　：　範囲指定不可⇒単一指定しかできない。

# 選択
```vb
  Range("A1:C3").Activate　` Active : 範囲選択する
　Range("A5").Select       ` Select : カーソルを合わせる
```

# 挿入・削除
```vb
  Rows(行位置).Delete
  Rows(行位置).Insert
  Columns(列位置).Delete
  Columns(列位置).Insert
```

# Rangeのプロパティ
## Resize
　Rangeの選択範囲を変更する

```vb
  ' A1を起点として2行3列 (A1:C2)にサイズを変更する。
　Range("A1").Resize(2, 3).Select
```
## Offset
```vb
  ' A1の起点を2行2列ずらし(A1:B2) -> (C3:D4)に変更する。
  Range("A1:B2").Offset(2, 2).Value = 10
```


# RangeとFor Each文
・走査の順序はA1, A2...C2,C3である。 (→ ↓)



```vb
  Dim r As Range
  For Each r In Range("A1:C3")
    MsgBox (r.Value)
  Next
```
Python3.9でのPygame Zeroインストール

最新のPython 3.9.2でPygame Zeroをインストール（ pip install pgzero ）したところエラーになった。

```
ERROR: Command errored out with exit status 1:
```

これはPygameの1.9.6がインストールできないため。Pygameの2.0.0を入れて、Pygame Zeroを依存関係無しでインストールするとうまくいく。

```
pip install pygame==2.0.0
pip install pgzero --no-deps
```

なお、ダウンロードしたPygameのキャッシュが残っている場合にはうまくいかないので、まずキャッシュをクリアする。

```
pip cache purge
```
AWS上でCloudWatch、タスク実行を使ったテストを行う

## CloudWatch Eventを使ったテスト
CloudWatchでは指定したスケジュールに基づいて、自動的に実行される。
例えば、

```
毎週水曜日の12時30分に実行
```
のようなもの。

とはいえ、テストをしたいと思ってもそのスケジュールを待つのはさすがに時間がもったいないことになるので、
テストのときだけ一時的にスケジュールを今から1～2分後の時間に書き換えればいい。(※日本時間ではなくUTC時間です)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/ce664da3-ab14-7353-471a-b67e30266f79.png)

この画面に行ったら、右上の「アクション」を選択して「編集」をクリック


そしたら、この画面になるので、
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/11b2da3b-03ef-ae61-6386-4c6cd1580bd5.png)

ここの、Cron式の部分で、今から数分後の時間を指定したらいい。
もし今が水曜日の22時12分なら、UTC時間なので、13時12分を指定する。

あとは、保存するだけで勝手に実行してくれる。

※ここでは実行の際の設定を上書きとかは出来ないので、実行前にタスク定義で新しいリビジョンを作成して設定を決めてから、先ほどの時間を書き換えて実行して、テストを行う。


## タスクから実行
この画面になったら、任意のタスクをクリックする
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/6dff6851-13ed-cdfd-4ca9-b7a3b6867111.png)

新しいリビジョンを選択して、「アクション」→「タスクの実行」

あとは、任意の起動タイプとかクラスターVPC、サブネットとかいろいろ指定したらいい。
詳細オプションを開けば、現在タスクで設定している環境変数を一時的に上書きして実行できる(タスク実行後は元通りになる)

## 実行後にエビデンスを取っていく
実行結果は、CloudWatchのログや、クラスターを選択すると、システムが出したログとかエラー出力や終了コードとか見れて、クラスター選択すると、その時に実行したときの環境変数とかの設定情報が見れたりするし、S3を見に行けば実際にファイルがアップロードされているかも見れるので、結合テストでのシナリオで本当に正しい手順でテストしたのかや、実行後にどうなったのかのエビデンスを残せることができる。
C#でif (Hoge()) {} がビルドエラーになる時ってどんな時？

## 問題1

最初の書き方がビルドエラーになって、2番目の書き方がビルドエラーにならない時って、どんな場合でしょうか？

```cs
if (Hoge()) 
    Console.WriteLine("Hoge() == true");
```


```cs
if (Hoge() == true) 
    Console.WriteLine("Hoge() == true");
```


<br>

### 答え

それは、Hogeメソッドが、bool?を返す場合です。

```cs
static bool? Hoge()
{
    // false や null を返すかもしれない  
    return true;
}
```

このような定義の場合、以下のコードはビルドエラーになってしまいます。

```cs
if (Hoge()) 
    Console.WriteLine("Hoge() == true");
```


## 問題2

それでは、以下の書き方以外でビルドエラーにならない書き方はあるでしょうか？

```cs
if (Hoge() == true) 
    Console.WriteLine("Hoge() == true");
```

<br>


### 答え

??演算子を使って以下のように書けばビルドエラーは出なくなります。

```cs
if (Hoge() ?? false) 
    Console.WriteLine("Hoge() == true");
```

Hige()の戻り値がnullならば ?? 演算子で falseにしています。これで、Hoge()がtrueの時だけ `Hoge() ?? false`は、真になります。


## 問題3

それ以外の書き方はありますか？

<br>

### 答え

GetValueOrDefault()メソッドを使う方法もあります。

```cs
if (Hoge().GetValueOrDefault())
	Console.WriteLine("Hoge() == true");
```

bool値のdefault値はfalseなので、`Hoge().GetValueOrDefault()`は、Hoge()がtrueの時だけ真になります。
Ubuntu (debian系も？）にapt キャッシュサーバー機能を付けて転送を効率よくする（https問題も記述）

Ubuntu ( debian 系も？) に apt キャッシュサーバー機能を付けて転送を効率よくします。

下記コマンドでメインの PC に apt のキャッシュサーバー機能をインストールします。

````bash
sudo apt-get update; sudo apt-get install apt-cacher-ng ; echo 'Acquire::http::Proxy "http://127.0.0.1:3142";' | sudo tee /etc/apt/apt.conf.d/02proxy ;
````

次にサブ機で apt update する場合はキャッシュを見るように設定を行います。

````bash
sudo gedit /etc/apt/apt.conf.d/02proxy ;
````

192.168.0.xxx の部分はメインPCのIPアドレスを入力します。IPアドレスの確認は ifconfig コマンドで行えます。

````bash:/etc/apt/apt.conf.d/02proxy
Acquire::http::Proxy "http://192.168.0.xxx:3142";
````

これで、メイン機、サブ機ともに 192.168.0.xxx からキャッシュを読み込むようになります。

ちなみにたまにレポジトリが http ではなく https でエラーが出る場合は下記のようにキャッシュは使わず直接読みに行くようにします。

````bash
sudo gedit /etc/apt-cacher-ng/acng.conf ;
````

````bash:/etc/apt-cacher-ng/acng.conf
PassThroughPattern: .*
````

あとはサービスを再起動して設定を再読込させます。

````bash
sudo service apt-cacher-ng restart
````

マシンが増える場合はもちろんのこと、なるべく転送量を抑えたい IOT 系 SIM 向けに事前にキャッシュを作っておくと転送料金を気にしなくて良いかと思います。

####参考リンク
- [[メモ] aptのキャッシュサーバ(apt-cacher-ng) - Qiita ](https://qiita.com/mt08/items/c8b8187b1000382d77ae)
- [apt-cacher-ng で https リポジトリを直接アクセスするようにする – matoken's meme ](https://matoken.org/blog/2019/07/19/direct-access-to-https-repository-with-apt-cacher-ng/)
- [transitive.info - apt-cacher-ng ](http://transitive.info/2009/04/05/apt-cacher-ng/)
Flutterのwidget（ウィジェット）とは

##widgetを調べた理由
[チュートリアル](https://flutter.ctrnost.com/tutorial/tutorial03/)を進めていると
**Flutterでは、配置やパディング、レイアウトに関するほとんどすべてがウィジェットでできています。**
という一文があったため、この意味をしっかりと解釈するため調べた。


##一般的な意味
(名称のわからない)何とか部品、(ちょっとした)機械装置、(会社の製品の)代表製品

##IT業界での意味
widgetトとは、システム画面などに小さく表示される単機能のアプリケーションソフト。
また、コンピュータの操作画面（GUI）を構成する、何らかの機能を持った表示・操作要素。
前者は「ガジェット」（gadget）とも呼ばれる。

##身近なwidget（ウィジェット）
**アプリケーションソフト**
PCやスマートフォンのデスクトップ上やホーム画面上で動作する単一的な機能を持ったもの。（時計やカレンダーなど）
現状は、PC向けのwidgetの開発はほとんど行われてない。

上記の三つの意味を踏まえるとwidgetには
・部品
・単一的な機能を持ったもの
といった意味が含まれていることがわかる。

つまり、**Flutterでは、配置やパディング、レイアウトに関するほとんどすべてがウィジェットでできています。**
という一文は、
**Flutterでのアプリ開発のために様々なwidgetが用意されていて、それを組み合わせることでアプリを作成する。**
ということだったのか。


今から全力前進でFlutterのチュートリアル進めていきます！！！
自己紹介、です。

#初めまして
どうもどうも、Kiku(キク)と申します。
今年から本格的にマークアップエンジニアからフロントエンドエンジニアを目指すため、情報収集や備忘録作成のためQiitaを始めました。

よろしければポートフォリオサイト、Twitterもよろしくお願いいたします。
[ポートフォリオサイト](https://kiku-cha.github.io/portfolio/) / [Twitter](https://twitter.com/kiku_dondokodon)



：目次：
[ざっくりとした経歴紹介](#ざっくりとした経歴紹介)
[スキルとツールについて](#スキルとツールについて)
[最後に](#最後に)


___
#ざっくりとした経歴紹介
・元々はデザイナー志望ということもあって高校卒業後は地元・沖縄を出て、大阪のデザインの専門学校へ入学
　...しましたが、色々あってその年の冬に中退して沖縄に帰りました。

・沖縄に帰ってからは接客業や事務をしてましたが、「やっぱりデザインやりたい！」という気持ちがあったので
　ある企業のWEB人材育成コースに契約社員として入社。(ここでコーディングに触れる。)
　研修期間中にOJTで雑貨屋の商品デザインを担当。

・雑貨屋を退職後、職業訓練校でWEBクリエイター関連の内容を学習し直す。(コーディング、デザイン作成などなど。)

・職業訓練修了後、IT企業でアルバイト。
　制作の部署で本格的にコーディングをするようになりました。

・転職してからもコーダーとして働いてましたが、スキルアップなどを考えて退職。

・現在、転職活動中。

もうちょっと細かい紹介は、[ポートフォリオサイト](https://kiku-cha.github.io/portfolio/)の「Timeline」でご確認を・・・。


___
#スキルとツールについて
コーディング作業、結構好きです。
静的ページの作成は問題ないかと思うので、HTML5、CSS、Sassはある程度できているかと思います。
Javascript(Vue.js含む)は勉強中です。

PHPやWordpressは前職で改修作業、ページ作成などを行ったくらいなので
まだまだです・・・。(構築は一度だけです、一度だけ・・・。)
DB、SQLなどサーバー周りも弱いです。
ここら辺も落ち着いたらガッツリ勉強したいです。

ツールは
・エディタ：Atom、VScode
・画像作成：Photoshop
を使用しています。
商品デザインをしていた時はIllustratorがメインでしたが、5年以上はがっつり触っていません。(・ω・`)


___
#最後に
ぼんやりですが、「将来はフリーランスになる」という目標があるので、
慌てず、落ち着いて頑張ろうと思っています。
楽しみながらやっていきましょう〜٩('ω')و
pandasのread_csvでUnicodeDecodeErrorした際の対処法まとめ

pandasではデフォルトでutf-8のcsvを読み込むことになっているために起こるエラー。


## encoding:元ファイルの文字コードを指定するパターン
read_csvに対して、encoding='shift_jis'などのオプションを付与。
特にwindows環境下で作られたcsv（Excelで作成したものなど）は、shift_jisやcp932を指定することで解決する事がある。
参考：https://insilico-notebook.com/python-unicodedecodeerror/
（↑のサイトにはpythonが標準でサポートする日本語文字コードの一覧がある。）

本来はこれで解決するはずだが、解決しないことが多い。原因不明。

```python
import pandas as pd
df = pd.read_csv('data.csv', encoding='shift_jis')
```

## engine:エンコーディングをpythonで行う
read_csvに対して、engine="python"オプションを付与する方法。
https://punhundon-lifeshift.com/engine_python

```python
import pandas as pd
df = pd.read_csv('data.csv', engine='python')
```

## codecs(f, "ignore"):無視するパターン
fileopenにcodecsを使い、ignoreオプションを付けるパターン。
https://qiita.com/niwaringo/items/d2a30e04e08da8eaa643

どのようなファイル形式が来るか分からない中では、ignoreしてしまうのが手っ取り早い。
一方で、文字化けの原因を作る事にもなるので、推奨しづらい。
公式ドキュメント：https://docs.python.org/ja/3/library/codecs.html

```python
import pandas as pd
import codecs
with codecs.open("path/to/file", "r", "shift_jis", "ignore") as file:
    df = pd.read_csv('data.csv')
    print(df)
```

## codec.StreamRecorder:文字コードを変換する
code.StreamRecorderを使って文字コードを変換するパターン。
おそらく、この方法が最善。
https://dev.classmethod.jp/articles/python-encoding/
公式ドキュメント：https://docs.python.org/ja/3/library/codecs.html

StreamRecorderは引数でlookupメソッドから返されるCodecInfoを使うため、少し回りくどい書き方になっている。

サンプルでは、HttpRequestから受け取ったファイルストリームをShift_JISからutf-8へ変換している。

```python
            f = request.FILES['original_file'] #HttpRequestから受け取るファイルストリーム

            codec_sjis = codecs.lookup("shift_jis")
            codec_utf8 = codecs.lookup("utf-8")
            f_utf8 = codecs.StreamRecoder(
                f,
                codec_utf8.encode, codec_sjis.decode,
                codec_sjis.streamreader, codec_utf8.streamwriter,
            )

            data_frame = pd.read_csv(f_utf8)
```

## 元のファイルを何らかの方法でutf-8に変換
１回限りのread_csvなら許容だが、繰り返し使える方法ではない。

# ■文字コードを判別する方法
CSVの文字コードが予め分かっていない場合に、それを判別するには、chardetライブラリを使う。
https://blog.imind.jp/entry/2019/08/24/143939
多重度制限付き並行処理の実装

*追記：【注意】本記事の実装にはいくつかの改善点があります。内容と改善されている別実装はコメントを参照のこと。*

## やりたいこと

ただの並列処理ではなく、多重度に制限を付けられる並列処理。
例えば、100件の処理があったとき10を指定すると最大並列10で並列処理をして実施する

## ユースケース

APIをたくさん叩くときに多重度の制限やレートリミットがある場合など。

## 実装

```typescript
const limitedParallel = async <P, R>(
  limit: number,
  params: P[],
  process: (param: P) => Promise<R>,
): Promise<R[]> => {
  if (limit <= 0) return []

  const reqGroups: Promise<R[]>[] = []

  for (let i = 0; i < limit; i++) {
    reqGroups.push(
      new Promise<R[]>(async (resolve) => {
        const ret: R[] = []

        for (let j = i; j < params.length; j += limit) {
          const r = await process(params[j])
          ret.push(r)
        }

        resolve(ret)
      }),
    )
  }

  return Promise.all(reqGroups).then((ret) => {
    return Array.prototype.concat.apply([], ret)
  })
}

```

## メモ、備考

- limit === 0 のときはアサーションや例外でも良いかもしれない
- Array.prototype.concat.apply([], ret)はそのうちret.flat()に置き換える
- 他に良さそうな実装があったら教えてください
apktoolでリコンパイル＆jarsignerで署名したアプリのインストールにコケたけど解決した話

# いきなりまとめ
* apktoolでdecompile & recompileしてjarsignerで署名してadb install app.apkしたけどコケた
* Android11からはapk署名スキームv2を使う必要あり
* そのためにはjarsignerではなくapksignerを使う


# おさらい
## apktoolでdecompile & recompile

```memo:まずはデコンパイル。
apktool d targetapp.apk
```

```memo:次にリコンパイル
apktool b targetapp -o output.apk
```

```:[備忘録]自分がよくやるデコンパイル・リコンパイルの間の作業

AndroidManifest.xmlの編集
追加：android:networkSecurityConfig="@xml/network_security_config" 
追加：android:debuggable="true#

追加：res/xml/network_security_config.xml
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
    </debug-overrides>
</network-security-config>
```

## 署名する
```:署名に使う証明書作成
keytool -genkey -v -keystore test.keystore -alias TEST -keyalg RSA -validity 10000
```

```:jarsignerでの署名
jarsigner -verbose -keystore test.keystore app.apk TEST
```

```:apksignerでの署名
apksigner sign --ks test.keystore -v --v2-signing-enabled true --ks-key-alias TEST app.apk
```

※各種ツールの細かい使い方はヘルプ参照。
Vmware player で NAT 接続から Bridge 接続に変更した場合、うまくネットにつながらない場合の対策

Vmware player で NAT 接続からメインの起動しているパソコンと同じグループにする bridge 接続にした場合、うまくネットにつながらい場合の対処方法です。

※このページ下部に追記あります。

基本的には vmware player の再インストールが良いようです。
なんじゃそりゃって感じですが、どうしても解決しなかったのでこれになりました。

まずはすでにインストールされている vmware player をアンインストールします。

````bash
sudo vmware-installer -u vmware-player ;
````

次に公式サイトから最新の vmware player をダウンロードします（会員登録が必要かと思います）。

- [製品のダウンロード ](https://my.vmware.com/jp/web/vmware/downloads/#all_products)

そして、下記コマンドでインストールを行います。

````bash
sudo bash VMware-Player-*.x86_64.bundle ;
````

再度ブリッジ接続の設定を行うとちゃんと仮想ハブを通して同じグループのIPアドレスが取得できるかと思います。

####追記

仮想ハブが死んでいる可能性があるので、プロセス番号を調べて、killして再稼働すればOKっぽいです。
もしくはメインマシンを再起動させます。

````bash
ps aux  | grep vmnet-bridge ;
sudo kill XXPIDXXX ;
sudo /usr/bin/vmnet-bridge -s 6 -d /var/run/vmnet-bridge-0.pid -n 0 ;
````

####参考リンク
- [Bridged networking won't start after sleep - VMware Technology Network VMTN]( https://communities.vmware.com/t5/VMware-Workstation-Pro/Bridged-networking-won-t-start-after-sleep/td-p/2123966)
- [Solved: VMware Workstation 12 Bridging problem with vmnet0 - VMware Technology Network VMTN ](https://communities.vmware.com/t5/VMware-Workstation-Pro/VMware-Workstation-12-Bridging-problem-with-vmnet0/td-p/927892)
- [Workstation Player のアンインストール ](https://docs.vmware.com/jp/VMware-Workstation-Player-for-Linux/15.0/com.vmware.player.linux.using.doc/GUID-0F7D2C5C-2B5C-4857-9166-A0B3B0C72B5F.html)
- [製品のダウンロード ](https://my.vmware.com/jp/web/vmware/downloads/#all_products)
- [Ubuntu で VMware Workstation Player バージョン 15 のインストール]( https://www.kkaneko.jp/tools/vmware/vmwareplayerubuntu.html)
JavaScriptの変数 [var] についての基礎知識

##この記事で整理する用語

- 変数
- var


----------
##変数とは？

データを一時的に保管しておくための「箱」のような物をイメージする。
変数には好きな「名前」をつけることができます。
なお変数を「識別子」と呼ぶこともあります。



変数の使い方

　変数を使用するためには、まずは変数を作ります。より正確には、「変数を宣言する」といいます。そのためには `var` キーワードに続けて変数名を書きます。


    var a = 100 // a という名前の変数を宣言し 100 という値を入れる


変数名のルール


- 変数名に使用できる文字は英数字と _ (アンダースコア) $ (ダラー) の記号
- 変数名はアルファベット(a-z, A-Z) または _ (アンダースコア) $ (ダラー) から始めること
- 変数を数字(0-9)から始めるとエラーになります


変数を使用するときは以下のように書きます


    var hoge = 500 // hoge という変数に 500 という値を格納
    var $a = 1000 // $a という変数に 1000 という値を格納
    var _abc = 999 // _abc という変数に 999 という値を格納


大文字と小文字は区別される


    var a = 100
    var A = 200
    // a と A は別の変数として宣言される

よくある間違い(エラーになることをコンソールで確認してください)

    var myFirstName = 100
    console.log(myFirstname) // N -> n 大文字と小文字が間違っているのでエラーになる

###【重要】変数には意味のある名前をつける


　名前があるとコードの意味を理解しやすくなります。どんな値が格納されているかの説明にもなるので、変数にはパッと見たときにそのデータが何か分かる名前をつけるようにしましょう。


    var price = 500 // 値段
    var age = 34 // 年齢
    var boxCount = 5 // 箱の数


変数には様々なデータが格納できる

格納(=保持)です。箱にデータを入れるイメージなので、変数にデータを入れることを「格納」と表現することが多いです。


- 配列やオブジェクト、関数なども格納できます
- 


    var name = '山田太郎' // 文字
    var age = 33 // 数値
    var is_programmer = true // 真偽値
    var favorite_foods = ['焼肉', '寿司'] // 配列
    var result = 11 * 22 / 0.5 // 計算結果

###Uncaught SyntaxError とは？

例えばJavaScriptの構文に違反したコードを書いてみましょう。


    var a =; alert // ;　　　(コロン)がおかしい
    var 3_name = 100 // 　　変数名のつけ方が規則違反

　JavaScript構文として解釈できないコードが実行されると、Uncaught SyntaxErrorというエラーが出ます。このエラーは単純な書き間違いが原因です。コードをよく見て冷静に間違いを見つけ修正しましょう。


![](https://paper-attachments.dropbox.com/s_0D9BF6D0A3BE8CD529AD744215E8AC6EB0A9B16203000C9B89305CE4B2F374C8_1583109499992_+2020-03-02+9.38.05.png)

###変数だけをまず宣言し、後から値を入れる書き方ができる

　
宣言と値の格納は分けることもできます


    var name
    var age
    
    name = '山田太郎'
    age = 33


一度に複数の変数を宣言することができる

カンマ記号で区切ることで複数の変数を一度に宣言できます


    // この書き方もOK
    var name, age, job_name, school_name,


    // こちらの書き方もOK 宣言と同時に初期化(値のセット)しています
    var name = '山田太郎', age = 33, school_name = '山田塾', 


![](https://i.gyazo.com/fe563b6fea7884a69794a0982dac7e1f.png)

変数の中身は書き換えることができる

var で宣言した変数の中身は他のデータで書き換えることも可能です


    var price = 500 // 値段
    var tax = 0.10 // 消費税
    var postage = 120 // 送料
    price = price + (price * tax) // 消費税込みの値段を計算した結果を price へ再度格納
    price = price + postage // 送料込みの値段を計算



##まとめ：var とは何か？
- `var` は `変数` を宣言するための `キーワード`
- 変数に使える文字は決まっている
- 大文字と小文字は区別される
- `var` 以外にも `let` `const` というキーワードがある
- `var` を使って宣言した変数の中身は書き換えることができる
PySimpleGUIによるQRコード生成するアプリを作ってみた。

# PySimpleGUIで簡単なアプリを作成

## GUIを簡単に作れるけど
PySimpleGUIはものすごく簡単にGUI画面を作れますが、実用的な物を作ろうとすると「この値をどうやって渡せばいいのかわからない」という状態になります。
自分の覚書きとして、自分と同じ状態になる人用にシンプル且つ意外と実用的な
「テキストボックスの文字をQRコード画像にするアプリ」という物を作りました。

PySimpleGUIは慣れてしまうと体感的で使いやすいので、どうぞ使ってみてください！

## インストールするライブラリ


```
pip install pysimplegui
pip install pyqrcode
pip install pypng
```

## ソースコード
インストールしたライブラリのpypngはimportを明示する必要はない。
QRコードは
ソースコードと同じフォルダにPNG画像として保存される。

```qr_gui.py
import PySimpleGUI as sg
import pyqrcode

def qr_gui():
    layout = [[sg.Text("QRコードにしたい文字を入力してね")],
              [sg.InputText(key='-qr_text-'),
               sg.Submit(button_text="実行",key="-submit-")],
             ]
    window = sg.Window('qrコード作成',layout)

    while True:
        event,values = window.read()
        """
         ↓のif文は必須である。付けないと
         「if event == sg.WINDOW_CLOSED付けてね」と
         コマンドプロンプトからctrl+Cで強制終了するまで言ってくる。
        """
        if event == sg.WINDOW_CLOSED or event == 'Exit':
            break

        # valuesは{'-qr_text-': ''}の形で入ってくる。
        qr_text = values['-qr_text-'] 
        if event == '-submit-' and qr_text:
           create_qrcode(qr_text) 
           sg.Popup('{}のQRコードを作成しました。'.format(qr_text))
        elif qr_text == '': 
           sg.Popup('空白です。入力してください')

    window.close()


def create_qrcode(qr_text):
    qr = pyqrcode.create(content=qr_text,error='H') 
    qr.png(file='{}.png'.format(qr_text),scale=6)


if __name__ == '__main__':
    qr_gui()
```

## 完成したアプリの使い方
1.テキストボックスに適当に文字を入力して実行を押す。
![gui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655653/554282f2-c76a-ee1e-aebc-9ae68e60ab18.png)

2ポップアップ画面が表示。QR画像の作成完了をメッセージ表示。OKボタンを押す。
![gui2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655653/3718c31d-eedb-2126-d3d3-99b65b647a41.png)

3.実行ファイルと同じフォルダにQRコードが作成される。
![12345.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655653/0cc714cf-8927-4e8a-0a63-227bf0f0a71d.png)

慣れてしまうとちょっとしたものならすぐに作れてしまいます。
以上です。
[PowerToys] Keyboard Manager「かな」「英数」キーでATOKで日本語入力のオン・オフをする

ATOKを使い始めたのだが、
PowerToysをインストールして、Keyboard ManagerからVK22, VK26に無変換と変換を割り当てればOKでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/8396b06a-0303-e17b-c297-c6b1c0768607.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/6a39633f-0260-c61a-a7ee-3833aa4446e6.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/c9396d8a-f4a4-1659-83a6-f1c7b15a65d9.png)
【Windows】node-gyp ERRで困ったときの対処法

electronでディープリンク（Custom URL Schema）実装時に[electron-deeplink](https://github.com/glawson/electron-deeplink) を使おうと思ったのですが、そこでnode-gypのエラーが出て躓いたので、その時の対処法をメモします。
ディープリンクについては[electron-deeplink](https://github.com/glawson/electron-deeplink)を使って実装したら（少なくとも開発環境では）簡単にできましたので割愛します。

# 結論
Python や Visual C++ といった必要なものをインストールする

# エラー内容
`yarn add electron-deeplink`したところ、

```
gyp ERR! find Python
gyp ERR! find Python Python is not set from command line or npm configuration
```
とか、Pythonをインストールした後も

```
gyp ERR! find VS
gyp ERR! find VS You need to install the latest version of Visual 
Studio
gyp ERR! find VS including the "Desktop development with C++" workload.
```

という感じで

# 参考
[nodejs/node-gyp](https://github.com/nodejs/node-gyp)
[Windowsでnpm installしてnode-gypでつまずいた時対処方法](https://qiita.com/AkihiroTakamura/items/25ba516f8ec624e66ee7)

# ERR! find Pythonと出た場合のPythonインストール
```powershell:powershell
python
```
と打つと、[Python公式ページ](https://www.python.org/downloads/)が開くのでそこからダウンロード＆インストール
（バージョンは[nodejs/node-gyp](https://github.com/nodejs/node-gyp)から対応してるものを選ぶように）

ぼくの場合はこれでも「VSが見つからん！」と怒られたので`windows-build-tools`を使いました。

```bash:bash
yarn add global windows-build--tools
```
で、成功すれば下記の表示が出るので、`vs_BuildTools.exe`を起動します

```
Downloaded vs_BuildTools.exe. Saved to C:\Users\{ユーザ名}\.windows-build-tools\vs_BuildTools.exe.
```


```powershell:powershell
PS C:\Users\{ユーザ名}> .\.windows-build-tools\vs_BuildTools.exe
```
起動できると下記のような画面が出ます。
ぼくの場合とりあえず一度デフォルトのままインストールしたものの、再度modifyをしてインストールしたので表示が違うかもしれません
`Visual C++ build tools`にチェックを入れて、`Install` or `Modify` をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58707/e1366fad-939b-4bda-eb5c-1176143050b6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58707/f83a7846-439e-e5e4-f502-71f75b4a32ea.png)

# electron-deeplink インストールし直す
```bash:bash
yarn add electron-deeplink
#なんやかんや
$ electron-builder install-app-deps
  • electron-builder  version=22.9.1
  • loaded configuration  file=C:\Users\{path-to-project}\electron-builder.yml
  • rebuilding native dependencies  dependencies=electron-deeplink@1.0.6 platform=win32 arch=x64
  • rebuilding native dependency  name=electron-deeplink version=1.0.6
Done in 36.12s.
```

これで解決
ディープリンクも簡単に実装できました。
【Xcode12】「UIApplication.shared.isIdleTimerDisabled = false」を書いたのにiPhone実機がスリープしない【Swift5】

#はじめに
アプリがスリープモードにならない状態とスリープモードになる状態をコードで書いて試していました。
なぜか、スリープ状態になるコードを書いたのにスリープにならないという状態になりました。
そこで今回調べたので記事を書きました。

#環境
Xcode12.3
Swift5.3.2
macOS Catalina 10.15.4

#実行した事

```swift
 override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        UIApplication.shared.isIdleTimerDisabled = false
}
```
※ UIApplication.shared.isIdleTimerDisabled = true にしてスリープモードを解除し、再度スリープモードにするという事を試していました。

#結果
アプリがスリープモードになりませんでした。

#原因
[参照サイト](https://iritec.jp/web_service/3740/)に書かれているように、Xcode側からiPhone実機をビルドしている事が原因でした。
Xcodeと実機の接続を切って再度実行したところ、スリープになりました。

#補足
[公式](https://developer.apple.com/documentation/uikit/uiapplication/1623070-isidletimerdisabled)よりdefaultでは「 UIApplication.shared.isIdleTimerDisabled = false」に設定されています。

```Swift
//スリープモードを無効
 UIApplication.shared.isIdleTimerDisabled = true
//スリープモードを有効
 UIApplication.shared.isIdleTimerDisabled = false
```

#参照サイト
https://iritec.jp/web_service/3740/
https://developer.apple.com/documentation/uikit/uiapplication/1623070-isidletimerdisabled
https://qiita.com/imj164/items/f35187a8fe84d9a0cd35


#終わりに
Xcode側からiPhone実機をビルドする事も、Xcode側からiPhone実機の接続を切って実行する事も同じ事だと思っていたので勉強になりました。

[Twitter](https://twitter.com/koara1237)やっています。
【TypeScript × Nuxt.js】練習がてら超簡易ToDoアプリ作りました【入門】

TypeScirptの基本構文を一通り学習したのでNuxt.jsと組み合わせて超簡易ToDoアプリを作りました。

また今回Composition-APIにも挑戦しました。

# 開発環境

- macOS Catalina 10.15.7
- @nuxt/cli v2.14.7
- npm 6.9.0
- node v10.16.0
- TypeScript 4.1.3
- @nuxtjs/composition-api 0.20.2

# 完成物

![demo](https://gyazo.com/3156886949d5ac2b4c70fafd6373e8ec/raw)

```vuejs:index.vue
<template>
  <div class="container">
    <h1>Nuxt-ToDo-App</h1>
    <br />
    <h3>
      <form @submit.prevent="addTask()">
        Add Task : <input v-model="task" type="text" />
      </form>
      <br /><br />
      <table>
        <tbody>
          <tr v-for="(task, index) in tasks" :key="task.id">
            <td :class="{ done: task.isDone }">{{ task.name }}</td>
            <td
              v-if="task.isDone"
              class="pointer"
              @click="task.isDone = !task.isDone"
            >
              [済]
            </td>
            <td v-else class="pointer" @click="task.isDone = !task.isDone">
              [未]
            </td>
            <td class="pointer" @click="removeTask(index)">[x]</td>
            <br />
            <br />
          </tr>
        </tbody>
      </table>
    </h3>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs } from '@nuxtjs/composition-api'

interface Task {
  name: string
  isDone: boolean
}

export default defineComponent({
  setup() {
    const state = reactive({
      task: '',
      tasks: [] as Task[],
    })

    const addTask = () => {
      const taskObj: Task = { name: state.task, isDone: false }
      state.tasks.push(taskObj)
      state.task = ''
    }

    const removeTask = (index: number) => {
      state.tasks.splice(index, 1)
    }

    return {
      ...toRefs(state),
      addTask,
      removeTask,
    }
  },
})
</script>

<style>
.container {
  text-align: center;
}

table {
  margin: 0 auto;
}

.done {
  text-decoration: line-through 3px;
}

.pointer {
  cursor: pointer;
}
</style>
```

***

TypeScript × Nuxt.js × compositon-API の記事は今はまだ少なめですよね

何か良い教材があれば良いのですが・・・
webpackのloaderで無用なコードをignoreしましょう

開発環境でデバッグする際にconsole.log()をよく使いますけど、本番環境ではあまり使わないので、ここでconsole.log()を例として、webpackのloaderで無用なコードをignoreする方法を説明させて頂きます。

そもそもwebpackのloaderはfunctionなので、~~正規表現とreplace()メソッドで無用なコードを空文字列で交換するfunctionを実装します：~~ ネストされた括弧を扱うのはjavascriptの正規表現の処理能力を超えいるため、ここで、再帰関数で実装します：

```js:loaders/ignoreUnuseCode.js
function ignoreUnuseConsoleLog(code) {
    const indexStart = code.indexOf("console.log(")
    if (indexStart === -1) return code
    let i = indexStart + "console.log(".length - 1
    let leftParenthesisNeedToBeMatched = 1
    for (i < code.length ; i++;) {
      if (code[i] === "(") {
        leftParenthesisNeedToBeMatched +=1
      }
      if (code[i] === ")") {
        leftParenthesisNeedToBeMatched -=1
        const next = i + 1
        if (code[next] === ";") i++
      }
    
      if (leftParenthesisNeedToBeMatched === 0) break
    }
    const unuseConsoleLog = code.slice(indexStart, i+1)
    code = code.replace(unuseConsoleLog, "")
    return ignoreUnuseConsoleLog(code)
}

module.exports = ignoreUnuseConsoleLog
```
or
再帰使用しない：

```js:loaders/ignoreUnuseCode.js
function ignoreUnuseConsoleLog(code) {
    const indexes = [...code.matchAll(/console\.log\(/g)]
    const resultArr = []
    let left = indexes[0]
    let remain = 1
    for (let i = 0; i < code.length; i++) {
      const char = code[i]
      if (left) {
        if (i < left.index)
        resultArr.push(char)
        else if (i >= left.index + 12) {
          if (char === '(')
            remain += 1
          else if (char === ')')
            remain -= 1
          if (remain === 0) {
            remain = 1
            while (left = indexes.shift()) {
              if (left.index > i)
                break
            }
          }
        }
      } else
        resultArr.push(char)
    }
    return resultArr.join('')
}

module.exports = ignoreUnuseConsoleLog
```

本番環境のwebpack configファイルにignoreUnuseCodeのloaderを追加します、resolveLoaderでloadersフォルダを指定することを忘れないように：

```js:webpack.prod.conf.js
var path = require('path')
module.exports = {
  /*他のオプション...*/
  module: {
    rules: [
      {
        test: /\.js$/,
        use: ['ignoreUnuseCode'],
      },
    ]
  },
  resolveLoader: {
    modules: ['node_modules', path.resolve(__dirname, 'loaders')]
  }
}
```

```js:demo.js
document.write('<h1>Hello World</h1>');
console.log("debug something");alert("alert something");console.log("debug something");
function debug(a) {
    return a
}
console.log(debug())
```

結果として：
`ignoreUnuseCode loaderを利用する前：`
![WechatIMG44.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269934/d0359da9-de4f-fe48-6a42-44efec4177e9.jpeg)





`ignoreUnuseCode loaderを利用する後：`
![WechatIMG45.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269934/5f301373-e079-a8d9-d261-3091ef5681a7.jpeg)
Gitlabでmasterにプッシュできない

# 経緯
外注先からの成果物をgitlabにアップロードしてもらうために、ユーザを作ってdeveloper権限振って、プッシュしてもらおうと思ったら、下記のエラーが発生したとの連絡が

```
! [remote rejected] master -> master (pre-receive hook declined)
```

# 結論
どうやらgitlabでは、developer権限者のmasterブランチへのpushをデフォルトで禁止しているようでした
この設定は設定のプロテクトから変更することができるのですが、ファーストプッシュ前ではレポジトリが作成されていないため、設定が存在しないため、変更することができない（デフォルトの設定が適用される）

# 解決策①：Maintainer権限を付与する
これが一番手っ取り早くてかんたんです
私はこの方法でやりました（めんどくさかったので。。。）

# 解決策②：正攻法？
1. 作成者（Owner権限を持っているユーザー）がREADME.mdをコミットしてリポジトリとmasterブランチを作成する
2. プロテクトを外すorDeveloperに権限付与（Setting→Repository→Protected BranchesをExpand）

![SnapCrab_NoName_2021-2-24_20-54-15_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553852/20c69ad4-32f7-26ff-8262-f5546f56ec30.png)

# 解決策③：masterを使わない
developブランチなどを作成してそちらにプッシュしてもらう
masterへのマージは管理者で行う

これがあるべき姿な気はします
今回は小規模なプロジェクトだったので省きました

ちなみにこの方法でも②-1の手順を踏み、masterブランチを作成する必要があります

# まとめ
上記を調べると、「プロテクト外せばいいよー」ってでてきたんだけと、「プロテクトなんてないじゃん。。。」てなって手詰まったので備忘録として残しておきます
React + TypeScript で defaultProps の型定義をする

GatsbyJS をTypeScript化してみて気付いたのですが、
`defaultProps`を設定した際に props の型は`undefined`型も許可してしまう問題があります。これではせっかくpropsの型定義をしても意味が無いですね。
そこで GatsbyJS の src/components/header.js をTypeScript化して header.tsx にしてみたものを例として解決方法を提示しておきます。
※GatsbyJS の src/components/header.js には defaultProps が元から定義してあるのですが、defaultPropsは最終的に廃止される予定とのことなので設定するかどうかについては注意です。詳細は[こちら](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/default_props/)をご参照ください。

# 悪いdefaultPropsの設定例
```（悪い例）src/components/header.tsx
.
.
type Props = {
  siteTitle: string
}

const Header: React.FC<Props> = ({ siteTitle }) => (
  <header
    style={{
      background: `rebeccapurple`,
      marginBottom: `1.45rem`,
    }}
  >
  .
  .
  </header>
)

Header.defaultProps = {
  siteTitle: ``, // ここがstring以外の型だったら、一応は下記画像のように怒ってくれます。しかし、undefined型だと怒ってくれません。
}
```

#### defaultProps の型が string と undefined 以外だと、 Props の型と違うので怒ってくれる例
![スクリーンショット 2021-02-24 17.50.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189135/15ebfb96-80ba-273b-9f33-ce5766b11747.png)

#### undefined だと怒ってくれません
![スクリーンショット 2021-02-24 18.07.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189135/75f06c77-62e4-d56e-e75b-55e5d05e1c99.png)

## 解決方法
方法としては、
Propsの型定義をする際に、`Intersection Types（&）`と`typeof`を使用して、 defaultProps の型定義も一緒にしてしまう方法です。
まずは defaultProps は const で変数として宣言してあげて、それをPropsの型定義をする際に一緒に当て嵌めてしまいます。
そして定義した defaultProps を Header.defaultProps に代入してあげます。
詳細は以下になります。

```（良い例）src/components/header.tsx
.
.
type Props = {
  siteTitle: string
} & typeof defaultProps

const defaultProps = {
  siteTitle: ``,
}

const Header: React.FC<Props> = ({ siteTitle }) => (
  <header
    style={{
      background: `rebeccapurple`,
      marginBottom: `1.45rem`,
    }}
  >
  .
  .
  </header>
)

Header.defaultProps = defaultProps
```

defaultProps の値をstring型以外の型の値に設定してみた場合はもちろん怒ってくれますし、
![スクリーンショット 2021-02-24 18.26.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189135/b257004f-3cb0-8a81-86cc-b2cd7bdcb719.png)

defaultProps の値を undefined に設定してみた場合も、怒ってくれるようになりました。
![スクリーンショット 2021-02-24 18.28.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189135/61c5ecd8-bf1a-09f3-baae-29c340cac6e4.png)



### 参考にさせていただいたURL
[Typing defaultProps](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/default_props/#typing-defaultprops)
M5cameraに取り付けたGroveセンサーの値がおかしい時の解決策

- M5cameraについて
- 背景
- 現象
- 原因
- 解決策
- 参考

解決に時間がかかったため備忘もかねて記事を書きました。

#M5cameraについて

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1148900/4cec403b-fac6-f91d-034e-47d33be6c9a9.png" width=50%>


スイッチサイエンス社が販売している、ESP32ベースの小型カメラユニット。
Arduino IDEを使ってプログラム可能。
GROVE互換のインターフェースを持っており、GROVEセンサを利用可能。

https://www.switch-science.com/catalog/5207/

#背景
観葉植物の育成でM5cameraを活用しようと思い、
カメラユニットで撮影しGoogleDriveへの保存（タイムラプスへ変換予定）、
＋　GROVEの水分センサーにて土の渇きを検知して通知するシステムを考えています。
上記の記事については今後書こうかなと考えています。
[GROVE 水分センサー](https://www.switch-science.com/catalog/814/)

M5cameraはESP32ベースでWifiユニットが利用できることが決め手でした。

#現象
####■水分センサーを読み取るアプリケーションだけをコンパイルし動作させた場合
analog.read()の初期値：0
※センサーで値変動あり。

####■Wifi接続と水分センサーを読み取るアプリケーションをコンパイルし動作させた場合
analog.read()の値「4095」
※センサーで値変動なし。。

#原因
ESP32でWifi接続時に使用できないピンがあるとのこと。
https://rikoubou.hatenablog.com/entry/2017/07/26/193021

待て待て待て、M5cameraはGROVEユニットが１つなので別のピンを利用しようにも使えないくないか。。
Wifi使ったときはセンサーが利用できないとか正直使えないなぁ。。
と思ったら、Githubのarudino-esp32のIssuesに挙げられていました。
（2016年からある問題のようです。）

https://github.com/espressif/arduino-esp32/issues/102

#解決策
上記Issueの中で解決されていたのでそのソースを拝借させていただいております。
（本当にありがとう！）

①Wifi接続前にレジスタの値を保存（追記したコード部分①）
②analogRead前にレジスタ値を復元（追記したコード部分②）
③12bitが反転して4095が出力されるらしいので反転（追記したコード部分③）

```cpp:sample.ino
#include <WiFi.h>
#include "esp32-hal-adc.h" // needed for adc pin reset
#include "soc/sens_reg.h"　// needed for adc pin reset
uint64_t reg_b;// Used to store Pin registers

const char* ssid = "*******";
const char* password = "********";

void setup() {
//■■■追記したコード部分①■■■
  reg_b = READ_PERI_REG(SENS_SAR_READ_CTRL2_REG);
//■■■■■■■■■■■■■■■■■■■■■■■
  
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
}

int sensorPin=13;
int sensorValue = 0;

void loop() {

//■■■追記したコード部分②■■■
    WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, reg_b);
//■■■■■■■■■■■■■■■■■■■■■■■
//■■■追記したコード部分③■■■
    SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV); 
//■■■■■■■■■■■■■■■■■■■■■■■

    sensorValue = analogRead(sensorPin);
    Serial.print("Moisture = " );
    Serial.println(sensorValue);
    delay(1000);
}
```

#参考
[【ESP32】Wifi接続時のanalogReadについて](https://rikoubou.hatenablog.com/entry/2017/07/26/193021)
[Conflict Between Wifi & analogRead()?](https://github.com/espressif/arduino-esp32/issues/102)
【1ヶ月で合格】AWSソリューションアーキテクトアソシエイト試験合格までにやったこと

１ヶ月でAWSソリューションアーキテクトアソシエイト試験を取得したのでそれまでにやったことについて書きます。１ヶ月勉強して78%で合格しました。経験から言うと可能な限り新しく、出題傾向が似ている教材で勉強することをおすすめします。

# 受験のきっかけ
都内でITコンサルタントをしている社会人1年目です。学生時代はコンピュータサイエンスを専攻していて、FPGAを利用したデータ分析の研究をしていました。クラウドはあまり使ったことがなく、試験取得のきっかけは、数ヶ月間実務でAWSの一部のサービスを触った際にサービスの組み合わせ方をもっと深く理解したいと思ったのがきっかけでした。試験勉強を通して、仕事でサービスの特徴や使い所について基本的なところはおさえて議論ができるようになったと感じています。

# やったことまとめ
主に役に立った４つに絞って紹介します。

1. 書籍「[改訂新版 徹底攻略AWS認定ソリューションアーキテクトアソシエイト - アソシエイト教科書[SAA-C02]対応](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E6%95%99%E7%A7%91%E6%9B%B8%EF%BC%BBSAA-C02%EF%BC%BD%E5%AF%BE%E5%BF%9C-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-ebook/dp/B08SGSD479/ref=pd_vtp_1?pd_rd_w=Lltsp&pf_rd_p=638bbfd4-45be-4377-9648-d1b79b701034&pf_rd_r=DNWCS1TYC8X0YY6RRZDM&pd_rd_r=cc05ac64-a214-49c6-8973-851df2c3ebd4&pd_rd_wg=MoHPO&pd_rd_i=B08SGSD479&psc=1)」 2021/1/11 初版発行<br>
教科書的に使ってました。2021/2月に受験したので、他の教材に載っていない情報でここだけに載っていて助かった場面がありました。
2. 書籍「[一夜漬け AWS認定 ソリューションアーキテクトアソシエイト[C02対応]直前対策テキスト](https://www.amazon.co.jp/%E4%B8%80%E5%A4%9C%E6%BC%AC%E3%81%91-AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-C02%E5%AF%BE%E5%BF%9C-%E7%9B%B4%E5%89%8D%E5%AF%BE%E7%AD%96%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88/dp/4798062960)」 2020/11/9 発行<br>
AやEから始まるサービスの略語の区別がつくようになってから読むと実践的な対策になると思います。
3. Udemy講座「[これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）](https://www.udemy.com/course/aws-associate/)」 <br>
長いので取得のためには全部をやる必要はないと思います。2倍速で気になるところだけ見て、最後にある３回分の模擬試験は合格まで解き直しました。
4. Udemy講座「[【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)」 <br>
難しかったのであまりやる必要はないのかもしれません。６回分の模擬試験のうち、３回分だけ解きました。2週間前に受けて40%台だったので、自分に危機感をあたえるのに使いました。

# やってみて続けなかったこと
少しやってみて遠回りに感じて使わなかったものです。

1. 無料配布の問題集アプリ<br>古い情報を見つけてから使いませんでした。
2. 無料のWEB問題集<br>出題傾向が他の教材と違ったので使いませんでした。

# 試験勉強のポイント

1. 書籍を選ぶ時はSAA-C02対応で、最新のものがおすすめです。<br>
   登場して1年くらいのサービスも出題されるので、古い本だけで勉強するのはおすすめしません。
2. 無料の問題集のアプリは情報が古い場合もあるので注意する。<br>
   例えば2020/12月にS3の特性が「結果整合性」から「強い整合性」に変わりましたが、「結果整合性」が答えになっているなど、最新でない情報がある場合もあるので、これだけで勉強するのはおすすめしません。
3. Udemyは絶対セールで買う。<br>
これはUdemyあるあるだと思いますが、初めて使う人はセールを意識するといいと思います。

# 受験前日のレベル感
受験前日のレベルとして、下記で配布されているサンプル問題が9/10迷わず解ける状態でした
https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/

# 試験の注意点
ピアソンVUEで応募し、試験会場に行って受験しました。試験の流れはスタッフの方が丁寧に説明してくれたので困ることはなかったです。試験の当日はアンケート回答後にすぐ結果がでますが、アンケートが長く感じます笑
1. 会場予約は早めにする。<br>受験会場ごとに人数制限があり、日曜日で探したのですがどこも埋まっていて受験予定日から1週間後になってしまいました。知り合いによると、キャンセルなのか水曜日に予約するとその週の日曜日が空いているらしいです笑
2. 会場で身分証明書が２種類必要<br>試験に行く方は調べると思うのですが、私は運転免許書とクレジットカードを持って行きました。

# まとめ
784点(720点以上合格)とそこそこぎりぎりな結果だったのですが、時間対効果的には可能な限り新しく、出題傾向が似ている教材で勉強する勉強法はよかったのかなと思いました。試験の後にスコアレポートを受け取るのですが、４分野すべてについて、十分な知識を要する判定が出ていました。 もし取得を迷っている方の参考になれば嬉しいです。
eccube4のテーブル拡張、管理画面

#はじめまして
qiitaの投稿をはじめました。普段は関西のweb系の会社でインターンをしています。phpとjqueryを中心にバックエンド開発をしており、laravel, wordpress, eccubeを使って開発をしています。今日はeccubeのデータベースを拡張して商品やカテゴリの内容を追加(例えば各商品にpdfファイルを追加したいとか)にはどうすればよいかを書いていきたいと思います。最近けっこうeccube4をさわっているので当分それ系の記事が多くなるかもしてませんね。また、自分自身の備忘録もかねています。

#テーブルの拡張
eccube4 はご存知の方もおおいと思いますが、symfonyが使われていますので、symfonyに則ってやることを考えるのが一番いいと思います。

###traitを作成する
たとえば、Eccube/Entity/Product.php(dtb_product テーブル)を拡張したいとき、基本的には /app/Customize/Entityの配下にProductTrait.phpファイルを作成し、そこに追加したい項目を書くのがよいでしょう。

```php

<?php

namespace Customize\Entity;

use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation\EntityExtension;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @EntityExtension("Eccube\Entity\Product")
 */
trait ProductTrait
{

    /**
    * @ORM\Column(type="string", length=100, nullable=true)
    */
    private $paperPdf;

    /**
     * @return string|null
     */

     /**
     * @return \String
     */
    public function getPaperPdf()
    {
        return $this->paperPdf;
    }

    /**
     * @param string
     * @return Eccube\Entity\Product
     */
    public function setPaperPdf($paperPdf)
    {
        $this->paperPdf = $paperPdf;
        return $this;
    }
}

```

###作ったtraitファイルを元にテーブルを拡張する
ます、symfonyに、さきほど作ったProductTrait.phpを認識させることからはじめます。

```bash
$ php bin/console cache:clear --no-warmup
$ php bin/console eccube:generate:proxies
```

やっていることは上の行でキャッシュを消して、次でproxyを作成してsymfonyがこのファイルも認識して読み込むようにしています。キャッシュを消さないとほぼTraitを認識してくれません。

```bash
$ php bin/console doctrine:schema:update --dump-sql
$ php bin/console doctrine:schema:update --force
```

上の--dump-sqlのコマンドをうつとsql文が吐かれるので、ここで自分が意図したsqlになっているかどうかを確認してください。(ここではまだマイグレーションはされていない)  つぎの--forceでテーブルが拡張されます。

#管理画面で入力できるようにしたい！
テーブルを拡張したけど、管理画面から閲覧したり登録できてほしいというときは SymfonyのFormTypeを使います。formTypeは /src/Eccube/Form/Typeの中にたくさん入っています。管理画面のformtypeはその配下のAdminフォルダに入っています。

```php
<?php
use Symfony\Component\Form\Extension\Core\Type\TextType;

/**
 * 省略
 */
class ProductType extends AbstractType
{
    /**
     * @var CategoryRepository
     */
    protected $categoryRepository;

    

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            /**
            * 省略
            * 下を追加
     　　　　*/
            ->add('paper_pdf', TextType::class, [
                'required' => false,
            ])
            
          /**
            * 省略
     　　　　*/
     }
```

最後に管理画面のtwigファイルに {{ form.paper_pdf }}を追加する

```twig
{{ form_widget(form.paper_pdf) }}
{{ form_errors(form.paper_pdf) }}
```

#最後に
これを読んだほとんどの人が formtypeのpaper_pdfとentityの$paperPdfがどうやって関連づけられているのかと思うかもしれませんが、僕もまだあまりわかっていません。また追々勉強していきたいと思います。
OpenShift 4.4を構築してアプリを動かしてみる - VMWare ESXi 初期設定編 -

2021年1月現在、VMware ESXiのバージョンは7.0が登場していますが、稼働実績のある6.7で構築いたします。

## VMware ESXi 6.7の初期設定
rootユーザでESXiにログインし、永久利用ライセンスを設定します。

### 1.ログイン画面画面
WMWare ESXiの電源を投入し、VMWware ESXiを立ち上げます。
立ち上げが完了したら画面に表示されているアドレスにアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/95b2e5e8-dc5c-6b3f-6bc9-d4bb0732ea8b.png)

#### 
自己証明書を使用しているため、一部のブラウザでは以下のような画面が表示されますが正常です。
[詳細設定]を選択し、画面下部の「～にアクセスする（安全ではありません）」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/f655d9a1-6c9d-2aee-7276-c9a2e7bf117a.png)


### 2. rootでログイン
ユーザ名に「root」を設定し、インストール時に設定したrootのパスワードを入力してログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/3c143005-1af3-5c6f-f6cd-90de9da2c7cc.png)


### 3. 初回画面（品質向上の確認）
以下の画面が表示されます。品質向上の参加は自由に選択していただき、「OK」押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/562f6119-d5fe-0754-0832-fca6b425a6dc.png)


### 4. VMware ESXiの試用ライセンスによる永久利用化
左のナビゲーターのメニューから[ホスト] - [管理] を選択します。
管理の画面で、「ライセンス」のタブを開き、「ライセンスの割り当て」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/d67f53e6-67cf-d3b2-2dfb-c7fde6382d98.png)

### 5.ライセンスキーの入力
以下のサイトでユーザ登録後、発行されたライセンスキーを入力します。
https://my.vmware.com/ja/web/vmware/evalcenter?p=free-esxi6
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/5921934b-1a45-2602-942b-75283f628b82.png)

正常にライセンスが割り当てられると以下のような画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/1ab52f3f-b8d1-1a33-8f96-0e2f3a1ba1a1.png)
デブサミ2021登壇資料を公開しました！

リンクアンドモチベーション エンジニアチームです！

###先日開催された [Developers Summit（デブサミ）2021](https://event.shoeisha.jp/devsumi/20210218/)のスポンサーセッションにて開発責任者の柴戸が登壇しました。

本セッションでは、__[「ARR20億円を3年で達成したエンジニア組織が実現した3つのDeveloper eXperience～訪れる壁と突破方法～」](https://event.shoeisha.jp/devsumi/20210218/session/3068/?fbclid=IwAR2gFXUHEbC3XYos9T2ue171YMGEKg-Y4vvkcjRdXKssHkesgrU-xge62o8)__というテーマで、社内初のエンジニアとして入社した柴戸より、社員エンジニア1名から組織を拡大していくにあたり、ぶつかった壁やその乗り越え方を、挑戦と葛藤のリアルエピソードを交えながらお話させていただきました。

* __負債が生まれるメカニズムと上手な付き合い方__
* __ケイパビリティの指標化と優先順位のつけ方__
* __ビジネスサイドと協働するための秘訣...など__

皆さまの普段の業務のヒントにしていただければ幸いです！

# デブサミ2021 登壇資料
当日の資料をSpeaker Deckにて公開しておりますので、ぜひご覧くださいませ！

[__「ARR20億円を3年で達成したエンジニア組織が実現した3つのDeveloper eXperience
～訪れる壁と突破方法～」__](https://speakerdeck.com/lmi/arr20yi-yuan-wo3nian-deda-cheng-sitaenziniazu-zhi-gashi-xian-sitadeveloper-experience-3tufalsefang-rerubi-totu-po-fang-fa)
![safe_image.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325578/573b2a44-e808-f6aa-71cd-f0fc759cbf35.jpeg)

### 資料アジェンダ
* 私たちの紹介
* 開発組織はどんな状況だったか
* ぶつかった壁と突破方法について
* 勉強会・フォローアップイベントのご案内

---
私たちは、__独自の基幹技術「モチベーションエンジニアリング」を用いて組織課題の解決、企業で働く個人の成長支援__を行っています。技術やエンジニアリング論以外に、開発組織づくりのプロフェッショナルとして開発組織論の観点からも情報を発信して行きたいと思います！
【Python】読込むブック名とセルの値をパラメーターにする。④

pythonを使用してExcelファイルの操作を勉強しています。
本日の気づき(復習)は、パラメーターに関してです。
pythonでExcelを操作するため、openpyxlというパッケージを使用しています。

後々レイアウトを変更したり、プログラムで読み込むブック名やセルの値を変えてしまうかもしれない時の対処法です。
なんだかちょっと実戦形式っぽくてワクワクしてます。

今回はこちらのブック「日報.xlsx」を、使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927441/bbc57acb-3d52-bacc-6512-533a4f62f4bf.png)

# configparserモジュール
事前に設定ファイルにパラメーターを記述しておき、後から呼び出す方法です。

私はVScodeを使って作成しています。ファイルの文字コードは「UTF=8」です。

```ini:sample.ini
[DEFAULT]
filename = 日報.xlsx
cellno = I1
```

「DEFAULT」はパラメーターの大まかな分類を表します。(セクションと呼ぶそうです。)
上記のように「=」や「:」で区切った形式で記述します。
設定ファイルに記述できる形式など、詳しくは下記をご確認ください。
https://docs.python.org/ja/3/library/configparser.html#supported-ini-file-structure

先ずは configparser.ConfigParserオブジェクトを生成します。

```python
config = configparser.ConfigParser()
```

お次に、設定ファイルを読み込むためにConfigParser.readメソッドを使います。

```python
config.read(設定を記述したファイル名, encoding=使用する文字コード)
```

設定ファイル内の値は以下の書式で取得できます。

```python
config[セクション名][引数名]
```

これらを踏まえて

```python:config_arguments.py
import configparser
from openpyxl import load_workbook

config = configparser.ConfigParser()
config.read('sample.ini', encoding='utf-8')

default = config['DEFAULT']
filename = default['filename']
cellno = default['cellno']

wb = load_workbook(filename, read_only=True)
ws = wb.active

print(ws[cellno].value)
```

個人的にはinputの次にしっくりきました。
いちいちプログラム実行のたびに入力しなくても済むのが大きな理由です。
VSCode で EJS のフォーマットを正しく整形されるようにする

# 問題
Node.js のデザインテンプレートに EJS を使用しています。
ヘッダーなどを全画面で共通部品化したいので、こんな感じのファイルを書いています。

```javascript:index.ejs
<% function scripts (buf) { %>
    <script src="test.js" />
<% }; %>

<% function content(buf) { %>
    <h1>コンテンツタイトル</h1>
    <p>本文</p>
<% }; %>

<% include ../layout/layout %>
```

*※共通部品化をする方法については[**こちら**](https://qiita.com/fnobi/items/6225673eb52c698844eb)を参考にさせていただきました。*
　*大変参考になりました。ありがとうございます。*

保存時に自動フォーマットをする設定にしているのですが、こんな感じで崩れて整形されてしまいます。

```javascript:index.ejs
<% function scripts (buf) { %>
    <script src="test.js" />
    <% }; %>

        <% function content(buf) { %>
            <h1>コンテンツタイトル</h1>
            <p>本文</p>
            <% }; %>

                <% include ../layout/layout %>
```

どこでJavaScriptのブロックが閉じているかを判別できないんですね。困った。

# ネット上の回答
対処法を検索したところ、「ejsファイルをhtmlとしてフォーマットさせる」という記述が見つかりました。
しかし、残念ながら私の環境では解決できませんでした。

# 解決方法
下記のように、閉じタグのようなもの「**</%>**」を挟むことで綺麗に整形されるようになりました。

```javascript:index.ejs
<% function scripts (buf) { %>
    <script src="test.js" />
</%>
<% }; %></%>

<% function content(buf) { %>
    <h1>コンテンツタイトル</h1>
    <p>本文</p>
</%>
<% }; %></%>

<% include ../layout/layout %></%>
```

# 問題点
下記の問題が残っています。

* コード整形のためだけのコードを記載しないといけない
  - 短いとはいえ、JavaScriptの感覚でコードを読んでいると少し気になります。
* コンパイルされたHTMLに不要なコードが生成されてしまう
  - 下記画像のように、**<!--%-->**という行が生成されてしまいます。実行上影響はないですが気になります。
![html実行結果.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471221/4a646c1e-0432-46db-5ab8-8f416ecddb05.png)

# 最後に
自動フォーマットは手放せないため、この方法を採用することにします。
もし良い方法をご存じの方がいらっしゃったら教えて下さい。

# 参考リンク（ありがとうございました）
[ejsでextendっぽいことをする方法](https://qiita.com/fnobi/items/6225673eb52c698844eb)