package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request){
fmt.Fprintf(w, "Hi %s!", r.URL.Path[1:])
}
func main(){
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
A Tour to Go
The rule is that public functions, types, etc., should be upper case.
Variable
package main
import "fmt"
func main(){
var msg string
msg = "hello world"
fmt.Println(msg)
msg := "hello world"
fmt.Println(msg)
a, b:= 10, 15
}
基本データ型
package main
import "fmt"
func main(){
a := 10
b := 12.3
c := "hoge"
var d bool
fmt.Printf("a: %d, b:%f, c:%s, d:%t\n", a, b, c, d)
}
const, iota: https://github.com/golang/go/wiki/Iota
package main
import "fmt"
func main(){
// const name = "yoshida"
// name = "tanaka"
const (
sun = iota
mon
tue
)
fmt.Println(sun, mon, tue)
}
pointer
package main
import "fmt"
func main(){
a := 5
var pa *int
pa = &a // a address
fmt.Println(pa)
fmt.Println(*pa)
}
function
package main
import "fmt"
func hi(name string) string{
msg := "hi!" + name
return msg
}
func main(){
fmt.Println(hi("tanaka"))
}
swap
package main
import "fmt"
func swap(a, b int)(int, int){
return b, a
}
func main(){
fmt.Println(swap(5, 2))
}
array
a := [...]int{1, 3, 5}
a := [5]int{1, 3, 5, 8, 9}
s := a[2:4]
fmt.Println(s)
fmt.Println(len(s))
fmt.Println(cap(s))
s := []int{1, 3, 5}
s = append(s, 8, 2, 10)
t := make([]int, len(s))
n := copy(t, s)
map
m := make(map[string]int) m["tanaka"] = 200 m["sato"] = 300 fmt.Println(m)
if
score := 83
if score > 80 {
fmt.Println("great")
} else {
fmt.Println("soso")
}
range
s := []int{2, 3, 8}
for i, v := range s{
fmt.Println(i, v)
構造体
type user struct {
name string
score int
}
func main(){
u := new(user)
u.name = "tanaka"
fmt.Println(u)
}
go routine
package main
import (
"fmt"
"time"
)
func task1(){
time.Sleep(time.Second * 2)
fmt.Println("task1 finished!")
}
func task2(){
fmt.Println("task2 finished!")
}
func main(){
go task1()
go task2()
time.Sleep(time.Second * 3)
}
Getting started with Go lang
Go is a cool programming language. Check out golang.org
install:sudo yum install golang
[vagrant@localhost go]$ go version go version go1.7.3 linux/amd64
package main
import "fmt"
func main(){
fmt.Println("hello world")
}
Go言語では、go buildでコンパイルしますが、go run xxx.goの1行で、実行することも可能です。
[vagrant@localhost go]$ go build hello.go [vagrant@localhost go]$ ls hello hello.go [vagrant@localhost go]$ ./hello hello world [vagrant@localhost go]$ go run hello.go hello world
mono-opt インストール
centOSによるC#の実行環境を整えるため、monoの公式サイトより、Linux向けインストールを実行します。
cd /etc/yum.repos.d yum install epel-release wget https://copr.fedoraproject.org/coprs/tpokorra/mono-opt/repo/epel-6/tpokorra-mono-opt-epel-6.repo yum install monodevelop-opt nunit-opt . /opt/mono/env.sh mono --version
[vagrant@localhost yum.repos.d]$ mono --version
Mono JIT compiler version 4.6.0 (Stable 4.6.0.245/746756c Sat Sep 24 06:33:41 UTC 2016)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS: __thread
SIGSEGV: altstack
Notifications: epoll
Architecture: amd64
Disabled: none
Misc: softdebug
LLVM: yes(3.6.0svn-mono-/)
GC: sgen
Monoのコンパイルコマンド
[vagrant@localhost csharp]$ mcs MyApp.cs [vagrant@localhost csharp]$ ls MyApp.cs MyApp.exe [vagrant@localhost csharp]$ mono MyApp.exe
迷路
左上を迷路のスタート地点、右下を迷路のゴール地点とし、0と1の配列で道と壁を作成しています。迷路作成のアルゴリズムは、棒倒し法で記載しています。考えた人は天才ですね。。
棒倒し法
1.一つとびに壁を作る 1れつ目の棒を上下左右のどちらかに倒す
2.2列目以降の棒を左以外のどれかに倒す
00010
11010
00000
01011
01000
どの位置を0から1に変更するかは、以下のように記載します。
var points = [
[0, -1],
[0, 1],
[1, 0],
[-1, 0],
];
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MAZE</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<style>
body {
font-family: "Century Gothic";
font-size: 16px;
}
#container {
text-align: center;
margin: 20px auto;
}
#mycanvas {
background: #AAEDFF;
}
.btn {
margin: 3px auto;
width: 200px;
padding: 5px;
background: #00AAFF;
color: #ffffff;
border-radius:3px;
cursor: pointer;
}
.btn:hover{
opacity: 0.8;
}
</style>
</head>
<body>
<div id="container">
<canvas width="100" height="100" id="mycanvas">
Canvasに対応したブラウザを用意してください。
</canvas>
<div id="reset" class="btn">RESET</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
(function(){
var Maze = function(col, row){
this.map = [];
this.col = col;
this.row = row;
this.startX = 0;
this.startY = 0;
this.goalX =col - 1;
this.goalY =row - 1;
this.points = [
[0, -1],
[0, 1],
[1, 0],
[-1, 0],
];
this.rand = function(n) {
return Math.floor(Math.random() * (n + 1));
};
this.init = function() {
for (var x = 0; x < col; x++) {
this.map[x] = [];
for (var y = 0; y < row; y++) {
this.map[x][y] = 0;
}
}
for (var x = 1; x < col; x += 2) {
for (var y = 1; y < row; y += 2) {
this.map[x][y] = 1;
}
}
for (var x = 1; x < col; x += 2) {
for (var y = 1; y < row; y += 2) {
do {
if (x === 1) {
// 上下左右に倒す
var r = this.points[this.rand(3)];
} else {
// 左以外に倒す
var r = this.points[this.rand(2)];
}
} while (this.map[x + r[0]][y + r[1]] === 1);
this.map[x + r[0]][y + r[1]] = 1;
}
}
};
this.draw = function() {
var view = new View();
view.draw(this);
};
};
var View = function(){
this.wallSize = 10;
this.wallColor = '#3261AB';
this.routeColor = '#ff0088';
this.canvas = document.getElementById('mycanvas');
if (!this.canvas || !this.canvas.getContext){
return false;
}
this.ctx = this.canvas.getContext('2d');
this.draw = function(maze){
this.canvas.width = (maze.col + 2) * this.wallSize;
this.canvas.height = (maze.row + 2) * this.wallSize;
// 上下の壁
for (var x = 0; x < maze.col + 2; x++) {
this.drawWall(x, 0);
this.drawWall(x, maze.row + 1);
}
// 左右の壁
for (var y = 0; y < maze.row + 2; y++) {
this.drawWall(0, y);
this.drawWall(maze.col + 1, y);
}
// 迷路の内部
for (var x = 0; x < maze.col; x++){
for(var y = 0; y < maze.row; y++){
if(maze.map[x][y] === 1){
this.drawWall(x + 1, y + 1);
}
if ((x === maze.startX && y === maze.startY) || (x === maze.goalX && y === maze.goalY))
{
this.drawRoute(x + 1, y + 1);
}
}
}
};
this.drawWall = function(x, y) {
this.ctx.fillStyle = this.wallColor;
this.drawRect(x, y);
};
this.drawRoute = function(x, y) {
this.ctx.fillStyle = this.routeColor;
this.drawRect(x, y);
};
this.drawRect = function(x, y){
this.ctx.fillRect(
x * this.wallSize,
y * this.wallSize,
this.wallSize,
this.wallSize);
};
};
function reset(){
var maze = new Maze(13, 13);
maze.init();
maze.draw();
}
reset();
document.getElementById('reset').addEventListener('click', function(){
reset();
});
// // 迷路のデータを配列で用意
// // 0と1の配列で、1を壁と表現する ※奇数でないと道ができない
// // canvasで描画
// // 棒倒し法
// // 一つとびに壁を作る 1れつ目の棒を上下左右のどちらかに倒す
// // 2列目以降の棒を左以外のどれかに倒す
// // 00010
// // 11010
// // 00000
// // 01011
// // 01000
// var map = [];
// // map[0] = [0, 0, 0];
// // map[1] = [0, 1, 1];
// // map[2] = [0, 0, 0];
// var col = 13; // 奇数
// var row = 13; // 奇数
// for (var x = 0; x < col; x++){
// map[x] = [];
// for (var y = 0; y < row; y++){
// map[x][y] = 0;
// }
// }
// for (var x = 1; x < col; x += 2){
// for(var y = 1; y < row; y += 2){
// map[x][y] = 1;
// }
// }
// var points = [
// [0, -1],
// [0, 1],
// [1, 0],
// [-1, 0],
// ];
// function rand(n){
// return Math.floor(Math.random() * (n + 1));
// }
// for (var x = 1; x < col; x += 2){
// for(var y = 1; y < row; y += 2){
// map[x][y] = 1;
// do {
// if (x === 1){
// var r = points[rand(3)];
// } else {
// var r = points[rand(2)];
// }
// } while (map[x + r[0]][y + r[1]] === 1);
// map[x + r[0]][y + r[1]] = 1;
// }
// }
// var startX = 0;
// var startY = 0;
// var goalX =col - 1;
// var goalY =row - 1;
// var wallSize = 10;
// var wallColor = '#3261AB';
// var routeColor = '#ff0088';
// var canvas = document.getElementById('mycanvas');
// if (!canvas || !canvas.getContext){
// return false;
// }
// var ctx = canvas.getContext('2d');
// canvas.width = (col + 2) * wallSize;
// canvas.height = (row + 2) * wallSize;
// // 上下の壁
// for (var x = 0; x < col + 2; x++) {
// drawWall(x, 0);
// drawWall(x, row + 1);
// }
// // 左右の壁
// for (var y = 0; y < row + 2; y++) {
// drawWall(0, y);
// drawWall(col + 1, y);
// }
// // 迷路の内部
// for (var x = 0; x < col; x++){
// for(var y = 0; y < row; y++){
// if(map[x][y] === 1){
// drawWall(x + 1, y + 1);
// }
// if ((x === startX && y === startY) || (x === goalX && y === goalY))
// {
// drawRoute(x + 1, y + 1);
// }
// }
// }
// // 壁を描画
// function drawWall(x, y) {
// ctx.fillStyle = wallColor;
// drawRect(x, y);
// }
// function drawRoute(x, y) {
// ctx.fillStyle = routeColor;
// drawRect(x, y);
// }
// function drawRect(x, y){
// ctx.fillRect(
// x * wallSize,
// y * wallSize,
// wallSize,
// wallSize);
// }
})();
</script>
</body>
</html>
pinpongゲーム
canvasを使って、x座標、y座標で、setTime関数で動かしています。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pong Game</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<style>
body {
margin: 0;
font-family: "Century Gothic";
font-size: 16px;
}
#container {
text-align: center;
margin: 5px auto;
}
#mycanvas {
background: #AAEDFF;
}
#btn {
margin: 3px auto;
width: 200px;
padding: 5px;
background: #00AAFF;
color: #FFFFFF;
border-radius: 3px;
cursor: pointer;
}
#btn:hover {
opacity: 0.8;
}
</style>
</head>
<body>
<div id="container">
<canvas width="280" height="280" id="mycanvas">
Canvasに対応したブラウザを用意してください。
</canvas>
<div id="btn">START</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(function(){
var ctx,
myPaddle,
myBall,
mouseX,
score,
scoreLabel,
isPlaying = false,
timerId;
var canvas = document.getElementById('mycanvas');
if (!canvas|| !canvas.getContext) return false;
ctx = canvas.getContext('2d');
var Label = function(x, y){
this.x = x;
this.y = y;
this.draw = function(text){
ctx.font = 'bold 14px "Century Gothic"';
ctx.fillStyle = '#00AAFF';
ctx.textAlign = 'left';
ctx.fillText(text, this.x, this.y);
}
}
var Ball = function(x, y, vx, vy, r){
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.r = r;
this.draw = function(){
ctx.beginPath();
ctx.fillStyle = '#FF0088';
ctx.arc(this.x, this.y, this.r, 0, 2*Math.PI, true);
ctx.fill();
};
this.move = function(){
this.x += this.vx;
this.y += this.vy;
if (this.x + this.r > canvas.width || this.x - this.r < 0){
this.vx *= -1;
}
if (this.y - this.r < 0){
this.vy *= -1;
}
if (this.y + this.r > canvas.height){
// alert("game over");
isPlaying = false;
$('#btn').text('REPLAY?').fadeIn();
}
};
this.checkCollision= function(paddle){
if ((this.y + this.r > paddle.y && this.y + this.r < paddle.y + paddle.h) &&
(this.x > paddle.x - paddle.w / 2 && this.x < paddle.x + paddle.w /2)){
this.vy *= -1;
score++;
if (score % 2 === 0){
this.vx *= 1.3;
paddle.w *= 0.9;
}
}
}
}
var Paddle = function(w, h){
this.w = w;
this.h = h;
this.x = canvas.width / 2;
this.y = canvas.height - 30;
this.draw = function(){
ctx.fillStyle = '#00AAFF';
ctx.fillRect(this.x - this.w / 2, this.y, this.w, this.h);
};
this.move = function(){
this.x = mouseX - $('#mycanvas').offset().left;
}
};
function rand(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function init(){
score = 0;
isPlaying = true;
myPaddle = new Paddle(100, 10);
myBall = new Ball(rand(50, 250), rand(10, 80), rand(3, 8), rand(3, 8), 6);
scoreLabel = new Label(10, 25);
scoreLabel.draw('SCORE: ' + score);
}
function clearStage(){
ctx.fillStyle = '#AAEDFF';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
function update(){
clearStage();
scoreLabel.draw('SCORE: ' + score);
myPaddle.draw();
myPaddle.move();
myBall.draw();
myBall.move();
myBall.checkCollision(myPaddle);
timerId =setTimeout(function(){
update();
}, 30);
if(!isPlaying) clearTimeout(timerId);
}
$('#btn').click(function(){
$(this).fadeOut();
init();
update();
});
$('body').mousemove(function(e){
mouseX = e.pageX;
});
});
</script>
</body>
</html>
rpsecによるリファクタリング
require 'calc'
RSpec.describe "A calc" do
before do
@calc = Calc.new
end
it "given 2 and 3, returns 5" do
expect(@calc.add(2, 3)).to eq(5)
end
it "given 5 and 8, returns 13" do
expect(@calc.add(5, 8)).to eq(13)
end
end
class Calc
def add(a, b)
a + b # 仮実装
end
end
[vagrant@localhost rspec]$ rspec .. Finished in 0.00235 seconds (files took 0.11087 seconds to load) 2 examples, 0 failures
describeはcontextを書き換えることも可能。また、コマンドラインはrspec -fdとしても使われる。
pendding
require 'calc'
RSpec.describe Calc do
describe "when normal mode" do
it "given 2 and 3, returns 5" do
calc = Cal.new
expect(calc.add(2, 3)).to eq(5)
end
describe "when graph mode" do
it "draws graph" do
end
end
matcher:https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
expect(calc.add(2, 3)).to eq(5) #matcher
expect(calc.add(2, 3)).not_to eq(5) #matcher
expect(calc.add(2, 3)).to be true #matcher
expect(calc.add(2, 3)).to be false #matcher
expect(calc.add(2, 3)).to be > 10 #matcher
expect(calc.add(2, 3)).to be_between(1, 10).include #matcher
expect(calc).to respond_to(:add) #matcher
expect(calc.add(2, 3).integer?).to be true
subject
require 'calc'
RSpec.describe Calc do
subject(:calc){ Calc.new }
it {
# calc = Calc.new
expect(calc.add(2, 3)).to eq(5)
}
end
let
context "tax 5%" do
let(:tax){ 0.05 }
it { expect(calc.price(100, tax)).to eq(105)}
end
context "tax 8%" do
let(:tax){ 0.08 }
it { expect(calc.price(100, tax)).to eq(108)}
end
message expectation
class Calc
def initialize(logger)
@logger = logger
end
def add(a, b)
@logger.log
a + b
end
end
rspecによるBDD
rspec install
[vagrant@localhost rspec]$ gem install rspec [vagrant@localhost rspec]$ ruby -v ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux] [vagrant@localhost rspec]$ rspec -v 3.5.4
TDD/BDD 開発サイクル
1.失敗するテストを書く(Red)
2.最小限のコードを書いてテストをパスさせる(Green)
3.リファクタリング
initフォルダの作成
[vagrant@localhost rspec]$ rspec --init create .rspec create spec/spec_helper.rb
テストファイルは〇〇_spec.rbとし、specフォルダの中に書きます。
1.ミスするコード
RSpec.describe "A calc" do
it "given 2 and 3, return 5" do
calc = Calc.new
epect(calc.add(2, 3)).to eq(5)
end
end
[vagrant@localhost rspec]$ rspec
F
Failures:
1) A calc given 2 and 3, return 5
Failure/Error: calc = Calc.new
NameError:
uninitialized constant Calc
# ./spec/calc_spec.rb:3:in `block (2 levels) in '
Finished in 0.00317 seconds (files took 0.32741 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/calc_spec.rb:2 # A calc given 2 and 3, return 5
2.パスするコードを作成
class Calc
def add(a, b)
5 # 仮実装
end
end
require 'calc'
RSpec.describe "A calc" do
it "given 2 and 3, returns 5" do
calc = Calc.new
expect(calc.add(2, 3)).to eq(5)
end
end
実行
[vagrant@localhost rspec]$ rspec . Finished in 0.00095 seconds (files took 0.10059 seconds to load) 1 example, 0 failures
flexbox
cssのdisplayをflexとし、幅の比率や順番を簡単に記述することができます。
.container {
width: 300px;
height: 300px;
color: #fff;
background: #eee;
display: flex;
/*flex-direction:column-reverse;*/
/*flex-wrap: wrap;*/
/*flex-wrap: wrap-reverse;*/
/*flex-flow: wrap column;*/
/*justify-content: flex-start;*/
/*justify-content: flex-end;*/
/*justify-content: space-between;*/
/*justify-content: space-around;*/
/*align-items: flex-start;*/
/*align-items: flex-end;*/
/*align-items: flex-center;*/
/*align-items: stretch;*/
/*align-content: flex-start;*/
/*align-content: space-between;*/
/*align-content: space-around;*/
justify-content: center;
align-items: center;
}
.box {
width:80px;
height: 80px;
}
/*
flex-grow, shrink, basis,
margin:auto;
*/
.box-1 { background: tomato;
/*flex: 0 1 120px;*/
/*order: 1;
align-self: flex-end;*/}
/*.box-2 { background: slategray;
/*flex: 0 2 120px;*/ }*/
/*.box-3 { background: pink;
margin-left: auto;
/*flex: 0 3 120px;*/ }*/
Kotlin 構文2
getter, setter
class User(var name: String){
var team = "red"
get(){
return field.toUpperCase()
}
set(value){
if (value !=""){
field = value
}
}
fun sayHi(){
println("hi $name")
}
}
fun main(args: Array<String>){
val tom = User("tom")
println(tom.team)
tom.sayHi()
}
class override
class AdminUser(name: String): User(name){
fun sayHello(){
println("hello $name")
}
override fun sayHi(){
println("what $name")
}
}
open class User(var name: String){
open fun sayHi(){
println("hi $name")
}
}
fun main(args: Array<String>){
val bob = AdminUser("bob")
println(bob.name)
bob.sayHi()
}
アクセス修飾子: privateとpublic
open class User(private var name: String){
open fun sayHi(){
println("hi $name")
}
}
class extension
fun User.sayHello(){
println("hello $name")
}
val User.myName: String
get() = "I am $name"
class User(var name: String){
open fun sayHi(){
println("hi $name")
}
}
fun main(args: Array<String>){
val bob = User("bob")
bob.sayHello()
bob.sayHi()
println(bob.myName)
}
抽象クラス
abstract class User {
abstract fun sayHi()
}
class Japanese: User(){
override fun sayHi(){
println("こんにちは")
}
}
class American: User(){
override fun sayHi(){
println("hi")
}
}
fun main(args: Array<String>){
val tom = American()
val taro = Japanese()
tom.sayHi()
taro.sayHi()
}
interface
interface Sharable{
// 抽象プロパティ、抽象メソッド、メソッド
val version: Double
fun share()
fun getInfo(){
println("Share I/F ($version)")
}
}
class User: Sharable {
override val version = 1.1
override fun share(){
println("Sharing..")
}
}
fun main(args: Array<String>){
val user = User()
user.share()
user.getInfo()
}
generics
class MyData<T> {
fun getThree(x: T){
println(x)
println(x)
println(x)
}
}
fun main(args: Array<String>){
val i = MyData<Int>()
i.getThree(32)
val s = MyData<String>()
s.getThree("hello")
}
データクラス
data class Point(val x: Int, val y: Int)
fun main(args: Array<String>){
val p1 = Point(3, 5)
val p2 = Point(3, 5)
val p3 = p1.copy()
println(p1)
println(if (p1 == p2) "same" else "not same")
}
List
fun main(args: Array<String>){
val sales: List<Int> = listOf(20, 30, 40)
println(sales[1])
println(sales.size)
for (sale in sales){
println(sale)
}
}
set
fun main(args: Array<String>){
val answers: Set<Int> = setOf(3, 5, 8, 3)
println(answers)
println(answers.contains(3))
val set1 = setOf(1, 3, 5, 8)
val set2 = setOf(3, 5, 8, 9)
println(set1.intersect(set2))
println(set1.union(set2))
println(set1.subtract(set2))
}
Map
fun main(args: Array<String>){
val users: Map<String, Int> = mapOf("kobayashi" to 10, "kagawa" to 22, "tanaka" to 33)
println(users["kobayashi"])
println(users.size)
println(users.keys)
println(users.values)
println(users.entries)
}
map, filter, foreach
fun main(args: Array<String>){
val prices = listOf(53.2, 48.2, 32.8)
prices
/*.map { n -> n + 1.08} //*/
.map { it * 1.08 }
.filter { it > 50 }
.forEach { println(it) }
}
例外処理
fun div(a: Int, b: Int){
try {
println(a / b)
} catch(e: ArithmeticException) {
println(e.message)
}
}
fun main(args: Array<String>){
div(3, 0)
}
Nullable型
fun main(args: Array<String>){
val s: String? = null
/*println(s)*/
/*if (s != null){
println(s.length)
} else {
println(null)
}*/
println(s?.length ?: -1)
}