choose the middle in merge sort - python-3.x

I was trying to complete a merge sort in Python. I found when I use middle = (len(x)-1)//2, the right part was in infinity loop and never reached the base case, but if I changed middle = len(x)//2, it worked normally. So why?

The solution does lie in the middle variable. After abit of experimenting I found that using middle = len(alist)//2 fixes the whole program. Despite this not being technically mathematical, it does seem to work.
You could also increase efficiency by replacing the if and else at the start of the mergesort() function with a simple if len(alist) > 1: and then return alist at the end of the function, rather than at the end of each if and else, if that makes sense. (This would also mean you can just replace the com variable with alist).
For reference, heres my code (some variables are renamed):
from random import shuffle
### INIT ###
arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
shuffle(arr)
print("Starting List: " + str(arr))
### SORT ###
# Merge
def merge(left,right):
sorted = []
i, j = 0, 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
sorted.append(left[i])
i += 1
else:
sorted.append(right[j])
j += 1
sorted += right[j:]
sorted += left[i:]
return sorted
# Decomposition
def sort(arr):
#print(arr)
if len(arr) > 1:
middle = len(arr)//2
left = sort(arr[:middle])
right = sort(arr[middle:])
arr = merge(left, right)
return arr
arr = sort(arr)
print("Ending List: " + str(arr))

Related

How to print change from previous printed line?

I have a function that reads temperatures from a device. After printing the temperature, I'd like to print the change in temperature from the previous printed line. Is there an easy way to do this?
While i < 50000:
T = getTemps()
print(T)
print(deltaT) # <-- I want to do this
I think you can keep the previous temperature as a separate variable, and once you print the delta, you can reassign previous one with the current one, because anyway with next loop you will get new value;
t = getTemps()
tPrevious = t
while i < 50000:
t = getTemps()
print(t)
print(t - tPrevious)
tPrevious = t
I think somethink like that
prev_T = 0 # Default value for first iteration
i = 0
while i < 50000:
T = getTemps()
print(T)
print(T - prev_T)
prev_T = T
i += 1

Use Python to reverse the words in a sentence

The question was: Return a sentence with the words reversed
>>> master_yoda('I am home')
'home am I'
It will eventually reverse the words of the line.
I am learning and performing Python in Jupyter Notebook.
def master_yoda(string):
l = string.split()``
p = len(string) - 1
final = ''
while p<0:
final = final + ' ' + s[p]
p = p-1
print (final)
master_yoda('Hello my name is Aryan')
The output is nothing..
No syntax errors , but still no output ...
Perhaps you should try this.
def master_yoda(string):
reversed_list = string.split(' ')
reversed_list.reverse()
reversed_string = ' '.join(reversed_list)
print(reversed_string)
master_yoda("i am home")
The big problem with the code is that you were testing for p < 0 but since p starts off with a positive value, the code never enters the while loop. You should really have been testing for p >= 0. The following code should do what you want, they way you seem to want it to:
def master_yoda(string):
l = string.split()
p = len(l) - 1
final = l[p]
p -= 1
while p >= 0:
final += ' ' + l[p]
p -= 1
return final
Note that this implementation fails if an empty string is passed as input. I tried to keep the code in the spirit of your own code and checking for an empty string would make it more complex. The simplest and most robust solution would be:
def master_yoda(string):
return ' '.join(reversed(string.split()))

Python. Trying to write a function called one_frame. Does not seem to work. Help would be greatly appreciated

As of right now, this is my code:
def get_orf(DNA):
codon = ''
if(DNA[0:3] == 'ATG'):
codon = DNA[0:3]
for x in range(3,len(DNA)+1,3):
if DNA[x:x+3] == "TAG" or DNA[x:x+3] == "TAA" or DNA[x:x+3] == "TGA":
return codon
else: codon = codon + DNA[x:x+3]
if codon[-3:] in ["TAG", "TAA", "TGA"]:
return codon
else: return 'No ORF'
def one_frame(DNA):
x = 0
ORFlist = []
while x < len(DNA):
codon = DNA[x:]
if DNA.startswith('ATG'):
get_orf(DNA[x:])
if codon:
ORFlist.append(codon)
x += len(codon)
return(ORFlist)
get_orf function works fine but my one_frame function doesn't work.
The one_frame function is supposed to take a DNA string as input. It searches that
string from left to right in multiples of three nucleotides–that is, in a single reading frame. When
it hits a start codon “ATG" it calls get_orf on the slice of the string beginning at that start codon
(until the end) to get back an ORF. That ORF is added to a list of ORFs and then the function skips
ahead in the DNA string to the point right after the ORF that we just found and starts looking for
the next ORF. This is repeated until we’ve traversed the entire DNA string.
I can see a few obvious problems but not sure exactly what you want so hope this helps. Firstly your for loop in one_frame will never end unless DNA starts with 'ATG'. I think you want to check codon.startswith instead of DNA.startswith. You also need to do the x+= command outside of the if statement, or it will never be updated when you don't hit 'ATG' and so your loop will continue forever. You're also not using the value of get_orf at all.
I think this will do the trick,
def one_frame(DNA):
x = 0
ORFlist = []
while x < len(DNA):
codon = DNA[x:]
# Check codon instead of DNA
if codon.startswith('ATG'):
# Record the return value of get_orf
orf_return_value = get_orf(DNA[x:])
if orf_return_value:
ORFlist.append(orf_return_value)
x += len(orf_return_value)
# Increment by 3 if we don't hit ATG
else:
x += 3
return(ORFlist)

Run length encoding python; String index out of range error

I'm trying to implement run length encoding into python with this code.
When I run it I get string index out of range error, not sure what is causing the error though
text="aaabbbcc"
def encode(text):
prev = text[0]
lentext = len(text)
i = 1
while prev == text[i] and i < lentext:
i += 1
return prev + str(i) + encode(text[i:])
print(encode(text))
Before you can check if i is less than the text length, you already try to access the ith element of text, which causes the exception. Instead, write your while loop as:
while i < lentext and prev == text[i]:
This will make sure i is in range before trying to access that index of text.
Also note that if you are going to use a recursive algorithm, you need a base case to exit the chain of recursive calls from. Probably something like the following at the top of your function:
if not text:
return ""
So all together:
text="aaabbbcc"
def encode(text):
if not text:
return ""
prev = text[0]
lentext = len(text)
i = 1
while i < lentext and prev == text[i]:
i += 1
return prev + str(i)+ encode(text[i:])
print(encode(text))

Binary search code not working

Good afternoon everyone,
I'm trying to sort out names which are already sorted in alphabetical order. I can't figure out why my program isn't working. Any tips or pointers would be nice. Thanks.
def main():
names = ['Ava Fiscer', 'Bob White', 'Chris Rich', 'Danielle Porter', 'Gordon Pike', 'Hannah Beauregard', 'Matt Hoyle', 'Ross Harrison', 'Sasha Ricci', 'Xavier Adams']
input('Please enter the name to be searched: ', )
binarySearch
main()
def binarySearch(names):
first = 0
last = len(names) - 1
position = -1
found = False
while not found and first <= last:
middle = (first + last) / 2
if names[middle] == value:
found = True
position = middle
elif arr[middle] > value:
last = middle -1
else:
first = middle + 1
return position
What does it mean that the program isn't working? Is it a syntax error or is the problem in the wrong results?
With the code you pasted, there are several indentation problems, but besides that, lines:
input('Please enter the name to be searched: ', )
binarySearch
are also syntactically incorrect, the comma is redundant and only the function name appearing just like that is plain wrong. If you are interested in the correctness of your algorithm, it seems alright, but the boundaries can always be tricky. My code below is working and syntactically correct, if you find it helpful. (names are numbers, but that is irrelevant in this case)
names = [1,2,4,5,6,8,9]
def bs(n):
start = 0
end = len(names)
while end - start > 0:
m = (start+end)/2
if names[m] == n:
return m
elif n < names[m]:
end = m
else:
start = m + 1
return -1
print (bs(1))
print (bs(6))
print (bs(9))
print (bs(3))
print (bs(10))
print (bs(-8))
Another thing I would like to point out is that this kind of binary search is already in the python standard library, the bisect module. However, if you are writing your own for practice or for any other reason that is just fine.
if you are using python 3.* then you are going to want to change
m = (start+end)/2
to
m = (start+end)//2
When you do /2 it outputs a float in 3.*

Resources