OmniAICreator/Qiita-1.07M huggingface dataset:
GitHub Pagesで数式を書く方法と主なトラブルについて

# はじめに
GitHub Pagesを利用すればmarkdownファイルを静的なwebページとして公開することができます。（その際mdファイルはhtmlファイルに変換されます）
ですがそのままではmarkdownに数式を書くことができないので、ここではMathJaxを使ってTeX記法で数式を記述する方法に説明します。
また、実際にやってみてプレビューでは正しく表示されるにもかかわらずGitHub Pagesでは表示がおかしい箇所もあったため解決できた点については対処法も記載します。

# 準備
markdownファイル内に以下の記述を追加します

```html
<script type="text/x-mathjax-config">MathJax.Hub.Config({tex2jax:{inlineMath:[['\$','\$'],['\\(','\\)']],processEscapes:true},CommonHTML: {matchFontHeight:false}});</script>
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
```

これでMathJaxを使う準備ができました。あとは\$\sqrt{2}\$のようにTeX記法で数式を書くことができます。
amsmathパッケージなどにも対応しているようです。

# GitHub Pagesで数式を使う際のトラブル
必ず発生するわけではありませんが、ローカル（VSCodeの拡張機能など）では正しくプレビューできたのにGitHub Pagesでは表示がおかしくなるパターンがありました。
ここではそれらの原因となりうる記述および回避法について記載します。

## 絶対値
普段であれば絶対値の記号には|を使うと思いますが、表の区切りと誤認識されることがあります。

### 対処法
かわりに\lvert（左側） \rvert（右側）コマンドを使うことで回避可能です。

## 下付き文字
アンダーバーで囲むと\<em>タグによる強調になるため、これも誤認識のきっかけになることがあります。残念ながらコマンドの回避はおそらく無理です。

### 対処法
アンダーバーの前後に半角スペースを1つずつ空けることで回避可能です。下付き文字のためであれば1つ空白が入っていても問題なく表示されます。

## 微分のダッシュ
f''などと書いた際にダッシュではなくアポストロフィが表示されることがあります。
2階微分以上でよく見る気がしますが1個だけのときもたまに発生します。

### 対処法
\primeコマンドを使うことで回避できます。2階微分などでは\prime\primeのように連続で書いてOKです。

## \\\\での改行
使う場面としては行列を書く場合などです。基本的には\\\\と書けば改行されますが、たまにエスケープのミスでバックスラッシュ1個と解釈されることがあります。

### 対処法
強引ですが\\\\\\\\とすれば一応回避可能です。上記までのトラブルと異なり、もともとちゃんと表示されていた箇所でこれをやるとデザインが崩れるためあくまで誤エスケープ対策です。

#おわりに
現時点で見つけたトラブルは以上です。今後も色々な数式を書く上で新たな不具合が発生するかもしれないのでその際は（できれば解決法と併せて）追記したいと思います。
JConsoleでJMXに接続してもすぐ切断される（泣）

JMXにjconsoleを使って接続しても一瞬繋がるけどすぐ切れる現象に遭遇

openjdk14.0.1 のjconsoleから接続していたけれど
openjdk12.0.2 にしたら切れなくなりました。

ちなみに環境は
サーバー(JMX) CentOS7 + JDK1.8.0_211 
クライアント(jconsole) ubuntu20.04
Drupal8 Japanese Translation  日本語翻訳ファイル(ja.po)の import/export後のエラー対策

先日Drupal8.9.1で起きた現象でした。

環境Aで定義した日本語翻訳データはExportし(ja.poとして出力される)、環境BでそのファイルをImportした後、環境Bの「コンテンツ > ファイル」画面（/admin/content/files）がエラーとなって、開けなくなりました。

####手順
【環境A】
　Admin側の「環境設定 > 地域と言語 > User interface translation」画面で、翻訳データの日本語を入力し、保存後、同じ画面の「エクスポート」タブを開き、Languageは「Japanese」に選択し、エクスポートオプションにチェック入れて、エクスポートする
　※　デフォルトはja.poファイルとして出力される

【環境B】
　1．Admin側の「環境設定 > 地域と言語 > User interface translation」画面で、「インポート」タグを開き、上記出力された「ja.po」ファイルをインポートする
　※　インポートは順調で終わりました。

　2．別件の確認ために、「コンテンツ > ファイル」画面を開こうとすると、エラーが発生し、表示されませんでした。:scream:
　　以下のようなエラーが出力される↓
　　>> LogicException: PO files URL should not be public. in Drupal\locale\StreamWrapper\TranslationsStream->getExternalUrl() (line 55 of core/modules/locale/src/StreamWrapper/TranslationsStream.php).


####対策方法
　ネット上で調べると、以下の記事に辿り着いた↓
　https://www.drupal.org/project/drupal/issues/2449895#comment-13453160
　
　記事に掲載されている[8.9系用のPatch](https://www.drupal.org/files/issues/2020-02-06/2449895-72.patch)があるので、そのPatachを与えることによって解決できるではないかと思った。

　一番早い方法として、ComposerでPatchを設定して試したが、エラーになって、Composer installできませんでした。。:cry:
　仕方なく、上記のPatchの修正箇所を確認しながら、ほかのメンバーが直接ソースを手動修正することになった。

　ソースを修正した後、エラーとなった「コンテンツ > ファイル」画面が無事表示された！:clap::innocent:
　※　Importした「ja.po」はファイルリストの一番目に表示されている
nuxt+Typescriptで「Property 'component' does not exist on type 'RouteConfig'」のエラーを直す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271765/81b7033c-aa13-3116-9fad-8f0e2263ec21.png)

nuxtで普通にTypescriptのプロジェクトを作成すると，いきなりエラー出てびっくりした．

エラーメッセージはこんな感じ

```shell
・・・
・・・
Property 'component' does not exist on type 'RouteConfig'.

    12 |   chunkName?: string
    13 |   chunkNames?: Record<string, string>
  > 14 |   component?: RouteConfig['component'] | string
       |                           ^
    15 | }
    16 | 
    17 | export interface NuxtConfigurationRouter extends RouterOptions {
・・・
・・・
```

調べてみると，すでに解決済みっぽい

Githubのissueにこんなものがあった．

[vue-router breaks nuxt/types #7502](https://github.com/nuxt/nuxt.js/issues/7502)

解決方法としては，

`tsconfig.json`の中にある`@nuxt/types`をちょっとだけ書き換える

変更後

```
・・・
    "types": [
      "@types/node",
      "@nuxt/types@0.7.9+"
    ]
・・・
```

これだけ．

誰かの参考になれば
DataDog Logsを有効にできないと思ったらええ～～っな原因だった話


```
> sudo nano /etc/datadog-agent/datadoc.yaml
```
して
`logs_enabled: true`
にするのねハイハイ

```
> sudo systemctl restart datadog-agent
> sudo systemctl status datadog-agent
● datadog-agent.service - Datadog Agent
   Loaded: loaded (/lib/systemd/system/datadog-agent.service; enabled; vendor preset: enabled)
   Active: failed (Result: start-limit-hit) since Fri 2020-06-26 05:05:32 UTC; 1min 2s ago
  Process: 6456 ExecStart=/opt/datadog-agent/bin/agent/agent run -p /opt/datadog-agent/run/agent.pid (code=exited, status=255)
 Main PID: 6456 (code=exited, status=255)

Jun 26 05:05:31 ip-172-31-40-66 systemd[1]: datadog-agent.service: Unit entered failed state.
Jun 26 05:05:31 ip-172-31-40-66 systemd[1]: datadog-agent.service: Failed with result 'exit-code'.
Jun 26 05:05:32 ip-172-31-40-66 systemd[1]: datadog-agent.service: Service hold-off time over, scheduling restart.
Jun 26 05:05:32 ip-172-31-40-66 systemd[1]: Stopped Datadog Agent.
Jun 26 05:05:32 ip-172-31-40-66 systemd[1]: datadog-agent.service: Start request repeated too quickly.
Jun 26 05:05:32 ip-172-31-40-66 systemd[1]: Failed to start Datadog Agent.
Jun 26 05:05:32 ip-172-31-40-66 systemd[1]: datadog-agent.service: Unit entered failed state.
Jun 26 05:05:32 ip-172-31-40-66 systemd[1]: datadog-agent.service: Failed with result 'start-limit-hit'.
```

おいどゆこっちゃ。

なんぼやっても結果変わらない
`logs_enabled: true` をコメントアウトしたら動く

で、調べた結果出た答えが

```
##################################
## Log collection Configuration ##
##################################

## @param logs_enabled - boolean - optional - default: false
## Enable Datadog Agent log collection by setting logs_enabled to true.
#
# logs_enabled: false
```
を

```
 logs_enabled: true
```
にしてたけど

```
logs_enabled: true
```
が正解
logs_の前に半角スペース入ってたらダメだった。

ついつい、ほにゃらら.conf とか使っているとコメント外すだけでいけると思いがちだけど、yamlみたいなインデントで深さが決まる系のやつは一番上の階層でスペース入れたらダメと分かるはずと言われれば返す言葉がない。
でもやっちまったものは仕方ない、またやらかす可能性を否定しきれないのでここに残しておく。
Python+Selenium+Chromeでスマホモードに切り替える方法

#1．概要

Python+Selenium+Chromeを用いて自動テストを行っていたのですが、どうもスマホ画面にアクセスするとPC画面にリダイレクトされ、スマホ画面をテストできないことがありました。

そのため、Chromeのスマホモードを使ってうまく自動化できないか調べましたので、その方法をまとめます。

#2．スマホモードで起動するプログラム

調べた結果をまとめると、以下のプログラムを実行することでスマホモードで起動できるようです。（そのままコピペしても動作します）

```python:smp_mood.py
from selenium import webdriver
import time

def smp_mood():
	url = "https://www.yahoo.co.jp/"

	mobile_emulation = { "deviceName": "Galaxy S5" }
	options = webdriver.ChromeOptions()
	options.add_experimental_option("mobileEmulation", mobile_emulation)
	driver = webdriver.Chrome(options=options)

	driver.get(url)
	time.sleep(2)

smp_mood()
```
上記はYahooのサイトに「Galaxy S5」でアクセスしています。

#3.端末の切り替え方

上記プログラムの、

	"Galaxy S5"

を書き換えることで、利用したい端末に変更することが可能です。

切り替えられる端末は、Chromeで右クリックを押下し、「検証」を押下。その後、画面右上のスマホマークを押下しスマホモードに変更後、画面左上に表示されている「端末名＞Edut...」を押下して表示される一覧が、変更できる端末になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/dc90ec60-8e93-e19b-49ea-f2b2d606a0e3.png)

　↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/c088b351-760d-b245-96e1-490b7f46ea90.png)

上記をもとに、

	"iPhone 6"

などと書き換えることで、対象の端末を変更できます。
初めてのアプリ　SwiftUI自動で消えるAnimationを実装

![IMG_6413.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644086/38bafd95-d230-4383-a2ed-6f1711791f53.gif)

アプリの中でよくあるこのような表示ですが、
私のアプリの中にも実装してみたいと思っていました。
結構時間がかかりました。

最初は、Buttonの後ろに.Alertで入れてみましたが、
１秒後に自動に消える機能がなく、AlertのPop画面でユーザに「OK」をクリックしてもらって
消えるしかありません。

そして、プログラミング動画を見てZStackの意味を勘違いしていたのに気づいて、
ZStack Viewで実現できるかもしれないと思って、手を動かして一日くらいやっとう実現できました。

ZStackViewで「画像／文字」のViewを出すのは簡単ですが、
消えてもらうのは難しい、Delay,Disappear,Disable,Removeなど色々KeyWordで検索しても。。。
Animationの中にあるtimingCurveは使えると思っていましたが、勘違いでした。

プログラミング動画（UIKitのAnimationの使い方）を見て、ViewのX/Yの値を変えることによって、
Viewを画面のBottomのさらに下で表示させるか、画面の中で表示させると変えられます。
それを真似してSwift UIの中のOffset（x:,y:）で実装できました！

ソースコードはこんな感じです。
withAnimation{click.wrappedValue = false}は、
withAnimation{click.wrappedValue.toggle()}でもいいですが、
実際に実装する際、他のButtonとViewと支障が出たりするので、
そこら辺をもうちょっと工夫して修正する必要があります。


```swift:starHeadView
func alertMessage(click:Binding<Bool>,imageYes:String,imageNo:String,
                  textYes:String,textNo:String,colorYes:Color,colorNo:Color)
                  -> some View {
        HStack{
            if userData.userStarProfiles[starProfileIndex].favorite {
                Image(systemName:imageYes)
                .frame(width: 30, height: 30)
                .foregroundColor(colorYes)
                Text(textYes).fontWeight(.light)
                .onDisappear(perform: {
                    withAnimation{
                        click.wrappedValue = false
                    }
                })
            }else if !userData.userStarProfiles[starProfileIndex].favorite {
                Image(systemName:imageNo)
                .frame(width: 30, height: 30)
                .foregroundColor(colorNo)
                Text(textNo).fontWeight(.light)
                .onDisappear(perform: {
                    withAnimation{
                        click.wrappedValue = false
                    }
                })
            }
        }
        .animation(Animation.easeOut(duration: 1.5)).offset(x:110,y: click.wrappedValue ? 50 : -300)
    }
```

そして、ZStack Viewの中で上記関数を呼び出す。

```swift:starHeadView
alertMessage(click: self.$favoriteClick, imageYes: "heart.fill", imageNo:"heart", textYes: "好き！", textNo: "", colorYes: .pink, colorNo: .gray)
```
Virtual Chara開発 - その3

店舗接客などに使える仮想のキャラクターが扱えるアプリ開発をしました。そちらの説明はこちらになります。
https://qiita.com/NestVisual/items/fe4dd168178e27156682

環境：
Windows 10
Unity 2018.4.1
RealSense D435i

###Nuitrackのデバッグについて:
![Debug Info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626158/a4236b02-8c94-490d-fcdf-cba19eacc324.png)


テスト中に視覚的なデバッグ情報を得ることは最初から大切でした。Nuitrackのドキュメントページに、骨格データを有用な方法で可視化するUnityのチュートリアルがあるのは良かったです：
https://download.3divi.com/Nuitrack/doc/UnityRGBandSkeletons_page.html
SimpleSkeletonAvatar.cs クラスを継承し、いくつかの調整を加えることで、骨格表現を常に ビデオ画像に合うようにスケールしたり移動させたりすることができました。こうすることで、利用者動画や骨格の可視化を縮小して右上に移動させて、キャラクターの邪魔にならないようにができました。 また、デバッグデータが表示されるのを切り替える機能をキーにマッピングしました。

フェイストラッキングを実装する際には、視覚的なデバッグ用の顔データを表示する機能も必要になりました。残念ながらチュートリアルはありませんが、方法は似ていました。トラッキングされた顔の資料を取る方法はここに記載しています：
https://download.3divi.com/Nuitrack/doc/Instance_based_API.html

Nuitrack.GetInstancesJson()というメソッドがあるので、最新アップデートからすべての顔トラッキング資料を含むjson文字列を返します。この資料を「FaceInfo」というNuitrack SDKクラスに変換することができます。このクラスから得られる最も興味深い変数は 「landmark」 で、31の顔のポイントを含むVector2配列です。これらの正規化された座標から、利用者の顔に対応する目印を動画像上にインスタンス化するための投影座標を計算することができます。

```C#:sample1.cs
private void ProcessFaceLandmark()
{
    nuitrack.Skeleton skeleton = CurrentUserTracker.CurrentSkeleton;
    _faceInfo = NuitrackHelper.GetFaceInfo();

    if (CanProcessFaceLandmark(skeleton))
    {
        for (int i = 0; i < _landmarks.Count; i++)
        {
            Vector2 landmarkNormalizedPos = _faceInfo.Instances[0].face.landmark[i];

            _landmarks[i].SetActive(true);
            _landmarks[i].transform.position = GetLandmarkRenderPosition(_image, landmarkNormalizedPos);
        }
    }
    else
    {
        for (int i = 0; i < _landmarks.Count; i++)    _landmarks[i].SetActive(false);
    }
}

private Vector2 GetLandmarkRenderPosition(RawImage image, Vector2 landmarkPosition)
{
    float width = _image.rectTransform.rect.width;
    float height = _image.rectTransform.rect.height;
    Vector2 imagePosition = _image.gameObject.transform.position;
    float jointX = (imagePosition.x - (width / 2.0f)) + (landmarkPosition.x * width);
    float jointY = (imagePosition.y + (height / 2.0f)) - (landmarkPosition.y * height);
    return new Vector2(jointX, jointY);
}
```
次回はNuitrackの関節の回転制限に関して投稿します。それではまた
【Firebase】Unhandled promise rejection: ReferenceError: Can't find variable: atob と出た時の対処法

#はじめに
ReactNativeとFirebaseを組み合わせていた際に以下のようなエラーが出た

```
Unhandled promise rejection: ReferenceError: Can't find variable: atob
```

Firebase7.9.1以降のバージョンで多くの人が遭遇しているらしい

Firebaseのバージョンを7.9.0に戻すことでも解決できるとは思うが、以下の方法でも解決できた。

base-64モジュールをインストール

```
$ npm install base-64
```

問題のページの一番先頭に以下のコードを記入

```index.js
if (!global.btoa) {
  global.btoa = encode;
}
if (!global.atob) {
  global.atob = decode;
}
import {decode, encode} from 'base-64';
```
Flutter の GlobalKey を StatelessWidget で使いたいときはどうすればいいの？

## TL;DR

`GlobalKey` は `StatefullWidget` で使われる機能で、キーを設定したウィジェットの状態変化を外部から参照できるようになります。
（子ウィジェットの状態変化を親ウィジェットが参照できるなど）



ですが、 `StatelessWidget` では使うことができません。パッケージでキーを利用しているものもあり、困りますよね？
そんなときは `GlobalObjectKey` を使えば OK です！

```dart
class Sample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  
    const key = GlobalObjectKey<FormState>(context);
  
    return RaisedButton(
      child: Text("Button"),
      onPressed: () => key.currentState.save(),
    );
  }
}
```



キーを複数要しする場合に`GlobalObjectKey` のコンストラクタの引数に `context` を渡すとエラーになるので、次のように一意の値を渡すといいです。

```dart
class Sample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  
    const key1 = GlobalObjectKey<FormState>('__KEY1__');
  	const key2 = GlobalObjectKey<FormState>('__KEY2__');

	// ...      	
  }
}
```



## まとめ

TL;DR で終わる短い話でしたが、あまり情報が多く出てこないのでまとめました。
この記事がどなたかの役に立てれば幸いです :yum:



## 参考

:link: [Flutter Widget Keyの種類と使い方について](https://qiita.com/kurun_pan/items/0517fb62f1b47c90882c)
:link: [Multiple widgets used the same GlobalKey error](https://github.com/flutter/flutter/issues/16630)
[awesome][リンク集] コードリーディング

# はじめに

他人のコードや自分が昔に書いたコードを効率良く苦労せずに読む方法のメモとリンク集をまとめていきます。追加の情報があれば、その都度更新します。


# 総論

## 選ぶコツ


- 自分が知ろうとしていることを明確にする
  - 自分が知ろうとしていることが分からない漠然とした状態だと、いくら何かを知ろうとしても何も分かることはない
- 自分が得意とする分野に絞り込む
- 設計ドキュメントが充実しているソフトウェアをピックアップする


## 読むコツ

- 読む前にコードを動かして動作を知る
- コードに関する専門(業務)知識が不足しているなら補足する　
- 静的読解をする
  - コールグラフ(関数同士の呼び出しの関連図)を描く
- 動的読解をする
  - printデバッグ、コードの改造等


# 基礎編

[ソースコードを読むための技術
](http://loveruby.net/ja/misc/readingcode.html)loveruby

[大規模ソースコードの読み方](https://www.slideshare.net/satorutakeuchi18/viewing-source-code)
satorutakeuchi18

[ソースコードの追い方、読み方の方法やコツをまとめておく
](https://boukenki.info/sorce-code-oikata-yomikata-houhou-kotu-matome/)boukenki.info

[How to read code – a primer](https://technikhil.wordpress.com/2010/07/06/how-to-read-code-a-primer/)
Technikhil Writing

[How to quickly and effectively read other people’s code](https://selftaughtcoders.com/how-to-quickly-and-effectively-read-other-peoples-code/)
self-taught coders

[How to read code without ripping your hair out
](https://medium.com/launch-school/how-to-read-source-code-without-ripping-your-hair-out-e066472bbe8d
)Sun-Li Beatteay



# 実践編

[Rubyソースコード完全解説
](http://i.loveruby.net/ja/rhg/book/)loveruby


# オープンソースで学習する

**自分に合ったソフトウェアを探す**

[GitHub](https://github.com/)
言わずと知れたソースコード共有サイト

[sourceforge](https://sourceforge.net/)
様々なオープンソースプロジェクトを探せる

[Google Code Archive](https://code.google.com/archive/d/code.google.com)
sourceforgeと基本的に同じ。現在はサービス終了のため新規プロジェクトはなくアーカイブのみ閲覧できる。

[MINIX](https://en.wikipedia.org/wiki/MINIX)
Unix系のOSに慣れ親しんでいる人向け


---


**良いソースコードに出会うこと**

コードリーディングを身につけるための学習に用いるオープンソースソフトウェアは、設計に関するドキュメントが充実しているソフトウェアをピックアップする


---


**推理小説を読むように楽しむ**

何はともあれ、ソフトウェアを動かさなければ始まらない。動かし方を知る

次に、どんなデザインパターンなのかを意識しながら、物理構造を俯瞰して、main関数から流し読みする

そして、気になる箇所があれば、printデバッグやテスト文を書いて、コードの依存間系を紐解く

コードを読み終えた後の気持ちは、推理小説を読み終えた後の気持ちのようです

---

**目的の決定**

>「ソースコードを読むための極意」は『目的をもって読む』ことです。
これはRuby作者のまつもとさんの言だ。なるほど、この言葉には非常にうなず けるものがある。「カーネルくらいは読んどかなきゃいかんかなあ」と思って ソースコードを展開したり解説本を買ったりしてはみたものの、いったいどう していいのかわからないまま放ってしまった、という経験のある人は多いので はないだろうか。その一方で、「このツールのどこかにバグがある、とにかく これを速攻で直して動かさないと納期に間に合わない」……というときには他 人のプログラムだろうとなんだろうと瞬く間に直せてしまうこともあるのでは ないだろうか。

>この二つのケースで違うのは、意識の持ちかたである。自分が何を知ろうと しているのかわからなければ「わかる」ことはありえない。だからまず自分が 何を知りたいのか、それを明確に言葉にすることが全ての第一歩である。
http://i.loveruby.net/ja/rhg/book/intro.html


---

**目的の具現化**

>まず第一に、そのプログラムを書いた人間になった つもりで考えてみることだ。そのときにはプログラムを作るときの知識が流用できる。例えば伝統的な「構造化」プログラムを読むとしたら、こちらも 構造化プログラムの手法に則って考えるようにする。即ち目的を徐々に徐々に分割していく。あるいはGUIプログラムのようにイベントループに入ってグルグル するものならば、とりあえず適当にイベントループを眺めてからイベントハンドラの役割を調べてみる。あるいはMVC（Model View Controler）のMをまず調べてみる。
http://i.loveruby.net/ja/rhg/book/intro.html

---
Linuxのリダイレクト vol.1

今日はリダイレクトについて。

###リダイレクトとは
出力の向かう先を変更すること、つまりあるページに移行したときに、強制的に別ページに飛ぶことである。
Linuxでは、向かう先を変更するとは、標準入力、標準出力、標準エラー出力のこと。

このコマンド例上では、以下の通りである。
・標準入力：`echo Hello_World`
・標準出力：`Hello_World`
・標準エラー：`-bash: ech: コマンドが見つかりません`

コマンド例
`[root@taki ~]# echo Hello_World
Hello_World
[root@taki ~]# ech Hello_World
-bash: ech: コマンドが見つかりません`


###リダイレクトの使用方法
・標準出力をファイルへ出力する
→画面に出力される文字列をファイルへ保存できる
→コマンドラインでは画面は文字列で大量に埋め尽くされる。**何もしなければ、結果が上へ画面外へどんどん流れていってしまう。結果を確認しようと思っても確認できないという状況が発生する。**
→リダイレクト使いファイルに結果を保存閲覧する

###標準入力、標準出力、標準エラー
Linuxではデフォルトで以下のように割り振られている。
・標準入力→0
・標準出力に→1
・標準エラー出力→2

######実際にやってみよう
1. 標準出力
※1は省略可能

①　標準出力
`[root@taki ~]# echo Hello_world
Hello_world`

②　Hello_WorldをTest_Hello_World.txtに出力している
`[root@taki ~]# echo Hello_World > Test_Hello_World.txt
[root@taki ~]#`

③　②の確認
`[root@taki ~]# cat Test_Hello_World.txt
Hello_World`

④　Hello_WorldをTest_Hello_World.txtに出力している
`[root@taki ~]# echo Hello_World > Test_Hello_World.txt
[root@taki ~]#`

⑤　Close_WorldをTest_Hello_World.txtに出力している
`[root@taki ~]# echo Close_World >> Test_Hello_World.txt`

⑥　⑤の確認
`[root@taki ~]# cat Test_Hello_World.txt
Hello_World
Close_World`

以上よりわかることは、

|記号  |説明  |
|---|---|---|
|>  |標準出力の出力先を指定  |
|>>  |標準出力の出力先を指定し、標準入力出力先に追記  |




###参考文献
https://eng-entrance.com/linux-redirect


長くなったから今日はこの辺で。表を加えることが出来た。表の前には1行空欄を。
【初心者向け】AWSとは？

# AWSとは？
正式名称：**Amazon Web Services**
GCPやAzureに並ぶ、3大クラウドプラットフォームの名称のこと。
元々は、Amazonの社内の**ビジネス課題を解決するため**に誕生した。
2020年6月4日の時点で、**世界シェアの約3割**を占めている。

#### AWSの特徴
**Design for Failure(故障に備えた設計)**がされているため、**耐故障性に優れたクラウド**という特徴がある。この点が利用者が多い理由の一つ。
WEB上からの操作だけで、世界中にサーバーを立てられるようになっており、個人がクラウドサーバを用意することも容易にできます。

#### AWSをこれから使おうとされている方へ、ちょっとした情報をご提供
・アカウント作成は無料
・料金は従量課金制 (アカウント開設時には無料枠が適用されます。)
詳しくは以下のURLを参照
https://aws.amazon.com/jp/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc
・AWS認定資格あり
・国内のイベントやセミナーが豊富
・東京に「AWS Loft Tokyo」という場所がある。
ここでAWSの相談もできる。
(おしゃれなオフィスで一日中滞在可能！私も行ってみたい！)

### 有名なサービスの例
**・Amazon S3 (最強のファイル置き場！と言われている)**
(Simple Strage Serviceの略)
最初はこれだけだったそうです。

**・Amazon EC2 (仮想サーバ)**
(Elastic Compute Cluodの略)
Elasticには、弾力のある、伸縮自在な、という意味があります。
※仮想サーバを後から増やしたり、減らしたりすることが容易にできるから。

他にも100種類以上のサービスがあります。
AWSのURL：https://aws.amazon.com/jp

簡単にですが、AWSについて書かせていただきました。
texをatomで使う


*texはインストール済みの話

#### atomを開いてパッケージをインストール

`language-latex` : Atom内でLaTeXのシンタックスハイライトを行う
`latex` : Atom内でLaTeXのスクリプトをコンパイルする
`pdf-view` : Atom用のPDF viewer

必要ならインストール
`latexer` : Atom内でのLaTeXの自動補完
　　・ `\cite{`とか書くと補完候補を出してくれる

#### 日本語に対応させる
そのままでは日本語でエラーがでるので日本語対応させる

`latex`パッケージのsettingsに行き、
`Engine`を`uplatex`に変更してatomを再起動


これでcommand+sでセーブすると勝手にビルドされてpdfが出てくるようになる

勝手にビルドをやめてほしい場合は`latex`のsettingsの
`Build on Save`のチェックを外す

以上


bibtexをatom上で使う方法まだわからないので
使い方がわかったら追記

追記： bibtexも勝手にタイプセットしてやってくれるみたい。
試しに参考文献引用してみたらbibtexもタイプセットしてくれていた
GnuPG での鍵の生成方法

# GnuPG での鍵の生成方法
## 主鍵(MasterKey)の作成
主鍵を生成する.
事前に`.gnupg/gpg-agent.conf`に`pinentry-program`の設定をしておくことをお勧めする．

```console
% gpg --full-gen-key
```
ここではReal Nameを`hoge`, Mail addressを`foo@var.com`としています．

```console
gpg: keybox'/Users/hoge/.gnupg/pubring.kbx'が作成されました
ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
  (14) カードに存在する鍵
あなたの選択は? 1
RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (2048) 4096
要求された鍵長は4096ビット
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0) 0
鍵は無期限です
これで正しいですか? (y/N) y

GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名: hoge
電子メール・アドレス: foo@var.com
コメント:
次のユーザIDを選択しました:
    "hoge <foo@var.com>"

名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)? o

公開鍵と秘密鍵を作成し、署名しました。

pub   rsa4096 2020-06-26 [SC]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid                      hoge <foo@var.com>
sub   rsa4096 2020-06-26 [E]
```
個人管理のマスタ−キ−なので，期限は無期限としています．
またマスタ−キ−は，`~/.gnupg`ディレクトリごと外部ストレ−ジなどにコピ−して保管しておくこと．

## 複鍵(SubKey)の作成
期限付きの複鍵を生成します．ここでは6ヶ月の期限とします．

```console
% gpg --edit-key "hoge <foo@var.com>"
gpg (GnuPG) 2.2.20; Copyright (C) 2020 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

秘密鍵が利用できます。

sec  rsa4096/YYYYYYYYYYYYYYYY
     作成: 2020-06-26  有効期限: 無期限      利用法: SC
     信用: 究極        有効性: 究極
ssb  rsa4096/ZZZZZZZZZZZZZZZZ
     作成: 2020-06-26  有効期限: 無期限      利用法: E
[  究極  ] (1). hoge <foo@var.com>

gpg> addkey
ご希望の鍵の種類を選択してください:
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
   (5) Elgamal (暗号化のみ)
   (6) RSA (暗号化のみ)
  (14) カードに存在する鍵
あなたの選択は? 6
RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (2048) 4096
要求された鍵長は4096ビット
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0)6m
鍵は水 12/23 12:16:18 2020 JSTで期限切れとなります
これで正しいですか? (y/N) y
本当に作成しますか? (y/N) y
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。

sec  rsa4096/YYYYYYYYYYYYYYYY
     作成: 2020-06-26  有効期限: 無期限      利用法: SC
     信用: 究極        有効性: 究極
ssb  rsa4096/ZZZZZZZZZZZZZZZZ
     作成: 2020-06-26  有効期限: 無期限      利用法: E
ssb  rsa4096/WWWWWWWWWWWWWWWW
     作成: 2020-06-26  有効期限: 2020-12-23  利用法: E
[  究極  ] (1). hoge <foo@var.com>

gpg> save
```

## 作成した複鍵を出力する

```console
gpg --export-secret-keys WWWWWWWWWWWWWWWW > secret.gpg
gpg --export WWWWWWWWWWWWWWWW > public.gpg
```
6ヶ月で失効する期限付きの秘密鍵と対の公開鍵が出力されている．秘密鍵の管理は厳重に．

## このあとにすること
コマンドラインベ−スのパスワ−ド管理ツ−ル[Pass](https://www.passwordstore.org/)に適用するためにいろいろと試す予定．
【Swift】 Color Setを使うときのちょっとした注意

iOS11(Xcode9)からImage Setのように、色を定義することの出来るColor Setが実装され、Storyboard上での色管理の煩わしさから開放されました。
もちろん、コード上からも使うことが出来てとても便利なのですが、ちょっとした注意点があったので、備忘録として残しておこうかなと思いました。

あるプロジェクトで遭遇したことなのですが、Storyboard上で定義したLabelで、コード上からAttributedTextで色を変更しようとしたときのことです。
iOS13で起動したときは確かに色が変わっていたはずなのに、iOS11や12の端末で起動してみると、

### 色が変わらない

という現象が発生しました。
Great Scott!（BTTF大好き）と何度もつぶやきながら調べましたが、どうやら原因は「Storyboard上でColor Setを使用しているから」のようです。

特にサイトを調べたりしたわけではなく、Storyboardをいじっていたら発見したことなので本当かは定かではありませんが、少なくともStoryboard上で該当LabelのtextColorを、Xcodeで最初から定義されている色（black, white, default, etc...）に戻して再度アプリを実行すると、

### ちゃんと色が変わってる！

という結果が得られました。

## まとめ

iOS11や12を対象とするプロジェクトでColor Setを使う場合、Storyboardで設定した色を変更するときは注意が必要です。

意外と見落としがちなところかもしれないので、実際にそういったアプリを制作されている方は少しだけ注意したほうがいいかもしれません
docker on raspberry pi

# Introduction
[overview](https://docs.docker.com/get-started/overview/)
![](https://docs.docker.com/engine/images/architecture.svg)
# Install
`sudo apt-get update && sudo apt-get upgrade`
`curl -sSL https://get.docker.com | sh`
# Setting
Create the docker group.
`sudo groupadd docker`
Add a Non-Root User to the Docker Group
`sudo usermod -aG docker [user_name]`
`sudo usermod -aG docker ${USER}`
`sudo usermod -aG docker pi`
You would need to loog out and log back in so that your group membership is re-evaluated or type the following command:
`su -s ${USER}`

**[Check your env](https://iotbytes.wordpress.com/create-your-first-docker-container-for-raspberry-pi-to-blink-an-led/)**
```
cat /proc/cpuinfo | grep model
cat /etc/os-release
```
analyze an image file
[https://github.com/wagoodman/dive](https://github.com/wagoodman/dive)

# Verify
`docker run hello-world`
`docker image pull nginx`
`docker image inspect nginx`
# Cheatsheet  
[PDF](https://www.docker.com/sites/default/files/d8/2019-09/docker-cheat-sheet.pdf)
# Build
Build an image from the Dockerfile in the current directory and tag the image
`docker build -t myimage:1.0 .`
List all images that are locally stored with the Docker Engine
`docker image ls`
Delete an image from the local image store
`docker image rm alpine:3.4`

# Remove all image
`docker rmi $(docker images -a -q)`
`docker container rm $(docker container ls -aq)`
# Run

`docker run -it <image> /bin/bash`  

Run a container from the Alpine version 3.9 image, name the running container “web” and expose port 5000 externally, mapped to port 80 inside the container.
`docker container run --name web -p 5000:80 alpine:3.9`
Stop a running container through SIGTERM 
`docker container stop web`
Stop a running container through SIGKILL
`docker container kill web`
List the networks
`docker network ls`
List the running containers (add --all to include stopped containers)
`docker container ls`
Delete all running and stopped containers
`docker container rm -f $(docker ps -aq)`
Print the last 100 lines of a container’s logs
`docker container logs --tail 100 web`
# Share
# Copy Docker images to another host
To get the image id:
`sudo docker images`
Say you have an image with id(**REPOSITORY**) "table-data".
Save the image with id:
`sudo docker save -o /home/table/table-data.tar table-data`
Copy the image from the path to any host. Now import to your local Docker installation using:
`sudo docker load -i <path to copied image file>`
# hub

# Choose Docker Base Image Wisely
https://towardsdatascience.com/how-to-build-slim-docker-images-fast-ecc246d7f4a7
https://pythonspeed.com/articles/base-image-python-docker-images/

open cv docker
[1.v3 & v4](https://github.com/mohaseeb/raspberrypi3-opencv-docker)
[2.v3](https://github.com/sgtwilko/rpi-raspbian-opencv)
# [tutorial](https://docker-curriculum.com/#playing-with-busybox)
C++備忘録：文字列に関する色々

こんにちは。C++を学び始めました。
文法ミスでエラー出してハマることが多いので、テンプレを記録して困ったときはこれを見ます。
今回は、文字列周り。

参考：http://vivi.dyndns.org/tech/cpp/string.html#decl

2020/06/27 修正: @tyu_ru_cpp様のコメントよりアドレスのキャストに関し修正致しました

```c++:string_templete.cpp
#include <bits/stdc++.h>
using namespace std;

vector<string> split(const string &str, char sep);

// 文字列系
int main(){
  string s; //空文字列で初期化
  string str = "aiueo"; //初期化
  string str_copy(str); //コピーコントラクタ
  cout << str.size() << endl; //文字数
  cout << str.length() << endl; //文字数
  cout << str.capacity() << endl; //確保メモリ数
  cout << (void*)&str[0] <<' '<< reinterpret_cast<uintptr_t>(&str[0]) << endl; //先頭アドレス(１６進表示・１０進表示)
  cout << (void*)str.c_str() <<' '<< reinterpret_cast<uintptr_t>(str.c_str()) << endl; //先頭アドレス(１６進表示・１０進表示)
  cout << (void*)str.data() <<' '<< reinterpret_cast<uintptr_t>(str.data()) <<  endl; //先頭アドレス(１６進表示・１０進表示)
  cout << str.front() << ' ' << str[0] <<endl; //先頭文字
  cout << str.back() << ' ' << str[str.size()-1] << endl; //末尾文字
  str.push_back('k'); cout << str << endl; //末尾に文字を追加
  str.pop_back(); cout << str << endl; //末尾の文字を削除
  cout << str.substr(2, 2) << endl; //文字列切り出し(開始位置番号, 切り出し長)
  str_copy.clear(); cout << str_copy << endl; //文字列を空にする 
  cout << str_copy.empty() << ' ' << (str_copy == "") << endl; //空判定;
  string str_num = "12345"; cout << atoi(str_num.c_str()) << endl; //文字列整数をintに変換
  str.resize(3); cout << str.size() <<' '<< str << endl; //文字列を一定長さにする(はみ出た分はカット)
  str.resize(8,'a'); cout << str.size() <<' '<< str << endl; //文字列を一定長さにする（余りの部分を文字で埋める）
  str.reserve(1000); cout << str.capacity() << endl; //高速化の為に先に十分なメモリを確保
  str.shrink_to_fit(); cout << str.capacity() << endl; //余分なメモリを開放
  string a="a", b= "b"; a.swap(b); cout <<"a:"<< a <<" b:"<< b <<endl; //文字列同士を交換
  str="aiueoaiueo"; cout << (int)str.find("ue") << endl; //文字列内の文字列を検索し位置を返す
  str="aiueoaiueo"; cout << (int)str.find("ue",5) << endl; //文字列内の指定位置から文字列を検索し位置を返す
  str="aiueoaiueo"; cout << (int)str.rfind("ue") << endl; //文字列内の文字列を先頭方向に検索し位置を返す
  str="aiueoaiueo"; cout << (int)str.rfind("ue",5) << endl; //文字列内の指定位置から先頭方向に文字列を検索し位置を返す
  str="aiueo"; cout << str.replace(1,2,"xyz") << endl; //指定位置から文字数だけ置換文字列で置換する（指定位置,置換対象文字数,置換文字列）
  string num = to_string(123.456); cout << num << endl; //整数や浮動小数点数を文字列に変換 
  vector<string> strvec; //文字列の配列の宣言
  vector<string> strVec = {"abc", "123", "xyz"}; cout << strVec[0] << endl; //文字列の配列をリテラルで初期化
  list<string> strList = {"abc", "123", "xyz"}; auto itr = strList.begin(); cout << *itr << endl; //listによる文字列の配列
  //split関数(下記定義): 指定区切り文字で文字列を分割し配列に
  vector<string> vec = split("abcdefg", 'd'); for(int i=0; i<vec.size(); i++) cout << vec[i] << ", "; cout<<endl;
  return 0;
}

//split関数(下記定義): 指定区切り文字で文字列を分割し配列に
vector<string> split(const string &str, char sep){
    vector<string> v; // 配列の空箱
    stringstream ss(str);
    string buffer; 
    while(getline(ss, buffer, sep)) v.push_back(buffer);
    return v;
  }

/*------------------実行結果--------------------
5
5
15
0x61fe00 6422016
0x61fe00 6422016
0x61fe00 6422016
a a
o o
aiueok
aiueo
ue

1 1
12345
3 aiu
8 aiuaaaaa
1000
15
a:b b:a
2
7
7
2
axyzeo
123.456000
abc
abc
abc, efg,
*/
```
Docker Compose Yaml形式のECSタスク定義で、DependsOnを利用する方法

# 概要

タスク定義（JSON）で指定できる全てを Docker Compose Yaml 形式で指定できるわけではありません。
そのため、一度 Docker Compose Yaml 形式でタスク定義を作成したあとに、jqコマンドで修正します。
今回は設定したい優先度が（私の中で）高いDependsOnを設定するのが主目的ですが、似たような方法で他の項目も修正可能です。

## Docker Compose Yaml形式でのタスク定義作成

```docker-compose.yml
version: '3'
services:
  app:
    image: nginx
    ports:
      - "80:80"
    logging:
      driver: awsfirelens
      options:
        Name: datadog
        apiKey: "hogehoge"
        dd_service: "app-service"
        dd_source: "nginx"
        dd_tags: "project:example"
        provider: "ecs"
  log_router:
    image: 906394416424.dkr.ecr.ap-northeast-1.amazonaws.com/aws-for-fluent-bit:latest
    logging:
      driver: awslogs
      options:
        awslogs-group: firelens-container
        awslogs-region: ap-northeast-1
        awslogs-stream-prefix: firelens
        awslogs-create-group: "true"
```

Taskは[以前の私の記事](https://qiita.com/edi_t/items/877243fb98a05c0db472)を流用してます。
中身そのものに興味がある場合は読んでいただければと思います。
また、Docker Compose Yaml形式でのタスク定義そのものについてはAWS公式を見てください。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/cmd-ecs-cli-compose-ecsparams.html

ここでは、`app` と `log_router` に依存関係を設定したい(DependsOn）と思います。

```sh
ecs-cli compose --project-name app-task \
-f docker-compose.yml \
--ecs-params "ecs-params.yml" \
create --region ap-northeast-1 \
--launch-type EC2
```

## DependsOn設定

```sh
taskDefinitionArn=$(aws ecs list-task-definitions --family-prefix app-task --status ACTIVE --sort DESC --max-items 1 | jq -r '.taskDefinitionArns[0]')
taskDefinition=$(echo ${taskDefinition} | jq -r '.containerDefinitions[] |= if .name == "app" then . + {"dependsOn":[{"containerName":"log_router","condition":"HEALTHY"}]} else . end')
aws ecs deregister-task-definition --task-definition ${taskDefinitionArn}
aws ecs register-task-definition --cli-input-json "${taskDefinition}"
```

一度作成されたTask情報を出力して、JSON構文を解析し、適切な箇所に `dependesOn` 設定を埋め込みます。
jqで必要な箇所を特定して埋め込むのは少し慣れが必要です（私は必要でした）。
詳細は下記公式を参照して、機能を駆使してください。

https://stedolan.github.io/jq/

Task定義のJSON構文は下記公式情報を参照してください。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html

その後、改修したTask情報（JSON）でTask定義を再作成します。
再作成前に元のTask定義は削除(deretister)しておきます。


## まとめ

こんな感じで、タスク定義を作成したあとに修正したタスク定義をもう一度作成するという方法で可能です。
タスク定義のリビジョンは2つインクリメントされますが、リビジョンは1万まで増やせるのでたぶん、大丈夫だと思います。

問題は埋め込む箇所がちょっと入り組んでると、jqコマンドを組み立てるのがちょっと難しいというのがあります。
`ecs-cli` ツールがバージョンアップすれば対応する設定も増えていくと思います。
ですが、残念ながら現状では記述のし安さや可読性と引き換えに、タスク定義の全ての設定をYamlで記述することはできません。
需要は少ないかもしれないですが、AWSにはアップデートをがんばってもらいたいです。
[AWS RDS][Rails]環境構築

# これは何
Railsでアプリを作成中、データベースをRDSに切り替えました。
Qiitaの記事などでRDSの作成手順はあるのですが、その後のRailsのデータベースとして設定していくのにハマったので備忘録として残します。

# バージョン
Rails 5.2.4.2
MySQL 5.6.4

# RDS構築
私はUdemyの教材を参考に作成しましたが、
こちらの記事を参考にすれば問題ないかなと思います。
[(DB・サーバー構築編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで](https://qiita.com/naoki_mochizuki/items/22cfbf4bf7ec95f6ac1c)

# 設定
database.ymlの記述を変えていくのですが、そこにパスワード などを直接記入することはセキュリティ上問題なので、credentials.ymlを使っていきます。

```credentials.yml
rds:
  DATABASE_USERNAME: *****
  DATABASE_PASSWORD: ターミナルからRDSに接続するときのパスワード
  DATABASE_HOST: RDSのエンドポイント
```
RDSのエンドポイントは、AWSコンソールのRDSのデータベースをクリックして、下にスクロールするとあります。

続いて、database.ymlの変更

```database.yml
production:
  <<: *default
  database: アプリ名_production
  username: <%= Rails.application.credentials.rds[:DATABASE_USERNAME] %>
  password: <%= Rails.application.credentials.rds[:DATABASE_PASSWORD] %>
  host: <%= Rails.application.credentials.rds[:DATABASE_HOST] %>
  socket: /var/lib/mysql/mysql.sock
```
終わったら、プッシュアンドデプロイ。


ターミナルからRDSに接続し、

```
mysql>　show tables from アプリ名_production;
mysql>  select * from アプリ名.users;
```
などで中身を確認してみましょう！
反映されていますかね〜。

私はRDSに切り替えるのにずっと検索し続け、1日かかりました、、、

何はともあれ以上です！
ありがとうございました！
Qiita の記事を自動投稿するシステムをサーバーレスで組んだ

サーバーレスの勉強と実益を兼ねて、[自分のQiitaの記事](https://qiita.com/hassaku_63)を自動でサマリして簡単なポートフォリオ代わりに使える記事を出してみようと思いました。

# 成果物

こちらの記事です。

[Qiita Contributions Portfolio (Auto Generated)](https://qiita.com/hassaku_63/items/6a042079656ee4c19edc)

自分の投稿記事について、使用したタグと Like数が多いものを表示します。


# 要件

- 自分が投稿したすべての記事を集計して、その集計結果を報告する記事を自動生成したい
- 自動生成する記事は、定期的に集計結果の更新を行い、その結果が自動的に反映されるようにしたい

# 構成図

全体的な構成は以下の図の通りです。

![qiita-publish-outline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78417/e50828e0-2220-630f-14ce-b3e91751a586.png)

記事の作成／更新の機能と、記事の投稿内容となる変数の部分を計算するジョブの2つの部分からなります。

事前に Jinja2 をベースにした記事のテンプレートを作成しておきます。記事のタイトルやタグ、テンプレート変数を動的に DynamoDB から取得して本文をレンダリングし、投稿します。 Qiita への投稿部分は Step Functions で実装しています。

テンプレート変数部分は定期的に再計算して記事更新したいので、テンプレート変数の値を求めるための lambda を別で動かしています。集計処理と記事投稿は密結合したくない要素なので、自動投稿との間に SQS を挟んでいます。

SQS のコンシューマ側にあたる lambda でテンプレート変数を DynamoDB に永続化し、続いて Step Functions を起動します。

DynamoDB では 記事ID をハッシュキーとして記事情報を保持します。次のような情報を持っています。

- タイトル、タグ
- テンプレート変数（本文のレンダリングに使用）
- レンダリング時に使用すべきテンプレートの名前
- Qiita の記事公開状態のステート（公開済みである場合は、Qiita側が持っている記事IDも保持）

Step Functions の中身は次のような内容になっています。

![qiita-publish-sfn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78417/26409efc-c688-e9ac-6996-c8f46c6d72ff.png)

このステートマシンは入力として記事ID（QiitaのItem IDではなく、このシステム内部でのみ使用する管理用変数）を受け取ります。

記事ID を指定して、 DynamoDB から投稿内容等の情報を取得します。見つからなければ記事投稿の情報が存在しないということなので、その時点で Fail させます。

次に、公開状態のステートを評価します。公開済みステートの場合は Qiita API を呼び出し、その記事が実際に存在しているかどうかを確認します。

その後、公開状態のステートを評価し、記事を新規作成すべきか、更新すべきかを判定します。新規作成の場合は最後に公開状態のステートを更新して終了です。

# 設計ポイント

記事更新に必要な構成要素はほぼ集計側から分離している点が設計上のメリットとなります。集計側としては結果を dict にしてキューイングするだけでよく、後続に存在する DynamoDB や Step Functions などの詳細は知る必要がありません。

今回は1つの記事だけ自動生成していますが、別の記事を同じ仕組みに乗せることも簡単です。任意の記事IDを決めてあげて、

- 記事のテンプレート (Jinja2) を作成
- DynamoDB に記事の投稿情報を Put しておく
  - タイトル、タグ
  - 作成したテンプレートの名前
- テンプレート変数の値を計算するための仕組み (今回の例ではlambda を使用) を開発する
  - 計算したテンプレート変数は SQS にキューイングする

Qiita の投稿部分に Step Functions を使用したことで、中で行うロジックの見通しが良くなっています。雑に lambda を書いていると1本の function に多くの仕事をさせてしまいがちですが、Step Functions であれば各ステップの実装だけを綺麗にやれば後は繋ぎ込みを Serverless Framework のリソース定義で用意するだけです。

function 1本あたりでやっていることがシンプルなので、自然とコードは本質的なロジックのみをそれぞれ関数化しただけの、すっきりした構造になります。 また、Step Functions では分岐の制御構造を No Code で実装できるので、（今回の例では微々たる量ではあるものの）コードの記述量もより少なく済みます。

# 改善点

いくつかありますが、目につくのは次のポイントです。

- Jinja2 テンプレートがソースコードに直接含まれている
  - S3 に置けるようにしたい
- 初投稿を行うためには、予め DynamoDB に記事投稿の情報を Put しておく必要がある
  - 単純に面倒くさい
- 他の人に横展開しづらい構成になっている
  - 私が作成したい記事の集計ロジックと jinja2 テンプレートが投稿システムと同じソースに含まれてしまっている

他の人にも使ってもらおうと考えたとき、私が使っている Jinja2 のテンプレートがソースに含まれている状態はあまりよろしくない感じがします。また、テンプレートは Static Contents なので、置き場はできれば外部化したいです。

Jinja2 + S3 なら誰かが拡張機能を作ってそうな気はするので、既存パッケージを使って実現可能ならサクッとやりたいです。ローカルか S3 か、データソースを選択できるようになってるとよりよいのではないか、という気もします。

# ソース

https://github.com/hassaku63/qiita-autogenaration

モジュールの切り方や命名にセンスがないので改善したいなという思いはありますが、ひとまず公開してみました。

sfn のタスク名などもいい加減なのでいずれ直したいですが、ご査収ください。

aws 関係は libs/aws/ 以下に寄せる、 libs/ 直下にはユースケース的な抽象インタフェースにして裏の仕組み (AWS) を意識させない名前を提供するように変更する、などの改善余地があると考えています。
【初心者】Mac OS Catalina でパスを通すまで



## はじめに

Macを使い始めた、現在プログラミング勉強中の初心者です。
OS：Catalina

今回Laravelの環境構築でパスを通す時につまずいたのでその解決方法です。

##### Laravelに限らず、環境構築の段階でパスを通すことは多いと思います。
##### つまずくことも多いと思ったので参考になればと思い作成しました。

パスを通すとは？　という方へのオススメ記事
[PATHを通すとは？ (Mac OS X)](https://qiita.com/soarflat/items/09be6ab9cd91d366bf71)

## 対象者
- 勉強を始めた初心者の方

- Mac OS Catalina を使っている方

- パスが通ったが設定が保持されず困っている方

## 問題が起きた手順
まず、下記を参考にまずパスを通しました。
[PATHを通すために環境変数の設定を理解する (Mac OS X)](https://qiita.com/soarflat/items/d5015bec37f8a8254380)

具体的にはこんな感じです↓

ホームディレクトリの```.bash_profile```（なければ作成）に追加したいパスを記述
（```.bash_profile```はbashを使う際に読み込まれるファイルの１つです）

```:.bash_profile
export PATH=$HOME/.composer/vendor/bin:$PATH
```

```source``` コマンド（ファイルに書かれたコマンドをシェルで実行するコマンド）で実行 

```:ターミナル
source ~/.bash_profile
```



実行するとその時は使えるが、ターミナルの新規ウィンドウや再起動後はパスが通っていない表示がされてしまう

```:ターミナル
% laravel -v
zsh: command not found: laravel
```

## 原因
###**シェルの種類が違っていた**
調べたところ、Macのシェルはこれまでは ```bash``` を使っていたが、Catalinaから ```zsh``` に変更されたとのこと。
【参考】：[zsh を Mac のデフォルトシェルとして使う](https://support.apple.com/ja-jp/HT208050)

そのため、Macユーザー向けの記事でもCatalina以前のOSだと注意が必要。

```zsh``` というシェルを使っているのにパスの設定を```bash```用で行っていたためうまく行かないのだとわかった。

##解決策

###**ファイル名を変更するだけ**

bashにおける```.bash_profile```　は　zshにおける```.zprofile```というファイルのため中身はそのままにファイル名を変更

```:ターミナル
mv ~/.bash_profile .zprofile
```
※同じくホームディレクトリには```.bash_history```という似た名前のファイルがあるので気をつけてください。

再びsourceコマンドを実行
 
```:ターミナル
source ~/.zprofile 
```
これで再起動後も問題なくパスが通るようになりました。
AtCoder Beginner Contest 171におじさんが挑戦しました

##はじめに
今回、AtCoderに初めて挑戦しました。
結果は6問中惨敗でした。
今までの軌跡は[こちら](https://qiita.com/gtkr/items/228d16314576974e9b07)にまとめています。
本家の解説は[こちら](https://img.atcoder.jp/abc171/editorial.pdf)です。

##αlphabet
問題は[こちら](https://atcoder.jp/contests/abc171/tasks/abc171_a)。
これに対して自分の回答は以下です。

```cpp
#include<iostream>

using namespace std;

int main()
{
    char a, b, c;
    cin >> a;

    if(90 >= a && a >= 65)
        cout << 'A' << endl;
    else if(122 >= a && a >= 97)
        cout << 'a' << endl;

    return 0;
}
```
大文字と小文字は文字コードが連続しているので、それで判別しています。

本家の解説ではPythonでislower関数を使って、数行で済ませていました。
なんか、悔しいですね。
短い時間でコーディング量を減らすには、ある程度ライブラリ類を覚えておく必要がありますね。

##Mix Juice
問題は[こちら](https://atcoder.jp/contests/abc171/tasks/abc171_b)。
これに対して自分の回答は以下です(不正解ですが・・・)。

```cpp
#include<iostream>
#include<cmath>
#include <cstring>

using namespace std;

int main()
{
    int n, k;

    cin >> n >> k;

    int* vals = new int[n];
    int* comb = new int[k];
    int tmp_val;
    int min = 1000 * 1000;
    int pattern = pow(n, k);

    for(int i = 0; i < n; i++)
    {
        cin >> vals[i];
    }

    for(int i = 0; i < pattern; i++)
    {
        int tmp = i;
        tmp_val = 0;
        for(int j = 0; j < k; j++)
        {
            comb[j] = tmp % n;
            tmp_val += vals[comb[j]];
            tmp /= n;
        }

        bool flag = false;
        for(int j1 = 0; j1 < k ; j1++)
        {
            for(int j2 = 0; j2 < k; j2++)
            {
                if(j1 == j2) continue;
                if(comb[j1] == comb[j2])
                {
                    flag = true;
                    break;
                }
            }
            if(flag) break;
        }
        if(flag) continue;

        if(min > tmp_val)
        {
            min = tmp_val;
        }
    }

    cout << min << endl;
    return 0;
}
```
コードが長いですね。
いい方法が思いつかず、全探索しています。
解説みると先にソートしてますね。言われてみれば確かに！という感じです。
ちなみに不正解の理由はよくわかってません・・・

##One Quadrillion and One Dalmatians
問題は[こちら](https://atcoder.jp/contests/abc171/tasks/abc171_c)。
これに対して自分の回答は以下です(不正解ですが・・・)。

```cpp
#include<iostream>
#include<sstream>
#include<algorithm>

using namespace std;

int main()
{
    int n;
    char c_base = 97;
    stringstream name;

    cin >> n;
    int tmp = n - 1;

    while(tmp >= 26)
    {
        char c = tmp % 26;
        tmp /= 26;
        name << (char)(c_base + c);
    }

    char c = tmp % 26;
    name << (char)(c_base + c - 1);

    string name2 = name.str();
    reverse(name2.begin(), name2.end());
    cout << name2 << endl;;

    return 0;
}
```
26進数の問題ですね。
方向性は解説と一致していると思います。
ただ、自分の回答は桁上がりの前後で思った値にならず、不正解となっています。
落ち着けばすぐ直せたと思いますが、残り時間が少なくなるとパニックになりますね・・・

##残り
* Replacing
* Red Scarf
* Strivore

回答できず！
【spock】application.propertiesの外部設定値を取得する(ダミーのproperty設定)

application.propertiesに設定している値を
コントローラやサービスで取得することがあると思います。
今回はそれのspockの書き方メモ

```properties:application.properties
test.param=test_aaaaaaaa
```

```java:Controller
//省略
@Value("test.param")
private String param;
//省略
```

spock側ではこう書く

```groovy:ServiceImplTest

    @RunWith(Sputnik.class)
class ServiceImplTest extends Specification {

    SampleController target

    def setup() {
        target = new SampleController()
    }

    @Unroll
    def "application.propertiesの外部設定値を取得する"() {
        setup:
         ReflectionTestUtils.setField(target, "param", "test_aaaaaaaa")

        when:
        //省略

        then:
        //省略

        where:
        //省略
    }
```

## おわり
上記のように記載してあげればよしなにしてくれる
GoogleChrome 人のサイトの任意の場所にアンカーリンク＋ハイライト表示

# アンカーリンクって知ってる？

[アンカーリンク](#アンカーリンク)
でページ内の指定の場所に移動するやつ。
ページ内リンク。

# 通常のアンカーリンクの設定方法
HTMLタグの`id`要素にごにょごにょ書いて、そこにリンクを指定する。

```HTML
<h1>
  <span id="アンカーリンク" class="fragment"></span>
  <a href="#アンカーリンク">
    <i class="fa fa-link"></i>
  </a>
  アンカーリンク
</h1>
```

# GoogleChromeの機能
`#:~:text=ページ内リンク` って指定すると、`id`設定無くても好きなところにジャンプできるよ！
[ページ内リンク](#:~:text=ページ内リンク)
指定箇所が黄色でハイライトされるよ！
指定文字が複数ある場合は先頭にマッチしたところでとまるよ！
長い文章のハイライトにも対応してるよ！
　`#:~:text=ごにょごにょ,指定`
 [ごにょごにょ](#:~:text=ごにょごにょ,指定)

（追記）
Qiitaで反応しない、、、かなしみ
[wikipedia:ケルビン] (https://ja.wikipedia.org/wiki/%E3%82%B1%E3%83%AB%E3%83%93%E3%83%B3#:~:text=%E7%B5%B6%E5%AF%BE%E9%9B%B6%E5%BA%A6,%E4%B8%89%E9%87%8D%E7%82%B9%E3%81%AE%E7%86%B1%E5%8A%9B%E5%AD%A6%E6%B8%A9%E5%BA%A6)
あとマークダウンでも反応しない、、、かなしみ
動作は以下のリンクで確認してね（）
https://ja.wikipedia.org/wiki/%E3%82%B1%E3%83%AB%E3%83%93%E3%83%B3#:~:text=%E7%B5%B6%E5%AF%BE%E9%9B%B6%E5%BA%A6,%E4%B8%89%E9%87%8D%E7%82%B9%E3%81%AE%E7%86%B1%E5%8A%9B%E5%AD%A6%E6%B8%A9%E5%BA%A6

# アンカーリンク
これはページ内リンク用の段落です。

# Qiitaデビュー
初めて記事を書いたよ。
リンク周りは自分の記事がどういうリンクになるか分からないから暫定で、後で修正するよ。

# （追記の追記）いろいろ試す。
[マークダウンでアンカー指定のみ](#:%7E:text=%E3%83%9A%E3%83%BC%E3%82%B8%E5%86%85%E3%83%AA%E3%83%B3%E3%82%AF)
[マークダウンでフルURL](https://qiita.com/bracket_i/items/dcc69f0158cddf8e8c85#:%7E:text=%E3%83%9A%E3%83%BC%E3%82%B8%E5%86%85%E3%83%AA%E3%83%B3%E3%82%AF)
フルURL：直書き
https://qiita.com/bracket_i/items/dcc69f0158cddf8e8c85#:%7E:text=%E3%83%9A%E3%83%BC%E3%82%B8%E5%86%85%E3%83%AA%E3%83%B3%E3%82%AF

上と同じリンク
[マークダウンでwikipedia:ケルビン] (https://ja.wikipedia.org/wiki/%E3%82%B1%E3%83%AB%E3%83%93%E3%83%B3#:~:text=%E7%B5%B6%E5%AF%BE%E9%9B%B6%E5%BA%A6,%E4%B8%89%E9%87%8D%E7%82%B9%E3%81%AE%E7%86%B1%E5%8A%9B%E5%AD%A6%E6%B8%A9%E5%BA%A6)
直書きでwikipedia
https://ja.wikipedia.org/wiki/%E3%82%B1%E3%83%AB%E3%83%93%E3%83%B3#:~:text=%E7%B5%B6%E5%AF%BE%E9%9B%B6%E5%BA%A6,%E4%B8%89%E9%87%8D%E7%82%B9%E3%81%AE%E7%86%B1%E5%8A%9B%E5%AD%A6%E6%B8%A9%E5%BA%A6
Rspecではデフォルトでviewテンプレートがレンダリングされない

長年minitestを使っていて、rspecを書くことになったのですが、rspecだとコントローラのテストを書く時にデフォルトではviewファイルがレンダリングされない事を知らず。本番で変数がnilでバグが出るという現象に遭遇しました。

rspecでは明示的に`render_views`を呼ぶことでviewテンプレートの内容もテストする事ができます。


```
require "spec_helper"

describe RecordsController do
  render_views

  describe "GET index" do
    # ...
  end
end
```
Laravel v7で「Formクラスが無い」とエラーが出た時の対処法

# formファサードを使おうと思ったら「Formクラスが無い」とゆうエラーがでた

そういえば手動でcomposer.jsonをいじらなきゃいけないことを思い出し、下記をcomposer.jsonに追加。



 
```
"require": {
        "laravelcollective/html": " 7.17.2"
    },
```
追加したら**$ composer update**をする。

しかし下記のエラーが出る

```
Your requirements could not be resolved to an installable set of packages.
  Problem 1
    - Conclusion: remove laravel/framework v7.17.2
    - Conclusion: don't install laravel/framework v7.17.2
    - Conclusion: don't install laravel/framework v7.17.1
    - Conclusion: don't install laravel/framework v7.17.0
    - Conclusion: don't install laravel/framework v7.16.1
    - Conclusion: don't install laravel/framework v7.16.0
    - Conclusion: don't install laravel/framework v7.15.0
    - Conclusion: don't install laravel/framework v7.14.1
    - Conclusion: don't install laravel/framework v7.14.0
    - Conclusion: don't install laravel/framework v7.13.0
    - Conclusion: don't install laravel/framework v7.12.0
    - Conclusion: don't install laravel/framework v7.11.0
    - Conclusion: don't install laravel/framework v7.10.3
    - Conclusion: don't install laravel/framework v7.10.2
    以下省略
```

どうやらこの投稿日時点では"laravelcollective/html"のversionがlaravelのv7に対応していないみたい。。

解決としてはlaravelcollective/html"の最新versionを指定してあげれば解決する。

```
"require": {
        "laravelcollective/html": " 6.1.2"
    },
```

もう一度**$ composer update**をする。
これでいけるはず。

あとは他の記事にもあるように、app.phpファイルに下記を追加。

```
   'providers' => [
        Collective\Html\HtmlServiceProvider::class,
    ],

    'aliases' => [
        'Form' => Collective\Html\FormFacade::class,
        'Html' => Collective\Html\HtmlFacade::class,
    ],
```

解決です。
【spock】MessageSourceをmock化_message.propertiesからの外部取得はどう対応する？

下記実装はMessageSourceをコンストラクタインジェクションしてる。よくみるやつ
message.propertiesとかでメッセージを一括管理できるから便利

```java:Controller
//省略
messageSource.getMessage("message",null,Locale.JAPAN)
//省略
```

spock側ではこう書く

```groovy:ServiceImplTest

    @RunWith(Sputnik.class)
class ServiceImplTest extends Specification {

    SampleController target
    MessageSource messageSource

    def setup() {
        messageSource = Mockito.mock(MessageSource.class)
        target = new SampleController(messageSource)
    }

    @Unroll
    def "MessageSource"() {
        setup:
        Mockito.when(messageSource.getMessage("message",null,Locale.JAPAN)).thenReturn("dummy-message")

        when:
        //省略

        then:
        //省略

        where:
        //省略
    }
```

## おわり
上記のように記載してあげればよしなにしてくれますー
日本語のドキュメントがほとんど存在しなかったから苦労した
.zshrc だけで作るzsh設定


サーバ等でzshを使う際に、余計なものを追加したくない場合に利用している .zshrc です。

```zsh
# alias
alias ls='ls -F --color=auto'
alias la='ls -laF --color=auto'
alias lah='ls -lahF --color=auto'
alias ga='git add . '
alias gb='git branch '
alias gc='git checkout '
alias gcb='git checkout -b '
alias gs='git status '
alias gl='git log --oneline '

# 色を使用
autoload -Uz colors
colors
# 色の設定
export LSCOLORS=Exfxcxdxbxegedabagacad
# 補完時の色設定
export LS_COLORS='di=01;34:ln=01;35:so=01;32:ex=01;31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30'

# 補完
autoload -Uz compinit
compinit

# history
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
# 他のターミナルとヒストリーを共有
setopt share_history
# ヒストリーに重複を表示しない
setopt histignorealldups
# ヒストリーに保存するときに余分なスペースを削除する
setopt hist_reduce_blanks
# ヒストリーを呼び出してから実行する間に一旦編集できる状態になる
setopt hist_verify

# prompt
autoload -Uz vcs_info
setopt prompt_subst
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr '%F{yellow}!'
zstyle ':vcs_info:git:*' unstagedstr '%F{red}+'
zstyle ':vcs_info:*' formats ' %F{green}%c%u(%b)%f'
zstyle ':vcs_info:*' actionformats ' (%b|%a)'
precmd () { vcs_info }
PROMPT='%F{yellow}[%*]%f%F{green}%m%f:%F{cyan}%~%f${vcs_info_msg_0_}\$ '
```