There is an is_reverse program in Think Python as follows:
def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2) - 1
while j > 0:
print(i, j)
if word1[i] != word2[j]:
return False
i = i + 1
j = j - 1
return True
The author asks to figure out an error in it which I am unable to after much brainstorming.
The program works just fine and returns this:
0 3
1 2
2 1
True
The error pertains to this output. Please help me figure it out.
Change the while condition in is_reverse method to -
while j >= 0:
The function suppose to check if word1 is reserve of word2 (I think, please post what you expect the function to do next time)
The function does not check final word and beginning word. It does not check word1[-1] (last character) and word2[0] (first character)
w1 = 'Dogx'
w2 = 'ggoD'
print (is_reverse(w1, w2))
The problem is here:
while j > 0:
The loop terminate before checking word2[0]. I suggest add =. THus, change the condition to:
while j >= 0:
Maybe the indentation is incorrect? Would not error if it was this:
def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2) - 1
while j > 0:
print(i, j)
if word1[i] != word2[j]:
return False
i = i + 1
j = j - 1
return True
I would write this function like this:
def is_reverse(word1, word2):
return word1[::-1] == word2
But neither of these functions deal with uppercase to lowercase comparisons. I'm not sure how you want to handle that.
def is_reverse(word3, word4):
if len(word3) != len(word4):
return False
iii = 0
j = len(word4)-1
while j >= 0:
print(iii, j)
print(word3[iii], word4[j])
print("----------------")
if word3[iii] != word4[j]:
return False
iii += 1
print("j printed", j)
j -= 1
is_reverse("spot","tops")
Related
I wrote this code, and I'm struggling to replace using break since it says in the homework that we are not allowed to use continue/break statements in our loops.
The code's goal is:
finds the character that appears most frequently in the input parameter string and returns it. For Example, if the string is "Canada day" the function returns the string "a"
If there are two characters or more with the same frequency, the function should return the first of many values with the same frequency.
def find_frequent(s):
"""
-------------------------------------------------------
description
Use:
-------------------------------------------------------
Parameters:
name - description (type)
Returns:
name - description (type)
------------------------------------------------------
"""
L = []
count = 0
char = 0
i = 0
words = True
while i < 1 and words:
x = s[i]
for j in range(len(L)):
if x == L[j]:
words = False
L[j + 1] = L[j + 1] + 1
else:
L.append(x)
L.append(1)
for i in range(1, len(L), 2):
if L[i] > count:
count = L[i]
char = L[i - 1]
return char
the output should look like this
`Enter a string: Hello Hi`
output should be
`Most frequent characters: H`
I'm getting this output
Enter a string: canada
Most frequent character: c
You can replace the break statement in a for loop with a while loop.
print("using for loop + break")
for i in range(0, 5):
print(i)
if i == 3:
break
print("using while")
i = 0
keep_searching = True
while i < 5 and keep_searching:
print(i)
if i == 3:
keep_searching = False
i += 1
The output is:
using for loop + break
0
1
2
3
using while
0
1
2
3
I think you can figure it out from here, but if you need help with finding the most frequent character (a different issue from the break), take a look here and here.
No need for a break if you don't use a loop in the first place :-)
def find_frequent(s):
return max(s, key=s.count)
(I'm actually serious... forbidding break sounds to me like your teacher didn't want you to write it with such nested loops.)
Or if you want to teach your teacher a lesson (the lesson being that they shouldn't forbid stuff), you could fake the break:
for i in range(0, len(s), 1):
x = s[i]
it = iter(range(len(L))) # make it an iterator
for j in it:
if x == L[j]:
L[j + 1] = L[j + 1] + 1
*it, # exhaust the iterator
it = None # make it false
if it: # instead of `else`
L.append(x)
L.append(1)
I am looking to understand what I can do to make my code to work. Learning this concept will probably unlock a lot in my programming understanding. I am trying to count the number of times the string 'bob' occurs in a larger string. Here is my method:
s='azcbobobegghakl'
for i in range(len(s)):
if (gt[0]+gt[1]+gt[2]) == 'bob':
count += 1
gt.replace(gt[0],'')
else:
gt.replace(gt[0],'')
print count
How do I refer to my string instead of having to work with integers because of using for i in range(len(s))?
Try this:
def number_of_occurrences(needle, haystack, overlap=False):
hlen, nlen = len(haystack), len(needle)
if nlen > hlen:
return 0 # definitely no occurrences
N, i = 0, 0
while i < hlen:
consecutive_matching_chars = 0
for j, ch in enumerate(needle):
if (i + j < hlen) and (haystack[i + j] == ch):
consecutive_matching_chars += 1
else:
break
if consecutive_matching_chars == nlen:
N += 1
# if you don't need overlap, skip 'nlen' characters of 'haystack'
i += (not overlap) * nlen # booleans can be treated as numbers
i += 1
return N
Example usage:
haystack = 'bobobobobobobobobob'
needle = 'bob'
r = number_of_occurrences(needle, haystack)
R = haystack.count(needle)
print(r == R)
thanks. your support help to birth the answer in. here what I have :
numBobs = 0
for i in range(1, len(s)-1):
if s[i-1:i+2] == 'bob':
numBobs += 1
print 'Number of times bob occurs is:', numBobs
def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2)
while j > 0:
if word1[i] != word2[j]:
return False
i = i+1
j = j-1
return True
is_reverse('pots', 'stop')
I had defined above function to check two given words reversely match to each other.
but when I run it, it keeps reminding me of indentation error.
How to gauge the indentation level in python?
You can look the Indentation Section in PEP8:
In general
Use 4 spaces per indentation level.
(don't mix tabs and spaces).
When you start the body of a new block (e.g., in your if and `while), keep the body indented 4 spaces relative to the line introducing the block.
So when you write
if len(word1) != len(word2):
...
...
Everything that should happen if the condition occurred, should have 4 spaces relative to the if, for example. If there's another if, or while inside, you increase its body's indent 4 spaces further, and so on.
As a side note, note that you can check if two words are reverse matches of each other with
def is_reverse(word1, word2):
return word1 == reversed(word2)
Indentation matters in python, because it defines which code belongs together (which is done e.g. with brackets in other languages).
Because your code is heavily malformed, please have a look at the reformatted code:
def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2)-1
while j >= 0:
if word1[i] != word2[j]:
return False
i = i+1
j = j-1
return True
is_reverse('pots', 'stop')
-> True
Notice I also changed j = len(word2)-1 and while j >= 0:, since a word of length x has letters in positions 0..x-1.
Hint: string reversal can be achieved with slicing notation and a step size of -1:
"pots"[::-1] == "stop"
General rule is 4 space indentation.
Below is an example of proper indentation, without changes to the original code:
def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2)
while j > 0:
if word1[i] != word2[j]:
return False
i = i+1
j = j-1
return True
The number of spaces used for an indentation level in python is not syntactically important, it can be any arbitrary number (in most cases 2, 4 or 8 spaces are used per level), but it has to be consistent. So after an if block, you have to return to the same indentation level you had before, like this:
def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2)
while j > 0:
if word1[i] != word2[j]:
return False
i = i+1
j = j-1
return True
is_reverse('pots', 'stop')
This code won't throw an IndentationError. Of course, for stylistic reasons, it's good to have a constant indentation level, like this:
def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2)
while j > 0:
if word1[i] != word2[j]:
return False
i = i+1
j = j-1
return True
is_reverse('pots', 'stop')
Your code also has a logical error, as the starting value of j should be 1 less than the length of the string (due to zero-based indexing), and go down all the way to 0, like this:
i = 0
j = len(word2) - 1
while j >= 0:
if word1[i] != word2[j]:
return False
i = i+1
j = j-1
Supposed to take in a string for example "Maroon 5" and then return only the number in the statement. In this case it's "5" but I just get no output. Thank you!
def findNumbers(str):
found1 = False
found2 = False
i = 0
while not found1 and i<len(str):
if str[i] in "0123456789":
found1 = True
else:
i = i + 1
if found1:
j = 0
while not found2 and j<len(str):
if str[j] in "0123456789":
found2 = False
else:
j = j + 1
else:
return 0
istr = str[i:j]
n = (istr)
return n
print (findNumbers("Maroon 5"))
You have two important errors in your code. One is that once you've found a digit, you jump back to the start of the string:
j = 0
Instead, you want to continue from there:
j = i
The other, bigger problem is that you have an infinite loop. The second loop may continue indefinitely if str[j] is a digit, since setting found2 to False does not end the loop. The code should be
while not found2 and j<len(str):
if str[j] not in "0123456789":
found2 = True
else:
j = j + 1
you can do it like this:
def findNumbers(str):
for i in range(0,len(str)):
if (str[i].isdigit()):
print str[i]
findNumbers("Maroon 5")
It should print the number 5
You can try this way: This will return a list of tuples with the numbers and their indexes
def findNumbers(string):
num = '1234567890'
return ([(string[x], x) for x in range(len(string)) if string[x] in num])
I have been working on the Bonetrousle problem in hacker rank using python. After many hours the below code passes all the test cases except one where it times out. Any suggestions on how I can make the code quicker would be appreciated. I believe the problem is the code that deals with the remainder, I put comments below and above it so it is easy to find. Unfortunately I am at a loss on how to refactor it so it works faster.
The code I wrote gets the right answer for all test cases, I have verified this in pycharm. The only problem is that it is to slow for one of the hacker rank test cases.
Here is the link to the problem https://www.hackerrank.com/challenges/bonetrousle
Here is a link to the test case it fails
https://hr-testcases-us-east-1.s3.amazonaws.com/21649/input12.txt?AWSAccessKeyId=AKIAJAMR4KJHHUS76CYQ&Expires=1473987910&Signature=xaHGvYRVmUVJHh4r3on%2BWgoIsjs%3D&response-content-type=text%2Fplain
firstLine = int(input())
for a in range(0, firstLine):
nums = input()
numsArr = list(map(int, nums.split(" ")))
n = numsArr[0]
k = numsArr[1]
b = numsArr[2]
num1 = 0
rem = 0
answer = True
remAdded = False
count = 0
boxArr = []
for i in range(1, b+1):
count += i
boxArr.append(i)
num1 = (n - count)//b
rem = (n - count)%b
for j in range(0, len(boxArr)):
boxArr[j] = boxArr[j] + num1
if boxArr[j] > k:
answer = False
# In below code -> if there is a remainder I am adding it to an element in the array that has box numbers
# I check to see if I can add the remainder to an element in the array
#without that element exceeding k, the number of sticks. If I can't then the bool remAdded doesn't get set to True
# The below code works but it seems inefficient and looks like the problem
if rem == 0:
remAdded = True
elif answer != False:
for r in range(len(boxArr) - 1, 0, -1):
if boxArr[r] + rem <= k and r == len(boxArr) - 1:
boxArr[r] = boxArr[r] + rem
remAdded = True
break
else:
if boxArr[r] + rem <= k and (boxArr[r] + rem) not in boxArr:
boxArr[r] = boxArr[r] + rem
remAdded = True
break
# above is code for dealing with remainder. Might be the problem
if answer == False or remAdded == False:
print(-1)
elif 0 in boxArr:
print(-1)
else:
for z in range(0, len(boxArr)):
if z != len(boxArr) - 1:
print(boxArr[z], end =" ")
else:
print(boxArr[z])
Replace the code between your comments by:
if rem == 0:
remAdded = True
elif boxArr[-1] + 1 > k:
remAdded = False
elif answer != False:
l = len(boxArr)-1
for r in range(l, l-rem, -1):
boxArr[r] += 1
remAdded = True
This gets rid of the expensive (boxArr[r] + rem) not in boxArr, basically. It passes all test cases for me.