Skip to content

Simple app to motivate and track foreign language speaking practice

Notifications You must be signed in to change notification settings

mrkthmpsn/hablo-un-poco

Repository files navigation

hablo-un-poco

Raison d'être

After a while plugging away at Duolingo, I wanted something more than mini-games.

This project is an attempt to set up and encourage speaking practice sessions, with data monitoring and a hook-up to the Google Translate API to leave or review tricky words before and after the session.

Demo

https://youtu.be/pmHW0hU7DUg

Technologies/practices used

✨ = new; 👨‍‍🏫 = learning; 🤝 = familiar

  • streamlit 🤝
  • streamlit.AppTest for streamlit testing ✨
  • pytest for general testing 👨‍‍🏫
  • Google Translate API/SDK ✨
  • Test-driven development as a general approach ✨
    • (mostly adhered to)
  • bump2version for version management ✨

'Roadmap'

Chores

  • Finish Google Translate API instructions
  • Write tests for the Google Translate API translation util
  • Demo
  • Containerise
  • Complete the session state maintenance when moving between pages
    • (Only did the pre-session components as the ones most likely to be interrupted by a page change)

Features

  • Add option in settings to set languages
    • And add this to the saved data
    • And let the data view be filterable by the languages
  • Add notes for each session to the data saved
    • This could take the form of words that have been translated
  • 'Game-ify' features

Running locally

Google Translate API

[Written July 2024] Unfortunately, you need to deal with Google authentication - 'unfortunately' because Google's docs are labrynthine.

Log in to Google Cloud and create a new project. You will have to supply billing information, but if your account is new you'll get free credits which will more than cover the API costs (in development and use over the past month, my Google Translate costs are nearly 3p).

Google authentication uses Application Default Credentials for local development. Follow 'Configure ADC with your Google Account' instructions. Grab the path of the application_default_credentials.json file as described in the 'User credentials provided by using Google CLI' section here and add it to your .env file.

Using the file path isn't strictly necessary for local development, but I didn't like the 'magic' of the Google client finding the file in my directory undocumented.

Please get in touch if you have problems with this or can improve on the documentation of this process.

Set-up files

Create an .env file in the root directory, following the template in .env.example

Create user_data.csv and user_categories.csv files in the data folder, following the template in that folder's README.md.

Everything else

Run pytest . to check that everything is working (and that, if anything breaks, it's not you who did it).


Useful Streamlit links and notes

Session state

Session state is important and/but something with some quirks in Streamlit. Thankfully, they have some specific pages about this in their documentation.

There's a section about using buttons to modify or reset other widgets here, which is really useful as buttons are one of the most frequent, most simple aspects you can use.

Another important concept is widget state and the ways it can interact with session state. On a multi-page app, widgets (according to my understanding) get torn down when you switch page, which means that their value will be reset. The way around this is documented in this section about session state and widget state.

Testing

The testing framework is a fantastic addition to Streamlit. It is relatively well-documented in the App testing section of the docs here.

There are a couple of main quirks that I think it's worth being aware of:

  • You can call st.<widget_type> within a test and it will return a list of all of the widgets of that type. As far as I can tell, you then reference specific instances by their index in this list - it might be useful if you could reference by the widget key.
  • The st.write widget, which is 'magic' and smart about how it outputs what is passed to it, will depend based on said input. Written text is output as st.markdown. This wasn't obvious to me from the testing docs but makes sense when reading the st.write page itself.
  • Each instance of a widget (e.g. the 0th item in the st.write list) will be a Streamlit element class. As far as I can tell, these aren't documented, although using an IDE like Pycharm will help you find the attributes you need. Generally, looking for .value will be enough.

Making a timer in Streamlit

The timer/stopwatch component was a crucial one of this idea, and I thought this would be an easy plug and play. I wasn't sure how, but assumed there'd be either a native or third-party solution. Not quite.

There wasn't one of either. My mind then went to use an st.html block (as I was aware they existed and it seemed like a task ChatGPT could bash out), but that didn't work because st.html didn't allow javascript to be executable.

Fortunately, others have had similar questions on the Streamlit Discuss community. This question supplied a base that kinda worked, but not really for my uses; more of a timer than a stopwatch, and I wanted more of a stopwatch Then, this comment on another question and the subsequent comments further down, led me to the working version that I have now. The main difference between my version and the code derived from those comments is that I decided to maintain a version of the output when the function was paused.

App functionality design thoughts

The app is very simple but there were a few deliberate choices that I wanted to note.

Confidence scale

Some days you don't feel good and some days you feel great!

I think having this at the top is a nice, implicit acknowledgement of that which actually makes me more likely to give it a go even if I'm not feeling confident.

Part of that is because I figured the 'target time' should be linked to that confidence level. How you're feeling is going to have an effect on what 'success' looks like, and I think the changing limits of the target time make it a better incentive.

Also, the seven-point scale. I like seven-point scales. Everyone knows that people shy away from the extremes of scales, and I reckon this is particularly going to be the case when talking about confidence at speaking in a foreign language. Also, really, if you're feeling at the negative extreme you're probably not going to be doing a speaking session in the first place.

Google Translate integration

The integration before and after the speaking session was deliberate.

I've found, personally, that trying to speak while sat in front of the Google Translate website leads to me relying on it more and more. Part of speaking a foreign language is needing to navigate around your ability in it in the moment, and having a dictionary in front of you makes it tempting to start 'translating' rather than speaking.

It also meshes quite nicely with the 'focus topic' idea. The topic helps make it clearer what you might need to translate ahead of time, while a completely open speaking session may make the pre-session translation overwhelming.

About

Simple app to motivate and track foreign language speaking practice

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages