Compare commits

...

10 Commits

Author SHA1 Message Date
40cd963202 uml 2024-01-21 16:40:11 +01:00
d2ffcf8c9a Synthèse os 2024-01-18 15:46:08 +01:00
a66a649b48 exam modal dev aout 2023 2024-01-14 10:00:35 +01:00
df9e43e534 chap4 2023-12-21 23:39:21 +01:00
babed7eb09 chap3 2023-12-21 23:36:03 +01:00
990b77ed18 Adding reference to the uml 2.0 reference 2023-11-21 15:40:17 +01:00
025b0e2166 useCase prototype 2023-11-20 19:11:26 +01:00
c4e193e45f use case diagram 2023-11-17 16:10:39 +01:00
3b2f4c84d7 Merge remote-tracking branch 'refs/remotes/origin/bac2' into bac2 2023-11-08 09:43:08 +01:00
58acfde2b4 chap3 2023-11-08 09:42:46 +01:00
82 changed files with 12996 additions and 6 deletions

View File

@ -0,0 +1,9 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# Linux start script should use lf
/gradlew text eol=lf
# These are Windows script files and should use crlf
*.bat text eol=crlf

View File

@ -0,0 +1,5 @@
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>question1</name>
<comment>Project question1 created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1705161555233</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -0,0 +1,13 @@
arguments=--init-script /home/tonitch/.dotfiles/vim/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/workspace/config_linux/org.eclipse.osgi/55/0/.cp/gradle/init/init.gradle
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=/usr/lib/jvm/java-21-openjdk
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/resources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>app</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1705162039553</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -0,0 +1,13 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=..
eclipse.preferences.version=1
gradle.user.home=
java.home=
jvm.arguments=
offline.mode=false
override.workspace.settings=false
show.console.view=false
show.executions.view=false

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=21
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=21

View File

@ -0,0 +1,44 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.5/userguide/building_java_projects.html in the Gradle documentation.
*/
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
application
eclipse
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation(libs.junit.jupiter)
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
// This dependency is used by the application.
implementation(libs.guava)
}
// Apply a specific Java toolchain to ease working on different environments.
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
application {
// Define the main class for the application.
mainClass.set("question1.App")
}
tasks.named<Test>("test") {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}

View File

@ -0,0 +1,14 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package question1;
public class App {
public String getGreeting() {
return "Hello World!";
}
public static void main(String[] args) {
System.out.println(new App().getGreeting());
}
}

View File

@ -0,0 +1,49 @@
package question1;
import java.util.HashMap;
public class InventoryManagement {
// cnt[zone][product] = quantity
HashMap<Integer, HashMap<Integer, Integer>> cnt = new HashMap<>();
// ajoute dans une zone du stock une quantité donnée dun produit donné
void replenish(int product, int quantity, int destination_zone) throws ZoneFullException{
cnt.putIfAbsent(destination_zone, new HashMap<>());
cnt.get(destination_zone).putIfAbsent(product, 0);
Integer q = cnt.get(destination_zone).get(product) + quantity;
if(q > 100)
throw new ZoneFullException();
cnt.get(destination_zone).put(product, q);
}
// retire dune zone spécifique du stock une quantité donnée dun produit donné pour lenvoyer vers le réseau de distribution
void distribute(int product, int source_zone, int quantity) throws StockOutException{
cnt.putIfAbsent(source_zone, new HashMap<>());
cnt.get(source_zone).putIfAbsent(product, 0);
Integer q = cnt.get(source_zone).get(product) - quantity;
if(q < 0)
throw new StockOutException();
cnt.get(source_zone).put(product, q);
}
// déplace une quantité donnée dun produit vers une autre zone
void move(int product, int quantity, int source_zone, int destination_zone) throws StockOutException, ZoneFullException {
distribute(product, source_zone, quantity);
try {
replenish(product, quantity, destination_zone);
}catch(ZoneFullException e){
replenish(product, quantity, source_zone);
throw e;
}
}
// retourne la quantité disponible dun produit donné dans le stock, toutes zones confondues
int quantity(int product){
int sum[] = {0};
cnt.forEach((key, value) -> {
sum[0] += value.getOrDefault(product, 0);
});
return sum[0];
}
}

View File

@ -0,0 +1,6 @@
package question1;
public class StockOutException extends Exception{
}

View File

@ -0,0 +1,4 @@
package question1;
public class ZoneFullException extends Exception {}

View File

@ -0,0 +1,14 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package question1;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AppTest {
@Test void appHasAGreeting() {
App classUnderTest = new App();
assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
}
}

View File

@ -0,0 +1,55 @@
package question1;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
public class InventoryManagementTest {
@Test
public void testExceptions() throws Exception {
InventoryManagement iv = new InventoryManagement();
iv.replenish(0, 10, 0);
assertThrows(ZoneFullException.class, () -> iv.replenish(0, 96, 0));
}
@Test
public void testExceptions2() throws Exception {
InventoryManagement iv = new InventoryManagement();
assertThrows(StockOutException.class, () -> iv.distribute(0, 0, 92));
}
@Test
public void testQuantity() throws Exception {
InventoryManagement iv = new InventoryManagement();
iv.replenish(2, 42, 0);
iv.replenish(2, 21, 1);
iv.replenish(2, 0, 3);
assertEquals(63, iv.quantity(2));
}
@Test
public void testMove() throws Exception {
InventoryManagement iv = new InventoryManagement();
iv.replenish(42, 50, 1);
iv.move(42, 21, 1, 2);
assertEquals(50, iv.quantity(42));
}
@Test
public void testFailure() throws Exception {
InventoryManagement iv = new InventoryManagement();
iv.replenish(42, 50, 1);
iv.replenish(42, 50, 2);
assertEquals(5050, iv.quantity(42)); // Should return a Failure
}
@Test
public void testError() throws Exception {
InventoryManagement iv = new InventoryManagement();
iv.replenish(42, 100, 1);
iv.replenish(42, 1, 1); // Should create an error
}
}

View File

@ -0,0 +1,10 @@
# This file was generated by the Gradle 'init' task.
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
[versions]
guava = "32.1.2-jre"
junit-jupiter = "5.10.0"
[libraries]
guava = { module = "com.google.guava:guava", version.ref = "guava" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }

Binary file not shown.

View File

@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

249
bac2/modalDev/e23/question1/gradlew vendored Executable file
View File

@ -0,0 +1,249 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

92
bac2/modalDev/e23/question1/gradlew.bat vendored Normal file
View File

@ -0,0 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,14 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
* For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.5/userguide/building_swift_projects.html in the Gradle documentation.
*/
plugins {
// Apply the foojay-resolver plugin to allow automatic download of JDKs
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}
rootProject.name = "question1"
include("app")

9
bac2/modalDev/tp1/.gitattributes vendored Normal file
View File

@ -0,0 +1,9 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# Linux start script should use lf
/gradlew text eol=lf
# These are Windows script files and should use crlf
*.bat text eol=crlf

5
bac2/modalDev/tp1/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>tp1</name>
<comment>Project tp1 created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1701330804548</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -0,0 +1,13 @@
arguments=--init-script /home/tonitch/.dotfiles/vim/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/workspace/config_linux/org.eclipse.osgi/51/0/.cp/gradle/init/init.gradle
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=app
eclipse.preferences.version=1
gradle.user.home=
java.home=/usr/lib/jvm/java-17-openjdk
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true

BIN
bac2/modalDev/tp1/TP1.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,12 @@
# TP's Answer
## Exercice 2.1
1)
test1) ❎ devrais fail car $ E1 \neq E2 $
test2) ✅
test3) ❎ shoud throw an error (no real number)
2-4) dans fichiers
## Exercice 2.2

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/resources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>app</name>
<comment>Project app created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1701330804524</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -0,0 +1,13 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=
jvm.arguments=
offline.mode=false
override.workspace.settings=false
show.console.view=false
show.executions.view=false

View File

@ -0,0 +1,32 @@
package tp1.ex2_1;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
/**
* Suite de tests pour vérifier la méthode sqrt dans la classe Sqrt
*/
public class SolveEquationTest {
@Test
public void test1() {
SolveEquation se = new SolveEquation(1.0, -2.0, -3.0);
assertEquals(se.getNbSolutions(), 2);
assertTrue(se.getSolutions().getE1()
.equals(se.getSolutions().getE2()));
}
@Test
public void test2() {
double epsilon = 0.0001;
SolveEquation se = new SolveEquation(1.0, 0.0, 0.0);
assertEquals(se.getSolutions().getE1(),
se.getSolutions().getE2(), epsilon);
assertEquals(se.getNbSolutions(), 1);
}
@Test
public void test3() {
SolveEquation se = new SolveEquation(5.0, 0.0, 3.0);
assertEquals(se.getSolutions().getE1(), se.getSolutions().getE2());
}
}

View File

@ -0,0 +1,45 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.4/userguide/building_java_projects.html in the Gradle documentation.
*/
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
application
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation("org.junit.jupiter:junit-jupiter:5.9.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
// This dependency is used by the application.
implementation("com.google.guava:guava:32.1.1-jre")
implementation("org.mockito:mockito-core:5.7.0")
}
// Apply a specific Java toolchain to ease working on different environments.
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
application {
// Define the main class for the application.
mainClass.set("tp1.App")
}
tasks.named<Test>("test") {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}

View File

@ -0,0 +1,15 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package tp1;
public class App {
// for the sake of showing an example of testing
public String getGreeting() {
return "Hello World!";
}
public static void main(String[] args) {
System.out.println(new App().getGreeting());
}
}

View File

@ -0,0 +1,27 @@
package tp1.ex2_1;
public class Pair<T> {
private T e1, e2;
public Pair(T e1, T e2) {
this.e1 = e1;
this.e2 = e2;
}
public T getE1() {
return e1;
}
public T getE2() {
return e2;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Pair) {
Pair<?> p = (Pair<?>) obj;
return e1.equals(p.e1) && e2.equals(p.e2);
}
return false;
}
}

View File

@ -0,0 +1,53 @@
package tp1.ex2_1;
public class SolveEquation {
private double a, b, c;
public SolveEquation(double a, double b, double c) {
this.a = a;
this.b = b;
this.c = c;
}
/*
* Gives the number of solutions of the equation .
*
* @return the number of solution .
*
* @throws ArithmeticException if there
* is an infinite number of solutions .
*/
public int getNbSolutions() throws ArithmeticException {
double delta = b * b - 4 * a * c;
if (delta < 0)
throw new ArithmeticException("No real solution");
else if (delta == 0)
return 1;
else
return 2;
}
/*
* * Gives the equation s solutions for x .
*
* @return the 2 solutions of the equation . If there is
* only 1 solution , the 2 members of the pair are equal .
*
* @throws ArithmeticException if there is no real
* solution for x , or if there is an infinite number
* of solutions .
*/
public Pair<Double> getSolutions() throws ArithmeticException {
double delta = b * b - 4 * a * c;
if (delta < 0)
throw new ArithmeticException("No real solution");
else if (delta == 0) {
double x = -b / (2 * a);
return new Pair<Double>(x, x);
}
else
return new Pair<Double>(
(-b - Math.sqrt(delta)) / (2 * a),
(-b + Math.sqrt(delta)) / (2 * a));
}
}

View File

@ -0,0 +1,40 @@
package tp1.ex2_2;
import java.lang.Math;
/**
* Calcule la racine carrée d'un nombre positif
*/
public class Sqrt
{
public static final double EPSILON = 1e-8;
/**
* Cacule la racine carrée d'un nombre positif en utilisant la méhtode
* de Newton.
* Il s'agit de calculer la racine de l'équation x^2-b=0 avec b
* le nombre dont on veut la racine carrée.
* La méthode de Newton consiste à utiliser la formule suivante :
* x_i = x_(i-1) - f(x_(i-1)) / f'(x_(i-1)).
* @param val La valeur dont on cherche la racine carrée (val >= 0)
* @return La racine carrée de val avec une précision de 1e-12.
* @throws IllegalArgumentException Si val < 0
*/
public static double sqrt(double val) throws IllegalArgumentException
{
if(val < 0)
throw new IllegalArgumentException("ne peut pas être négatif");
if(val == 0 || val == 1)
return val;
double curr = nextIteration(val, val);
while(Math.abs(val - Math.pow(curr, 2)) > EPSILON){
curr = nextIteration(val, curr);
}
return curr;
}
private static double nextIteration(double val, double curr){
return (curr + (val / curr))/2;
}
}

View File

@ -0,0 +1,19 @@
package tp1.ex2_3;
public class Fibonacci {
public static int fibo(int n) throws IllegalArgumentException {
if (n < 0) {
throw new IllegalArgumentException();
} else {
int f_n_1 = 1;
int f_n = 0;
int tmp;
for (int i = 0; i < n; i++) {
tmp = f_n;
f_n = f_n + f_n_1;
f_n_1 = tmp;
}
return f_n;
}
}
}

View File

@ -0,0 +1,14 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package tp1;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AppTest {
@Test void appHasAGreeting() {
App classUnderTest = new App();
assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
}
}

View File

@ -0,0 +1,38 @@
package tp1.ex2_1;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
/**
* Suite de tests pour vérifier la méthode sqrt dans la classe Sqrt
*/
public class SolveEquationTest {
@Test
public void test1() {
SolveEquation se = new SolveEquation(1.0, -2.0, -3.0);
assertEquals(se.getNbSolutions(), 2);
assertFalse(se.getSolutions().getE1()
.equals(se.getSolutions().getE2()));
}
@Test
public void test2() {
double epsilon = 0.0001;
SolveEquation se = new SolveEquation(1.0, 0.0, 0.0);
assertEquals(se.getSolutions().getE1(),
se.getSolutions().getE2(), epsilon);
assertEquals(se.getNbSolutions(), 1);
}
@Test
public void test3() {
SolveEquation se = new SolveEquation(5.0, 0.0, 3.0);
assertThrows(ArithmeticException.class, () -> se.getSolutions(), "No real solution");
}
@Test
public void test4(){
SolveEquation se = new SolveEquation(3, 0, 0);
assertEquals(se.getNbSolutions(), 1);
}
}

View File

@ -0,0 +1,32 @@
package tp1.ex2_1;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
/**
* Suite de tests pour vérifier la méthode sqrt dans la classe Sqrt
*/
public class SolveEquationTest {
@Test
public void test1() {
SolveEquation se = new SolveEquation(1.0, -2.0, -3.0);
assertEquals(se.getNbSolutions(), 2);
assertTrue(se.getSolutions().getE1()
.equals(se.getSolutions().getE2()));
}
@Test
public void test2() {
double epsilon = 0.0001;
SolveEquation se = new SolveEquation(1.0, 0.0, 0.0);
assertEquals(se.getSolutions().getE1(),
se.getSolutions().getE2(), epsilon);
assertEquals(se.getNbSolutions(), 1);
}
@Test
public void test3() {
SolveEquation se = new SolveEquation(5.0, 0.0, 3.0);
assertEquals(se.getSolutions().getE1(), se.getSolutions().getE2());
}
}

View File

@ -0,0 +1,49 @@
package tp1.ex2_2;
import static org.junit.jupiter.api.Assertions.*;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/**
* Suite de tests pour vérifier la méthode sqrt dans la classe Sqrt
*/
public class SqrtTest {
@Test
public void testSortie(){
assertTrue(Sqrt.sqrt(42) >= 0);
}
@Test
public void testprecision(){
assertEquals(Math.sqrt(16), Sqrt.sqrt(16), Sqrt.EPSILON);
}
@Test
public void testValidInput(){
double t1 = Sqrt.sqrt(0.4);
assertTrue(t1 > 0 && t1 < 1);
double t2 = Sqrt.sqrt(21);
assertTrue(t2 > 1);
}
@Test
public void testBorne(){
assertEquals(0, Sqrt.sqrt(0));
assertEquals(1, Sqrt.sqrt(1));
}
@Test
public void testBig(){
double val = assertTimeoutPreemptively(Duration.ofSeconds(1), () -> Sqrt.sqrt(1e16));
assertEquals(Math.sqrt(1e16), val, Sqrt.EPSILON);
}
@Test
public void testInvalid(){
assertThrows(IllegalArgumentException.class, () -> Sqrt.sqrt(-42));
}
}

View File

@ -0,0 +1,21 @@
package tp1.ex2_3;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class FibonacciTest {
@Test
void test1() {
assertEquals(2, Fibonacci.fibo(2));
}
@Test void test2() {
assertTrue(Fibonacci.fibo(-2) >= 0);
}
@Test void test3() {
assertTrue(Fibonacci.fibo(4) == 3);
}
}

Binary file not shown.

View File

@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

249
bac2/modalDev/tp1/gradlew vendored Executable file
View File

@ -0,0 +1,249 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

92
bac2/modalDev/tp1/gradlew.bat vendored Normal file
View File

@ -0,0 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,14 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
* For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.4/userguide/building_swift_projects.html in the Gradle documentation.
*/
plugins {
// Apply the foojay-resolver plugin to allow automatic download of JDKs
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}
rootProject.name = "tp1"
include("app")

View File

@ -2,19 +2,27 @@
CC = gcc
CFLAGS = -g -Wall
all: ex1
SRC = ex1 ex2 ex3 ex4 ex5 ex6 ex7 group
all: $(SRC)
group: group.o mergeSort.o
$(CC) $(CFLAGS) -o $@ $+
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
ex1: ex1.o
%: %.o
$(CC) $(CFLAGS) -o $@ $+
clean:
rm -f *.o core.*
rm -f plot.png
rm -f $(SRC)
mrproper: clean
rm -f ex1
run: ex1
run: group
./$<
graph: run
graph -Tpng plot > plot.png
nsxiv plot.png

14
bac2/os/chap3/ex2.c Normal file
View File

@ -0,0 +1,14 @@
#include <unistd.h>
#include <stdio.h>
#define printvi(X) printf("%s = %d\n", #X, X);
int main(void)
{
printvi(getpid());
pid_t f = fork();
if(f != 0)
getchar();
}

25
bac2/os/chap3/ex3.c Normal file
View File

@ -0,0 +1,25 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#define printvi(X) printf("%s = %d\n", #X, X);
int main(void)
{
pid_t f = fork();
if(f == 0){
srand(time(NULL));
int delay = 1 + rand() % 10;
int value = rand() % 256;
printvi(delay);
printvi(value);
sleep(delay);
return value;
}
int child_ret = 0;
wait(&child_ret);
printvi(WEXITSTATUS(child_ret));
}

29
bac2/os/chap3/ex4.c Normal file
View File

@ -0,0 +1,29 @@
#include <sys/time.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#define printvi(X) printf("%s = %d\n", #X, X);
#define printvf(X) printf("%s = %lld\n", #X, X);
typedef struct timespec timespec_t;
timespec_t start, end;
long long int dtime(timespec_t *start, timespec_t *end){
return (end->tv_sec - start->tv_sec) * 1e9 + end->tv_nsec - start->tv_nsec;
}
int main(void)
{
FILE* fd = fopen("plot", "w");
long long int time, time_sum;
for (int i = 0; i < 10000; ++i) {
clock_gettime(CLOCK_REALTIME, &start);
usleep(1);
clock_gettime(CLOCK_REALTIME, &end);
time = dtime(&start, &end);
time_sum += time;
fprintf(fd, "%d %lld\n", i, time);
}
}

29
bac2/os/chap3/ex5.c Normal file
View File

@ -0,0 +1,29 @@
#include <sys/time.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#define printvi(X) printf("%s = %d\n", #X, X);
#define printvf(X) printf("%s = %lld\n", #X, X);
typedef struct timespec timespec_t;
timespec_t start, end, s = {0, 1};
long long int dtime(timespec_t *start, timespec_t *end){
return (end->tv_sec - start->tv_sec) * 1e9 + end->tv_nsec - start->tv_nsec;
}
int main(void)
{
FILE* fd = fopen("plot", "w");
long long int time, time_sum;
for (int i = 0; i < 10000; ++i) {
clock_gettime(CLOCK_REALTIME, &start);
nanosleep(&s, NULL);
clock_gettime(CLOCK_REALTIME, &end);
time = dtime(&start, &end);
time_sum += time;
fprintf(fd, "%d %lld\n", i, time);
}
}

44
bac2/os/chap3/ex6.c Normal file
View File

@ -0,0 +1,44 @@
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#define THREADS 9
int cmp(const void * first, const void *second){
return (*(int*)first) - (*(int*)second);
}
void* threaded(){
int delay = rand() % 6;
int value = rand() % 256;
int *ret = malloc(sizeof(int));
*ret = value;
sleep(delay);
return ret;
}
int main(void)
{
srand(time(NULL));
pthread_t threads[THREADS];
int returned[THREADS];
for (int i = 0; i < THREADS; ++i) {
pthread_create(threads+i, NULL, threaded, NULL);
}
int *ret= NULL;
for (int i = 0; i < THREADS; ++i) {
pthread_join(threads[i], (void*)&ret);
returned[i] = *ret;
}
qsort((void* ) returned, THREADS, sizeof(int), cmp);
for (int i = 0; i < THREADS; ++i) {
printf("%d\n", returned[i]);
}
return 0;
}

6
bac2/os/chap3/ex7.c Normal file
View File

@ -0,0 +1,6 @@
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
}

24
bac2/os/chap3/group.c Normal file
View File

@ -0,0 +1,24 @@
#include "mergeSort.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define printlist(s, x) printf("%s = [", #x); for (int i = 0; i < s; ++i) { printf("%d, ", x[i]); } printf("\b\b]\n");
#define listSize 1000000
int list[listSize];
int main(void)
{
// liste de nombre aléatoires
srand(time(NULL));
for (int i = 0; i < listSize; ++i) {
list[i] = rand()%listSize;
}
/* printlist(listSize, list); */
mrg_t args = merge_init(list, listSize);
merge_sort(&args);
printlist(listSize, list);
}

View File

@ -0,0 +1,18 @@
.PHONY: clean, all
CC = gcc
CFLAGS = -g -Wall
all: group
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
group: group.o mergeSort.o
$(CC) $(CFLAGS) -o $@ $+ $(LDFLAGS)
clean:
rm -f *.o core.*
rm -f group
run: group
./$<

View File

@ -0,0 +1,24 @@
#include "mergeSort.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define printlist(s, x) printf("%s = [", #x); for (int i = 0; i < s; ++i) { printf("%d, ", x[i]); } printf("\b\b]\n");
#define listSize 1000000
int list[listSize];
int main(void)
{
// liste de nombre aléatoires
srand(time(NULL));
for (int i = 0; i < listSize; ++i) {
list[i] = rand()%listSize;
}
/* printlist(listSize, list); */
mrg_t args = merge_init(list, listSize);
merge_sort(&args);
printlist(listSize, list);
}

View File

@ -0,0 +1,58 @@
#include "mergeSort.h"
#include <stdlib.h>
#include <assert.h>
#include <pthread.h>
void* merge_sort(void* args) {
mrg_t* f = (mrg_t*) args;
if(f->slice.start < f->slice.final) {
int middle = (f->slice.start + f->slice.final) / 2;
mrg_t args1 = {f->array, f->_depth+1, {f->slice.start, middle}};
mrg_t args2 = {f->array, f->_depth+1, { middle+1, f->slice.final}};
if(f->_depth * f->_depth < THREADS){
pthread_t t1, t2;
assert(!pthread_create(&t1, NULL, merge_sort, (void*) &args1));
assert(!pthread_create(&t2, NULL, merge_sort, (void*) &args2));
assert(!pthread_join(t1, NULL));
assert(!pthread_join(t2, NULL));
}else{
merge_sort((void*) &args1);
merge_sort((void*) &args2);
}
merge(f->array, f->slice.start, middle, f->slice.final);
}
return NULL;
}
void merge(int array[], uint8_t start, uint8_t middle, uint8_t final) {
uint8_t countL = middle - start + 1;
int *arrayL = malloc(countL * sizeof(int));
for(uint8_t currentL = 0; currentL < countL; currentL ++)
arrayL[currentL] = array[start + currentL ];
uint8_t countR = final - middle;
int* arrayR = malloc(countR * sizeof(int));
for(uint8_t currentR = 0; currentR < countR; currentR ++)
arrayR[currentR] = array[middle + 1 + currentR ];
uint8_t currentL, currentR, current;
for(currentL = 0, currentR = 0, current = start;
current <= final && currentL < countL && currentR < countR;
current ++)
if(arrayL[currentL] <= arrayR[currentR])
array[current] = arrayL[currentL++];
else
array[current] = arrayR[currentR++];
while(currentR < countR)
array[current++] = arrayR[currentR++];
while(currentL < countL)
array[current++] = arrayL[currentL++];
free(arrayL);
free(arrayR);
}

View File

@ -0,0 +1,21 @@
#pragma once
#include <pthread.h>
#include <inttypes.h>
#define THREADS 4
#define merge_init(array, size) {(array), 0, {1, (size)}}
typedef struct{
int start;
int final;
} SLICE;
typedef struct {
int* array;
int _depth;
SLICE slice;
} mrg_t;
void* merge_sort(void*);
void merge(int array[], uint8_t start, uint8_t middle, uint8_t final);

58
bac2/os/chap3/mergeSort.c Normal file
View File

@ -0,0 +1,58 @@
#include "mergeSort.h"
#include <stdlib.h>
#include <assert.h>
#include <pthread.h>
void* merge_sort(void* args) {
mrg_t* f = (mrg_t*) args;
if(f->slice.start < f->slice.final) {
int middle = (f->slice.start + f->slice.final) / 2;
mrg_t args1 = {f->array, f->_depth+1, {f->slice.start, middle}};
mrg_t args2 = {f->array, f->_depth+1, { middle+1, f->slice.final}};
if(f->_depth * f->_depth < THREADS){
pthread_t t1, t2;
assert(!pthread_create(&t1, NULL, merge_sort, (void*) &args1));
assert(!pthread_create(&t2, NULL, merge_sort, (void*) &args2));
assert(!pthread_join(t1, NULL));
assert(!pthread_join(t2, NULL));
}else{
merge_sort((void*) &args1);
merge_sort((void*) &args2);
}
merge(f->array, f->slice.start, middle, f->slice.final);
}
return NULL;
}
void merge(int array[], uint8_t start, uint8_t middle, uint8_t final) {
uint8_t countL = middle - start + 1;
int *arrayL = malloc(countL * sizeof(int));
for(uint8_t currentL = 0; currentL < countL; currentL ++)
arrayL[currentL] = array[start + currentL ];
uint8_t countR = final - middle;
int* arrayR = malloc(countR * sizeof(int));
for(uint8_t currentR = 0; currentR < countR; currentR ++)
arrayR[currentR] = array[middle + 1 + currentR ];
uint8_t currentL, currentR, current;
for(currentL = 0, currentR = 0, current = start;
current <= final && currentL < countL && currentR < countR;
current ++)
if(arrayL[currentL] <= arrayR[currentR])
array[current] = arrayL[currentL++];
else
array[current] = arrayR[currentR++];
while(currentR < countR)
array[current++] = arrayR[currentR++];
while(currentL < countL)
array[current++] = arrayL[currentL++];
free(arrayL);
free(arrayR);
}

21
bac2/os/chap3/mergeSort.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include <pthread.h>
#include <inttypes.h>
#define THREADS 4
#define merge_init(array, size) {(array), 0, {1, (size)}}
typedef struct{
int start;
int final;
} SLICE;
typedef struct {
int* array;
int _depth;
SLICE slice;
} mrg_t;
void* merge_sort(void*);
void merge(int array[], uint8_t start, uint8_t middle, uint8_t final);

10000
bac2/os/chap3/plot Normal file

File diff suppressed because it is too large Load Diff

27
bac2/os/chap4/Makefile Normal file
View File

@ -0,0 +1,27 @@
.PHONY: clean, mrproper, run
CC = gcc
CFLAGS = -g -Wall
exos = ex4 group
all: $(exos)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
ex1: ex1.o RingBuffer.o
$(CC) $(CFLAGS) -o $@ $+
ex%: ex%.o
$(CC) $(CFLAGS) -o $@ $+
group: group.o
$(CC) $(CFLAGS) -o $@ $+
clean:
rm -f *.o core.*
rm -f out group
rm -f ${exos}
run: group
./$<

View File

@ -0,0 +1,20 @@
#include "RingBuffer.h"
void rb_push(rb_t* rb, int el){
if(rb->filled)
return;
rb->data[rb->w_pos] = el;
rb->w_pos = (rb->w_pos + 1) % rb->size;
if(rb->w_pos == rb->r_pos)
rb->filled = true;
}
int rb_pop(rb_t* rb){
if(rb->w_pos == rb->r_pos && !rb->filled){
rb->error = true;
return 0;
}
int ret = rb->data[rb->r_pos];
rb->r_pos = (rb->r_pos + 1) % rb->size;
rb->filled = false;
return ret;
}

View File

@ -0,0 +1,27 @@
#pragma once
#include <pthread.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#define rb_init(size, type)\
{(size),\
0, 0, false, false,\
type,\
malloc(sizeof(int)*(size)),\
PTHREAD_MUTEX_INITIALIZER};
#define rb_free(rb) free(rb.data)
typedef struct rb{
size_t size;
size_t w_pos, r_pos;
bool filled;
bool error;
enum {DROP, WAIT} type;
int* data;
pthread_mutex_t m;
} rb_t;
void rb_push(rb_t*, int);
int rb_pop(rb_t*);

46
bac2/os/chap4/ex1.c Normal file
View File

@ -0,0 +1,46 @@
#include "RingBuffer.h"
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#define THREADS 10
void* process(void* args);
int main(void)
{
srand(time(NULL));
rb_t rb = rb_init(50, DROP);
pthread_t threads[THREADS];
int even, odd = {0};
for (int i = 0; i < THREADS; ++i) {
pthread_create(threads+i, NULL, process, (void*) &rb);
}
int val;
while(true){
usleep(250);
val = rb_pop(&rb);
printf("got -> %d\n", val);
if(val % 2)
odd++;
else
even++;
printf("%d nombres pairs et %d nombre impairs\n", even, odd);
}
rb_free(rb);
}
void* process(void* args){
rb_t *rb = (rb_t*) args;
while(true){
usleep((rand() % 4500) + 500);
rb_push(rb, rand());
}
}

46
bac2/os/chap4/ex2.c Normal file
View File

@ -0,0 +1,46 @@
#include "RingBuffer.h"
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#define THREADS 10
void* process(void* args);
int main(void)
{
srand(time(NULL));
rb_t rb = rb_init(50, WAIT);
pthread_t threads[THREADS];
int even, odd = {0};
for (int i = 0; i < THREADS; ++i) {
pthread_create(threads+i, NULL, process, (void*) &rb);
}
int val;
while(true){
usleep(250);
val = rb_pop(&rb);
printf("got -> %d\n", val);
if(val % 2)
odd++;
else
even++;
printf("%d nombres pairs et %d nombre impairs\n", even, odd);
}
rb_free(rb);
}
void* process(void* args){
rb_t *rb = (rb_t*) args;
while(true){
usleep((rand() % 4500) + 500);
rb_push(rb, rand());
}
}

34
bac2/os/chap4/ex4.c Normal file
View File

@ -0,0 +1,34 @@
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#define SIZE 32768
pthread_t child_thread;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int table[SIZE];
int cmp(const void* a1, const void* a2){
return *((int*)a2) - *((int*)a1);
}
void* child(void* args){
pthread_mutex_lock(&mutex);
for (int i = 0; i < SIZE; ++i) {
table[i] = rand();
}
pthread_mutex_unlock(&mutex);
sleep(1);
pthread_mutex_lock(&mutex);
return NULL;
}
int main(void)
{
pthread_create(&child_thread, NULL, child, NULL);
pthread_mutex_lock(&mutex);
qsort(table, SIZE, sizeof(int), cmp);
pthread_mutex_unlock(&mutex);
}

45
bac2/os/chap4/group.c Normal file
View File

@ -0,0 +1,45 @@
/***************************************************************************
* Le dinner des philosophes *
* Two phase locking: *
* - array de baguettes *
* - manger(): tente l'acquisition des deux. attente passive si non dispo *
****************************************************************************/
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#define TABLE_SIZE 5
#define RIGHT(x) ((x)) % TABLE_SIZE
#define LEFT(x) ((x)+1) % TABLE_SIZE
typedef unsigned int PHILOSOPHE; // philosophe's id in the table
pthread_mutex_t baguettes[TABLE_SIZE], tableLock;
int main(void)
{
}
void penser(){
usleep(100 + rand() % 500);
}
void manger(){
usleep(100 + rand() % 500);
}
void prendre(){
}
void deposer(){
}
void* thread_philosophe(void* arg){
while(42){
penser();
prendre();
manger();
deposer();
}
}

View File

@ -0,0 +1,11 @@
#ifndef PHILOSOPHES_H
#define PHILOSOPHES_H
#ifndef PHILOSPHES_IMPLEMENTATION
#endif /* end of implementation */
#endif /* end of include guard: PHILOSOPHES_H */

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

View File

@ -0,0 +1,389 @@
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepackage{graphicx}
\usepackage{amsmath, amsfonts, amssymb, amsthm}
\title{Synthèse Système d'éxploitation}
\author{Debucquoy Anthony}
\begin{document}
\maketitle
\tableofcontents
\newpage
Ce document est une synthèse du cours de système d'exploitation. Il n'est pas complet et ne
peut pas se substituer à une lecture du document originale. Il permet toutefois de lister les
diffèrents points et d'y accompagner une brève explication.
\section{Events}
Un programme est composé:
\begin{itemize}
\item \textbf{Du code machine}: exécuté par la machine
\item \textbf{D'un espace de données}: Stock les données statiques et dynamiques
\item \textbf{D'une stack}: Stoque les variables locales et les appels
\end{itemize}
Ces composants se trouvent dans un "espace d'adresssage" commun et sont liés logiquements par le
biais d'appels (lw, j, ...)
\begin{figure}[h]
\centering
\includegraphics[width=0.8\textwidth]{prog_components.png}
\caption{Composents d'un programme}
\end{figure}
Lors de l'éxécution, les composents sont placés dans la mémoire afin d'y être accésible par le processeur.
L'entièretée d'un programme est alors définie par 4 éléments:
\begin{enumerate}
\item La valeur des registres
\item le contenu de la stack (et le pointeur vers son sommet)
\item L'espaces de données utilisés
\item L'IP (instruction pointer)
\end{enumerate}
Nous pouvons alors sauvegarder l'état (instantané) du programme.
\subsection{Gestion d'évènements}
Nous distingons 2 types d'évènements traités par le processeur:
\begin{enumerate}
\item erreur / exceptions: ayant une origine \textbf{interne} au processeur
ex: division par zero, op-code invalide, right-fault, ...
\item evènement / interuptions: ayant une origine \textbf{externe} au processeur
ex: clavier, fichier pret, packet, clk, ...
\end{enumerate}
Suite à ces évènements, le programme sera mis en pause pour pouvoir traiter l'évènement. Puis
le programme pourra (ou non) reprendre son cours. Dans le cas d'un évènement \textbf{récupérable},
le programme continue. Dans l'un cas d'un évènement \textbf{irécupérable}, le programme s'arrète.
Pour que le programme puisse poursuivre, il faut sauvegarder son contexte. cette "snapshot" est
placée sur la stack. (cette stack peut basculer vers une autre pendant l'évènement pour éviter
de laisser la posibilitée au programme de récupérer des informations sur l'évent sans autorisation).
Cette sauvegarde sert à la fois pour les programmes récupérable pour la reprise/poursuite mais également
pour les programmes irécupérables, ces informations sont utiles au dévelopeur pour le debug de l'app.
Il est également nécéssaire de libèrer les resources aloués.
\subsection{Reprise ou poursuite}
Lors que l'évènement à été pris en charge par le processeur, nous envisageons deux scénario.
\begin{enumerate}
\item \textbf{reprise}: retente l'éxécution du IP
\item \textbf{pouruite}: passe à l'instruction suivante
\end{enumerate}
En générale, les intéruptions constituent tous des évènements récupérables avec poursuite.
\subsection{Déroutement}
Chaques architectures implémente sa propre méthode de déroutement. voici quelques examples:
\begin{itemize}
\item \textbf{Registre de cause}: C'est un registre mis à jours lors d'une exception ou d'une
intéruption. au terme du cycle d'éxécution, le processeur consulte ce registre pour savoir
si un déroutement est nécéssaire et dans ce cas vers quel adresse.
\item \textbf{Vectorisation}: chaques évent est un numéro dans une table de descripteur(IDT). Ce
descripteur est l'adresse de la fonction de gestion de l'évènement.
\end{itemize}
\subsection{Niveau de privilège}
Le jeu d'instruction du processeur contient des instructions "système" qui ne sont pas accésibles en
principe à tout les utilisateurs. Un programme typiquement fait appel à l'OS qui à son tours fait
les appels systèmes. on parle de ring 3/0 (0 étant le plus privilégié/OS)
\subsection{Basculement de stack}
Lors d'un déroutement, L'os utilise son propre stack. (après avoir sauvegardé le contexte du
programme) ainsi, le programme ne peu pas accéder a son contenu lors de la continuation.
\subsection{Multiple évènements}
Lorsque plusieurs évènements surviennents, la prioritée est : Abandon > Reprise > Poursuite.
Il est également envisageable qu'un évènement survienne pendant la gestin d'un autre évènement. Dans
ce cas, étant donné que nous utilisons le stack pour le stockage du contexte du programme, il est
tout à fait envisageable d'utiliser ce même stack pour le stockage du contexte de la gestion du dit
évènement. Nous avons alors une imbrication des évènement à la manière de fonctions récursives.
Dans le cas ou nous authorisons plusierus évènements à dérouter en même temps, il peut être
nécéssaire d'implémenter un ordre de priorité. Pour ce faire une solution est d'utiliser un masque
d'interruption. Un évènement place alors les bits de sa prioritée. un évènement postèrieur est
déclencher ou non selon son propre masque de priorité.
\section{Memoire}
Nous avons vu qu'un programme étais composé de trois compostantes: le code machine, l'espace de
données et le stack. Ces composantes sont liées logiquement au sein du programme à l'aide d'adresse.
(branchements, ...). Deux problèmes se posent alors:
\begin{enumerate}
\item \textbf{La concurence d'adresse}: Il est possible que les adresses choisies soient déjà
utilisées par un autre programme. Il est également important de vérifier quelles mémoires
sont accédées pour éviter qu'un programme accède à des donnes ne lui appartenant pas.
\item \textbf{Gestion de la mémoire disponible}: L'OS doit savoir quelle partie de la mémoire
est libre et quelle partie est utilisé.
\end{enumerate}
Il nous faut résoudre ces problèmes de manière efficace et performante. car ces opérations sont les
plus utilisées
\subsection{Projection et protection}
\begin{itemize}
\item \textbf{Adressage absolu}: Cas de figure le plus directe. Les adresses du programmes sont
copiées précisément aux adresses de la mémoire choisies au moment de la compilation.
Le programme fonctionne alors parfaitement. Si certaine des adresses du programme ne sont
pas libres, Nous pourions comprometre l'intègritée du système. Il n'est également pas
possible de vérifier si le programme accède a des adresse qui ne sont pas autorisées.
\item \textbf{Adressage relatif}: Nous définissons un décalage (offset) au démarage du
programme. Cet offset sera appliqué à tout les adresse utilisées dans le programme.
\begin{itemize}
\item \textbf{static}: Modifie les adresse en y ajoutant l'offset (adresse de base) à la
volée lors de la mise en mémoire. Pour celà, l'éxécutable doit contenir une table
contenant les emplacement des adresse à modifier. Cette aproche n'empèche toujours
pas l'accés à des adresse hors mémoire. De plus, les adresse générées pendant le
déroulement du programme ne seront pas corigées
\item \textbf{dynamique}: L'ajout de l'offset se fait à chaques accés mémoires pendant
l'éxécution. nous stockong également la \textbf{limite} (la taille du programme) qui
permet de vérifier, lors d'un accès mémoire, si cette addresse est inférieur à
limite. si ça n'est pas le cas c'est que le programme tente de d'accèder à une
adresse ne lui appartenant pas. dans le cas contraire, l'adresse est additionée à
\textbf{base}. Un avantage de cette aproche est que le programme peut à tout moment
être déplacer dans la mémoire en métant à jour \textbf{base} et \textbf{limit}. A
contrario, chaques appel mémoire demande deux opérations (une comparaison et une
addition). ajout non négligable même si ces opérations font partie des plus rapides
du procésseur
\end{itemize}
\item \textbf{Segmentation}: Le programme est ségmenté dans la mémoire physique. chaques
ségments est encodé dans un \textbf{déscripteur de ségment} à l'aide de sa \textbf{base} et
\textbf{limit} (il est également possible de stocker le type, la permission, la direction,
la présence et un champ pour savoir si l'adresse a été modifiée ultérieurement). ces
déscripteurs sont stocké dans une \textbf{table de segments} en mémoire physique. Pour
gagner du temps cette table est stocké dans un registre de sélécteur de ségment.
Ces ségments sont crées à la compilation et la table de segments est liée au programme.
Un avantage de la ségmentation est \textbf{le partage de segment}. En effet, il est possible
pour plusieurs programmes de partager un segment de mémoire physique commun (ex: librairies).
\item \textbf{Pagination}: Meilleure solution pour la souplesse dans la gestion de mémoire. Nous
considérons deux espaces. La pagination repose sur un découpage uniforme de ces deux espaces (e.g. 4Kib, 4Mib).
\begin{itemize}
\item \textbf{espace physique} : dont la taille dépend de l'architecture du processeur
(16/32/64 bits). Cet espace sera découpé en \textbf{pages}
\item \textbf{espace virtuel} : dont la taille dépend du controlleur et de la quantitée
de mémoire disponible. Cet espace sera découpé en \textbf{cadre}
\end{itemize}
Par conséquent, une page peut être contenue dans un cadre. Pour localiser l'endroit où une
page réside en mémoire physique, nous utilisons une \textbf{table des pages} (propre à
chaques programmes) \textbf{exhaustive} (contient une entrée pour chaques pages) et est
stockée dans la mémoire physique. L'MMU (\textit{Memory Management Unit}) s'occupe de la
traduction d'une page vers un cadre. La taille de la table des pages peut être trouvé par
\[\text{Taille} = \frac{\text{Espace virtuel}}{\text{Taille de page}} \times \text{Taille d'une
entrée}\]
Chaques entrées dans la table des pages contient un numéro de cadre qui identifie l'adresse
du cadre occupé par la page en question.(Nous y accompagnons un bit de présence, permission,
référencée, modifiée).
Un accés mémoire par le procésseur sépare l'adresse virtuelle en deux parties, suivant la
taille de découpage. Nous avons donc une portion qui encode le numéro de page (utilisé en
indice dans la table des pages) ainsi que l'offset qui sera apliqué une fois l'adresse
physique trouvée. L'utilisation du bit de présence est expliqué ci-dessous, il permet en
effet l'éxécution d'un programme quelque soit la quantité de mémoire physique disponible
pour le stocker.
\end{itemize}
Les méthodes utilisant le \textbf{bit de présence} permetent l'éxistance partielle d'un programme en mémoire.
Dans le cas d'un appel vers une mémoire non présente, le processeur déclanche une \textbf{excéption}
de type défaut de page qui va recharger la partie concernée en mémoire physique. Si au moins un
cadre est disponible, il peut être pris. Si ça n'est pas le cas, un remplacmeent doit être
effectué \ref{sec:Eviction} Eviction de page
Il devra alors modifier les entrées base et limites en conséquence ainsi que mettre le bit de
présence à 1.
\label{sec:Eviction}
L'éviction d'une entrée dans la table des pages prends en compte le bit \textbf{modifié}. Celà
permet d'éviter de perdre du temps d'écriture car si la page n'est pas modifiée, elle est encore
accècible. IL existe alors plusieurs stratégies d'évicitions:
\begin{itemize}
\item \textbf{Least Recently Used}: Eviction de la page la moins utilisée. nécéssite de
connaitre le temps depuis le dernier accès
\item \textbf{Not Recently Used} permet une simplification du LRU, un simple bit est tenu à
jours à la place du temps.
\item \textbf{First In First Out}: la page la plus ancienne est choisie. une structure de type
\textit{FIFO} peut être utilisée. Il est également possible d'implémenter la stratégie de la
\textbf{dernière change}. C'est à dire, d'implémenter l'utilisation du bit de référence
(régulièrement mis à jours par l'os) pour garder les pages régulièrement chargées. Il est
finalement possible d'implémenter une structure circulaire.
\end{itemize}
la \textbf{Préemption} est le fait de libèrer de la mémoire d'un programme qui ne s'éxécute pas à
l'instant pour la donner à un autre programme en cours.
\subsection{Gestion de la mémoire physique}
Le système d'exploitation doit pouvoir, à tout moment, connaitre l'état d'occupation de la mémoire
physique. L'allocation de mémoire est alors plus dynamique.
\begin{itemize}
\item \textbf{Bitmap}: tableau de bits, la mémoire physique est découpée en unités d'allocation
de taille constante. on place les bits respectifs selon si l'espace est aloué ou non.
\[\text{Nombres d'unités} = \frac{\text{Mémoire physique}}{\text{Taille d'une unité}}\]
\[\text{Taille du bitmap} = \frac{\text{Nombres d'unités}}{8}\]
Nous pouvons alors trouver le bit corespondant à une unitée en divisant l'adresse par la
taille d'une unitée. Il suffit alors à l'os de trouver des suites de bits consécutifs libre
pour alouer de la mémoire en conséquence.
\item \textbf{Liste chainée}: chaques noed est une plage d'adresse particulière. un champ
contient:
\begin{itemize}
\item état: libre ou aloué
\item base
\item longeur
\item suivant
\end{itemize}
Nous avons finalement une chaine d'état alternant entre libre et aloué. lorsqu'un programme
souhaite alouer une plage, il parcours la liste afin de trouver une plage libre dont la
taille est supérieur à celle demandée. et de crée une maille de la chaine avec l'état
aloué. lorsque nous avons deux états consécutifs, nous pouvons les fusioner en gardant
l'adresse du premier mayon et en sommant les longeurs.
\end{itemize}
\section{Processus}
Un processus représente la mise en activité d'un programme qui réside en mémoire. (complétement ou
partiellement). Ce processus va occuper un processeur en utilisant le context de sa stack lorsque
son code sera en cours d'éxécution. Ces processus auront la capacitée de faire des appels systems
(syscall) qui seront transmis à l'OS pour exécution. Il est donc nécéssaire d'alterner entre
l'éxécution du processus et celui de l'os (notament pour les évènements/syscall).
\begin{figure}[h]
\center
\includegraphics[width=0.8\textwidth]{process_exe.png}
\caption{Temps d'éxécution d'un processus}
\end{figure}
Le temps d'éxécution du programme augmente donc. Il est même souvent nécéssaire de partager le
processeur avec d'autre programmes en cours d'éxécution. (\textit{interleaving})
Tout les processus sont stockés dans la \textbf{table des processus} attaché à leurs état. Cet état
peut être: \textbf{éxécution, pret, bloqué, zombie} et chaques processus contient un context
nécéssaire à son fonctionnement. Il est également nécéssaire de sauvegarder l'état de la mémoire.
(avec sa table des segments ou la table des pages). Finalement nous devons garder les divers
descripteurs de resources (fichiers ouvers, ... et leurs status, décalage dans le fichiers, ...)
L'\textbf{état} est un élément éssentiel pour le processus. Celui-ci est constament dans l'un des
états décrits ci-dessous. Celà permet de savoir comment le processus est censé se comporter à un
instant t.
\begin{itemize}
\item \textbf{éxécution}: Le processus suis son éxécution courante. peut être utilisateur, où
les instructions du programme s'enchainent et passe en éxécution système lors d'un
évènement. Une fois cet évènement traité, le système redonne la main à l'utilisateur qui
peut continuer l'éxécution du programme. Il est également possible que l'évènement soit
irrécupérable. dans ce cas, le programme se termine est passe à l'état \textbf{zombie}
\item \textbf{prêt}: le processus est pret à etre éxécuté mais le processeur est actuellement
occupé. une fois celui-ci libéré, il choisit (en fonction de méthodes discutés plus tard) un
processus à l'état prêt et commence son éxécution.
\item \textbf{bloqué}: Le processus ne peux pas continuer car il n'a pas les resources
nécéssaire. Il peut par example attendre un signal réseau, une touche clavier, ... une fois
cet élément reçu, le processus passe à l'état \textbf{prèt}. Le tout se fait pendant
l'éxécution d'un évènement. ce qui implique que le procéssus en cours donne la main au
système.
\item \textbf{Zombie}: Un processus à l'état zombie ne peux plus rien faire. Il donne son état à
son processus parent qui peut, une fois cet état reçu, terminer le processus.
\end{itemize}
Un procéssus peut créer à son tours d'autre processus (parents/enfants) Le système fonctionne alors
sous forme d'arborescence de processus, tous défini par leurs entrée dans la table des processus.
\begin{figure}[h]
\centering
\includegraphics[width=0.8\textwidth]{process_diag.png}
\caption{cycles de vie des processus}
\end{figure}
Suite à cet agencement, il est nécéssaire de trouver des méthode d'ordonnancement. Ces méthodes
doivent s'assurer la bonne répartition du temps processeur qui sont pret. Nous en étudierons sous 3
type des systèmes différents.
Un point important à éviter est la \textbf{famine}. c'est à dire qu'une tache resterait à pret sans
jammais se voir éxécuter.
\subsection{systèmes batch}
éxécute des taches de manière régulière. chaques tache est simples mais effectuée sur une quantitée
importante de données. Les taches sont garantie de terminer et il est possible d'estimer le temps
d'une tache donnée.
Il faut alors une équité dans les resources distribuées.
Nous regardons deux unitées. le \textit{Throughput}: nombre de taches par unité de temps, à
maximiser; le \textit{Turnaround}: temps moyen entre création et terminaison, à minimiser.
\begin{itemize}
\item \textbf{First come first served (FCFS)}: Par ordre d'arrivé à l'état pret. Peut
s'implémenter à l'aide d'une file. cette méthode est équitable et évite la famine car toutes
les taches finirons par s'éxécuter. Mais ne garantis pas une utilisation optimale des
\item \textbf{Shortest job first (SJF)}: Nous pouvons éstimer la durée des tache (car batch)
donc nous pouvons priorisé les taches courtes. Cette stratégie minimise le turnaround mais
n'est pas équitable vis à vis des tache longues. nous avons un risque de famines.
\item \textbf{Shortest Remaining Task First (SRTF)}: Nous gardons le temps restant d'éxécution
de chaques processus. l'ordre d'éxécution suis alors cette liste.
\end{itemize}
\subsection{Systèmes intéractifs}
Centré autours de l'utilisateur et l'intéraction. Nous voulons une équité entre les utilisateurs et
les resources utilisées. Nous utilisons les métriques suivantes: \textit{latence}: le temps qui
s'écoule entre une action de l'utilisateur et la réaction du système, \textit{Proportionalité}
en adéquation avec les attentes de l'utilisateur.
\begin{itemize}
\item \textbf{Round-Robin}: Le temps CPU est divisé en \textit{quantum} de temps de durée fixe.
Ces quantums sont distribués aux processus prets. Nous pouvons l'implémenter à l'aide d'une
liste cylindrique. l'Os configure un timer pour générer une intérruption à la fin du quantum
de temps pour passer à l'éxécution suivante. Cette stratégie garantit une répartition
équitable du CPU entre les procéssus. Il ne faut pas que le quantum soit trop bas car au
final il y aurais plus de temps nécéssaire à la commutation qu'à l'éxécution des processus.
\item \textbf{Priority Schéduling}: Mise en place d'un niveau de priorité par processus.
\item \textbf{Guaranteed Scheduling}: A pour but une répartition du nombre de processs face à un
délai garanti.
\[\text{Délai garanti} = \frac{\text{Temps depuis sa création}}{\text{Nombre de processus}}\]
L'ordonnanceur réalise un suivi du temps d'éxécution par chaque processus.
\[\rho = \frac{\text{Temps reçu}}{\text{Délai garanti}}\]
L'ordonnancement se base alors sur la valeur minimale.
\item \textbf{Fair-share scheduling} : Deux niveau de round robin, un pour les utilisateurs et
un par processus d'un utilisateur. Celà permet une répartition équitable du temps CPU par
utilisateur.
\end{itemize}
\subsection{Systèmes temps réel}
Système nécéssitant un controle du temps (réel) critique. Il se doit de réagir dans un temps
déterminé. (example système de défense anti-missile scannant continuellement son périmètre.)
Dans ces système. chaques évènements est précisément calibré pour être traités dans un temps
impartis avec échéances strictes. Ce système est ordonnancable uniquement si
\[\sum_{i=1}^m \frac{C_i}{P_i} \leq 1\]
avec $P$ intervalle entre deux occurence d'évènements et $C$ Temps nécéssaire au traitement.
\vspace{1cm}Un thread (processus léger) permet un découpage des traitement qui, au sein d'un processus, peuvent
être effectué de mainère indépendante les uns des autres (\textbf{multi-threading} )
Le coup de la gestion d'un thread est moindre que celui d'un processus. car celui-ci prends toutes
les resources déjà alouées de son thread principal. Il suffit juste d'effectuer une allocation de
mémoire pour héberger le stack du thread engendré. La continuation est nest rendu également plus
simple.
L'implémentation d'un thread peut se faire à deux niveaux.
\begin{itemize}
\item \textbf{User-level}: l'os n'a pas conscience des threads, c'est à l'application de gérer
son ordonencement. Mais n'est pas très évicace faces aux évènements car un blocage
(ouverture de fichiers, ...) bloquera tout les autres threads
\item \textbf{Kernel-level}: la stratègie d'ordonencement apliqués aux processus est appliqué
aux threads. Le blocage n'a donc pas de conséquence sur les autres threads du même
processus.
\end{itemize}
\section{Concurence}
\section{Systèmes de fichiers}
\section{Entrées-sorties}
\end{document}

23
bac2/pgl/usecase/Makefile Normal file
View File

@ -0,0 +1,23 @@
.PHONY: all clean run
all: extension_messagerie.pdf
%.pdf: %.tex
pdflatex $<
extension_messagerie.pdf: extension_messagerie.tex extension_messagerie.bbl use_case_messagerie.tex
pdflatex extension_messagerie.tex
use_case_messagerie.tex: use_case_messagerie.uml
plantuml -tlatex:nopreamble use_case_messagerie.uml
extension_messagerie.bbl: references.bib
biber $<
clean:
latexmk -C
rm -f use_case_messagerie.tex
rm -f extension_messagerie.{bbl,run.xml}
run: extension_messagerie.pdf
xdg-open $<

View File

@ -0,0 +1,98 @@
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amsmath, amsfonts, amssymb, amsthm}
\usepackage{tikz}
\usepackage{biblatex}
\author{Debucquoy Anthony}
\title{Extension messagerie}
\addbibresource{references.bib}
\begin{document}
\section{Use case diagram}
\begin{figure}
\resizebox{345pt}{!}{
\input{./use_case_messagerie.tex}
}
\caption{Use Case Diagram of the messaging extension}
\label{fig:useCase:msg_ext}
\end{figure}
In the diagram Figure~\ref{fig:useCase:msg_ext},
the <<extend>> definition is not pulled from the "Genie logiciel" course
of the University of Mons (UMONS). It is in fact the definition from
the Dan Pilone's pocket reference \cite{Pilone2006-fn}.
\subsection{Answer topic}
The user should be able to answer to a topic created by a teacher.
This answer will depend on the type of topic. The answer could be a selection on a poll,
a private answer (which mean that the answer is not visible to the other users except to the professor).
The answer could finally be a basic answer to the topic and be visible to other users browsing the topic.
\subsection{Create discutions}
The user can select multiple users and group them into a discussion.
In this discussion, users will be able to exchange messages readable by
every other members of the discussion
\subsubsection{Send messages}
Allow the creation of a message in a discussion.
The text sent to others shall be received by other users
and these users shall be notified of this message by the notification
system.
\subsection{Ask appointment}
A student can ask for an appointment to a teacher.
In this request, the student will have to give a date, a time
and a subject he want to propose to the teacher.
\subsubsection{Export to calendar}
When an appointment is made. The program can export the event
to an open format that can be read by calendar software to add
the event to the user's calendar.
\subsection{Manage appointment}
When a teacher received an appointment, he is able to
validate, deny or propose a new appointment schedule to the
student.
\subsubsection{Propose new appointment}
If the teacher can't attend to an appointment because of his
schedule, he can make a new time proposal and send it to
the student. The student then receive a notification of
the proposed modifications.
\subsection{Create forum}
The teacher can create a new forum under a specific course
The new forum will then make every student of this course
follow the forum and its topic.
\subsubsection{Post topics}
The teacher can post a new topic inside a forum to let
the student know of something specific or to ask a question to
them.
\subsubsection{Post poll}
When posting a topic to a forum, the teacher can choose to
make the post as a poll. In that case, student will have to vote
for one of the options or if allowed by the teacher, create a new option.
\printbibliography
\end{document}

View File

@ -0,0 +1,9 @@
@BOOK{Pilone2006-fn,
title = "{UML} 2.0 Pocket Reference",
author = "Pilone, Dan",
publisher = "O'Reilly Media",
month = mar,
year = 2006,
address = "Sebastopol, CA",
language = "en"
}

View File

@ -0,0 +1,39 @@
@startuml
left to right direction
:Student: as s
:Teacher: as t
package "Messagerie"{
(Answer topics) as at
(Ask appointement) as aa
(Create Discution) as cd
(Create Forum) as cf
(Manage appointement) as ma
s -- at
s -- aa
s -- cd
t -- cd
t -- cf
t -- ma
(Export to calendar) as etc
aa <-- etc : << extend >>
ma <-- etc : << extend >>
(Post topics) as pt
cf <-- pt : << include >>
pt <|-- (Post poll)
cd <-- (Send messages) : << include >>
ma <-- (Propose new appointment) : << exlude>> \n [refuse]
}
@enduml

BIN
bac2/uml/ATM_usecase.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
bac2/uml/activity.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

201
bac2/uml/notes.md Normal file
View File

@ -0,0 +1,201 @@
Notes de cours UML
==================
Introduction
------------
Nous devons voir les diagrammes :
- de cas d'utilisation
- d'interraction overview
- **de Class**
- **d'état**
- d'objet
- d'activitée
- de séquence
Modélisation logicielle
------------------------
un **modèle** est une représentation simplifiée d'une partie de la réalité dans un but spécifique.
Ces modèles ont pour "valeurs":
- L'abstraction
- Compréhension
- Précision
- Prédictibilité
- Rentabilité
Dans tout les diagrammes uml, les commentaire sont encadrée et reliés avec des ligne discontinue
Diagramme de cas d'utilisation
------------------------------
Représente une "vitrine" du produit avec ces fonctions principales d'un point de vue utilisateurs.
Représente:
- Un système (carré entourant une partie du diagramme)
- Un ensemble de cas d'utilisation (dans un oval)
- Accompagné d'une descriptin semi-structurée
- Toujours lié à un acteur (sauf <\<include\>> et <\<exlude\>>)
- Les acteurs (bonnome batons)
- Les relations entre eux
Attention de ne pas modéliser des dépendances causales ou séquentielles.
### Relations
- extension: ajoute un comportement supplémentaire à un point d'extension.
- Dans le cas d'une condition, ajouter "[condition]" à la flèche
- inclusion: inclus dans le comportement d'un autre cas d'utilisation
- généralisation: remplace un cas d'u par un autre qui fournit plus de détails.
- peut être entre cas d'u: spécialisation
- peut être entre acteurs: héritage
![ATM Use Case diagram](./ATM_usecase.png "use case diagram")
Diagramme d'interaction
-----------------------
Permet de faire un diagramme d'activité avec les use case. C'est en quelques sorte un use case
diagramme séquentielle et causale.
Activity diagram
----------------
Permet de modéliser un comportement dynamique, une succession d'activités dans un système pour une
certaine tâche ainsi que son flux de controle.
Resemble à un diagramme d'état sans les états.
- activité: rectangle arrondi
- transitions: flèches
- chaques activités doit avoir une transition sortante et peut avoir plusieurs transition
entrante.
- Entrée: cèrcle noir
- Sortie: Cible
- Fin de flux: cercle baré
- Point de jonction/ Décision: losange
- choix entre deux séquence mutuellement exclusive.
- Condition notées en "[condition]"
- sert à merge des chemins alternatifs (!pas chemins concurents)
- barre de synchronisation: ligne épaisse avec transition entrante et sortantes.
- Un fork qui n'est pas join doit se terminer par un point de sortie (pour une terminaison de
l'acitivité complète) ou par un symbole de fin de flux (dans le cas ou l'activité continue
même sans cette branche).
- swimlanes: couloirs d'activité
- Objets: Rectangle
- Récurence: Sablier avec "[timeline]" pour spécifier la récurence
- Signal: Rectangle avec flèche et anti-flèche
-
Il est possible de représenter des sous activitées en dessinant un diagramme d'activité dans un
rectangle.
![Activity Diagram](activity.png "activity")
Class diagram
-------------
Représente les structures statiques d'un système (classes, interfaces et leurs relations)
- Classes: Rectangle
- Noun in PascalCase
- Si interface, noté <\<interface\>>
- Souligné si instance (et/ou :Type)
- Attributs: listées dans rectangle de classe
- noun camelCase
- peut avoir un type (primitif ou complexe)
- peut avoir une valeur par défaut
- une portée (class scope = souligné)
- une liste de valeurs possibles (enum)
- une visibilité (+, -, #, ~)
- Opérations: listées dans rectangle de classe
- verb in camelCase
- peut avoir un type de retour
- peut avoir des arguments
- une portée
- une visibilité (+, -, #, ~)
- Les getter & setter des attr ne sont généralement pas mentionnées.
- Associations: ligne
- connexion bidirectionnelle entre classe
- peut être accompagné en annonation du role de cette association (de part et d'autre)
- peut être accompagné d'une quantification: m .. n avec * signifiant zero ou plus
- peut être étiquetée par explicité ( works for |> )
- peut être associé à elle même
- Ajouter une croix à la base d'une association permet de la rendre uni-directionnelle
- Gnéralisations: Flèche ouverte
- Contraintes: commentaire
- "{or}" exclusion mutuelle
- Agrégation: diamand (<>--)
- apartient-à ou est-une-partie-de ou est-composé-de
- Composition: diamand solide (<@>--)
- agrégat mais avec dépendance forte (si l'agrégat est détruit alors ses parties aussi)
Sequence
--------
Décrire comment le programme doit se comporter. Comportement des diagrammes statiques.
La verticalitée représente le temps.
- Objets: Etiquette au dessus des lifeline (sous forme d'instance avec :)
- Plusieurs instance = plusieurs rectangles superposés
- lifeline: ligne verticale
- Activation: boite sur la ligne de vie
- message: flèches entre les lignes de vies
- retour: flèche pointiée
- Création: objet au bout d'un message
- destruction: X en bas d'une ligne de vie
- Opérateurs: Rectangle d'une zone avec label
- loop (while [...] do ...)
- alt (if [...] then ... else ...)
- opt (if [...] then ...)
- break (if [...] then ... exit)
- par (parallel)
- neg (invalide)
- critical (section critique)
D'autre diagrammes peuvent être utilisé à l'intérieur du diagramme de séquence
Stateshart
----------
Un stateshart décrit le comportement d'un système, d'une partie d'un système ou d'un objet
Resemble fortement à un activity diagram mais représente des états.
- Etat initial: Cercle noir
- Etat final: target
- State: rectangle arondi
- peut être un diagrame d'état lui même
- transition d'état : flèche avec condition de la transition
- actions: format: "event [guard] / action"
- sur la flèche si lors de la transition
- interne avec mots clés (events)
- entry: lorsque le système entre dans un état
- exit: lorsque le système sort d'un état
- every x s / after x s: se déclenche selon l'évent
- guard: Condition pour que la transition ai lieu
- il vaut mieux etre détermiste (avoir des guard mutuelement exclusif)
- Transition composite: diamand (<>)
- etat historique: cercle avec H ou H*
- mémorise le dernier état visité
- Une transition peut en sortir dans le cas ou cet état n'aurais jammais été défini
Le stateshart est décrit dans un document.
```stateshart
interface <interface>
in event <name>
...
out event <name>
...
interface <interface2>
operation <name>(<parm>):<ret>
```