Python print with integer string mix and group matching problem - python

import re
import string
line = "F1,F2,F3,F6,R1,R3,R341,C1,C10,C2,FL1,FL5"
line_no_digits= re.findall("\D",line)#produce line with refernces F,F,F,F,R,R,R,C,C,C,FL,FL
line_no_digits_string= ''.join(map(str,line_no_digits))
#############################################################
res = line_no_digits_string.split(",")
alpha_char_unique=[]
for i in res: #get unique reference prefix
if i not in alpha_char_unique:
alpha_char_unique.append(i)
#############################################################
line2 = line.split(",")
preLine = ""
result = ""
for j in alpha_char_unique:
p = re.compile(j)
preLine = [s for s in line2 if p.match(s)]
numbers_only = [int(re.search('\d+', l).group(0)) for l in preLine if re.search('\d+', l) is not None]#pull numbers for matches or prefix, not working correctly
numbers_only.sort()#sort the numbers to work in code below
#print(numbers_only)
c = 0#counter
result = ""#output result
current = None
run = False
x = len(numbers_only)
while c < x:#number sorter
if current == None:
result += f'{numbers_only[c]}'
elif numbers_only[c] - current == 1:
run = True
if c == len(numbers_only) - 1:
result += f'-{numbers_only[c]}'
elif run:
result += f'-{current},{numbers_only[c]}'
run = False
else:
result += f',{numbers_only[c]}'
current = numbers_only[c]
c += 1
print(result)
The result is
1,1-3,5-6
1,3,341
1-2,10
1,5
I would like it to be
F1-F3,F6
R1,R3,R341
C1-C2,C10
FL1,FL5
matching may not be the best for this. I am looking for suggestions on how to make sure that F1-F3 and FL1,FL5 are not grouped together. I am open to suggestions.

This does it.
import re
import string
from collections import OrderedDict
line = "F1,F2,F3,F6,R1,R3,R341,C1,C10,C2,FL1,FL5"
result = []
def add_result(result,last_letters,starting_num,latest_num):
if last_letters is None:
return
if latest_num > starting_num:
result.append('%s%d-%s%d' % (last_letters,starting_num,last_letters,latest_num))
else:
result.append('%s%d' % (last_letters,starting_num))
letter_map = OrderedDict()
for letters,number in re.findall('([A-Z]+)(\\d+)',line):
number = int(number)
if not letters in letter_map:
letter_map[letters] = []
letter_map[letters].append(number)
last_letters = starting_num = latest_num = None
for letters,numbers in letter_map.items():
for number in sorted(numbers):
if last_letters is None:
last_letters = letters
starting_num = latest_num = number
elif letters == last_letters:
if number == latest_num + 1:
latest_num = number
else:
add_result(result,last_letters,starting_num,latest_num)
starting_num = latest_num = number
else:
add_result(result,last_letters,starting_num,latest_num)
last_letters = letters
starting_num = latest_num = number
add_result(result,last_letters,starting_num,latest_num)
final_result = ','.join(result)
print(final_result) #F1-F3,F6,R1,R3,R341,C1-C2,C10,FL1,FL5
Edit:
For your modified version from your comment, I think you have a couple of typos: "R1,2" should be "R1.2" and "F2.," should be "F2,". Let me know if those are not typos. Assuming they are, the minimal update to get it working is to accept more than just letters as the prefix, but also allow trailing numbers if they end with a dot. Also allow an underscore. The only thing that needs to change is the regular expression in the re.findall line.
import re
import string
from collections import OrderedDict
line = "F1.1,F1.2,F1.3.F2,F3,F6,R1.1,R1.2,R1.3,R2,R3,R341,C1,C10,C2,FL_1,FL_5"
result = []
def add_result(result,last_letters,starting_num,latest_num):
if last_letters is None:
return
if latest_num > starting_num:
result.append('%s%d-%s%d' % (last_letters,starting_num,last_letters,latest_num))
else:
result.append('%s%d' % (last_letters,starting_num))
letter_map = OrderedDict()
for letters,number in re.findall('([A-Z]+_{0,1}(?:[0-9]+\\.){0,1})(\\d+)',line):
number = int(number)
if not letters in letter_map:
letter_map[letters] = []
letter_map[letters].append(number)
last_letters = starting_num = latest_num = None
for letters,numbers in letter_map.items():
for number in sorted(numbers):
if last_letters is None:
last_letters = letters
starting_num = latest_num = number
elif letters == last_letters:
if number == latest_num + 1:
latest_num = number
else:
add_result(result,last_letters,starting_num,latest_num)
starting_num = latest_num = number
else:
add_result(result,last_letters,starting_num,latest_num)
last_letters = letters
starting_num = latest_num = number
add_result(result,last_letters,starting_num,latest_num)
final_result = ','.join(result)
print(final_result) #F1.1-F1.3,F2-F3,F6,R1.1-R1.3,R2-R3,R341,C1-C2,C10,FL_1,FL_5```

Related

finding the longest common prefix of elements inside a list

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'm getting IndexError: list index out of range when I know the index is within range

I'm getting the IndexError on line 50 (the sixth line of checkForDisallowedCharacters while j < len(resultSet[i]):)
I get this error when I input '***er', 't', and 'canpilru' into the console when prompted
Using my print statements I've found that this error occurs when the resultSet array has a length of 141, and when i is 0
resultSet[0] is 'paper' and it clearly exists
If anyone can explain why this is throwing an error I would be very grateful
import csv
import os
import sys
def buildDictionary():
dictionary = []
with open("./wordle-helper/wordle-dictionary.csv", newline='') as csvfile:
spamreader = csv.reader(csvfile, delimiter='\t')
for row in spamreader:
dictionary.append(row)
for i in range(len(dictionary)):
dictionary[i] = dictionary[i][0].lower()
return dictionary
def buildTestWordComposition(testWord):
testWordComposition = []
for i in range(len(testWord)):
if testWord[i] == "*":
testWordComposition.append(i)
return testWordComposition
def buildThreshold(testWord):
threshold = 0
for character in testWord:
if character != "*":
threshold += 1
return threshold
def checkForSoftMatches(dictionary, testWord, threshold):
resultSet = []
for word in dictionary:
testThreshold = 0
for i in range(5):
if testWord[i] == "*":
continue
elif testWord[i] == word[i]:
testThreshold += 1
if testThreshold == threshold:
resultSet.append(word)
return resultSet
def checkForDisallowedCharacters(resultSet, disallowedCharacters):
i = 0
while i < len(resultSet):
print(len(resultSet), i, resultSet[i][0])
j = 0
while j < len(resultSet[i]):
for character in disallowedCharacters:
if resultSet[i][j] == character:
try:
resultSet.remove(resultSet[i])
finally:
i -= 1
j = -1
break
j += 1
i += 1
if i < 0:
i = 0
elif i >= len(resultSet):
break
return resultSet
def checkForRequiredCharacters(resultSetNoDisallowedCharacters, requiredCharacters, testWordComposition):
resultSetChecked = []
threshold = len(requiredCharacters)
m = 0
resultSetCheckedLength = 0
while m < len(resultSetNoDisallowedCharacters):
compareToThreshold = 0
for aCharacter in requiredCharacters:
for number in testWordComposition:
if resultSetNoDisallowedCharacters[m][number] == aCharacter:
compareToThreshold += 1
break
if len(resultSetChecked) != resultSetCheckedLength:
break
if compareToThreshold == threshold:
resultSetChecked.append(resultSetNoDisallowedCharacters[m])
resultSetCheckedLength = len(resultSetChecked)
m += 1
return resultSetChecked
def wordleHelper(testWord, requiredCharacters=[], disallowedCharacters=[]):
dictionary = buildDictionary()
testWordComposition = buildTestWordComposition(testWord)
threshold = buildThreshold(testWord)
resultSet = checkForSoftMatches(dictionary, testWord, threshold)
resultSetNoDisallowedCharacters = checkForDisallowedCharacters(resultSet, disallowedCharacters)
resultSetChecked = checkForRequiredCharacters(resultSetNoDisallowedCharacters, requiredCharacters, testWordComposition)
if not resultSetChecked:
return resultSetNoDisallowedCharacters
return resultSetChecked
def printWordleHelper(testWord, requiredCharacters=[], disallowedCharacters=[]):
print("All possible words are listed below\n\n-----------------------------------------------\n")
for word in wordleHelper(testWord, requiredCharacters, disallowedCharacters):
print(word)
def handlePersistentCharacters(disallowedCharactersComplete):
willDisallowedCharactersPersist = input("Would you like to continue using your previous list of grey letters? (y/n): ")
if willDisallowedCharactersPersist == "y":
return disallowedCharactersComplete
elif willDisallowedCharactersPersist == "n":
return []
else:
print("Please enter a valid character")
handlePersistentCharacters(disallowedCharactersComplete)
def clearConsole():
if sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
os.system('clear')
elif sys.platform.startswith('win'):
os.system('cls')
def buildParsed(unparsed):
parsed = []
for letter in unparsed:
parsed.append(letter)
return parsed
def handleUserContinue(disallowedCharactersComplete):
willUserContinue = input("Would you like to use World Helper (tm) again? (y/n): ")
if willUserContinue == "n":
sys.exit()
persistentDisallowedCharacters = handlePersistentCharacters(disallowedCharactersComplete)
if willUserContinue == "y":
promptUser(persistentDisallowedCharacters)
def promptUser(persistentDisallowedCharacters=[]):
clearConsole()
testWord = input("Please enter your Wordle guess in the form of *la*t where 'l', 'a', and 't' are the green letters from your guess, and the '*'s are yellow or grey letters from your guess: ")
requiredCharacters = input("Please enter your letters in yellow here in the form of 'abcxyz' (do not enter letters which are already in your Wordle guess string): ")
disallowedCharacters = input("Please enter your letters in grey here (in the form of 'abcxyz'): ")
requiredCharactersParsed = buildParsed(requiredCharacters)
disallowedCharactersParsed = buildParsed(disallowedCharacters)
disallowedCharactersComplete = persistentDisallowedCharacters + disallowedCharactersParsed
printWordleHelper(testWord, requiredCharactersParsed, disallowedCharactersComplete)
handleUserContinue(disallowedCharactersComplete)
promptUser()

How to replace an old value in a string with a new one?

So the problem states that if the given word in a sentence begins and ends with the same character I remove that character and keep on doing that until they are not the same anymore or their length is less than 3.
Example: aabaa -> aba -> b
And that is not the problem, so now I should replace the word 'aabaa' with 'b' in original string.
The only problem i have is when the sentence is given without spaces. For example:
Trust,is,all. -> rus,is,all.
Also to note characters such as (. , ! ? ; :) are to be ignored but have to be there in the final output.
So far I've wrote this but it doesn't satisfy the example above:
s1 = str(input())
sentence = s1.split()
news = []
ignorabelCharacters = ['.',',','!','?',';',':']
helpList = []
for i in range(len(s1)):
if s1[i] in ignorabelCharacters:
helpList.append([s1[i],i])
for i in sentence:
i = str(i)
j = 0
while j < len(i):
if i[j] in ignorabelCharacters:
i = i.replace(i[j],' ').strip()
j+=1
else:j+=1
news.append(i)
s2 =' '.join(news)
newSentence = s2.split()
def checkAgain(newSentence):
newNewSentance = []
count = []
x=0
for i in newSentence:
j = len(i)
while j > 2:
if i[0].lower() == i[-1] or i[0].upper() == i[-1]:
i = i[1:-1]
j-=2
x+=2
else:
break
count.append(x)
newNewSentance.append(i)
x=0
return [newNewSentance,count]
newNewSentence = checkAgain(newSentence)[0]
count = checkAgain(newSentence)[1]
def finalProcessing(newNewSentence,sentence,newSentence):
finalSentence = []
for i in range(len(sentence)):
if len(newNewSentence[i]) == len(sentence[i]):
finalSentence.append(newNewSentence[i])
else:
x = len(sentence[i]) - len(newSentence[i])
if x ==0:
finalSentence.append(newNewSentence[i])
else:
value = newNewSentence[i] + sentence[i][-x:]
finalSentence.append(value)
return finalSentence
finalSentence = finalProcessing(newNewSentence,sentence,newSentence)
def finalPrint(finalSentece):
for i in range(len(finalSentece)):
if i == len(finalSentece) -1:
print(finalSentece[i],end='')
else:
print(finalSentece[i],end= ' ')
finalPrint(finalSentence)
This approach is different from yours but here is how I would do it.
def condenseWord(w):
ln = len(w)
while ln >= 3:
if w[0].lower() == w[-1].lower():
w = w[1:-1]
ln = len(w)
else:
break
return w
def collapseString(s):
sep_chars = {' ', ',', '.', ';', ':', '!', '"', "'"}
out = r''
wdstrt = 0
lstltr = 0
for i in range(len(s)):
if s[i] in sep_chars:
ck = condenseWord(s[wdstrt:i])
out += ck
out += s[i]
wdstrt = i+1
lstltr = i+1
else:
lstltr = i
out += s[wdstrt:lstltr]
return out
Then
collapseString('aabaa') -> 'b', and
collapseString('Trust,is,all.' ) -> 'rus,is,all.'

write a program in python which does not contain any repeating character from input string . example: A is repeated of a

input is: This is An Example
Output: This An Exmpl
li = input("Enter your Sting")
res = ''
for ch in li:
if ch not in res :
res = res + ch
print(res, end=' ')
li = input("Enter your string")
res = ''
for ch in li.lower():
if ch not in res:
res = res + ch
print(res.title(), end='')
I am sure there will be a more elegant way to do this but for now here is a working version which you could refactor or reduce if needed
user_input = input("sentance: ")
seen = set()
filtered_words = []
for word in user_input.split():
filtered_word = ""
for char in word:
if char.lower() in seen:
continue
filtered_word += char
seen.add(char.lower())
if filtered_word != "":
filtered_words.append(filtered_word)
print(*filtered_words)

Why does Python 3 for loop output and behave differently?

This is a password generator, I couldn't really determine where the problem is, but from the output, I could say it's around turnFromAlphabet()
The function turnFromAlphabet() converts an alphabetical character to its integer value.
The random module, I think doesn't do anything here as it just decides whether to convert a character in a string to uppercase or lowercase. And if a string is in either, when sent or passed to turnFromAlphabet() it is converted to lowercase first to avoid errors but there are still errors.
CODE:
import random
import re
#variables
username = "oogisjab" #i defined it already for question purposes
index = 0
upperOrLower = []
finalRes = []
index2a = 0
#make decisions
for x in range(len(username)):
decision = random.randint(0,1)
if(decision is 0):
upperOrLower.append(True)
else:
upperOrLower.append(False)
#Apply decisions
for i in range(len(username)):
if(upperOrLower[index]):
finalRes.append(username[index].lower())
else:
finalRes.append(username[index].upper())
index+=1
s = ""
#lowkey final
s = s.join(finalRes)
#reset index to 0
index = 0
def enc(that):
if(that is "a"):
return "#"
elif(that is "A"):
return "4"
elif(that is "O"):
return "0" #zero
elif(that is " "):
# reduce oof hackedt
decision2 = random.randint(0,1)
if(decision2 is 0):
return "!"
else:
return "_"
elif(that is "E"):
return "3"
else:
return that
secondVal = []
for y in range(len(s)):
secondVal.append(enc(s[index]))
index += 1
def turnFromAlphabet(that, index2a):
alp = "abcdefghijklmnopqrstuvwxyz"
alp2 = list(alp)
for x in alp2:
if(str(that.lower()) == str(x)):
return index2a+1
break
else:
index2a += 1
else:
return "Error: Input is not in the alphabet"
#real final
finalOutput = "".join(secondVal)
#calculate some numbers and chars from a substring
amount = len(finalOutput) - round(len(finalOutput)/3)
getSubstr = finalOutput[-(amount):]
index = 0
allFactors = {
};
#loop from substring
for x in range(len(getSubstr)):
hrhe = re.sub(r'\d', 'a', ''.join(e for e in getSubstr[index] if e.isalnum())).replace(" ", "a").lower()
print(hrhe)
#print(str(turnFromAlphabet("a", 0)) + "demo")
alpInt = turnFromAlphabet(hrhe, 0)
print(alpInt)
#get factors
oneDimensionFactors = []
for p in range(2,alpInt):
# if mod 0
if(alpInt % p) is 0:
oneDimensionFactors.append(p)
else:
oneDimensionFactors.append(1)
indexP = 0
for z in oneDimensionFactors:
allFactors.setdefault("index{0}".format(index), {})["keyNumber"+str(p)] = z
index+=1
print(allFactors)
I think that you are getting the message "Error: input is not in the alphabet" because your enc() change some of your characters. But the characters they becomes (for example '#', '4' or '!') are not in your alp variable defined in turnFromAlphabet(). I don't know how you want to fix that. It's up to you.
But I have to say to your code is difficult to understand which may explain why it can be difficult for you to debug or why others may be reluctant to help you. I tried to make sense of your code by removing code that don't have any impact. But even in the end I'm not sure I understood what you tried to do. Here's what I understood of your code:
import random
import re
#username = "oogi esjabjbb"
username = "oogisjab" #i defined it already for question purposes
def transform_case(character):
character_cases = ('upper', 'lower')
character_to_return = character.upper() if random.choice(character_cases) == 'upper' else character.lower()
return character_to_return
username_character_cases_modified = "".join(transform_case(current_character) for current_character in username)
def encode(character_to_encode):
translation_table = {
'a' : '#',
'A' : '4',
'O' : '0',
'E' : '3',
}
character_translated = translation_table.get(character_to_encode, None)
if character_translated is None:
character_translated = character_to_encode
if character_translated == ' ':
character_translated = '!' if random.choice((True, False)) else '_'
return character_translated
final_output = "".join(encode(current_character) for current_character in username_character_cases_modified)
amount = round(len(final_output) / 3)
part_of_final_output = final_output[amount:]
all_factors = {}
for (index, current_character) in enumerate(part_of_final_output):
hrhe = current_character
if not hrhe.isalnum():
continue
hrhe = re.sub(r'\d', 'a', hrhe)
hrhe = hrhe.lower()
print(hrhe)
def find_in_alphabet(character, offset):
alphabet = "abcdefghijklmnopqrstuvwxyz"
place_found = alphabet.find(character)
if place_found == -1 or not character:
raise ValueError("Input is not in the alphabet")
else:
place_to_return = place_found + offset + 1
return place_to_return
place_in_alphabet = find_in_alphabet(hrhe, 0)
print(place_in_alphabet)
def provide_factors(factors_of):
for x in range(1, int(place_in_alphabet ** 0.5) + 1):
(quotient, remainder) = divmod(factors_of, x)
if remainder == 0:
for current_quotient in (quotient, x):
yield current_quotient
unique_factors = set(provide_factors(place_in_alphabet))
factors = sorted(unique_factors)
all_factors.setdefault(f'index{index}', dict())[f'keyNumber{place_in_alphabet}'] = factors
print(all_factors)
Is near what your wanted to do?

Categories

Resources