Machine Learning A-Z [WIP]

Machine Learning A-Z™: Hands-On Python & R In Data Science
by Kirill Eremenko and Hadelin de Ponteves on Udemy

Actually a couple of new jobs and task at work and obviously major curiosity have led me to have a dive into Machine Learning. Guess what, I absolutely love it. It’s fantastic to get your head around the theory, but also try out some simple examples of applied ML – even if it is just to understand when people talk about it. Actually applying it to own real world problems is of course a different story, but this is a first step for me. It all boils down to ask the right question and to understand what the data might be able to tell you, rather then using Machine Learning for the sake of it.
I highly recommend the course, join me if you’d like!

This is the table of content as described on Udemy:

Part 1 – Data Preprocessing
Part 2 – Regression:

  • Simple Linear Regression
  • Multiple Linear Regression
  • Polynomial RegressionSVR
  • Decision Tree Regression
  • Random Forest Regression

Part 3 – Classification:

  • Logistic Regression
  • K-NN
  • SVM
  • Kernel SVM
  • Naive Bayes
  • Decision Tree Clssification
  • Random Forest Classification

Part 4 – Clustering:

  • K-Means
  • Hierarchical Clustering

Part 5 – Association Rule Learning:

  • Apriori
  • Eclat

Part 6 – Reinforcement Learning:

  • Upper Confidence Bound
  • Thompson Sampling

Part 7 – Natural Language Processing: Bag-of-words model and algorithms for NLP
Part 8 – Deep Learning:

  • Artificial Neural Networks
  • Convolutional Neural Networks

Part 9 – Dimensionality Reduction:

  • PCA
  • LDA
  • Kernel PCA

Part 10 – Model Selection & Boosting:

  • k-fold Cross Validation
  • Parameter Tuning
  • Grid Search
  • XGBoost

visual graphing program [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 10
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 16 Exercise 10

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"
#include "std_lib_facilities.h"
#include <functional>

// layout
constexpr int xmax = 600;
constexpr int ymax = 600;

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 40;

constexpr int x_scale = 20;
constexpr int y_scale = 20;

// layout
constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

typedef double Fcti(double);

double mysin(double x) { return sin(x); }
double mycos(double x) { return cos(x); }

template <class T> class myFct : public Shape {
public:
	myFct(Fcti* f, double r1, double r2, Point orig, int count = 100, double xscale = 25, double yscale = 25, T precision = 1.0);
	~myFct() {}

	void set_f(Fcti* p) { f = p; }
	void set_r1(double r) { r1 = r; }
	void set_r2(double r) { r2 = r; }
	void set_orig(Point o) { orig = o; }
	void set_count(int c) { count = c; }
	void set_xscale(double x) { xscale = x; }
	void set_yscale(double y) { yscale = y; }
	void set_precision(T p) { precision = p; }

	double get_r1() { return r1; }
	double get_r2() { return r2; }
	Point get_orig() { return orig; }
	int get_count() { return count; }
	double get_xscale() { return xscale; }
	double get_yscale() { return yscale; }
	T get_precision() { return precision; }

	void calc();
	void reset(Fcti* f, double r1, double r2, Point orig, int count = 100, double xscale = 25, double yscale = 25, T precision = 1.0);

private:
	Fcti* f;
	double r1;
	double r2;
	Point orig;
	int count;
	double xscale;
	double yscale;
	T precision;
};

template <class T> myFct<T>::myFct(Fcti* f, double r1, double r2, Point orig, int count, double xscale, double yscale, T precision)
	:f(f), r1(r1), r2(r2), orig(orig), count(count), xscale(xscale), yscale(yscale), precision(precision)
{
	calc();
}

template <class T> void myFct<T>::calc()
{
	if (r2 - r1 <= 0) error("bad graphing range");
	if (count <= 0) error("non-positive graphing count");
	double dist = (r2 - r1) / count;
	double r = r1;

	// had to add void clear_points() { points.clear(); }
	// to the protected section of the Shape class - annoying
	clear_points();	

	for (int i = 0; i < count; ++i) {
		int x = orig.x + int(int(r * xscale) / precision) * precision;
		int y = orig.y - int(int(f(r) * yscale) / precision) * precision;
		add(Point(x, y));
		r += dist;
	}
}

template <class T> void myFct<T>::reset(Fcti* f, double r1, double r2, Point orig, int count, double xscale, double yscale, T precision)
{
	set_f(f);
	set_r1(r1);
	set_r2(r2);
	set_orig(orig);
	set_count(count);
	set_xscale(xscale);
	set_yscale(yscale);
	set_precision(precision);

	calc();
}

// ------------------------------ GRAPHING END-------------------------

struct application_window : Window {
	enum graph_enum
	{
		sin_g, cos_g
	};

	application_window(Point xy, int w, int h, const string& title);

	void draw_graph();

private:

	//------------- LAYOUT

	// quit button
	Button quit_button;

	// convert button
	Button graph_button;

	// graph type button;
	Button graph_type;
	Menu graph_type_menu;

	// in
	In_box x_parameter;
	Out_box base_equation;
	Out_box equation;

	//
	graph_enum g_type;

	// axis
	Axis x_axis;
	Axis y_axis;

	// function
	myFct<double> funct;

	//double x_manipulation(double x, int m) { return x * m; }
	double my_sin(double x) { return sin(x); }
	double my_cos(double x) { return cos(x); }

	// actions invoked by callbacks
	void quit() { hide(); }

	void graph_type_menu_pressed() { graph_type.hide(); graph_type_menu.show(); }

	void sin_graph();
	void cos_graph();	

	// callback functions
	static void cb_quit(Address, Address pw) { reference_to<application_window>(pw).quit(); }
	static void cb_calculate(Address, Address pw) { reference_to<application_window>(pw).draw_graph(); }

	static void cb_graph_type_menu_pressed(Address, Address pw) { reference_to<application_window>(pw).graph_type_menu_pressed(); }

	static void cb_sin_graph(Address, Address pw) { reference_to<application_window>(pw).sin_graph(); }
	static void cb_cos_graph(Address, Address pw) { reference_to<application_window>(pw).cos_graph(); }

	//------------- LAYOUT END
};

application_window::application_window(Point xy, int w, int h, const string& title)
	: Window(xy, w, h, title)
	, quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
	, graph_button(Point(x_max() - 70, 20), 70, 20, "Graph", cb_calculate)
	, graph_type(Point(20, 0), 100, 20, "Graph Type", cb_graph_type_menu_pressed)
	, graph_type_menu(Point(20, 0), 100, 20, Menu::vertical, "Graph Type")
	, base_equation(Point(x_max() / 2, 0), 90, 20, "equation")
	, x_parameter(Point(100, 40), 20, 20, "t-paramter")
	, equation(Point(x_max() / 2, 40), 90, 20, "equation")
	, x_axis(Axis::x, Point(orig.x - 200, orig.y), 400, 20, "1 == 20")
	, y_axis(Axis::y, Point(orig.x, orig.y + 200), 400, 20, "1 == 20")
	, funct(mysin, r_min, r_max, orig, n_points, x_scale, y_scale)
{
	attach(quit_button);
	attach(graph_button);
	attach(graph_type);
	attach(base_equation);
	attach(x_parameter);
	attach(equation);

	graph_type_menu.attach(new Button(Point(0, 0), 0, 0, "sin", cb_sin_graph));
	graph_type_menu.attach(new Button(Point(0, 0), 0, 0, "cos", cb_cos_graph));

	attach(graph_type_menu);

	x_axis.set_color(Color::black);
	y_axis.set_color(Color::black);
	attach(x_axis);
	attach(y_axis);

	funct.set_color(FL_BLACK);
	attach(funct);
	funct.set_color(Color::invisible);

	graph_type_menu.hide();
}

void application_window::sin_graph()
{
	graph_type_menu.hide();
	graph_type.show();

	base_equation.put("y = sin(x) * t");
	g_type = sin_g;
}

void application_window::cos_graph()
{
	graph_type_menu.hide();
	graph_type.show();

	base_equation.put("y = cos(x) * t");
	g_type = cos_g;
}

void application_window::draw_graph()
{	
	// GRAPHS
	if(g_type == sin_g)
	{		
		equation.put("y = sin(x) * " + x_parameter.get_string());

		// most painful lambda to function pointer work-around ever.
		// saved the day:
		// https://deviorel.wordpress.com/2015/01/27/obtaining-function-pointers-from-lambdas-in-c/

		int t = x_parameter.get_int();
		auto la = [=](double x) { return sin(x) * t; };

		static function< double(double) > static_variable;
		static_variable = la;
		double(*ptr)(double) = [](double x) { return static_variable(x); };

		funct.reset(
			[](double x) { return static_variable(x); }
			, r_min
			, r_max
			, orig
			, n_points
			, x_scale
			, y_scale
		);

	}
	if(g_type == cos_g)
	{
		equation.put("y = cos(x) * " + x_parameter.get_string());

		int t = x_parameter.get_int();
		auto la = [=](double x) { return cos(x) * t; };

		static function< double(double) > static_variable;
		static_variable = la;
		double(*ptr)(double) = [](double x) { return static_variable(x); };

		funct.reset(
			[](double x) { return static_variable(x); }
			, r_min
			, r_max
			, orig
			, n_points
			, x_scale
			, y_scale
		);
	}

	funct.set_color(Color::visible);
	redraw();
}

// ------------------------------ INTERFACE END-------------------------

int main()
try {
	application_window win(Point(100, 100), xmax, ymax + 20, "currency converter");

	return gui_main();
}
catch (exception& e) {
	cerr << "exception: " << e.what() << endl;
	char c;
	while (cin >> c&& c != ';');
	return 1;
}
catch (...) {
	cerr << "exception\n";
	char c;
	while (cin >> c && c != ';');
	return 2;
}

visual calculator [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 9
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:

//	Philipp Siedler
//	Bjarne Stroustrup's PP
//	Chapter 16 Exercise 9

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"
#include "std_lib_facilities.h"

// ------------------------------ CALCULATOR ---------------------------

const char let = '#';
const char quitProg = 'Q';
const char print = ';';
const char number = '8';
const char name = 'a';
const char sqroot = 'S';
const char power = 'P';
const char constant = 'C';
const char reset = 'R';
const char help = 'H';

struct Token {
	char kind;
	double value;
	string name;
	Token(char ch) :kind(ch), value(0) { }
	Token(char ch, double val) :kind(ch), value(val) { }
	Token(char ch, string val) :kind(ch), name(val) { }
};

class Token_stream {
	bool full;
	Token buffer;
	;
public:
	Token_stream() :full(0), buffer(0) { }
	Token get(stringstream& ist);
	void unget(Token t) { buffer = t; full = true; }
	void ignore(char);
};

Token Token_stream::get(stringstream& ist)
{
	/*
	if (full) {
	full = false;
	return buffer;
	}

	char ch;
	ist >> ch;
	*/

	if (full) {
		full = false; return buffer;
	}
	char ch;
	ist.get(ch);

	while (isspace(ch)) {
		if (ch == '\n') return Token(print); // if newline detected, return print Token
		ist.get(ch);
	}

	switch (ch) {
	case '(':
	case ')':
	case '+':
	case '-':
	case '*':
	case '/':
	case '%':
	case ';':
	case '=':
	case 'k':
	case ',':
	{
		return Token(ch);
	}
	case '#':
	{
		return Token(let);
	}
	case '.':
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	{
		ist.unget();
		double val;
		ist >> val;
		return Token(number, val);
	}
	default:
	{
		if (isalpha(ch) || ch == '_') { //is ch a letter?
			string s;
			s += ch;
			while (ist.get(ch) && (isalpha(ch) || isdigit(ch) || ch == '_')) { //reads chars, strings or digits
				s += ch;
			}
			ist.unget(); //puts the most recently read character back into the stream
			if (s == "quit") return Token(quitProg);
			if (s == "sqrt") return Token(sqroot);
			if (s == "pow") return Token(power);
			if (s == "const") return Token(constant);
			if (s == "reset") return Token(reset);
			if (s == "help" || s == "Help") return Token(help);
			return Token(name, s);
		}
		error("Bad token");
		return Token(' ');
	}
	}
}

void Token_stream::ignore(char c)
{
	if (full && c == buffer.kind) {
		full = false;
		return;
	}
	full = false;
	char ch;
	while (cin >> ch) {
		if (ch == c) return;
	}
}

struct Variable {
	string name;
	double value;
	bool immutable;
	Variable(string n, double v, bool i) :name(n), value(v), immutable(i) { }
};

class Symbol_table {
public:
	vector<Variable> var_table;
	double get(string);
	void set(string, double);
	bool is_declared(string);
	double declare(char, stringstream& ist);
	bool is_immutable(string);
};

Token_stream ts;
double expression(stringstream& ist);
double primary(stringstream& ist);

double Symbol_table::get(string s)
{
	for (int i = 0; i < var_table.size(); ++i) {
		if (var_table[i].name == s) {
			return var_table[i].value;
		}
	}
	error("get: undefined name ", s);
	return 0.0;
}

void Symbol_table::set(string s, double d)
{
	for (int i = 0; i <= var_table.size(); ++i) {
		if (var_table[i].name == s) {
			var_table[i].value = d;
			return;
		}
	}
	error("set: undefined name ", s);
}

bool Symbol_table::is_declared(string s)
{
	for (int i = 0; i < var_table.size(); ++i) {
		if (var_table[i].name == s) return true;
	}
	return false;
}

double Symbol_table::declare(char kind, stringstream& ist)
{
	Token t = ts.get(ist);
	if (t.kind != name) {
		error("name expected in declaration");
	}

	string name = t.name;
	if (kind == let || kind == constant) {
		if (is_declared(name)) error(name, " declared twice");
	}
	else if (kind == reset) {
		if (!is_declared(name))
			error(name, " has not been declared");
		if (is_immutable(name))
			error(name, " is a constant");
	}
	else {
		error("unknown statement");
	}

	Token t2 = ts.get(ist);
	if (t2.kind != '=') error("= missing in declaration of ", name);
	double d = expression(ist);
	if (is_declared(name))
		set(name, d);
	else
		var_table.push_back(Variable(name, d, (kind == constant)));
	return d;
}

bool Symbol_table::is_immutable(string s)
{
	for (int i = 0; i<int(var_table.size()); ++i)
		if (var_table[i].name == s && var_table[i].immutable) return true;
	return false;
}

double pow_function(Token _t, stringstream& ist) {
	_t = ts.get(ist);
	if (_t.kind != '(') {
		error("'(' expected");
	}

	double x = expression(ist);

	_t = ts.get(ist);
	if (_t.kind != ',') {
		error("',' expected");
	}

	double n = expression(ist);
	_t = ts.get(ist);
	if (_t.kind == ')') {
		return pow(x, n);
	}
	else {
		error("Expected ')'");
	}
}

double sqrt_function(Token _t, stringstream& ist) {
	_t = ts.get(ist);
	if (_t.kind != '(') {
		error("'(' expected");
	}
	ts.unget(_t);
	double d = primary(ist);
	if (d < 0.0) {
		error("negative square root");
	}
	return sqrt(d);
}


Symbol_table st;

double primary(stringstream& ist)
{
	Token t = ts.get(ist);
	switch (t.kind) {
	case '(':
	{
		double d = expression(ist);
		t = ts.get(ist);
		if (t.kind != ')') error("')' expected");
		return d;
	}
	case '-':
	{
		return -primary(ist);
	}
	case '+':
	{
		return primary(ist);
	}
	case number:
	{
		return t.value;
	}
	case sqroot:
	{
		return sqrt_function(t, ist);
	}
	case power:
	{
		return pow_function(t, ist);
	}
	case name:
	{
		return st.get(t.name);
	}
	default:
	{
		error("primary expected");
		return 0.0;
	}
	}
}

double term(stringstream& ist)
{
	double left = primary(ist);
	while (true) {
		Token t = ts.get(ist);
		switch (t.kind) {
		case 'k':
		{
			left *= 1000;
			break;
		}
		case '*':
		{
			left *= primary(ist);
			break;
		}
		case '/':
		{
			double d = primary(ist);
			if (d == 0) error("divide by zero");
			left /= d;
			break;
		}
		case '%':
		{
			int i1 = narrow_cast<int>(left);
			int i2 = narrow_cast<int>(primary(ist));
			if (i2 == 0) error("%: divide by zero");
			left = i1%i2;
			break;
		}

		default: {
			ts.unget(t);
			return left;
		}
		}
	}
}

double expression(stringstream& ist)
{
	double left = term(ist);
	while (true) {
		Token t = ts.get(ist);
		switch (t.kind) {
		case '+':
		{
			left += term(ist);
			break;
		}
		case '-':
		{
			left -= term(ist);
			break;
		}
		default:
		{
			ts.unget(t);
			return left;
		}
		}
	}
}

double statement(stringstream& ist)
{
	Token t = ts.get(ist);
	double d;
	if (t.kind == let || t.kind == reset || t.kind == constant) {
		d = st.declare(t.kind, ist);
	}
	else {
		ts.unget(t);
		d = expression(ist);
	}
	t = ts.get(ist);
	if (t.kind != print) {
		error("Missing terminator");
	}

	return d;
}

void clean_up_mess()
{
	ts.ignore(print);
}

static void calculate(stringstream& ist, ostringstream& ost)
{
	while (ist) try {
		Token t = ts.get(ist);
		ts.unget(t);
		ost << statement(ist);
		break;
	}
	catch (runtime_error& e) {
		ost << e.what() << endl;
		clean_up_mess();
	}
}

// ------------------------------ CALCULATOR END------------------------

// ------------------------------ INTERFACE ----------------------------

// layout
constexpr int xmax = 400;
constexpr int ymax = 400;

struct application_window : Window {
	application_window(Point xy, int w, int h, const string& title);

private:

	//------------- LAYOUT

	// quit button
	Button quit_button;

	// convert button
	Button calculate_button;

	// in
	In_box value_in;
	Out_box value_out;

	// actions invoked by callbacks
	void quit() { hide(); }
	void cal();

	// callback functions
	static void cb_quit(Address, Address pw) { reference_to<application_window>(pw).quit(); }
	static void cb_calculate(Address, Address pw) { reference_to<application_window>(pw).cal(); }

	//------------- LAYOUT END
};

application_window::application_window(Point xy, int w, int h, const string& title)
	: Window(xy, w, h, title)
	, quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
	, calculate_button(Point(x_max() - 70, 20), 70, 20, "Calculate", cb_calculate)
	, value_in(Point(70, 60), 70, 20, "equation")
	, value_out(Point(x_max() / 2, 60), 70, 20, "solution")
{
	attach(quit_button);
	attach(calculate_button);
	attach(value_in);
	attach(value_out);
}

void application_window::cal()
{
	ostringstream os;
	stringstream ss;
	ss.str(value_in.get_string() + ";");
	
	calculate(ss, os);

	string s(os.str());
	value_out.put(s);
}

// ------------------------------ INTERFACE END-------------------------

int main()
try {
	application_window win(Point(100, 100), xmax, ymax + 20, "currency converter");
	return gui_main();
}
catch (exception& e) {
	cerr << "exception: " << e.what() << endl;
	char c;
	while (cin >> c&& c != ';');
	return 1;
}
catch (...) {
	cerr << "exception\n";
	char c;
	while (cin >> c && c != ';');
	return 2;
}

visual currency converter [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 8
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Exercise 8

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"
#include <time.h>

// layout
constexpr int xmax = 400;
constexpr int ymax = 400;

enum currencies
{
	euro = 0, pound
};

struct application_window : Window {
	application_window(Point xy, int w, int h, const string& title, const string& conversion_rate_file_location);

private:

	//------------- DATA

	currencies from;
	currencies to;

	// data
	float conversion_rate;

	// methods
	float get_conversion(const string& crfl);

	//------------- DATA END


	//------------- LAYOUT

	// quit button
	Button quit_button;

	// convert button
	Button convert_button;

	// menu button
	Button from_menu_button;
	Button to_menu_button;

	// menu
	Menu from_menu;
	Menu to_menu;

	// in
	In_box value_in;
	Out_box value_out;
	Out_box value_in_currency;	
	Out_box value_out_currency;

	// actions invoked by callbacks
	void quit() { hide(); }

	void convert();

	void hide_from_menu() { from_menu.hide(); from_menu_button.show(); }
	void hide_to_menu() { to_menu.hide(); to_menu_button.show(); }

	void from_menu_pressed() { from_menu_button.hide(); from_menu.show(); }
	void to_menu_pressed() { to_menu_button.hide(); to_menu.show(); }

	void from_euro_pressed() { hide_from_menu(); value_in_currency.put("euro"); from = euro; }
	void from_pound_pressed() { hide_from_menu(); value_in_currency.put("pound"); from = pound; }

	void to_euro_pressed() { hide_to_menu(); value_out_currency.put("euro"); to = euro; }
	void to_pound_pressed() { hide_to_menu(); value_out_currency.put("pound"); to = pound; }
	
	// callback functions
	static void cb_quit(Address, Address pw) { reference_to<application_window>(pw).quit(); }

	static void cb_convert(Address, Address pw) { reference_to<application_window>(pw).convert(); }

	static void cb_from_menu(Address, Address pw) {	reference_to<application_window>(pw).from_menu_pressed(); }
	static void cb_from_euro(Address, Address pw) { reference_to<application_window>(pw).from_euro_pressed(); }
	static void cb_from_pound(Address, Address pw) { reference_to<application_window>(pw).from_pound_pressed(); }

	static void cb_to_menu(Address, Address pw) { reference_to<application_window>(pw).to_menu_pressed(); }
	static void cb_to_euro(Address, Address pw) { reference_to<application_window>(pw).to_euro_pressed(); }
	static void cb_to_pound(Address, Address pw) { reference_to<application_window>(pw).to_pound_pressed(); }

	//------------- LAYOUT END
};

application_window::application_window(Point xy, int w, int h, const string& title, const string& conversion_rate_file_location)
	: Window(xy, w, h, title)
	, quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
	, convert_button(Point(x_max() - 70, 20), 70, 20, "Convert", cb_convert)
	, from_menu_button(Point(0, 20), 70, 20, "From", cb_from_menu)
	, to_menu_button(Point(x_max() / 2, 20), 70, 20, "To", cb_to_menu)
	, from_menu(Point(0, 20), 70, 20, Menu::vertical, "From")
	, to_menu(Point(x_max() / 2, 20), 70, 20, Menu::vertical, "To")
	, value_in(Point(0, 60), 70, 20, "enter value")
	, value_out(Point(x_max() / 2, 60), 70, 20, "")
	, value_in_currency(Point(70, 60), 70, 20, "")
	, value_out_currency(Point(x_max() / 2 + 70, 60), 70, 20, "")
{
	conversion_rate = get_conversion(conversion_rate_file_location);

	from = euro;
	to = euro;

	attach(quit_button);
	attach(convert_button);
	attach(from_menu_button);
	attach(to_menu_button);

	attach(value_in);
	attach(value_out);

	attach(value_in_currency);
	attach(value_out_currency);

	value_in_currency.put("euro");
	value_out_currency.put("euro");

	from_menu.attach(new Button(Point(0, 0), 0, 0, "euro", cb_from_euro));
	from_menu.attach(new Button(Point(0, 0), 0, 0, "pound", cb_from_pound));

	to_menu.attach(new Button(Point(0, 0), 0, 0, "euro", cb_to_euro));
	to_menu.attach(new Button(Point(0, 0), 0, 0, "pound", cb_to_pound));

	attach(to_menu);
	attach(from_menu);

	to_menu.hide();
	from_menu.hide();
}

float application_window::get_conversion(const string& crfl)
{
	string iname = crfl;
	ifstream ist(iname);

	float rate;
	if (!ist) { error("File could not be read: ", iname); }
	else { ist >> rate; }

	return rate;
}

void application_window::convert()
{
	float input = strtof((value_in.get_string()).c_str(), 0);

	if (from == euro && to == pound)
	{
		input *= conversion_rate;

		ostringstream ss;
		ss << input;
		string s(ss.str());

		value_out.put(s);
	}
	else if (from == pound && to == euro)
	{
		input *= 1.0 + (1.0 - conversion_rate);

		ostringstream ss;
		ss << input;
		string s(ss.str());

		value_out.put(s);
	}
	else
	{
		ostringstream ss;
		ss << input;
		string s(ss.str());

		value_out.put(s);
	}
}

int main()
try
{
	application_window win(Point(100, 100), xmax, ymax + 20, "currency converter", "Data/conversion_rate.txt");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}
catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}
Input:
Text file: Data/conversion_rate.txt
0.87

flying airplane image animation [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 7
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:
//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Exercise 7

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"
#include <time.h>

// layout
constexpr int xmax = 400;
constexpr int ymax = 400;

// HANDS
struct Airplane : Shape
{
	Airplane(string content_location, Point& position, int canvas_width, int canvas_height)
		: content_location(content_location)
		, position(position)
		, canvas_width(canvas_width)
		, canvas_height(canvas_height)
	{
		image_width = 250;
		image_height = 150;
		velocity = Point(1, 1);
	}

	void move();
	void draw_lines() const;

	string content_location;
	Point position;

	Point velocity;

	int image_width;
	int image_height;

	int canvas_width;
	int canvas_height;
};

void Airplane::move()
{
	

	if (position.x <= canvas_width - image_width)
	{
		position.x += velocity.x;
	}
	if (position.y <= canvas_height - image_height)
	{
		position.y += velocity.y;
	}

	if (position.x == canvas_width - image_width || position.x == 0)
	{
		velocity.x *= -1;
	}
	if (position.y == canvas_height - image_height || position.y == 0)
	{
		velocity.y *= -1;
	}

}

void Airplane::draw_lines() const
{
	Image image0(position, content_location);
	image0.set_mask(Point(100, 70), image_width, image_height);

	if (color().visibility()) {		
		// draw content image
		image0.draw();
	}
}

struct animation_window : Window {
	animation_window(Point xy, int w, int h, const string& title)
		: Window(xy, w, h, title),
		quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
		start_stop_button(Point(x_max() - 70, 20), 70, 20, "Start/Stop", cb_start_stop)
	{
		attach(quit_button);
		attach(start_stop_button);
		//position = Point(0, 0);
		Airplane plane("Data/airplanes-work-1.jpg", Point(0, 0), w, h);
		run = false;

		while (true) {
			Fl::wait();
			Sleep(10);
			draw_shape(plane);
			if (run)
			{
				plane.move();
				Fl::redraw();
			}
			
		}
	}

	Vector_ref<Shape> s;
	void draw_shape(Airplane& plane);

	Button quit_button;
	Button start_stop_button;

	bool run;

private:

	static void cb_quit(Address, Address addr) { reference_to<animation_window>(addr).quit(); }
	static void cb_start_stop(Address, Address addr) { reference_to<animation_window>(addr).start_stop(); }

	void quit() { hide(); }
	void start_stop()
	{
		if (run) { run = false; }
		else { run = true; }
	}

};

void animation_window::draw_shape(Airplane& plane)
{
	if (s.size() != 0)
	{
		for (int i = 0; i < s.size(); i++)
		{
			detach(s[i]);
		}
	}

	s.push_back(plane);
	attach(s[s.size() - 1]);
}

int main()
try
{
	animation_window win(Point(100, 100), xmax, ymax + 20, "flying airplane");

	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}
catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

analog clock [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 6
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Exercise 6

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"
#include <time.h>

// layout
constexpr int xmax = 400;
constexpr int ymax = 400;

// HANDS
struct Hands : Open_polyline
{
	Hands(Point center, Point end, Fl_Color color)
	{
		add(Point(center));
		add(Point(end));
		c = color;
	}

	void draw_lines() const;
	Fl_Color c;
};

void Hands::draw_lines() const
{
	fl_color(c);
	Open_polyline::draw_lines();
}

struct Analog_clock_window : Window {
	Analog_clock_window(Point xy, int w, int h, const string& title)
		: Window(xy, w, h, title),
		quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
	{
		attach(quit_button);		

		while (true) {
			Fl::wait();
			Sleep(1000);			
			cout << "sleep" << endl;
			draw_shape();
			Fl::redraw();
		}
	}
	
	Vector_ref<Shape> s;
	void draw_shape();

	Button quit_button;

private:
	time_t rawtime;
	bool button_pushed;

	void print_current_time(time_t &rt);

	static void cb_quit(Address, Address addr) { reference_to<Analog_clock_window>(addr).quit(); }
	void quit() { hide(); }
};

void Analog_clock_window::print_current_time(time_t &rt)
{
	#pragma warning(disable : 4996) //_CRT_SECURE_NO_WARNINGS

	struct tm * timeinfo;
	timeinfo = localtime(&rt);
	printf("Current local time and date: %s", asctime(timeinfo));

	cout << timeinfo->tm_sec << endl;
}

void Analog_clock_window::draw_shape()
{
	if (s.size() != 0)
	{
		for (int i = 0; i < s.size(); i++)
		{
			detach(s[i]);
		}
	}

	Point center(xmax / 2, ymax / 2);

	for (int i = 0; i < 12; i++)
	{
		Point pt1(0, -100);
		Point pt2(0, -95);
		double rad = ((2 * M_PI) / 12) * i;

		Point rotated_pt1 = Point(cos(rad) * pt1.x - sin(rad) * pt1.y, sin(rad) * pt1.x + cos(rad) * pt1.y);
		Point rotated_pt2 = Point(cos(rad) * pt2.x - sin(rad) * pt2.y, sin(rad) * pt2.x + cos(rad) * pt2.y);

		s.push_back(new Hands(Point(rotated_pt1.x + center.x, rotated_pt1.y + center.y), Point(rotated_pt2.x + center.x, rotated_pt2.y + center.y), Color::black));
		attach(s[s.size() - 1]);
	}

	#pragma warning(disable : 4996) //_CRT_SECURE_NO_WARNINGS
	time_t rawT;
	time(&rawT);

	struct tm * timeinfo;
	timeinfo = localtime(&rawT);
	asctime(timeinfo);

	printf("Current local time and date: %s", asctime(timeinfo));

	// SECOND HAND
	Point origin_Pt1(0, -100);

	double rad = timeinfo->tm_sec * ((2 * M_PI) / 60);
	Point rotated_Pt1 = Point(cos(rad) * origin_Pt1.x - sin(rad) * origin_Pt1.y, sin(rad) * origin_Pt1.x + cos(rad) * origin_Pt1.y);
	
	s.push_back(new Hands(center, Point(rotated_Pt1.x + center.x , rotated_Pt1.y + center.y), Color::red));
	attach(s[s.size() - 1]);
	
	// MINUTE HAND
	Point origin_Pt2(0, -80);

	rad = timeinfo->tm_min * ((2 * M_PI) / 60);
	Point rotated_Pt2 = Point(cos(rad) * origin_Pt2.x - sin(rad) * origin_Pt2.y, sin(rad) * origin_Pt2.x + cos(rad) * origin_Pt2.y);

	s.push_back(new Hands(center, Point(rotated_Pt2.x + center.x, rotated_Pt2.y + center.y), Color::blue));
	attach(s[s.size() - 1]);

	// HOUR HAND
	Point origin_Pt3(0, -60);

	rad = timeinfo->tm_hour * ((2 * M_PI) / 12) + (timeinfo->tm_min * ((2 * M_PI) / 60)) / 12;
	Point rotated_Pt3 = Point(cos(rad) * origin_Pt3.x - sin(rad) * origin_Pt3.y, sin(rad) * origin_Pt3.x + cos(rad) * origin_Pt3.y);

	s.push_back(new Hands(center, Point(rotated_Pt3.x + center.x, rotated_Pt3.y + center.y), Color::black));
	attach(s[s.size() - 1]);
}

int main()
try
{
	Analog_clock_window win(Point(100, 100), xmax, ymax + 20, "analog clock");

	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}
catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

randomly moving shape [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 5
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Exercise 5

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"

// layout
constexpr int xmax = 400;
constexpr int ymax = 400;

struct My_window : Window {
	My_window(Point xy, int w, int h, const string& title, string url)
		: Window(xy, w, h, title),
		next_button_pushed(false),
		next_button(Point(x_max() - 140, 0), 70, 20, "Next", cb_next),
		quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
		url(url),
		counter(0)
	{
		attach(next_button);
		attach(quit_button);

		// open input stream
		ifstream ist(url);
		int input_x;
		char comma;
		int input_y;

		// store data in vectors
		while (ist >> input_x >> comma >> input_y)
		{
			in_x.push_back(input_x);
			in_y.push_back(input_y);
		}
	}

	void wait_for_button()
	{
		while (!next_button_pushed) Fl::wait();
		next_button_pushed = false;
		Fl::redraw();
	}

	Button next_button;
	Button quit_button;
	
private:
	bool next_button_pushed;
	string url;
	int counter;
	Vector_ref<Shape> s;

	vector<int> in_x;
	vector<int> in_y;

	static void cb_next(Address, Address addr)
	{
		reference_to<My_window>(addr).next();
	}

	static void cb_quit(Address, Address addr)
	{
		reference_to<My_window>(addr).quit();
	}

	void next();
	void quit() { hide(); }
};

void My_window::next()
{
	if (s.size() < in_x.size())
	{
		if (s.size() != 0) { detach(s[s.size() - 1]); }
		s.push_back(new Circle(Point(in_x[counter], in_y[counter]), 20));
		attach(s[s.size() - 1]);
		redraw();
		counter++;
	}
}

int main()
try
{
	My_window win(Point(100, 100), xmax, ymax + 20, "next buttons window", "Data/point_sequence.txt");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}
catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

shape drawing with menu [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 4
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Exercise 4

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"

// layout
constexpr int xmax = 600;
constexpr int ymax = 400;

// QUAD
struct Quad_center : Closed_polyline
{
	Quad_center(Point center, int w, int h)
	{
		add(Point(center.x - w / 2, center.y - h / 2));
		add(Point(center.x + w / 2, center.y - h / 2));
		add(Point(center.x + w / 2, center.y + h / 2));
		add(Point(center.x - w / 2, center.y + h / 2));
		
	}

	void draw_lines() const;
};

void Quad_center::draw_lines() const
{
	fl_color(FL_BLACK);
	Closed_polyline::draw_lines();
}

// TRIANGLE
struct Triangle : Closed_polyline
{
	Triangle(Point origin, int edge_length)
	{
		int h = sqrt(3) / 2 * edge_length;

		Point p(origin.x - edge_length / 2, origin.y + edge_length / 2);
		add(p);		
		add(Point(p.x + edge_length, p.y));
		add(Point(p.x + edge_length / 2, p.y - h));
	}

	void draw_lines() const;
};

void Triangle::draw_lines() const
{
	fl_color(FL_BLACK);
	Closed_polyline::draw_lines();
}

// HEXAGON
struct Hexagon : Closed_polyline
{
	Hexagon(Point origin, int radius)
	{
		int n = 6;
		for (int i = 0; i < n; i++) {
			add(Point(origin.x + radius * cos(2 * M_PI * i / n), origin.y + radius * sin(2 * M_PI * i / n)));
		}
	}

	void draw_lines() const;
};

void Hexagon::draw_lines() const
{
	fl_color(FL_BLACK);
	Closed_polyline::draw_lines();
}

// DRAW SHAPES WINDOW
struct Shapes_window : Window {
	Shapes_window(Point xy, int w, int h, const string& title);
private:
	// data
	enum Shapes
	{
		circle, square, triangle , hexagon
	};

	Vector_ref<Shape> s;

	// widgets
	Button quit_button;	// end program
	In_box draw_pos_x;
	In_box draw_pos_y;
	Out_box xy_out;
	Menu shape_menu;
	Button menu_button;

	void hide_menu() { shape_menu.hide(); menu_button.show(); }

	// actions invoked by callbacks
	void menu_pressed() { menu_button.hide(); shape_menu.show(); }
	void draw_shape(Shapes s);
	void quit();

	// callback functions
	static void cb_circle(Address, Address);
	static void cb_square(Address, Address);
	static void cb_triangle(Address, Address);
	static void cb_hexagon(Address, Address);
	static void cb_menu(Address, Address);
	static void cb_quit(Address, Address);
};

Shapes_window::Shapes_window(Point xy, int w, int h, const string& title)
	:Window(xy, w, h, title),
	quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
	draw_pos_x(Point(x_max() - 310, 0), 50, 20, "pos x:"),
	draw_pos_y(Point(x_max() - 210, 0), 50, 20, "pos y:"),
	xy_out(Point(100, 0), 100, 20, "drawn at (x,y):"),
	shape_menu(Point(x_max() - 70, 30), 70, 20, Menu::vertical, "shape"),
	menu_button(Point(x_max() - 80, 30), 80, 20, "shape menu", cb_menu)
{
	attach(quit_button);
	attach(draw_pos_x);
	attach(draw_pos_y);
	attach(xy_out);

	xy_out.put("no shape");

	shape_menu.attach(new Button(Point(0, 0), 0, 0, "circle", cb_circle));
	shape_menu.attach(new Button(Point(0, 0), 0, 0, "square", cb_square));
	shape_menu.attach(new Button(Point(0, 0), 0, 0, "triangle", cb_triangle));
	shape_menu.attach(new Button(Point(0, 0), 0, 0, "hexagon", cb_hexagon));
	
	attach(shape_menu);
	shape_menu.hide();
	attach(menu_button);
}

void Shapes_window::draw_shape(Shapes shape)
{

	if (draw_pos_x.get_int() == -999999)
	{
		xy_out.put("enter position");
	}
	else {

		int x = draw_pos_x.get_int();
		int y = draw_pos_y.get_int();

		switch (shape)
		{
		case circle: { s.push_back(new Circle(Point(x, y), 20)); break; }
		case square: { s.push_back(new Quad_center(Point(x, y), 40, 40)); break; }
		case triangle: { s.push_back(new Triangle(Point(x, y), 40)); break; }
		case hexagon: { s.push_back(new Hexagon(Point(x, y), 20)); break; }
		}

		// update current position readout
		ostringstream ss;
		ss << '(' << x << ',' << y << ')';
		xy_out.put(ss.str());

		attach(s[s.size() - 1]);
		redraw();
		hide_menu();
	}
}

void Shapes_window::quit()
{
	hide();
}

void Shapes_window::cb_circle(Address, Address pw)
{
	reference_to<Shapes_window>(pw).draw_shape(circle);
}

void Shapes_window::cb_square(Address, Address pw)
{
	reference_to<Shapes_window>(pw).draw_shape(square);
}

void Shapes_window::cb_triangle(Address, Address pw)
{
	reference_to<Shapes_window>(pw).draw_shape(triangle);
}

void Shapes_window::cb_hexagon(Address, Address pw)
{
	reference_to<Shapes_window>(pw).draw_shape(hexagon);
}

void Shapes_window::cb_menu(Address, Address pw)
{
	reference_to<Shapes_window>(pw).menu_pressed();
}

void Shapes_window::cb_quit(Address, Address pw)
{
	reference_to<Shapes_window>(pw).quit();
}

int main()
try
{
	Shapes_window win(Point(100, 100), xmax, ymax, "lines");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

button changing random location on click [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 3
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Exercise 3

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"
#include <random>

inline int rand_int(int min, int max)
{
	static default_random_engine ran;
	return uniform_int_distribution<>(min, max)(ran);
}

// layout
constexpr int xmax = 400;
constexpr int ymax = 400;

struct My_window : Window {
	My_window(Point xy, int w, int h, const string& title)
		: Window(xy, w, h, title),
		next_button_pushed(false),
		next_button(Point(x_max() - 140, 0), 70, 20, "Next", cb_next),
		quit_button_pushed(false),
		quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
	{
		attach(next_button);
		attach(quit_button);
	}

	void wait_for_button()
	{
		while (!next_button_pushed) Fl::wait();
		next_button_pushed = false;
		Fl::redraw();
	}

	Button next_button;
	Button quit_button;

private:
	bool next_button_pushed;
	bool quit_button_pushed;

	static void cb_next(Address, Address addr)
	{
		reference_to<My_window>(addr).next();
	}

	static void cb_quit(Address, Address addr)
	{
		reference_to<My_window>(addr).quit();
	}

	void next() { next_button_pushed = true; }
	void quit() { hide(); }
};

struct Random_button_win : My_window
{
	Random_button_win(Point xy, int w, int h, const string& title, const string& url)
		:My_window(xy, w, h, title),
		url(url),
		rand_button(Point(xmax/2, ymax/2), 40, 40, "", cb_rand),
		button_image(Point(xmax / 2, ymax / 2), url)
	{
		attach(rand_button);
		button_image.set_mask(Point(xmax / 2, ymax / 2), 40, 40);
		attach(button_image);
	}
		
	Button rand_button;
	Image button_image;
	
private:
	string url;

	static void cb_rand(Address, Address addr)
	{
		static_cast<Random_button_win*>(addr)->change_button_pos();
	}

	void change_button_pos()
	{
		rand_button.hide();

		int current_x = rand_button.loc.x;
		int current_y = rand_button.loc.y;

		int new_x = rand_int(0, xmax - 40) - current_x;
		int new_y = rand_int(20, ymax - 40) - current_y;
		
		rand_button.move(new_x, new_y);
		button_image.move(new_x, new_y);
		redraw();
	}
};

int main()
try
{
	Random_button_win win(Point(100, 100), xmax, ymax + 20, "random buttons window", "Data/supercell.jpg");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}
catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

checker board square buttons [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 16 Exercise 2
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Exercise 2

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
#include "GUI.h"

// layout
constexpr int xmax = 400;
constexpr int ymax = 400;

struct My_window : Window {
	My_window(Point xy, int w, int h, const string& title)
		: Window(xy, w, h, title),
		next_button_pushed(false),
		next_button(Point(x_max() - 140, 0), 70, 20, "Next", cb_next),
		quit_button_pushed(false),
		quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
	{
		attach(next_button);
		attach(quit_button);
	}

	void wait_for_button()
		// modified event loop
		// handle all events (as per default), but quit when button_pushed becomes true
		// this allows graphics without control inversion
	{
		while (!next_button_pushed) Fl::wait();
		next_button_pushed = false;
		Fl::redraw();
	}

	Button next_button;
	Button quit_button;

private:
	bool next_button_pushed;
	bool quit_button_pushed;

	static void cb_next(Address, Address addr) // callback for next_button
											   //	{ reference_to<Simple_window>(addr).next(); }
	{
		reference_to<My_window>(addr).next();
	}

	static void cb_quit(Address, Address addr) // callback for quit_button
											   //	{ reference_to<Simple_window>(addr).quit(); }
	{
		reference_to<My_window>(addr).quit();
	}

	void next() { next_button_pushed = true; }
	void quit() { hide(); }
};

struct cheker_board_buttons : My_window
{
	cheker_board_buttons(Point xy, int w, int h, const string& title)
		:My_window(xy, w, h, title)
	{
		int x_size = xmax / 4;
		int y_size = ymax / 4;

		// initialize buttons
		buttons.push_back(new Button(Point(0, 20), x_size, y_size, "b0", cb_change_0));
		buttons.push_back(new Button(Point(x_size, 20), x_size, y_size, "b1", cb_change_1));
		buttons.push_back(new Button(Point(x_size * 2, 20), x_size, y_size, "b2", cb_change_2));
		buttons.push_back(new Button(Point(x_size * 3, 20), x_size, y_size, "b3", cb_change_3));
		buttons.push_back(new Button(Point(0, y_size + 20), x_size, y_size, "b4", cb_change_4));
		buttons.push_back(new Button(Point(x_size, y_size + 20), x_size, y_size, "b5", cb_change_5));
		buttons.push_back(new Button(Point(x_size * 2, y_size + 20), x_size, y_size, "b6", cb_change_6));
		buttons.push_back(new Button(Point(x_size * 3, y_size + 20), x_size, y_size, "b7", cb_change_7));
		buttons.push_back(new Button(Point(0, y_size * 2 + 20), x_size, y_size, "b8", cb_change_8));
		buttons.push_back(new Button(Point(x_size, y_size * 2 + 20), x_size, y_size, "b9", cb_change_9));
		buttons.push_back(new Button(Point(x_size * 2, y_size * 2 + 20), x_size, y_size, "b10", cb_change_10));
		buttons.push_back(new Button(Point(x_size * 3, y_size * 2 + 20), x_size, y_size, "b11", cb_change_11));
		buttons.push_back(new Button(Point(0, y_size * 3 + 20), x_size, y_size, "b12", cb_change_12));
		buttons.push_back(new Button(Point(x_size, y_size * 3 + 20), x_size, y_size, "b13", cb_change_13));
		buttons.push_back(new Button(Point(x_size * 2, y_size * 3 + 20), x_size, y_size, "b14", cb_change_14));
		buttons.push_back(new Button(Point(x_size * 3, y_size * 3 + 20), x_size, y_size, "b15", cb_change_15));

		// attach buttons
		for (int i = 0; i < buttons.size(); i++) { attach(buttons[i]); }
	}

	// button setup
	Vector_ref<Button> buttons;
	int last = 16;
	void reset_button() { if(last != 16) { buttons[last].show(); } }	

	// button behaviour
	void change_b0() { reset_button(); last = 0; buttons[0].hide(); };
	void change_b1() { reset_button(); last = 1; buttons[1].hide(); };
	void change_b2() { reset_button(); last = 2; buttons[2].hide(); };
	void change_b3() { reset_button(); last = 3; buttons[3].hide(); };
	void change_b4() { reset_button(); last = 4; buttons[4].hide(); };
	void change_b5() { reset_button(); last = 5; buttons[5].hide(); };
	void change_b6() { reset_button(); last = 6; buttons[6].hide(); };
	void change_b7() { reset_button(); last = 7; buttons[7].hide(); };
	void change_b8() { reset_button(); last = 8; buttons[8].hide(); };
	void change_b9() { reset_button(); last = 9; buttons[9].hide(); };
	void change_b10() { reset_button(); last = 10; buttons[10].hide(); };
	void change_b11() { reset_button(); last = 11; buttons[11].hide(); };
	void change_b12() { reset_button(); last = 12; buttons[12].hide(); };
	void change_b13() { reset_button(); last = 13; buttons[13].hide(); };
	void change_b14() { reset_button(); last = 14; buttons[14].hide(); };
	void change_b15() { reset_button(); last = 15; buttons[15].hide(); };

private:
	vector<bool> pressed;

	// call back functions
	static void cb_change_0(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b0(); }
	static void cb_change_1(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b1(); }
	static void cb_change_2(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b2(); }
	static void cb_change_3(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b3(); }
	static void cb_change_4(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b4(); }
	static void cb_change_5(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b5(); }
	static void cb_change_6(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b6(); }
	static void cb_change_7(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b7(); }
	static void cb_change_8(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b8(); }
	static void cb_change_9(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b9(); }
	static void cb_change_10(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b10(); }
	static void cb_change_11(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b11(); }
	static void cb_change_12(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b12(); }
	static void cb_change_13(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b13(); }
	static void cb_change_14(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b14(); }
	static void cb_change_15(Address, Address addr) { reference_to<cheker_board_buttons>(addr).change_b15(); }
};

int main()
try
{
	cheker_board_buttons win(Point(100, 100), xmax, ymax + 20, "checker board buttons");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}