TIL a Cool PowerPoint Designer Hack

I don’t consider myself creative or artistic. The artistic bias probably goes back to school, where the requirement of an art elective ruined my chances at a 4.0 grade average (and exemplified by my Featured Image attempts, which even AI can’t seem to help me with).

The creative bias is that I usually can’t do it on demand. I’ve also learned that if you get out of your own way, creativity happens fairly naturally. This is similar to how Douglas Adams describes how one learns to fly. Anyway, one way to get over a lack of creativity and artistic sense is to let AI tools do it for you, and one that I find really handy for my handicap is PowerPoint Designer. (For those who think Designer isn’t AI, marketing is clearly doing it’s job, and perhaps missing the point, and here is proof— as long as the link is valid).

Personally, I don’t mind boring slides. I actually like have really basic slides where the purpose of the slide is for people to remember what we’re talking about when their minds inevitably wander. But, sometimes I am creating slides for other people, or need to meet the expectations of people with different opinions on the matter, so I need to make them a bit less boring, and designer is a great way to do that. One frustration I have with designer is that it so often gives me this message: Microsoft PowerPoint Designer "Sorry" message.

Usually this can be fixed by simplifying the slide, i.e., remove the cool graphic you added and let it focus on the text. Or you can split the graphic and text into separate slides and then combine the results after the magic happens.

Oh, and one word of caution: Copy your original slide before letting Designer have its way with it, because sometimes the new formatting is no longer easy to copy and paste.

Back to the cool hack part. My second annoyance with Designer, after it apologizing for having no suggestion of how to improve my work that clearly needs improvement, is that it gives so few suggestions. This seems to have gotten worst, and I suspect it is because those data centers are saving cycles for the AI that the marketing folks are calling AI. Recently, it was only giving me four or five options, many of which were just minot variations on the themes, like this:

PowerPoint suggestions for a slide with plain bullets.
PowerPoint suggestions for a slide with plain bullets.

I wasn’t too thrilled with any of the options, but I picked one just to move on and make some progress. Maybe an AI image would spruce it up enough (in the end, it did). Being the paranoid person who has lost early versions that I wished I could go back to, I made a copy first. Usually, when I make a copy, I start working in the copy. But this time, for no particular reason, I went back to the original…where Designer was showing entirely new options based on it’s own modification:

PowerPoint Designer suggestions after accepting a suggestion.
PowerPoint Designer suggestions after accepting a suggestion.

It seemed I had accidently cracked the code to get more options, like in the good ole days before everyone was using these tools, too. Just to prove my theory, I tried repeating the process, and sure enough…

PowerPoint Designer Keeps on Designing
PowerPoint Designer Keeps on Designing

I didn’t really find  an end to variations, though I admit that the quality of options generally declined, with an occasional interesting one coming up here and there. Full disclosure: this may have just been the raw material I started with, but that is back to my bias against my own creativity.

So, that’s my big discovery for the day. Well, there were really more, but I have to get back to “real work”, until this writing stuff actually starts paying some bills. Forward this to your friends (or enemies) if you would like to contribute to this hobby.

If you found this interesting, please share.

© Scott S. Nelson
Software Time and Complexity

Is your CI/CD missing the third C?

If you are reading this post you know that both C’s in CI/CD represent “Continuous” (and if you didn’t already know that, your curiosity is admirable…and, no, “curiosity” isn’t the third C).

Getting to CI/CD can be a challenge, especially if it isn’t set up as part of the first release. (Challenge is not our third C, either, though it is becoming apparent there are many words that start with C related to software systems, so we’ll ignore the false possibilities from here on out). Adding to the procedural challenge of timing, there is also the conceptual challenge of semantics. Some organizations define the continuous Cs as every time a commit is made to the repository; others say it begins with a merge after a review; some say that if it is done “correctly” (are you still counting the “C”s?) there is no need for a review; still others will say that hourly (or daily, or twice daily, etc.) counts; some say you only really need I or D continuously (and others will certainly debate that); and there are bound to be more that don’t come to mind at the moment. What those contiguous definitions of continuous have in common is that they are all correct, depending on the context.

The cruel thing about continuous is that, technically, if it ever isn’t, it never was and cannot be again. Which is not correct, because even when done perfectly, there will be the occasional hiccup and things will need to be re-calibrated to continue being continuous.

Except when they don’t.

When they don’t, there can be several symptoms that are confused with causes. At some point, commits became synonymous with the cards on the Kanban. Sometimes it’s because management thought it would be useful to automate tracking with branches, or people used build failures as a measurement of skill rather than assignment of bug fixes, or PRs are preferred over testing—despite the fact that this approach often leads to more production issues and longer MTTR.

So what prevents those problems (and others) from discontinuing (or preventing the adoption of) CI/CD? It’s the third C, and…

The third C is Culture.

CI/CD requires the adoption of a “shift left” mentality, which in turn requires a culture of fearless experimentation where testing before committing is done as a point of pride, and every time the tests pass is a reason to commit (or “another test passes”, if you are following TDD). This also requires using feature flags that are either centrally managed (which supports runtime management in production) or developer managed, which requires automated testing of the flag.

A successful CI/CD culture depends on the team’s attitude—an attitude built on one part pride, one part professionalism, one part discipline (maybe two parts), and is most easily maintained when it includes the participation of leadership (perhaps the next post will be about the missing “P’s” in technology).

So, after that long walk through what was really a short concept, the key takeaway is that if your team is struggling with starting or sustaining a true (because there are many that are in name only, and you know which ones) continuous pipeline, focus on fostering a cultural shift within your team before investing in tools.

If you found this interesting, please share.

© Scott S. Nelson

Why People Never Listen (to Me)

I received my weekly James Clear newsletter today. I almost filed with all the other newsletters I subscribe to and just never seem to have time to read. But then I remembered that I’m on PTO, and Clear lives up to his name, so I jumped in. Then stopped in my tracks when I got to:

“You have to work hard to discover how to work smart. You won’t know the best solutions until you’ve made nearly all the mistakes.”

My first thought was “Hmm”, followed by “that makes sense”, and then “but what is the point of trying to teach people how to do things?”.

I mentally spun on this for a while. I know that I learn from others (directly or indirectly via person, print, or video) faster if I have had some experience with the topic and struggled with doing or understanding, or at least dissatisfied with the results. I’m also familiar with constructivism and similar concepts where some level familiarity, even if only having heard the term in passing, makes it easier for the mind to grasp and incorporate details when they are presented.

Then I realized that what I struggle with is some of the qualitative terms in the statement, i.e.,

“You have to work hard to discover how to work smart. You won’t know the best solutions until you’ve made nearly all the mistakes.”

Is it impossible to learn how to work smart without having worked hard? If a student, mentee, trainee, etc. trusts the person teaching them and is highly and intrinsically motivated to learn, I think they can do so without the prior high level of effort. That said, I think that the skill of teachers (generically rather than academically, and based on skill of transferring knowledge as well as knowledge of skill) and the motivation of learners have been steadily declining and that this circumstance as an exception has become fairly rare.

As to the second of Mr. Clear’s sentences, I might be putting too fine of a point on my umbrage. I believe that one will appreciate how much better a solution is than alternatives if they have witnessed the outcomes of the others, and that appreciation will increase with experience over mere observation. I do, however, take issue with “nearly all” at several levels. The first is the fuzziness of it. Is it all but 1? Is it 99%? And I really truly believe that some, with that fuzzy level being at least less than half, of the mistakes is more than adequate for some people, especially those that are either impatient (while motivated) or highly self critical (a motivation that tries the patience).

My  protests aside, I think James Clear’s statement is accurate often enough to be accepted as a general (if not a hard and fast) rule. I am positive in my belief that his experience with people in this context is much broader than my own.

I do tend to wander in my writing, so let’s wrap up the thought on why people never listen. They do, but the absorption, retention, and results of that listening vary between individuals and over time. Some folks will get it right away because they are motivated and trust the source (and sometimes that motivation is just lack of self trust); some will have to prove it right before they believe it, and then they may experience the source has their own actions (not all, but some); some will filter it through their own thinking until they reach a threshold where they will try anything, even something that is presented as proven already to be effective; and some will just never get it, for a variety of reasons that could be it’s own book, let alone blog post.

No matter the motivation or outcome, if you are trying to share wisdom, be wise enough to know that you may need to both vary and repeat your message to eventually be heard. If you are trying to learn something, you may want to apply what you know earlier and more often so that you are well prepared to know more.

If you found this interesting, please share.

© Scott S. Nelson

Simplifying Deploy and Destroy with the SF CLI

Personally, I never had any problems  with the SFDX CLI, which is why I was surprised they were replacing it with the SF CLI. What I now sometimes struggle with is translating all of my cheat sheet references from one to the other, and the sifting through the plethora of search results that still refer to the SFDX way of doing things. OK, I know I can minimize the second part by setting the date range in my Google searches, but when I’m being lazy (or in a hurry, both of which are more common than I prefer) I use Perplexity.ai rather than Google.

Most recently my conversion conundrum cropped up with removing components that I had deployed through the CLI. I found a great SFDX syntax in Perplexity literally one day before it was slated to be retired. Here is the relevant part of the session that got me to the solution:

Question: cli to delete objects from an org

Answer:
To delete objects from a Salesforce org using the CLI, you can use the destructive changes process. Here’s how to do it:

Step 1: Create Destructive Changes XML

Create a file named destructiveChanges.xml with the following structure:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>ObjectName1__c</members>
        <members>ObjectName2__c</members>
        <name>CustomObject</name>
    </types>
</Package>
Replace ObjectName1__c and ObjectName2__c with the API names of the objects you want to delete.

Step 2: Create Empty Package XML

Create a file named package.xml with the following content:
xml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <version>62.0</version>
</Package>

Step 3: Deploy Destructive Changes

Run the following Salesforce CLI command:
bash
sfdx force:mdapi:deploy -d . -w -1 -u YourOrgAlias
This command deploys the destructive changes to your org:
  • -d . specifies the current directory as the deployment source
  • -w -1 waits for the deployment to finish
  • -u YourOrgAlias specifies the target org alias

Additional Considerations

  • Ensure you have the necessary permissions to delete objects in your org.
  • Deleting objects will also delete all associated records and metadata (fields, validation rules, etc.).
  • Some objects may have dependencies that prevent deletion. You might need to remove these dependencies first.
  • Always test this process in a sandbox environment before applying it to production.
  • Consider backing up your metadata and data before performing destructive changes.
If you need to delete other types of metadata (like Apex classes, Visualforce pages, etc.), you can include them in the destructiveChanges.xml file using the appropriate metadata type names.
Remember, this process permanently deletes the specified objects and their data from your org, so use it with caution.

When I ran it, it worked perfectly, and output a warning that it would no longer work the next day (I did not preserve the message content, but I can tell you the date was 11/4/24 because UpNote metadata is useful). As I mentioned, I’m often in a hurry, so I often make mistakes, and what has kept me in technology since the original Wolfenstein was released is always making sure I have a way of undoing whatever I do. So I decided to go find the cool new sf CLI solution. Which was not terribly clear to me. I found the documentation a bit confusing. Going back to the old-fashioned Google search (trust me, it pains me more to write “old-fashioned Google search” than it does for you to read it), I found a Trailblazer Community post by Max Goldfarb that greatly clarified how to make the new sf call.

I have since refined the process clarified by Max once I read the documentation while in less than my usually rushed efforts. First, I keep that step 2 XML that Perplexity gave me stored in my repo as antiPackage.xml, the full path being manifest\destructiveArchive\antiPackage.xml. I could then generate the destructive xml with:

sf project generate manifest --source-dir force-app/main/default/[WHATEVER-I-WANT-TO-DESTROY] --type destroy

and then run my simplified killer command:

sf project deploy start --manifest manifest/destructiveArchive/antiPackage.xml --pre-destructive-changes manifest/destructiveArchive/destructiveChangesALL.xml -o [ALIAS]

and boom! stuff removed. I even keep a set of destructive xmls in a special folder (you may have noticed it in the command above). I continued to use this happily for a few weeks.

Today I was messing with a single component that was giving me problems (or, more accurately, I was giving it problems by building it incorrectly) and started by removing just it. Then I went about making my fixes and, feeling less hectic than usual, decided to have a package.xml just for it so the deployment would go faster (yes, I know I can do that with a right-click, but once I am comfortable with a CLI, I prefer it, and it lets me make sure that my eventual release script will have fewer issues). It was very small, which made the content leap out at me more, and, so I realized…There is no difference between the XML output with or without the “–type destroy” switch!

So now I just keep one XML for each context in manifest\deployArchive and reference it for both deploy and destroy.

If you found this interesting, please share.

© Scott S. Nelson