Pad a Python string to a specified length - python

A string is given in which there are no beginning and ending spaces. It is necessary to change it so that the length of the string becomes equal to the specified length, greater than the current length of the string. This should be done by inserting additional spaces between the words. The number of spaces between individual words should not differ by more than one space (that is, spaces are added evenly).
The string itself is entered by the user from the keyboard. The teacher said that I need to solve the problem using slices, but I don't understand exactly how. The problem is that it is not known in advance how long the entered string will be. And how many initial gaps there will be in it. At the same time, it is necessary that the length of the final line exactly matches the length that the user entered.
Here's what I've come up with so far. This code evenly adds spaces to the beginning and end of the entered line, if there were no spaces in it initially.
line_0 = input('Enter the required line:\n')
print('Current string length:\n', len(line_0), sep = '')
num_0 = len(line_0)
num_1 = int(input('Enter the total length of the string:\n'))
num_d = num_1 - num_0
s = line_0.count(' ')
line_1 = ''
if s == 0:
if (num_d % 2) != 0:
cup_1 = ' ' * (num_d // 2 + 1)
cup_2 = ' ' * (num_d // 2)
line_1 = cup_1 + line_0 + cup_2
else:
cup_1 = ' ' * (num_d // 2)
line_1 = cup_1 + line_0 + cup_1
print("'^' - the beginning and end of the line (not included in the
length of the final line).")
print('The resulting string is long ', len(line_1), ':\n', '^', line_1,
'^', sep = '')

First you need to figure how many spaces you will have to add.
In the same time, you'll split the initial string in a list of words.
Than, you calculate the minimum amount of spaces to add to each word, and the remaining that you'll add to the n first words.
Finally you add the spaces and maxe the words and spaces a str.
initial_sentence = "Lorem ipsum dolor sit amet"
spaces_to_add = int(input("Length needed : ")) - len(initial_sentence)
words = initial_sentence.split(" ")
number_words = len(words) - 1
min_spaces_added = spaces_to_add // number_words
spaces_remaining = spaces_to_add % number_words
final_string = ""
for word_ID in range(number_words) :
final_string = final_string + words[word_ID] + " "*(1+min_spaces_added) #the initial space after the word that has been removed by the .split() + the minimum required
if word_ID+1 <= spaces_remaining :
final_string += " "
final_string += words[-1]#the last word
print(final_string)

Related

How can I create a loop to add spaces between elements of a string in python?

I am looking for a way to add spaces between words in a string until len(string) < n is reached.
I've tried this:
string = "you are great"
n = 20
res = []
for i in string:
if ord(i) == 32 and len(string) < num:
res = [string + i]
And I want it to add spaces between "you" and "are", and "are" and "great.
So it gives me something like this:
res = ["you are great"]
But instead I get this
"you are great "
No need of loops:
string = "you are great"
n = 20
a = n - len(string.replace(' ', '')) # amount of spaces to add
b = string.split() # list of words (without spaces)
if a & 1:
b[0] += ' ' # if 'a' is odd, add an extra space to first word
d = (' ' * (a // 2)).join(b) # concatenate all words with 'a' spaces between them
print(d)
The output is:
"you are great"
You code is doing what it is suppose to do but as you can see in the second output it adds a space to your string. The code below is the issue.
Res = [string + i]

Python Count Characters

Write a program whose input is a string which contains a character and a phrase, and whose output indicates the number of times the character appears in the phrase. The output should include the input character and use the plural form, n's if the number of times the characters appears is not exactly 1.
Ex: If the input is:
n Monday
the output is:
1 n
Ex: If the input is:
z Today is Monday
the output is:
0 z's
Ex: If the input is:
n It's a sunny day
the output is:
2 n's
Case matters. n is different than N.
Ex: If the input is:
n Nobody
the output is:
0 n's
This is what I have so far:
user_string=input(str())
character=user_string[0]
phrase=user_string[1]
count=0
for i in phrase:
if i == character:
count = count+1
if count!= 1:
print(str(count) + " " + character + "'s")
else:
print(str(count) + " " + character)
This works great for the phrases that have 0 characters matching. But its not counting the ones that should match.
user_string=input(str())
character=user_string[0]
phrase=user_string[1:]
count=0
for i in phrase:
if i == character:
count = count+1
if count != 1:
print(str(count) + " " + character + "'s")
else:
print(str(count) + " " + character)
We will take the user's input, with the assumption that the first letter is the one that you are counting, and find that character with user_string.split()[0]. We will then take all the other words from the user's input (with user_string.split()[1:]), join them with ''.join and then explode them into a list of letters with [*]. We will return a list of "hits" for the character we are looking for. The length of that list will be the number of "hits".
user_string=input()
numOfLetters = [letter for letter in [*''.join(user_string.split()[1:])]
if user_string[0]==letter]
print(f'Number of {user_string[0]} is: {len(numOfLetters)}')
t This is a test # Input
Number of t is: 2 # Output
h Another test for comparison # Input
Number of h is: 1 # Output
Suggest just using str.count.
user_string = input()
character, phrase = user_string[0], user_string[1:]
count = phrase.count(character)
print(f"{count} {character}" + "'s" if count != 1 else '')
user_phrase=input()
letter=user_phrase[0]
if letter in user_phrase:
if user_phrase.count(letter)>2:
print (f'{user_phrase.count(letter)-1} {letter}\'s')
elif user_phrase.count(letter)==1:
print(f'0 {letter}\'s')
else:
print(f'{user_phrase.count(letter)-1} {letter}')
letter_and_phrase = str(input())
number_times_char_appears = 0
begin_letter = letter_and_phrase[0]
split_phrase = letter_and_phrase[1:].strip(' ')
for letter in split_phrase:
if letter in begin_letter:
number_times_char_appears += 1
if number_times_char_appears > 1:
print(f"{number_times_char_appears} {begin_letter}'s")
elif number_times_char_appears == 0:
print(f"{number_times_char_appears} {begin_letter}'s")
else:
print(f"{number_times_char_appears} {begin_letter}")

Python Message Cipher Indexation Error + WhiteSpace issue

I am working on an exercise to encode a message in Python. The following function is supposed to take in a message and a number to shift the letters in each word by that amount in the alphabet i.e. the letter a if moved 3 spaced would become d.
I have two issues:
The length of the alphabet is only 26 characters long. If you shift a letter too far right i.e. past the 26th position of Z you get the following error:
IndexError: string index out of range
I'd be happy with a fix that shifts the index back to the start again and moves the letter index based on the remainder of whatever goes past 26 characters i.e. if there is a shift of 9 with the char y then the remaining 9 after 26 could be positioned start from a again, making y the letter i.
If I were to input a message with spaces i.e. "I need help", the returned characters do not retain the original white space between each word.
Can anyone help with questions 1 or 2?
def message_to_code():
normal_message = input(str("Please enter a message you would like coded: "))
Cipher_shift = int(input("Please enter the whole number you would like to act as the key to hide your message "))
Alphabet = "abcdefghijklmnopqrstuvwxyz"
Cipher_message = ' '
for letter in normal_message:
Encrypted_letter = Alphabet.find(letter) + Cipher_shift
Cipher_message = Cipher_message + Alphabet[Encrypted_letter]
return print(Cipher_message)
message_to_code()
Your first problem can be easily fixed by checking if Alphabet.find(letter) + Cipher_shift >= len(Alphabet). If it is, than Encrypted_letter = Encrypted_letter - len(Alphabet).
Your second problem was tricky to completely understand, but I think the fix you are looking for is checking if letter is a space. If it is, loop to the next character, if it's not, do the logic with that character.
The bug fixes look like this:
def message_to_code():
normal_message = input(str("Please enter a message you would like coded: "))
Cipher_shift = int(input("Please enter the whole number you would like to act as the key to hide your message "))
Alphabet = "abcdefghijklmnopqrstuvwxyz"
Cipher_message = ' '
for letter in normal_message:
if letter != ' ':
Encrypted_letter = Alphabet.find(letter) + Cipher_shift
if Encrypted_letter >= len(Alphabet):
Encrypted_letter -= len(Alphabet)
Cipher_message = Cipher_message + Alphabet[Encrypted_letter]
else:
Cipher_message += ' '
I also fixed some other problems. For example, if you have a capital letter, your original code wouldn't catch that, since Alphabet is only filled with lower-case letters. To fix this, I added a second array dedicated to capital-letters, and check to see if letter is capital or not.
The second fix is checking if letter is a part of the alphabet or not. If it isn't, that would mean letter is: '/', '.', ',', ':', ';', etc. If it does happen to be one of these characters, it just adds its original self to the encrypted string.
The modified code looks like this:
def message_to_code():
normal_message = input(str("Please enter a message you would like coded: "))
Cipher_shift = int(input("Please enter the whole number you would like to act as the key to hide your message "))
Alphabet = "abcdefghijklmnopqrstuvwxyz"
AlphabetCaps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Cipher_message = ""
is_letter = True
for letter in normal_message:
if letter != ' ':
if Alphabet.find(letter) != -1:
Encrypted_letter = Alphabet.find(letter) + Cipher_shift
is_letter = True
elif AlphabetCaps.find(letter) != -1:
Encrypted_letter = AlphabetCaps.find(letter) + Cipher_shift
is_letter = True
else:
is_letter = False
if is_letter:
if Encrypted_letter >= len(Alphabet):
Encrypted_letter -= len(Alphabet)
if Alphabet.find(letter) != -1:
Cipher_message += Alphabet[Encrypted_letter]
else:
Cipher_message += AlphabetCaps[Encrypted_letter]
else:
Cipher_message += letter
else:
Cipher_message += ' '
return print(Cipher_message)

Counting specific punctuation symbols in a given text, without using regex or other modules

I have a text file with a huge text written in paragraphs.
I need to count certain punctuation symbols:
without using any module, not even regex
count , and ;
also needs to count ' and -, but only under certain circumstances. Specifically:
count ' marks, but only when they appear as apostrophes surrounded by letters, i.e. indicating a contraction such as "shouldn't" or "won't". (Apostrophe is being included as an indication of more informal writing, perhaps direct speech.)
count - signs, but only when they are surrounded by letters, indicating a compound-word, such as "self-esteem".
Any other punctuation or letters, e.g. digits, should be regarded as white space, so serve to end words.
Note: Some of the texts we will use include double hyphen, i.e. --. This is to be regarded as a space character.
I first created a string and stored some punctuations inside it for example punctuation_string = ";./'-" but it is giving me the total; what I need is count for individual punctuation.
Because of that I have to change certain_cha variable number of times.
with open("/Users/abhishekabhishek/downloads/l.txt") as f:
text_lis = f.read().split()
punctuation_count = {}
certain_cha = "/"
freq_coun = 0
for word in text_lis:
for char in word:
if char in certain_char:
freq_coun += 1
punctuation_count[certain_char] = freq_count
I need values to be displayed like this:
; 40
. 10
/ 5
' 16
etc.
but what I get is total (71).
You will need to create a dictionary where each entry stores the count of each of those punctuation characters.
For commas and semicolons, we can simply do a string search to count the number of occurences in a word. But we'll need to handle ' and - slightly differently.
This should take care of all the cases:
with open("/Users/abhishekabhishek/downloads/l.txt") as f:
text_words = f.read().split()
punctuation_count = {}
punctuation_count[','] = 0
punctuation_count[';'] = 0
punctuation_count["'"] = 0
punctuation_count['-'] = 0
def search_for_single_quotes(word):
single_quote = "'"
search_char_index = word.find(single_quote)
search_char_count = word.count(single_quote)
if search_char_index == -1 and search_char_count != 1:
return
index_before = search_char_index - 1
index_after = search_char_index + 1
# Check if the characters before and after the quote are alphabets,
# and the alphabet after the quote is the last character of the word.
# Will detect `won't`, `shouldn't`, but not `ab'cd`, `y'ess`
if index_before >= 0 and word[index_before].isalpha() and \
index_after == len(word) - 1 and word[index_after].isalpha():
punctuation_count[single_quote] += 1
def search_for_hyphens(word):
hyphen = "-"
search_char_index = word.find(hyphen)
if search_char_index == -1:
return
index_before = search_char_index - 1
index_after = search_char_index + 1
# Check if the character before and after hyphen is an alphabet.
# You can also change it check for characters as well as numbers
# depending on your use case.
if index_before >= 0 and word[index_before].isalpha() and \
index_after < len(word) and word[index_after].isalpha():
punctuation_count[hyphen] += 1
for word in text_words:
for search_char in [',', ';']:
search_char_count = word.count(search_char)
punctuation_count[search_char] += search_char_count
search_for_single_quotes(word)
search_for_hyphens(word)
print(punctuation_count)
following should work:
text = open("/Users/abhishekabhishek/downloads/l.txt").read()
text = text.replace("--", " ")
for symbol in "-'":
text = text.replace(symbol + " ", "")
text = text.replace(" " + symbol, "")
for symbol in ".,/'-":
print (symbol, text.count(symbol))
Because you don't want to import anything this will be slow and will take some time, but it should work:
file = open() # enter your file path as parameter
lines = file.readline() # enter the number of lines in your document as parameter
search_chars = [',', ';', "'", '-'] # store the values to be searched
search_values = {',':0, ';':0, "'":0, '-':0} # a dictionary saves the number of occurences
whitespaces = [' ', '--', '1', '2', ...] # you can add to this list whatever you need
for line in lines:
for search in search_chars:
if search in line and (search in search_chars):
chars = line.split()
for ch_index in chars:
if chars [ch_index] == ',':
search_values [','] += 1
elif chars [ch_index] == ';':
search_values [';'] += 1
elif chars[ch_index] == "'" and not(chars[ch_index-1] in whitespaces) and not(chars[ch_index+1] in whitespaces):
search_values ["'"] += 1
elif chars[ch_index] == "-" and not(chars[ch_index-1] in whitespaces) and not(chars[ch_index+1] in whitespaces):
search_values ["-"] += 1
for key in range(search_values.keys()):
print(str(key) + ': ' + search_values[key])
This is obviously not optimal and it is better to use regex here, but it should work.
Feel free to ask if any questions should arise.

Removing And Re-Inserting Spaces

What is the most efficient way to remove spaces from a text, and then after the neccessary function has been performed, re-insert the previously removed spacing?
Take this example below, here is a program for encoding a simple railfence cipher:
from string import ascii_lowercase
string = "Hello World Today"
string = string.replace(" ", "").lower()
print(string[::2] + string[1::2])
This outputs the following:
hlooltdyelwrdoa
This is because it must remove the spacing prior to encoding the text. However, if I now want to re-insert the spacing to make it:
hlool tdyel wrdoa
What is the most efficient way of doing this?
As mentioned by one of the other commenters, you need to record where the spaces came from then add them back in
from string import ascii_lowercase
string = "Hello World Today"
# Get list of spaces
spaces = [i for i,x in enumerate(string) if x == ' ']
string = string.replace(" ", "").lower()
# Set string with ciphered text
ciphered = (string[::2] + string[1::2])
# Reinsert spaces
for space in spaces:
ciphered = ciphered[:space] + ' ' + ciphered[space:]
print(ciphered)
You could use str.split to help you out. When you split on spaces, the lengths of the remaining segments will tell you where to split the processed string:
broken = string.split(' ')
sizes = list(map(len, broken))
You'll need the cumulative sum of the sizes:
from itertools import accumulate, chain
cs = accumulate(sizes)
Now you can reinstate the spaces:
processed = ''.join(broken).lower()
processed = processed[::2] + processed[1::2]
chunks = [processed[index:size] for index, size in zip(chain([0], cs), sizes)]
result = ' '.join(chunks)
This solution is not especially straightforward or efficient, but it does avoid explicit loops.
Using list and join operation,
random_string = "Hello World Today"
space_position = [pos for pos, char in enumerate(random_string) if char == ' ']
random_string = random_string.replace(" ", "").lower()
random_string = list(random_string[::2] + random_string[1::2])
for index in space_position:
random_string.insert(index, ' ')
random_string = ''.join(random_string)
print(random_string)
I think this might Help
string = "Hello World Today"
nonSpaceyString = string.replace(" ", "").lower()
randomString = nonSpaceyString[::2] + nonSpaceyString[1::2]
spaceSet = [i for i, x in enumerate(string) if x == " "]
for index in spaceSet:
randomString = randomString[:index] + " " + randomString[index:]
print(randomString)
string = "Hello World Today"
# getting index of ' '
index = [i for i in range(len(string)) if string[i]==' ']
# storing the non ' ' characters
data = [i for i in string.lower() if i!=' ']
# applying cipher code as mention in OP STATEMENT
result = data[::2]+data[1::2]
# inserting back the spaces in there position as they had in original string
for i in index:
result.insert(i, ' ')
# creating a string solution
solution = ''.join(result)
print(solution)
# output hlool tdyel wrdoa
You can make a new string with this small yet simple (kind of) code:
Note this doesn't use any libraries, which might make this slower, but less confusing.
def weird_string(string): # get input value
spaceless = ''.join([c for c in string if c != ' ']) # get spaceless version
skipped = spaceless[::2] + spaceless[1::2] # get new unique 'code'
result = list(skipped) # get list of one letter strings
for i in range(len(string)): # loop over strings
if string[i] == ' ': # if a space 'was' here
result.insert(i, ' ') # add the space back
# end for
s = ''.join(result) # join the results back
return s # return the result

Categories

Resources