python multiplication table error - python

I am building a multiplication table in python using while loops. The output is strange though as the numbers line up. The table is fine in terms of completion but it looks ugly. How can i straighten the last three columns? I would post a pic of the output but i am a new user and it will not let me.
width = int(input("Please enter the width of the table:"))
def print_times_table(width):
row = 0
col = 0
width += 1
spaces = ' '
while row < width:
col = 0
while col < width:
print(row*col, spaces, end="")
col += 1
print("\n", end='')
row +=1
print_times_table(width)
output: http://i.stack.imgur.com/C9AzE.jpg

First, you don't need a picture; you should be able to show the output as text just by indenting four spaces (or using the {} icon):
Please enter the width of the table:4
0 0 0 0 0
0 1 2 3 4
0 2 4 6 8
0 3 6 9 12
0 4 8 12 16
The problem is that you're assuming each number will be the same width. This works up to 3x3, because everything is one character wide, but for 5x5, some numbers are one character, some are two (and of course it gets even worse at 10x10).
The easy way to fix this is to force each cell to be the same width.
First, you have to calculate the biggest size you'll need. But that's easy: it's the size of width*width.
Next, you have to know how to force the numbers to use up that many characters. Python has a few ways to do this. I'll show how to do it with old-fashioned field specifiers, but you should look into how to convert this to new-style format strings. (If this is homework, someone teaching you Python 3 will probably grade you down for using old-style fieldspecs. If it's just for your own self-education, it's worth figuring out how to do it both ways.) Or, alternatively, you should look at how to convert it to use a variable-width format spec ('%*d') instead of building a static '%4d' spec. (nneonneo's answer should give a clue to that.)
width = int(input("Please enter the width of the table:"))
def print_times_table(width):
row = 0
col = 0
fieldspec = '%' + str(len(str(width * width))) + 'd'
width += 1
while row < width:
col = 0
while col < width:
print(fieldspec % (row*col,), ' ', end="")
col += 1
print("\n", end='')
row +=1
print_times_table(width)
Now you get:
Please enter the width of the table:4
0 0 0 0 0
0 1 2 3 4
0 2 4 6 8
0 3 6 9 12
0 4 8 12 16

Use a variable-width field specifier:
print('%*d' % (8, row*col), end='')
This automatically adds enough padding to fill the number out to (here) 8 spaces. You can pass that spacing parameter in as an argument, too.
To use a variable width using the new-style formatting syntax:
print('{:{width}}'.format(row*col, width=8), end='')

why not just use your variable in combonation with .ljust? like so:
width = int(13)
def table(width):
row = 1
col = 1
width += 1
spaces = ' '
while row < width:
col = 1
while col < width:
print(str(row*col).rjust(5, ' '), end="")
col += 1
print("\n", end='')
row +=1
table(width)
it works the exact same(you can use whatever numbers you wish, doesn't matter) and just adjust accordingly depending on how large your numbers are getting...

Related

How to print a rectangle pattern using numbers in python

I am having trouble solving the following question:
Write a program that draws “modular rectangles” like the ones below. The user specifies the width and height of the rectangle, and the entries start at 0 and increase typewriter fashion from left to right and top to bottom, but are all done mod 10. Example: Below are examples of a 3 x 5 rectangular:
The following code is what I have tried to solve the problem:
I know it's bad but I still don't know how to print the 5 till 9 numbers on top of each other.
width = int(input("Enter the width of the rectangle:"))
height = int(input("Enter the height of the rectangle:"))
for x in range(0, width, 1):
for y in range(0, height, 1):
print(y, end = ' ')
print()
Thank you all in advance.
You're on the right track, but you have a few issues. Firstly you need to iterate y before x, since you process the columns for each row, not rows for each column. Secondly, you need to compute how many values you have output, which you can do with (y*width+x). To output a single digit, take that value modulo 10. Finally range(0, width, 1) is just the same as range(width). Putting it all together:
width = 5
height = 3
for y in range(height):
for x in range(width):
print((y*width+x)%10, end=' ')
print()
Output:
0 1 2 3 4
5 6 7 8 9
0 1 2 3 4

select region from sequence with Phobius output in Python

I need to use a certain program, to validate some of my results. I am relatively new in Python. The output is so different for each entry, see a snippit below:
SEQENCE ID TM SP PREDICTION
YOL154W_Q12512_Saccharomyces_cerevisiae 0 Y n8-15c20/21o
YDR481C_P11491_Saccharomyces_cerevisiae 1 0 i34-53o
YAL007C_P39704_Saccharomyces_cerevisiae 1 Y n5-20c25/26o181-207i
YAR028W_P39548_Saccharomyces_cerevisiae 2 0 i51-69o75-97i
YBL040C_P18414_Saccharomyces_cerevisiae 7 0 o6-26i38-56o62-80i101-119o125-143i155-174o186-206i
YBR106W_P38264_Saccharomyces_cerevisiae 1 0 o28-47i
YBR287W_P38355_Saccharomyces_cerevisiae 8 0 o12-32i44-63o69-90i258-275o295-315i327-351o363-385i397-421o
So, I need the last transmembrane region, in this case its always the last numbers between o and i or vise versa. if TM = 0, there is no transmembrane region, so I want the numbers if TM > 0
output I need:
34-53
181-207
75-97
186-206
28-47
397-421
preferably in seperate values, like:
first_number = 34
second_number = 53
Because I will be using a loop the values will be overwritten anyway. To summarize: I need the last region between the o and i or vise versa, with very variable strings (both in length and composition).
Trouble: If I just search (for example with regular expression) for the last region between o and i, I will sometimes pick the wrong region.
If the Phobius output is stored in a file, change 'Phobius_output' to the path, then the following code should give the expected result:
with open('Phobius_output') as file:
for line in file.readlines()[1:]:
if int(line.split()[1]) > 0:
prediction = line.split()[3]
i_idx, o_idx = prediction.rfind('i'), prediction.rfind('o')
last_region = prediction[i_idx + 1:o_idx] if i_idx < o_idx else prediction[o_idx + 1:i_idx]
first_number, second_number = map(int, last_region.split('-'))
print(last_region)

While Loop to produce Mathematical Sequences?

I've been asked to do the following:
Using a while loop, you will write a program which will produce the following mathematical sequence:
1 * 9 + 2 = 11(you will compute this number)
12 * 9 + 3 = 111
123 * 9 + 4 = 1111
Then your program should run as far as the results contain only "1"s. You can build your numbers as string, then convert to ints before calculation. Then you can convert the result back to a string to see if it contains all "1"s.
Sample Output:
1 * 9 + 2 = 11
12 * 9 + 3 = 111
123 * 9 + 4 = 1111
1234 * 9 + 5 = 11111
Here is my code:
def main():
Current = 1
Next = 2
Addition = 2
output = funcCalculation(Current, Addition)
while (verifyAllOnes(output) == True):
print(output)
#string concat to get new current number
Current = int(str(Current) + str(Next))
Addition += 1
Next += 1
output = funcCalculation(Current, Next)
def funcCalculation(a,b):
return (a * 9 + b)
def verifyAllOnes(val):
Num_str = str(val)
for ch in Num_str:
if(str(ch)!= "1"):
return False
return True
main()
The bug is that the formula isn't printing next to the series of ones on each line. What am I doing wrong?
Pseudo-code:
a = 1
b = 2
result = a * 9 + b
while string representation of result contains only 1s:
a = concat a with the old value of b, as a number
b = b + 1
result = a * 9 + b
This can be literally converted into Python code.
Testing all ones
Well, for starters, here is one easy way to check that the value is all ones:
def only_ones(n):
n_str = str(n)
return set(n_str) == set(['1'])
You could do something more "mathy", but I'm not sure that it would be any faster. It would much more easily
generalize to other bases (than 10) if that's something you were interested in though
def only_ones(n):
return (n % 10 == 1) and (n == 1 or only_ones2(n / 10))
Uncertainty about how to generate the specific recurrence relation...
As for actually solving the problem though, it's actually not clear what the sequence should be.
What comes next?
123456
1234567
12345678
123456789
?
Is it 1234567890? Or 12345678910? Or 1234567900?
Without answering this, it's not possible to solve the problem in any general way (unless in fact the 111..s
terminate before you get to this issue).
I'm going to go with the most mathematically appealing assumption, which is that the value in question is the
sum of all the 11111... values before it (note that 12 = 11 + 1, 123 = 111 + 11 + 1, 1234 = 1111 + 111 + 11 + 1, etc...).
A solution
In this case, you could do something along these lines:
def sequence_gen():
a = 1
b = 1
i = 2
while only_ones(b):
yield b
b = a*9 + i
a += b
i += 1
Notice that I've put this in a generator in order to make it easier to only grab as many results from this
sequence as you actually want. It's entirely possible that this is an infinite sequence, so actually running
the while code by itself might take a while ;-)
s = sequence_gen()
s.next() #=> 1
s.next() #=> 11
A generator gives you a lot of flexibility for things like this. For instance, you could grab the first 10 values of the sequence using the itertools.islice
function:
import itertools as it
s = sequence_gen()
xs = [x for x in it.islice(s, 10)]
print xs

Printing in a loop

I have the following file I'm trying to manipulate.
1 2 -3 5 10 8.2
5 8 5 4 0 6
4 3 2 3 -2 15
-3 4 0 2 4 2.33
2 1 1 1 2.5 0
0 2 6 0 8 5
The file just contains numbers.
I'm trying to write a program to subtract the rows from each other and print the results to a file. My program is below and, dtest.txt is the name of the input file. The name of the program is make_distance.py.
from math import *
posnfile = open("dtest.txt","r")
posn = posnfile.readlines()
posnfile.close()
for i in range (len(posn)-1):
for j in range (0,1):
if (j == 0):
Xp = float(posn[i].split()[0])
Yp = float(posn[i].split()[1])
Zp = float(posn[i].split()[2])
Xc = float(posn[i+1].split()[0])
Yc = float(posn[i+1].split()[1])
Zc = float(posn[i+1].split()[2])
else:
Xp = float(posn[i].split()[3*j+1])
Yp = float(posn[i].split()[3*j+2])
Zp = float(posn[i].split()[3*j+3])
Xc = float(posn[i+1].split()[3*j+1])
Yc = float(posn[i+1].split()[3*j+2])
Zc = float(posn[i+1].split()[3*j+3])
Px = fabs(Xc-Xp)
Py = fabs(Yc-Yp)
Pz = fabs(Zc-Zp)
print Px,Py,Pz
The program is calculating the values correctly but, when I try to call the program to write the output file,
mpipython make_distance.py > distance.dat
The output file (distance.dat) only contains 3 columns when it should contain 6. How do I tell the program to shift what columns to print to for each step j=0,1,....
For j = 0, the program should output to the first 3 columns, for j = 1 the program should output to the second 3 columns (3,4,5) and so on and so forth.
Finally the len function gives the number of rows in the input file but, what function gives the number of columns in the file?
Thanks.
Append a , to the end of your print statement and it will not print a newline, and then when you exit the for loop add an additional print to move to the next row:
for j in range (0,1):
...
print Px,Py,Pz,
print
Assuming all rows have the same number of columns, you can get the number of columns by using len(row.split()).
Also, you can definitely shorten your code quite a bit, I'm not sure what the purpose of j is, but the following should be equivalent to what you're doing now:
for j in range (0,1):
Xp, Yp, Zp = map(float, posn[i].split()[3*j:3*j+3])
Xc, Yc, Zc = map(float, posn[i+1].split()[3*j:3*j+3])
...
You don't need to:
use numpy
read the whole file in at once
know how many columns
use awkward comma at end of print statement
use list subscripting
use math.fabs()
explicitly close your file
Try this (untested):
with open("dtest.txt", "r") as posnfile:
previous = None
for line in posnfile:
current = [float(x) for x in line.split()]
if previous:
delta = [abs(c - p) for c, p in zip(current, previous)]
print ' '.join(str(d) for d in delta)
previous = current
just in case your dtest.txt grows larger and you don't want to redirect your output but rather write to distance.dat, especially, if you want to use numpy. Thank #John for pointing out my mistake in the old code ;-)
import numpy as np
pos = np.genfromtxt("dtest.txt")
dis = np.array([np.abs(pos[j+1] - pos[j]) for j in xrange(len(pos)-1)])
np.savetxt("distance.dat",dis)

Is there a better way to convert from decimal to binary in python?

I need to convert from an integer to a list of size 8 that is the binary representation of that number (number <= 255) and back. Currently I am using these lines
list(bin(my_num)[2:].rjust(8,'0'))
int("".join(my_list),2)
I did some googling, but had a hard time finding relevant information. I'm just curious if there is a faster, or more standard way to do this.
edit:
Would using bit masking make it faster. E.g. something like this
[(my_num>>y)&1 for y in xrange(7,-1,-1)]
Like I mentioned in a comment I am using this for a steganography app I am writing, so I am doing this thousands of times (3 times per pixel in an image), so speed is good.
In Python 2.6 or newer, use format syntax:
'{0:0=#10b}'.format(my_num)[2:]
# '00001010'
One of the neat things about Python strings is that they are sequences. If all you need to do is iterate through the characters, then there is no need to convert the string to a list.
Edit: For steganography, you might be interested in converting a stream of characters into a stream of bits. Here is how you could do that with generators:
def str2bits(astr):
for char in astr:
n=ord(char)
for bit in '{0:0=#10b}'.format(n)[2:]:
yield int(bit)
And to convert a stream of bits back into a stream of characters:
def grouper(n, iterable, fillvalue=None):
# Source: http://docs.python.org/library/itertools.html#recipes
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
return itertools.izip_longest(*[iter(iterable)]*n,fillvalue=fillvalue)
def bits2str(bits):
for b in grouper(8,bits):
yield chr(int(''.join(map(str,b)),2))
For example, you could use the above functions like this:
for b in str2bits('Hi Zvarberg'):
print b,
# 0 1 0 0 1 0 0 0 0 1 1 0 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 1 1 0 1 0 0 1 1 1 0 1 1 0 0 1 1 0 0 0 0 1 0 1 1 1 0 0 1 0 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0 1 0 1 1 1 0 0 1 0 0 1 1 0 0 1 1 1
# To show bits2str is the inverse of str2bits:
print ''.join([c for c in bits2str(str2bits('Hi Zvarberg'))])
# Hi Zvarberg
Also, SO guru Ned Batchelder does some steganography-related experiments using Python and PIL here. You may be able to find some useful code there.
If you find you need more speed (and still want to code this in Python), you may want to look into using numpy.
You could use zfill instead of rjust.
list(bin(my_num)[2:].zfill(8))
Here is one method for decimal to binary conversion:
divide the decimal number by 2
take the remainder and record it in on the side
divide the quotient by 2
repeat until the decimal cannot be divided further
record the remainder in reverse order and you get the resultant binary number
Which may be coded as:
d=int(raw_input("enter your decimal:"))
l=[]
while d>0:
x=d%2
l.append(x)
d=d/2
l.reverse()
for i in l:
print i,
print " is the decimal representation of givin binary data."
I have given here program for decimal to binary conversion.
print "Program for Decimal to Binary Conversion"
n = 0
bin = 0
pos = 1
print "Enter Decimal Number:",
n = input()
while(n > 0):
bin = bin + (n % 2) * pos;
n = n / 2;
pos *= 10;
print "The Binary Number is: ", bin
#sample output
#Program for Decimal to Binary Conversion
#Enter Decimal Number: 10
#The Binary Number is: 1010
First solution:
A fast method must not use loops.
I would recommend using a lookup table that you would build once and use as often you wish.
tb = []
for i in range(256):
tb.append( f"{i:08b}")
# once build you can use it for the whole image.
print( tb[27]) # will print: 00011011
Second solution:
but if you're really serious about speed, you should not use characters. You should load your image in a bytearray (it is mutable) and directly modify bits in pixel.
img[2][8] |≃ 0b10 # set second bit from right
img[2][8] |= 1<<1 # same
img[2][8] &= ~0b10 # reset second bit
img[2][8] &= ~1<<1 # same
img[2][8] ^= 0b1010 # invert second and fourth bits

Categories