Find only integer value where you have multiple strings in python - python

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 :)

Related

Determining validity if sum divisible by 10

Outline:
Find out if id is acceptable. Acceptable parameters is the sum of the
digits for each part of the id. If each sum is evenly divisible by 10
then the function returns the string "Acceptable", otherwise it
returns the string "Unacceptable".
Example:
isValid('123-12-134') → 'Unacceptable'
isValid('550-55-055') → 'Acceptable'
isValid('123-55-055') → 'Unacceptable'
I've tried converting the entire string into an int, but get some differing results in determining divisible by 10.
My attempted code is:
def isValid(id) :
id=id.replace('-','0')
id=int(id)
if id % 10==0:
return "Valid"
else:
return "Invalid"
Thanks in advance!
You might as well return boolean variables and just compare the output to determine what to print:
def summation(item):
return sum([int(i) for i in item])
def isValid(id_) :
id_part = id_.split('-')
result = [summation(item) % 10 == 0 for item in id_part]
return all(result)
Essentially this loops through all the characters in the split string and determines their sum - 3 sums per provided id.
Then we convert the summed list to a boolean list using your condition of x%10 == 0.
Finally we look at all() the elements of this boolean list to determine if it all True or contains a False.
If all are True then the return of isValid(id_) is True else it is False.
Usage:
ids = ['123-12-134', '550-55-055', '123-55-055']
for id_ in ids:
validity = isValid(id_)
print("Acceptable") if validity else print("Unacceptable")
Output:
Unacceptable
Acceptable
Unacceptable
you mean like this?
sentence = "123-123-123"
a = sum(int(x) for x in sentence if x.isdigit())
Hope this code can help you.
Found on this answer
you mean like this?
sentence = "123-123-123"
a = sum(int(x) for x in sentence if x.isdigit())
return a % 10 == 0
Hope this code can help you.
Found on this answer
We want to short-circuit the 'Unacceptable'.
def isValid(ID):
s = 0
for x in ID:
if x.isdigit():
s += int(x)
else:
if s % 10 == 0:
s = 0
else:
return 'Unacceptable'
return 'Acceptable' if s%10 == 0 else 'Unacceptable'
The solution requires splitting the string into parts using hyphens as separators, which are tested to ensure that the sum of each part's characters is a multiple of 10. The test fails if any of the parts are not a multiple of ten, so each part must be greater than or equal to ten. If any part fails, the string fails, so, there is no need to continue testing if a failed part is found. Acceptable must be returned if the string passes, or Unacceptable if it fails.
This single function solution is easy to read:
def teststring(test):
for part in test.split('-'):
part_failed = int(part)<10
if not part_failed:
sum_chars = 0
for char in part:
sum_chars += int(char)
part_failed = ((sum_chars % 10) != 0)
if part_failed: break
return 'Acceptable' if not part_failed else 'Unacceptable'
This solution uses list comprehension in two functions:
def testpart_comprehended(part):
return ((int(part)>=10) and ((sum(int(char) for char in part) % 10) == 0))
def acceptable_comprehended(test):
return 'Acceptable' if all(testpart_comprehended(part) for part in test.split("-")) else 'Unacceptable'
This solution uses list comprehension in one function:
def all_comprehended(test):
return 'Acceptable' if all(((int(part)>=10) and ((sum(int(char) for char in part) % 10) == 0)) for part in test.split("-")) else 'Unacceptable'
These answers are all too understandable. Please use
isValid = lambda x: (any(sum(map(int, s)) % 10 for s in x.split('-'))
* 'un' + 'acceptable').title()
Unacceptable
for example
>>> isValid('123-123')
'Unacceptable'
>>> isValid('123-127')
'Unacceptable'
>>> isValid('127-127')
'Acceptable'

How do I find the predominant letters in a list of strings

I want to check for each position in the string what is the character that appears most often on that position. If there are more of the same frequency, keep the first one. All strings in the list are guaranteed to be of identical length!!!
I tried the following way:
print(max(((letter, strings.count(letter)) for letter in strings), key=lambda x:[1])[0])
But I get: mistul or qagic
And I can not figure out what's wrong with my code.
My list of strings looks like this:
Input: strings = ['mistul', 'aidteh', 'mhfjtr', 'zxcjer']
Output: mister
Explanation: On the first position, m appears twice. Second, i appears twice twice. Third, there is no predominant character, so we chose the first, that is, s. On the fourth position, we have t twice and j twice, but you see first t, so we stay with him, on the fifth position we have e twice and the last r twice.
Another examples:
Input: ['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']
Output: magic
Input: ['sacbkt', 'tnqaex', 'vhcrhl', 'obotnq', 'vevleg', 'rljnlv', 'jdcjrk', 'zuwtee', 'xycbvm', 'szgczt', 'imhepi', 'febybq', 'pqkdfg', 'swwlds', 'ecmrut', 'buwruy', 'icjwet', 'gebgbq', 'djtfzr', 'uenleo']
Expected Output: secret
Some help?
Finally a use case for zip() :-)
If you like cryptic code, it could even be done in one statement:
def solve(strings):
return ''.join([max([(letter, letters.count(letter)) for letter in letters], key=lambda x: x[1])[0] for letters in zip(*strings)])
But I prefer a more readable version:
def solve(strings):
result = ''
# "zip" the strings, so in the first iteration `letters` would be a list
# containing the first letter of each word, the second iteration it would
# be a list of all second letters of each word, and so on...
for letters in zip(*strings):
# Create a list of (letter, count) pairs:
letter_counts = [(letter, letters.count(letter)) for letter in letters]
# Get the first letter with the highest count, and append it to result:
result += max(letter_counts, key=lambda x: x[1])[0]
return result
# Test function with input data from question:
assert solve(['mistul', 'aidteh', 'mhfjtr', 'zxcjer']) == 'mister'
assert solve(['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn',
'mzsev', 'saqbl', 'myead']) == 'magic'
assert solve(['sacbkt', 'tnqaex', 'vhcrhl', 'obotnq', 'vevleg', 'rljnlv',
'jdcjrk', 'zuwtee', 'xycbvm', 'szgczt', 'imhepi', 'febybq',
'pqkdfg', 'swwlds', 'ecmrut', 'buwruy', 'icjwet', 'gebgbq',
'djtfzr', 'uenleo']) == 'secret'
UPDATE
#dun suggested a smarter way of using the max() function, which makes the one-liner actually quite readable :-)
def solve(strings):
return ''.join([max(letters, key=letters.count) for letters in zip(*strings)])
Using collections.Counter() is a nice strategy here. Here's one way to do it:
from collections import Counter
def most_freq_at_index(strings, idx):
chars = [s[idx] for s in strings]
char_counts = Counter(chars)
return char_counts.most_common(n=1)[0][0]
strings = ['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih',
'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']
result = ''.join(most_freq_at_index(strings, idx) for idx in range(5))
print(result)
## 'magic'
If you want something more manual without the magic of Python libraries you can do something like this:
def f(strings):
dic = {}
for string in strings:
for i in range(len(string)):
word_dic = dic.get(i, { string[i]: 0 })
word_dic[string[i]] = word_dic.get(string[i], 0) + 1
dic[i] = word_dic
largest_string = max(strings, key = len)
result = ""
for i in range(len(largest_string)):
result += max(dic[i], key = lambda x : dic[i][x])
return result
strings = ['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']
f(strings)
'magic'

How to return an array of characters in cypher program (python3)

i wrote code when input for example is "a" he return "h". But how i can make it work if i want to return array of characters, for example if is input "aa"
to return "hh"?
def input(s):
for i in range(len(s)):
ci = (ord(s[i])-90)%26+97
s = "".join(chr(ci))
return s
Never use built-in names as input
l = []
def input_x(s):
for i in s:
i = (ord(i)-90)%26+97
l.append(chr(i))
s = ''.join(l)
return s
You can use strings to do this. My variable finaloutput is a string that I will use to store all the updated characters.
def foo(s):
finaloutput = ''
for i in s:
finaloutput += chr((ord(i)-90)%26+97)
return finaloutput
This code uses string concatenation to add together a series of characters. Since strings are iterables, you can use the for loop shown above instead of the complex one that you used.
def input_x(s):
result = ""
for i in s:
ci = (ord(i)-90)%26+ 97
result += chr(ci)
print(result)

Getting the middle character in a odd length string

def get_middle_character(odd_string):
variable = len(odd_string)
x = str((variable/2))
middle_character = odd_string.find(x)
middle_character2 = odd_string[middle_character]
return middle_character2
def main():
print('Enter a odd length string: ')
odd_string = input()
print('The middle character is', get_middle_character(odd_string))
main()
I need to figure out how to print the middle character in a given odd length string. But when I run this code, I only get the last character. What is the problem?
You need to think more carefully about what your code is actually doing. Let's do this with an example:
def get_middle_character(odd_string):
Let's say that we call get_middle_character('hello'), so odd_string is 'hello':
variable = len(odd_string) # variable = 5
Everything is OK so far.
x = str((variable/2)) # x = '2'
This is the first thing that is obviously odd - why do you want the string '2'? That's the index of the middle character, don't you just want an integer? Also you only need one pair of parentheses there, the other set is redundant.
middle_character = odd_string.find(x) # middle_character = -1
Obviously you can't str.find the substring '2' in odd_string, because it was never there. str.find returns -1 if it cannot find the substring; you should use str.index instead, which gives you a nice clear ValueError when it can't find the substring.
Note that even if you were searching for the middle character, rather than the stringified index of the middle character, you would get into trouble as str.find gives the first index at which the substring appears, which may not be the one you're after (consider 'lolly'.find('l')...).
middle_character2 = odd_string[middle_character] # middle_character2 = 'o'
As Python allows negative indexing from the end of a sequence, -1 is the index of the last character.
return middle_character2 # return 'o'
You could actually have simplified to return odd_string[middle_character], and removed the superfluous assignment; you'd have still had the wrong answer, but from neater code (and without middle_character2, which is a terrible name).
Hopefully you can now see where you went wrong, and it's trivially obvious what you should do to fix it. Next time use e.g. Python Tutor to debug your code before asking a question here.
You need to simply access character based on index of string and string slicing. For example:
>>> s = '1234567'
>>> middle_index = len(s)/2
>>> first_half, middle, second_half = s[:middle_index], s[middle_index], s[middle_index+1:]
>>> first_half, middle, second_half
('123', '4', '567')
Explanation:
str[:n]: returns string from 0th index to n-1th index
str[n]: returns value at nth index
str[n:]: returns value from nth index till end of list
Should be like below:
def get_middle_character(odd_string):
variable = len(odd_string)/2
middle_character = odd_string[variable +1]
return middle_character
i know its too late but i post my solution
I hope it will be useful ;)
def get_middle_char(string):
if len(string) % 2 == 0:
return None
elif len(string) <= 1:
return None
str_len = int(len(string)/2))
return string[strlen]
reversedString = ''
print('What is your name')
str = input()
idx = len(str)
print(idx)
str_to_iterate = str
for char in str_to_iterate[::-1]:
print(char)
evenodd = len(str) % 2
if evenodd == 0:
print('even')
else:
print('odd')
l = str
if len(l) % 2 == 0:
x = len(l) // 2
y = len(l) // 2 - 1
print(l[x], l[y])
else:
n = len(l) // 2
print(l[n])

Parsing strings in python

So my problem is this, I have a file that looks like this:
[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1
This would of course translate to
' This is an example file!'
I am looking for a way to parse the original content into the end content, so that a [BACKSPACE] will delete the last character(spaces included) and multiple backspaces will delete multiple characters. The [SHIFT] doesnt really matter as much to me. Thanks for all the help!
Here's one way, but it feels hackish. There's probably a better way.
def process_backspaces(input, token='[BACKSPACE]'):
"""Delete character before an occurence of "token" in a string."""
output = ''
for item in (input+' ').split(token):
output += item
output = output[:-1]
return output
def process_shifts(input, token='[SHIFT]'):
"""Replace characters after an occurence of "token" with their uppecase
equivalent. (Doesn't turn "1" into "!" or "2" into "#", however!)."""
output = ''
for item in (' '+input).split(token):
output += item[0].upper() + item[1:]
return output
test_string = '[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1'
print process_backspaces(process_shifts(test_string))
If you don't care about the shifts, just strip them, load
(defun apply-bspace ()
(interactive)
(let ((result (search-forward "[BACKSPACE]")))
(backward-delete-char 12)
(when result (apply-bspace))))
and hit M-x apply-bspace while viewing your file. It's Elisp, not python, but it fits your initial requirement of "something I can download for free to a PC".
Edit: Shift is trickier if you want to apply it to numbers too (so that [SHIFT]2 => #, [SHIFT]3 => #, etc). The naive way that works on letters is
(defun apply-shift ()
(interactive)
(let ((result (search-forward "[SHIFT]")))
(backward-delete-char 7)
(upcase-region (point) (+ 1 (point)))
(when result (apply-shift))))
This does exactly what you want:
def shift(s):
LOWER = '`1234567890-=[];\'\,./'
UPPER = '~!##$%^&*()_+{}:"|<>?'
if s.isalpha():
return s.upper()
else:
return UPPER[LOWER.index(s)]
def parse(input):
input = input.split("[BACKSPACE]")
answer = ''
i = 0
while i<len(input):
s = input[i]
if not s:
pass
elif i+1<len(input) and not input[i+1]:
s = s[:-1]
else:
answer += s
i += 1
continue
answer += s[:-1]
i += 1
return ''.join(shift(i[0])+i[1:] for i in answer.split("[SHIFT]") if i)
>>> print parse("[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1")
>>> This is an example file!
It seems that you could use a regular expression to search for (something)[BACKSPACE] and replace it with nothing...
re.sub('.?\[BACKSPACE\]', '', YourString.replace('[SHIFT]', ''))
Not sure what you meant by "multiple spaces delete multiple characters".
You need to read the input, extract the tokens, recognize them, and give a meaning to them.
This is how I would do it:
# -*- coding: utf-8 -*-
import re
upper_value = {
1: '!', 2:'"',
}
tokenizer = re.compile(r'(\[.*?\]|.)')
origin = "[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1"
result = ""
shift = False
for token in tokenizer.findall(origin):
if not token.startswith("["):
if(shift):
shift = False
try:
token = upper_value[int(token)]
except ValueError:
token = token.upper()
result = result + token
else:
if(token == "[SHIFT]"):
shift = True
elif(token == "[BACKSPACE]"):
result = result[0:-1]
It's not the fastest, neither the elegant solution, but I think it's a good start.
Hope it helps :-)

Categories