User input for triangles in python - python

I would like to create a triangle and take user input from the user. I have already created the function for creating triangles.
Function:
def triangle(rows):
PrintingList = list()
for rownum in range (rows ):
PrintingList.append([])
for iteration in range (rownum):
newValue = raw_input()
PrintingList[rownum].append(newValue)
But this takes input in this way..
3
7
4
2
4
6
8
5
9
3
I need it to take a input like this:
3
7 4
2 4 6
8 5 9 3
How do it change it to take input in this way? need some guidance on this...

for rownum in range (rows ):
PrintingList.append([])
newValues = raw_input().strip().split()
PrintingList[rownum] += newValues
I don't see here if you need or not to convert input from strings to ints.. But if you need, this will look like
for rownum in range (rows ):
PrintingList.append([])
newValues = map(int, raw_input().strip().split())
PrintingList[rownum] += newValues

Related

Python: How to print multiplication table based on two inputs?

I'm attempting to write a program called multChart(x,y) that prints a multiplication table based on two inputs, one specifying the number of rows to print and another specifying the number of columns. So it would look like this:
>>> multChart(4,5):
1: 1 2 3 4 5
2: 2 4 6 8 10
3: 3 6 9 12 15
4: 4 8 12 16 20
Here's what my current code looks like:
def multChart(x,y):
for i in range(1,x+1):
print(i,':',i*1,i*2,i*3,i*4,i*5)
I'm totally stuck on how to implement the y value. I also know there should be a better way of printing the multiplication instead of i * multiples of five, but I'm not sure what loop to use. Any help would be greatly appreciated.
You need another loop inside your print for looping over the y range:
def multChart(x, y):
for i in range(1, x+1):
print(i, ':', *[i * z for z in range(1, y+1)])
def multChart(x,y):
for i in range(1,x+1):
print(i, ':', end=" ")
for j in range(1,y+1):
print(i*j, end =" ")
print()
multChart(4,5)
produces
1 : 1 2 3 4 5
2 : 2 4 6 8 10
3 : 3 6 9 12 15
4 : 4 8 12 16 20
You can use a second for loop for the second index. Also, note that you can use end in the print statement.
def multChart(x,y):
for i in range(1,x+1):
print(i,':',*list(map(lambda y: i*y,list(range(1,y+1 ) ) ) ) )
multChart(4,5)

Group by a range of numbers Python

I have a list of numbers in a python data frame and want to group these numbers by a specific range and count. The numbers range from 0 to 20 but lets say there might not be any number 6 in that case I want it to show 0.
dataframe column looks like
|points|
5
1
7
3
2
2
1
18
15
4
5
I want it to look like the below
range | count
1 2
2 2
3 1
4 1
5 2
6 0
7 ...
8
9...
I would iterate through the input lines and fill up a dict with the values.
All you have to do then is count...
import collections
#read your input and store the numbers in a list
lines = []
with open('input.txt') as f:
lines = [int(line.rstrip()) for line in f]
#pre fill the dictionary with 0s from 0 to the highest occurring number in your input.
values = {}
for i in range(max(lines)+1):
values[i] = 0
# increment the occurrence by 1 for any found value
for val in lines:
values[val] += 1
# Order the dict:
values = collections.OrderedDict(sorted(values.items()))
print("range\t|\tcount")
for k in values:
print(str(k) + "\t\t\t" + str(values[k]))
repl: https://repl.it/repls/DesertedDeafeningCgibin
Edit:
a slightly more elegant version using dict comprehension:
# read input as in the first example
values = {i : 0 for i in range(max(lines)+1)}
for val in lines:
values[val] += 1
# order and print as in the first example

How to delete a matrix cell's neighbors which are the same value with it

I have a matrix as shown below (taken from a txt file with an argument), and every cell has neighbors. Once you pick a cell, that cell and all neighboring cells that containing the same number will disappear.
1 0 4 7 6 8
0 5 4 4 5 5
2 1 4 4 4 6
4 1 3 7 4 4
I've tried to do this with using recursion. I separated function four parts which are up(), down() , left() and right(). But I got an error message: RecursionError: maximum recursion depth exceeded in comparison
cmd=input("Row,column:")
cmdlist=command.split(",")
row,column=int(cmdlist[0]),int(cmdlist[1])
num=lines[row-1][column-1]
def up(x,y):
if lines[x-2][y-1]==num and x>1:
left(x,y)
right(x,y)
lines[x-2][y-1]=None
def left(x,y):
if lines[x-1][y-2]==num and y>1:
up(x,y)
down(x,y)
lines[x-1][y-2]=None
def right(x,y):
if lines[x-1][y]==num and y<len(lines[row-1]):
up(x,y)
down(x,y)
lines[x-1][y]=None
def down(x,y):
if lines[x][y-1]==num and x<len(lines):
left(x,y)
right(x,y)
lines[x][y-1]=None
up(row,column)
down(row,column)
for i in lines:
print(str(i).strip("[]").replace(",","").replace("None"," "))
When I give the input (3,3) which represents the number of "4", the output must be like this:
1 0 7 6 8
0 5 5 5
2 1 6
4 1 3 7
I don't need fixed code, just the main idea will be enough. Thanks a lot.
Recursion error happens when your recursion does not terminate.
You can solve this without recursing using set's of indexes:
search all indexes that contain the looked for number into all_num_idx
add the index you are currently at (your input) to a set tbd (to be deleted)
loop over the tbd and add all indexed from all_num_idx that differ only in -1/+1 in row or col to any index thats already in the set
do until tbd does no longer grow
delete all indexes from tbd:
t = """4 0 4 7 6 8
0 5 4 4 5 5
2 1 4 4 4 6
4 1 3 7 4 4"""
data = [k.strip().split() for k in t.splitlines()]
row,column=map(int,input("Row,column:").strip().split(";"))
num = data[row][column]
len_r =len(data)
len_c = len(data[0])
all_num_idx = set((r,c) for r in range(len_r) for c in range(len_c) if data[r][c]==num)
tbd = set( [ (row,column)] ) # inital field
tbd_size = 0 # different size to enter while
done = set() # we processed those already
while len(tbd) != tbd_size: # loop while growing
tbd_size=len(tbd)
for t in tbd:
if t in done:
continue
# only 4-piece neighbourhood +1 or -1 in one direction
poss_neighbours = set( [(t[0]+1,t[1]), (t[0],t[1]+1),
(t[0]-1,t[1]), (t[0],t[1]-1)] )
# 8-way neighbourhood with diagonals
# poss_neighbours = set((t[0]+a,t[1]+b) for a in range(-1,2) for b in range(-1,2))
tbd = tbd.union( poss_neighbours & all_num_idx)
# reduce all_num_idx by all those that we already addded
all_num_idx -= tbd
done.add(t)
# delete the indexes we collected
for r,c in tbd:
data[r][c]=None
# output
for line in data:
print(*(c or " " for c in line) , sep=" ")
Output:
Row,column: 3,4
4 0 7 6 8
0 5 5 5
2 1 6
4 1 3 7
This is a variant of a "flood-fill-algorythm" flooding only cells of a certain value. See https://en.wikipedia.org/wiki/Flood_fill
Maybe you should replace
def right(x,y):
if lines[x-1][y]==num and y<len(lines[row-1]):
up(x,y)
down(x,y)
lines[x-1][y]=None
by
def right(x,y):
if lines[x-1][y]==num and y<len(lines[row-1]):
lines[x-1][y]=None
up(x - 1,y)
down(x - 1,y)
right(x - 1, y)
and do the same for all the other functions.
Putting lines[x-1][y]=None ensure that your algorithm stops and changing the indices ensure that the next step of your algorithm will start from the neighbouring cell.

How to print a sequence stacked in a "pyramid" with alternating sort?

I want to print the following sequence of integers in a pyramid (odd rows sorted ascending, even rows sorted descending). If S=4, it must print four rows and so on.
Expected output:
1
3 2
4 5 6
10 9 8 7
I tried out the following code but it produced the wrong output.
S=int(input())
for i in range(1,S+1):
y=i+(i-1)
if i%2!=0:
print(*range(i,y+1))
elif i%2==0:
print(*range(y,i-1,-1))
# Output:
# 1
# 3 2
# 3 4 5
# 7 6 5 4
You need some way of either keeping track of where you are in the sequence when printing each row, generating the entire sequence and then chunking it into rows, or... (the list of possible approaches goes on and on).
Below is a fairly simple approach that just keeps track of a range start value, calculates the range stop value based on the row number, and reverses even rows.
rows = int(input())
start = 1
for n in range(1, rows + 1):
stop = int((n * (n + 1)) / 2) + 1
row = range(start, stop) if n % 2 else reversed(range(start, stop))
start = stop
print(*row)
# If rows input is 4, then output:
# 1
# 3 2
# 4 5 6
# 10 9 8 7
Using itertools.count and just reversing the sublist before printing on even rows
from itertools import count
s = 4
l = count(1)
for i in range(1, s+1):
temp = []
for j in range(i):
temp.append(next(l))
if i % 2:
print(' '.join(map(str, temp)))
else:
print(' '.join(map(str, temp[::-1])))
1
3 2
4 5 6
10 9 8 7

How to make a grid with integers in python?

I have the following code which has to print out a board with numbers according to the size the user specified (for instance 3 means a 3 x 3 board):
n = d * d
count = 1
board = []
for i in range(d):
for j in range(d):
number = n - count
if number >= 0 :
tile = number
board.append[tile]
else:
exit(1)
count += 1
print(board)
I need to get this in a grid, so that the board is 3 x 3 in size ike this:
8 7 6
5 4 3
2 1 0
What I tried to do is to get each row in a list (so [8 7 6] [5 4.. etc) and then print those lists in a grid. In order to do that, I guess I would have to create an empty list and then add the numbers to that list, stopping after every d, so that each list is the specified length.
I now have a list of the numbers I want, but how do I seperate them into a grid?
I would really appreciate any help!
Here a function that takes the square size and print it.
If you need explanation don't hesitate to ask.
def my_print_square(d):
all_ = d * d
x = list(range(all_))
x.sort(reverse=True) # the x value is a list with all value sorted reverse.
i=0
while i < all_:
print(" ".join(map(str, x[i:i+d])))
i += d
my_print_square(5)
24 23 22 21 20
19 18 17 16 15
14 13 12 11 10
9 8 7 6 5
4 3 2 1 0
By default the print() function adds "\n" to the end of the string you want to print. You can override this by passing in the end argument.
print(string, end=" ")
In this case we are adding a space instead of a line break.
And then we have to print the linebreaks manually with print() at the end of each row.
n = d * d
count = 1
max_len = len(str(n-1))
form = "%" + str(max_len) + "d"
for i in range(d):
for j in range(d):
number = n - count
if number >= 0 :
tile = number
else:
exit(1)
count += 1
print(form%(tile), end=" ")
print()
EDIT: by figuring out the maximum length of the numbers we can adjust the format in which they're printed. This should support any size of board.
You can create the board as a nested list, where each list is a row in the board. Then concatenate them at the end:
def get_board(n):
# get the numbers
numbers = [i for i in range(n * n)]
# create the nested list representing the board
rev_board = [numbers[i:i+n][::-1] for i in range(0, len(numbers), n)]
return rev_board
board = get_board(3)
# print each list(row) of the board, from end to start
print('\n'.join(' '.join(str(x) for x in row) for row in reversed(board)))
Which outputs:
8 7 6
5 4 3
2 1 0
If you want to align the numbers for 4 or 5 sized grids, just use a %d format specifier:
board = get_board(4)
for line in reversed(board):
for number in line:
print("%2d" % number, end = " ")
print()
Which gives an aligned grid:
15 14 13 12
11 10 9 8
7 6 5 4
3 2 1 0

Categories