Python Code Review: LibreOffice Automation and the Python Standard Library

Real Python · Beginner ·🛠️ AI Tools & Apps ·9y ago

Key Takeaways

This video demonstrates a Python code review of a LibreOffice automation script, focusing on PEP 8 cleanup and best practices using the Python Standard Library.

Full Transcript

hey there I think it's time for another Python code review unplugged episode here and I got this script or Python script code snippet here from from Roger who send it over to me and via Twitter and asked me to give him some feedback on that and this is short and sweet so I'll be able to go over this relatively quickly I think but there are a couple of things in there that I think could be improved a little or just cleaned up a little bit and so hopefully seeing how to do that will be useful to you alright so let's dig right in so I haven't really looked at this before but basically all I did is I loaded this into my editor so I'm using sublime text for this we've kind of to set up that I explained on my website and I'm using a built-in linter here so this is giving me feedback on well it's basically running flake 8 on the Python source code and giving me inline feedback on what's going on here so in this case like one of the first things I usually do in the code review like this or it's sort of like a cleanup pass like this is I would just make sure it you know the code is Peppe compliant and it's kind of formative nicely so probably the first thing I would do here is actually get rid of this commented outline and then I would get my import straight so I like to split these up so this you know thing looks like it's a third-party thing that is used for interacting with LibreOffice so this is a like a libreoffice script to do some automation with libreoffice and so I imagine this is something LibreOffice specific and what I like to do is I kind of split up my my sort of Python built-in or standard library libraries put them on top and then below that I put the third-party libraries now this one here I would probably turn that into a dark string you know just for great consistent and all of this stuff is I know is very nitpicky to the Gris but I feel like it really helps structuring the code in a way that makes it easy year two well just to understand and easier to work with so I like to do that okay yeah so we've got this uno thing honestly I I don't feel like this comment is giving me giving me a lot here like we're importing this here like to me it seems pretty clear that we would need it later so I probably actually get rid of this I would get rid of the like personally I don't I don't usually try not to do stuff like that I did that in the past you know trying to sort of embellish my source files with these separators and stuff but I stopped doing that I stopped doing that like I know several years ago and never came back to it because I feel like it's often doesn't add a lot of value I mean I might occasionally do it but in this case I feel like it's not really adding adding a ton of clarity yeah so another thing I'm seeing here like just you know kind of glancing at this is that this is longer than the 80 lines the 80 characters per line standard here so that's why I'm getting a bunch of wrapping and also you know for the sake of you watching this video I'm also gonna change that to be fully paid compliant so it makes it a little bit easier to read in the video so yeah so I probably would do here so again turn this into like a nice and clean dark string you know just wrap this nicely and okay so maybe this needs to be called create dock because it's that's something that that is called or that's how Libre Office calls it but I personally I would like I would call this create underscore dock yeah and then okay so here we're grabbing the context and then looks how we're doing anything with the context nope so I would probably do something like this oh wait okay we do need the context nevermind we don't really need the service manager right so I might actually do something like this like I know it's some sometimes it's um it's not a good idea to have these like long nested lines here but I feel like this actually looks better now and there's not really benefit to capturing that in a variable and then I'm just I'm gonna take advantage of the the open parentheses continuation here this looks like this which not neat this space here yeah and then I'm just gonna sort out here the the spacing here and then I usually like to indent stuff like that right and then here in this next line open a writer document probably also do the same formatting trick personally I'm not a huge fan of using this syntax to create a tuple so I would maybe just use something like this to make sure you know like to make the the intent here perfectly clear that we're just creating an empty tuple for to me that's clearer but obviously the other one would also work yeah so I'm so I'm having some thoughts around this these constants here maybe if they should be made actual constants in the code sorta on the fence with that it's probably probably fine to leave it like that so we've got some debug stuff in here so I'm just gonna get rid of that as well okay so we're grabbing a document text are we ever using this for anything oh yeah okay so we're keeping track of that grabbing the cursor I guess we need to take the cursor the tab so I'm thinking actually that's the taps thing this would this would make a pretty good constant so I take that out actually place it here and then I would do this yeah and make that a constant and then here getting getting ahead of myself here okay so now we're creating the stuff grabbing the desktop and doing the creating the document here so okay so it looks like we're doing some date parsing here this works only if the year is four digits and the day month are two digits oh yeah okay because we're splitting we're splitting that string here and then we're reassembling that okay so so a couple of ideas here probably the first thing that I would do is that I would extract this into a function right because every time I you have something like this where you're doing a bunch of operations and calculating a bunch of intermediate values only to combine them into one sort of result then that's a pretty good candidate for a function right because in this case we're only using two day date and I'm seeing that down here so what I would probably do is I would as a first step take this out and then create this sort of helper function let's just call it format date and this would take a this would take a date and then we could change this to be a function and we could say wait so this is what we're passing in here right so I would extract that out and I would say this is how formatting it and then I would say today date equals format date of the current date time date end know day time determine okay so I think you can actually do the day time date today so I'm gonna do let me check this date time date today yeah so this is gonna be the same as doing daytime daytime now date right because daytime now gives the full date time with the time and we just want this so we can we can shorten this and the reason whoops the reason I passing this in as a as a date is to have a little bit more flexibility and then later we could potentially also write tests for this and I'm gonna rename this just to make that nice and Python E or pythonic here with the underscore okay let's just clean up some of the spacing here maybe that was done to align yeah I guess that's aligning these these guys here yeah you know what I'm gonna get rid of that but it might actually not be a bad idea to have this this alignment here it might not really hurt okay so let's see so we've got this actually I think this is time it's time for another function here but we can take a look at that all right so here we're doing a bunch of date time or like date formatting now okay so a couple of things here we could I guess we could keep that which gets like this I mean this would technically work but what I think could be improved about this is there's Python has a built-in way to format dates this is something that I need to Google so just fire up a browser here alright so the date class has a stir f time that you can use or stir f time function that you can use to create a formatted string based on the the value of that date so I would probably factor this to something like this and we might actually decide to to bring this back into the the other function here so I probably do something like this where I'm doing date stir F time and it looks like we want a month here I'm gonna go back here into the interpreter just to play with this a little bit so there's a couple of options here okay let me let me do it this way so I'm gonna say I'm gonna grab today's date right so this is today and then what I can do with this I could either use ISO format which sorry that's the wrong one today dot ISO format so I could either use ISO format here which would format my date like this which it looks like that's not what you want right you want day month here so for that we need to do stir if time and then we need to find out what the right formatting string is we need to construct here so we want a day which would be percent d and we want % m and you can decide whether or not these should be 0 padded so i think you want 0 padded here right because if the way you're splitting this yeah okay so we probably want to D slash em and then let's see if if it's that you may want this yeah okay it's like a mini formatting language that you can use to build a perfect formatting string for your your dates here and I think this is exactly what we want it so we can say date star F time and now this replaces all of this code and it's like a little bit fiddly you know character manipulation here so based on the fact that we're only using this in one place I'm actually tempted to get rid of this function again and to do to do this yeah and I wait so let's I wanted to see if I could get the date here yeah but we'll just all do it all in one one line right so okay so this is this would be the same thing and now now we can talk about this this guy here so I'm seeing some duplication here for example I mean everything all the way up here is usually the same and then I don't know what the zero does and we want to sort of terminate those lines with a slash end so it might actually sense it might make sense to introduce a helper function for that so I would probably do something like this [Music] and our text takes the text so is this called text I guess is the dark text make sure this is clear dark text and then we want the actual the actual text your not named very well and we want the indentation then I would say out okay so we need talk text cursor all right and then I would say so I we need to pre-paint the tabs and this stuff so I would say do an if statement and then we just modify text to be tabs plus plus text + /n and otherwise I would say we're just gonna do this and then just use this text here and just remember what this needs to look like yeah right and then here this would be the same for everything it's gonna automatically indent so I could just go along replace all of these we also don't need the the the new line at the end and then here we just want the empty string and not half the indentation because we want a completely empty line right so get rid of that but yeah so this is probably what I okay so actually yeah alright and then okay so now dark text isn't defined so we would need to that's actually let's rename this yeah so this is this is probably what I would do as a first first pass on this okay so and I see you use different quotes here so I want to I want to match that quote style um yeah this is probably what I would do here and as a first pass just a quick clean up okay one more thing alright it's a quick cleanup I hope this script still works because I made a couple of changes and I don't have LibreOffice installed here so I can really be a hundred percent sure I didn't introduce some kind of bug or mistake here but for for a first pass I think this is a little bit more cleaned up and probably like changing this here with the using to use ster F time instead of doing the date manipulation manually that probably had the biggest impact on readability so maybe that's something you can like that's a trick you can pick up in the future but other than that gap this is probably what I would do like we could argue about like you know factoring out some more of that stuff and like you could actually turn this into a list and just have it like go over the lines and apply them look I think this is okay you don't want to overdo these things because then it just gets a little bit ridiculous if this is just like a simple automation script but but overall I think this is how I would change this and I think that improved the readability and the formatting a bit alright so I hope this was helpful and yeah that's it for me happy Pythian ii

Original Description

https://dbader.org/python-mastery ► Adopting an expert's mindset is the biggest factor for becoming great at Python Python Code Review: Unplugged – Episode 5: Code Review for Roger This is a Python code review I did for Roger's LibreOffice automation script. I do a PEP 8 cleanup pass on the code and then start refactoring and extracting functions to make the program easier to read. In one instance I was also able replace several lines of code with a built-in function from the Python standard library. You can get the original and refactored version of Roger's script at the link below: https://gist.github.com/dbader/8006381c5ca340274936ff0d5b1b2942 Did I miss anything? Anything that could be improved? Refactoring and talking at the same time is hard :) Leave a comment below and let me know! FREE COURSE – "5 Thoughts on Mastering Python" https://dbader.org/python-mastery SUBSCRIBE TO THIS CHANNEL: https://dbader.org/youtube * * * ► Python Developer MUGS, T-SHIRTS & MORE: https://nerdlettering.com FREE Python Tutorials & News: » Python Tutorials: https://dbader.org » Python News on Twitter: https://twitter.com/@dbader_org » Weekly Tips for Pythonistas: https://dbader.org/newsletter » Subscribe to this channel: https://dbader.org/youtube
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Real Python · Real Python · 46 of 60

1 A better Python REPL – bpython vs python interpreter
A better Python REPL – bpython vs python interpreter
Real Python
2 Introducing large-type.com – A Utility Website
Introducing large-type.com – A Utility Website
Real Python
3 Reading Hacker News Without Wasting Tons of Time
Reading Hacker News Without Wasting Tons of Time
Real Python
4 Forward References and Python 3 Type Hints
Forward References and Python 3 Type Hints
Real Python
5 Using Sublime Text as your Git Editor
Using Sublime Text as your Git Editor
Real Python
6 Python Code Linting and Auto-Complete for Sublime Text
Python Code Linting and Auto-Complete for Sublime Text
Real Python
7 Make your Python Code More Readable with Custom Exceptions
Make your Python Code More Readable with Custom Exceptions
Real Python
8 Write Better Tests with Sublime Text's Split Layout Feature
Write Better Tests with Sublime Text's Split Layout Feature
Real Python
9 How to Use Sublime Text from the Command Line
How to Use Sublime Text from the Command Line
Real Python
10 Rename Variables with Multiple Selection in Sublime Text
Rename Variables with Multiple Selection in Sublime Text
Real Python
11 Sublime Text Settings for Writing PEP 8 Python
Sublime Text Settings for Writing PEP 8 Python
Real Python
12 Write Cleaner Python with Sublime Text's Indent Guides
Write Cleaner Python with Sublime Text's Indent Guides
Real Python
13 Sublime Text Whitespace Settings for Python Development
Sublime Text Whitespace Settings for Python Development
Real Python
14 Function Argument Unpacking in Python
Function Argument Unpacking in Python
Real Python
15 Python Code Review: Debugging and Refactoring "Conway's Game of Life" +  Automated Tests
Python Code Review: Debugging and Refactoring "Conway's Game of Life" + Automated Tests
Real Python
16 Using "get()" to Return a Default Value from a Python Dict
Using "get()" to Return a Default Value from a Python Dict
Real Python
17 A Python Shorthand for Swapping Two Variables
A Python Shorthand for Swapping Two Variables
Real Python
18 Python Code Review: Refactoring a Web Scraper, PEP 8 Style Guide Compliance, requirements.txt
Python Code Review: Refactoring a Web Scraper, PEP 8 Style Guide Compliance, requirements.txt
Real Python
19 Click & Jump to Test Failures from the Command Line (iTerm2)
Click & Jump to Test Failures from the Command Line (iTerm2)
Real Python
20 Setting up Sublime Text for Python Developers
Setting up Sublime Text for Python Developers
Real Python
21 Sublime Text + Python Guide Overview
Sublime Text + Python Guide Overview
Real Python
22 Python Code Review: Adding Pytest Tests to an Existing Python Web Scraper
Python Code Review: Adding Pytest Tests to an Existing Python Web Scraper
Real Python
23 Type-Checking Python Programs With Type Hints and mypy
Type-Checking Python Programs With Type Hints and mypy
Real Python
24 A Shorthand for Merging Dictionaries in Python 3.5+
A Shorthand for Merging Dictionaries in Python 3.5+
Real Python
25 Python Code Review Flask Web Security Tutorial + Virtualenvs, requirements.txt
Python Code Review Flask Web Security Tutorial + Virtualenvs, requirements.txt
Real Python
26 My Python Code Looks Ugly and Confusing – Help!
My Python Code Looks Ugly and Confusing – Help!
Real Python
27 Setting Up a Programmer Portfolio/Developer Blog – How To Get Started
Setting Up a Programmer Portfolio/Developer Blog – How To Get Started
Real Python
28 Do I Need a GitHub/GitLab/Bitbucket Profile as a Developer?
Do I Need a GitHub/GitLab/Bitbucket Profile as a Developer?
Real Python
29 Programmer Portfolio – Example and Walkthrough
Programmer Portfolio – Example and Walkthrough
Real Python
30 How to Get Your 1st Speaking Gig at a Tech Conference
How to Get Your 1st Speaking Gig at a Tech Conference
Real Python
31 How to Build Your Public Speaking Skills as a Developer
How to Build Your Public Speaking Skills as a Developer
Real Python
32 The Object-oriented Version of "Spaghetti Code" is "Lasagna Code" ?!
The Object-oriented Version of "Spaghetti Code" is "Lasagna Code" ?!
Real Python
33 Setting up Sublime Text for Python Developers – Lesson #1
Setting up Sublime Text for Python Developers – Lesson #1
Real Python
34 Cool New Features in Python 3.6
Cool New Features in Python 3.6
Real Python
35 "is" vs "==" in Python – What's the Difference? (And When to Use Each)
"is" vs "==" in Python – What's the Difference? (And When to Use Each)
Real Python
36 Emulating switch/case Statements in Python with Dictionaries
Emulating switch/case Statements in Python with Dictionaries
Real Python
37 Python Function Argument Unpacking Tutorial (* and ** Operators)
Python Function Argument Unpacking Tutorial (* and ** Operators)
Real Python
38 What Code Should I Put On My GitHub/GitLab/BitBucket Profile?
What Code Should I Put On My GitHub/GitLab/BitBucket Profile?
Real Python
39 A Crazy Python Dictionary Expression ?!
A Crazy Python Dictionary Expression ?!
Real Python
40 String Conversion in Python: When to Use __repr__ vs __str__
String Conversion in Python: When to Use __repr__ vs __str__
Real Python
41 Method Types in Python OOP: @classmethod, @staticmethod, and Instance Methods
Method Types in Python OOP: @classmethod, @staticmethod, and Instance Methods
Real Python
42 Optional Arguments in Python With *args and **kwargs
Optional Arguments in Python With *args and **kwargs
Real Python
43 Python Context Managers and the "with" Statement (__enter__ & __exit__)
Python Context Managers and the "with" Statement (__enter__ & __exit__)
Real Python
44 Installing Python Packages with pip and virtualenv / venv
Installing Python Packages with pip and virtualenv / venv
Real Python
45 "For Each" Loops in Python with enumerate() and range()
"For Each" Loops in Python with enumerate() and range()
Real Python
Python Code Review: LibreOffice Automation and the Python Standard Library
Python Code Review: LibreOffice Automation and the Python Standard Library
Real Python
47 Managing Python Dependencies With Pip and Virtual Environments – Lesson #1
Managing Python Dependencies With Pip and Virtual Environments – Lesson #1
Real Python
48 Python Tutorial: List Comprehensions Step-By-Step
Python Tutorial: List Comprehensions Step-By-Step
Real Python
49 Leveraging Python's Implicit "return None" Statements
Leveraging Python's Implicit "return None" Statements
Real Python
50 What's the meaning of underscores (_ & __) in Python variable names?
What's the meaning of underscores (_ & __) in Python variable names?
Real Python
51 Python Data Structures: Sets, Frozensets, and Multisets (Bags)
Python Data Structures: Sets, Frozensets, and Multisets (Bags)
Real Python
52 Writing automated tests for Python command-line apps and scripts
Writing automated tests for Python command-line apps and scripts
Real Python
53 How to find great Python packages on PyPI, the Python Package Repository
How to find great Python packages on PyPI, the Python Package Repository
Real Python
54 Immutable vs Mutable Objects in Python
Immutable vs Mutable Objects in Python
Real Python
55 PyPI vs Warehouse, the Next-Generation Python Package Repository
PyPI vs Warehouse, the Next-Generation Python Package Repository
Real Python
56 pep8.org — The Prettiest Way to View the PEP 8 Python Style Guide
pep8.org — The Prettiest Way to View the PEP 8 Python Style Guide
Real Python
57 My Experience at PyCon 2017 in Portland
My Experience at PyCon 2017 in Portland
Real Python
58 Pylint Tutorial – How to Write Clean Python
Pylint Tutorial – How to Write Clean Python
Real Python
59 "Reverse a List in Python" Tutorial: Three Methods & How-to Demos
"Reverse a List in Python" Tutorial: Three Methods & How-to Demos
Real Python
60 Python Refactoring: "while True" Infinite Loops & The "input" Function
Python Refactoring: "while True" Infinite Loops & The "input" Function
Real Python

This video teaches how to review and improve Python code for LibreOffice automation, focusing on PEP 8 and best practices. It's essential for Python developers to master code review skills to write high-quality code. By following the steps outlined in the video, viewers can improve their code quality and automation skills.

Key Takeaways
  1. Import the necessary libraries
  2. Define functions for automation tasks
  3. Use PEP 8 to cleanup and format the code
  4. Apply best practices for code organization and readability
  5. Test the automated script
💡 Applying PEP 8 standards and best practices is crucial for writing high-quality Python code, especially when automating tasks with LibreOffice.

Related Reads

Up next
How to Get Your Brand Cited by ChatGPT, Claude and Gemini
Arvow
Watch →