OmniAICreator/Qiita-1.07M huggingface dataset:
OpenOfficeでドキュメント変換

#はじめに
ドキュメントを別のフォーマットのドキュメントに変換したい場合があります。
例えば、ExcelをPDFに変換したい。
PCの場合は、OfficeのExcelでは簡単にほかのフォーマットを保存するだけで変換されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/b805b422-d756-2b4a-493a-67ce99cc7c6f.png)

ユーザー操作ではなく、プログラムで自動変換したい場合は、Openofficeを利用することで実現できます。

#OpenOfficeインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/3e276bcf-623e-8df8-18b7-ad48ffe8192a.png)

コマンド：

```shell
sudo su -

wget https://sourceforge.net/projects/openofficeorg.mirror/files/4.1.6/binaries/ja/Apache_OpenOffice_4.1.6_Linux_x86-64_install-rpm_ja.tar.gz

tar -xvzf Apache_OpenOffice_4.1.6_Linux_x86-64_install-rpm_ja.tar.gz

cd ja/RPMS

rpm -Uvih *rpm

# インストール確認
ll /opt/openoffice4

# シンボルリンクを作成する
ln -s /opt/openoffice4/program/soffice /usr/local/bin/soffice

# 日本語フォントインストール
sudo yum install ipa-gothic-fonts ipa-pgothic-fonts
sudo fc-cache -fv

```

# OpenOffice起動
```shell
# en_US.UTF-8だと日本語文字化けなので、日本語を設定
export LANG=ja_JP.UTF-8

# 起動
nohup soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard &

# 起動確認
ps aux | grep soffice
```
#コマンドで変換
testfile.txtをPDFファイルに変換するサンプルです。
`soffice --headless --convert-to pdf testfile.txt`

# プログラムで変換
## ライブラリ
jodconverterというライブラリで変換
jodconverter：https://github.com/sbraconnier/jodconverter/

## ライブラリ導入
```gradle
// https://mvnrepository.com/artifact/org.jodconverter/jodconverter-local
compile group: 'org.jodconverter', name: 'jodconverter-local', version: '4.2.2'
```

## 変換サンプル
```DocConverter.java
import java.io.File;

import org.jodconverter.DocumentConverter;
import org.jodconverter.LocalConverter;
import org.jodconverter.office.LocalOfficeManager;
import org.jodconverter.office.OfficeException;
import org.jodconverter.office.OfficeManager;

public class DocConverter {

	public static void main(String[] args) throws OfficeException {

		OfficeManager officeManager = LocalOfficeManager.make();
		DocumentConverter converter = LocalConverter.make(officeManager);
		try {
			officeManager.start();

			File inputFile = new File("/data/test.xlsx");
			File outputFile = new File("/data/test.pdf");
			// Convert...
			converter.convert(inputFile).to(outputFile).execute();
		} finally {
			officeManager.stop();
		}
	}
}

```

# Liferayは設定だけでドキュメントの変換可能
コントロールパネル⇒設定⇒サーバ管理⇒外部サービス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/9f182aef-51c5-0dae-56a9-022eb06ad960.png)



URL:https://www.openoffice.org/


以上
gcloud app deployしたアプリが動かずにかなりハマった話

皆さん、こんにちは。

最近、GAE(Google App Engine)を使ってGOのアプリを開発をしているのですが、デバッグも終わっていざデプロイしてみると、起動した後に以下のような画面になって全く動かない、という現象に遭遇しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466621/d6e2a271-fb83-5460-02c8-710bf3048f44.png)

結論として、原因はapp.yamlファイルにあったのですが、どこがおかしいのか分かりますか？

```app.yaml
runtime: go112

env_variables:
  DB_USER: "XXX"
  DB_PASSWORD: "XXX"
  SERVER_PORT: "8000"
```

ちょっと考えてみてください。


...

...

...

...

...


はい、ポートがダメです。

```
SERVER_PORT: "8000"
```

GAEではデフォルトのポート番号が8080で固定されているので、そこに気づかずに別ポートを指定してしまうと、ファイアウォールにブロックされてしまうわけですね。(よく考えたら、当たり前の話でした。。)

ポート番号を8080に書き換えたら、無事ページが表示されました。

デフォルトのポート番号がある、ということを知らずに結構ハマってしまいましたが、このハマりが誰かの助けになれば幸いです。
AtCoderのkotlin(1.0.0)でPriorityQueueを使う(+ ジャッジサーバの環境を調査)

## AtCoder Beginner Contest 141 D問題
https://atcoder.jp/contests/abc141/tasks/abc141_d
昨日のAtCoderD問題は割引券の問題で、
簡単にいえば使用すれば何回でも半額になる割引券をいかに効率よく適用させていくかの問題になります。


割引を効率よく適用させるには、都度都度最大値の品物を取得する必要があるのですが
そのために、要素の追加、最大値の取得がそれぞれlogNと1でできる優先度付きキュー（PriorityQueue）を使用します。
（今回の解説を読んで初めて知った）

というわけで以下のようにPriorityQueueをインスタンス化します。

```Main.kt
    val tmpQueue: Queue<Int> = PriorityQueue<Int>() { i1: Int, i2: Int ->
        return@PriorityQueue i2 - i1
    }
```

これでローカル上では完璧に動いた！と思ったのですが、AtCoderのジャッジサーバではコンパイルエラーが発生します。

```エラーメッセージ
Main.kt:16:32: error: none of the following functions can be called with the arguments supplied: 

```

調べた所、Comparatorのみを渡してPriorityQueueをインスタンス化するコンストラクタはJava1.8から入ったそうで、もしやと思い、Java1.8よりも前からあるPriorityQueue(int initialCapacity, Comparator<? super E> comparator)を使用した所、コンパイルエラーが解消されました。

```Main.kt
    val tmpQueue: Queue<Int> = PriorityQueue<Int>(size) { i1: Int, i2: Int ->
        return@PriorityQueue i2 - i1
    }

```

そういえばジャッジサーバのランタイムバージョンを知らないなぁと思って、システム情報を出力するプログラムをちゃちゃっと書いて確かめてみる。

```CodeTest.kt
fun main(args: Array<String>) {
    for ((key,value) in System.getProperties()) {
        println("key -> $key value -> $value")
    }
}
```

以下その結果

```標準出力
key -> java.runtime.name value -> OpenJDK Runtime Environment
key -> sun.boot.library.path value -> /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64
key -> java.vm.version value -> 24.121-b00
key -> java.vm.vendor value -> Oracle Corporation
key -> java.vendor.url value -> http://java.oracle.com/
key -> path.separator value -> :
key -> java.vm.name value -> OpenJDK 64-Bit Server VM
key -> file.encoding.pkg value -> sun.io
key -> user.country value -> US
key -> sun.java.launcher value -> SUN_STANDARD
key -> sun.os.patch.level value -> unknown
key -> java.vm.specification.name value -> Java Virtual Machine Specification
key -> user.dir value -> /imojudge
key -> java.runtime.version value -> 1.7.0_121-b00
key -> java.awt.graphicsenv value -> sun.awt.X11GraphicsEnvironment
key -> java.endorsed.dirs value -> /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/endorsed
key -> os.arch value -> amd64
key -> java.io.tmpdir value -> /tmp
key -> line.separator value -> 

key -> kotlin.home value -> /opt/kotlinc
key -> java.vm.spec...
```

やっぱりランタイムはJava1.7でした。
ということはJava1.8で追加されたメソッド類は使えません。

今後気をつけなければ。。。

## 参考リンク
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Comparator.html
Xcode 11 GM SeedでRLMExceptionが発生した時の対処法

# 概要
Xcode 11 GM SeedでRLMExceptionが発生した時の対処法についてです。
RealmSwiftを使って実装していたら、下記のエラーが発生しました。

```console
uncaught exception 'RLMException', reason: 'Primary key property 'id' does not exist on object
```

プロパティキーのプロパティである'id'が存在しませんよーというエラーですが、実装しているモデルにはちゃんと'id'が設定されているため、原因が謎でした。

調べてみたところ、realmのIsuueに同じような現象が起きている人が何人もいて、解決策も提示されていたのでこちらにも共有しようと思います。
[Support Xcode 11 things #6163](https://github.com/realm/realm-cocoa/issues/6163)

# 対処法
結論としては、Realmの開発者様が最新バージョンで対応してくれているので、GitHubのmasterブランチのrealmを直接インストールすれば解決します。
以下CocoaPodsを用いた最新版インストールのやり方です。

まず、podfileに下記2行を追加します。すでにrealmを記載している人は書き換えましょう。

```vim
pod 'RealmSwift', git: 'https://github.com/realm/realm-cocoa.git', branch: 'master', submodules: true
pod 'Realm', git: 'https://github.com/realm/realm-cocoa.git', branch: 'master', submodules: true
```

次に`pod install`を実行し、プロジェクトをクリーンビルドします。
するとRLMExceptionが解消され、正常にビルドできるようになります。

上記を行っても正常に動かない場合は、実機デバイスやシミュレータから対象アプリを削除してからもう一度ビルドしてみましょう。
seleniumを使ってC#でGoogle Chromeの自動操作をする

#やりたいこと
1.Google Chromeで[https://www.google.co.jp/](https://www.google.co.jp/)を開く
2.テキストボックスに"Selenium"を入力
3.「Google 検索」ボタンをクリック
##環境
- Windows 7
- Google Chrome 77
- Visual Studio Community 2019


##準備
1.C#のコンソールアプリでプロジェクトを作成
2.NuGetパッケージ管理にて以下をインストール
- Selenium.WebDriver
- Selenium.WebDriver.ChromeDriver

##ソース
```Program.cs
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumChromeSample
{
    class Program
    {
        /// <summary>
        /// SeleniumでIEを自動操作するサンプル
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            IWebDriver driver = new ChromeDriver();
            IWebElement textbox;
            IWebElement findbuttom;

            //Webページを開く
            driver.Navigate().GoToUrl("https://www.google.co.jp/");

            //検索ボックス
            textbox = driver.FindElement(By.Name("q"));
            //検索ボックスに検索ワードを入力
            textbox.SendKeys("Selenium");

            //検索ボタン
            findbuttom = driver.FindElement(By.Name("btnK"));
            //検索ボタンをクリック
            findbuttom.Click();
        }
    }
}
```

##参考
[Selenium - Web Browser Automation](https://www.seleniumhq.org/projects/)
Karabiner-Elementsを使ってセミコロンエンターを実現する

# はじめに

Mac OSXでキーバインドを変更できるツール[Karabiner-Elements](https://pqrs.org/osx/karabiner/)を使っている人が多いと思う。
実は単純なキーのリマップだけでなく、少し複雑な処理も自分でjsonファイルを書くことで実現できる。

この記事ではセミコロンをエンターにリマップする方法を紹介する。セミコロン`;`は右手小指のホームポジションにあるキーだが、そこをenterキーに変えるとめちゃくちゃ作業が捗る。
エンターキーを押す頻度は本当に高いが、そのキーが近くにあると本当に楽になるのでぜひ一度試してほしい。試せばわかる。

この時、単純に`;`をエンターキーにリマップしてしまうと、セミコロンを打つ手段がなくなってしまう。`ctrl + ;`を打つと`;`を打てるようにする。

ちなみにこの記事の内容は Karabiner-Elements 1.27.0 で動作確認している。

# 手順

Karabiner-Elementsの"complex modifications"という機能を使う。

## 手順1: キーリマップを定義したJSONファイルの準備

以下のようなjsonファイルを `~/.config/karabiner/assets/complex_modifications`ディレクトリに配置する


```json:semicolon_enter.json
{
  "title": "semicolon to enter",
  "rules":
  [
    {
      "description": "semicolon to enter",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "semicolon",
            "modifiers": {
              "mandatory": [
                "control"
              ]
            }
          },
          "to": [
            {
              "key_code": "semicolon"
            }
          ]
        },
        {
          "type": "basic",
          "from": {
            "key_code": "slash",
            "modifiers": {
              "mandatory": [
                "control"
              ]
            }
          },
          "to": [
            {
              "key_code": "semicolon"
            }
          ]
        },
        {
          "type": "basic",
          "from": {
            "key_code": "semicolon",
            "modifiers": {
              "optional": [
                "caps_lock"
              ]
            }
          },
          "to": [
            {
              "key_code": "return_or_enter"
            }
          ]
        }
      ]
    }
  ]
}
```

書式は[公式ドキュメント](https://pqrs.org/osx/karabiner/json.html)にも書いてあるが、上記のjsonファイルを見れば何をどうマップしているのかだいたい理解できると思う。
（ここでは`ctrl + /`も`;`にマップしている。これは自分の趣味）

## 手順2: Karabiner-Elementsにロードする

"Complex modifications"のタブから"Add rule"をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/5da62813-045e-e671-62bd-ba024ec69438.png)

先ほど追加したルール(semicolon to enter)の"Enable"をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/0bec290d-cda1-8ef9-e8e1-6a81d06100db.png)

以上で完了。すぐに変更が反映されるはず。

# 参照

- [公式ドキュメント](https://pqrs.org/osx/karabiner/json.html)
- [Karabiner-Elementsの設定項目をまとめました](https://qiita.com/s-show/items/a1fd228b04801477729c)
Web開発用Javaフレームワーク Spring Boot2 紹介(初心者向け)

<html>
<head>
「Web開発用Javaフレームワーク」 Spring Boot2の紹介を致します.<br><br>
</head>
<body>
以下はGoogleトレンドを使用した2019年現在(9/16)日から過去2年間の代表的なJavaフレームワークの人気となっています.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497973/b6e39074-87ad-0ce9-d923-a9e8055a1395.png)
<font color="gray">(本題として紹介したい為Spring Bootの検索方法が少しズルい気がしますが...)</font><br><br><br><br>
上記からWeb開発用JavaフレームワークとしてSpring Bootが注目されていることがわかります.<br>
Webアプリケーションの土台として様々な設計思想・基盤があり,複数人でのチーム開発を基本とする昨今の開発スタイルにおいてフレームワークを使用することは意志共有・管理のしやすさ・業務の効率化の上で欠かせないものであると考えます.
こうした背景の上で,フレームワークのトレンドを仕入れることは業務上において大きな武器となるのではないでしょうか.<br>
(link：Spring BootとPlay Framework、どっちがどう良いの？ 専門家が5つの視点で徹底解説 様)https://employment.en-japan.com/engineerhub/entry/2019/03/15/103000
<br><br><br><br><br>


前段はさておき,早速Spring Boot2の紹介に入りたいと思います.<br><br><br><br>

Spring BootはSpring MVCを継承したModel-View-Controllerアーキテクチャーによるフレームワークとなっています.
しかしながら,これらを利用するには多数のライブラリを正確に組み合わせて環境を構築しなければならず,
手早くアプリケーションを作り上げるにはかなり大変であった,という背景があるそうです.
(多数のDIをxmlに記述しいくつものエラーが発生した方は経験いらっしゃるかと思います...)<br>
その後,Spring MVCを補完するライブラリとして登場したのがSpring Rooというもので,
アプリケーションの枠組みがある程度自動化できるようになりましたが,それでもまだ十分とはいえない状態でした.<br>
今回紹介するSpring Boot2はSpring MVCやその他のSpring Frameworkのライブラリを組み合わせてWebアプリケーションを高速に作成するためのスターターパッケージとして提供された いわば<font color = "red">「Spring MVCの完成形」</font>となるものです.
xmlファイルに専用のライブラリを記述することで一通りのライブラリを読み込み,環境を構築し,圧倒的な速さで組み立てることが可能となっているそうです.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497973/61db9579-5097-9bda-0499-2004edd7f21b.png)
<font color="gray">JPAを使いやすくしたSpring Boot Starter Data JPA,データベース周りでの圧倒的な利便さ「Repository」など
<br><br><br><br>
また,既存のWebアプリケーションではjspを使用したviewの作成が基本となっていました.
<font color = "blue">jspの強みとしてjsp内にjavaのソースを記述できるが,それ故に区別なくjavaのソースを記述出来る為
処理がわかりづらくなってしまい,保守・管理する上では決して優れたものではないと評価されているようです.</font>
(link:出羽ブログ 様)https://dewa.hatenadiary.org/entry/20080304/1204709346<br>
Spring Bootではこの問題を解決できる<font color = "green">「Thymeleaf」</font>といったテンプレートエンジンが存在しており,
th:hoge  といった属性をHTMLタグに追加することにより処理を組み込める他,独自タグを使わない為HTML等の親和性も高く
編集しやすいのが利点となっています.
(link:teratail 様)https://teratail.com/questions/77163



最後に,強力なrepositoryを使用したサンプルコードの紹介を以って本記事の終わりとしたいと思います.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497973/71780fc5-ac19-22dc-3116-8c41dde92989.png)
(引用元：Spring Boot2 チートシート 様)
https://qiita.com/azul915/items/5f7003bb78917dff6bb1#jparepository%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E5%AE%9F%E8%A3%85%E4%BE%8B
Wi-Fi通信速度測定 2　～ここWi-Fi飛んでんな～

## 【序文】
前回 [Wi-Fi通信速度測定](https://qiita.com/god19/items/a3d76434ee24d2001923 "Wi-Fi通信速度測定") の続き。
[WI-U2-433DHP](https://www.buffalo.jp/product/detail/wi-u2-433dhp.html "WI-U2-433DHP _ Wi-Fiアダプター _ AirStation _ バッファロー") が安売りされていたので買ってきて Pi3 に繋げてみたので記録に残す。

## 【ドライバ導入】
Linux で Wi-Fi は鬼門。ドライバが問題になる。しかも RapberryPi は ARM だしで。
幸い同機（同チップ）ドライバのコンパイルを含めた導入手順を公開している方がいらっしゃったのでそちらを参考にさせていただいた。多謝。
[USB端子に接続して使う11ac対応無線LAN子機 WI-U2-433DHP をRaspberry Pi 3 につけてみた – とりあえずノートがわりに書いてます](https://mynotebook.h2np.net/post/1545 "USB端子に接続して使う11ac対応無線LAN子機 WI-U2-433DHP をRaspberry Pi 3 につけてみた – とりあえずノートがわりに書いてます")

## 【その他の設定】
ドライバのインストールが完了すると無事認識してくれた。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/a91067c5-47e3-a907-609a-c9b77ea13252.png" width=20%>

```
$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000
    link/ether b8:27:eb:ac:f7:00 brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DORMANT group default qlen 1000
    link/ether b8:27:eb:f9:a2:55 brd ff:ff:ff:ff:ff:ff
4: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
    link/ether 18:c2:bf:b1:77:50 brd ff:ff:ff:ff:ff:ff
```

wlan0 がオンボード Wi-Fi、wlan1 が追加したやつ。
このままでは、オンボードの Wi-Fi が優先されてしまうので、以下コマンドで止める。

```
$ sudo iwconfig wlan0 txpower off
```

因みにモジュールの登録は rootユーザで。

```
# echo rtl8821au > /etc/modules-load.d/rtl8821au.conf
```

## 【速度測定】
[前回](https://qiita.com/god19/items/a3d76434ee24d2001923 "Wi-Fi通信速度測定") と同様に速度測定。

```
pi@raspberrypi3:~ $ iperf3 -c 192.168.11.101
Connecting to host 192.168.11.101, port 5201
[  4] local 192.168.11.110 port 52798 connected to 192.168.11.101 port 5201
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec  12.2 MBytes   102 Mbits/sec    0    559 KBytes       
[  4]   1.00-2.00   sec  11.2 MBytes  94.4 Mbits/sec    1    461 KBytes       
[  4]   2.00-3.00   sec  11.2 MBytes  93.9 Mbits/sec    0    509 KBytes       
[  4]   3.00-4.00   sec  11.2 MBytes  94.3 Mbits/sec    0    543 KBytes       
[  4]   4.00-5.00   sec  11.2 MBytes  94.3 Mbits/sec    0    563 KBytes       
[  4]   5.00-6.00   sec  11.2 MBytes  94.4 Mbits/sec    0    571 KBytes       
[  4]   6.00-7.00   sec  11.2 MBytes  93.9 Mbits/sec    0    574 KBytes       
[  4]   7.00-8.00   sec  11.2 MBytes  94.4 Mbits/sec    0    574 KBytes       
[  4]   8.00-9.00   sec  11.2 MBytes  93.8 Mbits/sec    0    574 KBytes       
[  4]   9.00-10.00  sec  11.2 MBytes  94.3 Mbits/sec    0    580 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   113 MBytes  95.0 Mbits/sec    1             sender
[  4]   0.00-10.00  sec   112 MBytes  94.0 Mbits/sec                  receiver

iperf Done.
```

95.0 Mbits/sec と、3B+ のオンボード Wi-Fi と同程度の結果。
可もなく不可もなくな感じ。
千葉県のサポート情報の地図を紙で綺麗に印刷できるサイトを作った

千葉県南部では停電が続き、大変な状況のようです。エンジニアはエンジニアらしく、コードで貢献できるところがあればと思って活動しています。

そこで、何かの役に立てばと思い以前広島の洪水の際に作った印刷プロジェクトを再度稼働しました。

一言で言えば、以下のように、**A4縦型でサポート情報の地図を表示できる**ものです。

![スクリーンショット 2019-09-16 02.58.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399/416ff0d4-213e-a611-7edd-9788db76d9c5.png)

[https://codeforjapan.github.io/mapprint/map.html](https://codeforjapan.github.io/mapprint/map.html) からアクセスすることができます。

大元のデータは、許可を得て[【千葉】ガソリン (赤：無事、黒点：未確認)・給水・避難所・携帯充電・無料Wifi マップ](https://www.google.com/maps/d/viewer?mid=18v4csEC-qPW_aeXhEnuzgMfUAqWcbF5q&ll=35.67442129451116%2C140.02272653174054&z=10) からダウンロードして使わせていただきました。有志の手で Google マイマップを使ってデータを収集されています。素晴らしい活動をありがとうございます。（最低1日1回程度は手作業で取り込み作業をしています。）

ただし、元データに緯度経度が入っていないものが多く、全てのサポート情報が入っているわけではありません。お気を付けください。

## 紙地図素晴らしい
PCから見るのであればGoogleマイマップのままでも十分使えはするのですが、お年寄りには難しいですし、停電しているのでそもそも見れないという方も多いと思います。そんなときに便利なのが「紙の地図」です。おばあちゃんにそのまま渡すこともできますし、避難所に貼っておくこともできます。コピーも取れますし、コンビニプリントも可能です。独自の情報を書き込んで使うこともできます。

使い方は簡単。上記のサイトにアクセスして、表示したい範囲を指定して、「A4で印刷する」ボタンを押すだけです。（あまり表示範囲が広すぎると、リストが長くなりすぎてしまいますので注意。）

是非千葉県の方にお伝えいただきたいです。

## コントリビュータ募集！
なぜQiitaにこの記事を書いているかと言うと、まだまだ改善点があるので、エンジニアやデザイナーの皆様に手助けをいただきたいからです。

https://github.com/codeforjapan/mapprint でオープンに開発しておりますので、ぜひお手伝いください。参加の仕方は README.md と CONTRIBUTE.md を見てください。

Issues の中の、`good first issue` ラベルの付いたものは、比較的簡単な修正ですので、とっつきやすいです。

技術としては、フレームワークに `Middleman + npm + Gulp` を使っており、コミットのタイミングで `CircleCI` 経由でコードをデプロイし、 `GitHub Pages` に静的ホスティングをしています。地図ライブラリは `MapboxGL.js` を使っています。

初心者の方も大歓迎です。募金やボランティア以外にも何か手を動かしたいと思っている方、ぜひお願いします。オープンソースプロジェクトへの参加が初めて、という方にも丁寧にサポートします。

## どんな作業があるの？
[「faviconが無いから作りたいんだよね！」](https://github.com/codeforjapan/mapprint/issues/159)や[「スマホで見たときに表示がおかしい」](https://github.com/codeforjapan/mapprint/issues/165)といった簡単なものから、[「jQuery やめて Vue.js に移行したいね」](https://github.com/codeforjapan/mapprint/issues/148) や[「突貫対応で飛ばしてしまったテストコードを書き直そう」](https://github.com/codeforjapan/mapprint/issues/144)
のような難易度の高いものまで、様々な作業があります。

このサイト自体は、最終的には複数の地図をサービスできるように考えています。

また、使っていて「こうした方が良いな」といった提案や、見つけた不具合を新たな Issue として登録するだけでも立派な貢献ですし、README 等のドキュメントを充実していただくのもありがたいです。

背景情報が少なくて確認したいことがある、環境構築で躓いた、といったことがあれば、それも Issue を使って聞いてみてください。

Code for Japan の Slack に今回のプロジェクト用のチャンネルもありますので、ぜひ加入してください。
Nuxt.js/Vue.jsでもスワイプでページ移動したい

Nuxt.jsで開発しているけど、スワイプで画面遷移とかしたいなと思い、
いろいろ調べたときの備忘録。

[vue-touch-events](https://github.com/jerrybendy/vue-touch-events)というのが良さそう(*´ω｀*)
[hammer.js](http://hammerjs.github.io/)というライブラリのラッパーらしい。

hammer.jsではスワイプだけでなく、
Pan / Pinch / Press / Rotate / Tapも検知できるよう。すごい。。


### インストール

```console
$ npm i -S vue2-touch-events
```


### pluginの作成

`~/plugins/vue2-touch-events.ts`を作成

```javascript
import Vue from 'vue'
import Vue2TouchEvents from 'vue2-touch-events'

Vue.use(Vue2TouchEvents)
```

### nuxt.config.tsの設定

作ったプラグインを設定する

```typescript
const config: NuxtConfiguration = {
  plugins: [
    { src: "~/plugins/vue2-touch-events.ts", ssr: false }
  }
}
```

### 使ってみる

```html
<template>
  <div
    v-touch:swipe.left="() => $router.push('left_page')"
    v-touch:swipe.right="() => $router.push('right_page')"
  >
  </div>
</template>
```

簡単( ﾟдﾟ)!

`v-touch:swipe.left`などのディレクティブが用意されているので、
必要なものを選択してcallback関数を設定すればOK。

タップなどの他のものは、GitHubの[README](https://github.com/jerrybendy/vue-touch-events)を参照。

### モバイルだけスワイプを有効にする

ユーザエージェントを見て有効/無効を設定する。
ユーザエージェントの判定は、[nuxt-user-agent](https://github.com/fukuiretu/nuxt-user-agent)が便利♪

設定方法や使い方などは、以前書いた[こちらの記事](https://www.memory-lovers.blog/entry/2019/07/27/073000)を参照ください。

nuxt-user-agentと一緒に使って、モバイルだけスワイプを有効にするとこんな感じ。

```html
<template>
  <div
    v-touch:swipe.left="() => { if(!$ua.isFromPc()) $router.push('left_page') }"
    v-touch:swipe.right="() => { if(!$ua.isFromPc()) $router.push('right_page') }"
  >
  </div>
</template>
```

### 作ってるサービスではこんな感じに

開発している[Webサービス](https://tsundoku.site)ではこんな感じに♪
サクッと導入できて便利でした(*´ω｀*)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おぉスワイプでページ遷移できたかも( ﾟдﾟ)!<br><br>vue2-touch-eventsすごい...(*´ω｀*) <a href="https://t.co/vOZjQOmiLA">pic.twitter.com/vOZjQOmiLA</a></p>&mdash; 積読ハウマッチ📚きらぷか (@kira_puka) <a href="https://twitter.com/kira_puka/status/1173349137292464128?ref_src=twsrc%5Etfw">September 15, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ランキングにもスワイプをつけてみた(*´ω｀*)<br><br>これでスマホでもスイスイ見れるヽ(=´▽`=)ﾉ <a href="https://t.co/jJL1zUvFGk">pic.twitter.com/jJL1zUvFGk</a></p>&mdash; 積読ハウマッチ📚きらぷか (@kira_puka) <a href="https://twitter.com/kira_puka/status/1173358673550163968?ref_src=twsrc%5Etfw">September 15, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## こんなのつくってます！！

最近、積読用の読書管理アプリ「積読ハウマッチ」をリリースしました！
[積読ハウマッチ](https://tsundoku.site)は、Nuxt.js+Firebaseで開発してます!

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/>

もしよかったら、遊んでみてくださいヽ(=´▽`=)ﾉ

要望・感想・アドバイスなどあれば、
公式アカウント([@MemoryLoverz](https://twitter.com/MemoryLoverz))や開発者([@kira_puka](https://twitter.com/kira_puka))まで
【GitHub Actions】自作Actionsのリリースを自動化する

TypeScriptでGitHub Actions用のActionsを自作する際に、色々と面倒臭い部分をGitHub Actions上で自動化したので共有します。
開発・メンテナンスしにくかった理由は、開発用のブランチでnode_modulesをトレース対象にし、ローカルでブランチ変えて`npm install --production`したりなど、普段の開発ではありえないことをする必要があったからです。
特に複数人で開発する際には列挙したことはかなりネックになると思います。
それでは、これらの解消方法を説明していきます!

今回の成果物は[release.yml](https://github.com/homoluctus/slatify/blob/master/.github/workflows/release.yml)にあります。これは実際に[homoluctus/slatify](https://github.com/homoluctus/slatify)で動いているので実質的に動作が保証されています。

# 自動化したこと

1. TypeScriptのビルド
2. 本番用のnode_modulesを作成(`npm install --production`)
3. 変更箇所のコミット
4. リリース用ブランチにプッシュ

# Workflow

```release.yml
name: Prepare for release

# イベントトリガーをpushに設定して、対象ブランチをreleases/*、ファイルパスをsrc/*に制限する
on:
  push:
    branches:
      - releases/*

    paths:
      - src/*

jobs:
  release:
    name: Build production
    runs-on: ubuntu-18.04
    steps:
      # remotes/origin/releases/v1にチェックアウト
      - uses: actions/checkout@v1
        with:
          ref: remotes/origin/releases/v1

      - name: Git checkout
        run: git checkout -b releases/v1

      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'

      - name: Install dependencies
        run: npm install

      # typescriptをコンパイル
      - name: NPM build
        run: npm run build

      # リリース用に.gitignoreからnode_modulesを削除
      - name: Not ignore node_modules
        run: sed -i '/node_modules*/d' .gitignore

      # リリース用にプロダクション用のモジュールのみインストール
      - name: Install dependencies for production
        run: |
          rm -rf node_modules
          npm install --production

      # gitのコンフィグ回りを設定
      - name: Setup git
        env:
          # GitHubのPersonal access tokens
          ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
        run: |
          git config --local user.name homoluctus
          git config --local user.email xxxxxxxx@xxxxxx
          git remote set-url origin https://homoluctus:${ACCESS_TOKEN}@github.com/homoluctus/slatify.git

      - name: Git commit
        run: |
          git add -A

          DIFF=`git diff --cached --numstat | wc -l`
          if [ $DIFF -eq 0 ]; then
          # ファイルの変更がなければjobを正常終了する
            exit 0
          fi

          git commit -am '[UPDATE] prepare for release'

      - name: Git push
        run: git push origin HEAD

      - name: Slack Notification
        uses: homoluctus/slatify@master
        if: always()
        with:
          type: ${{ job.status }}
          job_name: ':truck: *Prepare for release*'
          channel: '#develop'
          url: ${{ secrets.SLACK_WEBHOOK }}

  # releases/v1にプッシュしたコードが正常に動作するか確認
  check:
    name: Check action
    runs-on: ubuntu-18.04
    needs: release
    steps:
      - uses: actions/checkout@master

      - name: Slack Notification
        uses: homoluctus/slatify@releases/v1
        if: always()
        with:
          type: ${{ job.status }}
          job_name: ':robot_face: *Check action*'
          channel: '#develop'
          url: ${{ secrets.SLACK_WEBHOOK }}

```


# おわりに

今回説明したのを応用すると、Actionsの開発に限らず様々な場面でCIでコードを編集してコミット→プッシュすることができます。
煩雑な作業は自動化してスピーディーな開発を目指していきましょう!
数学 Cov(X, Y)のcovとは?

#Cov
Covは英語の「Covariance(共分散)」の略。Cov(X,Y)の場合、XとYの共分散のことを言っている。

#共分散
共分散は、「Xの偏差　×　Yの偏差」の平均と定義されている。期待値記号を使って書くと、
E[(X-μX)(Y-μY)]
となる
退会時に投稿データを削除する [Rails] 

#初めに
ポートフォリオを作成中、退会ユーザのデータの処理に困った結果、退会時に投稿データを削除することにしました。
※今回は論理削除を導入している為、論理削除が度々出てくると思いますが論理削除を導入していない場合でも、大丈夫です。

#開発環境
・ruby-2.5.5
・Rails 5.2.3

gem
・devise
・paranoia(論理削除用）

#前提条件
・deviseを使用したユーザ登録する。
・ユーザが退会すると削除フラグを設置し、論理削除扱いにする。
論理削除をついては[こちら](https://qiita.com/mailok1212/items/c5a1682e4f02eb0aea71)をご覧ください。

#現状
LINEの様なポートフォリオを作成中です。
ユーザが退会するとユーザ情報を論理削除されます。
しかし、退会ユーザの投稿はDB内に存在しているので、ある条件下（退会ユーザがコメントしたチャットルームに入る）ではエラーが発生します。

#改善策
退会時に、ユーザの投稿を削除することにしました。


#改善

##コントローラー
コントローラーに退会機能を記述します。
初心者でも見たことある記述だと思います。

```ruby:users_controller.rb
  def destroy
    user = User.find(params[:id]) #ユーザ毎の情報を得る
    user.destroy #ユーザ情報を削除（退会）
    redirect_to home_path #削除後、homeに移動させる
  end
```

##モデル
userモデルとmessageモデルは`１対多`になっています。

###message.rb
optional: trueは外部キーにnilを許可するものです。
```ruby:message.rb
belongs_to :user, optional: true
```
###user.rb
ここが重要です。
dependent => :destroyを記述することで、退会時にユーザID情報(user_idを持つもの）を持つデータを削除します。

```ruby:user.rb
has_many :messages, :dependent => :destroy#退会時コメントも削除
```

#最後に
たったこれだけで、退会時にデータを同時に削除できます。
もしよかったら参考にしてみてください。
AtCoder Beginner Contest 141のDをPython3で解いたメモ

問題↓
[D - Powerful Discount Tickets](https://atcoder.jp/contests/abc141/tasks/abc141_d)

# とりあえず自分が書いたやつ(TLE)
最安にしたいんだから, 現状最大のやつを値段半分にしていけばいいかと考えて書いた.
悪くはないと思うんだけどTLE. 時間切れでコンテスト中はここまで.

```python
N, M = map(int, input().split(" "))
A = [int(i) for i in input().split(" ")]

for i in range(M):
    tmp_index = A.index(max(A))
    A[tmp_index] = A[tmp_index] / 2
    
import math
B = [math.floor(A[i]) for i in range(len(A))]
print(sum(B))

```

# heapqモジュールを使えば最大値の取り出しが高速になるらしい
[Pythonでヒープ構造を使う（heapqモジュール）](http://inaz2.hatenablog.com/entry/2013/04/11/032256)

heapqは最小値を高速で見つけるものらしいので, とりあえずリスト内の値すべてに-1をかけておくというのが常套手段っぽい。
heapq.heapify(list)でソート, heapq.heappop(リスト)で最小値の値を取得&リストからその値を除去, heapqpush(リスト, 値）でリストに値を追加とのこと.

```python
import math
import heapq

N, M = map(int, input().split(" "))
A = [-int(_) for _ in input().split(" ")]

for i in range(M):
    heapq.heapify(A)
    heapq.heappush(A, heapq.heappop(A)/2)

B = [math.floor(-A[i]) for i in range(len(A))]
print(sum(B))
```

しかし結果はほぼ変わらず(TLE)

# math関数が足を引っ張っている可能性
切り捨てを行うのにmath.floorでやってたけれども遅いらしい.
[Python で割り算をするときの
切り上げと切り捨て](https://python.ms/sub/misc/division/#%EF%BC%93%E3%81%A4%E3%81%AE%E3%82%84%E3%82%8A%E6%96%B9)


これが一番高速らしい

```python
# 切り捨て
4 // 3

# 切り上げ
-(-4 // 3)
```

というわけでそっちを修正したバージョンを

```python
N, M = map(int, input().split(" "))
A = [int(_) for _ in input().split(" ")]

for i in range(M):
    tmp_index = A.index(max(A))
    A[tmp_index] = A[tmp_index] // 2    # ここが修正箇所

print(sum(A))
```

結果はTLE.

# heapqの書き方が悪いだけだった

毎回, heapq.heapifyやってるせいで計算時間がかかりすぎてるっぽいので修正

```python
import heapq

N, M = map(int, input().split(" "))
A = [-int(_) for _ in input().split(" ")]

heapq.heapify(A)

for i in range(M):
    heapq.heappush(A, -(-heapq.heappop(A)// 2))
    
print(-sum(A))
```

これでAC.
webアプリでデータをどこに保存するか

データの保存場所に悩む

- dbとapiサーバーを別に立てる
  - 一番確実だけど、一番手間がかかる。車輪の再発明もいいとこ
- localstorageに保存する
  - 一番簡単だけど、何かの拍子で消えるのが怖い。
  - 大量のデータには向いてない。最初に全部読み込んで、保存時は全部書き込む くらいの勢いが必要
- indexedDb
  - 手間は中くらい。ライブラリ使わず直で叩くのは、ギリ悩む程度には面倒くさい。
  - ブラウザだけで完結するのが強み。大量のデータもOK
  - 所詮chrome管理だから、何かの拍子で消えるリスクはある。
- firebase
  - 手間はindexedDbと同じくらいかな
  - firebaseの管理も必要なのがめんどくさい
  - 消えるリスクは考えなくていい

chromeの中に保存する方法はhtmlファイルだけで完結するけど、chromeのキャッシュクリアとかその辺でデータが飛ぶリスク有り。OSがぶっ壊れてchromeのユーザプロファイルのデータから直にデータを抜くのは結構めんどい。

外部にデータを保存する方法は管理が面倒。個人利用ならfirebaseの無料プランで収まるだろうけど。firebaseがいくら高速としても、chromeの中で完結する方法にはかなわないから読み込み速度の問題もある。

### nodejsの場合

- sqlite
  - windowsだとsqliteモジュールのインストールに失敗する事があるのでトラウマ。
- json
  - データをまるごとjsonに書き出すのが手っ取り早い

firebaseかな。
AtCoder Beginner Contest 141のＣをPython3で解いたメモ

問題はこちら
[C - Attack Survival]
(https://atcoder.jp/contests/abc141/tasks/abc141_c)

# まずは愚直な方法で解く
```python
N, K, Q = map(int, input().split(" "))
A = [int(input()) for i in range(Q)]

score = [K for i in range(N)]

for i in range(Q):
    num_ans_person = A[i] - 1
    score[num_ans_person] += 1
    for j in range(len(score)):
        score[j] += -1

for i in range(N):
    if score[i] > 0:
        print("Yes")
    else:
        print("No")
```

これだと計算時間がかかりすぎるためにTLE.
テストケースのsub1_13.txtはACだったが, 1285 msの時間がかかっている.

# 余事象側を考えてみる
正解数のほうに注目して高速化を図る.

```python
N, K, Q = map(int, input().split(" "))
A = [int(input()) for i in range(Q)]
 
tmp = []
for i in range(N):
    tmp.append(A.count(i+1)) #正解数
# 得点は, 最初の点数 - 他人の正解数
# 他人の正解数は, 問題数 - 自分の正解数
# 得点は, 最初の点数 - 問題数 + 自分の正解数
# 得点 > 0 であれば, "Yes"
for i in range(N):
    if K - Q + tmp[i] > 0:
        print("Yes")
    else:
        print("No")
```

テストケースのsub1_13.txtでは, 264 msと, 高速になってはいるもののTLE.

本質的な部分で計算量が変わっていないのかと.
おそらくは, 下の部分の処理が素人くさくて遅い。

```python
for i in range(N):
    tmp.append(A.count(i+1))
```

# 計算量を考えてみる
計算量を真面目に考える必要がありそう. O(N)みたいなやつ.

愚直な方法では, 問題数についてQ回の操作, 不正解の(N-1)人の点数を1点ずつ減点するので, O(QN).（多分）
N, Qがそれぞれ10^5なので, 最大10^10の計算量.

正解数に注目した方は, Q個のデータの入ったリストに対し, count関数でN回のループで計算.
これも同じような計算量になりそう.
forループを使わなかったことだけが高速化に効いてるだけっぽい.

# 毎回長さがQのリストを参照しているのが原因っぽいので直してみる
これでACでした.

```python
N, K, Q = map(int, input().split(" "))    # N:人数, K:初期スコア, Q:問題数
A = [int(input()) for i in range(Q)]    # 正解者のリスト
B = [0 for i in range(N)]    # 各人の正解数

for i in range(Q):
    num_ans_person = A[i] - 1
    B[num_ans_person] += 1

# 得点は, 最初の点数 - 他人の正解数
# 他人の正解数は, 問題数 - 自分の正解数
# 得点は, 最初の点数 - 問題数 + 自分の正解数
# 得点 > 0 であれば, "Yes"
for i in range(N):
    if K - Q + B[i] > 0:
        print("Yes")
    else:
        print("No")
```
[Vue warn]: Failed to mount component　のエラー解決メモ

Laravel + Vue で開発していて

遷移をVue Routerでおこなっていたら
以下のようなエラーに詰まった
<img width="912" alt="スクリーンショット 2019-09-16 2.50.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223280/7dcb598f-e9f3-9e3a-8f49-bcc65468c48c.png">

```
app.js:41007 [Vue warn]: Failed to mount component: template or render function not defined.

found in

---> <Anonymous>
       <Root>
```

マウントに失敗したと言っている。app.jsをみてみる。


```vuejs:app.js

let routes = [
  { path: '/dashboard', component: require('./components/Dashboard.vue')},
  { path: '/profile', component: require('./components/Profile.vue')}
]
```

結論からいうとこのソースを下のソースに変える。

```vuejs:app.js
let routes = [
  { path: '/dashboard', component: require('./components/Dashboard.vue').default },
  { path: '/profile', component: require('./components/Profile.vue').default }
]
```

.defaultをつけるようにすると遷移がうまくいった。
faviconを使おう！

# faviconを作ってみた！
（홈페이지 파비콘 만들어봤다!）

作り方はいくつかあるんだが、今回私はfavicon.icoイメージを作ってくれるサイトから作った。
(만드는 방법은 여러가지가 있지만 이번에는 파비콘을 만들어주는 사이트에게 도움을 받았다.)


それがこちら。
⬇️(사진참고)
![スクリーンショット 2019-09-16 2.38.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219806/6fac5e8e-18bf-9673-c4d4-6426b833fe75.png)

今日は練習なので自分の写真を使用したが、なんか作って入れたいと思う！
(오늘은 연습이라서 내사진을 사용했다.)

# ※注意すること※
(주의할점)
・fileの拡張名は必ず(file名.ico)にする。
(파일확장명을 꼭 .ico를 사용할것)

本日はここまで。よくやった。毎日アップするよ〜
(오늘은 여기까지.잘했다.매일매일 업로드 할꺼야~)
CentOS 7 に Nginx  をインストールする手順

以下では [stable 版をインストール](https://qiita.com/ousaan/items/ae061e1765e6954d81d0)する。[公式ドキュメント](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/#prebuilt_redhat)には EPEL を使う方法と公式レポジトリを使う方法があるが、公式レポジトリを使う方が新しいバージョンになるので、公式レポジトリを使う。

`sudo -i` で管理者になっておくと便利。

### レポジトリの作成

`/etc/yum.repos.d/nginx.repo` というファイル名で以下の内容のファイルを作成する。

```
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
```

### インストール
```
# yum install nginx
```

###確認
```
$ nginx -v
```

### 自動起動の有効化
```
# systemctl enable nginx
```
踏み台環境でchromeが同時起動できない問題の解決方法

同一ユーザー複数セッションで接続できる環境だと、それぞれのセッションでchromeを同時起動できない問題が発生する。

chromeが使用するユーザープロファイルは、ユーザー毎に作成されるので、セッションは違ってもログインユーザーが同じだと、先に起動したセッションがユーザープロファイルに排他を掛けるのでそのセッション以外では起動できなくなってしまう。

そういう時は、以下のように起動時に引数を渡すことでユーザープロファイルを変えて起動することで問題を解決できる。

##### chromeを同一ユーザー複数セッションでそれぞれ開きたい時
起動時に引数を渡して、デフォルトユーザープロファイル以外の設定で起動させる
※引数は存在しないパスでOK（起動時に自動で新規作成してくれる）
`"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:\Program Files (x86)\Google\Chrome\Application\another_user1"`

上記のようなコマンドをショートカットに設定しておけば楽に起動できる。
実用的なCodiMD設定項目を調べてみた

# Markdownっていいよね
よく仕事のメモをMarkdownでまとめるんですが、今までそのメモをチームメンバに連携するときにはメールに貼り付けたりファイルを添付したりしてました。

一方的に一度っきりで送りつけるならそれでいいんですが、こんなときに困ってました。

* お互い更新する（デグレ…）
* ちょっとした誤字訂正（変更箇所を注記してまた全量送らないと…）

# CodiMDとの出会い
そんなときに出会ったのがCodiMDでした。
突然ですがCodiMDについては、ぐぐるとたくさん出てくるので紹介は割愛します。
※サボりではなく、既にインターネット上に情報が充実してるので。

簡単に言うと、
ローカルでMarkdown公開／編集サーバを立てることができ、
ブラウザでMarkdownを書くことができ、
URLをメール(やチャット)で送れば相手が常に最新のMarkdownを確認でき、
相手もSign Upすれば編集ができるようになります。

# CodiMDを使いたい
と思ったものの、設定項目を紹介しているサイトとか、サクッとコピペで使えそう、というものに出会えなかったので、本記事を書きました。
（先日CodiMD出会ったばっかりなので、間違っているところがあるかもしれません、そのときはご指摘いただければと思います）

**※注意事項**
*セキュリティなど、サクッと済ませられない事項については各自ご確認下さい。以下記載内容に関する一切の責任は負えません。*

### 設定概要

設定項目は以下の公式サイトに全て書いてあります。
https://hackmd.io/c/codimd-documentation/%2Fs%2Fcodimd-configuration

こんな感じの設定です。

* `hackmd` は何度でも作り直せる
* 画像はローカルに保存したい
* Gravatarを使いたい
* 公開範囲を意識しなくてもいいよう、新規作成したノートのデフォルトは、ログインしないと閲覧できない `limited` にする
* http://{ip}:{port}でアクセスする

設定していないこと

* Sign up制御
* SSL

```docker-compose.yml
version: '3'
volumes:
  hackmd-postgres-data:
    external: true

services:
  hackmdPostgres:
    image: postgres:9.6.5
    environment:
      - POSTGRES_USER=hackmd
      - POSTGRES_PASSWORD=hackmdpass
      - POSTGRES_DB=hackmd
    restart: always
    volumes:
      - hackmd-postgres-data:/var/lib/postgresql/data
    ports:
      - "127.0.0.1:5432:5432"
  hackmd:
    image: hackmdio/hackmd:1.3.1-alpine
    environment:
      - DEBUG=true
      - CMD_ALLOW_GRAVATAR=true
      - CMD_ALLOW_FREEURL=true
      - CMD_DOMAIN=192.168.2.1
      - CMD_DEFAULT_PERMISSION=limited
      - HMD_URL_ADDPORT=true
      - HMD_ALLOW_ANONYMOUS=false
      - HMD_EMAIL=true
      - HMD_ALLOW_EMAIL_REGISTER=true
      - HMD_ALLOW_FREEURL=true
      - HMD_IMAGE_UPLOAD_TYPE=filesystem
      - POSTGRES_USER=hackmd
      - POSTGRES_PASSWORD=hackmdpass
    restart: always
    volumes:
      - ./.docker-compose/hackmd/uploads:/hackmd/public/uploads
    links:
      - hackmdPostgres:hackmdPostgres
      - hackmdPostgres:hackmdpostgres
    ports:
      - "3000:3000"
```

# ちょっと困ってること

※アップロードしたファイルがどこにあるのか掴みきれていません。。
docker内の /codimd/public/uploads にあるのは分かっているのですが、
マウントには失敗しているようで、dockerの外の .docker-compose/hackmd/uploadsには入っておらず、
それにも関わらずdocker rmしてupし直した後も見えます。。
imgurに上がっちゃっているのか・・・？
MVCの仕組みについて

#はじめに
おそらく技術的な質問の際よく聞かれるであろうMVCの仕組みについて、アウトプットも兼ねて自分なりにまとめて見たいと思います。

##MVC(Model View Controller)とは
MVCとはModel(モデル)、View(ビュー)、Controller(コントローラー)の略で一連の流れとしてはブラウザに表示されるまでに、ルーティング→コントローラー(C)→モデル(M)（必要に応じて）→ビュー(V)という処理が行われています。
##M(Model)とは
Model(モデル)とはWebアプリケーションを取り扱うデータを表現する要素であり、Controllerからの命令に従ってデータベースから必要な情報を返したり、情報を書き込んだり出来るデータを司る存在です。
##V(View)とは
View(ビュー)とはクライアント側に表示される見た目の部分であり、コントローラーから受け取ったデータをどう表示させるかインターフェースを司る存在です。
##C(Controller)とは
Controller(コントローラー)とはユーザーからのリクエストを受け取り、それをModelやViewに支持を出すいわば司令塔です。直接、Viewへの描画を行ったり、Modelの内部を直接操作したりはせず、あくまでレスポンスに必要なデータの用意を行います。

#最後に
頭ではわかっていても、いざ記事にしてみようとすると難しいですね。あくまでアウトプット用なので以下の記事も参考にして下さい。
https://qiita.com/tentom/items/de95f63bc9e2da2bd0bf
https://qiita.com/s_emoto/items/975cc38a3e0de462966a
[Unity]イベントとかでよく見るWipeをShaderで書いてみる

初めまして、demです。
最近UnityでShaderを勉強しているのですが、学びの中でできたものを不定期に載せていこうと思います。
タイトルにもあるようにイベントでよく見るWipeを作っていこうかと思います。
今回はShaderとそれを描画するスクリプトを書いていきます。
早速コードの方を・・・まずはShaderの方から。

```EventWipe.shader
Shader"SmyCustom/EventWipe"{
	Properties{
		_MainTex("None",2D)="white"{}
		_Length("Length",Range(0,0.5))=0.5
	}
	SubShader{
		Pass{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata {
				float4 vertex:POSITION;
				float2 uv:TEXCOORD0;
			};

			struct v2f {
				float4 vertex:SV_POSITION;
				float2 uv:TEXCOORD0;
			};

			sampler2D _MainTex;
			float _Length;

			v2f vert(appdata v) {
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}

			fixed4 frag(v2f i) :COLOR{
				//ここでカメラに写っている色情報を取得する
				fixed4 c = tex2D(_MainTex,i.uv);
				//uv座標のｙから0.5を引いた値の絶対値（ここでは画面の真ん中を(0.5,0.5)としている）
				fixed l = abs(i.uv.y - 0.5);
				//lの値が＿Length以下ならそのまま描画する。違うのなら黒く描画
				fixed4 color = (l < _Length) ? c : fixed4(0, 0, 0, 1);
				
				return color;
			}
			ENDCG
		}
	}
}
```

次に実際に描画するためのスクリプトを書きます。

```C#:EffectDisplay.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EffectDisplay: MonoBehaviour
{
    [SerializeField]
    private Material mat = null;

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source, destination, mat);
    }
}

```

そのあとはこのスクリプトをカメラにアタッチしてマテリアルの部分に先ほど書いたShaderを適応したマテリアルを入れてあげればOKです！数値はマテリアルにあるスライダーを動かすとワイプが上下から出てきます！

<img width="393" alt="Wipe1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482043/42089305-5fd2-ad9c-88f9-5fb458c034f6.png">

スライダーの数値を0に近づけると黒い部分が多くなるのでフェードとかでも使えそうですね。
<img width="394" alt="Wipe2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482043/9943777f-fcb1-208f-c1b9-227614536c87.png">

Shaderというよりポストエフェクト的な何か・・・？
以上になります。まだまだ初心者なのでコードに関しては変なことをしているかもしれませんが温かい目で見守っていただけると幸いです。
MSIのGS65にUbuntuを入れて使ってみた

## 機械学習用のノートパソコンが欲しい！
MSIのGS65 Stealth（RTX2070-MaxQ搭載）を機械学習用に使います．

自分にとっての作業ボトルネックが通信コストでした．
もちろんまとまった学習タスクはサーバーに投げますが，PoCぐらいまではローカルでコーディングから実行までまとめてできると作業効率が数倍良いです．

## この文書には何が書いてあるか
そこでUbuntu 18.04 LTSをセットアップしましたが，その上で生じた問題とその解決策を（その解決策を使った日付とあわせて）記録しておきます．

### (20190916) Ctrl-;に「クリップボードから貼り付ける項目を選択」のメニューが割り当てられている
FcitxのClipboardというアドオンのせいだそうです．「Fcitx設定」からキーバインドを変えました：
https://askubuntu.com/questions/894673/why-my-ctrlsemicolon-was-binded-globally

### (20190916) SuspendするとWiFiデバイスが認識されなくなる
正直原因はよく理解していないですが，「Suspend後に機内モードのショートカットを2回押す」ことでWifiが復活するようです．
機内モードのショートカットは，以下の方法で有効にする必要があります：
https://askubuntu.com/questions/1043547/wifi-hard-blocked-after-suspend-in-ubuntu-on-gs65/1057793#1057793
ここにもその方法を書いておくと，
1. `$ sudo vim /etc/default/grub` して `GRUB_CMDLINE_LINUX_DEFAULT="acpi_osi=! acpi_osi='Windows 2009' quiet splash"` を書く
2. `$ sudo update-grub`
3. `$ reboot`
ここまでやると，「Fn+F10」で機内モードを操作できるようになります．サスペンド後にこの組み合わせを2回押せばWifiが有効になります．
もちろんこれは理想形ではないのですが，自分の環境では唯一Wifiが再度有効になる方法でした．
もし有効な方法が出てきたらこちらに追記します．

原因について：
サスペンド前後では，`$ lspci -knn | grep Net -A3; rfkill list`の出力の「Wireless LAN」の`Hard blocked`が`no`から`yes`に変化します．直接の原因かどうかは分かりませんが関係はありそうです．
vue nuxt vuex メモ

今後同じところで引っかからないように自分用のメモ
ドキュメントに全部しっかり載っていると思われます。

####絶対関数にするのを忘れない、returnで返す！
振り返ってみるとなんでこんなんミスるんって感じ

```index.vue
<template>
  <div>
    <h1>counter</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>

export default {
//ここから下の部分
  data(){
    return {
      message: 'カウントできます'
    }
  }
}
</script>
```

####vuex モジュールモードでstate.js,getters.js,actions.js,mutattions.jsに分けて書いた時の謎のミス
※nuxtjsの時です、storeフォルダの中にあると思ってください
クラシックモードならこれでいいんですけどね、、、
意外にも全然気付きませんでした、ちなみに四つ全部エラー出ます。
ミスっている方
エラーコード　[vuex] getters should be function but "getters.getters" is {}.

```getters.js
export const getters = {
  counter(state){
    return state.counter
}

```

正しい方

```getters.js
export default {
  couter(state){
    return state.counter
  }
}
```
なんかgetters二回呼んでね？ってなってよくみたらおかしかったです。
クラシックモードからモジュールモードに書き換える時にやりそう。

ちなみにstateだけ書き方違うので注意

```state.js
export default () => ({
  counter: 0
})
```

まだまだたくさん理解しなかんところたくさんあるので頑張っていきましょう
HackerRank 30Days of Code Python3で解いてみた　その2

##はじめに
未来電子テクノロジー（https://www.miraidenshi-tech.jp/intern-content/program/）
でインターンをしているrayaと申します。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

##Day6 Let's Review
与えられた文字列の偶数番目の文字と奇数番目の文字を分けて表示させる問題。

```py

def evenoddstr(s):
    even = ''
    odd = ''
    for i in range(len(s)):
        if i%2==0:
            even += s[i]
        else:
            odd += s[i]
    result = even + ' ' + odd 
    print(result)

if __name__ == '__main__':
    for _ in range(int(input())):
        evenoddstr(input())
```
・s[i]：文字列sのi番目の文字を表す。リストのインデックスのように表示できる

・even += s[i] ：あらかじめ定義した空の文字列に要素を追加できる。evenがリストだったとしてもこのように記述できる（append()メソッドを使用しない記述方法）

・even + ' ' + odd：文字列の連結。＋を用いて連結可能。

##Day7 Arrays
与えられたリストの要素を逆順にした文字列を出力する問題

```py

if __name__ == '__main__':
    n = int(input())
    arr = list(map(int, input().rstrip().split()))

    for i in reversed(arr):
        print(i, end=" ")
```
・map関数：map関数はイテレーターを返すだけなので、list関数で囲うことで、リストとして扱うことができる。print関数の中身をイテレーターにした場合とリストにした場合の違いを確認すると良い。

・rstripメソッド：引数に指定した値を削除したオブジェクトを返す。今回は何も指定していないので空白を削除する。

・print(i, end=" ")：endはprint関数のオプション。末尾に文字列の空白を追加できる。配列を文字列にしたい時に便利。他にもsepオプションがあり、sep='\n'とすれば改行できる。

##Day8 Dictionaries and Maps
名前と番号の辞書を作り、その中に与えられた名前があるかを確認する問題。
RuntimeErrorに引っかかりすぎて萎えました。

```py

num = int(input())
phonebook = dict(input().split() for _ in range(num))

while True:
    try:
        key = input()
        print(key + "=" + phonebook[key] if key in phonebook else "Not found")
    except EOFError:
        pass
        break
```
・dict関数：keyとvalueを設定できるような形で引数を与えれば辞書にしてくれる関数。今回は、splitで2つに分けているのでdict関数が適用されている。

・try関数：例外処理を行う場合に使う。今回はEOFErrorは無視しています。

```
try:
実行する処理（エラーする可能性あり）
except:例外処理したいエラー名
そのエラーが発生した時に実行する処理
```
・なぜRuntime Errorに苦しんだか：同じ名前があるか確認する回数をfor _ in range(n)にせずにwhile Trueとしているのがポイントです。Discussionを参考にしたところ、この問題は「作った辞書の数（for _ in range(n)）」と「同じ名前が辞書の中にあるか確認する回数」が異なるという点に気づかなければなりません。辞書のkey,valueのセット数よりも同じ名前があるか確認する回数が少ない場合があります。そこに気づかずに、確認する回数をfor _ in range(n)とすると処理回数が増えてしまいRuntimeErrorが発生します。

・if key in phonebook：inを使うことで、keyがphonebookの中にあるかで条件分岐できる。
【VSCode】SynthWave '84：ネオンサイン風テーマでVScodeを彩る

# VScodeテーマ「Synthwave '84」
VScodeは多種多様なテーマで見た目をカスタマイズできるようになっていますが、その中でも最近、VScodeのテーマ「Synthwave '84」が気に入ったので、紹介します。

[SynthWave '84 - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=RobbOwen.synthwave-vscode)

作者によると、80年代カルチャーに影響されて作ったテーマだそうです。

実際にインストールして設定を行うと、下のような画面になります。

![620ceef309bacd7c44374de031e522b7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173746/902144ca-c7af-2375-b82e-391327ff0f9b.png)


ネオンサイン風のシンタックスハイライトが特徴的ですね。画像ではJavaScriptファイルにシンタックスハイライトが効いていますが、他言語にも適用されます。人とはちょっと違うテーマを使いたい人にオススメです。

## インストール・設定手順
普通のテーマは拡張機能からインストールして終わりですが、このテーマは設定に数ステップ必要です。
（インストール手順は公式ページに書いてあります）

### ベーステーマをインストールする
まずはベースとなるテーマ「Synthwave '84」をインストールします。
拡張機能から検索してインストールするか、`ctrl-p`で出てきた入力欄で下のコマンドを実行します。

```
ext install RobbOwen.synthwave-vscode
```

### ネオンサイン風の表示にするための設定
ネオンサイン風の表示にするためにはベーステーマのインストールに加えて、次の拡張機能の追加・設定が必要です。

[Custom CSS and JS Loader](https://marketplace.visualstudio.com/items?itemName=be5invis.vscode-custom-css)

この拡張機能を使うことでカスタムCSS・JSをVScodeに適用することができるようになります。

#### 1. 「Custom CSS and JS Loader」のインストール
拡張機能一覧から探すか、`ctrl-p`で入力欄に次のコマンドを打ってインストールします。

```
ext install be5invis.vscode-custom-css
```

#### 2. カスタムCSSファイルのダウンロード
ネオンサイン風の表示にするために[synthwave84.css](https://github.com/robb0wen/synthwave-vscode/blob/master/synthwave84.css)をローカルの好きな場所に保存します。ファイル名は自由です（次の手順で使うパスではそのファイル名を指定するように注意）

#### 3. settings.jsonの設定
VScodeの基本設定ファイル`settings.json`に次のスニペットを追加します。`vscode_custom_css.imports`は保存したCSSファイルのファイル名とパスに合うように変えてください。

```javascript:settings.json
    "vscode_custom_css.imports": [
        // MacのホームディレクトリにCSSファイルを保存した場合※
        "file:///Users/<ユーザーネーム>/synthwave84.css"
        //  Windowsの例としては、file:///C:/Users/<ユーザーネーム>/synthwave84.cssとか
        ],
    "vscode_custom_css.policy": true,
```

※ 注意：形式は`File URL`である必要があるため、**先頭の`file://`の部分は必須**です。

#### 4. VSCodeの所有者を変更する
カスタムCSSファイルを適用できるようにVScodeの所有者を変更します

##### Windows
管理者権限でVScodeを再起動してください

##### Mac/Linux
ターミナルからVScodeの所有者を次のコマンドで変更します。

```shell
# VScodeの所有者を変更する
# <Path to VSCode>の部分はOSによって変わる
# Mac: /Applications/Visual Studio Code.app/Contents/MacOS/Electron
# Mac(Insidersバージョン): /Applications/Visual Studio Code - Insiders.app/Contents/MacOS/Electron
# 大抵のLinuxディストリビューション: /usr/share/code
# Arch Linux: /opt/visual-studio-code/

$ sudo chown -R $(whoami) <Path to VScode>
```

Mac/Linuxでは所有者の変更によって「VScodeはサポート対象外です」のようなシステムメッセージが出るかもしれませんが、基本は無視で大丈夫だと思います。気になる場合は所有者を元に戻すかVScodeを再インストールすれば消えます（この場合カスタムCSSは適用されなくなります）。

#### 5. 設定を反映させる
所有者が変更できたら、`Shift-Ctrl-p`を押して`Reload Custom CSS and JS`を選択して、実行します。

最後にVScodeを再起動してください。

これで写真のようにネオンサイン風の表示が反映されるようになると思います。

## もしも気に入らなかったら...
以下の操作を行えば設定を元に戻すことができます。

- ベーステーマ「Synthwave '84」を無効にするかアンインストールする
- `settings.json`から追加した部分を削除するかコメントアウトする
ラズパイZeroでLチカ with Greengrassコネクタ

Greengrass Coreがv1.9.3でArmv6lをサポートしました。ラズパイZeroでもGreengrassが動作するようになりました。

https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/what-is-gg.html


久しぶりにGreengrassに触るので、Greengrassコネクタを使ってLチカをしてみました。
Greengrassコネクタに`Raspberry Pi GPIOコネクタ`が用意されているので簡単です。

# ラズパイZeroの準備

以下の公式ドキュメントに従って行います。

Raspberry Pi のセットアップ
https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/setup-filter.rpi.html

モジュール 2: AWS IoT Greengrass Core ソフトウェアのインストール
https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/module2.html


# Greengrassの設定

## リソースの追加

Raspberry Pi GPIOコネクタがGPIOにアクセスするため、リソースを設定します。

対象のGreengrassグループを選択し、`リソース`タブを表示し、`ローカルリソースの追加`ボタンを押します。

| 設定項目 | 設定値 |
|---|---|
|リソース名|任意の名前|
|リソースタイプ|デバイス|
|デバイスパス|/dev/gpiomem|
|グループ所有者のファイルアクセス許可|リソースを所有するLinuxグループのOSグループアクセス許可を自動的に追加|
|Lambda関数の関連|無指定でOK|

## コネクタの追加

Raspberry Pi GPIOコネクタを追加します。

対象のGreengrassグループを選択し、`コネクタ`タブを表示し、`コネクタの追加`ボタンを押します。

Raspberry Pi GPIOを選択したあと、パラメータはこんな感じで指定しました。

| 設定項目 | 設定値 |
|---|---|
|Resource for /dev/gpiomem device|作成したリソース|
|Input GPIO pins|2 ※ボタンのGPIOピン番号|
|Input GPIO polling period|50(millisecond)|
|Output GPIO pins|17 ※LEDのGPIOピン番号|

## Lambdaの作成

`ボタンが押された/離された`イベントで起動し、`LEDのオン/オフを設定する`処理を行います。試行錯誤したのであまりきれいではありませんが。。

```python
import os
import greengrasssdk
import json
import sys
import logging

# Setup logging to stdout
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

iot_client = greengrasssdk.client('iot-data')

thingName = os.environ['AWS_IOT_THING_NAME']

def get_read_topic(gpio_num):
    return '/'.join(['gpio', thingName, str(gpio_num), 'read'])

def get_write_topic(gpio_num):
    return '/'.join(['gpio', thingName, str(gpio_num), 'write'])

def send_message_to_connector(topic, message=''):
    iot_client.publish(topic=topic, payload=str(message))

def set_gpio_state(gpio, state):
    send_message_to_connector(get_write_topic(gpio), str(state))

def read_gpio_state(gpio):
    send_message_to_connector(get_read_topic(gpio))

def function_handler(event, context):
    logger.info("Received message!")
    logger.info(event)
    logger.info(type(event))
    
    # event 
    # 1 : button off
    # 0 : button on
    
    state = 0
    if(event == 0):
        state = 1
    set_gpio_state(17, state)
        
    return
```

Lambdaには`AWS IoT Greengrass Core SDK for Python`を含める必要があります。このあたりを参考にしました。

Lambda 関数の作成とパッケージ化
https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/create-lambda.html

## Lambdaの追加

作成したLambdaをGreengrassに追加します。

対象のGreengrassグループを選択し、`Lambda`タブを表示し、`Lambdaの追加`ボタンを押します。

| 設定項目 | 設定値 |
|---|---|
|Lambdaの追加|既存の Lambda 関数の使用|
|Lambda の選択|作成したLambda|
|Lambda バージョンの選択|作成したLambdaのバージョン|

## サブスクリプションの追加

対象のGreengrassグループを選択し、`サブスクリプション`タブを表示し、`サブスクリプションの追加`ボタンを押します。

ボタンイベント -> Greengrassコネクタ -> Lambda呼び出し

| ソース | ターゲット | トピック |
|---|---|---|
|Raspberry Pi GPIO|Lambda|gpio/+/ボタンのGPIOピン番号/state|

Lambda -> Greengrassコネクタ -> LEDオンオフ

| ソース | ターゲット | トピック |
|---|---|---|
|Lambda|Raspberry Pi GPIO|gpio/+/LEDのGPIOピン番号/write|

サブスクリプションをいじれば、クラウド経由でLチカも簡単です。

## デプロイ

これで設定は完了です。デプロイしましょう。
ReactにGoogle Fontsを追加する方法 (style jsx)

こんな感じ

```jsx
<style jsx>{`
    @import url('https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz&display=swap');

      div {
        background-color: #FAFDF6;
        color: #454545;
        display: flex;
        font-family: 'Yanone Kaffeesatz', sans-serif;
      }
...
```

一番最初に読み込むファイルの`styled jsx`の中で、Web Fontを`@import`して、`font-family`で呼び出す
Laravelコードメモ

#随時更新

```:〇〇.blade.php
//ログイン中のユーザー情報取得
{{ Auth::user()->name }}

//ログアウト
<a class="dropdown-item" href="{{ route('logout') }}"
　onclick="event.preventDefault();
　document.getElementById('logout-form').submit();">{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">@csrf</form>
```