[PHP7.4.11] 二次元配列

配列の中に配列

$ary = [
["a", "b", "c", "d"],
["e", "f", "g", "h"],
["i", "j", "k", "l"]
];

echo "<pre>";
var_dump($ary);
echo "</pre>";

配列の追加

$ary = [
// 省略
];

$ary[] = ["m", "n", "o", "p"];

多次元配列

$ary = [
	"fruits" => ["apple", "banana"],
	"animal" => ["monkey", "cat"]
];

多次元配列の追加

$ary = [
	"fruits" => ["apple", "banana"],
	"animal" => ["monkey", "cat"]
];

$ary_b = [
	"contory" => ["japan","usa"]
];


echo "<pre>";
var_dump(array_merge($ary, $ary_b));
echo "</pre>";

ただこれ、下のようにやると、fruitsが上書きされてしまうな。

$ary = [
	"fruits" => ["apple", "banana"],
	"animal" => ["monkey", "cat"]
];

$ary_b = [
	"fruits" => ["kui"]
];

こうすると上手くいく

$ary = [
	"fruits" => ["apple", "banana"],
	"animal" => ["monkey", "cat"]
];

$ary["fruits"][] = "kui";

echo "<pre>";
var_dump($ary);
echo "</pre>";

OK, これを応用して考える

[Python3.8.5] Stripeを試してみたい

Stripe手数料:3.6%
-> smartHR, Booking.com, slack, shopify, freee, cookpad
-> Ruby, Java, Scala and Javascript

### Stripeの特徴
– 初期費用がかからず、事前審査不要
– 少額の場合は他社より料率・振込手数料が安価
– 決済画面への遷移がなくて決済フォームもシンプル
– 顧客へ返金時に返金手数料はかからないものの、元の決済手数料は一切返金なし

### 実装方法
自前でサーバを用意するパターン(custom payment flow)と、ドロップインソリューション(prebuild checkout page)といって Stripeが用意した決済画面を利用する方法がある。

docs: https://stripe.com/docs/payments/accept-a-payment?integration=elements

$ python3 –version
Python 3.8.5
$ pip3 install stripe
$ pip3 install flask

server.py

import os
from flask import Flask, jsonify, request

import stripe

stripe.api_key = 'sk_test_***'

app = Flask(__name__,
			static_url_path='',
			static_folder='.')

YOUR_DOMAIN = '192.168.33.10:5000'

@app.route('/create-session', methods=['POST'])
def create_checkout_session():
	try:
		checkout_session = stripe.checkout.Session.create(
			payment_method_types=['card'],
			line_items=[
				{
					'price_data': {
						'currency': 'usd',
						'unit_amount': 2000,
						'product_data': {
							'name': 'Stubborn Attachments',
							'images': ['https://i.imgur.com/EHyR2nP.png'],
						},
					},
					'quantity': 1,
				},
			],
			mode='payment',
			success_url=YOUR_DOMAIN + '/success.html',
			cancel_url=YOUR_DOMAIN + '/cancel.html',
		)
		return jsonify({'id': checkout_session.id})
	except Exception as e:
		return jsonify(error=str(e)), 403

if __name__ == '__main__':
	app.run(host='0.0.0.0')

success.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Thanks for your order!</title>
	<link rel="stylesheet" href="">
</head>
<body>
	<section>
		<p>
			We appreciate your business! If you have any questions, please email <a href="mailto:info@hpscript.com">info@hpscript.com</a>.
		</p>
	</section>
</body>
</html>

cancel.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Checkout canceled</title>
	<link rel="stylesheet" href="">
</head>
<body>
	<section>
		<p>
			Forgot to add something to your car? Shop around then come back to pay!
		</p>
	</section>
</body>
</html>

checkout.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Buy cool new product</title>
	<link rel="stylesheet" href="">
	<script src="https://polyfill.io/v3/polyfill.min.js?version=3.52.1&features=fetch"></script>
	<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
	<section>
		<div class="product">
			<img src="https://i.imgur.com/EHyR2nP.png" alt="The cover of Stubborn Attachments">
			<div class="description">
				<h3>Stubborn Attachments</h3>
				<h5>$20.00</h5>
			</div>
		</div>
		<button id="checkout-button">Checkout</button>
	</section>
</body>
<script type="text/javascript">
	var stripe = Stripe("pk_test_***");
	var checkoutButton = document.getElementById("checkout-button");

	checkoutButton.addEventListener("click", function(){
		fetch("/create-session", {
			method: "POST",
		})
			.then(function (response){
				return response.json();
			})
			.then(function (session){
				return stripe.redirectToCheckout({ sessionId: session.id });
			})
			.then(function(result){
				if(result.error){
					alert(result.error.message);
				}
			})
			.catch(function(error){
				console.error("Error:", error);
			});
	});
</script>
</html>

$ ls
cancel.html checkout.html other server.py style.css success.html

$ python3 server.py

ん? strip.jsはhttpsでないとダメっぽい。。

[paypal] APIを使ってみる

Basic Integrationに沿ってやっていきます。
https://developer.paypal.com/docs/checkout/integrate/#

– Render the PayPal Smart Payment Buttons
– Set up a one-time transaction and immediately capture the funds into your account
– Test the button and take it live on your site

まず前提として、paypalアカウントが必要。
paypalアカウントでdeveloperサイトにログインする。
https://developer.paypal.com/developer/applications

create appとすると、paypal account, client ID, secretが生成されるのでメモしておく。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<script
    src="https://www.paypal.com/sdk/js?client-id=${clientId}"></script>
    <div id="paypal-button-container"></div>
    <script>
		paypal.Buttons().render('#paypal-button-container');
    </script>
</body>
</html>

$ python3 -m http.server 8000

やばっ

valueは$USっぽいです。

<script>
		paypal.Buttons({
			createOrder: function(data, actions){
				return actions.order.create({
					purchase_units: [{
						amount: {
							value: '0.01'
						}
					}]
				});
			},
			onApprove: function(data, actions){
				return actions.order.capture().then(function(details){
					alert('Transaction completed by ' + details.payer.name.given_name);
				});
			}
		}).render('#paypal-button-container');
    </script>

productionではbusinessアカウントが必要っぽい。
$0.01がカゴに入ってます。

なるほど、JSで管理するんやな、日本はpaypalは普及してませんが、イメージは掴めました。

[jdk14.0.2] 基礎4

ArrayList

import java.util.*;

public class MyApp {

	public static void main(String[] args){

		List<Integer> sales = new ArrayList<>();

		sales.add(10);
		sales.add(20);
		sales.add(30);

		for (int i = 0; i < sales.size(); i++){
			System.out.println(sales.get(i));
		}

		sales.set(0, 100);
		sales.remove(2);

		for (Integer sale: sales){
			System.out.println(sale);
		}
	}
}

HashSet // 重複しない、順番が定まらない
L TreeSet, LinkedHashSet

public static void main(String[] args){

		// HashSet<Integer> = new HashSet<>();
		Set<Integer> sales = new HashSet<>();

		sales.add(10);
		sales.add(20);
		sales.add(30);
		sales.add(10);

		System.out.println(sales.size());
		for(Integer sale:sales){
			System.out.println(sale);
		}

		sales.remove(30);

		for(Integer sale:sales){
			System.out.println(sale);
		}
	}

HashMap

public class MyApp {

	public static void main(String[] args){
		// HashMap: key value
		// HashMap<String, Integer> sales = new HashMap<>();
		Map<String, Integer> sales = new HashMap<>();

		sales.put("tom", 10);
		sales.put("bob", 20);
		sales.put("steve", 30);

		System.out.println(sales.get("tom"));
		System.out.println(sales.size());

		for(Map.Entry<String, Integer> sale: sales.entrySet()){
			System.out.println(sale.getKey() + ":" + sale.getValue());
		}

		sales.put("tom", 100);
		sales.remove("steve");

		for(Map.Entry<String, Integer> sale: sales.entrySet()){
			System.out.println(sale.getKey() + ":" + sale.getValue());
		}
	}
}

StreamAPI

public static void main(String[] args){
		List<Integer> sales = new ArrayList<>(Arrays.asList(12, 30, 22, 4, 9));

		// for(Integer sale: sales){
		// 	System.out.println(sale);
		// }
		sales
			.stream()
			.filter(e-> e % 3 == 0)
			.map(e-> "(" + e + ")")
			.forEach(System.out::println);
		
	}

LocalDateTime class

import java.time.*;
import java.time.format.DateTimeFormatter;

public class MyApp {

	public static void main(String[] args){
		LocalDateTime d = LocalDateTime.now();

		System.out.println(d.getYear());
		System.out.println(d.getMonth().getValue());

		System.out.println(d.plusMonths(2).minusDays(3));

		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy!MM!dd!");
		System.out.println(d.format(dtf));
	}
}

[jdk14.0.2] 基礎3

exception

class MyException extends Exception {
	public MyException(String s){
		super(s);
	}
}

public class MyApp {

	public static void div(int a, int b){
		try {
			if(b < 0){
				throw new MyException("not minus!");
			}
			System.out.println(a / b);
		} catch(ArithmeticException e){
			System.err.println(e.getMessage());
		} catch(MyException e){
			System.err.println(e.getMessage());
		} finally {
			System.out.println(" -- end -- ");
		}
	}

	public static void main(String[] args){
		div(3, 0);
		div(5, -2);
	}
}

wrapper class

public class MyApp {

	public static void main(String[] args){
		// Integer i = new Integer(32);
		// int n = i.intValue();
		Integer i = 32; // auto boxing 参照型
		int n = i; // auto unboxing
		System.out.println();
	}
}

generics 型の汎用化

class MyData<T> {
	public void getThree(T x){
		System.out.println(x);
		System.out.println(x);
		System.out.println(x);
	}
}

public class MyApp {

	public static void main(String[] args){
		MyData<Integer> i = new MyData<>(); //参照型
		i.getThree(32);

		MyData<String> s = new MyData<>(); //参照型
		s.getThree("What's up");
	}
}

Thread

class MyRunnable implements Runnable {
	@Override
	public void run(){
		for (int i = 0; i < 500; i++){
			System.out.print('*');
		}
	}
}

public class MyApp {

	public static void main(String[] args){
		MyRunnable r = new MyRunnable();

		Thread t = new Thread(r);
		t.start();

		for (int i = 0; i < 500; i++){
			System.out.print('.');
		}
	}
}

無名クラス

public class MyApp {

	public static void main(String[] args){
		new Thread(new Runnable() {
			@Override
			public void run(){
				for (int i = 0; i < 500; i++){
					System.out.print('*');
				}
			}
		}).start();

		for (int i = 0; i < 500; i++){
			System.out.print('.');
		}
	}
}

ラムダ式

new Thread(()-> {
			for (int i = 0; i < 500; i++){
				System.out.print('*');
			}
		}).start();

		for (int i = 0; i < 500; i++){
			System.out.print('.');
		}

String

public class MyApp {

	public static void main(String[] args){
		String s = "abcdef";
		System.out.println(s.length());
		System.out.println(s.substring(2, 5));
		System.out.println(s.replaceAll("ab", "AB"));

		String s1 = "ab";
		String s2 = "ab";

		if(s1.equals(s2)){
			System.out.println("same!");
		}

		if(s1 == s2){
			System.out.println("same!same!");
		}

		String ss1 = new String("abc");
		String ss2 = new String("abc");

		if(ss1 == ss2){
			System.out.println("same!same!same!");
		}
	}
}

printf

public class MyApp {

	public static void main(String[] args){

		int score = 50;
		double height = 165.8;
		String name ="hpscript";

		System.out.printf("name: %-10s, score: %10d, height: %5.2f\n", name, score, height);

		String s = String.format("name: %10s, score: %-10d, height: %5.2f\n", name, score, height);
		System.out.println(s);
	}
}

random

import java.util.Random;

public class MyApp {

	public static void main(String[] args){

		double d = 53.234;
		
		System.out.println(Math.ceil(d));
		System.out.println(Math.floor(d));
		System.out.println(Math.round(d));
		System.out.println(Math.PI);

		Random r = new Random();
		System.out.println(r.nextDouble()); // 0 - 1
		System.out.println(r.nextInt(100));
		System.out.println(r.nextBoolean());
	}
}

決済系APIを実装したい

### PayPal
月間のペイパルによる売上高
30万円以下:3.6 % + 40 円 / 件
30万円超 100万円以下:3.4 % + 40 円 / 件
100万円超 1,000万円以下:3.2 % + 40 円 / 件
1,000万円超:2.9 % + 40 円 / 件

paypalの実装方法:
https://qiita.com/PPJP/items/db5c57991c2c3fe80ac7

### Stripe
手数料:3.6%
-> smartHR, Booking.com, slack, shopify, freee, cookpad
-> Ruby, Java, Scala and Javascript

### PAY.JP
ベーシックプラン
月額費用:0¥
visa / master:3.0%
jcb / american express / dinersclub /discover:3.6%

プロプラン
月額費用:10,000¥
visa / master:2.59%
cb / american express / dinersclub /discover:3.3%

-> クレジットカード決済を導入できる
-> bizreach, baseなど

### Square
https://squareup.com/jp/ja
3.6%(Visa/MasterCard/American Expressのみ)
-> 決済種類豊富
-> HPを見る限り、店舗中心か

とりあえず、上から順番に試していきますかー

[jdk14.0.2] 基礎2

package hpscript.myapp;
import hpscript.myapp.model.User;
import hpscript.myapp.model.AdminUser;

public class MyApp {

	public static void main(String[] args){

		User tom;
		tom = new User("john");

		System.out.println(tom.name);
		tom.sayHi();

		AdminUser bob = new AdminUser("bob");
		System.out.println(bob.name);
		bob.sayHello();
	}
}

$ javac hpscript/myapp/MyApp.java
$ java hpscript.myapp.MyApp

getter, setter

class User {
	private String name;
	private int score;

	public User(String name, int score){
		this.name = name;
		this.score = score;
	}

	public int getScore(){
		return this.score;
	}

	public void setScore(int score){
		if (score > 0){
			this.score = score;
		}
	}
}



public class MyApp {

	public static void main(String[] args){

		User tom = new User("tom", 65);
		tom.setScore(85);
		tom.setScore(-22);
		System.out.println(tom.getScore());
	}
}

static

class User {
	private String name;
	private static int count = 0;

	public User(String name){
		this.name = name;
		User.count++;
	}

	public static void getInfo(){
		System.out.println("# of instances: " + User.count);
	}
}

public class MyApp {
	public static void main(String[] args){
		User.getInfo();
		User tom = new User("tom");
		User.getInfo();
		User bob = new User("bob");
		User.getInfo();
	}
}

initializer

class User {
	private String name;
	private static int count;

	static {
		User.count = 0;
		System.out.println("Static initializer");
	}

	{
		System.out.println("instance initializer");
	}

	public User(String name){
		this.name = name;
		User.count++;
		System.out.println("Constructor");
	}

	public static void getInfo(){
		System.out.println("# of instances: " + User.count);
	}
}

public class MyApp {
	public static void main(String[] args){
		User.getInfo();
		User tom = new User("tom");
		User.getInfo();
		User bob = new User("bob");
		User.getInfo();
	}
}

final

class User {
	protected String name;
	private static final double VERSION = 1.1;

	User(String name){
		this.name = name;
		User.VERSION = 1.2;
	}

	void sayHi(){
		System.out.println("Hi!" + this.name);
	}
}

class AdminUser extends User{
	AdminUser(String name){
		super(name);
	}

	void sayHi(){
		System.out.println("[admin] Hi!" + this.name);
	}

}

public class MyApp {
	public static void main(String[] args){
		User tom = new User("tom");
		User.sayHi();
		AdminUser bob = new AdminUser("bob");
		AdminUser.sayHi();
	}
}

abstract

abstract class User {
	public abstract void sayHi();
}

class JapaneseUser extends User {
	@Override
	public void sayHi(){
		System.out.println("こんにちは!");
	}
}

class AmericanUser extends User {
	@Override
	public void sayHi(){
		System.out.println("Hi");
	}
}


public class MyApp {
	public static void main(String[] args){
		AmericanUser tom = new AmericanUser();
		JapaneseUser aki = new JapaneseUser();
		tom.sayHi();
		aki.sayHi();
	}
}

interface

interface Printable {
	// 定数
	// 抽象メソッド default, static
	double VERSION = 1.2;
	void print();
	public default void getInfo(){
		System.out.println("I/F ver. " + Printable.VERSION);
	}
} 

class User implements Printable{
	@Override
	public void print(){
		System.out.println("Now printing user profile...");
	}	
}


public class MyApp {
	public static void main(String[] args){
		User tom = new User();
		tom.print();
		tom.getInfo();
	}
}

列挙型

enum Result {
	SUCCESS,
	ERROR,
}

public class MyApp {
	public static void main(String[] args){
		Result res;

		res = Result.ERROR;

		switch (res){
			case SUCCESS:
				System.out.println("OK!");
				System.out.println(res.ordinal());
				break;
			case ERROR:
				System.out.println("NG!");
				System.out.println(res.ordinal());
				break;
		}
	}
}

[jdk14.0.2] 基礎1

compile
$ javac MyApp.java
$ java MyApp

basic

public class MyApp {

	public static void main(String[] args){
		System.out.println("Hello world!");
	}
}

variable

String msg;
		msg = "Hello world!";
		System.out.println(msg);

variable
L primitiveなデータ型はメモリ領域を確保する
L String, arrayなど参照型はメモリの番地を確保して、番地を参照している

public static void main(String[] args){
		// String, char
		char a = 'a';
		// byte short int long
		int x = 10;
		long y = 55555555L;
		// 浮動小数点数 float double
		double d = 23423.334;
		float f = 32.33F;
		// 論理値
		boolean flag = true;
		// \n
		String msg = "Hello wo\nr\tld";
		System.out.println(msg);
	}
int i;
		i = 10 / 3;
		System.out.println(i);
		i = 10 % 3;
		System.out.println(i);
		int x = 5;
		x++;
		System.out.println(x);
		x--;
		System.out.println(x);

cast

double d = 52343.213;
int i = (int)d;

		int i = 10;
		double d = (double)i / 4;
		System.out.println(d); 

if

		int score = 85;
		if(score > 80){
			System.out.println("great");
		} else if (score > 60){
			System.out.println("good"); 
		} else {
			System.out.println("soso"); 
		}

		int score = 25;
		String msg = score > 80 ? "great!": "soso ...!";
		System.out.println("soso");

switch

		String signal = "red";
		switch(signal) {
			case "red":
				System.out.println("stop!");
				break;
			case "blue":
				System.out.println("go!");
				break;
			case "yellow":
				System.out.println("caution!");
				break;
			default:
				System.out.println("wrong signal!");
				break;
		}

while

		int i = 0;
		while(i < 10){
			System.out.println(i);
			i++;
		}

		do {
			System.out.println(i);
			i++;
		}while(i < 10);

for

for(int i = 0; i < 10; i++) {
			if (i == 5){
				continue;
			}
			System.out.println(i);
		}

配列

		int[] sales;
		sales = new int[3];

		sales[0] = 100;
		sales[1] = 200;
		sales[2] = 300;

		System.out.println(sales[1]);

		sales[1] = 1000;
		System.out.println(sales[1]);

		sales = new int[] {100, 200, 300};
		int[] sales = {100, 200, 300};

		int[] sales = {100, 200, 300};

		for(int i = 0; i < sales.length; i++){
			System.out.println(sales[i]);
		}

		for (int sale : sales){
			System.out.println(sale);
		}

基本データ型と参照型

		int[] a = {3, 5, 7};
		int[] b = a;
		b[1] = 8;
		System.out.println(a[1]);
		System.out.println(b[1]);

		// 文字列の場合は、別の領域にメモリを確保する
		String s = "hello";
		String t = s;
		t = "world";
		System.out.println(s);
		System.out.println(t);

method

	public static void sayHi(String name){
		System.out.println("Hi!" + name);
	}

	public static void main(String[] args){
		sayHi("Tom");
		sayHi("Bob");
	}

	public static String sayHi(String name){
		return "hi!" + name;
	}

	public static void main(String[] args){
		String msg = sayHi("Steve");
		System.out.println(msg);
	}

	// overload
	public static void sayHi(){
		System.out.println("Hi! Nobody!");
	}

	public static void main(String[] args){
		sayHi("Steve");
		sayHi();
	}

class

class User {
	String name = "Me!";

	void sayHi(){
		System.out.println("Hi!");
	}
}

public class MyApp {

	public static void main(String[] args){

		User tom;
		tom = new User();

		System.out.println(tom.name);
		tom.sayHi();
	}
}

constructor
L thisはclassのcontructorという意味

class User {
	String name;

	User(String name){
		this.name = name;
	}

	void sayHi(){
		System.out.println("Hi!" + this.name);
	}
}

public class MyApp {

	public static void main(String[] args){

		User tom;
		tom = new User("Tom");

		System.out.println(tom.name);
		tom.sayHi();
	}
}

継承

class AdminUser extends User{
	AdminUser(String name){
		super(name);
	}

	void sayHello(){
		System.out.println("Hello!" + this.name);
	}

}

public class MyApp {

	public static void main(String[] args){

		User tom;
		tom = new User("john");

		System.out.println(tom.name);
		tom.sayHi();

		AdminUser bob = new AdminUser("bob");
		System.out.println(bob.name);
		bob.sayHello();
	}
}

[openjdk-14] ubuntu20.04にopenjdkをinstallする

$ cat /etc/os-release
NAME=”Ubuntu”
VERSION=”20.04.1 LTS (Focal Fossa)”

$ sudo apt search openjdk-\(\.\)\+-jdk$
Sorting… Done
Full Text Search… Done
openjdk-11-jdk/focal-updates,focal-security 11.0.9+11-0ubuntu1~20.04 amd64
OpenJDK Development Kit (JDK)

openjdk-13-jdk/focal-updates 13.0.4+8-1~20.04 amd64
OpenJDK Development Kit (JDK)

openjdk-14-jdk/focal-updates 14.0.2+12-1~20.04 amd64
OpenJDK Development Kit (JDK)

openjdk-8-jdk/focal-updates,focal-security 8u272-b10-0ubuntu1~20.04 amd64
OpenJDK Development Kit (JDK)

$ sudo apt install openjdk-14-jdk
$ java -version
openjdk version “14.0.2” 2020-07-14
OpenJDK Runtime Environment (build 14.0.2+12-Ubuntu-120.04)
OpenJDK 64-Bit Server VM (build 14.0.2+12-Ubuntu-120.04, mixed mode, sharing)
$ javac -version
javac 14.0.2

[google analytics] APIでアクセス数を取得したい

1. Google Dev ConsoleでAnalytics APIを有効にします。

認証情報を作成

– サービスアカウントの作成
L p12の秘密鍵を作成

– Google analyticsの対象のサービスに権限の追加でコンソールで作成したメールアドレスを追加
L 項目は表示と分析

$ git clone -b v1-master https://github.com/google/google-api-php-client.git

app.php

require_once 'google-api-php-client/src/Google/autoload.php';
$service_account_email = 'myapp-***@analytics-hoge.iam.gserviceaccount.com';
$key = file_get_contents('analytics-fugafuga.p12');
$profile = '***';

$client = new Google_Client();
$analytics = new Google_Service_Analytics($client);

$cred = new Google_Auth_AssertionCredentials(
	$service_account_email,
	array(Google_Service_Analytics::ANALYTICS_READONLY),
	$key
);

$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()){
	$client->getAuth()->refreshTokenWithAssertion($cred);
}

$result = $analytics->data_ga->get(
	'ga:' . $profile,
	'7daysAgo',
	'yesterday',
	'ga:sessions,ga:pageviews'
);

echo $result -> rows[0][0] . "\n";
echo $result -> rows[0][1] . "\n";

$ php app.php
*****
*****

人気記事の取得も配列を使ってできるようです。
なるほど、割と簡単に実装できますね。