I need help with a task in my intro to python programming course that requires a code that will print the following using two 'for-loops', one being nested:
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
So far i have come up with the following code, but my triangle of numbers begins at the digit 1 instead of 0:
for i in range(-1,9):
print ('\n')
for i in range (int(i+1)):
j = i+1
print (j, end=' ')
Can anyone advise what I should do to make my list of digits begin from 0 instead of 1? Also any suggestions on how to make my code more readable? Thanks.
When using range, if you want the last integer to be included, you need to add one. With this in mind, I think the following makes sense:
for i in range(9+1): # +1 since you want the loop to include 9
for j in range(i+1): # +1 since you want your print to include i
print (j, end=' ')
print ('\n')
The print(\n) statement can go before or after your j for-loop, although the output will be slightly different. (Maybe because I'm used to mechanical typewrites, I think of \n as finishing a line rather than getting ready for a new one, but both are reasonable.)
I don't like the idea of starting at -1 so you can then add 1 later. It's unduly complicated, and a bad habit to start with as a beginner.
Keeping your code structure, the following will work:
for i in range(-1, 10): # you need 10 so that the triangle goes up to 9
print("\n")
for j in range(i + 1):
print(j, end=" ")
Result:
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
Related
I have a pandas data frame and a list -
d={'abc':[0,2,4,5,2,2],'bec':[0,5,6,4,0,2],'def':[7,6,0,1,1,2],'rtr':[5,6,7,2,0,3],'rwr':[5,6,7,1,0,5],'xx':[4,5,6,7,8,7]}
X=pd.DataFrame(d)
abc bec def rtr rwr xx
0 0 0 7 5 5 4
1 2 5 6 6 6 5
2 4 6 0 7 7 6
3 5 4 1 2 1 7
4 2 0 1 0 0 8
5 2 2 2 3 5 7
l=[ 'bec','def','cef','ghd','rtr','fgh','ewr']
Now I want to append the list to data frame in the following way-
For each row in dataframe- We count the number of non zero elements in it(lets say it is 3 in the first row
We take 50% of 3= 1.5 (rounded to 1) and we append those many elements from the list l to the row(starting from the beginning). For the first row it is 'bec', since 'bec' is already present in the
row we increase its count by 1.
If the element from list is not present in the dataframe we append it at the end.
Dry run-
for row 1(index 1)- no of non zero elements is 6. So 50% of it is 3. So we take the first 3 elements from list['bec','def','cef']. 'bec' is already present so its count increases by 1 and it becomes(2,2)=6.
Similarly 'def' is present so it becomes(2,3)=7. 'cef' isn't present in the dataframe so we add it and make the count as 1.
The final output looks like this-
abc bec def rtr rwr xx cef
0 0 1 8 5 5 4 0
1 2 6 7 6 6 5 1
2 4 7 1 7 7 6 0
3 5 5 2 2 1 7 1
4 2 1 1 0 0 8 0
5 2 1 1 3 5 7 1
We can use ne + sum along axis=1 to count the non zero values in each row, followed by floordiv with 2 to consider only 50% of these counts, next create a list of record with the help of dict.fromkeys method inside a list comprehension, now create a dataframe lets say y from these records and add it with X to get the desired result
y = pd.DataFrame(dict.fromkeys(l[:i], 1)
for i in X.ne(0).sum(1).floordiv(2).astype(int))
X.add(y.fillna(0), fill_value=0).astype(int)
abc bec cef def rtr rwr xx
0 0 1 0 8 5 5 4
1 2 6 1 7 6 6 5
2 4 7 0 1 7 7 6
3 5 5 1 2 2 1 7
4 2 1 0 1 0 0 8
5 2 3 1 3 3 5 7
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'])
I am attempting to create a nested for loop where the inner loop will have a different range the first time the loop runs and then use a different range for each subsequent loop.
The program is a sudoku solver. And it works by taking a position on the 9x9 board (board[k][l]), checking a condition, and then moving to the board position directly to the left (board[k][l-1]).
If l is 0 than we need to move to the previous row (k-1) and the farthest position to the right where l equals 8.
The problem I am having is on the first iteration of the inner loop the loop will not always begin with l equal to 8.
For example a user my select the square board[3][3].
The function should then check board[3][2]
then board[3][1]
then board[3][0]
then board[2][8]
etc.
The code below only works if l=8
for i in range(k, -1, -1):
for j in range(l, -1, -1):
For clarity, I can achieve the desired result using multiple for loops, but I am trying to make this code more concise:
k = user selection
l = user selection
for j in range(l, 0, -1):
test(k,j)
for i in range(k-1, -1, -1):
for j in range(9, 0 , -1):
test(i,j)
I don't like this for two reasons, first we encounter a problem if either k or l starts at 0, second it seems unnecessary to use two for loops here.
Isn't it just a matter of putting an if statement in there?
>>> k = 8
>>> l = 3
>>> run_one = True
>>> for i in range(k, -1, -1):
... if run_one:
... run_one = False
... for j in range(l, -1, -1):
... print(i, j)
... else:
... for j in range(8, -1, -1):
... print(i, j)
...
8 3
8 2
8 1
8 0
7 8
7 7
7 6
7 5
7 4
7 3
7 2
7 1
7 0
6 8
6 7
6 6
6 5
6 4
6 3
6 2
6 1
6 0
5 8
5 7
5 6
5 5
5 4
5 3
5 2
5 1
5 0
4 8
4 7
4 6
4 5
4 4
4 3
4 2
4 1
4 0
3 8
3 7
3 6
3 5
3 4
3 3
3 2
3 1
3 0
2 8
2 7
2 6
2 5
2 4
2 3
2 2
2 1
2 0
1 8
1 7
1 6
1 5
1 4
1 3
1 2
1 1
1 0
0 8
0 7
0 6
0 5
0 4
0 3
0 2
0 1
0 0
>>>
You can manage this in one single loop if you use an extra if (or a ternary expression like here):
l = 2
k = 5
for i in range(l, -1, -1):
max = k if i == l else 9
for j in range(max, 0, -1):
print("{},{}".format(i,j))
gives:
2,5
2,4
2,3
2,2
2,1
1,9
1,8
1,7
1,6
1,5
1,4
1,3
1,2
1,1
0,9
0,8
0,7
0,6
0,5
0,4
0,3
0,2
0,1
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?
major minor col
0 0 5
1 6
2 4
0 0 8
1 5
2 6
1 0 3
1 6
2 9
1 0 5
1 1
2 7
First I'd like to get
major minor col
0 0 5
1 6
2 4
0 0 8
1 5
2 6
and then select over both major '0's, that is, choose the first major 0 or the second:
major minor col
0 0 5
1 6
2 4
or
major minor col
0 0 8
1 5
2 6
Unfortunately df.xs(0,level=0,drop_level=False) doesn't exactly fit the job, since it maintains major '1's in the index, although empty. Any ideas?
I still do not understand your data structure. I'm right now working with
val
major minor col
0 0 5 1
1 6 1
2 4 1
0 8 1
1 5 1
2 6 1
I still don't understand how in your case you have two major zeros, since I get only one with the same structure. Therefore, I can't tell you exactly how you could pick any of the *major*s.
Using traditional slicing, you can get where df.major == 0 using
df[df.major == 0]
In order to select any single of the subgroups now, it depends on how they're different. Do they have another unique feature? Then you could do
df[(df.major == 0) && (df.someColumn == someValue)]
(notice the brackets). Otherwise, if you know there are 3 rows per group, df[df.major == 0].iloc[:3] (or 3:) will give you the records.
Also, have a look at the (currently experimental)df.query() (documentation).
Generally, you can do stuff such as
df[df.major == 0] to get all the values where the major is zero. If it's a (labeled) index or a normal column does not matter. You can also stack these to do
`df[(df.major == 0)
I start with
In[264]: df
Out[262]:
val
major minor col
0 0 5 1
1 6 1
2 4 1
0 8 1
1 5 1
2 6 1
1 1 3 1
6 1
2 9 1
1 5 1
1 1
2 7 1
and then I do
In[263]: df.query('major == 0')
Out[261]:
val
major minor col
0 0 5 1
1 6 1
2 4 1
0 8 1
1 5 1
2 6 1