OmniAICreator/Qiita-1.07M huggingface dataset:
【個人用メモ】Python,Django

#Memo


##仮想環境立ち上げ
```
$pip3 install pipenv
$pipenv shell
```
##仮想環境にdjangoインストール
```
$pipenv install django==バージョン
```

##プロジェクト作成
```
$django-admin startproject プロジェクト名
```
プロジェクトを作成するとプロジェクト名と同じディレクトリが作成される。
ここにプロジェクト全体で使いファイルが保存される。

 \_\_inti\_\_.py
　>Djangoプロジェクトを実行する時の初期化処理を行うスクリプトファイル。
asgi.py
　>ASGIという非同期Webアプリケーションを作成するためのプログラム
settings.py
　>プロジェクトの設定情報を記述ファイル,アプリケーション作成時にINSTALLED_APPS[]にアプリケーション名を追加する
urls.py
　>プロジェクトでURLを管理
wsgi.py
　>WSGIという一般的なwebアプリケーションのプログラム

##アプリケーション作成
```
$python manage.py startapp アプリケーション名
```

==アプリケーションフォルダ作成時の構成==
migrationsフォルダ
　>データベース関係の機能のファイルがまとめられる
\_\_inti\_\_.py
　>アプリケーションの初期化処理のためのファイル
admin.py
　>管理者ツールのためのファイル
apps.py
　>アプリケーション本体の処理をまとめる
models.py
　>モデルに関する処理
tests.py
　>プログラムのテストに関するもの
views.py
　>画面表示に関するもの

==個別に作成項目==
urls.py
　>アプリケーションごとにルーティングを設定する必要があるため
templatesフォルダ
　>テンプレート機能を利用(templatesフォルダ内にアプリケーション名のフォルダを作成する。settings.pyに追記したアプリケーションとの連携,render関数でレンダリングしにいく)
staticフォルダ
　>静的ファイルの利用,staticフォルダ内にアプリケーション名のフォルダを作成する,staticテンプレートタグを使用することで自動的にstaticフォルダ内をみてくれる
##webサーバー起動
```
$python manage.py runserver
```

##マイグレーションファイル作成
```
$python manage.py makemigrations アプリケーション名
```

##マイグレーション実行
```
$python manage.py migrate
```
##既存のDBに接続する
[・Django既存DBへの接続参考URL](https://qiita.com/okoppe8/items/82a9cc2bb99de05f8dbb)

今回ははheroku環境にあるClearDB(mysql)に接続する必要があったのでそれを記録。

```settings.py
DATABASES = {
    'default': {
        # 既存コード
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': BASE_DIR / 'db.sqlite3',

        # herokuDB接続情報
        'ENGINE': 'django.db.backends.mysql',
        'HOST': os.getenv('DB_HOSTNAME'),
        'NAME': os.getenv('DB_NAME'),
        'USER': os.getenv('DB_USERNAME'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
    }
}
```
■接続テスト
下記コマンドで設定ファイルのDBに接続できればOK

```
$python manage.py dbshell
```
■herokuDBへの接続情報の確認
herokuにログイン後、下記コマンドを実行
　環境変数を一覧することができるのでCLEARDB_DATABASE_URLにあるのがDBへの接続情報

```
$heroku config --app アプリケーション名
```
##既存DBからのモデル作成(自動生成)
接続テストが完了したら実際にdjangoで使えるようにモデルを作成します。

```
$python manage.py inspectdb
```
こちらのコマンドを打ち込むとDBの情報をもとに
モデルのコードが返ってくる。(この際には特に保存はされません。)

返ってきたモデルのコードが問題なさそうならコピーペーストでモデルに貼り付け。
もしくは下記コマンドを打つことでモデルファイルが生成される。

```
$python manage.py inspectdb >> models.pyへのパス/models.py
```
VSCode 多段SSH Vagrant内のDocker Containerを編集

#sshconfig作成
C:\Users\ユーザーネーム\.sshにconfigファイル作って下記を記述

```
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile D:/vagrant/centos7/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL
```

#powershellで下記実行

```
$ scp .vagrant/machines/default/virtualbox/private_key default:/home/vagrant/.ssh/
```

#vagrantへログイン後、下記実行

```
$ vagrant ssh
# private_key の実行権限を変更
$ chmod 600 ~/.ssh/private_key
```

#秘密鍵の転送
```
# 注意 `vagrant up` したディレクトリで実行する
> scp .vagrant/machines/default/virtualbox/private_key vagrant-os:/home/vagrant/.ssh/

# Guest OS に SSH接続
> vagrant ssh

# private_key の実行権限を変更（Guest OS 内）
$ chmod 600 ~/.ssh/private_key
```
#Docker Container の起動

```
FROM ruby:2.5.1

# リポジトリを更新し依存モジュールをインストール
RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       nodejs

# ルート直下にwebappという名前で作業ディレクトリを作成（コンテナ内のアプリケーションディレクトリ）
RUN mkdir /webapp
WORKDIR /webapp

# ホストのGemfileとGemfile.lockをコンテナにコピー
ADD Gemfile /webapp/Gemfile
ADD Gemfile.lock /webapp/Gemfile.lock

# bundle installの実行
RUN bundle install

# ホストのアプリケーションディレクトリ内をすべてコンテナにコピー
ADD . /webapp

# puma.sockを配置するディレクトリを作成
RUN mkdir -p tmp/sockets


# ここから最後までがopenssh設定
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd

# /etc/ssh/sshd_config の設定書き換え
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

# 公開鍵をコピー
COPY authorized_keys /root/authorized_keys

EXPOSE 22

# Activate authorized_keys & Boot sshd
CMD mkdir ~/.ssh && \
    mv ~/authorized_keys ~/.ssh/authorized_keys && \
    chmod 0600 ~/.ssh/authorized_keys &&  \
    # 最後に ssh を起動
    /usr/sbin/sshd -D

# 公開鍵をコピー
$ cp ~/.ssh/authorized_keys .

# build
$ docker build ./ -t example

# Docker Container を起動
# Port:10000 を Port:22 に転送
$ docker run -d -p 10000:22 example

# Docker Container に SSH 接続
$ ssh -o 'StrictHostKeyChecking no' root@127.0.0.1 -p 10000 -i ~/.ssh/private_key
```
#powershellで確認

```
$ ssh -o 'StrictHostKeyChecking no' docker-os
```

#.ssh/configファイル 編集
```
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile D:/vagrant/centos7/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

# 下記追記
Host docker-os
Hostname 127.0.0.1
User root
Port 10000
ProxyCommand C:\Windows\System32\OpenSSH\ssh.exe -W %h:%p default
IdentityFile D:/vagrant/centos7/.vagrant/machines/default/virtualbox/private_key
```

VScodeを起動後
拡張機能からRemote Developmentインストール
リモートエクスプローラーでsshTargetsから編集
Thor と Rubocop



# 目次

今回はThorとRubocopなるものについて触れていく

-   [Thor](#thor)
-   [Rubocop](#rubocop)


# Thor

以前Rakeを使用して見たが，似たようなものとしてThorというものが存在するようだ．これはコマンドラインを作るgemだ．

まずは初期では入っていないので

    sudo gem install thor

でインストール．

では実際に使用してみる．

    $ bundle gem hello_rudy -b

こうすることで作業しているディレクトリにhello\_rudyというものが作成される．その中に入る．

    $ cd hello_rudy
    $ ls exe/hello_rudy

このままだとexe/hello\_rudyに権限がないので与えておく．

    $ chmod a+x exe/hello_rudy

次に「hello\_rudy.gemspec」というファイルがあるのでそに中身を

    require_relative 'lib/hello_rudy/version'
    
    Gem::Specification.new do |spec|
      spec.name          = "hello_rudy"
      spec.version       = HelloRudy::VERSION
      spec.authors       = ["[yours]"]
      spec.email         = ["[yours]"]
    
      spec.summary       = %q{hello rudy}
      spec.description   = %q{hello rudy}
      spec.homepage      = "https://hoge.hoge"
      spec.license       = "MIT"
      spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
    
    #  spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
    
      spec.metadata["homepage_uri"] = spec.homepage
    #  spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
    #  spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
    
    # Specify which files should be added to the gem when it is released.
    # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
      spec.files         = Dir.chdir(File.expand_path('..', __FILE__)) do
        `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
      end                                                                           
      spec.bindir        = "exe"
      spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
      spec.require_paths = ["lib"]
    
      spec.add_runtime_dependency('thor')
    end 

と書き換える．

その後，#+begin\_example$ sudo exec exe/hello\_rudy hello rudy\#+end\_example

を実行．おそらく動く．動かなかったとしても僕は知りません．直してください．

そして，libの中にあるhello\_rudy.rbに以下のコードを書く．

```ruby:hello_rudy.rb
require "thor"
require "hello_rudy/version"

#module HelloRudy
#class Error < StandardError; end

class HelloRudyCLI < Thor
  desc "hello NAME", "say hello to NAME"
  def hello(name)
    puts "Hello " + name
  end
end

HelloRudyCLI.start(ARGV)
```

また，「lib/hello\_rudy/version.rb」の中身を，

```ruby:version.rb
class HelloRudy
  VERSION = "0.1.0"
end
```

    $ bundle update
    $ bundle install
    $ bundle exec exe/hello_rudy
    Commands:
      hello_rudy hello NAME      # say hello to NAME
      hello_rudy help [COMMAND]  # Describe available commands or one specific co...
    $ bundle exec exe/hello_rudy hello rudy
    Hello Rudy

これで動くはず．

[目次へ](#目次)


# Rubocop

これはコードをフォーマットしてくれるツールだ．コードが複雑になるとあまりよろしくないので警告を出したりしてくれる．

    $ sudo gem install rubocop

でインストール後，

    rubocop --auto-correct ファイル名

とすることで使用できる．


# まとめ

今回はThorとRubocopを導入した．


# 参考



------
 - **source** ~/prog/github/grad_members_20f/members/miyanagi/post/thor.org
Excelで湯婆婆を実装してみる

「[湯婆婆 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/yubaba)」の 20 日目の記事です。

ざっと検索してみた感じ Excel Formula で(≠VBA)湯婆婆している人がいないようなので,簡単にですがやってみようと思います。

そういやぁ LAMBDA が入ったことで素直に(あー, つまり循環参照とかを見なかったことにして, ということ)「順次(関数の適応順による)」「分岐(`IF`系関数による)」「反復(再帰関数による)」ができるようになって Excel Formula もチューリング完全になったんですよねぇ。 これって実質宣言型プログラミングと言えるのではないでしょうか? Competitive Excel Formula が始まる日も近い(来ない)。

## シートの作成

上の方で偉そうに VBA ちゃうでとか言っておいてなんなんですが, ブックをそのままアップロードするのもアレなんで, シートを作る部分だけ VBA で書きました(数式入れたり書式設定したりしてるだけです)。 一度実行するだけなんで xlsx 形式での保存で OK です。

```vb
Option Explicit

Public Sub MakeYubaba()
    Cells.Delete

    Range("C3").Formula = "= IF(ISBLANK(C12),""契約書だよ。C12に名前を書きな。"",""フン。""&C12&""というのかい。贅沢な名だねぇ。"")"
    Range("C4").Formula = "= IF(ISBLANK(C12),"""",""今からお前の名前は""&C13&""だ。いいかい、""&C13&""だよ。"")"
    Range("C5").Formula = "= IF(ISBLANK(C12),"""",""分かったら返事をするんだ、""&C13&""!!"")"
    Range("C13").Formula = "= IF(ISBLANK(C12),"""",MID(C12,RANDBETWEEN(1,LEN(C12)),1))"

    Dim fc As FormatCondition

    Set fc = Range("C12").FormatConditions.Add(xlExpression, xlEqual, "= ISBLANK(C12)")
    With fc
        .Borders(xlEdgeLeft).Color = RGB(0, 0, 0)
        .Borders(xlEdgeTop).Color = RGB(0, 0, 0)
        .Borders(xlEdgeRight).Color = RGB(0, 0, 0)
        .Borders(xlEdgeBottom).Color = RGB(0, 0, 0)
    End With
    Set fc = Range("C12").FormatConditions.Add(xlExpression, xlEqual, "= NOT(ISBLANK(C12))")
    fc.Font.Color = RGB(255, 255, 255)

    Set fc = Range("C13").FormatConditions.Add(xlExpression, xlEqual, "= NOT(ISBLANK(C12))")
    With fc
        .Borders(xlEdgeLeft).Color = RGB(0, 0, 0)
        .Borders(xlEdgeTop).Color = RGB(0, 0, 0)
        .Borders(xlEdgeRight).Color = RGB(0, 0, 0)
        .Borders(xlEdgeBottom).Color = RGB(0, 0, 0)
    End With
End Sub
```

これを白紙のシートをアクティブにして実行すれば OK です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241027/4eb6f439-2f3b-7cf7-2bd0-21c3e73f5161.png)

随分味気ないシートですね。 まあ適当に湯婆婆の画像でも貼ってお楽しみください。

## 処理

各数式を見ていただいて分かるとおり, `C12`セルに値が入っているかどうかで分岐しています。

`C12`に値が入っている場合, `C12`セル自体の枠が消滅し, また文字色も白になるため見えなくなります。

代わりに, `C13`は`C12`から乱数で一文字選び, それを表示します。 また, 枠を表示させます。 これによって「名前を奪う」を表現しています。

`C3:C5`のメッセージはやはり`C12`の値の有無によって表示を変えます。 もとの名前は`C12`から, 奪ったあとの名前は`C13`から取得しています。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241027/c325f6b9-046e-de26-1e39-b75805ab7709.png)

## クラッシュ

[湯婆婆の仕様](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2#%E3%81%8A%E3%81%BE%E3%81%91)(?)として「空文字列を入れたらクラッシュ」があるはずですが, `C12`に入力されていなければ動かないならこれができないのでは? とお考えの方も多いかと思います。

大丈夫です。 `ISBLANK(range)`は`range = ""`と違い, ほんとうの意味で「セルが値を持たない」かどうかを判定します。 つまり, `C12`に式`= ""`を与えればちゃんとクラッシュします(あるいはそれを値として貼り付けでもいけます)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241027/e553f821-9054-846d-905b-2b64212fc946.png)

成し遂げたぜ。

## 裏面

[裏 20 日目](https://qiita.com/BlueRayi/items/18d0699c2c3a74466e60)もございますのでよろしかったらどうぞ。
Siv3Dで画像をステンドグラス風に加工する

この記事はhttps://qiita.com/advent-calendar/2020/siv3d 20日目の記事です。

# 概要
クリスマス前なので、画像をステンドグラス風に加工するサンプルを作りました。

# 結果
入力画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151080/e68179c9-c8b5-d0c7-b396-ef719c19de71.png)

出力画像
![スクリーンショット (77).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151080/397bec10-f444-fa48-acf7-0c407ac1c8e5.png)

# ソースコード
```Main.cpp
# include <Siv3D.hpp>

void Main()
{
    Window::Resize(1280, 960);
    Scene::SetBackground(ColorF(0.99));
    
    //点群の生成
    double r = 10.0;
    PoissonDisk2D pd(Scene::Size(), r);

    //もとになる画像を用意
    Image image(U"image.png");
    image.resize(1280, 960);

    //ボロノイ図の生成
    const Rect rect(0, 0, Scene::Size());
    Subdivision2D subdiv(rect);
    Array<VoronoiFacet> facets;
    Array<Polygon> facetPolygons;
    
    for (const auto& point : pd.getPoints()) {
        if (rect.contains(point))
        {
            subdiv.addPoint(point);
        }
    }

    subdiv.calculateVoronoiFacets(facets);
    
    //ポリゴンを加工
    facetPolygons = facets.map([rect = rect.asPolygon()](const VoronoiFacet& f)
    {
        return Geometry2D::And(Polygon(f.points), rect).front();
    });



    while (System::Update())
    {
        for (auto [i, facetPolygon] : Indexed(facetPolygons))
        {
            const Vec2 pos = facets[i].center;

            facetPolygon.draw(image[static_cast<int32>(pos.y)][static_cast<int32>(pos.x)]).drawFrame(3, ColorF(0.25));
        }
    }
}
```
nuxt.jsで共通関数を作る

ページとかコンポーネントで同じ関数は書きたくない共通関数でまとめたい。。。
と言うことで、

# 共通関数を作る

pluginsディレクトリがあるのでここに`common.js`を作る。

```js:plugins/common.js
export default {
  outputLog(message) {
    console.log(`LOG: ${message}`)
  }
}
```

# 共通関数を登録する

nuxt.config.jsの`plugins`に`common.js`を設定する。

```js:nuxt.config.js
export default {
  plugins: ['@/plugins/common.js']
}
```

# 共通関数を使う

`common.js`をインポートして共通関数を呼び出す。

```vue:pages/index.vue
<template>
  <div>
  </div>
</template>

<script>
import Common from '@/plugins/common'

export default {
  created {
    Common.outputLog('hello!')
  }
}
</script>
```

# インポートをしないで使う

アプリ全体で使うしインポートがめんどくさいと思ったら

## 作る時

共通関数を`inject`する。

```js:plugins/common.js
export default ({ app }, inject) => {
  inject('outputLog', (message) => {
    console.log(`LOG: ${message}`)
  })
}
```

## 使う時

共通関数の前に`$`を付ける。

```vue:pages/index.vue
<template>
  <div>
  </div>
</template>

<script>
export default {
  created {
    this.$outputLog('hello!')
  }
}
</script>
```
SceneBuilder英語版を導入しVSCodeでFXMLをSceneBuilderで開く

# やること
以前VSCodeでJavaFXを開発する環境を整えました。
その時の記事はこちらです。
[JavaFX15を導入してVSCodeでGUI開発を行う](https://qiita.com/kazushi47/items/66fbd4a6b3db8e7c2851)

今回はその続きということで、SceneBuilderを導入してみたいと思います。

> **SceneBuilderとは**
> JavaFXでUIのデザインを行う際にあると便利なデザインツール。

それだけではなく、今回はVSCode上でFXMLファイルから直接SceneBuilderを開く設定もやっていきます。

ではやっていきましょう！

# SceneBuilderの導入
まずはSceneBuilderの導入からです。
## SceneBuilderのインストール
まずSceneBuilderのインストーラーを入手します。
ダウンロードはこちらから行うことができます。
https://gluonhq.com/products/scene-builder/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961112/c8db409a-bad8-16d9-2ea5-ea13922c8188.png)
Scene Builder for Java 11のWindowsInstallerをダウンロードしました。

ダウンロードが終わったらインストーラーを起動してインストールをしてください。

## 文字化けしているので、英語版にする設定
SceneBuilderと言えばこの文字化け問題です。
もし起動時に文字化けしていたら、それは日本語版の設定ファイルが破損しているからです。

> この破損ファイルを修正して日本語版にする方法もあるみたいですが、
> わざわざ日本語にするのも面倒なので今回はしません。

英語版にするには簡単なのでその設定をやりましょう。

SceneBuilderインストール先の中に`app\SceneBuilder.cfg`というファイルがあるはずです。
筆者の場合は次のパスにありました。
`C:\Program Files\SceneBuilder\app\SceneBuilder.cfg`

こちらのファイルをメモ帳などで開いてください。

開いたら次の行を追加編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961112/92cd790e-2474-ba38-2803-c7f97dc1ff74.png)

```text:SceneBuilder.cfg
-Duser.language=en
```

これで英語版のSceneBuilderが使えるようになりました！

# VSCodeでFXMLをSceneBuilderで開く設定
続いてVSCodeの設定に入ります。

まずは`FXML Viewer`という拡張機能をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961112/72cc9de8-d168-4801-bd00-955f6809064f.png)
このように「fxml」などと検索すると出てくる`FXML Viewer`をインストールしてください。

次に拡張機能の設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961112/c860f39e-6379-437d-cde8-ee35ce0d34ff.png)
拡張機能の設定を開くにはこのように⚙→「Extension Settings」を選択して下さい。

すると次の画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961112/53b9111b-674e-d037-cfc0-e61ee478bd1e.png)
このようにSceneBuilderの.exeがあるフルパスを入力します。

これでVSCodeの設定は完了です！

# VSCodeでFXMLを開いてみる
最後に実際に開けるか試してみましょう。

対象のFXMLファイルを**右クリック**し、`Open FXML`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961112/f37eac24-3270-b79f-32ab-92a068e006fa.png)

するとSceneBuilderが立ち上がりFXMLファイルを開くことができました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961112/8852f892-a901-c3af-368e-bf3b73c84526.png)
AzureFunctionsのTypeScript関数のテストでcontextオブジェクトをモックしたい

# はじめに
株式会社センシンロボティクスの @s-okamura です。社内では主にフロントエンド／バックエンド実装およびインフラ構築を担当しています。今回はAzureFunctionsのTypeScript関数のユニットテストを作成する場合に、contextをモックする方法を紹介します。

# 概要
AzureFunctionsのトリガー関数は第1引数として `context` オブジェクトが渡され、バインディングデータの受け渡しやログ出力、レスポンスなどに使用されます。jestのユニットテストを作成する際、この `context` オブジェクトをモックしたいケースがあり、その方法を調査しました。

# 関数例
何か処理をして正常終了するような、非常にシンプルなQueueトリガーな関数の例です。

``` typescript
import {AzureFunction, Context} from '@azure/functions';

const queueTrigger: AzureFunction = async function (context: Context, queueMessage: string): Promise<void> {
  // do something 
  context.res = {
    status: 200
  }
};

export default queueTrigger;
```

# 方法
こちらの [jest-mock-extended](https://github.com/marchaos/jest-mock-extended) を利用します。ドキュメントに従いインストールすると、`const context = mock<Context>()` とすることでcontextオブジェクトをモックすることができます。

``` typescript
import {mock} from 'jest-mock-extended';
import {Context} from '@azure/functions';
import queueTrigger from 'index';

test('context.res.statusが200であること', async () => {
  // Contextオブジェクトをモックする
  const context = mock<Context>();
  await queueTrigger(context, 'test-message');
  expect(context.res.status).toEqual(200);
});
```
Amazon EC2 Mac インスタンスのシステムボリュームをEBSボリュームサイズまで拡張する

# はじめに

AWS re:Invent 2020 で待望のEC2 Macインスタンスが発表されましたね！
cf. https://aws.amazon.com/jp/about-aws/whats-new/2020/12/aws-announces-mac-instances-amazon-ec2/


早速使用感を確かめたく使ってみたのですが、どうもアタッチしたEBSボリュームのサイズに関わらず初期状態のシステムボリュームが認識するボリュームサイズは 32GB になっているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137950/280bb451-3466-3c3b-c189-5a2208d57c62.png)

これではXcodeのインストールすらできません！！
ということで、この記事ではシステムボリュームのサイズをアタッチしたEBSボリュームのサイズまで拡張する方法をご紹介します。

ここ、GUIのディスクユーティリティだと何故かうまくいかなくて、地味にハマりました。。

# ブートボリュームコンテナをリサイズする

それでは、早速リサイズしていきましょう。
ここでは起動したMacインスタンスへの接続方法などは割愛します。

ターミナルに接続して以下のコマンドを叩くことでブートボリュームコンテナのIDを取得します。

```
$ diskutil list physical external | awk '/Apple_APFS/ {print $7}'
disk1s2
```

次に以下のコマンドを叩いてAPFSコンテナをリサイズします。
サイズに 0 を指定することでEBSボリュームいっぱいまでリサイズします。

```
$ diskutil apfs resizeContainer disk1s2 0
```

もし、上記のコマンドがエラーになったら下記を叩いてから実行すると上手くいくかもしれません。

```
$ diskutil repairDisk disk2  
```

リサイズに成功すると、こんな感じで即座に認識されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137950/689f2527-0fcd-b8f8-43d4-be837f44fd4e.png)

# おわり

これでXcodeをインストールして開発・ビルドができますね！
[Android]Firebase Storage + Glide

Androidで`DataBinding`を使って`Firebase Storage`から画像を読み込む方法です。
`Glide`も一緒に使います。Kotlinで書いています。

## セットアップ

FirebaseとDataBindingのセットアップは割愛します。

### Glide

KotlinでGlideを使う場合は、

```app/build.gradle
dependencies {
  implementation 'com.github.bumptech.glide:glide:4.11.0'
  kapt 'com.github.bumptech.glide:compiler:4.11.0'
}
```
→本家のgithubでは２つ目は`annotationProcessor`でしたが、Kotlinでは`kapt`を使います。

次に、`AppGlideModule`を継承したクラスを作成します。

```MyAppGlideModule.kt

@GlideModule
class MyAppGlideModule : AppGlideModule() {

}
```

これで、自動的に`GlideApp`が使えるようになります。

### Firebase Storage UI

通常のFirebaseに加え、[Firebase UI](https://github.com/firebase/FirebaseUI-Android)も追加します。

```app/build.gradle
dependencies {
    implementation 'com.firebaseui:firebase-ui-storage:7.1.1'
}
```

## GlideでFirebase Storageの読み込み

Glideそのままでは、Firebase Storageの読み込みに対応していないので、StorageReferenceを読み込めるようにします。

```app/build.gradle
@GlideModule
class MyAppGlideModule : AppGlideModule() {

    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        registry.append(
            StorageReference::class.java, InputStream::class.java,
            FirebaseImageLoader.Factory()
        )
    }

}
```

## GlideでImageViewに画像を読み込み

データモデルは

```Image.kt
data class Image(val path: String)
```

`path`はFirebase Storageのパスとします。

DataBindingを使い、GlideからImageViewで読み込むためには、

```ImageBindingAdapter.kt
object ImageBindingAdapter {
    @JvmStatic
    @BindingAdapter("imageURL")
    fun ImageView.imageURI(string: String?) {
        if (string == null || string.isEmpty()) { return }
        val reference = FirebaseStorage.getInstance().getReference(string)
        GlideApp.with(this.context)
            .load(reference)
            .into(this)
    }
}
```

`object`で定義し、`@JvmStatic`と`@BindingAdapter("imageURL")`アノーテーションを付けます。

次に、xmlレイアウトファイルで以下のように記述します

```layout.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="image" type="com.example.Image" />
    </data>
    .....
      <ImageView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          imageURL="@{image.path}"
          />
    .....
</layout>
```

これで、Firebase Storageから画像をImageViewに読み込みができます。
※画像へのアクセス権がある前提です。

## 参考

https://torajirousan.hatenadiary.jp/entry/2020/05/19/101907
https://github.com/bumptech/glide
https://github.com/firebase/FirebaseUI-Android
https://allyourbase.hatenablog.com/entry/glide-binding-adapter
【Laravel 6.*】テーブルでカラムの変更方法

#【Laravel 6.*】テーブルでカラムの変更方法

###使用環境
* windows10
* XAMPP 7.3.18
* Laravel 6.*

##背景
テーブルのカラムを変更しようと[公式ドキュメント ReadDouble](https://readouble.com/laravel/6.x/ja/migrations.html)に従い```composer
　require doctrine/dbal```を実施。しかし、ドライバーがないとエラーが発生。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/fda96666-aa6e-e270-b7b1-0cd9310c6570.png)

**エラー内容**

```
   Symfony\Component\Debug\Exception\FatalThrowableError  : Class 'Doctrine\DBAL\Driver\PDOMySql\Driver' not found

  at C:\laravel\taion\vendor\laravel\framework\src\Illuminate\Database\MySqlConnection.php:64
    60|      * @return \Doctrine\DBAL\Driver\PDOMySql\Driver
    61|      */
    62|     protected function getDoctrineDriver()
    63|     {
  > 64|         return new DoctrineDriver;
    65|     }
    66| }
    67|

  Exception trace:

  1   Illuminate\Database\MySqlConnection::getDoctrineDriver()
      C:\laravel\taion\vendor\laravel\framework\src\Illuminate\Database\Connection.php:892

  2   Illuminate\Database\Connection::getDoctrineSchemaManager()
      C:\laravel\taion\vendor\laravel\framework\src\Illuminate\Database\Schema\Grammars\ChangeColumn.php:37


```

##原因
どうやら、Laravel 6.* ではdoctrine/dbalの対応バージョンが3.* ではなく2.* らしい。

##対処方法
バージョン指定し古いバージョンをインストール。
```composer require "doctrine/dbal:2.*"```を実施。
実施する場所はLaravelプロジェクトのフォルダ内でOK。
バージョンを下げた結果、テーブルのカラム変更ができた。
グループワークで気をつけたい８つのこと

グループワークを開催する際に、事前に参加者に共有しておきたいポイントを備忘録として残します。

## 1. 注意を払って聴く

いわゆる **傾聴** の意識です。
他の方が話しているときに、他のコトに気を取られないように集中します。
『うなずき』などで相槌を取ると、話している側は聴いてもらえていると認識し、緊張が和らぎます。

## 2. 個人情報は持ち出さない

安心して話していただくために、最低限のマナーとして、情報に配慮をします。
自分がやられて嫌なコトは相手にもしない。

## 3. 相手の意見を一方的に判断したり、決めつけたりしない

人それぞれ、価値観は違います。自分の意見を持つことは大事ですが、一方的なコミュニケーションは控えましょう。
どうしても納得がいかないときは、建設的にディスカッションできるよう、別の場を設けると良いかもしれません。
このとき、できるだけ第三者を交えて場を整えると客観的な視点で会話できます。

## 4. 自分自身を決めつけない

『自分はXXXだから、発言しても仕方ないな・・・』という考えでアウトプットを阻害しないようにしましょう。
何かを決めるのは、アウトプットしてから、インプットとアウトプットを繰り返しながら、自分の可能性を拡げましょう。

## 5. 率直に言う（フィードバック）

同じ目的で集まっている仲間に自分の気持を素直に伝えてみましょう。

## 6. 自己開示は自分で決める

どこまで伝えるかは自分で決めましょう。良くも悪くも、自分で決めたことには自分で対処できます。
他人に依存せず、自分で決めることを続けると、自信につながります。

## 7. 傍観者にならないで、できるだけグループに参加する

第三者ではなく、当事者として参加しましょう。タイミングを図れないときは、司会者に相談してみましょう。
メモを取るのも大事かもしれませんが、グループに伝わるようにリアクションしてみましょう。

## 8. グループの時間を独占しない

自分ばかりアウトプットし続けないこと。グループワークの時間はグループ全員の貴重な時間です。
不安なときは、グループワークが始まるときに、司会者に持ち時間を確認しましょう。

## まとめ

場の雰囲気を客観的な目線で俯瞰することが大事です。
第三者の目で自分を見ているような感覚を目指せられれば良いなと思い、備忘録にしました。
Windows10でスリープ後、画面が真っ黒になり操作不能になることへの対応

# スリープ後、画面が真っ黒になって何も映らない

　私はLenovoのノートパソコンをつかってます。
　あるとき、少しの間放置してスリープ状態になってたのを復帰させようとするも、真っ黒のまま画面が映りませんでした。
ファンは回っているし、電源のボタンのランプは点灯している。

　いろいろネットで探すと、30日スタンバイとか記事があったけど、結局、以下の方法でとりあえず対応できました。

# 電源オプションの「カバーを閉じたときの動作」を「スリープ状態」に変更

　私の場合の原因は、電源オプションの「カバーを閉じたときの動作」が「何もしない」になっていました。
　これを「スリープ状態」に変更しました。

　これで問題は解決しました。

　同じ原因で困っている人の参考になればと思います。
 別の原因があるかもしれないですが、一応参考程度に。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/5f2c805e-9452-af5e-a014-a1f9b2fa7940.png)
障害発生時に見るべきサイト

# はじめに

この記事はシスコの同志による Advent Calendar の一部として投稿しています
- 2017年版: https://qiita.com/advent-calendar/2017/cisco
- 2018年版: https://qiita.com/advent-calendar/2018/cisco
- 2019年版: https://qiita.com/advent-calendar/2019/cisco
- 2020年版: https://qiita.com/advent-calendar/2020/cisco (今ここ)



# 自己紹介
勝男です。
2020年はたくさん障害があってたくさんのサービスが落ちることがありました。
特に9/25~10月の頭は

そこで障害発生時にどこで発生してどれぐらいの影響範囲があるのか？
エンジニアとしては知っておきたいですね。
そこで今回は参考になりそうなURLと見方を解説したいと思います

#ThousandEyes

![スクリーンショット 2020-11-25 16.17.59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314181/e80a251a-9399-3c85-3b89-edc5505dfa9c.jpeg)


　ThousandEyesが昨年発表した「Internet Insights（インターネット・インサイト）」により
上記の画像のように世界中のどこのASで障害を起きているか？を検知できます
URL→https://www.thousandeyes.com/outages/


これらはThousandEyes社が世界中に置いてあるエージェントを経由して監視しているので他のサイトより信頼性はあると思います。
今障害情報と検索すれば出てくるのはhttps://downdetector.jp/ですが
DowndetectorはSNSの情報を集めているサイトですので信頼性という意味では?が出ます。

#その他
さてこれだけでは内容が薄いのでThousandEyesでこんなことできるよって紹介です

ThousandEyesでテストを作成すると任意のホームページにping等を送信することができて
ページが落ちてないか？の確認をすることができます。
次の画像では自分のGithubのページに対して行ってます。

![スクリーンショット 2020-11-23 11.20.55.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314181/b1ecdfe9-c420-1847-2be6-27c70049a2f9.jpeg)

監視をするツールとしてThousandEyes便利そうですね
何よりWebページが軽いのでストレスもないのでとても良い監視ツールだと思っています。

障害発生時にどこのソースを確認するか？もエンジニアとして大事だと思います。
その一つの参考になれば良いと考えています。
アドベントカレンダー18日目：SREを読んでみた「Googleにおける自動化の進化」編④

今回は、Googleの自動化の実例を扱います。
また、その解決にどのような取り組みをしていったのかについても見ていきます。

## Googleの自動化の歴史②
クラスタインストラクチャSREチームは、数か月ごとに採用を行っている状況がありました。
新人がクラスタ内部にサービスを立ち上げることは、サービス内部に触れることになるため、自然とトレーニングになると思われていました。
クラスタを使えるようにするためのステップは、以下のようなステップで行われていました。

> **1. データセンターののビルディングに、電源と冷却機構を整える。**
**2. コアスイッチをインストールして設定し、バックボーンに接続する。**
**3. 最初のサーバーラックをいくつかインストールする。**
**4. DNSやインストールなどの基本サービスを設定し、続いてロックサービス、ストレージ、コンピューティングの設定をする。**
**5. 残りのマシンのラックを設置する。**
**6. ユーザーが使うサービスリソースを割り当て、ユーザーのチームがサービスをセットアップできるようにする。**<sup>1</sup>

当時のストレージやコンピュートのサブシステムは、開発が行われており、毎週のように新しいフラグやコンポーネント、最適化が行われていました。
サービスの中には100以上のさまざまなコンポーネントサブシステムを持つものがあり、それぞれが網目のように依存関係を持っていました。
1つのサブシステムの設定に失敗したりすれば、それはサービス障害を仕込むようなものでした。
初期の自動化はクラスタの素早い提供に焦点を当てており、パッケージの配布やサービスの初期化をSSHをうまく使って解決していました。
このような型にはまらない方法は、初めは上手くいきましたが、技術的負債を残すことになりました。

## Prodtestでの不整合の検出
先のような状況において、クラスタを設定するために使われていたシェルスクリプトは、変更を行う人数やクラスタ数の観点からスケーラビリティを持っていませんでした。
そして、以下のような懸念点がありました。

> * **サービスの依存対象が全て利用可能で、適切に設定されているか。**
* **すべての設定とパッケージは、他の動作環境と一貫しているか。**
* **例外的な設定はすべて意図的なものであることを確認できたか。**<sup>1</sup>

GoogleはProdtestによって、この問題を解決しました。
これによって、実際のサービスをユニットテストできるようになりました。Prodtestは、pythonのユニットテストのフレームワークの拡張です。チームのクラスタ名を指定すると、そのクラスタ内のチームのサービスを検証できるようになります。
これにより、サービスが適切に設定されているか、あるいはされていないかを素早く知ることができるようになりました。また、予想外の設定ミスによって、遅延が生じた場合、その原因となったバグを登録できます。それにより、素早く問題の検出を行えるようになりました。
この取り組みのおかげで、プロジェクト管理者は、クラスタがライブ状態になる時期を予測できるようになり、実際に提供中になるまでに6週間以上かかる理由を理解できるようになりました。

そして、SREにシニア管理者からミッションが与えられました。

> **「3か月以内に、5つのクラスタが同日にネットワークの準備完了状態になる。そのクラスタを1週間以内にたちあげてほしい」<sup>1</sup>**

##まとめ
* Googleの初期のSREは、サービスの設定をシェルで行っており、そのせいで設定のばらつきが生じることがあった。
* 設定のばらつきをProdtestを導入することで検知できるようにした。
* そのため、管理者はどの程度作業が進んでいるかを知ることができるようになった。

#### 雑記
書籍の記述が若干エモい。苦労したんだろうなあ。

#### 参考文献
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　77-79
Ubuntu 20.04 (LTS)にraspi-configをインストール

# はじめに

年末セールでRaspberry pi 4(2GB)が少し安く購入できた。

すぐに使う予定はなかったが初期不良確認がてらRaspberry pi上で[Rosetta@home](https://boinc.bakerlab.org/rosetta/)（新型コロナ(COVID-19)の解析をサポートするプロジェクト用ソフトウェア）を動かしてみた。

Rosetta@homeを動かすには64ビット環境が必要でRaspberry pi 4の標準OS（Raspberry pi OS、正式版は32ビットのみ、64ビットはまだβ版）ではなく、Ubuntu Server 20.04 LTS（64ビット）をインストールした。しかし、raspi-configが含まれておらず、別途インストールが必要だったのでまとめておく。

# 環境

主に初期不良確認のためなので環境はかなり適当。

Raspberry pi 4 (2GB)
Ubuntu Server 20.04 LTS (64ビット)

+ 執筆時点(2020/12/20現在)で国内で入手できるRapberry pi 4は搭載メモリが2GB/4GB/8GBのモデルがある。2GBモデルを選択したのは単純に安価だったため

+ Ubuntu Server版を選択したのは、購入したRaspberry pi 4のメモリが2GBしかなくDesktop版がインストールできなかったのと、そもそもGUIが不要だったため

+ Ubuntu 20.04 LTSを選択したのは、執筆時点(2020/12/20現在)でRasberry Pi Imager V1.5 (Windows版)でインストールできるUbuntuの唯一のLTSバージョンだったため（なお、18.04 LTSも2023年4月までサポート対象）。LTSバージョンを選択したのは、しばらく触る予定がなかったのでサポート期限が長い方が良いだろう、という程度の理由。

# raspi-configインストール手順

@ivvakanniさんの[投稿「ubuntu 18.04 にraspi-configをインストールしてGPIOの初期設定を変更した話」](https://qiita.com/ivvakanni/items/e29378dc666d8204fa58)を参考にした

```
sudo echo "deb http://archive.raspberrypi.org/debian/ buster main" >> /etc/apt/sources.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 7FA3303E
sudo apt-get update
sudo apt-get install raspi-config
sudo mount /dev/mmcblk0p1 /boot
```

ポイントは`jessie`（debian 8.0）を`buster`（debian 10.0）にすること。`jessie`のままではエラーになってしまう。

Ubuntu 20.04 LTSでは`/etc/debian_version`が`bullseye/sid`なので`bullseye`（debian 11.0）ベースのようだ。`http://archive.raspberrypi.org/`には`bullseye`がないので`buster`にした。今のところ問題はなさそう。

# 最後に

そもそもraspi-configは各種設定ファイルを変更すれば必須ではないらしいが、将来的に純正のGPIOファン（raspi-configで設定可能）を取り付ける予定なのでインストールしてみた。

デスクトップ環境でGUIを使用すると動かない場合は、CUI(コンソール)で試して欲しい。
Rust+Rocket++Ruqlite+Teraで作るWebアプリケーション

#目的
最近、Rustに個人的にハマっているので勉強も兼ねて作ってみた。

#構成
Rust : 1.50.0-nightly 
Rocket : 0.4.5
Rusqlite : 0.23
Tera : 0.4.6(2020/12/19)

#作った物
簡単なtodoリストを作ってみた。ここにあります。
https://github.com/issei1203/Rust_WebApp_Sample

#動作
実行してlocalhost8080/indexに繋ぐとこんな画面が表示される。
![スクリーンショット 2020-12-20 12.55.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685025/3233047b-c804-2467-dbdb-e5853439abe1.png)

下の入力欄を埋めて送信すると..
![スクリーンショット 2020-12-20 12.59.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685025/c8811998-f4ca-bbe9-af59-65642701cfb8.png)

こんな感じで表示される。
![スクリーンショット 2020-12-20 13.00.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685025/79b6a257-3479-7cda-cc28-61cff3c4911b.png)

TODOリストの送信を押すとこんな感じで移動する。
![スクリーンショット 2020-12-20 13.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685025/1cc48d87-260c-cf81-b417-4da30f6085e4.png)
ちなみにdoingにある時に送信を押すとdoneの欄に移動。doneの欄にいるときはDBから削除して画面からも消えるようになっている。

#感想
慣れてしまうとあまり難しくなかったが、慣れるまで時間がすごいかかった。
というのも、日本語記事が少なく英語が苦手なので公式のリファレンスを読むのに時間がかかってしまった。
またRustは書いていて楽しいのでもっと使う人が増えればいいなと思う今日この頃...
Pythonの正規表現でデキると思わせる

言語処理１００本ノックをやっているとき、正規表現するときに`re`に関して新しく学んだこともあるので、ここでまとめておこうと思う。

## searchとmatchの違い

* searchはマッチ対象文字列の先頭からマッチしていなくてもマッチする。
* matchは必ずマッチ対象文字列の先頭からマッチしていないとマッチしない。

たとえば、`grape`と言う文字列に対して`ape`というパターンをマッチさせる場合、`search`を使った場合は`grape`には`ape`が含まれているのでマッチするが、`match`を使った場合は、`ape`は含まれているが先頭からは始まっていないので、マッチしない。

```py
m = re.match('ape', 'grape') # マッチしない
m = re.search('ape', 'grape') # マッチする
```

## マッチした部分を取り出す

正規表現でマッチした時、そのマッチした部分を取り出したい時がある。

次の例で言うと、`'1993'`や`'7'`, `'2'`を取り出したい場合である。

```py
s = "1993年7月2日生誕"
p = "([0-9]+)年([0-9]+)月([0-9]+)日"

m = re.search(p, s)
```

マッチ対象文字列(前述のスニペットの`s`)のうち、`()`でくくられたパターンにマッチした部分は、`m.group(n)`メソッドで取り出すことができる。引数の`n`は次のようにする。

* パターン全体とマッチした文字列: n=0
* 先頭からi番目の`()`に該当する文字列: n=i

つまり、上記の例で言うとこうなる。

```py
m.group(0) # -> '1993年7月2日'
m.group(1) # -> '1993'
m.group(2) # -> '7'
m.group(3) # -> '2'
```

注意点として、`.group()`の返り値は数値ではなく必ず文字列になるので、数値として扱いたい場合は、適宜キャストして使おう。

## マッチさせる部分に名前をつける

前項のケースで、数字ではわかりづらいと言う場合がある。その時は、`(?P<name>regex)`のように書くと、先ほど`.group()`で引数でどの部分を取り出すか指定したところを、`name`という名前で取り出すことができるようになる。

具体的には次のようにする。

```py
s = "1993年7月2日生誕"
p = "(?P<year>[0-9]+)年(?P<month>[0-9]+)月(?P<day>[0-9]+)日"

m = re.search(p, s)

m.group(0) # -> '1993年7月2日'
m.group('year') # -> '1993'
m.group('month') # -> '7'
m.group('day') # -> '2'
```

## マッチした部分を全て取り出す

長い文章で正規表現抽出を行っている時、たとえば「con」で始まる単語を全て取り出したい場合がある。そのような時は`re.findall()`を使おう。

```py
s = 'It\'s convenient to conclude you are conservative.' 
p = 'con\w+'

m = re.findall(p, s)

m # -> ['convenient', 'conclude', 'conservative']
```


## 改行文字にマッチする

パターン文字列に`.`を使う場合、任意の文字にマッチできるが、例外として改行文字(`\n`)にはマッチできない。

例えば下記の場合、`'abc=def\nghi\njkl'`がマッチすると思いきや、`'abc=def'`までしかマッチしない。

```py
s = 'abc=def\nghi\njkl'
p = '^abc=.+'

m = re.search(p, s)
m.group() # -> 'abc=def'
```

これは、`'.'`というメタ文字が`\n`には例外的にマッチしないことに由来している。こういうときは、`search()`の第３引数に`re.DOTALL`フラグを立てる。

```py
s = 'abc=def\nghi\njkl'
p = '^abc=.+'

m = re.search(p, s, re.DOTALL)
m.group() # -> 'abc=def\nghi\njkl'
```

ね？簡単でしょ？

## 複数行の文章のにマッチする

Webスクレイピングすると、ある特定のタグで始まる行だけ取り出したい、と言うケースもあるのではないか。(やったことないけど)

```py
s = """<p>Pieter Pipar piked a peck of pickled pepers.</p>
<hr>
<p>A pek of pickled pepers Pieter Pipar piked.</p>
<p>If Pieter Pipar piked a pek of pickled pepers,<p>
<hr>
<p>How many pickled pepper did Pieter Pipar picked?</p>"""

p = "^<p>.+$"
```

適当に`<p>`で囲んで、`<hr>`で水平線入れてみた。
この状態から、`<p>`で始まる行だけ取り出したいとする。

このとき、`.findall`を使うが、改行文字が含まれるので、`re.MULTILINE`フラグを使うと、改行文字で分割した上で、それぞれの行に対してパターンマッチすることができる。

```py
m = re.findall(p, s, re.MULTILINE)
m
# ['<p>Pieter Pipar piked a peck of pickled pepers.</p>',
#  '<p>A pek of pickled pepers Pieter Pipar piked.</p>',
#  '<p>If Pieter Pipar piked a pek of pickled pepers,<p>',
#  "<p>Where's the pek of pickled pepers that Pieter Pipar picked?</p>"]
```

最後だけダブルクォーテーションになってるのは謎だが、便利だね。

# 参考

* re — Regular expression operations — Python 3.9.1 documentation  
  https://docs.python.org/3/library/re.html
* ピーター・パイパー - Wikipedia  
  https://ja.wikipedia.org/wiki/%E3%83%94%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%BB%E3%83%91%E3%82%A4%E3%83%91%E3%83%BC
unityでタイヤ回転プログラム【unity】【C#】

###やりたいこと
- unityで車を移動させたけどタイヤも回転させたい。

プログラム

```c#:tire_rotation.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class tire_rotation : MonoBehaviour
{	

        void FixedUpdate() 
        {
            if (Input.GetAxis("Vertical")==1)//もし上キーが押されたら
            {
                transform.Rotate(new Vector3(1, 0, 0));//タイヤ回転
            } else if(Input.GetAxis("Vertical")==-1)//下キーだったら。
            {
                transform.Rotate(new Vector3(-1, 0, 0));//タイヤ逆回転
            } else//何も押されてないなら
            {
                 transform.Rotate(new Vector3(0, 0, 0));//タイヤ回転停止
            }
               
            
            
        }
}

```
R.swiftの実行が激重になったので改善した話

こんにちは。iOSアプリエンジニアの @zrn-ns です。

結構前の話になりますが、Xcode11にアップデートしたあたりからiOSプロジェクトのビルド速度が遅くなり始め、気づくと差分ビルドにかかる時間が1分を超えるようになっていました。

# 発生した問題

差分ビルドで1分かかるのは流石に遅すぎるので原因を調査したところ、R.swiftの実行に50秒近くかかっている事がわかりました。

[mac-cain13/R.swift](https://github.com/mac-cain13/R.swift/blob/master/Documentation/Examples.md#localized-strings)

R.swiftは、ターゲット内に含まれるリソースファイルのパスを集約した構造体を生成してるOSSです。
画像ファイルやjsonなどのリソースを取得するとき、ファイル名やパスを直接指定してしまうとファイル名の変更を行ったときなどに実行時エラーを引き起こしてしまいますが、R.swiftを使用すればファイルに静的にアクセスできるため、そういった危険性を排除できます。

プロジェクトでは3ターゲットでR.swiftで実行していたので、1ターゲットあたり15秒くらいかかっていたと思います。


# 調査

そもそも全てのファイルを走査するような処理に時間がかかるというのは当たり前のことだと思っていたので、最初はR.swift側の改善を待とうかな、なんて考えていたのですが、一向に同じような現象に悩まされている人がいないようだったので、うちのプロジェクト側の設定の問題を疑い始めました。（基本的に問題が起きると自分側の問題💀）

しばらく調べていると、下記のIssueへのコメントを見つけました。
https://github.com/mac-cain13/R.swift/issues/479#issuecomment-575534254

> With just one line **/CampaignsAndFormats.strings it was increasing script time from 4 to 11 seconds.


## 原因

コメントで書かれていたのは、 `**/` **を使うとスクリプトの実行時間が大幅に増加するということ**。

あれ、と思い `.rswiftignore`(R.swiftの除外設定ファイル)を開いてみると、そこには下記のようなパスが記されていました。

```sh
**/*.storyboard	
**/*.xib
```

# 改善

どうやらこのパス指定が原因だったようです。

別にstoryboardとxibを除外する必要もなかったのでこの設定ファイルを削除したところ、R.swiftの実行スピードが**6秒**まで短縮されました。
（1ターゲットあたり2秒程度）

この時間なら全然許容できます。


# 感じたこと

再帰的なワイルドカード `**` を使うと処理が重くなるようです。
これはR.swiftに限らず、Unix環境全般で言えるのだと思うのですが、調べてもそういう情報を見つけられませんでした。
（詳しい人がいたら教えて下さい...）

今後は同様の問題を起こさないように気をつけたいなと感じました。

少しでも、同じような問題で苦しんでいる人の力に慣れれば幸いです。ではでは。
__name__や__main__に関する備忘録

今回は、プログラム中でよく見かける`__name__`や`__main__`に関して記述していきたいと思います。

# 開発環境
MacOS
Python3.7(anaconda)
VSCode

[Pythonのif __name__ == "__main__" とは何ですか？への回答](https://blog.pyq.jp/entry/Python_kaiketsu_180207)

# ファイルをimportすると実行までされてしまう問題
言葉で説明するよりも実際にコードを実行して確認する方がわかりやすいと思いますので。

```python:a.py
def hello():
    print('Hello World')

hello() -> Hello World
```
このコードを実行すると、もちろん`Hello World`が出力されます。

そこで、ふとこの`hello関数`を別のファイルに読み込みたいなと思ったときはファイルaを別のファイル上で`import`をすると思います。

```python:b.py
import a -> Hello World
```
しかし、ここで困ったことに、`ファイルa`が実行までされてしまうのです。

お分かりでしょうか？
別のファイルにある関数を使って処理をしたいだけなのに、実行までされてしまうので良い迷惑ですよね。


# `__name__`とは
とあるファイル`a.py`において、このファイルを実行すると、`__main__`が出力されます。

```python:a.py

def A():
    print(__name__)

A() -> __main__
```

つまり、`__name__`の中は通常であれば、`__main__`が入力されることになります。

## ファイルaをファイルbにimportする
ここで、先ほどと同じように`ファイルa`を`ファイルb`にimportします。
先ほどと同じであれば、ファイルbにimportしただけで、`__main__`が出力されるということになります。

```python:b.py
import a -> a
```

しかし、今回出力されるのは、`importされたファイル名`である`a`なのです。

## __name__は別のモジュール(ファイル)にimportされたら中身が変わる
通常であれば、`__main__`が入ってくるというのが`__name__`でしたが、importされて別のファイル上で実行されるという状況になった場合、`__name__`の中身は、importされた`ファイル名(モジュール名)`になります。

# if `__name__` == `'__main__'`:とは何なのか
`if __name__ == '__main__':`はこの条件文が書かれたファイルが別のファイルにimportされていない場合だけ、条件文以下のコードを実行する、という意味になります。

```python:a.py
def hello():
    print('Hello World')

if __name__ == '__main__':
    hello()


def A():
    print(__name__)

A()
```
`ファイルa`を`ファイルb`にimportした場合に、`if __name__ == '__main__':`が無ければ、`__name__`の中身が`__main__`ではなく、ファイル名である`a`に代わるので、`Hello World`と`a`が出力されます。

```python:b.py
import a -> a
```
しかし、今回は、ファイルaに`if __name__ == '__main__':`が記述されており、`__name__`の中身は`__main__`ではなくっているため、`hello()`は実行されず、`a`のみが出力されました。


# まとめ
`if __name__ == '__main__':`は不思議な条件式のように見えますが、ちゃんと理解すると必要な条件式だなと思いました。

importされたファイルは`実行までされる`というのがわかっていないと必要性を感じないのではないかと思いました。
[GoLand]コード折りたたみを無効化する

# 1.はじめに
GoLandを新しいPCにインストールするたびに忘れるので書きました。

## 1-1.この記事を読んだらどうなるのか
コード折りたたみを無効化できるようになる。

## 1-2.対象読者
GoLandでコードが折りたたまれて苦しんでいる人
![scratch.go 2020-12-20 12-38-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309702/255c9306-09fc-cf6c-309a-3d400860e42d.png)


#  2.GoLandの設定
以下の設定を行います。
Preferences > Editor > General > Code Folding
imports, One line returns, One line panics,Format, stringsのチェックボックスを外して、ApplyすればOKです。
![Preferences 2020-12-20 12-44-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309702/667ecd30-6488-ec67-6481-ecf23d79883b.png)
[ServiceNow]ログローテーション

今回もセキュリティに関係のあることに関して記述していきます。
今回はログについてです。

#ServiceNowで管理されるログ
ServiceNowでは様々はログが管理されています。
セキュリティログ、システムログ、UpdateSet適用などの開発ログ。

ただ、ServiceNowで管理されるログの中には、ローテーションされるものがあり、一定期間でインスタンス上から消えてしまうログがあります。
ローテーションされるログの確認方法について以下に示します。

##ログローテーション

###メジャーバージョン
- Paris

###前提
- ログを画面から見れるのは、admin権限

###確認方法
1. [システム定義 ⇒ テーブルローテーション]に移動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/e52e3a74-9376-5260-36a2-ae2de498d06e.png)

2. 表示されたテーブルがローテーション対象
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/9b94842b-4eac-f673-4f84-2da6a1fa02ec.png)

###注意
ローテーションの設定を安易にすることはお勧めできません。性能面などにも影響があり、ServiceNowでは推奨されていないようです。

###参考文献
- [ログ履歴](https://docs.servicenow.com/bundle/paris-platform-administration/page/administer/time/reference/security-log-history.html)


###補足
Eventログなどはインスタンス上での保存期間が短く（1日×7ローテー=7日分ん）、企業に導入するにはその企業のセキュリティ要件を満たさないことが予想されます。その時は、MIDサーバにログをエクスポートするなど別途保管する方法を検討する必要があるかもですね。
【SwiftUI】SwiftUIでAppDelegateの処理を実装する方法

SwiftUIでアプリを作成していた際に、起動時の処理を実装する必要が生まれ`AppDelegate`を実装する必要が出てきたので、その手順を備忘録として書き留めておきます。

## 生成されるファイルについて
Xcode 12でプロジェクトを新規作成すると`Lifecycle`という項目が追加されています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484337/728ec54c-8250-4b45-9b23-9fbb1d8286eb.png" width=50%>

これを`UIKit App Delegate`にすることで今まで通り`AppDelegate`などが作成されます。
一方で`SwiftUI App`を選択すると<プロジェクト名>App.swiftファイルが生成されます。
今回は、後者の`<プロジェクト名>App.swiftファイル`でのAppDelegateの実装方法について記述していきます。

## SwiftUI Appで起動時の処理を実装する方法
`@UIApplicationDelegateAdaptor`を使用することで、既存のAppDelegateを利用することができるようになります。

```swift

import SwiftUI

@main
struct SwiftUIAppSample: App {
    // swiftlint:disable weak_delegate
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate  // 追加する
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

// 以下を追加する
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        return true
    }
    // 必要に応じて処理を追加
}
```

`UIKit App Delegate`よりもコード記述量を減らして実装することができます。

以上がSwiftUIでAppDelegateを実装する手順になります。
【Vue.js】値がnullのとき、マスタッシュ {{ }} ごと非表示にしたい

## したいこと

v-forなどで回しつつ `{{}}` を使って表示させたいけど、nullのときもあるよ、というときの話です。理想は以下。

```
八海山（はっかいさん）　← name_kanaがあるとき
八海山　← name_kanaがないとき
```

今回は`result.name`は必ず存在するけど、`result.name_kana`がnullのときに文字列（ここでは丸カッコ）ごと非表示にしたい場合を例にとりあげます。


## うまくいかない例
### 例１

このように書けば、nullのときは自ずと非表示になります。でも、今回の場合は、ああ、違った。文字列ごといらないんだよな、という話です。

```vue
<div v-for="result in results" :key="result.id">
  <p>{{ result.name }}（{{ result.name_kana }}）</p>
</div>
```

```
八海山（）
```

### 例２
こうする？ というとこれでもないじゃないですか。

```vue
<div v-for="result in results" :key="result.id">
  <p>{{ result.name }}{{ '（' + result.name_kana + '）' }}</p>
</div>
```

```
八海山（null）
```



## うまくいく例
### 例１：　マスタッシュ内に直接、式を書く

```vue
<div v-for="result in results" :key="result.id">
  <p>{{ result.name }}{{ result.name_kana ? `（${result.name_kana}）` : '' }}</p>
</div>
```

存在しているかどうかを都度確かめて、表示・非表示を振り分けています。

### 例２：　メソッドを使う
```vue
<div v-for="result in results" :key="result.id">
  <p>{{ result.name }}{{ exist(result.name_kana) }}</p>
</div>
```

methodsに次のような物を用意しておきます。

```js

export default {
  methods: {
    exist(data) {
      return data ? `（${data}）` : ''
    }
  }
}
```
そうすると、データが存在しているときだけ返ってきます。かわりにマスタッシュのなかがスッキリしますね。

### 例３：　フィルタを使う

```vue

<div v-for="result in results" :key="result.id">
  <p>{{ result.name }}{{ result.name_kana | nonNull }}</p>
</div>
```

```js

export default {
  filters: {
    nonNull(data) {
      return data ? `（${data}）` : ''
    }
  }
}
```

メソッドと似た発想ですが、フィルタを使っても書けます。

### 例４：　v-ifを使う

```vue

<div v-for="result in results" :key="result.id">
  <p>{{ result.name }}<span v-if="result.name_kana">{{ `（${result.name_kana}）` }}</span></p>
</div>
```
`v-if`を使ってもできますね。

## おわりに
シンプルな事柄すぎてまとめている方があまりいらっしゃらなかったので、記事にしてみました。他にも「こんな方法があるよ」「いや、こう書けや」というのがあれば、ぜひ教えていただけると嬉しいです。
【Node.js Express】Node.js Expressアプリケーションにフラッシュメッセージを実装する方法

※当方駆け出しエンジニアのため、間違っていることも多々あると思いますので、ご了承ください。また、間違いに気付いた方はご一報いただけると幸いです。

フラッシュメッセージを使うには、**connect-flash** パッケージを用います。
フラッシュメッセージはリクエスト間で渡されるため、セッションとクッキーに依存します。

よって下記の３つのインストールが必要となります。

```
npm i connect-flash cookie-parser express-session -S
```

インストールしたモジュールをロードし、設定します。

```main.js
"use strict";

//モジュールロード
const express = require("express"),
  app = express(),
  router = express.Router(),
  expressSession = require("express-session"),
  cookieParser = require("cookie-parser"),
  connectFlash = require("connect-flash"),

//cookie-parserをミドルウェアとして設定
router.use(cookieParser("secret_passcode"));

//express-sessionをミドルウェアとして設定
router.use(
  expressSession({
    secret: "secret_passcode",
    cookie: {
      maxAge: 4000000
    },
    resave: false,
    saveUninitialized: false
  })
);

//connect-flashをミドルウェアとして設定
router.use(connectFlash());

//フラッシュメッセージをresのローカル変数のflashMessagesに代入　※１
router.use((req, res, next) => {
  res.locals.flashMessages = req.flash();
  next();
});
```

express-sessionについてはこちらも参考
[【Node.js express】express-validatorでバリデーションを実装し、通過した値をセッションに格納する。](https://qiita.com/sho_U/items/f31763fd6fea1e0d6999)

コントローラーにフラッシュメッセージの処理を組み込み（Userモデルcreateの例)

```usersController.js

module.exports = {
  create: (req, res, next) => {
    let userParams =  {
      name: req.body.name,
      email: req.body.email,
    };
    User.create(userParams)
      .then(user => {
        req.flash("success", "account created successfully!");
        res.redirect("users"); //上記の※１ミドルウェアを経由する。
        //success型
      })
      .catch(error => {
        req.flash("error", `Failed ${error.message}.`); //セッションを経由して表示
        res.redirect("users/new"); //フォームに戻す//上記の※１ミドルウェアを経由する。
        //error型
      });
  },
};
```

ビュー側でフラッシュメッセージを組み込み

```layout.ejs
	<div class="flashes">
          <% if (flashMessages) { %>  //flashMessagesがあった場合
           <% if (flashMessages.success) { %>　//success型があった場合
             <div class="flash success">
	       <%= flashMessages.success %>
	     </div>
           <% } else if (flashMessages.error) { %> //error型があった場合
	     <div class="flash error">
	       <%= flashMessages.error %>
	     </div>
	   <% } %>
	 <% } %>
	</div>
```
アナログ回路 その15

# 概要

circuit sandboxをplunkerでホスティングした。
アナログ回路をシュミレーションで、説明してみる。

# ダイオード・全波整流回路

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7c6b4613-0e5c-3dbf-dddc-8ab3f56bb8a1.jpeg)


# 結果

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/03033dc8-d4f6-6b7e-29c0-0661be1bea6a.jpeg)


# 説明

全波に対応するようダイオードをタスキ掛けしてる。

# 成果物

https://embed.plnkr.co/plunk/KjvtqkJ0TaScEkfj


以上。
チーム開発に必要だったbing map でピン表示までやってみた


ECサイト構築宣言から急にMapの話に飛びました。w
でもチーム開発用に必要だったのとつまづきまくったので記事にしました。

おそらくプログラミングの流れや情報の受け渡し、
データの読まれ方の順序などを把握している方はつまづかないポイントかも
しれませんが、同じように写経がメインであまり理解が進んでない
誰かのためになればと思い投稿します。

やったこと：
・bing map api キーを取得する
・自分のキーを使ってマップを表示する
・表示したマップに緯度経度を指定してピンを表示する


![スクリーンショット 2020-12-20 12.03.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527518/5cc0b6d2-10a0-3b6f-1ff5-6a563df6f8ff.png)
![スクリーンショット 2020-12-20 12.04.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527518/7bfd4796-0e9f-212f-1eb7-d0f08bca334f.png)
![スクリーンショット 2020-12-20 12.04.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527518/54763248-7858-2f67-0602-f8ed033d0a67.png)


上からコードが読まれていくので、

ズームの拡大縮尺やタイムアウトを何秒にするかの設定(const = set)
↓
何色のピンをどこに表示する？の表示の宣言(pushPin(lat, lng, map))
↓
マップ表示の宣言(mapsInit)
---この関数の中で「ピンをマップ上に表示するためpushPinを宣言」
↓
エラーが起きた際の表示(mapsError)
↓
mapsInit, mapsError, set を全て実行する関数を定義(GetMap)
↓
最後、window.onload でGetMapを宣言し実行


これで現在地のマップ表示とピン表示ができました。
Laravelのローカル環境で困ったときにやること

エンジニアがプッシュしたものをプルしたあとに、ローカルでエラーが出たときなどに試すことをまとめていきます。

php周りの操作

キャッシュのクリア

```bash
php artisan cache:clear
```

新しくページが追加されたときやルーティングの変更があったとき
ex: ページが404になるなど

```bash
php artisan route:clear
```

コンフィグの変更があったとき

```bash
php artisan config:clear
```

データベースの仕様変更やテーブル追加があったとき実行

```bash
php artisan migrate
```

コンポーザー以下略

```bash
composer dump-autoload
```
Azure DevOps プロジェクトに組織外のアカウントを追加する

Azure DevOps プロジェクトに組織外のアカウントを追加する方法です。

プロジェクトにメンバーを追加するとき、Project settings の Teams で既定の Team に追加していませんか。ここで追加するときは、アカウント名を入力して表示される候補の中から選択します。Active Directory 内のアカウントであれば候補に出るので困ることはありません。しかし、組織外のアカウントは候補に表示されません。

公式ドキュメントに解説があります。2020年12月時点ではまだ邦訳されていません。

[Add, invite guest external users to your organization - Azure DevOps Services | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/devops/organizations/accounts/add-external-user?view=azure-devops&tabs=preview-page)

組織外のアカウントは、Project で扱う前に、一つ上の階層の Organization に追加しなければならないのです。ということは、普段からプロジェクトにメンバーを追加するとき Organization settings から作業していたなら、何も困ることはなかったのかも。

Organization settings の Users で **Add users** ボタンをクリックして作業を開始します。

| 入力項目 | 説明 |
|---|---|
| Users | 招待するマイクロソフト アカウントを指定します。複数指定できて便利。 |
| Access level | Visual Studio のサブスクリプションを持っているユーザーなら _Visual Studio Subscriber_ を選択することで、Repo にアクセスできるようになります。サブスクリプションを持っていない場合、Repo にアクセスしたければ _Base_、Repo へのアクセスが不要なら _Stakeholder_ を選択します。あとで変更できます。 |
| Add to projects | 追加するProjectを選択。複数選択可。 |
| Azure DevOps Groups | ユーザーを追加する先となる Group を選択。プロジェクト内の Team に入れる作業はあとでプロジェクト側で行います。なお、ここで _Contributors_ を選択したとしても、Acces Level が _Stakeholders_ ならやっぱり Repo にはアクセスできません。 |
| Send email invites | チェックします。画面に表示される説明の通りですが、送られてくるメールのリンクをユーザーがクリックする必要があります。メールはあとで送り直すことができます。 |

**Add** ボタンをクリックして作業完了です。

「あとで変更できます」「あと送り直すことができます」と書きましたが、場所が分かりにくくて迷いました。Organization settings の Users で、ユーザーにマウスオーバーすると右端に点々のアイコンが現れます。これをクリックするとメニューが表示されます。Access level の変更は **Change access level**、メールの再送は **Resend invite** です。
アナログ回路 その14

# 概要

circuit sandboxをplunkerでホスティングした。
アナログ回路をシュミレーションで、説明してみる。

# ダイオード・半波整流回路

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4eb1c0dc-fd79-8151-30bf-a48a266e91fd.jpeg)


# 結果

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/12b5d2f7-990c-5a94-21fe-9b9f6d67a6bb.jpeg)


# 説明

50Hzのsin波を半波だけ通す。

# 成果物

https://embed.plnkr.co/plunk/WlWOvCZPS1EUwhKA


以上。
ローカルの git リポジトリを Azure DevOps に乗せる

ローカルで作り始めた git リポジトリが順調に育って、これで行こう、そろそろ Azure DevOps に乗っけよう、という気になったときの手順です。

まず、Azure DevOps に空のリポジトリを作ります。

1. Azure DevOps の Project の **Repos** を開く。
1. リポジトリのドロップダウンメニューの中の **New repository** をクリックする。
1. **Create a new repository** ウィンドウで、
  - **Repository name** を適宜入力する。
  - **Add a README to describe your repoistory** をチェック _"しない"_。
  - **Add a .gitignore:** で _None_ を選択する。
1. **Create** をクリックする。

リポジトリ作成後の画面で次の作業が指示されます。

- Clone to your computer
- or push an existing repository from command line
- or import a repository
- or initialize with a README or gitignore

今回の場合は2番目になります。コマンドラインから `remote add` して `push` です。