not object is essentially a shorthand for bool(object) == False. It's generally used to negate the truth value of object. 
However, the truth value of object depends on object's type:
- If objectis a boolean, thenTrueevaluates toTrueandFalseevaluates toFalse.
- If objectis an number (integer or floating-point), then0evaluates toFalseand any other value evaluates toTrue
- If objectis a string, then the empty string""evaluates toFalseand any other value evaluates toTrue(this is your case at the moment)
- If objectis a collection (e.g. list or dict), then an empty collection ([]or{}) evaluates toFalse, and any other value evaluates toTrue.
- If objectisNone, it evaluates toFalse. Barring the above cases, ifobjectis notNone, it will usually evaluate toTrue.
These are generally grouped into two categories of truthy and falsey values - a truthy value is anything that evaluates to True, whereas a falsey value is anything that evaluates to False.
Python programmers use if not object: as a shorthand to cover multiple of these at once. In general, if you're not sure, you should check more specifically. In your case:
data = ""
if data == "":
    print("Hello")
else:
    print("Goodbye")
or if you wanted to make sure that, say, data didn't end with the character p, you could do this:
data = "orange"
if not data.endswith(p):
    print("data does not end with p")
else:
    print("data ends with p")