TypeScript tutor

静的型付け

var x:number  = 10;
x = "hello";

コンパイルエラーとなります。

var x:number  = 10;
x = "hello";

様々な型

// number, string boolean, any
var i = 10;
var x; // var x: any

var results: number[]
results = [10, 5, 3]

列挙型

enum Signal {
  Red = 0,
  Blue = 1,
  Yellow = 2
}
var result: Signal;

// if (result === Signal.Yellow){}
// if (result === Signal['Yellow']){}
console.log(Signal[2])

関数宣言

function add(a: number, b?: number): number {
 if (b){
 return a + b;
 } else{
 return a + a;
 }
}

console.log(add(5, 3));

関数式

var add = (a: number, b: number): number =>{
 return a + b;
}
var add = (a: number, b: number): number => a + b
console.log(add(5, 3));

関数のオーバーロード

function add(a: number, b: number): number; //シグネチャ
function add(a: string, b: string): string;

function add(a: any, b: any): any {
 if(typeof a === "string" && typeof b === "string"){
 return a + " " + b;
 }
 return  a + b;
}
console.log(add(5, 3));
console.log(add("hello", "world"));

class

class User {
  name: string;
  constructor(name: string){
     this.name = name;
  }
  sayHi(); void {
  console.log("hi! i am " + this.name);
  }
}

var tom = new User("tom");
console.log(tom.name);
tom.sayHi();

getter, setter

class User {
  name: string;
  constructor(private _name: string){
     this.name = name;
  }
  sayHi(); void {
  console.log("hi! i am " + this.name);
  }
  get name(){
   return this._name;
  }
  set name(newValue: string){
    this._name = newValue;
  }
}

extends, override

class User {
  name: string;
  constructor(private _name: string){
     this.name = name;
  }
  sayHi(); void {
  console.log("hi! i am " + this.name);
  }
}

class AdminUser extends User{
 private _age: number;
 constructor(_name: string, _age: number){
  super(_name);
  this._age = _age;
 }
  public sayHi(): void {
    console.log("my age:" + this._age);
    super.sayHi();
  }
}

private:メソッドの中のみ可能
protected:クラスの中のみアクセス可能

静的メンバ:static

class User {
  name: string;
  constructor(private _name: string){
     this.name = name;
     User.count++;
  }
  sayHi(); void {
  console.log("hi! i am " + this.name);
  }
  static count: number = 0;
  
}

インターフェイス

interface Result {
  a: number;
  b: number;
}


function getTotal(result: {a: number; b: number}){
  return result.a + result.b;
}

var result = {
 a: 32,
 b: 58
};

console.log(getTotal(result));

interfaceの継承

interface SpringResult {
  a: number;
}

interface FallResult{
 b: number;
}

interface FinalResult extends SpringResult, FallResult {
 final?: number;
}

ジェネリクス

function getArray<T>(value: T): T[]{
 return[value, value, value];
}

console.log(getArray<number>(3));
console.log(getArray<string>("hello"));

ジェネリクスの制約

interface Result {
  a: number;
  b: number;
}


class MyData<T extends Result>{
  constructor(public value: T){}
  getArray(): T[]{
    return [this.value, this.value, this.value];
  }
}

内部モジュール

module UserModule{
  export var name = "yamada";
  export modlue AddressModlue {
     var zip = "123-4567"
  }
}

console.log(UserModule.name);
console.log(UserModlue.AddressModlue.zip);

Getting started Type Script

TypeScriptは大規模開発にも適したjavascriptの拡張ランゲージです。microsftが開発しています。npmでインストールします。

[vagrant@localhost typescript]$ sudo npm install -g typescript
/usr/bin/tsc -> /usr/lib/node_modules/typescript/bin/tsc
/usr/bin/tsserver -> /usr/lib/node_modules/typescript/bin/tsserver
typescript@2.0.10 /usr/lib/node_modules/typescript

拡張子はtsを使います。
main.ts

class User {

}

console.log("hello world")

変換後のjsファイルです。
main.js

var User = (function () {
    function User() {
    }
    return User;
}());
console.log("hello world");
[vagrant@localhost typescript]$ tsc main.ts
[vagrant@localhost typescript]$ ls
main.js  main.ts
[vagrant@localhost typescript]$ node main.js
hello world

phpでMySQLに接続する書き方

phpでMySQLに接続, sql文にてデータを挿入する書き方例
$stmt->executeにて実行しています。変数の$dbhはdbhandlerの略です。

  try {
    $dbh = new PDO('mysql:host='/DB_HOST.';dbname='.DB_NAME,DB_USER,DB_PASSWORD);
  } else (PDOException $e){
    echo $e->getMessage();
    exit;
  }

  $stmt = $dbh->prepare("select * from users where instagram_user_id=:user_id limit 1");
  $stmt->execute(array(":user_id"=>$json->user->id));
  $user = $stmt->fetch();

if (empty($user)){
    $stmt = $dbh->prepare("insert into users(instagram_user_id, instagram_user_name, instagram_profile_picture, instagram_access_token, created, modified) values (:user_id, :user_name, :profile_picture,  :access_token, now(), now());");
    $pramas = array(
      ":user_id" =>$json->user->id,
      ":user_name" =>$json->user->username,
      ":profile_picture" =>$json->user->profile_picture,
      ":access_token"=>$json->access_token
    );
    $stmt->execute($params);

データの取得

$stmt = $dbh->prepare("select * from users where id=:last_insert_id limit 1");
    $stmt->execute(array(":last_insert_id"=>$dbh->lastInsertId()));
    $user = $stmt->fetch();

Instagram Authentication

Client ID, Client Secretを発行し、php、mysqlでInstagramのOauthの仕組みを使ったログインを実装していきます。

リフェレンス
http_build_query:Generates a URL-encoded query string from the associative (or indexed) array provided.
PDO::prepare — 文を実行する準備を行い、文オブジェクトを返す
$dbh = new PDO:PDOオブジェクトのメソッドでデータベースを操作、$dbhという変数でPDOオブジェクトを管理
fetch:フィールドの配列参照として次の行を取り出す
Instagram Authentication: https://www.instagram.com/developer/authentication/

<?php

require_once('config.php');

session_start();

if (empty($_GET&#91;'code'&#93;)){
   // 認証前の準備
   $params = array(
     'client_id' => CLIENT_ID,
     'redirect_uri' => SITE_URL.'redirect.php',
     'scope' => 'basic',
     'response_type' => 'code'
   );
   $url = 'https://api.instagram.com/oauth/authorize/?'.http_build_query($params);

   header('Location: '.$url);
   exit;
   // instagramへ飛ばす
} else {
  // 認証後の処理
  // usr情報の取得
  $params = array(
    'client_id' => CLIENT_ID,
    'client_secret' => CLIENT_SECRET,
    'code' => $_GET['code'],
    'redirect_uri' => SITE_URL.'redirect.php',
    'grant_type' => 'authorization_code'
  );
  $url = "https://api.instagram.com/oauth/access_token";

  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_POST, 1);
  curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params));
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

  $res = curl_exec($curl);
  curl_close($curl);

  var_dump($res);
  exit;

  //user情報の格納
  // ログイン処理
  // index.phpに飛ばす
}

Using OAuth 2.0 to Access Google APIs

Google APIでクライアントID、クライアントシークレットを発行し、OauthでGoogle APIにアクセスします。

<?php

require_once('config.php');
require_once('functions.php');

session_start();

if (empty($_GET&#91;'code'&#93;)){
  // 認証前

  // 認証ダイアログ
  // csrf
  $_SESSION&#91;'state'&#93; = sha1(uniqid(mt_rand(), true));

  $params = array(
        'client_id' => CLIENT_ID,
        'redirect_uri' => 'dev.hogehoge.com:8000/redirect.php',
        'state' => $_SESSION['state'],
        'approval_prompt' => 'force',
        'scope' => 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email',
        'response_type' => 'code'
    );

  // googleへ飛ばす
  $url = 'https://accounts.google.com/o/oauth2/auth?'.http_build_query($params);
    header('Location: '.$url);
    exit;
} else {
  // 認証後
  // ssrf state check
  if ($_SESSION['state'] != $_GET['state']){
    echo "不正な処理でした!";
    exit;
  }

  // access_tokenを取得

  // ユーザー情報

  // DBに格納

  // ログイン処理

  // index.phpへ飛ばす
}

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向けインストールを実行します。

mono-project

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&#91;x&#93; = &#91;&#93;;
                    for (var y = 0; y < row; y++) {
                        this.map&#91;x&#93;&#91;y&#93; = 0;
                    }
                }
					for (var x = 1; x < col; x += 2) {
                    for (var y = 1; y < row; y += 2) {
                        this.map&#91;x&#93;&#91;y&#93; = 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&#91;this.rand(3)&#93;;
                            } else {
                                // 左以外に倒す
                                var r = this.points&#91;this.rand(2)&#93;;
                            }
                        } while (this.map&#91;x + r&#91;0&#93;&#93;&#91;y + r&#91;1&#93;&#93; === 1);
                        this.map&#91;x + r&#91;0&#93;&#93;&#91;y + r&#91;1&#93;&#93; = 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&#91;x&#93;&#91;y&#93; === 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 = &#91;&#93;;
		// // map&#91;0&#93; = &#91;0, 0, 0&#93;;
		// // map&#91;1&#93; = &#91;0, 1, 1&#93;;
		// // map&#91;2&#93; = &#91;0, 0, 0&#93;;

		// var col = 13; // 奇数
		// var row = 13; // 奇数

		// for (var x = 0; x < col; x++){
		// 	map&#91;x&#93; = &#91;&#93;;
		// 	for (var y = 0; y < row; y++){
		// 		map&#91;x&#93;&#91;y&#93; = 0;
		// 	}
		// }

		// for (var x = 1; x < col; x += 2){
		// 	for(var y = 1; y < row; y += 2){
		// 		map&#91;x&#93;&#91;y&#93; = 1;
		// 	}
		// }

		// var points = &#91;
		// 	&#91;0, -1&#93;,
		// 	&#91;0, 1&#93;,
		// 	&#91;1, 0&#93;,
		// 	&#91;-1, 0&#93;,
		// &#93;;



		// 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&#91;x&#93;&#91;y&#93; = 1;
		// 		do {
		// 			if (x === 1){
		// 				var r = points&#91;rand(3)&#93;;
		// 			} else {
		// 				var r = points&#91;rand(2)&#93;;
		// 			}
		// 		} while (map&#91;x + r&#91;0&#93;&#93;&#91;y + r&#91;1&#93;&#93; === 1);
		// 		map&#91;x + r&#91;0&#93;&#93;&#91;y + r&#91;1&#93;&#93; = 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&#91;x&#93;&#91;y&#93; === 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>