0% found this document useful (0 votes)
7 views

dart

Uploaded by

Alaise Tchindou
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

dart

Uploaded by

Alaise Tchindou
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 42

Introduction :

Dart is a versatile programming language created by Google, designed for building


web, server, desktop, and mobile applications. It is the backbone of Flutter,
Google's popular UI toolkit for crafting natively compiled applications for mobile,
web, and desktop from a single codebase. Dart's syntax is simple and familiar to
those who have experience with other object-oriented languages like Java or C#,
making it an accessible language for beginners and experienced developers alike.

One of Dart's standout features is its strong support for asynchronous programming,
which is crucial for building responsive applications. Dart achieves this through
its single-threaded, event-driven model, and its use of "isolates" for concurrent
programming, allowing developers to run multiple tasks simultaneously without
blocking the main thread.

Dart is often praised for its comprehensive tooling support, including a powerful
package manager (pub), a rich set of core libraries, and seamless integration with
IDEs like IntelliJ IDEA and Visual Studio Code. Its development environment is
further enhanced by the Dart VM, which supports a fast development cycle through
features like hot reload, making it easier to iterate on your code quickly.

Flutter leverages Dart to provide a highly efficient and flexible framework for UI
development. With Flutter, developers can create stunning, high-performance
interfaces with customizable widgets that adhere to platform-specific guidelines
for iOS and Android. The framework's reactive model, which is inspired by React,
allows developers to build applications with expressive and flexible UI designs.

A key advantage of using Dart with Flutter is the ability to create applications
for multiple platforms from a single codebase. This cross-platform capability
reduces development time and effort while maintaining native performance and
aesthetics. Additionally, Dart's compilation capabilities—ranging from just-in-time
(JIT) compilation for a speedy development cycle to ahead-of-time (AOT) compilation
for optimized performance in production—make it a powerful choice for building
robust applications.

In summary, Dart and Flutter together provide a compelling solution for modern
application development, offering a blend of simplicity, efficiency, and cross-
platform capabilities. Whether you're new to programming or an experienced
developer, Dart's straightforward syntax and Flutter's rich UI framework can help
you create high-quality applications with ease.

---

**Setting Up the Dart Development Environment**

To begin developing with Dart, you need to set up a suitable development


environment. This chapter provides a detailed guide on how to set up Dart for
development, covering both online and local environments.

### Executing Scripts Online with DartPad

DartPad is an excellent tool for quickly writing and testing Dart scripts without
installing anything locally. It is a web-based editor available at [DartPad]
(https://dartpad.dev/). DartPad supports both HTML and console output, making it a
versatile choice for experimenting with Dart code.
**Features of DartPad:**

- **Preset Code Samples:** DartPad comes with a variety of code samples that you
can modify and experiment with, allowing you to learn Dart interactively.
- **Strong Mode:** DartPad offers a feature called "Strong Mode," which enhances
static and dynamic checking. This mode helps in generating idiomatic JavaScript
code, improving interoperability with JavaScript projects.

**Using DartPad:**

1. Visit [DartPad](https://dartpad.dev/).
2. Write your Dart code in the editor.
3. Click the "Run" button to execute your code.
4. View the output in the console output pane.

**Example:**

```dart
void main() {
print('hello world');
}
```

The above code will display the following output:

```
hello world
```

### Setting Up the Local Environment

For a more robust development setup, it's essential to configure Dart locally on
your machine. This setup involves installing the Dart SDK and choosing a suitable
text editor or Integrated Development Environment (IDE).

#### Choosing a Text Editor or IDE

You can write Dart code using various text editors or IDEs. Some popular options
include:

- **Visual Studio Code:** A lightweight and powerful editor with extensions for
Dart and Flutter.
- **IntelliJ IDEA:** Offers comprehensive support for Dart and Flutter development.
- **Atom:** A customizable editor with plugins available for Dart.

For basic editing, you can also use text editors like Notepad++ or Sublime Text.

#### Installing the Dart SDK

The Dart SDK contains essential tools for developing Dart applications, including
the Dart VM, dart2js compiler, and core libraries.

**Installation Steps:**

1. **Download the Dart SDK:**

- Visit the Dart SDK download page: [Dart SDK Downloads](https://dart.dev/get-


dart).
- Choose the version suitable for your operating system and follow the
installation instructions provided.

2. **Set the PATH Environment Variable:**

After installing the SDK, you need to update the PATH environment variable to
include the Dart SDK's `bin` directory. This step allows you to run Dart commands
from any terminal window.

**Example Path Setting (Windows):**

```shell
set PATH=<dart-sdk-path>\bin;%PATH%
```

Replace `<dart-sdk-path>` with the path where you installed the Dart SDK.

#### Verifying the Installation

To ensure that Dart is installed correctly, you can verify the installation by
running the following command in your command prompt or terminal:

```shell
dart --version
```

If the installation is successful, you will see the Dart runtime version
information displayed.

### Conclusion

By following these steps, you can set up an efficient Dart development environment,
whether you prefer coding online with DartPad or working locally with a powerful
editor and the Dart SDK. This setup will empower you to build Dart applications for
various platforms, leveraging Dart's strong typing, concurrency support, and cross-
platform capabilities.

---

---

**Data Types in Dart**

In Dart, data types define the kind of data that can be stored and manipulated
within a program. Understanding these types is essential for writing effective Dart
code. Dart supports a variety of data types, each serving a specific purpose:

### 1. Numbers

Numbers are used to represent numeric values in Dart and come in two primary forms:

- **Integer (int):** Represents whole numbers without fractional parts. Integers in


Dart are typically used when you don't need decimal precision. They are denoted by
the `int` keyword.

**Example:**
```dart
int age = 30;
int year = 2024;
```

- **Double (double):** Represents 64-bit (double-precision) floating-point numbers.


This type is used for numbers with decimal points, providing precision for
fractional values.

**Example:**

```dart
double price = 9.99;
double pi = 3.14159;
```

Dart also supports arithmetic operations like addition, subtraction,


multiplication, and division on these number types.

### 2. Strings

Strings in Dart are used to represent sequences of characters. They are useful for
storing text such as names, addresses, and messages. Strings are UTF-16 encoded and
can be defined using either single or double quotes.

**Example:**

```dart
String firstName = 'John';
String lastName = "Doe";
```

**String Interpolation:** Dart allows you to insert the value of expressions into
strings using the `${expression}` syntax or `$variableName` for simple variables.

```dart
String name = 'John';
String greeting = 'Hello, $name!';
```

### 3. Booleans

The Boolean data type is used to represent logical values—`true` and `false`.
Boolean values are crucial for controlling flow in programs through conditional
statements and loops.

**Example:**

```dart
bool isStudent = true;
bool isGraduated = false;
```

### 4. Lists

Lists in Dart are ordered collections of objects and are similar to arrays in other
programming languages. They can hold elements of any data type and are defined
using square brackets `[]`.
**Example:**

```dart
List<int> numbers = [1, 2, 3, 4, 5];
List<String> fruits = ['apple', 'banana', 'orange'];
```

Lists support operations like accessing elements, adding new elements, and
iterating over elements.

### 5. Maps

Maps are collections of key-value pairs. Each key is unique, and it maps to a
corresponding value. Maps are useful for storing and retrieving data by keys.

**Example:**

```dart
Map<String, int> fruitPrices = {
'apple': 2,
'banana': 1,
'orange': 3
};
```

You can access map values using keys:

```dart
int applePrice = fruitPrices['apple'];
```

### 6. The Dynamic Type

Dart is an optionally typed language, meaning you can choose whether to specify
types. If a variable's type is not specified, it defaults to the `dynamic` type.
This allows the variable to hold any data type.

**Example:**

```dart
dynamic value = 5;
value = 'hello'; // Now value holds a string
```

The `dynamic` keyword can also be used explicitly to declare a variable that can
hold values of any type.

### Type Safety and Type Inference

Dart is a statically typed language, but it offers type inference, meaning the Dart
compiler can automatically determine the type of a variable based on the assigned
value. This feature enhances code readability while maintaining type safety.

**Example:**

```dart
var score = 100; // Inferred as int
var name = 'Alice'; // Inferred as String
```

### Conclusion

Understanding Dart's data types is crucial for developing robust applications.


Whether dealing with numbers, text, collections, or dynamic content, Dart provides
flexible and powerful types to meet your programming needs. By leveraging these
types, you can write clear, concise, and efficient Dart code.

---

---

**Expressions, Variables, and Constants in Dart**

Dart, like most programming languages, uses variables to store data and expressions
to perform operations. Understanding how to declare and use variables, as well as
the difference between variables and constants, is fundamental to writing efficient
Dart code.

### Variables

A variable in Dart is a named location in memory that stores a value. Variables are
crucial for data manipulation and storage in your programs.

#### Naming Rules for Identifiers

1. **Cannot be keywords**: You cannot use reserved keywords as variable names.


2. **Alphabets and numbers**: Identifiers can contain letters and numbers.
3. **No spaces or special characters**: Except for the underscore `_` and dollar
`$` sign.
4. **Cannot start with a number**: Identifiers must begin with a letter or
underscore.

#### Declaring Variables

You must declare a variable before using it. Dart provides flexible ways to declare
variables:

##### Using `var`

The `var` keyword is used when you don't want to explicitly specify the data type.
The type is inferred based on the assigned value.

```dart
var name = 'Smith'; // Inferred as String
var age = 30; // Inferred as int
```

##### Type Annotations

You can explicitly specify the data type of a variable. This enables type-checking,
ensuring that the variable only holds values of the specified type.

```dart
String firstName = 'John';
int score = 85;
```

**Example:**

```dart
void main() {
String name = 1; // Error: Type 'int' can't be assigned to type 'String'
}
```

This example produces an error because the assigned value does not match the
declared data type.

#### Initial Values

All uninitialized variables in Dart have a default initial value of `null`. This is
because every variable in Dart is an object, and `null` is an object of type
`Null`.

**Example:**

```dart
void main() {
int num;
print(num); // Outputs: null
}
```

#### Dynamic Variables

Variables without a specified type are implicitly dynamic. You can also declare a
variable explicitly as `dynamic`.

```dart
dynamic x = "tom";
print(x); // Outputs: tom
```

The `dynamic` keyword allows the variable to change type at runtime.

### Constants

Constants are variables whose values cannot be changed once set. Dart provides two
ways to declare constants: `final` and `const`.

#### Using `final`

A `final` variable can only be set once and is initialized when accessed.

**Syntax:**

```dart
final variableName;
final dataType variableName;
```

**Example:**

```dart
void main() {
final val1 = 12;
print(val1); // Outputs: 12
}
```

#### Using `const`

A `const` variable is a compile-time constant. This means the value is determined


at compile time and cannot be changed at runtime.

**Syntax:**

```dart
const variableName;
const dataType variableName;
```

**Example:**

```dart
void main() {
const pi = 3.14;
const area = pi * 12 * 12;
print("The output is ${area}"); // Outputs: The output is 452.16
}
```

**Key Differences:**

- `final`: Can be set only once and is initialized when the variable is accessed.
- `const`: Must be initialized at the time of declaration and cannot be changed. It
is a compile-time constant.

#### Modifying Constants

Attempting to modify a `final` or `const` variable will result in an error.

**Example:**

```dart
void main() {
final v1 = 12;
const v2 = 13;
v2 = 12; // Error: Can't assign to a final variable
}
```

The above code will throw an error because `v2` is a `const` variable, and its
value cannot be changed.

### Operators in Dart

In Dart, operators are special symbols that are used to perform operations on
operands. Operators in Dart can be categorized into different types based on the
kind of operations they perform. Understanding these operators is crucial for
writing effective Dart code.
#### 1. Arithmetic Operators

Arithmetic operators are used to perform basic mathematical operations.

| Operator | Meaning | Example | Result |


|----------|-------------------------|---------------|--------|
| `+` | Addition | `5 + 3` | `8` |
| `-` | Subtraction | `5 - 3` | `2` |
| `-expr` | Unary minus (negation) | `-5` | `-5` |
| `*` | Multiplication | `5 * 3` | `15` |
| `/` | Division | `5 / 3` | `1.6667` |
| `~/` | Integer division | `5 ~/ 3` | `1` |
| `%` | Modulo (remainder) | `5 % 3` | `2` |
| `++` | Increment | `a++` (if `a = 5`) | `6` (after increment) |
| `--` | Decrement | `a--` (if `a = 5`) | `4` (after decrement) |

**Example:**

```dart
void main() {
int a = 5;
int b = 3;
print(a + b); // 8
print(a - b); // 2
print(a * b); // 15
print(a / b); // 1.6666666666666667
print(a ~/ b); // 1
print(a % b); // 2
print(++a); // 6
print(--b); // 2
}
```

#### 2. Equality and Relational Operators

Relational operators compare two operands and return a Boolean value (`true` or
`false`).

| Operator | Description | Example | Result |


|----------|---------------------------|--------------|--------|
| `>` | Greater than | `5 > 3` | `true` |
| `<` | Less than | `5 < 3` | `false`|
| `>=` | Greater than or equal to | `5 >= 3` | `true` |
| `<=` | Less than or equal to | `5 <= 3` | `false`|
| `==` | Equality | `5 == 3` | `false`|
| `!=` | Not equal | `5 != 3` | `true` |

**Example:**

```dart
void main() {
int a = 10;
int b = 20;
print(a > b); // false
print(a < b); // true
print(a >= b); // false
print(a <= b); // true
print(a == b); // false
print(a != b); // true
}
```

#### 3. Type Test Operators

Type test operators check the type of an object at runtime.

| Operator | Meaning | Example | Result |


|----------|------------------------------|---------------|---------|
| `is` | True if the object is of the specified type | `a is int` | `true` |
| `is!` | True if the object is not of the specified type | `a is! String` |
`true` |

**Example:**

```dart
void main() {
int a = 10;
print(a is int); // true
print(a is! String); // true
}
```

#### 4. Bitwise Operators

Bitwise operators perform operations on binary representations of integers.

| Operator | Description | Example | Result


|
|----------|--------------------------------------------|-------------|------------
|
| `&` | Bitwise AND | `5 & 3` | `1`
|
| `|` | Bitwise OR | `5 | 3` | `7`
|
| `^` | Bitwise XOR | `5 ^ 3` | `6`
|
| `~` | Bitwise NOT (inverts bits) | `~5` | `-6`
|
| `<<` | Left shift (shifts bits to the left) | `5 << 1` | `10`
|
| `>>` | Right shift (shifts bits to the right) | `5 >> 1` | `2`
|

**Example:**

```dart
void main() {
int a = 5; // 0101
int b = 3; // 0011
print(a & b); // 1 -> 0001
print(a | b); // 7 -> 0111
print(a ^ b); // 6 -> 0110
print(~a); // -6 -> 1010 (Two's complement representation)
print(a << 1); // 10 -> 1010
print(a >> 1); // 2 -> 0010
}
```
#### 5. Assignment Operators

Assignment operators are used to assign values to variables. They combine simple
assignment with an operation.

| Operator | Description | Example |


Equivalent to |
|----------|-------------------------------------------------|---------------|-----
----------|
| `=` | Simple assignment | `a = b` |
|
| `??=` | Assign only if the variable is null | `a ??= b` |
|
| `+=` | Add and assign | `a += b` | `a =
a + b` |
| `-=` | Subtract and assign | `a -= b` | `a =
a - b` |
| `*=` | Multiply and assign | `a *= b` | `a =
a * b` |
| `/=` | Divide and assign | `a /= b` | `a =
a / b` |
| `%=` | Modulo and assign | `a %= b` | `a =
a % b` |
| `<<=` | Left shift and assign | `a <<= b` | `a =
a << b` |
| `>>=` | Right shift and assign | `a >>= b` | `a =
a >> b` |
| `&=` | Bitwise AND and assign | `a &= b` | `a =
a & b` |
| `^=` | Bitwise XOR and assign | `a ^= b` | `a =
a ^ b` |
| `|=` | Bitwise OR and assign | `a |= b` | `a =
a | b` |

**Example:**

```dart
void main() {
int a = 10;
int b = 5;
a += b; // a = 15
print(a);
a -= b; // a = 10
print(a);
a *= b; // a = 50
print(a);
a ~/= b; // a = 10
print(a);
a %= b; // a = 0
print(a);
a ??= b; // a = 0 because it's not null
print(a);
}
```

#### 6. Logical Operators

Logical operators are used to combine multiple conditions or expressions.


| Operator | Description | Example |
Result |
|----------|------------------------------------------|---------------------------|
---------|
| `&&` | Logical AND (returns true if both conditions are true) | `(a > 5 && b
< 10)` | `true` |
| `||` | Logical OR (returns true if at least one condition is true) | `(a > 5
|| b < 10)` | `true` |
| `!` | Logical NOT (returns the inverse of a condition) | `!(a > 5)`
| `false` |

**Example:**

```dart
void main() {
int a = 10;
int b = 20;
print(a > 5 && b < 10); // false
print(a > 5 || b < 10); // true
print(!(a > 5)); // false
}
```

#### 7. Conditional Expressions

Dart provides conditional expressions to simplify the logic in your code. They are
concise and improve readability.

- **Ternary Operator**: `condition ? expr1 : expr2`

If `condition` is true, `expr1` is evaluated; otherwise, `expr2` is evaluated.

- **Null-aware Operator**: `expr1 ?? expr2`

If `expr1` is non-null, its value is returned; otherwise, `expr2` is evaluated


and its value is returned.

**Example:**

```dart
void

main() {
var a = 10;
var result = a > 12 ? "value greater than 10" : "value less than or equal to 10";
print(result); // value less than or equal to 10

var b = null;
var c = 12;
var res = b ?? c;
print(res); // 12
}
```

### Conclusion

Understanding operators in Dart is crucial for performing operations on data


effectively. They allow you to manipulate data, compare values, and control the
flow of your program. By mastering these operators, you can write more efficient
and readable Dart code.

---

### Decision-Making Constructs in Dart

Decision-making constructs in Dart allow you to control the flow of execution based
on certain conditions. These constructs enable you to execute specific code blocks
when particular conditions are met, making your programs dynamic and responsive to
different scenarios.

#### 1. `if` Statement

The `if` statement is the simplest form of decision-making. It executes a block of


code if a specified condition is true.

**Syntax:**

```dart
if (condition) {
// statements to execute if the condition is true
}
```

**Example:**

```dart
void main() {
int num = 10;
if (num > 5) {
print("Number is greater than 5.");
}
}
```

In this example, the program checks if the variable `num` is greater than 5. Since
the condition is true, it prints "Number is greater than 5."

#### 2. `if...else` Statement

The `if...else` statement provides an alternative path of execution when the `if`
condition is false.

**Syntax:**

```dart
if (condition) {
// statements to execute if the condition is true
} else {
// statements to execute if the condition is false
}
```

**Example:**

```dart
void main() {
int num = 3;
if (num > 5) {
print("Number is greater than 5.");
} else {
print("Number is less than or equal to 5.");
}
}
```

In this example, since the condition `num > 5` is false, the program prints "Number
is less than or equal to 5."

#### 3. `else if` Ladder

The `else if` ladder allows you to test multiple conditions sequentially. It is
useful when you have more than two paths to choose from.

**Syntax:**

```dart
if (condition1) {
// statements to execute if condition1 is true
} else if (condition2) {
// statements to execute if condition2 is true
} else if (condition3) {
// statements to execute if condition3 is true
} else {
// statements to execute if all conditions are false
}
```

**Example:**

```dart
void main() {
int num = 8;
if (num > 10) {
print("Number is greater than 10.");
} else if (num == 10) {
print("Number is equal to 10.");
} else if (num > 5) {
print("Number is greater than 5 but less than 10.");
} else {
print("Number is less than or equal to 5.");
}
}
```

In this example, the program evaluates multiple conditions. Since `num > 5` is
true, it prints "Number is greater than 5 but less than 10."

#### 4. `switch`...`case` Statement

The `switch` statement is an alternative to the `else if` ladder. It evaluates an


expression and executes the matching case block. The `switch` statement is often
cleaner and more readable when dealing with multiple constant conditions.

**Syntax:**
```dart
switch (expression) {
case value1:
// statements to execute if expression == value1
break;
case value2:
// statements to execute if expression == value2
break;
...
default:
// statements to execute if no case matches
}
```

**Example:**

```dart
void main() {
int day = 3;
switch (day) {
case 1:
print("Monday");
break;
case 2:
print("Tuesday");
break;
case 3:
print("Wednesday");
break;
case 4:
print("Thursday");
break;
case 5:
print("Friday");
break;
case 6:
print("Saturday");
break;
case 7:
print("Sunday");
break;
default:
print("Invalid day");
}
}
```

In this example, the program evaluates the `day` variable. Since `day` is `3`, it
prints "Wednesday."

#### Important Notes:

- **Break Statement**: Each `case` block typically ends with a `break` statement to
prevent fall-through, which is the execution of subsequent cases regardless of
their conditions. If a `break` statement is omitted, the program will continue
executing the next case block(s) until it encounters a `break`.

- **Default Case**: The `default` case is optional but recommended. It executes


when none of the `case` values match the `switch` expression. It's similar to the
`else` block in an `if...else` structure.

- **Data Types**: In Dart, the `switch` expression can evaluate only specific data
types like `int`, `String`, `enum`, or `const`.

### Conclusion

Decision-making constructs in Dart enable you to control the flow of your program
based on conditions. By using `if`, `if...else`, `else if`, and `switch...case`
statements, you can implement complex logic and make your programs more dynamic and
responsive. Understanding these constructs is crucial for effective Dart
programming, allowing you to handle different scenarios and conditions with ease.

### Advanced Decision-Making Constructs in Dart

Beyond the basic `if`, `else if`, `else`, and `switch` statements, Dart offers
several other ways to make decisions in your code, each with its own specific use
cases and advantages. Here are some additional constructs and techniques for
decision-making in Dart:

#### 1. Conditional Expressions

Dart provides two conditional expressions that allow you to evaluate expressions
more succinctly. These are the ternary operator and the `??` (null-aware) operator.

##### Ternary Operator (`?:`)

The ternary operator is a shorthand for `if...else` that allows you to write
compact code for simple conditions.

**Syntax:**

```dart
condition ? expr1 : expr2
```

If `condition` is true, `expr1` is evaluated and returned; otherwise, `expr2` is


evaluated and returned.

**Example:**

```dart
void main() {
int num = 8;
String result = num > 5 ? "Greater than 5" : "Less than or equal to 5";
print(result);
}
```

Here, the ternary operator checks if `num` is greater than 5 and assigns the
appropriate string to `result`.

##### Null-Aware Operator (`??`)

The null-aware operator returns the value of the left operand if it is not null;
otherwise, it evaluates and returns the right operand. This is useful for providing
default values.

**Syntax:**

```dart
expr1 ?? expr2
```

**Example:**

```dart
void main() {
String? name;
String displayName = name ?? "Guest";
print(displayName);
}
```

In this example, if `name` is null, `displayName` is set to "Guest".

#### 2. Null Safety and Null-Aware Operators

Dart's null safety features and null-aware operators provide additional tools for
decision-making by allowing you to safely handle null values.

##### Null-Aware Access (`?.`)

The null-aware access operator allows you to call a method or access a property
only if the object is not null, avoiding null reference exceptions.

**Example:**

```dart
class User {
String? name;
void greet() => print("Hello, $name!");
}

void main() {
User? user;
user?.greet(); // Does nothing if user is null
}
```

In this example, `user?.greet()` calls `greet()` only if `user` is not null.

##### Null-Aware Assignment (`??=`)

The null-aware assignment operator assigns a value to a variable only if the


variable is currently null.

**Example:**

```dart
void main() {
int? a;
a ??= 10;
print(a); // Prints 10
a ??= 20;
print(a); // Still prints 10
}
```

Here, `a` is assigned 10 only if it is null.

#### 3. Cascading Notation (`..`)

Cascading notation allows you to perform multiple operations on the same object
without needing to refer to the object multiple times.

**Example:**

```dart
class Point {
double x = 0;
double y = 0;
void setX(double x) => this.x = x;
void setY(double y) => this.y = y;
void printCoordinates() => print("x: $x, y: $y");
}

void main() {
Point point = Point()
..setX(5)
..setY(10)
..printCoordinates();
}
```

In this example, cascading notation (`..`) is used to set the coordinates and print
them in a single expression.

#### 4. Assert Statements

The `assert` statement is used for debugging purposes. It helps verify that certain
conditions are true at runtime. If the condition is false, the program will
terminate with an error.

**Syntax:**

```dart
assert(condition, "Error message");
```

**Example:**

```dart
void main() {
int age = 18;
assert(age >= 18, "Age must be at least 18");
print("Age is $age");
}
```

In this example, if `age` is less than 18, the program will throw an assertion
error with the specified message.
#### 5. Custom Error Handling

Dart provides the ability to throw exceptions and handle them using `try`, `catch`,
`on`, and `finally` blocks, offering another way to handle decision-making based on
error conditions.

**Syntax:**

```dart
try {
// Code that might throw an exception
} on SpecificException catch (e) {
// Handle specific exception
} catch (e) {
// Handle any exception
} finally {
// Code that always runs, regardless of exceptions
}
```

**Example:**

```dart
void main() {
try {
int result = 10 ~/ 0;
print("Result is $result");
} on IntegerDivisionByZeroException {
print("Cannot divide by zero");
} catch (e) {
print("An error occurred: $e");
} finally {
print("This block is always executed");
}
}
```

In this example, the program catches the `IntegerDivisionByZeroException` and


provides an error message.

### Conclusion

Dart offers a rich set of decision-making constructs and techniques, from basic
conditional statements like `if`, `else if`, `else`, and `switch`, to more advanced
features like conditional expressions, null-aware operators, cascading notation,
assertions, and custom error handling. These constructs enable you to write
flexible and robust code, allowing for dynamic responses to varying conditions and
states within your programs. Understanding and effectively using these constructs
is essential for mastering Dart programming.

## Loops in Dart

Loops are used to execute a block of code repeatedly, which is particularly useful
for iterating over collections, processing data, or simply repeating an operation a
specific number of times. Dart offers several types of loops: definite loops and
indefinite loops, along with loop control statements.

### Definite Loops

Definite loops are used when the number of iterations is known beforehand. They are
commonly used to iterate over collections or perform operations a fixed number of
times.

#### 1. `for` Loop

The `for` loop is a traditional loop structure that executes a block of code a
specified number of times. It consists of three parts: initialization, condition,
and increment/decrement.

**Syntax:**

```dart
for (initialization; condition; increment/decrement) {
// Code block to be executed
}
```

**Example:**

```dart
void main() {
for (int i = 0; i < 5; i++) {
print("Iteration $i");
}
}
```

In this example, the `for` loop runs five times, printing the iteration number each
time.

#### 2. `for...in` Loop

The `for...in` loop is used to iterate over the elements of a collection, such as a
list or a set. It simplifies the iteration process by directly accessing each
element in the collection.

**Syntax:**

```dart
for (var element in collection) {
// Code block to be executed for each element
}
```

**Example:**

```dart
void main() {
List<String> fruits = ["apple", "banana", "cherry"];
for (var fruit in fruits) {
print(fruit);
}
}
```
This example iterates over a list of fruits and prints each one.

### Indefinite Loops

Indefinite loops are used when the number of iterations is not known in advance and
depends on a condition that is evaluated during runtime.

#### 1. `while` Loop

The `while` loop repeatedly executes a block of code as long as a specified


condition is true. The condition is checked before the loop body is executed, which
means the loop body may not execute at all if the condition is false initially.

**Syntax:**

```dart
while (condition) {
// Code block to be executed
}
```

**Example:**

```dart
void main() {
int counter = 0;
while (counter < 5) {
print("Counter: $counter");
counter++;
}
}
```

In this example, the loop runs as long as `counter` is less than 5.

#### 2. `do...while` Loop

The `do...while` loop is similar to the `while` loop, but the loop body is executed
at least once before the condition is tested. This is useful when the loop needs to
execute at least once regardless of the condition.

**Syntax:**

```dart
do {
// Code block to be executed
} while (condition);
```

**Example:**

```dart
void main() {
int counter = 0;
do {
print("Counter: $counter");
counter++;
} while (counter < 5);
}
```

In this example, the loop executes the code block once before checking the
condition.

### Loop Control Statements

Dart provides loop control statements to alter the flow of execution within loops.

#### 1. `break` Statement

The `break` statement is used to exit the loop prematurely. When a `break`
statement is encountered, control is transferred to the statement immediately
following the loop.

**Example:**

```dart
void main() {
for (int i = 0; i < 5; i++) {
if (i == 3) {
break;
}
print("Iteration $i");
}
}
```

In this example, the loop breaks when `i` equals 3, and the loop exits.

#### 2. `continue` Statement

The `continue` statement skips the current iteration of the loop and jumps to the
next iteration. It effectively skips the remaining code in the loop body for the
current iteration.

**Example:**

```dart
void main() {
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue;
}
print("Iteration $i");
}
}
```

In this example, the iteration where `i` equals 3 is skipped.

### Using Labels to Control Flow

Labels can be used with `break` and `continue` statements to control flow more
precisely, especially in nested loops.

**Label with Break Example:**


```dart
void main() {
outerloop: // This is the label name
for (var i = 0; i < 5; i++) {
print("Outerloop: $i");
innerloop:
for (var j = 0; j < 5; j++) {
if (j > 3) break;
if (i == 2) break innerloop;
if (i == 4) break outerloop;
print("Innerloop: $j");
}
}
}
```

In this example, labels allow you to break out of specific loops or even exit
nested loops entirely.

**Label with Continue Example:**

```dart
void main() {
outerloop: // This is the label name
for (var i = 0; i < 3; i++) {
print("Outerloop: $i");
for (var j = 0; j < 5; j++) {
if (j == 3) {
continue outerloop;
}
print("Innerloop: $j");
}
}
}
```

Here, `continue outerloop;` causes the program to skip to the next iteration of the
outer loop, effectively bypassing the inner loop.

### Conclusion

Loops are a fundamental aspect of programming that enable the repeated execution of
code blocks. Dart provides various types of loops (`for`, `for...in`, `while`, and
`do...while`) to accommodate both definite and indefinite iterations. Additionally,
loop control statements like `break` and `continue`, combined with labels, offer
powerful mechanisms to control the flow within loops, making it easier to write
clear and efficient code. Understanding these concepts is crucial for handling
repetitive tasks and processing collections in Dart applications.

Dart provides a robust set of features for working with numbers, including various
types, methods, and properties to handle different numerical operations. Here’s a
comprehensive guide to Dart numbers, covering integers, floating-point numbers,
parsing, properties, and methods.

## Dart Numbers

Dart numbers can be broadly classified into two types: `int` and `double`. The
`num` type is a superclass of both `int` and `double` and serves as a common base
for numeric operations.

### 1. Integer (`int`)

- **Description**: Represents whole numbers. Dart integers are of arbitrary size,


meaning they can grow as large as memory allows.
- **Declaration**: `int variableName;`
- **Example**:

```dart
void main() {
int num1 = 10;
print(num1); // Output: 10
}
```

### 2. Double (`double`)

- **Description**: Represents 64-bit double-precision floating-point numbers as


specified by the IEEE 754 standard. Used for fractional numbers.
- **Declaration**: `double variableName;`
- **Example**:

```dart
void main() {
double num2 = 10.50;
print(num2); // Output: 10.5
}
```

### 3. Common Type (`num`)

- **Description**: The superclass of both `int` and `double`. Used for operations
that can work with both types.
- **Declaration**: `num variableName;`
- **Example**:

```dart
void main() {
num number = 10.5;
print(number); // Output: 10.5
number = 10;
print(number); // Output: 10
}
```

## Parsing Numbers

You can convert strings to numbers using the `num.parse()` method. This method
throws a `FormatException` if the string cannot be parsed into a number.

### Example: Parsing Numeric Strings

```dart
void main() {
print(num.parse('12')); // Output: 12
print(num.parse('10.91')); // Output: 10.91
}
```

### Example: Handling Invalid Formats

```dart
void main() {
try {
print(num.parse('12A')); // This will throw FormatException
} catch (e) {
print('Error: $e'); // Output: Error: FormatException: Invalid number
}
}
```

## Number Properties

Dart numbers come with several properties that provide information about their
state:

### Properties

| Property | Description
| Example |
|--------------|-------------------------------------------------------------------
-|-------------------------------|
| `hashCode` | Returns a hash code for the number.
| `10.hashCode` |
| `isFinite` | Returns `true` if the number is finite; otherwise, `false`.
| `(double.infinity).isFinite` |
| `isInfinite` | Returns `true` if the number is positive or negative infinity.
| `(double.infinity).isInfinite`|
| `isNaN` | Returns `true` if the number is "Not-a-Number" (NaN).
| `(double.nan).isNaN` |
| `isNegative` | Returns `true` if the number is negative.
| `(-10).isNegative` |
| `sign` | Returns `-1`, `0`, or `1` based on the sign of the number.
| `10.sign` |
| `isEven` | Returns `true` if the number is even.
| `10.isEven` |
| `isOdd` | Returns `true` if the number is odd.
| `11.isOdd` |

### Example:

```dart
void main() {
double num = -10.5;
print(num.isNegative); // Output: true
print(num.isEven); // Output: false
}
```

## Number Methods

Dart provides several methods for numerical operations and conversions.

### Methods

| Method | Description |
Example |
|---------------|------------------------------------------------------------|-----
---------------------|
| `abs` | Returns the absolute value of the number. | `(-
10).abs()` |
| `ceil` | Returns the smallest integer greater than or equal to the number.
| `(10.2).ceil()` |
| `compareTo` | Compares the current number to another number. |
`10.compareTo(12)` |
| `floor` | Returns the largest integer less than or equal to the number. |
`(10.9).floor()` |
| `remainder` | Returns the remainder after dividing the number by another
number. | `(10).remainder(3)` |
| `round` | Returns the integer closest to the number. |
`(10.5).round()` |
| `toDouble` | Converts the number to a `double`. |
`(10).toDouble()` |
| `toInt` | Converts the number to an `int`. |
`(10.5).toInt()` |
| `toString` | Converts the number to its string representation. |
`(10.5).toString()` |
| `truncate` | Discards the fractional part and returns the integer. |
`(10.9).truncate()` |

### Example:

```dart
void main() {
double num = 10.75;
print(num.abs()); // Output: 10.75
print(num.ceil()); // Output: 11
print(num.compareTo(10)); // Output: 1
print(num.floor()); // Output: 10
print(num.remainder(3)); // Output: 1.75
print(num.round()); // Output: 11
print(num.toDouble()); // Output: 10.75
print(num.toInt()); // Output: 10
print(num.toString()); // Output: 10.75
print(num.truncate()); // Output: 10
}
```

### Conclusion

Dart provides a comprehensive set of features for working with numbers, including
various types (`int`, `double`), parsing methods, properties, and operations.
Understanding these features will help you handle numerical data effectively,
perform calculations, and manage numeric conversions in your Dart applications.

### Dart Strings: A Comprehensive Guide

The `String` data type in Dart represents a sequence of characters encoded in UTF-
16. Strings are essential for handling text and are immutable, meaning that any
modification to a string results in a new string being created.

#### **1. String Representation**


In Dart, strings can be represented in different ways:

- **Single-Line Strings**: You can use either single quotes (`'`) or double quotes
(`"`).

```dart
String singleLine1 = 'This is a single line string.';
String singleLine2 = "This is also a single line string.";
```

- **Multi-Line Strings**: Use triple quotes (`'''` or `"""`) to create multi-line


strings.

```dart
String multiLine1 = '''This is a multi-line string.
It spans multiple lines.''';

String multiLine2 = """This is another multi-line string.


It also spans multiple lines.""";
```

**Example:**

```dart
void main() {
String str1 = 'This is a single line string.';
String str2 = "This is another single line string.";
String str3 = '''This is a multi-line string.
It spans multiple lines.''';
String str4 = """This is another multi-line string.
It also spans multiple lines.""";

print(str1);
print(str2);
print(str3);
print(str4);
}
```

**Output:**

```
This is a single line string.
This is another single line string.
This is a multi-line string.
It spans multiple lines.
This is another multi-line string.
It also spans multiple lines.
```

#### **2. String Interpolation**

String interpolation allows you to embed expressions inside string literals. This
is done using `${}` syntax.

- **Basic Concatenation**:

```dart
void main() {
String str1 = "Hello";
String str2 = "World";
String result = str1 + " " + str2;
print("The concatenated string: $result");
}
```

- **Interpolation with Expressions**:

```dart
void main() {
int n = 1 + 1;
String str1 = "The sum of 1 and 1 is $n";
print(str1);

String str2 = "The sum of 2 and 2 is ${2 + 2}";


print(str2);
}
```

**Output:**

```
The concatenated string: Hello World
The sum of 1 and 1 is 2
The sum of 2 and 2 is 4
```

#### **3. String Properties**

Dart strings have several useful properties:

- **`codeUnits`**: Returns an unmodifiable list of UTF-16 code units of the string.

```dart
void main() {
String str = "Hello";
print(str.codeUnits); // Output: [72, 101, 108, 108, 111]
}
```

- **`isEmpty`**: Returns `true` if the string is empty.

```dart
void main() {
String str = "";
print(str.isEmpty); // Output: true
}
```

- **`length`**: Returns the length of the string, including spaces and special
characters.

```dart
void main() {
String str = "Hello World!";
print(str.length); // Output: 12
}
```

#### **4. String Methods**

Here are some common methods available for manipulating strings in Dart:

- **`toLowerCase()`**: Converts all characters in the string to lower case.

```dart
void main() {
String str = "Hello World!";
print(str.toLowerCase()); // Output: hello world!
}
```

- **`toUpperCase()`**: Converts all characters in the string to upper case.

```dart
void main() {
String str = "Hello World!";
print(str.toUpperCase()); // Output: HELLO WORLD!
}
```

- **`trim()`**: Removes leading and trailing whitespace from the string.

```dart
void main() {
String str = " Hello World! ";
print(str.trim()); // Output: Hello World!
}
```

- **`compareTo()`**: Compares the string to another string.

```dart
void main() {
String str1 = "apple";
String str2 = "banana";
print(str1.compareTo(str2)); // Output: -1 (str1 is less than str2)
}
```

- **`replaceAll()`**: Replaces all occurrences of a pattern with a specified value.

```dart
void main() {
String str = "Hello World!";
print(str.replaceAll("World", "Dart")); // Output: Hello Dart!
}
```

- **`split()`**: Splits the string into a list of substrings based on a delimiter.

```dart
void main() {
String str = "Hello,World,Dart";
List<String> parts = str.split(",");
print(parts); // Output: [Hello, World, Dart]
}
```

- **`substring()`**: Returns a substring from the string, from `startIndex`


(inclusive) to `endIndex` (exclusive).

```dart
void main() {
String str = "Hello World!";
print(str.substring(0, 5)); // Output: Hello
}
```

- **`toString()`**: Returns the string representation of the object.

```dart
void main() {
String str = "Hello";
print(str.toString()); // Output: Hello
}
```

- **`codeUnitAt()`**: Returns the 16-bit UTF-16 code unit at a specified index.

```dart
void main() {
String str = "Hello";
print(str.codeUnitAt(0)); // Output: 72 (the code unit for 'H')
}
```

#### **5. Special String Operations**

- **String Immutability**: Strings in Dart are immutable, meaning that any


modification to a string creates a new string.

```dart
void main() {
String original = "Hello";
String modified = original + " World!";
print(original); // Output: Hello
print(modified); // Output: Hello World!
}
```

- **Raw Strings**: Use `r'...'` for raw strings where escape sequences are not
processed.

```dart
void main() {
String rawString = r'This is a raw string: \n will not be processed.';
print(rawString); // Output: This is a raw string: \n will not be processed.
}
```

- **String Concatenation**: Use `+` for simple concatenation or interpolation for


dynamic expressions.

```dart
void main() {
String name = "Alice";
String greeting = "Hello, $name!";
print(greeting); // Output: Hello, Alice!
}
```

#### Méthodes de `String` en Dart

| **Méthode** | **Description**
| **Exemple** |
|----------------------------|-----------------------------------------------------
----------------------------|--------------------------------------|
| `toLowerCase()` | Convertit tous les caractères en minuscules.
| `string.toLowerCase();` |
| `toUpperCase()` | Convertit tous les caractères en majuscules.
| `string.toUpperCase();` |
| `trim()` | Supprime les espaces du début et de la fin.
| `string.trim();` |
| `trimLeft()` | Supprime les espaces du début.
| `string.trimLeft();` |
| `trimRight()` | Supprime les espaces de la fin.
| `string.trimRight();` |
| `replaceAll()` | Remplace toutes les occurrences d'un motif par une
nouvelle chaîne. | `string.replaceAll('old', 'new');` |
| `replaceFirst()` | Remplace la première occurrence d'un motif par une
nouvelle chaîne. | `string.replaceFirst('old', 'new');` |
| `split()` | Divise la chaîne en une liste de sous-chaînes.
| `string.split(',');` |
| `substring()` | Renvoie une sous-chaîne de la chaîne.
| `string.substring(1, 4);` |
| `indexOf()` | Renvoie l'index de la première occurrence d'une
sous-chaîne. | `string.indexOf('sub');` |
| `lastIndexOf()` | Renvoie l'index de la dernière occurrence d'une
sous-chaîne. | `string.lastIndexOf('sub');` |
| `padLeft()` | Ajoute des caractères au début de la chaîne jusqu'à
atteindre une longueur spécifiée. | `string.padLeft(10, '0');` |
| `padRight()` | Ajoute des caractères à la fin de la chaîne jusqu'à
atteindre une longueur spécifiée. | `string.padRight(10, '0');` |
| `replaceRange()` | Remplace une plage de caractères par une nouvelle
chaîne. | `string.replaceRange(1, 4, 'new');` |
| `allMatches()` | Renvoie toutes les correspondances d'un motif dans
la chaîne. | `string.allMatches('pattern');` |
| `compareTo()` | Compare la chaîne à une autre chaîne.
| `string.compareTo('other');` |
| `contains()` | Vérifie si la chaîne contient une sous-chaîne
spécifiée. | `string.contains('sub');` |
| `endsWith()` | Vérifie si la chaîne se termine par une sous-chaîne
spécifiée. | `string.endsWith('end');` |
| `startsWith()` | Vérifie si la chaîne commence par une sous-chaîne
spécifiée. | `string.startsWith('start');` |
| `codeUnitAt()` | Renvoie l'unité de code UTF-16 à l'index spécifié.
| `string.codeUnitAt(0);` |

### Conclusion

Dart strings are versatile and feature-rich, providing multiple ways to represent,
manipulate, and perform operations on text data. Understanding these features
allows you to efficiently handle and process string data in your Dart applications.

## Dart Lists: A Comprehensive Guide

Les listes (ou arrays) sont des collections couramment utilisées en programmation.
En Dart, les listes sont représentées sous forme d'objets `List`. Une `List` est
simplement un groupe ordonné d'objets. La bibliothèque `dart:core` fournit la
classe `List` qui permet de créer et de manipuler des listes.

### Représentation Logique d'une Liste

- **test_list** : C'est l'identifiant qui fait référence à la collection.


- La liste contient les valeurs 12, 13, et 14. Les blocs mémoire contenant ces
valeurs sont appelés éléments.
- Chaque élément de la `List` est identifié par un numéro unique appelé l'index.
L'index commence à zéro et s'étend jusqu'à `n-1`, où `n` est le nombre total
d'éléments dans la `List`. L'index est également appelé sous-script.

### Types de Listes

Les listes peuvent être classées en deux catégories :

1. **Fixed Length List**


2. **Growable List**

Nous allons maintenant discuter en détail de ces deux types de listes.

---

### Fixed Length List

Une liste de longueur fixe ne peut pas changer de taille à l'exécution. La syntaxe
pour créer une liste de longueur fixe est la suivante :

#### Étape 1 : Déclarer une liste

```dart
var list_name = new List(initial_size);
```

Cette syntaxe crée une liste de la taille spécifiée. La liste ne peut ni grandir ni
rétrécir à l'exécution. Toute tentative de redimensionnement de la liste entraînera
une exception.

#### Étape 2 : Initialiser une liste

La syntaxe pour initialiser une liste est la suivante :

```dart
lst_name[index] = value;
```

**Exemple :**

```dart
void main() {
var lst = new List(3);
lst[0] = 12;
lst[1] = 13;
lst[2] = 11;
print(lst);
}
```

**Sortie :**

```
[12, 13, 11]
```

---

### Growable List

Une liste extensible peut changer de taille à l'exécution. La syntaxe pour déclarer
et initialiser une liste extensible est la suivante :

#### Étape 1 : Déclarer une Liste

```dart
var list_name = [val1, val2, val3];
```

--- crée une liste contenant les valeurs spécifiées


OU
```dart
var list_name = new List();
```
--- crée une liste de taille zéro.

#### Étape 2 : Initialiser une Liste

L'index (ou sous-script) est utilisé pour référencer l'élément à remplir avec une
valeur. La syntaxe pour initialiser une liste est la suivante :

```dart
list_name[index] = value;
```

**Exemple :**

L'exemple suivant montre comment créer une liste de 3 éléments.

```dart
void main() {
var num_list = [1, 2, 3];
print(num_list);
}
```

**Sortie :**

```
[1, 2, 3]
```

**Exemple :**
L'exemple suivant crée une liste de longueur zéro en utilisant le constructeur
`List()`. La fonction `add()` de la classe `List` est utilisée pour ajouter
dynamiquement des éléments à la liste.

```dart
void main() {
var lst = new List();
lst.add(12);
lst.add(13);
print(lst);
}
```

**Sortie :**

```
[12, 13]
```

---

Voici un tableau complet de 20 méthodes de manipulation des listes en Dart, avec


une description et un exemple pour chaque méthode :

| **Méthode** | **Description**
| **Exemple** |
|----------------------------|-----------------------------------------------------
----------------------------|--------------------------------------|
| `List.add()` | Ajoute la valeur spécifiée à la fin de la liste.
| `list.add(5);` |
| `List.addAll()` | Ajoute tous les éléments d'une collection spécifiée
à la fin de la liste. | `list.addAll([6, 7, 8]);` |
| `List.insert()` | Insère un élément à l'index spécifié.
| `list.insert(1, 9);` |
| `List.insertAll()` | Insère tous les éléments d'une collection à l'index
spécifié. | `list.insertAll(2, [10, 11]);` |
| `List.replaceRange()` | Remplace une plage d'éléments dans la liste par de
nouveaux éléments. | `list.replaceRange(1, 3, [7, 8]);` |
| `List.remove()` | Supprime la première occurrence d'une valeur
spécifique. | `list.remove(5);` |
| `List.removeAt()` | Supprime l'élément à l'index spécifié.
| `list.removeAt(2);` |
| `List.removeLast()` | Supprime le dernier élément de la liste.
| `list.removeLast();` |
| `List.removeWhere()` | Supprime tous les éléments qui répondent à une
certaine condition. | `list.removeWhere((item) => item < 3);` |
| `List.clear()` | Supprime tous les éléments de la liste.
| `list.clear();` |
| `List.indexOf()` | Renvoie l'index de la première occurrence d'une
valeur spécifiée. | `list.indexOf(5);` |
| `List.lastIndexOf()` | Renvoie l'index de la dernière occurrence d'une
valeur spécifiée. | `list.lastIndexOf(5);` |
| `List.contains()` | Vérifie si la liste contient une valeur spécifiée.
| `list.contains(5);` |
| `List.sublist()` | Renvoie une nouvelle liste contenant une partie de
la liste originale. | `list.sublist(1, 3);` |
| `List.sort()` | Trie les éléments de la liste.
| `list.sort();` |
| `List.shuffle()` | Mélange les éléments de la liste de manière
aléatoire. | `list.shuffle();` |
| `List.reversed` | Renvoie un itérateur qui parcourt les éléments de la
liste dans l'ordre inverse. | `list.reversed;` |
| `List.asMap()` | Renvoie une vue de la liste en tant que map.
| `list.asMap();` |
| `List.fillRange()` | Remplit une plage d'éléments avec une valeur
spécifiée. | `list.fillRange(1, 3, 0);` |
| `List.setAll()` | Remplace tous les éléments de la liste à partir d'un
index spécifié. | `list.setAll(1, [4, 5, 6]);` |

### List Properties

La table suivante présente quelques propriétés couramment utilisées de la classe


`List` dans la bibliothèque `dart:core`.

| **Propriété** | **Description** |
| --- | --- |
| `first` | Renvoie le premier élément de la liste. |
| `isEmpty` | Renvoie `true` si la collection ne contient aucun élément. |
| `isNotEmpty` | Renvoie `true` si la collection contient au moins un élément. |
| `length` | Renvoie la taille de la liste. |
| `last` | Renvoie le dernier élément de la liste. |
| `reversed` | Renvoie un objet itérable contenant les valeurs de la liste dans
l'ordre inverse. |
| `single` | Vérifie si la liste ne contient qu'un seul élément et le renvoie. |

## Dart Maps: A Comprehensive Guide

Un objet `Map` est une simple collection de paires clé/valeur. Les clés et les
valeurs dans un `Map` peuvent être de n'importe quel type. Un `Map` est une
collection dynamique, ce qui signifie qu'il peut grandir et rétrécir à l'exécution.

### Déclaration des Maps

Les `Maps` peuvent être déclarés de deux manières :

1. **En utilisant les littéraux de Map**


2. **En utilisant un constructeur Map**

---

### Déclarer un Map en utilisant les Littéraux de Map

Pour déclarer un `Map` en utilisant des littéraux, vous devez inclure les paires
clé-valeur entre des accolades `{ }`.

**Syntaxe :**

```dart
var identifier = { key1: value1, key2: value2 [,….., key_n: value_n] };
```

---

### Déclarer un Map en utilisant un Constructeur Map


Pour déclarer un `Map` en utilisant un constructeur, deux étapes sont nécessaires.
Tout d'abord, déclarez le `Map`, puis initialisez-le.

**Syntaxe :**

```dart
var identifier = new Map();
```

Ensuite, utilisez la syntaxe suivante pour initialiser le `Map` :

```dart
map_name[key] = value;
```

---

### Exemples de Map

**Exemple : Map Littéral**

```dart
void main() {
var details = {'Username':'tom', 'Password':'pass@123'};
print(details);
}
```

**Sortie :**

```
{Username: tom, Password: pass@123}
```

**Exemple : Ajouter des Valeurs aux Littéraux de Map à l'Exécution**

```dart
void main() {
var details = {'Username':'tom','Password':'pass@123'};
details['Uid'] = 'U1001';
print(details);
}
```

**Sortie :**

```
{Username: tom, Password: pass@123, Uid: U1001}
```

**Exemple : Map Constructor**

```dart
void main() {
var details = new Map();
details['Username'] = 'admin';
details['Password'] = 'admin@123';
print(details);
}
```

**Sortie :**

```
{Username: admin, Password: admin@123}
```

---

### Propriétés des Maps

La classe `Map` dans le package `dart:core` définit les propriétés suivantes :

| **Propriété** | **Description**
| **Exemple** |
|----------------------------|-----------------------------------------------------
----------------------------|--------------------------------------|
| `length` | Renvoie le nombre de paires clé-valeur dans la map.
| `map.length;` |
| `isEmpty` | Renvoie `true` si la map est vide.
| `map.isEmpty;` |
| `isNotEmpty` | Renvoie `true` si la map n'est pas vide.
| `map.isNotEmpty;` |
| `keys` | Renvoie un itérable contenant toutes les clés de la
map. | `map.keys;` |
| `values` | Renvoie un itérable contenant toutes les valeurs de
la map. | `map.values;` |
| `entries` | Renvoie un itérable contenant toutes les entrées
(paires clé-valeur) de la map. | `map.entries;` |
| `hashCode` | Renvoie le code de hachage de la map.
| `map.hashCode;` |
| `runtimeType` | Renvoie le type au moment de l'exécution de la map.
| `map.runtimeType;` |
| `isEmpty` | Renvoie `true` si la map est vide.
| `map.isEmpty;` |
| `isNotEmpty` | Renvoie `true` si la map n'est pas vide.
| `map.isNotEmpty;` |

---

### Fonctions des Maps

Voici les fonctions les plus couramment utilisées pour manipuler les `Maps` en Dart
:

| **Méthode** | **Description**
| **Exemple** |
|----------------------------|-----------------------------------------------------
----------------------------|--------------------------------------|
| `addAll()` | Ajoute toutes les paires clé-valeur d'une autre map
à cette map. | `map.addAll({'key2': 'value2'});` |
| `clear()` | Supprime toutes les paires clé-valeur de la map.
| `map.clear();` |
| `containsKey()` | Vérifie si la map contient une clé spécifiée.
| `map.containsKey('key1');` |
| `containsValue()` | Vérifie si la map contient une valeur spécifiée.
| `map.containsValue('value1');` |
| `forEach()` | Applique une fonction à chaque paire clé-valeur de
la map. | `map.forEach((k, v) => print('$k: $v'));` |
| `putIfAbsent()` | Ajoute une paire clé-valeur si la clé n'existe pas
déjà dans la map. | `map.putIfAbsent('key3', () => 'value3');` |
| `remove()` | Supprime la paire clé-valeur associée à la clé
spécifiée. | `map.remove('key1');` |
| `update()` | Met à jour la valeur associée à une clé spécifiée.
| `map.update('key1', (v) => 'newValue');` |
| `updateAll()` | Met à jour toutes les valeurs de la map en utilisant
une fonction. | `map.updateAll((k, v) => 'newValue');` |
| `addEntries()` | Ajoute toutes les paires clé-valeur d'un itérable
d'entrées à cette map. | `map.addEntries([MapEntry('key4', 'value4')]);` |

---

# Les Fonctions en Dart : Guide Complet

Les fonctions sont des blocs de construction essentiels pour écrire du code
lisible, maintenable et réutilisable. Une fonction est un ensemble d'instructions
qui accomplit une tâche spécifique. Elles permettent d'organiser le programme en
blocs logiques, facilitant ainsi la réutilisation du code, la lecture, et la
maintenance.

## 1. Définition d'une Fonction

Une fonction en Dart peut être définie de plusieurs manières. Voici les principales
:

### 1.1 Fonction avec Nom (Fonction Nommée)

C'est la manière la plus courante de déclarer une fonction. Une fonction nommée a
un nom, un type de retour (facultatif), et peut prendre des paramètres.

```dart
int addition(int a, int b) {
return a + b;
}

void main() {
int resultat = addition(3, 4);
print(resultat); // Output: 7
}
```

### 1.2 Fonction Anonyme (Fonction sans Nom)

Une fonction anonyme n'a pas de nom et est souvent utilisée comme argument pour
d'autres fonctions ou pour des callbacks.

```dart
void main() {
var liste = [1, 2, 3];
liste.forEach((element) {
print(element); // Output: 1, 2, 3
});
}
```
### 1.3 Fonction Lambda (Arrow Function)

Les fonctions lambda sont des fonctions courtes et concises. Elles sont utiles pour
des opérations simples.

```dart
int carre(int x) => x * x;

void main() {
print(carre(5)); // Output: 25
}
```

## 2. Appel d'une Fonction

Pour exécuter une fonction, il faut l'appeler. L'appel d'une fonction passe les
paramètres nécessaires et récupère éventuellement un résultat.

```dart
void saluer(String nom) {
print('Bonjour, $nom!');
}

void main() {
saluer('Alice'); // Output: Bonjour, Alice!
}
```

## 3. Retour de Valeur par une Fonction

Une fonction peut renvoyer une valeur au code qui l'appelle en utilisant le mot-clé
`return`.

```dart
double division(int a, int b) {
if (b == 0) {
print('Erreur: division par zéro');
return 0.0;
}
return a / b;
}

void main() {
double resultat = division(10, 2);
print(resultat); // Output: 5.0
}
```

### 3.1 Types de Retour

Dart permet à une fonction de retourner différents types de données. Voici quelques
exemples courants :

- **Fonction retournant un entier** (`int`):


```dart
int getNombre() {
return 42;
}
```

- **Fonction retournant une chaîne** (`String`):


```dart
String getSalutation() {
return 'Hello';
}
```

- **Fonction retournant un booléen** (`bool`):


```dart
bool estPair(int nombre) {
return nombre % 2 == 0;
}
```

- **Fonction ne retournant rien** (`void`):


```dart
void afficherMessage() {
print('Ceci est un message.');
}
```

## 4. Les Paramètres de Fonction

Les fonctions peuvent accepter des paramètres, qui sont des valeurs passées à la
fonction pour être utilisées dans ses calculs. Dart supporte plusieurs types de
paramètres :

### 4.1 Paramètres Positionnels

Les paramètres sont passés selon leur position dans l'appel de la fonction.

```dart
void afficherInfos(String nom, int age) {
print('Nom: $nom, Âge: $age');
}

void main() {
afficherInfos('Bob', 25); // Output: Nom: Bob, Âge: 25
}
```

### 4.2 Paramètres Només

Les paramètres nommés permettent de passer des valeurs aux paramètres par leur nom,
ce qui rend l'appel de la fonction plus lisible.

```dart
void afficherInfos({required String nom, required int age}) {
print('Nom: $nom, Âge: $age');
}

void main() {
afficherInfos(nom: 'Bob', age: 25); // Output: Nom: Bob, Âge: 25
}
```

### 4.3 Paramètres Optionnels avec Valeurs par Défaut


Les paramètres optionnels peuvent être laissés de côté lors de l'appel de la
fonction. On peut aussi définir des valeurs par défaut pour ces paramètres.

```dart
void afficherInfos(String nom, {int age = 30}) {
print('Nom: $nom, Âge: $age');
}

void main() {
afficherInfos('Alice'); // Output: Nom: Alice, Âge: 30
afficherInfos('Bob', age: 40); // Output: Nom: Bob, Âge: 40
}
```

### 4.4 Paramètres Optionnels Positionnels

Les paramètres positionnels peuvent également être optionnels, en les plaçant entre
crochets `[]`.

```dart
void afficherInfos(String nom, [int? age]) {
if (age != null) {
print('Nom: $nom, Âge: $age');
} else {
print('Nom: $nom');
}
}

void main() {
afficherInfos('Alice'); // Output: Nom: Alice
afficherInfos('Bob', 40); // Output: Nom: Bob, Âge: 40
}
```

## 5. Fonctions Récursives

La récursion est une technique où une fonction s'appelle elle-même pour résoudre un
problème en plusieurs étapes.

```dart
int factorielle(int n) {
if (n <= 1) return 1;
return n * factorielle(n - 1);
}

void main() {
print(factorielle(5)); // Output: 120
}
```

## 6. Fonctions Lambda

Les fonctions lambda, également appelées fonctions fléchées, sont une manière
concise de définir des fonctions simples.

```dart
void main() {
var liste = [1, 2, 3];
var listeCarree = liste.map((e) => e * e).toList();
print(listeCarree); // Output: [1, 4, 9]
}
```

---

**Conclusion**
Les fonctions en Dart sont un outil puissant pour structurer et réutiliser du code.
Elles permettent de diviser un programme en blocs logiques, facilitant ainsi la
lecture, la maintenance, et la réutilisation du code. Comprendre les différentes
manières de déclarer et d'utiliser des fonctions en Dart est essentiel pour tout
développeur souhaitant écrire du code efficace et propre.

You might also like