Inserting "-" in string after elements of variable lengths - python

Is there a way to convert the string "12345678aaaa12345678bbbbbbbb" to "12345678-aaaa-1234-5678-bbbbbbbb" in python?
I am not sure on how to do it, since I need to insert "-" after elements of variable lengths say after 8th element then 4th element and so on.

This function inserts a char at a postion for a string:
def insert(char,position,string):
return string[:position] + char + string[position:]

Python strings cannot be mutated. What we can do is create another string with the hyphen inserted in between, as per your wish.
Consider the string s = "12345678aaaa12345678bbbbbbbb"
Giving s[:8] + '-' + s[8:] will give you 12345678-aaaa12345678bbbbbbbb
You can give the hyphen as you wish by adjusting the : values.
For more methods to add the hyphen, refer to this question thread for answer as to how to insert hypForhen.
Add string in a certain position in Python

You can follow this process :
def insert_(str, idx):
strlist = list(str)
strlist.insert(idx, '-')
return ''.join(strlist)
str = '12345678aaaa12345678bbbbbbbb'
indexes = [8, 4, 4, 4]
resStr = ""
idx = 0
for val in indexes:
idx += val
resStr = insert_(str,idx)
str = resStr
idx += 1
print(str)
output :
12345678-aaaa-1234-5678-bbbbbbbb

This doesn't exactly create the string you want but posting it anyway.
It finds all the indexes where digit becomes alpha and vice versa.
Then it inserts "-" at these indexes.
a = "12345678aaaa12345678bbbbbbbb"
lst = list(a)
index = []
for ind,i in enumerate(list(a)[:-1]):
if (i.isdigit() and lst[ind+1].isalpha()) or (i.isalpha() and lst[ind+1].isdigit()):
index.append(ind)
for i in index[::-1]:
lst.insert(i+1,"-")
''.join(lst)
'12345678-aaaa-12345678-bbbbbbbb'

Simplest solution:
str = '12345678aaaa12345678bbbbbbbb'
indexes = [8, 4, 4, 4]
i = -1
for index in indexes:
i = i + index + 1
str = str[:i] + '-' + str[i:]
print str
Prints: 12345678-aaaa-1234-5678-bbbbbbbb
You are free to change indexes array to achieve what you want.

If your want do this in one time , you can like this.
str = "12345678aaaa12345678bbbbbbbb"
def insert(char,positions,string):
result = ""
for post in range(0, len(positions)):
print(positions[post])
if post == 0:
result += string[:positions[post]] + char
elif post == (len(positions) -1 ):
result += string[positions[post-1]:positions[post]] + char + string[positions[post]:]
else:
result += string[positions[post-1]:positions[post]] + char
print(result)
return result
insert("-", [8, 12, 16, 20], str)

Related

How can I create a new list when giving intergers, and have to return hexadecimal

Given the following list:
list = [2,10,10,10,4,5]
How can I write a function that returns the output:
output = 210AA:45
I was working with this code so far, but don't know what else to add so that once a number between 10 and 15 is repeated, return the repeated number in its hexadecimal form as in the output
def int_to_string(data):
string = ""
for i in data:
hexadecimal = hex(i)
string += hexadecimal[2:]
string[0] = 15
return string
Use a list [] instead of a string ""
strings are immutable and don't support index lookup and assignment.
append the hex val and then edit the first index as you see fit to get your result
and retun a joined list with
''.join(#ur_lst)
A dictionary describing the mapping between decimal and hex could add readability.
Remark: don't shadow the name of build-functions, in this case list. See doc for a complete list.
lst = [2,10,10,10,4,5,13,15,0] # <- new testing list
# dictionary for conversion
num2hex = {i: str(i) for i in range(10)}
num2hex.update(zip(range(10, 16), "ABCDEF"))
# conversion list -> str
res = ''
consecutve_hex, is_last_hex = 0, False
for d in lst:
if 10 <= d <= 15:
consecutive_hex += 1
is_last_hex = False
if consecutive_hex > 1:
res += num2hex[d]
else:
res += str(d)
else:
if not is_last_hex:
if res:
res += ':'
consecutive_hex = 0
is_last_hex = True
res += str(d)
print(res)
#210AA:4513F:0

Creating string based on first letters of each element of the list

Example:
list = [abcc, typpaw, gfssdwww]
expected result = atgbyfcpscpsadwwww
Any ideas?
This is what i made so far:
def lazy_scribe(sources: list):
result: str = ''
i = 0
while i < len(max(sources, key=len)):
for source in sources:
for char in source:
if i <= len(source):
result = result + source[int(i)]
else:
continue
i += 1 / (len(sources))
break
return result
sources = ["python", "java", "golang"]
print(lazy_scribe(sources))
print(len(sources))
result: "pjgyaoyvlhaaononngn". I dont know why there is "y" instead of t (7 char in result string)
If I understand the problem correctly, this should work.
list = ["abcc", "typpaw", "gfssdwww"]
max_len = len(max(list, key=len))
res = ""
char_iterator = 0
while char_iterator < max_len:
for word in list:
if char_iterator < len(word):
res += word[char_iterator]
char_iterator += 1
print(res)
Another possible solution is as follows:
l = ['abcc', 'typpaw', 'gfssdwww']
max_len = len(max(l, key=len))
padded_l = list(zip(*[e + " " * (max_len - len(e)) for e in l]))
''.join([''.join(e) for e in padded_l]).replace(' ', '')
find the longest string in the list
then pad all the strings in the list with blank space
use zip on the result list
join the elements and replace the blank space to get the desired result

Replace all occurrences of the substring in string using string slicing

I want to replace all substring occurrences in a string, but I wish not to use the replace method. At the moment, experiments have led me to this:
def count_substrings_and_replace(string, substring, rpl=None):
string_size = len(string)
substring_size = len(substring)
count = 0
_o = string
for i in range(0, string_size - substring_size + 1):
if string[i:i + substring_size] == substring:
if rpl:
print(_o[:i] + rpl + _o[i + substring_size:])
count += 1
return count, _o
count_substrings_and_replace("aaabaaa", "aaa", "ddd")
but I have output like this:
dddbaaa
aaabddd
not dddbddd.
Update 1:
I figured out that I can only replace correctly with a string of the same length of substring. For example for count_substrings_and_replace("aaabaaa", "aaa", "d") I got output: (2, 'dbaad') not dbd
Update 2:
Issue described in update 1 did appear because of string comparing relative to the original string (line 8) that does not change throughout the process.
Fixed:
def count_substrings_and_replace(string, substring, rpl=None):
string_size = len(string)
substring_size = len(substring)
count = 0
_o = string
for i in range(0, string_size - substring_size + 1):
if _o[i:i + substring_size] == substring:
if rpl:
_o = _o[:i] + rpl + _o[i + substring_size:]
count += 1
return count, _o
count_substrings_and_replace("aaabaaa", "aaa", "d")
Output: (2, dbd)
You never update the value of _o when a match is found, you're only printing out what it'd look like if it was to be replaced. Instead, inside that innermost if statement should be two lines like:
_o = _o[:i] + rpl + _o[i + substring_size:]
print(_o)
That would print the string every time a match is found and replaced, moving the print statement to run after the for loop would make it only run once the entire string was parsed and replaced appropriately.
Just my mistake. I had to pass the value to the variable on each iteration not print:
_o = _o[:i] + rpl + _o[i + substring_size:]

Is there any way to convert the string back to previous one?

The Question Description:
You write all your passwords in a diary so that you don't forget them. But clearly, this is too risky, so you came up with a simple plan, you will simply write it by shifting all the alphabets by a certain step. For eg: if you decide your step to be 3, then 'a' will become 'd', and 'k' will become 'n' and so for all alphabets. The last alphabets will simply circle back to 'a'. In this case, 'y' will become 'b' and so on. Now you just have to remember the step size, can then you can check the password anytime you want.
Input:
A list of two elements.
The first element will be a string consisting of only alphabets that are taken from the diary and the second element will be the step size.
Output:
A string denoting the password
Sample input: ['ytLvei', 4]
Sample output: upHrae
Explanation:
The password was 'upHrae'. Upon changing it by step of 4,
u became y,
p became t,
H became L,
r became v,
a became e,
e became i,
and thus what was written in the diary was ytKveh
Sample input: ['banana', 7]
Sample output: utgtgt
To get the above output I have written the code is given below.
import at
n = ast.literal_eval(input())
n1 = n[0]
step = n[1]
def enc_dec(string,step):
result = ''
for i in string:
temp = ''
if i=='':
result = result+i
elif i.isupper():
temp = chr((ord(i) - step - 65) % 26 + 65)
else:
temp = chr((ord(i) - step - 97) % 26 + 97)
result = result + temp
return result
print(enc_dec(n1,step))
My sample test cases i.e.
Sample input1: ['banana', 7]
Sample output2: utgtgt
Sample input2: ['ytLvei', 4]
Sample output2: upHrae
Both the above sample inputs are passing but when I try to convert the 'upHare' to 'ytLvei' I am getting another output i.e. 'qlCnwz'.
Can anyone tell me why this is happening?
This is because you are changing it up by step of 4. You need to change it down by 4. Your code doesn't work either-- you can't add and subtract ints by strs in python!
Here is a new code that should work:
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
def convert_str(string, step):
converted = ""
for char in string:
if char != "Z":
converted += letters[letters.index(char) + step]
else:
converted += letters[step-1]
return converted
in_str = input("string: ")
print(convert_str(in_str, 4))
This will make upHare to ytLevi.
To convert down, use negative numbers:
print(convert_str(in_str, -4))
The cipher as described rotates the alphabet in one direction to encode, and another to decode; they aren't interchangeable operations. If you aren't allowed to specify a negative step when testing your input, then define different functions for encoding/decoding:
def encode(message: str, step: int) -> str:
return enc_dec(message, step)
def decode(message: str, step: int) -> str:
return enc_dec(message, -step)
Now you can do:
>>> print(decode('upHrae', 4))
ytLvei
This should work even when the cases are different lower or higher
import ast
n = ast.literal_eval(input())
string = n[0]
step = n[1]
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
l1='abcdefghijklmnopqrstuvwxyz'
l2='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
converted = ""
def convert_str(string, step):
converted = ""
for char in string:
if char.islower():
converted += l1[l1.index(char) + step]
elif char.isupper():
converted += l2[l2.index(char) + step]
elif char != "Z":
converted += letters[letters.index(char) + step]
print(converted)
else:
converted += letters[step-1]
return converted
print(convert_str(string, -step))

How to get the index of duplicates in a string [duplicate]

I am trying to find all the occurences of "|" in a string.
def findSectionOffsets(text):
startingPos = 0
endPos = len(text)
for position in text.find("|",startingPos, endPos):
print position
endPos = position
But I get an error:
for position in text.find("|",startingPos, endPos):
TypeError: 'int' object is not iterable
The function:
def findOccurrences(s, ch):
return [i for i, letter in enumerate(s) if letter == ch]
findOccurrences(yourString, '|')
will return a list of the indices of yourString in which the | occur.
if you want index of all occurrences of | character in a string you can do this
import re
str = "aaaaaa|bbbbbb|ccccc|dddd"
indexes = [x.start() for x in re.finditer('\|', str)]
print(indexes) # <-- [6, 13, 19]
also you can do
indexes = [x for x, v in enumerate(str) if v == '|']
print(indexes) # <-- [6, 13, 19]
It is easier to use regular expressions here;
import re
def findSectionOffsets(text):
for m in re.finditer('\|', text):
print m.start(0)
import re
def findSectionOffsets(text)
for i,m in enumerate(re.finditer('\|',text)) :
print i, m.start(), m.end()
text.find returns an integer (the index at which the desired string is found), so you can run for loop over it.
I suggest:
def findSectionOffsets(text):
indexes = []
startposition = 0
while True:
i = text.find("|", startposition)
if i == -1: break
indexes.append(i)
startposition = i + 1
return indexes
If text is the string that you want to count how many "|" it contains, the following line of code returns the count:
len(text.split("|"))-1
Note: This will also work for searching sub-strings.
text.find() only returns the first result, and then you need to set the new starting position based on that. So like this:
def findSectionOffsets(text):
startingPos = 0
position = text.find("|", startingPos):
while position > -1:
print position
startingPos = position + 1
position = text.find("|", startingPos)

Categories