🤖 Are we under their control, or are they under our control, or what? 🤖
On parle beaucoup d’intelligence artificielle (IA), mais, tout compte fait, c’est une expression récente déjà identifiée dans les milieux spécialistes des nouvelles technologies. L’intelligence est à comprendre au sens qui se rapproche le plus de son étymologie : « la capacité à faire des liens ». Cette suite de liens est bénéfique pour apporter des résultats, pas pour les apprécier ni avoir une conscience extra-humaine, en tout cas pour l’instant. D’ailleurs, c’est à l’occasion de l’une de mes premières expériences professionnelles que j’ai découverte l’art numérique et son histoire : récente, certes, mais très riche. Difficile de classer en sous-catégories les œuvres d’art numérique, mais on peut au moins distinguer la littérature numérique, produite sur des programmes et parfois éditées en CD-Rom. Je ne citerai que l’exemple de Machines à écrire, dont la filiation à la poésie générative de Raymond Queneau est plus qu’explicite (Cent mille milliards de poèmes). Avant de parler d’IA, il y a beaucoup à creuser dans la littérature numérique produite en France. Dans un mémoire traitant de la poésie numérique de 2017, Marc Morereau affirme, page 30, que « La France est un pays d’avant-garde dans la poésie numérique, précurseurs dans de nombreux domaines, elle développe même des intentionnalités propres, se dote d’une esthétique et contribue à diffuser cette forme poétique et à expérimenter de nouvelles voies. » (HAL). Moi-même, je n’ai pas fini de découvrir de nombreuses richesses poétiques encore semi-visibles.
En écrivant ce billet, je repense aux paroles de la chanson du groupe Newcleus intitulé Computer Age (Push the Button). Rythme entraînant, chants robotisés, paroles très adéquates avec le propos. Les ordinateurs nous aident à faire un travail que le cerveau ne pourrait accomplir qu’au terme de tout une vie. La puissance de calcul permet d’obtenir des résultats de recherche encore plus fournis car les cerveaux humains ont discipliné la machine en ce sens. A chaque outil créé et exploité par l’humain, il y a, au bout de la chaîne, une influence réciproque dans les méthodes de travail. D’ailleurs, pour plus de détails, une histoire synthétique et une présentation de ces enjeux est disponible dans l’édito d’Hervé Christofol et Chantal Pacteau : Intelligence artificielle : révolution ou outil ? (VRS n°437, juin 2024).
Je n’invente rien en écrivant tout ceci, mais c’est une bonne entrée en matière pour parler de mon expérience, je trouve. La musique de Newcleus, au-delà d’avoir contribué grandement aux prémices du hip-hop électronique, questionne déjà cette dimension propre à l’ordinateur comme ami ou ennemi. D’autres écrivains ou écrivaines dystopiques écrivaient déjà dessus, mais c’est moins dansant. D’ailleurs, le morceau ci-dessous, le premier du premier album, Jam on Revenge (Sunneyview, 1984), ne rend pas justice à la superbe pochette afro-futuriste illustrant. Elle est visible ici.
Computer age is now
Everyone must have a machine
They say it’s gonna make life easier
Je souhaite modifier les métadonnées embarquées « titre » de plusieurs fichiers PDF à l’aide d’un script Python
Voici donc à quoi ressemble le script permettant d’éditer les métadonnées « Titre » et « Auteur » de chaque fichier PDF présents dans un même dossier. Le nombre de fichiers doit correspondre avec le nombre de valeurs saisies dans le code pour que l’exécution soit réalisée sans erreur.
import os
from pypdf import PdfReader, PdfWriter
def change_pdf_metadata(directory, new_metadata):
# List all PDF files in the directory
pdf_files = [f for f in os.listdir(directory) if f.endswith('.pdf')]
if len(pdf_files) != len(new_metadata):
print("The number of PDF files and new metadata entries does not match.")
return
for pdf_file, metadata in zip(pdf_files, new_metadata):
file_path = os.path.join(directory, pdf_file)
try:
# Read the existing PDF
reader = PdfReader(file_path)
writer = PdfWriter()
# Copy all pages to the writer
for page in reader.pages:
writer.add_page(page)
# Update the metadata
writer.add_metadata({
'/Title': metadata['title'],
'/Author': metadata['author'],
})
# Write out the updated PDF
output_path = os.path.join(directory, f"../modif/{pdf_file}")
# For a new filename, use prefix "f"New_{pdf_file}"
with open(output_path, 'wb') as output_file:
writer.write(output_file)
print(f"Changed metadata of {pdf_file} to Title: {metadata['title']}, Author: {metadata['author']}")
except Exception as e:
print(f"Could not change metadata for {pdf_file}: {e}")
# Directory containing the PDF files
directory = "my_PDF_files"
# List of new metadata entries
new_metadata = [
{"title": "New title of Document 1", "author": "Author 1"},
{"title": "New title of Document 2", "author": "Author 2"},
{"title": "New title of Document 3", "author": "Author 3"},
{"title": "New title of Document 4", "author": "Author 4"},
# Add more metadata entries as needed
]
change_pdf_metadata(directory, new_metadata)
Changed metadata of My_PDF_document_1.pdf to Title: New title of Document 1, Author: Author 1 Changed metadata of My_PDF_document_2.pdf to Title: New title of Document 2, Author: Author 2 Changed metadata of My_PDF_document_3.pdf to Title: New title of Document 3, Author: Author 3 Changed metadata of My_PDF_document_4.pdf to Title: New title of Document 4, Author: Author 4
- ID ARK saisi : il s’agit de l’identifiant pérenne attribué au document Gallica. Ici, bpt6k5819033c
- Format de sortie choisi : il y a deux choix possibles : le format tif, brut et originel lors de la numérisation, ou jpg, format compressé adapté à une lecture sur navigateur.
- Nom du dossier créé : les fichiers seront automatiquement enregistrés dans un dossier dont le titre correspond à l’identifiant ark saisie lors de la première étape. Ici, le dossier sera intitulé bpt6k5819033c
- Choix de téléchargement : également deux choix possibles, page ou intervalle. S’il s’agit d’une seule page, le téléchargement se lance. Si un intervalle de pages doit être téléchargé, alors on obtient la demande suivante :
- Numéro de la première page saisi : pour notre exemple, je souhaite commencer le téléchargement à partir de la 8e numérisation, il faut donc vérifier sur l’interface si cela correspond à ma requête. Ici, la 8e numérisation se trouve à cette adresse.
- Numéro de la dernière page saisi : ce numéro clôt l’intervalle. Je ne souhaite que 4 pages dans mon exemple, j’arrête donc le téléchargement à la 12e numérisation incluse.
Télécharger des images provenant de Gallica à la pièce ou par intervalle de folios¶
import os
import requests
# Demander à l'utilisateur l'ID ARK et le format de sortie
var_id_ark = input("Entrez l'ID ARK (par exemple, bpt6k63117658): ")
print(f"ID ARK saisi : {var_id_ark}")
format_de_sortie = input("Entrez le format de sortie (JPG ou TIF): ").strip().lower()
print(f"Format de sortie choisi : {format_de_sortie}")
# Valider le format de sortie
if format_de_sortie not in ['jpg', 'tif']:
print("Format de sortie invalide. Veuillez choisir entre JPG et TIF.")
exit(1)
base_url = "https://gallica.bnf.fr/iiif/ark:/12148/"
# Créez un nom de dossier basé sur l'ID ARK
var_nom_dossier = var_id_ark.replace(':', '').replace('/', '_')
print(f"Nom du dossier créé : {var_nom_dossier}")
# Créez le répertoire de téléchargement s'il n'existe pas
download_directory = os.path.join(var_nom_dossier)
os.makedirs(download_directory, exist_ok=True)
# Fonction pour télécharger une image
def download_image(ark_id, page_number, output_dir, prefix, file_format):
url = f"{base_url}{ark_id}/f{page_number}/full/full/0/native.{file_format}"
output_path = os.path.join(output_dir, f"{prefix}_{page_number:04d}.{file_format}")
response = requests.get(url, stream=True)
if response.status_code == 200:
with open(output_path, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
file.write(chunk)
print(f"Téléchargé: {output_path}")
else:
print(f"Échec du téléchargement: {url}")
# Demander à l'utilisateur s'il souhaite télécharger une page spécifique ou un intervalle
download_choice = input("Voulez-vous télécharger une seule page ou un intervalle de pages? (Entrez 'page' ou 'intervalle'): ").strip().lower()
print(f"Choix de téléchargement : {download_choice}")
if download_choice == 'page':
page_number = int(input("Entrez le numéro de la page que vous souhaitez télécharger: "))
print(f"Numéro de page saisi : {page_number}")
download_image(var_id_ark, page_number, download_directory, var_nom_dossier, format_de_sortie)
elif download_choice == 'intervalle':
start_page = int(input("Entrez le numéro de la première page de l'intervalle: "))
print(f"Numéro de la première page saisi : {start_page}")
end_page = int(input("Entrez le numéro de la dernière page de l'intervalle: "))
print(f"Numéro de la dernière page saisi : {end_page}")
for i in range(start_page, end_page + 1):
download_image(var_id_ark, i, download_directory, var_nom_dossier, format_de_sortie)
else:
print("Choix invalide. Veuillez entrer 'page' ou 'intervalle'.")
ID ARK saisi : bpt6k5819033c
Format de sortie choisi : tif Nom du dossier créé : bpt6k5819033c
Choix de téléchargement : intervalle
Numéro de la première page saisi : 8
Numéro de la dernière page saisi : 12 Téléchargé: bpt6k5819033c\bpt6k5819033c_0008.tif Téléchargé: bpt6k5819033c\bpt6k5819033c_0009.tif Téléchargé: bpt6k5819033c\bpt6k5819033c_0010.tif Téléchargé: bpt6k5819033c\bpt6k5819033c_0011.tif Téléchargé: bpt6k5819033c\bpt6k5819033c_0012.tif
Tadaa! La magie opère. J’exagère, rien de sorcier, mais ça fait toujours plaisir quand un script fonctionne sans encombre. C’est un usage parmi tant d’autres. ChatGPT a été bien utile pour ne pas avoir à réalisé soit-même le code, aussi simple soit-il. Néanmoins, passée cette étape « découverte », il me semble pertinent de continuer à explorer ces usages car l’IA raccourcit le temps entre l’idée humaine, la conception de sa mise en œuvre et sa réalisation.
« I’m no longer in controlI can’t program my machine Now it wants to take my soul Stop it or it will proceed! »
Je reprends la suite des paroles de la chanson de Newcleus, plus dystopique, cette fois. Sans être happé par l’IA, nous devons en tirer les bénéfices tout en essayant de prendre du recul par rapport à tout cela. Nos habitudes de travail et de consommation en seront sûrement changées, tant dans la sphère publique que dans la sphère privée. Il y a quelques mois, j’avais suivi une intervention du professeur de l’université de Technologie de Compiègne Bruno Bachimont. À la fois informaticien et philosophe, sa présentation était résumée sous le titre « L’intelligence a toujours été artificielle » (École polytechnique fédérale de Lausanne, 11 avril 2024). Je retiens qu’il avait évoqué le fait que nous étions, avec cet outil, en train de jouer comme des enfants dans un bac à sable. Cela signifie que l’IA sera probablement encore plus puissante dans 5 ou 10 ans. Elle balayera sans doute ces petits scripts, pratiques, mais finalement assez peu novateurs. En tout cas, ils permettent à la personne qui les créé (moi) de se saisir de tous ces enjeux.
Alexandre Wauthier