1.本家(kobore.net)の方
2.WordPress版の方(wp.kobore.net)の方
江端智一のホームページ
1.本家(kobore.net)の方
2.WordPress版の方(wp.kobore.net)の方
1. 背景と目的
(1)後僚より、『知財担当者から、「特許明細書作成のロジックを説明しろ」と、言われたけど、なんのことか分からない』と相談された。
(2)そこで、江端が独断と偏見に基いて確立した「特許明細書のロジック」を開示する。
(3)なお、本内容は、知財担当者(弁理士を含む)にも開示したが、少なくともクレームは受けなかった(ように思う)。
従って、内容的には大きく外れてはいないのだろう、と考えている。
2. 知財担当者からの要請
知財担当者殿より、『「特許明細書のロジック」を説明する場合には、以下のように説明して欲しい』との要請を受けている。
====================================================================== 先ほど、「背景技術→背景技術の問題点→本発明」と書きましたが、 詳細には、下記の点についてご説明頂きたくお願い致します。 (Step.1)発明のバックグラウンドとなる分野の説明 ↓ (Step.2)その分野における一般的な課題の説明 ↓ (Step.3)公知例がどのように上記課題を解決するかの説明 ↓ (Step.4)その公知例でも解決できない課題の説明 ↓ (Step.5)それをどう解決するかの説明(*本発明のロジック) *本発明について、代表となる図を記載して頂けると助かります。 ======================================================================
3. 江端の付帯説明
(面倒なので、以下メールより抜粋)
知財担当者殿のフローチャートの内容は完璧なので、そこに、私が具体例を書きます。
私はこういう風に書いてきて、発明検討会を何十回も突破して、(分割と共同を含めて)100本以上の明細書に関わってきたのですから、
(1)発明のバックグラウンドとなる分野の説明
(ポイント:ここは「技術」を書くな) ○有線でやっていたメータリングを無線でやろうとする試みはあった。 ○が、「メータおばさん」のコストの方が圧倒的に安かった。 ○近年、無線のリソースが滅茶苦茶安くなってきた。 ○「メータおばさん」の産業構造が崩れる可能性がでてきた。 ○アドホックに関する技術も、かなり溜ってきた。 ○実験ネットワークで、華々しい報告もある。 ○太陽光発電とか、未知のシステム構成要素が入ってきている。
(2)その分野における一般的な課題の説明
(ポイント:「技術」を書いても良いが、基本的には「金」「不安」で良い) ○事業的困難性 インフラコストが高い、設置面倒、メンテ面倒、保守コスト試算困難、 事業主体が不明瞭、金主が不明、ビジネスモデルが作れん ○技術的困難性 無線に対する信頼性がない(本当にない)。実績がない。 ○失敗時のインパクト 課金不公平→暴動→政権倒れる→革命(というのは冗談だが) 深刻な社会不安、インフラに対する信頼性の下落
(3)公知例がどのように上記課題を解決するかの説明
(ポイント:他人の文献公知発明を褒め称える) ○A社の特許文献1は、アドホックを自由に構築できる。 上記の技術的困難性を見事に解決できる。素晴しい(と褒め称える)。 ○B社の特許文献2は、無線をこんなに高信頼にして、社会インフラレベル にもっていける。 上記の失敗時のインパクトを見事に回避できる。 実に素晴しい(と褒め称える)。 ○C社の非特許文献1は、これらを低コストで製品化している。誠に素晴 しい(と褒めちぎる) 上記の事業的困難性を解決できるではないか。 涙が出そうな程、見事である(と褒め称える)。 【特許文献1】特開2007-278XXX号公報 【特許文献2】特開2002-132XXX号公報 【非特許文献1】「XXXXX」、Ebata Inc..[online][平成20年4月7日検索]、 インターネット
(4)その公知例でも解決できない課題の説明
(ポイント:褒め称えた発明を、掌を返して、鬼のように非難する) ○しかし、よくよく見るとA社の特許文献1は、×××はできないし、△△ △はできない。カスな発明である(と、罵しる) ○また、B社の特許文献2は、★★★★★はできないし、■■■■■はでき ない。こんなものが現実世界で使える訳がない(と、嘲笑う) ○それに、C社の非特許文献1は、安いだけで、絶対必要となる○○○と いう機能がなく、お話になりゃしない(と、コケにする)
(5)それをどう解決するかの説明(*本発明のロジック)
(ポイント:自分の発明を絶賛する(弱点については黙っている)) ○ {俺の/あたしの}発明は、こういう内容だ(*本発明のロジック)。 (ここで技術の話が始めて登場する) ○A社の特許文献1の問題点である、×××を解決し、△△△を可能とする。 この発明は完璧だ(と、自己陶酔する) ○またB社の特許文献2の弱点である、★★★★★もできるし、■■■■■ もできる。この発明は凄すぎる(と、自画自賛する) ○加えて、C社の非特許文献1が具備していない機能を、{俺の/あたしの} 発明は持っていて、産業上の利用性も完璧!(と、誇大妄想する) ○以下、その理屈をお前達に、説明してやるから、実施例を見ろ!!! (以下実施例に続く)とりあえず、こんな風に乱暴に理解して下さい。 ロジックとは、ようするに「物語」です。
(6)その他
江端が発明を評価する場合の評価方法は3つです。
(1)コスト(製造、メンテ、人材)が 1/10になる。
(2)性能(速度、メモリ、ハードディスク等)が10倍になる。
(3)上記(1)(2)に該当しなくても、(こじつけでも)「億円」の単位で儲かる。
これを、私は『特許発明 10分の1、10倍の法則』と名づけています。
『5%向上』程度なら出願やめとけ、と言っています。学生の研究ではないのだから。
また、ソフトウェアのアルゴリズムで、到底外部から発見できないようなものならやめとけ、とも。
書くだけ無駄です。侵害を立証できませんから。
# 山程書いてきた私が言っているのだから間違いない。
では、頑張って下さい。
以上
$ pacman -Su
エラー: mingw32: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" は不明です
エラー: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" をリモートで検索できませんでした
エラー: mingw64: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" は不明です
エラー: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" をリモートで検索できませんでした
エラー: msys: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" は不明です
エラー: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" をリモートで検索できませんでした
エラー: データベース 'mingw32' は無効です (無効または破損したデータベース (PGP 鍵))
エラー: データベース 'mingw64' は無効です (無効または破損したデータベース (PGP 鍵))
エラー: データベース 'msys' は無効です (無効または破損したデータベース (PGP 鍵))
てな感じのことが続き、
$pacman -S tree // treeのインストール
すら、できない有様。
で、1時間くらい回遊し続けて、この記事「MSYS2でPGP鍵が不明とか」の内容を試してみました。
$ wget http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz $ wget http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig $ pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz{.sig,} $ pacman -U --config <(echo) msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz $ pacman -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz
インストールするか? の問いには、"Y(es)"を連打していました。
全く理由は分かりませんが、PGP鍵の交換はできたようで、"tree"のインストールできました。
Dockerコンテナのサーバ化には、目処がついたので、今度はクライアント化の方を検討中です。
まずは、mkdir ~/go_echo/client を作って、そこにclient.goを放り込みました。
現時点での、Dockerfileは以下です。
# ベースとなるDockerイメージ指定
FROM golang:latest
# コンテナ内に作業ディレクトリを作成
RUN mkdir /go/src/client
# コンテナログイン時のディレクトリ指定
WORKDIR /go/src/client
# ホストのファイルをコンテナの作業ディレクトリに移行
ADD . /go/src/client
# gorillaのパッケージを入れる
RUN go get github.com/gorilla/websocket
現時点での、docker-compose.ymlは以下です。
version: '3' # composeファイルのバーション指定
services:
client: # service名
build: . # ビルドに使用するDockerfileがあるディレクトリ指定
tty: true # コンテナの起動永続化
volumes:
- .:/go/src/client # マウントディレクトリ指定
#ports:
# - "8080:8080"
#expose:
# - "8080"
で、$ docker-compose build
$ docker-compose up -d
$ (winpty) docker container exec -it client_client_1 bash を実施して、
root@d561a99d0f67:/go/src/client# go run client.go
を実施したら、
connecting to ws://localhost:8080/echo
dial:dial tcp 127.0.0.1:8080: connect: connection refused
exit status 1
となりました。このlocalhostは、コンテナ内のホストだから、コンテナの外にあるホストOSや、別のコンテナの中にあるサーバには、繋らないんだろうなぁ、と。
その証拠に、
root@d561a99d0f67:/go/src/client# ping kobore.net
PING kobore.net (49.212.198.156) 56(84) bytes of data.
64 bytes from 49.212.198.156 (49.212.198.156): icmp_seq=1 ttl=37 time=12.0 ms
と、外部には、バッチリ繋っている(でも、これは、ちょっと凄いと思う)
では、ここからトライアル。
docker-compose.ymlの最後に、
extra_hosts:
- "local_dev:192.168.0.1"
を追加 → 失敗。 ちなみに、"127.0.0.1"も失敗しました。
もしからしたら、と思い、 extra_hosts:をコメントアウトして、client.goの方のアドレスを直書きしてみました。今、PC本体のアドレスが、
C:\Users\ebata>ipconfig
Windows IP 構成
イーサネット アダプター イーサネット:
接続固有の DNS サフィックス . . . . .:
IPv4 アドレス . . . . . . . . . . . .: 192.168.0.8
サブネット マスク . . . . . . . . . .: 255.255.255.0
デフォルト ゲートウェイ . . . . . . .: 192.168.0.1
なので、client.goの一行を以下のように換えてみました。
//var addr = flag.String("addr", "localhost:8080", "http service address")
//var addr = flag.String("addr", "0.0.0.0:8080", "http service address")
var addr = flag.String("addr", "192.168.0.8:8080", "http service address")
これで動きましが、正直、なんとも気持ち悪いです。
ただ、これを解決するためには、dockerでIPフォワーディングとかやらなければならないのだと思うと、結構ウンザリした気分になりましたので、このままで放置することにします(動けばいいんですよ。ここは踏んばるところではありません)
以上
このサーバをさらにDockerのコンテナに搭載します。
サーバも何も入っていないが、Golang開発環境だけが入っているコンテナを作ります。DockerでGoの開発環境を構築するを参考させて頂きました。
mkdir work # workディレクトリ作成 cd work # 作成したworkディレクトリに移動
ここに、Dockerfileとdocker-compose.ymlを作ります。
(Dockerfileの内容)
# ベースとなるDockerイメージ指定
FROM golang:latest
# コンテナ内に作業ディレクトリを作成
RUN mkdir /go/src/work
# コンテナログイン時のディレクトリ指定
WORKDIR /go/src/work
# ホストのファイルをコンテナの作業ディレクトリに移行
ADD . /go/src/work
上記の、/go/src/work は、ローカル(PC)のディレクトリではなくて、コンテナの中のディレクトリなので、パスの構成は気にしなくてよい。
(docker-compose.yml
の中身)
version: '3' # composeファイルのバーション指定
services:
app: # service名
build: . # ビルドに使用するDockerfileがあるディレクトリ指定
tty: true # コンテナの起動永続化
volumes:
- .:/go/src/work # マウントディレクトリ指定
次に、
docker-compose build
を実行する。
$ docker-compose build
Building app
Step 1/4 : FROM golang:latest
---> a794da9351a3
Step 2/4 : RUN mkdir /go/src/work
---> Using cache
---> 094b928e9bfb
Step 3/4 : WORKDIR /go/src/work
---> Using cache
---> b7a938d02446
Step 4/4 : ADD . /go/src/work
---> 9d95f42d64e3
Successfully built 9d95f42d64e3
Successfully tagged work_app:latest
さらに、docker-compose up -d を実行する。
$ docker-compose up -d
Creating network "work_default" with the default driver
Creating work_app_1 ... done
コンテナができているか同化を確認します。
$ docker-compose ps
Name Command State Ports
------------------------------------
work_app_1 bash Up
現在、~/go_echo にある、server.goを、~/go_echo/workにコピーします。
これで、server.go が、ローカル(PC)と、コンテナの中で共有されるようになります。
では、コンテナの中に入ります。
$ winpty docker container exec -it work_app_1 bash # 江端のMSYS2 のシェルでは、"winpty"を付ける必要があるが、通常のシェルでは不要
root@abe44622eccf:/go/src/work# ls
'#main.go#' Dockerfile Dockerfile~ server.go docker-compose.yml docker-compose.yml~ main main.go main.go~ websocket-server.go
ここで、Goプログラムを実行します。
root@abe44622eccf:/go/src/work# go run server.go
server.go:21:2: cannot find package "github.com/gorilla/websocket" in any of:
/usr/local/go/src/github.com/gorilla/websocket (from $GOROOT)
/go/src/github.com/gorilla/websocket (from $GOPATH)
ふむ、やはり、こうなりますね。では、パッケージをインストールしましょう。
root@abe44622eccf:/go/src/work# go get github.com/gorilla/websocket
何のメッセージも出さずに20秒後くらいに静かにプロンプトが戻ってきました(ちょっと不安になる)。
root@abe44622eccf:/go/src/work# go run client_multi_agent.go
connecting to ws://localhost:8080/echo
dial:dial tcp 127.0.0.1:8080: connect: connection refused
exit status 1
うーん、やっぱりネットワーク回りの設定をしていないから当然か。ポート開けていないし。docker-compose downして、docker-compose.ymlに以下を追加してみました。
ports:
- "8080:8080"
$ more docker-compose.yml
version: '3' # composeファイルのバーション指定
services:
app: # service名
build: . # ビルドに使用するDockerfileがあるディレクトリ指定
tty: true # コンテナの起動永続化
volumes:
- .:/go/src/work # マウントディレクトリ指定
ports:
- "8080:8080"
それと、"go get github.com/gorilla/websocket"を毎回実行しない為には、Dockerfileに "RUN go get github.com/gorilla/websocket"を1行加えれば良いみたい。
# ベースとなるDockerイメージ指定
FROM golang:latest
# コンテナ内に作業ディレクトリを作成
RUN mkdir /go/src/work
# コンテナログイン時のディレクトリ指定
WORKDIR /go/src/work
# ホストのファイルをコンテナの作業ディレクトリに移行
ADD . /go/src/work
# gorillaのパッケージを入れる
RUN go get github.com/gorilla/websocket
そんでもって、再びdocker-compose build → docker-compose up -d を実施して、docker container exec -it work_app_1 bash をして、コンテナの中に入って、go run server.goをやったんだけど、ブラウザで、http://localhost:8080やっても表示されない。
C:\Users\ebata\go_echo\work>curl http://localhost:8080/
curl: (52) Empty reply from server
となっているところを見ると。8080ポートは外側に見えていないみたい。
でも、
C:\Users\ebata\go_echo\work>netstat -a | grep 8080
TCP 0.0.0.0:8080 DESKTOP-P6KREM0:0 LISTENING
TCP [::]:8080 DESKTOP-P6KREM0:0 LISTENING
にはなっているんだよなぁ。
試しに、コンテナの中で"curl http://localhost:8080/"をやってみたら、
oot@b30e685f9cc6:/go/src/work# curl http://localhost:8080/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
window.addEventListener("load", function(evt) {
var output = document.getElementById("output");
var input = document.getElementById("input");
var ws;
てな感じで、ばっちり見えます。
うーん、変だなぁ。"8080:8080"ってポートフォワードしているじゃないのか? WebSocketの場合は、特殊な設定がいるのか?分かりません。
もう6時間くらい闘ったので、引き上げようとして、最後に、"curl: (52) Empty reply from server" でググってみたら、ドンピシャな感じの記事を見つけました。
docker上のアプリにlocalhostでアクセスしたらERR_EMPTY_RESPONSEが出る
まさに、同じ現象が表われていて、『そう! そう!』と言いながら読み進めていき、結果として、
(解決) アプリの設定を0.0.0.0でLISTENするよう変更する
と記載されていましたので、server.goのソースコードを、
//var addr = flag.String("addr", "localhost:8080", "http service address")
var addr = flag.String("addr", "0.0.0.0:8080", "http service address") // テスト
と変更してみたところ、http://localhost:8080 でWebもcurlも表示されるようになりました。
ああ、これで、サーバのコンテナ化にメドがついた ―― と思ったら、どっと疲れが出てきました。
『Dockerのコンテナは、江端が作れ』と、指示されていましたので。
Dockerfileの最後に、
CMD ["go", "run", "server.go"]
をつけると、dockerコンテナをサーバ化にできる。
ただし、
# docker-compose build,
# docker-compose up (-d ← これを付けたらダメ。バックグラウンドで起動するとDockerが終了してしまう)
で起動すること。
Go言語は、スレッド化による並列処理が得意という話を聞いていましたので、先日の
の"client.go"を改造して、「とりあえず、動かして、止めることができればいい」という割り切りだけでコードをごそごそを変えてみました。(server.goは変更なしで大丈夫)。 ファイルは、~/go_echo/に置くこととします。
// go run client_multi_agent.go
// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
package main
import (
"flag"
"log"
"net/url"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
var addr = flag.String("addr", "localhost:8080", "http service address")
var interrupt = make(chan os.Signal, 1) // Go のシグナル通知は、チャネルに os.Signal 値を送信することで行います。
// これらの通知を受信するためのチャネル (と、プログラムが終了できること
// を通知するためのチャネル) を作ります。
var u = url.URL{Scheme: "ws", Host: *addr, Path: "/echo"} // JSON型の配列記述方法?
func main() {
flag.Parse() //引数の読み込み argv, argcと同じ
log.SetFlags(0) // ログの出力で時間の情報、この時点で0秒にセット
// interrupt := make(chan os.Signal, 1) // Go のシグナル通知は、チャネルに os.Signal 値を送信することで行います。
// // これらの通知を受信するためのチャネル (と、プログラムが終了できること
// // を通知するためのチャネル) を作ります。
signal.Notify(interrupt, os.Interrupt) // 指定されたシグナル通知を受信するために、 与えられたチャネルを登録
// します。
log.Printf("connecting to %s", u.String()) // ここは単にプリントしているだけ(だろう)
///// ここまでは共通 /////
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
go sub_main()
time.Sleep(time.Millisecond * 333) // 333ミリ秒
ticker := time.NewTicker(time.Second) // 1秒おきに通知 (sleepと同じ)
for {
select{
case <-ticker.C: // tickerのチャネルはデフォルトで付いているらしい
case <-interrupt: // こっちは手動割り込みだな検知だな
return;
}
}
}
func sub_main(){
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) // これがコネクションの実施
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close() // deferは、どこに書かれていようとも、関数から抜ける前に実行される
done := make(chan struct{}) // 配列といってもいいし、並行処理用のキューといってもいい
// 値が入っていないとデッドロックする
go func() { // 受信用スレッドを立ち上げる(スレッドの中でスレッド立ち上げているが、大丈夫だろうか)
defer close(done)
for {
_, message, err := c.ReadMessage() // このメソッドの返り値は3つで、最初の返り値は不要
if err != nil {
log.Println("read:", err)
return
}
log.Printf("recv: %s", message) // 受信したら、そのメッセージを表示する
}
}()
ticker := time.NewTicker(time.Second) // 1秒おきに通知 (sleepと同じ)
defer ticker.Stop() // このループを抜ける時に終了する
for { // 無限ループの宣言かな(C/C++ で言うとろの、whileとかdoとか)
select {
case <-done: // doneの中に何かが入っていたら、このルーチンはリターンして終了となる
// (でも何も入っていないところを見ると、func()ルーチンの消滅で、こっちが起動するんだろう)
return
case t := <-ticker.C: // tickerのチャネルはデフォルトで付いているらしい
// 時間が入ってくるまでロックされる
// この場合1秒単位でチャネルに時間が放り込まれるのでそこで動き出す。
err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) // サーバに(時刻の)メッセージを送付する
if err != nil {
log.Println("write:", err)
return
}
case <-interrupt: // こっちは手動割り込みだな検知だな
log.Println("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
// close メッセージを送信してから、サーバーが接続を閉じるのを
// (タイムアウトして)待つことで、接続をきれいに閉じます
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done: // これも上記の"done"の説明と同じでいいかな
case <-time.After(time.Second): // このメソッド凄い time.Secondより未来ならひっかかる
}
return
}
}
}
まあ、main()と sub_main()で同じ割り込みを使っているので、タイミングによっては、main()を止めることができず、sub_main()を個別に止めていくことになるが、とりあえず動いたので、これで良しとする。
go sub_main() と書くだけで、いきなりスレッド化させることができる手軽さは、かなり驚いた。
こんなんや、こんなんで、いろいろ苦労してきたんだけど、これからも、マルチエージェントシミュレーションを自力で書いていくことを考えると、正式にGo言語に移るべきかな、と思っています。
go webassembly experiments をローカルPCで動かす とかも、いろいろやっていきたいことですし。
いらんことしなければいいのですが、function.phpとかをいじって、何度かWPを壊しかけました。
という訳で、バックアップツールの"All-in-One WP Migration"を入れました。
後は、"ファイル"を選んで、PCに保存できます。
以上
を見て、コーディングしてみたのですが、全然思うような結果になりません。
サンプル数を増やすと、どんどん0に近づいていくんだけど(そりゃそうだ)、サンプル数を減らした方が、2越えは発生するけど、解説の内容と会いません。
以下のコーディングで致命的に変な点があったら、どなたかご教示下さい。
package main
import (
crand "crypto/rand"
"fmt"
"github.com/seehuhn/mt19937"
"math"
"math/big"
"math/rand"
"time"
)
type Scratch_Card struct {
UpperLeft int64
LowerLeft int64
UpperRight int64
LowerRight int64
}
var sc Scratch_Card
func main() {
//計算開始日時
started := time.Now()
//乱数の設定
seed, _ := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
rng := rand.New(mt19937.New())
rng.Seed(seed.Int64())
for k := 0; k < 1; k++ {
var pattern1_count, pattern2_count, pattern3_count, pattern4_count int64;
var pattern1_sum, pattern2_sum, pattern3_sum, pattern4_sum float64;
var rightCat,rightPattern int64
var leftCat,leftPattern int64
//fmt.Println(sc.UpperLeft,sc.UpperRight)
//fmt.Println(sc.LowerLeft,sc.LowerRight)
//fmt.Println()
for i := 0; i < 400; i++ {
// スクラッチカード1枚を作る
sc.UpperLeft = rng.Int63()%2
sc.LowerLeft = rng.Int63()%2
sc.UpperRight = rng.Int63()%2
sc.LowerRight = rng.Int63()%2
// スクラッチカードの左側を削る
if rng.Int63()%2 == 0 { // 上を削ることになった
leftPattern = 0 // 左上が削られたことのフラグ
leftCat = sc.UpperLeft // 左上のネコがスクラッチから表われる
} else { // 下を削ることになった
leftPattern = 1 // 左下が削られたことのフラグ
leftCat = sc.LowerLeft // 左下のネコがスクラッチから表われる
}
// スクラッチカードの右側を削る
if rng.Int63()%2 == 0 { // 上を削ることになった
rightPattern = 0 // 右上が削られることになったフラグ
rightCat = sc.UpperRight// 右下のネコがスクラッチから表われる
} else { // 下を削ることになった
rightPattern = 1 // 右下が削られることになったフラグ
rightCat = sc.LowerRight// 右下のネコがスクラッチから表われる
}
////////////////////
// ○○
// ××
if leftPattern == 0 && rightPattern == 0 {
pattern1_count += 1 // パターン1の回数の加算
if leftCat == rightCat { // マークが同じ
pattern1_sum += 1
} else { // マークが違う
pattern1_sum -= 1
}
}
// ××
// ○○
if leftPattern == 1 && rightPattern == 1 {
pattern2_count += 1 // パターン2の回数の加算
if leftCat == rightCat { // マークが同じ
pattern2_sum += 1
} else { // マークが違う
pattern2_sum -= 1
}
}
// ×○
// ○×
if leftPattern == 1 && rightPattern == 0 {
pattern3_count += 1 // パターン3の回数の加算
if leftCat == rightCat { // マークが同じ
pattern3_sum += 1
} else { // マークが違う
pattern3_sum -= 1
}
}
// ○×
// ×○
if leftPattern == 0 && rightPattern == 1 {
pattern4_count += 1 // パターン4の回数の加算
if leftCat == rightCat { // マークが同じ
pattern4_sum += 1
} else { // マークが違う
pattern4_sum -= 1
}
}
}
fmt.Println("pattern1_count ", pattern1_count, "pattern1_sum", pattern1_sum)
fmt.Println("pattern2_count ", pattern2_count, "pattern2_sum", pattern2_sum)
fmt.Println("pattern3_count ", pattern3_count, "pattern3_sum", pattern3_sum)
fmt.Println("pattern4_count ", pattern4_count, "pattern4_sum", pattern4_sum)
var pattern1_ave,pattern2_ave,pattern3_ave,pattern4_ave float64
pattern1_ave = pattern1_sum / float64(pattern1_count)
pattern2_ave = pattern2_sum / float64(pattern2_count)
pattern3_ave = pattern3_sum / float64(pattern3_count)
pattern4_ave = pattern4_sum / float64(pattern4_count)
fmt.Println()
fmt.Println("pattern1_ave ", pattern1_ave)
fmt.Println("pattern2_ave ", pattern2_ave)
fmt.Println("pattern3_ave ", pattern3_ave)
fmt.Println("pattern4_ave ", pattern4_ave)
fmt.Println()
}
//計算終了日時から計算開始日時を差し引いて、経過時間を出力
fmt.Println("Elapsed: ", time.Now().Sub(started))
}
以前、書いていた投稿を編集しなおして、その編集の最新日時にしたいというニーズは、私の中では結構高くて、色々なプラグインを入れて試していたのですが、上手く動きませんでした(多分、phpファイルをいじっているからだろうなぁと思っていますが)
とこが、気がつかなったのですが(あるいはWPがバージョンアップしてできるようになったのか?)、今、WP5.5ではこの機能があることに気がつきました。
結構盲点だったので、メモしておきます。
以上