OmniAICreator/Qiita-1.07M huggingface dataset:
【HTML Form】ポップアップウィンドウへ結果を表示させる場合の button タグ 注意点

##発生した事象
　検索結果をポップアップウィンドウに表示する際、Javascriptでポップアップウィンドウを作り、target をそのウィンドウに合わせるという常套手段を書いていたのですが、結果が呼び出し元のウィンドウにも同時に表示されるという状態になってしまった。具体的にはこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97384/53056d88-0ae4-7790-8d48-cffd2fdd783c.png)
（大きなウィンドウが呼び出し元）

　後ほど紹介する検証コードで、解決はみているのですが、なんでこんなシンプルな話が上手く行かないのかハマってしまいました。

###検証環境
xampp (Windows) 7.2.34
Egde 87 , Chrome 87 , Firefox 84

##結論
* button タグを使う場合 **formtarget 属性が必要**
* input タグは特に属性を必要とせず想定通りの挙動となる

##検証コード
```php:abc.php
<?php
  // フォームからPOSTで受け取った場合は、OK! というテキストだけを表示する。
  if(isset($_POST['popup'])){
    echo 'OK!';
    exit;
  }
?>

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>input VS button</title>
  <script>
    function result_pop() {
      var frmPost = document.getElementById('frmpost');
      var printform = window.open('about:blank','pop','width=300,height=200');
      frmpost.target = 'pop';
      frmpost.submit();
      printform.focus();
      frmpost.target = "";
    }
  </script>
</head>
<body>
  <!-- 以下 formタグ action のURL に #result とあるのは、製品のコードにそう書いてあったため。
       書いてなくても挙動に変化はありませんでしたが、一応記述。 -->
  <form id="frmpost" name="frmpost" action="./abc.php#result" method="post">
    <input type="hidden" id="popup" name="popup" value="dummy">
    <input  onClick="result_pop();" type="button" value=" [A] input tag. "> inputタグの利用<br>
    <button onClick="result_pop();"> [B] button tag only. </button> buttonタグの利用 属性なし<br>
    <button onClick="result_pop();" formtarget="pop"> [C] button tag and formtarget attr. </button> buttonタグ と formtarget 属性の利用.
  </form>
</body>
</html>
```

　結論にも書いたとおり、input タグ（[A]のボタン）は、もともと想定したように、ポップアップウィンドウに結果が表示されます。

　ハマったのは［B］のタイプでボタンを作っていたからでした。この時、冒頭のキャプチャ画面にあるように、同じ結果が呼び出し元画面、ポップアップ画面の2画面とも表示されてしまう。
　buttonタグで実装する場合は［C］ボタンのように、formtarget 属性を付加し、ポップアップするウィンドウに付けたターゲット名を指定することで解決です。
　上記のコードでは、"pop"がそれにあたります。

以上

###言い訳と反省
　HTML5以前の古いコードをメンテしていながら、buttonタグを使って簡易検証してたのが良くなかった。検証はHTML5以前を意識しないとダメなのが反省と糧ですね。
Ubuntu + qemu 上の FreeBSD のデスクトップ環境の設定

#はじめに
Linux + qemu 上の FreeBSD で、Xfce4 というデスクトップ環境を使用するためのインストールと設定の手順を説明します。
*　[Linux + qemu 上で FreeBSD を動かす](https://qiita.com/masatonasou/private/e60d4af99550617fab30) も参照してください。

以下の各説明では実際に実行するコマンドを以下のような形で記述しています。

```
# pkg install パッケージ名
```
実際には上記のコマンドを実行するとパッケージインストールの進捗状況が表示されますが、本ページではそれらの表示を省いています。
* 上記の行頭にある "# " は、root のプロンプトを表しています。
* 一般ユーザ権限で実行する場合には、"$ " と表記します。

#実行環境など
Ubuntu 20.04.1 LTS を使用します。
* 仮想マシンを起動する際に新しい Window が表示されるので、Desktop 環境で実行して下さい。
qemu 上で実行する FreeBSD は、12.2 RELEASE です。

#パッケージのインストール
FreeBSD 上で root でログインし、以下のパッケージをインストールします。

```
# pkg install xorg
# pkg install xfce
# pkg install japanese/font-std
# pkg install ja-fcitx-mozc
# pkg install firefox
```
上から順番に
* X Window System
* Xfce4 デスクトップ環境
* 日本語フォント
* 日本語入力システム
* web browser
です。

上の例ではパッケージを一つずつ指定していますが、以下のようにまとめて指定しても構いません。

```
# pkg install xorg xfce japanese/font-std ja-fcitx-mozc firefox
```

#システムの設定
Xfce4 で D-Bus を使用するので、以下の手順で D-Bus を起動します。

```
# sysrc dbus_enable="YES"
# service dbus start
```

#個人環境の設定
root 権限で実行している shell を抜けてから、一般ユーザ権限でログインし直します。

```
# exit
logout

FreeBSD/amd64 (fbsd122) (ttyv0)

login: yamada
Password:

$ 
```

vi/emacs などのテキストエディタを使用して、ホームディレクトリに .xinitrc ファイルを作成し以下の設定を記述してください。
* FreeBSD では Emacs は標準ではインストールされていないので、root 権限で pkg install emacs を実行して Emacs をインストールしてください。

```
export LC_ALL=ja_JP.UTF-8
export LANGUAGE=ja_JP.UTF-8
export LANG=ja_JP.UTF-8
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=xim
export XMODIFIERS=@im=fcitx
/usr/local/bin/mozc start
/usr/local/bin/fcitx -r -d
exec /usr/local/bin/xfce4-session
```
日本語キーボードを使用している場合には、以下の行を最終行 xfce4-session の直前に入れてください。

```
/usr/local/bin/setxkbmap -layout jp
```

#デスクトップ環境の起動
startx コマンドを実行し、デスクトップ環境を起動します。

```
$ startx
```
以下のように Xfce4 のデスクトップ環境が表示されれば成功です。
![qemu-xfce4-start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/915655/8272a792-619c-0c22-d150-3154ca6f40ba.png)

左上の「アプリケーション」クリックするとメニューが表示されます。メニューの「ウェブブラウザー」をクリックすると、Firefox が起動します。
![qemu-xfce4-japanese.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/915655/c26370d9-acdd-3fd6-54c2-c42e3e77f1bf.png)
日本語の入力には、Ctrl キーと SPACE キーを同時に押します。文字を入力して、SPACE キーで変換します。もう一度 Ctrl キーと SPACE キーを同時に押すと、英語の入力に戻ります。

右上の「ユーザー名」をクリックするとメニューが表示されるので、「ログアウト」をクリックするとデスクトップ環境が終了します。
![qemu-xfce4-logout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/915655/5bf868bf-5269-a8e4-8b4b-611f0e9db4ff.png)
![qemu-xfce4-logout2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/915655/1a3cc025-6a9c-91fa-088f-59642c2b6f5e.png)

#問題が発生した場合
「デスクトップ環境が表示されない」、「日本語が入力できない」といった問題が発生した場合には、ホームディレクトリ以下に作成した .xinitrc ファイルの中身を確認してください。
* 大文字・小文字を間違えていないか？
* アンダースコア (_)・ハイフン (-) などの記号を間違えていないか？
など、上記の例と食い違いがないか確認してください。
【壮大な検証】Webエンジニアになりたい人に捧げる学習ロードマップどおりにやるとどうなるか【途中】

注意：完全に自己責任でやっていますので、本記事に記載された会社さん、個人の方は一切関係ありません！

おはようございます。
こんにちは。
こんばんは。

えだまめです！(*^^*)
身長と血液型だけなら松潤と一緒です。

半導体メーカーでキャリアを積み、28歳からWebエンジニアになることを決意。
UIUXデザイナーになるために勉強中です。

#こちらの記事について
この記事は半永久的に続く仕様となっています。
その理由は結果でなく過程を記述するためのものだからです。

では、なにについての過程を記述するかというと、
【UIUXデザイナーになるまでのストーリー】です！

#UIUXデザイナーとは
・・・カタカナはかっこいいのですが、言葉は辞書通りに使いたいので調べます。
「メロンパン」と聞いてあなたと私の思うメロンパンは一致しないことが・・・・いやメロンパンは一緒だろ（たとえ下手かっ）
「ユーモア」とかそうですよね。

・・・さて、こちらから引用します！
↓↓↓
[・【徹底解説】UI/UXデザイナーってどんな仕事？転職するには？年収は？ | プロテンマガジン - 転職のためのキャリアアップ情報](https://proten.jp/magazine/knowledge/28)

>UIとはユーザーインターフェイス（User Interface）の略称で、少しわかりづらいですがそのままの意味は、人とモノの接点となります。
そこから人が機械を操作するため接するモノ、という意味で用いられています。つまりUIデザイナーとはそうしたモノを創る人のことを指します。
一方、UXとはユーザーエクスペリエンス（User Experience）の略称で、製品やサービスを利用して得られる経験のことを指します。
ユーザーにとって使いやすい、分かりやすい、ということだけではなく、楽しく快適に使うことを目的に製品やサービスをデザインすることをUXデザインと呼びます。
つまりそうしたモノを創る人のことをUXデザイナーと呼ぶわけです。


#UIUXデザイナーの価値はなんぞや
例えば、
女性向けのファッションのサイトを作りたいという話があったときに、
それを作る僕は男性で、使うのは女性。
この矛盾を抱えながらも、サイトをアクセスした女性にどんなアクションをしてほしいという依頼主の意図を汲み取って、ものづくりをすることに価値を感じています。（三方良し！）
そんな人になりたいという想いがあります。
なので、「どうなりたいの？」の答えはおそらく「UIUXデザイナーさん」だと思っています。

そんなことに気づかせてくださった先駆者がこちら
刺激を本当にありがとうございます！
↓↓↓
[・東大・山中俊治さんの考える「デザインエンジニア」とは](https://www.ashita-lab.jp/special/5441/)
[・TakramCast「Design Engineeringとは #1」｜田川欣哉 (Takram)｜note](https://note.com/kinya_tagawa/n/n463d52b5c560)
[・プロダクト開発に不可欠なエンジニアリングとデザインの関係性。技育祭イベントレポート｜Blog｜Goodpatch グッドパッチ](https://goodpatch.com/blog/geeksai-2020/)

#いまやっていること
やっと本題。
「いま目標達成のためになにをやっているんですかー」はこちらに書いていきます。
「どうやら学習ロードマップがあるらしく、それどおりにやったらなれるんじゃないか」という仮説を検証していきます。
完全に自己責任でやっていますので、本記事に記載された方は一切関係ありません。（これ冒頭にも載せておこう！)

【キャリアのロードマップ】（予定なので方向転換や路線変更する前提です）
大目標：UIUXデザイナーになる
　上流工程から関わり良いUIを作る
中目標：フロントエンドエンジニアになる
小目標：JavaScriptの実装を経験する
今後の目標：マーケティング、デザインを考えることができる人材になる

学習のロードマップはこちら！（心から感謝です）
↓↓↓
[・Webエンジニアになりたい人に捧げる学習ロードマップ｜Gizumo-inc｜note](https://note.com/gizumo_inc/n/nd435c11a4ef4)
>1. HTML/CSSによるWebサイトコーディング経験（レスポンシブ対応含む）
2. JavaScriptの基礎構文理解
3. JavaScriptを使った動くUI(複数パターン)の実装経験
4. jQueryのプラグインやAjaxを使った実装経験
5. タスクランナー(gulp)やモジュールバンドラー(Webpack)の利用経験
6. Vue.jsもしくはReact.jsを使ったミニアプリの開発経験
7. 上記のスキルが証明できるポートフォリオサイトもしくはGitHubアカウントの提出


現在はこちらのフェーズです。
>JavaScriptを使った動くUI(複数パターン)の実装経験

[こちら](http://itm-test.weblike.jp/itami-web/soybeans/MyPortfolio/index.php)にできたものを公開します♪

#これまでのキャリア
どの立場の人がこの記事を書いているのかお伝えできればと思いメモ程度に記載します。

いつでも【関わったものが人の役に立つことが仕事の喜び】を軸にしています。
///きゃーかっこいい！

これまで、以下のように歩んで来ました。
・半導体製造メーカー(新卒から3年間)
半導体は某メーカーに従兄弟が勤めていて、従兄弟のようになりたいと
理系→情報系大学→情報系大学院→半導体メーカーと進んできました。

・SIer系エンジニア(退職後２年間)
ハードウェアからソフトウェアへ業界を変える時に、同じ年のフリーランスの友人に相談しました。（話聞いてくれてありがとうー！）
フリーランスは「一番厳しい選択」だけど「一番成長できる」と感じたので、その道を選びました。

【Webデザイン・エンジニア】
2020/1月〜現在
■各種ディレクション
・バナー
・LP
・WEBサイト
［Pjt規模］複数名
［役割］ディレクション、デザイン、ライディング
［開発環境］Photoshop／illustrator／WordPress
JAVAScript／HTML／CSS／PHP
Slack／Figma／Googleドキュメント／Googleスプレッドシート

#日々の情報発信について
[こちら](https://twitter.com/edamamethebest)でつぶやいております！
*最近嵐と将棋のつぶやきが増えた
Flutter 画像, ページ遷移

```dart:main.dart
import 'package:flutter/material.dart';
import 'package:flutter_app/next_page.dart';
import 'package:flutter/rendering.dart';

void main() {
  debugPaintSizeEnabled = true;
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(

        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  String text = "次へ";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('gonzaサンプルアプリ'),
        actions: <Widget> [Icon((Icons.add)),Icon((Icons.share))],
      ),
      body: Container(
        width: double.infinity,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Image.network(
                'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'
            ),
            RaisedButton(
              child: Text(text),
              onPressed: () async {
                final result = await Navigator.push(context,
                  MaterialPageRoute(
                      builder: (context) => NextPage("gonza")
                  ),
                );
                text = result;
                print(result);
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
```

```dart:next_page.dart
import 'package:flutter/material.dart';

class NextPage extends StatelessWidget {
  NextPage(this.name);
  final String name;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('次の画面'),
      ),
      body: Container(
        height: double.infinity,
        color: Colors.red,
        child: Column(
          children: <Widget>[
            Text(name),
            Center(
            child: RaisedButton(
              child: Text('戻る'),
              onPressed: () {
                Navigator.pop(context, "gonzaさん");
              },
            ),
          ),
          ],
        ),
      ),
    );
  }
}
```
Linux　日本語配列のキーボードに対応させる方法

# linuxで日本語キーボードに合わせるためのメモ

mainMenue -> Setting -> Keyboard -> Layout -> Keyboard layoutで
「japanese(OADG 109A)」を選択

![スクリーンショット 2020-12-18 11.33.23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169789/04f8af50-1798-6333-ae5d-57fa18ab5b82.jpeg)
pythonのchromedriverのver.相違の問題の解決

PythonからSeleniumを使おうとしたら、ChromeDriverのVersion(以下ver)が合わないとエラーがでて、泣く泣くchromedriverを手動インストール、なんてあるかと思います。

ここ数日から`chromedriver-binary-auto`が[pypi@chromedriver-binary](https://pypi.org/project/chromedriver-binary/)から提供がされ始めました。

便利な事に下記2つとchromedriverをインストールするだけで、導出済みchromedriverに合わせたversionをPython上で使用してくれるものです。多少のver違い気にされない方が多いと思うので導入必須でしょうね、便利です。
- Python側で下記Wrapperを導入
    - chromedriver-binary
    - chromedriver-binary-auto
- OS側ではChromeDriverをインストする事
    - MacOS: homebrewで。
    - Windows: Chocoletelyが良い

以上。
Javascript(JavascriptでHTMLフォームに入力された文字を取得し表示)

# 目的
テキストフォームに入力されたデータを取得する。

そして、[フォームに入力された値] を検索中です。　と画面に表示させる。

# コード

## HTML

```html:form.html
<form action ="#" id ="form">
  <input type ="text" name ="word">
  <input type ="submit" value ="送信">
</form>

<p id="output"></p>
```

## Javascript

```javascript:app.js
  use 'strict';

  document.getElementById('form').onsubmit = function(event){
  event.preventDefault();
  const input = document.getElementById('form').word.value;
  document.getElementById('output').textContent = `${input}の検索中です。`;
  };
```

# 解説
## 1行目
```javascript:app.js
  
  document.getElementById('form').onsubmit = function(event){
  };
```
formというidを持ったフォームが送信された時に処理を実行させるという意味。

## 2行目
```javascript:app.js
  
  event.preventDefault();
```
formタグの次のページにいくという基本動作を無効にするためイベントオブジェクトのpreventDefaultメソッドを使用。

## 3行目
```javascript:app.js
  
  const input = document.getElementById('form').word.value;
```
name属性がwordのインプットフォームに入力された値を取得して、定数 input に格納。

## 4行目
```javascript:app.js
  
  document.getElementById('output').textContent = `${input}の検索中です。`;
```

idがoutputの要素に フォームに入力された値である定数inputと共に表示。

#引用

> 確かな力がつくJavaScript超入門 狩野　祐東
空白を除いて表示させる方法を考えてみた

#はじめに
オリジナルアプリを作成中に任意のカラムであるが値のあるレコードだけ表示をさせたいと思い、試行錯誤した内容をアップします。
ググっても記事がなかったので、間違っていたり、もっといい方法があれば教えてください！

#環境
rails, '~> 6.0.0'
ruby '2.6.5'

#概要
任意のカラムであるwanted_listに対し、値があるものだけを表示させる

#eachメソッド内の条件分岐を試してみた
```
<div class='item-lists'>
  <% @tweets.each do |tweet|%>
    <% unless tweet.wanted_list.blank? %>
       <%= tweet.wanted_list %>
    <%end%>
  <%end%>
</div>
```
@tweetsには投稿した全てのレコードが入っているため、eachメソッドで配列として呼び出し、wanted_listが空""でなければリストを出力するとした。

しかし、空のレコードも全て呼び出されてしまいました。。
そこで初めて、if文は最初のレコードのみに影響することが判明し、使用を断念しました。

#selectメソッドで条件分岐を試してみた
```
<div class='item-lists'>
  <% @tweets.last(8).select do |tweet|%>
    <% if tweet.wanted_list!="" %>
      <%= tweet.wanted_list %>
    <%end%>
  <%end%>
</div>
```
書き方はeachメソッドとほぼ一緒です。
異なる点は、条件分岐で !=""　と定義し空でなければとしてみました。
イメージとしては、一つずつピックアップして条件に当てはめる感じです。
これで、
「wanted_listが空のときは表示させない＝wanted_listに値のあるものだけを表示」
させることに成功しました。

※last(8)は最新のレコードから8個という意味・・・controllerのorderメソッドによります。

#結論
eachメソッドはスタート値に依存するため、細かい条件分岐には向かないことがわかりました。
私は、selectメソッドを使用しましたが、他にいい方法があれば教えていただけたら幸いです！
iOSでmethod swizzling使って、共通の処理を実装する

## はじめに
- iOSで共通の処理を実装するときにいろいろなパターンを考えてみましたのでまとめます。今回は`method swizzling`を中心に考えてみます。

## 環境
```
Xcode 12.3
Build version 12C33
Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
Target: x86_64-apple-darwin19.6.0
```

## method swizzlingとは
- method swizzlingはすでに存在するメソッドの処理を入れ替える機能です
- Objective-C の全てのクラスに対して使用できる。
- 共通の処理を継承せずに実装できる

## クラスでの継承との違い
- クラスでの継承とmethod swizzlingでの実装の違いについてまとめました。

|  | ⭕️ | ❌ |
| :--- | :--- | :--- |
| method swizzling |入れ替えたクラスに処理が反映される | 影響範囲が見えづらいので不具合が起きた時に対処しずらい |
| クラスの継承 | 継承したクラスのみで処理が実行されるのでコントロールしやすい。 | 実装が必要なクラスをすべて書き換える必要があるので |

- 実装方法には一長一短あることがわかります。使い所よく考える必要があります。


## 活用例
### kickstater
- ViewModelのbindingやstyleを反映させる処理などに活用されています
- https://github.com/kickstarter/ios-oss/blob/master/Library/UIViewController-Preparation.swift

### 画面のトラッキング
- `viewWillAppear`の実装を入れ替えて、Firebaseなどを使えば、画面表示のイベントを送る処理が楽に実装できます

```swift
import ObjectiveC
import UIKit

private func swizzle(_ vc: UIViewController.Type) {
  [
    (#selector(vc.viewWillAppear(_:)), #selector(vc.hoge_viewWillAppear(_:)))
  ]
  .forEach { original, swizzled in

    guard let originalMethod = class_getInstanceMethod(vc, original),
      let swizzledMethod = class_getInstanceMethod(vc, swizzled) else { return }

    let didAddViewDidLoadMethod = class_addMethod(
      vc,
      original,
      method_getImplementation(swizzledMethod),
      method_getTypeEncoding(swizzledMethod)
    )

    if didAddViewDidLoadMethod {
      class_replaceMethod(
        vc,
        swizzled,
        method_getImplementation(originalMethod),
        method_getTypeEncoding(originalMethod)
      )
    } else {
      method_exchangeImplementations(originalMethod, swizzledMethod)
    }
  }
}

private var hasSwizzled = false

extension UIViewController {
  public final class func doBadSwizzleStuff() {
    guard !hasSwizzled else { return }

    hasSwizzled = true
    swizzle(self)
  }

  @objc internal func hoge_viewWillAppear(_ animated: Bool) {
    self.hoge_viewWillAppear(animated)
    let instanceType = type(of: self)
    let name = String(reflecting: instanceType)
    print(name)
  }
}
```


## まとめ
- `method swizzling`は便利ではあるが使い方を見極めて、使うことが必要


## 参考リンク
- https://github.com/kickstarter/ios-oss/blob/master/Library/UIViewController-Preparation.swift
- https://www.mininny.dev/ios/exploring-method-swizzling/
「Unable to find any of pip2, pip to use.  pip needs to be installed.」のエラーが出た時

反映先のサーバで、pipコマンドを使ってライブラリをインストールしようとしたときに「Unable to find any of pip2, pip to use.  pip needs to be installed.」のエラーが出ました。

原因は反映先のサーバではpip3モジュールがインストールされている状態で、pip2がない状態で、pip2を利用してインストールしようとしていたのが原因でした。

ネットで上記エラーを検索すると、ansible_cfgファイルに以下を「ansible_python_interpreter=/usr/bin/python3」を指定すれば解決できると言う情報を見てやってみたんですが、解決できず。。

結局以下のスクリプトで無事pip3でインストールするようになりました。

```shell
- name: install selenium
  pip:
    name: selenium
    state: present
    executable: pip3
```
micro:bit v2で自作のカスタムブロックを新たなプロジェクトに入れると過去にいれてたコードが動く件

# 謎の呪われたコード
micro:bit v1.5で動いてた自作のカスタムブロックが入ったコードをv2で動かすとLEDの表示が現在のコードには入っていない過去にいれた記憶のある表示になったり、ボタンのイベントを消してるはずなのにボタンイベントが動いてしまう現象が発生しました。
v1.5では発生を確認できてなくて、シリアル通信などやってるからおかしいのかな？とか思いつつ一晩寝て気づきました。
僕のカスタムブロックの作りに問題がありました。

# 発生した原因
原因ですが非常に簡単なことでした。
新たなプロジェクトからgitから入れたカスタムブロック自体にはサンプルコードとしてブロックを配置したmain.tsも入れていました。
これが問題で、新規で作ったmain.tsとカスタムブロック内のmain.tsが並行して動くという状態になっていました。
順番としてmain.tsが実行されてからカスタムブロック内のmain.tsが動く感じでボタンなどのイベントが複数存在する感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/d510ca67-5937-d1e8-a1a5-f00cf6480ec5.png)


# 解決方法
カスタムブロックを作成するときには main.ts と main.blocks のを消すか中身を削除しましょう。
そして読み込んでるプロジェクトでコードにしてエクスプローラーからリロードボタンを押して再度読み込ませます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/97d67cee-7c0c-5546-a585-0bd2bce44446.png)

# 結論
サンプルコードとして置いた感じにすると悲しい出来事が発生します。前に書いた記事のままだと特にそうなってしまいます。
https://qiita.com/wakasamasao/items/eedf7f8d6308e828986a
このお作法は適当に作ってた僕が知らなかっただけというオチなんですが。
とりあえず、v1.5では発生してなかったのにv2ではなぜかカスタムブロック内のコードがひっそり動いてしまうので通信系だと変なコード埋め込まれて動いてるとかもできなくないので結構怖いですね。
SendGridで添付画像をHTMLメール本文中にインライン表示する

使ってる環境はcakephp3、SendGrid（[sendgrid/sendgrid-php](https://github.com/sendgrid/sendgrid-php)）

webで公開している画像をhtmlメールで表示するのは何の苦労もないけど、添付ファイルをhtmlメール内にインライン表示したい。
結論から言うと、Attachmentのdispositionにinlineを指定すればいい。
なかなか見つからなかったのでメモ。

```php
use SendGrid;
use SendGrid\Mail\Attachment;
use SendGrid\Mail\Mail;
use SendGrid\Mail\From;
use SendGrid\Mail\To;
use SendGrid\Mail\Subject;
use SendGrid\Mail\PlainTextContent;
use SendGrid\Mail\HtmlContent;

// …略

// 添付ファイル
$attachment = new Attachment();
$attachment->setContent($base64EncodedImage);
$attachment->setType($contentType);
$attachment->setFilename($filename);
// dispositionのデフォルトはattachmentで、添付するだけになっている
$attachment->setDisposition('inline');
$attachment->setContentId($contentId);

$email = new Mail();
$email->setFrom($from);
$email->addTo($to);
$email->setSubject($subject);
$email->addAttachment($attachment);
// マルチパートにするならtext/plainもaddContentする
$email->addContent('text/html', $content);

$sendgrid = new SendGrid('SendGridKey');
try {
    $response = $sendgrid->send($email);
} catch (Exception $e) {
    // ログ出力など
}
```

htmlメールのソース

```html
<html>
<head><title></title></head>
<body>
<p><img src="cid:setContentIdで入れた値" /></p>
<p>添付画像がインラインで表示されるよ</p>
</body>
</html>
```

動作確認
表示される：iOSデフォルトメールアプリ、Gmail（web、iOSアプリ、Androidアプリ）、Yahoo!メールweb、Outlook
表示されない：Yahoo!メールiOSアプリ
IBMCloud vSRXパスワード変更について

##小ネタ
vSRXを利用する際、主にOS Reloadなどをする場合は、
IBMCloudポータルに表示されるパスワードと、実機のパスワードを一致させる必要がある。
今回は、実機を変更した際に、ポータル側のパスワードを実機に合わせる方法を記載する。

* ポータルと実機のパスワードを合わせる必要がある
    * クラスタの**root**ユーザ
    * Node0の**root**ユーザ
    * Node1の**root**ユーザ
* ポータルと実機のパスワードを合わせる必要がない
    * クラスタの**admin**ユーザ

その他にもFirewallを開けておく必要もあるので、下記を参照
OS Reloadの前には、Readiness Checkが必要で、実施することでどこに異常があるかわかる。
https://cloud.ibm.com/docs/vsrx?topic=vsrx-readiness-errors&locale=en

###クラスタパスワード
クラスタの場合は、**root**を一致させる必要がある。
**admin**はポータルと実機を一致させなくても問題ない
![IBM_Cloud_-_Gateway_details.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/b47a9520-0cd6-39b0-d4f8-e86c04356285.png)

左下の**root**右にある鉛筆アイコンからパスワードを変更し、実機に合わせる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/5b0a7bf3-de30-2ec4-406a-08acbeea3947.png)

###Node0/1パスワード
Node0/1(Ubuntu)のパスワード変更は、各ノードのページに移動する必要があるので、**ノードの名前＊＊を選択する。
![IBM_Cloud_-_Gateway_details.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/9d16255f-2f07-c972-c731-1c7dc85c3213.png)

**Password** -> **Actions** -> **Edit credentials**を選択
![貼り付けた画像_2020_12_18_10_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/78fc7d7a-c1f5-7b29-915d-73d88a7d62c2.png)

ここで実機のパスワードと合わせる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/8a5c5b2c-2d1f-c295-7fee-b2215d9d8949.png)
Asanaを使ってデイリーMTGがちょっと楽になった話

こんにちは、食べログでDXエンジニアをしている@sarataniです。

職種の性質・特徴かもしれませんが、日々の仕事の中で同時並行で色々な仕事を進めることも多く、タスク管理をどうしようと日々考えていました。

そんな中、ふとしたことをきっかけにAsanaを使い始めることになったのですが、AsanaをMTGに組み込むことで、タスク管理がちょっと楽になった話を書いていきたいと思います。

## 前提情報
### 想定読者
- 日々のタスク管理をメモアプリなどで管理している方
- MTGで出てきたタスクの整理に悩んでいる方

### Asanaについて
- 詳細は[公式HP](https://asana.com/ja)をご確認ください
- 個人・法人問わず無料で利用することができる、ワークマネージメントツールです
    - 無料で利用する場合は機能制限があります

## Asanaを使う前

Asanaを使う前は、主にPCローカルのメモアプリなどを使って以下のようにタスク管理をしていました。

- MTG中に出てきたタスクをメモアプリに残す
- MTGの議事メモを後で読み返してタスクとしてメモアプリに残す
- チャット等のテキストコミュニケーションから出てきたタスクをメモとして残す
- とりあえず何か思いついたら、メモアプリに書いて残す

一つのファイルに書き足していくのではなく、ファイルを分けて（タブを分けて）書き残していくスタイルで運用していました。

これを続けていく中で、このスタイルによるメリット・デメリットはこんなところです。

### メリット
- シュッと書き残せるので素早い

### デメリット
- 自分以外の誰かへ共有がしづらい
    - 暗黙的に自分が読んで分かる前提で運用がされる
        - ただし時間が経つと「これなんだっけ？」もたまにある…
    - 抜け漏れが発生する可能性が高い
- タスクの意図を誤って認識し、それをメモに残して進めていたケースもある
- 表現がテキストのみなので、文量が多いと読みづらい・追いかけづらいことがある
- きちんとデータを保存しておかないと、最悪消えてしまう可能性がある
- タブが無限に増えていくので、探しものがある時はちょっと大変


ふり返ってみるとデメリットの方が多いものの、慣れと手軽さが勝っていて、このスタイルを続けていました。

こんな状況下だったのですが、ふとしたことから[Asana](https://asana.com/ja)を使うことになりました。


## Asanaを使い始めてから
Asanaを使うことで色々なメリットや創意工夫が生まれました。
全てを紹介すると分量が膨大になるため、例えばデイリーMTGでの一例ですが・・・

- デイリーMTGのAsanaタスクを作成する（1週間ごとに1タスク作る）
- MTGの会話で出てきた"やること"を上記Asanaタスクのサブタスクとして登録する

シンプルですが、こうすることで抜け漏れを減らしながら、やることを整理して残せます。
タスクの粒度として"1週間以内にやること"を目安にしているため、1週間ごとに1タスクという具合にしています。

こうすることで **「この週のデイリーMTGで出てきた、今週目処にやっていくタスクはここを見ればわかる」が一発で出来上がります。** 


この手法のメリットとしては・・・

- タスクの期日・担当者などが変更となった場合でも、簡単に情報を変更することができる
- （MTGでは画面共有する前提ですが）話しながらタスクに残していくので、認識ズレが減る
- 一つのタスクの中にやることが集約されるので「どこだっけ？」になりにくい
- データ消失の可能性が減る
- 自分以外の人も見ることができる、共有しやすくなる



## まとめ
このスタイルに切り替えてから、MTGでのやること整理がだいぶ楽になりました！

また、日々使っているツールを見直す・今までやっていることに疑問を持ってみることで、日々の仕事が楽になるという良い機会でもありました。

今回のケースはAsanaでなくとも「チームで利用可能なタスク管理ツール」でも実現できると思います。
毎日同じようにやっていると、改善点がなかなか思い浮かばない、アイデアが出てこないということも多いです。
年末というタイミングもあり、 **来年からちょっとだけ仕事のやり方を変えてみる** のはいかがでしょうか？

明日は、@nakia さんの「リリースしてから１年経ったのでフロントエンド技術選定の振り返りをする」です。お楽しみに！！
UIkitのswitcherで今のindexと次のindexを取得する

UIkitのSwitcherを利用していてコンテンツが入れ替わる際に，今よりも前のコンテンツに移動するのか後のコンテンツに移動するのかを判定したい場合があると思います．

そのような際に現在表示されているコンテンツのindexと，次に表示されるコンテンツのindexを下記のように取得することができます．

```
document.addEventListener('beforehide', function(e) {
    let now_index = UIkit.util.index(e.target);
    let next_index = e.detail[0].index();
});
```

## 参考サイト
https://github.com/uikit/uikit/issues/3279
FastDFS systemd script

```shell
[Unit]
Description=The fastdfs storage server
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
ExecStop=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf stop
ExecRestart=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart

[Install]
WantedBy=multi-user.target
```

```shell
[Unit]
Description=the fastdfs tracker server
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
ExecStop=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf stop
ExecRestart=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart

[Install]
WantedBy=multi-user.target
```
metabaseでパレート図を作ってみた(SQLite)


副問い合わせを用いたものは割とよくありますが、windows関数をつかってパレート図のデータを作る方法がみつからず、
ちょっと作ってみたときのメモです。

データが少ないのでもしかしたらうまくいかないケースがあるかもしれません ^^;

# 準備

sqlite に man_hour というテーブルを作成して、以下のデータを投入し、
metabaseから接続しておく。

~~~csv
名前, 実績
hoge,	2
hoge,	2
fuga,	3
test,	2
~~~

# グラフの作成

## 質問内容（記述したSQL）

~~~sql
-- データの絞り込み and ソート
with dataitem as (
select
    sum(実績) as 実績,
    名前
from man_hour
group by
    -- グルーピングしておく
    名前
order by
    -- ここでグルーピングしたものを多い順に並べ替えておく
    sum(sum(実績)) over (partition by 名前) desc
)

-- グラフ用
select 
    実績,
    -- 最初のデータから現在の行までを合計したものを、すべての合計で割る
    sum(実績) over (rows between unbounded preceding and current row) / sum(実績) over () as 累積比率,
    名前
from dataitem
~~~

## グラフの設定(metabase)
  1. コンボを選択
  2. 「表示」の「累積比率」を展開し、どちらの軸で「左」を選択する。
  3. 「表示」の「実績」を展開し、どちらの軸で「右」を選択する。
  4. 「表示」の目標ラインをオンにして、目標値に「0.8」を記述する
  5. 「データ」の「累積比率」の歯車アイコンを押し、スタイルを「percent」にする


# できたグラフ
 
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281608/cce8d982-0a9a-bfa0-6875-caff50d5fe4f.png)

グラフの左右の軸は反対にしたいが、metabaseの目標ライン機能を使いたかったので、
左側に累計比率をおいている（違和感があるが・・・）



# そのほか

  * 「目標ライン」の点線が、なぜかずれる（たぶんmetabaseのバグ）
Openboxでウィンドウに角丸を

# Openbox始めました
Xfceが重く感じてきたのでデスクトップ環境を探していたけれど、調べているうちにLxdeのウィンドウマネージャであるOpenboxに興味を持ったので使い始めました。Openboxは軽量でカスタマイズ性が高く、シンプルなのでとてもいいと思います。
# 角丸にしたい
色々カスタマイズを加えていく中で、以前のXfwmのようにウィンドウが角丸になったらいいのになぁと思い、やり方を調べました。
ところが、ネット上にそのような情報があまりなく、かなり大変だったのでわかりやすく残しておくことにします。
# 大まかな手順
1.ソースコードのダウンロード
2.パッチを当てる
3.コンパイル
4.インストール
5.セッションの設定
# 実際にやってみる
環境は以下の通りです。
OS: Debian 10 (buster)
Arch: i386
DM: LightDM
## 1.ソースコードのダウンロード
Githubにソースコードがあったので落とします。

```
$ git clone https://github.com/Mikachu/openbox.git ./openbox
```

## 2.パッチを当てる
GithubにOpenbox用の角丸パッチがあるのでクローンします。

```
$ git clone https://github.com/dylanaraps/openbox-patched.git ./openbox-patched
```

以下のコマンドを実行します。

```
$ cd ./openbox
$ patch -up1 < ../openbox-patched/*rounded-corners.patch
```

これでパッチを当てられました。
## 3.コンパイル
まずは依存パッケージをインストールします。

```
$ sudo apt-get install \
build-essential \
pkg-config \
libpango1.0-dev \
libglib2.0-dev \
libxml2-dev \
libxcursor-dev \
libimlib2-dev \
libstartup-notification0-dev \
xlibs-dev \
libxext-dev \
x11proto-randr-dev
```

次に、以下のコマンドを実行します。

```
$ ./bootstrap
$ ./configure —-prefix=/usr/local
$ make
```

## 4.インストール
以下のコマンドでインストールします。インストール先は/usr/local内になります。

```
$ sudo make install
```

Openboxの設定ファイルで角丸を有効にします。

```
$ vim ~/.config/openbox/rc.xml

# <theme></theme>内の末尾に以下を追記
<cornerRadius>4</cornerRadius>
```

## 5.セッションの設定
角丸パッチ版のOpenboxのインストールができましたが、今のままではディスプレイマネージャが認識してくれません。そこで、/usr/share/xsessions内にセッションファイルを作ります。

```
$ sudo cp /usr/local/share/xsessions/openbox.desktop /usr/share/xsessions/openbox-patched.desktop
$ sudo vim /usr/share/xsessions/openbox-patched

# 以下の内容を変更
Name=Openbox —> Name=Openbox-Patched
```

あとは再起動するかディスプレイマネージャを再起動すれば、ディスプレイマネージャのセッションを選ぶところでOpenbox-Patchedが見つかるはずです。

# 最後に
以下のように角丸になりました。満足です。
![FCB466BC-0A51-4818-8CD3-22BFB7DEB293.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637875/f8bb6517-04e8-2011-fbca-aec79f37860c.png)
AndroidでOne Touch(確認無し)で電話する方法(Java)

ネットで、確認なしで電話をかける方法をいくら調べても、

Intent intent = new Intent(Intent.ACTION_DIAL, "tel:0123345678);
のACTION_DIALのところを
Intent intent = new Intent(Intent.ACTION_CALL, "tel:012345678");
のようにACTION_CALLにするだけでOKと書いてあるのに、実行するとなぜか落ちる(?_?)

もちろん、AbdroidManifest.xmlに、
uses-permission android:name="android.permission.CALL_PHONE"
を入れるのも忘れてないし、なぜだろうと悩んだところ、
アプリにCALL_PHONEへのアクセス権を与えてやらなければいけないことが判明。

アプリ起動時に、以下のようにアクセス権を与える許可ダイアログを表示してやらなければならなかった。
CALL_PHONEはdangerousパーミッションだから、ユーザにいちいち許可をもらわなければならないのね(^^;)

public class MainActivity extends AppCompatActivity {
    static final int REQUEST_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)==PackageManager.PERMISSION_DENIED) {
            ActivityCompat.requestPermissions(
                    this, new String[] { Manifest.permission.CALL_PHONE }, REQUEST_CODE);
        }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        if (requestCode == REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Dangerous パーミッションのリクエストが許可
            } else {
                Toast toast = Toast.makeText(getApplicationContext(), "電話機能のアクセス権限を追加しないと使えません", Toast.LENGTH_LONG);
                toast.show();
                finish();
            }
        }
    }
ElastiCacheを扱う場合に必須の知識

# あと2時間でElastiCacheのメモリが枯渇！そのときあなたは何をしますか？
## リンク
https://zenn.dev/e_koma/articles/20201218-adventcalendar-1a8e2ea4

## 個人的なコメント
* 複雑なキャッシュ構造持ってるサービスを扱うと、この程度の基礎がないとどう対応していいか検討する段階にすら入れない
 
* datadogも監視方法についてレクチャーしてくれてる
https://github.com/DataDog/the-monitor/blob/master/translations/ja-jp/elasticache/monitoring-elasticache-performance-metrics-with-redis-or-memcached.md

* キャッシングとは何かを理解すること。また、ソフトウェアごとに管理方法が異なるので自分が使うものについて把握すること（異なるから使い分けが生じる）
[Amazon ElastiCache ベストプラクティス](https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/mem-ug/BestPractices.html)
[Redis 用 Amazon ElastiCache](https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/BestPractices.html)
[RedisとElastiCacheを分かりやすくまとめてみた](https://qiita.com/gold-kou/items/966d9a0332f4e110c4f8)
Visual Studio 2019 でマークダウンのプレビュー表示

# はじめに
Visual Studio 2019 では、標準では、マークダウン ファイルのプレビュー表示を行うことができません。
ここでは、Visual Studio の拡張機能を使って、マークダウン ファイルのプレビュー表示を行う方法を説明します。

# 拡張機能のインストール
Visual Studio 2019 のメニュー [拡張機能] - [拡張機能の管理] を選択。
[オンライン] - [Visual Studio Marketplace] を選択。
[検索] ボックスに、"Markdown" と入力。
今回は、[Markdown Editor] を選択し、[ダウンロード] を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/574b09c4-88ce-5a26-3395-41c434e3d7a6.png)

起動中のすべての Visual Studio 2019 を閉じると、VSIX Installer が起動する。 
[Modify] を選択する。インストール完了後、[Close] を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/4d04c531-d97d-96d3-298c-ded589403012.png)

# マークダウン ファイルのプレビュー表示
Visual Studio 2019 を起動する。
マークダウン ファイルを開くと、プレビュー付きで表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/a6a454c2-6703-5b51-1717-585f879b9516.png)
もちろん、編集すれば、リアルタイムでのプレビュー表示もできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/06e3e7da-c139-ac85-e054-8e78669bd7c8.png)
【PostgreSQL】DBバックアップ（sql.gz）とリストアメモ

PostgreSQLのデータベースバックアップ（sql.gz）とリストアのメモ書きです。
PostgreSQLのコマンドを使って実行します。

<手順>
①バックアップを取得する（sql.gz）。以下で時分秒付きのファイルを生成する。
　例：backup.20200101-010101.sql.gz
＄ pg_dump [DB名] | gzip -c9 > [フルパス]/backup.$(date "+%Y%m%d-%H%M%S").sql.gz

②リストア前に、DB削除。
＄ dropdb [DB名]

③空DB作成。
＄ createdb -U postgres -O [DB作成者(ユーザ)] psql [DB名]

④sql.gzのリストアを行う。
$ gzip -dc [DBバックアップファイル(フルパス)] | psql [DB名]
【C#】Enumでよく使うけど忘れがちなもののメモ

# はじめに
毎回「あれ、どう書くんだっけ」と調べているので、まとめておこうと思います。

```C#
// 各サンプルコードで使用するEnum
public enum Seasons
{
    Spring,
    Summer,
    Autumn,
    Winter
}
```

# 全要素取得してループ
```C#
foreach (var season in (Seasons[])Enum.GetValues(typeof(Seasons)))
{
}
```

# Enumにメソッドを実装（拡張メソッド）
```C#
public static class SeasonsExt
{
    public static string GetJapaneseName(this Seasons param)
    {
        switch (param)
        {
            case Seasons.Spring:
                return "春";
            case Seasons.Summer:
                return "夏";
            case Seasons.Autumn:
                return "秋";
            case Seasons.Winter:
                return "冬";
        }
    }
}

// 使い方
var season = Seasons.Spring;
var japaneseName = season.GetJapaneseName();
```

# 定義されている値かどうかチェック
```C#
Console.WriteLine(Enum.IsDefined(typeof(Seasons), 0));  // True
Console.WriteLine(Enum.IsDefined(typeof(Seasons), 4));  // False
Console.WriteLine(Enum.IsDefined(typeof(Seasons), "Spring"));  // True
Console.WriteLine(Enum.IsDefined(typeof(Seasons), "spring"));  // False（大文字・小文字区別される）
```

# 型変換
## int ⇔ Enum変換
```C#
// int -> Enum
System.Console.WriteLine((Seasons)0);  // Spring
System.Console.WriteLine((Seasons)4);  // 4（定義されていない値でも例外は発生しない）

// Enum -> int
System.Console.WriteLine((int)Seasons.Winter);  // 3
```

## string ⇔ Enum変換
```C#
// string -> Enum
if (Enum.TryParse<Seasons>("Summer", out var season))
{
    System.Console.WriteLine(season);  // Summer
}
// 数値の文字列も変換できる
if (Enum.TryParse<Seasons>("1", out var season))
{
    System.Console.WriteLine(season);  // Summer
}

// Enum -> string
System.Console.WriteLine(Seasons.Winter.ToString());  // Winter
```

## int/string -> Enumの変換用メソッド作ってみた
なんだか少しまどろっこしいかんじになってしまいました。

```C#
public static T? ConvertToEnum<T>(object value) where T : struct
{
    // TがEnumかどうかチェック
    // where T : Enum にすると、戻り値をNullableにできないので...
    if (!typeof(T).IsEnum) return null;

    string stringValue;
    switch (value)
    {
        case int intVal:
            stringValue = intVal.ToString();
            break;
        case string stringVal:
            stringValue = stringVal;
            break;
        default:
            // int, string以外は処理対象外とする
            return null;
    }

    // TryParseする前に、定義されている値かチェックする
    // ※ 数値の場合、定義されていない値でもTryParseが成功してしまうため
    if (!Enum.IsDefined(typeof(T), value)) return null;

    if (Enum.TryParse<T>(stringValue, out var result))
    {
        return result;
    }
    return null;
}
```
Ubuntu20.04でvimをビルドする方法

# Ubuntu20.04でvimをビルドする方法

最新vimの開発が活発なので最新のvim気になりますよね。
私はライトvimmerですが、それでも最新が気になります。

この情報は、ほぼ公式ページ通りですが、公式は情報がすこし古いのでUbuntu20.04でビルドできるように整理するのが目的です。

https://vim-jp.org/docs/build_linux.html

## ライブラリ・言語のインストール

ビルドに必要なライブラリと言語 python, ruby, lua, perlあたりも入れておきます

```bash
sudo apt install -y git build-essential autoconf automake cproto gettext
sudo apt install -y libacl1-dev libgpm-dev libgtk-3-dev libtinfo-dev libxmu-dev libxpm-dev libncurses-dev 
sudo apt install -y libperl-dev liblua5.2-0 liblua5.2-dev libluajit-5.1-dev lua5.2 luajit python-dev python3-dev ruby-dev
```

## vimのclone
```bash
git clone https://github.com/vim/vim.git
```

## ビルド&インストール

```bash
./configure  --prefix=/usr/local/ --with-features=huge --enable-multibyte --enable-gpm --enable-cscope --enable-perlinterp --enable-python3interp --enable-rubyinterp --enable-luainterp --enable-acl --enable-fontset --enable-xim --enable-terminal --enable-fail-if-missing --with-luajit --with-x
make
sudo make install
```

### pyenvのPythonでビルドしたい場合

**--with-python3-command=**を使用してpyenvのpythonのパスを指定しましょう

`--enable-python3interp --with-python3-command=$(echo $HOME)/.anyenv/envs/pyenv/shims/python`

```bash
./configure  --prefix=/usr/local/ --with-features=huge --enable-multibyte --enable-gpm --enable-cscope --enable-perlinterp --enable-python3interp --with-python3-command=$(echo $HOME)/.anyenv/envs/pyenv/shims/python --enable-rubyinterp --enable-luainterp --enable-acl --enable-fontset --enable-xim --enable-terminal --enable-fail-if-missing --with-luajit --with-x
make 
sudo make install
```

## 最後に

朝起きてPCを起動したら`git pull`してビルド&インストールしましょう。
最新のvim体験があなたをまっています。
【Rails】多対多の作成

<h1>本投稿の目的</h1>
・Railsについての議事録です。

---
<h1>学習に使った教材</h1>
Udemyの以下2つの教材を参考にまとめました。
・["はじめてのRuby on Rails入門-RubyとRailsを基礎から学びWebアプリケーションをネットに公開しよう"](https://www.udemy.com/course/the-ultimate-ruby-on-rails-bootcamp/) 
・["フルスタックエンジニアが教える 即戦力Railsエンジニア養成講座"](https://www.udemy.com/course/rails-kj/)

---

<h1>○多対多の関係とは?</h1>

・複数のcolumnが相互に紐づいたmodel同士の関係
・例):掲示板アプリのboard とtagのような関係 (投稿内容は異なるがtagが同じような投稿は多対多の関係)

<h1>○紐付けのポイント</h1>

・中間テーブルを用意する (本投稿での説明では,model(中)と定義)
・中間テーブルは [:id,多1_id,多2_id] のみのシンプルな構造

<h1>○紐付け設定方法</h1>

<h3>①model多1とmodel多2を普通にgenerateする</h3>

```
rails g <model(多)1> <column情報>
rails g <model(多)2> <column情報> 
```

<h3>②中間テーブルをgenerateする</h3>

```
rails g model <model(中)> <model(多)1>:references <model(多)2>:references
```

・中間テーブルは通常は "model(多)1_model(多)2_relations" という名前が一般的
・model名称は全て小文字,単数形でOK

<h3>③migrationを実行</h3>

```
rails db:migrate
```

・①②で設定したmodelがdbのtableに反映される

<h3>④中間テーブルのmodelへの記述</h3>

```model(中).rb
class model(中) < ApplicationRecord
  belongs_to :model(多)1
  belongs_to :model(多)2
end
```

・この記述はgenerate時に自動記述
・belongs_toが2つ設定済みのためノータッチでOK

<h3>⑤moel(多)1のmodelへの処理</h3>

```model(多)1.rb
class model(多)1 < ApplicationRecord
has_many :<model(中)s>
has_many :<model(多)2s>, through: :<model(中)s>
end
```

・`through: :<model(中)s>` は,2つのmodel間にmodel(中)を経由するという意味
・(model(多)1 → model(中) → model(多)2 という意味)
・中間テーブルを経由することをここで記述して置く必要がある
・model名は複数形で記述

<h3>⑥model(多)2のmodelへの処理</h3>

```model(多)2.rb
class model(多)2 < ApplicationRecord
has_many :<model(中)s>
has_many :<model(多)1s>, through: :<model(中)s>
end
```

・model(多)1と同様に2つのhas_manyを設定
・model名は複数形で記述

---
順次更新: Apple Silicon対応ソフトを勝手に入れてくれるHomebrewリポジトリを作った

ようやくM1対応MacBookが届いたので早速Apple Siliconがいかほどか試してみると早い早い...ファンが全然回らない...とにかく化け物です。  
しかし、ソフトウェアの中には標準ではIntelバイナリしか対応しておらず(Rosseta2でも十分早いですが...) Apple Siliconの威力が発揮できないものが多くあります。  
ただ、すでにApple Siliconにネイティブ対応したアプリケーションがBetaテスト相当になっていたりApp Storeではなく公式のホームページから対応バイナリを配布したりしています。  
そこで、Apple Silicon対応のバイナリを簡単に試せるようにHomebrewリポジトリの作成を行いました。よろしければお試しください。

>> AppStoreで公開がなく公式のHomebrew Caskで対応がないものを基準に追加しています。


# Homebrew Repositoryの追加
このリポジトリを追加するには以下のTapを追加する必要があります。

`$ brew tap shotastage/shotacask`

もし不要になったら、`untap`も忘れずにお願いいたします。


# パッケージの探し方

一般的なHomebrewのようにbrew searchでパッケージ検索ができます。また、このリポジトリでは以下の命名規則を設定しています。　　
例えば、`brew search google-chrome`を実行すると以下の結果が返ってきます。
![Screen Shot 2020-12-18 at 10.23.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44018/047a4513-97dc-ab29-dc7e-8c4ccb8a5817.png)

この`google-chrome-asr`がApple Silicon対応のパッケージです。
Apple Siliconに対応したパッケージには`-asr`もしくは`-universal`のサフィックスが付加されています。`-asr`はApple Silicon Readyの略でApple Siliconのみで動作するものやApple Siliconを前提に配布が行われているUniversal Binaryです。
また、UniversalはApple SiliconとIntel両方で動作するソフトウェアです。

# 順次更新: Apple Silicon対応ソフトウェア
以下のソフトウェアがこのリポジトリに含まれています。

| 名称 | バージョン | バイナリ | 更新日 | 参考リンク | 備考 |
|:-------|:-----------------|:--------------|:------|:------|:-----|
| Docker | 20.10.1 Preview7 | Apple Silicon | 12/17 | [Docker Preview](https://www.docker.com/blog/download-and-try-the-tech-preview-of-docker-desktop-for-m1/)
| Google Chrome | 87.0.4280.88 | Universal (ただしM1専用に提供) | 1/4 | [Chrome ダウンロード](https://www.google.com/intl/ja_jp/chrome/) | 公式のCaskリポジトリがUniversalバイナリをダウンロード | 
| Microsoft Edge | 89.0.736.0 | Universal (ただしM1専用に提供) | 12/17 | [Edge Insiderビルド](https://www.microsoftedgeinsider.com/ja-jp/download) |
| Visual Studio Code | 1.53.0-insider | Apple Silicon | 12/17 | [Visual Studio Code Insider](https://code.visualstudio.com/insiders/) |
| Slack | 4.12.0 | Apple Silicon | 12/17 | [Slack ダウンロード](https://slack.com/intl/ja-jp/downloads/mac) | 公式のCaskリポジトリで対応済 |
| Basic Tex | 2020 | Intel Rosseta (Universalバイナリ公開済み対応予定) | 12/17 | [About Arm](http://www.tug.org/mactex/aboutarm.html) |
| Parallels Desktop | 16 | Apple Silicon | 1/4 | [Parallels Technical Preview](https://www.parallels.com/blogs/parallels-desktop-apple-silicon-mac/) |
| Go | 1.16Beta | Apple Silicon (公式リポジトリで対応済)| 1/4 | [Homebrew Go Formula](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/go.rb) | Homebrew上は1.15.6がダウンロードされるが実態は1.16Beta |
| JDK | 8-17 | Apple Silicon | 1/21 | [Zulu OpenJDK](https://jp.azul.com/downloads/zulu-community/?os=macos&architecture=arm-64-bit&package=jdk) | 現在15と11LTSをCaskに追加済 |
【Rails】dependentの設定

<h1>本投稿の目的</h1>
・Railsについての議事録です。

---
<h1>学習に使った教材</h1>
Udemyの以下2つの教材を参考にまとめました。
・["はじめてのRuby on Rails入門-RubyとRailsを基礎から学びWebアプリケーションをネットに公開しよう"](https://www.udemy.com/course/the-ultimate-ruby-on-rails-bootcamp/) 
・["フルスタックエンジニアが教える 即戦力Railsエンジニア養成講座"](https://www.udemy.com/course/rails-kj/)

---

<h1>○dependent の設定</h1>
・1対多のmodelの関係において,model(1)のcolumnが消去されると,そのcolumnに紐づくmodel(多)のcolumnは必要なくなる
・これを自動的に消去してくれる設定であるdependentには以下2つがある
・どちらもmodel(1)ファイルに対して記述を追加する

<h3>○dependent: :delete_all</h3>

```model(1).rb
class model(1) < ApplicationRecord
has_many :model(多), dependent: :delete_all
end
```

・model1の削除=紐付けデータも同時削除 になる 
・親が削除されると子たちは自動で消される
・例):親であるquestionのcolumn情報が削除されると,それに紐づいたanswer のcolumn情報も一緒に削除される

<h3>○dependent: :destroy</h3>

```model(1).rb
class model(1) < ApplicationRecord
has_many :model(多), dependent: :destroy
end
```

・`delete_all`と同じ処理がされるが,オブジェクトを1つずつ消していく
・パフォーマンスは`delete_all`に比べて低い
・紐付けが2階層以上ある場合は,こちらを使用しないとできないことがある
*(基本的に1階層の時は,`delete_all`を使用する)

<h1>○dependentの有効範囲</h1>

・紐づけ自動削除機能は,destroyアクション時のみ有効 
・controllerのdeleteメソッドをdestroyメソッドに変更しておく必要がある

---
1分で理解！Firestoreのサブコレクション

＊この記事ではJavaScriptで書いていきます。

NoSQLについてはこちらの記事へ↓
https://qiita.com/Yu-kiFujiwara/items/c1c52495fd321373c544

##そもそもfirestoreってどういう形で保存するん？
firestoreはNoSQLの中でもドキュメント型と言われ、JSON形式のまま保存することができます。
firestoreではコレクション、ドキュメント、フィールド、データという4つの情報、
Key-Valueペアで構成されるデータを持つフィールド、フィールドを複数持つドキュメント、ドキュメントをまとめたコレクションという形でデータが構成されており、スキーマを決める必要がないため、自由にデータを保存することができます。

![スクリーンショット 0002-12-18 8.36.52（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608770/8a7754ca-6e3e-489e-79ad-c9dacbd8dd64.png)

```javascript
//書き込み
firebase.firestore().collection("auther").set({name: "太郎", age: 20})

//読み込み
firebase.firestore().collection("auther").where("name", "===", "太郎").where("age", "===", 20)

//更新
firebase.firestore().collection("auther").doc(1).update({age: 21})
```

##サブコレクションってなんなん？
また、firebaseにはサブコレクションという考え方もあり、
1つのコレクションにリレーションを組むような形でコレクションを持たせることができます。
DB構成は下記の通りです。

![スクリーンショット 0002-12-18 9.01.21（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608770/7d2f7c76-2d82-7335-9997-f7b35048f7fa.png)

autherコレクションがpostコレクションを保有するという、
より現実に近いような形でDBを構成することができます。


```javascript
//書き込み
firebase.firestore().collection("auther").doc(1).collection("post").set({text: こんにちは})

//読み取り
firebase.firestore().collection("auther").doc(1).collection("post").where("text", "===", "こんにちは")

//更新
firebase.firestore().collection("auther").doc(1).collection("post").doc(1).update({text: こんばんは})
```

##どう設計すべきか
・リレーションを組んでおらず、joinリクエストができないので一度にデータを取得できるようにデータを持つ
・データを重複して持つことを許容する
・データを更新する場合は重複したデータに対してそれぞれ更新リクエストをかける

RDBではNGとされている、これらのデータの持たせ方、更新の仕方が推奨されています。

##参照
https://www.footchantech.com/post/firestore_subcollection
WindowsのGitの改行コード自動変換設定

# 背景
Windowsにgitをインストールしてgithubからリポジトリをクローンしたら、改行コードがLFからCRLFに変換されてしまっていた。
チェックアウト、コミットするとき改行コードを自動変換する設定があるので内容をまとめる。

# 環境
Windows 10
git version 2.28.0.windows.1

# 改行コード自動変換設定

改行コード自動変換を無効にする

`git config --global core.autocrlf false`

改行コード自動変換を有効にする

`git config --global core.autocrlf true`

コミット時だけ改行コード自動変換する

`git config --global core.autocrlf input`
YouTubeのサムネ一覧をスプレッドシートで一括取得する方法

#YouTubeのサムネ一覧をスプレッドシートで一括取得する方法

##この記事の役割

国内のメディア企業でYouTubeチャンネルの制作とデータ分析を担当しているstNaoです。

弊社ではスプレッドシートを用いてYouTube動画の分析を管理しているのですが、
直感的に動画分析を行いたい時にサムネイルを表示させることで見やすくさせています。

この記事では、下の画像のように動画のサムネ一覧をスプレッドシートで表示する方法を紹介いたします。

![Screen Shot 2020-12-18 at 9.03.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/549172a3-326d-1009-9c53-dfea69420c8b.png)


#YouTubeの動画IDを取得する

YouTube動画には動画ごとにIDが割り振られています。
このIDはURLから確認ができます。

![Screen Shot 2020-12-18 at 9.04.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/feb688b7-35d2-48d9-3db0-28cdebfbc475.png)


URLを見ると

```:url
https://www.youtube.com/watch?v=4jlDCS-z7TI

# watch?v=4jlDCS-z7TI

```

上記のようになっていますが、この中の


```:url
watch?v=4jlDCS-z7TI
```

こちらの部分に注目してください。
動画のIDは、`watch?v=` 以下の`4jlDCS-z7TI`この部分です。

こちらをスプレッドシートに貼り付けます。

![Screen Shot 2020-12-18 at 9.10.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/ef49f12c-2d61-d65f-17d7-404893cf92d4.png)

#スプレッドシートのIMAGE函数とは

スプレッドシート には画像を表示させる関数であるIMAGE関数があります。

この関数と動画IDを使ってサムネイルを表示させます。

#画像表示

次の式をB1セルに入力します。

```:式
=image("http://i3.ytimg.com/vi/iROAUHfCrnU/hqdefault.jpg")
```

すると画像が表示されます。

![Screen Shot 2020-12-18 at 9.13.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/5b204b07-2ced-9e79-bd11-2a67e60d5bef.png)


次に、B1をコピーして、B2:B6に貼り付けます。

![Screen Shot 2020-12-18 at 9.16.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/2c0e3ed1-4656-27b7-c788-ddae2540a5b5.png)

全て同じサムネイルになってしまいました。

これではいけないので、B1セルの式を変更します。

```:式
#=image("http://i3.ytimg.com/vi/iROAUHfCrnU/hqdefault.jpg")
#変更前

=image("http://i3.ytimg.com/vi/"&A1&"/hqdefault.jpg")
#変更後
```

動画IDの部分をセル参照に変更しました。まだ見た目に変化はありません。

ここからB1をコピーし、再度B2:B6までペースとします。

![Screen Shot 2020-12-18 at 9.19.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/6dc32018-1c7d-679e-76de-73c3d698e6cc.png)

無事、セルにサムネイルが表示されました！


以上です。

YouTubeの分析について、「こうしたい」「ああしたい」といった疑問がありましたらコメントにてリクエストお願いいたします。
Vue CLIでdebuggerを使えるようにする方法

#あらすじ
開発に`debugger`を使う人が少ないせいか、
ESLintで`debugger`を許可する方法がなかなか見つからず
長い間泣きながら開発をしていた問題をやっと解決したので、
簡潔に記録しておきます。

#1. 全てのファイルで使えるようにする方法
ルートフォルダ直下に作成されている`package.json`の`"rules"`の内容に追記する。

```json:package.json
"rules": {
  "no-debugger": 0
}
```

#2. 特定のファイルで使えるようにする方法
.jsファイルであればファイルの一番上に、
.vueファイルであればscriptタグ内の一番上にコメントを追記する。

```JavaScript
/* eslint-disable no-debugger */
```

#補足
####`console.log()`を使えるようにする方法
`debugger`だけでなく`console.log()`も使えなくなる人がいるそうです。
その場合、上記の`no-debugger`の部分を`no-console`に変えて、
同じように設定することで解決できます。

####警告を残す方法
`0`ではなく`1`を指定すると、コンパイル時にエラーではなく警告が発生するようになるそうです。
無視することに慣れてしまうような警告を出す意味があるのかは疑問ですが、活用したい方はどうぞ。

####Special Thanks
[Why I can't use debugger or console.log on my Vue app - Stack Overflow](https://stackoverflow.com/questions/58614732/why-i-cant-use-debugger-or-console-log-on-my-vue-app)
[たった一行！！Vue CLIでconsole.logを有効化する方法 - Qiita](https://qiita.com/saio-th/items/111f6f5cc62f421cf045)
【Stereo Depth】Dedge-AGMNet : depth edgeを推定して精度向上

<h1>Dedge-AGMNet:an effective stereo matching network optimized by depth edge auxiliary task</h1>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/95dbb890-0d6b-f1d8-6ac3-f36cb3fb3345.png)

久しぶりにデファクトスタンダードになりそうなStereo Depthの論文を見つけてしまった。
今まではEdge Detectionを行う論文はいくつか見たが、Depth Edgeを推定する論文は初めて見たと思う(StereoDepthの論文は50本以上読んだ)。


<h1>新規性</h1>
AGM Moduleは今回は無視して、Depth Edge DetectionとDedge SPPを見ていきたいと思う。


<h2>Depth Edge Detection</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/9598f5b1-6d25-5ce1-36a0-af8ed2431205.png)
上の図のFeature Extractionのbranchからそれぞれ畳み込み結合させ、最大値を取った後sigmoidを掛ける。

sigmoidを掛ける事でDepth EdgeのProbabilityを0~1で正規化出来る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/a47ed72e-d7ad-ec44-76d0-e32cee102326.png)
2値分類問題でおなじみのBinary Cross Entropy Lossを用いる事で学習出来る。




<h2>Dedge-SPP</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/e9071cc2-f52f-96b6-24ac-7eed83363fc4.png)
推定したDepth Edgeを[PSMNet](https://qiita.com/minh33/items/b365e2fa66a3164a0177)で使われているSPP Moduleに結合する事でDepth Edgeの特徴量を組み込む事が出来る。


<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/4cb3eab0-5284-6410-5263-59767a9637ff.png)
Depth Edge Detectionのparameterをshareすることでよりmian BranchのFeature Extractionが一般化され精度が上がったように見える。意外な事にDedge SPPでDepth Edgeの情報を付与しても精度はさほど変わっていない。

<h1>結論</h1>
・従来のEdge DetectionではInner Edgeを見つけてしまう事や、Semantic Segmentaionだと同じクラスの物体が隣あっている時にEdgeを検出出来ないという問題があった。それを今回のDepth Edgeでは本来の物体の境界線を推定する事が出来た。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/cff3ae75-63f7-9f3d-213f-d0a678badf17.png)
Dege-SPPで精度が上がらなかったらしいのがなんか悔しいので、Depthの推定の前に結合して1 stride Conv2dを何枚か噛ませて、DepthのSmoothingとEdge辺りのDepthの補正が出来そう。


<h1>参考文献</h1>
Dedge-AGMNet:an effective stereo matching network optimized by depth edge auxiliary task
https://ecai2020.eu/papers/225_paper.pdf
【Rails6】ランキング機能

#はじめに

補助金に関する記事の閲覧・検索ができるアプリケーションの作成をしています。今回いいね機能が実装できたため、いいねの数が多い順番に記事を並べる、ランキング機能を実装しました。備忘録及び復讐のため記述します。

#環境

Ruby on Rails '6.0.0'
Ruby '2.6.5'

#前提

・ユーザー管理機能実装済み(Userテーブル）
・記事の投稿・閲覧機能実装済み（Articleテーブル）
・いいね機能実装済み（Likeテーブル）

#実装方法

複数の記事の中からいいね数が多い順番に取得することができれば良いため、Articleテーブルからの記事の取得方法を記述します。

#コントローラーの編集

先に実装方法を記述し、中身について解説していきます。

```ruby:app/controllers/articles_controller.rb
  def index
    @ranks = Article.find(Like.group(:article_id).order('count(article_id) DESC').limit(4).pluck(:article_id))
  end
```

#####Article.find(~)
- findメソッドを使用して()の中で指定する記事を探して取得します。

#####Like.group(:article_id)
- Likeテーブルの中にある、article_idが重複するレコードをまとめて並べ替えています。

#####order('count(article_id) DESC')
- count(article_id)したデータをDESC（降順）で並べ替えています。

#####count(article_id)
- article_idが同じものを数えるメソッドです。Likeテーブルに保存されているレコードを数えることで、いいねの数を取得しています。

#####limit(4)
- 上から4つ取得するメソッドです。今回は4位まで表示させたいと思ったので、この表現にしました。

#####pluck(:article_id)
- 引数としてカラム名のリストを与えると、指定したカラムの値の配列を、対応するデータ型で返します。

#おわりに

https://qiita.com/mitsumitsu1128/items/18fa5e49a27e727f00b4

こちらの記事を参考にさせていただきました！！！ありがとうございました。

#2020/12/23追記

いいねの数が多い順に記事を表示する実装はできましたが、記事ごとに「第１位」などの表示ができたらと思い、追加実装しました。

```ruby:app/views/articles/_ranking_article.html.erb
<% @ranks.each.with_index(1) do |article, i| %>
    <div class="card-group col-md-6 col-lg-3">
      <span class="article-info"><i class="fas fa-crown"></i> 第<%= i %>位</span>
```

順位を表示するには、「.with_index(1)」を使用すること順位を表示できました。

https://docs.ruby-lang.org/ja/latest/method/Enumerator/i/with_index.html

参考URLです！