OLD MACDONALD: Write a function that capitalizes the first and fourth letters of a name
I'm trying to write this in different ways and I also feel like there's an easier way to do this. Cant, you directly apply it without getting all the other words of a string? Or a split or something?
Here is one of my attempts at trying it another way. I'm trying to do it with a for AND an if statement too. Any help is appreciated.
def old_macdonald(words):
wordletter = words[0]
fourthletter = words[3]
newword = []
for i,l in enumerate(words):
if i[0]:
newword = l.capatalize
return newword
if i[3]:
newword = l.capatalize
return newword
This is the most legible way IMO
def old_macdonald(name):
mylist = list(name)
mylist[0] = mylist[0].upper()
mylist[3] = mylist[3].upper()
return ''.join(mylist)
def old_macdonald(name):
letters = list(name)
for index in range(len(name)):
if index == 0:
letters[index] = letters[index].upper()
elif index == 3:
letters[index] = letters[index].upper()
return "".join(letters)
This one worked for me
this code will make first and forth element of the string Capital.
def cap(name):
first = name[0]
mid = name[1:3]
second = name[3]
rest = name[4:]
return first.upper() + mid + second.upper() + rest
cap('kahasdfn')
Here's one way. You do need to split the string into a list of characters to change individual characters, because strings are immutable, and then use join afterward to convert them back into a string.
def old_macdonald(name):
letters = list(name)
for letter_to_capitalize in [1, 4]:
if len(letters) >= letter_to_capitalize:
letters[letter_to_capitalize - 1] = letters[letter_to_capitalize - 1].upper()
return "".join(letters)
A pretty simple and modifiable example.
def old_mcdonald(word):
indexes = (0,3) #letters i want to cap
new_word = "".join([v.capitalize() if i in indexes else v for i,v in enumerate(word)])
return new_word
def old_macdonald(s):
return ''.join([s[:1].upper(), s[1:3], s[3:4].upper(), s[4:]])
# s[:1] - letter index 0 (first)
# s[1:3] - letters index 1-2
# s[3:4] - letter index 3 (fourth)
# s[4:] - letters index 4 onward
test_string = "abcdefghijklmnopqr"
print(old_macdonald(test_string )) # AbcDefghijklmnopqr
I like writing it this way:
def old_macdonald(word):
indices = (0, 4)
return ''.join(c.capitalize() if index in indices else c for index, c in enumerate(word))
Although it's a little long, so you might prefer writing it more clearly as:
def old_macdonald(word):
indices = (0, 4)
new_string = []
for index, c in enumerate(word):
new_string.append(c.capitalize() if index in indices else c)
return ''.join(new_string)
def old_macdonald(s):
w=""
for i in s:
t=s.index(i)
if t==0:
w=w+i.upper()
elif(t==3):
w=w+i.upper()
else:
w=w+i
print(w)
old_macdonald("aman")
def old_macdonald(s):
return s[0:3].capitalize() + s[3:].capitalize()
https://ideone.com/2D0qbZ
This one worked
def old_macdonald(name):
word = ''
for index,letter in enumerate(name):
if index == 0 or index == 3:
letter = name[index].capitalize()
word += letter
else:
word += letter
return word
Related
I have two input strings. In the first one - words with spaces. In the second - the word with same count of symbols without spaces. The task is to split the second string into array by spaces in the first one.
I tried to make it with cycles but there is problem of index out of range and i can't find another solution.
a = str(input())
b = str(input())
b_word = str()
b_array = list()
for i in range(len(a)):
if a[i] != " ":
b_word += b[i]
else:
b_array += b_word
b_word = str()
print(b_array)
Input:
>>head eat
>>aaabbbb
Output:
Traceback (most recent call last):
File "main.py", line 29, in <module>
b_word += b[i]
IndexError: string index out of range
Expected output:
>> ["aaab", "bbb"]
Thanks in advance!
Consider a solution based on iterator and itertools.islice method:
import itertools
def split_by_space(s1, s2):
chunks = s1.split()
it = iter(s2) # second string as iterator
return [''.join(itertools.islice(it, len(c))) for c in chunks]
print(split_by_space('head eat or', 'aaaabbbcc')) # ['aaaa', 'bbb', 'cc']
a = input() # you don't need to wrap these in str() since in python3 input always returns a string
b = input()
output = list()
for i in a.split(' '): # split input a by spaces
output.append(b[:len(i)]) # split input b
b = b[len(i):] # update b
print(output)
Output:
['aaab', 'bbb']
You can do something like this:
a = input()
b = input()
splitted_b = []
idx = 0
for word in a.split():
w_len = len(word)
splitted_b.append(b[idx:idx+w_len])
idx += w_len
print(splitted_b)
The idea is taking consecutive sub-strings from b of the length of each word on a.
Instead of using indices, you can iterate over each character of a. If the character is not a space, add the next character of b to your b_word. If it is a space, add b_word to the b_array
b_iter = iter(b) # Create an iterator from b so we can get the next character when needed
b_word = []
b_array = []
for char in a:
# If char is a space, and b_word isn't empty, append it to the result
if char == " " and b_word:
b_array.append("".join(b_word))
b_word = []
else:
b_word.append(next(b_iter)) # Append the next character from b to b_word
if b_word: # If anything left over in b_word, append it to the result
b_array.append("".join(b_word))
Which gives b_array = ['aaab', 'bbb']
Note that I changed b_word to a list that I .append to every time I add a character. This prevents the entire string from being recreated every time you append a character.
Then join all the characters using "".join(b_word) before appending it to b_array.
So to accomodate for any number of spaces in the input it gets a bit more complex as the indexes of the letters will change with each space that is added. So to gather all of the spaces in the string I created this loop which will account of the multiple spaces and alter the index with each new space in the initial word.
indexs = []
new = ''
for i in range(len(a)):
if len(indexs) > 0:
if a[i] == ' ':
indexs.append(i-len(indexs))
else:
if a[i] == ' ':
indexs.append(i)
Then we simple concatenate them together to create a new string that includes spaces at the predetermined indexes.
for i in range(len(b)):
if i in indexs:
print(i)
new += " "
new += b[i]
else:
new += b[i]
print(new)
Hope this helps.
Code
sone = input()
stwo = 'zzzzzxxxyyyyy'
nwz = []
wrd = ''
cnt = 0
idx = 0
spc = sone.split(' ') #split by whitespace
a = [len(i) for i in spc] #list word lengths w/out ws
for i in stwo:
if cnt == a[idx]: #if current iter eq. word length w/out ws
nwz.append(wrd) #append the word
wrd = '' #clear old word
wrd = wrd + i #start new word
idx = idx + 1
cnt = 0
else:
wrd = wrd + i #building word
cnt = cnt + 1
nwz.append(wrd) #append remaining word
print(nwz)
Result
>'split and match'
['zzzzz', 'xxx', 'yyyyy']
The input I gave is like this
Input- abccdddeffg
and the output I want is character and it's occurrence number
Output- a1b1c2d3e1f2g1
my code
uni = []
string = 'abcccdd'
for i in range(0, len(string)):
for j in range(i+1, len(string)):
if (string[i] == string[j]):
uni.append(string[i])
for oc in uni:
cou= uni.count(oc)
print(oc,cou)
Thanks in advance
You can use the Counter from collections to get the count of every character in the list. Then use a forloop to generate your result and use set to make sure no character is repeated in the result.
from collections import Counter
string = "abccdddeffg"
counts = Counter(string)
sets = set()
result = []
for s in string:
if s not in sets:
result.append(f"{s}{counts[s]}")
sets.add(s)
result = ''.join(result)
print(result)
Firstly, your output contains an error, there should be 1 next to e as it was there in first occurring characters.
After clearing this, this is what you need:
import collections
s = "abccdddeffg" # your string
a = dict((letter,s.count(letter)) for letter in set(s))
a = collections.OrderedDict(sorted(a.items()))
answer = "" # to store the result
for i,j in zip(a.keys(),a.values()):
answer+= i + str(j)
print(answer)
answer will return:
'a1b1c2d3e1f2g1'
Here is a simpler approach:
def freq_string(string):
output, buffer = "", ""
for letter in string:
if buffer != letter:
buffer = letter
output += f"{letter}{string.count(letter)}"
return output
Note: this does assume that same characters are in succession rather than spread randomly around the string.
Assuming your input string is sorted and has at least one letter, you can do a simple loop to handle it:
if len(string) == 1:
# print out the only string and 1 as its occurences
print(string + '1')
else:
# initialize first string, its counter, and our result string
prev = string[0]
counter = 1
result = ''
# loop over each letter
for letter in string[1:]:
curr = letter
# if current letter is different from previous letter,
# concat the result and refresh our counter
# else just increase the counter
if curr != prev:
result = result + prev + str(counter)
counter = 1
else:
counter = counter + 1
prev = curr
# don't forget to handle the last case
result = result + prev + str(counter)
print(result)
in the simplest way:
inp = 'abccdddeffg'
l=[]
o=""
for i in inp:
if i in l:
pass
else:
l.append(i)
o+="{}{}".format(i,inp.count(i))
print(o)
output
'a1b1c2d3e1f2g1'
My goal is to write a function which change every even letter into upper letter and odd to lower (space also count as a one element).
This is my code
def to_weird_case(s):
for i in s:
if len(i) % 2 == 0:
s[i] = i.upper() + s(i+1)
else:
s[i] = i.lower() + s(i+2)
return i
I think it should be quite correct, but it gives me error.
line 7, in to_weird_case
s[i] = i.lower() + s(str(i)+2)
TypeError: must be str, not int
EDIT:
I have a sugesstion but I don't know how to make it. I try it for myself and back here.
This needs to definitly explicietly state that the zero indexing uppercase is for each word.
Do you know guys how to make it?
So we can analyze your code and just explain what you typed:
def to_weird_case(s):
for i in s: # s is your string, and i is the actual character
if len(i) % 2 == 0: # if your length of the character can be divided by 2. Hmm this is weird
s[i] = i.upper() + s(i+1) # s[i] change a character in the string but you should provide an index (i) so an integer and not a character. But this is not supported in Python.
else:
s[i] = i.lower() + s(i+2)
return i # This will exit after first iteraction, so to_weird_case("this") will return "t".
So what you need to is first create a output string and fill that. And when iteration over s, you want the index of the char and the char value itself.
def to_weird_case(s):
output = ""
for i, myChar in enumerate(s):
if i % 2 == 0:
output += myChar.upper()
else:
output += myChar.lower()
return output
my_sentence = "abcdef"
print(to_weird_case(my_sentence))
And when you want to ignore spaces, you need to keep track of actual characters (excluding spaces)
def to_weird_case(s):
output = ""
count = 0
for myChar in s:
if myChar.isspace():
output += myChar
else:
if count % 2 == 0:
output += myChar.upper()
else:
output += myChar.lower()
count += 1
return output
my_sentence = "abc def"
print(to_weird_case(my_sentence))
Test this yourself
def to_weird_case(s):
for i in s:
print (i)
After doing this you will find that i gives you characters.
if len(i) % 2 == 0:
This line is incorrect as you are trying to find the length of a single character. len(s) would be much better.
So the code will be like
def to_weird_case(s):
s2 = "" #We create another string as strings are immutable in python
for i in range(len(s)):
if i % 2 == 0:
s2 = s2 + s[i].upper()
else:
s2 = s2 + s[i].lower()
return s2
From #RvdK analysis, you'ld have seen where corrections are needed. In addition to what has been pointed out, I want you to note that s[i] will work fine only if i is an integer, but in your case where (by assumption) i is a string you'll encounter several TypeErrors. From my understanding of what you want to do, it should go this way:
def to_weird_case(s):
for i in s:
if s.index(i) % 2 == 0:
s[s.index(i)] = i.upper() + s[s.index(i)]
elif s.index(i) % 2 == 1:
s[s.index(i)] = i.lower() + s[s.index(i)]
return i # or possibly return s
It is possible to do in a single line using a list comprehension
def funny_case(s):
return "".join([c.upper() if idx%2==0 else c.lower() for idx,c in enumerate(s)])
If you want to treat each word separately then you can split it up in to a list of words and "funny case" each word individually, see below code
original = "hello world"
def funny_case(s):
return "".join([c.upper() if idx%2==0 else c.lower() for idx,c in enumerate(s) ])
def funny_case_by_word(s):
return " ".join((funny_case(word) for word in s.split()))
print(funny_case_by_word(original))
Corrected code is as follows
def case(s):
txt=''
for i in range(len(s)):
if i%2==0:
txt+=s[i].upper()
else:
txt+=s[i].lower()
return txt
String assignment gives error in Python therefore i recommend considering my approach
When looping over elements of s, you get the letter itself, not its index. You can use enumerate to get both index and letter.
def to_weird_case(s):
result = ''
for index, letter in enumerate(s):
if index % 2 == 0:
result += letter.upper()
else:
result += letter.lower()
return result
correct code:
def to_weird_case(s):
str2 = ""
s.split() # through splitting string is converted to list as it is easy to traverse through list
for i in range(0,len(s)):
n = s[i] # storing value in n
if(i % 2 == 0):
str2 = str2 + n.upper()
else:
str2 = str2 + n.lower()
return str2
str1 = "hello world"
r = to_weird_case(str1)
print(r)
I am trying to create a function that takes a string as an argument and returns a list of all of the generated words by swapping a letter with its immediate neighbor.
I first take each letter and create a list of strings and each string contains one letter.
Then I iterate through the new list of letters and try to swap them.
Then I join the letters together to form a string.
Then I append the new string to the list that I return.
Here is my code. Please tell me how to fix it. I don't want it to display the passed word in the list. Thank you.
def mixedString(word):
word = word.lower()
letters = []
newArray = []
for n in word:
letter = f"{n}"
letters.append(letter)
newList = []
for i in range(len(letters)):
newWord = ""
newArray = letters[i:] + letters[:i]
newWord = "".join(newArray)
newList.append(newWord)
return newList
myWord = "Dog"
print(mixedString(myWord))
Hint: there are only n - 1 distinct words where one letter of the original word has been swapped. To see why, note that ab only has ba as result.
If a word has the letters are position i and i+1 swapped the letters before i are unchanged and the letters after i + 1 also are unchanged.
def swap(s, i):
return s[:i] + s[i+1] + s[i] + s[i+2:]
def neighbors(s):
return [swap(s, i) for i in range(len(s)-1)]
You can swap letters like this:
def swap(string, place_1, place_2):
string = list(string)
string[place_1], string[place_2] = string[place_2], string[place_1]
return ''.join(string)
a = '1234'
print(swap(a, 1, 2))
>>> 1324
There are many points of improvement, but I will be addressing the one you ask for
I don't want it to display the passed word in the list.
Just skip the first iteration in the relevant loop, e.g. by replacing this:
for i in range(len(letters)):
with this:
for i in range(1, len(letters)):
I tried this: Capitalize a string. Can anybody provide a simple script/snippet for guideline?
Python documentation has capitalize() function which makes first letter capital. I want something like make_nth_letter_cap(str, n).
Capitalize n-th character and lowercase the rest as capitalize() does:
def capitalize_nth(s, n):
return s[:n].lower() + s[n:].capitalize()
my_string[:n] + my_string[n].upper() + my_string[n + 1:]
Or a more efficient version that isn't a Schlemiel the Painter's algorithm:
''.join([my_string[:n], my_string[n].upper(), my_string[n + 1:]])
x = "string"
y = x[:3] + x[3].swapcase() + x[4:]
Output
strIng
Code
Keep in mind that swapcase will invert the case whether it is lower or upper.
I used this just to show an alternate way.
This is the comprehensive solution: either you input a single word, a single line sentence or a multi line sentence, the nth letter will be converted to Capital letter and you will get back the converted string as output:
You can use this code:
def nth_letter_uppercase(string,n):
listofwords = string.split()
sentence_upper = ''
for word in listofwords:
length = len(word)
if length > (n - 1):
new_word = word[:n-1] + word[n-1].upper() + word[n:]
else:
new_word = word
sentence_upper += ' ' + new_word
return sentence_upper
calling the function defined above (I want to convert 2nd letter of each word to a capital letter):
string = '''nature is beautiful
and i love python'''
nth_letter_uppercase(string,2)
output will be:
'nAture iS bEautiful aNd i lOve pYthon'
I know it's an old topic but this might be useful to someone in the future:
def myfunc(str, nth):
new_str = '' #empty string to hold new modified string
for i,l in enumerate(str): # enumerate returns both, index numbers and objects
if i % nth == 0: # if index number % nth == 0 (even number)
new_str += l.upper() # add an upper cased letter to the new_str
else: # if index number nth
new_str += l # add the other letters to new_str as they are
return new_str # returns the string new_str
A simplified answer would be:
def make_nth_letter_capital(word, n):
return word[:n].capitalize() + word[n:].capitalize()
You can use:
def capitalize_nth(text, pos):
before_nth = text[:pos]
n = text[pos].upper()
new_pos = pos+1
after_nth = text[new_pos:]
word = before_nth + n + after_nth
print(word)
capitalize_nth('McDonalds', 6)
The outcome is:
'McDonaLds'
I think this is the simplest among every answer up there...
def capitalize_n(string, n):
return string[:n] + string[n].capitalize() + string[n+1:]
This works perfect