Autcomplete words that were previously on a list - python

Autocomplete words which were previously on a list. That list was obtained by user input.
User inputs words which identifies them.
Ex: happy, lazy, skinny.
Then I want to store that into a list which will become a database.
I will do the same input as before, updated version, which will use the list created before and will autocomplete any tag that the user starts writing
Ex: If user enters L, all the words with L will appear. ex: Lazy, Likeable, Loser.
User scrolls down with the keyboard arrows and when he finds the correct word he presses tab to choose it.
In fact stackoverflow's Tags uses a version of what I want

Starting from "I'm just building a toy for fun" and going to "I need the answer now and it's going into production", here are some suggestions:
The simplest code would be to simply find all strings that start with the current text.
dictionary = ['happy', 'lazy', 'skinny']
input_so_far = 'L'
suggestions = [
word
for word in dictionary
if word.lower().startswith(input_so_far.lower())
]
If you want simpl'ish code, but need a semi-serious solution that can cope with a serious dictionary, you'll need to look into some proper data structures, like B-trees, or...
... if you have the text in a database (e.g. PostGreSQL), there may be builtin indices or plugins that would support textual search. But if you need the most general and/or performant solution...
... use a dedicated textual search capability such as Lucene. Funny enough, textual auto-complete is something people do a lot of, so tools for handling text and doing rapid lookup are common and really good.
EDIT: as follow up, since it looks like you're looking for a way to do this in a simple terminal, check out this other question for suggestions about how to enable responsiveness with the user's input. Not all those solutions have auto-completion built in (some might), the point is more about how to get the input and what to do with the output of the approaches I suggest above.

Related

Asking for help breaking down a piece of code --- Head First Python 2nd Edition (11/9/2022) pg 102

https://prnt.sc/B4pFd_w5reM0
<<< photo of page
https://prnt.sc/bfCN6MN3P9DM
<<< screenshot of code
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
friends = ['phil', 'sarah']
for name in favorite_languages.keys():
print(f"Hi {name.title()}.")
if name in friends:
language = favorite_languages[name].title()
print(f"\t{name.title()}, I see you love {language}!")
I am not sure why [name] is in brackets instead of language. We are interested in the language they prioritize and not who the person is (for the value 'language' in specific at least). So I am wondering why the brackets have 'name' inside them, and not 'language'.
Also.... could someone breakdown what is happening in this code? I think I am just lost in general.
First we have a dictionary called favorite_languages
first column are keys, second column are values
going down, we have a list called friends, I think the words inside are called values.
for name in favorite_languages.keys():
this line of code says tells the editor? right? that the keys (first column), each of the keys will be categorized as a 'name'. correct? the keys in the dictionary (named favorite_languages).
print(f"Hi {name.title()}.")
line of code says we will print a message. Hi (with a name pulled from the dictonary with the first letter capitalized by the (.title() command) Just not sure how to describe the f... all I know is that it is needed... and that it exists.
if name in friends:
as the names from the dictonary get pulled, this line of code tells the editor to check if the name pulled is identical to one of the values in the list 'friends'.
language = favorite_lanugages[name].title()
this is where I am stuck. the name pulled from the dictionary, is the same as the value in the list.... so we tell the editor to put the name back into the dictonary... we find the value that is next to it? and then that value gets its first letter capitalized and becomes known as the value 'language'? or is it a variable? and not a value...
print(f"\t{name.title()}, I see you love {language}!")
coming back full circle. We are going to print on a new line. The message starts with the name we pulled from the dictionary that is also identical to a value found in the list. The name has it's first letter capitalized. Text is added ', I see you love '. Then we add the value we created earlier called 'lanugage' and add an exclaimation point after it. Close the quotation marks and close the parenthesis.
What did I miss? Is my thought process right or wrong? Am I on the right track?
You are asking several questions at once, so I will answer them one at a time.
I will preface my answer by saying this:
Python is a programming language. A programming language consists of instructions that are provided to a computer program. The computer program simply reads one instruction at a time, and performs some work according to the contents of the instruction. Therefore, programming languages have strict rules about every operation that they support. The programming language provides a set of operations that it supports, and we build programs by combining those operations.
Moreover, programs need to be converted from text into a version of those instructions that the computer understands. Therefore the text must also follow a specific and clearly-defined syntax. The meaning of something like [] is and must be unambiguous, otherwise it would be impossible for the computer to interpret our programs.
The important conclusion here is that computer programs must be expressed in a specific way, and that every piece of text has a specific purpose and meaning. Python does not and cannot ever understand what your intentions are. Programming consists of taking your ideas and translating them into the specific operations and syntax provided by the programming language.
I write this because you seem to be taking an interpretive approach to reading code, and you seem to be lacking the fundamental knowledge required to understand it properly. You seem to be trying to guess at the meaning of code by broadly matching it up to how it looks in English. As nice as it is that Python looks like plain English text, it is not plain English text. It is a programming language like any other, and its rules are as strict as any other. If you don't know what something means, resist the temptation to guess at what it means.
I strongly suggest finding a structured learning resource, such as an online course or a book. It will guide you through all of the concepts, syntax elements, and data types that you will need to learn programming. You must learn what these things are. You will never be able to read or write code by interpreting and guessing based on visual patterns.
I am not sure why [name] is in brackets instead of language. We are interested in the language they prioritize and not who the person is (for the value 'language' in specific at least). So I am wondering why the brackets have 'name' inside them, and not 'language'.
It is in brackets because the names are the keys of the dictionary. The favorite_languages is a lookup table from names to languages. It is not a lookup table from languages to names.
In general, a dictionary is a one-way lookup table. The things on the left of : are the "keys", and the things on the right are the "values". The keys must be unique, but the values can be non-unique. The [] syntax performs lookups from keys to values only.
What you are "interested in" is relevant only insofar as it is the goal of your program. You do not get to choose what [] means, based on what you are interested in. Its meaning is built into Python and cannot be changed without modifying Python itself. You must use the tools that you are given, and cannot use tools that do not exist.
first we have a dictionary called favorite_languages first column are keys, second column are values
It's not helpful to think of a dictionary as "columns", like a spreadsheet. Think of it as a lookup table. That's why it's called a dictionary. The keys of the dictionary are like words in a traditional dictionary, and the values are like definitions.
It is important to have a clear understanding of what dictionaries do. Otherwise you won't understand when or how to use them, and you won't understand code that uses them. That might be what is happening here.
going down, we have a list called friends, I think the words inside are called values.
This is a somewhat different usage of the term "value".
Outside the context of dictionaries, "value" does not have a strict technical meaning. The word is usually used to distinguish values, which are tangible things, from variables, which are placeholders for things and do not mean anything on their own.
So when we talk about the values in a list, we are just talking about the things inside the list. People also use the word elements to mean the same thing.
editor? right?
I assume you are talking about an "editor" as in a "text editor" or "code editor". No. That's just a program that you use to edit text. It does not run your code. Some code editors like VS Code have built-in features that help you write code. But your code never "tells" your text editor anything. The code exists to be interpreted by Python. Anything else is just an attempt to help you write the code.
for name in favorite_languages.keys(): this line of code says tells the editor? right? that the keys (first column), each of the keys will be categorized as a 'name'. correct? the keys in the dictionary (named favorite_languages).
No. This code does not categorize anything.
The .keys() method accesses the keys of a dictionary (as explained above). This loops over favorite_languages.keys() and assigns the looped values to name.
The syntax for x in things: loops over the elements of things. It assigns the first element to x, then runs the code in the block, then assigns the second element to x, then runs the code in the block, etc. Loops are an essential tool in programming, and it is very important that you spend time on understanding how they work and how to use them.
print(f"Hi {name.title()}.")
Your understanding seems correct.
name is the key from favorite_languages.keys(), because of for name in favorite_languages.keys():. We also happen to know that this corresponds to people's names.
if name in friends:
Correct. name in friends is an expression that returns True if and only if the value of name is equal to one of the elements in friends.
The if then executes the code inside the block if and only if the result is True (or is equivalent to True in a specific sense that you don't need to worry about right now).
language = favorite_languages[name].title()
This code does not put anything back into the dictionary. This code does not operate by finding values "next to" anything.
favorite_languages is a dictionary, i.e. a lookup table. This code uses the value of name to look up a language in favorite_languages.
Finally, it assigns the result to the language variable. From the perspective of Python, this variable is completely unrelated to the favorite_languages. It is a completely separate placeholder.
The fact that they both say "languages" is relevant to you, the reader and programmer, but not relevant to Python.
print(f"\t{name.title()}, I see you love {language}!")
\t is a tab characdter, not a new line.
Otherwise yes, your interpretation is correct.

Replacing keystrokes using Python

I use a multilingual keyboard. Sometimes I write something in one language, forgetting to switch the keyboard layout (e.g. Alt+Shift in Windows) and getting gibberish, which I then erase, switch languauges and rewrite.
I thought of writing a script that replaces highlighted text automatically and assign a keyboard shortcut to it (in Linux). This is intended as a recreational project, and I'm a programming noob, so I don't yet know how to do most of it and I don't have code to share.
My concrete question is (assuming Python, but I haven't started yet so willing to consider alternatives):
Is there an efficient way to map keystrokes in one layout with keystrokes in another layout?
Right now my default idea is to create an explicit table of replacements, e.g. a<->ש, b<->נ etc.
But this would be neither pleasant nor elegant.
Any suggestions?
EDIT: I'll emphasize that I'm not asking about how to perform the actual replacement (e.g. via a dicitionary if using Python), but rather if there is a way to avoid writing an explicit table (dictionary or whatever) for each character in my keyboard.
For example, if there is a way to say "given the layout ENG (US), the letter 'a' corresponds to this phyiscal key right here on the left side of the keyboard, and this physical key, when using the HEB layout, corresponds to the letter ש".
If there's a way to do such a thing, I can write something like keyID = GetKeyID(char,layout) followed by altchar = GetChar(keyID,altlayout).
I hope this makes sense. Note this was only an example of what I might hope for, I'd be happy to hear other ideas!

Google cloud speech to text grammar to narrow results to a number?

I very simply want to pass is a tiny audio clip (8Khz telephony) containing a single digit number, and get back a single digit number as text, narrowed down to a number.
File in > number as text out. Preferably via the python command line API.
The problem is, by default, it recognises things like 1,2,3,4,5 as won,too,free,fore,5 ... no good!
I believe I want what is called a grammar? Or something like Amazon's number slot types it uses in Alexa? I've looked over the cloud speech docs and can't find it. The only thing I could think of is looping over the alternatives given and see if any match an int rather than a word. And if none do, then what?
Thanks.
A.Queue's answer is correct, however, in case others are bitten by the docs:
The link given suggests:
{ "phrases": [ string], }
The python documentation says:
speech_contexts
Optional: A means to provide context to assist the speech recognition.
The python examples show:
language_code='en-US',
max_alternatives=max_alternatives,
profanity_filter=True,
speech_contexts=['Google', 'cloud'],
What actually works is:
speech_contexts=[speech.types.SpeechContext(
phrases=['Google', 'cloud'],
)]
I managed to get this from a Googler on Slack who pointed me to some alternative more comprehensive and accurate documentation. Bookmark that last link for future sanity.
Try adding speechContexts. You can then add a few phrases that you think are most probable.

Localization and future-proofing

so I know this is a not a good question for the StackOverflow format. but I am at a bit of a loss, feel free to recommend a different place to put this where it may get some eyeballs
I am very familliar with the xgettext stuff for localizing your python program. currently we are saving user preferences as strings (eg: user_prefs = {'temperature':u'\u00b0C Fahrenheit', 'volumetric':'Cubic inches', ...} )
this works fine, and when operating in foreign languages we attempt(mostly successfully) to reverse the string localization back to english before saving it. so that the saved string is always the english version, and then we localize them when we start the program.
however it leads to problems later if we change 'Cubic inches' to u'in\u00b3' or even a small change like 'Cubic inches' to 'Cubic Inches'. we have somewhat compensated for this by always doing comparisons in lower case, but it feels hackish to me, and it seems like there must be a better way to do it such as saving an id (be it an index into an array or even just some unique identifier). but wondering about others experiences here with regards to future proofing user preferences so that they will always be recognized.
I suspect this will get closed (asking for subjective answers) but maybe I can get some good insight before it does
It sounds like you are trying to use the English representation of your text as a unique ID for the message, but then when you change the English representation, it no longer matches the IDs in your previously stored preference files. The solution is to use a unique and permanent ID for each message. This ID could be English-readable, but you have to commit to never changing it. It's probably helpful to use a simple and standardized naming convention for this ID, with no unicode or uppercase characters. For example, one message ID might be 'cubic inches'. Another could be 'degrees fahrenheit'
Then, you should define internationalized text for displaying this message in every language, including English. So if you want to display the 'cubic inches' message on an English system, you will lookup the English equivalent for this ID and get 'Cubic inches', 'Cubic Inches', u'in\u00b3' or whatever you like. Then your application can display that text. But you will always store the permanent message ID ('cubic inches') in the preferences file. This gives you the flexibility to change the English-language representation of the message, as shown to the user, without invalidating the IDs in previously-stored preference files.
i don't get your actual problem, where are you storing.
but hope "base64 utf encoding decoding" can solve your problem.

Widget to add, remove, and sort entries in a wxpython program

I'm working on a program that outputs a text procedure file, based on user input. ie, the user will have a few options they can select from, and I'd like for them to be able to add them, reorder them, etc. into a custom order, and have it output that list into a text file.
I'd like to write this in python, and I am familiar with wxWidgets, but not tied to that. Any ideas?
If you're talking about some kind of list box with strings in it, then you might want to look at the EditableListBox, which is in wx.gizmos.EditableListBox. See the wxPython demo for more info.
Otherwise you'll have to roll your own, which really shouldn't be that hard.

Categories