You will get better at this through practice, but for starters separate "words" with _. When using abbreviations, this makes it clear what is and isn't separated: for example automsg vs. auto_msg. Note that some of the rest of this is specific to Python, and that in general languages and the communities around them develop conventions. That said I'm not getting way into Python-specific idiom, and if you go to Rust or C++ or whatever else with these guidelines it'll be fine.
Consistency is more important than anything, but functions are usually verb-noun: get_health, not health_get.
I haven't picked apart your original code, but also note that globals are bad, not just for the obvious reasons but also because naming them is hard. Python functions can take keyword arguments with default values:
def say(message, loud = False, braille = False, immediate = False):
# stuff
say("hello", loud = True)
say("braille", braille = True)
say("hello", loud = True, immediate = True)
If you do it this way it's obvious that the function parameters are for the messaging function and so they don't need to say anything about messaging. The order doesn't matter as long as the names match. Other languages will usually have a pattern of some sort for how you handle default arguments to functions; some don't, but the ones that don't have any way to handle it are very much in the minority. If you want to be even more readable and/or plan to distribute the code to others:
def say(message, loud = False, immediate = False, braille = False):
"""Communicate a message through a screen reader interface.
message: The message to say.
loud: If true, also play an alarm.
braille: If true, send this message to a braille display instead.
immediate: If true, interrupt any previous messages.
If no screen reader is present, throws NoScreenReaderError.
"""
# my code here.
Which immediately tells you and anyone else what's going on. Also if you format that right and set up Sphinx that'll give you a nice HTML manual.
Python classes are camel case with leading capitals: MyClass. Errors (things you intend to raise, which inherit from Exception) are MyError, rarely MyException.
Long variable names are better than short variable names. If you're going to use abbreviations, they should always be the same abbreviation for your entire program.
Introduce consistent terminology, and use it everywhere. Where possible, use standard terminology, but if you don't know what it is always at least use the same thing. For example controls aren't controls in one file and widgets in another file. For a game example, you shouldn't use npc, mob, enemy, robot, etc. for the things that aren't the player just because. Npc being a base class for enemy and ally is fine, for example, or robot being special might mean it deserves a term, because in those cases there's a reason for it being different.
You should always have a reason for the words you pick, and it shouldn't be just offhand. If it's a loop variable using i or j is fine. The reason for that is that everyone else in programming land does. If it's a variable that's going to be used for 2 lines, tmp is fine, because after 2 lines it doesn't matter, and tmp is a good name for something that's going to be used right now and then never again. But the more code it's going to be in, the more important it is to be able to justify to yourself why you made whatever choice you made. If it's a function, method, or class it should *always* have a justified name. If it's going to be used beyond this file it should also be named taking into account that no one wants to play hunt the name to find out what it does.
If something is private to a module, class, etc. Python names it like _my_private_function. This doesn't have any special meaning or anything, it's just convention that lets everyone know you're not supposed to touch it from outside.
Never have a variable hold two different types of things. Don't assign a number and then assign a string later. While Python allows you to, it's confusing if variables are sometimes one kind of thing and sometimes another. There is very rarely a good reason but the chances of you encountering them yourself right now are basically nonexistant, I don't have an example offhand, and if I try to give you one it's going to be contrived and probably involve pretty serious metaprogramming stuff that no one does outside libraries.
You aren't finding a class or something though because there are no hard and fast rules. Some of programming is science. Some of programming is art. This is the part that's art. Everyone does this a little bit differently. It's like learning to speak a second language, a little bit. The first things you learn are how the for loop works, and that's all well and good, you can get it from the programming textbook. But then you have to start learning not to "speak" like a foreigner. Only in programming there are bigger consequences, because generating good names is actually a large part of what lets you handle big projects. Good names don't require you to memorize them, and can be guessed from first principles once you understand the project's style. You know you have good names when the project is 5000 lines, you leave it for 2 weeks, you come back to work on it, you open a Python shell, and you immediately know which things to import and what the methods on them are going to be within 2 or 3 tries of guessing from thin air.
My BlogTwitter: @ajhicks1992