So i've managed to get Pascals Triangle to print successfully in terms of what numbers are printed, however, i can't get the formatting correct using:
n = int(input("Enter value of n: "))
def printPascal(n):
if n <= 0: #must be positive int
return "N must be greater than 0"
elif n == 1: #first row is 1, so if only 1 line is wanted, output always 1
return [[1]]
else:
next_row = [1] #each line begins with 1
outcome = printPascal(n-1)
prev_row = outcome[-1]
for i in range(len(prev_row)-1): #-1 from length as using index
next_row.append(prev_row[i] + prev_row[i+1])
next_row += [1]
outcome.append(next_row) #add result of next row to outcome to print
return outcome
print(printPascal(n))
this prints as:
Enter value of n: 6
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1]
which is correct, however i want it to be formatted as a right angle triangle such as:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
my issue is, i'm new to this language and cannot work out where to put the splits and such in my code to be able to get it to print as this.
Any help or nudge in the right direction would be very much appreciated.
Thanks.
You want to use the str.join() function, which prints out all elements in a list separated by a string:
>>> L = printPascal(6)
>>> for row in L:
... print ' '.join(map(str, row))
...
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
' '.join(list) means you're printing out every element in a list separated by a space (' ').
However, every element in the list needs to be a string in order for the join function to work. Yours are integers. To fix this, I've changed all the integers to strings by doing map(str, row). This is equivalent to:
new_list = []
for item in row:
new_list.append(str(item))
Or as a list comprehension:
[str(item) for item in row]
Related
I have a dataFrame:
df =
a b c d e
0 0 1 2 3 4
1 1 2 3 0 4
2 2 3 1 4 0
I would like to get the values that occur N times in a certain column.
For example, if I want to get all the values that occur 2 times in column "e", i would get result = [4], and if I would like to get all the values that occur 1 time in column "d", I would get result = [3,0,4].
I can do df['e'].value_counts() == 2 but that gives a True/False series. I would just want to get the values in "True".
What you did returns a True/False series, so we need to use this to get the index values!
col = 'd'
n = 1
df[col].value_counts() == n
# 3 True
# 0 True
# 4 True
# Name: d, dtype: bool
To get the indeces that have True behind them, we can do:
df[col].value_counts().index[df[col].value_counts() == n]
# Int64Index([3, 0, 4], dtype='int64')
To create a list, we only need to use list():
list(df[col].value_counts().index[df[col].value_counts() == n])
# [3, 0, 4]
EDIT:
You can assign val_counts = df[col].value_counts() and use this like so (or see the answer from #jezrael):
list(val_counts.index[val_counts == n])
# [3, 0, 4]
You can filter index values after Series.value_counts:
s = df['e'].value_counts()
L = s.index[s.eq(2)].tolist()
print (L)
[4]
s = df['d'].value_counts()
L = s.index[s.eq(1)].tolist()
print (L)
[0, 4, 3]
There are three columns in df: mins, maxs, and col. I would like to generate a binary list according to the following rule: if col[i] is smaller than or equal to mins[i], add a "1" to the list and keep adding "1" for each row until col[i+n] is greater than or equal maxs[i+n]. After reaching maxs[i+n], add "0" to the list for each row until finding the next row where col[i] is smaller than or equal to mins[i]. Repeat this entire process till going over all rows.
For example,
col mins maxs
2 1 6 (0)
4 2 6 (0)
2 3 7 (1)
5 5 6 (1)
4 3 8 (1)
4 2 5 (1)
5 3 5 (0)
4 0 5 (0)
3 3 8 (1)
......
So the list would be [0,0,1,1,1,1,0,0,1]. Does this make sense?
I gave it a shot and wrote the following, which unfortunately did not achieve what I wanted.
def get_list(col, mins, maxs):
l = []
i = 0
while i <= len(col):
if col[i] <= mins[i]:
l.append(1)
while col[i+1] <= maxs[i+1]:
l.append(1)
i += 1
break
break
return l
Thank you so much folks!
My answer may not be elegant but should work according to your expectation.
Import the pandas library.
import pandas as pd
Create dataframe according to data provided.
input_data = {
'col': [2, 4, 2, 5, 4, 4, 5, 4, 3],
'mins': [1, 2, 3, 5, 3, 2 , 3, 0, 3],
'maxs': [6, 6, 7, 6, 8, 5, 5, 5, 8]
}
dataframe_ = pd.DataFrame(data=input_data)
Using a for loop iterate over the rows. The switch variable will change accordingly depending on the conditions was provided which results in the binary column being populated.
binary_switch = False
for index, row in dataframe_.iterrows():
if row['col'] <= row['mins']:
binary_switch = True
elif row['col'] >= row['maxs']:
binary_switch = False
binary_output = 1 if binary_switch else 0
dataframe_.at[index, 'binary'] = binary_output
dataframe_['binary'] = dataframe_['binary'].astype('int')
print(dataframe_)
Output from code.
col mins maxs binary
0 2 1 6 0
1 4 2 6 0
2 2 3 7 1
3 5 5 6 1
4 4 3 8 1
5 4 2 5 1
6 5 3 5 0
7 4 0 5 0
8 3 3 8 1
Your rules give the following decision tree:
1: is col <= mins?
True: l.append(1)
False: next question
2: was col <= mins before?
False: l.append(0)
True: next question:
3: is col >= maxs?
True: l.append(0)
False: l.append(1)
Making this into a function with an if/else tree, you get this:
def make_binary_list(df):
l = []
col_lte_mins = False
for index, row in df.iterrows():
col = row["col"]
mins = row["mins"]
maxs = row["maxs"]
if col <= mins:
col_lte_mins = True
l.append(1)
else:
if col_lte_mins:
if col >= maxs:
col_lte_mins = False
l.append(0)
else:
l.append(1)
else:
l.append(0)
return l
make_binary_list(df) gives [0, 0, 1, 1, 1, 1, 0, 0, 1]
I'm trying to loop through the array, so that we take the first two values from the array at once, then the following iterations will take one value at a time until half of the array. When it comes to the middle of the field, it starts the same way, but from the end of the field towards the beginning. It takes first the last two values and then further iterations one value at a time to the center of the array.
I can do each part separately, the problem is putting it together
classic forward loop:
for i in a:
print(i)
output:
1
2
3
4
5
6
reverse loop:
for i in reversed(a):
print(i)
output:
6
6
5
4
3
2
1
a cycle that takes 2 values:
myList =np.array([1, 2, 3, 4, 5, 6])
for x,y in (myList[i:i+2] for i in range(0,len(myList),2)):
print(x,y)
output:
1 2
3 4
5 6
reverse loop:
for x,y in (myList[i:i+2] for i in reversed(range(0,len(myList),2))):
print(x,y)
output:
5 6
3 4
1 2
I would need such an output
example
a=np.array([1,2,3,4,5,6,7,8])
output
1 2
3
4
7 8 #or 8 7
6
5
or
a=np.array([1,2,3,4,5,6,7,])
output:
1 2 #or 1 2
3 #3
7 6 #4
5 #7 6
4 #5
the array can be of different sizes without restriction.
It is possible?
You can see the problem like that
each group of values is printed the same way
you apply to the first half and to the second half in reverse
def print_half(half_values):
print(*half_values[:2])
print(*half_values[2:], sep="\n")
def print_array(values):
print_half(values[:len(values) // 2])
print_half(list(reversed(values[len(values) // 2:])))
print_array([1, 2, 3, 4, 5, 6, 7])
print_array([1, 2, 3, 4, 5, 6, 7, 8])
The best way I can see is by storing a current index. First, the current index is 0, and after the first step it is set to 2 (first 2 items). Then, we keep incrementing while current_index < len // 2, at which point we set current_index = len - 1 and while current_index > len // 2 we decrement.
import numpy as np
def printArr(List):
for i in range(len(List)):
if i < 2:
print(List[i], end=' ')
continue
elif i == 2:
print('\n', end='')
print(List[i])
a=np.array([1,2,3,4,5,6,7,])
midle = int(len(a) / 2)
list1, list2 = a[:midle], a[-1: midle-1: -1]
printArr(list1)
printArr(list2)
while I was working on the Python practice, I found a question that I cannot solve by myself.
The question is,
Input one integer(n), and then write the codes that make a triangle using 1 to 'n'. Use the following picture. You should make only one function, and call that function various times to solve the question. The following picture is the result that you should make in the codes.
Receive one integer as an argument, print the number from 1 to the integer received as a factor in a single line, and then print the line break character at the end. Once this function is called, only one line of output should be printed.
So by that question, I found that this is a question that requires the
recursion since I have to call your function only once.
I tried to work on the codes that I made many times, but I couldn't solve it.
global a
a = 1
def printLine(n):
global a
if (n == 0):
return
for i in range(1, a + 1):
print(i, end=" ")
print()
a += 1
for k in range(1, n+1):
print(k, end=" ")
print()
printLine(n - 1)
n = int(input())
printLine(n)
Then I wrote some codes to solve this question, but the ascending and descending part is kept overlapping. :(
What I need to do is to break two ascending and descending parts separately in one function, but I really cannot find how can I do that. So which part should I have to put the recursive function call?
Or is there another way can divide the ascending and descending part in the function?
Any ideas, comments, or solutions are appreciated.
Thx
You can use the below function:
def create_triangle(n, k: int = 1, output: list = []):
if n == 1:
output.append(n)
return output
elif k >= n:
output.append(" ".join([str(i) for i in range(1, n + 1)]))
return create_triangle(n - 1, k)
else:
output.append(" ".join([str(i) for i in range(1, n + 1)[:k]]))
return create_triangle(n, k + 1)
for i in create_triangle(5):
print(i)
Output:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
# function to print all the numbers from 1 to n with spaces
def printLine(k):
# create a range. if k is 4, will create the range: 1, 2, 3, 4
rng = range(1, k + 1)
# convert each number to string
str_rng = map(lambda x: str(x), rng)
# create one long string with spaces
full_line = " ".join(str_rng)
print(full_line)
# capture input
n = int(input())
# start from 1, and up to n, printing the first half of the triangle
for i in range(1, n):
printLine(i)
# now create the bottom part, by creating a descending range
for i in range(n, 0, -1):
printLine(i)
Using default parameter as a dict, you can manipulate it as your function variables, so in that way, you can have a variable in your function that keeps the current iteration you are at and if your function is ascending or descending.
def triangle_line(n, config={'max':1, 'ascending':True}):
print(*range(1, config['max'] + 1))
if config['ascending']:
config['max'] += 1
else:
config['max'] -= 1
if config['max'] > n:
config['ascending'] = False
config['max'] = n
elif config['max'] == 0:
config['ascending'] = True
config['max'] = 1
Each call you make will return one iteration.
>>> triangle_line(4)
1
>>> triangle_line(4)
1 2
>>> triangle_line(4)
1 2 3
>>> triangle_line(4)
1 2 3 4
>>> triangle_line(4)
1 2 3 4
>>> triangle_line(4)
1 2 3
>>> triangle_line(4)
1 2
>>> triangle_line(4)
1
Or you can run on a loop, two times your input size.
>>> n = 4
>>> for i in range(0,n*2):
... triangle_line(n)
...
1
1 2
1 2 3
1 2 3 4
1 2 3 4
1 2 3
1 2
1
I have
for i in range(0, 11): print i, "\n", i
I'd like my python program to print this way for each for loop
1st loop:
1
1
2nd loop:
1
2
2
1
3rd loop:
1
2
3
3
2
1
I've tried using \r\n or \033[1A but they just overwrite the previous line. Is there a way I can "push" the outputted line down so I don't overwrite it?
One way to do this,
def foo(x, limit):
if x < limit :
print x
foo(x + 1, limit)
print x
foo(1, 11)
It's not possible to do it in 1 for loop as you're currently trying.
As I suggested, you can do it like this by using lists
>>> l1 = []
>>> l2 = []
>>> for i in range(0, 11):
... l1.append(i)
... l2 = [i] + l2
>>> l1.extend(l2)
>>> for i in l1:
... print i
0
1
2
3
4
5
6
7
8
9
10
10
9
8
7
6
5
4
3
2
1
0
Concatenation of two list generators.
>>> ladder = [x for x in range(5)] + [x for x in range(5,-1,-1)]
>>> ladder
[0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0]
>>> for x in ladder:
... print x
...
0
1
2
3
4
5
4
3
2
1
0
>>>
one of ways to solve this
def two_side_print(start, end):
text = [str(i) for i in range(start,end)]
print '\n'.join(text), '\n', '\n'.join(reversed(text))
two_side_print(1, 11)
Another option is to save the printed values in a list and print that list in reverse order in each loop iteration.
My suggestion:
l = []
for i in range(1, 5):
print 'Loop '+str(i) # This is to ease seeing the printing results
for val in l:
print val
print i
l.insert(len(l),i)
for val in reversed(l):
print val
The output for a loop iterating from 0 to 5:
Loop 1
1
1
Loop 2
1
2
2
1
Loop 3
1
2
3
3
2
1
Loop 4
1
2
3
4
4
3
2
1
I hope this is what you are looking for.
You can use a recursive function to help here:
def print_both_ways(start, end):
print(start)
if start != end:
print_both_ways(start+1, end)
print(start)
Usage:
print_both_ways(1,3) # prints 1,2,3,3,2,1 on separate lines