Print odd index in same line - python

I'm trying to complete challenge on HackerRank ( Day 6 : Let's review!) and I only did to print the even numbers on the same line, but I can't print the odd indexes that would be needed to complete the challenge.
This is my code:
word_check = input()
for index, char in enumerate (word_check):
if (index % 2 == 0):
print( char ,end ="" )
This is the most specific task:
Given a string, S , of length N that is indexed from 0 to N -1 , print its even-indexed and odd-indexed characters as space-separated strings on a single line.
Thanks!!!
RavDev

You can use slice notation for indexing the original string:
word_check[::2] + " " + word_check[1::2]
[::2] means "start at the beginning and skip every second element until we reach the end" and [1::2] means "start at the second element and skip every second element until we reach the end". Leaving out either start or stop arguments of the slice implies beginning or end of the sequence respectively. Leaving out the step argument implies a step size of 1.

Slice notation is a better approach, but if you want to use for loop and stick to your approach, you can do in this way:
even =''
odd=''
for index, char in enumerate (word_check):
if (index % 2 == 0):
even += char
else: odd += char
print (even, odd)

I am currently trying to solve the same problem. To get your answers on the same line, initiate two strings: one for even and one for odd. If the character's index is even, add it to the even string and vice versa. Here is my working code so far:
def indexes(word,letter):
result = list()
for i,x in enumerate(word):
if x == letter:
result.append(i)
return result
T = int(input())
if T <= 10 and T>= 1:
for i in range(T):
evenstring = ""
oddstring = ""
lastchar = False
S = input()
if len(S) >= 2 and len(S) <= 10000:
for index, char in enumerate (S):
if (index % 2 == 0):
evenstring += char
else: oddstring += char
if len(indexes(S, char)) > 1:
evenstring.replace(evenstring[evenstring.rfind(char)], '')
oddstring.replace(oddstring[oddstring.rfind(char)], '')
print(evenstring, oddstring)
Your next problem now is trying to remove any reoccurrences of duplicate letters from your final answer (they show up in other test cases)

Related

Checks for a Path in a List of Strings Given a Starting and Ending Point

We are tasked to create a program that will check if there is a possible way of going from a starting string to an end string, given a list of strings with the same length. There is a catch, we can only go from the current string to the adjacent string if both strings only have one character that is different. If there is no possible path from the starting string to the end string, just print not possible but if there is, output the number of steps from the start to end.
Example:
li = ["booster", "rooster", "roaster", "coaster", "coasted"]
start = "roaster"
end = "booster"
Output: 3
li = ["booster", "rooster", "roaster", "coastal", "coasted"]
start = "roaster"
end = "coasted"
Output: none
I made an approach which manually checks if adjacent strings only have 1 character differences and returns the result based on these differences. Kinda slow if you ask me, given that the length of the list could be at most 100. Can you demonstrate a faster approach?
def checker(str1, str2, change = 0):
for index, character in enumerate(str1): # Traverses the whole
if character != str2[index]: # string and checks for
change+=1 # character differences
return True if change == 1 else False # Only 1 character is different
li = ["booster", "rooster", "roaster", "coaster", "coasted"]
m = len(li)
for j in range(m): li.append(input())
start, end = input().split()
if end in li: endI = li.index(end) # Gets end string index in the list
else:
print("not possible")
break
if start in li: startI = li.index(start) # Gets start string index in the list
else:
print("not possible")
break
if startI < endI: # If start string comes first before
# the end string, keep incrementing.
while li[startI] != end and startI < m-1:
if not checker(li[startI], li[startI+1]):
print("not possible")
break
startI += 1
print(abs(startI-(li.index(start)+1)))
else: # Otherwise, keep decrementing.
while li[startI] != end and startI > 0:
if not checker(li[startI], li[startI-1]):
print("not possible")
break
startI -= 1
print(abs(startI-(li.index(start)+1)))
If my approach is the fastest (which I highly doubt), I want to know if there are loopholes in my approach. Assume that the start and end strings can also be absent in the list given. Just print not possible if they are not in the list.
I hope that looks better:
import regex
def word_path(words, start, end):
if end in words and start in words:
endI = words.index(end)
startI = words.index(start)
else:
return "not possible"
step = 1 if startI <= endI else -1
for index in range(startI, endI, step):
if not regex.match("(%s){e<=1}" %li[index], li[index + step]):
return "not possible"
return abs(startI - endI) + 1
li = ["booster", "rooster", "roaster", "coastal", "coasted"]
start, end = input().split()
print(word_path(li, start, end))
It is supposed to be regex. Regex provides additional regular expression features, e.g. it makes it possible to check for a number of errors {e<=1}. The re- module doesn't provide these features. I guess that is the reason for the wrong result. You may need to install the regex-module with pip install regex first, but then it should work:
regex_module

How to uppercase even letter and lowercase odd letter in a string?

I am creating a function that takes in a string and returns a matching string where every even letter is uppercase and every odd letter is lowercase. The string only contains letters
I tried a for loop that loops through the length of the string with an if statement that checks if the index is even to return an upper letter of that index and if the index is odd to return a lowercase of that index.
def my_func(st):
for index in range(len(st)):
if index % 2 == 0:
return st.upper()
else:
return st.lower()
I expected to have even letters capitalize and odd letter lowercase but I only get uppercase for the whole string.
Some issues in your code:
Currently you are returning from the function on the first index itself, i.e index=0 when you do return st.lower(), so the function will stop executing after it encounters the first index and breaks out of the for loop
Doing st.lower() or st.upper() ends up uppercasing/lowercasing the whole string, instead you want to uppercase/lowercase individual characters
One approach will be to loop over the string, collect all modified characters in a list, convert that list to a string via str.join and then return the result at the end
You also want to refer to each individual characters via the index.
def my_func(st):
res = []
#Iterate over the character
for index in range(len(st)):
if index % 2 == 0:
#Refer to each character via index and append modified character to list
res.append(st[index].upper())
else:
res.append(st[index].lower())
#Join the list into a string and return
return ''.join(res)
You can also iterate over the indexes and character simultaneously using enumerate
def my_func(st):
res = []
#Iterate over the characters
for index, c in enumerate(st):
if index % 2 == 0:
#Refer to each character via index and append modified character to list
res.append(c.upper())
else:
res.append(c.lower())
#Join the list into a string and return
return ''.join(res)
print(my_func('helloworld'))
The output will be
HeLlOwOrLd
You can store your operations beforehand and use them in join with enumerate:
def my_func(st):
operations = (str.lower, str.upper)
return ''.join(operations[i%2](x) for i, x in enumerate(st))
print(my_func('austin'))
# aUsTiN
Tweaking your code a bit, You can use the 'enumerate' and keep appending to the string based on the condition evaluations( for me this was easier since I have been coding in java :))
def myfunc(st):
str=''
for index, l in enumerate(st):
if index % 2 == 0:
str+=l.upper()
else:
str+=l.lower()
return str
def myfunc(str):
rstr = ''
for i in range(len(str) ):
if i % 2 == 0 :
# str[i].upper()
rstr = rstr + str[i].upper()
else:
#str[i].lower()
rstr = rstr + str[i].lower()
return rstr
l = 'YourString'
li=[]
for index,i in enumerate(l):
if index % 2 == 0:
i=i.lower()
li.append(i)
elif index % 2 == 1:
i=i.upper()
li.append(i)
print(''.join(li))
Use this enumerate method to perform your operation
return will terminate your function, so there isn't much point of the loop
st is the whole string, so st.upper() will yield the whole string in upper case.
You can use a bitwise and (&) to check for odd positions. The enumerate function will give you both the positions and the characters so you can easily use it in a list comprehension:
def upLow(s):
return "".join(c.lower() if i&1 else c.upper() for i,c in enumerate(s))
upLow("HelloWorld") # HeLlOwOrLd
The below code should do what you are looking for.
def myfunc(name):
str=""
lc=1;
for character in name:
if(lc%2==0):
str+=character.upper()
else:
str+=character.lower()
lc+=1
return str
def myfunc(a):
newString = ''
for count, ele in enumerate(a, 0):
if count %2 == 0:
newString += (a[count].lower())
else:
newString += ((a[count].upper()))
return newString
You can deconstruct string into collection of characters, apply transformations and reconstruct string back from them
Logic:
First enumerate() over the string to generate key-value pairs of characters and their positions
Then use comprehensions to loop over them and use conditional statement to return odd position characters in lower() case and even position in upper()
Now you have the list ready. Just join() it with an empty string '' to convert the list into a string
Code:
str = 'testing'
''.join([y.upper() if x%2 ==0 else y.lower() for x,y in enumerate(str)])

Is there a problem with my string replacement code?

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"

How do I go about ending this loop?

I am trying to count the longest length of string in alphabetical order
s = 'abcv'
longest = 1
current = 1
for i in range (len(s) - 1):
if s[i] <= s[i+1]:
current += 1
else:
if current > longest:
longest = current
current = 0
i += 1
print longest
For this specific string, 'Current' ends up at the correct length, 4, but never modifies longest.
EDIT: The following code now runs into an error
s = 'abcv'
current = 1
biggest = 0
for i in range(len(s) - 1):
while s[i] <= s[i+1]:
current += 1
i += 1
if current > biggest:
biggest = current
current = 0
print biggest
It seems my logic is correct , but I run into errors for certain strings. :(
Although code sources are available on the internet which print the longest string, I can't seem to find how to print the longest length.
break will jump behind the loop (to sam indentation as the for statement. continue will jump to start of loop and do the next iteration
Your logic in the else: statement does not work - you need to indent it one less.
if s[i] <= s[i+1]:
checks for "is actual char less or equal then next char" - if this is the case you need to increment your internal counter and set longest if it is longer
You might get into trouble with if s[i] <= s[i+1]: - you are doing it till len(s)-1. "jfjfjf" is len("jfjfjf") = 6 - you would iterate from 0 to 5 - but the if accesses s[5] and s[6] which is more then there are items.
A different approach without going over explicit indexes and split into two responsibilities (get list of alphabetical substring, order them longest first):
# split string into list of substrings that internally are alphabetically ordered (<=)
def getAlphabeticalSplits(s):
result = []
temp = ""
for c in s: # just use all characters in s
# if temp is empty or the last char in it is less/euqal to current char
if temp == "" or temp[-1] <= c:
temp += c # append it to the temp substring
else:
result.append(temp) # else add it to the list of substrings
temp = "" # and clear tem
# done with all chars, return list of substrings
return result
# return the splitted list as copy after sorting reverse by length
def SortAlphSplits(sp, rev = True):
return sorted(sp, key=lambda x: len(x), reverse=rev)
splitter = getAlphabeticalSplits("akdsfabcdemfjklmnopqrjdhsgt")
print(splitter)
sortedSplitter = SortAlphSplits(splitter)
print (sortedSplitter)
print(len(sortedSplitter[0]))
Output:
['ak', 's', 'abcdem', 'jklmnopqr', 'dhs']
['jklmnopqr', 'abcdem', 'dhs', 'ak', 's']
9
This one returns the array of splits + sorts them by length descending. In a critical environment this costs more memory then yours as you only cache some numbers whereas the other approach fills lists and copies it into a sorted one.
To solve your codes index problem change your logic slightly:
Start at the second character and test if the one before is less that this. That way you will ever check this char with the one before
s = 'abcvabcdefga'
current = 0
biggest = 0
for i in range(1,len(s)): # compares the index[1] with [0] , 2 with 1 etc
if s[i] >= s[i-1]: # this char is bigger/equal last char
current += 1
biggest = max(current,biggest)
else:
current = 1
print biggest
You have to edit out the else statement. Because consider the case where the current just exceeds longest, i.e, from current = 3 and longest =3 , current becomes 4 by incrementing itself. Now here , you still want it to go inside the if current > longest statement
s = 'abcv'
longest = 1
current = 1
for i in range (len(s) - 1):
if s[i] <= s[i+1]:
current += 1
#else:
if current > longest:
longest = current
current = 0
i += 1
longest = current
print longest
Use a while condition loop, then you can easy define, at what condition your loop is done.
If you want QualityCode for longterm:
While loop is better practice than a break, because you see the Looping condition at one place. The simple break is often worse to recognize inbetween the loopbody.
At the end of the loop, current is the length of the last substring in ascending order. Assigning it to longest is not right as the last substring in ascending is not necessarily the longest.
So longest=max(current,longest) instead of longest=current after the loop, should solve it for you.
Edit: ^ was for before the edit. You just need to add longest=max(current,longest) after the for loop, for the same reason (the last ascending substring is not considered). Something like this:
s = 'abcv'
longest = 1
current = 1
for i in range (len(s) - 1):
if s[i] <= s[i+1]:
current += 1
else:
if current > longest:
longest = current
current = 0
i += 1
longest=max(current,longest) #extra
print longest
The loop ends when there is no code after the tab space so technically your loop has already ended

I need to count like characters in the same position in python, but I have no idea how to get it right, as i am new to the program

Write a Python script that asks the user to enter two DNA
sequences with the same length. If the two sequences have
different lengths then output "Invalid input, the length must
be the same!" If inputs are valid, then compute how many dna bases at the
same position are equal in these two sequences and output the
answer "x positions of these two sequences have the same
character". x is the actual number, depending on the user's
input.
Below is what I have so far.
g=input('Enter DNA Sequence: ')
h=input('Enter Second DNA Sequence: ')
i=0
count=0
if len(g)!=len(h):
print('Invalid')
else:
while i<=len(g):
if g[i]==h[i]:
count+=1
i+=1
print(count)
Do this in your while loop instead (choose better variable names in your actual code):
for i, j in zip(g, h):
if i == j:
count += 1
OR replace the loop entirely with
count = sum(1 for i, j in zip(g, h) if i == j)
This will fix your index error. In general, you shouldn't be indexing lists in python, but looping over them. If you really want to index them, the i <= len(g) was the problem... it should be changed to i < len(g).
If you wanted to be really tricky, you could use the fact that True == 1 and False == 0:
count = sum(int(i == j) for i, j in zip(g, h))
The issue here is your loop condition. Your code gives you an IndexError; this means that you tried to access a character of a string, but there is no character at that index. What it means here is that i is greater than the len(g) - 1.
Consider this code:
while i<=len(g):
print(i)
i+=1
For g = "abc", it prints
0
1
2
3
Those are four numbers, not three! Since you start from 0, you must omit the last number, 3. You can adjust your condition as such:
while i < len(g):
# do things
But in Python, you should avoid using while loops when a for-loop will do. Here, you can use a for-loop to iterate through a sequence, and zip to combine two sequences into one.
for i, j in zip(g, h):
# i is the character of g, and j is the character of h
if i != j:
count += 1
You'll notice that you avoid the possibility of index errors and don't have to type so many [i]s.
i<=len(g) - replace this with i<len(g), because index counting starts from 0, not 1. This is the error you are facing. But in addition, your code is not very pretty...
First way to simplify it, keeping your structure:
for i in range(len(g)):
if g[i]==h[i]:
count+=1
Even better, you can actually make it a one-liner:
sum(g[i]==h[i] for i in range(len(g)))
Here the fact that True is evaluated to 1 in Python is used.
g = raw_input('Enter DNA Sequence: ')
h = raw_input('Enter Second DNA Sequence: ')
c = 0
count = 0
if len(g) != len(h):
print('Invalid')
else:
for i in g:
if g[c] != h[c]:
print "string does not match at : " + str(c)
count = count + 1
c = c + 1
print(count)
if(len(g)==len(h)):
print sum([1 for a,b in zip(g,h) if a==b])
Edit: Fixed the unclosed parens. Thanks for the comments, will definitely look at the generator solution and learn a bit - thanks!

Categories