💾 Archived View for twotwos.pollux.casa › code › scrambler_handler › scrambler_handler.py captured on 2023-01-29 at 15:44:06.

View Raw

More Information

⬅️ Previous capture (2022-01-08)

-=-=-=-=-=-=-

import time
import sys
import itertools
#we're definitely going to need all of these things




try:
    from collections_extended import bag
except ModuleNotFoundError:
    print("Please install collections_extended by running this command: ")
    print("pip install collections_extended")
    print("If you have multiple python installations all bouncing around inside your OS, this is probably better:")
    print("[command you used to run this program (python3 for example)] -m pip install collections_extended")
    sys.exit()
    #collections_extended needs to be installed!

def load_words(dictionary):
    with open(dictionary+".txt",errors="ignore") as word_file: #just guess what the files are called
        valid_words = word_file.read().split()
    return valid_words

def sprint(string, time_):
    print(string)
    time.sleep(time_/2)
    #saves me the effort

def enable_multiword():
    global multiword_mode
    global word_count
    multiword_mode = True
    while True:
        preliminary_words = input("How many words should we check for? More takes longer > ")
        try: 
            word_count = int(preliminary_words)
            break
        except:
            sprint("Please enter an integer", 0.5)
    sprint("Confirmed!",0.5)
    options.insert(0,multiword_off)
    options.remove(multiword)

def switch_load():
    global dictionary
    global wordlist
    while True:
        dictionary = input("Please enter the name of the dictionary you wish to use. Options are " + str(available_dictionaries) +  " > ")
        if dictionary in available_dictionaries:
            wordlist = load_words(dictionary)
            break
        else:
            sprint("That's not right...", 0.3)
    print("Confirmed! ")


def disable_multiword():
    global multiword_mode
    multiword_mode = False
    options.insert(0,multiword) #keeps it at the right spot
    options.remove(multiword_off)
    sprint("Multiword mode disabled ", 0.3)

def do_a_search(mode):
    global word_count
    global ridiculous
    while True:
        preliminary_scrambled_word = input("Please input a word (or words) which you would like to unscramble > ").lower().replace(" ","")
        if not preliminary_scrambled_word.isalpha():
            sprint("Please input a word with letters only", 0.3)
        else:
            scrambled_word = preliminary_scrambled_word
            break
    scrambled_word_bag = bag(scrambled_word)
    found_anagrams = []
    potential_anagrams = []
    print("Wait one moment...")
    #I've written the same thing 4 times to save one if statement every loop. Which is probably a big difference.
    if mode == "normal":
        for word in wordlist:
            if bag(word) == scrambled_word_bag: #checks if all the letter counts are the same between this word and the other
                found_anagrams += [word]
                print(word,end="\r")
                #Show anagrams as they are found. Looks cool, serves no function.
    elif mode == "partial":
        for word in wordlist:
            if bag(word) >= scrambled_word_bag: #checks if the user's word could be in this word
                found_anagrams += [word]
                print(word,end="\r")
    elif mode == "containing":
        for word in wordlist:
            if bag(word) <= scrambled_word_bag: #checks if this word could be in the user's word
                found_anagrams += [word]
                print(word,end="\r")
    elif mode == "multiword":
        for word in wordlist:
            if bag(word) <= scrambled_word_bag: #checks if this word could be in the user's word
                potential_anagrams += [word]
                print(word,end="\r")
        if word_count > len(scrambled_word)*0.5:
            word_count = round(len(scrambled_word)*0.5)
            print("Reduced max word count to " + str(word_count))
            #Two letters per word, no less!
        for n in range(1,word_count+1):
            #one word, two words, three words, four...
            print("Generating combinations of length " + str(n))
            combinations = tuple(itertools.combinations(potential_anagrams, n)) #does what the previous print statement tells you it does. Can take an age.
            print("Testing those combinations...")
            if not ridiculous:
                #every way to add that many words
                for combination in combinations:
                    #surely you can figure out what this does
                    bag_neue = bag() #empty!
                    sentence = "" #also empty!
                    for word in combination:
                        bag_neue += bag(word) #just chuck the letters into a bag
                        sentence += (word + " ") #writes a beautiful sentence
                    if bag_neue == scrambled_word_bag: #can we scramble the letters in these words to make the original one?
                        found_anagrams.append(sentence)
                        print(sentence,end="\r")
            else:
                for combination in combinations:
                    if not((combination[0][0] != "s") and (combination[0][0] != "e") and (combination[0][0] != "v") and (combination[0][0] != "r") and (combination[0][0] != "g") and (combination[0][0] != "e")): 
                        if n > 1:
                            found_anagrams.append(combination[0] + " " + combination[1])
                        else:
                            found_anagrams.append(combination[0])
                #found_anagrams = found_anagrams + combinations
    ridiculous = False


    if len(found_anagrams) > 1:
        sprint("I found these words for you: ", 0.3)
        for anagram in found_anagrams:#sorted(alphabetic,key=len): #sorts by length, then alphabetically. If we just sorted alphabetically, they'd go alphabetically and then by length, which is all wrong
            sprint(anagram, 1/len(found_anagrams)) #goes faster the more there are
    elif len(found_anagrams) == 1:
        sprint("I found one word!", 0.3)
        if found_anagrams[0] == scrambled_word: #these aren't bags
            sprint("it's just \"" + scrambled_word + "\" again, though...", 0.3)
        else:
            sprint("It's \"" + found_anagrams[0] +"\"! ", 0.3)
    else:
        sprint("I couldn't find anything...", 0.3)

def partial_search():
    do_a_search("partial")

def standard_search():
    if multiword_mode:
        do_a_search("multiword")
    else:
        do_a_search("normal")

def containing_search():
    do_a_search("containing")

def ridiculous_search():
    global ridiculous
    ridiculous = True
    do_a_search("multiword")
    

ridiculous = False


def exit_program():
    print("Goodbye!")
    sys.exit()



class option:
    def __init__(self, name, function, include = True):
        self.name = name
        self.function = function
        if include:
            options.append(self)
#strictly unnessecary
options = []

#change the defaults if you like
multiword_mode = False
dictionary = 'long'
word_count = 3
available_dictionaries = ["short","long","names"] #if you add your own, put the file names (without .txt) in here


multiword = option("Enable multiword mode to search for multiple-word results", enable_multiword, include = not multiword_mode)
multiword_off = option("Disable multiword mode. ", disable_multiword, include = multiword_mode)
load = option("Switch between dictionaries. Currently using ", switch_load)
standard_find = option("Search for an anagram! ", standard_search)
partial_find = option("Search for words containing the letters in a word", partial_search) # can be used to cheat at countdown
containing_find = option("Search for words contained in a word", containing_search)
special_find = option("Search for multiple words contained in a word?",ridiculous_search)
exit = option("Exit the program ", exit_program)

assassins = False #don't worry about it

wordlist = load_words(dictionary)

while True:
    i = 0
    for thing in options:
        if thing != load: #special exception
            sprint("["+str(i)+"] "+thing.name,0)
        else:
            sprint("["+str(i)+"] "+thing.name+dictionary+".",0)
        i += 1
    while True:
        try:
            choice = int(input("> "))
            break
        except ValueError:
            print("Please enter an integer")
    options[choice].function()
    sprint("Back to the menu... ",1)