Formatting lists - python

I need to create a function that takes inputs of lists from the user and returns them as such:
>>> print_table([[0,1,2,3,4,5],[0,1,4,9,16,25],[0,1,8,27,64,125]])
0 1 2 3 4 5
0 1 4 9 16 25
0 1 8 27 64 125
>>> print_table(times_table(6,6))
0 0 0 0 0 0 0
0 1 2 3 4 5 6
0 2 4 6 8 10 12
0 3 6 9 12 15 18
0 4 8 12 16 20 24
0 5 10 15 20 25 30
0 6 12 18 24 30 36
The times_table refers to my current code:
def times_table(s):
n = int(input('Please enter a positive integer between 1 and 15: '))
for row in range(n+1):
s = ''
for col in range(n+1):
s += '{:3} '.format(row * col)
print(s)
Help me if you can....

To get two values as input from the user, i.e. number of columns and rows, you can do as follows:
in_values = input('Please enter two positive integers between 1 and 15, separated by comma (e.g. 2,3): ')
m,n = map(int, in_values.split(','))
print(m,n)

To print out a formatted list of lists, you may wish to consider using string formatting through the format() method of strings. One thing I notice in your upper example is that you only get to 3 digits, and the space between the numbers seems to be unchanging. For lists with large numbers, this will likely mess up the formatting of the table. By using the format() method, you can take this into account and keep your table nicely spaced.
The easiest way I can think of to accomplish this is to determine what is the single largest number (most digits) in the entire list of lists and then incorporate that in the formatting. I would recommend you read up on string formatting for the python type string (including the mini formatting language).
Assuming s is the argument passed in to print_table:
maxchars = len(str(max(max(s))))
This will provide the largest number of characters in a single entry in the list. You can then utilize this number in the formatting of the rows in a for loop:
for lst in l:
output = ""
for i in lst:
output += "{0:<{1}} ".format(i, maxchars)
print(output)
the line output += "{0:<{1}} ".format(i, maxchars) means to print the number ({0} maps to the i in the call to format) left adjusted (<) in a space of characters "maxchars" wide ({1} maps to maxchars in the call to format).
So given your list of lists above, it will print it as:
0 1 2 3 4 5
0 1 4 9 16 25
0 1 8 27 64 125
but if the numbers are much larger (or any of the numbers are much larger, such as the 125 being replaced with 125125, it will unfortunately look like this because it is padding each item with the appropriate number of character spaces to contain a number of 6 characters:
0 1 2 3 4 5
0 1 4 9 16 25
0 1 8 27 64 125125
The above example takes a variable number of characters into account, however you could also format the string using an integer by replacing the {1} with an integer and omitting the maxchars portion (including both setting it and it being passed to format) if that is sufficient.
output += "{0:<4} ".format(i)
Optionally, you could figure out how to determine the largest number in a given column and then just format that column appropriately, however I am not going to put that in this answer.

Related

Unable to return index from Series using value match for numeric values

A pandas Series object is created from a list of numbers and characters, charSeries, copied below for reference.
A random five digit string of characters and numbers, created from the below list, is made:
code_core = Q5YUO
Each character in code_core is iterated through to get the corresponding index:
for character in code_core:
index_tosum = charSeries[charSeries == character].index(0)
This works for all alphabet characters. However for any number an error is returned. In the above core_core, an error is returned for character '5':
return getitem(key)
IndexError: index 0 is out of bounds for axis 0 with size 0
It is found that for 5, or any number,
charSeries[charSeries == character]
is empty. I do not see why this is as 5 is one of the values in the Series below and has an index of 5.
What is the error in my code or my approach?
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 B
11 C
12 D
13 F
14 G
15 H
16 J
17 K
18 L
19 M
20 N
21 P
22 Q
23 R
24 S
25 T
26 V
27 W
28 X
29 Y
30 Z
IIUC use next with iter with default value if no match, also if mixed numeric and string values convert them to strings by astype:
code_core = 'Q5YUO'
for character in code_core:
out = next(iter(charSeries.index[charSeries.astype(str) == character]), 'no match')
print (out)
22
5
29
no match
no match

Table of Squares and Cubes

I am learning Python on my own and I am stuck on a problem from a book I purchased. I can only seem to get the numbers correctly, but I cannot get the title. I was wondering if this has anything to do with the format method to make it look better? This is what I have so far:
number = 0
square = 0
cube = 0
for number in range(0, 6):
square = number * number
cube = number * number * number
print(number, square, cube)
What I am returning:
0 0 0
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
I would like my desired output to be this:
number square cube
0 0 0
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
Here we can specify the width of the digits using format in paranthesis
print('number square cube')
for x in range(0, 6):
print('{0:6d}\t {1:7d}\t {2:3d}'.format(x, x*x, x*x*x))
This would result in
number square cube
0 0 0
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
You need to print the header row. I used tabs \t to space the numbers our properly and f-stings because they are awesome (look them up).
number = 0
square = 0
cube = 0
# print the header
print('number\tsquare\tcube')
for number in range(0, 6):
square = number * number
cube = number * number * number
# print the rows using f-strings
print(f'{number}\t{square}\t{cube}')
Output:
number square cube
0 0 0
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
The only thing this doesn't do is right-align the columns, you'd have to write some custom printing function for that which determines the proper width in spaces of the columns based on each item in that column. To be honest, the output here doesn't make ANY difference and I'd focus on the utility of your code rather than what it looks like when printing to a terminal.
There is a somewhat more terse method you might consider that also uses format, as you guessed. I think this is worth learning because the Format Specification Mini-Language can be useful. Combined with f-stings, you go from eight lines of code to 3.
print('number\tsquare\tcube')
for number in range(0, 6):
print(f'{number:>6}{number**2:>8}{number**3:>6}')
The numbers here (e.g.:>6) aren't special but are just there to get you the output you desired. The > however is, forcing the number to be right-aligned within the space available.

How do I create a horizontal multiplication table in Python?

So far I have tried to create a table of the first 6 multiples of 2 that should give:
2 4 6 8 10 12
My code for this currently looks like:
i = 1
while i <= 6:
print(2*i ,' \t' , )
i = i + 1
But this outputs them vertically, not horizontally so:
2
4
6
8
10
12
There is also a tab after each number.
You can use a simple for-loop as they are more Pythonic for this application than while loops.
So just loop through the numbers between 1 and 6 and print that number multiplied by 2 with a space instead of the new-line character. Finally, you can call one more print at the end to move to the next line after they have all been printed.
for i in range(1, 7):
print(i * 2, end=' ')
print()
which outputs:
2 4 6 8 10 12
If you wanted do this whole thing in one-line, you could use a generator and string.join(). You may not fully understand this, but the following produces the same result:
print(" ".join(str(i*2) for i in range(1, 7)))
which gives:
2 4 6 8 10 12
Note that one last thing is that this method doesn't produce a uniformly spaced table. To show what I mean by "uniformly spaced", here are some examples:
not uniformly spaced:
1234 1 123 12 12312 123
uniformly spaced:
1234 1 123 12 12312 123
To make the output print nicely like above, we can use .ljust:
print("".join(str(i*2).ljust(3) for i in range(1, 7)))
which gives a nicer table:
2 4 6 8 10 12
Finally, if you wanted to make this into a function that is more general purpose, you could do:
def tbl(num, amnt):
print("".join(str(i*num).rjust(len(str(num*amnt))+1) for i in range(1,amnt+1)))
and some examples of this function:
>>> tbl(3, 10)
3 6 9 12 15 18 21 24 27 30
>>> tbl(9, 5)
9 18 27 36 45
>>> tbl(10, 10)
10 20 30 40 50 60 70 80 90 100
Change your print statement to be like this: print(2*i, end=' \t') The end key argument sets what the ending character should be. By default, it's a newline, as you know.

Python and CodeEval: Why isn't my solution to this Multiplication Table challenge not correct?

So I've been digging into some of the challenges at CodeEval during the last couple of days. One of them asks you to print a pretty-looking multiplication table going up to 12*12. While on my computer this solution works properly, the site does not accept it.
Can somebody help me out?
for i in range(1,13):
for j in range(1,13):
if j==1:
print i*j,
elif i>=10 and j==2:
print '{0:3}'.format(i*j),
else:
print '{0:4}'.format(i*j),
print
Here's a description of the challenge:
Print out the table in a matrix like fashion, each number formatted to a width of 4 (The numbers are right-aligned and strip out leading/trailing spaces on each line).
Print out the table in a matrix like fashion, each number formatted to a width of 4
(The numbers are right-aligned and strip out leading/trailing spaces on each line).
I think that following code may pass, according to the given rules. But it's only a guess
as I'm not playing on codeeval.
# python3 code, use from __future__ import print_function if you're using python2
for i in range(1,13):
for j in range(1,13):
print('{:4}'.format(i*j), end="")
print ("")
I guess your problem is that you're having a 5 alignment because you forgot that the print foo,
syntax in python 2 is adding a space. Also they say width of 4, whereas you tried to be smart, and
align accordingly to the size of the value.
edit: here's more details about what's wrong in your code, let's take two lines of your output:
1 2 3 4 5 6 7 8 9 10 11 12
10 20 30 40 50 60 70 80 90 100 110 120
AA␣BBB␣CCCC␣CCCC␣CCCC␣CCCC␣CCCC␣CCCC␣CCCC␣CCCC␣CCCC␣CCCC␣
so what your code is doing is:
if j==1: print i*j,
outputs the AA␣,
elif i>=10 and j==2:
print '{0:3}'.format(i*j),
outputs the BBB␣ and
else:
print '{0:4}'.format(i*j),
outputs the CCCC␣.
The ␣ is an extra space added by python because of the use of the , at the end of the print, to get that, see that snippet:
>>> def foo():
... print 1234,
... print 1234,
... print
...
>>> foo()
1234 1234
The format '{0:3}' right aligns the integer to the right as expected, but only with a padding of three, whereas the '{0:4}' does it according to the rules. But as you're adding an extra space at the end, it's not working as you're writing it. That's why it's better to use python3's print expression that makes it simpler, using the end keyword.
Print out the table in a matrix like fashion, each number formatted to a width of 4 (The numbers are right-aligned and strip out leading/trailing spaces on each line).
However, the output fails to meet this requirement which is made more visible by timing bars.
1 2 3 4 5 6 7 8 9 10 11 12^N
2 4 6 8 10 12 14 16 18 20 22 24^N
3 6 9 12 15 18 21 24 27 30 33 36^N
||||----||||----||||----||||----||||----||||----||||----
This correct padding for a "width of 4, right-aligned" should look like
1 2 3 4 5 6 7 8 9 10 11 12^N
||||++++||||++++||||++++||||++++||||++++||||++++
And then with "strip out leading/trailing spaces on each line" the correct result is
1 2 3 4 5 6 7 8 9 10 11 12^N
|++++||||++++||||++++||||++++||||++++||||++++
While the current incorrect output, with the timing bars for correct output looks like
1 2 3 4 5 6 7 8 9 10 11 12^N
|++++||||++++||||++++||||++++||||++++||||++++???????????

Can anyone help me figure out the parsing error in this code?

The output of this code is quite similar but not exactly what it's supposed to be.
The code is:
def printMultiples(n):
i = 1
while (i <= 10):
print(n*i, end = ' ')
i += 1
n = 1
while (i<= 3):
printMultiples(n)
n += 1
The output is:
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30
Whereas it should be like:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
How should this code be modified?
add an empty print at the end of the printMultiples, outside the while (i <= 10): loop.
Your problem is that you are not printing a new line after each list of multiples. You could solve this by putting at the end of your printMultiples function outside of the loop the line
print()
To make the columns line up, you will need to completely change your approach. Currently, printMultiples() cannot know how many spaces to put after each number because it doesn't know how many times it will be called in the outer while loop.
What you might do is:
create a two dimensional array of string representations for each multiple (without printing anything yet) - the str() function will be useful for this
for each column, check the length of the longest number in that column (it will always be the last one) and add one
print each row, adding the appropriate number of spaces after each string to match the number of spaces required for that column
A simpler approach, if you're only interested in columnar output and not the precise spacing, would be to print each number with enough space after it to accommodate the largest number you expect to output. So you might get:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
(Note how there are three spaces after each number in the first three columns even though you don't need all three spaces.)
Changing your existing code to do that would be easier. See Format String Syntax for details.
If you already know you wish to pad numbers to be of width 3, then a suitable (and more pythonic) printMultiples is
def printMultiples(n):
txt = "".join(["{0: <3d}".format(n*i) for i in range(1, 11)])
print(txt)
Better would be to allow the width to change. And you could then pass a width you prefer as, eg, the width of the largest number you expect
def printMultiples(n, width=3):
txt = "".join(["{0: <{1}d}".format(n*i, width) for i in range(1, 11)])
print(txt)
width = len(str(4 * 10)) + 1
for i in range(1, 4):
printMultiples(i, width )

Categories

Resources