-2

Went on a break and decided to tweak my 2 second decorator, in anticipation of an early early Spring (cross your fingers). Twenty minutes after adding umbrellas (you might have to replace them with another UTF-8 character), the first line was driving me nuts, no matter what 'I wish it worked this way' stuff I threw at the string.

Finally, using the + operator (the second line) fixed my problem, even though it couldn't be used in the first separation. So, I ask you: Why is the spacing off at all (when both concatenation operators are the same), and, well, why does this non-standard approach work?

from functools import wraps

def dasher(f):
    @wraps(f)
    def wrapped(*args, **kwargs):
        brella = '\U00002602'
        print(f"{brella} #", f"{brella} # "*8, f"{brella}")
        print(f"{brella} #", f"{brella} # "*8 + f"{brella}") # concat and crazy
        # print("\U00002602 #","\U00002602 # "*8,"\U00002602")
        # print(f"\U00002602 #",f"\U00002602 # "*8,f"\U00002602")

        print()
    return wrapped

@dasher
def dashed():
    pass

dashed()

☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ #  ☂
☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂

Pythonic Refactoring

Thanks to Chris Doyle's answer in the comments, following an explanation of spacing differences between , and +, the following dirties things up again with some complexity, but extends usability, illustrating spacing while avoiding the need for sep=''.

print(' # '.join(brella*3), '#' ,' xx '.join(brella*5) , '#' ,' # '.join(brella*3))
print(' # '.join(brella*3) + ' o ' +' xx '.join(brella*5) + ' o ' +' # '.join(brella*3))

With output:

☂ # ☂ # ☂ # ☂ xx ☂ xx ☂ xx ☂ xx ☂ # ☂ # ☂ # ☂
☂ # ☂ # ☂ o ☂ xx ☂ xx ☂ xx ☂ xx ☂ o ☂ # ☂ # ☂ 
Tim Pozza
  • 498
  • 6
  • 9
  • 3
    when you pass multiple items to print (I.E seperated by comma by default print will put a space between them). So when you multiply your inner brella you end each string with a space, then you use a `,` So print will put another space in – Chris Doyle Feb 28 '20 at 22:20
  • 1
    So to be clear, the `,` is not a concat operator. Print is a a function in python 3. So calling `print("foo", "bar")` is passing 2 string arguments to print . print function will then join these with the value of `sep` which by deafult is a space unless you change it. calling print("foo" + "bar") will result in two strings being first concat together then a single string argument being passed to print. So `,` and `+` are not both concatenation operators here. – Chris Doyle Feb 29 '20 at 17:18

1 Answers1

1

When you pass multiple items to print by deafault print will use space as the seperator. So when you give your first string you end it with a #. you then follow this with a comma and pass in your next item to print(So since the default separator for items in print is space the first item and second item will be separated by a space. So you will have hash space umbrella

however your second string which you multiply ends in a space. you then give a comma then your third item. So your second item ends with a space then print will put in a space between your second and third item. resulting in you having a double space. so you will have hash space space umbrella

If you dont want this behavior, manually put in the space at the end of your first item to make it consistent like your second item which ends with a space and then at the end of your print set the separator as an empty string.

Alternatively you can just multiply your brella by 10 and then use " # " as the joiner to connect them all.

brella = '\U00002602'
print(f"{brella} #", f"{brella} # "*8, f"{brella}")
print(f"{brella} #", f"{brella} # "*8 + f"{brella}")
print(f"{brella} # ", f"{brella} # "*8, f"{brella}", sep='')
print(' # '.join(brella*10))

OUTPUT

☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ #  ☂
☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂
☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂
☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂
Chris Doyle
  • 10,703
  • 2
  • 23
  • 42
  • Thank you. `sep=''` was wholly absent from my thinking. The explanation is great and very usable. – Tim Pozza Feb 28 '20 at 22:45
  • 1
    Of course you could write this all much more concisely by just multiplying brella by 10 then using " # " as the joiner between them `print(' # '.join(brella*10))` – Chris Doyle Feb 29 '20 at 07:32
  • That feels a lot more pythonic and flips the quick and dirty approach on its head for being quick -- and clean. – Tim Pozza Feb 29 '20 at 16:26