• Become a Power user Intro to AutoHotkey Intermediate AutoHotkey Intermediate Objects GUIs are Easy w/AutoHotkey Painlessly switch from V1 to V2

February AutoHotkey Newsletter

24th of February AutoHotkey Newsletter

Howdy %Name%,

I’m one to do my best to “practice what I preach”.  Many times, Jackie and I have talked about how important it is to write “pseudocode” before you actually program.  Lately I’ve taken this to heart and make sure that, when I start a new script,  I quickly write out several lines of text that describes my goals / what I want to achieve.

The more I do it, the more it’s been helping! 👍

First, in case you’re not aware of what it is: Pseudocode is a human readable description of the steps planned steps in your script. Pseudocode is intended for human reading (not your AHK programming code).

Now that I’m writing pseudocode more frequently my scripts are far better organized and much more likely to take into account things that I wouldn’t normally think of. Also, by doing it more often, I’ve gotten to a point where it takes almost no time to do!

Think of it more as writing a 1️ st draft.  Don’t try and get anything “perfect”.  Don’t worry about misspellings or grammatical errors.  Just make short notes to yourself about what you’re going to do.  Trust me, after doing this for a while you’ll be so glad you started!

Are you writing pseudocode before you program?

Now on with the show…

ActiveX vs. GDIp

Did you catch the great video last week with where Dimitri Geerts created some amazing GUIs with an ActiveX GUI in 🅰️🇺t🇴🇭🇴tk🇪🇾 🇻2️?  At the end of the video we were wondering how GDI would stack-up in comparison.  Well Dimitri decided to put it to the test and build the game of life in both ActiveX and GDI.  This is a really fun video where we demo the comparisons and discuss what is actually being done with the code.

GDI vs ActiveX Which is faster 🚀? The answer may surprise you!

Arrays & Pseudo Arrays

Speaking of “pseudo” things, one thing that confuses people new to AutoHotkey are the usage of Arrays and Pseudo Arrays.   In this video RaptorX walks us through using them in a command.  BTW- I had a call with Isaias Baez / RaptorX last night and he’s ready to come back to work! 😁  Can’t wait to get back in our grove!

arrays vs Pseudo arrays and using a dynamic variable

Are you cheating at work?

Continuing on with this concept of “is AutoHotkey cheating at work” I Ryan W. (Automation expert and marketing guru) his thoughts on the idea.  It turned into a great chat (thankfully I’d recorded it).  We continued on discussing how to evangelize AutoHotkey.

The book I mentioned is from John Carlton: The Entrepreneur’s Guide To Getting Your Shit Together.  Chapter 2 has a ton of amazing quotes to live by.  I’m going to include some of them at the bottom of the newsletter but there are a lot more in the book.  The book mentioned by Ryan is Darren Hardy: The compound effect. It’s an amazing book with great ideas and tips how to be more productive!

Cheating at work & how to better evangelize automation with Ryan Wells

🔎Searching / Replacing text within files

Do you need to find some code but don’t know the file name / location?  I’ve been using grepWin for a really long time.  It’s an amazing free tool that allows you to, easily, find and replace text within files.  It’s allows you to filter on many things to limit the search and allows you to see the content of the file w/o opening it.  Here I walk through a few examples how to use GrepWin.

grepWin for Searching and Replacing Text within files: Must have tool!

The-Automators’ Podcast

What we’re reading 📚

AutoHotkey GURU 👨‍🏫 Interview: Joe Winograd

For those of you on the AutoHotkey forum, you’ll be familiar with Joe Winograd.  He runs/operates a business where he develops code for clients.  In our AutoHotkey Guru interview I got to know him better and picked up some great AHK tips from one of the few people I know that works in AutoHotkey but IS A PROGRAMMER!  He has some great content on working with PDFs and AutoHotkey.

Examples of AutoHotkey |AutoHotkey Experts: Joe Winograd

Productivity tips  ⚡️

Short and sweet: Kill your social  pages (Facebook, LinkedIn, etc.) while you’re working!

A spot of Humor 🤣

Do you watch The IT Crowd?  It’s one of the funniest shows I’ve ever seen🤣. They really nail many aspects of corporate world and geeks🤓!   Here’s a short excerpt from S1 Episode 2.  Freaking genius!  The main tagline in the show is “Have you tried turning it on and off again”?  What a great burn 🔥 on Windows!

The IT Crowd - Series 1 - Episode 2: Fire!

Beta testing Clipboard 📋 manipulation tool

Many of us have this need but don’t even realize it!  Wouldn’t it be cool if you could write some rules that would monitor your clipboard and apply them w/o you having to think about it?  That’s just one of the uses of Quick Access Clipboard;  a new tool from Jean Lalonde (author of QAP).  He’s currently looking for beta testers to QAC.  To learn more take a look at this video if you’d like to learn more and you can go here.

Automating Clipboard replacement with QAC-Looking for Beta testers

Quotable quotes 🗣️ 💭

  • The secret to getting ahead is getting started. The secret of getting started is breaking your complex, overwhelming tasks into small manageable tasks, and then starting on the first one. — Mark Twain
  • You’ll never be criticized by someone who is doing more than you. You’ll always be criticized by someone doing less —Denzel Washington
  • Effective performance is preceded by painstaking preparation. — Brian Tracy

Live AutoHotkey Support Tomorrow

Don’t forget on Friday’s you can get free AutoHotkey support on my YouTube channel.  Or you can sign up for reminders and join the zoom room.

Intro to AutoHotkey HotStrings with AutoHotkey Intermediate AutoHotkey GUIs are Easy with AutoHotkey Intro to DOS & AutoHotkey AutoHotkey FAQ AutoHotkey FAQ


Joe and staff

P.S.  Special thanks to the following for purchasing multiple AutoHotkey Udemy courses this month!

6 Peter E. 2 Marc P. 2 Ewelina W.
3 Sam B. 2 Malgorzata M. 2 Ewa N.
3 Carlos M. 2 Magdalena O. 2 Emilie Viola H.
3 Łukasz G. 2 Magdalena F. 2 Doug B.
2 VCALD. 2 Maciej W. 2 Damian G.
2 Sylwia B. 2 Lidia D. 2 Claudia J.
2 Swen B. 2 Kosma W. 2 Charles Oduk II.
2 Sean M. 2 Kinga C. 2 Cezary K.
2 R. 2 Katarzyna U. 2 Cesar A.
2 Qun G. 2 Karolina S. 2 Bartosz B.
2 Przemysław M. 2 K. 2 B.
2 Piotr Pawel B. 2 Justyna K. 2 Annet S.
2 Paulina D. 2 Joanna R. 2 Anna C.
2 Natalia P. 2 J. 2 Anna B.
2 Monika B. 2 Izabela K. 2 Alicja C.
2 MateuszH. 2 Iwona S. 2 Aleksandra P.
2 Mateusz T. 2 Iwona Granacka-P. 2 Agnieszka W.
2 Mateusz J. 2 G. 2 Abdulmalik A.

Double P.S.  Quotes from John Carlton: The Entrepreneur’s Guide To Getting Your Shit Together

  • It’s not how much you screw up that counts. Nope. It’s how you fix your messes that matters.
  • You must stop expecting perfection — either from yourself, or your employees, or your customers and clients. It will never happen.
  • Life isn’t a calm pond — it’s an unpredictable ocean… you gotta learn to enjoy the ride, no matter what.
  • Real tragedy is having a loved one pass away, or getting bad news from the doctor.  Everything else is just a small bump on the road as you haul ass through life.
  • Live below your means. And avoid all debt — if you can’t pay cash-in-full, don’t buy it. Let your thrill be in your accomplishments, not the toys you can suddenly afford on credit.
  • Put aside a healthy pile of “Up Yours” money, so you can walk away from any situation you don’t like, and know you’ll survive.
  • Be a good animal. Sweat a little bit every day, sleep well, eat well, purge your system, live like a warrior-poet. You can monitor how healthy you are by walking up a hill.
  • Learn some basic self-defense, today. The first thing a mugger does to a mark is knock you down –most people can’t handle any jostling at all, and freeze. The simple confidence of knowing what your options are — and where the “soft targets” are on an attacker — can save your life.
  • Do the right thing every time, as a habit. If you’re not clear on what the right thing is, that means you’re facing another life lesson. Figure it out. The test begins now.
  • Say “sorry” and “I love you” often and without self-consciousness
  • Take responsibility for your actions. This simple habit has profound consequences you will learn to enjoy. Fix what you break, clean up your mess, watch your buddy’s back.
  • You want it, you take it, you pay the price. There really is no free lunch.
  • If what you’ve done over the past 5 years hasn’t worked for you, then change what you’re doing. Or the next 5 years will be one long boring re-run of the same bullshit.
  • Wake up. Challenge your belief systems. It’s better to realize you’ve been wrong for years, than to stubbornly hold onto a delusion that holds you back.
  • Stop doing things that don’t work. Too many people go through their entire lives marrying the same type of mate over and over again, making the same behavior mistakes, and making excuses for themselves.
  • Stop making excuses. I don’t care how badly your parents, or your teachers, or the system screwed up your head. You’re old enough to make the decision to start over and rewrite your script. Nothing will change for you until you do.
  • Keep a master list of long-range goals
  • Accept defeat with grace. Learn your lesson, adjust, and plan for victory next time out.  Know how to cheat. Don’t do it, but understanding the game thoroughly requires knowing how others take advantage.
  • Work hard, play hard. Think harder.
  • Just do it. The meek may inherit the earth, but only after the bold are through with it
  • It it’s critical, do it yourself. If it’s not, delegate. Learn the difference
  • Don’t lie. If you’re in a position where you can’t tell the truth, learn how to weasel-word your way around trouble or hurting innocent bystanders. But don’t lie.
  • Some things are and always will be out of your control. Stop freaking out about it.  If you gotta cry, cry. Don’t make a big deal of it. Life has tears built-in.
  • Don’t borrow. Pay as you go. You borrow, you’re a kept man.
  • Right now, you owe someone a phone call. If it’s not yet past 8 p.m., make the call, even if your hand shakes as you dial.
  • Spending time with someone is more important than spending money on them.
  • Don’t try to change anyone. Learn the difference between actual help and co-dependent enabling.
  • Allow people to blossom or fail on their own. This takes ungodly patience, but it’s the only way it works.
  • Stop arguing.
  • Lead by example, not big talk. In fact, shut up until you’ve earned the right to talk by honing your chops.
  • You’re going to be an idiot occasionally. Embrace this opportunity for a good story, learn from it, forgive yourself, and try not to make idiocy a common event in your day.
  • Your reputation is built one act at a time, and a lifetime of good work can be squandered the same way. Respect is earned by consistent behavior.
  • Be where you said you’d be, when you said you’d be there, ready to do what you said you’d do.
  • Struggle is not a bad word. Accomplishment is impossible without it.
  • Intellectually-sound people change their minds when the facts change. Ideology sucks as a lifestyle.
  • Turn off the TV and go read.
  • Listen more than you talk. And when you talk, observe the rules of conversation. If these rules are a mystery to you, go hunt them down.
  • Don’t interfere with people disciplining their kids. Do interfere when clear abuse is occurring next door.
  • Tip twenty percent. If you’ve never worked in a job where you had to be nice to rude people, tip even more. You won’t start a trend, but you will make someone’s day and generate good karma.
  • Learn empathy. Get a vivid picture of what it’s like to walk in the other guy’s shoes.
  • Go the extra mile. Even when no one does it for you.
  • Eleanor Roosevelt was right: No one can make you feel inferior without your permission.
  • Sometimes you gotta take one for the team.
  • Learn to tell a joke. But don’t rely on them. True wit is intelligence and humor, not one-upmanship or memorization.
  • Not everyone likes you.
  • Right now is a good time to stop the bullshit. Get real. Take a painful review of yourself, and be honest. Face your faults, and begin the fix.
  • Love will always have baggage attached. Get over it. Love is essential to a full life. No matter what.
  • What people think of you is irrelevant. But how you leave this world matters. Even if it’s all futile in the end, play your part as well as you can. Real courage is fear, in action. Play your hand.

17th of February AutoHotkey Newsletter

Hi %Name%,

Let’s force ourselves to have an anxiety attack!  Sounds crazy but anytime we step into unknown areas we ALL experience anxiety.  It’s just human nature.   It’s undoubtedly the #1 reason people stop trying to learn AutoHotkey!

AutoHotkey is an amazing language that allows people (like you and I) to “program” without really being programmers.   However, the majority of people that start to use AutoHotkey stop right away (or never even try) because they see they have to “program” and believe they can’t do it.

Some will get started but then get very confused and even consider themselves “dumb” because they see others “getting it” in seconds.   When I first started WebScraping I nearly gave up.  I thought “I just don’t get it”.  What I didn’t realize at the time is that WE ALL went through that learning (feeling stupid) process!  Rarely are we all at the same “level” when learning something new.

But what gets some of us to keep plugging along into the dark abyss?   Is it that some of us are just smarter?


Those of us that continue to learn have “had a win”.  We’ve automated something and then felt the joy of using that script, over and over, and avoid the mundane work.  %name%, can you remember the script that saved you time?  I used HotStrings and Hotkeys for the first 3 years of using AutoHotkey.

And they made me a Rockstar!

It’s a rough part of life but we need that carrot🥕!  That reward for the work to continue on.  If there’s no gain, then why submit to the pain?

This is one of the big reasons I created the AutoHotkey Udemy courses.  Because AutoHotkey is so vast (with some many applications) having a clear path really helps!  My courses aren’t “amazing” but they do provide a very clear path to start learning AutoHotkey.

Now on with the show…

Amazing ActiveX example with AutoHotkey V2

The other day I published a short video documenting how Maestrith had shown how to create an ActiveX GUI.  Dimitri Geerts was inspired by it and did some amazing work!  He then joined me in Zoom to demo some of it which was spectacular!     The 2d work was amazing but the 3d version and “game of life” was really, really over-the-top!  I should point out that it’s all done in V2 (mainly because GUIs are a bit simpler in V2 because they’re functions).  Check out the video and let me know what you think!  Click here if you’d like to learn more about AutoHotkey V2.

Taking ActiveX to a new level with AutoHotkey V2 by Dimitri

Awareness of Automation

It’s been a few years, perhaps Jackie and I need to go look at the current stats to see if the bar has moved at all?  Are people more aware of ways to automate?

AutoHotkey Podcast: 024 Awareness of Automation tools / RPA

Parsing Text with AutoHotkey

In this video I show some tips & tricks how to parse text with AutoHotkey.  The more programming you do, the more splitting text becomes “a thing”.   RegEx is great but StrSplit() and InStr() are faster and simpler to get started with.

Parsing more Text with StrSplit and InStr

The-Automators’ Podcast

What we’re reading 📚

AutoHotkey GURU 👨‍🏫 Interview:

I remember this call with RaptorX / Isaias Baez.  RaptorX (AHKTuts on YouTube) was one of my inspirations for creating a YouTube channel.  I’d watched his videos ~10 years before and was amazed at what was possible.  This call was so much fun and educational, it’s no wonder we started working together a while after.  BTW I’ve been in contact with him and he’s hoping to be back here in the next month or so.  😊

Examples of AutoHotkey |AutoHotkey Experts: Isaias Baez / RaptorX

Productivity tips  ⚡️

One of the best ways to spot “what to automate” is by batching your work!  When you batch your work together you’re much more efficient!  As a side benefit, it becomes painfully obvious what processes can be automated!  Give it a try and tell me if I’m wrong!

Productivity tip #7 Batching #Shorts

A spot of Humor 🤣

I’d like to say “I’ve been there” but I’m not so sure I have!  lol

Quotable quotes 🗣️ 💭

  • The tragedy in life doesn’t lie in not reaching your goal. The tragedy lies in having no goal to reach. — Benjamin E. Mays
  • If it’s critical, do it yourself. If it’s not, delegate. Learn the difference — John Carlton
  • When the whole world is running towards a cliff, he who is running in the opposite direction appears to have lost his mind.” —S. Lewis
  • You wouldn’t have won if we’d beaten you — Yogi Berra 🤣

Live AutoHotkey Support Tomorrow

Don’t forget on Friday’s you can get free AutoHotkey support on my YouTube channel.  Or you can sign up for reminders and join the zoom room.

Intro to AutoHotkey HotStrings with AutoHotkey Intermediate AutoHotkey GUIs are Easy with AutoHotkey Intro to DOS & AutoHotkey AutoHotkey FAQ AutoHotkey FAQ


Joe and staff

P.S. Special thanks to the following for purchasing multiple
AutoHotkey Udemy courses this month!

  • 6 Peter E.
  • 3 Sam B.
  • 2 Łukasz G.
  • 2 VCALD.
  • 2 Sylwia B.
  • 2 Swen B.
  • 2 Sean M.
  • 2 R.
  • 2 Qun G.
  • 2 Przemysław M.
  • 2 Piotr Pawel B.
  • 2 Paulina D.
  • 2 P.
  • 2 Natalia P.
  • 2 Monika B.
  • 2 MateuszH.
  • 2 Mateusz T.
  • 2 Mateusz J.
  • 2 Marc P.
  • 2 Malgorzata M.
  • 2 Magdalena O.
  • 2 Magdalena F.
  • 2 Maciej W.
  • 2 Lidia D.
  • 2 Kosma W.
  • 2 Kinga C.
  • 2 Katarzyna U.
  • 2 Karolina S.
  • 2 K.
  • 2 Justyna K.
  • 2 Joanna R.
  • 2 J.
  • 2 Izabela K.
  • 2 Iwona S.
  • 2 Iwona Granacka-P.
  • 2 G.
  • 2 Ewelina W.
  • 2 Ewa N.
  • 2 Emilie H.
  • 2 Doug B.
  • 2 Damian G.
  • 2 Claudia J.
  • 2 Charles O.
  • 2 Cezary K.
  • 2 Cesar A.
  • 2 Bartosz B.
  • 2 B.
  • 2 Annet S.
  • 2 Anna C.
  • 2 Anna B.
  • 2 Alicja C.
  • 2 Aleksandra P.
  • 2 Agnieszka W.
  • 2 Abdulmalik A.

10th of February AutoHotkey Newsletter

Howdy %Name%,

It was 24 years ago, however I remember it like it was yesterday.  I took my first class in Advanced statistics 🧮 and sweated my way through it!  I was cursing to myself because it was downright uncomfortable and painful.  At times it made me feel incompetent and stupid.

When we’re trying something new, we feel awkward uncomfortable, and we might not like it.  The question to answer is, “Is it worth it?” If the answer is “yes”, then continue to work through the discomfort.

Why did I continue learning stats after my first unpleasant experience? Simple. I knew that it was good for me. And I LOVED the outcome (finding hidden patterns in data)

Many of us learn AutoHotkey because, compared to other languages, it’s very easy to get started on.  There’s nothing wrong with starting off with the basics!  I used HotStrings and Hotkeys for the first 3 years!  And it made me a Rock Star 🎸 compared to my colleagues!  But, when I finally started learning more advanced AutoHotkey functionality, I really blew-doors by everyone and my productivity skyrocketed! 🚀

Keep at it!

Trust me %Name%, learning is ALWAYS worth it!  Carve-out a regular time to learn at least twice a week!

Developer’s Corner

Simple way to select items

Sometimes “simple” is the way to go!  In this short video I show how you can easily automate selecting items form a list.  I happen to be in Chrome in the example however, the general approach, will work in most programs.

Simple AHK Script to Select many items in Chrome with AutoHotkey

Getting properties from an Outlook email

Outlook has a COM object which allows us to, easily, connect to it and access various properties.   Here I demonstrate how you can get info from the currently-selected emailCOM rocks!   You can learn more about using COM with Outlook and Excel in this AutoHotkey webinar.   Don’t forget we have over 60 AutoHotkey webinars you can watch!

Outlook Email Object- Getting Name, email, Send date, etc.

Learning XML

I stumbled upon a video I hadn’t published where Maestrith (author of AHK Studio) was teaching me how to use his XML class.  If you’re storing data XML is a great approach  for smaller amounts of data (let’s say under 10,000 items)

Learning XML with Maestrith and the-Automator

Automating Graphs in Excel

I’m coaching some current grad students and remembered, a lifetime ago, I had automated graphs in Excel.  Sadly the code I have now no-longer works but I’m planning on updating it once I have the time.  Still the concept is amazing!  Do you regularly make graphs?  Why not have it down to hitting a button to make them?  Be sure to check out my over 50 Excel tutorials and download my XL Function library.

How I automated Excel graphs with AutoHotkey | Amazing time saver!

AutoHotkey Guru👨‍🏫 Interview with  JoeDF from the AHK forum

Back in 2018 I was able to have a chat with JoeDF from the AutoHotkey forum.  Joe’s done some amazing things with AutoHotkey and, for such a young guy, has an amazing amount of posts on the AutoHotkey forum (currently 7,270).

Examples of AutoHotkey / AutoHotkey expert: joedf

The-Automators’ Podcast

What we’re reading 📚

Productivity tips ⚡️

Right now is a good time to stop the bullshit. Get real. Take a painful review of yourself, and be honest. Face your faults, and begin the fix. — John Carlton

A spot of Humor 🤣

David Letterman causing havoc while working a Mc Donald’s Drive-in.   Freaking hilarious!

Dave Works The McDonald's Drive-Thru | Letterman

Quotable quotes 🗣️ 💭

  • The ladder of success is best climbed by stepping on the rungs of opportunity. — Ayn Rand
  • Effective performance is preceded by painstaking preparation. — Brian Tracy
  • The towels were so thick there I could hardly close my suitcase — Yogi Berra

Live AutoHotkey Support Tomorrow

Don’t forget on Friday’s you can get free AutoHotkey support on my YouTube channel.  Or you can sign up for reminders and join the zoom room.

Intro to AutoHotkey HotStrings with AutoHotkey Intermediate AutoHotkey GUIs are Easy with AutoHotkey Intro to DOS & AutoHotkey AutoHotkey FAQ AutoHotkey FAQ


Joe and staff

P.S. Some of you may not have been receiving the AHK newsletter for a couple of weeks.  A bug crept into my script that pulls the list ☹.  Sorry for that!  Many of the past Newsletters are posted on the-Automator in case you want to check them out or share them.


3rd of February AutoHotkey Newsletter

Howdy %Name%,

Do you feel stuck in the same position? 😲  Do you get the feeling people (things) are going around you?

Start learning to automate your work and I guarantee you you’ll be your boss / colleague’s best friend!  Being more efficient and productive was always part of my plan in corporate America.  It reminds me of this video where I discuss how to get a raise💲.  Here’s a hint:  Be WORTH MORE!

Want to get a raise? Be worth it!- Investing in yourself is critical to succeeding!

Raptor❎ / Isaias Baez

Just an FYI- I had a call with Isaias the other day.  He stopped working for me as he had some personal things he had to take care of  however he’s hoping to be able to come back in the next month or so.  Here’s to hoping!  I have lots of things I’m looking forward to working on with him (not to mention making some more deep-dive videos).  Here’s one where we discuss various ways to store data with AutoHotkey

the-Automators AHK-talk: Various ways to store data and their uses

Debugging 🏴‍☠️

A little while back Jean Lalonde gave us  a tutorial on using classes with AutoHotkey.   I mentioned, in that video, that his use of SciTE4AutoHotkey debugging was amazing!  If you’re not using a tools that has debugging, you’re really missing out!  I have an intro to debugging in SciTE here.  Or, if you’re an AutoHotkey Studio user like me, you can check this video out.  Isaias / Raptor X prefers debugging in VS code.  Or take a look around at my debugging playlist.

Debug AutoHotKey with SciTE | Level up your AHK programming today!

Comparing lists

I used to build SQL queries and would have to compare lists to make sure I 1) had everything and 2) didn’t have duplicates.   This simple AutoHotkey script made it really easy!

Compare Sets

Learning what can be automated by watching others

I conducted a couple dozen interviews with other AutoHotkey users.  One of my favorite ones was with Gio Sperotto out of Brazil.  He uses AutoHotkey at his family’s company and has done some AMAZING things!  He also lead the webinar on Neural Networks.

Examples of AutoHotkey |AutoHotkey Experts: Gio Sperotto

AutoHotkey Resources

Jackie Sztuk and I discuss many of the AutoHotkey resources.   Amazingly not much has changed!  Are you aware of them all?   Which ones do 👉you use %Firstname%?

AutoHotkey Podcast: 012 AutoHotkey websites / Communities Part 1

Using a variable as the index when getting it from an Object

If you’re still learning objects and arrays, this is a great, short, video showing you how to access them if the index is stored in a variable.  In objects, the dot notation literally looks for that value (not a reference)

Using a Variable as the Index when getting it from an Object in AutoHotkey

The-Automators’ Podcast

What we’re reading 📚

Productivity tips  ⚡️

Be decisive and make decisions however, when you have a mistake, remember it is just that; a mistake. Don’t get caught up in that you are the mistake in recognize that we all learn by doing mistakes the important point is not to do them again

A spot of Humor 🤣

This may seem edgy, but it’s 100% true! All code has a few WTF. If it doesn’t you proably spent too much time working on it!

Quotable quotes 🗣️ 💭

  • Never see failure as failure, but only as a learning experience – Tom Hopkins
  • The tragedy in life doesn’t lie in not reaching your goal. The tragedy lies in having no goal to reach. — Benjamin E. Mays
  • When the whole world is running towards a cliff, he who is running in the opposite direction appears to have lost his mind.” —S. Lewis
  • If you ask me anything I don’t know, I’m not going to answer — Yogi Berra

Live AutoHotkey Support Tomorrow

Don’t forget on Friday’s you can get free AutoHotkey support on my YouTube channel.  Or you can sign up for reminders and join the zoom room.  We are having a severe storm in Texas so, if I’m not there, the power is out! 🥶

Intro to AutoHotkey HotStrings with AutoHotkey Intermediate AutoHotkey GUIs are Easy with AutoHotkey Intro to DOS & AutoHotkey AutoHotkey FAQ AutoHotkey FAQ


Joe and staff

P.S. Special thanks to the following for purchasing multiple AutoHotkey Udemy courses last month!

  • 4 Peter W. M.
  • 4 Jeremy K.
  • 3 Michele B.
  • 3 Manazael Zuliani J.
  • 3 Jozef V.
  • 3 Fronu L.
  • 3 Drew S P.
  • 3 C.
  • 2 Z.
  • 2 Sion H.
  • 2 Saadiq D.
  • 2 Robert James P.
  • 2 Philip D.
  • 2 Joseph De La R.
  • 2 Johannes von B.
  • 2 Herbert P.
  • 2 Henry M.
  • 2 Fred I.
  • 2 Emam A.
  • 2 Drew B.
  • 2 Devin J.
  • 2 Arie de R.
  • 2 Ahmad K.

Debugging Python- Have your best debug code at the tip of your fingers

debugging pythonDebugging Python

I’m learning how to program in Python and have put together some decent gui code which can be very helpful when trouble-shooting your code.

Trying to solve issues by just looking at your code can be done but it isn’t nearly as fast as using some real debugging python code.


AutoHotKey Debugging Python code

#SingleInstance , Force
Menu, tray, icon, B:ProgsIconsProgsPython.ico, 1
Menu,Py_Lists,Add, Count of x,            Py_Lists_Count

Menu,Py_Lists,Add, Append,                Py_Lists_Append
Menu,Py_Lists,Add, Concatenate,           Py_Lists_Concatenate
Menu,Py_Lists,Add, Insert,                Py_Lists_Insert
Menu,Py_Lists,Add, Pop,                   Py_Lists_Pop
Menu,Py_Lists,Add, Remove,                Py_Lists_Remove
Menu,Py_Lists,Add, Replace x,             Py_Lists_Replace
Menu,Py_Lists,Add, Reverse,               Py_Lists_Reverse
Menu,Py_Lists,Add, Sort,                  Py_Lists_Sort

	Menu,Py_Strings_Case,Add, Cap 1st Letter,      Py_Strings_Capitalize_first
	Menu,Py_Strings_Case,Add, Lowercase,           Py_Strings_Lower
	Menu,Py_Strings_Case,Add, Uppercase,           Py_Strings_Upper
	Menu,Py_Strings_Case,Add, Title case,          Py_Strings_Title	

Menu,Py_Strings,Add, Change Case, :Py_Strings_Case
	Menu,Py_Strings_Slice,Add, Slice me,      Py_Strings_Capitalize_first
Menu,Py_Strings,Add, Slicing, :Py_Strings_Slice
	Menu,Py_Strings_Return,Add, Count of Substring,  Py_Strings_Count
	Menu,Py_Strings_Return,Add, index of Substring,  Py_Strings_Find
	Menu,Py_String_Returns,Add, Length,              Py_Strings_Length
Menu,Py_Strings,Add, Index and Counts, :Py_Strings_Return
	Menu,Py_Strings_Append_Trim,Add, LTrim,          Py_Strings_LTrim
	Menu,Py_Strings_Append_Trim,Add, Strip (drops front and back),Py_Strings_Strip
Menu,Py_Strings,Add, Append / Trim, :Py_Strings_Append_Trim

	Menu,Py_Strings_Regex,Add, email,          			 Py_Strings_Regex_Email
	Menu,Py_Strings_Regex,Add, Match -named subvars,  	 Py_Strings_Regex_Named_Match
	Menu,Py_Strings_Regex,Add, Split on Whitespace, 	 Py_Strings_Regex_Split_WhiteSpace
	Menu,Py_Strings_Regex,Add, Split on range in needle, Py_Strings_Regex_Split_On_Range
Menu,Py_Strings,Add, RegEx, :Py_Strings_Regex

Menu, Py_Tuples, Add, Sort, 							Py_Tuple_Sort
Menu, Py_Tuples, Add, Functions Available, 				Py_Tuple_Avail_Funcs
	Menu,Py_Change_Case,Add, Lowercase Tuple,			Py_Tuple_LowerCase
	Menu,Py_Change_Case,Add, Uppercase Tuple,			Py_Tuple_UpperCase
Menu,Py_Tuples,Add, Change Case, 						:Py_Change_Case
;**********************Panda Options*********************************
Menu,Py_Pandas_Options,Add, Have df wrap columns,		Py_Pandas_Options_Expand_Frame
Menu,Py_Pandas_Options,Add, Width of your disply,	 	Py_Pandas_Options_Width
Menu,Py_Pandas_Options,Add, Max column width, 			Py_Pandas_Options_Max_Col_Width
Menu,Py_Pandas_Options,Add, Max # columns,	 			Py_Pandas_Options_Max_Col
Menu,Py_Pandas_Options,Add, Max # rows, 				Py_Pandas_Options_Max_Rows
Menu,Py_Pandas_Options,Add, Column Header Justification,Py_Pandas_Options_ColHead_Justify
Menu,Py_Pandas_Options,Add, Number of decimal places ,	Py_Pandas_Options_Precision
Menu,Py_Pandas_Options,Add, Default encoding, 			Py_Pandas_Options_Encoding
	Menu,Py_Pandas,Add, Options, :Py_Pandas_Options
;**********************Panda Data Frame*********************************
		Menu,Py_Pandas_DataFrame,Add, Select Multiple Columns, 			Py_Pandas_DataFrame_Col_Select
		Menu,Py_Pandas_DataFrame,Add, Frequency Count on Column,		Py_Pandas_DataFrame_Col_Count
		Menu,Py_Pandas_DataFrame,Add, Filter Column on Single value,	Py_Pandas_DataFrame_Col_Filter_Single
		Menu,Py_Pandas_DataFrame,Add, Filter Column on Multiple values,	Py_Pandas_DataFrame_Col_Filter_Multiple
	Menu,Py_Pandas,Add, DataFrame, :Py_Pandas_DataFrame
		Menu,Py_Pandas_Graph, Add, Graph necessities for plot,  		Py_Pandas_Graph_Graph_Necess
	Menu,Py_Pandas,Add,Graph, :Py_Pandas_Graph
menu,Py_Tuples 		,Add, Tuple example, 						Py_DUMMY_PLACEHOLDER
menu,Py_Stats  		,Add, Pandas, 						:Py_Pandas
menu,Py_Dictionaries,Add, Dictionaries example, 				Py_DUMMY_PLACEHOLDER

;**********************Convert Vars*********************************
Menu,Py_Convert		,Add, Convert Integer to String,     		Py_Convert_To_String
Menu,Py_Convert		,Add, Convert String to Integer,     		Py_Convert_To_Integer
Menu,Py_Convert		,Add, Convert String to Float,  	   		Py_Convert_To_Float
Menu,Py_Convert		,Add,
Menu,Py_Convert		,Add, Convert List to Tuple,	     		Py_Convert_List_to_Tuple
Menu,Py_Convert		,Add, Convert Tuple to List,	     		Py_Convert_Tuple_To_List

	Menu,Py_Funcs_FruitLess,Add,Fruitless Functions, 		Py_DUMMY_PLACEHOLDER
Menu,Py_Funcs	,Add, Fruit LESS Functions, 		:Py_Funcs_FruitLess

	Menu,Py_Funcs_Fruitful,Add,Fruitful Functions, 				Py_DUMMY_PLACEHOLDER
Menu,Py_Funcs	,Add, Fruit FULL Functions, 		:Py_Funcs_Fruitful

	Menu,Py_Loops_While	,Add, Iterate through object, 			Py_DUMMY_PLACEHOLDER
	Menu,Py_Loops_While	,Add, Dedupe, 							Py_DUMMY_PLACEHOLDER
Menu,Py_Loops,Add, While,  	:Py_Loops_While

	Menu,Py_Loops_For	,Add, While loops, 						Py_DUMMY_PLACEHOLDER
Menu,Py_Loops,Add, For,  	:Py_Loops_For
;**********************Debugging Python*********************************

Menu,Py_Debugging,Add, Python Path, 						Py_Python_Path
Menu,Py_Debugging,Add, Global Variables and their types,	Py_Globals
Menu,Py_Debugging,Add, Local Variables and their types,		Py_Locals
Menu,Py_Debugging,Add, Structure / Shape,					Py_StructShape
Menu,Py_Debugging,Add, Interactive mode in SciTE,			Py_Interactive
Menu,Py_Debugging,Add, Display Documentation,				Py_Display_Doc
Menu,Py_Debugging,Add, Display Help via Browser,			Py_Display_Help_HTML
Menu,Py_Debugging,Add, List installed Modules and Version,	Py_Installed_Modules_Versions

;**********************Tools  / Utils*********************************
Menu,Py_Tools_Utils,Add, Print function with optional title,Py_Tools_Utils_Print
Menu,Py_Tools_Utils,Add, Current date/time 				   ,Py_Tools_Utils_Date_Time
Menu,Py_Tools_Utils,Add, Launch iPython,					Py_Tools_Utils_iPython

;**********************Python Main menu*********************************
Menu,Python, Add, Lists,       	:Py_Lists
Menu,Python, Add, Strings,     	:Py_Strings
Menu,Python, Add, Tupless,     	:Py_Tuples
Menu,Python, Add, Dictionaries,	:Py_Dictionaries
Menu,Python, Add, Convert Vars,	:Py_Convert
Menu,Python, Add, Stats,		:Py_Stats
Menu,Python, Add,  ;blank line to separate
Menu,Python, Add, Functions,	:Py_Funcs
Menu,Python, Add, Loops,		:Py_Loops
Menu,Python, Add,  ;blank line to separate
Menu,Python, Add, Debugging,		:Py_Debugging
Menu,Python, Add, Tools / Utilities,:Py_Tools_Utils
;~ Menu,Python, Add, Non-Fruitful Functions,:Py_Fruit_Func

^+Lbutton::Menu, Python, Show  ; Control + Left mouse button

ClipProcess("import sys  # Shows Executable, bitness and paths`r`nprint ""rExecutable:"",sys.executable,""r  Platform:"",sys.platform,""r""`r`nfor i in sorted(sys.path): print ""      Path: "",i`r`n")

ClipProcess("for varname,value in globals().items():`r`n  print varname,' = ',value,' : ',type(value)  # Prints global variables")
ClipProcess("for varname,value in locals().items():`r`n  print varname,' = ',value,' : ',type(value)  # Prints Local variables")
ClipProcess("from structshape import structshape  #prints structure and shape of object from Think Python`rprint structshape(MyVar)")

ClipProcess("import code; code.interact(local=locals())  #Allows shell w/in SciTe- look at output window")

ClipProcess("help(MyModule)  # swap out MyModule with Method or object")

ClipProcess("import os `; os.system('python -m pydoc -g')  #Display help in HTML")

ClipProcess("import pip; print('n'.join(sorted(['%s=%s' % (i.key, i.version) for i in pip.get_installed_distributions()])))  #Lists installed Python Modules and their versions")

ClipProcess("MyList.append(x)  # Add an item to the end of the list; x is new item")

ClipProcess("ct = MyList.count('a')  # Return the number of times x appears in the list")

ClipProcess("MyList + [36,49,64]  # Concatenate values to list")

ClipProcess("MyList.insert(7,'Insert 7')  # Insert item at position. MyList.insert(0,'32') inserts 32 at beginning")

ClipProcess("MyList.pop(7)  # Remove item at position in the list, AND RETURN IT. If no index is specified, removes and returns the last item. (The brackets around the i denote that the parameter is optional)")

ClipProcess("MyList.remove('text')  # Remove the FIRST item from the list whose value is x. It is an error if there is no such item.")

ClipProcess("MyList[7]= '65'  # Replace the indexed value with 65")

ClipProcess("MyList.reverse()  # Reverse the elements of the list")

ClipProcess("list_Name.sort(cmp=None, key=None, reverse=False)  # Sort the items of the list in place (the arguments can be used for sort customization, see sorted() for their explanation).")
;**********************Python Strings*********************************
ClipProcess("MyVar = MyVar.capitalize()  # Use w/o 'MyVar =' if you don't need to change original variable")

ClipProcess("ct = MyVar.count('l',0,33) # Return the # of non-overlapping occurrences of substring sub in the range (range is optional)")

ClipProcess("i = MyVar.find('l',0,33)  # Return the lowest index in the string where substring sub is found. Returns -1 if not found")

ClipProcess("len(MyVar)  # obtain length of string")

ClipProcess("MyVar = MyVar.lower()  # Use w/o 'MyVar =' if you don't need to change original variable")

ClipProcess("MyVar = MyVar.lstrip('trim')  # Return a copy of the string with leading characters removed. (Removes whitespace if no charcters provided")

ClipProcess("MyVar = MyVar.strip('trim')  # Return a copy of the string with leading and ending characters removed. (Removes whitespace if no charcters provided")
ClipProcess("MyVar = MyVar.upper()  # Use w/o 'MyVar =' if you don't need to change original variable")

ClipProcess("MyVar = MyVar.title()  # Use w/o 'MyVar =' if you don't need to change original variable")

ClipProcess("import re`rstr = 'purple alice-b@google.com monkey dishwasher'`rmatch = re.search('([w.-]+)@([w.-]+)', str)`rif match:`r    print match.group()   ## 'alice-b@google.com' (the whole match)`r    print match.group(1)  ## 'alice-b' (the username, group 1)`r    print match.group(2)  ## 'google.com' (the host, group 2)")

ClipProcess("import re`r######### Named Regex extracting address`rname = r'[a-zA-z_]w+'`rneedle = '(?:' + name + ')'`rhaystack='Joe King 836 Kilbridge Ln.  Coppell  tx  75029nJoe Two 836 Kilbridge Ln.  Coppell  tx  75029'`rneedle='(?P<First_Name>w+)s+(?P<Last_Name>w+)s+(?P<Address>d{1,5}s+w+s+w+.?)s+(?P<City>w+)s+(?P<State>ww)s+(?P<Zipcode>d{1,5})'`rm = re.match(needle, haystack,re.I)`rprint m.group('First_Name'),m.group('Last_Name'), m.group('Address'), m.group('City'), m.group('State').upper(),m.group('Zipcode')")

ClipProcess("import re`rprint(re.split(r'(s*)', 'heare are some words'))  # s is whitespace and splits Haystack")

ClipProcess("import re`rprint(re.split(r'[a-fA-F]', 'jfdsklajfkeawfjkSawDFaw',re.I|re.M)) #splits on range listed in needle")
ClipProcess("print(dir(MyTuple))  # List of functions available on Tuple")

ClipProcess("Lower_MyTuple=[x.lower() for x in MyTuple]  #List comprehension on Tuple")

ClipProcess("Upper_MyTuple=[x.upper() for x in MyTuple]  #List comprehension on Tuple")

ClipProcess("s=sorted(MyTuple)  #Sort tuple")
;**********************Pandas Options*********************************
ClipProcess("pd.options.display.width = 1000  #Set default width")
ClipProcess("pd.options.display.max_colwidth = 100  #Set Max col width")
ClipProcess("pd.options.display.max_columns = 10  #None =no max cols 0=Autodetect")
ClipProcess("pd.options.display.max_rows = 50  #Max number of rows")
ClipProcess("pd.options.display.expand_frame_repr = False  #show DataFrame across multiple lines")
ClipProcess("pd.options.display.precision = 4  #Control decimals")
ClipProcess("pd.options.display.colheader_justify = 'left' #left right justify header")
ClipProcess("pd.options.display.encoding = 'UTF-8' #this is default so prob not needed")
;**********************data frame*********************************
ClipProcess("mydf=df[['MyCols 1','MyCols 2','MyCols 3']][0:14]  #Select columns and first 15 rows")

ClipProcess("df['MyCol 1'].value_counts()  #Count of items- use max row to expand")

ClipProcess("myFiltered=df['MyCol'] == 'My Value'  #filter single column on value")

ClipProcess("MyFilter_1 = df['MyVar 1'] == 'MyVal 1'  #Filter 1`rMyFilter_2 = df['MyVar 2'] == 'MyVal 2'  #Filter 2`rMyFilterd_All_Cols = df[MyFilter_1 & MyFilter_2][:99] #2 filters, all cols, 99 rows`rMyFilterd_Spc_Cols = df[MyFilter_1 & MyFilter_2][['MyVar 1','MyVar 2','MyVar 3']][:99]  #2 filters, spec cols, 99 rows")

;**********************Pandas- Graph*********************************
ClipProcess("import matplotlib.pyplot as plot  #Necessary to add so plot will show up`nplot.show()")

;**********************Convert Var*********************************
ClipProcess("MyVar = int(MyVar)  # Converts string to Integer. Use w/o 'MyVar =' if you don't need to change original variable")

ClipProcess("MyVar = str(MyVar)  # Converts to string. Use w/o 'MyVar =' if you don't need to change original variable")

ClipProcess("MyVar = float(MyVar)  # Converts to float. Use w/o 'MyVar =' if you don't need to change original variable")

ClipProcess("MyList=list(MyTuple)  #re-casting tuple to list")

ClipProcess("MyTuple=tuple(MyList)  #re-casting list to tuple")

;**********************Tools / Utilities*********************************
ClipProcess("def p(arg,title=''):  #My Print Function`r`tprint('<<<---START------'+str(title)+'------>>>r'+str(arg)+'r<<<---END------'+str(title)+'--->>>rr')")

ClipProcess("import datetime `; print('Today is: {0:%a %b %d %H:%M:%S %Y}'.format(datetime.datetime.now()))")

ClipProcess("import os `; os.system('ipython notebook')  #Display help in HTML")

;~ ClipProcess("")
;**************ClipProcess function*********************************
Send, ^v
Sleep, 60

There are other tools for debugging Python but this is a good starting place.

Debugging with SciTE Part 2- Additional Tips & Tricks

Debugging with SciTE

Debugging with SciTE 2 – Additional Tips & Tricks

In this second Debugging with SciTE video I show a few more tips & tricks that I didn’t mention /wasn’t aware of at the time of the first video.  This video compliments the last so be sure you watch the first one before this one.

Make sure you play till the end as I demonstrate the AutoHotkey dmp function which allows for easily seeing what text is in an array / object as well as demonstrate how you can use the Output panel as the command shell.

Debug with SciTE – Reduce AutoHotkey coding time with this 1 Amazing mind blowing tool

Debug with SciTE

Debug with SciTE and AutoHotKey

Debugging can be very time consuming. If you’re using SciTE with AutoHotKey, there is built-in functionality that is very helpful.  This video walks through some of the cool debugging features in SciTE.  I also have  a second debugging with SciTE video that you should check out after watching this one.

Make sure you take the time to review both videos!  I guarantee it will increase your speed of developing code and trouble-shooting issues!

Debug with SciTE

Debug with SciTE

Below is the AutoHotKey script I used in the video:

#SingleInstance, Force

OutputDebug Line %A_LineNumber%: A_Index is: %A_Index% and Var is: %Var%
GoSub Looper
MsgBox end of program

;***********************First loop********************************.
loop, 15
OutputDebug Line %A_LineNumber%: A_Index is: %A_Index% and Var is: %Var%
GoSub SubLooper

;***********************Sub loop********************************.
Loop, 3
OutputDebug Line %A_LineNumber%: A_Index is: %A_Index% and Var is: %Var% and Sublooper index is: %SubLooperVar%