0

I have a build a Python script that uses python-pptx module to generate a powerpoint deck. The code runs over 300 lines of code due to various formatting. So I plan to split into several sub-functions so that it is easy to maintain in future.

Given below is a sample of what I have tried:

Created a sub-function called sub_func() as below

def sub_func():
    # create presentation with 1 slide ------
    prs = Presentation()
    slide = prs.slides.add_slide(prs.slide_layouts[5])

    # define chart data ---------------------
    chart_data = CategoryChartData()
    chart_data.categories = ['Zone1', 'Zone2', 'Zone3']
    chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

    # add chart to slide --------------------
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
    slide.shapes.add_chart(
XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data
    )
    prs.save('chart-00.pptx')

Saved the above to sub_func.py

Given below is my main function:

from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Inches
from sub_func import sub_func

def func():
    # create presentation with 1 slide ------
    prs = Presentation()
    slide = prs.slides.add_slide(prs.slide_layouts[5])

    # define chart data ---------------------
    chart_data = CategoryChartData()
    chart_data.categories = ['East', 'West', 'Midwest']
    chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

    # add chart to slide --------------------
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
    slide.shapes.add_chart(
XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data
    )
    ##Calling the sub-function below

    sub_func()

    prs.save('chart-01.pptx')

This above generates a powerpoint file but does not execute the sub function. Could anyone advice as to where am I going wrong.

Edited code:

from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Inches
from subfolder import func1
from pptx.parts.chart import ChartPart
from pptx.parts.embeddedpackage import EmbeddedXlsxPart

def func():
    # create presentation with 1 slide ------
    prs = Presentation()
    slide = prs.slides.add_slide(prs.slide_layouts[5])

    # define chart data ---------------------
    chart_data = CategoryChartData()
    chart_data.categories = ['East', 'West', 'Midwest']
    chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

    # add chart to slide --------------------
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
    slide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy,chart_data)

    ##Calling the sub-function below

    def Add_Slide(self):
        xml_slides = prs.slides._sldIdLst
        xml_slides1 = prs1.slides._sldIdLst
        slides = list(xml_slides)
        slides1 = list(xml_slides1)
        xml_slides.append(xml_slides1)

    prs.save('chart-01.pptx')

Given below is the sub function:

from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Inches


def func1():
    # create presentation with 1 slide ------

    prs1 = Presentation()
    slide = prs1.slides.add_slide(prs1.slide_layouts[5])

    # define chart data ---------------------
    chart_data = CategoryChartData()
    chart_data.categories = ['East', 'West', 'Midwest']
    chart_data.add_series('Series 1', (100.2, 21.4, 16.7))

    # add chart to slide --------------------
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
    slide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy,chart_data)

Using the above edited code, I see the main function gets executed but the sub function does not get executed, is it because it does not have a prs.save for the sub-function. Could you please advice..

hello kee
  • 289
  • 2
  • 6
  • 17

3 Answers3

3

is sub_func.py in your python path? If it is just in your working directory, this will most likely result in a ModuleNotFoundError. You'll need to use a relative import then

from .sub_func import sub_func

If that is not the problem, but just the fact that it has no effect, then that is because you didn't tell it to have an effect. It creates a presentation with 1 slide, but doesn't save it. It doesn't get returned by the method, and the return value is not captured by a variable

Maarten Fabré
  • 6,938
  • 1
  • 17
  • 36
  • I think the module is working fine, otherwise, he'd get an error. However, I agree with you. He is not saving the presentation. That's the problem. – André Pacheco Feb 08 '19 at 11:18
  • @Maarten I have also tried saving the file in the sub-function as well but it still does not help – hello kee Feb 08 '19 at 11:19
0

I don't think so issue is due to import statements. You are re-initialling the presentation object again in sub_module.

prs = Presentation()

you can pass the prs object to sub_func like below and try if problem is getting solved

main function

from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Inches
from sub_func import sub_func

def func():
    # create presentation with 1 slide ------
    prs = Presentation()
    slide = prs.slides.add_slide(prs.slide_layouts[5])

    # define chart data ---------------------
    chart_data = CategoryChartData()
    chart_data.categories = ['East', 'West', 'Midwest']
    chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

    # add chart to slide --------------------
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
    slide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy,chart_data)

    ##Calling the sub-function below

    sub_func(prs)

    prs.save('chart-01.pptx')

and in sub_func do the changes like below

def sub_func(prs):
    # create presentation with 1 slide ------
    # prs = Presentation() -------Remove this line
    slide = prs.slides.add_slide(prs.slide_layouts[5])

    # define chart data ---------------------
    chart_data = CategoryChartData()
    chart_data.categories = ['Zone1', 'Zone2', 'Zone3']
    chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

    # add chart to slide --------------------
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
    slide.shapes.add_chart(
XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data
    )
    prs.save('chart-00.pptx')
PythonUser
  • 706
  • 4
  • 15
  • a better alternative might be to return `prs` instead of saving it to an arbitrary filename. You can additionaly also accept `prs` as a parameter with default argument `None`, and do `prs = Presentation()` if `prs is None`. That way you won't break other uses of this sub_func – Maarten Fabré Feb 08 '19 at 14:53
  • `Presentation()` is a constructor. Calling it again in sub_func() creates a new, separate presentation that can be manipulated and saved without affecting any other `Presentation` object (as long as it's saved with a distinct name, as it is). @MaartenFabré is on the right track here though, there's no obvious need to create a separate presentation unless you wanted each slide to be in its own .pptx file (which has its use cases but is uncommon). – scanny Feb 08 '19 at 16:49
  • @scanny , I came across some code online that tries to append slides from different files but it still does not help.. I have updated the initial post with this code. Could you please advice. Thanks.. – hello kee Feb 14 '19 at 11:25
  • That would be a separate question hello kee. Have a search on that topic and if you don't find what you're looking for post a new question focused on that topic specifically. – scanny Feb 14 '19 at 17:56
-1
from .sub_func import sub_func