Why doesnt this reverse all the way? - python-2.7

I am doing another exam question and the snipped of code is given as the following:
def reverse(a):
i=0
while i < len(a):
j = len(a) - 1
tmp = a[i]
a[j] = tmp
a[i] = a[j]
i = i +1
a = sys.argv
reverse(a)
print " ".join(a)
One of the questions asked is that you find the 5 errors. I have found 3 of the 5 but when I am trying to find the last two but my code does not fully sort the list.
Example if you did "1", "2", "3" it would print "3", "1", "2"
My edits to the above code:
import sys #error 1
def reverse(a):
i = 0
while i < len(a):
j = len(a[i])-1 #error 2
tmp = a[i] #I know its either this one or the two below...
a[i] = a[j]
a[j] = tmp
i = i +1
a = sys.argv[1:]# error 3
reverse(a)
print " ".join(a)
I cannot use any builtin functions from python such as ".sort()"

def reverse():
i = 0
while i < int(len(a) / 2):
j = len(a) - 1 - i
tmp = a[i]
a[i] = a[j]
a[j] = tmp
i = i + 1
Reverse algorithm should do something like, swap 1-5, 2-4 then stop.
For 5 element input, you only need to do 2 swaps. Also j should move backward as i moves forward while you are iterating over input.
Since you are not returning anything from method and modify global a, you don't need the parameter.
BTW, in Python, instead of using tmp variable, you can use to swap elements.
a[i], a[j] = a[j], a[i]

Related

Python Subsequence

Example: I have the array[9,0,1,2,3,6,4,5,0,9,7,8,9] and It should return the max consecutive subsequence, so the answer should be (and if the number is 9 and the next one is 0 than it's fine) 9,0,1,2,3, but my code is returning 0,1,2,3
Starting from each element, do a loop that compares adjacent elements, until you get a pair that isn't consecutive.
Instead of saving all the consecutive sublists in another list, just save the sublist in a variable. When you get another sublist, check if it's longer and replace it.
def constructPrintLIS(arr: list, n: int):
longest_seq = []
for i in range(n-1):
for j in range(i, n-1):
if not (arr[j] == arr[j+1]-1 or (arr[j] == 9 and arr[j+1] == 0)):
break
else:
# if we reach the end, need to update j
j = n
if j - i > len(longest_seq):
longest_seq = arr[i:j+1]
if n - i <= len(longest_seq):
# there can't be any longer sequences, so stop
break
printLIS(longest_seq)

No output when finding most frequent k-mers in Text

When I execute this, there is no response. Why or what might be causing this problem to occur?
Here is the code that I have tried.
#Frequent Words
name = raw_input("Enter file:")
if len(name) < 1 :
name = "dataset_2_10.txt"
handle = open(name,"r")
Text = handle.read()
k = raw_input("Enter k:")
k = int(k)
def PatternCount(Text,Pattern):
count = 0
i = 0
while i < len(Text)-len(Pattern):
if Text[i:i+len(Pattern)] == Pattern :
count = count + 1
i = i + 1
return count
FrequentPatterns = list()
i = 0
Count = list()
while i < len(Text)-k:
Pattern = Text[i:i+k]
Count.append(PatternCount(Text,Pattern))
i = i + 1
maxCount = max(Count)
#print maxCount
j = 0
while j < len(Text)-k:
if Count[j] == maxCount:
FrequentPatterns.append(Text[j:j+k])
print Count[j]
j = j + 1
print FrequentPatterns
Any help would be much appreciated.
You do not get any output, because you run into an infinite loop every time you provide a k larger than one.
This is because in the second while loop you only increment j if the k-mer has been found. But since the condition if Count[j] == maxCount: is not always satisfied for k > 1, you do not reach the j = j + 1 and j stays the same. (You can see that, if you add a print statement to your loop.)
To fix this move the j = j + 1 from the if block (where it is now) to the loop body, like this:
j = 0
while j < len(Text)-k:
if Count[j] == maxCount:
FrequentPatterns.append(Text[j:j+k])
print Count[j]
j = j + 1
Now j is incremented every time, regardless if the k-mer was found or not.
That said, in python there is a better way to do this. You can use a for-loop to iterate over all indices like you do now, but without the danger of infinite loops. Consider this:
i = 0
while i < 10:
print i
i = i + 1
for j in range(10):
print(j)
The second loop yields the same result and is much less prone to failure. You generate a list of the numbers [0, .., 9] with range(10) and then use each item from the list.

edit distance solution with O(n) space issue

Found a few different solutions and debugging, and especially interested in below solution which requires only O(n) space, other than store a matrix (M*N). But confused about what is the logical meaning of cur[i]. If anyone have any comments, it will be highly appreciated.
I posted solution and code.
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.length(), n = word2.length();
vector<int> cur(m + 1, 0);
for (int i = 1; i <= m; i++)
cur[i] = i;
for (int j = 1; j <= n; j++) {
int pre = cur[0];
cur[0] = j;
for (int i = 1; i <= m; i++) {
int temp = cur[i];
if (word1[i - 1] == word2[j - 1])
cur[i] = pre;
else cur[i] = min(pre + 1, min(cur[i] + 1, cur[i - 1] + 1));
pre = temp;
}
}
return cur[m];
}
};
You can think of cur as being as a mix of the previous line and the current line in the edit distance matrix. For example, think of a 3x3 matrix in the original algorithm. I'll number each position like below:
1 2 3
4 5 6
7 8 9
In the loop, if you are computing the position 6, you only need the values from 2, 3 and 5. In that case, cur will be exactly the values from:
4 5 3
See the 3 in the end? That's because we didn't updated it yet, so it still has a value from the first line. From the previous iteration, we have pre = 2, because it was saved before we computed the value at 5.
Then, the new value for the last cell is the minimum of pre = 2, cur[i-1] = 5 and cur[i] = 3, exactly the values mentioned before.
EDIT: completing the analogy, if in the O(n^2) version you compute min(M[i-1][j-1], M[i][j-1], M[i-1][j]), in this O(n) version you'll compute min(pre, cur[i-1], cur[i]), respectively.

Bubble Sorting - confused about 2 lines (Beginner)

I understood most of the code however I'm just confused about two lines
position = position + 1
N = N - 1
What do they do in the code and why are they at the end? What alternative ways are there to write these two lines? Is there a more efficient way of writing this code?
data = [8,7,12,4,9,6,5]
N = len(data)
swapped = True
while swapped:
swapped = False
position = 0
while (position < N - 1):
if (data[position] > data[position + 1]):
hold = data[position]
data[position] = data[position + 1]
data[position + 1] = hold
else:
swapped = True
position = position + 1
N = N - 1
print(data)
len(data)=7 // length of array
position=0 //to set at beginning of the array
while(position<N-1) // scans your entire array till end of the array
if(data[position]>data[position+1]) // checks if 8 >7 if true store 8 in temp variable
then loop through to get smallest number at data[position] and
else
N=N-1 //get next value of N to meet the condition data[position]>data[position+1]
// prints(sorted array)
Equivalent code in C:
for(int x=0; x<n; x++)
{
for(int y=0; y<n-1; y++)
{
if(array[y]>array[y+1])
{
int temp = array[y+1];
array[y+1] = array[y];
array[y] = temp;
}
}
}
Notice that this will always loop n times from 0 to n, so the order of this algorithm is O(n^2). This is both the best and worst case scenario because the code contains no way of determining if the array is already in order.
Well "I think the bubble sort would be the wrong way to go." :)

Python implementation for next_permutation in STL

next_permutation is a C++ function which gives the lexicographically next permutation of a string. Details about its implementation can be obtained from this really awesome post. http://wordaligned.org/articles/next-permutation
Is anyone aware of a similar implementation in Python?
Is there a direct python equivalent for STL iterators?
itertools.permutations is close; the biggest difference is it treats all items as unique rather than comparing them. It also doesn't modify the sequence in-place. Implementing std::next_permutation in Python could be a good exercise for you (use indexing on a list rather than random access iterators).
No. Python iterators are comparable to input iterators, which are an STL category, but only the tip of that iceberg. You must instead use other constructs, such as a callable for an output iterator. This breaks the nice syntax generality of C++ iterators.
Here's a straightforward Python 3 implementation of wikipedia's algorithm for generating permutations in lexicographic order:
def next_permutation(a):
"""Generate the lexicographically next permutation inplace.
https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
Return false if there is no next permutation.
"""
# Find the largest index i such that a[i] < a[i + 1]. If no such
# index exists, the permutation is the last permutation
for i in reversed(range(len(a) - 1)):
if a[i] < a[i + 1]:
break # found
else: # no break: not found
return False # no next permutation
# Find the largest index j greater than i such that a[i] < a[j]
j = next(j for j in reversed(range(i + 1, len(a))) if a[i] < a[j])
# Swap the value of a[i] with that of a[j]
a[i], a[j] = a[j], a[i]
# Reverse sequence from a[i + 1] up to and including the final element a[n]
a[i + 1:] = reversed(a[i + 1:])
return True
It produces the same results as std::next_permutation() in C++ except it doesn't transforms the input into the lexicographically first permutation if there are no more permutations.
itertools is seems to be what you need.
An implementation for the lexicographic-ally next permutation in Python (reference)
def lexicographically_next_permutation(a):
"""
Generates the lexicographically next permutation.
Input: a permutation, called "a". This method modifies
"a" in place. Returns True if we could generate a next
permutation. Returns False if it was the last permutation
lexicographically.
"""
i = len(a) - 2
while not (i < 0 or a[i] < a[i+1]):
i -= 1
if i < 0:
return False
# else
j = len(a) - 1
while not (a[j] > a[i]):
j -= 1
a[i], a[j] = a[j], a[i] # swap
a[i+1:] = reversed(a[i+1:]) # reverse elements from position i+1 till the end of the sequence
return True
A verbose implementation of this approach on lexicographic ordering
def next_permutation(case):
for index in range(1,len(case)):
Px_index = len(case) - 1 - index
#Start travelling from the end of the Data Structure
Px = case[-index-1]
Px_1 = case[-index]
#Search for a pair where latter the is greater than prior
if Px < Px_1 :
suffix = case[-index:]
pivot = Px
minimum_greater_than_pivot_suffix_index = -1
suffix_index=0
#Find the index inside the suffix where ::: [minimum value is greater than the pivot]
for Py in suffix:
if pivot < Py:
if minimum_greater_than_pivot_suffix_index == -1 or suffix[minimum_greater_than_pivot_suffix_index] >= Py:
minimum_greater_than_pivot_suffix_index=suffix_index
suffix_index +=1
#index in the main array
minimum_greater_than_pivot_index = minimum_greater_than_pivot_suffix_index + Px_index +1
#SWAP
temp = case[minimum_greater_than_pivot_index]
case[minimum_greater_than_pivot_index] = case[Px_index]
case[Px_index] = temp
#Sort suffix
new_suffix = case[Px_index+1:]
new_suffix.sort()
#Build final Version
new_prefix = case[:Px_index+1]
next_permutation = new_prefix + new_suffix
return next_permutation
elif index == (len(case) -1):
#This means that this is at the highest possible lexicographic order
return False
#EXAMPLE EXECUTIONS
print("===INT===")
#INT LIST
case = [0, 1, 2, 5, 3, 3, 0]
print(case)
print(next_permutation(case))
print("===CHAR===")
#STRING
case_char = list("dkhc")
case = [ord(c) for c in case_char]
print(case)
case = next_permutation(case)
print(case)
case_char = [str(chr(c)) for c in case]
print(case_char)
print(''.join(case_char))
The algorithm is implemented in module more_itertools as part of function more_itertools.distinct_permutations:
Documentation;
Source code.
def next_permutation(A):
# Find the largest index i such that A[i] < A[i + 1]
for i in range(size - 2, -1, -1):
if A[i] < A[i + 1]:
break
# If no such index exists, this permutation is the last one
else:
return
# Find the largest index j greater than j such that A[i] < A[j]
for j in range(size - 1, i, -1):
if A[i] < A[j]:
break
# Swap the value of A[i] with that of A[j], then reverse the
# sequence from A[i + 1] to form the new permutation
A[i], A[j] = A[j], A[i]
A[i + 1 :] = A[: i - size : -1] # A[i + 1:][::-1]
Alternatively, if the sequence is guaranteed to contain only distinct elements, then next_permutation can be implemented using functions from module more_itertools:
import more_itertools
# raises IndexError if s is already the last permutation
def next_permutation(s):
seq = sorted(s)
n = more_itertools.permutation_index(s, seq)
return more_itertools.nth_permutation(seq, len(seq), n+1)