Programme python pour calculer un investissement
RésoluBonjour,
Je cherche à créer un script python pour un investissement et je n'y arrive pas.
- Je pars de 50€ je prends 8% des 50€, puis les additionnes à 50€ ce qui me donne 54€ (50 * 0.08 == 4).
- Puis je rajoute 50€, et cette fois je prends les 8% de 104€ (104*0.08 = 8.32) et je les additionne à 104€ ce qui me donne 112.32
- Et ainsi de suite... à l'infini en rajoutant à chaque fois 50€
3 réponses
-
Bonjour,
Il vaudrait mieux formuler ton problème comme une suite définie par récurrence ce serait plus clair. Et j'ai l'impression que tu t'es un peu emmêlé les pinceaux car si on rajoute 50€ à chaque fois on devrait avoir 162.32€ et non 112.32€. Voici à quoi ça ressemblerait :
#!/usr/bin/env python3 # -*- coding: utf-8 -*- u0 = 0 a = 1.08 b = 50 def f(n): return ( u0 if n == 0 else a * f(n - 1) + b ) for n in range(10): print(f"{f(n):.2f}")Ensuite, tu peux faire encore mieux en calculant la forme clause de ta suite définie par récurrence, voir ce lien :
Les suites récurrentes à 1 terme, ou d'ordre 1, de la forme u_n+1 = a * u_n + b où a, b et u_0 sont des nombres réels donnés, s'étudient très simplement :
-
Le cas a = 1 correspond à une suite arithmétique de raison b.
-
Le cas b = 0 correspond à une suite géométrique de raison a.
Lorsque a est distinct de 1, il suffit d'étudier la suite auxiliaire définie par v_n = u_n - L où L désigne la limite éventuelle de (u_n), c'est à dire vérifiant L = aL + b, soit L = b/(1 - a). La solution générale est alors donnée par :
u_n - L = a^n * (u_0 - L)
Dans ton cas (si j'ai bien compris) u0 = 0, a = 1.08 (on gagne 8%), b = 50 (on met 50€ à chaque tour de boucle) et donc L = 50 / (1 - 1.08).
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import math u0 = 0 a = 1.08 b = 50 l = b / (1 - a) def u(n): return math.pow(a, n) * (u0 - l) + l for n in range(10): print(f"{u(n):.2f}")Résultat :
0.00 50.00 104.00 162.32 225.31 293.33 366.80 446.14 531.83 624.38Bonne chance
-
Sinon sans module, on peut écrire le code de cette manière ?
u = 0 a = 0.08 b = 50 for i in range(10): def jsp(x, y): global b pr = x / (1-y) + 50 b = pr print(b) jsp(b, a)Corrige moi si je me trompe.
Il peut aussi être marrant de visualiser graphiquement l'investissement. Je me suis amusé à donc le modéliser :
import matplotlib.pyplot as plt nb = 0 nbl = [] xy = [] a = 0.08 b = 50 def jsp(x, y): global b global nb global nbl global xy pr = int(x / (1-y) + 50) b = pr nb += 1 nbl.append(nb) xy.append(b) print(b) for i in range(1000): jsp(b, a) print(nbl) print(xy) plt.plot(nbl, xy) plt.show() plt.close()Il y a des choses qui ne vont effectivement pas.
Dans le premier extrait de code :
- Même si c'est syntaxiquement correct, il n'y a pas de raison de déclarer jsp dans la boucle for (la redéclaration est faite à chaque tour de boucle). Généralement, on déclare les fonctions plutôt en début de fichier, une fois pour toute.
- On évite autant que possible les variables globales, comme c'est le cas pour b. C'est une mauvaise idée et en général ça n'est pas nécessaire. dans le cas présent, la fonction jsp devrait simplement retourner b, et du coup j'imagine l'appel devient b = jsp(n, a).
- Ni a ni u ne sont utilisés, donc ça ne fait pas exactement la même chose que le code que je t'ai proposé. Par rapport à ton exercice, le fait que a ne soit pas utilisé montre que tu ne calcules pas ce qu'il faut.
- Normalement on met des espaces autour des opérateurs (dont la soustraction) afin de se conformer à la norme PEP8.
Dans le second extrait de code, mes remarques additionnelles sont :
- En terme de design, jsp n'a pas a remplir xy (ni nbl). C'est plutôt dans ta boucle for i qu'il faut construire ces deux vecteurs.
- Vu que le comportement de u (cf mon message #1) est exponentiel, il est plus adéquat d'utiliser une échelle logarithmique sur l'axe des ordonnées.
- Toute courbe devrait avoir :
- Un titre
- Un label sur l'axe des abscisses (et l'unité de la grandeur associée, si elle en a une)
- Un label sur l'axe des ordonnées (et l'unité de la grandeur associée, si elle en a une)
- Je recommande l'utilisation d'une grille pour améliorer la lisibilité
- plt.close() n'est pas nécessaire.
Voici à quoi ça pourrait ressembler :
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import math import matplotlib.pyplot as plt u0 = 0 a = 1.08 b = 50 l = b / (1 - a) def u(n): return math.pow(a, n) * (u0 - l) + l n = 1000 x = [i for i in range(n)] y = [u(i) for i in range(n)] plt.xlabel("i") plt.ylabel("log(u(i)) (€)") plt.title("Progression de l'investissement") plt.grid(True) plt.semilogy(x, y)Bonne chance
merci beaucoup. Je ne vais pas te mentir, mon niveau en programmation n'est pas encore très élevé. Je n'ai pas l'habitude d'utiliser le module math ou numpy, ce qui doit être la cause des problèmes de mon programme. J'ai essayé de refaire ton programme sans code.
Je n'ai rien à dire sur tes remarque très constructives que j'appliquerai dans mes projets. Et petit message, mais ça tu ne pouvais pas le savoir avant, je suis en seconde et je n'ai pas encore vu les logarithmes. C'est pour cela que je n'utilise pas ce procédé mathématique qui m'est encore pour l'heure inconnu.
Merci à toi. Et à bientôt sur le forum.
-
-
-
Bonjour mamiemando
Il me semble que jessaye14 et worox sont 2 personnes différentes, du coup mettre le sujet résolu à la suite des messages de worox ne serait pas judicieux si j'ai raison,
D'autre part, je me permets une remarque.Si j'ai bien compris la demande initiale, pour une période, on ajoute 50€ puis on perçoit 8% d'intérêt.
Donc pour la première période, on part de 0, auxquels on ajoute 50, on a donc 50, puis on augmente ce capital de 8%, soir 54€ à la fin de cette période.
Pour, la seconde période, on ajoute 50, on a donc 104, puis on augmente ce capital de 8%, soit 112,32€ à la fin de la période.
Je suis donc raccord avec la question initiale de jessaye14.
Mais tu lui as répondu
si on rajoute 50€ à chaque fois on devrait avoir 162.32€ et non 112.32€.
En début de 3eme période, ok, on bien 162,32, mais le but n'est il pas de connaître le total avec les intérêts générés sur la 3eme période, car si on se contente de montant en début de période, il y a 50 qui n'ont pas encore fait de petits.
Pour moi, le logiciel de devrait sortir un truc du style
"Période 1 investissement 50 €, capital 54€" "Période 2 investissement 100 €, capital 112,32€" "Période 3 investissement 150 €, capital 175,3056€"
-
Ce qui, décomposé,donnerait ce code
capital = 0 investissementPeriodique = 50 taux = 1.08 for i in range(1,10): capital += investissementPeriodique capital *= taux print("Période", i, ": Investissement", i * investissementPeriodique, "€, capital", capital)Et cette sortie
Période 1 : Investissement 50 €, capital 54.0 Période 2 : Investissement 100 €, capital 112.32000000000001 Période 3 : Investissement 150 €, capital 175.3056 Période 4 : Investissement 200 €, capital 243.330048 Période 5 : Investissement 250 €, capital 316.79645184000003 Période 6 : Investissement 300 €, capital 396.1401679872001 Période 7 : Investissement 350 €, capital 481.8313814261761 Période 8 : Investissement 400 €, capital 574.3778919402703 Période 9 : Investissement 450 €, capital 674.328123295492 -
Ah c'est possible, et j'avoue que quand j'ai répondu, j'avais des doutes sur mon interprétation. En tout cas si ton interprétation est la bonne, la démarche reste la même, il suffit simplement corriger la récurrence :
#!/usr/bin/env python3 # -*- coding: utf-8 -*- u0 = 0 a = 1.08 b = 50 def f(n): return ( u0 if n == 0 else a * (f(n - 1) + b) # == a * f(n - 1) + a * b ) for n in range(10): print(f"{f(n):.2f}")On voit que si à l'époque on ajoutait à chaque fois b maintenant on ajoute a * b. Pour la version itérative, il suffit de corriger b à 50 * 1.08:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import math import matplotlib.pyplot as plt u0 = 0 a = 1.08 b = 50 * 1.08 l = b / (1 - a) def u(n): return math.pow(a, n) * (u0 - l) + l for n in range(10): print(f"{f(n):.2f}")Concernant le fait que worox et jessaye14 sont deux personnes différentes, je ne sais pas, c'est possible. Vu la timeline, je pense que c'est simplement jessaye14 qui a créé un profil worox entretemps. Si ce sont deux personnes différentes, elles sont probablement dans la même classe (pour avoir le même exercice au même moment !) et j'imagine que si on répond à l'une, alors l'autre devrait aussi avoir sa réponse. Et si ça n'est pas le cas, rien n'empêchera cette éventuelle seconde personne de demander des précisions :-)
-