OmniAICreator/Qiita-1.07M huggingface dataset:
FactoryBot,Fakerの導入

今回はテストコードを実行する上で、FactoryBotを使用する際の手順です。
以下のURLを最初に実行した後の記事なので、RSpecの導入が終わられていない場合は下記の記事を参照していただけると幸いです。
[RSpecの導入と単体テストコード実行の手順](https://qiita.com/mr0216/items/7bd9b0f6b660560ebfea)

##FactoryBotを導入
FactoryBotとはインスタンスをまとめることができるGemです。他のファイルであらかじめ各クラスのインスタンスに定める値を設定しておき、各テストコードで使用します。

##GemFileの編集
```ruby:GemFile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails', '~> 4.0.0'
  gem 'factory_bot_rails'
end
```
記入後はbundle installを実行。

spec/factories/users.rbを手動で作成

##FactoryBotを使用してインスタンス生成を共通化
```ruby:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              {"test"}
    email                 {"test@example"}
    password              {"000000"}
    password_confirmation {password}
  end
end
```
記入後はFactoryBot.build(:user)の記述でユーザーが新しく生成されます。

```ruby
# FactoryBotを利用しない場合
user = User.new(nickname: "test", email: "test@example", password: "000000", password_confirmation: "00000000")
# FactoryBotを利用する場合
user = FactoryBot.build(:user)
```

##テストコードの記述
```ruby:spec/models/user_spec.rb
require 'rails_helper'
RSpec.describe User, type: :model do
  before do
    @user = FactoryBot.build(:user)
  end

  describe 'ユーザー新規登録' do
    it "nicknameが空だと登録できない" do
      @user.nickname = ""
      @user.valid?
      expect(@user.errors.full_messages).to include "Nickname can't be blank"
    end
    it "emailが空では登録できない" do
      @user.email = ""
      @user.valid?
      expect(@user.errors.full_messages).to include "Email can't be blank"
    end
  end
end
```

記述後はコマンドを実行し、成功することを確認します。

```ruby:ターミナル
% bundle exec rspec spec/models/user_spec.rb 
```

続いてランダムな値の入力を実行するFakerの導入

```ruby:GemFile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails', '~> 4.0.0'
  gem 'factory_bot_rails'
  gem 'faker'
end
```
記入後はbundle installを実行。

##Fakerを使用した記述に変更

```ruby:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              {Faker::Name.initials(number: 2)}
    email                 {Faker::Internet.free_email}
    password              {Faker::Internet.password(min_length: 6)}
    password_confirmation {password}
  end
end
```

テストコードを実行し、結果を確認して全てOKだったらテストコード終了です。

```ruby:ターミナル
% bundle exec rspec spec/models/user_spec.rb 
```

以上議事録でした。
AWS Tools for PowerShellで不要なMFAデバイス登録したプロフィールでのロール切替えが失敗する

# 概要

AWS Tools for PowerShellでロール切替え用のプロフィールを作る際、MFA不要のロールに対してはMFAデバイスを**登録してはいけない**。不要に登録すると、このプロファイルでの操作が `Error calling AssumeRole for role (ロールのarn)` で失敗する。

# 詳細

AWS Tools for PowerShellでロール切替えをしたいときは、ロール切替え用のプロファイルを作成するのが便利。作成するプロファイルが `MyRole` で使用する認証情報のプロファイルが `MyCredProfile` だとして、こんな感じ。 `^` はコマンドが複数行にわたるときのWindows PowerShell環境でのシンボルなので、Linux環境では `\` に置き換えてください。

```
PS> Set-AWSCredential -StoreAs MyRoleProfile -SourceProfile MyCredProfile ^
    -RoleArn arn:aws:iam::123456789012:role/MyRole
```

登録したプロファイルが使用されるように `Set-AWSCredential` で指定しておく。

```
PS> Set-AWSCredential -ProfileName MyRoleProfile
```

ここでもし使用するロールがMFA（多要素認証）必須の場合、次のようにしてMFAデバイスも登録しておく。

```
PS> Set-AWSCredential -StoreAs MyRoleProfile -SourceProfile MyCredProfile ^
    -RoleArn arn:aws:iam::123456789012:role/MyRole
    -MfaSerial arn:aws:iam::123456789012:mfa/MyName
```

こうすると、コマンドレット実行時に適宜MFAコードを問合わせてくれる。

```
PS> Get-IAMUserList
Enter MFA code:*******
```

さて、もしここでロール `arn:aws:iam::123456789012:role/MyRole` がMFAを要求しないロールの場合どうなるか？もちろん、MFAコードを聞かれないとか、聞かれても無視されて、操作は成功すると思ってた。でも実際には、エラーになる。

```
PS> Get-IAMUserList
Enter MFA code:*******
Get-IAMUserList: Error calling AssumeRole for role arn:aws:iam::123456789012:role/MyRole
```

結論としてAWS Tools for PowerShellでロール切替え用のプロフィールを作る際、**MFA不要のロールに対してはMFAデバイスを登録してはいけない**。不要に登録すると、このプロファイルでの操作が `Error calling AssumeRole for role (ロールのarn)` で失敗する。このエラー内容でこれがいけないのだとは気づきにくいと思うのだけど、気づけないとMFAコード入力し間違えたかなとか認証用プロファイルおかしいだろうかとか無駄な調査をすることになる。

# 参照

* [Set-AWSCredential Cmdlet | AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/reference/items/Set-AWSCredential.html)
* [AWS Tools for PowerShell での認証情報の共有 - の AWS ツールPowerShell](https://docs.aws.amazon.com/ja_jp/powershell/latest/userguide/shared-credentials-in-aws-powershell.html#shared-credentials-assume-role)
Android Kotlin Lifecycle

## Activityのライフサイクル
![activity_lifecycle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953777/0eb7168f-a0c5-216a-693f-59fb4ab6c9e9.png)

## Fragmentのライフサイクル
![fragment-view-lifecycle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953777/e01c3f96-a42d-af6d-9fbf-7245bd96521c.png)

---

**Loggingを追加して、ライフサイクルを確認してみよう**

`onCreate()`

```kotlin:MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
 Log.i("MainActivity", "onCreate Called")
}
```
このようになっていれば、呼び出しが成功したことになります。

![onCreate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953777/9cf34254-d981-997b-0208-fc0db06acecd.png)

`onStart()`

```kotlin:MainActivity.kt
override fun onStart() {
   super.onStart()
   Log.i("MainActivity", "onStart Called")
}
```

次はログライブラリを使用してます。
今回は、Timberを使用します。

下記のコードを追加します。

```gradle:build.gradle
implementation 'com.jakewharton.timber:timber:4.7.1'
```

Applicationクラスを作成し、Timberを初期化します

```kotlin:SampleApplication.kt
class SampleApplication: Application() {
  override fun onCreate()
    super.onCreate()

  Timber.plant(Timber.DebugTree)
}
```

## Timberログステートメントを追加する

```kotlin:MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
  Timber.i("onCreate called")
}

override fun onStart() {
   super.onStart()
   Timber.i("onStart Called")
}
```

これでライフサイクルのログについては、一旦終了です。

## Fragmentのログについて

```kotlin:TestFragment.kt
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   Log.i("Test", "onCreate called")
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    Log.i("Test", "onViewCreated called")
}
```
以上となります。

参考サイト：
https://developer.android.com/studio/debug/am-logcat
https://github.com/JakeWharton/timber#download
https://qiita.com/hkusu/items/d4f24141d11e05f57451
時間計測を with 構文でするようにしてコードを綺麗にする

# 普通に計算する

Python コード内で時間を計測する場合、開始時点と終了時点で `time.time()` を呼び出し、その差分で秒数を計算します。

```python
import time

start_time = time.time()

# 処理
time.sleep(5)

print("{:.2f} sec".format(time.time() - start_time))
```

出力

```shell
5.01 sec
```

# 課題点

上記のやり方で問題があるわけではありませんが、時間計測が沢山必要な場合、計算ロジックを描くことで行数が増えますし、一時的な変数も増えます。

# with 内の時間を計算する

with の内部に入ったときに開始、出るときに終了を計測し、時間を表示するクラスです。

```python:tm.py
import time

class Timer:
    def __init__(self):
        pass

    def __enter__(self):
        self.time = time.time()

    def __exit__(self, ex_type, ex_value, trace):
        print("{:.2f} sec".format(time.time() - self.time))
```

使ってみた例

```python
import time

# 読み込み
import tm

with tm.Timer():
    # 処理
    time.sleep(3)
```

出力結果

```shell
3.00 sec
```
Node.js npmをインストールする時の備忘録

知識が少ない自分のための記事

Cordovaを使おうとnpmをインストールした際

ほとんどはこの記事のまま実行
[買いたてのＭacにNode.jsとnpmをインストール](https://qiita.com/taketakekaho/items/dd08cf01b4fe86b2e218)

実行パスを通すところの理解がたらず手間取ってしまった。

```
$ nodebrew setup
Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================
```

この

```
PATH=$HOME/.nodebrew/current/bin:$PATH
```
を使用して

```
$ echo 'export PATH=$HOME/.nodebrew/current/bin' >> ~/.bashrc
```
と 書き込む

いずれ理解を深めていきたい


###参考サイト
[nodebrewのセットアップ&操作方法(Mac)](https://qiita.com/uhooi/items/1fd481bfaf1459e29f6a)
VBoxでポートフォワーディングするときにはまった

## 背景
VirtualBoxを業務でも使うそうなのでvagrantを使わずにApatchを入れて自分でポートフォワーディングしてアクセスしようとしたときにハマったのでメモ

## 結論
仮想OSのファイヤーウォールの設定ができていなかった。

## 解決法
VBox側でポートフォワーディングは設定済み。Apatchの設定でもServerNameをlocalhost:80に設定
次にOSのファイヤーウォールを設定する。

```:console
$ firewall-cmd --zone=public --add-service=http --permanent
$ firewall-cmd --reload
$ firewall-cmd --list-all
```

これで一覧にhttpが表示されていれば80ポートでの通信も可能になる。

## 所感
Vagrantを使わないと気付くことがあって面白い。今までAWSをいじっていたのが幸いしたのか、ファイヤーウォールの設定をしなくてはいけないというのが腹落ちして問題解決できた。
Ubuntuがログインできない問題

##ログイン画面が繰り返される
*僕がいつも直している方法のメモです。

cudaのdriverエラーが起きている可能性が高い。
この時はログイン画面から

#####1.コンソールに入る
```
ctrl+alt+f4
```


#####2.古いドライバーの削除

```
sudo apt-get --purge remove nvidia-*
sudo apt-get --purge remove cuda-*
```

#####3.ドライバーの実行
自分のPCにあったドライバーをnvidiaの公式サイトからダウンロードする。
不具合がまた出る可能性があるのでダウンロードしたドライバーは保存しておいたほうがよい。
[nvidia公式サイト](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)

ダウンロードした実行ファイルを実行

```
./Nvidia-Linux-x86-64-(番号).run
```

#####4.これでエラーが出る場合
GUIを停止させるため

```
sudo service lightdm stop
```

これを実行してから、もう一度ダウンロードした実行ファイルを実行する。

####それでもできない場合

```
sudo /usr/bin/nvidia-uninstall
```

これで完全にuninstallされる

####それでもできない場合2

```
sudo lsof -n -w /dev/nvidia*

kill -9 [PID]
```
mock化まとめ - 初心者用 -

#はじめに
初めて記事を書きます。ここ一か月弱、ずっと単体テストを書いていたのでその備忘録。
モック化についてまとめたいと思います。

#####18日担当者の簡単なプロフィール
- 今年からプログラミングのバイトを始めた
- 完全な初心者に毛が生えた程度

よって、この記事は単体テストに困っている初心者向けのものとなっております。

##モック化とは？
まずはここから行きたいと思います。
そもそもモック化とは、単体テストを書くときのハリボテのようなものです。（そう言う風に私はまず習った・・・と思いたい。記憶違いだったらごめんなさい。）

例えば、テストを書いている時にこんな問題があったとします。
- コードが未実装
- そもそも処理が膨大

これをいちいち気にしていたら、大変ですよね？
って言うことで、mock化をしてとりあえずハリボテにしちゃって部品として使えるようにしようぜ！って言う話です。少なくとも私はそう言う風に認識しております。

mock化は便利ですけど、忘れちゃいけないのはverifyです。
これで、mock化をしたのはいいが、きちんと呼び出されているのか・・・！？という問題を解消できます。
きちんと呼び出し検証はやりましょう！（自分にも言い聞かせながら）


##publicメソッドのモック化
全てmock化していい場合はこっち

```
Smaple Smaple = mock(Smaple.class);
```
インスタンスだけmock化したい時はこっち

```
Smaple Smaple = spy(new Smaple());
```

値を入れていく。

```
//戻り値がある場合
doRutrn(hoge).when(hoge).method();
when(hogClass.method()).thenReturn();

//戻り値がない場合
doNothing().when(hoge).method();
```

mock化したら、値の確認を行う。

```
assertThat(hoge, is(hoge));

//nullの場合
assertThat(hoge, nullValue());

//listの場合
assertThat(list.get(0), is(hoge1));
assertThat(list.get(1), is(hoge1));
:

```
こんな感じでやっていく。
基本的にmock化したものは全て確認すべき。mock化しただけでは意味がないことに注意。



最後に呼び出し検証を行う。

```
verify(hoge）.method();

//何回呼び出されていたのか検証する場合
verify(hoge, times(num)）.method();
```
##privateメソッドのモック化
privateメソッドであれば、上記のやり方ではできないため、注意。

まずインタンスを作る。

```
Sample　mockInstance= PowerMockito.mock(Sample.class);

//spyのとき
PowerMockito.spy(Sample.class);	
```

次にmock化。

```
PowerMockito.doReturn(hoge).when(Smaple.class, "sampleMethod");
PowerMockito.doReturn(hoge).when(Smaple.class, "sampleMethod2", hoge, hoge);

//戻り値がない場合
PowerMockito.doNothing().when(Smaple.class, "sampleMethod");
```

値の確認を行った後、verifyで呼び出し検証を行う。
そのやり方は以下の通り。

```
verifyPrivate(Sample).invoke("sampleMethod");
verifyPrivate(Sample).invoke("sampleMethod2", hoge, hoge);
```

##staticメソッドのモック化

インスタンスを作って、実行するまで。

```
 PowerMockito.mockStatic(Smaple.class);

//実行
when(Smaple.method()).thenReturn(hoge);
```

値の検証をした後、verifyで呼び出し検証を行う。

```
PowerMockito.verifyStatic();	
Sample.method();
```

##newをモック化する方法
newのmock化は方法が二つある。

####①PowerMockitoを使って行う

```
//引数がない場合
PowerMockito.whenNew(Sample.class).withNoArguments().thenReturn(hoge);
//引数がある場合
PowerMockito.whenNew(Sample.class).withArguments().thenReturn(hoge);
//戻り値がない場合
doNothing().when(Smaple.class).persist(any(Object));
```

setされているものがある場合はassertThatで値の確認をすることを忘れないようにする。

####②caputerを使う

caputerの使い方は以下の通り

```
ArgumentCaptor<Sample> captor = ArgumentCaptor.forClass(Smample.class);
doNothing().when(hoge).persist(captor.capture());
```

また、次のようにやれば値が取れるようになる。

```
captor.getValue();
captor.getAllValues();
```
これを使って、assertThatで検証。

##おわりに
いかがでしたでしょうか？
自分がやっていて困ったところも含めて記事にしております。
これが誰かのお役に立てれば、そんなに嬉しいことはありません。

また、このようなまとめて整理する機会をくださった先輩に謝辞を改めて申し上げます。
GitHub CLIを使う方法

#はじめに
おはようございます。こんにちは。こんばんは。
Watatakuです。
今回は、GitHub CLIが登場したという事で早速使って行こうという記事です。
**<font color="red">※この記事はmacを使っての解説です。</font>**

#GitHub CLIとは
公式がリリースしたGitHubがコマンドラインツール。
[https://github.com/cli/cli](https://github.com/cli/cli)

#インストール
brewでインストールできます。

```console
$ brew install gh
```
インストールが完了すると``gh``コマンドが使えます。
お察しだと思いますが、``gh``コマンドが今回の主役です。

```
Work seamlessly with GitHub from the command line.

USAGE
  gh <command> <subcommand> [flags]

CORE COMMANDS
  gist:       Manage gists
  issue:      Manage issues
  pr:         Manage pull requests
  release:    Manage GitHub releases
  repo:       Create, clone, fork, and view repositories

ADDITIONAL COMMANDS
  alias:      Create command shortcuts
  api:        Make an authenticated GitHub API request
  auth:       Login, logout, and refresh your authentication
  completion: Generate shell completion scripts
  config:     Manage configuration for gh
  help:       Help about any command
  secret:     Manage GitHub secrets

FLAGS
  --help      Show help for command
  --version   Show gh version

EXAMPLES
  $ gh issue create
  $ gh repo clone cli/cli
  $ gh pr checkout 321

ENVIRONMENT VARIABLES
  See 'gh help environment' for the list of supported environment variables.

LEARN MORE
  Use 'gh <command> <subcommand> --help' for more information about a command.
  Read the manual at https://cli.github.com/manual

FEEDBACK
  Open an issue using 'gh issue create -R github.com/cli/cli'
```

#認証
最初に自分のGitHubアカウントと連携するために認証が必要です。

```console
$ gh auth login
```
するといくつか認証のための質問がるので答えます。

```
? What account do you want to log into?  [Use arrows to move, type to filter]
> GitHub.com
  GitHub Enterprise Server
```
どのアカウントにログインしますか？と聞かれています。自分は``GitHub.com``です。

```
? How would you like to authenticate?  [Use arrows to move, type to filter]
> Login with a web browser
  Paste an authentication token
```
日本語にすると以下です。

```
？ どのように認証しますか？ [矢印を使用して移動し、入力してフィルタリングします]
> Webブラウザでログインします
   認証トークンを貼り付けます
```
自分はwebブラウザでログインします。

コマンドライン上に認証コードが表示されるので、
Enterキーを押してブラウザを起動します。
そのブラウザに先程の認証コードを入力します。

その後再び、質問が続けられるので答えていきます。
まずデフォルトのgitプロトコルを選択します。
``HTTPS``でいいでしょう。
最後に、GitHubの認証情報でGitを認証しますか？を``yes``

これで,自身のGitHubアカウントとの連携ができました。

ここまでできるとブラウザを開いてマウスカーソルで操作する必要がなくなり最高に便利です。
新しくリポジトリを作成する時や過去のプルリクエストの検索の際などに、いちいちブラウザを開いて集中力を途切れさせる必要はありません。そのままエディタ、ターミナルと向き合えば良いのです。

[こちら](https://github.com/watataku8911/github-cli-test/blob/master/README.md)に主要コマンドをまとめているのでご参照ください。

以上。
[GitHubブログ](https://github.blog/jp/2020-09-18-github-cli-1-0-is-now-available/) ←参照
free5GC stage1 のDBをクエリする

free5GC stage1 を用いてSubscriberを登録し、その情報を保持するMongoDBにクエリを行い、情報を確認します。


# Subscriberの情報

| |Suscriber1 |Subscriber2 |
| ---- | ---- |---- |
IMSI | 208930100001111 | 208930100001112 |
Subscriber Key(Ki) | 8baf473f2f8fd09487cccbd7097c6862 | 8baf473f2f8fd09487cccbd7097c6862 |
Operator Key(OPc) | e734f8734007d6c5ce7a0508809e7e9c | e734f8734007d6c5ce7a0508809e7e9c |
USIM Type | OPc |  OPc |
APN | internet |  internet |

# MongoDBにアクセスし、クエリを行う

```
$ mongo
switched to db free5gc
> show collections
accounts
sessions
subscribers
> db.subscribers.find() 
{ "_id" : ObjectId("5fd6a7a7f3ea3d009b16d045"), "imsi" : "208930100001111", "pdn" : [ { "apn" : "internet", "_id" : ObjectId("5fd6a7a7f3ea3d009b16d046"), "pcc_rule" : [ ], "qos" : { "qci" : 9, "arp" : { "priority_level" : 8, "pre_emption_vulnerability" : 1, "pre_emption_capability" : 1 } }, "type" : 2 } ], "ambr" : { "downlink" : NumberLong(1024000), "uplink" : NumberLong(1024000) }, "subscribed_rau_tau_timer" : 12, "network_access_mode" : 2, "subscriber_status" : 0, "access_restriction_data" : 32, "security" : { "k" : "8baf473f2f8fd09487cccbd7097c6862", "amf" : "8000", "op" : null, "opc" : "e734f8734007d6c5ce7a0508809e7e9c" }, "__v" : 0 }
{ "_id" : ObjectId("5fd6a7b5f3ea3d009b16d047"), "imsi" : "208930100001112", "pdn" : [ { "apn" : "internet", "_id" : ObjectId("5fd6a7b5f3ea3d009b16d048"), "pcc_rule" : [ ], "qos" : { "qci" : 9, "arp" : { "priority_level" : 8, "pre_emption_vulnerability" : 1, "pre_emption_capability" : 1 } }, "type" : 2 } ], "ambr" : { "downlink" : NumberLong(1024000), "uplink" : NumberLong(1024000) }, "subscribed_rau_tau_timer" : 12, "network_access_mode" : 2, "subscriber_status" : 0, "access_restriction_data" : 32, "security" : { "k" : "8baf473f2f8fd09487cccbd7097c6862", "amf" : "8000", "op" : null, "opc" : "e734f8734007d6c5ce7a0508809e7e9c" }, "__v" : 0 }
Docker環境でMySQLのログを確認する

まず、dockerのMySQLコンテナに入ります。
MySQLサーバにログインして、以下のように`general_log`の位置を確認します。

```
mysql> show variables like 'general_log%';
+------------------+---------------------------------+
| Variable_name    | Value                           |
+------------------+---------------------------------+
| general_log      | OFF                             |
| general_log_file | /var/lib/mysql/55ca40b8744.log |
+------------------+---------------------------------+
2 rows in set (0.00 sec)
```

`OFF`になっているので、`ON`にします。
こうしないとファイルが出現しないようです。

```
mysql> set global general_log = on;
Query OK, 0 rows affected (0.01 sec)
```

MySQLからぬけて、`var/lib/mysql`に移動します。ここのファイルの内容を参照すれば見れます。

```
root@55ca40b8744e:~# cd /var/lib/mysql
root@55ca40b8744e:/var/lib/mysql# cat 55ca40b8744.log 
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
2020-12-18T17:18:27.044729+09:00	   26 Quit
```

先ほど MySQLのサーバを抜けたので、Quitしたと出ています。

試しに`delete`したときのログは以下のように出ます。

```
2020-12-18T17:02:09.716428+09:00	   67 Prepare	DELETE FROM `TABLE` WHERE `table`.`id` = ?
2020-12-18T17:02:09.716513+09:00	   67 Execute	DELETE FROM `TABLE` WHERE `table`.`id` = 0
```
「プログラムでシダを描画する」をなでしこで描画する

2015年に空前のシダ描画ブーム到来して以来、私たちは『何か』を待っていました。それが何かはそのときは分かりませんでした。しかし、2020年の年末ついにその『何か』が明らかになりました。

それは・・・なでしこでシダを描画したかったんです！

- (元ネタ) https://qiita.com/qt-luigi/items/b22204c7ef73260324bd

こんな風に描画できます！

![sida.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/610e93be-a033-d36f-33eb-214c84d7e01c.png)

# 手っ取り早く動かしたい方は

 - [こちら](https://nadesi.com/v3/storage/id.php?370)で実際にWebブラウザ上で実行できます

# なでしこv3のプログラム

もし余力があれば、以下のプログラムを、[なでしこv3のエディタ](https://nadesi.com/v3/storage/index.php?page=new&action=show)に貼り付けて実行してみてください。キャンバスは500x550に設定すると全体が描画されます。

```シダ.nako3
# 「プログラムでシダを描画する」
N = 20
xm = 0
ym = 0.5
h = 0.6

width = 500
height = 500

W1x = 関数(x, y) それは、0.836 * x + 0.044 * y。ここまで。
W1y = 関数(x, y) それは、-0.044 * x + 0.836 * y + 0.169。ここまで。
W2x = 関数(x, y) それは、-0.141 * x + 0.302 * y。ここまで。
W2y = 関数(x, y) それは、0.302 * x + 0.141 * y + 0.127。ここまで。
W3x = 関数(x, y) それは、0.141 * x - 0.302 * y。ここまで。
W3y = 関数(x, y) それは、0.302 * x + 0.141 * y + 0.169。ここまで。
W4x = 関数(x, y) それは、0。ここまで。
W4y = 関数(x, y) それは、0.175337 * y。ここまで。

●(kのxとyで)fとは
　　もし、0 < kならば
　　　　f(k - 1, W1x(x, y), W1y(x, y))
　　　　もし、(10の乱数) < 3ならば
　　　　　　f(k - 1, W2x(x, y), W2y(x, y))
　　　　ここまで。
　　　　もし、(10の乱数) < 3ならば
　　　　　　f(k - 1, W3x(x, y), W3y(x, y))
　　　　ここまで。
　　　　もし、(10の乱数) < 3ならば
　　　　　　f(k - 1, W4x(x, y), W4y(x, y))
　　　　ここまで。
　　違えば
　　　　s = 490
　　ここまで。
　　XX = INT(x * s + width * 0.5)
　　YY = INT(height - y * s)
　　[XX, YY, 1, 1]へ四角描画。
ここまで。

「少し実行まで時間がかかります。気長に待ってね。」と表示。
C=RGB(0,129,0)
1に線太設定。Cに線色設定。Cに塗色設定。
1秒後には
　　f(N, 0, 0)
ここまで。
```

# まとめ

「え？！もっと日本語プログラミングっぽく書きたい？！」って？！
もちろん、もうちょっと自然な日本語のプログラムになります。
当然、変数名とか日本語がいいですよね？

というのも、これは他の言語のシダを移植しただけですからね。

きっと、若者たちが、シダをもっと日本っぽくしてくれるでしょう。
私はそれを待つことにします。
Nuxt(Vue)でツイートを埋め込みたい(埋め込みウィジェット, vue-tweet-embed)

この記事は「[株式会社オープンストリーム "小ネタ" Advent Calendar 2020](https://qiita.com/advent-calendar/2020/opst-mini)」の 17 日目の記事です。

以前、Nuxt(Vue)に Twitter のツイートを埋め込むときは vue-tweet-embed のパッケージを使うとよさそうと考えましたが、 うまくいかないときがあったので諦めてました。

確かめる機会ができたのでここにまとめます。

## 環境

- Nuxt.js 2.14.9
- Storybook 6.0.10

```
$ node -v
v14.5.0

$ yarn -v
1.22.5
```

## 通常通りツイートを埋め込む

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216963/f46d75dc-7c82-c6de-daf5-55a3f488030a.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216963/a23c1b11-9e65-d81f-ed9a-bd1507ea6e11.png)


Twitter のコードを使ってツイートを埋め込むときは次の 2 つの情報が必要になります。

- screen_name
- tweet の id

DB のテーブルに `id` しか保存していない場合は、別のテーブルから `screen_name` を持ってこなければならないので厄介です。

また、埋め込み用コードのほかに https://platform.twitter.com/widgets.js のスクリプトを読み込む必要があり、読み込む位置によって SPA でページ遷移した後の挙動がおかしくなるなど注意が必要です。

私もスクリプトをねじ込んでツイートを埋め込みましたが、こちらのコードのほうが SPA でのページ遷移が考慮されているため紹介します。

Nuxt.js で Twitter シェアボタンやツイートの埋め込みなどの widgets を追加する方法 | mintsu's blog
https://blog.mintsu-dev.com/posts/2020-05-23-nuxt-spa-twitter-share/

## vue-tweet-embed を使う

初めに使ったのは [vue-tweet-embed](https://www.npmjs.com/package/vue-tweet-embed) です。screen_name が不要でツイートの ID だけで埋め込み表示までできるため結構重宝しました。

```bash
yarn add vue-tweet-embed
```

最初のうちはきちんとツイートが埋め込みで表示されてたのですが、README の方法で記述するとうまくいきません。

```vue
import Tweet from 'vue-tweet-embed/tweet'
```

現在の `vue-tweet-embed` だと `yarn dev` ができますが、コンパイルで次のエラーが出ます。

> This dependency was not found:
>
> - vue-tweet-embed/tweet in ./node_modules/babel-loader/lib??ref--12-0!./node_modules/ts-loader??ref--12-1!./node_modules/@nuxt/components/dist/loader.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/index.vue?vue&type=script&lang=ts&

`vue-tweet-embed` が古いなどプロジェクトの構成によっては次のエラーが出て `yarn dev` すらできなくなります。

> warning nuxt > @nuxt/webpack > @nuxt/babel-preset-app > core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core
> -js@3.
> error eslint@6.7.2: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "11.4.0"
> error Found incompatible module.

当時は解決できなくて 1-2 年ぐらい放置していたのですが、次の方法でうまくいきました。

```vue:
import { Tweet } from 'vue-tweet-embed'
```

また、Tweet コンポーネントを読み込めても"Whoops! We couldn't access this Tweet. "が表示される場合は、ツイートの ID が JavaScript の仕様で丸められた可能性があります。
この場合は Twitter API でいう `id_str` を ID として使います。

このパッケージは 2020/12/16 現在で Last publish が a year ago になっているため、今後更新されない場合は先ほどの通常通りな方法を試すしかないようです。

### TypeScript で使用する場合は自分で d.ts を作る必要がある

TypeScript を使ったコンポーネントで `vue-tweet-embed` 使うと型がないというエラーがでます。npm で型定義ファイルがないので自分で作る必要があります。

any 型とみなして良いのであれば次の内容で d.ts ファイルを作ります。そうでなければ `vue-tweet-embed` のパッケージからソースコードを自分で読んで自分で型を定義します。。。

```ts:types/vue-tweet-embed.d.ts
declare module "vue-tweet-embed";
```

作成した d.ts を使うように tsconfig.json の `compilerOptions` で `typeRoots` を追加します。

```ts:tsconfig.json
{
  "compilerOptions": {
    "typeRoots": ["types"],

```
ぴえん🥺かどうか判定するクソアプリをつくった

どうも、株式会社メイクリーの黒神（@kokushing）と申します。
クソアプリ2 Advent Calendar 2020 18日目の投稿です。

## 作ったもの

写真に写っている顔が「ぴえん🥺」かどうかを判定するクソアプリです。

[🥺 pien-chekcer](https://pien.netlify.app/)

画像を選択すると、顔を検出し、ぴえんかどうかを判定します。

![スクリーンショット 0002-12-18 午後5.24.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57867/037cee2d-02e9-cb63-060b-816e82d5a4ec.png)

ぴえんスコアが90を超えると「ぱおん🐘」になります。

![スクリーンショット 0002-12-18 午後5.20.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57867/0fbf35e9-36ca-0059-8fd7-658547df65fa.png)

判定はけっこうガバガバです。

## 経緯

今年も[昨年](https://qiita.com/kokushin/items/253ef1d5bd90d4c68d14)に引き続き、face-api.jsというtensorflow.jsを用いたJavaScriptライブラリを利用しようということでパッと思いついたのがこのクソアプリです。

ぶっちゃけ5秒で思いつきました。
これくらいのスピード感がクソアプリ開発には必要ですよね（謎）

最初は手書きHTMLからソースコードを書き起こしてWebサイト作れるクソアプリを作っていましたが、真面目すぎるな〜と思い転向しました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">手書きテキストからソースコード生成するクソアプリ作ってる <a href="https://t.co/cC2ESsvCxH">pic.twitter.com/cC2ESsvCxH</a></p>&mdash; 黒神 / makery, inc CEO (@kokushing) <a href="https://twitter.com/kokushing/status/1333858363185131522?ref_src=twsrc%5Etfw">December 1, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">tensorflow使ってぴえんかどうかを判定するクソアプリつくってる <a href="https://t.co/fKEce1pyRW">pic.twitter.com/fKEce1pyRW</a></p>&mdash; 黒神 / makery, inc CEO (@kokushing) <a href="https://twitter.com/kokushing/status/1335126590833844225?ref_src=twsrc%5Etfw">December 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

あと余談なんですが、 [三省堂 辞書を編む人が選ぶ「今年の新語2020」](https://dictionary.sanseido-publ.co.jp/shingo/2020/)の大賞は「ぴえん」らしいですよ。めでたい。

## 実装

React.js、TypeScript、face-api.js、react-dropzone、styled-componentsで実装しました。
画像のダウンロードにはhtml2canvasというライブラリを利用しています。
インフラはNetlify先輩。Vercel先輩も気になっているので今度試します。

このクソアプリの仕組みは単純で、react-dropzoneで受け取った画像データをface-api.jsで解析し、顔の表情を数値として取得します。

あとは数値によって結果を変えるだけ。シンプルですね。

悲しい顔の数値を取得するには下記のように書くと取得できます。

```js
(async () => {
  const inputEl = document.getElementById("input") as HTMLImageElement;
  const MODEL_URL = `${process.env.PUBLIC_URL}/models`;
  await faceapi.nets.tinyFaceDetector.load(MODEL_URL);
  await faceapi.nets.faceExpressionNet.load(MODEL_URL);

  const detectionsWithExpressions = await faceapi
    .detectAllFaces(inputEl, new faceapi.TinyFaceDetectorOptions())
    .withFaceExpressions();

  const score =
    detectionsWithExpressions.length > 0
      ? detectionsWithExpressions[0].expressions.sad
      : -1;

  console.log(score); // 悲しみの数値を取得
})();
```

## あとがき

本当はOG画像とかSSRしてTwitterでシェアできるようにしたかったんですが、時間の都合で断念しました。

ぴえん🥺

## Photo by
[ぱくたそ](https://www.pakutaso.com/20200253041post-25758.html)
[パブリックドメインQ](https://publicdomainq.net/little-girl-crying-tears-0019532/)
double型とfloat型について（違い）

#####データ型にはいろいろありますがdouble型とfloat型について説明してください！と言われて答えられなかった、、、
データ型について聞かれた際、説明できなかったことを反省して「データ型について」、「double型とfloat型の違いについて」いろいろなものを参考にして調べてわかったことを整理してまとめてみました。

#〜型って何？
double型とfloat型というような「〜型」とは、「変数の型」や「データ型」と言い、変数（プログラミングにおける値を入れておく箱）の種類の一つです。箱（変数）にどんな種類の物を入れるかということを決めます。
種類としては文字列型や整数型、浮動小数点型など他にもいろいろあります。

例えば、箱があったとして、Aさんがその箱に数字用というラベルを貼ります。
すると、数字しか入れてはいけなくなるため数字用という箱に文字を入れると怒られます。

この話における箱が「変数」で、ラベルの「数字用」というのが「変数の型」になります。


#double型とfloat型の違は？

double型は倍精度浮動小数点型と言い、上の例に当てはめると箱が「double型の変数」で箱に貼るラベルが「小数用（変数の型）」となり「この箱には（有効桁数の大きい）小数を入れて良いですよ」ということになります。

float型は単精度浮動小数点型と言い、double型の仲間です。
double型とfloat型どちらも「小数を入れて良いですよ」ということになります。

####じゃあ、何が違うのか？
####結論：double型とfloat型の違いは、箱の大きさです！！！
double型の方が箱が大きく、より有効桁数の大きい（小数点以下が細かい）数字を入れることができます。

箱が大きいということは、それだけ場所を取るため、小さい物しか入れない時はfloat型を使い、float型で入らない場合はdouble型を使用するような使い分けをします。
【Android】Image Asset Studio でアプリアイコンを作成する方法

#プログラミング勉強日記
2020年12月18日
Android Studioでアイコンを作ることができるのを知ったのでその方法をまとめる。

#Image Asset Studio でアプリアイコンを作成する

##1. `ファイル(File)`→`新規(New)`→`画像アセット(Image Asset)`を開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/e2da860c-3e2d-65fe-1acf-46769143bcc7.png)


##2. 好きなようにアイコンを作成する
　アイコンタイプ(Icon Type)は`Launcher Icons (Adaptive and Legacy)`を選択する。テキストの色とフォントを変更するオプションがあるので自由に変更する。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/268e2c75-1ace-7ed7-ab97-adde3177280e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/33bf9814-42f6-6805-8ffb-2cc9f119cc8e.png)


##3. アイコンを作成したら`次へ(Next)`→`完了(Finish)`を押す
　`次へ(Next)`を押すとファイル作成のプレビューが見れる。`完了(Finish)`でファイルが作成される。

プレビュー画面↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/ee1ee23e-63ed-c39f-f245-4d1f804c93d5.png)

#注意

　<b>Adaptive Icon</b>：foregroundとbackground画像をアプリが提供すれば、システムがこの2つの画像を組み合わせて使用する概念
　<b>Legacy Icon</b>：Adaptive Iconが出る前のアイコン

　Adaptiveアイコンは<b>AndroidのO(API 26)以上</b>で動作し`mipmap-anydpi-v26/ic_launcher.xml`でVectorに実装されているため、解像度ごとに画像ファイルを作成する必要がない。そのため、AndroidのO(API 26)未満のバージョンではLegacyアイコンを提供する必要がある。



#参考文献
[Image Asset Studio を使用してアプリアイコンを作成する](https://developer.android.com/studio/write/image-asset-studio?hl=ja)
[アンドロイドスタジオでは、Adaptive、一般のアイコンを作成](https://codechacha.com/ja/generate-icons-in-android-studio/)
レガシー環境用のTLS1.2対応リバースプロキシを golang で簡単に作る

## はじめに
CentOS5 などのレガシーシステムでは TLS1.2 が利用できません。
OSバージョンアップや別サーバで Reverse Proxy を構築するのが一般的ですが結構な手間です。
そこで今回は、golang でちょちょいと TLS1.2 対応の Reverse Proxy を実装します。

## やってみよう

#### 必用なもの
* golang v1.9以前（※ レガシーシステムではv1.9以前でコンパイルしないと動きません）

#### やりかた
golang ならわずか10行くらいのロジックでリバースプロキシができちゃいます。

```go:main.go
package main

import (
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
)

func main() {
	// プロキシしたいレガシーサーバのURL
	target, _ := url.Parse("http://localhost:80")
	// シングルホストの場合はこれだけでOK
	proxy := httputil.NewSingleHostReverseProxy(target)
	// ハンドラ内でヘッダーを設定してプロキシする
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		r.Header.Set(`X-Forwarded-Host`, r.Header.Get(`Host`))
		r.Header.Set(`X-Forwarded-Proto`, r.URL.Scheme)
		proxy.ServeHTTP(w, r)
	})

	// TLS1.2でListen
	err = http.ListenAndServeTLS(":443", "path to ssl cert", "path to ssl key", nil)
	if err != nil {
		log.Fatal(err)
	}
}
```

また、http.HandlerFunc()内では、以下のように Request Header も設定できます。
レガシーサーバ側が X-Forwarded-Proto などに対応していない場合は、Request をゴニョゴニョやって対応しましょう！

```go:
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		r.Header.Set(`X-Forwarded-Host`, r.Header.Get(`Host`))
		r.Header.Set(`X-Forwarded-Proto`, r.URL.Scheme)
		r.URL.Host = target.Host
		r.URL.Scheme = target.Scheme
		proxy.ServeHTTP(w, r)
	})

```
初学者必見！Headerにある項目を動的に変化させる方法

今回は、ログインしている時だけ「ログアウト」ボタンを表示させたいと思ったので、そのやり方を備忘録として書いていきます。

最後まで見て、よかったらLGTMお願いします！！（今じゃなくていいです）

<br>

それでは順を追って説明します。

<br>



Vuexの機能を使い、sotre/index.jsのstateにユーザーがログインしているかを判断するauthを設定します。

```store/index.js

import Vue from "vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate";

Vue.use(Vuex);

export default new Vuex.Store({
  plugins: [createPersistedState()],  //永続的にログインできるプラグイン
  state: {
    auth: "", //userがログインしているか
    user: "", //user情報
  },
)}
```

vuex-persistedstateについては[こちら](https://qiita.com/akki-memo/items/7bacb897e50025d23b76)の記事でご紹介しているので、ぜひご覧ください。

次に、computedを使って、authの変更を検知します。
computedは**自動で値の変更を検知**してくれるので大変便利です。


```components/Header.vue
<div class="headB" :class="{'open' : isClass}">
          <ul>
            ～
            <li>
              <a @click="logoutButton" v-if="auth === true">ログアウト</a>
              <a @click="loginButton" v-else>ログイン</a>
            </li>
          </ul>
 </div>

<script>
export default{
    computed: {
      auth() {
        return this.$store.state.auth;  //store/index.jsのstateにあるauthを取得
      }
    },
}
</script>
```

これでログインしているときにログアウトが表示されるようになります。

これはHeaderだけでなく、他にも応用できそうですね。

以上、「Headerにある項目を動的に変化させる方法」でした。
【MicroPython】ESP32で入力フォームを作成

## はじめに
ESP32 MicroPythonでWi-FiアクセスポイントとWebサーバーを立ち上げ入力フォームページを作成してみました．
↓こんな感じ
![esp32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/794860/5b6087c5-29f0-f31d-9573-48d2b8a7223b.png)
## 前提条件
- ESP32-WROOM-32
- MicroPython v1.13

## プログラム


```Python:main.py
import socket
import network
import ssl
import re

ESSID = "ESP32"
PASSWORD = "ESPWROOM32"
IP = "192.168.5.1"

def wifi(essid, pwd, ip, mask, gw, dns):
    ap = network.WLAN(network.AP_IF)
    ap.config(essid = essid, authmode = 3, password = pwd)
    ap.ifconfig((ip,mask,gw,dns))
    # print("(ip,netmask,gw,dns)=" + str(ap.ifconfig()))
    ap.active(True)
    return ap

wifi(ESSID, PASSWORD, IP, '255.255.255.0', IP, '8.8.8.8')

def web_page():
    html = """
    <html lang = "ja">
    <head>
    <title>test</title>
    <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" href="data:,">
    <style>
    </style>
    </head>
    <body>
    <h1>test page</h1>
    <h2>入力フォーム</h2>
    <form action = "" method = "GET">
    <p><input type="text" name="test" size="40"></p>
    <p><input class="button" type="submit" value="送信"></p> 
    </form>
    </body>
    </html>
   """
    return html

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)

while True:
    conn, addr = s.accept()
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    request = str(conn.recv(1024)).lower()
    # print("request : "+  request)
    m = re.search(r'test=(\w+)', request)
    if m != None :
        word = m.group(0)
        print(word[5:])
    conn.close()

```

### コード解説

- ```def wifi(essid, pwd, ip, mask, gw, dns)```<br>
Wi-Fiアクセスポイントを立ち上げ
- ```s.bind(('', 80))```<br>
HTTPポート80番で接続を待機
- ```m = re.search(r'test=(\w+)', request)```<br>
クライアントの入力データを取得
- ```word = m.group(0)```<br>
入力データを変数に入れる

## 実行
スマホなどからESP32のアクセスポイントに接続しブラウザで```192.168.5.1```にアクセスしてください．

## おわりに
おわりです．
【初心者】PHPで配列の重複を削除する

## array_uniqueを使ってみる。
配列内で同じ値があって、それを削除したい！
いきなりそんなことを思うなんてことはないでしょう。
ただ、私がそんな事態に直面してしまったのか、他に方法があったのかわからないが、これを使うことによって一つ問題を解くことができたので、良かった。というだけのことです。
例えば…

```php
$array = ["A", "D", "A", "G", "B", "C", "B"];
```
こんな配列があったとしましょう。
この配列内で重複したものを削除したいと思った時、

```php
array_unique(配列);
```
これを使ってみます。
print_r関数で出力しみます。すると、

```php
$array = ["A", "D", "A", "G", "B", "C", "B"];
print_r(array_unique($array));
// 以下出力結果です。
Array
(
    [0] => A
    [1] => D
    [3] => G
    [4] => B
    [5] => C
)
```
このような出力結果となりました。
この状態だと、見てお分かりだと思いますが配列のキーが飛び飛びになってしまいます。
せっかくなので、この配列のキーもきちんとしてしまいましょう。
## array_valuesも使ってみる。

```php
array_values(配列)；
```
この関数を使うとこのようになります。

```php
print_r(array_values(array_unique($array)));
// 以下出力結果です。
Array
(
    [0] => A
    [1] => D
    [2] => G
    [3] => B
    [4] => C
)
```
これで色々なことに使える形になったような気がします。

今回の学びは私にとって大きな一歩になったような気がします。
SQL文簡単なまとめ

##SQL文の基礎
###データの取得(SELECT)
データを取得する。

```
列を指定して取得
SELECT 列1, 列2, … FROM テーブル名;

全ての列を指定して取得
SELECT * FROM テーブル名;
```

###列に別名をつける(AS)
「列名 as 付けたい名前」とすることで、列に別名をつけられる。

```
SELECT name AS 名前, age AS 年齢 FROM users;
```

###条件を指定してデータを取得(WHERE)
WHEREを使って条件を指定する。

```
SELECT 列1, 列2, … FROM テーブル名 WHERE 条件;
```

###比較演算子

```
= 等しい
> より大きい
>= 以上
< より小さい
<= 以下
<> 等しくない
!= 等しくない
in ある値が含まれているか
not in ある値が含まれていないか
is null 値がnull
is not null 値がnullではない
like パターンマッチング,あいまい検索
between A and B 値がAとBの間に含まれているか
```

###パターンマッチング
ワイルドカード文字(%,_)を使って文字列のパターンを指定する。

```
% 0文字以上の任意の文字列
_ 任意の1文字

'り%' りで始まる文字列 りんご
'%菜%' 菜を含む文字列 野菜ジュース
'%ト' トで終わる文字列 デザート
'___ケーキ' 何か3文字で始まり、ケーキで終わる文字列 いちごケーキ

```

###取得件数を制限(LIMIT)
LIMITを使って取得件数を絞る。

```
OFFSET使う場合
SELECT 列1, 列2, … FROM テーブル名 LIMIT 行数 OFFSET 開始位置;
OFFSET使わない場合
SELECT 列1, 列2, … FROM テーブル名 LIMIT 開始位置, 行数;
```


##データの追加・更新・削除(INSERT,UPDATE,DELETE)
INSERTでデータを追加する

```
INSERT INTO テーブル名 (列1, 列2, …) VALUES (値1, 値2, …);

列を省略してINSERTする場合 *テーブルの全列に値指定する必要あり
INSERT テーブル名 VALUES (値1, 値2, …);

複数行に同時にINSERTする場合
INSERT INTO 
  テーブル名 (列1, 列2, …) 
VALUES 
  (値1, 値2, …),
  (値1, 値2, …),
  (値1, 値2, …);
```
UPDATEでデータを更新する。

```
UPDATE テーブル名 SET 列1 = 値1, 列2 = 値2,… WHERE 条件式;
```

DELETEで行を削除する。

```
DELETE FROM テーブル名 WHERE 削除条件;
```

##データの集約
###集約関数

|集約関数|説明|
|:---:|:---:|
|SUM()|合計を返す|
|AVG()|平均を返す|
|MAX()|最大値を返す|
|MIN()|最小値を返す|
|COUNT()|個数を返す|

count(*)でテーブルの行数を取得できる

###データをグループ化(GROUP BY)
GROUP BYで列名を指定してグループ化する

```
SELECT
  列名
FROM
  テーブル名
GROUP BY 
  列名;
```

###集約結果に対して条件を指定(HAVING)
集約結果をさらに絞る場合にHAVINGを使用する

```
SELECT
  列名
FROM
  テーブル名
WHERE
  条件式
GROUP BY 
  列名
HAVING
  条件式;
```

##データの並び替え(ORDER BY)
ORDER BYで指定した列を並び替える

```
ORDER BY 列名,式,並び順,…

ASC 昇順(デフォルト)
DESC 降順
```

##データの結合

##サブクエリ
条件をさらに絞り込む。

```
SELECT
  列名,…
FROM
  テーブル名
WHERE
  列名 演算子(SELECT 列名 FROM テーブル名 …);
```

##条件分岐(CASE)
条件によって返す値を変える。

```
case
  when 条件式1 then 値1
  when 条件式2 then 値2
  else 値3
end
```

##データベース操作
###データベースの追加
データベースを新たに追加する。

```
CREATE DATABASE データベース名;
```
###データベースの削除
データベースを削除する。

```
DROP DATABASE データベース名;
```
###テーブルの追加
テーブルを新たに追加する。

```
CREATE TABLE テーブル名(列名1 データ型や順序など,列名2 データ型や順序など, …);
```
###テーブルの削除
テーブルを削除する。

```
DROP TABLE テーブル名;
```
###列名の削除
列を削除する。

```
ALTER TABLE テーブル名 drop 列名;
```
IEのキャッシュフォルダをやっつける

# 何をしたいか
IEのキャッシュが嫌い（様々な意味を含む）なので、リモートコンピュータのIEキャッシュフォルダを始末したい。



# 対象フォルダ
`ユーザーフォルダ\AppData\Local\Microsoft\Windows\WebCache`
`ユーザーフォルダ\AppData\Local\Microsoft\Windows\INetCache`
どっちもシステム属性・隠し属性を消してから手を出す。

# 書いたもの
削除だとキャッシュが多かった場合に思わぬ時間をとられるので、リネームにした。
実行する自分は相手を管理できるユーザーでないとならない。
また、当該PCにログオン中のユーザーには手を出せないのでエラーになる。

```powershell:IECache_Clear_Remote.ps1
Write-Output "WebCache, INetCacheのリネーム"
$HostName = Read-Host "対象コンピュータ名を入力(止める場合はそのままEnter)"
if($null -eq $HostName){
  Write-Output "終了します"
  Start-Sleep -s 1
  exit
}else{
  Write-Output "${Hostname}のIEキャッシュフォルダをリネーム"
}

$RenameTime = get-date -Format yyyyMMddThhmmss

(Get-ChildItem -path "\\${HostName}\c$\Users" -Exclude Public).Name |
ForEach-Object{
  $WebCachePath = "\\${HostName}\c$\Users\${_}\AppData\Local\Microsoft\Windows\WebCache"
  $INetCachePath = "\\${HostName}\c$\Users\${_}\AppData\Local\Microsoft\Windows\INetCache"

  Write-Output "--------------------"
  Write-Output $_

  if(Test-Path $WebCachePath){
    Set-ItemProperty -LiteralPath $WebCachePath -Name Attributes -Value "Normal"
    (Rename-Item $WebCachePath "${WebCachePath}_${RenameTime}" -PassThru).Name
  }else{
    "${_} WebCacheフォルダ無し"
  }

  if(Test-Path $INetCachePath){
    Set-ItemProperty -LiteralPath $INetCachePath -Name Attributes -Value "Normal"
    (Rename-Item $INetCachePath "${INetCachePath}_${RenameTime}" -PassThru).Name
  }else{
    "${_} INetCacheフォルダ無し"
  }
}
Write-Output "--------------------"
Read-Host "Enterで閉じる..."
```

# 改良案
* エラーハンドリング。
* リネーム済みのフォルダを対象にして削除できるようにする。
* 最初から削除も選べるようにする。
* ログ残す。
日付から年と月と日を取り出す（できれば和暦も）


```python
from datetime import datetime

# fulldateは文字列形式でもdatetime形式でもOK

def date_to_ymd(fulldate):
    if type(fulldate) == type('string'):
        tmp = fulldate.replace("-", "/").replace(".", "/").split("/")
        year = int(tmp[0])
        month = int(tmp[1])
        day = int(tmp[2])
    else:
        year = fulldate.year
        month = fulldate.month
        day = fulldate.day
    return year, month, day


def date_with_nengou(fulldate, wareki=False):
    year, month, day = date_to_ymd(fulldate)
    if wareki == False:
        return '西暦', year, month, day
    elif year <= 1867:
        return '慶応', year-1864, month, day
    elif year <= 1911:
        return '明治', year-1867, month, day
    elif year <= 1925:
        return '大正', year-1911, month, day
    elif year <= 1988:
        return '昭和', year-1925, month, day
    elif year <= 2018:
        return '平成', year-1988, month, day
    else:
        return '令和', year-2018, month, day

```
AWSでプッシュ通知の送る方法

AWSでプッシュ送りたいであれば、サービスは２件あります：

- SNS (Simple Notification Service)
- Pinpoint


#SNS
SNSの中でも２パターンが存在してます、ユーザーを一人一人にプッシュを送信するかユーザーをTOPICに登録して、そのTOPICに送信する。

![Screenshot 2020-12-18 at 14.39.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878226/a3d8b592-b61d-3382-b8de-3d1660c1634f.png)

###Snsの流れ
SNSでアプリをApplicationを作成して、そのApplicationにエンドポイント（ユーザーのDeviceToken）を登録して、そのエンドポイントを送信する。送信後はSNSにそのユーザーに送信出来たかどうかの確認する。一人一人のユーザーに送信したいならSNSのソフトリミットは1秒1500件を送ります。

でも１<>１の送信だけではなくてTopicにも送信出来ます。


###TOPICとは？

Topicは送信先のエンドポイントです、120万エンドポイントまで登録出来るエンドポイントです。エンドポイントはSNSの中で「送信出来る場所」になります。
たとえば、このアプリは100ユーザーを使ってます、プッシュ通知を送りたいならユーザーをSNSのApplicationに登録して、一人一人に送信するですが、もっと早い方法欲しいであれば、Applicationに登録する時はその１エンドポイントをTopicにsubscribeすることです。100ユーザーをsubscribeするなら、Topicに送信する時は１リクエストで100ユーザーに送信出来ます。

####それは100ユーザーでも、100万ユーザーでも変わらないです！

![Screenshot 2020-12-18 at 16.58.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878226/55b2e506-b23a-ad9b-07fa-63c9d4674dcf.png)




Topicのいいところは送信速度早いとAWSのApiを1回のみです。

#pinpoint

Pinpointはお話題になったサービスで、今年に日本で使えるようになりました！SNSと違って、一気に１００ユーザーを登録して、一気にプッシュ出来ます！

pinpointのプッシュ流れはシンプル、セグメントを作成して、セグメント作成する時はユーザーのファイルをインポートする
![Screenshot 2020-12-18 at 16.09.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878226/0afaa3e2-c65f-93c2-8af4-21b45e59c1ea.png)

ファイルのサンプル
>import.csv :
>ChannelType,Address,Location.Country,Demographic.Platform,Demographic.Make,User.UserId
>APNS,482aba02e7da338707541bb4c4a570b0ec090b8b0001b28ae1634ee680f2cbc4,JP,iOS,Apple,255830951

ユーザーのdeviceTokenとプラットフォームと他の情報で組み合わせのCSVやJsonです。

セグメント作成したあとはそのセグメントに対してキャンペーンを作成して、プッシュの設定をして（タイトルとメッセージ）と送信の設定（繰り返し送信などは出来ます）をして終わりです！

![Screenshot 2020-12-18 at 16.23.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878226/0b9b5ef2-be8a-d399-4ac2-63e87e9a55de.png)

送信速度も早い、1秒2万件送信されてます。

だが、

![Screenshot 2020-12-18 at 16.26.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878226/a3ca49af-12d0-0dd1-924c-15e9e2775eb9.png)

送信率をもらえますが、誰に送信出来たか出来てないは出来ません。どこのユーザーをアンインストールしたどかも出来ません。Pinpointと言う名前なのにユーザーを特定出来ないは微妙ですね...その上、安いSNSに対しては大きなユーザー数あればPinpointは高いです。
https://aws.amazon.com/jp/pinpoint/pricing/
>通知 100 万件までは無料、その後は通知 100 万件あたり 1 USD。
MTA の 5,000 エンドポイントまでは無料、その後は 1,000 エンドポイントあたり 1.20 USD。

なので１プッシュで200万ユーザーなら１ヶ月2400ドルになります。自分の使い方としてならPinpointは合わないです、地裁ユーザーベースでたくさんのプッシュ送りたいなら出来そうです。


#SNSーPinpoint

判断する為に200万ユーザーを送りたい場合はどれぐらいかかる（送信時間と値段）：

![Screenshot 2020-12-18 at 16.40.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878226/709935ce-da8f-b5d2-fef8-c4267634cb94.png)


SNSとpinpointは両方いいところありますが今回の要望としては大きくな対象ユーザーがあれば、Topicは一番使いやすいです。

以上
ROSについてまとめてみる #4

この記事は、[ROSについてまとめてみる #3](https://qiita.com/hatt_takumi/items/a909a6e3949652a38445)の続きです。
＊重複している部分もありますが、ひとまずこのまま公開します。
＊この記事の記載内容はROS1に関するものです。

#ROSでの通信
ROSの肝は、まずこの通信を理解することです。
ここではROSの通信についてまとめます。

##メッセージ
ROSで使われるPub/Sub型の通信。TCPベースで実装されている。

![ROS_message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467051/a37eb8c3-33ee-4cd2-0594-51e2b0c18155.png)

Publisherは、プロセス起動時に、自身の発行するTopic名と、ノードのアドレスをMasterに登録します。
Subscriberは、起動時にMasterに購読したいTopicを検索してもらい、そのTopicを発行しているPublisherのアドレスを取得します。
あとは、SubscriberがPublisherに直接接続し、ピアツーピアのメッセージの送受信が行われます。

##サービス
ROSで使われるReq/Rep型の通信。あるノードが他のノードの関数を使う。RPCとも呼ばれる。

![ROS_service.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467051/33d9d065-1a7c-4c1c-564d-bf70f65811ed.png)

サービスはクライアント、サーバー形式の通信です。Serverは、起動時に自身のService名と、ノードのアドレスをMasterに登録します。
Clientはサービス利用時に、MasterにService名を検索してもらい、そのServiceを発行しているServerのアドレスを取得します。
Clientはその情報をもとにServerにリクエストを要求し、ServerはClientにレスポンスを返します。

##パラメータ
パラメータに関しては文献によって通信に分類されないものもありますが、用途としてはここにまとめてもいいような気もするので、書いておきます。

パラメータサーバーは、ROS Masterが有する機能で、システム内の全ノードから参照できる値を保持します。
利用できるデータ型が決まっているため、簡単に利用でき、システム内の全ノードから参照できます。
実際には文字列のやり取りが行わており、各ノードが適した形式に読み替えているようです。

##使い分け
 - メッセージ: 非同期ストリーミング
 - サービス: 同期での単一データ通信や、機器の操作など
 - パラメータ: システム内の全ノードから参照できる値を保持する

#アクション
ROSのサービスは同期なので、クライアントがサーバーからレスポンスを受け取るまでプロセスがロックします。
単純なスイッチのOn/Offや、ステータスの取得等ならこれでもいいのですが、ロボットの移動などの時間のかかるタスクには向きません。移動中はサーバーから何も返ってこないばかりか、失敗すれば一生何も返ってこないこともあり得ます。
こういった時のために、ROSには、複数のトピックを組み合わせた、アクションと呼ばれる非同期の手法があります。
アクションでも基本的にはトピックの仕組みが使われています。
**ゴール**というトピックにメッセージを送信することで、アクションサーバーは動作を開始します。実行中、アクションクライアントは**フィードバック**というトピックを通じて、途中結果を受け取ることができます。そしてすべてが実行し終わると、**リザルト**というトピックから、結果を受け取ります。


\#5へつづく
#参考
ROS
http://wiki.ros.org/

プログラミングROS(O'Reilly Japan)
https://www.oreilly.co.jp/books/9784873118093/

ROSプログラミング(森北出版株式会社)
https://www.morikita.co.jp/books/book/3010
Pythonで学ぶアルゴリズム　第7弾：年号変換

# #Pythonで学ぶアルゴリズム< 年号変換 >

##はじめに
基本的なアルゴリズムをPythonで実装し，アルゴリズムの理解を深める．
その第7弾として年号を扱う．

##西暦を年号へ
今回は明治～令和まで変換できるようにした．ただし，後でも記述するが，今回は汎用性のあるプログラムとしたため，年号の基準と年号名だけ追加することでいくらでも拡張することができる．ただし，同じ年の年号(例: 昭和64年と平成元年)は新たな元号とする．

明治～令和までの元年に対する西暦，つまり年号の境界を次に示す．

|年号|西暦|
|:-:|:-:|:-:|:-:|
|明治元年|1868年|
|大正元年|1912年|
|昭和元年|1926年|
|平成元年|1989年|
|令和元年|2019年|

以上を踏まえて，pythonに実装する．
以下にコードと出力を示す．

#####コード

```python:era_name.py
"""
2020/12/18
@Yuya Shimizu

年号変換
"""

def trans2era_name(year):
    year_dict = {2019:"令和", 1989:"平成", 1926:"昭和", 1912:"大正", 1868:"明治"} #年号の境界
    change = True #変換できたかどうかの判定用変数
    
    #年号判定
    for Y in year_dict:
        if year >= Y:
            year -= Y
            if year == 0:
                print(year_dict[Y] + "元年")
            else:    
                print(year_dict[Y] + str(year + 1) + "年")
            change = False
            break
        
    # 年号変換対象外に対してのエラーメッセージ
    if change:
        print("明治～令和の範囲でのみ変換が可能です")
        
trans2era_name(1868)
```

#####出力１（2020年）
```
令和2年
```

#####出力２（1868年）
```
明治元年
```

#####出力３（1800年）
```
明治～令和の範囲でのみ変換が可能です
```

はじめにも述べたように，我ながら汎用性の高いものができたのではないかと思う．コードの説明を少し行う．year_dictの中に年号とその元年の西暦の組を格納している．定義した関数では，forでその辞書型配列を回しているため，**year_dictの中身を追加するだけで，年号変換の対象を拡張することができる**．ただし，年号変換できなかったときに出力されるエラーメッセージの内容は変える必要があるかもしれない．
※コメント欄の@shiracamusによる改良版ならば，その心配もなく，自動でエラーメッセージも変化してくれる．

##感想
今回取り扱った年号変換は参考文献の確認問題として出題されていたもので，自分で考えてプログラムを作成した．先ほども記述したように，我ながらうまくまとめれられたのではないかと思う．アルゴリズムは学び始めたばかりであるが，アルゴリズムや考え方は大切であると感じられ，いっそうアルゴリズムへの学習意欲が高まった．

##参考文献
Pythonで始めるアルゴリズム入門　伝統的なアルゴリズムで学ぶ定石と計算量
　　　　　　　　　　　　　　　　　　　　　　　　 増井 敏克　著　　翔泳社
CloudFunctionsでStorageのフォルダを削除する

##はじめに
Firestoreのドキュメントの削除をトリガーにしています。
なので、ここに関しては状況に応じて変更してください

##実装

```JavaScript
exports.onDeleteUser = functions.firestore.document('users/{uid}')
.onDelete((snap, context) => {

  const deletedUserId = context.params.uid;
  const bucket = admin.storage().bucket();

  bucket.deleteFiles({
    //ここでフォルダのパスを指定します
    prefix: 'userIcons/' + deletedUserId + '/'
  })

  return null;
})
```
これでuserIcons/deletedUserIdより下の階層にあるデータを全て削除することができます。
私の周りのPython 2020年ふりかえり

##私の周りのPython 2020年ふりかえり

　Python歴４年目に入った、いつもはメーカ系列でIoT屋やっている者です。
私の周りのPython 2020年と少し語ってみます。


###私の周りのPython 2020年まで
　2017年～2018,9年頃までは、研究開発やそれに付随するPoC（実証実験）で、
IoT機器でのデータ収集やカメラ制御による画像関連、
AWSなどクラウド上での分析処理ぶん回し（笑）になどなどにpythonを利用していました。
それぞれの研究題材の特化したpythonプログラムがほとんどで、
いわゆるゴリゴリのコーディング（書いた本人しかわからんのでは？）。
正常動作して目的を達成すればよいって感じ。

　あくまでPythonは、研究者や技術者が目的達成の為に一時的に利用しているに過ぎない存在でした。



###私の周りのPython 2020年
　ところが今年(2020年）徐々に状況が変化してきたのです。
実用的な場面でPythonが利用され始めているのを実感した１年になりました。
　例えば、
・情報提供系システムでの、バッチ処理や　Diango,Flaskを利用したWebアプリケーション
　Dashなど利用した、情報の見やすい可視化！
・IoT機器とのデータ連携の急増：非同期処理が使いやすくなってきている！（使いやすいハードの出現も要因）
・Apiサーバでの活用
などなど。


　それらは、
・Python経験者が増えてきた（特に若手）
・情報見える化のさらなる要求（現場でもデータ分析＆結果からの次アクションのローテー）
のような事での利用拡大でありますが、
その他、Python的には、
・個人レベルでの開発でなく、ある程度の規模での開発＆その為のルール付けや型ヒント等の開発支援のようなもの
が充実してきている。（もちろんエディタ等も）
・情報をみせるライブラリ・通信ライブラリの拡充
などなどが、後押ししているのでは
と、思っています。


###そして2021年
　さて2021年のPython事情はどの様になっているでしょうか？
コロナ過でどこも予算厳しい時期でありますが、知恵絞りながらでも
上記2020年の動きのさらなる拡大は止まらんだろうなと。


それでは！
【超簡単！】Three.jsでUIを作る(3) 

# あらすじ

←[前回：【超簡単！】Three.jsでUIを作る(2)](https://qiita.com/Yamkaz/items/93fd11ebe772f24f9594)
![text2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276138/0707e58c-5482-c346-7ffa-c04e9f2b39e1.gif)

僕の大好きな、「[Experiments with Google](https://experiments.withgoogle.com/)」が制作した「[Assisted Melody](https://experiments.withgoogle.com/assisted-melody)」のWebアプリケーションがUIがWebGLで制作されていました。こんなUI簡単に実装したいですよね..。

探しても、この辺りの情報をまとめてくれている人がいなかったので自分で作ることにしました。

# sample03. マウスの位置に向く四角

四角形を描画するコードと、マウスの位置に合わせて、四角形の位置と角度が変わる最小限のコードを書きました。

コード内に解説は全て書いたので、読んでください。
![text5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276138/ff0010c5-3256-92d5-95c8-0c6560356280.gif)

<p class="codepen" data-height="765" data-theme-id="dark" data-default-tab="js,result" data-user="yamkaz" data-slug-hash="gOwWEoE" style="height: 765px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="ThreeJS: Plane Geometry + Distoration">
  <span>See the Pen <a href="https://codepen.io/yamkaz/pen/gOwWEoE">
  ThreeJS: Plane Geometry + Distoration</a> by やまかず / Kazuyuki Yamamoto (<a href="https://codepen.io/yamkaz">@yamkaz</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

→次回作 Comming soon...
[【超簡単！】Three.jsでUIを作る(4) sample04. マウスの位置に合わせて画像の揺れが変わる](https://qiita.com/Yamkaz/items/30bd97583e682504910b)
「Linux 標準教科書」読みました！

![スクリーンショット 2020-12-18 13.30.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/958041/b2e7ebf8-502b-7bb3-ea90-f877e04be15f.png)
Linux 標準教科書読みました！
Linuxの役割やできることについて以下のことが大まかにわかりました。
・ファイルやフォルダの操作
・vimの使い方
・ユーザーによる権限とその変更
・シャルスクリプトについて
・ネットワークの確認と設定
・プロセスの実行と確認
正直パイプの繋ぎや正規表現あたりはいまいち飲み込めませんでしたがいずれは理解できるようになりたいです。
Amazonから基本情報技術者の本が届いたので次はこれを学習していきます！