message = str(input())
for i in message:
if i == " ":
print(" ")
else:
# ord(i) returns the ASCII number for i
# To get the actual alphabetical position of i, you have to do ASCII of letter - ASCII of A + 1.
print(ord(i)-ord("a")+1)
This program converts each character of the users input to a letter, based on their alphabetical order (a = 1, b = 2, ect) and prints each number output on a new line. How do I get change this so that when each number is printed, it is on the same line as the last? (eg 123)
Set the optional end argument to "" in print() as:
print(ord(i)-ord("a")+1, end="")
Use this
print("what ever you want to print",end= " ")
It will print without taking the cursor down a line.
Related
I am trying to create a function which is able to detect when two letters back to back are duplicates, for example the ls in "hello", and split the duplicate letters with the letter "x". Here is my code:
plaintext = input("Enter plaintext here: ")
plaintext = plaintext.lower() # makes plaintext lowercase
plaintext = plaintext.replace(" ", "") # removes all spaces
# this separates all duplicate letters
i = 0 # sets i to 0
for letter in plaintext:
if plaintext[-1] == plaintext[-2]: # if the last letter is the same as the second to last
plaintext = plaintext[:-1] + "x" + plaintext[-1:] # separate them with an x
elif plaintext[i] == plaintext [i+1]: # if one letter is the same as the next letter
# the line above makes an error
plaintext = plaintext[:i+1] + "x" + plaintext[i+1:] #separate them with an x
i += 1
else:
i += 1
This code works when I enter hello there as the input; I receive helxlothere. However, when I test another input, such as heythere, IndexError: string index out of range shows up for elif line (line 12). How can I make this code work for all inputs?
You can use regex to achieve this.
For both approaches, it will work for hello there hey there
The difference comes when more than two character repetition happens.
approach 1
import re
string='hello there'
# find Any repeated character and add x in between them
answer = re.sub(r'(.)\1{1}', r'\1x\1', string)
print(answer)
Here for hellllo there text, you will get output helxllxlo there
approach 2
alternatively, you can use this method.
s="hello there"
for match in re.finditer(r"(.)\1+", s):
old=s[match.start():match.end()]
s=s.replace(old,'x'.join(old))
print(s)
here for hellllo there text, you will get output helxlxlxlo there as output.
I think the second approach will be more appropriate.
The IndexError is caused by the fact that you are looking at plaintext[i+1]. As you can see in the word heythere, there are no letters which match back to back, and therefore the code continues until it hits the end, and so you get an IndexError because there is no element i+1.
You can fix this by using this code instead:
plaintext = input("Enter plaintext here: ")
plaintext = plaintext.lower() # makes plaintext lowercase
plaintext = plaintext.replace(" ", "") # removes all spaces
# this separates all duplicate letters
i = 0 # sets i to 0
for letter in plaintext:
if plaintext[-1] == plaintext[-2]: # if the last letter is the same as the second to last
plaintext = plaintext[:-1] + "x" + plaintext[-1:] # separate them with an x
try:
elif plaintext[i] == plaintext [i+1]: # if one letter is the same as the next letter
# the line above makes an error
plaintext = plaintext[:i+1] + "x" + plaintext[i+1:] #separate them with an x
i += 1
else:
i += 1
except IndexError:
pass
This code should stop your code from crashing in the elif statement, while also completing properly.
Hope this helps, have a nice day!
You are receiving the IndexError because during iterating, when the loop reaches the last letter,
elif plaintext[i] == plaintext [i+1]:
this line checks for the letter after the last letter, which does not exist, which causes the program to run into IndexError.
You have to check till the second last letter, for it to work properly.
A simple and easier way to arrive at the same output with a bit easier logic.
Logic
Create a new string and insert all letters which are in the old string, plaintext, to the new string, newPlainText, and check only for one condition that is whether the last letter is same as current or not and if yes then also insert letter 'x' into the newPlainText and that's it!
plaintext = input("Enter plaintext here: ")
plaintext = plaintext.lower() # makes plaintext lowercase
plaintext = plaintext.replace(" ", "") # removes all spaces
# this separates all duplicate letters
newPlainText = plaintext[0] # copy the first letter of plaintext to the new string which will handle the duplicates and insert `x` between them
i = 1 # sets i to 1
while i < len(plaintext):
if plaintext[i] == plaintext[i-1]: # we check that if prev and current letters are same then also append x to the new string
newPlainText += "x"
newPlainText += plaintext[i] # we insert the required current letter to the new string in each iteration
i += 1
print(newPlainText)
So when I encode "hello" in my Encode() function, with a shift of three I get the result "khoor". When I attempt to decode "khoor" using my decode function with a shift of three, I get "hellor". This is strange because an extra letter "r" is returned, despite only decoding 5 letters. This happens with every string I attempt to decode, and I have noticed that the last letter of every string to be encoded is added as an additional letter to the decoded string.
ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
def Menu():
print("Please choose from the following: \n")
print("'e' to encode a string.")
print("'d' to decode a string.")
print("'q' to quit.\n")
choice = input("Please enter one of the letters above.\n")
if choice == "e":
print (Encode())
if choice == "d":
print (Decode())
if choice == "q":
print("The program will now exit.")
quit()
def stringValidation():
while True:
try:
valid = str(input("Enter a string to encode.\n"))
return valid
break
except:
print("Value Error. Enter a string with only letters from the alphabet.")
continue
def shiftValidation():
while True:
try:
valid = int(input("Enter the number of shifts you would like.\n"))
return valid
break
except:
print("Value Error. Please enter an integer.")
def decodeShiftValidation():
while True:
try:
valid = int(input("Enter the key. (Number of shifts used to encrypt the encoded word.)\n"))
return valid
break
except:
print("Value Error. Please enter an integer.")
def Encode():
data = []
string = stringValidation() # asks the user for the string input to be encoded
shift = shiftValidation() # asks the user for the number of shifts
for i in string: # for the letters in string...
if i.strip() and i in ALPHABET: # i.strip removes all default whitespace characters from i (string input by user.)
data.append(ALPHABET[(ALPHABET.index(i) + shift) % 26]) # gets position of the letters from input string in ALPHABET using indexing, and adds the shift to get the new position and new letter.
else:
data.append(i) # if it is a space, simply append it to the data.
output = ''.join(data)
return output
encoded_string= Encode()
print(encoded_string)
def Decode():
data = []
string = input("Please enter the string you wish to decode.\n")
shift = int(input("Enter the key. (Number of shifts used when encoding original word. \n"))
for i in string:
if i.strip() and i in ALPHABET:
data.append(ALPHABET[(ALPHABET.index(i) - shift) % 26])
else:
data.append(i)
output = ''.join(data)
return output
Menu()
An indentation error makes the else of your Decode function a else for the for loop (which is a lesser-known feature of for loop: if no break is encountered, the else executes, adding an extra letter in your case).
That explains why you don't get an error but unexpected behaviour.
More here: Why does python use 'else' after for and while loops?
Aside, a very clumsy way to search in the alphabet is to use index, when you can compute the index directly with characters codes:
data.append(ALPHABET[(ord(i)-ord(ALPHABET[0]) + shift) % 26])
Aside #2: note that decode & encode methods are very similar. Factorize them with the shift as parameter (which is the opposite from one method to the other)
I got errors trying to run your script until I changed all of the input statements to raw_input. But I don't quite understand the logic behind if i.strip() and i in ALPHABET:. Also, you don't have to accumulate letters in a list one at a time and then join them back, when Python lets you append strings directly. In any case, when I simplified your Decode() function to the following, it worked for me:
def Decode():
string = raw_input("Please enter the string you wish to decode.\n").lower().strip()
if string.isalpha():
shift = int(raw_input("Enter the key. (Number of shifts used when encoding original word. \n"))
return ''.join([ ALPHABET[(ALPHABET.index(c) - shift) % 26] for c in string])
I also added in a .lower() and .isalpha() check in case the user uses any capital letters or non-alphabetic strings, but there are other things like this you can add to handle other use cases.
So, I'm a beginner to programming. I am trying to create a program where the user can input a sentence and the program will tell the user how many letters are in that sentence.
counter=0
wrd=raw_input("Please enter a short sentence.")
if wrd.isalpha():
counter=counter+1
print "You have" + str(counter) +"in your sentence."
When I enter this, my output is blank. What is my mistake in this program?
You need to indent code inside if blocks. In the code you have provided, you've forgotten to indent counter = counter + 1.
You are missing a loop across all characters of wrd. Try this instead,
counter = 0
wrd = raw_input("Please enter a short sentence.")
# Iterate over every character in string
for letter in wrd:
# Check if the letter is an alphabet
if letter.isalpha():
# Increment counter only in this condition
counter += 1
print "You have " + str(counter) + " in your sentence."
First of all as #kalpesh mentioned, the statement counter=counter+1 should be indented.
Second of all, you need to iterate over the entire string entered and then count the number of characters or whatever the logic you need.
counter=0
wrd=raw_input("Please enter a short sentence.")
for i in wrd:
if i.isalpha():
counter = counter+1
print "You have " + str(counter) +"in your sentence."
Once you start learning more, then you can use the below code,
counter=[]
count = 0
wrd=raw_input("Please enter a short sentence.")
counter = [len(i) for i in wrd.split() if i.isalpha()]
print "You have " + str(sum(counter)) +"in your sentence."
I am just splitting the word and then checking if it is alpha or not and using the list comprehension to iterate over the string entered.
wrd.isalpha() returns a boolean (true or false). So if the function returns true, counter=counter+1 will be called once (and only once). You need to iterate through every letter of wrd and call isalpha() on each letter.
You could always remove the spaces from your sentence using replace() then use len() to get how many characters are in the sentence.
For example:
sentence = input("Type in a sentence: ") # Ask the user to input a sentence
sentence = sentence.replace(" ", "") # Replace the spaces in the sentence with nothing
print("Your sentence is " + str(len(sentence)) + " characters long") # Use len() to print out number of letters in the sentence
string = input("Enter a string:")
character = input ("Enter a character:")
if character in string: #checks string to see if character is in it
print ("Character found!")
else:
print ("Character not found!")
blank = (" _ " * len(string))
print (blank)
I am making a hangman game and I am stuck at this part.
How can I make it so that when the person guesses a letter it replaces the specific " _ " for where the letter should be? Should I be using a for loop to go through all the " _ " 's and then use an if statement?
If someone could show me how it would be great.
You can use a method similar to the following to update your guess string each time the player guesses something.
def update_guesses(current_guess_string, key_string, character_guessed):
out_string = ""
for i in range(len(current_guess_string)):
if current_guess_string[i] == "_" and key_string[i] == character_guessed):
out_string += character_guessed
else: out_string += current_guess_string[i]
return out_string
Building on your code, here's a set of changes that get you to a working game:
Set your string input to a fixed case and move your blank initialization to just after string input. Change them both to lists so you can modify
them as needed:
# normalize case and convert to a mutable data structure
string = list(input("Enter a string: ").lower())
# the blank list matches the string except it starts all blanks
blank = list("_" * len(string))
Get a loop going for handling guesses. Here I'm stopping the loop when the string list is all one character, presumably blanks, as we'll be swapping characters between the blank and input string lists:
while len(set(string)) > 1: # when the string is all blanks, stop
Make sure to cleanup the user input to be only one character and change it to the same case as the string input:
# normalize case on input and make sure to only get 1 character
character = input("Enter a character: ").lower()[0]
After you test if the character is in the string, swap the character, by position, with a character in the blank string. Do this in a loop so you get all instances of the guessed character:
if character in string: # checks string to see if character is in it
print("Character found!")
# find the character in the string and swap it with what's in
# the blank string so we can handle multiple same characters
# correctly
while character in string:
index = string.index(character)
string[index] = blank[index]
blank[index] = character
else:
print("Character not found!")
The last step in the main loop is to print the current state of the guesses:
# print correct guesses and blanks
print(*blank, sep='')
The output I should get if I type in "eat" should be "hdw" if I shift it by 3. However, the end result is only "w". I'm pretty sure I have everything I need, but maybe it's the formatting?
def shifter():
phrase = input("Please enter a message: ")
key = eval(input("Please enter the number of places to be shifted: "))
list = phrase.split()
for word in list:
for ch in word:
conversion = (chr)((ord(ch) - ord("a") + key) % 26 + ord("a"))
newPhrase = " "
newPhrase = newPhrase + conversion
print(newPhrase)
shifter()
The issue is that you are setting conversion inside your for loop, instead of appending to it, so only the last character in the word is appended to the newPhrase at the end.
You should be appending to conversion, rather than setting it.
Also, you should initialize newPhrase outside the loop and then append to it inside.
Example -
def shifter():
phrase = input("Please enter a message: ")
key = eval(input("Please enter the number of places to be shifted: "))
list = phrase.split()
newPhrase = ""
for word in list:
conversion = ''
for ch in word:
conversion += (chr)((ord(ch) - ord("a") + key) % 26 + ord("a"))
newPhrase = newPhrase + conversion + " "
print(newPhrase)
shifter()
I think it's with your indenting!
Right now, before you do anything with the variable conversion, you've already looped through every ch in word, so you're stuck at the last ch.
Try doing conversion += ... Instead of conversion = ...
(You might need to initialize conversion before that but idts.)