I have been working on an encryption software and I got to the code given. But now I’m stuck. I need a way to get the encrypted letter out from the function.
num = input()
word = input()
num = int(num)
def encrypt(letter, var):
if letter == "a":
var = "m"
if letter == "b":
var = "n"
if letter == "c":
var = "b"
if letter == "d":
var = "v"
if letter == "e":
var = "c"
if letter == "f":
var = "x"
if letter == "g":
var = "z"
if letter == "h":
var = "p"
if letter == "i":
var = "o"
if letter == "j":
var = "i"
if letter == "k":
var = "u"
if letter == "l":
var = "y"
if letter == "m":
var = "t"
if letter == "n":
var = "r"
if letter == "o":
var = "e"
if letter == "p":
var = "w"
if letter == "q":
var = "q"
if letter == "r":
var = "a"
if letter == "s":
var = "s"
if letter == "t":
var = "d"
if letter == "u":
var = "f"
if letter == "v":
var = "g"
if letter == "w":
var = "h"
if letter == "x":
var = "j"
if letter == "y":
var = "k"
if letter == "z":
var = "l"
list = list(word)
if num == 1:
if num == 2:
var1, var2 = word
if num == 3:
if num == 4:
if num == 5:
if num == 6:
if num == 7:
if num == 8:
if num == 9:
if num == 10:
if num == 11:
if num == 12:
if num == 13:
if num == 14:
if num == 15:
Basically what happens is the first section (ends with the carriage return) just takes the word you want to encrypt and how long it is. Then the second section is the actual encryption which would recive the letter it is encrypting and the variable it would be. Such as the input would be encrypt(y, var1) and it would output the letter y would be encrypted then outputted as var1. Then the final section (which is unfinished) would be what takes the word turns it into a list then turns that list into a single letter then it outputs that to the encrypter.
Can someone give help on the final section and how to get an output from the mid section.
Note: this is an encryper not a decrypter. That’s part 2
Your code has a few problems.
You repeat the same code a lot, which isn't needed; what you're creating is what's called a substitution cipher and you're basically just replacing specific characters with another specific character.
You want to replace the letters one at a time and are looking to put the text in a string in a list to do so; you don't have to though, Python allows you to loop over a string just as easily as over a list.
You are trying to modify a variable you passed to a function (var), but that doesn't work for immutable types like a string; you can either return a value from the function, or pass it a mutable type (like a list) and modify that.
You picked a cipher that's very easy to guess; a substitution cipher is very easy to crack to begin with, but picking a cipher that's literally in front of everyone with a keyboard may be a bit much :)
This would do the same:
def encrypt(letter):
key = 'abcdefghijklmnopqrstuvwxyz'
cipher = 'mnbvcxzpoiuytrewqasdfghjkl'
return cipher[key.index(letter)]
word = input()
letters = list(word)
encrypted_letters = [encrypt(ch) for ch in word]
print('Encrypted:' + ''.join(encrypted_letters))
That still turns the word into a list, but since the number you were reading didn't really affect anything, I left it out.
It returns the encrypted letter and those are captured one at a time in what's known as a 'list comprehension': [encrypt(ch) for ch in word], resulting in a list of encrypted characters.
This still naively goes through 'encryption' one letter at a time, but it just looks up the position of the letter in the key, and then returns the letter at the same position in the cipher - a lot shorter.
It could be a lot simpler still though:
CIPHER = {chr(i + 97): replacement for i, replacement in enumerate('mnbvcxzpoiuytrewqasdfghjkl')}
def encrypt(s):
return ''.join(CIPHER[letter] if letter in CIPHER else letter for letter in s)
word = input()
print(f'Encrypted: {encrypt(word)}')
Here, the cipher is created as a dictionary, which is the ideal way to look up a value (that's what it's for). And it's created outside the function, so it only gets created once, since it doesn't change.
The cipher uses the fact that the characters of the alphabet (in lowercase) can be generated by a function chr() by giving it the ascii code for a character, 97 for 'a', 98 for 'b', etc. That way, you don't have to include the alphabet in the code again.
The function just loops over the letters in the word itself and returns the encrypted word - already joined back together.
And instead of just adding the strings together in the print line, that uses a so-called f-string to print the returned value inside the string, making it all a bit easier to read and avoiding some complications in many cases.
First of hopefully many questions to come as I dive deeper into Python. I'm following along to the Giraffe Academy course and have tried to create a more complex program. It's a silly little decoder tool but it's helping me learn a lot of the python basics. I have the first part of the program below:
import string
std = string.ascii_lowercase
rvs = string.ascii_lowercase[::-1]
vwls = {'a':5,'e':1,'i':4, 'o':2, 'u':3}
def translate(phrase):
phrase = phrase.lower()
translation = ""
for letter in phrase:
if letter.isspace() == True:
translation = translation + " "
elif letter in ".!?":
translation = translation + letter
elif letter in vwls:
if str(vwls[letter]) not in translation:
translation = translation + str(vwls[letter])
vwls[letter] = vwls[letter] + 5
else:
indx = std.index(letter)
translation = translation + rvs[indx]
return translation
print(translate(input("Enter a phrase: ")))
My goal is to create the decoder for the output of the previous code. The good news is I know what is causing my problem. Because the message is a string, any vowel that goes past 2 digits wont be picked up by my code below. I need to find a way to include the next character in the string so that it can choose the correct key/value pairing in the dict. Below is what I have so far:
import string
std = string.ascii_lowercase
rvs = string.ascii_lowercase[::-1]
vwls = {'5':'a','1':'e','4':'i','2':'o','3':'u'}
def translate(phrase):
translation = ""
for letter in phrase:
if letter.isspace() == True:
translation = translation + " "
elif letter in ".!?":
translation = translation + letter
elif letter in vwls:
if letter in vwls[letter]:
translation = translation + vwls[letter]
vwls[str(int(letter) + 5)] = vwls[letter]
del vwls[letter]
else:
for index in range(len(phrase)-1):
if phrase[index] == phrase[index+1]:
translation = translation + 'poop'
else:
indx = rvs.index(letter)
translation = translation + std[indx]
return translation
print(translate(input("Enter a phrase: ")))
Any feedback is greatly appreciated! I have tried searching for similar issues and I am still learning the rules for stack overflow so I apologize if I have broken any rules regarding this question.
good luck with your diving
tried here something, not sure if its correct
few points
for each vowel, the %5 is the same, for example u can be 3,8,13,18.. they all have % 5 of 3
the biggest match you can find is the correct one, 23 is either ou or just u after few iteration, so if the dict say u value is 23 the correct value is u
there is a problem with the translate function you provided
eeee is decoded to 1611 which is eee, missing one e
def decode(phrase):
vwls = {'a':5,'e':1,'i':4, 'o':2, 'u':3}
reverse_vwls = {0:'a',1:'e',4:'i',2:'o',3:'u'}
translation = ""
i=0
while i < len(phrase):
if phrase[i].isspace() == True:
translation = translation + " "
i+=1
continue
if phrase[i] in ".!?":
translation = translation + phrase[i]
i+=1
continue
if str.isdigit(phrase[i]): #check if the letter is a digit
tmp_index = i
str_num = ""
while tmp_index<len(phrase) and str.isdigit(phrase[tmp_index]): # take all the co
str_num = str_num+phrase[tmp_index]
tmp_index+=1
int_num = int(str_num) # turn the digits string into int
while int_num:
current_digit = int_num%10
curent_vwl = reverse_vwls[current_digit%5] #the ones digit % 5 is permenent f
if vwls[curent_vwl] == int_num:
vwls[curent_vwl] = vwls[curent_vwl]+5
translation = translation+curent_vwl
i = i+len(str(int_num))
break
int_num = int(int_num/10)
continue
indx = rvs.index(phrase[i])
translation = translation + std[indx]
i+=1
return translation
Basically my plan was to return text with random-sized letters in words i.e. "upper" or "lower". The script is working, though it seems raw (I am a Beginner and I'd appreciate some corrections from You).
The problem is:
It is not consistent. With that said, it can print word 'about' even if it should be 'About' or something similar.
I want to be sure that the maximum of UPPER or lower letters in a row do not exceed 3 letters. and I don't know how to do it.
Thank you in advance.
#!/usr/bin/env python3
import random
message = input()
stop = ''
def mocking(message):
result = ''
for word in message:
for letter in word:
word = random.choice(random.choice(letter.upper()) + random.choice(letter.lower()))
result += word
return result
while stop != 'n':
print(mocking(message))
stop = input("Wanna more? y/n ").lower()
if stop == 'n':
break
else:
message = input()
You need to split the input into words, decide how many positions inside the word you want to change (minimum 3 or less if the word is shorter).
Then generate 3 unique positions inside the word (via random.sample) to change, check if upper then make lower else make upper. Add to resultlist and join words back together.
import random
message = "Some text to randomize"
def mocking(message):
result = []
for word in message.split():
len_word = len(word)
# get max 3 random positions
p = random.sample(range(len_word),k = min(len_word,3))
for position in p:
l = word[position]
if l.isupper():
word = word[:position] + l.lower() + word[position+1:]
else:
word = word[:position] + l.upper() + word[position+1:]
result.append(word)
return ' '.join(result)
while True:
print(mocking(message))
stop = input("Wanna more? y/n ").lower()
if stop == 'n':
break
else:
message = input()
See Understanding slice notation for slicing
At most 3 modifications? I would go with something like this.
def mocking(message):
result = ''
randomCount = 0
for word in message:
for letter in word:
newLetter = random.choice( letter.upper() + letter.lower() )
if randomCount < 3 and newLetter != letter:
randomCount += 1
result += newLetter
else:
result += letter
randomCount = 0
return result
If the random choice has modified the letter then count it.
I'm coding a hangman game for my Computer Science class, and I'm trying to create a dictionary that has each character of the word given and a 0 to notate whether it's been guessed or not.
gamestart = 0
guesses = 5
gamewin = 0
while gamestart == 0:
word = input("Welcome to hangman!" + "\nEnter a word: ")
if word.find(" ") > -1:
print("\nSorry Please use one word only!\n")
elif word.find(" ") == -1:
gamestart = 1
for i in range(len(word)):
wordspacing = [0] * i
wordstore = list(word)
wordstore = dict(zip(wordspacing, wordstore))
print(wordstore)
however when I try to put the two lists I have together I get the output:
Welcome to hangman!
Enter a word: word
{0: 'r'}
Could someone identify the reason for this happening. I would also like a little bit of criticism in terms of efficiency.
The problem is that you are making a dictionary of 0 to letters, and each key can only have one value.
Try just using a dictionary comprehension
wordstore = {letter: 0 for letter in word}
To achieve the desired output using your method you need to switch the order of the zipped objects
wordstore = dict(zip(wordstore, wordspacing))
Also for wordspacing, you don't want to continually assign a value to wordspacing, plus you only end up with [0,0,0] instead of [0,0,0,0] since the last value of i is 3 and not 4. So go with the following
wordspacing = [0] * len(word)
I'm trying to create a little game.
The rules are very straightforward: you give an English word, and the computer will try to guess this word letter by letter.
The thing is, I'm trying to make the computer guess the letters in a smart way. Let me give you a simple example of what I'm trying to build so you can understand:
You give the word "cat" to the computer to guess.
The 130K words list I have is narrowed to only the words who have 3 characters, which makes up to 805 words only. And from this list of words, an alphabet is created, containing only 25 letters (not the whole 26) because the new 805 words list contains all the letters of the alphabet but the "z". So we now have a list containing 25 (different) letters.
-- As I can't upload anything here on SO, we will say for this example that the massive 130K words list is a 10 words list (variable name "fullDice") --
If you try to run my code, pick a word from inside this list or else
it's not going to work
The computer now guesses a random letter from this 25 letters list.
If the letter is not in the word, he doesn't do anything and re-guess a letter from the list.
But if the letter is in the word, that's where things become more complicated. Let's say the computer guess the letter "c". I want the computer to re-narrow the possible words list, to only those having a "c" in the first character. That way, the 805-words list become now an only 36 words list. Because there are only 36 words who are 3 characters and starts with a "c", a new alphabet is created. And the new alphabet is now made of only 14 letters, making it easier for the computer to guess the next letter and be correct about it. And so on until he finds all the letters.
I'm stuck on part 5. If you try to run my code just below, you'll see that the dictionnary list is never narrowed. That's my problem.
import time
from random import randint
fullDice = ["panda", "tiger", "cat", "elephant", "whale", "leopard", "gorilla", "fish", "snake", "eagle"]
askForWord = input("Please enter an english word: ")
while True:
updatedDice = []
for k in range (0, len(fullDice)):
if len(askForWord) == len(fullDice[k]):
updatedDice += [fullDice[k]]
alphabet = []
for i in range (0, len(updatedDice)):
for n in range (0, len(updatedDice[i])):
if updatedDice[i][n] not in alphabet:
alphabet += [updatedDice[i][n]]
guessRandomLetter = alphabet[randint(0, len(alphabet) - 1)]
print("I guess the letter: " + guessRandomLetter)
print("From this dice: " + str(len(updatedDice)))
print("From this amount of letters: " + str(len(alphabet)) + "\n")
time.sleep(0.75)
guessedWordUnderlined = "_" * len(askForWord)
if guessRandomLetter in askForWord:
for m in range(0, len(askForWord)):
if askForWord[m] == guessRandomLetter: # CHECKING IF THE GUESSED LETTER IS INSIDE THE WORD
guessedWordUnderlined = list(guessedWordUnderlined)
guessedWordUnderlined[m] = guessRandomLetter
guessedWordUnderlined = ''.join(map(str, guessedWordUnderlined))
if guessedWordUnderlined == askForWord: # CHECK IF USER HAS WON
print("YOU WON")
break
you just asked a qs including that code.
i tryed to make it work only with the available words in the dictionnary you gave as "python".
from random import randint
import random
import time
import datetime
random.seed(datetime.datetime.now())
wordOfTheUser = input("ENTER ENGLISH WORD HERE: ")
if wordOfTheUser in ("abracadabra", "python", "coding", "soup", "paper", "list", "leader", "program", "software", "eating","abcdefghigklmnopqrstuvwxyz"):
pass
else:
print("your word is not on the list, still devlopping.")
raise
diceList1 = ["abracadabra", "python", "coding", "soup", "paper", "list", "leader", "program", "software", "eating","abcdefghigklmnopqrstuvwxyz"]
diceList2 = []
for k in range (0, len(diceList1) - 1):
if len(diceList1[k]) == len(wordOfTheUser):
diceList2 += [diceList1[k]]
makeAlphabet = []
for b in range (0, len(diceList2)):
for x in range (0, len(diceList2[b])):
if diceList2[b][x] not in makeAlphabet:
makeAlphabet += [diceList2[b][x]]
computerWordSize = "_" * int(len(wordOfTheUser))
a= len(makeAlphabet)
while True:
try:
randomIndex = randint(0, a)
except ValueError:
randomIndex = randint(0, a)
pass
try:
letterChosenRandomly = makeAlphabet[randomIndex]
except IndexError as e:
try:
randomIndex = randint(0, int(len(makeAlphabet)))
letterChosenRandomly = makeAlphabet[randomIndex]
except:
pass
print("I guess the letter -> " + letterChosenRandomly)
diceList3 = []
if letterChosenRandomly in wordOfTheUser:
print("\n=== WON ===> " + letterChosenRandomly)
print("=== ALPHABET ===> " + str(len(makeAlphabet)))
print("=== HDW1 ===> " + str(len(diceList1)))
print("=== hdw2 ===> " + str(len(diceList2)))
print("=== hdw3 ===> " + str(len(diceList3)) + "\n\n")
k=-1
makeAlphabet = []
for i in range (0, len(wordOfTheUser) ):
if letterChosenRandomly == wordOfTheUser[i]:
computerWordSize = list(computerWordSize)
computerWordSize[i] = letterChosenRandomly
for l in range (0, len(diceList2)):
if computerWordSize[i] == diceList2[l][i]:
diceList3 += [diceList2[l]]
for d in range(0, len(diceList3)):
for h in range(0, len(diceList2[b])):
if diceList2[d][h] not in makeAlphabet:
makeAlphabet += [diceList2[d][h]]
won = False
computerWordSize = ''.join(map(str, computerWordSize))
print(computerWordSize)
if computerWordSize == wordOfTheUser:
won = True
if won is True:
print("YOU WON")
break
time.sleep(1)
else:
print("\n=== LOOSE ===> " + letterChosenRandomly)
print("=== ALPHABET ===> " + str(len(makeAlphabet)))
print("=== HDW1 ===> " + str(len(diceList1)))
print("== hdw2 ===> " + str(len(diceList2)))
print("=== hdw3 ===> " + str(len(diceList3)) + "\n\n")
try:
makeAlphabet.remove(letterChosenRandomly)
except:
print ("Letters not in list")
break
k=0
diceList3 = []
for q in range (0, len(wordOfTheUser) - 1):
for l in range(0, len(diceList2)):
if computerWordSize[q] == diceList2[l][q]:
diceList3 += [diceList2[l]]
for d in range(0, len(diceList3)):
for h in range(0, len(diceList2[b])):
try:
if diceList2[d][h] not in makeAlphabet:
makeAlphabet += [diceList2[d][h]]
except:
try:
for s in range(0, len(diceList3)):
for f in range(0, len(diceList2)):
if diceList2[s][f] not in makeAlphabet:
makeAlphabet += [diceList2[s][f]]
except:
("your word is too short")
time.sleep(1)
I believe the problem is that if guessedWordUnderlined in askForWord will never be true. The in operator tests whether the first operator is within the second argument, which is a container, such as a list or string. "_" * len(askForWord), the value of guessedWordUnderlined, is a string of underscores, and you are testing whether or not that is in askForWOrd. If the vale of askForWord is cat, askForWord can be thought of as ["c", "a", "t"], so the in operator will be testing "___" == "c" or "___" == "a" or "___" == "t", none of which will be true. This means that the code beneath it will never execute, so the code just repeats forever, randomly guessing letters within the word. I cannot really tell what the function of this if is, as you already know each letter you could have chosen is in askForWord, though I'm sure I'm missing something obvious.
As an aside, you frequently use a construction similar to for x in range(0, len(LIST): ... LIST[x], which can be more concisely and obviously written as for x in LIST: ... x. For example, your code
for k in range (0, len(fullDice)):
if len(askForWord) == len(fullDice[k]):
updatedDice += [fullDice[k]]
alphabet = []
could be written as
for k in fullDice:
if len(askForWord) == len(k):
updatedDice += [k] # This should be updatedDice.append(k), but I
# have left it as-is for simplicity's sake.
alphabet = []
which should help your code become more readable. There are a few other edits that could be made to make your code more pythonic, but aside from that line I cannot see anything functionally wrong with it. If you share what this if is supposed to help, it might make it a bit easier to find any other errors in your code. I hope this helps, and good luck!
Having reviewed your code again, I believe the problem is in the statement guessedWordUnderlined = "_" * len(askForWord). This creates a string of underscores whose length is equal to that of askFOrWord. The problem is that each at each iteration of the while True: loop, a new string. This means that at each iteration, the string becomes a list of underscores with one correct letter, but in the next iteration it is overridden. To fix this, you should move the line guessedWordUnderlined = "_" * len(askForWord) from its current location to directly below askForWord = input("Please enter an english word: "). This will mean that it is present in the global scope rather than the local scope, meaning it won't get overwritten. You should also put the line global guessedWordUnderlined at the beginning of the while loop, if I'm not mistaken. This may require you to rework some code. Hope this works for you!