OmniAICreator/Qiita-1.07M huggingface dataset:
ネット炎上。匿名アカウントの批判はノーカウント。匿名のいいねも。1人の人間が複数アカウントで荒らしてる説。証明不可能なので攻め手有利。ずるっ。暴力やハラスメントのロジックを理解して、心のレジリエンスな対策しよう。ここでもセルフトークは役立つから心理セラピーとしてオススメ。

ぷち炎上から1日以上が経過した。それで、メンタル的には問題なかったはずだけど、最後の最後でちょっとダメージが大きいやつが来そうだな。この感覚、久しぶりだなぁ。怒っていいと思うんだけど、やはり匿名での暴力と言うのは、やばい。匿名アカウントでの揶揄。そして、匿名のいいね。 https://t.co/6tCDg6vNXU

# Ref

[エンジニアには国語的能力が重要だ。実は言語的能力が80%を占める文系の仕事だとさえ思える。理系的な要素だけでプログラミングが成り立つと思ったら間違えた。ロマンロランのジャンクリストフを読もう。良い小説だから。日本語や言語的なものを大いに愛そうじゃないか。僕らプログラマは。 - Qiita](https://qiita.com/YumaInaura/items/8a0cc0721ae78175bce4#comment-11f3ea04acf7d800539b)

![image](https://user-images.githubusercontent.com/13635059/51483089-8e107f80-1ddb-11e9-949b-410f4953a977.png)

# Twitterでの罵詈雑言とかは、まだ可愛げがあるというか、

発信元がわかると言う点で、こちらにも相手の発言に言及するなり、相手のTwitterアカウントを見てフムフムどんな人間だろうと思うなり、対応のやり方と言うものがある。

だが匿名アカウントでのコメントと、匿名のいいねがつく世界では、こちらに何の反論も許されていないということがミソだ。このように、たかがデジタルの数字であっても、匿名と言う仕組みそのものが、人間の想像力を爆発させがち。

Yahoo!のニュースサイトとかでも、コメントが荒れがちで、あれはコメントに無数のいいねがつくことによって、あれは果てしない数の暴力を演出していると思ったことがあったけど、

# Qiitaの仕組み的にも、それが起こり得ることがわかった。

最初僕も一瞬、デジタルの数字に対して、悪い想像力が爆発しそうな感じもあったけれど、今冷静になって考えると、匿名アカウントを取って誹謗中傷を投げてくる輩であるから、匿名アカウント10個取得して、いいねをつけている可能性もある。

むしろその可能性が濃厚だと思う。それを僕側からは確認できないわけだけれど。ここで想像力を爆発、暴発さえさせなければ、この数字に怯える事は無い。

思うに、この1年が今のタイミングで10個ついたと言うこと、このサービスで否定的なコメントにそこまで多くのいいねがつくと言うこと、それ自体が訝しい感じがする。だって、

# プチ炎上はもうほとんど終わりかけなのだから。

これが99とかいう数字だったら、全く嘘っぽいし、10と言うのは、なんかリアルに想像できそうな数字で、人の心をかき乱すことに長けた、いってみれば卑怯者タイプな弱虫さんは、人の心を怯えさせることに最適化しているかもしれない。

そういえばかなり昔ニコニコ動画に歌ってみたの画像、アップロードしてみた時も、ものすごい数の揶揄するコメントがたくさんついたんだけど、結局それはフィルターをしてみると、

# 1人の人間が発言し続けていたと言うことがあったな。

だけどこれは問題があって、あまりにも多くの批判のコメントがついていると、全く悪気なく見ている人から見ても、あー、この動画は批判に値するものなんだと言う認識に変わってしまいそうで。

そう考えてしまうアップロードの主の想像力の爆発も、なかなか厄介だ。つまり、多くの有名人がTwitterやらで悩んでいるように、匿名の暴力と言うのには圧倒的な破壊力があって、基本的に、攻めがより、守りが圧倒的不利な立場にあるのだ。

だって、人間が社会的な動物であることに加えて、例えば犯罪者のように、例えば万引き犯みたいに、人間の隙をつくことばかりを考えてきた人たちは、それが最大の長所なのだから、

# 破壊力を気ままに行使してもおかしくは無い。

そして、この人間社会は基本的にお互いの信頼、善意によって成り立っている部分が大きいので、その隙をついて悪いことをすると言うのは、実はものすごく難易度が低くて、簡単なことなのだ。

まぁ、実際に批判コメントにいいねをつけたのが、誰であろうとも、直接コメントせずに匿名アカウントのコメントの影に隠れて、メッセージを送るような輩は、

# そもそも相手にする必要がないと、自分自身の感情さえ割り切れたそれでオーケーなのだ。

問題は自分自身の感情が悟れるかどうかなのであって、細かいロジックは問題ではない。やはりここでもセルフトークの技術が役に立った。冷静に、匿名アカウントのコメントが取るに足らないものであると割り切ることができたし、その暴力のロジックについてもまた考察が深まった。

たとえどんなに仮に、自分が馬鹿なエンジニアであろうとも、愚かな文系高卒プログラマーであろうと、日本語力の低い低偏差値の間抜けであろうとも、

# そんなことよりも、もっと大事なのは人間としての品位なんじゃないかな。

自分がバカだと認めている、さらに馬鹿だと笑うのは、もっとバカなんだぜ。わかっているかな、匿名アカウントの皆様。いや、もしくは、おそらく、匿名アカウントのたった1人の君。

ということで、僕らはいくら脇が硬くても、いつかネット炎上にあったり、匿名や実名の暴力、もしくはありとあらゆる登録にさらされる可能性が常にあるのだから、暴力そのもののロジック、構造を理解して、心の対策を作っておこうじゃないか。

ネット炎上。匿名アカウントの批判はノーカウント。匿名のいいねも。1人の人間が複数アカウントで荒らしてる説。証明不可能なので攻め手有利。ずるっ。暴力やハラスメントのロジックを理解して、心のレジリエンスな対策しよう。ここでもセルフトークは役立つから心理セラピーとしてオススメ。 https://t.co/YgihTbsRzw


---

https://twitter.com/yumainaura

https://github.com/YumaInaura/YumaInaura/issues









<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
シェルスクリプトでうるう年

#うるう年のスクリプト
会社でLPICの研修を受ける中、雑談の中で出た入力した年がうるう年か否かを判定する
簡単なスクリプトを、シェルスクリプトのifを使って書きました、その備忘録になります。

```uruu.sh
#!/bin/bash

echo "確認したい年を入力してください"
read year

year4=`expr $year % 4`
echo $year4

if [ `expr $year % 4` -eq 0 ]
then
    if [ `expr $year % 100` -eq 0 ]
    then
        if [ `expr $year % 400` -eq 0 ]
        then
            leapyear=true
        else
            leapyear=false
        fi
    else
        leapyear=true
    fi
else
    leapyear=false
fi

if [ $leapyear = true ]
then
    echo "うるう年です"
else
    echo "うるう年ではありません"
fi
```

以上になります。もっと簡素なやり方もあるかとは思いますが、現状こんな感じです。
EC2でのdiskpartに失敗する


# AWSのDiskPartの話

時期は2018年10月頃
EC2上からEBSをマウントして、DiskPartしたらすんなりできない話。（GUI操作ではすんなりできた）

**結論** :意識高い系はよくないのかもしれない

## 条件
AWS-EC2
DiskPart

## 事象
EC2に新EBSをマウントし、WindowsのDiskpartからDISKの初期化をできなかった。

## 解決方法
DISKに設定されている読み取り専用属性を消す。

Diskpart > attributes disk clear readonly


## 経緯

```cmd:diskpart.cmd
diskpart 
Select disk 1
List disk 
Convert gpt 
DiskPart にエラーが発生しました: このメディアは書き込み禁止になっています。
詳細については、システム イベント ログを参照してください。
```


### イベントログ
VDS はクリーン操作の最中にディスクにブート コードを書き込めません。エラー コード: 80070013@02070008

![aws_ebs_evt01.png](https://qiita-image-store.s3.amazonaws.com/0/242511/caba30d4-4625-8c68-ec2b-6cfa7e7de181.png)

## 原因
DISKが読み取りモードになっていることが原因

```cmd
DISKPART > detail disk
NVMe Amazon Elastic B SCSI Disk Device

ディスク ID: 00000000
種類       : NVMe
状態       : オンライン
パス       : 0
ターゲット : 0
LUN ID     : 0
場所のパス : PCIROOT(0)#PCI(1900)#NVME(P00T00L00)
現在の読み取り専用状態: はい
読み取り専用  : はい
ブート ディスク  : いいえ
ページ ファイル ディスク  : いいえ
休止状態ファイル ディスク  : いいえ
クラッシュ ダンプ ディスク  : いいえ
クラスター化ディスク  : いいえ

ボリュームがありません。
```

**現在の読み取り専用状態: はい**
**読み取り専用  : はい**
あはい。読み取りだから、書き込みできない。わかる。

### 参考URL

Micorosoftにそのものズバリのエラーメッセージで記載がありました。
[You may see "Media is Write Protected" Error or VDS error 80070013 after bringing SAN disk online via Diskpart in Windows Server 2008](https://support.microsoft.com/ja-jp/help/971436/you-may-see-media-is-write-protected-error-or-vds-error-80070013-after)



## 設定変更

```cmd
diskpart
DiskPart >  attributes  disk clear readonly
ディスクの属性が正しく消去されました。
DiskPart >  convert gpt
DiskPart は選択されたディスクを GPT フォーマットに正常に変換しました。
```

**解決**
【JavaScript 】乱数を取得する

# 乱数を取得する
```javascript:
'use strict';

// 0以上1未満の乱数
console.log(Math.random()); // 0 ~ 0.999...

// 1から6までのランダムな整数（サイコロ）
console.log(Math.floor(Math.random() * 6 + 1)); // 1 ~ 6

// min 以上 max 未満のランダムな整数
const min = 1;
const max = 10;
const num = Math.floor(Math.random() * (max - min) + min);
console.log(num); // 1 ~ 9
```
※Google Chrome で確認
※ES8
Nokogiri で DOM の切った貼ったメモ 

備忘録ですが何かの役に立てればと思って公開します。DOM の切り貼りがメインです。Nokogiri でスクレイピングができる人が対象です。スクレイピングに使いたい人はぐぐればたくさん例が出てくるのでこんな読みづらいメモを読んで時間を無駄にすることはないと思います :smile:

備忘録ですので随時内容の修正、追加をおこないます。

## 準備

`bundler` を使って `nokogiri` のインストールをするというよくあるやつです。

* 適当なディレクトリを作って移動
* 必要なら rbenv とかで ruby のバージョンをどうのとかやる
* `$ bundle init` で Gemfile を生成
* Gemfile 末尾に `gem "nokogiri"` の行を付け加える
* `$ bundle install --path=.bundle/vendor/bundle`

ここまでで `Nokogiri` がインストールされ使えるようになりました。続いて初期のコードです。

```ruby:
#!/usr/bin/env ruby
require 'bundler'
Bundler.setup(:default, :ci)
require 'nokogiri'

RAW_HTML = DATA.read # __END__ の次行から末尾まで読み込む

def get_document
  Nokogiri::HTML(RAW_HTML, nil, 'utf-8')
end

__END__
<html>
<head>
<title>hello</title>
</head>
<body>
<p>hello</p>
<p id="foo">goto <a href="https://qiita.com">Qiita</a> site!</p>
</body>
</html>
```

以後この get_document で `Nokogiri::HTML::Document` を生成してからコード例を挙げていきます。いちいち生成し直すのは紹介するメソッドの殆どが破壊的メソッドだからです。なおコード例は `__END__` の前に記述してください。

## 例題

### 内容の変更

```ruby:
doc = get_document
doc.at_css('title').content = 'new title'
puts doc.at_css('title') # => '<title>new title</title>'

# #foo の子供の最初のノード (goto ) を書き換える
doc.at_css('#foo').children[0].content = 'this is '
puts doc.at_css('#foo') # => '<p id="foo">this is <a href="https://qiita.com">Qiita</a> site!</p>'
```

ただし `Nokogiri::XML::Text#content=` にタグつきの文字列を渡してもエスケープされてしまいます。

### メソッド `css` と `at_css` の違いについて

スクレイピング方面の話題ですが、よく忘れるので。ノード (要素) を CSS セレクタで特定する二種類のメソッドがあります[^1]。

```ruby:
doc = get_document
p doc.css('p').map{|x| x.to_s} # => ["<p>hello</p>", "<p id=\"foo\">goto <a href=\"https://qiita.com\">Qiita</a> site!</p>"]
puts doc.at_css('p').to_s # => <p>hello</p>
```

要は

* `Nokogiri::XML::Searchable#css` は条件に合致する要素をすべてリストアップする
* `Nokogiri::XML::Searchable#at_css` は条件に合致した最初の要素を返す

ということです。`id` 属性で取り出すときなんかはドキュメント中にひとつしかないので `at_css` で取るとよいかと思います。

### 特定要素の内容をごっそり入れ替える

```ruby:
doc = get_document
doc.at_css('#foo').children.unlink
doc.at_css('#foo') << '<span>new text</span>'
puts doc.at_css('#foo') # => '<p id="foo"><span>new text</span></p>'
```

こちらはタグが使えます。ちなみに `Nokogiri::Node#<<` メソッドは要素の内容の末尾に付け加えるものです。なので最初の行の `〜.children.unlink` がなければ、「site!」の後ろに `span` 要素が挿入されることになります。やってみるとわかると思います。

## 参考文献
* [Module: Nokogiri](http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri) 多分ここが一次資料です

[^1]: xpath で指定する方法もあるようですがが使ったことがありません。
Nefryのデータをクリアする

Nefryで次のようなエラーが発生したときやFlash Memoryをクリアしたいときに対応する手順を簡単にまとめておきます。

```
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11572
entry 0x40078a5c
assertion "false && "item should have been present in cache"" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/nvs_flash/src/nvs_item_hash_list.cpp", line 85, function: void nvs::HashList::erase(size_t)
abort() was called at PC 0x400d3427 on core 0

Backtrace: 0x4008e6f0:0x3ffcfd90 0x4008e8cb:0x3ffcfdb0 0x400d3427:0x3ffcfdd0 0x400fad3c:0x3ffcfe00 0x400fb3f6:0x3ffcfe20 0x400fb725:0x3ffcfe70 0x400fa784:0x3ffcfed0 0x400fa1a2:0x3ffcff20 0x400fa23b:0x3ffcff40 0x400fa286:0x3ffcff60 0x400ef500:0x3ffcff80 0x400e366b:0x3ffcffa0 0x400d3d12:0x3ffcffd0
```

# 手順

次の手順で行います。

1. 空のプログラムを書き込んでみる　復活しないのであれば次
2. フラッシュメモリのクリアを実行する
3. メモリを初期化する

## フラッシュメモリのクリアを実行する

Pythonをインストールが済んでいる前提で```$ pip install esptool```を実行します。
インストールが完了した状態でバージョンを確認するとこのような表示がでれば大丈夫です。

```
$esptool.py version
esptool.py v2.6
2.6
```

クリアしたいNefryのポートを確認します。Macなら ```/dev/ttyUSB```Windowsなら```COM3```とかだと思います。
それを次のコマンドのポートを変更して合わせましょう。

```
esptool.exe  --chip esp32 --port COM3 --baud 921600 erase_flash
```

次のデータは実行結果です。

```
esptool.py v2.6
Serial port COM3
Connecting........_____..
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: b4:e6:2d:15
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Erasing flash (this may take a while)...
Chip erase completed successfully in 7.0s
Hard resetting via RTS pin...
```

このようになればフラッシュメモリのクリアは完了です。

## メモリを初期化する
このままではクリアされただけでモジュール名なども初期化されてしまいます。
なので必要な部分は初期化を行わないといけません。

次のプログラムをArduinoで書き込んでください。

```
#include <Nefry.h>
void setup() {
  Nefry.ndelay(1000);
  Nefry.setModuleID(getDefaultModuleId());
  for (int i = 0; i < 8; i++) {
    Nefry.setStoreValue(0, i);
    Nefry.setStoreStr("", i);
  }
}

void loop() {
}

String getDefaultModuleId() {
  String moduleName;
  String _devstr, ms;
  switch (boardId)
  {
    case 0:
    case 1:
    case 2:
    case 3:
      moduleName = "NefryBT";
      break;
  }
  _devstr = WiFi.macAddress();
  _devstr.replace(":", "");
  return moduleName + (String)"-" + _devstr.substring(8);
}
```

これでクリアは完了です。


Nefryに書き込みたいプログラムをつくってぜひあそんでみてください！
IntelijとMacのショートカットキー記号

これが何なのか分からなかったので

<img width="59" alt="Image 6.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/257048/132249b6-0701-197c-3488-8630b76610fd.jpeg">

これは
Control + Option + Oキーという意味らしい
https://pleiades.io/help/idea/mastering-keyboard-shortcuts.html
laravelで勉強がてらWebサイトを作成してみる

#はじめに
だいぶお久しぶりの投稿です。先日laravelを勉強したので、その成果にlaravel使って簡単なwebサイトでも作ってみようかなと思いました。
具体的には「自己紹介」「自分の開発成果物の紹介」に加えて、これまでに読んだ本の紹介とかもできるものです。まだまだ開発中ですが、なんとなく形にはなってきたので、メモ代わりにQiitaに公開します。

ソースコード：https://github.com/gitk47320/mysite
heroku（まだまだ未完成）：https://mysite-laravel.herokuapp.com/top

#開発環境など
言語とFW：PHP7.2+laravel5.7
DB：MySQl5.7
エディタ：Visual Studio Code
検証環境：クライアント：Webサーバはlaravel付属のもの（artisan serve）、
　　　　　DBサーバ：Ubuntu16.04＋MySQl5.7(VMwareで構築）

#具体的な機能
##トップページ
訪問者が本サイトに最初に訪れるページ。簡単なプロフィールとかを記載する
##読書記録
メインコンテンツの一つ。自分が読んだ本のタイトル、作者、感想、５段階評価を表示する。
管理者（要するに私自身）ページで編集が可能
##開発成果物
自分がこれまで遊び？で実装したものを紹介する。

#工夫した点
・読書記録を登録する際に、jsonファイルからの一括登録が可能（画面からは一冊ずつしか登録できないが、json形式であれば複数冊一気に登録可能）

#改善したいこと
・テストコード書いてしっかりテストしたい
・各画面でバリデーションを設計し、実装したい
・ログイン機能などうまく活用したい
・セキュリティ周りをしっかり考慮したい

#今後取り入れていきたい機能
・管理者用ページの拡張（ログイン機能追加など）
・開発成果物機能の実装（テーブル定義など）
・お気に入り画像集（ネット上で拾った気に入った画像を保存するもの）
・読書記録をユーザ登録制にして、本棚として活用してもらう。さらに公開/共有できるようにする
GASでスプレッドシートの内容をSlackに投稿

# 目的
自分はTeamに所属していて会計をやっています。
スプレッドシートで会計の記録を管理してるんだけど一々支払いを呼びかけるの面倒臭いから自動でSlackに通知してしまおう。という目論見で開発。

# GASとは？
- Google Apps Scriptの略
- Googleが提供するサービスをスクリプトで操作できる

# Slackの設定
- 「Manage team members」 → 「Home」 → 「Incoming WebHooks」 → 「Add Configuration」からWebhookを追加する。
- チャンネル名の設定、WebhookURLの保管、アイコンの設定などを必要に応じて行う。

# スプレッドシートの作成
**スプレッドシートの中身は割愛するが、下図の該当箇所をSlackに送りたい。**
![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/344952/f58a8d26-1e08-a9c8-f26e-b60f8c5ce017.png)

# GASの作成
**「ツール」 → 「スクリプトエディタ」にてプロジェクト作成**
**作成したプロジェクトに以下を記載**

```
//WebhookのURLとチャンネル名
var postUrl = 'hogehoge';
var postChannel = '#money';

//スプレッドシートのメッセージ取得
function getMessage(){
  //スプレッドシートのURL
  var spreadSheet = SpreadsheetApp.openByUrl('hogehoge');
  //シートの番号
  var sheet = spreadSheet.getSheets()[2];
  //取得するシートの行列(28行目、１列目、5行分、2列分)
  var messageArray = sheet.getRange(28, 1, 5, 2).getDisplayValues(); //２次元配列
  var message = new Array();
  
  //2次元配列を1次元配列に変換
  for(var i = 0; i < messageArray.length; i++){
    for(var j = 0; j < messageArray[i].length; j++){
      message.push(messageArray[i][j]);
    }
  }
  //配列を改行で連結
  var sendMessage = message.join('\n');

  return sendMessage;
}

//Main
function postToSlack(){
  //('送信するメッセージ', '送信するユーザー名', '送信するユーザーのアイコン')
  sendHttpPost(getMessage(), 'money', ':moneybag:');
}

function sendHttpPost(message, username, icon){
  //チャンネル、ユーザー名、アイコン、メッセージ内容をJsonで設定
  var jsonData = {
    "channel" : postChannel,
    "username" : username,
    "icon_emoji" : icon,
    "text" : message
  };
  var payload = JSON.stringify(jsonData);
  //送信設定
  var options = {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };
  //POSTリクエスト
  UrlFetchApp.fetch(postUrl, options);
}
```

# 動作テスト
**postToSlack()を実行する**
![スクリーンショット 2019-01-21 23.20.05.png](https://qiita-image-store.s3.amazonaws.com/0/344952/4f3dd53c-3c72-6b97-435c-bac5d714a3d0.png)

# トリガーの設定
**Excel VBAとは異なり、トリガーを設定することで、サーバーで自動的に実行される。**

- 「編集」 → 「現在のプロジェクトのトリガー」 → 「トリガーを追加」にて様々な設定のトリガーが追加できる。
- 今回は毎月23日に実行されるよう設定。

# まとめ
面倒だった会計処理もGASのおかげで楽になった。
VBA_配列からNothingを除外

#1.概要
オブジェクトの配列においてNothingであるものを除外する関数
※自己クラスの配列において、不要なものを予めNothingにし、
　後にまとめて除外したいことがあったため作成

#2.ソースコード

```vb
'引数の配列からNothingを除外する
Public Function DeleteNothingObj(arg_array As Variant)
    
    Dim i As Long 'カウンタ
    Dim buf_ As New Collection '消さないオブジェクトのバッファ
    
    '引数の配列からNothingでないオブジェクトをバッファへ格納
    For i = 0 To UBound(arg_array)
        If Not arg_array(i) Is Nothing Then
            Call buf_.Add(arg_array(i))
        End If
    Next
    
    '引数の配列をバッファのオブジェクト数にRedim
    ReDim arg_array(buf_.Count - 1)
   
    '引数に再格納
    For i = 0 To UBound(arg_array)
        Set arg_array(i) = buf_(i + 1)
    Next
        
End Function


```

#3.出力結果
～略～
MacOS Mojave でM5Stackの環境設定する。


##TL;DL

MacOS MojaveでVCPドライバーがインストールできない問題の自分用メモ

M5Stackを買ったのでさあ遊ぼうと思ったところ、Macでドライバーをインストールしても認識してくれず

USBでシリアルCOM接続するポートがttyに表示できませんでした。

最新版のOSだとカーネル周りがセキュリティを強化するために変更されているためExtensionにドライバーファイルがインストールされてもRootが変更を拒否してしまうみたい

QiitaとかにもMacのトラブルシュートが乗ってなかったので参考になればなと

##やったこと

解消方法はカーネルの変更を許可を起動前に設定する必要があります。

Macを一旦再起動する

```
MacBook-Pro:~ pcuser$ sudo reboot
```

もしくは🍎マークで再起動（Restart）を選択

再起動後、リンゴマークがある間に⌘＋Rを押し続けてセーフブートにします。

ここでターミナルを開けばRoot権限で操作が可能のでターミナルを選択肢コンソールにログインしましょう。

サードパーティ製カーネル拡張KEXTが実行できるように以下のコマンドを実行する

```
# spctl kext-consent disable
```

実行後はターミナルを閉じて通常起動してください。

起動後は公式にあるリンクのVCPドライバーをダウンロードしてインストールすればOK

ドライバーが正常に読み込まれていることを確認するにはlsコマンドで
`SLAB_USBtoUART`が表示されていることをターミナルで確認します。

 
```
MacBook-Pro:~ pcuser$ ls /dev/cu.*

/dev/cu.Bluetooth-Incoming-Port

/dev/cu.SRS-XB10-CSRGAIA-1

/dev/cu.MALS                    

/dev/cu.SLAB_USBtoUART　☆これ

/dev/cu.SOC

```

ちなみにこの機能はHighSierra以降に実装されたSecure Kernel Extension Loading(SKEL)の機能が有効になっているため起こっている事象で、パッケージインストールの時点では正常にインストールされたように見えるのが難点

（エラーを何も出力しないので問題を発見しづらい）

 
確かに配置自体は問題なくできるしドライバーをロードするコマンドも見た目上実行できます。（参考に以下コマンド）

```
sudo kextload -v 6 SiLabsUSBDriver.kext
```

##雑感

他の人はOSXを使っているので最新でデバッグしてる人がググっても出なかったからちょっと手こずった（今月のQiitaはM5Stack特集にしようかな）

Linuxの流儀で行けるかなーと思ってたけどよく考えたらMacってBSD系だしかつ商用OSなんだよね確か、そりゃ違うわ

参考リンク

https://www.silabs.com/community/interface/forum.topic.html/cp210x_usb_to_uartb-73qX
Docker hubについて理解したこと

## 背景

- 先日Jshellの記事を書いた
- その前にはJavaのバージョンテストの記事も書いた
- バージョンの取得をなんとなくできていたものの、ちゃんと理解せずにdocker imageを取得していたので、備忘録的に理解したことをアウトプットしておく

## 用意したもの

- terminal 
- Google Chrome

## まずはじめにDocker hubとは？

- https://hub.docker.com/
- クラウド上にDockerコンテナ公開されているオープンソースのサービス（日本語あってます？）

### もう少しわかりやすく言うと

- 無料で使える
- Dockerのイメージ（例えばJavaとかKotlinとか）が置いてあって、それを指定して取得してあげることで、ローカルとかCI環境で環境構築を可能にしてくれるやつ（違ったらすみません）

## で、本題

- 先日の記事で・・・

```
docker run -it openjdk:11 jshell
```

と書きましたが、、、"openjdk:11"ってなによ？って思ったわけです。（わからないまま記事にしてごめんなさい）

## 結論

- 知らないうちにDockerhubにおけるリポジトリとタグを指定してました（笑）
- ちゃんと説明すると・・・

- こんな感じで検索をして・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245191/d9581c7a-e3db-5118-51a7-10201c96f8ba.png)

- 引っかかると・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245191/5cfdc68c-1af6-2042-0d86-345d9aac544d.png)

- こんな感じでタグが出てきます！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245191/a014bc3d-68eb-91a0-6c45-6a94f5b91649.png)

- 要するに最初の検索で引っかかったやつ（これがリポジトリで）次にたくさん出てきたやつ（これがタグ（カンマ区切りのやつなら、どれを指定しても問題ないみたい））をdockerコマンドにうまい具合に渡せてあげていたおかげで実行できていたらしいです。

## 今度は・・・

- ここまでで、なんとなくリポジトリとタグの指定の仕方はわかったのですが新たな疑問が生じました

### なんでこんなにタグがあるんだろう？
- すごい疑問でした
- なんなら、Java11を使うのにどれを選べば良いのか決め手に欠いていました

###結論

- 微妙にimageの中身が違う！！！

### 試しにこの2つを比較してみました

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245191/c5a373d7-4c0d-b8e3-acc9-73b57359d77a.png)

### すると・・・

- (11/jdk/Dockerfile)の方だけUTF-8追加してくれてる！！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245191/2c78b79e-f152-dbb4-1800-eb2b8a7bc9c8.png)

### きっかけ

- これがわかったのは、最初に上の方のやつ（oracleの方）を指定していたのですが、日本語を渡したときに文字化けしてしまってどうしようかなーと対処法を調べてたときに、ちゃんとリポジトリの中までみたことで原因と代替案が見つかった次第です

## まとめ

- 普段コーディングしてばかりで、こういうところの理解を疎かにしていたことを痛感した
- 気になったこと（なんで動いているんだろう？とか）をちゃんと気にすることで意外な発見ができる！

## 参考リンク

https://hub.docker.com/
Pythonのミュータブルなリスト

##はじめに
　先日、センター試験が終わりました。息抜きも兼ねての初投稿です。

　Pythonのリストはミュータブルなオブジェクトです。ただ、この特徴を活かせずにいました。そんな中でも使えそうな方法をいくつか紹介します。

##ミュータブル、イミュータブルについて
pythonでは、
int, str, tuple ... -> イミュータブル
list, dict ... -> ミュータブル
なオブジェクトとなっています。
イミュータブルなオブジェクトは変更時にID（参照先）が変更されますが、ミュータブルなオブジェクトは変更されません。

```python
>>> a = int(11)  #int型の変数
>>> id(a)
... 3077501696  #値の参照先
>>> b = a
>>> id(a) == id(b)
... True  #複製では変更されない。
>>> a = 7
>>> id(a)
... 3077501632  #IDが変わった
>>> c = list([1, 2, 3])  #list型の変数
... 2977380172
>>> c[0] = 10
>>> c.append(4)  #値の変更等
>>> id(c)
... 2977380172  #IDは変わらない
```

##利用その１　参照渡しのように扱う
int型等と異なり、再代入をする必要がありません。

```python:immutable1.py
def square(n):
    return pow(n, 2)

a = int(10)
a = square(a)
```

```python:mutable1.py
def square(num_list):
    for i, num in enumerate(num_list):
        num_list[i] = pow(num, 2)

num_list = list(range(1, 6))  #-> [1, 2, 3, 4, 5]
square(num_list)
print(num_list)  #-> [1, 4, 9, 16, 25]
```
これは、リストのIDが値の変更時に変化しないからこそできるのです。

```python:sample1.py
def square(num_list):
    print(id(num_list))  #-> 3037287628
    for i, num in enumerate(num_list):
        num_list[i] = pow(num, 2)
    print(id(num_list))  #-> 3037287628 変わらない

num_list = list(range(1, 6))  #-> [1, 2, 3, 4, 5]
print(id(num_list))  #-> 3037287628
square(num_list)
print(id(num_list))  #-> 3037287628　変わらない
print(num_list)  #-> [1, 4, 9, 16, 25]
```
ちなみに、num_list[i]はint型なので変更時にIDが変化します。

```python:sample1.py
def square(num_list):
    print(id(num_list[0]))  #-> 3078230624 変わらない  
    for i, num in enumerate(num_list):
        num_list[i] = pow(num, 2)
    print(id(num_list[0]))  #-> 3078232576 変わる

num_list = list(range(1, 6))  #-> [1, 2, 3, 4, 5]
print(id(num_list[0]))  #-> 3078230624
square(num_list)
print(num_list)  #-> [1, 4, 9, 16, 25]
```

## 利用その２　要素数を増やしながらループさせる
<code>for i in 配列:</code>に対して用います。

```python:immutable2.py
seq = tuple([1])  # type -> tuple
for i in seq:
    if i > 5:  break
    seq += (i+1,)
    print(i)  #-> 1
```
```python:mutable2.py
seq = [1]  # type -> list
for i in seq:
    if i > 5:  break
    seq.append(i+1)
    print(i)  #-> 1 2 3 4 5
```
可読性等の面で実用的とは言えませんが、フィボナッチ数列等を完結に表現できます。

```fib.py
def fib1(n):
    seq = [0, 1]
    if n <= 2:  return seq[0:n]
    for i in range(n-2):
        seq.append(seq[i]+seq[i+1])
    return seq

def fib2(n):
    return [(seq.append(seq[i]+seq[i+1]), seq[i])[1] for seq in [[0, 1]] for i in range(n)]
```

##おわりに
他にも面白い使い方を探して行きたいと思います。（受験後に）
まだ初心者なので間違いもあるかもしれません。もし解釈の間違いや実際にあった難解な使い方がありましたら、訂正等のコメントをよろしくお願いします。
【JavaScript 】分割代入

# 分割代入
```javascript:
'use strict';

// 配列
const xyz = [1, 2, 3];
const [x, y, z] = xyz;
console.log(x); // 1
console.log(y); // 2
console.log(z); // 3

// スプレッド演算子
const arr = [10, 20, 30, 40, 50];
const [a, b, ...c] = arr;
console.log(a); // 10
console.log(b); // 20
console.log(c); // [30, 40, 50]

// オブジェクト
const obj = {
    oa: 10,
    ob: 20,
    oc: 30,
    od: 40,
}
const {oa, ob, ...cd} = obj;
console.log(oa); // 10
console.log(ob); // 20
console.log(cd); // {c: 30, d: 40}
```
※Google Chrome で確認
※ES8
【Pythonista】photos モジュール

Pythonistaで利用できる **photos モジュール** 触ってみた。

# ■参考サイト
[photos — Photo Library Access on iOS](http://omz-software.com/pythonista/docs/ios/photos.html#module-photos)

# ■検証時に使用したコード

```
import photos as ph

#Get the last photo, and show it in the concole
def show_last_asset():
	all_assets = ph.get_assets()
	last_asset = all_assets[-1]
	img = last_asset.get_image()
	#img = last_asset.get_ui_image()
	img.show()

#Get the oldest screenshot image, and delete it from the library
def show_oldest_screenshot_delete():
	album = ph.get_screenshots_album()
	screenshots = album.assets
	
	if not screenshots:
		print("You have no screenshots in your library.")
	else:
		oldest = screenshots[0]
		if oldest.can_delete:
			#This will automatically show a confirmation dialog:
			#削除して良いかのダイアログが自動的に表示される
			oldest.delete()
		else:
			print("Oldest screenshot is not deletable")

#Get the last photo, and convert it to grayscale, saving the edit in-place
def convert_grayscale():
	album = ph.get_recently_added_album()
	last = album.assets[-1]
	
	if last.can_edit_content:
		img = last.get_image()
		grayscale_img = img.convert("L")	#グレーへの色変更
		grayscale_img.save(".edit.jpg", quality=90)
		last.edit_content(".edit.jpg")
	else:
		print("The asset is not editable")

#Show an image picker dialog (allowing multiple selection) and print the result
def image_picker():
	assets = ph.pick_asset(assets=ph.get_assets(), title="Pick some assets", multi=True)
	print(assets)

```

# ■感想
iOSのフォトライブラリにアクセスして、いろいろ操作することができるのはとても便利。
アセットのサイズによって多少動作が遅かったりしたのがちょっと残念。
もし、アプリ開発とかするのであれば、負荷とかをいろいろと考慮しないといけないと思う。
AWS初心者がDynamoDBを(できるだけ)一括でオンデマンド課金にしてみた

##はじめに
### 初投稿です
### AWS初心者です
### シェル初心者です
AWSのリソース「DynamoDB」には**プロビジョニング済みキャパシティーモード**と、**オンデマンドキャパシティーモード**があります。
オンデマンドキャパシティーは2018年11月に発表された設定で、違いは以下の通りです。

+ オンデマンドキャパシティーモード

>オンデマンドキャパシティーモードを利用している場合、DynamoDB の料金は、アプリケーションがテーブルに対して実行したデータの読み取り/書き込みに対して発生します。※

　開発時等、業務時間以外は DynamoDB を利用しない、
　または、急にリクエストは頻発する場合に利用するとよさそうです。

+ プロビジョニング済みキャパシティーモード

>プロビジョニング済みキャパシティーモードでは、アプリケーションに必要と予想される 1 秒あたりの読み込みと書き込みの回数を指定します。※

　DynamoDB へのリクエストに対してある程度予測できる、
　または、24 時間リクエストが定量的に存在する場合に使うとよさそうです。

※以下のサイトより引用
　[Amazon DynamoDB 料金](https://aws.amazon.com/jp/dynamodb/pricing/)


違いを比較すると、リクエストが少ないテーブルにはオンデマンドモードを設定した方がコストは低くなります。
特に、開発環境の場合、業務時間外では、DynamoDB にアクセスすることは少ないと思います。
ただし、今使っているDynamoDB に対して、CloudFormation を通じて設定するのは面倒・・・
かといって、たくさんのテーブルに対して、手動で設定を変えたくるのも面倒・・・

という訳で、今回、DynamoDB を(できるだけ)一括でオンデマンド課金にする、スクリプトを作りました。

## 必要なもの
[AWS CLI](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-welcome.html)と[jq](https://stedolan.github.io/jq/)を使います。
各サイトに記載されている方法でインストールしましょう。


##書いてみた

書いてみたスクリプトはこちら。

```sh
#!/bin/bash

# 念のため、環境を確認してもらう
region='ap-northeast-1'
profile=$(echo $AWS_PROFILE)
read -p "${profile}環境で実行します。よろしいですか? (y/N): " yn
case "$yn" in [yY]*) ;; *) echo "処理を終了します。" ; exit ;; esac

#リクエスト課金になっていないテーブルを抽出する
#同時にUpdateできる最大テーブル数は50なので、実行数を制限している
no_ondemand_tables=$(aws dynamodb list-tables | jq -r '.TableNames[]' | xargs -I tablename aws --profile=${profile} dynamodb describe-table --table-name tablename | jq -r '.Table | select(.BillingModeSummary == null) | .TableName')
list=(`echo $no_ondemand_tables`)

for (( i = 0; i < 50; ++i ))
do
  aws dynamodb update-table --table-name ${list[$i]} --billing-mode PAY_PER_REQUEST
done
```


オンデマンド課金になっていないテーブルは`BillingModeSummary `が NULL になっています。
`list-tables`で一度テーブルを取得し、整形してから抽出します。


公式のドキュメントでは、[テーブルへの操作は同時に10テーブルまで](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/APIReference/API_UpdateTable.html)と記載されていますが、
制限数を決めずに実行させると、50テーブル実行後、`LimitExceededException`が発生しました。
(制限があり、全テーブルに対して一括にはできないので、タイトルに「できるだけ」をつけています)

なお、1テーブルの設定がオンデマンド課金になるまで、20分程度かかりました。
一括で更新したい場合、業務時間終了間近にスクリプトを実行し、
翌日確認するのがいいかもしれません。

## リクエスト課金にした結果
1日約 15$ かかっていましたが、リクエスト課金にした結果、なんと1日約 **0.2$** になりました！！:raised_hands:
1か月あたり、**約440$** のコスト削減になります！！:open_mouth:
個人でしたら旅行に行けてしまいますね。
DynamoDB の運用にもよりますが、コスト抑えたい方はリクエスト課金にしてみるのはいかがでしょうか。
Ruby

今日は、Rubyの文法を学びました。

・条件
・if式
 result "AAA" if num < 0 && num < 100
・メソッド

def aa(bb , cc)
 puts "あああ"
end

aa (99, 100)

・繰り返し
ブロックパラメーター
100.times do |name|
 puts name + 1 , ","
end

2.upto(10) do |i|

each
ブロックパラメーターに配列の要素入れる

array = ["apple" ,"orange" ,"banana"]

array.each do |fruit|
 puts fruit + ","
end
Cloud Firestoreに大きめのドキュメントを格納したらコンソールでの閲覧が無理め

# 概要

Firestoreに大きめのドキュメントを格納してみたら、コンソールでの閲覧時にブラウザが応答なしを連発したので、大きめのドキュメントは取扱注意という話です。


# 読者対象

- Firestoreに大きめのドキュメント（200Byte程度のJSONを配列に1000個格納したJSON）を格納予定の方。


# 現象

ブラウザタブの描画更新ができないほどCPU使用率が上がり、画像のようにブラウザから待機か否かの選択を迫られます。
5回以上待機して10分程度で表示に成功した時もありました。
リージョンがアメリカのプロジェクトなので、もしかしたら東京だと状況は緩和されるかもしれません。

![Firestore大きなデータNG.png](https://qiita-image-store.s3.amazonaws.com/0/310578/fe9cc112-0e7b-6b30-3f7b-d07ef48c9a8d.png)

表示に成功しても、ドキュメント削除のメニュー表示から、実行確認とつらい状況は続き、数分かけて1つのドキュメント削除が完了します。
β版ということもあって、GAまでにはこの辺はスキップなり警告なりが追加されるかもしれません。
ちなみに根気よく待っても場合によってはこの仕打ちw

![ブラウザエラー.png](https://qiita-image-store.s3.amazonaws.com/0/310578/80fadefd-e6ca-2e03-a024-1dba863af42b.png)




# 対処

## コードで削除する

削除には削除対象のドキュメントIDが必要ですが、コレクションの一番先頭のドキュメントが大きいと対象のドキュメントIDのコピペすら難しいです。
私はデータが少なかったので手打ちで行きました(;^_^A

公式ドキュメントの削除操作ページ
https://firebase.google.com/docs/firestore/manage-data/delete-data?hl=ja

```javascript:delete.js
const db = firebase.app().firestore();

const deleteTestItems = async (documentId) => {
    try {
        await db.collection("items").doc(documentId).delete();
    } catch (e) {
        console.error("error:", e);
    };
}
```

公式見るとコレクションの場合はトランザクション使って再起処理で削除回してますね。


## CLIで削除する

削除した後に公式にCLIでの削除を見てしまったので、CLIでも実施してみる。

```terminal
firebase firestore:delete items/documentId000 --project projectId000
```

削除対象のコレクションがitemsでドキュメントIDがdocumentId000、プロジェクト指定のオプション含めたときの例です。（プロジェクトIDはprojectId000の時）
公式通りに--projectなしで実行したら`Error: No project active. Run with --project <projectId>`と教えてもらったのでそれに沿った形です。


# まとめ

Firestoreに大きめのドキュメントを格納してみたら、コンソールでの閲覧は現時点では要注意という話でした。
特にチームで作業している際は、他のメンバーに影響が出る可能性があるので事前の周知が必要でしょう。
この問題もGAまでに緩和や解消の可能性があるので、大きめのドキュメントの格納する際には自身で確認してみてください。

私は検証のためあえてJSONそのままでドキュメントに入れましたが、大きなデータになる場合には公式ドキュメントのサブコレクション化を検討してみるのがいいかと思います。
https://firebase.google.com/docs/firestore/manage-data/structure-data?hl=ja#subcollections
MySQL8.0が接続できない

# 背景
Ruby on Railsで個人アプリ開発中にMySQLへの接続ができないエラーが発生した。
MySQLのバージョンを8.0に上げたことが大きな原因のようだった。以下に詳細を示す。

# 環境
- mac OS Mojova 10.14.2
- MySQL 8.0.13 for osx10.14 on x86_64 (Homebrew)
- ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin17]
- Rails 4.2.10


# 目次
エラーは主に2つ。
- Sequel Proからrootユーザーで接続できない
- ```schema_migrations```テーブルが存在しない。

## Sequel Proからrootユーザーで接続できない

### エラー概要
- SequelProからrootユーザでローカルのMysqlに接続...できず。
- ターミナルからMysqlにログインし、確認しようとしたら下記エラー。

```
$ mysql -uroot

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
```

### 原因
- あったはずのrootユーザが存在しなくなっていた。（これは原因不明でした...）

### 解決
##### 1. MySQL再起動、接続

```
$ mysql.server stop
//MySQL停止

$ mysql.server start --skip-grant-tables
//MySQL起動（権限不要のオプションをつける）

$ mysql -uroot
//MySQL接続
```

##### 2. データベース選択、userレコード削除

```
mysql> use mysql;
// userテーブルがあるmysqlDBを選択。

mysql> truncate table user;
//userテーブルのレコードをすべて削除

mysql> flush privileges;
//DBに反映
```

##### 3. rootユーザ作成

```
mysql> CREATE USER 'root'@'%' IDENTIFIED BY '';
//rootユーザ作成（権限無し）
//   passwordを指定してもよい。その場合は下記（passwordの文字列は任意で指定）
//   mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'passpord';

mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
//rootユーザに全権限を付与

mysql> flush privileges;
//DBに反映
``` 

これでユーザ権限問題は解決。

#### 参考
https://dev.mysql.com/doc/refman/8.0/en/privilege-changes.html
https://www.aipacommander.com/entry/2014/05/26/152247
https://stackoverflow.com/questions/50177216/how-to-grant-all-privileges-to-root-user-in-mysql-8-0


## ```schema_migrations```テーブルが存在しないとのこと。

## エラー概要
Railsサーバーを立ち上げ、アプリアクセス時にAcitiveRecordでエラー。MySQLに```schema_migrations```テーブルが存在しないとのこと。

```
ActiveRecord::StatementInvalid: Mysql2::Error: The user specified as a definer ('mysql.infoschema'@'localhost') does not exist: SHOW TABLES LIKE 'schema_migrations'
```

### 解決
- 以下のコマンドを入力

```
$mysql_upgrade -u root -p
```

#### 参考
https://qiita.com/yoshi1729/items/8a023d28c92dc5e62f86
上記記事の内容をなぞった。感謝。

## 最後に
- 上記方法で解決しましたが、かなり時間がかかりました。
- 内容の誤り等ありましたらコメントいただけると幸いです。
【JavaScript 】スプレッド演算子

# スプレッド演算子
```javascript:
'use strict';

// 配列
const x = [3, 4];
const y = [1, 2, ...x];
console.log(y); // [1, 2, 3, 4]

// 値はコピーされている
x[1] = 5;
console.log(x); // [3, 5]
console.log(y); // [1, 2, 3, 4]

// オブジェクト
const ox = {x: 1};
const oy = {y: 2};
const oz= {...ox, ...oy}
console.log(oz); // {x: 1, y: 2}

// 引数
const xyz = [1, 2, 3];
const sum = (x, y, z) => x + y + z;
console.log(sum(...xyz)); // 6
```
※Google Chrome で確認
※ES8
kintone プラグイン開発メモ　その２（何もしない設定画面を表示する）

[その１](https://qiita.com/sy250f/items/011254b5c0ffac9a9a05)はこちら。

その２では、設定画面を作成して、設定値を保存・読み込みしていきます。

参考：[kintone プラグインJavaScript API](https://developer.cybozu.io/hc/ja/articles/203661160)

# 設定値を保存・読み込みする
プラグインには設定値を保存・読み込みする仕組みが用意されているので、そちらを使ってみたいと思います。

 1. 設定画面を作成
 2. 設定値を保存
 3. 設定値を読み込み

上記の流れで作成してみたいと思います。

# 設定画面を作成
[kintone プラグイン開発手順](https://developer.cybozu.io/hc/ja/articles/203455680#step1)を参考にして設定画面を作成していきます。
はじめは、何もしない設定画面を作りたいと思います。

### 設定画面用のディレクトリとファイルを作成

```sh
cd src
$ ls
image		js		manifest.json
$ mkdir html
$ cd html
$ touch config.html
```

### 設定画面用のファイルを作成

```config.html
<html>
    <body>
        <h1>Hello,world設定画面</h1>
    </body>
</html>
```
### マニフェストファイル修正
設定画面用のファイルをパッケージできるようにmanifest.jsonに追記します。

```manifest.json
{
    "manifest_version": 1,
    "version": 1,
    "type": "APP",
    "name": { 
        "ja": "サンプルプラグイン",
        "en": "sample plugin"
    },
    "description": { 
        "ja": "これはサンプルプラグインです。",
        "en": "This is sample plugin."
    },
    "icon": "image/icon_helloworld.png",
    "homepage_url": { 
        "ja": "https://example.com/jp/",
        "en": "https://example.com/en-us/"
    },
    "desktop": {
        "js": [
            "js/customize.js"
        ]
    },
    "config": {
        "html": "html/config.html"
    }
}
```

### 再パッケージング
再パッケージする際は、最初にパッケージした時に同時に作成される「秘密鍵ファイル」も指定します。

```sh
$ ~/.npm-global/bin/kintone-plugin-packer --ppk 秘密鍵ファイル.ppk src
Succeeded: /Users/kazoo/local/kintone/plugin/hello_world/plugin.zip
```

### デプロイ
kintoneシステム管理からプラグインを選択してプラグインファイルを読み込みます。

### 設定画面の確認
アプリの設定画面からプラグインを選択するとプラグインに歯車マークが表示されていることが分かります。
<img width="548" alt="スクリーンショット 2019-01-21 22.41.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/4b33a9b7-8dd7-6602-598e-7148c7301188.png">

歯車マークを押下すると、設定画面が表示されます。
<img width="651" alt="スクリーンショット 2019-01-21 22.42.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/22d63d5e-5043-8b0a-850e-045708807244.png">

次回は設定画面にテキストボックスを追加してみます。
sympyで「センター試験2019 数学I・数学Ａ問題 第1問」 をやってみたい

センター試験2019 数学I・数学Ａ問題 第1問｜解答速報2019｜予備校の東進
https://www.toshin.com/center/q/sugaku-1a.pdf#page=5
2乗の平方根
http://examist.jp/mathematics/math-1/expression/nijyou-heihoukon/
Simplify problem, sqrt(t*t) 
https://github.com/sympy/sympy/issues/11584
Wolfram|Alpha｜Abs(3*a - 1) + Abs(a + 2)
https://www.wolframalpha.com/input/?i=Abs(3*a+-+1)+%2B+Abs(a+%2B+2)


参考　センター数学1A（2019年）をpythonで解いてみた
https://qiita.com/ryo_110/items/2af3b85f9cf56d556558

```fullscript.py
from sympy import *
a=Symbol("a", real=True)
KA=Symbol("KA", real=True)
KI=Symbol("KI", real=True)
f=9*a**2-6*a+1
g=solve(f-(KA*a-KI)**2,KA,KI)
KA=g[1][0]
KI=g[1][1]
print("ア=",KA)
print("イ=",KI)
LA1=sqrt((KA*a-KI)**2)
LA2=abs(a+2)
print("LA=",LA1,"+",LA2)
# ア= 3
# イ= 1
# LA= Abs(3*a - 1) + Abs(a + 2)
```
いい方法ありませんか。よろしくお願いします。続く。



#2019-02-05 ちょっと修正

```fullscript.py
from sympy import *
import re
a=Symbol("a", real=True)
KA=Symbol("KA", real=True)
KI=Symbol("KI", real=True)
f=9*a**2-6*a+1
str_G = str(factor(f,a))
KA=int(re.search( r'\((.+)\*a\s-\s(.+)\)\*\*2', str_G ).group(1))
KI=int(re.search( r'\((.+)\*a\s-\s(.+)\)\*\*2', str_G ).group(2))
print("ア=",KA)
print("イ=",KI)
LA=sqrt((KA*a-KI)**2)+abs(a+2)
print("LA=",LA)
# ア= 3
# イ= 1
# LA= Abs(a + 2) + Abs(3*a - 1)
```
sympy convert (absolute polynomial---> Piecewise) > Ask Question
https://stackoverflow.com/questions/54462853/sympy-convert-absolute-polynomial-piecewise
CookieとSessionの違いを簡単にまとめます[備忘録]

<h2>はじめに</h2>
通常、WEBページで入力された情報は前回どんなリクエストがあったかなどの情報は保持していません。これをストーレスと呼びます。ストー(状態)レス(無い)ということらしいです。

ですが、実際のWEBサイトは自動ログインや前回のログイン情報を保持している機能があります。
もう少しわかりやすくいうと、facebookやtwitterなどはログインしている状態でないと投稿機能が利用できませんので、ログイン情報を持っています。

本来WEBはストーレスの状態ですが、なぜ現実にWEBはログイン情報を保持しているのでしょうか？

<h2>Cookieを使用する</h2>
ログインは「Cookie」という機能を使用します。
ブラウザに保存されているテキストデータのことで、別ページへ移動した際にもログイン情報を破棄することはありません。

つまり、さきほど紹介したfacebookやtwitter等はCookieを使用することでログイン機能を保持したまま別ページへ移動できるのです。

<h2>Sessionを使用する</h2>
Cookieには弱点があります。それはCookieはクライアント側に依存するため悪意ある人間であればデータ改ざんし、乗っとることができてしまいます。

そこで、Sessionを使用します。
Sessionは情報がサーバー側に依存し、暗号化した情報をクライアント側にCookieとして保存する方法を採用しています。

ただし、Sessionも完全にはなりすましを防ぐことができるわけではありませんので、開発者は日々セキュリティに敏感になる必要があります。
JOINについて

#はじめに
エンジニア1年生です。
日々の学びのメモとしてコツコツと記事を書こうと思っています。
今回はSQLのJOINについて書いていきます。

##JOINとは？？
テーブルを操作する際に複数のテーブルを結合して検索を行いたい場面が多々あるかと思います。
そんな時に複数のテーブルを結合する命令が「JOIN」です。

##内部結合と外部結合
###今回使用するテーブル

![animalテーブル.png](https://qiita-image-store.s3.amazonaws.com/0/272935/aeed305e-e4a1-8774-f71e-1781802b151f.png)


##内部結合とは？
内部結合は2つのテーブルを結合する際に一致したデータのみを取り出します。

####文法
` SELECT * FROM [テーブル名1] INNER JOIN [テーブル名2] ON [結合条件]`


####実行SQL
```sql
SELECT * FROM animal INNER JOIN name ON animal.id = name.animal_id
```
####結果

![内部結合.png](https://qiita-image-store.s3.amazonaws.com/0/272935/7778200d-a339-7a9a-303f-3e1b93feb7f6.png)


結合条件に一致しないデータ（animalテーブルのid:5）がないことが分かります。
結合する際に一致したデータのみを取り出す。
これが「内部結合」です。

##外部結合とは？
軸になるテーブルを指定して軸になるテーブルにデータがあれば
結合されるテーブルと一致しなくてもデータを取り出します。

軸になるテーブルデータ全件取得して結合条件に一致したテーブルデータを結合するイメージです。
####文法
` SELECT * FROM [テーブル名1] LEFT OUTER JOIN [テーブル名2] ON [結合条件]`
`SELECT * FROM [テーブル名1] RIGHT OUTER JOIN [テーブル名2] ON [結合条件]`


####実行SQL
```sql
SELECT * FROM animal LEFT OUTER JOIN name ON animal.id = name.animal_id
```

####結果

![外部結合.png](https://qiita-image-store.s3.amazonaws.com/0/272935/6fc101f9-d324-4ca1-74d2-fc051b52d7cf.png)

内部結合の時と異なり一致しないデータも取り出されていることが分かります。
`軸になるテーブルデータ全件＋結合条件に一致したテーブルデータを結合`する。
これが「外部結合」です。

「LEFT」「RIGHT」これでどちらのテーブルを軸にするかを指定しています。
LEFT：左側に指定されたテーブルが軸になります。
RIGHT：右側に指定されたテーブルが軸になります。

以上です。
初心者エンジニアがLINE DEVELOPPER DAY 2018に参加してきました。

#linedevday2018に参加してきました.
プログラミングを始めて1ヶ月も経たないけど、運良くチケットがgetできたのでカンファレンス初参加.
**結論：エンジニアっていいね**
webエンジニア？ソフトウェアエンジニア？も楽しそうだなと素直に思えた.
通学のため１０分ほど満員電車に乗るけど、明らかにその満員電車に乗っている人たちとは目が違うように思った.
スーツ着てる人もほとんど見なかったし
あと目立ったのはアジア系の外国人が多い印象を受けた.英語での会話があちこちで聞こえてきた.
ポスターセッション, c-3, c-4, LINEサマーインターンシップの舞台裏と狙い, c-6, closing sessionに参加しました.

##ポスターセッション　　

###Voice UIによる音楽検索 -「ねえClova、打ち上げ花火かけて」の大変さ-　　四倉晋平　　

lineclovaの開発の裏側を聞いた
clovaは発売当初から後れをとっていると思っていたけど、音楽検索に関しては使えるレベルまできているみたい
最近はアニメタイアップの関連で、なにかのアニメのキーワードと組み合わせて検索されているらしい。
keyword neologd,自然言語処理

##c-3

###今すぐ使える特選Chatbot

飲食店代理予約サービスであるぺコッターの開発話を聞いた
サービスとしてあるのは知っていたけど使ったことはなかった。現在では月に約2万件もの予約依頼が飛んでくるらしい。
予約変更やキャンセルもテキストチャットだけで完結するのはいいね

ぺコッターの裏側は実際には電話をかけていない的なことを言っていて, スライドもあったのだけど実際の様子ではなかった. なにか見せられない事情でもあるのかな.

今Ruby,Railsを勉強していて、linebotをつくってみたいと思っていたのでとても勉強になった.

##cafe

###LINEサマーインターンシップの舞台裏と狙い

scheduleを見た時に絶対に見ようと決めていたもののひとつだ
実際にインターンのメンター&カリキュラム作成に携わった人から話を聞くことができた。

就業コースとスクールコースがある
スクールコースはアプリ開発経験を問わないとはいうものの、WEBテストで８割ほどの点数をとる必要があるそう
就業コースもwebテストの合格水準は同じで、面接でカルチャーに合うかやどの部署がよいか、情報共有の適正などを見ていると言っていた.
学生教育に力を入れると言っていたのでもっと力をつけて挑戦したい.

##c-6

###今日作れるスマートスピーカースキル - Clova SDK ライブコーディング -

このセッションではライブコーディングを見た
実際にclovaのスキルを実装するために30分の中でコーディングをしていた

流れ自体は自分の知識不足でわからないことが多かったが, たったの30分で機能を実装するまでに至っていた

##closing session

closing sessionでは砂金さんが今後のline(nextline)についての展望を語っていた.
個人的に興味深かったのは、現状のエンジニア2100人を3000人までに増やしたいというものだった.
卒後は福岡に戻りたい（今）と思っているので、lineの福岡オフィスのぞいて見たい

##懇親会

懇親会ではお酒を飲み過ぎてしまった
寿司とローストビーフを永遠ループし最後にデザートをいただいて１時間半ほどで退散した.

ノベルティはqiの充電パッド、珪藻土コースター,どら焼きだった.

なんでも良いからlinebot作って見ようと思います.
IT業界単語メモ

#分からない単語メモ

<b>SPA（シングルページアプリケーション）</b>
1枚のページだけで動くWebアプリケーションのこと
ユーザーが何かを操作すると画面上の変更する部分だけを書き換えて実行する
SPAを作ることのできるライブラリとして有名なのは「AngularJS」、「React」など

<b>フレームワーク</b>
全体の処理の流れが実装されており、その中の一部の具体的な処理を自分で実装して、はめ込めるようになっているシステム

<b>ライブラリ</b>
ライブラリは、使いたい部品が入っている道具箱
フレームワークみたいな全体を動かすためのロジックがないということ

<b>AngularJS</b>
SPAのライブラリ

<b>React</b>
SPAのライブラリ

<b>フロントエンド</b>
ユーザーからの入力情報をバックエンドが使用できるかたちに加工する
ユーザーなどと直接やり取りをする要素のこと

<b>バックエンド</b>
フロントエンドの入力データや指示をもとに、処理を行って結果を出力したり、記録媒体に保存したりする処理

<b></b>
「安心したいから」やるミーティングは無駄

様々な会社で様々なプロジェクトを見てきましたが、毎朝必ず朝会をやるチーム、毎夕必ず夕会をやるチームで、意識共有が出来ているチームを見た事がありません。

少し前に、会社のチーム横断のメンバーで「自分の仕事術」をお互いに教え合うという会に参加させてもらいました。
その際、自分の仕事術として「毎日、朝会と夕会をやってチームメンバーと意識合わせをする」と胸を張って答えた後輩がいました。
「えっ、毎日？朝会と夕会？それ、意味あるの？」
まさかこれでツッコミが入るとは……という顔で、答えられずにいる後輩。
「前の日の夕方と朝なんて、業務時間的にはせいぜい１時間か２時間、何も進んでないって言われても仕方ないと思うんだけど。時間の無駄では？」
「朝はその日の予定を確認したいんです。夕会はその日の進捗を確認したいんです」
「それを”全員が揃って”やる必要あるの？ミーティングで進捗報告会っていうのは、全員が”自分の進捗”を答えるだけじゃなく”他の人の進捗を聞く”時間も必要なんだよ。可動がかかるんだよ。無料じゃないんだよ。ミーティングする事自体反対派なんだけど、その目的であれば、夕会１回で済む話だよね？」
「でも、そうしないと、安心しないんです。」
ああ、これは言っても無駄なパターンだなぁと思いつつ、一応は言っておいた。
「安心したいなら、それこそ対面で話をしないと。打ち合わせの席じゃ緊張して上手くしゃべれない人もいるんだよ(特に自分たちの業界では……というデリケートな事は思っても言わない)。さっきの可動の話もある。
リーダーが安心したいだけの夕会なんて全く意味がないよ。
意識共有ならチャットやメーリスの方がまだいいよ。ミーティングだと、言った言わない論争だって発生してしまう。
朝回・夕会なんて、何も、いい事なんか無いんだよ」
しかし、結局、後輩は釈然としない、自分のやり方でチームは回っている、これが正しい、という考えは変えなかったようでした。

各個人へのヒアリングではなく、打ち合わせをする意義は何でしょうか。
ディスカッションだったり、他の人が詰まっている部分を解決したり出来る、いわゆる「問題発生と解消」ではないでしょうか。
それぞれがお互いに何をしているのかの把握に、打ち合わせは適しているとは思えません。
貴方の業務は、打ち合わせの席でちょっと話すだけで全体像がつかめるぐらい簡単な仕事なのでしょうか。そうではないでしょう。ですからチームメンバーに共有してるつもりでも、実際には「何となくあのひとはあの仕事をしてる人」程度の認識しか持たれません。
お互いが何をしているのかを把握し合うのであれば、業務的に全員を交代でその業務を体験させるか、勉強会をして共有するか、問題管理表を持ち回り制にするか等、もっと本腰を入れた対策をしなければ、単価に見合った効果は生まれません。

そう、単にリーダーが安心してるか、してないか。それだけです。実際は大きくかかった可動の分、損失を発生させているだけです。
リーダーの安心って、実務を超えるほど重要なのでしょうか？
da Vinci 1.0 のファームウェアを書き換える

# ファームウェアダウングレード
ヤフオクで3Dプリンターを12,800円（税込・送料込）で、落札し、入手しました。
ファームウェアのバージョンは、 1.3.4 です。これを 1.1.J にダウングレードします。
![DSC00493.JPG](https://qiita-image-store.s3.amazonaws.com/0/252891/938d3a90-95c8-6f7c-6463-31aeed52dae8.jpeg)

# 必要なもの
* da Vinci 1.0
* Windows 10 パソコン
* USBケーブル
* 特殊ドライバー
* ピンセット等

# ファームウェアの入手
次のページからファームウェアを入手します。
http://www.wctek.com/shop/content/11-repository
今回、書き込みツールも同梱されている[DAVINCI_1_0_RESET.zip](http://www.wctek.com/shop/files/DAVINCI_1_0_RESET.zip) を選びました。
ダウンロードし、C:\DAVINCI_1_0_RESET へ解凍します。

# 3Dプリンターのファームウェアリセット（完全消去）
ファームウェアを書き換えるために、3Dプリンターのファームウェアをリセットします。
このリセットを行うとファームウェアが完全消去され、初期化されます。
電源をオフにして、裏蓋をあけます。裏蓋は特殊ネジで、固定してあり、上部真ん中にツメがあります。
![DSC00497.JPG](https://qiita-image-store.s3.amazonaws.com/0/252891/b9e6b2b8-ec05-e54a-474b-5fe7fc2cd239.jpeg)
裏蓋をあけたら、リセット用のジャンパーピンを探します。JP1（またはJP37?）と印刷されているのがそれです。
![DSC00499.JPG](https://qiita-image-store.s3.amazonaws.com/0/252891/c47d8399-37ab-5630-6eb9-2cebf36faf9a.jpeg)
リセット用のジャンパーピンをピンセットなどでショートさせたまま、電源をオンにし、5秒間待ち、電源をオフにします。これで、リセットが完了です。
再び電源をオンにすると、LCDには、黒い帯が表示されたままになります。
![DSC00500.JPG](https://qiita-image-store.s3.amazonaws.com/0/252891/101f0362-933c-b4ff-c6b3-ce37843df7db.jpeg)

# パソコンとの接続
3DプリンターとパソコンとをUSBケーブルで接続すると、デバイスマネージャーで"Bossa Program Port"として、自動認識します。ここで、COMポート番号を控えておきます。
![BossaProgramPort.png](https://qiita-image-store.s3.amazonaws.com/0/252891/a66ec719-f6e0-956f-62a2-b71ac235ae77.png)

# ファームウェアの書き込み
コマンド プロンプトを開き、cd C:\DAVINCI_1_0_RESET で、カレントディレクトリを移動し、次のコマンドを実行します(今回、COMポート番号は、COM14です)。
bossac -p COM14 -R -e -w -v -b 3DP01_FW_V1.1.J.bin
![bossaccmd1.png](https://qiita-image-store.s3.amazonaws.com/0/252891/2755e0af-b907-5987-8df6-c42f1389bd07.png)

書き込みと検証が行われ、実行が完了します。
![bossaccmd2.png](https://qiita-image-store.s3.amazonaws.com/0/252891/83e1c0b8-63c9-1eb5-9a07-aa8e55a7a0ce.png)

正常に書き込みが完了すれば、デバイスマネージャーで"XYZprinting da Vinci"として自動認識されます。
![xyzprinting.png](https://qiita-image-store.s3.amazonaws.com/0/252891/ea5639d8-074e-99d1-b615-543568e47713.png)

# バージョンの確認
LCDには、1.1.Jと表示されました。
![DSC00504.JPG](https://qiita-image-store.s3.amazonaws.com/0/252891/7a691c7e-d84e-b81f-4f10-1c6f3649f234.jpeg)

# 自動アップグレード
XYZwareを利用していると、ファームウェアアップグレードの確認ダイアログが出てきますので、「いいえ」で、キャンセルします。
![upgrade.png](https://qiita-image-store.s3.amazonaws.com/0/252891/ac6de925-2a55-5aa8-d584-689a1ce30f2b.png)

# おわりに
これで、ファームウェアを自由に書き換えることが可能になりました。お好きなバージョンのファームウェアに書き換えたり、[カスタムファームウェア(Repetier-Firmware-4-Davinci)](https://github.com/luc-github/Repetier-Firmware-4-Davinci)に書き換えたりすることができます。
boto3でS3オブジェクトのpublicなURLを取得する方法

# 対象読者
boto3が提供しているAPIが `get_presigned_url` しかなくて困った仔羊に向けて :sheep:

# S3オブジェクトのpublicなURLを取得する場合のコード
```python:aws.py
import boto3

s3 = boto3.client('s3')

def get_public_url(bucket, target_object_path):
    """
    対象のS3ファイルのURLを取得する

    Parameters
    ----------
    bucket: string
        S3のバケット名
    target_object_path: string
        取得したいS3内のファイルパス

    Returns
    ----------
    url: string
        S3上のオブジェクトのURL
    """
    bucket_location = s3.get_bucket_location(Bucket=bucket)
    return "https://s3-{0}.amazonaws.com/{1}/{2}".format(
        bucket_location['LocationConstraint'],
        bucket,
        target_object_path)
```

# LocationConstraintの取得でAccess Deniedが出る場合
S3バケットのバケットポリシーを以下に設定する

```json:bucket_policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::[バケット名]/*",
                "arn:aws:s3:::[バケット名]"
            ]
        }
    ]
}
```

# 参考文献
https://stackoverflow.com/questions/33809592/upload-to-amazon-s3-using-boto3-and-return-public-url
PythonでFizzBuzzをやってみる

プログラム言語として人気急上昇のPython。
書き方も簡単ということでちょっとかじってみました。

今回、何をしたのかというとタイトルにもある通りFizzBuzzをやってみました。
いままでJavaScriptやPHPでやりましたが、今回はPythonでFizzBuzzに挑戦したいと思います。

今回試したPythonはPython3.7.2で実験をしました。もしかしたら２系だと正しく動かないかもしれないので注意が必要です。

## FizzBuzzとは？
１から１００までの数字を表示させます。ただし、３の倍数の時はFizz、５の倍数の時はBuzzと数字の代わりに表示させます。そして３と５の倍数の時はFizzBuzzと表示させます。
### 完成型
```
１
２
Fizz
４
Buzz
（中略）
１４
FizzBuzz
１６
（中略）
９８
Fizz
Buzz
```
## 完成するまでの手順
いきなりプログラムを書けるほどの能力はないので、まずは手順を考えていきたいと思います。
#### １．表示させる命令が必要
表示させないと意味がないので、まずは表示させられるようにします

```Python
print(i)
```
今回は表示させるためにprintを使っていきます。
#### ２．１から１００までを表示させる
```Python
print(1)
print(2)
print(3)
...
```
上のようにしてprintで１００まで書いていくのは現実的ではないですよね。と言うことで今回はwhileを使って１００まで繰り返し処理をさせていくことにします

```Python
i = 1
while i <= 100:
    print(i)
    i = i + 1
```
これで１から１００まで自動的に表示させてくれるようになりました。
##### 豆知識
先のコードに入っている『i = i + 1』ですが、ちょっとだけ短く書けます。

```Python
i += 1
```
上記の書き方でも『i = i + 1』と同じ意味なのでまずはわかりやすい方で書いてみると良いと思います。
#### ３．『Fizz』を入れてみる
数字で１００まで表示されるようになったので、今度は３の倍数をFizzに置き換えたいと思います。ここではif文を使っていきたいと思います。if文を文章で書くと次のような感じになります。

『もし、３の倍数ならFizzと、それ以外なら数字を表示させなさい。』

この文章を元にif文を作るとこんな感じになります

```Python
if i % 3 == 0:
    print('Fizz')
else:
    print(i)
```
Buzzも同じ考えで作れるのでコードだけ紹介

```Python
if i % 5 == 0:
    print('Buzz')
else:
    print(i)
```
#### ４．複数の条件で表示内容を変えてみる
３の倍数と５の倍数の時は上のコードでFizzやBuzzが出るようになりました。しかし、３と５の倍数でFizzBuzzと表示させるためのコードがまだ用意できていません。こちらもif文で作れるので用意していきたいと思います。

『３の倍数でなおかつ５の倍数の場合FizzBuzzと表示する。それ以外の場合は数字を表示する』

上の文章を元にコードにしていくと次のようなコードになります

```Python
if i % 3 == 0 and i % 5 == 0:
    print('FizzBuzz')
else:
    print(i)
```
if文の中でandを使うことで複数の条件で表示結果を分岐させることができます。
#### ５．結果を複数に分岐させていく
ここまでで３の倍数のとき、５の倍数のとき、３と５の倍数のとき、それぞれでFizz、Buzz、FizzBuzzと文字を表示させられるようになりました。あとはこれをひとつにまとめていきたいと思います。ここでもif文を使うんですが、複数に分岐する場合は『else』の代わりに『elif』を使います。phpでいうところの『else if』です。

『３と５の倍数のときはFizzBuzzと表示する。３の倍数のときはFizzと表示する。５の倍数のときはBuzzと表示する。それ以外のときは数字を表示する』

上の文章を元にif文を作っていきます。ここでのポイントは一番条件が厳しいFizzBuzzを一番最初にしていることです。３の倍数や５の倍数のときの条件をはじめにしてしまうと、その条件を満たしてしまうと次の処理に移ってしまうので思うように機能してくれません。

```Python
if i % 3 == 0 and i % 5 == 0:
    print('FizzBuzz')
elif i % 3 == 0:
    print('Fizz')
elif i % 5 == 0:
    print('Buzz')
else:
    print(i)
```
#### ６．FizzBuzzを完成させる
複数の条件分岐が完成したので、あとは最初に作ったwhile文の１から１００まで表示させるものとコードを合わせるとFizzBuzzの完成です。

```Python
i = 1
while i <= 100:
    if i % 3 == 0 and i % 5 == 0:
        print('FizzBuzz')
    elif i % 3 == 0:
        print('Fizz')
    elif i % 5 == 0:
        print('Buzz')
    else:
        print(i)
    i += 1
```

これでFizzBuzzは完成しているんですが、もう少しだけスマートな書き方に変えていきたいと思います。

#### For文を使ってFizzBuzzを作る
上のFizzBuzzでは１から１００まで繰り返すのにwhile文を使いました。この部分をfor文に変えていこうと思います。

```Python
for i in range(1, 101):
    if i % 3 == 0 and i % 5 == 0:
        print('FizzBuzz')
    elif i % 3 == 0:
        print('Fizz')
    elif i % 5 == 0:
        print('Buzz')
    else:
        print(i)
```
while文と違うところとしてrange関数を使ったところでしょうか。こんな書き方でもFizzBuzzができます。
【JavaScript 】オブジェクトのキーと値を取得する

# オブジェクトのキーと値を取得する
```javascript:
'use strict';

const obj = {
    a: 1,
    b: 2,
};

// キー
console.log(Object.keys(obj)) // ["a", "b"]

// 値
console.log(Object.values(obj)); // [1, 2]

// キーと値
console.log(Object.entries(obj)) // [["a", 1], ["b", 2]]

Object.keys(obj).forEach(key =>{
    console.log(`${key} = ${obj[key]}`);    
});
// a = 1
// b = 2

Object.entries(obj).forEach(([key, value]) =>{
    console.log(`${key} = ${value}`);
});
// a = 1
// b = 2
```
※Google Chrome で確認
※ES8
MacBook Proがフリーズしまくるので、解決方法を共有する

#私のMacの構成

macOS High Sierra
MacBook Pro (13-inch, 2016)
Memory 8GB

リファービッシュ品なので、購入は2018年3月

#フリーズが多い現象
少なくとも1日に1回はフリーズする。しかも長い。（5分とか）
フリーズ中には例のレインボーのくるくる（レインボーカーソルというらしい）が出るのだが、
**回らないで止まる**

という現象が発生していた。

#パターンがあることに気がつく

ある程度我慢していると、フリーズのタイミングが２つに絞れてきた。

・Safari使用中
・文字入力中


#解決方法

当たり前ですが、これら怪しいプログラムを使わないようにしました。

・Safari→Google Chromeに変更する
・Mac既定の文字入力→Google IMEをインストール

こんな簡単な事でフリーズが直りました。


#Appleサポートのクソっぷり

今までに役に立ったことがないのだが、一応Appleサポートに連絡してみた。

勿論返答は、
「インストールされている、他のアプリが悪い可能性があります」

だって。

いつもそれだよ。絶対OSXのせいでしょ。
GitHub Pages で使えるコメントウィジェット utteranc.es が便利

先日[ブログエンジンを自作して](https://7colou.red/blog/2019/flxble.html), GitHub Pages で自分のブログを構築したんですが, そこにコメント欄を付けたくて採用した [utteranc.es](https://utteranc.es) がかなりいい感じなので書いておきます.

## 仕組み

レポジトリにあらかじめ [utterances app](https://github.com/apps/utterances) をインストールしておくと, ブログ記事に対応した Issue がそのレポジトリに作られます. そして, ブログ記事のコメント欄に書き込むと該当の Issue のコメント欄に書き込まれ, Issue のコメント欄の内容がブログ記事のコメント欄の内容になります.

これによって, 静的サイトに簡単にコメント欄を付けることができます. ただし, コメントには GitHub のアカウントが必要になります.

utteranc.es は[オープンソース](https://github.com/utterance)で, 公式サイトいわくトラッキングも広告もなく, コメントデータは全て GitHub issue に保存されるので, 安心して使うことができそうです. 

## 導入方法

コメント欄を付けたい GitHub Pages があるレポジトリに [utterances app](https://github.com/apps/utterances) をインストールしたら, 記事に以下のスクリプトタグ

```html
<script src="https://utteranc.es/client.js"
        repo="<username>/<repository>"
        issue-term="pathname"
        theme="github-light"
        crossorigin="anonymous"
        async>
</script>
```

を貼り付けるだけです(`<username>`, `<repository>` はそれぞれ GitHub のユーザ名, レポジトリ名に変えてください). 
[utteranc.es](https://utteranc.es/) のウェブサイトで細かいカスタマイズをしたスクリプトタグを生成することができ, 例えば配色テーマや Issue との対応のさせかたなどを変更することができます.

## いいぞ

シンプルでエレガントなのであんまり書くことがないですね. GitHub のアカウントが必要なのが難点ですが, 勝手に広告を入れたりトラッキングしてきたりする外部サービス[^disqus]に頼るよりよっぽどいいと思います. なんで知名度がないのか不思議なのでみんな使いましょう.

[^disqus]: Disqus お前お前お前お前お前お前お前お前
[ESP32] GPSで自分の位置を確認する。その2


##以前の物語。

1. [[ESP32] GPSで自分の位置を確認する。その１](https://qiita.com/Dreamwalker/items/8a70c599fd198951e141)


##はじめに

こんにちは。以前には自分の位置を確認するため、ESP32とGPSモジュールを使ってUART通信で地球に自分の位置の座標を確認した。やはり、個人的にGPSは室内では使わないので、不便です。で、みんなビーコン使って室内位置を確認するんだと

でも、これは車とか運動とか山登りに自分の移動経路を確認したかった。

まず、条件を考えてみるとこれかなと

1. ポケットに入るくらいの小さいなサイズ。
2. 一日中ずっと使うくらいの稼動時間.
3. 座標や時間や高度をセーブするメモリー

後、問題あると変われるかもしれません。


#はんだ付け

![img](https://github.com/JAICHANGPARK/ESP-Dock/blob/master/ESP32/code/GPS/img/20190113_175614.jpg?raw=true)

これはESP32とGPSモジュールとOn/Offスイッチになります。


つづく。