Fonction open : ValueError: invalid mode

Résolu/Fermé
Arkassus Messages postés 18 Date d'inscription mardi 1 février 2022 Statut Membre Dernière intervention 18 janvier 2023 - Modifié le 28 sept. 2022 à 12:32
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 - 30 sept. 2022 à 09:54

Bonsoir,

J'ai commencé à écrire un script python pour afficher les nombres de la suite de Fibonacci, et je souhaite que l'utilisateur puisse enregistrer le résultat dans un fichier texte. Cependant je galère depuis plus de deux heures mais je n'arrive toujours pas à trouver l'erreur que j'ai faite.

Voici mon code : 

import os
a: int = 0
b: int = 1

fname = input(str("Quel est le nom que vous souhaitez donner au fichier texte ?"))
fname = fname + ".txt"
cheminfichier = input(str("Où souhaitez vous enregistrer le fichier (écrivez le chemin menant vers le fichier)"))
f = os.path.join(fname, cheminfichier)

nbfibonicci = input("Combien de nombres de la suite de Fibonicci souhaitez vous calculer ?")
nbfibonicci = int(nbfibonicci)
for fibonicci in range (nbfibonicci) :
    f = open(fname, cheminfichier)
    f.write(fibonicci)
    c: int = a + b
    a = b
    b = c

et le message d''erreur est :

Traceback (most recent call last):
  File "D:\programmation\python\project\test.py", line 13, in <module>
    f = open(fname, cheminfichier)
ValueError: invalid mode: 'D:\Python\azertix'

Quelqu'un pourrait-il m'aider à résoudre ce message d'erreur, s'il vous plait ?

A voir également:

5 réponses

mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
Modifié le 29 sept. 2022 à 14:18

Bonjour,

Concaténer un nom de dossier et de fichier

Pour concaténer un nom de dossier et un nom de fichier (afin d'obtenir un chemin absolu), tu peux utiliser pathlib qui est un module standard. Parmi les nombreux avantages :

  • par besoin de se préoccuper de la nature du séparateur de dossier (/ sous LInux et MacOS, \\ sous Windows)
  • pas besoin de se demander si le nom du dossier termine par un /
from pathlib import Path


dirname = Path("/home/toto")
filename = Path("mon_fichier")
path = dirname / filename
print(path)

Ceci dit, il n'y a pas vraiment d'intérêt à demander séparément le nom du dossier et le nom du séparément, généralement on demande à l'utilisateur de saisir lui-même le chemin complet. Libre à lui d'utiliser un chemin relatif ou absolu.

Ouvrir un fichier en écriture

Pour ouvrir un fichier, il est vivement recommandé de toujours passer par le context manager dédié. Cela évite d'oublier de fermer le fichier. Il est également recommandé de rattraper l'éventuelle exception levée si le fichier n'a pas pu être ouvert.

import sys

try:
    with open(path, "w") as f:
        print("hello world", file=f)
except Exception as exc:
    print(f"oops: {exc}", file=sys.stderr)

Suite de Fibonacci

Le calcul d'une suite de Fibonacci est un exemple typique de programmation dynamique. Si tu fais une simple récursion, à chaque fois que tu veux avancer dans la suite, tu dois recalculer tous les premiers termes. Si au contraire, tu prends le soin de mémoriser les termes intermédiaires de la suite, le programme sera bien plus rapide (et par la même occasion, plus écologique) car le calcul peut se faire en O(n) (actuellement tu es en O(2^n)).

Pour cela, tu peux stocker les résultats intermédiaires dans un dictionnaire. C'est ce que fais la classe ci-dessous, qui hérite de dict. Comme cette classe implémente la méthode __call__, toute instance de la classe Fibonacci peut s'utiliser comme une fonction (qui ici, prend un entier i en paramètre, l'index du terme la suite demandé). Dit autrement, l'instance fibonacci (de type Fibonacci) se comporte à la fois comme un dictionnaire dans lequel on mémorise les résultats intermédiaires (voir les utilisations de self[i]) et à la fois comme une fonction (voir les utilisations de self(i) dans la classe et de fibonacci(i) à l'extérieur de la classe) :

class Fibonacci(dict):
    def __init__(self):
        self[0] = 0  # terme initial F(0)
        self[1] = 1  # terme initial F(1)
    def __call__(self, i):
        if not isinstance(i, int) or i < 0:
            raise ValueError(f"Invalid parameter: {i}")
        if i >= len(self):
            self[i] = self(i - 1) + self(i - 2)  # F(i) = F(i - 1) + F(i - 2)
        return self[i]

fibonacci = Fibonacci()
print(fibonacci(8))  # Affiche 21
print(fibonacci)     # Affiche {0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21}

Bonne chance

1
yg_be Messages postés 22698 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 18 avril 2024 1 471
29 sept. 2022 à 21:56

La suite de Fibonacci est souvent donné comme un exemple de programmation dynamique.

En réalité, c'est un exemple exécrable, car il est totalement inutile de mémoriser tous les termes intermédiaires: il suffit de mémoriser les deux derniers termes intermédiaires.

L'erreur de départ, c'est d'utiliser la récursivité pour calculer cette suite.  La programmation dynamique atténue cette erreur.  Cependant, il est de loin préférable de n'utiliser ni récursivité, ni programmation dynamique pour calculer cette suite.

fib=list()
fm2, fm1 = 0,1
fib.append(fm2)
for i in range(100):
    fib.append(fm1)
    fm2,fm1=fm1,fm1+fm2
print(fib)
0
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748 > yg_be Messages postés 22698 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 18 avril 2024
30 sept. 2022 à 09:54

Bonjour yg_be,

Dans ton code, comme tu mémorises dans fib chaque terme, le code que tu proposes a une empreinte mémoire en O(n) - comme celui que j'ai proposé. Par contre, si tu ne gardais que les deux derniers termes (fm1, fm2) son empreinte mémoire serait en O(1), et là, ta remarque prendrait tout son sens.

En réalité, cette remarque est plus générale que ça et s'applique à de nombreux autres problèmes que l'on résout habituellement avec de la programmation dynamique. Un très bon exemple, c'est le calcul des distances d'édition (par exemple la distance de Levenshtein). Là aussi, il ne suffit de conserver en mémoire que les termes intermédiaires dont tu peux avoir encore besoin (donc tous les termes (i, j) intermédiaires tels que (i, j) sont maximaux au sens de Pareto). Bref, ce que j'essaye de dire, c'est que c'est plus lié à la manière dont tu implémentes ton programme qu'à la programmation dynamique elle-même.

0
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 330
26 sept. 2022 à 23:17

Normal tu lui passe le chemin au lieu du mode d'ouverture ...

https://www.w3schools.com/python/python_file_handling.asp


0
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 27 sept. 2022 à 11:07

Bonjour,

Tu peux remplacer fibonicci par fibonacci ..

Tu réouvre le fichier à chaque tour de boucle ligne 13 ???

input rend une string, donc tu peux enlever str ici:

fname = input("Quel est le nom que vous souhaitez donner au fichier texte ?")

et tu peux simplifier ici:

nbfibonacci = int(input("Combien de nombres de la suite de Fibonacci souhaitez vous calculer ?"))
f = open(fname, 'w')
for n in range (nbfibonacci):
    f.write(n)
    c: int = a + b
    a = b
    b = c

Après, il y a surement un truc qui manque dans la boucle car elle ne fait qu'enregistrer la suite de n:

si nbfibonacci = 5, par exemple, tu vas obtenir 0 1 2 3 4, mais pas la suite désirée

0
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 27 sept. 2022 à 13:46

Finalement, je ferais plus court:

a,b = 0,1

f_name = input('Nom du fichier : ')
nb = int(input('Combien de nombres de la suite ? : '))

with open(f_name, 'w') as f:
    while a < nb:
        f.write(str(a)+'\n')
        a, b = b, a+b
0
Arkassus Messages postés 18 Date d'inscription mardi 1 février 2022 Statut Membre Dernière intervention 18 janvier 2023
Modifié le 28 sept. 2022 à 11:20

Oui mon programme n'est pas du tout optimisé, je débute en python. Mais du coup comment faire pour pouvoir choisir le répertoire dans lequel écrire mon fichier, vu que mon code précédent ne fonctionne pas ?

0
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 330
Modifié le 28 sept. 2022 à 11:20

Ben tu donnes le chemin absolu vers le fichier.

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 28 sept. 2022 à 11:19

Bonjour,

Ca donnerait ça:

cheminfichier = input('Répertoire du fichier : (ex: C:\python\test\) ')
fname = cheminfichier+fname+'.txt'
0