OmniAICreator/Qiita-1.07M huggingface dataset:
Medium で GitHub のコードブロックを埋め込む

#Medium で海外案件をゲット

Qiita 読者様のなかに、海外からのお仕事がほしい方はいらっしゃいますか？
Medium　という英語のブログサービスがあり、
**技術記事もけっこう投稿されています**。
わりと有名なサービスらしく、ここに技術記事を書いておくと、
**海外から仕事の相談や依頼がきたりします**。
ぼくも数件きました。

![スクリーンショット 2021-07-09 8.32.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/1f0c3877-1b4a-05d4-1ef6-8c10186451ba.png)

#記事にコードブロックを埋め込む

###Medium のコードブロックは見にくい

さて、Medium に技術記事を書こう、と思ったとき、
直面するのがコードブロックの問題です。

**Qiita の便利なコードブロックになれた方は、 Medium のコードブロックが
あつかいづらく見にくいと感じるとぼくは思います**。

【**画像：Medium のコードブロック**】
![スクリーンショット 2021-07-09 8.15.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/907bead5-a519-9a25-c814-730ac33b0f92.png)

見にくくないですか？

コードブロックの貼り方は、シンプルに バッククォートキー(このチョン→ ` )３つでコードの前後を囲むことです。
このやり方は Qiita と同じですが、 

**Qiita とちがって言語指定ができない(全文字黒でメリハリがない)**

**コピペした時の改行とインデントがバラバラ**

といった問題があります。

【**画像：Xcode からコードをコピペした直後の現場**】

![スクリーンショット 2021-07-09 8.14.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/1406b54f-0abb-fcf4-2313-6093c561998b.png)

###代替手段としての GitHub gist

代替手段として、 **GitHub gist をコードブロックとして埋め込むことができます**。

![スクリーンショット 2021-07-09 8.27.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/3de84b85-8801-1e44-e2c8-25c53ac897d4.png)

GitHub のコードの断片の共有サービスにコードを書いて、 gist の URL を Medium の行に貼り付けると、上記のように表示されます。

メリットとして、

**コードが色分けされて見やすい**

**改行やインデントが保持されるので、貼り付けやすいし、見やすい**

といったことがあります。



###【gist を埋め込む手順】

**１、[GitHub gist](https://gist.github.com/) にアクセスして、
説明、ファイル名、コードを記入する。**

![スクリーンショット 2021-07-09 8.34.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/547e8b3c-f021-4049-8b07-758b9f2b9c7b.png)

**２、　右下の「 Create Secret gist 」を　「 Create Public gist 」にかえ、
公開する。**

![スクリーンショット 2021-07-09 8.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/d09687ca-6689-a25c-4ceb-6f0cfbe8a3ef.png)

**3、公開された gist のページ URL を直接 Medium の記事の行に貼り付ける。**

**※ embed の スクリプトではなく、ブラウザの URL に表示される URL です**

これであなたもグローバル・エンジニア。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
#5 リクエスト処理について

# ルーティング
ルーティングとは、リクエストに対してどんな処理をするかという道筋（ルート）を決めて、明記すること
例）
〇〇くんのページが見たい！→〇〇くんのページへ　＝＝　ルーティング成功！

〇〇くんのページが見たい！→▲▲くんのページへ　＝＝　ルーティング失敗！

# HTTPメソッド
HTTP通信をして送受信をする際、処理の内容によって、通信の種類が変わる（全8種類）

①GET（取得、ページを見るとき）
②POST（送信、情報を投稿するとき）
③PUT（更新、情報の更新をするとき）
④PATCH（更新、情報の更新をするとき）
⑤DELETE（削除、情報の削除をするとき）
︙

# ローカルホスト（localhost）

自分のパソコンのこと。開発中はテストとして自分のパソコン内にサーバーを立ち上げ自分のみ閲覧できるようにする。
自分のPC内なのでインターネットにつながなくてもOK（ローカル）
（クライアントとサーバーが同居しているイメージ）
FlutterでFirestoreからデータを取得する（null-safety）

Flutter初学者です。Flutterはものすごくアップデートが早いので今回はFirebsaseから値を取得するにあたって気をつけることを書きます。（2021年7月29日）　バージョンは以下のようになります。

```
・　firebase_core: ^1.3.0
・　cloud_firestore: ^2.3.0
```

まず正しく動くコードを載せておきます。

```dart:main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> main() async{
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  String? data;

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('title'),
        ),
        body: StreamBuilder<QuerySnapshot>(
          stream: FirebaseFirestore.instance.collection('books').snapshots(),
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
            return ListView(
              children: snapshot.data!.docs.map((DocumentSnapshot document) {
                return ListTile(
                  title: Text(document.get('title')),
                );
              }).toList(),
            );
          },
        ),
      ),
    );
  }
}

```

### 変更点

・　Firebaseの初期化が必要らしい

```dart
Future<void> main() async{
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}
```

・　これでnullを許可してあげる。

```dart
String? data;
```

・　FirestoreがFirebaseFirestoreに変更

```dart
FirebaseFirestore.instance.collection('books').snapshots()
```

・　documentsがdocsになったみたい
・　レシーバーが「null」になる可能性があるため、docsに無条件でアクセスするできない。そのためdata!とする必要がある。

```dart
snapshot.data!.docs.map((DocumentSnapshot document)
```



## 参考記事

https://matsumarudesu.com/flutterfirebasecloudfirestore-latest/

https://zenn.dev/captain_blue/articles/flutter-firestore-realtime-changes

https://zenn.dev/nagaho/articles/c9b84d7f99966d

https://gurutaka-log.com/flutter-firebase-firestore-sample#i-4
PrivateLink VPCエンドポイント疎通方法


# PrivateLink（VPCエンドポイントサービス　/ 疎通される側）

### 基本設定

[![Image from Gyazo](https://i.gyazo.com/9c6f7c6f358ca51ee8cdd0c760f5f200.png)](https://gyazo.com/9c6f7c6f358ca51ee8cdd0c760f5f200)


### NLB
[![Image from Gyazo](https://i.gyazo.com/42bcf15426f271fd23647ba6852768c8.png)](https://gyazo.com/42bcf15426f271fd23647ba6852768c8)


### ホワイトリストに登録されたプリンシパル
[![Image from Gyazo](https://i.gyazo.com/2cc46c091cd0c9b5b5973bb874d009cc.png)](https://gyazo.com/2cc46c091cd0c9b5b5973bb874d009cc)

### VPCエンドポイント許可
[![Image from Gyazo](https://i.gyazo.com/3c5fe53c6fc708d13639a99454932368.png)](https://gyazo.com/3c5fe53c6fc708d13639a99454932368)

# VPCエンドポイント（疎通する側）
[![Image from Gyazo](https://i.gyazo.com/dbbd45a04fb82339fd0b5a81f4e5c75c.png)](https://gyazo.com/dbbd45a04fb82339fd0b5a81f4e5c75c)

# Route53
[![Image from Gyazo](https://i.gyazo.com/088b70d59e5717f12ece79c4c68531d1.png)](https://gyazo.com/088b70d59e5717f12ece79c4c68531d1)
Spring Boot、MySQLにINSERTされてるのにできてなくて詰んだ（Commitもしてる）対処法

# Commitまでログ出てるんだけどレコードがない
SpringBootからMySQLへデータをInsertしたい。
ログを見るとInsert文もCommitも発行された形跡がある（SpringBoot・MySQLどっちのログにも）
エラーはどこにも出ていない。
でも、Selectしてみるとそんなレコードないんです。

# 結論：前提として、バッチ処理中のInsertでした。タスクが全部終わる時にコミットされます。
うまくいかないこのInsertはバッチ処理中のお話でした。
Insert文やCommitの命令は都度出ていたのですが、**バッチの全てのタスクがエラーなしで終了するその時**にCommitされるみたいです。

# 対処法
**@ Transactionalをつけているクラス（Service）に追記します**

```
@Transactional(value = Transactional.TxType.REQUIRES_NEW, rollbackOn = Throwable.class)
```
Spring Boot v2.6.0です。
ググったところ、前のバージョンだと指定する値の形式がちょっと異なるようですが、v2.6.0だとこれでうまく動きました！

アノテーションへのこの追記で、バッチ処理中その都度、しっかりDB InsertがCommitされるようになりました:tada:
【React】別タブが閉じたことを検知する【JavaScript】


## はじめに
「外部サービスを別タブで開き、その別タブが閉じたことを元のタブで検知したい」
なんて時に使える方法をご紹介します。

タイトルにReactを入れておりますが、Vueとかでも使えます。

## 結論
```sample.js
const url = "https://hogehoge.com" //任意の別タブのURL
const win = window.open(url, "_blank")
if (win) {
 const timer = setInterval(() => {
  if (win.closed) {
    window.clearInterval(timer);
    // 別タブ閉じた時にしたいこと
  }
}, 500);
```

## 簡単に解説

```
const win = window.open(url, "_blank")
```

定義したurlを別タブで開きます

```
 if (win.closed) {...}
```

Windowオブジェクトにあるclosedプロパティでウィンドウが閉じたかどうかを判定している。
参考：[Window: closed property - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/closed#change_the_url_of_a_window_from_a_popup)



```
setInterval(() => {...}, 500)
```

500ミリ秒が経過した後に、{...}を実行します。今回は500ミリ秒ごとにウィンドウが閉じているかの判定を行い、任意の処理を行なっている。
[WindowOrWorkerGlobalScope.setInterval()](https://developer.mozilla.org/ja/docs/Web/API/WindowOrWorkerGlobalScope/setInterval)


```
window.clearInterval(timer)
```

windowがclosedの場合、setIntervalを使用して設定された繰り返し動作をキャンセルします。
[window.clearInterval](https://developer.mozilla.org/ja/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval)

#### 追記
@9447al 様より、clearIntervalを使用しない方法をコメント頂けました。
そちらもご参照ください！

##最後に

結構最近はグローバルオブジェクトを使う機会が多い。
JS、、奥が深いぜ、、、
AtCoderログ：0011 - ABC 095 A

# 問題

https://atcoder.jp/contests/abc095/tasks/abc095_a

## 問題文
> ラーメン店「高橋屋」のラーメンの値段は $1$ 杯 $700$ 円ですが、トッピング（味玉、チャーシュー、ねぎ）を乗せた場合は $1$ 種類につき $100$ 円が加算されます。
> ある客がラーメンを一杯注文し、店員にトッピングの希望を伝えました。店員は注文の内容をメモ帳に文字列 $S$ として記録しました。$S$ の長さは $3$ 文字で、$S$ の $1$ 文字目が o のとき客のラーメンに味玉を乗せることを、x のとき味玉を乗せないことを表します。同様に、$S$ の $2$ 文字目、$3$ 文字目はそれぞれチャーシュー、ねぎの有無を表します。
> $S$ が入力されると、対応するラーメンの値段を出力するプログラムを書いてください。

## 制約
> ・$S$ は長さ $3$ の文字列である。
> ・$S$ の各文字は o または x である。

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067) ([第02問類題](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-2-%E5%95%8F--abc-081-a---placing-marbles-100-%E7%82%B9))

# 回答
## 回答1 (AC)
注文 $S$ を文字列 s として受け取り、合計金額を表す price に対し、s の各文字にあわせてトッピングの金額を加算するという方針でコーディングしました。

```C++:abc095a-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  string s;
  cin >> s;
 
  int price = 700;
  for ( int i=0; i<3; i++ ) {
    if ( s.at(i)=='o' ) {
      price += 100;
    }
  }
  cout << price << endl;
}
```

## 回答2 (AC)
A 問題は for 文を使わずに解けるとのことなので、
for 文を使わないコードも作成してみました。

```C++:abc095a-2.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  string s;
  cin >> s;
 
  if ( s=="ooo" ) {
    cout << 1000 << endl;
  } else if ( s=="xoo" || s=="oxo" || s=="oox" ) {
    cout << 900 << endl;
  } else if ( s=="oxx" || s=="xox" || s=="xxo" ) {
    cout << 800 << endl;
  } else {
    cout << 700 << endl;
  }
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc095/tasks/abc095_a/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/arc095/editorial.pdf)
回答1に近い方法が紹介されていました。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0010 - ABC 081 A](https://qiita.com/RoadLynton/items/dafadf919a845989d44d)
- 次の記事 → [AtCoderログ：0012 - ABC 085 A](https://qiita.com/RoadLynton/items/77bcb72d7b746391f3fa)
【Cloud9】Rails + React + MySQL 環境構築

# はじめに

ブラウザ上のIDEなんて使わないと思っていたのですが、いい使い方を思いついたのでCloud9を使うことになりました。
あくまで個別の例とはなりますが、自分がCloud9で環境構築した時の流れを載せます。

## Cloud9 環境構築

Cloud9の環境を作成するところは、他に記載されている方も多いので割愛します。
以下は、Cloud9環境内で実施していきます。

## yum アップデート

```bash
# yum アップデート
$ sudo yum update
```

## Ruby インストール

Cloud9 では Ruby のバージョン管理ツールとして```rvm```が使用されているので、こちらを使用してインストールと管理をします。

```bash
# Ruby インストール
$ rvm -v
$ rvm list
$ rvm install 2.6.0
$ rvm --default use 2.6.0
$ rvm list
```

## Git ソースコードインストール

Git にてソースコードを取得します。

```bash
# Git ソースコードインストール
$ git clone <URL>
$ cd <project_name>
```

## Rails ライブラリインストール

yumで```mysql-devel```をインストールする必要があります。ここで、少し時間をとってしまいました。

```bash
# Rails ライブラリインストール
# bundler ver.2 を使用しているため
$ gem install bundler:2.1.4

# 少しはまりました。
$ sudo yum install mysql-devel
$ bundle install
```


## MySQL セットアップ

ここで一番時間を取られてしまいました。
RailsとMySQLの連携がうまく取れなかったので、一旦MySQLをアンインストールをしてから再インストールすることにしました。

### MySQL アンインストール（うまく立ち上がらないため。）

```bash
# MySQL をアンインストール（うまく立ち上がらないため）
$ sudo yum remove mysql
$ sudo yum remove mysql-server
$ sudo yum remove mysql-libs
```


### MySQL(MariaDB) インストールおよび起動


```bash
# MySQL(MariaDB) インストールおよび起動
$ sudo yum --enablerepo=remi,epel,rpmforge install mysql-server
$ sudo service mariadb status
$ sudo service mariadb start

# MySQL(MariaDB) 接続確認
$ mysql -u root -p
-> exit
```

## Rails DB情報（database.yml）調整

```bash
# Rails の DB情報（database.yml）書き換え
password: 
socket: /var/lib/mysql/mysql.sock
```

## DB、テーブル作成、データ入力

```bash
# DB、テーブル作成、データ入力
$ rails db:create
$ rails db:migrate
$ rails db:seed
```



## yarn インストール

ここからは、Reactなどwebpackerを使用しているプロジェクトのみ必要となります。
yarn をインストールします。

```bash
# yarn インストール
$ npm install --global yarn
$ yarn --version
```

## package.json のライブラリインストール

```bash
# package.json のライブラリインストール
$ yarn install

# package.json 書き換え
    "start": "rails s -p $PORT -b $IP & bin/webpack-dev-server"
```

## サーバー起動

Rails でサーバー起動するためには```rails s```をするのが普通ですが、Cloud9では```rails s -p $PORT -b $IP```を実行する必要があります。

```bash
# サーバー起動
$ yarn start
```

```bash
# ブラウザで確認
Preview -> Preview Running Application
```

# まとめ

もしかしたら一般的な例ではないかもしれませんが、どなたかの役に立てればと思い書きました。

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
Object.values（）の代替

#概要

Object.values（）の代替

#Object.values（）

```
var obj = {
	foo: 'bar',
	baz: 42
};
console.log(Object.values(obj));

// ['bar', 42]

```

#代替

```
Object.prototype.values = function(obj) {
	var res = [];
	for (var i in obj)
	{
		if (obj.hasOwnProperty(i))
		{
			res.push(obj[i]);
		}
	}
	return res;
};



```

以上。
TypeScriptに文字列として記述したHTMLをVSCodeでフォーマットしたい

Chrome拡張開発をしています。JestでテストするためにサンプルページのHTMLのテキストが欲しくなりました。もちろんフォーマットしておきたい。

いくつか方法はあると思います。

- htmlファイルを書いてPrettierでフォーマットする（読み込みには以下が必要）
    - html-loaderインストール
    - WebPack設定
    - `declare module '*.html';`で型定義
- lit-html, typescript-lit-html-plugin のnpmインストールとlit-htmlのVSCodeプラグインを使う
- [lit-htmlのVSCodeプラグイン](https://marketplace.visualstudio.com/items?itemName=bierner.lit-html)を騙して文字列にフォーマットをかける

最初に考えたのはhtmlファイルを書いてPrettierでフォーマットです。

でも、テンプレートリテラルを使って書くならHTML構造の使い回しが出来るのでテストケースの作成が捗りそうですね。

調べていると lit というライブラリーを発見し、Usage通りにやってみることにしました。
テキストとして記述しているのにフォーマットも働くのでいい感じです！
![スクリーンショット 2021-07-09 2.26.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4196/5318af52-db0b-7f14-7701-a735e4b82ce5.png)

いざ`npm run test`を実行！　→ 失敗！！
調べてみると Issue になっていました。
[Unexpected token error in tests](https://github.com/lit/lit/issues/482)

なるほどね〜設定が細かくなるのはいやだな〜。。
このlit-htmlというライブラリーはいろいろ機能があるようなのですが、私は今のところ使わないんです。

TypeScriptに文字列として記述したHTMLをVSCodeでフォーマットしたいだけ。

ということで本題です。いい感じの方法を見つけました。

# TypeScriptに文字列として記述したHTMLをVSCodeでフォーマットしたい

lit-html, typescript-lit-html-pluginをインストールしなくても、[lit-htmlのVSCodeプラグイン](https://marketplace.visualstudio.com/items?itemName=bierner.lit-html)があれば以下のようなフォーマットのコードをちゃんと整形してくれます。
![スクリーンショット 2021-07-09 2.40.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4196/886f78c4-7411-a29b-9f35-fb04e7ab45a2.png)

ちなみに、`String.raw`, `styled.div`, `gql`といった関数で使われているテクニックはTagged Template Literalsというらしいです。 

私のケースだとhtmlという名前の関数が、単純に文字列を返すものであればいいんですよね。

調べて作ってみました。どうぞ使ってください。

```typescript
export const html = (literals: TemplateStringsArray, ...placeholders: string[]): string => {
  let result = "";
  placeholders.forEach((placeholder, i) => {
    result += literals[i];
    result += placeholder;
  });
  result += literals[literals.length - 1];
  return result;
};
```

こんな感じでテンプレートリテラルの書き方も出来ます。
![スクリーンショット 2021-07-09 2.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4196/398b07c5-69f5-efaa-d23c-8869499331db.png)

これで快適ですね！
【JAMstack】Next.js × Firebase で JAMstack なブログサイトを作る①［概要］

<!-- ======================================================= -->
# 概要
<!-- ======================================================= -->
**Next.js**の勉強を始め、公式のチュートリアルでブログサイトを作成しました。
その過程で、**JAMstack**とういうアーキテクチャを知り、最近勉強していた**Firebase**と組み合わせると自分でも作れそうだったので、頑張って作ってみました。

目標は、ブログ記事を投稿・削除すると、自動的にブログサイトに反映されるようにします。またブログサイトは、静的サイト生成（SSG）によって、SEOに強く各ページを高速に表示できるものとします。

記事をひとつにまとめると長くなるので、分割しました。

- [【JAMstack】Next.js × Firebase で JAMstack なブログサイトを作る①［概要］](https://qiita.com/nemutas/items/555c75f4473f605123fc)
- [【JAMstack】Next.js × Firebase で JAMstack なブログサイトを作る②［ブログサイト］](https://qiita.com/nemutas/items/bb312d26cf3349ce0230)
- [【JAMstack】Next.js × Firebase で JAMstack なブログサイトを作る③［Hooks］](https://qiita.com/nemutas/items/2e97e69f637e912e7f9b)
- [【JAMstack】Next.js × Firebase で JAMstack なブログサイトを作る④［管理アプリ］](https://qiita.com/nemutas/items/04fba5681101fd450bda)

<!-- ======================================================= -->
# 開発環境
<!-- ======================================================= -->
- Windows10
- VSCode
- npm

<!-- ======================================================= -->
# JAMstack とは
<!-- ======================================================= -->
以下の記事で詳しくまとめられています。

https://qiita.com/ozaki25/items/4075d03278d1fb51cc37

<!-- ======================================================= -->
# アーキテクチャ
<!-- ======================================================= -->
今回作成するサービスは、以下のようなアーキテクチャで構成されています。

![アーキテクチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/c71e3e3f-f61c-3303-c739-f51ebfb0ab22.png)


### コーディング
コーディング部分は3つに分かれます。

- <font color="Blue">ブログサイト</font>：公式チュートリアルに沿って、Next.js [TypeScript]で作成します。**Vercel**にデプロイします。
- <font color="Red">Hooks</font>：Firebase Storageの変更を監視するHook関数。**Firebase Functions**にデプロイします。
- <font color="Green">管理アプリ</font>：ブログ記事を投稿したり、削除したりするアプリケーションです。Reactで作成し、**Firebase Hosting**にデプロイします。

### JAMstack の動き
① 管理アプリから**Firebase Storage**に対して、記事の投稿・削除を行います。
② **Firebase Functions**は、Firebase Storageの変更状態を監視しています。
③ ①の変更により、API経由で**Vercel**にデプロイリクエストを送ります。
④ ブログサイトは静的サイト生成（SSG）で作成されているため、**Firebase Storage**から記事を取得してビルド・デプロイされます。

これにより、記事の変更に応じて自動的にブログサイトが更新されます。

# まとめ
Webサイト・アプリ開発は、今年から始めました。
趣味でやっていて開発の経験が浅いので、効率を無視したコーディングがあるかもしれませんがご容赦ください。

Next >

https://qiita.com/nemutas/items/bb312d26cf3349ce0230
Rubyの連続でない時間帯に含むかを判断

# TL;DR

```rb
delta = 10.minute
schedule = %w[10:00 12:00 14:00 16:00 18:00]

time_ranges = schedule.map do |t|
  (Time.parse(t) - delta)..(Time.parse(t) + delta)
end

case Time.now
when *time_ranges
  p "範囲内です"
else
  p "範囲外でござる"
end
```

# 経緯

とある要望で現在の時間が指定の時間帯に含まれるかをチェックする必要がありました。
**例:**


> 現在時刻が10:00、12:00、14:00、16:00、18:00の前後10分の区間内に含むかを判断せよ


大人しくIF文を組むのもいいですが、上記スケジュールもいつか変数になると考え、拡張性のある上手い書き方があるか考えました。

# 解説
## レガシーな`between?`
SQLもそうですが、含むか含まないかを判断するには、`Between`が王道でした。
もちろん、RubyにもBetweenができますが、下記のように、１つのBetweenは１つの区間しか対応できません。

```rb
Time.now.between?(Time.parse('10:00'), Time.parse('18:00'))
```

## `case..when`記法の活用
Rubyの`case..when`記法は、以下のメリットがあります。
- 複数条件が書けます。 Eg: `when 1,3,5,7`
- 範囲(Range)に対応します。 Eg: `when 1..5`
- 条件は[配列の展開式](https://qiita.com/koshilife/items/63ad4088adcd77b71e52)にも対応します。 Eg: `when *[5,10,15]`

上記仕様を利用すれば、簡単に連続でない不特定の区間を判定できます。

```rb
# まずはRangeリストを組むこと
# Railsではない時
require 'time' 
delta = 10 * 60

# Railsの時
delta = 10.minute

time_ranges = %w[10:00 12:00 14:00 16:00 18:00].map do |t|
  (Time.parse(t) - delta)..(Time.parse(t) + delta)
  # <含む...含まない> にしたい時は `...` を使うこと
end

=> [2021-07-09 09:50:00 +0900..2021-07-09 10:10:00 +0900,
 2021-07-09 11:50:00 +0900..2021-07-09 12:10:00 +0900,
 2021-07-09 13:50:00 +0900..2021-07-09 14:10:00 +0900,
 2021-07-09 15:50:00 +0900..2021-07-09 16:10:00 +0900,
 2021-07-09 17:50:00 +0900..2021-07-09 18:10:00 +0900]
```

```rb
# あとは上記Rangeリストを `case..when` 文に組み込むこと

case Time.now
when *time_range_list
  p "範囲内です"
else
  p "範囲外でござる"
end
```

# 参考
- [Ruby で楽に範囲のチェックをする](https://qiita.com/cho_co/items/2cbe429308edc93b7854)
- [Rubyのcase文において、複数対象したい場合は , 区切りで指定できるし、その定義は配列を使うこともできる](https://shinkufencer.hateblo.jp/entry/2019/04/16/230000)
- [Rangeクラス](https://docs.ruby-lang.org/ja/latest/class/Range.html)
Macでバッチからpythonファイル起動


#Macでバッチからpythonファイル起動する

(・・・かつ、何故かターミナル再起動する度にpythonのバージョンが
3から2に勝手に変わるのでpython3に変更しつつファイル起動。
ターミナルのシェルがzshなのにpathが.bash_profileに通っていた
だけの問題で、別にこちらは解決。じゃあこの記事誰向け？)

使い方 
下のファイルを start.commandとか好きな名前のcommandファイルにして保存。
pythonファイル実行したい時はstart.commandをダブルクリック。


```:start.command
cd desktop

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

python --version

python main.py
```

手順
1　好きなところに起動したいpythonファイル置く。
僕はいつも面倒な為desktopから起動しているのでそこに。
2　上のstart.command作成。1行目のcdの所にpythonファイル置いてあるディレクトリを書けばOK。
一番下のpython main.pyの所も、自分にあったファイル名を。main.pyを使うことが多いので僕はそれで。
3　pythonファイルを起動したくなったらstart_commandをダブルクリック。終わり。

補足
export PYENV_ROOT ~ evel "$(pyenv init -)"　までは
pythonが勝手に2になってしまう人用。ならない人には不要。
python --versionも同じ。2からちゃんと3になっているのを確かめたいので書いているだけ。
なので問題がない人は単に

```:start_command
cd desktop

python main.py
```

とかでOK。簡単だね。
[Rails]  Webpacker::Manifest::MissingEntryErrorが表示された時の対処法

利用環境
・ruby 2.7.3
・Rails 6.1.4

Webpacker::Manifest::MissingEntryErrorというエラーが出た際の解決方法を記載します。


```ruby:ターミナル
rails webpacker:install
rails webpacker:compile
```
上記を実行で解決


エラーコードの中にWebpacker can't find application.jsという表示があります。
要するにWebpackerが見つからないという意味なのでインストールしてあげましょう。
Mavenで単体テストのレポートを出力する。

Mavenで単体テスト結果をレポート出力してみました。その時の設定メモを残したいと思います。
Gradleの場合と同様にプラグインを入れて出力しています。(Gradleの場合はapply plugin: 'java')

※あくまでメモなのでそのままでは実行できない可能性が高いです。

#使用するプラグイン

- maven-surefire-report-plugin
- maven-site-plugin

maven-surefire-report-pluginだけでも出力はできますが、CSSなどが出力されません(チェックマークも表示されない)。
そのため、maven-site-pluginで作成できるプロジェクトサイトに使われるCSSを使うことにします。

#設定
pom.xmlにプラグインの設定を追加します。(...は省略)

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
...
<build>
...
	<plugins>
	...
		<!-- report -->
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-surefire-report-plugin</artifactId>
			<version>3.0.0-M4</version>
		</plugin>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-site-plugin</artifactId>
			<version>3.9.0</version>
		</plugin>
	</plugins>
</build>
...
</project>
```

#レポート出力
pom.xmlが存在するフォルダで、
以下のコマンドを実行してレポート出力します。

```console:レポート出力
$ mvn clean    # 実行しない場合、前回の結果が混ざってしまう
$ mvn site:site -DskipTests
$ mvn -Dtest=**/sample/*Test surefire-report:report
```

# 参考
https://maven.apache.org/surefire/maven-surefire-plugin/index.html
https://maven.apache.org/surefire/maven-surefire-report-plugin/index.html
https://maven.apache.org/plugins/maven-site-plugin/index.html
https://kikutaro777.hatenablog.com/entry/2013/01/13/201253
Windows10にElixirインストール

久しぶりにElixirをやってみようと思い、
Windows10にインストールしたのでその時の内容をメモします。

#Elixirインストール
Chocolateyを使用してインストールします。
管理者でコマンドプロンプトを起動して以下を実行します。
実行すると何度か応答が求められるのでメッセージに従って応答します。(基本Yで大丈夫です。)

```bash
> choco install elixir
```

以下を実行することでバージョンを確認できます。

```
> iex -v
IEx 1.11.2 (compiled with Erlang/OTP 21)
```

ElixirをインストールするとErlangもインストールされます。

```bash
> erl +V
Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version 12.0
```

#Elixirインタラクティブモード起動停止
ちょっとしたお試しはインタラクティブモードが便利です。以下で起動停止できます。
起動：`iex`
停止：`:init.stop`　または　`Ctrl+C`を押してYを押す

```bash
> iex
Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :init.stop
:ok
iex(2)>
>
```

```
> iex
Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> バッチ ジョブを終了しますか (Y/N)? y
>
```

ちなみに、PowerShellだとiexというコマンドがもともと存在するため起動しません。
代わりに以下のコマンドを使用します。別ウインドウで起動できます。

```bash
> iex.bat --werl
```

#スクリプトとして実行してみる。
以下のファイルを作成します。

```hello.exs
IO.puts "Hello world elixir script"
```

実行してみます。

```
> elixir hello.exs
Hello world elixir script
```


#参考
https://elixir-lang.org/
https://elixir-lang.jp/
https://elixirschool.com/ja/
Linux-findコマンドで正規表現を使う際には、ファイル名だけでなくパスで書く必要がある

#はじめに
自分がLinuxでfindコマンドを正規表現を使って実行した時にハマった内容について共有したいと思います。


##実行環境
実行環境は以下の通りです。（シェルはbash）

```
$ uname -rs
Linux 3.10.0-1160.31.1.el7.x86_64
$cat /etc/centos-release
CentOS Linux release 7.9.2009(Core)
```

#やりたかったこと
ホームディレクトリ直下のドット(.)で始まるファイル名のファイルだけを、
findコマンドで正規表現のオプションを用いて出力する。

#やったこと
以下のコマンドを打てばやりたかったことを実現できると思いました。

```
$ find ~/ -maxdepth 1 -regextype posix-basic -regex '\..*'
```

しかしこのコマンドを実行しても、何も表示されませんでした...
（-regextype を posix-awk, posix-egrep, posix-extended にそれぞれ変更してみても同様）

正規表現を使わずにやってみると、ドット始まりのファイルは確かにホームディレクトリ直下に存在しているのです。

```
$ find ~/ -maxdepth 1 -name '.*'
/home/user1/.bash_logout
/home/user1/.bash_profile
/home/user1/.bashrc
/home/user1/.bash_history
/home/user1/.viminfo
```


#分かったこと
色々と正規表現の書き方を変えて試した結果、このようにすると出力されました！

```
$ find ~/ -maxdepth 1 -regextype posix-basic -regex '.*/\..*'
/home/user1/.bash_logout
/home/user1/.bash_profile
/home/user1/.bashrc
/home/user1/.bash_history
/home/user1/.viminfo
```

ほうほう...ということはこうすればどうだ！と思ったら案の定これでもOKでした。

```
$ find ~/ -maxdepth 1 -regextype posix-basic -regex '/home/user1/\..*'
/home/user1/.bash_logout
/home/user1/.bash_profile
/home/user1/.bashrc
/home/user1/.bash_history
/home/user1/.viminfo
```

どうやら、findコマンドで正規表現を使う場合は、
**ファイル名の正規表現だけではダメで、ファイルのパスで指定してあげる必要がある**みたいです。（めんどくさい...）

`-name`オプションではファイル名部分だけでよかったのですが、
正規表現ではこれが通用せずかなりハマってしまいました...

#まとめ
findで正規表現を使う時はファイル名の正規表現の手前に`.*/`を書くのがよい。

それと、わざわざ正規表現を使わないでも`-name`オプションでできるならそれで済ませた方が楽。
バリデーションで投稿文字数を制限した時に単体テストコードを完結に記述する方法

#はじめに

口コミサイト作成中、感想が長すぎてもよろしくないと思ったので140文字以上は投稿できなくするバリデーションをかけました。

しかしテストコードで異常系を記述する時**140文字も書くの大変じゃん！**と思ってしまいしました。

この記述をなんとか短くできないかを考えたので投稿させて頂きます。

#バリデーションを定義する

```model.rb
class Model < ApplicationRecord

validates :text, length: { maximum: 140 }

end
```

これでtextに140文字以上の文字数は投稿に失敗します。

#単体テストコードを記述する

正常系でも投稿できるか検証するため`FactoryBotとFaker`を使いました。

```spec>factories>model.rb
FactoryBot.define do
  factory :review do
   text {Faker::Lorem.sentence}
  end
end
```
こうする事でランダムで文章が作られます。

```
[1] pry(main)> Faker::Lorem.sentence
=> "みなと漠然運ぶはじめて。"

[2] pry(main)> Faker::Lorem.sentence
=> "かちゅう金じきしょうそう見当たる。"
```

これでは140文字もできないので自ら書かなけらばなりません。

```model_spec.rb
  describe '投稿機能' do

   context '投稿できるとき' do
    #省略
   end

   context '投稿が失敗するとき' do
    it 'textが140文字以上だと投稿できない' do
      @model.text = 'テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。テストで140文字書いています。
      @model.valid?
      expect(@model.errors.full_messages).to include('感想は140文字以内で入力してください')
    end
  end
```

最初はこのように140文字びっしり書いてましたがあまり良くないなと思いました。

正しい書き方かは分かりませんが下記のように書いたらコンパクトに書くことができました。

```model_spec.rb
 it 'textが140文字以上だと投稿できない' do
   @model.text = `テストです` * 140
   @model.valid?
   expect(@model.errors.full_messages).to include('感想は140文字以内で入力してください')
 end
```

この記述で`テストです`という5文字に`140`を掛け算して140文字以上の記述をすることができました。

#最後に
この方法が正しいかは分かりません。。。
もっと簡潔な記述方法があれば教えて下さい。
yukicoder contest 303 参戦記

# yukicoder contest 303 参戦記

## [A 1585 Cubic Number](https://yukicoder.me/problems/no/1585)

*N*≦10<sup>18</sup> なので、シングルループで一発ではある.

```python
N = int(input())

for i in range(1, 10 ** 6 + 1):
    if i ** 3 != N:
        continue
    print('Yes')
    break
else:
    print('No')
```

にぶたんでもいい.

```python
N = int(input())

ok = 0
ng = 10 ** 6 + 1
while ng - ok > 1:
    m = ok + (ng - ok) // 2
    if m ** 3 <= N:
        ok = m
    else:
        ng = m
if ok ** 3 == N:
    print('Yes')
else:
    print('No')
```

三乗根を取って、その近辺をチェックしてもいい.

```python
N = int(input())

n = int(N ** (1 / 3))
for i in range(n - 1, n + 1 + 1):
    if i ** 3 != N:
        continue
    print('Yes')
    break
else:
    print('No')
```

## [B 1586 Equal Array](https://yukicoder.me/problems/no/1586)

操作自体が +1 と -1 の組で、トータルでは±0なので、合計が N の倍数になっているかが全て.

```python
N, *A = map(int, open(0).read().split())

if sum(A) % N == 0:
    print('Yes')
else:
    print('No')
```
pythonでPDF結合+外部モジュールが見つからないと言われた時の対処

# <strong>PDF結合をpythonにやらせたい+</strong> <strong>pipでインストールしたパッケージがNo module named〜 と言われるのを何とかしたい！！！</strong>


環境
M1Mac Big Sur ver11.2.3
Python 3.9.0


取り上げる内容
・python3と外部パッケージPyPDF2を用いたPDFファイルの結合
・pipでインストールした外部パッケージが認識されない時の対処法(パスを通す)




# <strong>PDF結合を楽にやりたい！！</strong>

電子書籍にするために大量にスキャンしたデータをPDFに、そして結合ということを最近やっていたが、どうも某iL○vePDFだと100MBまでしか作業できない。
・・・と調べていると、普通にpythonで出来るじゃん。
iL○vePDFがダメなら、自分でやればいいじゃない！・・・はい。

まずはpythonでPDF操作する用のパッケージをインストール。

```:ターミナル
XXXXXXMac ~ % pip install PyPDF2
```



その後書いたのが下のプログラム。意気揚々。

```python
# mergePDF.py
import PyPDF2

merger = PyPDF2.PdfFileMerger()

merger.append('sample1.pdf')
merger.append('sample2.pdf')
merger.write('merged.pdf')
merger.close()

print("done")
```

だがしかしbut・・・


# No module named PyPDF2を吐かれる ( ´Д`)y━･~~

上のpyプログラムの実行結果。

```:ターミナル
XXXXXXMac ~ % cd desktop
XXXXXXMac desktop % python mergePDF.py
Traceback (most recent call last):
  File "mergePDF.py", line 1, in <module>
    import PyPDF2
ImportError: No module named PyPDF2
```



<strong>「PyPDF2なんてモジュールありませんよ。」</strong>
いや何でだよ！もっと隈なく探せよ！！！！

とりあえず本当にPyPDF2が入っているか、及び場所の確認。
pip show PyPDF2で確認できる。

```:ターミナル
XXXXXXMac desktop % pip show PyPDF2
Name: PyPDF2
Version: 1.26.0
・・・略・・・
Location: /usr/local/lib/python3.9/site-packages
```
インストールはされてるっぽい。そして肝心なのが場所で、どうも
/usr/local/lib/python3.9/site-packages
に入ってると。はぁ。

では当のpython兄貴はいつもimport用にどこを探しているかと言うと、

```python
# print_sys_path.py
import sys, pprint
pprint.pprint(sys.path)
```

上のプログラムを作って実行すればわかる。

```:ターミナル
XXXXXXMac desktop % python print_sys_path.py
['/Users/(僕の名前)/Desktop',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload',
 '/Library/Python/2.7/site-packages',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC']
```
長い。けど要するに、PyPDF2が入っている<strong>/usr/local/lib/python3.9/site-packages</strong>の中は探してすらいないよと言うこと。そりゃ当然絶対入っていない引き出し漁っても見つかるわけがない。
要は<strong>「ここの引き出しの中も探してね」</strong>と教えてあげる必要がある。

#　path通すのはめちゃくちゃ簡単

さっきの.pyファイルの一番上にimport sysと、sys.path.append("パス")を追記。終わり。
再びターミナルで実行しまふ。

```python
#mergePDF.py
import sys
sys.path.append("/usr/local/lib/python3.9/site-packages")

import PyPDF2

merger = PyPDF2.PdfFileMerger()

merger.append('sample1.pdf')
merger.append('sample2.pdf')

merger.write('merged.pdf')
merger.close()

print("done")
```



```:ターミナル
XXXXXXMac desktop % python mergePDF.py
done
```

完了！至極簡単。圧倒的イージー。

感想
no module foundに一瞬戸惑ったが、pathの通し方さえわかれば簡単。
これでPDF操作も楽になったし、モジュールが見つからないと言われた時の対処法もバッチリ。
Universal  Modular   ACTOR  Formalism  for  Artificial  Intelligence のメモ

https://www.researchgate.net/publication/220812785_A_Universal_Modular_ACTOR_Formalism_for_Artificial_Intelligence

1973年に発表されたActorのオリジナル論文。OCRされてアップロードされているが、大変に読みにくい。。おそらくオリジナルのタイプライター原稿のフォーマットを再現しようとしているためなのだろうが、行送りが小さすぎたり単語間のスペースがおかしかったりしてかなり苦しい。さらに、なぜか一部OCRされていなかったりする。

「不思議の国のアリス」とかからよくわからない引用が。

## memo

- 1種類のオブジェクトActorに基づくアーキテクチャ
    - Actorは、仮想プロセッサ、アクティベーションフレーム、ストリーム でもある
- 実装は問わない。
- PLANNERというAIシステムにつかえる。
- 並列実行できる。並列にしても効率は落ちずむしろ向上する。並列にしても挙動は変わらない。
- 制御構造は汎用で、goto、割り込み、セマフォなどはいらない。

- INTENTIONというものがある。actorにメッセージが送られる前に、actorの事前状態をチェックするものらしい。Actorが外部の世界に対して結ぶcontractである。

- プロセッサへのマッピングも考えているようだ。自然といえば自然。Occamみたいな。
- Unification: デジタル回路設計、データベース、コンピュータ・アーキテクチャ設計、プログラミング言語設計、コンピュータシステム設計に共通のなにか。

- intrinsic computation <-> extrinsic computation
    - intrinsic definition - 内部構造ではなく、外部に対するインターフェイスで「オブジェクト」を規定する。
- データフローとコントロールフローは一致すべき。

- 階層構造
    - scheduling/inteition/monitoring/binding/resource management がそれぞれのactorについている。
    - これら自身もactorである。reflection towerみたいなこと言ってるな。
    - global state considered harmful

- 知識表現？、データベース
Actorの状態としてデータをためている、という話にしか見えない。これなにかすごいんだっけ？
最後の方にはMcCarthyがどこかにいるのを、空港に届ける、みたいなplanningを表現しようとしているように見える。
しかし、notationがわからなくて、actorにうまくマップできてるのかわからない。deduction ruleで
知識表現するのはprolog的だが、
【SwiftUI】この世でいちばんわかりやすいビューのアニメーション

#この投稿は何？
SwiftUIフレームワークでiOSアプリを開発する際に、ビューをアニメーションさせる方法について基本を解説します。

![スクリーンショット 2021-07-08 21.43.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/dda6f68e-0720-a9b9-d030-52cb896cbff6.png)


###実行環境
macOS 11.4
Xcode 12.5.1
Swift 5.4


#ハンズオン
以下は、アプリのメイン画面のコードです。

````Swift:メインの画面
struct ContentView: View {
    var body: some View {
        VStack {
            Smiley()    // ニコちゃんマーク 
            Button {
                // ボタンタップ時の処理
            } label: {
                Text("rotate smiley 90°")
                    .font(.title)
            }
        }
    }
}
````

このメイン画面では、笑顔の絵文字の下に「タップできるボタン」を配置しています。

###ビューを回転する
`rotateEffect(_:)`モディファイアは、指定した角度の分だけビューを回転します。

````Swift:
struct ContentView: View {
    var body: some View {
        VStack {
            Smiley()
                .rotationEffect(Angle(degrees: 90.0))    // 90度だけ回転する
            Button {
                // ボタンタップ時の処理
            } label: {
                Text("rotate smiley 90°")
                    .font(.title)
            }
        }
    }
}
````

`rotateEffect(_:)`モディファイアに指定する角度は、`Angle`型のインスタンスです。
ボタンをタップするごとに、`90`度ずつ回転するようにします。

````Swift:
struct ContentView: View {
    @State private var angle = 0.0    // State属性プロパティ
    
    var body: some View {
        VStack {
            Smiley()
                .rotationEffect(Angle(degrees: angle))
            Button {
                // 角度を90ずつ増分する
                angle += 90.0
            } label: {
                Text("rotate smiley 90°")
                    .font(.title)
            }
        }
    }
}
````

ボタンをタップするたびに、ニコちゃんマークが90度ずつ回転します。
ただし、アニメーションではなく、瞬時に表示が切り替わるだけです。

###アニメーションを適用する
`animation(_:)`モディファイアを使って、「ビューに適用済みのモディファイア効果」をアニメーション化することができます。

````Swift:
struct ContentView: View {
    @State private var angle = 0.0
    
    var body: some View {
        VStack {
            Smiley()
                .rotationEffect(Angle(degrees: angle))
                .animation(.easeInOut(duration: 1.0))    // 回転をアニメーション
            Button {
                angle += 90.0
            } label: {
                Text("rotate smiley 90°")
                    .font(.title)
            }
        }
    }
}
````

`animation(_:)`モディファイアには、「どのようにアニメーションするか」を指定することができます。
ここでは、`easeInOut(duration:)`メソッドを指定して、「1秒間で滑らかに」アニメーションさせています。
Keyが揃ってないJSONデータをjqでワンライナーでヘッダ付きCSVに変換する


業務で最近JSONをjqで弄ることが多くなったので、jqを使って遊んでたらCSVができましたという話です。

## 問題

元となるJSONはこんな感じです。

```hoge.json
{"col_chr1": "hoge", "col_num": 23, "col_bl1": false}
{"col_num": 24, "col_bl1": true, "col_bl2": true, "col_chr2": "nya-n"}
{"col_chr1": "hoge", "col_num": 2, "col_bl2": false}
```

カラムの有無もバラバラ。
これを、こんな感じにしたい。

```fuga.csv
"col_bl1","col_bl2","col_chr1","col_chr2","col_num"
false,,"hoge",,23
true,true,,"nya-n",24
,false,"hoge",,2
```

カラムの有無を揃えて、ヘッダも付けてCSVに。
さぁ、どうしましょうか。

## 答え

```sh
cat hoge.json | jq -s -r '(add | keys), ((add | keys | map({(.):null}) | add )+.[] | [.[]]) | @csv' >fuga.csv
```

おまじないみたいですね。

## 解説

### add

このjqではaddを多用しています。
addは、オブジェクトの配列を引数に取るときは、各要素を**マージ**してくれます。
つまり、新しいkeyはオブジェクト追加、同じkeyは後のオブジェクトで上書きということですね。
これを使って、ヘッダ項目を取得しています。

```sh
$ cat hoge.json | jq -s -r 'add'
{
  "col_chr1": "hoge",
  "col_num": 2,
  "col_bl1": true,
  "col_bl2": false,
  "col_chr2": "nya-n"
}

$ cat hoge.json | jq -s -r 'add | keys'
[
  "col_bl1",
  "col_bl2",
  "col_chr1",
  "col_chr2",
  "col_num"
]

```

### map({(.):null})

各keyに対して、valueがnullのオブジェクトを作ってあげます。

```sh
$ cat hoge.json | jq -s -r 'add | keys | map({(.):null}) | add'
{
  "col_bl1": null,
  "col_bl2": null,
  "col_chr1": null,
  "col_chr2": null,
  "col_num": null
}
```

これが何の役に立つのかというと、元のJSONと + してあげることで、**マージ**を使って足りないカラムを補完してくれるのです。

```sh
$ cat hoge.json | jq -s -r 'add | keys | map({(.):null}) | add + {"col_chr1": "hoge"}'
{
  "col_bl1": null,
  "col_bl2": null,
  "col_chr1": "hoge",
  "col_chr2": null,
  "col_num": null
}
```

### オブジェクトへの .[]
普段jqを使っていると `.[]` は配列に使って、各要素にそれぞれフィルタをかけるために使うわけですが、オブジェクトに対して`.[]`を適用すると、なんとvalueの要素を並べてくれます。

```sh
$ cat hoge.json | jq -s -r 'add | keys | map({(.):null}) | add + {"col_chr1": "hoge"} | .[]'
null
null
hoge
null
null
```

### くっつける
以上のテクニックを組み合わせると、ヘッダはこんな風にすると取れます。

```sh:header.sh
$ cat hoge.json | jq -s -r 'add | keys'
[
  "col_bl1",
  "col_bl2",
  "col_chr1",
  "col_chr2",
  "col_num"
]
```

さっきも出てきましたね。
そして明細はこんな感じ。

```sh:detail.sh
$ cat hoge.json | jq -s -r '(add | keys | map({(.):null}) | add )+.[] | [.[]]'
[
  false,
  null,
  "hoge",
  null,
  23
]
[
  true,
  true,
  null,
  "nya-n",
  24
]
[
  null,
  false,
  "hoge",
  null,
  2
]
```

あとはくっつけて `@csv` ってしてあげるだけです。

```sh:csv.sh
$ cat hoge.json | jq -s -r '(add | keys), ((add | keys | map({(.):null}) | add )+.[] | [.[]]) | @csv'
"col_bl1","col_bl2","col_chr1","col_chr2","col_num"
false,,"hoge",,23
true,true,,"nya-n",24
,false,"hoge",,2
```

以上！


## 参考

https://dev.classmethod.jp/articles/jq-manual-japanese-translation-roughly/
https://cloudpack.media/51306
https://medium.com/veltra-engineering/jq-supports-json-to-csv-fb5c951a9575
[Github]草を生やし忘れた過去に戻って草を生やしたい！

##はじめに
本記事は過去日付に戻ってcommitする方法について記述したものです。

私は毎日草を生やすことを意識してやってましたがまさかのcommit忘れ
絶望して打ち拉がれていました。。。

![スクリーンショット 2021-07-08 19.33.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991598/d7c06c38-53cf-338a-ae88-77d6b0f6fc0d.png)

しかし、調べてみると過去に戻ってcommitできることが判明しました！(タイムマシーン)
多用厳禁ですww

## 本題
結論以下のようなコードで遂行することができます。

```
git commit -m "コメント" --date="Jul 7 23:59:59 2021 +0900"
```

オプションとして`--date`を指定し上記のように日付を指定することで実行できます。


ものすごく便利な機能なので、多用してしまうと毎日コミットする癖が抜けてしまう可能性ありです。
みなさんも`--date`は度を越さないに使ってみてはいかがでしょうか。

##参考

https://zatoima.github.io/blog-github-contributions-before-date.html
みたこともないメッセージが。Googleより。

![IMG_3924.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324249/55a0fbd3-56d7-2cd4-e2e7-bd84cf53a082.png)

リロードしても、またこのメッセージが表示でした。

環境はios 14.6
safari
chrome
共におなじメッセージが表示されました。

PCのコンソールでみたところ、
google slide?のservice workerがなにか悪さしているぐらいです。

自分の方も、引き続き、切り分けて見ていきたいとおもいます。

追記）本スライド１３ページ目の[]を()にしたところ、メッセージがなくなりました。
　　[]ってサニタイズされてないのかな？インジェクション？スクリプトに影響するのであれば
　　変な攻撃されそうかもです。
Staticをわりかし理解する

staticとは
--
厳密に言えばStatic変数といわれ、インスタンスを生成せずにアクセスできる変数、メソッドを作る際に必要なやつ。

```javascript
class Person {

constructor(name,age) {
 this.name = name
 this.age  = age
 }
static who(){return "staticだよ"}
}

```

new 〇〇でインスタンスを生成する必要はないので```Person.who```でアクセスできる。
インスタンスを生成しないので関数内に```this```を使うことはできない。


え...?でもなんのためにあるの？
----
ここの理解が重要。
そもそもインスタンスを生成することはメモリをくう。クラス（設計図）をもとにインスタンス（実態）をつくっているわけだから当たり前の話だ。

newする度にクラスから作られたインスタンス化されたデータが勝手にメモリに入っていくわけですと、、
すると、エンジニアの方はクラス間で共通のデータ、関数を共有するのに困ってしまう。
この変数はインスタンスしなくても良いのになぁ、とか思うようになる。

だからこそ、```ｓtatic```
「そこの変数（もしくはメソッド）勝手にインスタンス化するな！静かにしてほしい！！（静的とかけて）」
という意味も込めて（知らないけど）インスタンス化しない　staticが生まれた（のかもしれない）
*備考　staticの日本語訳は「静的」
テストを書くのはエンジニアとしてのプライドを保つために必要という考え

# はじめに

テストは絶対書くべきだ！と思っていて、ここ数年は当たり前のようにカバレッジ100%でプログラムを書いてきたこともあり、テストの重要性について考えたこともありませんでした。最近、テストを導入するか否かの話し合いがあり、個人としては「絶対書くべきだ！」と思いつつも、非エンジニアの人と話すと不要という考え方も一理あるのではと思うことがあります。ただ、個人的にはテストを書かないことに対し、相当な嫌悪感があり、それ自体が大きなストレスとなっていることも事実で、このストレスは、品質低下を危惧しているのか、それともなんなのか考えてみたら、私なりの答えが出たので経験を踏まえて書きます。つまり、ポエムです。

## テスト書くメリット

テストを書くメリットは**リグレッションテストの品質が一定に保たれること**だと思います。経験上、バグは修正した箇所でなく、修正したことによって影響した他の箇所で発生することが多い傾向にあります。これを抑えるために、影響ある機能が正しく動作することのテスト、つまりリグレッションテストが必要となります。リグレッションテスト自体は手動、自動、どちらでも実現可能でありますが、手動ではアプリケーションの大きさによってテストケース数が比例するのでコスト増えます。また、人の入れ替えが発生し、アプリケーションの知見不足になり、リグレッションテスト自体の品質が担保出来なくなる恐れなど様々な問題があることも事実です。テスト書くとコスト掛かるけど最終的にペイできるよって内容でメリットを語ることが多いと思いますが、一番のリスクはコストでなく、リグレッションテストの品質低下によってテストすべきところがテストされてないことです。テストを書けば、機械的に一定の精度でテスト出来ますし、仕様変更したらテストが必ず落ちるので、テスト自体のメンテを継続して行われやすいはずです。リグレッションテストが形骸化しにくくなることで、一定の品質が保たれ、結果的にアプリケーション品質が向上するのがテストを書くメリットだと考えました。

## テストコードが拒まれる何か

テストを書くことによるデメリットはコスト面ぐらいで、そのコストもいずれペイできるのだからデメリットはなさそうですが、どの会社にも必ず**テストコードを拒まれる何か**が存在するはずです。

### 工数がかかる

おそらく一番多い理由はこれではないでしょうか。実は工数がかかるというのは嘘で、中規模アプリでも自動テストのケースが1000を超えることがザラなので、修正毎に大量のケースを手動でこなすほうが遥かに工数がかかります。人間は優秀で、影響のありそうな範囲をテストすれば良いという判断が可能なので、テストケースを絞って品質を担保出来るからテストを書くよりも工数が減らせる可能性が高いという選択が取れるというのが正しいはずです。また、学習コストが高いので、知見者以外が見積るとどうしても工数が上がってしまいます。

### 導入効果がわからない

「工数かかるのはわかったけど、見合った導入効果は見込めるの？」

この理由も多いのではないでしょうか。[t_wada](https://twitter.com/t_wada)さんの登壇資料を穴が開くまで読み、どうにかテストを導入出来ないか交渉したエンジニアは多いのではないでしょうか。私もその一人です。ただ、現実問題、非エンジニアの人にこの資料を見せても説得出来ないことが多いです。登壇資料が誤った情報を発信しているのではなく、悲しいことにエンジニアの意見を信じてもらえない、信頼関係にあることだと思います。

https://speakerdeck.com/twada/quality-and-speed-2020-autumn-edition?slide=19

### テストを書きたい！ vs 書きたくない！
これはエンジニア間で起こります。様々なテストに対する記事を見ると「スキル不足だ！」と書いてあったりしますが、実際は慣れの問題です。エンジニアとして、テストを書くことにデメリットはほぼないと思っているので、ここはプライドを捨てて少しずつ慣れていってほしいなと思います。私も数年前まで書けないから書きたくない！派だったのですが、優秀なエンジニアに出会い、１から丁寧に教えてもらったおかげでテストを書きたい派になりました。


## テストを書くべし！の一択か

もちろん書くに越したことはありませんが、工数がかかる、導入効果が不明なのは一理あります。実際に私が開発した個人サービスではテストを書いていません。個人サービスにテストは不要とは言いませんが、書く時間の確保やモチベーションがないのでテストを書いても利益はないと思っています。とあるベンチャーの情報漏洩の記事を読むと確実にテストを書いてなかっただろうと思いますし、完璧な品質を求めなくとも利益がついてくる場合はそちらを優先すべきだと思います。つまり、テストは利益がどれだけあるか、被害がどれだけ大きいかによって判断するべきと思っています。ここで、テストを書いたほうがスピードが早いと思っている人は優秀な数少ないエンジニアです。

## 結局は何のためにテストを書くのか

バグは信頼をなくします。さらに修正した箇所ではないところにバグが発生したらエンジニアとしてのスキルが疑われ、説明も難しいので非エンジニアは嫌悪感を増すばかりでしょう。信頼を得られない＝軽視されていると思うので、エンジニアのプライドを保つことが難しくなり、最悪の場合、負債の改修するだけのエンジニアとなる可能性もあります。プライドなんかくだらないかもしれませんが、エンジニアは事業成長に大きく貢献してますし第一線で活躍するためには必要なものです。自ら信頼を落とす方向に持ってく必要はありませんし、スキルも向上するのでテストは書くべきだと思います。なぜテストを書くのかといろんなソースを調べ、書くべき理由を探しましたが、一番は信頼を得てエンジニアとしての能力、地位を向上したいという情熱の部分だったのかもしれません。
RSpec FactoryBotの使い方とFakerについて

# Factoryとは
何かしらのデータを作る工場のこと

# Fakerとは
ダミーデータを作るFakergemのこと


Faker gemを公式ドキュメントから調べられます。

https://github.com/faker-ruby/faker


# FactoryBotのメソッド

```rb
FactoryBot.create(factory_name) レコード作成
FactoryBot.build(factory_name) インスタンスを作成(new)するメソッド
FactoryBot.attributes_for(factory_name) パラメーターを作成するメソッド

ex)　user modelのFactoryを使う場合
FactoryBot.create(:user)　　レコード作成
FactoryBot.build (:user)インスタンスを作成(new)するメソッド
FactoryBot.attributes_for(:user) パラメーターを作成するメソッド

```

*テストコードを書く時FactoryBotを省略できる

```rails_helper.rb
config.include FactoryBot::Syntax::Methods＃追記

```

# よく使うFaker

```rb
Faker::Name.name  #nameの後ろにはもっとたくさんついたりします。
Faker::Internet.email
Faker::Internet.password  #Internetの後ろはもっと色々使えます。

#まだ色々あるので調べてみてください
```
Faker gemを公式ドキュメントから調べられます。

https://github.com/faker-ruby/faker
中心極限定理　試してみた

#前提
母集団の平均を$ μ $、分散を$ σ^2 $とおく

中心極限定理は、
母集団から抽出した標本の平均$\overline{x}$は平均μ、分散$ σ^2/n$の正規分布に従う
というものである。(平均・分散が存在しさえすれば母集団の分布に寄らない)

実際にpythonで$\overline{x}$を計算するために抽出する標本数nを増やしていき比較してみた

#pythonでサイコロを例に試行

サイコロを1回振った時の平均$μ$と分散$σ^2$はそれぞれ$ μ=3.5 $、$ σ^2=35/12 $
である

今回は抽出する標本数を変化させて、その標本平均と標準偏差それぞれを計算してみる
※標本平均のばらつきをわかりやすくするため、標本平均を抽出する回数を10回とする
(pythonのstreamlitライブラリを使用)


# n=10の時
```Python
import streamlit as st
import numpy as np
import pandas as pd

st.title('n=10')

# 変数初期化
n = 10
sample_mean = []

for i in range(10): # 抽出回数は10回
    # 1～6までのさいころのランダムな目
    x = np.random.randint(1, 7, n)
    # 標本平均
    sample_mean.append(x.mean())

df = pd.DataFrame({
      '標本平均': sample_mean,
    })

# 結果
st.dataframe(df ,width=500)
st.write('標本平均の標準偏差：{}'.format(np.var(sample_mean)))
```

![nが10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1018986/9ede02f5-5fff-805f-7d24-2a84a256002b.png)

# n=100の時
```Python
st.title('n=100')

# 変数初期化
n = 100
sample_mean = []

for i in range(10): # 抽出回数は10回
    # 1～6までのさいころのランダムな目
    x = np.random.randint(1, 7, n)
    # 標本平均
    sample_mean.append(x.mean())

df = pd.DataFrame({
      '標本平均': sample_mean,
    })

# 結果
st.dataframe(df ,width=500)
st.write('標本平均の標準偏差：{}'.format(np.var(sample_mean)))
```
![nが100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1018986/94c2b2be-8b92-f147-4f1b-c5dab09636f3.png)

# n=1000の時
```Python
st.title('n=1000')

# 変数初期化
n = 1000
sample_mean = []

for i in range(10):　# 抽出回数は10回
    # 1～6までのさいころのランダムな目
    x = np.random.randint(1, 7, n)
    # 標本平均
    sample_mean.append(x.mean())

df = pd.DataFrame({
      '標本平均': sample_mean,
    })

# 結果
st.dataframe(df ,width=500)
st.write('標本平均の標準偏差：{}'.format(np.var(sample_mean)))
```

![nが1000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1018986/69bf8565-1f79-e69f-9186-ee6fbf8070d4.png)

#考察
標本数nが大きいほど、標本平均は3.5に近づいていき、標準偏差は小さくなることが分かる
同期メソッドから非同期メソッドを呼び出す

いろいろあって非同期にできないメソッドから非同期メソッドを呼び出す必要があって、単純に `Task.Wait()`したらスレッドがデッドロックした。解決するためには？

呼び出される方

```csharp
public class BarModel{
  public int Id {get; set;}
  public string Name {get; set;}
}
public class FooService{
  public async Task<BarModel> GetBarAsync(){
    // ... ここで ToListAsync()とかやる
  }
}
```

呼び出す方

```csharp
public class Program{
  public static void Main(){
    var service = new FooService();
    
    var model = Task.Run(()=>{
      return service.GetBarAsync();
    }).GetAwaiter().GetResult();    
  }
}
```

呼び出しを `Task.Run()` で囲み、 `GetAwaiter().GetResult()` とする。

正しいかな？
横にスクロールするUICollectionViewのCell

# 完成形はこちら
<img width="150" alt="D6F52781-3C99-44F5-8D30-7B67039AB8F0_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/63964e67-0a0b-a26d-1577-a0b673c58794.jpeg">


# 機能説明
* 横にスライドするUICollectionViewのCellをタップすると色が`UIColor.systemTeal`に変わります。 

# コードと簡単説明

* collectionViewを横にスライドできるようにするには、`UICollectionViewFlowLayout()のインスタンス.scrollDirection = .horizontal`を設定します。

* 今回は、UICollectionViewのCellをタッチした時の処理を追加しています。その為には、`func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {}`を使用します。

```Swift:ViewController
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!
    
    let collectionViewFlowLayout = UICollectionViewFlowLayout() //インスタンス作成
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.delegate = self
        collectionView.dataSource = self
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        collectionViewFlowLayout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        collectionViewFlowLayout.scrollDirection = .horizontal  //ここで、横にスクロールに変更してます
        collectionView.collectionViewLayout = collectionViewFlowLayout
        
    }
}

extension ViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        
        return 10
        
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
                        
        return cell

    }
 
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        return CGSize(width: collectionView.frame.size.width / 4 - 10, height: collectionView.frame.size.width / 4 - 10)

    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
        let selectCell = collectionView.cellForItem(at: indexPath)!
        
            selectCell.backgroundColor = UIColor.systemTeal
                  
        }
    }
```

# 終わり
最近、長くなったif文を短く出来ないか、考えるのが楽しくて楽しくて。
ご指摘、ご質問などありましたら、コメントまでお願い致します。
Progateで作ったWebアプリをDjangoで作ってみる2！ Part3 -ログイン機能編-

# 目標物の確認

ProgateのNode.jsコースで作ったブログアプリと同じものをDjangoで作ってみます。

Djangoでのアプリ開発の一連の流れを整理するために記していきます。

**完成イメージ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/147877a6-1b3a-25e2-7956-720596125802.png)

#ログイン機能の実装

Djangoでは簡単にログイン機能を実装できます。

**authenticate()**と**login()**を使うため、importします（☆1）。

**authenticate()**は、loginの前段階として、formから送られてきたデータとUserテーブルのデータを照合するために使用します。照合が無事にできた場合は、オブジェクトが返されます（☆2）。ウェブサイトではログインにメールアドレスが使われるのが一般的です。ですが、Djangoではデフォルトでユーザー名を使っており、メールアドレスでのログインは少し面倒なので今回はユーザー名を使います。

``if user is not None``というコードは二重否定になっているため、``user``が``None``でなければ、つまり``user``がいれば``if user is not None:``の下の行のコードが実行されます（☆3）。

**login()**を使うことによってユーザーをログイン状態にすることができます（☆4）。ログイン状態の管理にはsessionが使われます。sessionはユーザーの状態を記録するために用いられる機能であり、**login()**を使うことによって、ログインしたユーザーの情報をサーバーのsessionの中に保存できます。**setting.py**ファイルを見ると、``MIDDLEWARE``という変数があり、その中に`'django.contrib.sessions.middleware.SessionMiddleware'``というコードがあります。Djangoがあらかじめsessionの仕組みを準備してくれており、勝手にsession機能を使うことができます。

```python:blogapp/blog/views.py
from django.shortcuts import render, redirect
from django.views.generic import TemplateView
from django.contrib.auth.models import User
from django.db import IntegrityError
from django.contrib.auth import authenticate, login # ☆1

class BlogTop(TemplateView):...

def signupview(request):...

def loginview(request):
    if request.method == 'POST':
        username = request.POST['username'] # ☆2
        password = request.POST['password'] # ☆2
        user = authenticate(request, username=username, password=password) # ☆2

        if user is not None: # ☆3
            login(request, user) # ☆4
            return redirect('blog:list')
        else:
            return redirect('blog:login')
    
    return render(request,'blog/login.html')
```

ログイン用のページも作ります。

```HTML:login.html
{% load static %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>BLOG</title>
    <link rel="stylesheet" href="{% static 'blog/style.css' %}">
  </head>
  <body>
    <div class="sign">
      <div class="container">
        <h1><a href="{% url 'blog:list' %}">BLOG</a></h1>
        <div class="panel">
          <h2>ログイン</h2>
          <form action="" method="post">{% csrf_token %}
            <p>ユーザー名</p>
            <input type="text" name="username">
            <p>パスワード</p>
            <input type="password" name="password">
            <input type="submit" value="ログイン">
            <a href="{% url 'blog:list' %}">一覧にもどる</a>
          </form>
        </div>
      </div>
    </div>
  </body>
</html>
```

最後に、**urls.py**を編集して完了です（☆5）。

```python:blogapp/blog/urls.py
from django.urls import path
from .views import BlogTop, signupview, loginview # ☆5

app_name = 'blog'

urlpatterns = [
    path('', BlogTop.as_view(), name='top'),
    path('signup/', signupview, name='signup'),
    path('login/', loginview, name='login'), # ☆5

]
```

これでログインページの実装は完了です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/0c44934a-f667-8a33-af11-f66406753b06.png)