/// # Hello World
/*
void main() {
print('hello');
}
*/
/// # [dart: core]
/*
import 'dart:core'; /// is imported automatically
void main() {
var firstName = 11; /// can asign any type
String lastName = 'Ahsan'; /// only string
print(firstName.toString() + ' ' + lastName);
}
*/
/// # [dart: io]
/*
import 'dart:io';
void main() {
stdout.writeln('What is your name: ?');
String name = stdin.readLineSync();
print('Hello, $name');
}
*/
/// Data Type: [int], [double], [String], [dynamic]
/// Everything is object
///
/*
void main() {
int number; /// if not asigned, defult is [null] type
var number2 = 22;
print('$number, $number2 \n');
number = 1;
print('$number, $number2 \n');
double dNumber = 11.11;
var dNumber2 = 22.22;
print('$dNumber, $dNumber2 \n');
String name = 'Jame';
var name2 = 'Tom';
print('$name, $name2 \n');
bool isTrue = true;
var isTrue2 = false;
print('$isTrue, $isTrue2 \n');
dynamic weakVar;
print('$weakVar \n');
weakVar = 102;
print('$weakVar \n');
weakVar = 'Muhmad';
print('$weakVar \n');
}
*/
/// Difference between [var] & [dynamic]
/*
void main() {
/// [dynamic]
dynamic x = 'hal';
x = 123;
print(x);
/// [var]
var a = 'hal';
/* a = 123; /// throw `exception`, because var type can not be changed when has asigned. */
print(a);
}
*/
/// [String]
/*
void main() {
String s1 = "Sentences. pair of single quotes or double quotes.\n";
String s2 = "Sentences. \n'\\n' makes a newline.\n'\\' to not skip `\\`,`\'` and so on...\n";
String s3 =
'''
Paragraphs, trible quotes;
P1;
P2;
''';
print(s1);
print(s2);
print(s3);
/// [String] -> [double]/[int]
var one = int.parse('1');
assert(one == 1); /// verify
var onePointOone = double.parse('1.1');
assert(onePointOone == 1.1);
/// [double]/[int] -> [String]
var oneStr = 1.toString();
assert(oneStr == '1');
var piStr = 3.1415926.toStringAsFixed(2);
assert(piStr == '3.14', 'true');
}
*/
/// [const], can not be reasigned
/*
void main() {
const constNum = 0;
const constBool = true;
const constStr = 'a const string';
print(constBool);
print(constNum);
print(constStr);
print(constBool.runtimeType);
print(constNum.runtimeType);
print(constStr.runtimeType);
}
*/
/// Operators
/*
void main() {
int num = 2 + 3;
print(num);
num = num - 2;
print(num);
num = num * 3;
print(num);
num = num % 2;
print(num);
/// relation: ==, !=, >=, <=
if (num == 0){
print('Even number');
}
/// unary operators
num *= 2;
print(num);
num += 1;
print(num);
num -= 1;
print(num);
++num; // same as num++
print(num);
--num; // same as num--
print(num);
/// logical: &&, ||
if (num < 1 || num > 6) {
print('not a dice');
} else {
if (num >= 1 && num <= 3){
print('small');
} else {
print('big');
}
}
}
*/
/// Null aware operator: [?.], [??], [??=]
/*
class Num {
int num = 0;
}
void main() {
var n;
int number;
/*
if (n != null){ /// if not aware, the following will throw `exception`
number = n.num;
}
*/
/// shortcut of the above:
number = n?.num; /// if n != null, return n.num, else, return `null`.
print(number);
number = n?.num ?? 0; /// if n != null, return n.num, else, renturn `0`.
print(number);
int number2;
print(number2 ??= -1); /// if number22 is null, assigne it to -1
}
*/
/// Ternary operator
/*
void main() {
int x = 100;
var result = x % 2 == 0 ? 'Even' : 'Odd';
print(result);
}
*/
/// Conditional Statement
/*
void main() {
int number = 91;
if (number % 2 == 0){
print('Even');
} else if (number % 3 == 0) {
print('Trible');
} else {
print('Confused');
}
}
*/
/*
void main() {
int number = 91;
var result = number % 3;
switch(result) {
case 0: print('Trible'); break;
case 1: print('1 left'); break;
case 2: print('2 left'); break;
}
}
*/
/// Loop
/*
void main() {
for (var i = 1; i <= 10; i++) {
print(i);
}
var ls = [0,1,2,3];
for (var i in ls) {
print(i);
}
for (var i = 0; i < ls.length; i++) {
print(i);
}
ls.forEach(
(i) => print(i)
);
int i = 3;
while (i >= 0) {
print(i);
i--;
}
i = 3;
do{
print(i);
i--;
} while (i > 0);
}
*/
/// [break] and [continue]
/*
void main() {
for (var i = 0; i < 10; i++) {
if (i > 4) break;
print(i);
}
for (var i = 0; i <10; i++) {
if (i % 2 == 0) continue;
print("Odd: $i");
}
}
*/
/// Collection - [List]
/*
void main() {
List whateverList;
print(whateverList.runtimeType); /// [Null]
// Opt 0.
var names = List();
print(names.runtimeType); /// [List<dynamic>]
names = <String> ['Jame', 'Jack']; /// [List<String>]
print(names.runtimeType);
// Opt 1.
/* var names = <String>['Jame', 'Jack']; */
// Opt 2.
/* List <String> names = ['Jame', 'Jack']; */
// Opt 3.
/* List names = <String> ['Jame', 'Jack']; */
/// The above same as [Set]
print(names[0]);
print(names.length);
for (var name in names) { print(name); }
// mutable
List mixList = ['Max', 120, true];
print(mixList);
mixList[1] = 100;
print(mixList);
mixList[1] = 'Mary';
print(mixList);
// immutable
List <String> members = const ['Jame', 'Jack'];
/* members[1] = 'Mike'; /// will throw `exception` */
// copy to a new List
/* var members2 = members /// will refer to the same List */
var members2 = [...members]; /// no const, so immutable
print('Members: $members');
members2[1] = 'Mike';
print('Members3: $members2');
}
*/
/// Collection - [Set]
/*
void main() {
Set halogens = <String>{'fluorine', 'chlorine', 'fluorine', 'chlorine'};
for (var halogen in halogens) {
print(halogen); /// won't repeat
}
var halogens2 = {};
print(halogens2.runtimeType); /// [_InternalLinkedHashMap<dynamic, dynamic>], can not tell between [Set] and [Map]
var halogens3 = <String>{};
print(halogens3.runtimeType); /// [_CompactLinkedHashSet<String>]
}
*/
/// Collection - [Map] // similar to dictionary in python
/*
void main() {
Map gifts = {
'Mary': 'dolls',
'Bill': 'computers',
'Jill': 'books',
};
print(gifts['Mary']);
gifts['Mary'] = 'flowers';
print(gifts);
Map gifts2;
print(gifts2.runtimeType); /// [Null]
var gifts3 = {};
print(gifts3.runtimeType); /// [_InternalLinkedHashMap<dynamic, dynamic>]
var gifts4 = Map();
print(gifts4.runtimeType); /// [_InternalLinkedHashMap<dynamic, dynamic>]
}
*/
/// [function]
/*
void main() {
showResult(square(4));
showResult(add(5, 6)); /// positional prameters
showResult(add2(5, number2: 6)); /// number2 is [named] parameter
showResult(add2(5)); /// [named] parameter number2 has got a defult value
showResult(add4(5, 6)); /// [optional]
showResult(add4(5));
print(square.runtimeType); /// [(dynamic) => dynamic], the type of input and output
var ls = ['apples', 'bananas', 'oranges'];
ls.forEach((i) { print(i); }); /// Anonymous function, call back immediately
ls.forEach( (i) => print(i) ); /// Anonymous arrow function
}
dynamic square(var number) { /// Basic format of function
return number * number;
}
/// parameters defultly is [positional parameter]
dynamic add( var number1, var number2 ) => number1 + number2; /// One line arrow function
/// [{}] means [named parameter], can be assigned with default value.
/// Opt 0.
dynamic add2( var number1, {var number2} ) => number1 + (number2 ?? 0);
/// Opt 1.
dynamic add3( var number1, {var number2 = 0} ) => number1 + number2;
/// Can not give an unnamed parameter a defult value.
/* dynamic add3( var number1 = 0, {var number2 = 0} ) => number1 + number2; */
/// [[]] means [optional prameter]
/// Opt 0.
dynamic add4( var number1, [var number2]) => number1 + (number2 ?? 0);
/// Opt 1.
dynamic add5( var number1, [var number2 = 0]) => number1 + number2;
/// Can not use [named] and [optional] together.
/// Can not use [named] and [optional] before [positional]
void showResult(var msg) {
print('Result is $msg');
}
*/
/// [class]
/// Class 1 - constructor
/*
class Person {
// Init
String name;
int age;
// Default constructor
// Opt 0.
/*
Person(String name, [int age = 18]) { /// better to declare type, or won't check out the type error when compile, but runtime error will occur.
this.name = name;
this.age = age;
}
*/
// Opt 1.
Person(this.name, [this.age = (18)]); /// already init, no need to declare type
// Named constructor
Person.gest() {
name = 'Gest';
}
void showNameAndAge(){
print('$name, $age');
}
}
void main() {
Person person1 = Person('Mike');
person1.age = 39;
person1.showNameAndAge();
Person person2 = Person('Jack', 25);
person2.showNameAndAge();
Person person3 = Person('Anna');
person3.showNameAndAge();
Person person4 = Person.gest();
person4.showNameAndAge();
}
*/
/// Class 2 - final & static const
/*
class Person2 {
final String name; /// [final] type will be defined here or in the constructor
static const int age = 10; /// [const] type must be defined here and can not be changed
/// [const] type in class need kw [static]
Person2(this.name); /// if [final] type is defined in constructor, can be assigned when be constructed.
}
void main() {
var personA = Person2('Jack'); /// [const] can not be reassigned, so no [age] need; if final type [name] is defined when init, no [name] need either.
print(personA.name);
var personB = Person2('Mike');
print(personB.name);
/* print(person.age); /// static field can not be accessed */
/// Should call like this:
print(Person2.age);
}
*/
// Class 3 - extends
/*
class Vehicle {
String model;
Vehicle(this.model) {
print(this.model);
}
void showOutput() {
print(model);
}
}
class Car extends Vehicle {
int year;
double price;
Car(String model, this.year, this.price) : super(model);
void showOutput(){
super.showOutput(); /// model will be print twice
print(this.year);
print(this.price);
}
}
void main() {
var carA = Car('Accord', 2014, 15000);
carA.showOutput();
}
*/
// class 4 - override
/*
class X {
String name;
X(this.name);
void showOutput() {
print(this.name);
}
dynamic square(dynamic val) {
return val * val;
}
}
class Y extends X {
Y(String name) : super(name);
@override /// use override notation is a good practic, it will reminde you when super method is not exist.
/// though there is no issue if not use the notation.
void showOutput() {
print(this.name); /// override, same as parent
print('Hello');
}
}
*/
// Class 5 - getters & setters
/*
class Rectangle {
num left, top, width, height; /// [num]: [int] or [double]
Rectangle(this.left, this.top, this.width, this.height);
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
void showOutput() {
print('($left, $top), ($right, $top)');
print('($left, $bottom), ($right, $bottom)');
}
}
void main() {
var rect = Rectangle(3, 4, 20, 15);
rect.showOutput();
print(rect.left);
rect.right = 12;
print(rect.left);
rect.showOutput();
print(rect.top);
rect.bottom = 10;
print(rect.top);
rect.showOutput();
}
*/
/// Exception handling
int mustGreaterThanZero(int val) {
if (val <= 0) {
throw Exception('Value must be greater than zero');
}
return val;
}
void verifyValue(var val) {
var valueVerification;
try {
valueVerification = mustGreaterThanZero(val); /// more exception pattern: try...on..., not mentioned here
}
catch(e) {
print(e);
}
finally {
if (valueVerification == null) {
print('Value is not accepted');
} else {
print('Value verified: $valueVerification');
}
}
}
void main() {
verifyValue(10);
verifyValue(-1);
}