I want to do something like this:
>>> mystring = "foo"
>>> print(mid(mystring))
Help!
slices to the rescue :)
def left(s, amount):
return s[:amount]
def right(s, amount):
return s[-amount:]
def mid(s, offset, amount):
return s[offset:offset+amount]
If I remember my QBasic, right, left and mid do something like this:
>>> s = '123456789'
>>> s[-2:]
'89'
>>> s[:2]
'12'
>>> s[4:6]
'56'
http://www.angelfire.com/scifi/nightcode/prglang/qbasic/function/strings/left_right.html
Thanks Andy W
I found that the mid() did not quite work as I expected and I modified as follows:
def mid(s, offset, amount):
return s[offset-1:offset+amount-1]
I performed the following test:
print('[1]23', mid('123', 1, 1))
print('1[2]3', mid('123', 2, 1))
print('12[3]', mid('123', 3, 1))
print('[12]3', mid('123', 1, 2))
print('1[23]', mid('123', 2, 2))
Which resulted in:
[1]23 1
1[2]3 2
12[3] 3
[12]3 12
1[23] 23
Which was what I was expecting. The original mid() code produces this:
[1]23 2
1[2]3 3
12[3]
[12]3 23
1[23] 3
But the left() and right() functions work fine. Thank you.
You can use this method also it will act like that
thadari=[1,2,3,4,5,6]
#Front Two(Left)
print(thadari[:2])
[1,2]
#Last Two(Right)# edited
print(thadari[-2:])
[5,6]
#mid
mid = len(thadari) //2
lefthalf = thadari[:mid]
[1,2,3]
righthalf = thadari[mid:]
[4,5,6]
Hope it will help
This is Andy's solution. I just addressed User2357112's concern and gave it meaningful variable names. I'm a Python rookie and preferred these functions.
def left(aString, howMany):
if howMany <1:
return ''
else:
return aString[:howMany]
def right(aString, howMany):
if howMany <1:
return ''
else:
return aString[-howMany:]
def mid(aString, startChar, howMany):
if howMany < 1:
return ''
else:
return aString[startChar:startChar+howMany]
These work great for reading left / right "n" characters from a string, but, at least with BBC BASIC, the LEFT$() and RIGHT$() functions allowed you to change the left / right "n" characters too...
E.g.:
10 a$="00000"
20 RIGHT$(a$,3)="ABC"
30 PRINT a$
Would produce:
00ABC
Edit : Since writing this, I've come up with my own solution...
def left(s, amount = 1, substring = ""):
if (substring == ""):
return s[:amount]
else:
if (len(substring) > amount):
substring = substring[:amount]
return substring + s[:-amount]
def right(s, amount = 1, substring = ""):
if (substring == ""):
return s[-amount:]
else:
if (len(substring) > amount):
substring = substring[:amount]
return s[:-amount] + substring
To return n characters you'd call
substring = left(string,<n>)
Where defaults to 1 if not supplied. The same is true for right()
To change the left or right n characters of a string you'd call
newstring = left(string,<n>,substring)
This would take the first n characters of substring and overwrite the first n characters of string, returning the result in newstring. The same works for right().
There are built-in functions in Python for "right" and "left", if you are looking for a boolean result.
str = "this_is_a_test"
left = str.startswith("this")
print(left)
> True
right = str.endswith("test")
print(right)
> True
Based on the comments above, it would seem that the Right() function could be refactored to handle errors better. This seems to work:
def right(s, amount):
if s == None:
return None
elif amount == None:
return None # Or throw a missing argument error
s = str(s)
if amount > len(s):
return s
elif amount == 0:
return ""
else:
return s[-amount:]
print(right("egg",2))
print(right(None, 2))
print(right("egg", None))
print(right("egg", 5))
print("a" + right("egg", 0) + "b")
Related
Implement the is_jumping function, which accepts the number number and returns the string JUMPING, if each digit in the number differs from the adjacent one by 1. If the condition is not met - the string NOT JUMPING.
def is_jumping(number: int) -> str:
newStr = str(number)
for i in range(len(newStr)):
if len(newStr) == 1:
return "JUMPING"
elif int(newStr[i + 1]) - int(newStr[i]) == 1:
return "JUMPING"
else: return "NOT JUMPING"
AssertionError: assert is_jumping(12543) == "NOT JUMPING", ( "Function 'is_jumping' should return 'NOT JUMPING' " "when number is 12543" )
Where is a problem? why can not pass number 12543? Thank you!
UPD
According to your advice I made some change, but still it doesn't work. Any chance to make my code work?
def is_jumping(number: int) -> str:
newStr = str(number)
for i in range(len(newStr) - 1):
if int(newStr[i + 1]) - int(newStr[i]) != 1 or int(newStr[i + 1]) - int(newStr[i]) != -1:
return "NOT JUMPING"
return "JUMPING"
#Michael Butscher #bbbbbbbbb #Johnny
Problems in your code already explained in the comment section.
Regardless, no need to convert your input number to a string; try this:
def is_jumping(num: int) -> str:
while num >= 10:
x = num % 10
num //= 10
if num % 10 not in [x - 1, x + 1]:
return "NOT JUMPING"
return "JUMPING"
I have a sequence print(lcp(["flower","flow","flight", "dog"])) which should return fl. Currently I can get it to return flowfl.
I can locate the instances where o or w should be removed, and tried different approaches to remove them. However they seem to hit syntax issue, which I cannot seem to resolve by myself.
I would very much appreciate a little guidance to either have the tools to remedy this issue my self, or learn from a working proposed solution.
def lcp(strs):
if not isinstance(strs, list) or len(strs) == 0:
return ""
if len(strs) == 1:
return strs[0]
original = strs[0]
original_max = len(original)
result = ""
for _, word in enumerate(strs[1:],1):
current_max = len(word)
i = 0
while i < current_max and i < original_max:
copy = "".join(result)
if len(copy) and copy[i-1] not in word:
# result = result.replace(copy[i-1], "")
# result = copy[:i-1]
print(copy[i-1], copy, result.index(copy[i-1]), i, word)
if word[i] == original[i]:
result += word[i]
i += 1
return result
print(lcp(["flower","flow","flight", "dog"])) # returns flowfl should be fl
print(lcp(["dog","car"])) # works
print(lcp(["dog","racecar","car"])) # works
print(lcp([])) # works
print(lcp(["one"])) # works
I worked on an alternative which does not be solve removing inside the same loop, adding a counter at the end. However my instincts suggest it can be solved within the for and while loops without increasing code bloat.
if len(result) > 1:
counter = {char: result.count(char) for char in result}
print(counter)
I have solved this using the below approach.
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
N = len(strs)
if N == 1:
return strs[0]
len_of_small_str, small_str = self.get_min_str(strs)
ans = ""
for i in range(len_of_small_str):
ch = small_str[i]
is_qualified = True
for j in range(N):
if strs[j][i] != ch:
is_qualified = False
break
if is_qualified:
ans += ch
else:
break
return ans
def get_min_str(self, A):
min_len = len(A[0])
s = A[0]
for i in range(1, len(A)):
if len(A[i]) < min_len:
min_len = len(A[i])
s = A[i]
return min_len, s
Returns the longest prefix that the set of words have in common.
def lcp(strs):
if len(strs) == 0:
return ""
result = strs[0]
for word in strs[1:]:
for i, (l1, l2) in enumerate(zip(result, word)):
if l1 != l2:
result = result[:i]
break
else:
result = result[:i+1]
return result
Results:
>>> print(lcp(["flower","flow","flight"]))
fl
>>> print(lcp(["flower","flow","flight", "dog"]))
>>> print(lcp(["dog","car"]))
>>> print(lcp(["dog","racecar","car"]))
>>> print(lcp([]))
>>> print(lcp(["one"]))
one
>>> print(lcp(["one", "one"]))
one
You might need to rephrase your goal.
By your description you don't want the longest common prefix, but the prefix that the most words have in common with the first one.
One of your issues is that your tests only test one real case and four edgecases. Make some more real examples.
Here's my proposition: I mostly added the elif to check if we already have a difference on the first letter to then discard the entry.
It also overwrites the original to rebuild the string based on the common prefix with the next word (if there are any)
def lcp(strs):
if not isinstance(strs, list) or len(strs) == 0:
return ""
if len(strs) == 1:
return strs[0]
original = strs[0]
result = ""
for word in strs[1:]:
i = 0
while i < len(word) and i < len(original) :
if word[i] == original[i]:
result += word[i]
elif i == 0:
result = original
break
i += 1
original = result
result = ""
return original
print(lcp(["flower","flow","flight", "dog"])) # fl
print(lcp(["shift", "shill", "hunter", "shame"])) # sh
print(lcp(["dog","car"])) # dog
print(lcp(["dog","racecar","car"])) # dog
print(lcp(["dog","racecar","dodge"])) # do
print(lcp([])) # [nothing]
print(lcp(["one"])) # one
I received an interesting challenge in an algorithm Meetup. Given an input string, return a string in which all substrings within brackets have been replicated n times, where n is the integer outside the brackets. Characters outside brackets should simply be concatenated to the substring inside. For example:
2[ab] should return abab
a[3[bc]] should return abcbcbc
2[ab[cd]] should return abcdabcd
I've started implementing the solution using a stack, but I've got the feeling that my approach of checking each de-stacked character for a bracket is off, anyone have any suggestions? Code is below
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def length(self):
return len(self.items)
def is_number(s):
try:
int(s)
return True
except ValueError:
return False
def character_math(charstr):
final_output = ""
substring = ""
for i in charstr:
myStack.push(i)
for m in range(myStack.length() - 2):
destacked = myStack.pop()
# We want to go to the inner-most right bracket
if destacked != "]":
substring += destacked
if destacked == "[":
possible_multiplier = myStack.pop()
if is_number(possible_multiplier):
final_output += int(possible_multiplier) * substring
else:
final_output += possible_multiplier[::-1]
break
final_output += substring[::-1]
return "Final output is ", final_output
myStack = Stack()
# 3[ab[cd]] should return 'abcdabcd'
sample_str = '2[ab[cd]]'
print(character_math(sample_str))
The best way to do that is to use a recursive algorithm. The idea is to repeat a function until a condition is match. Here is the code I used, it works on your examples, and I don't think I forgot one of the possibilities.
# -*-coding:Utf-8 -*
Input = "2[ab[cd]]"
def Treatment(STR):
# Exit the treatment. That's the end condition.
if "[" not in STR:
return STR
# Find the inner [], in this case, the "cd" part
Bound1_ID = len(STR) - STR[::-1].index("[") - 1
Bound2_ID = STR.index("]")
# Separate STR into : First_part + middle between [] + Last_part
Last_part = STR[Bound2_ID + 1:]
# First_part depends if there is a number or not
try:
Multiplier = int(STR[Bound1_ID - 1])
First_part = STR[:Bound1_ID - 1]
except:
Multiplier = 1
First_part = STR[:Bound1_ID]
Middle_part = STR[Bound1_ID + 1: Bound2_ID] * Multiplier
# Assemble the new STR :
New_STR = First_part + Middle_part + Last_part
# Recursive command, repeat the function on the new STR
return Treatment(New_STR)
print (Treatment(Input))
EDIT : That's what it does :
First iteration : "2[ab[cd]]"
Second iteration : "2[abcd]"
Third iteration : abcdabcd => No more "[" so stop here.
i've searched the forum and found similar questions, but no luck in solving my problem.
My code is designed to swap every two letters of each word using recursion and print the result. For words with an even amount of letters, the word "None" is included in the output and i don't know how to fix...
here's the code:
def encryptLine(line, count):
headline = line[count:]
if length(headline) > 0:
if count == length(line) - 1:
new = headline
return new
elif count <= length(line):
new = head(tail(headline)) + head(headline)
new = new + str(encryptLine(line, count+2))
return new
print(encryptLine('abcd', 0))
the output for 'abcd' is badcNone, which is correct except for the word None. the output for 'abcde' is 'badce', which is correct...
thanks in advance for your help!
Add return "" to the function definition, that is
def encryptLine(line, count):
headline = line[count:]
if length(headline) > 0:
if count == length(line) - 1:
new = headline
return new
elif count <= length(line):
new = head(tail(headline)) + head(headline)
new = new + str(encryptLine(line, count+2))
return new
return ""
Otherwise, the function will return None if length(headline) > 0 does not hold.
None is here because your function return nothing.
There is 1 case where you return nothing it is
if length(headline) <= 0:
In Python, if there is no return to a function and you try to access to a return value, the value will be None.
I have an assignment said that to create a findString function that accept 2 string which are 'target' and 'query', and that returns
a
list
of
all
indices
in
target
where
query
appears.
If
target
does
not
contain
query,
return
an
empty
list.
For example:
findString(‘attaggtttattgg’,’gg’)
return:
[4,12]
I dont know how to start off with this function writing at all. Please help me everyone. Thank you so much!!!
since an answer has already been given:
def find_matches(strng, substrng):
substrg_len = len(substr)
return [i for i in range(len(strg) + 1 - substrg_len)
if strg[i:i+substrg_len] == substrg]
def find_string(search, needle):
start = -1
results = []
while start + 1< len(search):
start = search.find(needle, start +1)
if start == -1:
break
results.append(start )
return results
Here are a couple of hints to get you started.
target.find(query) will return the index of query in target. If query is not found, it will return -1.
A string can be sliced. target[pos:] will give you a substring of target starting from pos.
This may require some error handling:
def find_allPatterns(strVal, strSub):
listPos = []
strTemp = strVal
while True:
try:
posInStr = strTemp.index(strSub)
except ValueError:
posInStr = None
if posInStr:
listPos.append(posInStr)
subpos = posInStr + len(strSub)
strTemp = strTemp[subpos:]
else:
break
return listPos
print find_allPatterns('attaggtttattgg', 'gg')
Output:
[4, 6]