W by H grid tiles? - python

Imagine that we have a w by h grid, where the tiles are numbered starting at 1 in the top left corner. w (for width) and h (for height) have been stored in a function. You have access to these stored values, as long as you call them w and h. Write a program to return: The column number of a tile number given by the user. Start counting columns at column 1.
import subprocess
def template(w, h, t):
#w and h are memory locations that already contain values
tile = t
sum = ((t - 1) // w) + 1
#END OF YOUR CODE
failed = 0
width = 1
while width <= 3:
height = 1
while height <= 3:
tile = 1
while tile <= width * height:
result = template(width, height, tile)
col = (tile - 1) % width + 1
if (result == col):
print "On a " + str(width) + " by " + str(height) +" board, with tile " + str(tile) +", col is " + str(col) + ", you got it RIGHT!"
else:
print "On a " + str(width) + " by " +:str(height)%+" board, with tile " + str(tile)%+", col is " + str(col) + ", you got: " + str(result)
failed = 1
tile += 1
height += 1
width += 1
if (failed == 0):
print "Your code is CORRECT!"
print "Please check your code, at least one test case did not pass."
I am almost there I think, but this formula isn't quite right and I'm out of ideas.

See below pseudo code, this approach should work for you,
# divide t by h, the tile should reside in the next row
tileRow = (t/h)+1
# get the reminder of the division, that's the column number
tileColumn = t%h
see the sample code I tried below
>>> w = 5
>>> h = 10
>>> t =36
>>> tileRow = (t/h)+1
>>> tileRow
4 # the tile is in the 4th row
>>> tileColumn = t%h
>>> tileColumn
6 # the tile is in the 6th column
>>>
You may also have to check if the tile number is within in range, in the above example its w x h (50)
Please comment if you need anymore clarification. If this resolves your problem you may accept and vote the answer

To create the grid, use a list comprehension.
grid=[list(range(x,x+w))for x in range(1,w*h,w)]
To find the column number of t, find the remainder of t divided by w:
t%w
So the function would be:
def template(w,h,t):
grid=[list(range(x,x+w))for x in range(1,w*h,w)]
return t%w
Example:
template(6,5,22)
Output:
4

Related

I no longer have an alignment issue, however, when I print out my X's and O's there will be a 0 next to them. Does anyone know a different solution?

This is what I have so far, if you have any ideas please let me know. It would mean a lot to me.
a_list = list(range(1, squared_input + 1))
turn = 0
Symbol_1 = "X"
Symbol_2 = "O"
while turn <= 9:
X = 1
while X < squared_input + 1 :
print(str(a_list[X - 1]).zfill(2), end= "")
if X%board_size == 0 :
print("")
print(("--+" * (board_size - 1)), end="")
print("--")
else:
print("|", end="")
X = X + 1
turn = turn + 1
Symbol_1, Symbol_2 = Symbol_2, Symbol_1
print("You are user " + Symbol_1 + ".")
user_input = input("Please pick a slot on the game board (using numbers 1 - " + str(squared_input) + "): ")
a_list[int(user_input) - 1] = Symbol_1
The zeros come from your call to zfill which explicitly pads a string with 0 to a requested size. You call zfill(2) with a string that contains a single character. So the function pads that to length two by adding a 0.
To pad with blanks you can for example use the format() function or just something like
'%2d' % a_list[X-1]
which will pad each number to length 2 from the left with blanks, or
'%-2d' % a_list[X-1]
which will pad each number to length 2 from the right with blanks.

Printing an ASCII diamond with set width in python

Yes, this is a homework task. But just please, if you're going to give me the code please tell me what you've done in detail. I am extremely new to this.
So the task is to print an ASCII diamond depending on what width the user inputs. I can do the first half of the diamond, just not the bottom half, for some reason I just cannot see how to do it.
Here's my code:
wid = int(input("Width: "))
i = 1
while i <= wid:
print(" " * (wid - i) + "* " * i)
i = i + 1
Which will output the following if wid = 5:
Width: 5
*
* *
* * *
* * * *
* * * * *
I tried to explain the code with comments. I hope it helps.
wid = int(input("Width: "))
#no. of lines will be double the width
#each loop prints a line.
for i in range(wid *2):
#first half of the diamond
if i<=wid:
no_of_spaces = wid - i
no_of_stars = i
print(" "*no_of_spaces + "* "*no_of_stars)
#next half of the diamond
else:
no_of_spaces = i - wid
no_of_stars = 2*wid - i
print(" "*no_of_spaces + "* "*no_of_stars)
i=1
j=input("ENTER NO =")
l=0
for i in range(i,j-((j/2)-1),1):
print (' ' * ((j+1)/2-i)+'*' *(i*2-1))
l=(j/2+1)
while (i==l):
i=1
for i in range(i,j,1):
print (' ' *((i*2)-i)+'*' *(j-i*2))
if [i==j-1]:
l=raw_input('<press enter to exit>')
You start with i = 1 and go until i > wid to make the top. To make the bottom of the diamond, you must do the reverse of what you did for the top. The code is easy, but I won't write it unless you want me to.
after your while
i=i-2
while i>0:
print(" "*(wid-i)+"* "*i)
i=i-1;
One method
The simplest way would probably be have two loops; one counting i up to width, another counting i back down to 1.
width = int(input("Width: "))
i = 1
while i < width:
print " " * (width-i) + "* " * i
i += 1
while i > 0:
print " " * (width-i) + "* " * i
i -= 1
This is a bit unattractive because it's a little clumsy, but it's simple.
Another method
Another method is to have have a loop that counts to twice the width, doing one of two things. What it does depends on if i has passed the point of maximum width or not. So it does 'up' and 'down' in the same loop, counting i from 1 up to width*2.
width = int(input("Width: "))
i = 1
while i < width*2:
if i < width:
print " " * (width-i) + "* " * i
else:
print " " * (i-width) + "* " * (2*width-i)
i += 1
This:
print " " * (width-i) + "* " * i
...is your code. Spaces count from width down to 0, *'s from 1 up to width.
And this:
print " " * (i-width) + "* " * (2*width-i)
...is the same thing but inverted. Spaces count from 0 back up to width, and the *'s go back down from width to 1. This comes into play when i exceeds width.
Width: 4
* # first half does this onward
* *
* * *
* * * *
* * * # second half does the rest downward
* *
*
And another
Another alternative, more complex way is to use a for loop on a list that contains numbers counting up and down. For example: [1, 2, 3, 2, 1]
To make this list, this code has to be. I know, it's a bit ugly:
rows = []
for i in range(1, max+1):
rows.append(i)
rows += rows[-2::-1]
Then, you see, we run the for loop off it.
width = int(input("Width: "))
rows = []
for i in range(1, width+1):
rows.append(i)
rows += rows[-2::-1] # takes a reversed list and adds it on to the end: [1, 2, 3, 2, 1]
for i in rows:
print " " * (width-i) + "* " * i
i iterates through each of the numbers in the rows list, which looks something like [1, 2, 3, 2, 1]. Then we just need one printing gizmo.
In python, there's almost always a shorter and less comprehensible way of doing for loops, and in this case, we can get rid of two extra lines by shortening the first for loop:
width = int(input("Width: "))
rows = [ i for i in range(1, width+1)] # Brain-bending way of doing a for loop
rows += rows[-2::-1]
for i in rows:
print " " * (width-i) + "* " * i
And if you're feeling a bit crazy, here's a mere two line version of the whole thing!
width = int(input("Width: "))
print "\n".join([ " "*(width-i) + "* "*i for i in [ i for i in range(1, width+1) ]+[ i for i in range(1, width+1) ][-2::-1] ])
But I don't recommend this style of coding in general.
Sorry, I got a bit carried away at the end... but the best thing I can say to you now is try everything and play around!
Hope that helps. :)
Since some good methods have been addressed, here are some fun little hacky solutions.
Here's one using Python 2.7 string.center just for shits.
import string
width = int(raw_input("Width:"))
for i in range(width):
print string.center(i * " *", width * 2 )
for i in range(width,0,-1):
print string.center(i * " *", width * 2 )
And here's an outrageous one that ouputs using HTML to center.
file = open('file.html','w')
file.write("<div align='center'>")
for i in range(width):
file.write(i * " *")
file.write("<br>")
for i in range(width,0,-1):
file.write(i * " *")
file.write("<br>")
file.write("</div>")
file.close()
import webbrowser
webbrowser.open("file.html")
check it out (for python 2.7x) :
Filled ASCII Diamond :
width = 1
width += int(raw_input('Width : '))
for i in range (1,width):
for j in range (width,i,-1):
print " ",
for j in range (1,i,1):
print " * ",
print
for i in range (width,1,-1):
for j in range (width,i,-1):
print " ",
for j in range (1,i,1):
print " * ",
print
This works!! But not in any Browser window . . .

Python 3.3 - Create 3D-mesh as Wavefront obj-file from regular spaced vertices

I am writing a simple command line program in Python 3.3 which reads a text file of xyz-coordinates and outputs a the equivalent triangle faces in between. The export format are Wavefront obj-files (https://en.wikipedia.org/wiki/Wavefront_.obj_file). The algorthm is solely intended to work with regular spaced points from high resolution satellite scans of the earth. Actually, I am using a set of about 340000 points and creating 2 triangles in between a vertex quadrupel. The outer iteration goes in x-direction while the inner iteration is over the y-direction. So, pairs of triangle faces are creates for every vertex in y-direction until it moves on in x-direction and repeats the process. I will show you the principle pattern (the lines are the face edges):
v1--v5--v9
| \ | / |
v2--v6--v10
| / | \ |
v3--v7--v11
| \ | / |
v4--v8--v12
The code seems to work in way as importing the file in Blender or MeshLab gives reasonable results, except for one thing: All stripes of face pairs seem to be not connected with their neighbors along the x-axis. A rendered picture which demonstrates the problem:
unconnected stripes.
Normally, there shouldn't be an vertical offset between different face-stripes because they share the same vertices along their interior border(-line). Tests with less vertices and more common low coordinate values succeeded. The method was working perfectly fine. Maybe the problem lies not within my mesh generator but within the coordinate limitations of Blender, MeshLab, etcetera.
Here is the function which generates the faces and stitches everythin together in an return-string:
def simpleTriangMesh(verts):
printAll("--creating simple triangulated mesh", "\n")
maxCoords = [max(verts[0]), max(verts[1]), max(verts[2])]
minCoords = [min(verts[0]), min(verts[1]), min(verts[2])]
printAll("max. coordinates (xyz): \n", maxCoords, "\n")
printAll("min. coordinates (xyz): \n", minCoords, "\n")
xVerts = 0 # amount of vertices in x-direction
yVerts = 0 # amount of vertices in y-direction
faceAmount = 0 # amount of required faces to skin grid
i = 0
temp = verts[0][0]
while(i < len(verts[0])):
if(temp < verts[0][i]):
yVerts = int(i)
break
temp = verts[0][i]
i += 1
xVerts = int(len(verts[0]) / float(yVerts))
faceAmount = ((xVerts - 1) * (yVerts - 1)) * 2
printAll("vertices in x direction: ", xVerts, "\n")
printAll("vertices in y direction: ", yVerts, "\n")
printAll("estimated amount of triangle faces: ",
faceAmount, "\n")
printAll("----generating vertex triangles representing the faces", "\n")
# list of vertex-index quadrupels representing the faces
faceList = [[0 for line in range(0, 3)] for face in range(0, int(faceAmount))]
f = 0
v = 0
# rather to draw hypotenuse of the triangles from topleft to bottomright
# or perpendicular to that (topright to bottomleft)
tl = True # the one that changes in y-direction
tl_rem = False # to remember the hypotenuse direction of the last topmost faces
while(f < len(faceList)):
# prevent creation of faces at the bottom line
# + guarantees that v = 1 when creating the first face
if(( v % yVerts ) == 0):
v += 1
tl = not tl_rem
tl_rem = tl
if(tl):
faceList[f][0] = v
faceList[f][1] = v + yVerts
faceList[f][2] = v + yVerts + 1
f += 1
faceList[f][0] = v
faceList[f][1] = v + yVerts + 1
faceList[f][2] = v + 1
else:
faceList[f][0] = v
faceList[f][1] = v + yVerts
faceList[f][2] = v + 1
f += 1
faceList[f][0] = v + 1
faceList[f][1] = v + yVerts
faceList[f][2] = v + yVerts + 1
f += 1
v += 1
tl = not tl
printAll("----preparing obj-file-content for export", "\n")
rectMesh_Obj = "" # string containing the mesh in obj-format (ascii)
tempVerts = ""
tempFaces = ""
row = 0
while(row < len(verts[0])):
# temp = ("v" + " " + str(verts[0][row]) + " " + str(verts[1][row])
# + " " + str(verts[2][row]) + "\n")
temp = ("v" + " " + str(verts[0][row]) + " " + str(verts[2][row])
+ " " + str(verts[1][row]) + "\n")
tempVerts += temp
row += 1
row = 0
while(row < len(faceList)):
temp = ("f"
+ " " + str(int(faceList[row][0]))
+ " " + str(int(faceList[row][1]))
+ " " + str(int(faceList[row][2]))
# + " " + str(int(faceList[row][3]))
+ "\n")
tempFaces += temp
row += 1
rectMesh_Obj += tempVerts + tempFaces
return(rectMesh_Obj)
The verts-variable which is inputted into the function has the form of a 2-dimensional list, similar to:
# x y z
vertsExample = [[3334, 3333, 3332], [2555, 2554, 2553], [10.2, 5.2, 6.7]]
I hope some of you can help me out of the misery. If something requires more explanation, please let me know and I will add it to the first post.
I finally solved the issue. The problem wasn't in my mesh generator program. Blender and MeshLab (and most likely other 3D-Programs as well) do some weird things when the coordinates of vertices are too big. If am reducing the real world geographically projected coordinates to smaller relative coordinates everything works just fine (https://dl.dropboxusercontent.com/u/13547611/meshGenWorking001.png).
My guess:
The Wavefront obj-format has too limited byte-sizes for its numbers. or to be more correct: Common 3D-Programs do not expect the numbers to be so big like the real world ones. This way they interpret what they get in a confusing manner.
I hope this solution helps somebody in the future !

Draw inverted triangle of asterisk by using nested loops in Python

I've to write a program that get a series of valid inputs from user and then uses the nested loops to draw the inverted triangle.
I've managed to work out the triangle but I struggling on inverted triangle. Can anyone give me some hint on how to draw the inverted triangle by only print a single charater of * and without using * * rowlength?
Global constant
L = 10
Get rows number
rows = int(input ( 'Enter a number of rows: ' ) )
Rows cannot less than 10 or greater than 100
while rows < 10 or rows > 100:
if rows < L:
print( 'The number is too Low.' )
else:
print( 'The number is too high.' )
rows = int(input ( 'Enter the correct value: ' ) )
Display the triangle
for r in range(rows):
for c in range(r + 1):
print('*', end='')
print()
This is very similar to a question I had to do for class once, but we were implementing it in C. Actually, quite cool to go back now, reimplement it in python and look at the difference.
The problem we had in class was very similar. My python code to make this work is:
while True:
rows = input('Enter the number of rows: ')
if 3 <= rows <= 33:
break
else:
continue
padding = ' '*rows
while rows > 0:
print(padding[rows:] + '*'*rows)
rows = rows - 1
-- modified below, to print outline of inverted triangle:
# print the outline of an inverted triangle:
height = rows
# inner padding for min height (3)
inner_buffer = [0, 1, 3]
while len(inner_buffer) <= rows:
inner_buffer.append(inner_buffer[-1]+2)
while height > 0:
outer_padding = ' '*(rows - height)
if height == 1:
print(outer_padding + '*')
else:
inner_padding = ' '*(inner_buffer.pop()-2)
print(outer_padding + '*' + inner_padding + '*')
height = height - 1
There has got to be a more elegant want to code this, but simply a working hack to see if we are on the right track.
New revision below:
-- function that will produce a regular triangle, or inverted triangle as defined
def get_rows():
while True:
rows = input('Enter the number of rows: ')
if 3 <= rows <= 33:
return rows
def triangle(rows, regular=False, invert=True):
if invert:
height = -1 * rows
else:
height = 0
# inner padding for min height (3)
inner_buffer = [0, 1, 3]
while len(inner_buffer) <= rows:
inner_buffer.append(inner_buffer[-1]+2)
level = 0
while level <= rows:
outer_padding = ' '*(rows - abs(height))
if height == 0:
print(outer_padding + '*')
else:
inner_padding = ' '*( inner_buffer[ abs(height) ] )
print(outer_padding + '*' + inner_padding + '*')
height += 1
level += 1
Let me know :)

Matplotlib draw boxes

I have a set of data, where each value has a (x, y) coordinate. Different values can have the same coordinate. And I want to draw them in a rectangular collection of boxes.
For example, if I have the data:
A -> (0, 0)
B -> (0, 1)
C -> (1, 2)
D -> (0, 1)
I want to get the following drawing:
0 1 2
+++++++++++++
0 + A + B + +
+ + D + +
+++++++++++++
1 + + + C +
+++++++++++++
2 + + + +
+++++++++++++
How can I do it in Python using Matplotlib?
THANKS!
Just thought, maybe what you actually wanted to know was just this:
def drawbox(list,x,y):
# write some graphics code to draw box index x,y containing items 'list'
[[drawbox(u,x,y) for u in X.keys() if X[u]==(y,x)] for x in range(0,3) for y in range(0,3)]
# enter the data like this
X={'A':(0,0),'B':(0,1),'C':(1,2),'D':(0,1)}
# size of grid
xi=map(tuple.__getitem__,X.values(),[1]*len(X))
yi=map(tuple.__getitem__,X.values(),[0]*len(X))
xrng = (min(xi), max(xi)+1)
yrng = (min(yi), max(yi)+1)
for y in range(*yrng): # rows
print '+' * ((xrng[1]-xrng[0])*3) + '+'
k={} # each item k[x] is list of elements in xth box in this row
for x in range(*xrng):
# list of items in this cell
k[x]=[u for u in X.keys() if X[u]==(y,x)]
h=max(map(len, k.values())) # row height
for v in range(h): # lines of row
c=[]
for x in range(*xrng): # columns
if k[x]:
c.append(k[x][0])
del k[x][0]
else: c.append(' ') # shorter cell
s="+ " + "+ ".join(c) + "+"
print s
print "+" * ((xrng[1]-xrng[0])*3) + '+'
Perhaps it would be better to use the ReportLab.
Example

Categories

Resources