This function takes a dictionary as an argument and translates the given string. However, it has become an endless loop. I can't for the life of me figure out how to make it work normally. For example: it is supposed to take a string "hi" and translates it into "[-]1"
def translate(glyphs):
string = input("Enter string to be translated: ").strip()
new = ''
for keys in glyphs:
ind = string.upper().find(keys)
while ind != -1: #while there exists a key in the string
if len(glyphs[string[ind].upper()]) > 1: #if there is more than one value for key
rand = randint(0, 1) #choose randomly
transChar = glyphs[keys][rand]
new = string[:ind] + transChar + string[ind+1:]
ind = string.upper().find(keys)
print("hi1")
else:
transChar = glyphs[keys][0]
new = string[:ind] + transChar + string[ind+1:]
ind = string.upper().find(keys)
print("hi")
return new
Any help would be appreciated!
Looks like your dictionary contains lists of possible translations as values, from which you make random choices, and upper-case keys. This list comprehension should work, then:
import random
new = ' '.join(random.choice(glyphs[word]) \
for word in input_string.upper().split())
Related
I would like to ask as a python beginner, I would like to obtain strings from inside a square bracket and best if without trying to import any modules from python. If not it's okay.
For example,
def find_tags
#do some codes
x = find_tags('Hi[Pear]')
print(x)
it will return
1-Pear
if there are more than one brackets for example,
x = find_tags('[apple]and[orange]and[apple]again!')
print(x)
it will return
1-apple,2-orange,3-apple
I would greatly appreciate if someone could help me out thanks!
Here, I tried solving it. Here is my code :
bracket_string = '[apple]and[orange]and[apple]again!'
def find_tags(string1):
start = False
data = ''
data_list = []
for i in string1:
if i == '[':
start = True
if i != ']' and start == True:
if i != '[':
data += i
else:
if data != '':
data_list.append(data)
data = ''
start = False
return(data_list)
x = find_tags(bracket_string)
print(x)
The function will return a list of items that were between brackets of a given string parameter.
Any advice will be appreciated.
If your pattern is consistent like [sometext]sometext[sometext]... you can implement your function like this:
import re
def find_tags(expression):
r = re.findall('(\[[a-zA-Z]+\])', expression)
return ",".join([str(index + 1) + "-" + item.replace("[", "").replace("]", "") for index, item in enumerate(r)])
Btw you can use stack data structure (FIFO) to solve this problem.
You can solve this using a simple for loop over all characters of your text.
You have to remember if you are inside a tag or outside a tag - if inside you add the letter to a temporary list, if you encounter the end of a tag, you add the whole templorary list as word to a return list.
You can solve the numbering using enumerate(iterable, start=1) of the list of words:
def find_tags(text):
inside_tag = False
tags = [] # list of all tag-words
t = [] # list to collect all letters of a single tag
for c in text:
if not inside_tag:
inside_tag = c == "[" # we are inside as soon as we encounter [
elif c != "]":
t.append(c) # happens only if inside a tag and not tag ending
else:
tags.append(''.join(t)) # construct tag from t and set inside back to false
inside_tag = False
t = [] # clear temporary list
if t:
tags.append(''.join(t)) # in case we have leftover tag characters ( "[tag" )
return list(enumerate(tags,start=1)) # create enumerated list
x = find_tags('[apple]and[orange]and[apple]again!')
# x is a list of tuples (number, tag):
for nr, tag in x:
print("{}-{}".format(nr, tag), end = ", ")
Then you specify ',' as delimiter after each print-command to get your output.
x looks like: [(1, 'apple'), (2, 'orange'), (3, 'apple')]
I have below piece of code in python which I am using to get the component name of the JIRA issue some of them are single value in component field and some of them are multiple values in component field. My issue is that component field could have values with different name e.g R ABC 1.1 , R Aiapara 2.3A1(Active) etc.I don't want to do the way I am trying to do in below code.Is there any way I can find only the integer value from the component. from this component(R ABC 1.1) I need 1.1 and for 2nd component (R Aiapara 2.3A1(Active) I need 2.3 as well so this I would not need to depend on the name of the component
for version in issue["fields"]["components"]:
cacheData = json.dumps(version)
jsonToPython = json.loads(cacheData)
if jsonToPython['name'][:10] == "R Aiapara ":
allModules.append(jsonToPython["name"][10:])
print allModules
Below is the output I am getting
Retrieving list of issues
Processing SPTN-2
[u'1.6']
Processing SPTN-1
[u'1.5']
[u'1.5', u'1.6']
Using regex:
import re
s1 = "R ABC 4.4"
s2 = "R Ciapara 4.4A1(Active)"
print(re.findall(r"\d+\.\d+", s1))
print(re.findall(r"\d+\.\d+", s2))
Output:
['4.4']
['4.4']
I feel like I am not quite understanding your question, so I will try to answer as best I can, but feel free to correct me if I get anything wrong.
This function will get all the numbers from the string in a list:
def getNumber(string):
numbers = ".0123456789"
result = []
isNumber = False
for i in string:
if (i in numbers and isNumber):
result[-1] += i
elif i in result:
result+= [i]
isNumber = True
else:
isNumber = False
return result
However, if you want all the characters after the first number, then you will want this function. It will return everything after the first number, and False if there isn't a number there.
def getNumber(string):
numbers = ".0123456789"
result = []
isNumber = False
for i,char in enumerate(string):
if char in numbers:
return string[i:]
return False
Now, if you want everything between the first and last numbers, then try this one instead:
def getNumber(string):
numbers = ".0123456789"
result = string
isNumber = False
for i,char in enumerate(string):
if char in numbers:
result = result[i:]
break
for i in range(len(result)-1, 0, -1):
if result[i] in numbers:
result = result[:i+1]
break
return result
Hope this helps :)
This is the code I currently have:
letter = raw_input("Replace letter?")
traversed = raw_input("Traverse in?")
replacewith = raw_input("Replace with?")
traverseint = 0
for i in traversed:
traverseint = traverseint + 1
if i == letter:
traversed[traverseint] = replacewith
print i
print(traversed)
str in python are immutable by nature. That means, you can not modify the existing object. For example:
>>> 'HEllo'[3] = 'o'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
In order to replace the character in the string, ideal way is to use str.replace() method. For example:
>>> 'HEllo'.replace('l', 'o')
'HEooo'
Without using str.replace(), you may make your program run by using a temporary string as:
my_str = '' # Temporary string
for i in traversed:
# traverseint = traverseint + 1 # Not required
if i == letter:
i = replacewith
my_str += i
Here my_str will hold the value of transformed traversed. OR, even better way to do this is by transforming the string to list (as mentioned by #chepner), update the values of list and finally join the list to get back the string. For example:
traversed_list = list(traversed)
for i, val in enumerate(traversed_list):
if val == letter:
traversed_list[i] = replacewith
print i
my_str = ''.join(traversed_list)
I can not comment yet, but want add a bit to Moinuddin Quadri answer.
If index of replacement is not required, str.replace() should be a best solution.
If replacement index is required, just use str.index() or str.find() for determine an replacement index, then use slice (see table) to "cut" ends and sum replacement between begin and end, or just call str.replace().
while True:
index = traversed.find(letter)
if index < 0:
break
print index
traversed = traversed[:index] + replacewith + traversed[index + len(letter):]
#or
traversed = traversed.replace(letter, replacewith, 1)
Str is immutable, so direct slice assignment is not possible.
If you want directly modify a string, you should use a mutable type, like bytearray.
To check if string contains a substring you can use in
letter in traversed
"System" does not allow me to post more than 2 links. But all methods I have mentioned are on the same page.
You shouldn't modify containers you are iterating over. And you cant edit strings by position.
Make a copy of the string first and make it a list object
letter = raw_input("Replace letter?")
traversed = raw_input("Traverse in?")
modify = list(traversed)
replacewith = raw_input("Replace with?")
for traverseint,i in enumerate(modify):
if i == letter:
modify[traverseint] = replacewith
print i
print(''.join(modify))
You can also just create empty string and add letters (python 3.5)
letter = input("Replace letter?")
traversed = input("Traverse in?")
replacewith = input("Replace with?")
temp = ''
for i in traversed:
if i == letter:
temp += replacewith
else:
temp += i
print(temp)
We can also define own replace like below:
def replace(str, idx, char):
if -1 < idx < len(str):
return '{str_before_idx}{char}{str_after_idx}'.format(
str_before_idx=str[0:idx],
char=char,
str_after_idx=str[idx+1:len(str)]
)
else:
raise IndexError
Where str is string to be manipulated, idx is an index, char is character to be replaced at index idx.
I have to find the signs "a..,z", "A,..,Z", "space", "." and "," in some data.
I have tried the code:
fh = codecs.open("mydata.txt", encoding = "utf-8")
text = fh.read()
fh1 = unicode(text)
dic_freq_signs = dict(Counter(fh1.split()))
All_freq_signs = dic_freq_signs.items()
List_signs = dic_freq_signs.keys()
List_freq_signs = dic_freq_signs.values()
BUT it gets me ALL signs not the ones i am looking for?
Can anyone help?
(And it has to be unicode)
check dictionary iteration ..
All_freq_signs = [ item for item in dic_freq_signs.items() if item.something == "somevalue"]
def criteria(value):
return value%2 == 0
All_freq_signs = [ item for item in dic_freq_signs.items() if criteria(item)]
Make sure you import string module, with it you can get character ranges a to z and A to Z easily
import string
A Counter(any_string) gives the count of each character in the string. By using split() the counter would return the counts of each word in the string, contradicting with your requirement. So I have assumed that you need character counts.
dic_all_chars = dict(Counter(fh1)) # this gives counts of all characters in the string
signs = string.lowercase + string.uppercase + ' .,' # these are the characters you want to check
# using dict comprehension and checking if the key is in the characters you want
dic_freq_signs = {key: value for key, value in dic_all_chars.items()
if key in signs}
dic_freq_signs would only have the signs that you want to count as keys and their counts as values.
I'm new to Python, so maybe I'm asking for something very easy but I can't think of the problem in a Python way.
I have a compressed string. The idea is, if a character gets repeated 4-15 times, I make this change:
'0000' ---> '0|4'
If more than 15 times, I use a slash and two digits to represent the amount (working with hexadecimal values):
'00...(16 times)..0' ---> '0/10'
So, accustomed to other languages, my approach is the following:
def uncompress(line):
verticalBarIndex = line.index('|')
while verticalBarIndex!=-1:
repeatedChar = line[verticalBarIndex-1:verticalBarIndex]
timesRepeated = int(line[verticalBarIndex+1:verticalBarIndex+2], 16)
uncompressedChars = [repeatedChar]
for i in range(timesRepeated):
uncompressedChars.append(repeatedChar)
uncompressedString = uncompressedChars.join()
line = line[:verticalBarIndex-1] + uncompressedString + line[verticalBarIndex+2:]
verticalBarIndex = line.index('|') #next one
slashIndex = line.index('/')
while slashIndex!=-1:
repeatedChar = line[slashIndex-1:slashIndex]
timesRepeated = int(line[slashIndex+1:verticalBarIndex+3], 16)
uncompressedChars = [repeatedChar]
for i in range(timesRepeated):
uncompressedChars.append(repeatedChar)
uncompressedString = uncompressedChars.join()
line = line[:slashIndex-1] + uncompressedString + line[slashIndex+3:]
slashIndex = line.index('/') #next one
return line
Which I know it is wrong, since strings are inmutable in Python, and I am changing line contents all the time until no '|' or '/' are present.
I know UserString exists, but I guess there is an easier and more Pythonish way of doing it, which would be great to learn.
Any help?
The changes necessary to get your code running with the sample strings:
Change .index() to .find(). .index() raises an exception if the substring isn't found, .find() returns -1.
Change uncompressedChars.join() to ''.join(uncompressedChars).
Change timesRepeated = int(line[slashIndex+1:verticalBarIndex+3], 16) to timesRepeated = int(line[slashIndex+1:slashIndex+3], 16)
Set uncompressedChars = [] to start with, instead of uncompressedChars = [repeatedChar].
This should get it working properly. There are a lot of places where the code an be tidied and otpimised, but this works.
The most common pattern I have seen is to use a list of characters. Lists are mutable and work as you describe above.
To create a list from a string
mystring = 'Hello'
mylist = list(mystring)
To create a string from a list
mystring = ''.join(mylist)
You should build a list of substrings as you go and join them at the end:
def uncompress(line):
# No error checking, sorry. Will crash with empty strings.
result = []
chars = iter(line)
prevchar = chars.next() # this is the previous character
while True:
try:
curchar = chars.next() # and this is the current character
if curchar == '|':
# current character is a pipe.
# Previous character is the character to repeat
# Get next character, the number of repeats
curchar = chars.next()
result.append(prevchar * int(curchar, 16))
elif curchar == '/':
# current character is a slash.
# Previous character is the character to repeat
# Get two next characters, the number of repeats
curchar = chars.next()
nextchar = chars.next()
result.append(prevchar * int(curchar + nextchar, 16))
else:
# No need to repeat the previous character, append it to result.
result.append(curchar)
prevchar = curchar
except StopIteration:
# No more characters. Append the last one to result.
result.append(curchar)
break
return ''.join(result)