Parcours
/
Julia
Julia
/
Exercices
/
Échange de devises
Échange de devises

Échange de devises

Exercice d'apprentissage

Introduction

Julia est un langage polyvalent qui peut servir à la plupart des tâches de programmation. En pratique, cependant, ses principaux domaines d'application restent l'ingénierie et les sciences. Des calculs numériques rapides, polyvalents et sophistiqués sont au cœur de sa conception.

Nombres entiers

Un entier est un nombre « rond », sans virgule.

Dans le concept Basics, on a vu qu'on peut affecter une valeur entière à une variable sans en préciser le type.

Pour la lisibilité, on peut utiliser des tirets bas comme séparateur de chiffres. Ils sont ignorés par le compilateur.

julia> x = 3
3

julia> typeof(x)
Int64

julia> large_number = 1_234_567_890
1234567890

Nombres à virgule flottante

Sans surprise, les nombres à virgule flottante comportent une virgule, et une partie fractionnaire après celle-ci.

julia> f = 3.45
3.45

julia> typeof(f)
Float64

Bien sûr, la notation scientifique est prise en charge.

julia> avogadro = 6.02e23
6.02e23

Les valeurs maximale et minimale peuvent surprendre :

julia> typemax(Float64)
Inf

julia> typemin(Float64)
-Inf

L'infini est une valeur valide !

Opérateurs arithmétiques

Comme on l'a vu dans le concept Basics, les opérateurs arithmétiques fonctionnent globalement comme l'arithmétique classique, celle qu'on apprend à l'école. À noter que l'exponentiation utilise ^, et non ** (les deux sont courants dans d'autres langages).

2 + 3  # 5 (addition)
2 - 3  # -1 (subtraction)
2 * 3  # 6 (multiplication)
8 / 2  # 4.0 (division)
8 % 3  # 2 (remainder)
2 ^ 3  # 8 (exponentiation)

Cependant, quelques détails propres à Julia méritent qu'on s'y attarde.

Multiplication

julia> x = 4.2
4.2

julia> 2 * x
8.4

julia> 2x
8.4

julia> 2.4x
10.08

Voilà qui peut surprendre.

On peut toujours utiliser * comme opérateur infixe, comme dans la plupart des autres langages informatiques.

Cependant, Julia a été conçu par des personnes qui estiment que le code doit ressembler autant que possible à des équations mathématiques.

Comme les noms de variables doivent commencer par une lettre, faire précéder un nom d'un nombre (entier ou à virgule flottante) est interprété comme une multiplication implicite.

Par exemple, si on veut l'aire d'une sphère, au lieu de 4 * pi * r * r, on peut écrire ceci :

julia> surface(r) = 4π * r^2
surface (generic function with 1 method)

julia> surface(3)
113.09733552923255

Bien que π soit une constante intégrée, c'est aussi une lettre (grecque). L'analyseur syntaxique a donc toujours besoin d'un * explicite pour séparer π de r.

Division

L'opérateur infixe / donne toujours un résultat à virgule flottante, même avec des entrées entières.

Pour la division entière, il existe d'autres possibilités.

julia> 10 / 3  # floating-point division
3.3333333333333335

julia> div(10, 3)  # integer division
3

julia> 10 ÷ 3  # synonym for div()
3

julia> 10 // 3  # rational number (fraction)
10//3

La fonction div() sert à la division entière, avec un résultat tronqué vers zéro : vers le bas pour les nombres positifs, vers le haut pour les nombres négatifs.

Comme synonyme, on peut utiliser l'opérateur infixe ÷, toujours dans l'idée de rendre le code plus mathématique. Si tu utilises un éditeur qui connaît Julia, saisis \div puis appuie sur la touche <Tab>.

L'opérateur // dépasse le cadre de ce concept. Pour l'instant, disons simplement que le résultat de // est un nombre « rationnel », que la plupart des gens appellent une fraction.

Conversion des types numériques

Cela se produit souvent automatiquement :

julia> x = 2 + 3.5
5.5

julia> typeof(x)
Float64

On a additionné un Int64 à un Float64, et obtenu un résultat Float64.

En fait, l'entier a été silencieusement converti en Float64 avant l'addition.

Les conversions de flottant vers entier sont forcément plus délicates. Que faire de ce qui suit la virgule ?

  • La fonction round() arrondit au nombre entier le plus proche ; en cas d'égalité, comme 4.5, l'arrondi se fait vers le nombre entier pair le plus proche.
  • floor() arrondit vers le bas, ceil() vers le haut, trunc() vers zéro.
  • Tenter une conversion directe, par exemple avec Int32(), échoue avec une InexactError.

Cependant, par défaut, ces fonctions ne renvoient pas le type entier que tu attendais peut-être. On peut préciser le type de sortie souhaité.

julia> round(4.5)
4.0

julia> ceil(Int, 4.3)
5

On peut aussi arrondir à un nombre précis de chiffres après la virgule grâce au mot-clé digits.

julia> round(π, digits=10)
3.1415926536

Division par zéro

Une division par zéro lève forcément une erreur, non ? En fait, la situation n'est pas si simple.

La division entière avec ÷ ou // provoque une erreur, comme on peut s'y attendre.

La division à virgule flottante avec / adopte une approche que l'on pourrait qualifier d'ingénieur, plutôt que l'approche classique de l'informatique :

julia> 2 / 0
Inf

julia> 0 / 0
NaN

Comme on l'a vu dans une section précédente, l'infini est un nombre à virgule flottante valide en Julia, représenté par Inf.

Quand le numérateur est aussi zéro, le résultat est mathématiquement indéfini. Julia le considère alors comme un « not a number », représenté par NaN.

Instructions

Ton ami Chandler prévoit de visiter des pays exotiques aux quatre coins du monde. Malheureusement, Chandler n'est pas très doué en maths. Il a plutôt peur de se faire arnaquer par les bureaux de change pendant son voyage, et il aimerait que tu lui crées un calculateur de devises. Voici ses spécifications pour l'application :

1. Estime la valeur après le change

Crée la fonction exchange_money(), qui prend 2 paramètres :

  1. budget : le montant d'argent que tu prévois d'échanger.
  2. exchange_rate : le montant de monnaie locale égal à une unité de devise étrangère.

Cette fonction doit renvoyer la valeur de la devise échangée.

Remarque : si ta monnaie est l'USD et que tu veux échanger des USD contre des EUR avec un taux de change de 1.20, alors 1.20 USD == 1 EUR.

julia> exchange_money(127.5, 1.2)
106.25

2. Calcule le montant restant après un change

Crée la fonction get_change(), qui prend 2 paramètres :

  1. budget : le montant d'argent avant le change.
  2. exchanging_value : le montant d'argent qui est prélevé sur le budget pour être échangé.

Cette fonction doit renvoyer le montant d'argent qui reste du budget.

julia> get_change(127.5, 120)
7.5

3. Calcule la valeur des billets

Crée la fonction get_value_of_bills(), qui prend 2 paramètres :

  1. denomination : la valeur d'un seul billet.
  2. number_of_bills : le nombre total de billets.

Ce bureau de change ne traite qu'avec des espèces de certaines valeurs. Le total que tu reçois doit être divisible par la valeur d'un « billet » ou d'une unité, ce qui peut laisser une fraction ou un reste. Ta fonction doit renvoyer uniquement la valeur totale des billets (sans les montants fractionnaires) que le bureau te rendrait. Malheureusement, le bureau garde le reste en prime.

julia> get_value_of_bills(5, 128)
640

4. Calcule le nombre de billets

Crée la fonction get_number_of_bills(), qui prend amount et denomination.

Cette fonction doit renvoyer le nombre de billets que tu peux recevoir pour le montant amount donné. Autrement dit : combien de billets entiers tiennent dans le montant de départ ? Rappelle-toi : tu ne peux recevoir que des billets entiers, pas des fractions de billet, alors pense à diviser en conséquence. Concrètement, tu arrondis vers le bas jusqu'au billet entier le plus proche.

julia> get_number_of_bills(127.5, 5)
25

5. Calcule le reste après le change en billets

Crée la fonction get_leftover_of_bills(), qui prend amount et denomination.

Cette fonction doit renvoyer le montant restant qui ne peut pas être rendu à partir du montant amount de départ, compte tenu de la coupure des billets. Il est très important de savoir exactement combien le bureau garde pour lui.

julia> get_leftover_of_bills(127.5, 20)
7.5

6. Calcule la valeur après le change

Crée la fonction exchangeable_value(), qui prend budget, exchange_rate, spread et denomination.

Le paramètre spread est le pourcentage prélevé au titre des frais de change, écrit sous forme d'entier. Il faut le convertir en nombre décimal en le divisant par 100. Si 1.00 EUR == 1.20 USD et que le spread vaut 10, le taux de change total sera en réalité : 1.00 EUR == 1.32 USD, car 10 % de 1,20 font 0,12, et ces frais supplémentaires s'ajoutent au change.

Cette fonction doit renvoyer la valeur maximale de la nouvelle devise après avoir calculé le taux de change augmenté du spread. Rappelle-toi que la coupure de la devise est un nombre entier et ne peut pas être subdivisée.

Remarque : la valeur renvoyée doit être de type entier.

julia> exchangeable_value(127.25, 1.20, 10, 20)
80

julia> exchangeable_value(127.25, 1.20, 10, 5)
95
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Julia Exercism

Prêt à commencer Échange de devises ?

Inscris-toi sur Exercism pour apprendre et maîtriser Julia avec 35 concepts128 exercices, et un vrai mentorat humain, le tout gratuitement.