enchant.errors.Error: Don't pass bytestrings to pyenchant-python - python

I am trying to make a program where I can enter some characters in python and the program then goes through all the possible combinations of those letters. Then it compares that to check if it is in the dictionary or is a word. If it is, it gets appended to a list that will be printed out at the end. I had to look up how to do certain things and was doing great until I got this error. I can't find any forum that has this message. Can someone help me and tell me what I need to do to get it to work? Here is my code.
import itertools
import enchant
how_many_letters=True
letters=[]
possible_words=[]
d = enchant.Dict("en_US")
print("Welcome to combination letters helper!")
print("Type the word 'stop' to quit entering letters, other wise do it one at a time.")
while how_many_letters==True:
get_letters=input("Enter the letters you have with not counting spaces:")
if get_letters=='stop':
how_many_letters=False
letters.append(get_letters)
length=len(letters)
length=length-1
del letters[length:]
print(letters)
for i in range(length):
for subset in itertools.combinations(letters, i):#Subset is the combination thing
print(subset)
check=d.check(subset)
print(check)
if check==True:
possible_words.append(check)
print(possible_words)
Thanks in advance.

The answer to you question is this:
for i in range(1, length + 1):
for subset in itertools.combinations(letters, i):#Subset is the combination thing
s = ''.join(subset)
print(s)
check=d.check(s)
print(check)
if check==True:
possible_words.append(s)
print(possible_words)
You need to pass enchant a string not a tuple and your range was not working.
(It's possible you may want to look at itertools.permutations(), I don't know if that is what you want though.)

Related

How to create an encryption/decryption function using indexes?

I have been trying to solve this problem for hours now and I have no idea how. I am not going to write down the problem, only the part I am struggling with.
Let's say we have:
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
key = 'guwyrmqpsaeicbnozlfhdkjxtvGUWYRMQPSAEICBNOZLFHDKJXTV'
message = 'wncodhrlf'
As you can see, w in the message is equivalent to c, n is to o etc so the message spells out 'computer'. I need to define functions that can decode/encrypt a message using a random key, and I have been told that this is solved through indexes.
If you have any idea how to solve this please tell me. I do not need you to write a code, I simply need to be directed to a solution because I keep getting lost. Thank you for your time.
Simple translation:
>>> message.translate(str.maketrans(key, letters))
'computers'
If I understand correctly the actual letter and the encrypted letter have the same index in the letters and key variables respectively.
So to parse an encrypted string, you can just loop through the letters of the string, find each character's index in the key string, then get the letter at that index in the letters string.
For example, calling key.index('w') should return 2. Calling letters[2] will then return 'c'.
To encrypt an unencrypted string, you just do the opposite. E.g. to encrypt the 'c', call letters.index('c'), which returns 2. Then calling key[2] should return 'w'.
First off you need to access each individual letter of the message. One possible way is with indexes:
value = message[0]
From there, you need to see where in the key this letter is. String objects in Python have several helper methods.
index = key.index("a") # Finds 9 as the index
And now you have an index, finding the corresponding value in the list of letters is as simple as using an index:
decoded = letters[9] # Finds "j" in the list of letters
I'll leave it to you to piece this together.
I will note that many of these could have been found in the documentation, it's quite approachable, I recommend trying to read through it.
Explicit Python code using dictionary:
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
key = 'guwyrmqpsaeicbnozlfhdkjxtvGUWYRMQPSAEICBNOZLFHDKJXTV'
message = 'wncodhrlf'
assert len(letters) == len(key)
key_letter_mapping = {}
for i in range(len(key)):
key_letter_mapping[key[i]] = letters[i]
result = ''
for c in message:
result += key_letter_mapping[c]
print(result)

Longest alphabetical substring - where to begin

I am working on the "longest alphabetical substring" problem from the popular MIT course. I have read a lot of the information on SO about how to code it but I'm really struggling to make the leap conceptually. The finger exercises preceding it were not too hard. I was wondering if anyone knows of any material out there that would really break down the problem solving being employed in this problem. I've tried getting out a pen and paper and I just get lost. I see people employing "counters" of sorts, or strings that contain the "longest substring so far" and when I'm looking at someone else's solution I can understand what they've done with their code, but if I'm trying to synthesize something of my own it's just not clicking.
I even took a break from the course and tried learning via some other books, but I keep coming back to this problem and feel like I need to break through it. I guess what I'm struggling with is making the leap from knowing some Python syntax and tools to actually employing those tools organically for problem solving or "computing".
Before anyone points me towards it, I'm aware of the course materials that are aimed at helping out. I've seen some videos that one of the TAs made that are somewhat helpful but he doesn't really break this down. I feel like I need to pair program it with someone or like... sit in front of a whiteboard and have someone walk me step by step and answer every stupid question I would have.
For reference, the problem is as follows:
Assume s is a string of lower case characters.
Write a program that prints the longest substring of s in which the letters occur in alphabetical order. For example, if s = 'azcbobobegghakl', then your program should print
Longest substring in alphabetical order is: beggh
In the case of ties, print the first substring. For example, if s = 'abcbcd', then your program should print
Longest substring in alphabetical order is: abc
I know that it's helpful to post code but I don't have anything that isn't elsewhere on SO because, well, that's what I've been playing with in my IDE to see if I can understand what's going on. Again, not looking for code snippets - more some reading or resources that will expand upon the logic being employed in this problem. I'll post what I do have but it's not complete and it's as far as I get before I start feeling confused.
s = 'azcbobobegghakl'
current = s[0]
longest = s[0]
for letter in range(0, len(s) -1):
if s[letter + 1] >= s[letter]:
current.append(s[letter + 1])
if len(current) > len(longest):
longest = current
else:
current =
Sorry for formatting errors, still new to this. I'm really frustrated with this problem.
You're almost there in your example, just needs a little tweaking
s = 'azcbobobegghakl'
longest = [s[0],] # make them lists so we can manipulate them (unlike strings)
current = [s[0],]
for letter in range(0, len(s) -1):
if s[letter + 1] >= s[letter]:
current.append(s[letter + 1])
if len(current) > len(longest):
longest = current
else:
current = [s[letter+1],] # reset current if we break an alphabetical chain
longest_string = ''.join(longest) # turn out list back into a string
output of longest_string:
'beegh'
If you are struggling with the concepts and logic behind solving this problem, I would recommend perhaps stepping back a little and going through easier coding tutorials and interactive exercises. You might also enjoy experimenting with JavaScript, where it might be easier to get creative right from the outset, building out snippets and/or webpages that one can immediately interact with in the browser. Then when you get more fun coding vocabulary under your belt, the algorithmic part of it will seem more familiar and natural. I also think letting your own creativity and imagination guide you can be a very powerful learning process.
Let's forget about the alphabetical part for the moment. Imagine we have a bag of letters that we pull out one at a time without knowing which is next and we have to record the longest run of Rs in a row. How would you do it? Let's try to describe the process in words, then pseudocode.
We'll keep a container for the longest run we've seen so far and another to check the current run. We pull letters until we hit two Rs in a row, which we put it in the "current" container. The next letter is not an R, which means our run ended. The "longest-so-far" run is empty so we pour the "current" container in it and continue. The next four letters are not Rs so we just ignore them. Then we get one R, which we put in "current" and then an H. Our run ended again but this time our one R in "current" was less than the two we already have in "longest-so-far" so we keep those and empty "current."
We get an A, a B, and a C, and then a run of five Rs, which we put into the "current" container one by one. Our bag now contains the last letter, a T. We see that our run ended again and that "current" container has more than the "longest-so-far" container so we pour out "longest" and replace its contents with the five Rs in "current." That's it, we found the longest run of Rs in the bag. (If we had more runs, each time one ended we'd choose whether to replace the contents of "longest-so-far.")
In pseudocode:
// Initialise
current <- nothing
longest <- nothing
for letter in bag:
if letter == 'R':
add 'R' to current
else:
if there are more letters
in current than longest:
empty longest and pour
in letters from current
otherwise:
empty current to get ready
for the next possible run
Now the alphabetical stipulation just slightly complicates our condition. We will need to keep track of the most recent letter placed in "current," and in order for a run to continue, its not seeing another of the same letter that counts. Rather, the next letter has to be "greater" (lexicographically) than the last one we placed in current; otherwise the run ends and we perform our quantity check against "longest-so-far."
Generally, it is easier to create a listing of all possibilities from the input, and then filter the results based on the additional logic needed. For instance, when finding longest substrings, all substrings of the input can be found, and then only elements that are valid sequences are retained:
def is_valid(d):
return all(d[i] <= d[i+1] for i in range(len(d)-1))
def longest_substring(s):
substrings = list(filter(is_valid, [s[i:b] for i in range(len(s)) for b in range(len(s))]))
max_length = len(max(substrings, key=len)) #this finds the length length of the longest valid substring, to be used if a tie is discovered
return [i for i in substrings if len(i) == max_length][0]
l = [['abcbcd', 'abc'], ['azcbobobegghakl', 'beggh']]
for a, b in l:
assert longest_substring(a) == b
print('all tests passed')
Output:
all tests passed
One way of dealing with implementation complexity is, for me, to write some unit tests: at some point, if I can't figure out from "reading the code" what is wrong, and/or what parts are missing, I like to write unit tests which is an "orthogonal" approach to the problem (instead of thinking "how can I solve this?" I ask myself "what tests should I write to verify it works ok?").
Then, by running the tests I can observe how the implementation behaves, and try to fix problems "one by one", i.e concentrate on making that next unit test pass.
It's also a way of "cutting a big problem in smaller problems which are easier to reason about".
s = 'azcbobobeggh'
ls = [] #create a new empty list
for i in range(len(s) - 1): # iterate s from index 0 to index -2
if s[i] <= s[i+1]: # compare the letters
ls.append(s[i]) # after comparing them, append them to the new list
else:
ls.append(s[i])
ls.append('mark') # place a 'mark' to separate them into chunks by order
ls.append(s[-1]) # get back the index -1 that missed by the loop
# at this point here ls:
# ['a', 'z', 'mark', 'c', 'mark', 'b', 'o', 'mark', 'b', 'o', 'mark', 'b', 'e', 'g', 'g', 'h']
ls = str(''.join(ls)) # 'azmarkcmarkbomarkbomarkbeggh'
ls = ls.split('mark') # ['az', 'c', 'bo', 'bo', 'beggh']
res = max(ls, key=len) # now just find the longest string in the list
print('Longest substring in alphabetical order is: ' + res)
# Longest substring in alphabetical order is: beggh

How to make any random numbers and letters get printed at once and change everytime you re-run the code?

How to make any random numbers and letters get printed at once and change every time you re-run the code? e.g 0asd84hqe98asd8 Thanks
from string import letters, digits, lowercase
from random import choice
def random_string(n):
return ''.join([choice(digits + letters) for i in range(n)])
print random_string(15)
letters includes both cases. if you are only interested in getting lowercase,
change letters in the function to lowercase.
what I would do is use an array to hold values then random number for index and then loop it however many times u want there is probly a better way and I haven't put code as on bus right now(on phone) so wouldn't be able to test it

How can make this code interact with other programs?

So I have made a code that is sort of a brute force password guesser that is made to guess a 3 letter password.
I know this code is not correct because the while statement is obviously wrong so how could I fix that?
Also how could I make this code interact with other programs?
For example:
Winrar has some files that need a 3 word password and has an enter screen where you type the password. How could I make this my code interact or 'type' within that password enter box?
import random
import string
while password != correct:
letter 1 = random.choice(string.letters)
letter 2 = random.choice(string.letters)
letter 3 = random.choice(string.letters)
word = '%s%s%s'%(letter1, letter2, letter3)
if word == password:
print "The code is %s"%(word)
else:
break;
This is a terrible way to go about this, but....
import random
import string
while True:
# Do it until the `if` block says it's right, then break.
word = ''.join([random.choice(string.letters) for _ in range(3)])
if word == password:
print "The code is %s" % (word)
break
EDIT: ''.join([random.choice(string.letters) for _ in range(3)]) explained, as per your request in the comments.
[x for x in list_of_xs] is a list comprehension. You can do transformations on the resultant item (for example, all perfect squares from roots 1-10 is [x**2 for x in range(1,11)] or more simply [x**2 for x in [1,2,3,4,5,6,7,8,9,10] ]. There's lots of info out there on this, and tons of canonical SO answers.
random.choice(string.letters) you already use, so that much you get. ''.join is using the str.join command, which combines an iterable of strings into one string, using the str as a separator. ", ".join(["Eggs","Cheese","Bread","Milk"]) results in "Eggs, Cheese, Bread, Milk". In this case I'm using an empty string to combine.
Basically I'm building a list of three random.choice(string.letters) (the _ isn't anything special, it's just notation for the next programmer that comes along that this variable isn't necessary. [do_something for _ in range(x)] is a common idiom for a list of do_somethings x long), then combining them together with an empty string in between them (in other words, NOTHING in between them)
Maybe
import random
import string
while word != password:
# do the same stuff
But honestly what you're trying to do is:
import itertools as it
for attempt in (''.join(combo) for combo in it.combinations(string.letters,3)):
if attempt == password:
print "success:",attempt
else:
print "failure"
To pre-empt your question, itertools (which I imported as it) has a method combinations that returns all of the unique combinations of the iterable you hand it of the sequence length r. The notation is itertools.combinations(iterable,r). It returns a list of tuples, which then need to be combined in the same way I did above.
The only failing of THIS method is that it can't catch passwords like "aaa". Any repeated characters won't show up in combinations.
As far as your title: "How can I make this code interact with other programs" is too broad for this question. It's not a good fit unfortunately.

comparing occurrence of strings in list in python

i'm super duper new in python. I'm kinda stuck for one of my class exercises.
The question goes something like this: You have a file that contains characters i.e. words. (I'm still at the stage where all the terms get mixed up, I apologize if that is not the correct term)
Example of the file.txt content: accbd
The question asks me to import the file to python editor and make sure that no letter occurs more than letter that comes later than it in the alphabet. e.g. a cannot occur more frequently than b; b cannot occur more than c, and so on. In the example file, c occurs more frequently than d, so I need to raise an error message.
Here's my pathetic attempt :
def main():
f=open('.txt','r') # 1st import the file and open it.
data = f.read() #2nd read the file
words = list(data) #3rd create a list that contains every letter
newwords = sorted(words) # sort according to alphabetical order
I'm stuck at the last part which is to count that the former word doesn't occur more than the later word, and so on. I tried two ways but neither is working. Here's trial 1:
from collections import counter
for i in newwords:
try:
if counter(i) <=counter(i+1):
print 'ok'
else:
print 'not ok between indexes %d and %d' % (i, i+1)
except:
pass
The 2nd trial is similar
for i in newwords:
try:
if newwords.count(i) <= newwords.count(i+1):
print 'ok'
else:
print 'ok between indexes %d and %d' % (i, i+1)
except:
pass
What is the correct way to compare the count for each word in sequential order?
I had posted an answer, but I see it's for an assignment, so I'll try to explain instead of just splatting a solution here.
My suggestion would be to solve it in three steps:
1) in the first line, create a list of sorted characters that appear in the string:
from the data string you can use set(data) to pick every unique character
if you use sort() on this set you can create a list of characters, sorted alphabetically.
2) then use this list in a for loop (or list comprehension) to create a second list, of their number of occurrences in data, using data.count(<letter in the list>); note that the elements in this second list are technically sorted based on the alphabetical order of the letters in the first list you made (because of the for loop).
3) compare this second list of values with a sorted version of itself (now sorted by values), and see if they match or not. If they don't match, it's because some of the initial letters appears too many times compared to the next ones.
To be a little more clear:
In [2]: string = 'accbd'
In [3]: import collections
In [4]: collections.Counter(string)
Out[4]: Counter({'c': 2, 'a': 1, 'b': 1, 'd': 1})
Then it's just a for loop with enumerate(list_).

Categories

Resources