found = False
position = 0
while not found and position < len(inputString):
if inputString[position].isdigit():
found = True
else:
position += 1
if found:
print('first digit is at position', position)
else:
print('There are no digits in the string')
This is a simple program I found that deals with finding the first digit in an inputted string. Something I am having trouble understanding is...
if inputString[position].isdigit():
found = True
What exactly does this expression state, specifically the inputString[position] part. Are we looking for the position/index value of the first digit and then breaking the loop into the print statement below?
Are we looking for the position/index value of the first digit and
then breaking the loop into the print statement below?
Yes, that's true. It breaks because once a digit is found, in the next iteration while not found condition will give while False and break the while loop. Worth noting and short-circuits, so the second condition is not even evaluated.
If a digit is not found, position increments until it is equal to len(inputString), at which point the while loop breaks via the second condition, i.e. position < len(inputString).
A more Pythonic / idiomiatic way to write your while loop is via for loop and enumerate:
for idx, val in enumerate(inputString, 1):
if val.isdigit():
position = idx
break
else:
position = 0
if position:
print('first digit is at position', position)
else:
print('There are no digits in the string')
Notice, in this solution, since we start counting from 1, we can take advantage of the fact if a digit is found it must be "Truthy", i.e. non-zero. Therefore, we don't need an extra found variable.
You are looking for the value of inputString at the position, position. position is first initialized as zero, and then it while loops each position (notice position += 1) to see if it .isdigit().
The position is your iteration variable like in a for loop. So every time you don't find a digit you go to the next char in the string.
The inputString[position] reads what stands the position's place in the string. So if your string is abcdefg then inputString[2]= c (not b since python starts counting from 0).
The .isdigit() then looks if at this position is a digit. If it is a digit, then found = True and the while loop is stopped. (Else it continues.)
After the loop ends, the function prints one of the two messages depending on if there was a digit in the inputString.
inputString[position] gives the character at position in inputString. For example, if inputString = "Foobar" and position = 3, inputString[position] = "b".
When we find a digit this way, then found turns True, and the evaluation condition of the while becomes False. The program leaves the loop and prints.
A string in python can be used as an sequence, which means you can use an index to access its elements. For example:
"Victor"[0] is V.
So in your example you are retrieving one of the elements (characters) of the string. The function isdigit() is a string method which can check if that character is a digit.
Gather all the indexes of possible digits, if the list is not empty print the 0 index, else if the list is empty print your no digits statement.
lst = [i for i, v in enumerate(s) if v.isdigit()]
if len(lst):
print(f'First digit is at postion {lst[0]}')
else:
print('There are no digits in the string.')
Related
Only lower case string as input.
Only words as input
Invalid if characters like "#","#"... are present
Find the length of the longest substring of given string so that the characters in it can be rearranged to form a palindrome.
Output the length
I am unable to put it in terms of programming in python.
please help.
My line of thinking was to keep an initial counter as 1(as even a word with completely different letters will have 1 by default)
then add 2 for every 1 match in letters
Sample input: "letter"
Sample output: 5 #(1(by default + 2(for 2"t"s) + 2(for 2"e"s))
You can use this code to figure out the length of the longest substring which can be rearranged to form a palindrome:
def longestSubstring(s: str):
# To keep track of the last
# index of each xor
n = len(s)
index = dict()
# Initialize answer with 0
answer = 0
mask = 0
index[mask] = -1
# Now iterate through each character
# of the string
for i in range(n):
# Convert the character from
# [a, z] to [0, 25]
temp = ord(s[i]) - 97
# Turn the temp-th bit on if
# character occurs odd number
# of times and turn off the temp-th
# bit off if the character occurs
# even number of times
mask ^= (1 << temp)
# If a mask is present in the index
# Therefore a palindrome is
# found from index[mask] to i
if mask in index.keys():
answer = max(answer,
i - index[mask])
# If x is not found then add its
# position in the index dict.
else:
index[mask] = i
# Check for the palindrome of
# odd length
for j in range(26):
# We cancel the occurrence
# of a character if it occurs
# odd number times
mask2 = mask ^ (1 << j)
if mask2 in index.keys():
answer = max(answer,
i - index[mask2])
return answer
This algorithm is basically O(N*26). XOR basically checks if the amount of a certain character is even or odd. For every character in your string there is a certain XOR sequence of every character up to that point which tells you which characters have appeared an odd number of time and which characters have appeared an even number of times. If the same sequence has already been encountered in the past then you know that you have found a palindrome, because you have become back to where you started in the XOR sequence aka there are an even number of every character which appears between this point and the start point. If there is an even number of every character which appear between two points in the string, then you can form a palindrome out of them. The odd length check is just a special case to check for palindromes which are of odd length. It works by just pretending sequentially if a character appears an odd number of times, that it just assumes it to occur an even number of times to handle the special case of the character in the middle of an odd length palindrome.
Edit: here is the link to the original code and explanation.
I want to count how many leading repeat characters at the beginning of a string. So far the code I wrote:
def count_characters(s, target):
counter = 0
for i in range(len(s)):
if s[i] == target:
counter += 1
else:
return counter
It works. Now I just curious if there is a simpler way to get it done in one or two lines instead of writing an extra function?
If you strip the characters from the beginning, then you are left with a shorter string and can subtract its length from the original, giving you the number of characters removed.
return len(s) - len(s.lstrip(target))
Note: Your shown code will immediately return 0 if the first character does not match target. If you want to check if there is any repeated first character, you don't need to have target and can just use s[0]
You could use next and a range:
return next(i+1 for i in range(len(s)) if s[i] != s[0], len(s))
Homework question is asking me to write a program that would output True if an integer is odd and has the number "0" in the middle of it. I figured out how to get it to print True if a number is odd but can't figure out how to detect if the number 0 is in the middle.
I've figured out the first condition which would be detecting if it's odd.
input:
def is_cyclops(n):
if len(str (n)) % 2 != 0:
return True
return False
print (is_cyclops(11011))
output:
True
I want to know how to get the code to detect the number 0 in the middle.
I'll provide a response in the form of an algorithm:
Convert the number to a string
Detect whether the string has an even or odd number of characters (because even numbered strings don't have a single "middle" character)
Look at the middle character which is character # (len(str)/2)-0.5
That's your middle character
This code will work for an input n.
n = str(n)
if(len(n)%2==0): #Checks if even
if(n[len(n)/2]==0): #Checks for presence of 0
return True
else:
if(n[len(n+1)/2]==0): #Checks for presence of 0
return True
string = input()
for i in range(len(string)):
if i % 3 == 0:
final = string.replace(string[i], "")
print(final)
I was asked the question: "Given a string, delete all its characters whose indices are divisible by 3."
The answer for the input Python is yton. However, my code gives Pyton.
The code makes sense to me but I'm a beginner. Any help?
The problem is that while you are looping, you are overriding the final variable every time the index is divisible by 3.
Instead, try defining the final variable before you start the loop, and add the letters as you loop over them, and only when they their index is NOT divisible by 3 (thus, ignoring the ones where the index IS divisible by 3).
Something like this should work:
string = input()
final = ""
for i in range(len(string)):
if i % 3 != 0:
final += string[i]
print(final)
In your current code, final is used through each iteration of the loop. It continues updating by replacing one character. In each iteration, final is replaced by a different string with one letter from string removed. After the loop has completed, it effectively only replaced one letter, which in this case is "h".
Use this instead (thanks to Mateen Ulhaq for the idea):
print("".join(x for i, x in enumerate(input()) if i % 3 != 0))
string=input()
final=""
for i in range(len(string)):
if i % 3 != 0:
final+=string[i]
print(final)
In your code, the line final = string.replace(string[i], "") would run like this.
Supposing the input is "hellobaby":
i=0, final="ellobaby"
i=3, final="helobaby"
i=6, final="hellobby"
Here is a function I wrote that will take a very long text file. Such as a text file containing an entire textbook. It will find any repeating substrings and output the largest string. Right now it doesn't work however, it just outputs the string I put in
For example, if there was a typo in which an entire sentence was repeated. It would output that sentence; given it is the largest in the whole file. If there was a typo where an entire paragraph was typed twice, it would output the paragraph.
This algorithm takes the first character, finds any matches, and if it does and if the length is the largest, store the substring. Then it takes the first 2 characters and repeats. Then the first 3 characters. etc.. Then it will start over except starting at the 2nd character instead of the 1st. Then all the way through and back, starting at the 3rd character.
def largest_substring(string):
length = 0
x,y=0,0
for y in range(len(string)): #start at string[0, ]
for x in range(len(string)): #start at string[ ,0]
substring = string[y:x] #substring is [0,0] first, then [0,1], then [0.2]... then [1,1] then [1,2] then [1,3]... then [2,2] then [2,3]... etc.
if substring in string: #if substring found and length is longest so far, save the substring and proceed.
if len(substring) > length:
match = substring
length = len(substring)
I think your logic is flawed here because it will always return the entire string as it checks whether a substring is in whole string which is always true so the statement if substring in string will be always true. Instead you need to find if the substring occurs more than once in the entire string and then update the count.
Here is example of brute force algorithm that solves it :-
import re
def largest_substring(string):
length = 0
x=0
y=0
for y in range(len(string)):
for x in range(len(string)):
substring = string[y:x]
if len(list(re.finditer(substring,string))) > 1 and len(substring) > length:
match = substring
length = len(substring)
return match
print largest_substring("this is repeated is repeated is repeated")