I have been working on translating Matlab code into Python and came across a loop that I'm having some difficulty converting as I'm fairly new to both the languages.
if fdp >=2
degreeTwoVector=[];
counter =1;
for i = 1:numVariables
for j = 1:numVariables
degreeTwoVector(counter,:) = [i j 0];
counter = counter +1;
end
end
sortedDegreeTwoVector = sort(degreeTwoVector,2);
degreeTwoVector = unique(sortedDegreeTwoVector, 'rows');
combinationVector = [combinationVector; degreeTwoVector];
end
Here's what I could come up with while converting it to python(incomplete):
if fdp >= 2:
degreeTwoVector = np.array([])
counter = 1
for i in range(1, numVariables+1):
for j in range(1, numVariables+1):
degreeTwoVector(counter, :) = np.array([i, j, 0])
counter = counter + 1
break
sortedDegreeTwoVector = degreeTwoVector[np.argsort(degreeTwoVector[:, 1])]
I certainly know there are some mistakes in it. So I'd be grateful if you could help me complete the conversion and correct any mistakes. Thanks in advance!
You are not too far off:
You do not need a break statement, it is causing a precocious, well, break to the loop (at the first iteration).
So here you go:
numVariables = np.shape(X)[0] # number of rows in X which is given
if fdp >= 2:
degreeTwoVector = np.zeros((numVariables, 3)) # you need to initialize the shape
counter = 0 # first index is 0
for i in range(numVariables):
for j in range(numVariables):
degreeTwoVector[counter, :] = np.array([i, j, 0])
counter = counter + 1 # counter += 1 is more pythonic
sortedDegreeTwoVector = np.sort(degreeTwoVector, axis=1);
degreeTwoVector = np.vstack({tuple(row) for row in sortedDegreeTwoVector})
combinationVector = np.vstack((combinationVector, degreeTwoVector))
EDIT: added equivalent of code outside the loop in the original question.
Apart from the fact that i don't see where you defined combinationVector, everything should be okay.
Related
For example, ACTTTA occurs twice in ACTTACTTGATAAAGT, once at offset 0 with 2 mismatches, and once at offset 4 with 1 mismatch. So naive_2mm('ACTTTA', 'ACTTACTTGATAAAGT') should return the list |[0, 4].
I'm still a newbie. I've been working on this problem for almost a week now and I can't figure this out on my own.
This is the code that I develop. Can someone explain why this code does not work and how can I do this?
def naive_2mm(p,t):
occurences = []
counter = 0
for i in range(len(t)-len(p)+1):
while counter != (len(p)-2):
for j in range(len(p)):
if t[i+j] == p[j]:
counter += 1
continue
else:
occurences.append(i)
return occurences
Your code is pretty close. I think the counter initialization is just about the only issue. This works:
def naive_2mm(p,t):
occurrences = []
for i in range(len(t)-len(p)+1):
counter = 0
for j,k in zip(p, t[i:i+len(p)]):
counter += j==k
if counter >= len(p)-2:
occurrences.append(i)
return occurrences
needle = 'ACTTTA'
haystack = 'ACTTACTTGATAAAGT'
print(naive_2mm(needle,haystack))
Or, for those of you who like one-liners, you can replace the 3-line sequence creating counter with:
counter = sum(j==k for j,k in zip(p, t[i:i+len(p)]))
New to python here, so not sure if I'm posting in the right place but I was wondering why the following loop does not give an answer. I am trying to add all of the numbers previous to i, (1 + 2 + 3 + ... + i), but the loop I came up with does not complete.
j = 0
i = 17
while i > 0:
j = j + i
i - 1
print(j)
I expect j = 153, but the loop doesn't put out anything.
The issue is with i--you're not properly reducing it by 1, so this is an infinite loop. Try this:
j = 0
i = 17
while i > 0:
j = j + i
i -= 1
print(j)
Notice that your line in the while statement,
i-1, does not assign (= operator) a value to i. i stays 17 forever and ever, and so you see no output because the program gets stuck in your while loop. Try to fix your i assignment, like so:
j = 0
i = 17
while i > 0:
j = j + i
i = i - 1 # <= i = i - 1
print(j)
One way to debug your loop in the future is to put a print statement in the middle, like in the code below. The extra print statements slow your program down a bit, but you'll be able to easily see that your loop is going way more than you want!
j = 0
i = 17
while i > 0:
j = j + i
i = i - 1
print(j)
print(i) # so that we can see that i is going down :P
print(j)
Good luck :)
As noted above, you're not re-assigning to your i within the loop. But I'd also note that it's generally a bad idea to modify an iterator within the iteration loop. You can achieve the expected results in a more pythonic way using a range expression, and wrap it in a function also :)
def foo(max_num):
j = 0
for i in range(max_num+1):
j += i
return j
But even better, without the loop:
def foo(max_num):
return sum(range(max_num+1))
There are a couple of ways to do what you want to do. The way I recommend you do it is as shown below.
total = 0
i = 18
for j in range(i):
total += j
print(total)
The range(i) takes a maximum number i, and allows you to iterate through every number starting from 0 to i-1 (e.g. i = 5 will add numbers 0,1,2,3,4), therefore always make i one more than you need it to be if you want to be if you want to include the max number.
As already stated i - 1 wasn't assigned back to i
Following is a pythonic way of implementing the loop with a list comprehension
Code:
j = 0
i = 17
j = sum([j + x for x in range(i, 0, -1)])
print(j)
>>> 153
As a Function:
def sum_of_steps(start: int, stop: int, step: int) -> int:
return sum([x for x in range(start, stop, step)])
j = sum_of_steps(17, 0, -1)
print(j)
>>> 153
The function, sum_of_steps uses type hints or function annotations.
Python Basics: List Comprehensions
I am struggling with building a counting sort algorithm for the past 3 hours. I understand the concept and I can sort an array using the counting sort algorithm on paper with no problem. The problem is when trying to translate the steps from paper into code, my algorithm fails. The program breaks with error message "index out of bound". To understand the error, I used print functions to view the results at each iteration. The results were incorrect. What is the problem with the algorithm?
def count_sort(array):
minArr = min(array)
maxArr = max(array)
sumArray = [0 for _ in range(minArr, maxArr+1)]
for i in range(len(array)):
sumArray[array[i] - 1] += 1
print(sumArray)
sumCount = []
sumCount.append(sumArray[0])
for i in range(1, len(sumArray)):
sumCount.append(sumArray[i] + sumCount[i-1])
print(sumCount)
sortedArray = [0 for _ in range(len(array))]
for i in range(len(array)):
sortedArray[sumCount[array[i]] - 1] = array[i]
sumCount[array[i]] -= 1
print(sortedArray)
this line is a problem:
sortedArray[sumCount[array[i]] - 1] = array[i]
I think you need to shift array[i] down by one? In the last iteration of your example array[4] = 9, so it tries to set sortedArray[sumcount[9] - 1]. sumcount's index goes from 0 through 8, so 9 is out of range. Changing to sortedArray[sumcount[array[i]-1]-1] should fix it i think.
The nested list adds confusion and makes it harder to spot this. Break it up and use variables instead of trying to do it on one line if you are having trouble. Much easier to debug. You add print statements to print the values at each step so you know which list and index cause the out of bounds error
my_length = len(array)
print(f'for i in range({my_length}):')
for i in range(my_length):
print(f'x = array[{i}]')
x = array[i]
print(f'y = sumCount[{x}] - 1')
y = sumCount[x] - 1
print(f'sortedArray[{y}] = {x}')
sortedArray[y] = x
You need to replace
sortedArray[sumCount[array[i]] - 1] = array[i]
sumCount[array[i]] -= 1
by
sortedArray[sumCount[array[i]-1]-1] = array[i]
sumCount[array[i]-1]-= 1
I am a beginner to programming. I always encounter this problem for matrices. Please help me to correct this code and understand the concept behind this. Thank you.
def new_matrix(matrix_size, center_num):
c = matrix_size / 2
if matrix_size % 2 != 0:
p = matrix_size
print("enter a valid size for matrix")
else:
matrix = [[0] * matrix_size for z in range(matrix_size)]
for counting in range(center_num, (matrix_size ** 2) + center_num):
for i in range(2, matrix_size+1):
row = int(c)
column = int(c)
if (i % 2 == 0):
for k in range(1, i + 1): # moving right
column += 1
matrix[column][row] = counting
for k in range(1, i + 1): # moving up
row += 1
matrix[column][row] = counting
else:
for k in range(1, i + 1): # moving left
column -= 1
matrix[column][row] = counting
for k in range(1, i + 1): # moving down
row -= 1
matrix[column][row] = counting
print(matrix)
new_matrix(6, 2)
This issue here seems to be that your indexing is off. The end value in range(n) is n-1, which means that in your for loop when i = matrix_size and then you try to increment the column beyond this, you're trying to assign a value to an index in the matrix that doesn't exist.
You can either try and fix your loop, i.e. reduce it by one, or you can do something like the following,
try:
<your code goes here>
except IndexError:
pass
And then anytime the loop hits an index error it will skip that index and try the next. It's better to fix the code though!
I have st = 'aaaabbсaa'. My task is if in the string characters repeat then I must write the character plus a number counting the repeats.
My code (but it doesn't work):
st = "aaaabbcaa"
cnt = 0
cnt2 = 0
cnt3 = 0
j = len(st)
i = 0
while i < j:
if st[i] == st[i - 1]:
cnt += 1
print("a" + str(cnt), end="")
elif st[i] == st[i - 1]:
cnt2 += 1
print("b" + str(cnt2), end="")
elif st[i] == st[i - 1]:
cnt3 += 1
print("c" + str(cnt3), end="")
i += 1
Sample Input 1: aaaabbcaa
Sample Output 1: a4b2c1a2
Sample Input 2: abc
Sample Output 2: a1b1c1
This looks like a task for itertools.groupby.
from itertools import groupby
data = 'aaaabbсaa'
compressed = ''.join('{}{}'.format(key, len(list(group))) for key, group in groupby(data))
print(compressed)
Result
a4b2с1a2
This might help to understand what's happening here.
data = 'aaaabbсaa'
for key, group in groupby(data):
print(key, len(list(group)))
Result
a 4
b 2
с 1
a 2
You've got three problems with your code.
First, as gnibbler points out, all of your if/elif conditions are the same. And you don't need a separate condition for each letter, you just need to print the variable (like st[i]) instead of a literal (like "a").
Second, you're trying to print out the current run length for each character in the run, instead of after the entire run. So, if you get this working, instead of a4b2c1a2 you're going to get a1a2a3a4b1b2c1a1a2. You need to keep track of the current run length for each character in the run, but then only print it out when you get to a different character.
Finally, you've got two off-by-one errors. First, when i starts at 0, st[i - 1] is st[-1], which is the last character; you don't want to compare with that. Second, when i finally gets to j-1 at the end, you've got a leftover run that you need to deal with.
So, the smallest change to your code is:
st = "aaaabbcaa"
cnt = 0
j = len(st)
i = 0
while i < j:
if i == 0 or st[i] == st[i - 1]:
cnt += 1
else:
print(st[i - 1] + str(cnt), end="")
cnt = 1
i += 1
print(st[i - 1] + str(cnt))
As a side note, one really easy way to improve this: range(len(st)) gives you all the numbers from 0 up to but not including len(st), so you can get rid of j and the manual i loop and just use for i in range(len(st)):.
But you can improve this even further by looping over an iterable of st[i], st[i-1] pairs; then you don't need the indexes at all. This is pretty easy with zip and slicing. And then you don't need the special handling for the edges either either:
st = "aaaabbcaa"
cnt = 1
for current, previous in zip(st[1:]+" ", st):
if current == previous:
cnt += 1
else:
print(previous + str(cnt), end="")
cnt = 1
I think Matthias's groupby solution is more pythonic, and simpler (there's still a lot of things you could get wrong with this, like starting with cnt = 0), but this should be mostly understandable to a novice out of the box. (If you don't understand the zip(st[1:]+" ", st), try printing out st[1:], list(zip(st[1:], st)), and list(zip(st[1:]+" ", st) and it should be clearer.)
This is kind of a silly way to go about it, but:
def encode(s):
_lastch = s[0]
out = []
count = 0
for ch in s:
if ch == _lastch:
count +=1
else:
out.append(_lastch + str(count))
_lastch = ch
count = 1
out.append(_lastch + str(count))
return ''.join(out)
Example
>>> st = "aaaabbcaa"
>>> encode(st)
'a4b2c1a2'