Calling function and passing arguments multiple times - python

I want to call the function multiple time and use it's returned argument everytime when it's called. For example:
def myfunction(first, second, third):
return (first+1,second+1,third+1)
1st call: myfunction(1,2,3)
2nd call is going to be pass returned variables: myfunction(2,3,4) and loop it until defined times. How can I do such loop? Thank you!

a,b,c = 1,2,3
while i<n:
a,b,c = myfunction(a,b,c)
i +=1

def myF(x,y,z,i):
print x, i
while i:
x += 1
i -= 1
return myF(x,i)
This will keep calling myF until i is 0 which will break the while loop, example:
>>> myF(1,10)
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
11 0
For three arguments, you can do as follows:
>>> def myF(x,y,z,i):
print x,y,z,i
while i:
i -= 1
x,y,z = map(lambda s:s+1,(x,y,z))
return myF(x,y,z,i)
>>>
>>>
>>> myF(1,1,1,10)
1 1 1 10
2 2 2 9
3 3 3 8
4 4 4 7
5 5 5 6
6 6 6 5
7 7 7 4
8 8 8 3
9 9 9 2
10 10 10 1
11 11 11 0

Related

How to print following pattern getting issue with spaces?

I am trying to write the code but not getting how to achieve expected output
Causing issue with space and not able to make proper judgement how to get exact spaces after every iteration
My code :
n=15
cnt=0
lst=[str(' ') for x in range(1,n+1)]
initial_length=len(''.join(lst))
print(initial_length)
for row in range(1,n+1):
lst[cnt-1]=str(row)
cnt=cnt-1
print(' '.join(lst))
Output of above code is not as expected output
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
6 5 4 3 2 1
7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
11 10 9 8 7 6 5 4 3 2 1
12 11 10 9 8 7 6 5 4 3 2 1
13 12 11 10 9 8 7 6 5 4 3 2 1
14 13 12 11 10 9 8 7 6 5 4 3 2 1
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Expected output :
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
6 5 4 3 2 1
7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
11 10 9 8 7 6 5 4 3 2 1
12 11 10 9 8 7 6 5 4 3 2 1
13 12 11 10 9 8 7 6 5 4 3 2 1
14 13 12 11 10 9 8 7 6 5 4 3 2 1
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Another approximation, by knowing the quantity of spaces in advance using a recursive function:
def findDigits(N):
if N <= 1:
return N
# Changing number to string
s = str(N)
# Add length of number to total_sum
return len(s) + findDigits(N - 1)
def print_inverse_pyramid(n):
# Calculate number of total digits until n
total_digits = findDigits(n)
# Print the pyramid
for row in range(1, n + 1):
total_digits -= len(str(row))
l_r = [str(i) for i in range(row, 0, -1)]
print(" " * (total_digits + (n - row)) + " ".join(l_r))
print_inverse_pyramid(15)
You have to account for larger digits taking up more space, which means that when creating the list that contains spaces, you need to multiply the space by how many digits are in that number which you can get by len(str(number)):
n = 15
# create a list containing how many spaces each number will take up
# in reverse order because the figure is reverse
lst = [' ' * len(str(x)) for x in range(n, 0, -1)]
# go over each number
for x in range(1, n + 1):
# replace the digit in its place from end
# by the string represantion of itself
lst[-x] = str(x)
# print joined list
print(' '.join(lst))
Also:
I strongly suggest following PEP 8 - Style Guide for Python Code. Function and variable names should be in snake_case, class names in CapitalCase. Don't have space around = if it is used as a part of keyword argument (func(arg='value')) but have space around = if it is used for assigning a value (variable = 'some value'). Have space around operators (+-/ etc.: value = x + y(except here value += x + y)). Have two blank lines around function and class declarations. Object method definitions have one blank line around them.
Quick and dirty: 'looking' at the last line
n = 15
def serie(n):
return ' '.join([str(j) for j in range(n, 0, -1)])
maxlen = len(serie(n))
for i in range(1, n +1):
s = serie(i)
print(" " * (maxlen - len(s)) + s)
With math, computing the length as the sum of the int of the log10 of values and adding for the spaces
import math
n = 15
def lenserie(n):
return sum(map(lambda i : int(math.log(i, 10)) + 1 ,range(1, n+1))) + (n-1)
maxlen = lenserie(n)
for i in range(1, n+1):
print(" " * (maxlen - lenserie(i)) + " ".join([str(i) for i in range(i, 0, -1)]))

I want to generate a new column in a pandas dataframe, counting "edges" in another column

i have a dataframe looking like this:
A B....X
1 1 A
2 2 B
3 3 A
4 6 K
5 7 B
6 8 L
7 9 M
8 1 N
9 7 B
1 6 A
7 7 A
that is, some "rising edges" occur from time to time in the column X (in this example the edge is x==B)
What I need is, a new column Y which increments every time a value of B occurs in X:
A B....X Y
1 1 A 0
2 2 B 1
3 3 A 1
4 6 K 1
5 7 B 2
6 8 L 2
7 9 M 2
8 1 N 2
9 7 B 3
1 6 A 3
7 7 A 3
In SQL I would use some trick like sum(case when x=B then 1 else 0) over ... rows between first and previous. How can I do it in Pandas?
Use cumsum
df['Y'] = (df.X == 'B').cumsum()
Out[8]:
A B X Y
0 1 1 A 0
1 2 2 B 1
2 3 3 A 1
3 4 6 K 1
4 5 7 B 2
5 6 8 L 2
6 7 9 M 2
7 8 1 N 2
8 9 7 B 3
9 1 6 A 3
10 7 7 A 3

Randomizing Sentences In Python

I not long ago finished my project which comments on a video based on a keyword on YouTube, it will pick a random comment using the random library.
The program has been acting strange when "randomizing" the comments to add to the
YouTube videos. I'm starting to think I may need to improve the randomness, the fact being that
it has chosen the 4th comment (out of 9) 7 times, and the 9th one 3 times. Both of these
results occur after each other, in other words, it is sending the same message in a row
when it's meant to pick randomly and not repeat.
Is there any way I can increase how random this is? If you know, please do tell me, I will appreciate it a bunch!
PS: This is more of stopping it from repeating the same sentence on YouTube.
code:
if __name__ == "__main__":
from googleapiclient.errors import HttpError
import random
import time
import sys
# Comments are getting loaded
comments = load_comments('Comments.txt')
# Getting the number of comments you want to add
number_of_comments = int(input('Enter the number of comments: '))
count, cycle, videoid_store = 0, 1, []
# Getting the keyword
keyword = input('Enter the Keyword: ')
# This loop keeps running until all comments have been added
youtube = authentication()
while count < number_of_comments:
print("Searching for videos .. (Cycle:%d)" %cycle)
time.sleep(10)
random.shuffle(comments)
If you want to keep the randomness but avoid repeats or frequent re-occurrences, you have to remember the previous outcomes, to manipulate the odds in favour of the ones that have occurred less frequently so far.
Some examples:
Shuffle the outcomes. Go through all, by the order obtained. Repeat.
Keep a count of the last few outcomes. If we get an outcome that has been drawn X times already, draw again up to X times.
Code, for the above examples:
import random
import collections
class ShuffleAndExhaust(): # cycle in random order each time
def __init__(self,N): # N: number of possible outcomes
self.N = N
self.queue = list()
def draw(self):
if not self.queue: # exhausted (or 1st ever draw)
self.queue.extend(range(self.N))
random.shuffle(self.queue)
return self.queue.pop()
class RememberAndRetry(): # re-draw, if reoccurring
def __init__(self,N): # N: number of possible outcomes
self.N = N
self.history = collections.deque(maxlen=3*self.N) # maxlen = rule-of-thumb constant * N
def draw(self):
triesleft = collections.Counter(self.history)
while True:
n = random.randint(0,self.N-1)
if triesleft[n] > 0: # drew this number N times already
triesleft[n] -= 1 # 1 less try left drawing this same number until we accept it
else: break
self.history.append(n)
return n
Testing 100 draws of 10 possible outcomes:
>>> random.seed(0) # for reproducibility in testing only
>>> r = ShuffleAndExhaust(10)
>>> print(*(r.draw() for i in range(100)))
6 9 0 2 4 3 5 1 8 7 5 3 2 7 1 0 6 8 4 9 4 1 8 6 5 2 3 9 0 7 5 6 9 4 7 1 3 8 2
0 0 8 9 7 5 3 6 2 1 4 5 3 9 7 0 1 4 6 2 8 8 7 1 0 2 4 3 6 9 5 8 4 1 9 2 6 7 5
3 0 7 1 6 2 4 8 9 0 3 5 2 0 4 3 8 5 1 7 9 6
>>> r = RememberAndRetry(10)
>>> print(*(r.draw() for i in range(100)))
1 8 6 4 3 9 7 5 1 3 0 2 0 9 1 0 4 6 2 7 8 5 9 3 6 7 0 1 4 5 2 5 4 8 7 6 3 1 7
9 8 9 4 0 7 9 1 0 8 6 1 5 3 2 5 2 3 6 6 2 7 4 0 4 1 8 6 7 0 1 5 3 9 8 0 9 5 4
7 7 1 6 8 3 8 5 2 3 9 0 5 0 2 6 2 1 4 4 7 4
Use N = the number of comments and each draw as the index of the comment to pick.
Try random.choice()
x=random.choice(['option1','option2'])

Python Nested Loop number pattern outputting additional line?

I am trying to create a number grid specifically using for loops. My code is as follows
def draw_grid (num):#x represents row y representes column
for x in range (num):
print(x+1, end= ' ' )
print()
for y in range (num):
print(y+1, end= ' ' )
And my ouput results as this when I draw a grid of 10 for example.
1
1 2 3 4 5 6 7 8 9 10 2
1 2 3 4 5 6 7 8 9 10 3
1 2 3 4 5 6 7 8 9 10 4
1 2 3 4 5 6 7 8 9 10 5
1 2 3 4 5 6 7 8 9 10 6
1 2 3 4 5 6 7 8 9 10 7
1 2 3 4 5 6 7 8 9 10 8
1 2 3 4 5 6 7 8 9 10 9
1 2 3 4 5 6 7 8 9 10 10
1 2 3 4 5 6 7 8 9 10
I have tried manipulating it several different ways but I cannot discern what is creating the 1 at the top and the 2-10 on the rightmost column? Should my Y value be coded differently?
Here is what is happening
def draw_grid (num):#x represents row y representes column
for x in range (num):
print(x+1, end= ' ' )
print()
for y in range (num):
print(y+1, end= ' ' )
In your outer loop you are printing x + 1 on every iteration with no newline, end = ' ' and then printing a new line, print(). On your first iteration its printing 1 with no newline followed by a newline from print() and then it enters your inner loop and is printing 1-10 again with no new line at the end. Now when the second iteration of your outer loop occurs it prints 2, that's going to be printed right after all the y values followed by print() and the process repeats.
What you want is this most likely
def draw_g(num):
for x in range(num):
for y in range(num):
print(y + 1, end = ' ')
print()
draw_g(10)
Here we are only using our outer loop to determine the amount of rows, times we will print all the values in our inner loop. For our first iteration we print all the values of y + 1 in range(num) once that is completed we use print() to advance to the next line and then the second iteration of of outer loop takes place, this repeats for x in range(num)
. And the result is this.
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

Creating a number list with nested For loops in Python

I've been working on this now for well over four hours and i've tried to check several resources.
I'm trying to get something like this:
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
My current code for this is:
for i in range(10):
print(i, end = '')
for j in range(10):
print(j, end = '')
print()
which prints this:
00123456789
10123456789
20123456789
30123456789
40123456789
50123456789
60123456789
70123456789
80123456789
90123456789
So I just need to get rid of the very most left-hand side. Additionally, I'm trying to produce something that looks like this:
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9
And I can get it from this:
triangle = ''
n = 9
for i in range(0, n+1):
triangle = triangle + (str(i))
print(triangle)
print()
for i in range(11):
for j in range(0+i):
print(j,end=" ")
print()
The problem with the first one is there isn't two for loops, one nested in the other. The problem with the second one is that I have range at 11 to get it to print to 9.
Lastly, I'm trying for this:
10
11 12
13 14 15
16 17 18 19
20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36 37
38 39 40 41 42 43 44 45
46 47 48 49 50 51 52 53 54
Which I've been getting with this:
x = 10
for i in range (10):
print (*range (x, x+i))
x += i
But I need two for loops. I feel like I'm very close, but just can't get the finished product.
Thanks.
For the first instance, try this:
print('', end = '')
For the second instance, the mistake is that you are adding 0 to the second for loop. Change it to:
for j in range(0, 1+i):
The thing with range is that it goes until one number lower. Have a look at docs
For the last one, you can use the following code, where y starts at 10.
y = 10
for i in range(0,10):
for j in range(0, i):
print(y + j, end=' ')
print('')
y += i
Issue with first code is that you are printing i , you do not need to print i . Code would be something like -
for i in range(10):
for j in range(10):
print(j, end = ' ')
print()
For the rest of the question, if you are getting the answer without nested loops, why do you need nested loops?
Here is how to go about it -
First is very simple
ht = 10
y = range(ht)
"\n".join(map(lambda x: " ".join(map(str,x)), [y]*ht))
Second one is a bit interesting
ht = 10
y = range(ht)
for i in range(1, ht+1):
print " ".join(map(str, y[0:i]))
Third one
start = 10
ht = 9
limit = (ht*(ht+1))/2 # using the sum of n to find out total elements
y = range(start, limit+1)
for i in range(1, ht+1):
print " ".join(map(str, y[0:i]))
y = y[i:]
The complicated map(str, y) is only to get a string to be printed.
Is this what you want?

Categories

Resources