OmniAICreator/Qiita-1.07M huggingface dataset:
Linebotで投票システム作ってみた

# はじめに
８年ほど使用した自作PCが壊れたので、買い替えマシンを検討した結果MacBookがコスパ良さそうということでMacを購入。
折角なのでSwift勉強してみようかなと思ったけれどもバックグラウンドおじさんの自分にはいきなりアプリ開発は難易度が高い気がしたので知見のあるLINE Botと組み合わせて言語学習を行おうと思い、
iOSアプリ開発言語のSwiftでサーバーサイド処理を行えるフレームワーク"vapor"を使用してLine Botを作成してみました。

# 題材
高校の部活のOB会の幹事をやっているが、そろそろ代替わりしたいので
新しい幹事を決める投票Botを作成しました。

# 開発環境
|          | ver|
| --- | --- |
| OS | macOS Catalina |
| Xcode | 11.3 |
| Swift | 5.1.3 |
| vapor | 3.0.0 |

# LineBot作成
Linebotの作成方法はこちらに記載しています。
- [LINE Botで結婚式をペーパーレス化してみた](https://qiita.com/nishikori223/items/fda9db5b3da6919e9db5)
※余裕があればLineBot作成だけまとめた記事起こして置き換えます。

# Vapor
Vaporの実行環境作成はこちらに記載しています。

- [ServerSideSwift Vapor3.0をHerokuにデプロイ](https://qiita.com/nishikori223/items/dacfcd59cd8c57f8465e)

# リッチメニュー
今回は実行トリガーにリッチメニューを使用します。
機能として投票を行うだけなので、メニュー全画面で１ボタンとし、
ボタンに設定した文言を受け取ったら、候補者一覧をリプライするようにしました。
<img width="1107" alt="スクリーンショット 2020-06-17 0.19.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539781/7fa0a25b-0186-2242-17cc-8ab428cb3401.png">

# Flex Message
今回候補者は３０名前後となる為、候補者一覧はFlex Messageを使用して投票ボタンも兼ねる形にしました。
他メッセージタイプと違って扱える配列の最大数があり、一度のリプライで表示したい情報が制限されますが、
Flex MessageはCSS Flexible Boxを使ってメッセージのレイアウトと挙動を定義でき、
大量のコンテンツを送りたい場合に非常に役立ちます。
また、今回は投票という性質上そのまま投票トリガーのボタンとして扱うのに適していました。

<img width="250" alt="overviewSample.772a618f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453265/33757997-06fd-ca43-8f66-7b30343038b0.png">

公式にシミュレータもあるので、初めて触ってもある程度のものは難なく作成できました。
[Flex Message Simulator](https://developers.line.biz/flex-simulator/?status=success)

# 実行結果
![s8lo0-49ill.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453265/6c8bd1e3-88e2-8353-4991-d016bb3281e2.gif)

# 投票集計
今回はGoogle Apps Scriptを使用し、スプレッドシートに記録する形としました。
LineId(A列)と投票した候補者番号(B列)を記録します。
再度別な候補者を選んだ場合は、LineIdをキーに検索し候補者番号を上書き、
初投票なら最後尾に行を追加するようにしています。
投票回数をカウントしているのは無闇に連打する輩が現れないかチェックする為念のため・・・
私がLineIdでユーザプロフィールを取得しなければ(一応)匿名投票となります。
<img width="321" alt="スクリーンショット 2020-06-17 0.41.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539781/bd3abdca-63cc-05ca-c834-b65f3a6f681d.png">

# おまけ機能
Linebotを友達追加さえして貰えれば手間なく投票できるのですが、
友達追加することなくスルーする人がそこそこいるだろうなと予想し、
とりあえず追加してみようと気が起きるおまけ機能を実装しました。
<img width="344" alt="スクリーンショット 2020-06-17 0.55.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539781/6ac205a5-4960-9213-56ed-078a13efa5a2.png">
[PokeAPI](https://pokeapi.co/)を使用して図鑑番号に対応するポケモンの情報を返すようにしました。
金曜ロードSHOW！で名探偵ピカチュウが終わりかけを目掛けてLinebotのお知らせを流したところ、たくさん遊ばれて狙い通りでした。

# おわりに
新年会でそろそろ幹事代わってくれる人いませんかーと呼び掛けても誰もいない中（当たり前だけども)
Linebotという方法で投票者はほんの数秒で終わる方法での匿名投票だったので、
特に文句も出ず幹事交代出来たので今年からは気兼ねなく飲み会だけ参加できそうです。
Power Apps One Drive の Excel をソースとしたギャラリーが表示されない

備忘録として；
＜問題＞
One Drive に保存したExcel のテーブルをデータとしてPower Apps でGalleryを作成したが、テーブルの内容が表示されない。

＜原因＞
Excel のテーブルの中に計算式が入っていた。

＜解決策＞
Excel のテーブルの値を全て値で貼り付け直した。

ハマり時間　＝　2時間
中間テーブル実装後にカテゴリ別ページを表示

以前に多対多テーブルでカテゴリ機能を実装したのですが、カテゴリ別ページを制作するにあたって苦労したので記録します。

# 仕様
こちらの記事を参考にいたしました。
https://qiita.com/cawaz3/items/e755a58177212f2aca6c
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652092/8409f055-7fb8-83a8-2995-c1937bd70d02.png)

# 実現したいこと
カテゴリタグをクリックした際にカテゴリ別ページを開き、そのカテゴリが紐付けられた投稿一覧を表示する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652092/30ff25ba-576e-979b-1394-fbeff407b24d.png)
↑こちらのタグをクリックし投稿一覧を表示する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652092/c795b51d-6648-7890-2bb8-ee64386d8516.png)
↑こんな感じ

# コード
```ruby:posts.controller.rb
def category
    @category = Category.find(params[:id]) ここでクリックしたカテゴリIDを取得
    @post = Post.includes(:categories).where(post_category_relations: { category_id: @category })
end
```
whereで中間テーブルのカテゴリIDと合致するpostIDを取得しています。

```ruby:category.html.slim
.contents
  .card_header
    .card_header_title
      span.orange #&nbsp;
      = @category.name　カテゴリ名を取得し表示
  .card_contents
    - @post.each do |post|　　取得した投稿をeachにて繰り返し表示
      .card_item
        = link_to(post_path(post)) do
          = image_tag post.post_photo.url

```

取得したpostをviewにて表示

#includesとは
Railsのincludesは、関連している複数のテーブルからデータを取得してくるときのアクセス回数を大きく減らすことができるメソッドです。

また、事前に検索やフィルタリング、ソートなどをしたデータを取得することもできるため、アプリケーション側でそれらの処理を行う必要がなくなります。そのため、シンプルで効率的なプログラムになリマス。

N+1問題等で調べると色々出てくると思います。

#関連コード
```ruby:routes.rb
 get 'posts/category/:id', to: 'posts#category'
```
ファイル階層はview/posts/category.html.slim
ViewModel と変更通知プロパティ（ReactiveProperty）

## はじめに

オレオレ解釈の覚え書き　その１０

変更通知プロパティの話から派生して、強力なライブラリである ReactiveProperty についてご紹介します。

## 本文

前回ご紹介した変更通知プロパティは、View 側のバインドは楽ですが、値の変更通知はそれぞれのプロパティが自ら行う必要がありました。値の変更に合わせて処理を切り替える場合は、ViewModel 内で PropertyChanged のイベントを捉えて、どのプロパティが変更されたのかを判断する必要があるため、複数のプロパティが関わるようになれば途端に管理が難しくなります。

変更通知や処理への橋渡しを ReactiveProperty は自動で行ってくれます。下記は ReactiveProperty による変更通知プロパティとそれを利用するコマンドの実装例です。[名前] にバインドされた "Name" が変更通知プロパティです。[ゲスト] ボタンは常に活性な "GuestCommand" に、[登録] ボタンは [名前] に値が設定されているときだけ活性化する "SubmitCommand" にバインドされています。ここでの「活性」「非活性」とはコマンドに紐づく処理（WithSubscribe 内の処理）が実行可能かどうかだけでなく、ボタンの Enabled の状態まで制御されます。

```cs:ViewModel
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;

namespace TestApp.ViewModels
{
    public class MainWindowViewModel : IDisposable
    {
        private CompositeDisposable _disposable;

        public ReactiveProperty<string> Name { get; }
        public ReactiveCommand GuestCommand { get; }
        public ReactiveCommand SubmitCommand { get; }

        public MainWindowViewModel()
        {
            this._disposable = new CompositeDisposable();

            this.Name = new ReactiveProperty<string>()
                .AddTo(this._disposable);

            this.GuestCommand = new ReactiveCommand()
                .WithSubscribe(() => this.Name.Value = "Guest")
                .AddTo(this._disposable);

            this.SubmitCommand = this.Name
                .IsEmpty()
                .Inverse()
                .ToReactiveCommand()
                .WithSubscribe(() => this.ShowMessage(this.Name.Value))
                .AddTo(this._disposable);
        }

        public void Dispose()
        {
            this._disposable.Dispose();
        }

        private void ShowMessage(string text)
        {
            // メッセージを表示する
        }
    }
}
```

```xml:View
<Window x:Class="TestApp.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:p="http://prismlibrary.com/"
        p:ViewModelLocator.AutoWireViewModel="True">
    <StackPanel>
        <TextBox x:Name="名前"   Text="{Binding Text.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        <Button  x:Name="ゲスト" Command="{Binding GuestCommand, Mode=OneTime}"/>
        <Button  x:Name="登録"   Command="{Binding SubmitCommand, Mode=OneTime}"/>
    </StackPanel>
</Window>
```

注意が必要な点として、ReqctiveProperty とバインドする場合、内包された値にアクセスするため ".Value" の記載が必要になります。（ReqctiveCommand は ICommand の実装であるためこの記載は不要です。）

## おわりに

ReactiveProperty は neuecc さんが作成し、現在は okazuki さんによってメンテナンスされています。ライブラリの使い方はブログ等で大変分かりやすくまとめて頂いているため、より詳しい情報は是非開発者様のページをご覧ください。
・[ReactiveProperty : Rx + MVVMへの試み](http://neue.cc/2011/08/26_341.html)
・[MVVMをリアクティブプログラミングで快適にReactivePropertyオーバービュー](https://blog.okazuki.jp/entry/2015/12/05/221154)
・[ReactiveProperty v7.0.0 をリリースしました](https://qiita.com/okazuki/items/be42d2ef361d45209f0a)

次回は依存関係プロパティについてまとめます。
Windows10でWSLを無効化してVirtual Box + Vagrantが動作するように戻したメモ

## 概要

[前回](https://qiita.com/hibohiboo/items/f40cdb0d96cd9a15ff2b)でWSL2+Docker Desktopを試した。
既存のVirtual Box + Dockerと有意な違いを見ることが出来なかったので、既存の環境を立ち上げようとしたところ、
ssh設定のところでVagrantがtimeoutしてしまうようになった。
ので、WSL2をやめて既存の環境に戻す。

## 環境

* Windows10 バージョン2004(OS ビルド 19041.329)
* virtualbox v6.1.10
* vagrant v2.2.9
* Docker Desktop 2.3.1.0-edge

## Docker Desktopのアンインストール

[chocolatey docker desktop](https://chocolatey.org/packages/docker-desktop#uninstall)に従い、以下のコマンドをPowerShell（管理者）から実行。

```ps
choco uninstall docker-desktop --pre -y
```

## WSLの無効化

`Windows ロゴ キー + Rキー`でファイル名を指定して実行を立ち上げ、`optionalfeatures`と入力してOKを押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/4ddce23f-6cb5-4aa0-30f0-09365df32840.png)

`Linux用Windowsサブシステム`と`仮想マシンプラットフォーム`のチェックを外す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/034a93e6-0d1e-a5a4-8770-5ed48e965e65.png)

再起動すると、Virtual Boxが使用できる状態に復活した。

## 参考
[Windows10上のVirtualBoxがエラー吐いた時の備忘録](https://qiita.com/reef1217/items/e760b6e4078dedc0b434)
[WSL2とHyper-Vの関係](https://qiita.com/matarillo/items/ca1eecf8f9a3cd76f9ce)
[win10 tips](https://qiita.com/rubytomato@github/items/fefbfbb4f6212f1a2644)
【Rails】saveメソッドしたら、created_atの時間がずれたを解決する方法

#【Rails】saveメソッドしたら、created_atの時間がずれたを解決する方法
##どんな人向け
saveメソッドでDBを更新したが、created_at列、updated_at列の時間が今の時間と一致しない人向け

##実行環境
ruby 2.4.10
Rails 5.2.4.3,

##結論（原因）
railsの時刻設定がグリニッジ標準時になっている
config/application.rbから、タイムゾーンを設定することで、日本標準時に変更できる。

```Ruby:application.rb
module SampleApp
  class Application < Rails::Application
    config.time_zone = "Tokyo"
  end
end
```
##大まかな設定方法
①application.rbにタイムゾーン設定を追加
②railsコンソール再起動
③time.currentメソッドでタイムゾーン設定が適用されていることを確認

##具体的な設定方法
①application.rbにタイムゾーン設定を追加
config/application.rbを開いて、「config.time_zone = "Tokyo"」を追記

```Ruby:application.rb
module SampleApp
  class Application < Rails::Application
    config.time_zone = "Tokyo"
  end
end
```

②railsコンソールを起動

```
$ rails console
```

③time.currentメソッドでタイムゾーン設定が適用されていることを確認

```ruby
irb(main):003:0> Time.current => Wed, 17 Jun 2020 00:11:56 JST +09:00
```
Rails 6+Webpacker で Yarn, Node.js 環境をHerokuでもMacでも同じにする

Rails 6+Webpacker開発環境をJS強者ががっつりセットアップしてみた（翻訳）
https://techracho.bpsinc.jp/hachi8833/2019_11_28/83678

のなかの「再現可能な環境: Node.jsとYarn編」。


### .nvmrc
nvmを使用してNode.jsのversionを管理する
https://ikkyu.hateblo.jp/entry/2019/05/03/003636



### .yarnrc
```bash
$ yarn policies set-version 1.22.4
```

### package.json 
```js
  },
  "engines": {
    "node": "13.13.0",
    "yarn": "1.22.4"
  }
}
```

## 依存関係の自動Update
> JavaScriptやRubyの依存関係の自動アップデートについては、Renovateを一度チェックしてみることをおすすめします。

### Renovate
GitHub に無料で追加できた。
また、設定してすぐ `renovate/configure` ブランチからPRがきた。


Renovate ではじめる依存関係更新の自動化
https://engineer.recruit-lifestyle.co.jp/techblog/2019-12-10-renovate/

Renovateによるnpmパッケージ定期更新
https://user-first.ikyu.co.jp/entry/2018/05/07/193755

フロントエンド開発でパッケージのアップデートを継続的におこなう - Renovate
https://qiita.com/kasaharu/items/1af74b49e98658cf9a8e
オブジェクトから必要なキーを残す/不必要なキーを除く

TypeScriptのType aliasesはオブジェクトがその `key, property` を持っていることを証明するだけで、それ以外を持っていないことを証明しません

たとえば、以下のような例を考えます

```typescript
type UserInfo = Readonly<{
  account: string;
  email: string;
  password: string;
}>;
```

このType aliasesの具体例として以下を考えます。

```typescript
const user: UserInfo = {
  account: 'axolotl',
  email: 'axolotl@popocatepetl.com',
  password: 'axolotlAXOLOTL'
};
```

`user` を、 `UserInfo` に部分的に合致する以下のType aliasesに代入します

```typescript
type UserForLogging = Readonly<{
  account: string;
  email: string;
}>;
```

ちなみにこの `UserForLogging` は以下でも同じです

```typescript
type UserForLogging = Omit<UserInfo, 'password'>;
```

代入しますー

```typescript
const forLogging: UserForLogging = user;
```

ですが、この `forLogging` を表示させてみると、 `password` が出てしまいます。

```typescript
// will display password!!!! SHIT!!!
console.log(forLogging);
// { account: "axolotl", email: "axolotl@popocatepetl.com", password: "axolotlAXOLOTL" }
```

これでは情報がモレモレで会社はタジタジです。

そこで、このようなときに必要な `key, property` のみを新しいオブジェクトにして返却するモノをつくりました。

```typescript
const remain = <T>(obj: T, ...keys: Array<keyof T>): Partial<T> => {
  const newObj: Partial<T> = {};
  
  keys.forEach((key: keyof T) => {
    newObj[key] = obj[key];
  });

  return newObj;
};
```

使用例

```typescript
console.log(remain<UserForLogging>(user, 'account', 'email'));
// { account: "axolotl", email: "axolotl@popocatepetl.com" }
console.log(remain<UserForLogging>(user));
// {}
```

逆も作りました

```typescript
const eliminate = <T>(obj: T, ...keys: Array<keyof T>): Partial<T> => {
  const newObj: Partial<T> = {};

  const ks: Array<keyof T> = Object.keys(obj) as Array<keyof T>;
  
  ks.forEach((key: keyof T) => {
    if (!keys.includes(key)) {
      newObj[key] = obj[key];
    }
  });

  return newObj;
};
```

使用例

```typescript
console.log(eliminate<UserForLogging>(user, 'account', 'email'));
// { password: "axolotlAXOLOTL" }
console.log(eliminate<UserForLogging>(user));
// { account: "axolotl", email: "axolotl@popocatepetl.com", password: "axolotlAXOLOTL" }
```

どちらも `<T>` のGenericがあるおかげで第2引数以降のRest parametersにそのオブジェクトが持っていない `key` を指定するとTypeScriptから指摘がでます。これはいい！

```typescript
console.log(remain<UserForLogging>(user, 'bankAccount'));
// -> Argument of type '"bankAccount"' is not assignable to parameter of type '"account" | "email"'.
console.log(eliminate<UserForLogging>(user, 'bankAccount'));
// -> Argument of type '"bankAccount"' is not assignable to parameter of type '"account" | "email"'.
```

`delete` 使えっていうかた、正論！
Go言語でキャメルケースをスネークケースに変換する

こんばんは、ねじねじおです。

埃をかぶっていたMacBook Proに、VS Codeを入れました。
Go言語でキャメルケースをスネークケースに変換してみます。

```Go
import "strings"

func CamelToSnake(s string) string {
	if s == "" {
		return s
	}

	delimiter := "_"
	sLen := len(s)
	var snake string
	for i, current := range s {
		if i > 0 && i+1 < sLen {
			if current >= 'A' && current <= 'Z' {
				next := s[i+1]
				prev := s[i-1]
				if (next >= 'a' && next <= 'z') || (prev >= 'a' && prev <= 'z') {
					snake += delimiter
				}
			}
		}
		snake += string(current)
	}

	snake = strings.ToLower(snake)
	return snake
}
```

テストも書く。

```Go
import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestExampleSuccess(t *testing.T) {
	tests := []struct {
		in       string
		expected string
	}{
		{"RememberMe", "remember_me"},
		{"requestID", "request_id"},
		{"HTTPRequest", "http_request"},
		{"HTML5Script", "html5_script"},
	}

	for _, test := range tests {
		res := CamelToSnake(test.in)
		assert.Equal(t, test.expected, res)
	}
}
```

OK。
ねじねじおでした。
CodePen - やっつけな方法で7セグ数字認識（ライブラリレス）

思いついたら作らざるをえなかった。。
行列で重みづけして、教師替わりの7セグ配列データとの比較をして、符号とのハミング距離が最短なものを結果として採用する。
解説もやっつけな件・・・

<p class="codepen" data-height="500" data-theme-id="light" data-default-tab="js,result" data-user="kob58im" data-slug-hash="VweKqwa" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Guess A Digit">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/VweKqwa">
  Guess A Digit</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

ゼロを入れ忘れてる。。
gdalツールを使って shape ファイルのポリゴンを色々と加工してみる。

gdalツールを使って shape ファイルに含まれるポリゴンデータを加工してみる。

## 国土地理情報から都道府県ポリゴンをダウンロード

国土地理情報のダウンロードページから、自分の好きな地域のデータをダウンロードする。

https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03-v2_3.html

ZIPファイルを展開すると、xml や geojson なども入ってるけど、今回は .shp の拡張子がついた shape ファイルを扱う。

## ogr2ogr を使って座標参照系を変換

gdal は大きくラスター向けツールとベクター向けツールに別れており、ベクターデータである shape ファイルは ベクター向けツールの `ogr2ogr` を使う。

ダウンロードした shape ファイルは JGD_2011 の座標参照系で定義されてる。

QGISなどで shape ファイルを開くと横に間伸びしてる感じ。

![スクリーンショット 2020-06-16 23.42.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/da03cc1d-677b-668b-0058-b8f00ac4037a.png)

なので `ogr2ogr` を使って座標参照系を Web メルカトル (EPSG:3857) に変換してみる。

```
$ ogr2ogr -f "ESRI Shapefile" -t_srs EPSG:3857 output_3857.shp N03-19_01_190101.shp
```

コマンドによって生成された `output_3857.shp` ファイルを開くと、座標参照系 が JGD_2011 の時よりシュッとした絵が出てくる。

![スクリーンショット 2020-06-16 23.49.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/7c7e2e1f-119a-eba1-0082-e86906f48c7c.png)


## 市町村境界を ogr2ogr で消しちゃう

国土地理情報からダウンロードした shape ファイルのポリゴンデータには、市町村境界線も含まレている。今回、市町村境界線は使わないので、海岸線だけにしたい。

こういった場合も `ogr2ogr` を使うことができる。データを加工するための SQL をオプション引数に指定することで、output_3857.shp が持っている細かいポリゴンをまとめることができる。

```
$ ogr2ogr output_sealine.shp output_3857.shp -dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry FROM output_3857" 
```

ポリゴンの数が多いとそれなりに処理時間がかかる。

処理が完了し `output_sealine.shp` を開くと、こんな感じの絵が出てくる。

![スクリーンショット 2020-06-16 23.52.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/4a8d0a89-5f46-dbed-1f73-683d6095e3db.png)

ということで ogr2ogr ツールだけで shape ファイルのポリゴンを色々加工することができた。
Windows 10「ファイル名を指定して実行」でよく使うコマンド

タイトルの通りです。Windows 10 (バージョン1909)で確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51871/bb340201-3850-af70-48d2-86c841bdd008.png)

|#|コマンド|  |
|:--:|:--|:--|
|1| cmd | コマンドプロンプト |
|2|cmd|（「cmd」と入力後、Ctrl + Shift + Enterで）管理者として実行|
|3|notepad|メモ帳|
|4|calc|電卓くん|
|5|mspaint|クソペイント野郎|
|6|mstsc|リモートデスクトップ接続|
|7|control|コントロールパネル|
|8|ms-settings:windowsupdate|Windows Update|
|9|msinfo32|システム情報|
|10|winver|バージョン情報|
|11|appwiz.cpl|プログラムと機能|
|12|regedt32|レジストリ|
|13|regedit|レジストリ|
|14|firewall.cpl|ファイアウォール|
|15|ncpa.cpl|ネットワーク接続|
|16|shell:sendto|「送る」フォルダ|
|17|shell:startup|「スタートアップ」フォルダ|
|18|perfmon|パフォーマンスモニタ|
|19|perfmon /report|パフォーマンスモニタ（レポート）|
|20|inetcpl.cpl|インターネットオプション|
|21|services.msc|サービス|
|22|control schedtasks|タスクスケジューラー|
|23|taskmgr|タスクマネージャー|
|24|control /name Microsoft.CredentialManager|資格情報マネージャー|

# 応用
```:hostsファイルを管理者権限で開く
notepad %WINDIR%\system32\drivers\etc\hosts
# 上を入力後、[Ctrl]+[Shift]+[Enter]
```

# エイリアス
上のリスト、覚えづらいことが分かったので、バッチファイルを作りました。
https://github.com/yz2cm/WinUtil.git

## 使い方
1. `git clone https://github.com/yz2cm/WinUtil.git`
2.  1のバッチファイルを任意の場所にコピーする。
3. `sysdm.cpl`を実行して「システムのプロパティ」を開き、2の場所にパスを通す。
4. ファイル名を指定して実行から、エイリアスを叩く（例：`wu`を叩くと「Windows Update」が開きます）。

# 余談
関係ないけど、ペイントのこれ↓の違いを最近はじめて知った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51871/807d73b4-1b33-cd43-ae54-0a4df06c145b.png)
左がペンの色や図形の輪郭線の色、右が塗りつぶしの色、らしいです。そうだったのかー！
Formatter autopep8 is not installed. Install? の解決

# 起きてた問題
VScodeでpythonファイルのlint&formattingの設定をしたかった。
`python vscode lint`などと検索すると[このような記事](https://qiita.com/psychoroid/items/2c2acc06c900d2c0c8cb)に引っかかって、とりあえず書かれるがまま以下のコードを`setting.json`にそのままコピペしました。

```json:setting.json
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"python.linting.lintOnSave": true,
"python.formatting.provider": "autopep8",
"editor.formatOnSave": true
```

これで何となく保存時に整形を走らせてくれそうだと期待し、保存を試みたところ、VScodeから以下の警告が。
<img width="1120" alt="スクリーンショット 2020-06-16 23.52.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326593/b736076d-3dcf-d609-23ee-501357281efa.png">


`Formatter autopep8 is not installed. Install?`
というので、そのままYesを押したり、`pip install autopep8`でグローバルにautopep8をインストールしてみたり、パッケージマネージャとしてPoetryを使っている弊プロジェクトの`pyproject.toml`に`autopep8`を書き下したりしても警告は消えず保存時整形はされずで少々難儀していました

# 解決手順
自分のケースでは以下のコードを追記することで解決しました

```json:setting.json
"python.formatting.autopep8Path": "/Users/USERNAME/.pyenv/shims/autopep8"
```

formatting.providerとして走ってくれる`autopep8`のPathを教えてあげる必要があったみたいです。
`autopep8`のPathは（インストールされていれば）以下の手順で出力できます

```bash

$ which autopep8
$ pyenv which autopep8 #pyenvを使っている場合はこっち
```

# 参考
https://github.com/microsoft/vscode-python/issues/6495
https://gist.github.com/Tinitto/8d9f9638ff54e0a8351e4ba2d8a37441
すごい雑に特定フォルダにファイルが出現したらアラームを鳴らす

すごい雑。とりあえずテストで生成される巨大なログファイルの生成を待っている間席を外したい場合など。

ファイルが出力されるはずのフォルダに移動して、以下のコマンドを入力(ワンライナーなのでコピペでOK)

```powershell
 while($True){ if((dir ./*.*).Length -ne 0){C:\Windows\Media\Alarm01.wav; break} sleep 1 }
```

wavファイルにはあらかじめなんらかのプレイヤーが関連付けられている必要がある。なにかメディアプレイヤーをインストール/アンインストールしたあとは関連付けが外れている場合があるので注意する。

出力されるファイルの個数が決まっている場合は`(dir ./*.*).Length -ne 0`の数式を適当に変更すればヨシ。

以下にもアップしました。

* [ファイルが出力されたらアラームを鳴らす](https://gist.github.com/TakamiChie/5e0fcd51ad84e47fc23d45a876bad47a)
無料プログラミングスクール 何を学べるのか？

この記事は、僕が元々無料プログラミングスクールの卒業生なので、内容は事実しかありません。
無料プログラミングスクールを検討されている方、あるいはへぇそんなのあるんだっていう風にビジネスモデルとして見ておきたい方は是非一読を。

テンポ悪いかもですが、僕のその時の状況だったり、学んだ事は小出しに書いていくので読みづらかったらすみません…
最後に学んだ事は、まとめておきます。何が学べるんだよって人は「まとめ」の部分に飛んで読んでね。

## きっかけ
僕が無料プログラミングスクールに行こうと思ったきっかけは、「エンジニアとして就職出来なかったから」でした。
当時20歳で、とある体力系の仕事をしてまして、その職業からの転職という事でした。
その時はブラインドタッチを出来るようになったぐらいで、Progateを学びつつ、HTMLとCSSの本を勉強しているって感じでした。
そんな状態で就職活動してたんですが、「勉強してます」「頑張るので、開発したいです」と言っても全然信じてもらえなかったです…
なので方針を変えて、もう少し技術をつけて証明出来るようになってから就職活動しようというふうにしました。
HTMLやCSSは勉強していたんですが、プログラミングのことはまだ学べてなくてどう学んだら良いかさえも分からない状態で本を買うも全く分からずでした…
そんな時に見つけたのが、無料プログラミングスクールでした。体験があったので、行ったら良さそうだったので、通うことにしました。

## なぜ無料なのか
プログラミングスクールはどこも高額なのが印象的です。
そんな中、なぜ無料で運営できているか、このプログラミングスクールはプログラミングを教えた生徒を別の会社さんへ紹介しているからです。その紹介したお礼として企業から何十万という報酬をそのプログラミングスクールが受け取る事で成り立っています。
いわゆる人材紹介と同じような感じで、「育てて、紹介する」を繰り返しているんです。

後々、自分の懐から持っていかれる訳でもないので安心だなと当時の僕は思ったのを覚えてます。
その会社自体、新入社員研修で色々な会社のエンジニアに教えている実績もあるところだったので、そこも決め手でした。

## 学習体制
学習体制としては、とある学習スペースに行って、学習教材を自分のペースで進めていくという形式で、そこにはメンターが2人ほど居るのでそのメンターに分からない所は質問するという感じでした。
週3〜5が目安で、総学習推定時間は60日という学習スケジュールでした。
でもバイトしないとやばかったし、交通費は実費だったので、行く頻度は週に1,2回しか行っていませんでした。
それでも1.5ヶ月目には大体の課題が終了したって感じでした。(出席数12日くらい)

プログラミングはチームで開発する事も多いですが、このプログラミングスクールでは個人で進めていくので、チームではどうやっていくのかっていうのは、実感が湧かない感じでした。

ちなみにパソコンは自分のでも良いし、借りる事も出来るって感じです。
僕は何故かMacBookProを買っていたので、それ使いました

## 学習する事
学び方としては、スライドの解説を読んで、その後問題を解いていくという感じで、最後の方は自分でプログラムを書いていく感じでした。

最初は、IT用語の解説がザーッとありました。たぶん何だこれって意味不明に読み進めた気がします。
そしてここからメインのJavaの勉強です。まずはEclipseという開発環境のインストールからでした。Javaの文字出力や変数、型を学び、文法系を学んでいきました。
当時、自分のやり方で良かったなって思ったのは、直ぐにメンターに質問せずにどう分からないのか説明出来るようになってから質問する、メンターの手が空いていない時は先に出来る所からやって、後で分からない所をまとめて質問するっていう風にしてました。← これ結構良かったです。

そしてJavaを一通り勉強し終わったら、次にJSPの勉強が始まりました。コンソールへ表示するしかやって来なかった訳ですが、今度はHTMLのようにWebページとして表示していくという感じの事を学ぶ訳です。
これが結構辛かったです。

そして、SQLの勉強が始まりました。といっても、半日で終わる程度しか触れられませんでしたが。
簡単じゃん。おもろいじゃん。ってなりましたが、就職してからそれは痛い目を見ることに...

そこから、Javaを使ったECサイトの構築を勉強し、自分のアイデアで作るECサイトを作っていくという課題をクリアして、就職活動をしていったという流れになります。
僕が作ったのは、音楽が好きなので、CD販売ECサイトを作りました。デザインも拘ってウケが良かったです。
ちなみにECサイトだけど、決済の機能とかは導入してないです。管理画面で商品追加・変更・削除ができたり、お客様が見る方の画面でカートに入れたりできる程度のものです。(フレームワークを使ってないです。)
就職活動では、メンターとは別に担当の人がいて、サポートしてくれます。
自分がこんな会社が良いですと予め言ったことをある程度叶えてくれた企業を紹介して下さって、その企業に面接しにいきました。
担当の人が、これまでの学習態度を評価してくれてそれを面接前に企業が受け取っているので、面接は結構すんなりです。

無事僕は就職ができてスクールを卒業することとなりました。

## まとめ
無料プログラミングスクールで学んだ事は下記の事です。

- Java
- GitHub
- Bootstrap
- MySQL
- JavaとMySQLを使っての自作Webサービス作り
- 就職対策

就職してから苦労した事は、フレームワークを使っての開発が普通だと思いますがそれを使った事がなかったので、最初はそれの理解に戸惑いました。それからSQLが半日程度しか学んでいなかったので、えげつないくらい苦労しました。スクールでチーム開発ができなかったので、Gitがうまく使えないなーって感じでした。(そのスクールでは今では、有志でチーム開発も取り入れているらしいです。)

みんな誰しも苦労するものなので、今となっては良い経験でした。

この記事が良いと思った方は、LGTMをしていただければ嬉しいです！
フォローも是非お願い致します(^^)
ゼロから始めるLeetCode Day58 「20. Valid Parentheses」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day57 「35. Search Insert Position」](https://qiita.com/KueharX/items/a3ba02d7a9c29136537b)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

# 問題
[20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/)
難易度はEasy。

問題としては文字 '(', ')', '{', '}', '[' および ']' だけを含む文字列`s`が与えられた場合、入力された文字列が有効かどうかを判断します。

入力文字列は、以下のような場合に有効です。

開いているカッコは、同じ種類のカッコで閉じなければなりません。
カッコは正しい順序で閉じなければなりません。
空の文字列も有効とみなされることに注意してください。

>Input: "()"
Output: true

>Input: "()[]{}"
Output: true

>Input: "(]"
Output: false

>Input: "([)]"
Output: false

>Input: "{[]}"
Output: true

# 解法

例を見ればわかりますが、括弧の中で別に括弧が完結すれば`True`になり得ますが、そうでない場合ならば`False`になる、といった風になります。

始まりと終わりをきっちり確認できれば良い、ということはスタックを使うと管理しやすいかなと思います。

例えば、`Input: "{[]}"`の場合で考えてみましょう。
for文を使って`char`へと`s`を代入し、前から読み取っていきます。
すると読み込まれる文字の順は`'{','[',']','}'`となります。

それをif文できちんと括弧が正しい順番で閉じられているかをチェックしなければなりません。

そのために、チェックするための括弧の集合を自前で用意してあげる必要があります。

ここではリストか辞書で管理するのが一般的かなと思います。

仮に括弧の要素をリストで管理した場合だと

`open_str = ["[","{","("]  
close_str = ["]","}",")"] 
`

こんな感じになり、
辞書で管理するなら
`dict = {")":"(","]":"[","}":"{"}
`

こういった感じになるでしょう。
今回僕は辞書の方を使いました。

さて、ここまでくればあとはfor文で回した際に`dict`の中に`char`要素が存在した場合、存在しなかった場合の処理を書けばよくなります。
仮に要素が`dict.values`の中に存在したときはどうすれば良いでしょう。
その場合は用意した`stack`へと追加してあげると良いでしょう。

stackの性質は皆さんご存知の通りLIFO(Last in first out)ですから、最後から取り出していくスタックは今回のようなケースの場合、都合が良いのです。

では、次に`char`が`dict.keys`に存在する場合、そして最後にそれ以外の場合はどういった処理を行えば良いのか、ということになります。

その場合は新たに以下のような処理で書きました。

```Python
if stack == [] or dict[char] != stack.pop():
    return False
```

こうした場合、この内のどちらかに該当した場合`False`
を返します。
逆に言えば、これに該当しなければ処理は続きます。

そして、今まで書いたどの条件にも一致しない場合も`False`を返します。

これらをまとめて書いた内容が以下のようになります。

```python
class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        dict = {")":"(","]":"[","}":"{"}
        for char in s:
            if char in dict.values():
                stack.append(char)
            elif char in dict.keys():
                if stack == [] or dict[char] != stack.pop():
                    return False
            else:
                return False
        return stack == []
# Runtime: 36 ms, faster than 30.47% of Python3 online submissions for Valid Parentheses.
# Memory Usage: 13.8 MB, less than 77.84% of Python3 online submissions for Valid Parentheses.
```


思ったより解法パートが長くなってしまいました・・・
もっとスパッと書いた方が読む側としては楽かもしれませんね。色々読み手の側も考えながら書いていきたいと思います。

話変わりますが最近アルゴリズムやデータ構造に限らずCSについて学んでいるのですが興味があるジャンルについて勉強するのは楽しいですね！

では今回はここまで。
お疲れ様でした。
AtCoder Beginner Contest 170 A,B,Cまでをrubyで

##A問題

```ruby:abc170a.rb
xi = gets.chomp.split(" ").map!{|item| item.to_i}
for i in 1..5 do
    if xi[i-1] == 0
    print(i )
    end
end
```
##B問題

```ruby:abc170.rb
xi = gets.chomp.split(" ").map!{|item| item.to_i}
 
for f in 0..xi[0]
    if xi[1] == (f*2) + (xi[0]-f)*4
        puts "Yes"
        exit
    end
end
puts "No"
```
片方０のときを忘れてループを１から回してしまい一度wa

##C問題

```ruby:abc170.rb
x,n = gets.chomp.split(" ").map!{|item| item.to_i}
p = gets.chomp.split(" ").map!{|item| item.to_i}
p.sort!
if n == 0
    puts x
    exit
end

y = p.max+1
for i in 0..p.max+1 do
    if y > (x-i).abs
        if p.include?(i)
        else
        y = (x-i).abs
        a = i
        end
    end
end
puts a
```
yの初期値をpの最大値+1せずに回すと1 1 1の時waに気づけず、時間内に解けず。
文面通りに実装するより、差が０から１づつ増やしていき、配列中に含まれるか？を確認する方がコードとして単純ですね。
CTFにハマりかけの私が，どのようにCTFを説明をするのか

#前枠
LTで，CTFについて布教（するほどでもないかもしれないが）するつもりなので，原稿的なものを投稿しようと思います．

間違っている部分もあるかと思いますので，指摘・コメントいただけるとありがたいです．

#CTFを知ったきっかけ
https://kinako-mochimochi.hatenablog.com/entry/2019/02/20/131937
こちらの記事を読ませていただき，興味を持ち，問題に取り組んでいます．

#あなたがCTFに取り組むまで
- CTFってなに
- どんなコンテストがあるの
- どんな出題分野があるの
- 何から取り組めばいいのか

→CTFがやりたくなる（ようなLTを目指す）

#CTFってなに
「Capture The Flag」の略称．
与えられた問題を解いたり，与えられたデータから，答えとなる ”Flag” を導き出します．

暗号が与えられてそれを解いたり，ハッシュ化されたデータを元に戻したり．パケットキャプチャデータから掘り出したり…

個人的には，「謎解きゲーム」のような面白さ・魅力を感じます．

「攻防戦形式」という「取ってきたFlagを，他のプレイヤーから守るために防御を固める」という形式や，「クイズ形式」なるものもあるらしいですが，詳しいことがまだわからないので，説明はしません…．


#どんな出題分野があるの
まだCTFそのものが理解できてないので， [CpawCTFの分け方](http://sandbox.spica.bz/cpaw_ctf/about_ctf.html)を引用させていただきます．

- Web
- Crypto
- Reversing
- Pwn
- Forensic
- Network
- PPC
- Steganography
- Recon
- Trivia
- Misc(その他)

##Web
Webの脆弱性をついてFlagを手に入れます．
XSS：クロスサイトスクリプティング，SQLi：SQLインジェクションを利用したり，HTTPヘッダーを覗きに行ったりしてFlagを手に入れます．

Webへの攻撃方法＝防御方法を学べます．

##Crypto
暗号を解いてFlagを手に入れます．アルゴリズムが脆弱な暗号などが題材になるようです．

実用的に実装することができない暗号技術と，その理由が学べます．

##Reversing
binaryファイルを実行することでFlagを手に入れます．まずはどのように実行できるのかを調べます．


##Pwn
プログラムを解析し，脆弱性をついて，Flagを手に入れます．

深い知識が必要となる分野であり．初心者には敷居が高いことが多いようです．


##Forensic
ゴミ箱データや大量のデータを探索して，Flagを掘り出します．


##Network
通信データを解析したり，特定のターゲットへの通信によりFlagを手に入れます．

ネットワークに関する解析の技術について学ぶことができます．


##PPC
Flagを手に入れる手順は明示されており，実装できるプログラミング力があればFlagが手に入るようです．
競技プログラミングのようなものみたいです．


##Steganography
音声データや画像データを解析してFlagを見つけ出します．

データの性質上，ユニークな問題が多いようです．一問取り組んだことがありますが，謎解きゲームのような印象があり，ワクワクしながら問題を解いた覚えがあります．


##Recon
特定の人物の情報を収集してFlagを手に入れます．

Flagにたどり着くには，SNSからの情報収集が必要になるため，SNSでの情報の取り扱いについて学ぶことができます．


##Trivia
クイズを解くそうです．うまくググる能力が求められそうです．


#どんなコンテストがあるの
世界的なものだと [DEFCON](https://www.defcon.org/)があり，日本で開催されるものだと[SECCON](https://www.seccon.jp/2020/)が大規模なようです．


#何から取り組めばいいの
常設されているCTFや，本などで雰囲気を知るのがいいと思います．
私は現在，一つ目のCpawCTFに取り組んでいます．

- [CpawCTF](https://ctf.cpaw.site/index.php)
- [ksnctf](http://ksnctf.sweetduet.info/)(私は未経験です)
- [セキュリティコンテストチャレンジブック -CTFで学ぼう! 情報を守るための戦い方-](https://www.amazon.co.jp/%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%96%E3%83%83%E3%82%AF-CTF%E3%81%A7%E5%AD%A6%E3%81%BC%E3%81%86-%E6%83%85%E5%A0%B1%E3%82%92%E5%AE%88%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E6%88%A6%E3%81%84%E6%96%B9-%E7%A2%93%E4%BA%95-%E5%88%A9%E5%AE%A3/dp/4839956480/ref=asc_df_4839956480/?tag=jpgo-22&linkCode=df0&hvadid=295723231663&hvpos=&hvnetw=g&hvrand=8225892811882944491&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028852&hvtargid=pla-524447506066&psc=1&th=1&psc=1)（私は未経験です）

他にもあるようなので，自分が参加しやすい・取り組みやすいものを探してみるのがいいかもしれません．


#後枠
謎解きが好きな方は私と同じく，じわじわとハマっていくと思いますので，一緒に取り組んでみましょう．
CentOS8へgcc-4.1.2をインストール

# はじめに
gcc-4.1.2をCentOS8へインストールします。
結果、コンパイルは成功しインストールまで完了しました。

# 作業
## 準備：環境構築
OS: CentOS-8.1.1911_x86_64 (2020/06/15)
コンパイルに必要なツールをインストールします。

```
dnf config-manager --set-enabled PowerTools;  //← texinfoのため
dnf groupinstall "Development Tools";
dnf install wget bzip2 texinfo glibc-devel glibc-static glibc glibc-devel.i686 binutils vim;
```

## 準備：GCC4.4.7のインストール
gccをコンパイルするため[CentOS8へCentOS7のcompat-gcc-44-4.4.7をインストール - Qiita](https://qiita.com/tukiyo3/items/78c1b9351d3cd855847b)に書かれている通りに実行し、gcc44をインストールします。

CentOS8に同梱されているGCCでもCXXFLAGSを指定すればこの手順は不要かもしれません。
→ [CentOS 8で様々なバージョンのGCCをビルドしてみた](https://qiita.com/tukiyo3/items/d2b886db0288eac3a271)
 
## gcc-4.1.2のインストール
### ソースコードのダウンロード

```
wget ftp://ftp.gnu.org/gnu/gcc/gcc-4.1.2/gcc-4.1.2.tar.bz2;
tar -xvf gcc-4.1.2.tar.bz2;
```

### ソースコードのコンパイル

```
cd gcc-4.1.2;
./configure --prefix=/usr/local/gcc-4.1.2 --enable-languages=c,c++;
make;
```


今回の環境では2か所でエラーが生じています。

```
../.././gcc/config/i386/linux-unwind.h:58: error: 不完全型のポインタへの間接参照
make[3]: *** [libgcc.mk:519: libgcc/./unwind-dw2.o] エラー 1
```

もうひとつは

```
../.././gcc/config/i386/linux-unwind.h:141: error: field ‘info’ has incomplete type
make[3]: *** [libgcc.mk:1135: libgcc/32/unwind-dw2.o] エラー 1
```

これはglibcのバージョンが新しいため発生しているようです(詳しくは調べていません)。

### ソースコードの修正
エラーを解消するためにコードを修正します。

```c:gcc/config/i386/linux-unwind.h(54行目)
- struct ucontext *uc_ = context->cfa;
+ ucontext_t *uc_ = context->cfa;
```

```c:gcc/config/i386/linux-unwind.h(139,141-142行目)
struct rt_sigframe {
   int sig;
-  struct siginfo *pinfo;
+  siginfo_t *pinfo;
   void *puc;
-  struct siginfo info;
-  struct ucontext uc;
+  siginfo_t info;
+  ucontext_t uc;
} *rt_ = context->cfa;
```

### コンパイルしインストール
修正が完了したので再度コンパイル・インストールします。

```
make && make install;
```
おしまい。

# 次回
gcc4.1.2がCentOS5.11で使われていたglibcを使ってコンパイルするように設定する。

# 参考
* [在centOS7.2上编译gcc4.1.2](https://www.cnblogs.com/tianjiqx/p/6224126.html)
* [[Fedora]古いバージョンの gcc をインストールする[MATLAB]](http://blog.livedoor.jp/itukano/archives/51848514.html)
* [【備忘録】CentOS 8 と R](https://bitwalk.blogspot.com/2019/10/centos-8-r.html)
Mithril.js 親コンポーネント内から子コンポーネントを操作する - React ref 相当

# Mithril.js 親コンポーネント内から子コンポーネントを操作する - React ref 相当

親コンポーネント内から子コンポーネントの変数やDOMを操作する場合、悩ましい問題が有ります。
それは コンポーネントの view() メソッド内では、まだコンポーネントなので実態が有りません。DOMも生成されていません。
言い換えれば、まだクラスでありインスタンスではないので、さてどうやってアクセスしようかと悩むのです。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310537/d0bd18b3-4a6d-5141-19fa-92e0c175c16c.png)

この問題を解決するため React では ref 属性が用意されています。

では Mithrilではどうするか? ということですが、案外シンプルな方法で解決できます。

## 方法1 - oncreate() で DOMが作成された時点で vnode の参照を取得

`oncreate={ (vnode)=>{ this.ref = vnode; } }` で取得する方法

```tsx
class SubComponent{

	public SubValue = "hello world.";

	public  view(){
		return ".......";
	}
}

class MainComponent{

	public ref;		// SubComponent の vnode が入ります。

	public alertSubValue(){
		alert( this.ref.state.SubValue );
	}

	view(){
		return (
			<div>
				<SubComponent oncreate={ (vnode)=>{ this.ref = vnode; } } />		// !!!
				<button onclick={ ()=>{ this.alertSubValue() } } >show SubValue</button>
			</div>
		);

	}

}

```


## 方法2

この方法では ref の値が取れるタイミングは、DOMは作成された oncreate() の時点ではなく oninit() のタイミングに相当します。


`{ this.ref = <SubComponent /> }` で取得する方法

```tsx
class SubComponent{

	public SubValue = "hello world.";

	public  view(){
		return ".......";
	}
}

class MainComponent{

	public ref;		// SubComponent の vnode が入ります。

	public alertSubValue(){
		alert( this.ref.state.SubValue );
	}

	view(){
		return (
			<div>
				{ this.ref = <SubComponent /> }		// !!!
				<button onclick={ ()=>{ this.alertSubValue() } } >show SubValue</button>
			</div>
		);
	}

}

```


`{ this.ref = <SubComponent /> }`  という書き方が好みは出てくるのですが、 ` <SubComponent />` の内容を `this.ref` へ代入しつつ、view() での描画にも使われますので一石二鳥です。
SASテクニック sgplotプロシジャをtemplate化

# sgplotプロシジャのコードをtemplate(GTL)のコードに変換するテクニック
sgplotの方が個人的には書きやすいが、細かいオプション等はtemplateの方が優れているイメージのため、一度sgplotで作ってtemplateに変換したこともある
まぁあんま使わないけど...

# 準備

```sas
%* templateのコードをテキストファイルにはきだすので、パスとファイル名をマクロ変数に格納 *;
%let Pass = パス;
%let File = template_code.txt;
```

# sgplotプロシジャからtemplateプロシジャのコードを作成

```sas
ods select none;
proc Sgplot data = sashelp.CLASS tmplout = "&Pass.&File.";
  scatter x = NAME y = HEIGHT / group = AGE;
run;
ods select all;
```

tmploutオプションをつけることで、templateコードを作成
sgplotの結果いらないなら、上のようにods select none;で出力させないようにする

https://documentation.sas.com/?docsetId=grstatproc&docsetVersion=9.4&docsetTarget=p073bl97jzadkmn15lhq58yiy2uh.htm&locale=da#n086387n9y3ct3n1i9djru01fomy
Pillowで画像をnearest neighborでresizeするときの各ピクセル値を検証

# 概要
Pillowモジュールを使って画像をnearest neighborでresizeするとき、
どのピクセルから値を取得するのか（最近傍とするのか）を検証してみました。

各アルゴリズム（ニアレストネイバー、バイリニア、バイキュービック）で
画像がどのようになるのか（滑らかになるのかどうかなど）
について言及した記事はよく見ますが、
各ピクセルの値がどうなるのかについての情報が少なかったので書いてみました。

# ニアレストネイバー（Nearest neighbor、最近傍補完）について
アルゴリズム自体は単純。
下のリンク先などが参考になります。
詳しい内容はここでは割愛しますが、
要は一番近い場所のピクセル値をそのまま持ってくるアルゴリズムです。
https://algorithm.joho.info/image-processing/nearest-neighbor-linear-interpolation/

# 検証してみる
## 画像サンプルの作成
検証用として画像サンプルを作ってみました

```python
import numpy as np
from PIL import Image
import  matplotlib.pyplot as plt

A = np.eye(10, dtype=int)
B = np.arange(10, dtype=int) * 20
C = Image.fromarray(B * A)

plt.figure()
plt.imshow(C)
print(np.array(C))
```

 ![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618591/311ce59f-4e8d-6927-8a76-0862a3c9c64d.png)

格納されている値は以下になります

```
[[  0   0   0   0   0   0   0   0   0   0]
 [  0  20   0   0   0   0   0   0   0   0]
 [  0   0  40   0   0   0   0   0   0   0]
 [  0   0   0  60   0   0   0   0   0   0]
 [  0   0   0   0  80   0   0   0   0   0]
 [  0   0   0   0   0 100   0   0   0   0]
 [  0   0   0   0   0   0 120   0   0   0]
 [  0   0   0   0   0   0   0 140   0   0]
 [  0   0   0   0   0   0   0   0 160   0]
 [  0   0   0   0   0   0   0   0   0 180]]
```
対角の要素に0以外の値が入っているような感じですね

## 画像サンプルのリサイズ 10×10 ⇒ 5×5
この画像を、Pillowのresize(nearest neighbor）でリサイズしてみます
まず、10×10の元画像を5×5に圧縮します

```python

C_nn5 = C.resize([5, 5], resample=Image.NEAREST)
plt.figure()
plt.imshow(C_nn5)
print(np.array(C_nn5))
```
![Figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618591/eb893b39-b164-190e-a572-d8dc6c7abba1.png)

```
[[ 20   0   0   0   0]
 [  0  60   0   0   0]
 [  0   0 100   0   0]
 [  0   0   0 140   0]
 [  0   0   0   0 180]]
```
ここで、値を見るとわかりますが、
最近傍はピクセルの「後寄り」の値(20)になっています。
例えばリサイズ後の[0, 0]ピクセルは、
元画像の[1, 1]ピクセルの値が格納されています。
また、リサイズ後の[1, 1]ピクセルは
元画像の[3, 3]ピクセルの値(60)が格納されています。

ところが参考にした数式とは合わない…？
数式通りだとピクセルの「前寄り」のはず

```math
I'(0, 0) = I([0/0.5], [0/0.5]) = I(0, 0) = 0
```
```math
I'(1, 1) = I([1/0.5], [1/0.5]) = I(2, 2) = 40
```
なので、
例えばリサイズ後の[0, 0]ピクセルは、
元画像の[0, 0]ピクセルの値(0)が格納されるはず

なぜかを解決してくれている記事がありました
https://qiita.com/yoya/items/3b4a8080516259ece684
（むしろこの記事書く意味あったんかという…）
なるほどピクセルのスタートが0.5に変更されたんですね…

そうすると、

```math
I'(0, 0) = I([0.5/0.5], [0.5/0.5]) = I(1, 1) = 20
```
```math
I'(1, 1) = I([1.5/0.5], [1.5/0.5]) = I(3, 3) = 60
```

で値がちゃんと合いました。

## 画像サンプルのリサイズ 10×10 ⇒ 3×3
つぎに、10×10の元画像を3×3に圧縮します
![Figure_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618591/4755a44d-26bd-efce-e02b-920e332a19a6.png)

```
[[ 20   0   0]
 [  0 100   0]
 [  0   0 160]]
```

```math
I'(0, 0) = I([0.5/0.3], [0.5/0.3]) = I(2, 2) = 20
```
```math
I'(1, 1) = I([1.5/0.3], [1.5/0.3]) = I(5, 5) = 100
```
```math
I'(2, 2) = I([2.5/0.3], [2.5/0.3]) = I(8, 8) = 160
```
はい、問題なく値が合いました。

# まとめ
nearest neighborでresizeの場合、
計算式から最近傍のピクセルを計算することができるが、
元画像は「0.5」開始であることに注意
Node.jsで複数の画像をWebPに一度に変換する

既存の画像(jpgやpng)をディレクトリを分けつつコマンドで一度にWebPに変換するスクリプトを書きました。
WebPについての説明はここでは割愛します。
[公式アナウンス](https://developers.google.com/speed/webp)


## 環境

* MacOS
* Node.jsのバージョン・・・12.8.1
* npmのバージョン・・・6.10.2


### 前提

以下をインストール済みであることを前提としています。

* Node.js
* npm(又はyarn)


## ディレクトリ構造

```
├── node-extensions
│   └── sharp.js ← 実行するスクリプトファイル。
├── package.json
├── src
│   └── images
│       ├── original ← 元の画像を入れるディレクトリ。
│       └── webp ← 変換後の画像を入れるディレクトリ。
```

## パッケージのインストール・スクリプトの実行

### 必要なもの

* [sharp(0.25.4)](https://www.npmjs.com/package/sharp)・・・webpに変換
* [mkdirp(1.0.4)](https://www.npmjs.com/package/mkdirp)・・・ディレクトリを生成

### スクリプトを書く

``` javascript

const sharp = require('sharp');
const fs = require('fs');
const fsPromise = fs.promises;
const glob = require('glob');
const path = require('path');
const mkdirp = require('mkdirp');

const ORIGINAL_IMG_DIR = glob.sync('../src/images/original/*/'); // 変換前の画像のディレクトリ
const IMG_DIR_ARRAY = ORIGINAL_IMG_DIR.map(imgDirPath => imgDirPath.split('/', 5)[4]); // original/以下のディレクトリ
const WEBP_IMG_DIR = '../src/images/webp/'; // WebP変換後のディレクトリ
const WEBP_IMG_DIR_ARRAY = IMG_DIR_ARRAY.map((name) => WEBP_IMG_DIR + name); // WebP変換後の画像を入れるディレクトリ


/**
 * 画像をWebP形式に変換
 * @param {string} imgPath 元画像のフルパス
 * @param {string} outputDir 出力先のディレクトリ
 * @param {string} outputFilePath 出力するファイルパス
 */
const changeWebpImages = (imgPath, outputDir, outputFilePath) => {
  const fileName = outputFilePath.split('/').reverse()[0]; // 拡張子を含む画像ファイル名
  const imgName = fileName.split('.')[0]; // 拡張子を除く画像ファイル名

  sharp(imgPath)
    .webp({
      quality: 75
    })
    .toFile(`${outputDir}${imgName}.webp`, (err) => { // 画像ファイル名.webpで出力
      if ( err ) console.error(err);
      return;
    });
};


/**
 * 変換後の画像を格納するディレクトリを生成
 */
async function createWebpDir() {
  WEBP_IMG_DIR_ARRAY.forEach((pathName) => {
    mkdirp.sync(pathName);
  });
}


/**
 * 元画像のファイル情報を読み取ってWebPに変換する関数を実行
 */
async function writeFiles() {
  ORIGINAL_IMG_DIR.forEach((dirName, i) => {
    const resolvedPath = path.resolve(dirName);
    fsPromise.readdir(resolvedPath)
      .then((files) => {
        files.forEach((file) => {
          changeWebpImages(`${resolvedPath}/${file}`, `${path.resolve(WEBP_IMG_DIR_ARRAY[i])}/`, `${path.resolve(WEBP_IMG_DIR_ARRAY[i])}/${file}`);
        });
      })
      .catch((err) => {
        console.log(err.message);
      }); 
  });
}

async function init() {
  await createWebpDir();
  await writeFiles();
}

init();
```

### スクリプトを実行する

`node-extensions` のディレクトリまで移動して以下のコマンドを実行。

```
node sharp.js
```

`src/images/original/` の下に `hoge/` というディレクトリがある場合。
スクリプト実行後に `src/images/webp/hoge/` というディレクトリが生成されて、webpに変換した後の画像が格納されます。


## 余談

以下のような場合はPCが悲鳴を上げるので、一度に実行する量(ファイル容量・数)をほどほどにすることをお勧め致します。

* ファイルサイズが大きい(数MB単位)画像が50枚以上ある場合
* 元画像1枚あたりのファイルサイズが数百KBバイトで、1000枚近く一度に処理する場合
SASテクニック 変数ラベルとフォーマットをリセット

SASデータセットの変数ラベルとフォーマットを削除するプログラム


# datasetsプロシジャ

```sas
proc Datasets lib = ライブラリ名 nolist;
  modify データセット名 ;
  attrib _ALL_ label = "" format = informat = ;
quit;
```

変数情報などだけ読み込むため、重いデータでも速い
format = フォーマット名 でformatを指定するが、nullのためformatを削除(informatも同様)
formatとinformatがイコールってことではない


# data ステップ

```sas
data 出力データセット名 ;
  set 入力データセット名 ;

  format _ALL_;
  informat _ALL_;
  attrib _ALL_ label = "" ;
run;
```

setの前にformat等書いてしまうと、
入力データセットの変数情報で上書きされてしまうためformatなどが消せない
何かの処理をしつつformat等をリセットするならこっちのほうがいいかも

https://documentation.sas.com/?docsetId=proc&docsetTarget=n0k88cst84603rn12cu4dq3l3mv0.htm&docsetVersion=9.4&locale=ja
Flask　コーディングメモ

FlaskのコーデングをVSCodeでする際のちょっとした設定。

拡張機能
**[Better Jinja](https://marketplace.visualstudio.com/items?itemName=samuelcolvin.jinjahtml)**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362784/c5f10dba-5c7b-a29a-d33e-d0c3281a5e75.png)
FlaskやDjangoのtemplateを記述する際に言語モードをjinja HTMLにするとEmmetが利かなくなる


次の一行をsetting.jsonに追加する

```json:setting.json
"emmet.includeLanguages": {"jinja-html": "html"}
```

Emmet復活。
Docker-Compose＆Python3.6+NGINX+MariaDB10+uWSGIのDjango環境構築におけるMigrationエラー対処法について

"Docker-ComposeでPython3.6+NGINX+MariaDB10+uWSGIのDjango環境欲張りセット"のおまけ。
https://qiita.com/NickelCreate/items/bed3dc9d088b57127ba7

@NickelCreate ++

環境
- Python 3.6.10
- Django 3.0.7

# トラブル発生

つらつらと環境欲張りセットを実行していくと、マイグレーションコマンド実行でバージョン互換エラーが発生。

> docker-compose run web ./manage.py makemigrations

 `django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.`

モジュールを確認すると、以下のような構成（バージョンは最新版を当てたい）

``` requirements.txt
django
djangorestframework
django-filter
uwsgi
pymysql
```

MySQLクライアントモジュールを、pymysql から mysqlclient に変更＆最新化しても現象は解消せず。。

困った。

# トラブルシューティング

エラー文言でGoogleって見つかった参照記事【後述①】 を読んでみる。

「Fake PyMySQL's version and install as MySQLdb」
MySQLdb で偽装しろとな、まじか。

`setting.py` に書いてみる。

```python:setting.py
import os
import pymysql

# connect mysql
pymysql.install_as_MySQLdb()

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

（中略）

# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'YOUR_DB_NAME',
        'USER': 'YOUR_DB_USER',
        'PASSWORD': 'YOUR_DB_PWD',
        'HOST': 'db',
        'PORT': '3306',
    }
}

# Fake PyMySQL's version and install as MySQLdb 【偽装ポイント】
pymysql.version_info = (1, 4, 2, "final", 0)
pymysql.install_as_MySQLdb()

（以下略）
```

再度実行…

> docker-compose build
> docker-compose up
> docker-compose run web ./manage.py makemigrations

するも現象変わらず…

さらにGoogleると、 `__init__.py` も 追記修正必要な様子 【参照記事（後述②）】
`To resolve this error, add below code in DjangoHelloWorld / DjangoHelloWorld / __init__.py file.`

```python:src/your_app/__init__.py
import pymysql
# install pymysql as mysql database driver.
pymysql.install_as_MySQLdb()
```

再々度実行…

> docker-compose build
> docker-compose up
> docker-compose run web ./manage.py makemigrations

`[ERROR] InnoDB: Cannot open datafile for read-only: './your_app/django_migrations.ibd' OS error: 71`

なんか新しいエラーが出た、が前進している。

これはエラー発生時に作成されたファイル起因のようなので削除。
> rm -f ./mysql/your_app/django_mi>grations.ibd

再実行…

> docker-compose run web ./manage.py makemigrations

```
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
…
```

ようやっと、マイグレーションコマンドが通った。

お疲れ様でした。

■ 参照記事
① How to use PyMySQL with Django
https://adamj.eu/tech/2020/02/04/how-to-use-pymysql-with-django/

② How To Connect MySQL Database In Django Project
https://www.dev2qa.com/how-to-connect-mysql-database-in-django-project/
SASテクニック SQL 要約統計量を列に追加

# SASというよりかはSQLのtips

meansプロシジャなどで要約統計量を求めることができるが、
元データの横にそのまま持たせたいときがある
(合計値を横に持たせて割合出したりなど)

# SQLプロシジャを用いて横に持たせる例

```sas
proc Sql;
  create table work.CLASS as
    select
    * ,
    ( select max( AGE ) from sashelp.CLASS ) as MAX_AGE ,
    ( select mean( HEIGHT ) from sashelp.CLASS where SEX = "男子" ) as MEAN_HEIGHT_M ,
    ( select mean( HEIGHT ) from sashelp.CLASS where SEX = "女子" ) as MEAN_HEIGHT_F ,
    ( select count( * ) from sashelp.CLASS ) as OBS ,
    ( select mean( WEIGHT ) from sashelp.CLASSFIT ) as MEAN_PREDWEIGHT ,
    1 + 1 as TEST
    from sashelp.CLASS;
quit;
```

↑のように列に計算結果をどんどん追加できる


再マージされる機能を利用して以下のような書き方もできる
年齢ごとの要約統計量を列に追加

```sas
proc Sql;
  create table work.CLASS2 as
    select
      *,
      count( * ) as N ,
      sum( HEIGHT ) as SUM ,
      avg( HEIGHT ) as MEAN ,
      mean( HEIGHT ) as MEAN2
    from sashelp.class
    group by AGE;
quit;
```

# meansプロシジャとdataステップでも一応可能
meansで要約統計量を求め

```sas
data xxx;
  set yyy;
  if _N_ = 1 then meansの出力データ;
...
run;
```

など
【初心者】Cloud9とgithubを連携する方法

##はじめに
忘れないために書きました。
間違っていたりしたら、指摘などしていただければ助かります。

github登録、cloud9の設定は事前にしています。
##Cloud9でリポジトリを作成する
まずは、Cloud9のコンソールでwebアプリケーションのルートディレクトリに移動しましょう。

リポジトリに登録するには、git initをします。

```ruby:
$ git init
```
正しくリポジトリを作成できれば、コンソールのディレクトリ表記の後ろに(master)と表示されます。

とりあえず現在状態を全てコミットしてしまいましょう。
まずはgit add -Aコマンドで全てのファイルを選択しておきます。

```ruby:
$ git add -A
```

次に、コミットします。

```ruby:
$ git commit -m "first commit" 
```
すると、コミットされたファイルが表示されます。

このリポジトリをgithub上のリモートリポジトリへとpushします。
その前にリモートリポジトリ（github）を準備します。

##github上にリモートリポジトリを作る
New repositoryから作る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654313/694ba2cf-bbfe-d878-deb6-2b0e723dcdbc.png)
Repository Nameにリポジトリ名を入力して、Create repositoryをクリックしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654313/5f302464-75e5-b0dd-2d92-7e8df55fb9c8.png)

##SSH認証を行う
先ほどCloud9で作ってコミットしたローカルリポジトリの内容をpushします。
pushとは、ローカルリポジトリの内容を、リモートリポジトリへと移すことです。

データを移す際、安全にできるようにSSHという通信方法を使います。SSHによるアクセスは送信元を認証が必要です。
公開鍵認証方式では、送信元が発行した公開鍵をgithubに設定するだけです。最初に認証作業すれば完了です！

Cloud9の公開鍵を取得します。Cloud9のコンソールで以下のコマンドを打ちましょう。

```ruby:
$ cat ~/.ssh/id_rsa.pub
```
長い公開鍵が表示されるので、コピーしておいてください。
ssh-rsa から全部コピーをして、githubに登録します。

下から2番目の、**Settings**を開いて下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654313/7567e2e0-22d6-fc47-3acb-0f0c36c12ed3.png)
左側のメニューの中の**SSH and GPG keys**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654313/1a83c423-0fb5-479a-ed99-4654e0c96672.png)
**New SSH key**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654313/530bc005-a23e-1f20-873e-2a4f01d16999.png)

ここで送信元の公開鍵を登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654313/d6b4c8fd-552b-9e79-bbf8-9b3f148af482.png)
Add SSH keyをクリックしたら終わりです。

##githubにpushする
先ほど作った、リポジトリのUrlをコピーします。
HTTPSとSSHを選択で切り替えられるようになっているので、そのSSHの方を選択ししましょう（git@github.com:から始まるURL）です。
※HTTPSの方はパスワード認証でアクセスする用です。

では、Cloud9のコンソールでコピーしたUrlにpushします。

```ruby:
$　git push git@github.com:〜から始まるSSHProtcolURL master 
```
エラーが出なければ、正しくpushされたと思います。
gitHubを確認してみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654313/38b333a1-c964-0f7b-b968-06b6a45fba03.png)
こうなっていれば、okです。

##Cloud9上でSSHProtcolURLを登録しよう
上で、コピーしたUrlをoriginの後に貼り付けます。

```ruby:
 $ git remote add origin git@github.com:〜省略〜
```
登録しておけば、pushが楽になります

今後は、何か編集をgithubに送ろうと思ったら、Cloud9のコンソールにて以下のコマンド操作を行うことで送ることができます。
1.  $ git add -A
2.  $ git commit -m “説明”
3.  $ git push origin master 

で大丈夫です。
JavaScriptでクッキーをとってくる関数

`{key:value, key:value, ...}`という形でクッキーを返します。

```js
(function getCookies() {
	return !!document.cookie
		? document.cookie
			.split('; ')
			.map(items => items.split('='))
			.map(([key , value]) => Object.assign({}, { [key]: value }))
			.reduce((accum, pair) => Object.assign(accum, pair))
		: {};
})();


```