Auto-generating PowerPoint files with chatGPT and Dall-E#

In this notebook we will generate a Powerpoint file that guides us through the basics of research data management. The receipe, all text and images will be auto-generated using generative artificial intelligence. We will use this prompt:

prompt = """
Erklaere die Grundlagen von Datenmanagement. Fokussiere dich auf diese Aspekte:
* Lebenszyklus von Daten
* Arten von Daten
* Verantwortlichkeiten von Personen und Rollen, die mit Daten umgehen.
* Beispiele von Datenerzeugung, Datenverarbeitung und Datennutzung im Kontext einer Stadtverwaltung
"""
authors = "chatGPT, Dall-E and Robert Haase"
pptx_filename = "daten.pptx"

To make this notebook work, make sure some libraries are installed, e.g. using pip:

pip install pillow python-pptx openai scikit-image

These versions were used:

import pptx
pptx.__version__
'0.6.23'
import openai
openai.__version__
'1.5.0'
import PIL
PIL.__version__
'10.1.0'
import skimage
skimage.__version__
'0.22.0'
from pptx import Presentation
from pptx.util import Inches
from skimage.io import imread
from PIL import Image
from openai import OpenAI

First, we define some helper functions for adding slides, generating text and images.

def add_title_slide(presentation, title, authors):
    
    slide = presentation.slides.add_slide(presentation.slide_layouts[0])
    slide.placeholders[0].text = title
    slide.placeholders[1].text = authors
def add_slide(presentation, title, *args):
    """Add a new slide to a given presentation
    
    The presentation and the slide title are mandatory. 
    Addionally, text and images, or image urls can be passed as parameters.
    """
    from PIL import Image
    import os

    # we presume the second slide template (index=1) contains 1 object placeholders,  
    # the third slide (index = 2) contains two object placeholders, and so on
    num_objects = len(args)
    slide = presentation.slides.add_slide(presentation.slide_layouts[num_objects])

    # set title
    title_shape = slide.placeholders[0] 
    title_shape.text = title

    # add objects
    for i, object in enumerate(args):
        shape = list(slide.placeholders)[i + 1]

        # in case it's a numpy array
        if hasattr(object, "dtype") and hasattr(object, 'shape'):
            aspect_ratio = image.shape[0] / image.shape[1]

            image_path = 'temp.png'
            im = Image.fromarray(image)
            im.save(image_path)
            
            shape.text = ''
            slide.shapes.add_picture(image_path, shape.left, shape.top, height=shape.height)

            os.remove(image_path)
        
        # in case it's an image file
        elif isinstance(object, str) and len(object) > 4 and object[-4:] in ['.png', '.jpg', '.tif'] and os.path.exists(object):
            shape.text = ''
            image_path = object
            slide.shapes.add_picture(image_path, shape.left, shape.top, height=shape.height)

        # otherwise is should be a string/text
        else:
            shape.text = object
def draw_dall_e_image(prompt, size_str="1024x1024", model='dall-e-3'):
    """Generate an image using a given prompt"""
    from openai import OpenAI

    num_images=1
    
    client = OpenAI()
    response = client.images.generate(
      prompt=prompt,
      n=num_images,
      model=model,
      size=size_str
    )
    return images_from_url_responses(response)


def images_from_url_responses(response, input_shape = None):
    """Turns a list of OpenAI's URL responses into numpy images"""
    from skimage.io import imread
    from skimage import transform
    import numpy as np
    images = [imread(item.url) for item in response.data]

    if input_shape is not None:
        # make sure the output images have the same size and type as the input image
        images = [transform.resize(image, input_shape, anti_aliasing=True, preserve_range=True).astype(image.dtype) for image in images]

        if len(input_shape) == 2 and len(images[0].shape) == 3:
            # we sent a grey-scale image and got RGB images back
            images = [image[:,:,0] for image in images]

    if len(images) == 1:
        # If only one image was requested, return a single image
        return images[0]
    else:
        # Otherwise return a list of images as numpy array / image stack
        return np.asarray(images)
def prompt_openai(user_prompt, system_prompt, model="gpt-4-0125-preview"):
    """Send a text prompt to chatGPT and return its result as string"""
    from openai import OpenAI

    # assemble prompt
    system_message = [{"role": "system", "content": system_prompt}]
    user_message = [{"role": "user", "content": user_prompt}]

    # init client
    client = OpenAI()

    # retrieve answer
    response = client.chat.completions.create(
        messages=system_message + user_message,
        model=model
    )
    reply = response.choices[0].message.content

    return reply
story = prompt_openai(prompt + "\n" + "Separate important steps by two line breaks. Do not use separate headlines", "")
story
'Datenmanagement umfasst den systematischen Umgang mit Daten, von ihrer Erzeugung bis zur Löschung. Es ermöglicht Organisationen, den Wert ihrer Daten voll auszuschöpfen, indem es für Qualität, Zugänglichkeit, und Sicherheit der Daten sorgt.\n\n**Lebenszyklus von Daten**\n\nDer Lebenszyklus von Daten beginnt mit der Datenerzeugung und geht über die Speicherung, Nutzung, Weitergabe, Archivierung bis hin zur Löschung der Daten. Jede Phase erfordert angemessene Managementpraktiken, um Datenintegrität und Datenschutz zu gewährleisten. Während des Lebenszyklus können Daten verarbeitet, analysiert oder transformiert werden, um Entscheidungsprozesse oder operationelle Abläufe zu unterstützen.\n\n**Arten von Daten**\n\nDaten können in diverse Kategorien eingeteilt werden, darunter:\n\n- **Strukturierte Daten**, die in einer festgelegten Form vorliegen, wie in Datenbanken. Beispiele sind Zahlen und Text in Tabellen.\n- **Unstrukturierte Daten**, die keine feste Struktur haben und somit schwerer zu analysieren sind. Beispiele sind E-Mails, Videos und Bilder.\n- **Semi-strukturierte Daten**, die irgendwo dazwischen liegen, wie XML-Dokumente.\n- **Big Data**, das sich durch großes Volumen, hohe Geschwindigkeit und Vielfalt auszeichnet und spezielle Technologien und Methoden für das Management benötigt.\n\n**Verantwortlichkeiten von Personen und Rollen, die mit Daten umgehen**\n\nDie Verantwortlichkeiten beim Datenmanagement können je nach Rolle variieren, einschließlich:\n\n- **Dateninhaber** sind für die Datenqualität und den gesamten Lebenszyklus der Daten verantwortlich.\n- **Datenstewards** arbeiten an der Definition von Datenrichtlinien und -standards und unterstützen deren Einhaltung.\n- **Datenanalysten** analysieren Daten, um Einblicke und Information zu extrahieren, die Geschäftsentscheidungen unterstützen.\n- **IT-Sicherheitsexperten** gewährleisten, dass die Daten während ihres gesamten Lebenszyklus sicher sind.\n\n**Beispiele von Datenerzeugung, Datenverarbeitung und Datennutzung im Kontext einer Stadtverwaltung**\n\n- **Datenerzeugung:** Einwohner einer Stadt nutzen Online-Formulare auf der Website der Stadt, um Anträge zu stellen, Beschwerden einzureichen oder Veranstaltungen zu melden. Diese Aktionen generieren Daten in Form von strukturierten Datensätzen.\n\n- **Datenverarbeitung:** Die Stadtverwaltung verarbeitet diese Daten, indem sie sie sichtet, kategorisiert und in Datenbanken speichert. Weiterhin kann die Analyse dieser Daten Trends oder Problemfelder aufzeigen, z.B. in Bezug auf Straßenverkehr oder Umweltschutz.\n\n- **Datennutzung:** Auf Basis der analysierten Daten kann die Stadtverwaltung Maßnahmen ergreifen, wie die Planung von Infrastrukturprojekten, die Umsetzung von Verkehrsberuhigungsmaßnahmen oder die Organisation kommunaler Dienstleistungen. Diese Nutzung demonstriert, wie durch effektives Datenmanagement Entscheidungen, die einen direkten Einfluss auf die Lebensqualität der Einwohner haben, informiert und verbessert werden können.'
headline = prompt_openai('summarize the following into max 5 words:\n' + story, "")    
headline
'Datenmanagement: Erzeugung bis Löschung'

We now create a presentation file…

presentation = Presentation('ScaDS.AI_template.pptx')

… and add a first slide containing the headline and the authors.

add_title_slide(presentation, headline, authors)

We now split this story into parts to generate a slide for each part.

parts = story.split("\n\n")
len(parts)
13
for part in parts:
    
    image = draw_dall_e_image('draw an instructive image for this text section:\n' + part)

    headline = prompt_openai('summarize the following into max 5 words:\n' + part, "")    
    
    add_slide(presentation, headline, part, image)

    # save the PPTX file after adding a slide, just in case it crashes
    presentation.save(pptx_filename)

Enjoy!#

!explorer .