I need to create function that removes dash/underscore and combine the words. however if i use an empty string i get an error string index out of range
I believe whats causing this error is because of the line below. However this is impt in my code since it gets the first letter of my string.
# first_char = text[0]
import re
import string
def to_camel_case(text):
split_chars = []
ans = ''
small = ''
# store the first letter in variable
first_char = text[0]
# use split to separate the phrase given in text
for x in re.split('[-_]',text):
if text == None:
return
else:
ans += x.title()
# combine the vars
if ans[0] != first_char:
small += ans[0].lower()
return small + ans[1:]
else:
return ans
IndexError Traceback (most recent call last)
<ipython-input-64-f8cbc9c16e79> in <module>
----> 1 to_camel_case('')
<ipython-input-61-2bd3248e632d> in to_camel_case(text)
13
14 ## maintain the very first letter to its original form (lower or uppercase) and store it in a var
---> 15 first_char = text[0]
16
17
IndexError: string index out of range
You are trying to read a null value by text[0] as the string is empty. You can always check the input if it is null or have value. If value exist carry on with the operation otherwise return with a response.
Using text[0] needs that text has at least one character. So you must test if text is not empty before.
so this should work, your spacing wasn't good and as well, I've re-done the spacing and fixed your bug. The error was caused because text doesn't have any value when you want to get the first index. It's better to put as much as you can inside the body of the function.
import re
import string
def to_camel_case(text = 'Test'):
split_chars = []
ans = ''
small = ''
first_char = text[0]
# use split to separate the phrase given in text
for x in re.split('[-_]',text):
if text == None:
return
else:
ans += x.title()
# combine the vars
if ans[0] != first_char:
small += ans[0].lower()
return small + ans[1:]
else:
return ans
to_camel_case('StACKoverFLOW')
OUTPUT
Stackoverflow
Related
This question already has answers here:
Return middle part of string
(2 answers)
Closed 1 year ago.
Full problem:
Write a function named mid that takes a string as its parameter. Your function should extract and return the middle letter. If there is no middle letter, your function should return the empty string. For example, mid("abc") should return "b" and mid("aaaa") should return "".
Question:
How come at the very end print(x) and everything works as expected, but return x breaks the program with the following:
IndexError: list index out of range
import math
def mid(string):
enum = list(enumerate(string))
lastnum = enum[-1][0] + 1
if lastnum % 2 == 0:
return ""
else:
middle = math.floor(len(enum)/2)
x = enum[middle][1]
print(x)
return x
mid("asaba")
Here's an example of how I would approach it:
def mid(string):
if len(string) % 2 == 0:
return ""
else:
offset = int(len(string) / 2)
return string[offset: offset + 1]
mid("abc")
mid("asaba")
Your code fails on edge cases, specifically when given the empty string, but I found during my tests that it works for strings like "asaba", "aaaa", and "abc" but throws the error when given "". The reason for this is because lastnum = enum[-1][0] + 1 will give an index that does not exist for the empty string. The way to fix this would be to add a condition at the beginning of your function that checks if it's an empty string, so like this:
if len(string) == 0:
return ""
import math
def mid(string_1):
string_2 = ''
if len(string_1) %2 == 0:
return string_2
else:
string_2 = string_1[math.floor(len(string_1)/2)]
return string_2
print(mid("abc"))
I've done the function in this way and it works fine, the logic is the following:
If the length of the string is even return an empty string ""
If the length of the string is odd then returns the middle character, this is done by finding the index in the middle:
string_2 = string_1[math.floor(len(string_1)/2)]
Please bear with me, I am new to Python.
The first function I wrote was one to lowercase any uppercase characters in a string that passed through it, which works by itself, while ignoring any non-uppercase alphabetical ASCII characters.
However, when I try to use it in my second function, (which SHOULD use the lowercasing function on whatever the user inputs and then sticks it in a file) I'm left with a file that contains the the string that's initially passed through without any of the lowercasing function.
import os.path
from os import path
def lowercaser(text):
text = [ord(c) for c in text]
length = len(text)
i = 0
while length != i:
if 65 <= text[i] <= 90:
text[i] = text[i] + 32
i += 1
text = [chr(c) for c in text]
text = "".join(text)
def does_rfid_list_exist():
if path.exists("rfidList.txt"):
print("File found!")
else:
print("File was not located! Creating new file.\n")
f = open("rfidList.txt", "a+")
user_input = input("Please enter your name!\n")
lowercaser(user_input)
f.write(user_input)
f.close()
does_rfid_list_exist()
I have no idea why they don't work together, and I've broken it down as far as I can. Any ideas?
You seem to be expecting this call:
lowercaser(user_input)
to change the value of user_input. It won't do this. The reason is that string values are immutable, which means that every time you "change" a string, you create a new one. The original string object is not touched. So in this case, the variable user_input is pointing at a particular string when you call lowercaser. Once that function returns, user_input will still be pointing at the same string. Some other string will exist that will be the result of the processing the function did.
The way this usually works is that the lowercaser function will return the new string as the return value of the function, like this:
user_input = lowercaser(user_input)
This way, you are pointing user_input to a new string, the string that lowercaser produced for you. But to get this to work, you have to fix your lowercaser function to return its result. So you also have to add return text as the last line of your lowercaser function.
You need to first learn how to define a function.
You can learn it in w3school or any other source or book.
I am posting the solution here but it won't be productive for you.
Put
return text
in the last line of function. And put
user_input=lowercaser(user_input)
instead of
lowercaser(user_input)
the code looks not out of the ordinary , The only issue that I see is even though you are calling the function you are not updating the user_input
user_input = lowercaser(user_input)
Apart from this , return text from lower case function return text
import os.path
from os import path
def lowercaser(text):
text = [ord(c) for c in text]
length = len(text)
i = 0
while length != i:
if 65 <= text[i] <= 90:
text[i] = text[i] + 32
i += 1
text = [chr(c) for c in text]
text = "".join(text)
return text #### Change - 1
def does_rfid_list_exist():
if path.exists("rfidList.txt"):
print("File found!")
else:
print("File was not located! Creating new file.\n")
f = open("rfidList.txt", "a+")
user_input = input("Please enter your name!\n")
user_input = lowercaser(user_input) #### Change - 2
f.write(user_input)
f.close()
does_rfid_list_exist()
Using lower() on user_input
import os.path
from os import path
def lowercaser(text):
text = [ord(c) for c in text]
length = len(text)
i = 0
while length != i:
if 65 <= text[i] <= 90:
text[i] = text[i] + 32
i += 1
text = [chr(c) for c in text]
text = "".join(text)
return text #### Change - 1
def does_rfid_list_exist():
if path.exists("rfidList.txt"):
print("File found!")
else:
print("File was not located! Creating new file.\n")
f = open("rfidList.txt", "a+")
user_input = input("Please enter your name!\n")
user_input = user_input.lower() ### Change - 2
f.write(user_input)
f.close()
does_rfid_list_exist()
Bruv, there is not return statement, and even if there was the variable isn't stored anywhere. Meaning that text (a local variable that can only be accessed inside the function it originates from), is not accessible, passed on or stored in function does_rfid_list_exist(). Another problem is that user_input, which seems to be the data you are trying to manipulate, does not change after lowercaser() function because nothing is returned and the data isn't stored in anything. What I would do to fix is
To make it so that user_input
return text
after
text = "".join(text)
and replace
lowercaser(user_input)
with
user_input = lowercaser(user_input)
I think you got confused and thought that user_input is a public class of some sort.
I am trying to create a function in python that splits a string in to two strings, where the first one have all the lower case letters + some other special characters and the second one having all the upper case letters + special characters.
The point is to be able to type:
>>> first_message,second_message=string_split("SomEChaRacTers")
>>> print(first_message, second_message)
to get the result printed.
This is what i have right now:
def string_split(string):
first_message_signs = "_."
second_message_signs = " |"
one = ""
two = ""
if len(string) == 0:
return string
if string[0].islower() or string[0] in first_message_signs:
one += string[0] + string_split(string[1:])
return one
elif string[0].isupper() or string[0] in second_message_signs:
two += string[0] + string_split(string[1:])
return two
else:
return string_split(string[1:])
I am getting this error when making the first call in the prompt:
Traceback (most recent call last):
File "", line 1, in
ValueError: too many values to unpack (expected 2)
When i try with only message_one i get all the characters in one string.
What should i do?
Your first line
first_message,second_message=string_split("SomEChaRacTers")
expects string_split to return two values. However, your function only ever returns one.
What you want is
def string_split(string):
first_message_signs = "_."
second_message_signs = " |"
one = ""
two = ""
if len(string) == 0:
return one, two
if string[0].islower() or string[0] in first_message_signs:
one += string[0]
elif string[0].isupper() or string[0] in second_message_signs:
two += string[0]
ret1, ret2 = string_split(string[1:])
one += ret1
two += ret2
return one, two
On a side note, there's no compelling reason for string_split to be recursive. Try this:
def string_split(string):
first_message_signs = "_."
second_message_signs = " |"
one = ''.join(c for c in string if c.islower() or c in first_message_signs)
two = ''.join(c for c in string if c.isupper() or c in second_message_signs)
return one, two
when I run that code it comes out to me this error:
IndexError: string index out of range
I have no idea why I comes out to me this error and I don't have
any note but if you want to ask me about any thing don't hesitate
letters_string = "d g o"
letters_list = []
# Check Space
def convert_letters_to_list(word):
"""
This Function takes the letters from the users
and checks if users put more than one space
between letters if True It Removes The extra Spaces
"""
if word[0].isspace() == True:
convert_letters_to_list(word[1])
elif word[0].isalpha() == True:
letters_list.append((word[0])) + convert_letters_to_list(word[1:])
else:
convert_letters_to_list(word[1:])
convert_letters_to_list(letters_string)
print(letters_list)
You function is recursive so after a while, any letter index past 0 will be out of the original string.
Here is a fixed version of your code.
letters_string = "d g o"
letters_list = []
# Check Space
def convert_letters_to_list(word):
"""
This Function takes the letters from the users
and checks if users put more than one space
between letters if True It Removes The extra Spaces
"""
if word[0].isalpha() == True or (word[0].isspace() and not letters_list[-1].isspace()):
letters_list.append((word[0]))
if len(word) == 1:
return
convert_letters_to_list(word[1:])
convert_letters_to_list(letters_string)
print(letters_list)
I'm having trouble with creating a function that takes an argument of a string and returns just the numbers in type str. My code looks something like this.:
def check_if_number(number_string):
for ch in number_string:
if ch.isdigit():
num = number_string[ch]
return num
print(check_if_number('1655t'), end='')
It should print: 1655
You should add each char to a string if it is a digit :
def check_if_number(number_string):
digit_string = ""
for ch in number_string:
if ch.isdigit():
digit_string += ch
return digit_string
print(check_if_number('1655t'))
# 1655
Note that you can also use the re library :
import re
re.sub("\D", "", "1655t")
#1655
This code replace every non-digit character (matched by \D) by an empty string.
Have a look at this question to find more way to do it
You can do this :
def check_if_number(number_string):
num = ""
for ix in number_string :
if ix.isdigit():
num += ix
return int(num)
This function will return 1655, if the input is 1655t. You return from the function once you scan the complete string and append all ints to a string.
The easy way would be just using filter and concatenating the filtered letters in the end:
def check_if_number(number_string):
return ''.join(filter(str.isdigit, number_string))
Assuming all numbers are together (i.e. No letters exist between digits like "1e234g7"),
def check_if_number(number_string):
num = ''
for ch in number_string:
if ch.isdigit():
num += ch
return num
print(check_if_number('1655t'), end='')
This will return a string that only has digits in it. If you want to return a type int, then simply do return int(num).
If you want to take floats into account as well:
def check_if_number(number_string):
num = ''
for ch in number_string:
if ch == '.' or ch.isdigit():
num += ch
return num
print(check_if_number('1655t'), end='')
Similarly, this will return a string. If you want type float, simply do return float(num).
I tried not to deviate too much from what you already had... I hope this helps.
I'm uncertain what check_leap_year() function is so I just commented it out and called the function you gave us instead.
When you pass anything into a function in order to manipulate it and spit it back out different than it came in you should create a new variable for the changed data set.
In this case I used num = ""
By initiating an empty string inside of the function I can now add the data that pass my condition to that new, empty string.
isdigit() returns a boolean. So instead of using if x.isdigit: get in the habit of checking the boolean. Try if x.isdigit() is True instead.
Return your finished new string AFTER it is finished. Make sure your return statement is indented correctly or you are only going to return one number instead of all of them. The return should be outside of the loop so that it will only return once the loop is done.
num_string = "1a2s3d4f5g666hhh777jjj888kkk9l0"
def check_if_number(number_string):
num = ""
for ch in number_string:
if ch.isdigit() is True:
num += ch
return num
print(check_if_number(num_string))
Output:
>>> 1234566677788890