OmniAICreator/Qiita-1.07M huggingface dataset:
cscの作法 その11 カレンダー

#概要

cscの作法、調べてみた。
練習問題やってみた。

#練習問題
カレンダーを表示せよ。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/51531f5d-ccd1-cf59-6f5b-1bd87ad68992.png)


#サンプルコード


```
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	form1() {
		Text = "MonthCalendar";
		ClientSize = new Size(300, 200);

		MonthCalendar cal = new MonthCalendar();
		//cal.ClientSize = new Size(300, 200);
		Controls.AddRange(new Control[] {
			cal
		});

	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}




```

以上。
cscの作法 その10 sin波

#概要

cscの作法、調べてみた。
練習問題やってみた。

#練習問題

sin波を描け。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/773b19d0-0fbf-3129-b7e2-832a5b8c36c5.png)


#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	form1() {
		Text = "sin";
		ClientSize = new Size(300, 300);
	}
	protected override void OnPaint(PaintEventArgs e) {
		Graphics g = e.Graphics;
		Brush red = new SolidBrush(Color.Red);
		int j;
		double j0;
		double angle;
		for (j = 0; j < 720; j++)
		{
			if (j >= 360) j0 = j - 360;
			else j0 = j;
			angle = ((double) j0) / 360 * 2 * Math.PI;
			g.SetPixel(j,  (int)(100 * Math.Sin(angle) + 150), Color.Red);
		}
		base.OnPaint(e);
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}

```

以上。
初心者向け Jupyter Notebookでパスワードかトークンを求められたときの対処法

# 直面した問題
- ある朝、Jupyter Notebookを開こうとしたらこんな画面が出た。
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238597/78b3ca6f-8929-5635-5228-0823eef2e25e.png)
- ｢えっ、パスワードとか設定してないしどこでトークンもらえるん｣
- いつもどおり自己解決するためにGoogleとQiitaでいろいろ検索

# Qiitaで得られた情報
https://qiita.com/SaitoTsutomu/items/aee41edf1a990cad5be6
https://qiita.com/cafeal/items/dfc1619a60c3cdd63f1e

そもそも、このパスワード入力画面はJupyter Notebookを起動する度に本来は出る(?)らしい。しかし私の場合はいままで見たことがなかった。もう50回くらいは起動してるのに。なぜ今のタイミングだったのかは不明。

どうやら
1 `$ jupyter notebook --generate-config`
2 `$ jupyter notebook password`
とターミナルで入力すれば、たしかに**任意のパスワードを設定**できるような表示になったので、設定できた、はずだった。
しかし、これをChromeのフィールドに入力しても入れない。

# 公式のドキュメントを見る
なんやかんや公式が一番安心。もちろん英語だけど。
https://jupyter-notebook.readthedocs.io/en/latest/public_server.html

>### Automatic Password setup
>As of notebook 5.3, the first time you log-in using a token, the notebook server should give you the opportunity to setup a password from the user interface.

>You will be presented with a form asking for the current _token_, as well as your _new_ _password_ ; enter both and click on Login and setup new password.__

って書いてあったので、どうやら本来はパスワード要求画面から
- 設定したい任意のパスワード
- トークン
を入力すれば、それを設定してくれるらしい。

# トークンを取得する
トークンの取得方法は、よく見ればパスワード要求画面に書いてある。

> The command:

> jupyter notebook list
will show you the URLs of running servers with their tokens, which you can copy and paste into your browser. For example:
Currently running servers:
http://localhost:8888/?token=c8de56fa... :: /Users/you/notebooks
or you can paste just the token value into the password field on this page.

というわけで
`$ jupyter notebook list`
で帰ってきた値の
`http://localhost:8888/?token=(ここがトークン) :: /Users/(ユーザー名)`
をコピペして、Chromeの__Setup a Password__にこれを貼り付け、任意のパスワードを設定。Chromeがパスワードは覚えてくれるので嬉しい。

# 最後に
初心者ですので用語の間違いがあると思いますがご容赦ください。内容に間違いがあればご指摘を願います。
## 2022/03/18追記
最近は本業である勉学のためJupyterもPythonもほとんど触らなくなりましたが、本記事にLGTMやストックをいただいているようで、嬉しい限りです。誰かのお役に立てて光栄です。また気づきがあれば書こうと思います。なお、内容が古いので万一間違っていたら申し訳ありません。
cscの作法 その9 日の丸

#概要

cscの作法、調べてみた。
練習問題やってみた。

#練習問題

日の丸を描け。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4bfd0b47-6837-bec4-eed5-9a438540a085.png)


#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	form1() {
		Text = "maru";
		ClientSize = new Size(300, 300);
	}
	protected override void OnPaint(PaintEventArgs e) {
		Graphics g = e.Graphics;
		Brush red = new SolidBrush(Color.Red);
		g.FillEllipse(red, 30, 30, 230, 230);
		base.OnPaint(e);
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}


```

以上。
Local環境でのCookie / WebStorage 挙動

# はじめに
Local環境にてHTMLコンテンツを動かし複数のHTMLを使うために、データを保存する方法を模索しているときに、「Local環境でのCookie / WebStorage 挙動」について勉強になったのでまとめました。
まとめられたものが少なかったため、他の人に役立てばなと思っています。

#### 関連リンク
関連リンクを下記に載せておくので、参考にしてください。。

* WebStorage と Cookie の違い
    * https://qiita.com/syukan3/items/091b9b7f826dd9bec532
* Local上にて複数のHTMLコンテンツのデータを共有する方法（Store.js）
    * https://qiita.com/syukan3/items/c20ed695c1d676799a5a
* Local環境のXMLファイルからJavascriptを使って情報を取得する方法
    * https://qiita.com/syukan3/items/71c63cdccb6976e52f3d

## 検証方法
Cookie と WebStorage のそれぞれの検証用HTMLを各ブラウザでロードして、開発者ツールのコンソールにて期待する動作をするかどうか確認しました。

* Macbook Pro 15(2019)
* Windows10 Pro

## 検証結果
さっそく、検証した結果を表にまとめました。
結論としては、Cookieはlocal環境での使用を想定されていないものの、ブラウザによっては使用可能ということがわかりました。
今回は3つのブラウザでのみ検証をしておりますが、他のブラウザでの検証を実施したい場合は、下記の検証用HTMLを使って検証したいブラウザで表示させてみてください。

|   | IE | chrome | safari |
|---|:-:|:-:| :-: |
| cookie | ◯ | × | ◯ |
| sessionStorage | ◯ | ◯ | ◯ |
| localStorage | ◯ | ◯ | ◯ |

* ◯ ・・・ 使用可能
* × ・・・ 使用不可

## 検証用HTML
Cookieの検証をする時は、２回ロードしてください。
（１回目でCookieへの書き込み、２回目でCookieの読み込みをしています。）

```HTML:cookie_check.html
<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Cookie test</title>
  </head>
  <body>

    <script type="text/javascript">

      function enable_check(){

        // キャッシュがあるか
        if(document.cookie !== ""){
          console.log("ある");
          var w = document.cookie.split( '; ' );
          alert(w);
        } else {
        // なければ作成
          var expire = new Date();
          expire.setTime( expire.getTime() + 1000 * 60 );

          document.cookie = 'data=123;expires=' + expire.toUTCString();
          document.cookie = 'data2=abc;expires=' + expire.toUTCString();
          console.log("ない");
        }
      }

      enable_check();
    </script>

  </body>
</html>


```

```HTML:webstorage_check.html
<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>WebSession test</title>
  </head>
  <body>

    <script type="text/javascript">

      function enable_check(){

      // LocalStrage対応してる?
        if ( typeof(Storage) === "undefined" ) {
          alert('not support');
        } else {
          console.log('Support');
        }
      }

      enable_check();
    </script>

  </body>
</html>
```

# まとめ
ブラウザはlocal環境での動作保証はしていないはずですので、使用するときには各自検証の上で利用可否の判断をお願いします。
とはいえ、この内容が誰かの役に立てばいいなと思っています。


# 参考
https://teratail.com/questions/101774
https://qiita.com/uralogical/items/ade858ccfa164d164a3b
http://www.htmq.com/webstorage/

---
### 会社紹介

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

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
cscの作法 その8 画像

#概要

cscの作法、調べてみた。
画像表示してみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ad351901-5f7c-9a83-c710-0b477fc1c580.png)


#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	form1() {
		Text = "WebBrowser";
		ClientSize = new Size(420, 320);

		PictureBox pb0 = new PictureBox();
		pb0.Width = 400;
    	pb0.Height = 300;
        pb0.Image = Image.FromFile("C:\\1.png");
		Controls.AddRange(new Control[] {
			pb0
		});
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}

```

以上。
vagrant upに失敗した時の対処記録

# vagrant upに失敗した時の対処記録
下記の記事を参考にして、Vargrantで環境構築を進めたが、`vagrant up`でエラーが発生。
[Windows環境にVagrant+Ubuntuデスクトップ環境をインストール](https://qiita.com/mhagita/items/8f339106c3b48eb098ca)
自分が対処した時の手段をメモ。
## 環境
**ホスト環境**
Windows10 Home
Vagrant:2.2.6
VirtualBox:6.1.0
**仮想環境**
Ubuntu:16.04

## Rubyの修正
[Vagrant 2.2.6 と Virtualbox 6.1でvagrant up がエラー時の対処法](http://www.it-view.net/vagrant-2-2-6-%E3%81%A8-virtualbox-6-1%E3%81%A7vagrant-up-%E3%81%8C%E3%82%A8%E3%83%A9%E3%83%BC%E6%99%82%E3%81%AE%E5%AF%BE%E5%87%A6%E6%B3%95-385.html)
上記の記事を参考に対応。上記はlinuxなので、ファイルの場所だけ下記にメモ。
#### 修正ファイルの場所(windows版)
**meta.rbの場所**
C:\HashiCorp\Vagrant\embedded\gems\2.2.6\gems\vagrant-2.2.6\plugins\providers\virtualbox\driver\meta.rb
**version_6_1.rbの作成場所**
C:\HashiCorp\Vagrant\embedded\gems\2.2.6\gems\vagrant-2.2.6\plugins\providers\virtualbox\driver\version_6_1.rb
**plugin.rbの場所**
C:\HashiCorp\Vagrant\embedded\gems\2.2.6\gems\vagrant-2.2.6\plugins\providers\virtualbox
## ググって出てきた対処方法を一通り試す
上記の修正後に実行したが、修正前とは別のエラー。
→.vagrantとVagrantfileを削除して再度`vagrant init bento/ubuntu-16.04`と`vagrant up`を実行したけどまたエラー。
VirtualBoxをGUIで開いて、作成されているイメージを全部削除。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/47d96ff4-56d7-622d-0374-d003be986132.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/e55b46dc-396c-c61f-6ec8-813a011df725.png)
.vagrantとVagrantfileを削除して再度`vagrant init bento/ubuntu-16.04`と`vagrant up`を実行したがエラー。
VirtualBox-6.1.0-135406-Win.exeを起動して、アンインストールして再度インストールで再度実行したがエラー。
## Vagrantfileの修正
エラーメッセージをよく確かめたら、以下のメッセージを発見。

~~~
VBoxManage.exe: error: Unknown option: --clipboard
~~~

以下のサイトでオプションの確認。
[Chapter 8. VBoxManage](https://www.virtualbox.org/manual/ch08.html)
Vagrantfileのvb.customizeのオプションから--clipboardを`--clipboard-mode`に変更して再度実行→成功！
cscの作法 その7 graphics

#概要

cscの作法、調べてみた。
graphicやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/118a8dd5-f9b2-d928-817a-633b4d969a4a.png)

#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	public form1() {
		this.Text = "図";
		this.BackColor = SystemColors.Window;
		this.ClientSize = new Size(500, 300);
	}
	protected override void OnPaint(PaintEventArgs e) {
		Graphics g = e.Graphics;
		Pen penBlue = new Pen(Color.Blue, 2);
		Pen penRed = new Pen(Color.Yellow, 2);
		SolidBrush brush = new SolidBrush(Color.Red);
		g.DrawLine(penBlue, 10, 10, 100, 100);
		e.Graphics.DrawRectangle(penBlue, 110, 10, 100, 100);
		e.Graphics.DrawEllipse(penRed, 110, 10, 100, 100);
		Rectangle rect = new Rectangle(220, 10, 100, 100);
		e.Graphics.FillEllipse(brush, rect);
		penBlue.Dispose();
		penRed.Dispose();
		brush.Dispose();
		Font fontv = new Font("@MS ゴシック", 10);
		StringFormat sf = new StringFormat(StringFormatFlags.DirectionVertical);
		g.DrawString("あけまして", fontv, Brushes.Blue, 330, 10);
		g.DrawString("おめでとう", fontv, Brushes.Red, 410, 10, sf);
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}

```

以上。
Docker, React, TypeScriptを使用したプロジェクト作成

# はじめに

Dockerを使用して、React, TypeScriptを使用するプロジェクトを作成したのでメモとして残しておきます。

使用しているのは`Macbook`です。

# 参考

こちらのサイトを参考にさせていただきました。
ほとんどこちらで書かれていることと同じことをしています。
[Reactの開発環境をDockerで整えよう](https://code-ship-blog.wemotion.co.jp/technology/react%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92docker%E3%81%A7%E6%95%B4%E3%81%88%E3%82%88%E3%81%86/)

相違点としては以下が挙げられます。

- `TypeScript`を使用
- `Dockerfile`
    - `node:8.16.0-alpine`→`node:13.5.0-alpine3.11`
    - `RUN npm install --save prop-types`を削除
    - `RUN npm install -g create-react-app`を削除
        - 詳細は後述しますが、`npx`で実行するようにしたので、`Dockerfile`からは削除しました
- `docker-compose.yml`
  - そのまま


# やったこと

## `Dockerfile`, `docker-compose.yml`の作成

この作業を終えた後のディレクトリ構成は以下のようになります。

```bash
.
├── Dockerfile
└── docker-compose.yml
```

### `Dockerfile`の作成

以下のようにします。

```bash
FROM node:13.5.0-alpine3.11
WORKDIR /usr/src/app
```

### `docker-compose.yml`の作成

以下のようにします。

```yml
version: '3'
services:
  node:
    build:
      context: .
    tty: true
    environment:
      - NODE_ENV=production
    volumes:
    - ./:/usr/src/app
    command: sh -c "cd sample_app && yarn start"
    ports:
    - "3000:3000"
    
```

## `build`, `create-react-app`の実行

この作業を終えた後のディレクトリ構成は以下のようになります

```bash
.
├── Dockerfile
├── docker-compose.yml
└── sample_app
    ├── README.md
    ├── node_modules
    ├── package.json
    ├── public
    ├── src
    ├── tsconfig.json
    └── yarn.lock
```

### `build`の実行

```bash
docker-compose build
```

### `create-react-app`の実行

[ドキュメント](https://create-react-app.dev/docs/getting-started)を見たところ、`npx`を使用するのが推奨されているみたいなので、`npx`で実行するようにしました。

今回は`TypeScript`を使用するので、`template`として指定しています。

```bash
docker-compose run --rm node sh -c 'npx create-react-app sample_app --template typescript'
```

## アプリケーションの起動・停止

以下を実行するだけです

```bash
#起動
docker-compose up
#停止
docker-compose down
```

起動後
http://localhost:3000/
にアクセスすると、`Edit src/App.tsx and save to reload.`の画面が表示されているはずです。

ローカルの`src/App.tsx`を編集すると、即時反映されることも確認できます。

## `ESLint`
以下のコマンドで`edlint`の設定を作成できます。

```bash
node_modules/.bin/eslint --init
```

# まとめ

`Docker`を使って、`create-react-app`で`typescript`のプロジェクトを簡単に作成することができました。
cscの作法 その6 zundoko

#概要

cscの作法、調べてみた。
練習問題やってみた。

#練習問題

ズンドコやってみて。

#写真
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/67f7d42f-10b7-65fa-2769-7844cb4907df.png)


#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	TextBox bo1;
	form1() {
		Text = "fizzbuzz";
		ClientSize = new Size(300, 300);
		bo1 = new TextBox();
		bo1.Location = new Point(50, 80);
		bo1.Width = 200;
    	bo1.Height = 200;
		bo1.Multiline = true;
		Controls.AddRange(new Control[] {
			bo1
		});
		Button btn1 = new Button();
		btn1.Location = new Point(50, 50);
		btn1.Text = "test";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		int a = 0;
		int b = 0;
		Random r = new Random();
		string res = "";
		do
		{
			if (a == 0)
			{
				b++;
			}
			else
			{
				b = 0;
			}
			a = r.Next(2);
			if (a == 0)
			{
				res += "ズン ";
			}
			else
			{
				res += "ドコ ";
			}
		} while (!(a == 1 && b > 4));
		res += "キ・ヨ・シ！！";
		bo1.Text = res;
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```
以上。
DB登録ステップの設定ポイント

![store in data base 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/15025195-5b7d-a44f-371a-065e77c1c7fa.png)
設定内容は上記

【ポイント】
・レコードは英字で登録する
・一位になるようレコードを必ずいれる（例：NO）
・Noは文頭に入れる
・number はレコード登録できないので、integerで登録する

【sqlファイルの中身の例】
DROP TABLE kyuujinjyouhou;
CREATE TABLE kyuujinjyouhou (
         no FLOAT,
         company VARCHAR(255),
         baitai VARCHAR(255),
         kinmukeitai VARCHAR(255),
         mikeikenOK VARCHAR(255),
         kinmuti VARCHAR(255),
         shigotogaiyou VARCHAR(255),
         taisyou VARCHAR(255),
         keisaikikann VARCHAR(255),
         kinnmutiiki CLOB(2147483647),
         ObjectKey VARCHAR(255) NOT NULL,
         RobotName VARCHAR(255),
         ExecutionId VARCHAR(50),
         FirstExtracted TIMESTAMP,
         LastExtracted TIMESTAMP,
         ExtractedInLastRun VARCHAR(1),
         LastUpdated TIMESTAMP,
         PRIMARY KEY (ObjectKey));
【検証中】メール送信ステップ

bizrobo の「メール送信ステップ」を作成。
以下、検証実施した際の動作

・auth failのエラー
・gmailを使用
・端末からoutlookでメール送信しようとしたが、うまくいかない

端末依存の可能性もあるので、一旦保留
「リファクタリング 第2版」Swiftでコーディング その13

# 17-18頁 第1章 format変数の削除 「関数宣言の変更(p.130)」

## Swift版 main.swift

データ生成、結果表示付き。

```swift
import Foundation

makeData()

func playFor(aPerformance:Performance) -> Play {
    return plays[aPerformance.playID]!
}

func volumeCreditsFor(aPerformance:Performance) -> Int {
    var result = 0
    result += max(aPerformance.audience - 30, 0)
    if "comedy" == playFor(aPerformance: aPerformance).type {
        result += Int(aPerformance.audience / 5)
    }
    return result
}

func usd(aNumber:Int) -> String {
    let format = NumberFormatter()
    format.numberStyle = .currency
    format.locale = Locale(identifier: "en_US")
    return format.string(from: NSNumber(value: aNumber) / 100)!
}

func statement(invoice:Invoice, plays:Dictionary<String, Play>) -> String {
    var volumeCredits = 0
    var totalAmount = 0
    var result = "Statement for \(invoice.customer)\n"

    for perf in invoice.performances {
        volumeCredits += volumeCreditsFor(aPerformance: perf)

        result += "  \(playFor(aPerformance: perf).name): " + usd(aNumber: amountFor(aPerformance: perf)) + " (\(perf.audience) seats)\n"
        totalAmount += amountFor(aPerformance: perf)
    }
    result += "Amount owed is " + usd(aNumber: totalAmount) + "\n"
    result += "You earned \(volumeCredits) credits\n"
    return result
}

func amountFor(aPerformance:Performance) -> Int {
    var result = 0

    switch playFor(aPerformance: aPerformance).type {
    case "tragedy":
        result = 40000
        if aPerformance.audience > 30 {
            result += 1000 * (aPerformance.audience - 30)
        }
    case "comedy":
        result = 30000
        if aPerformance.audience > 20 {
            result += 10000 + 500 * (aPerformance.audience - 20)
        }
        result += 300 * aPerformance.audience
    default:
        print("error")
    }
    return result
}
 
let result = statement(invoice: invoices[0], plays: plays)
print(result)
```
「リファクタリング 第2版」Swiftでコーディング その12

# 17頁 第1章 format変数の削除

## Swift版 main.swift

データ生成、結果表示付き。

```swift
import Foundation

makeData()

func playFor(aPerformance:Performance) -> Play {
    return plays[aPerformance.playID]!
}

func volumeCreditsFor(aPerformance:Performance) -> Int {
    var result = 0
    result += max(aPerformance.audience - 30, 0)
    if "comedy" == playFor(aPerformance: aPerformance).type {
        result += Int(aPerformance.audience / 5)
    }
    return result
}

func format(aNumber:Int) -> String {
    let format = NumberFormatter()
    format.numberStyle = .currency
    format.locale = Locale(identifier: "en_US")
    return format.string(from: NSNumber(value: aNumber))!
}

func statement(invoice:Invoice, plays:Dictionary<String, Play>) -> String {
    var volumeCredits = 0
    var totalAmount = 0
    var result = "Statement for \(invoice.customer)\n"

    for perf in invoice.performances {
        volumeCredits += volumeCreditsFor(aPerformance: perf)

        result += "  \(playFor(aPerformance: perf).name): " + format(aNumber: amountFor(aPerformance: perf) / 100) + " (\(perf.audience) seats)\n"
        totalAmount += amountFor(aPerformance: perf)
    }
    result += "Amount owed is " + format(aNumber: totalAmount / 100) + "\n"
    result += "You earned \(volumeCredits) credits\n"
    return result
}

func amountFor(aPerformance:Performance) -> Int {
    var result = 0

    switch playFor(aPerformance: aPerformance).type {
    case "tragedy":
        result = 40000
        if aPerformance.audience > 30 {
            result += 1000 * (aPerformance.audience - 30)
        }
    case "comedy":
        result = 30000
        if aPerformance.audience > 20 {
            result += 10000 + 500 * (aPerformance.audience - 20)
        }
        result += 300 * aPerformance.audience
    default:
        print("error")
    }
    return result
}
 
let result = statement(invoice: invoices[0], plays: plays)
print(result)
```
cscの作法 その5 九九

#概要

cscの作法、調べてみた。
練習問題やってみた。

#練習問題

九九の表を作れ。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/cb8312fc-6ef3-6227-d131-46024ef39bdb.png)


#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	TextBox bo1;
	form1() {
		Text = "fizzbuzz";
		ClientSize = new Size(300, 300);
		bo1 = new TextBox();
		bo1.Location = new Point(50, 80);
		bo1.Width = 200;
    	bo1.Height = 200;
		bo1.Multiline = true;
		Controls.AddRange(new Control[] {
			bo1
		});
		Button btn1 = new Button();
		btn1.Location = new Point(50, 50);
		btn1.Text = "test";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		int i;
		int j;
		int s;
		string res = "";
		for (i = 1; i < 10; i++)
		{
			for (j = 1; j < 10; j++)
			{
				s = i * j;
				if (s < 10) res += " ";
				res += s.ToString() + " ";
			}
			res += "\r\n";
		}
		bo1.Text = res;
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

以上。
cscの作法 その4 fizzbuzz

#概要

cscの作法、調べてみた。
fizzbuzzやってみた。
textbox使ってみた。

#写真
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a24ff1d0-25da-f0f7-438e-9d003f122948.png)


#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	TextBox bo1;
	form1() {
		Text = "fizzbuzz";
		ClientSize = new Size(300, 300);
		bo1 = new TextBox();
		bo1.Location = new Point(50, 80);
		bo1.Width = 200;
    	bo1.Height = 200;
		bo1.Multiline = true;
		Controls.AddRange(new Control[] {
			bo1
		});
		Button btn1 = new Button();
		btn1.Location = new Point(50, 50);
		btn1.Text = "test";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		int i;
		string res = "";
		for (i = 1; i < 100; i++)
		{
			if (i % 15 == 0)
			{
				res += "fizzbuzz ";
			}
			else if (i % 5 == 0)
			{
				res += "buzz ";
			}	
			else if (i % 3 == 0)
			{
				res += "fizz ";
			}
			else
			{
				res += i.ToString() + " ";
			}
		}
		bo1.Text = res;
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

以上。
cscの作法 その3 fizzbuzz

#概要

cscの作法、調べてみた。
fizzbuzzやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/2450fd05-754b-a343-0306-abdfa7c6ec14.png)

#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	form1() {
		Text = "fizzbuzz";
		ClientSize = new Size(300, 300);
		Button btn1 = new Button();
		btn1.Location = new Point(50, 50);
		btn1.Text = "test";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		int i;
		string res = "";
		for (i = 1; i < 100; i++)
		{
			if (i % 15 == 0)
			{
				res += "fizzbuzz ";
			}
			else if (i % 5 == 0)
			{
				res += "buzz ";
			}	
			else if (i % 3 == 0)
			{
				res += "fizz ";
			}
			else
			{
				res += i.ToString() + " ";
			}
		}
		MessageBox.Show(res);
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}


```

以上。
cscの作法 その2 イベント

#概要

cscの作法、調べてみた。
イベントやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/22e2559a-176f-44fd-68b6-903b6be5c099.png)

#サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	form1() {
		Text = "hello";
		ClientSize = new Size(200, 200);
		Button btn1 = new Button();
		btn1.Location = new Point(50, 50);
		btn1.Text = "test";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		MessageBox.Show("Hello World", "こんちは");
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}
```

以上。
初心者によるプログラミング学習ログ 201日目

#100日チャレンジの201日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

201日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>201日目<br><br>udemyでvue.js、css+メディアクエリ、webサイトコーディング<br>いろいろやって疲れたけど継続<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1212483627730132994?ref_src=twsrc%5Etfw">January 1, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Firebase + Vuejsのアプリを複数環境に対応させる

# 要約

- Firebaseプロジェクトごとに環境変数を用意して複数環境に対応させる
- 環境変数は、`.env.xx.local`ファイルを用意

# 本文

Firebaseを使ったVueアプリを開発していると、
開発、ステージング、本番などの複数環境のFirebaseプロジェクトにデプロイする必要が出てきます。

ソースコードにベタで環境に関する記述をしてしまっても動くには動きますが、問題があります。

- いつか手作業を失敗して、思わぬ事故を起こしてしまう可能性がある
- Githubなどでソースコードを管理していると、APIキーなどを公開するのはセキュリティ上危険
  （ちなみに本当にやってしまうと、GitGuardianさんからアラートのメールが飛んできます）

そこで、Vue CLIが用意している環境変数の切替を利用しましょう。
以下の名称のファイルを用意します。

```
.env                # loaded in all cases
.env.local          # loaded in all cases, ignored by git
.env.[mode]         # only loaded in specified mode
.env.[mode].local   # only loaded in specified mode, ignored by git
```

Vue CLIでアプリを初期化した場合、`.gitignore`ファイルが自動で作られ`.env.local`と`.env.*.local`が記載されているので、gitにpushしたくない場合は.localをファイル名の最後に付けます。

環境変数はkey-value型で指定する、単純な構造です。
ただし、変数名には必ず`VUE_APP_`というプレフィックスをつけましょう。これが無いと、環境変数として認識されません。

```.env.local
FOO=bar
VUE_APP_SECRET=secret
```

上記の例だと、VUE_APP_SECRETは`secret`として認識されますが、FOOはundefinedとなります。
こうして作った環境変数のファイルの例

```.env.dev.local
VUE_APP_FIREBASE_API_KEY=xxxxxxxzzzzzz
VUE_APP_FIREBASE_AUTH_DOMAIN=xxxx.firebaseapp.com
VUE_APP_FIREBASE_DATABASE_URL=https://xxxx.firebaseio.com
VUE_APP_FIREBASE_PROJECT_ID=xxxx
VUE_APP_FIREBASE_STORAGE_BUCKET=xxxx.appspot.com
VUE_APP_FIREBASE_MESSAGING_SENDER_ID=1234567890
```

これをmain.ts(main.js)に書き入れて完成です。

```main.ts
/** firebase settings */
firebase.initializeApp({
  apiKey: process.env.VUE_APP_FIREBASE_API_KEY,
  authDomain: process.env.VUE_APP_FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.VUE_APP_FIREBASE_DATABASE_URL,
  projectId: process.env.VUE_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.VUE_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.VUE_APP_FIREBASE_MESSAGING_SENDER_ID
});
```

## おまけ

`npm run serve`で環境を指定するには以下のようにします

```bash
npm run serve -- --mode dev
```


# 参考
[Modes and Environment Variables](https://cli.vuejs.org/guide/mode-and-env.html#modes)
[Firebase を JavaScript プロジェクトに追加する](https://firebase.google.com/docs/web/setup?hl=ja)
Railsチュートリアルメモ - 第2章・第3章

[メモ目次はこちら](https://qiita.com/yokohama4580/items/dedfd5510080273dc2a0)

[Railsチュートリアル第2章はこちら](https://railstutorial.jp/chapters/toy_app?version=5.1#cha-a_toy_app)
[Railsチュートリアル第3章はこちら](https://railstutorial.jp/chapters/static_pages?version=5.1#cha-static_pages)

## 2.1 アプリケーションの計画
新しくrails newでtoy_appを作成する。
rails newすると、git initも実行されるようで.gitディレクトリがtoy_app配下に作成される。

```
tree
.
└── environment
    ├── hello_app
    └── toy_app
        └──.git
```

## 2.2 Usersリソース
RailsのscaffoldコマンドでUsersリソースを手軽に作成する実演の章

```
rails generate scaffold User name:string email:string
rails db:migrate
rails server
```
rails generateコマンドの素晴らしいところは、一発でmodelもviewもcontrollerも全部作成して、routes.rbまで追記してくれるところ。
ここからRubyに関する解説も入ってくる。

### ポイント
- @記号で始まる変数をRubyではインスタンス変数と呼ぶ
- Railsのコントローラ内で宣言したインスタンス変数はビューでも使えるようになる


## 2.3 Micropostsリソース
twitterをイメージしたアプリを作るため、Usersリソースと関連付けてMicroposts（投稿）リソースを作成する。
Rubyの継承についての解説がメイン。

### ポイント
- rails consoleでREPLを起動できる
- Railsのコントローラは必ずApplicationControllerを継承している

## 2.4 最後に
割愛

## 3.1 セットアップ
割愛

## 3.2 静的ページ
ここからはscaffoldを使わずにページを作成していく。

```
rails generate controller StaticPages home help
```
上記を実行すると、コントローラーとしてstatic_pages_controllerが作成されhomeメソッドとhelpメソッドが、ビューとしてhomeとhelpが作成される。モデルは作成されない。routes.rbには自動追記してくれる。

## 3.3 テストから始める
TDD（テスト駆動開発）についての解説と簡単な実演の章。
Red=>Green=>Refactoringのルールに則って開発を進める。

## 3.4 少しだけ動的なページ
少しだけ発展的なTDDの章。

### ポイント
- 「DRY」(Don’t Repeat Yourself: 繰り返すべからず)
- 「埋め込みRuby」(Embedded Ruby)
- provideメソッドとyeildメソッド

## 3.5 最後に
割愛

## 3.6 高度なセットアップ
テスト駆動開発を便利にしてくれるライブラリの紹介。
- `minitest reporters`:コンソールに表示されるテスト結果に色を付ける
- `Guard`:ファイル編集保存時にテストを自動実行してくれる
    - `bundle exec guard`で起動させておくと、ファイル保存時に自動でrails testを実行してくれる。
Kaggleの公式DockerイメージをGCPにデプロイしてJupyter Notebookに接続する

掲題の通り、GCPのVMインスタンスにKaggleの公式Dockerイメージをデプロイし、ローカルマシンからJupyter Notebookに接続するまでの手順を記述しています。

## gcloudの設定

gcloudをインストールしていない場合は、[インストール](https://cloud.google.com/sdk/install?hl=ja)しておいてください。
以下のように、認証と設定が済んでいる想定で進みます。ゾーンは`asia-northeast1-b`以外でも構いません。

```
$ gcloud auth login
$ gcloud config set project PROJECT_ID
$ gcloud config set compute/zone asia-northeast1-b
```

## インスタンス作成

以下のコマンドでインスタンスを作成します。

```
$ gcloud compute instances create kaggle-compute \
  --image-family=ubuntu-1804-lts \
  --image-project=gce-uefi-images \
  --boot-disk-size="100" \
  --custom-cpu 24 \
  --custom-memory 22GB \
  --maintenance-policy="TERMINATE" \
  --no-restart-on-failure \
  --preemptible
```

主な仕様は以下の通りです。

- インスタンス名: kaggle-compute
- OS: Ubuntu 18.04
- CPU: 24コア
- メモリ: 22GB
- ストレージ: 100GB

CPUのコア数を更に増やす場合は、別途割り当て上限の変更を申請する必要があります。

`--preemptible`を付けることで[プリエンプティブル VM インスタンス](https://cloud.google.com/compute/docs/instances/preemptible?hl=ja)としてインスタンスを作成できます。
これにより、可用性を犠牲にして大幅なコストカットが可能となります。

少し経つと以下のコマンドでssh接続できるようになります。

```
$ gcloud compute ssh kaggle-compute
```

sshできたら、インスタンスの初期設定をするため、以下のスクリプトを作成し、実行します。
このスクリプトにより`docker`、`docker-compose`、`pip`、`Kaggle API`、`unzip`がインストールされます。
unzipは必須ではないのですが、Kaggleのデータセットはzip形式で配布される場合もあるので、解凍するためにインストールしておきます。

```set_up.sh
#! /bin/bash
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get -y install docker-ce docker-ce-cli containerd.io
sudo curl -L https://github.com/docker/compose/releases/download//1.25.1-rc1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo apt-get install -y python3-pip
pip3 install kaggle
sudo apt-get -y install unzip
```

```
$ sh ./set_up.sh
```

## kaggle.jsonを配置

つぎに`kaggle API`を使用できるようにします。インストールは前述のスクリプトによって完了しているので、kaggle.jsonを置くだけです。
お好きな方法で`~/.kaggle/kaggle.json`を配置してください。

```
$ vim ~/.kaggle/kaggle.json # put your kaggle.json
$ chmod 600 ~/.kaggle/kaggle.json
$ kaggle --version
Kaggle API 1.5.6
```

## コンテナ起動

必要なファイルを以下のリポジトリにcommitしています。
https://github.com/shinsuke27/kaggle-docker

これをcloneして`docker-compose up --build`します。
このとき、`to login with a token:`というステートメントのあとにNotebookのURLがトークン付きで吐かれるのでこちらを控えておきます。

```
$ git clone https://github.com/shinsuke27/kaggle-docker.git kaggle
$ cd ./kaggle
$ mkdir ./input
$ sudo docker-compose up --build
```

なお、ここで作成したinputというディレクトリ内にコンペのデータを配置することで、KaggleのNotebookと同じパスでデータを読み込むことができます。

## Jupyter Notebookに接続

```
$ gcloud compute ssh kaggle-compute -- -L 8080:localhost:8080
```

ブラウザから http://loocalhost:8080/ に接続します。

# GPU対応させるには

こちらをご参照ください
https://qiita.com/shin27/items/50bf1df1b2bae3dba032
[Swift 5] swiftでラジオボタン実装

タイトルの通りです。

縦に配置したいこともあり（あとは見栄え的な問題で）、UISegmentedControlを用いずにラジオボタンを実装したかったのですが、調べても記事が古かったり、初心者の自分には手をつけがたい手法が多かったので、自分が理解できる手法で実装しました。
また、今回のコードでは、ボタンの数が可変的でも対応できるようにしています。

### バージョン
xcode: 11.2.1
swift: 5.1.2
### 準備
ボタンの画像を用意してAdd Fileからプロジェクトに追加します。
チェックボックスのフリー素材は探せばありますが、枠だけの方がないことが多かったので、自分はMac標準のプレビューで描きました。

<img width="225" alt="スクリーンショット 2020-01-02 3.20.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540869/dd420353-7ac1-adec-6e19-13b289679e91.png">

### 実装
ボタンをクリックしたときのsenderを用いて、ボタンの画像をcheck_on.pngに変えるとともに、ボタンのtagを活用してすでにチェックされているボタンをcheck_off.pngに変えているだけです。(tagを用いずに全てのボタンを一度check_off.pngに変えてもいいのですが)


```ViewController.swift
import UIKit

class ResultWindow: UIViewController {
    
    var NumberOfButtons: Int = 5  //ボタンの数
    var CheckedButtonTag = 0  //チェックされているボタンのタグ
    //それぞれ画像を読み込む
    let checkedImage = UIImage(named: "check_on")! as UIImage
    let uncheckedImage = UIImage(named: "check_off")! as UIImage
    
    //ラジオボタンを配置する
    func set_radiobutton(num:Int){
        let button = UIButton()
        let center = Int(UIScreen.main.bounds.size.width / 2)  //中央の位置
        let y = 170+45*num  //ボタン同士が重ならないようyを調整
        button.setImage(uncheckedImage, for: UIControl.State.normal)
        button.addTarget(self, action: #selector(butttonClicked(_:)), for: UIControl.Event.touchUpInside)
        button.frame = CGRect(x: center - 120,
                              y: y,
                              width: 40,
                              height: 40)
        button.tag = num
        self.view.addSubview(button)
    }
    
    //押されたボタンの画像をcheck_on.pngに変える
    @objc func butttonClicked(_ sender: UIButton) {
        ChangeToUnchecked(num: CheckedButtonTag)
        let button = sender
        button.setImage(checkedImage, for: UIControl.State.normal)
        CheckedButtonTag = button.tag  //check_on.pngになっているボタンのtagを更新
    }
    
    //すでにcheck_on.pngになっているボタンの画像をcheck_off.pngに変える
    func ChangeToUnchecked(num:Int){
        for v in view.subviews {
            if let v = v as? UIButton, v.tag == num {
                v.setImage(uncheckedImage, for: UIControl.State.normal)
            }
        }
    }

        
    override func viewDidLoad() {
        super.viewDidLoad()
        for i in 0..<NumberOfButtons {
            set_radiobutton(num: i)
        }
    }
}

```

コード汚くてすみません、、
<img width="300" alt="スクリーンショット 2020-01-02 3.41.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540869/7cb4fde6-0a28-437a-5114-4b503a4d3c21.png">
<img width="300" alt="スクリーンショット 2020-01-02 3.42.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540869/20a8fcec-be04-f1b7-0dbf-851a5b5209fa.png">

ラベルとかのコードは載せませんでしたがこんな感じでラジオボタンの実装はできると思います。
お粗末様でした。

### 参考
https://qiita.com/bohebohechan/items/49aa25ed9a24b04619a0
Observer NameNodeの紹介と現状の課題

Advent Calendar記事なのですが、大遅刻しました。ごめんなさい。

## Observer NameNode 概略

HDFSではActive NameNodeがread, writeなど全てのリクエストを受け付けるというアーキテクチャになっていますが、readリクエストはActive NameNodeじゃなくても(条件付きで)処理できるので、特別なStandby NameNode(以降、Observer NameNode)を用意してそれにオフロードさせましょう、というデータベースでよく見かけるタイプの機能です。HDFSでは、一般的な使い方をしていればreadリクエストが圧倒的多数になるはずなので、これによりActive NameNodeの負荷を大幅に削減することが期待されます。

Observer NameNodeを利用する場合は、もともとActive NameNodeとStandby NameNodeがいたところに新しくObserver NameNodeを追加するという形になります。ActiveとStandby、StandbyとObserver間は直接遷移しますが、ActiveからObserverに、ObserverからActiveにという遷移はしません。そのため、ActiveとObserverだけの構成はできないことに注意が必要です。

Observer NameNodeについては公式ドキュメントの ["Consistent Reads from HDFS Observer NameNode"](https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/ObserverNameNode.html) に詳しく記載されているので、英語が得意な方は読んでいただけると大体どういうものかがわかると思います。

公式ドキュメントのタイトルに"Consistent Reads"とあるとおり、Client Consistencyを保つように(簡単に言うと、あるクライアントが書いたデータを直後に同じクライアントが読んだときにデータが存在しない、ということがないように)実装されています。公式ドキュメント or/and @hayanige さんの[発表資料](https://www.slideshare.net/techblogyahoo/hdfs-136527062#31)に説明があるので、実装の詳細は省きます。

## Observer NameNodeの現状の課題

ここからが本題です。

### readリクエストと思っていたものがActive NameNodeで処理されてしまう

HDFSではaccess time(以下atime)を保持しているため、atimeを有効にしている場合はreadリクエストでもfsimageが更新されます。よって、Active NameNodeで処理されます。見も蓋もない話ですが、atimeは無効にするしかありません。atimeをアクセス解析目的などで利用している場合には注意が必要で、HDFSのaudit logをパースするなどの仕組みが別途必要となります。

JIRA: https://issues.apache.org/jira/browse/HDFS-14870

そもそもatimeの更新自体がfsimageのwrite lockを取る重い処理なので、atimeが不要であれば、Observer NameNodeを利用する前にatimeを無効にするチューニングをしてもいいかもしれません。

### Router-based Federationに未対応

Observer NameNodeを活用しても、1つのNamespaceが巨大になるとNameNodeのヒープも巨大になることには変わりありません。そのため Router-based Federation と組み合わせて導入してみたいのですが、まだ対応しておりません。

JIRA: https://issues.apache.org/jira/browse/HDFS-13522

そもそもRead-only DFSRouterを用意したほうがいいのではないか? という議論になったりしていて、あまり進捗していない状況です。

## おわりに

Router-based Federationを検証環境に導入するついでにObserver NameNodeも同時に導入できないかいろいろと試したのですが、上記2つ以外にもいろいろと踏んでいて現状ではかなりつらい感じです。今後の進捗に期待。自分も見ているだけでなくて開発、議論など頑張りたいところですが、Router-based Federationの方が業務上の優先度が高いのであまり手を付けられていない感じでごめんなさい、といったところです。
SharePoint リストを CSOM で取得する

SharePoint リスト（カスタムリスト、ドキュメントライブラリ、etc...）を C# の CSOM（Client Side Object Model）で取得します。 今回は特定の SharePoint リストを取得する場合のコードを紹介します。

# 環境
* .NET Framework 4.6.1
* Microsoft.SharePointOnline.CSOM 16.1.19515.12000
* SharePointPnPCoreOnline 3.16.1912

※ SharePointPnPCoreOnline は Microsoft.SharePointOnline.CSOM の拡張ライブラリで、便利なクラスや拡張メソッドが提供されています。  

# サンプルコード
[ListSample.cs](https://github.com/shibatea/sp-csom-library-sample/blob/master/Csom.Library.Sample/ListSample.cs)

## 前提
SharePoint のオブジェクトを取得するためには、その対象オブジェクトを Load してから ExecuteQuery を実行する必要があります。
 また、オブジェクトを取得するとき、既定で一部のプロパティにアクセスできません。これらのプロパティにアクセスするためには、プロパティを明示的に読み込む必要があります。  

## CSOM メソッド版
CSOM のメソッドで SharePoint リストを取得するためのメソッドは２つあります。 
ListCollection クラスの GetById, GetByTitle です。

```cs
// using CSOM
var listCsomById = context.Web.Lists.GetById(Guid.Parse("3542cfd9-85b5-4e7d-82fa-7ea70761c0c7"));
context.Load(listCsomById);
context.ExecuteQueryRetry();
Console.WriteLine(listCsomById.Title);

// using CSOM with expressions
// SharePoint リストオブジェクトを取得すると同時に
// 既定でアクセスできない HasUniqueRoleAssignments プロパティを読み込む
var listCsomByTitle = context.Web.Lists.GetByTitle("CsomByTitle");
// 2行で書くバージョン
context.Load(listCsomByTitle);
context.Load(listCsomByTitle, l => l.HasUniqueRoleAssignments);
// 1行で書くバージョン
//context.Load(listCsomByTitle, l => l, l => l.HasUniqueRoleAssignments);
context.ExecuteQueryRetry();
Console.WriteLine(listCsomByTitle.Title);
Console.WriteLine(listCsomByTitle.HasUniqueRoleAssignments);
```


## PnP 拡張メソッド版
PnP の拡張メソッドで SharePoint リストを取得するためのメソッドは３つあります。 
CSOM の Web クラスの拡張メソッド GetListById, GetListByTitle, GetListByUrl です。  

```cs
// using PnP
var listPnPById = context.Web.GetListById(Guid.Parse("f470fb72-1528-45e4-a929-a144146c1b1f"));
Console.WriteLine(listPnPById.Title);

// using PnP
var listPnPByUrl = context.Web.GetListByUrl("PnPByUrl");
Console.WriteLine(listPnPByUrl.Title);

// using PnP with expressions
var listPnPByTitle = context.Web.GetListByTitle("PnPByTitle", l => l.HasUniqueRoleAssignments);
Console.WriteLine(listPnPByTitle.Title);
Console.WriteLine(listPnPByTitle.HasUniqueRoleAssignments);
```

# PnP 拡張メソッドの特徴
PnP 拡張メソッドの特徴として、内部的に Load & ExecuteQuery を実行しているため、ユーザー側のコードに Load & ExecuteQuery を書く必要がありません。 
また、取得対象のオブジェクトが存在しない場合、拡張メソッドの戻り値として null を返します。 
大量のオブジェクトを繰り返し処理する場合を除けば、PnP 拡張メソッドを積極的に使っても良いと思います。 

CSOM や PnP の特徴（癖？）については後日まとめようと思います。

# 参照
[SharePoint .NET Server、CSOM、JSOM、および REST API インデックス | Microsoft Docs](https://docs.microsoft.com/ja-jp/sharepoint/dev/sp-add-ins/sharepoint-net-server-csom-jsom-and-rest-api-index)
[SharePoint のクライアント ライブラリ コードを使用して基本的な操作を完了する | Microsoft Docs
](https://docs.microsoft.com/ja-jp/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-client-library-code)
Haskellことはじめ

Haskell～教養としての関数型プログラミング～から学ぶ
第5章 関数

#### 関数リテラル
- 関数を変数に保存せずにその場で使うことができる

```
*Main> (\x -> x ^ x) 3
27

*Main> (\x n -> x ^ n) 3 2
9
```

#### 高階関数
関数を引数にとり関数を返す

``` twice.hs
-- 引数（関数）に引数xを適用した結果を関数fに適用する高階関数
twice = \f x-> f (f x)

-- 関数を3回適用する関数
thrice = \f x -> f (f ( f x))
```
- 高階関数を使用

```
# ひとつ前の値を返す
*Main> pred 8
7
# 次の値を返す
*Main> succ 8
9
# 高階関数twiceにsucc関数を渡す
*Main> twice succ 8
10
# 高階関数twiceにpred 関数を渡す
*Main> twice pred 10
8
```

#### 演算子と関数
- 演算子を()で囲むと関数になる

```
*Main> 5 + 5
10
*Main> (+) 5 5
10
*Main> (*) 5 5
25
```
- 関数をバッククォートで囲むと演算子になる  
つまり、関数をバッククォートで囲むことで演算子として利用することができる

```
*Main> mod 10 8
2
*Main> 10 `mod` 8
2
```

- 演算子（関数）の部分適用

```
# 3 ^ 2に等しい
*Main> (^2) 3
9
# 2 ^ 3 に等しい
*Main> (2^) 3
8

# mod 8 10に等しい
*Main> (mod 8) 10
8
# mod 10 8に等しい
*Main> (mod 10) 8
2

# 10 `mod' 8 に等しい
*Main> (`mod` 8) 10
2
# 10 `mod` 8に等しい
*Main> (10 `mod`) 8
2
```

#### カスタム演算子を定義
- 独自の演算子を定義することができる
カスタム演算子で使える記号  
`!#$%&+-./<=>?@\^|~:`  
ただし`:`は演算子の先頭文字では使用できない  

```func.hs
-- カスタム演算子 引数x, y を2乗してから加算する演算子
x *+ y = x ^ 2 + y ^ 2

-- カスタム演算子　金額x, 税率y を与えると税込み後の金額を返す演算子/*/を定義
x /*/ y = x + div (x * y) 100
```

```
# カスタム演算子 引数x, y を2乗してから加算する演算子を使用してみる
*Main> 2 *+ 3
13
```
このことから演算子は中置記法で書く引数を2つとる関数であると捉えることができる。
演算子は（）を使うことで関数に、関数はダブルクォーテーションを使うことで演算子に変換できる。

#### 振り返り
高階関数とか関数の部分適用はカッコいいなって思ってたヤツなんでこの本を読み終わるころには自然と使いこなせるようになっていたい。
カスタム演算子も面白い。カスタム演算子を使わなくても関数でこと足りるけど。
次はいよいよMaybe値の学び。
これってMaybeモナドのことであってるよね？
書き初め Re:VIEW 4.0

Re:VIEW で技術文章を書き初めします。

4.0 の docker イメージが出ていたのでこれを使います。
https://github.com/vvakame/docker-review

```zsh
docker pull vvakame/review:4.0
```

作業ディレクトリを作るために `review` の gem をインストールします。こちらも 4.0.0 を利用します。
https://rubygems.org/gems/review/versions/4.0.0

```zsh
gem install review -v "4.0.0"
```

`review-init` コマンドで雛形を作ります。

```zsh
review-init template-book
```

`template-book` ディレクトリの中にある `catalog.yml` `config.yml` `style.css` ファイル、そして `sty` ディレクトリをコピーして、新たな作業ディレクトリ `src` を作ります。

つまり構造はこのようにして、`.re` ファイルを書いていきます。`catalog.yml` を作った `.re` ファイルに合わせて修正します。

```
├── templatebook
└── src
    ├── catalog.yml
    ├── ***.re
    ├── config.yml
    ├── sty
    └── style.css
```

`src` ディレクトリがあるディレクトリで下記を実行します。

```zsh
docker run --rm -v `pwd`/src:/work vvakame/review:4.0 /bin/sh -c \
  "cd /work && review-pdfmaker config.yml"
```

これで PDF が生成されました。Re:VIEW 本当に素晴らしい。

この内容ソフトウェア開発初心者の方にもおすすめしたいなと思って、上記内容に加えて＋諸々『Re:VIEW を用いて技術本を作る』ことを丁寧めに解説した、小さな電子本を作りました。→ [作れる!技術書 Re:VIEW Book for Beginners - BOOTH](https://feb19.booth.pm/items/1757517)

上記電子本を作る上で、 Re:VIEW の命令の中で Re:VIEW の構文をエスケープするマニアックな方法を知れたので、とてもよかったです（といっても今後使うことあるのかわからないけど...）。

2020 あけましておめでとうございます！！（元旦これで潰した）
ESP32 Camera Web Server

　ESP32搭載ボードESP32-CAMを使いウェブカメラを製作する．
　ArduinoIDEのサンプルスケッチ　ESP32->Camera->CameraWebServerを使いSSIDやPASSを設定し，プログラムを書き込むと，ESP32上でhttpd（ウェブサーバ）が動き，ブラウザからアクセスできるウェブカメラを構築できる．
　ただし，ArduinoIDEのサンプルスケッチを使用した場合，ボードに搭載されたLEDをウェブアプリから制御できない（ウェブアプリの画面にコントロールが出ない）．
　そこで，ESP-IDFを使い，コードをGitHubから引っ張ってきてmakeしたら，無事LEDの輝度調整もウェブアプリからできるようになった．
　このプログラムではESP32上でFaceRecognitionも動く．
　Edgeではうまく動きません，筆者はChromeで検証しています．

![camerawebserver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/50024f80-2374-3a17-88aa-38781dfa2c06.png)

#配線
[ESP32-CAM]　　　[PC（USB)]
5V－－－ー－－－－ー5V
GND－－－－－－－－GND
U0R－－－－－－－－TxD
U0T－－－－－－－－RxD
IO0ー｜（書き込み時ジャンパ/実行時ジャンパ外す）
GNDー｜

#コードを取得
```bash
git clone --recursive https://github.com/espressif/esp-who.git
```
次のフォルダにプログラムがまとまっている
/examples/single_chip/camera_web_server/

```bash
cd esp-who/examples/single_chip/camera_web_server
make menuconfig
```

#menuconfigで以下の項目を設定する
●書き込みに使用するシリアルポート
Serial flasher config->Default serial port
●無線LANのSSID（ESP32をSTAで使用する場合）
Camera Web Server->WiFi Settings->WiFi STA SSID
●無線LANのパスワード
Camera Web Server->WiFi STA Password
●LEDをウェブアプリから使用する場合は選択・設定する
Camera Web Server->LED Illuminator
●使用するボードの設定
Camera Web Server->Camera Pins->Select Camera Pinout
●顔認識を使用する場合は選択する
Camera Web Server->ESP-WHO Face Detection
Camera Web Server->ESP-WHO Face Recognition

menuconfigしたらボードへ書き込み

```bash
make flash
```

#画像の方向を直す
このままでは，画像・映像の向きが90°回転している（ESP32-CAMボードを横向きで使用するなら正しい方向になっている）ので，httpdが吐き出すHTMLを編集して対応する．

```
cd esp-who/examples/single_chip/camera_web_server/main/web
vi index_ov2640.html
```

57行目　figure img{ の次に
transform: rotate( 90deg);
を追加
5行下のmargin-topを8px→15%に変更

クライアントへ投げるHTMLファイルは圧縮して保持しているようで，

```bash
./compress_pages.sh
```

再度書き込み

```bash
cd ../..
make flash
```

#ちなみに
　LEDは放熱しきれないと焼けてしまうので，MAXの輝度を設定しておくことが出来ます（menuconfigの中で）．

#参考文献
（ESP-IDF）
https://tomono.tokyo/2019/03/11/7519/
https://robotzero.one/esp32-camera-module/
（ArduinoIDE)
https://qiita.com/Nabeshin/items/b195cad1afe99ce29f1e
https://www.ovt.com/image-sensors/2-5-megapixels
GoogleカレンダーAPIを用いて予定への出欠登録を行う

# はじめに
明けましておめでとうございます。早いもので令和2年(2020年)になりました。
なかなか投稿できておらず、久々の投稿となってしまいました。
2020年も気軽に投稿していければなと思っています。
今回は、前回の記事「[GoogleカレンダーAPIを用いてカレンダー一覧を取得する](https://qiita.com/kenbou/items/0fc85fa787db15c8b807)」に続き、
GoogleカレンダーAPIに関する記事です。


## やりたいこと
+ Googleカレンダーに登録されてされている予定に対して出席・欠席の登録をAPI経由で行う

私はこのAPIをAlexaスキルに組み込んで、共有カレンダーに対して音声経由で出欠登録できるようにしてみました。

## 実装


```registEvent.js
'use strict';
const url = require('url');
const https = require('https');

const HTTP_RESPONSE_OK = 200;
const ACCESS_TOKEN = 'API実行に必要なアクセストークン';
let calendarId = '対象となるGoogleカレンダーのID';
let eventId = '出欠登録を行う予定のID';
let apiUrl = `https://www.googleapis.com/calendar/v3/calendars/${calendarId}/events/${eventId}`;

// PATCH用オブジェクト
let requestBody = new Object();
        
requestBody.attendees = [{
    'displayName': '表示名を設定',
    'email': 'メールアドレスを設定',
    'responseStatus': 'accepted', // 出席の場合（欠席の場合は'declined'）
}];

// PATCH用JSONデータ
let patchData = JSON.stringify(requestBody, null, 2);
        
// 実行URL、メソッドの準備
let options = url.parse(apiUrl);
        
options.method = "PATCH";
options.headers = {
    "Authorization":"Bearer " + ACCESS_TOKEN,
    "Content-Type":"application/json",
    "Content-Length":Buffer.byteLength(patchData),
};

// カレンダー一覧取得のためのAPI
let options = url.parse("https://www.googleapis.com/calendar/v3/users/me/calendarList");
options.method = "GET";
options.headers = {
    "Authorization":"Bearer " + ACCESS_TOKEN,
};

// API問い合わせ開始と、コールバックの記載
let req = https.request(options, (res) => {
    let result;
    if (res.statusCode === HTTP_RESPONSE_OK) {
        result = true;
    } else {
        result = false;
    }
          
    // 受信データに対する処理なし（定義が必須）
    res.on("data", (d) => {
        // 処理なし
    });
          
    // 応答終了イベント処理
    res.on("end", () => {
        if (result === true) {
            console.log('出欠情報の更新に成功');
        } else {
            console.log('出欠情報の更新に失敗');
        }
    }); 
});

req.on("error", (e) => {
    console.log('エラー発生');
});
          
// PATCH用データの送信
req.write(patchData);
        
// データ送信終了
req.end();

```

#おわりに
GoogleカレンダーAPIに関してはまた投稿するかもしれません。
遺伝的アルゴリズムでスーパーマリオをクリアする

vcoptを使用した遺伝的アルゴリズムによるスーパーマリオの学習については
https://vigne-cla.com/9-3/
に記載されており、ここから学習したときのログを残す。

ここでエラーを回避するため、上記サイトのコードを以下のように変更している。

from nes_py.wrappers import BinarySpaceToDiscreteSpaceEnv
↓
from nes_py.wrappers import JoypadSpace

env = BinarySpaceToDiscreteSpaceEnv(env, SIMPLE_MOVEMENT)
↓
env = JoypadSpace(env, SIMPLE_MOVEMENT)

```
!pip install gym-super-mario-bros
!pip install vcopt

#マリオ関連のimport
from nes_py.wrappers import JoypadSpace
import gym_super_mario_bros
from gym_super_mario_bros.actions import SIMPLE_MOVEMENT
env = gym_super_mario_bros.make('SuperMarioBros-1-1-v0')
env = JoypadSpace(env, SIMPLE_MOVEMENT)

#プロット関連のimport
import matplotlib.pyplot as plt
from matplotlib import animation, rc

#vcopt関連のimport
import numpy as np
import numpy.random as nr
from vcopt import vcopt

#ゲーム環境のリセット
env.reset()

#動画の準備
fig = plt.figure()
ims = []

#繰り返し操作してimsに追加
for i in range(1000):
    #0:
    #1:→
    #2:→＋ジャンプ
    #3:→→
    #4:→→＋ジャンプ
    #5:ジャンプ
    #6:←
    command = nr.randint(1, 7)
    state, reward, done, info = env.step(command)
    
    #imsに追加
    im = plt.imshow(env.render(mode='rgb_array'))
    ims.append([im])
    
    if done == True:
        break
        

#imsを表示
ani = animation.ArtistAnimation(fig, ims, interval=15, blit=True)
rc('animation', html='jshtml')
ani

#保存用
#ani.save('mario.gif', writer='imagemagick')
#ani.save('mario.mp4', writer="ffmpeg")
```
上記でアニメーションが確認できます。

- env = gym_super_mario_bros.make('SuperMarioBros-1-1-v0')
でどのステージか設定できる。
- for i in range(1000): の数字で試行回数が設定できる。

（記事作成中）
Rubyの文字列の添字アクセスでの書き換えが2.5以降でめっちゃ早くなってるメモ

自分が気になったこと、今後知りたいことのメモで何かの解決策とか役に立つことは一切書いてません。

年末年始でAtCoderを始めて問題を解くことにハマっています。difficulty1000前後の問題をやるのが楽しいです。

Rubyを利用して問題を解いている中で文字列の添字アクセスでの書き換え等を行ったりしていた際の処理速度に違和感を感じたので少し調査しました。

AtCoderで動作するRubyは2.3.3なので2.3系とそれ以降でDockerで実験してみました。

```ruby
require 'benchmark'

str = 'A' * 50000

puts Benchmark.measure{
  1000.times do
    10000.times do |i|
      str[i+25000] = "B"
    end
  end
}
```


```
$ docker run -v $HOME/sandbox:/sandbox ruby:2.3 ruby /sandbox/string_benchmark.rb
 28.600000   0.010000  28.610000 ( 28.656694)
$ docker run -v $HOME/sandbox:/sandbox ruby:2.4 ruby /sandbox/string_benchmark.rb
 29.080000   0.010000  29.090000 ( 29.140195)
$ docker run -v $HOME/sandbox:/sandbox ruby:2.5 ruby /sandbox/string_benchmark.rb
  1.380000   0.000000   1.380000 (  1.383977)
$ docker run -v $HOME/sandbox:/sandbox ruby:2.6 ruby /sandbox/string_benchmark.rb
  1.380000   0.000000   1.380000 (  1.386950)
$ docker run -v $HOME/sandbox:/sandbox ruby:2.7 ruby /sandbox/string_benchmark.rb
  1.450000   0.000000   1.450000 (  1.458249)
```

2.5でかなり高速化されていることが確認できます。

> Array#concat、Enumerable#sort_by、String#concat、String#index、Time#+、などの組み込みメソッドの速度が向上しました。

https://www.ruby-lang.org/ja/news/2017/12/25/ruby-2-5-0-released/

Rubyのstring.cの2.4=>2.5の変化に答えはあるんでしょうが、大規模C言語プロジェクトを自分がちゃんと追いきれずどの部分がこのパフォーマンスの変化に繋がったのかまだわかっていないので、そういう部分も追えるようになるのは今後の課題ですね。

http://i.loveruby.net/ja/rhg/book/

こちらのRubyソースコード完全解説が参考になるかもとは思うのですが書かれたのが1.7.3の頃で15年以上前のものなので、現代版が発売されて欲しい気持ちです。

ちなみにAtCoder上での文字列添字書き換えでのパフォーマンス低下に関しては`split('')`して配列として扱う、添字アクセスの変わりにgetbyte, setbyteを使う(ASCII文字だけなので)等で解決できました。

## 追記

2020年01月02日 11時54分 (JST)に肝心の実験コードを別のコードと取り違えている事に気づき、修正を行いました。
予習、復習の繰り返しで定着させる！

Railsでメモアプリをつくる。
Railsでログイン機能付きのブログアプリをつくる。

最近学んだ事の繰り返ししてアプリケーション作りの大まかな流れを体に叩き込んでいます。
エラーの解釈、ターミナルの表記の解釈、コード・etc.. 見慣れてきました・・・やっと💦

日進月歩で頑張ります。