This formating is really tricky

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Aug 25 22:45:45 EDT 2014


Seymore4Head wrote:

> import random
> sets=3
> for x in range(0, sets):
>     pb1=random.choice([1,2,3,4,5,6,7,8,9,10 [...] 52,53])
>     pb2=random.choice([1-53])

You can avoid the annoyance of typing out long lists of sequential numbers
by using the range() function. And you can avoid writing out the same value
over and over again by giving it a name. So:

numbers = list(range(1, 54))  # 1 is included, 54 is excluded.
random.choice(numbers)

will randomly select a number between 1 and 53 inclusive.

random.choice([1-53]) doesn't do what you hope. It calculates 1-53 which
gives -52, puts that inside a list [-52], then randomly chooses one of the
items in the list -- the *only* item in the list, -52 every single time.

Having said all that, *none* of the above code is relevant to your subject
line. Yes, formatting is tricky, but nothing seen so far is about
formatting.

A well-designed program should be like a sandwich, not a stew. If I have a
problem with a stew, there's no individual parts that I can easily point
to. "The stew doesn't taste nice, please fix it." There's not a lot to go
by. "Doesn't taste nice" could mean anything, and the only way to
understand the stew is to consider *everything*, from the start to the
finish, and that's hard work.

But consider a sandwich: "When I put the bread on the tomato, it keeps
falling off. Here is my tomato, why won't the bread stay on?" Answer: you
forgot to slice the tomato. It's easy to see, because you can ignore the
lettuce and the cheese and meat and the pickles and just look at the tomato
in isolation of everything else, and it's obvious.

In this case, the trick is to isolate the parts of your code that are to do
with formatting, and ignore everything else. That might mean writing a new,
smaller program. This will actually help you to understand what is going
on, by digesting it in small chunks, rather than everything at once.

So we come to the next part:

>     alist = sorted([pb1, pb2, pb3, pb4, pb5])
>     print ("Your numbers: {} Powerball: {}".format(alist, pb6))

There is no need to show all the stuff about selecting random numbers, or
that this is in a loop, or any of that. (Although, in this case you've
hopefully inadvertently learned something by doing so, in another case you
may just cause people reading to say "that's too hard, I'm too busy to read
all that code" and your question goes unanswered.) But the *real* reason to
learn to isolate the fault is that fault isolation is an essential skill
that you, as a programmer, will need all through your career.

Since the problem is with formatting, we can isolate the fault to just the
formatting:

print("Your numbers: {} Powerball: {}".format([1, 2, 3, 4, 5], 23))
print("Your numbers: {} Powerball: {}".format([11, 21, 31, 41, 51], 7))

And the results are:

Your numbers: [1, 2, 3, 4, 5] Powerball: 23
Your numbers: [11, 21, 31, 41, 51] Powerball: 7

They certainly don't line up. Did you expect them to? How is the first print
line supposed to know how far apart to space the numbers to match the
second print line?

Let's simplify even further:

print("Powerball: {}".format(23))
print("Powerball: {}".format(7))

which gives:

Powerball: 23
Powerball: 7

but we want the numbers to line up on the right, not the left. It's not
obvious how to do that, the formatting mini-language is a bit obscure, but
by reading the documentation, a bit of guesswork from half-remembered bits
and pieces, trial and error, and/or asking someone else, I came up with:

print("Powerball: {: >2}".format(23))
print("Powerball: {: >2}".format(7))

Powerball: 23
Powerball:  7

Success! The " >2" part of the format code inside the {} means to format the
value using two columns, padding with spaces on the left if needed.

So now we can format five columns for the five numbers, plus the powerball:

template = "Numbers: {: >2} {: >2} {: >2} {: >2} {: >2}  Powerball: {: >2}"
print(template.format(1, 2, 3, 4, 5, 23))
print(template.format(11, 21, 31, 41, 51, 7))

which gives:

Numbers:  1  2  3  4  5  Powerball: 23
Numbers: 11 21 31 41 51  Powerball:  7



-- 
Steven




More information about the Python-list mailing list