String handling in Python - python

I am trying to write a short python function to break a long one_line string into a multi_line string by inserting \n. the code works fine when i simply insert \n into the string but i get an index out of range error when i insert a conditional check to add hyphenation as well. Here is the code that i have written.
Sentence = "Python string comparison is performed using the characters in both strings. The characters in both strings are compared one by one. When different characters are found then their Unicode value is compared. The character with lower Unicode value is considered to be smaller."
for i in range(1, int(len(Sentence)/40)+1):
x = i*40
Sentence = Sentence[:x] + "\n" if Sentence[x] == " " else "-\n" + Sentence[x:]
print(Sentence)
Here is the error message i get.
Traceback (most recent call last):
File "/media/u1/data/prop.py", line 4, in <module>
Sentence = Sentence[:x] + "\n" if Sentence[x] == " " else "-\n" + Sentence[x:]
IndexError: string index out of range

The conditional expression is greedy, parsed as if you had written
Sentence = Sentence[:x] + \
("\n" if Sentence[x] == " " else "-\n" + Sentence[x:])
As a result, you are doing one of two operations:
Sentence[:x] + '\n' if you find a space
Sentence[:x] + "-\n" + Sentence[x:] if you find a different character.
Note that case 1 shortens your sentence incorrectly, but your range object is based on the original correct list.
The solution is to use parentheses to define the conditional expression correctly:
for i in range(1, int(len(Sentence)/40)+1):
x = i*40
c = Sentence[x]
Sentence = Sentence[:x] + (f"\n" if c == " " else f"{c}-\n") + Sentence[x+1:]
# ^ ^

Well the issue might not be obvious in the start but when you start looking at the if statement in the middle of string concatenation, you will understand. For a minute just focus on the following line:
Sentence = Sentence[:x] + "\n" if Sentence[x] == " " else "-\n" + Sentence[x:]
Python would parse this statement like so:
Sentence = (Sentence[:x] + "\n") if Sentence[x] == " " else ("-\n" + Sentence[x:])
Notice the brackets carefully. This is exactly the reason why the length of the string held by the variable Sentence is decreasing after each iteration which triggers the IndexError exception. Hence, in order to address this issue, we will have to explicitly tell Python what we are expecting. So, it could be written as such:
Sentence = Sentence[:x] + ("\n" if Sentence[x] == " " else "-\n") + Sentence[x:]

string = "Python string comparison is performed using the characters in both strings. The characters in both strings are compared one by one. When different characters are found then their Unicode value is compared. The character with lower Unicode value is considered to be smaller."
stc = ""
for j in range(1 + len(string) // 40):
stc += string[j * 40:40 * (j + 1)] + "\n"
print(stc)

Related

what is the purpose of return_string = " " in the code below. Additionally what is happening in line 4 when " " is added to str(x)

def even_numbers(maximum):
return_string = " "
for x in range(2, maximum+1, 2):
return_string += str(x) + " "
return return_string.strip()
Hi i recently started learning how to code and i dont understand equating empty quotation marks and in some codes adding empty quotation marks to strings like in line 4
It's not empty, it's a space.
Let's say you add the following words:
"hello" "friend"
Without the spaces it would become "hellofriend".
With the spaces it would be "hello friend".

When writing the Caeser Cipher exercise, the input Secret Message should be outputted as Vhfuhw Phvvdjh but it is outputting as VhfuhwqPhvvdjh instead

My current code is looking like this:
message = input("Message to be encrypted: ")
shift = int(input("Number to shift by: "))
def encrypt(message,shift):
encryption = ""
for i in range(len(message)):
char = message[i]
if (char.isupper()):
encryption += chr((ord(char) + shift-65) % 26 + 65)
else:
encryption += chr((ord(char) + shift - 97) % 26 + 97)
return encryption
print("Encrypted Text:",encrypt(message,shift))
And I am not too sure on my whitespace character is coming out as q instead of a normal " " in a string. This is my first few weeks of coding so I apologize if I have overlooked a simple mistake.
To get the expected result, you should add this conditional before the others:
if char == " ":
encryption += " "
continue
You are not getting the desired output because when you got a space in the input string and passes to the char variable, the space is not a upper letter so your code goes right in the else statement. Although it works for letters it won't work for other special characters. So, as described in the title of your question, if you wish to maintain the space between the words, you simply add the space in your encrypted sentence.
However, my first suggestion will work only for the spaces. If you wish to mantain other special characters (i.e. %, $, #, *, etc) you should use:
if char.isalnum() == False:
encryption += char
continue

How can i not count the spaces between my string

So I have, p.e, this string: ' I love python ' and I want to convert all the spaces to '_'. My problem is that I also need to delete the outside spaces so I dont finish with the result: '_I_love_python__' and more like this 'I_love_python'
I searched and found out that I can develop it with a single line of code mystring.strip().replace(" ", "_") which is unfortunaly is sintax that I cant apply in my essay.
So what I landed with was this:
frase= str(input('Introduza: '))
aux=''
for car in frase:
if car==' ':
car='_'
aux+=car
else:
aux+=car
print(aux)
My problem now is on deleting those outside spaces. What I thought about was runing another for i in in the start and another on the final of the string and to stop until they found a non space caracter. But unfortunaly I havent been able to do that...
Apreciate all the help you can suply!
I came up with following solution:
You iterate over the string, but instead of replacing the space with underscore as soon as it appears, you store the amount of spaces encountered. Then, once a non-space-character is reached, you add the amount of spaces found to the string. So if the string ends with lots of spaces, it will never reach a non-space-character and therefore never add the underscores.
For cutting off the spaces at the beginning, I just added a condition to add the underscores being: "Have I encountered a non-space-character before?"
Here is the code:
text = " I love python e "
out = ""
string_started = False
underscores_to_add = 0
for c in text:
if c == " ":
underscores_to_add += 1
else:
if string_started:
out += "_" * underscores_to_add
underscores_to_add = 0
string_started = True
out += c
print(out) # prints "I_love___python____e"
You can use the following trick to remove leading and trailing spaces in your string:
s = ' I love python '
ind1 = min(len(s) if c == ' ' else n for n, c in enumerate(s))
ind2 = max(0 if c == ' ' else n for n, c in enumerate(s))
s = ''.join('_' if c == ' ' else c for c in s[ind1:ind2 + 1])
print('*', s, '*', sep='')
Output:
*I_love_python*
If you are not allowed to use strip() method
def find(text):
for i, s in enumerate(text):
if s != " ":
break
return i
text = " I love python e "
text[find(text):len(text)-find(text[::-1])].replace(" ","_")
texts = [" I love python e ","I love python e"," I love python e","I love python e ", "I love python e"]
for text in texts:
print (text[find(text):len(text)-find(text[::-1])].replace(" ","_"))
output:
I_love___python____e
I_love___python____e
I_love___python____e
I_love___python____e
I_love___python____e
Given a string find will find the first non space character in the string
Use find to find the first nonspace character and the last nonspace character
Get the substring using above found indices
Replace all spaces with _ in the above substring

string index out of range, appears in random lines

I tried to make a small program that generates text like this:
M E T A
E E
T T
A A
My code:
line = 0
word = raw_input("")
for i in word:
print i,
print
for i in range(len(word)):
line += 1
print word[line] + " " * (line*2-1) + word[line]
It seems to technically work, but results in
Traceback (most recent call last): File "python", line 11, in IndexError: string index out of range
which can appear in different lines depending on input length. Also, if I input nothing, it will act as if I input RUN instead, but only sometimes. What's the reason behind this weird behaviour? I'm running it within Codeacademy's python lesson, if that makes any difference.
The logical doesn't work either, you need the following:
word = raw_input("Insert a word: ").upper()
print(" ".join(word))
for i in range(1, len(word)):
print(word[i] + " " * (i*2-1) + word[i])
If you already iterating over word chars your line var is useless. It will be enough to do just this:
for i in range(len(word)):
print word[i] + " " * (i*2-1) + word[i]
Or even something like this:
for i, ch in enumerate(word[1:]):
print ch + " " * ((i+1)*2-1) + ch
enumerate here is built-in function to iterate over some collection(word is collection here) and enumerate(index) each element. So on each iteration emumerate returns index of the element i and element itself ch.
word[1:] is operator for taking subset elements from the collection. It means that we will take all values begining from value with index 1.
String indexes go from 0 to len(string)-1. Your variable line has value len(word) in the last iteration, so the expression becomes word[len(word)], which overshoots the index by 1 and results in an "IndexError: string index out of range".

Python: count word lenth in site name

Got stuck with a part of the python script. For example I got 2 domain names like:
domain.com
new.domain1.us
is it possible to count word lenght of every word, splited with dot and put the lenght in brackets before every word like:
(6)domain(3)com
(3)new(7)domain1(2)us
string = 'domain.com'
answer = ''
for x in string.split('.'):
answer += '(' + str(len(x)) + ')' + x
print(answer)
The method split() will split the string at the given char into an array of strings.
len() will return you the length of the given string/array/...
With these two functions you can solve your problem:
domain = "www.google.de"
split_domain = domain.split('.')
domain_with_len = ""
for part in split_domain:
domain_with_len += "(" + str(len(part)) + ")" + part
if you print the domain_with_len you get the following result:
(3)www(6)google(2)de

Categories